From 305baf5bd419920f4b80ff6f0075c13dd42c2b94 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Wed, 27 Mar 2024 16:30:22 +0100 Subject: [PATCH 01/28] replace hub with scopes --- .../api/sentry-android-core.api | 28 +- .../core/ActivityBreadcrumbsIntegration.java | 17 +- .../core/ActivityLifecycleIntegration.java | 32 +- .../core/AndroidTransactionProfiler.java | 12 +- .../sentry/android/core/AnrIntegration.java | 19 +- .../sentry/android/core/AnrV2Integration.java | 14 +- .../AppComponentsBreadcrumbsIntegration.java | 16 +- .../android/core/AppLifecycleIntegration.java | 14 +- .../core/CurrentActivityIntegration.java | 4 +- .../core/EnvelopeFileObserverIntegration.java | 14 +- .../android/core/InternalSentrySdk.java | 24 +- .../sentry/android/core/LifecycleWatcher.java | 22 +- .../sentry/android/core/NdkIntegration.java | 9 +- .../core/NetworkBreadcrumbsIntegration.java | 21 +- .../PhoneStateBreadcrumbsIntegration.java | 20 +- .../core/SendCachedEnvelopeIntegration.java | 20 +- .../io/sentry/android/core/SentryAndroid.java | 11 +- .../SystemEventsBreadcrumbsIntegration.java | 20 +- .../TempSensorBreadcrumbsIntegration.java | 12 +- .../core/UserInteractionIntegration.java | 12 +- .../gestures/SentryGestureListener.java | 18 +- .../core/AndroidTransactionProfilerTest.kt | 12 +- .../sentry/android/core/AnrIntegrationTest.kt | 28 +- .../android/core/AnrV2IntegrationTest.kt | 90 +-- ...AppComponentsBreadcrumbsIntegrationTest.kt | 48 +- .../core/AppLifecycleIntegrationTest.kt | 16 +- .../core/CurrentActivityIntegrationTest.kt | 6 +- .../core/DefaultAndroidEventProcessorTest.kt | 8 +- .../EnvelopeFileObserverIntegrationTest.kt | 20 +- .../android/core/LifecycleWatcherTest.kt | 48 +- .../sentry/android/core/NdkIntegrationTest.kt | 22 +- .../core/NetworkBreadcrumbsIntegrationTest.kt | 108 ++-- .../PerformanceAndroidEventProcessorTest.kt | 20 +- .../PhoneStateBreadcrumbsIntegrationTest.kt | 38 +- .../core/SendCachedEnvelopeIntegrationTest.kt | 30 +- .../SystemEventsBreadcrumbsIntegrationTest.kt | 24 +- .../TempSensorBreadcrumbsIntegrationTest.kt | 32 +- .../SentryGestureListenerClickTest.kt | 22 +- .../SentryGestureListenerScrollTest.kt | 26 +- .../SentryGestureListenerTracingTest.kt | 58 +- .../api/sentry-android-fragment.api | 8 +- .../fragment/FragmentLifecycleIntegration.kt | 10 +- .../SentryFragmentLifecycleCallbacks.kt | 18 +- .../FragmentLifecycleIntegrationTest.kt | 16 +- .../SentryFragmentLifecycleCallbacksTest.kt | 14 +- .../android/mockservers/RelayAsserter.kt | 2 +- .../api/sentry-android-navigation.api | 10 +- .../navigation/SentryNavigationListener.kt | 24 +- .../SentryNavigationListenerTest.kt | 54 +- .../api/sentry-android-okhttp.api | 18 +- .../okhttp/SentryOkHttpEventListener.kt | 22 +- .../android/okhttp/SentryOkHttpInterceptor.kt | 16 +- .../android/sqlite/SQLiteSpanManager.kt | 12 +- .../android/sqlite/SQLiteSpanManagerTest.kt | 12 +- .../sqlite/SentrySupportSQLiteDatabaseTest.kt | 12 +- .../SentrySupportSQLiteStatementTest.kt | 12 +- .../api/sentry-android-timber.api | 4 +- .../android/timber/SentryTimberIntegration.kt | 6 +- .../sentry/android/timber/SentryTimberTree.kt | 8 +- .../timber/SentryTimberIntegrationTest.kt | 18 +- .../android/timber/SentryTimberTreeTest.kt | 52 +- sentry-apollo-3/api/sentry-apollo-3.api | 20 +- .../apollo3/SentryApollo3HttpInterceptor.kt | 36 +- .../apollo3/SentryApolloBuilderExtensions.kt | 10 +- .../SentryApollo3InterceptorClientErrors.kt | 40 +- .../apollo3/SentryApollo3InterceptorTest.kt | 40 +- ...ntryApollo3InterceptorWithVariablesTest.kt | 22 +- sentry-apollo/api/sentry-apollo.api | 6 +- .../sentry/apollo/SentryApolloInterceptor.kt | 20 +- .../apollo/SentryApolloInterceptorTest.kt | 38 +- sentry-graphql/api/sentry-graphql.api | 20 +- .../io/sentry/graphql/ExceptionReporter.java | 43 +- .../graphql/NoOpSubscriptionHandler.java | 4 +- .../SentryDataFetcherExceptionHandler.java | 14 +- ...tryGenericDataFetcherExceptionHandler.java | 4 +- .../sentry/graphql/SentryInstrumentation.java | 38 +- .../graphql/SentrySubscriptionHandler.java | 4 +- .../sentry/graphql/ExceptionReporterTest.kt | 32 +- .../SentryDataFetcherExceptionHandlerTest.kt | 8 +- ...yGenericDataFetcherExceptionHandlerTest.kt | 6 +- .../SentryInstrumentationAnotherTest.kt | 40 +- .../graphql/SentryInstrumentationTest.kt | 36 +- sentry-jdbc/api/sentry-jdbc.api | 2 +- .../sentry/jdbc/SentryJdbcEventListener.java | 14 +- .../jdbc/SentryJdbcEventListenerTest.kt | 16 +- .../java/io/sentry/jul/SentryHandler.java | 6 +- .../api/sentry-kotlin-extensions.api | 8 +- .../java/io/sentry/kotlin/SentryContext.kt | 28 +- .../io/sentry/kotlin/SentryContextTest.kt | 6 +- sentry-log4j2/api/sentry-log4j2.api | 2 +- .../java/io/sentry/log4j2/SentryAppender.java | 20 +- .../io/sentry/log4j2/SentryAppenderTest.kt | 6 +- .../io/sentry/logback/SentryAppender.java | 6 +- sentry-okhttp/api/sentry-okhttp.api | 18 +- .../io/sentry/okhttp/SentryOkHttpEvent.kt | 16 +- .../okhttp/SentryOkHttpEventListener.kt | 24 +- .../sentry/okhttp/SentryOkHttpInterceptor.kt | 22 +- .../io/sentry/okhttp/SentryOkHttpUtils.kt | 18 +- .../okhttp/SentryOkHttpEventListenerTest.kt | 28 +- .../io/sentry/okhttp/SentryOkHttpEventTest.kt | 52 +- .../okhttp/SentryOkHttpInterceptorTest.kt | 50 +- .../io/sentry/okhttp/SentryOkHttpUtilsTest.kt | 22 +- sentry-openfeign/api/sentry-openfeign.api | 4 +- .../io/sentry/openfeign/SentryCapability.java | 17 +- .../sentry/openfeign/SentryFeignClient.java | 14 +- .../sentry/openfeign/SentryFeignClientTest.kt | 22 +- .../OpenTelemetryLinkErrorEventProcessor.java | 26 +- .../opentelemetry/SentryPropagator.java | 24 +- .../opentelemetry/SentrySpanProcessor.java | 50 +- .../test/kotlin/SentrySpanProcessorTest.kt | 48 +- sentry-quartz/api/sentry-quartz.api | 2 +- .../io/sentry/quartz/SentryJobListener.java | 28 +- .../samples/android/ProfilingActivity.kt | 2 +- .../samples/spring/jakarta/AppConfig.java | 6 +- .../samples/spring/jakarta/WebConfig.java | 8 +- .../io/sentry/samples/spring/AppConfig.java | 6 +- .../io/sentry/samples/spring/WebConfig.java | 8 +- .../api/sentry-servlet-jakarta.api | 2 +- .../jakarta/SentryServletRequestListener.java | 20 +- .../SentryServletRequestListenerTest.kt | 12 +- sentry-servlet/api/sentry-servlet.api | 2 +- .../servlet/SentryServletRequestListener.java | 20 +- .../SentryServletRequestListenerTest.kt | 12 +- .../api/sentry-spring-boot-jakarta.api | 2 +- .../boot/jakarta/SentryAutoConfiguration.java | 43 +- .../SentrySpanRestClientCustomizer.java | 6 +- .../SentrySpanRestTemplateCustomizer.java | 6 +- .../SentrySpanWebClientCustomizer.java | 6 +- .../SentryWebfluxAutoConfiguration.java | 21 +- .../jakarta/SentryAutoConfigurationTest.kt | 12 +- .../SentrySpanRestClientCustomizerTest.kt | 22 +- .../SentrySpanRestTemplateCustomizerTest.kt | 22 +- .../SentrySpanWebClientCustomizerTest.kt | 22 +- .../jakarta/it/SentrySpringIntegrationTest.kt | 6 +- sentry-spring-boot/api/sentry-spring-boot.api | 4 +- .../spring/boot/SentryAutoConfiguration.java | 39 +- .../SentrySpanRestTemplateCustomizer.java | 6 +- .../boot/SentrySpanWebClientCustomizer.java | 6 +- .../boot/SentryWebfluxAutoConfiguration.java | 15 +- .../boot/SentryAutoConfigurationTest.kt | 12 +- .../SentrySpanRestTemplateCustomizerTest.kt | 22 +- .../boot/SentrySpanWebClientCustomizerTest.kt | 22 +- .../boot/it/SentrySpringIntegrationTest.kt | 6 +- .../api/sentry-spring-jakarta.api | 61 +- .../sentry/spring/jakarta/EnableSentry.java | 2 +- .../jakarta/SentryExceptionResolver.java | 10 +- .../spring/jakarta/SentryHubRegistrar.java | 4 +- .../jakarta/SentryInitBeanPostProcessor.java | 16 +- .../spring/jakarta/SentryRequestResolver.java | 16 +- .../spring/jakarta/SentrySpringFilter.java | 38 +- .../spring/jakarta/SentryTaskDecorator.java | 18 +- .../spring/jakarta/SentryUserFilter.java | 12 +- .../jakarta/checkin/SentryCheckInAdvice.java | 28 +- ...SentryCaptureExceptionParameterAdvice.java | 14 +- .../graphql/SentryBatchLoaderRegistry.java | 16 +- .../graphql/SentryDgsSubscriptionHandler.java | 6 +- .../SentrySpringSubscriptionHandler.java | 6 +- .../jakarta/tracing/SentrySpanAdvice.java | 14 +- ...entrySpanClientHttpRequestInterceptor.java | 18 +- .../SentrySpanClientWebRequestFilter.java | 14 +- .../jakarta/tracing/SentryTracingFilter.java | 31 +- .../tracing/SentryTransactionAdvice.java | 20 +- .../webflux/AbstractSentryWebFilter.java | 35 +- .../spring/jakarta/webflux/ReactorUtils.java | 35 +- .../SentryReactorThreadLocalAccessor.java | 18 +- .../webflux/SentryRequestResolver.java | 13 +- .../jakarta/webflux/SentryScheduleHook.java | 12 +- .../webflux/SentryWebExceptionHandler.java | 18 +- .../jakarta/webflux/SentryWebFilter.java | 16 +- ...entryWebFilterWithThreadLocalAccessor.java | 13 +- .../sentry/spring/jakarta/EnableSentryTest.kt | 4 +- .../spring/jakarta/SentryCheckInAdviceTest.kt | 94 +-- .../jakarta/SentryExceptionResolverTest.kt | 28 +- .../SentryInitBeanPostProcessorTest.kt | 10 +- ...yRequestHttpServletRequestProcessorTest.kt | 6 +- .../spring/jakarta/SentrySpringFilterTest.kt | 20 +- .../spring/jakarta/SentryTaskDecoratorTest.kt | 16 +- .../spring/jakarta/SentryUserFilterTest.kt | 20 +- ...ntryCaptureExceptionParameterAdviceTest.kt | 16 +- .../SentrySpringSubscriptionHandlerTest.kt | 14 +- .../mvc/SentrySpringIntegrationTest.kt | 24 +- .../jakarta/tracing/SentrySpanAdviceTest.kt | 40 +- .../tracing/SentryTracingFilterTest.kt | 52 +- .../tracing/SentryTransactionAdviceTest.kt | 38 +- .../jakarta/webflux/ReactorUtilsTest.kt | 45 +- .../jakarta/webflux/SentryScheduleHookTest.kt | 16 +- .../webflux/SentryWebFluxTracingFilterTest.kt | 93 +-- .../webflux/SentryWebfluxIntegrationTest.kt | 10 +- sentry-spring/api/sentry-spring.api | 37 +- .../spring/SentryExceptionResolver.java | 10 +- .../io/sentry/spring/SentryHubRegistrar.java | 4 +- .../spring/SentryInitBeanPostProcessor.java | 16 +- .../sentry/spring/SentryRequestResolver.java | 16 +- .../io/sentry/spring/SentrySpringFilter.java | 38 +- .../io/sentry/spring/SentryTaskDecorator.java | 14 +- .../io/sentry/spring/SentryUserFilter.java | 12 +- .../spring/checkin/SentryCheckInAdvice.java | 28 +- ...SentryCaptureExceptionParameterAdvice.java | 14 +- .../graphql/SentryBatchLoaderRegistry.java | 16 +- .../graphql/SentryDgsSubscriptionHandler.java | 6 +- .../SentrySpringSubscriptionHandler.java | 6 +- .../spring/tracing/SentrySpanAdvice.java | 14 +- ...entrySpanClientHttpRequestInterceptor.java | 14 +- .../SentrySpanClientWebRequestFilter.java | 14 +- .../spring/tracing/SentryTracingFilter.java | 31 +- .../tracing/SentryTransactionAdvice.java | 20 +- .../spring/webflux/SentryRequestResolver.java | 13 +- .../spring/webflux/SentryScheduleHook.java | 12 +- .../webflux/SentryWebExceptionHandler.java | 10 +- .../spring/webflux/SentryWebFilter.java | 33 +- .../io/sentry/spring/EnableSentryTest.kt | 6 +- .../sentry/spring/SentryCheckInAdviceTest.kt | 94 +-- .../spring/SentryExceptionResolverTest.kt | 28 +- .../spring/SentryInitBeanPostProcessorTest.kt | 10 +- ...yRequestHttpServletRequestProcessorTest.kt | 6 +- .../sentry/spring/SentrySpringFilterTest.kt | 20 +- .../sentry/spring/SentryTaskDecoratorTest.kt | 16 +- .../io/sentry/spring/SentryUserFilterTest.kt | 20 +- ...ntryCaptureExceptionParameterAdviceTest.kt | 16 +- .../SentrySpringSubscriptionHandlerTest.kt | 14 +- .../spring/mvc/SentrySpringIntegrationTest.kt | 24 +- .../spring/tracing/SentrySpanAdviceTest.kt | 40 +- .../spring/tracing/SentryTracingFilterTest.kt | 52 +- .../tracing/SentryTransactionAdviceTest.kt | 38 +- .../spring/webflux/SentryScheduleHookTest.kt | 14 +- .../webflux/SentryWebFluxTracingFilterTest.kt | 93 +-- .../webflux/SentryWebfluxIntegrationTest.kt | 10 +- .../api/sentry-test-support.api | 1 + .../main/kotlin/io/sentry/test/Reflection.kt | 11 +- sentry/api/sentry.api | 333 +++++++--- sentry/src/main/java/io/sentry/Baggage.java | 4 +- .../java/io/sentry/DirectoryProcessor.java | 8 +- .../main/java/io/sentry/EnvelopeSender.java | 10 +- sentry/src/main/java/io/sentry/Hub.java | 1 + .../src/main/java/io/sentry/HubAdapter.java | 22 +- .../main/java/io/sentry/HubScopesWrapper.java | 279 ++++++++ sentry/src/main/java/io/sentry/IHub.java | 595 +----------------- sentry/src/main/java/io/sentry/IScopes.java | 594 +++++++++++++++++ .../src/main/java/io/sentry/Integration.java | 4 +- .../main/java/io/sentry/MonitorConfig.java | 2 +- sentry/src/main/java/io/sentry/NoOpHub.java | 7 + .../src/main/java/io/sentry/NoOpScopes.java | 243 +++++++ .../src/main/java/io/sentry/OutboxSender.java | 14 +- .../io/sentry/PreviousSessionFinalizer.java | 8 +- .../main/java/io/sentry/ScopesAdapter.java | 286 +++++++++ ...achedEnvelopeFireAndForgetIntegration.java | 20 +- .../SendFireAndForgetEnvelopeSender.java | 6 +- .../sentry/SendFireAndForgetOutboxSender.java | 6 +- sentry/src/main/java/io/sentry/Sentry.java | 176 +++--- .../src/main/java/io/sentry/SentryTracer.java | 85 +-- .../main/java/io/sentry/SentryWrapper.java | 21 +- .../io/sentry/ShutdownHookIntegration.java | 6 +- sentry/src/main/java/io/sentry/Span.java | 30 +- .../java/io/sentry/SpotlightIntegration.java | 2 +- .../UncaughtExceptionHandlerIntegration.java | 12 +- .../backpressure/BackpressureMonitor.java | 11 +- .../file/FileIOSpanManager.java | 6 +- .../file/SentryFileInputStream.java | 42 +- .../file/SentryFileOutputStream.java | 44 +- .../file/SentryFileReader.java | 7 +- .../file/SentryFileWriter.java | 6 +- .../java/io/sentry/util/CheckInUtils.java | 15 +- .../java/io/sentry/util/TracingUtils.java | 18 +- ...aultTransactionPerformanceCollectorTest.kt | 8 +- .../java/io/sentry/DirectoryProcessorTest.kt | 16 +- .../test/java/io/sentry/EnvelopeSenderTest.kt | 20 +- .../src/test/java/io/sentry/HubAdapterTest.kt | 92 +-- sentry/src/test/java/io/sentry/HubTest.kt | 430 ++++++------- .../test/java/io/sentry/JsonSerializerTest.kt | 8 +- .../java/io/sentry/MainEventProcessorTest.kt | 6 +- .../test/java/io/sentry/OutboxSenderTest.kt | 28 +- .../io/sentry/PreviousSessionFinalizerTest.kt | 22 +- sentry/src/test/java/io/sentry/ScopeTest.kt | 24 +- .../test/java/io/sentry/ScopesAdapterTest.kt | 265 ++++++++ ...hedEnvelopeFireAndForgetIntegrationTest.kt | 34 +- .../test/java/io/sentry/SentryClientTest.kt | 28 +- sentry/src/test/java/io/sentry/SentryTest.kt | 112 ++-- .../test/java/io/sentry/SentryWrapperTest.kt | 32 +- .../io/sentry/ShutdownHookIntegrationTest.kt | 22 +- sentry/src/test/java/io/sentry/SpanTest.kt | 24 +- .../sentry/TraceContextSerializationTest.kt | 6 +- ...UncaughtExceptionHandlerIntegrationTest.kt | 62 +- .../backpressure/BackpressureMonitorTest.kt | 12 +- .../sentry/clientreport/ClientReportTest.kt | 8 +- .../file/FileIOSpanManagerTest.kt | 14 +- .../file/SentryFileInputStreamTest.kt | 22 +- .../file/SentryFileOutputStreamTest.kt | 12 +- .../file/SentryFileReaderTest.kt | 12 +- .../file/SentryFileWriterTest.kt | 12 +- .../internal/SpotlightIntegrationTest.kt | 10 +- .../java/io/sentry/protocol/SentrySpanTest.kt | 4 +- .../io/sentry/transport/RateLimiterTest.kt | 32 +- .../java/io/sentry/util/CheckInUtilsTest.kt | 91 +-- .../java/io/sentry/util/TracingUtilsTest.kt | 30 +- 294 files changed, 5314 insertions(+), 3889 deletions(-) create mode 100644 sentry/src/main/java/io/sentry/HubScopesWrapper.java create mode 100644 sentry/src/main/java/io/sentry/IScopes.java create mode 100644 sentry/src/main/java/io/sentry/NoOpScopes.java create mode 100644 sentry/src/main/java/io/sentry/ScopesAdapter.java create mode 100644 sentry/src/test/java/io/sentry/ScopesAdapterTest.kt diff --git a/sentry-android-core/api/sentry-android-core.api b/sentry-android-core/api/sentry-android-core.api index 8eb017346d..2afe788ef8 100644 --- a/sentry-android-core/api/sentry-android-core.api +++ b/sentry-android-core/api/sentry-android-core.api @@ -8,7 +8,7 @@ public final class io/sentry/android/core/ActivityBreadcrumbsIntegration : andro public fun onActivitySaveInstanceState (Landroid/app/Activity;Landroid/os/Bundle;)V public fun onActivityStarted (Landroid/app/Activity;)V public fun onActivityStopped (Landroid/app/Activity;)V - public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/android/core/ActivityFramesTracker { @@ -33,7 +33,7 @@ public final class io/sentry/android/core/ActivityLifecycleIntegration : android public fun onActivitySaveInstanceState (Landroid/app/Activity;Landroid/os/Bundle;)V public fun onActivityStarted (Landroid/app/Activity;)V public fun onActivityStopped (Landroid/app/Activity;)V - public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/android/core/AndroidCpuCollector : io/sentry/IPerformanceSnapshotCollector { @@ -87,7 +87,7 @@ public class io/sentry/android/core/AndroidProfiler$ProfileStartData { public final class io/sentry/android/core/AnrIntegration : io/sentry/Integration, java/io/Closeable { public fun (Landroid/content/Context;)V public fun close ()V - public final fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public final fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/android/core/AnrIntegrationFactory { @@ -104,7 +104,7 @@ public final class io/sentry/android/core/AnrV2EventProcessor : io/sentry/Backfi public class io/sentry/android/core/AnrV2Integration : io/sentry/Integration, java/io/Closeable { public fun (Landroid/content/Context;)V public fun close ()V - public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/android/core/AnrV2Integration$AnrV2Hint : io/sentry/hints/BlockingFlushHint, io/sentry/hints/AbnormalExit, io/sentry/hints/Backfillable { @@ -123,13 +123,13 @@ public final class io/sentry/android/core/AppComponentsBreadcrumbsIntegration : public fun onConfigurationChanged (Landroid/content/res/Configuration;)V public fun onLowMemory ()V public fun onTrimMemory (I)V - public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/android/core/AppLifecycleIntegration : io/sentry/Integration, java/io/Closeable { public fun ()V public fun close ()V - public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/android/core/AppState { @@ -177,7 +177,7 @@ public final class io/sentry/android/core/CurrentActivityIntegration : android/a public fun onActivitySaveInstanceState (Landroid/app/Activity;Landroid/os/Bundle;)V public fun onActivityStarted (Landroid/app/Activity;)V public fun onActivityStopped (Landroid/app/Activity;)V - public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/android/core/DeviceInfoUtil { @@ -193,7 +193,7 @@ public abstract class io/sentry/android/core/EnvelopeFileObserverIntegration : i public fun ()V public fun close ()V public static fun getOutboxFileObserver ()Lio/sentry/android/core/EnvelopeFileObserverIntegration; - public final fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public final fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public abstract interface class io/sentry/android/core/IDebugImagesLoader { @@ -219,19 +219,19 @@ public final class io/sentry/android/core/NdkIntegration : io/sentry/Integration public static final field SENTRY_NDK_CLASS_NAME Ljava/lang/String; public fun (Ljava/lang/Class;)V public fun close ()V - public final fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public final fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/android/core/NetworkBreadcrumbsIntegration : io/sentry/Integration, java/io/Closeable { public fun (Landroid/content/Context;Lio/sentry/android/core/BuildInfoProvider;Lio/sentry/ILogger;)V public fun close ()V - public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/android/core/PhoneStateBreadcrumbsIntegration : io/sentry/Integration, java/io/Closeable { public fun (Landroid/content/Context;)V public fun close ()V - public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/android/core/ScreenshotEventProcessor : io/sentry/EventProcessor { @@ -360,7 +360,7 @@ public final class io/sentry/android/core/SystemEventsBreadcrumbsIntegration : i public fun (Landroid/content/Context;)V public fun (Landroid/content/Context;Ljava/util/List;)V public fun close ()V - public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/android/core/TempSensorBreadcrumbsIntegration : android/hardware/SensorEventListener, io/sentry/Integration, java/io/Closeable { @@ -368,7 +368,7 @@ public final class io/sentry/android/core/TempSensorBreadcrumbsIntegration : and public fun close ()V public fun onAccuracyChanged (Landroid/hardware/Sensor;I)V public fun onSensorChanged (Landroid/hardware/SensorEvent;)V - public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/android/core/UserInteractionIntegration : android/app/Application$ActivityLifecycleCallbacks, io/sentry/Integration, java/io/Closeable { @@ -381,7 +381,7 @@ public final class io/sentry/android/core/UserInteractionIntegration : android/a public fun onActivitySaveInstanceState (Landroid/app/Activity;Landroid/os/Bundle;)V public fun onActivityStarted (Landroid/app/Activity;)V public fun onActivityStopped (Landroid/app/Activity;)V - public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/android/core/ViewHierarchyEventProcessor : io/sentry/EventProcessor { diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/ActivityBreadcrumbsIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/ActivityBreadcrumbsIntegration.java index dc03abe808..4a5ca63717 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/ActivityBreadcrumbsIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/ActivityBreadcrumbsIntegration.java @@ -8,7 +8,7 @@ import android.os.Bundle; import io.sentry.Breadcrumb; import io.sentry.Hint; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.Integration; import io.sentry.SentryLevel; import io.sentry.SentryOptions; @@ -23,7 +23,7 @@ public final class ActivityBreadcrumbsIntegration implements Integration, Closeable, Application.ActivityLifecycleCallbacks { private final @NotNull Application application; - private @Nullable IHub hub; + private @Nullable IScopes scopes; private boolean enabled; public ActivityBreadcrumbsIntegration(final @NotNull Application application) { @@ -31,13 +31,13 @@ public ActivityBreadcrumbsIntegration(final @NotNull Application application) { } @Override - public void register(final @NotNull IHub hub, final @NotNull SentryOptions options) { + public void register(final @NotNull IScopes scopes, final @NotNull SentryOptions options) { final SentryAndroidOptions androidOptions = Objects.requireNonNull( (options instanceof SentryAndroidOptions) ? (SentryAndroidOptions) options : null, "SentryAndroidOptions is required"); - this.hub = Objects.requireNonNull(hub, "Hub is required"); + this.scopes = Objects.requireNonNull(scopes, "Scopes are required"); this.enabled = androidOptions.isEnableActivityLifecycleBreadcrumbs(); options .getLogger() @@ -54,8 +54,9 @@ public void register(final @NotNull IHub hub, final @NotNull SentryOptions optio public void close() throws IOException { if (enabled) { application.unregisterActivityLifecycleCallbacks(this); - if (hub != null) { - hub.getOptions() + if (scopes != null) { + scopes + .getOptions() .getLogger() .log(SentryLevel.DEBUG, "ActivityBreadcrumbsIntegration removed."); } @@ -100,7 +101,7 @@ public synchronized void onActivityDestroyed(final @NotNull Activity activity) { } private void addBreadcrumb(final @NotNull Activity activity, final @NotNull String state) { - if (hub == null) { + if (scopes == null) { return; } @@ -114,7 +115,7 @@ private void addBreadcrumb(final @NotNull Activity activity, final @NotNull Stri final Hint hint = new Hint(); hint.set(ANDROID_ACTIVITY, activity); - hub.addBreadcrumb(breadcrumb, hint); + scopes.addBreadcrumb(breadcrumb, hint); } private @NotNull String getActivityName(final @NotNull Activity activity) { diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/ActivityLifecycleIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/ActivityLifecycleIntegration.java index 1121a6bfe7..76bedae5d0 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/ActivityLifecycleIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/ActivityLifecycleIntegration.java @@ -12,8 +12,8 @@ import android.view.View; import androidx.annotation.NonNull; import io.sentry.FullyDisplayedReporter; -import io.sentry.IHub; import io.sentry.IScope; +import io.sentry.IScopes; import io.sentry.ISpan; import io.sentry.ITransaction; import io.sentry.Instrumenter; @@ -60,7 +60,7 @@ public final class ActivityLifecycleIntegration private final @NotNull Application application; private final @NotNull BuildInfoProvider buildInfoProvider; - private @Nullable IHub hub; + private @Nullable IScopes scopes; private @Nullable SentryAndroidOptions options; private boolean performanceEnabled = false; @@ -102,13 +102,13 @@ public ActivityLifecycleIntegration( } @Override - public void register(final @NotNull IHub hub, final @NotNull SentryOptions options) { + public void register(final @NotNull IScopes scopes, final @NotNull SentryOptions options) { this.options = Objects.requireNonNull( (options instanceof SentryAndroidOptions) ? (SentryAndroidOptions) options : null, "SentryAndroidOptions is required"); - this.hub = Objects.requireNonNull(hub, "Hub is required"); + this.scopes = Objects.requireNonNull(scopes, "Scopes are required"); performanceEnabled = isPerformanceEnabled(this.options); fullyDisplayedReporter = this.options.getFullyDisplayedReporter(); @@ -150,10 +150,10 @@ private void stopPreviousTransactions() { private void startTracing(final @NotNull Activity activity) { WeakReference weakActivity = new WeakReference<>(activity); - if (hub != null && !isRunningTransactionOrTrace(activity)) { + if (scopes != null && !isRunningTransactionOrTrace(activity)) { if (!performanceEnabled) { activitiesWithOngoingTransactions.put(activity, NoOpTransaction.getInstance()); - TracingUtils.startNewTrace(hub); + TracingUtils.startNewTrace(scopes); } else { // as we allow a single transaction running on the bound Scope, we finish the previous ones stopPreviousTransactions(); @@ -225,7 +225,7 @@ private void startTracing(final @NotNull Activity activity) { // we can only bind to the scope if there's no running transaction ITransaction transaction = - hub.startTransaction( + scopes.startTransaction( new TransactionContext( activityName, TransactionNameSource.COMPONENT, @@ -278,7 +278,7 @@ private void startTracing(final @NotNull Activity activity) { } // lets bind to the scope so other integrations can pick it up - hub.configureScope( + scopes.configureScope( scope -> { applyScope(scope, transaction); }); @@ -356,10 +356,10 @@ private void finishTransaction( status = SpanStatus.OK; } transaction.finish(status); - if (hub != null) { + if (scopes != null) { // make sure to remove the transaction from scope, as it may contain running children, // therefore `finish` method will not remove it from scope - hub.configureScope( + scopes.configureScope( scope -> { clearScope(scope, transaction); }); @@ -371,9 +371,9 @@ private void finishTransaction( public synchronized void onActivityCreated( final @NotNull Activity activity, final @Nullable Bundle savedInstanceState) { setColdStart(savedInstanceState); - if (hub != null) { + if (scopes != null) { final @Nullable String activityClassName = ClassUtil.getClassName(activity); - hub.configureScope(scope -> scope.setScreen(activityClassName)); + scopes.configureScope(scope -> scope.setScreen(activityClassName)); } startTracing(activity); final @Nullable ISpan ttfdSpan = ttfdSpanMap.get(activity); @@ -429,10 +429,10 @@ public void onActivityPrePaused(@NonNull Activity activity) { // well // this ensures any newly launched activity will not use the app start timestamp as txn start firstActivityCreated = true; - if (hub == null) { + if (scopes == null) { lastPausedTime = AndroidDateUtils.getCurrentSentryDateTime(); } else { - lastPausedTime = hub.getOptions().getDateProvider().now(); + lastPausedTime = scopes.getOptions().getDateProvider().now(); } } } @@ -445,10 +445,10 @@ public synchronized void onActivityPaused(final @NotNull Activity activity) { // well // this ensures any newly launched activity will not use the app start timestamp as txn start firstActivityCreated = true; - if (hub == null) { + if (scopes == null) { lastPausedTime = AndroidDateUtils.getCurrentSentryDateTime(); } else { - lastPausedTime = hub.getOptions().getDateProvider().now(); + lastPausedTime = scopes.getOptions().getDateProvider().now(); } } } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidTransactionProfiler.java b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidTransactionProfiler.java index 3abfe1306a..0d232a6ada 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidTransactionProfiler.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidTransactionProfiler.java @@ -9,15 +9,15 @@ import android.os.Build; import android.os.Process; import android.os.SystemClock; -import io.sentry.HubAdapter; -import io.sentry.IHub; import io.sentry.ILogger; +import io.sentry.IScopes; import io.sentry.ISentryExecutorService; import io.sentry.ITransaction; import io.sentry.ITransactionProfiler; import io.sentry.PerformanceCollectionData; import io.sentry.ProfilingTraceData; import io.sentry.ProfilingTransactionData; +import io.sentry.ScopesAdapter; import io.sentry.SentryLevel; import io.sentry.SentryOptions; import io.sentry.android.core.internal.util.CpuInfoUtils; @@ -46,8 +46,8 @@ final class AndroidTransactionProfiler implements ITransactionProfiler { private long profileStartCpuMillis; /** - * @deprecated please use a constructor that doesn't takes a {@link IHub} instead, as it would be - * ignored anyway. + * @deprecated please use a constructor that doesn't takes a {@link IScopes} instead, as it would + * be ignored anyway. */ @Deprecated public AndroidTransactionProfiler( @@ -55,7 +55,7 @@ public AndroidTransactionProfiler( final @NotNull SentryAndroidOptions sentryAndroidOptions, final @NotNull BuildInfoProvider buildInfoProvider, final @NotNull SentryFrameMetricsCollector frameMetricsCollector, - final @NotNull IHub hub) { + final @NotNull IScopes scopes) { this(context, sentryAndroidOptions, buildInfoProvider, frameMetricsCollector); } @@ -311,7 +311,7 @@ public void close() { currentProfilingTransactionData.getTraceId(), true, null, - HubAdapter.getInstance().getOptions()); + ScopesAdapter.getInstance().getOptions()); } else if (transactionsCounter != 0) { // in case the app start profiling is running, and it's not bound to a transaction, we still // stop profiling, but we also have to manually update the counter. diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/AnrIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/AnrIntegration.java index 0ad2c242da..90d53a3c9b 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/AnrIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/AnrIntegration.java @@ -5,7 +5,7 @@ import android.annotation.SuppressLint; import android.content.Context; import io.sentry.Hint; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.Integration; import io.sentry.SentryEvent; import io.sentry.SentryLevel; @@ -48,12 +48,13 @@ public AnrIntegration(final @NotNull Context context) { private static final @NotNull Object watchDogLock = new Object(); @Override - public final void register(final @NotNull IHub hub, final @NotNull SentryOptions options) { + public final void register(final @NotNull IScopes scopes, final @NotNull SentryOptions options) { this.options = Objects.requireNonNull(options, "SentryOptions is required"); - register(hub, (SentryAndroidOptions) options); + register(scopes, (SentryAndroidOptions) options); } - private void register(final @NotNull IHub hub, final @NotNull SentryAndroidOptions options) { + private void register( + final @NotNull IScopes scopes, final @NotNull SentryAndroidOptions options) { options .getLogger() .log(SentryLevel.DEBUG, "AnrIntegration enabled: %s", options.isAnrEnabled()); @@ -67,7 +68,7 @@ private void register(final @NotNull IHub hub, final @NotNull SentryAndroidOptio () -> { synchronized (startLock) { if (!isClosed) { - startAnrWatchdog(hub, options); + startAnrWatchdog(scopes, options); } } }); @@ -80,7 +81,7 @@ private void register(final @NotNull IHub hub, final @NotNull SentryAndroidOptio } private void startAnrWatchdog( - final @NotNull IHub hub, final @NotNull SentryAndroidOptions options) { + final @NotNull IScopes scopes, final @NotNull SentryAndroidOptions options) { synchronized (watchDogLock) { if (anrWatchDog == null) { options @@ -94,7 +95,7 @@ private void startAnrWatchdog( new ANRWatchDog( options.getAnrTimeoutIntervalMillis(), options.isAnrReportInDebug(), - error -> reportANR(hub, options, error), + error -> reportANR(scopes, options, error), options.getLogger(), context); anrWatchDog.start(); @@ -106,7 +107,7 @@ private void startAnrWatchdog( @TestOnly void reportANR( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull SentryAndroidOptions options, final @NotNull ApplicationNotResponding error) { options.getLogger().log(SentryLevel.INFO, "ANR triggered with message: %s", error.getMessage()); @@ -122,7 +123,7 @@ void reportANR( final AnrHint anrHint = new AnrHint(isAppInBackground); final Hint hint = HintUtils.createWithTypeCheckHint(anrHint); - hub.captureEvent(event, hint); + scopes.captureEvent(event, hint); } private @NotNull Throwable buildAnrThrowable( diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/AnrV2Integration.java b/sentry-android-core/src/main/java/io/sentry/android/core/AnrV2Integration.java index 669233bb09..152ceed322 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/AnrV2Integration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/AnrV2Integration.java @@ -9,8 +9,8 @@ import io.sentry.Attachment; import io.sentry.DateUtils; import io.sentry.Hint; -import io.sentry.IHub; import io.sentry.ILogger; +import io.sentry.IScopes; import io.sentry.Integration; import io.sentry.SentryEvent; import io.sentry.SentryLevel; @@ -69,7 +69,7 @@ public AnrV2Integration(final @NotNull Context context) { @SuppressLint("NewApi") // we do the check in the AnrIntegrationFactory @Override - public void register(@NotNull IHub hub, @NotNull SentryOptions options) { + public void register(@NotNull IScopes scopes, @NotNull SentryOptions options) { this.options = Objects.requireNonNull( (options instanceof SentryAndroidOptions) ? (SentryAndroidOptions) options : null, @@ -90,7 +90,7 @@ public void register(@NotNull IHub hub, @NotNull SentryOptions options) { try { options .getExecutorService() - .submit(new AnrProcessor(context, hub, this.options, dateProvider)); + .submit(new AnrProcessor(context, scopes, this.options, dateProvider)); } catch (Throwable e) { options.getLogger().log(SentryLevel.DEBUG, "Failed to start AnrProcessor.", e); } @@ -109,17 +109,17 @@ public void close() throws IOException { static class AnrProcessor implements Runnable { private final @NotNull Context context; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @NotNull SentryAndroidOptions options; private final long threshold; AnrProcessor( final @NotNull Context context, - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull SentryAndroidOptions options, final @NotNull ICurrentDateProvider dateProvider) { this.context = context; - this.hub = hub; + this.scopes = scopes; this.options = options; this.threshold = dateProvider.getCurrentTimeMillis() - NINETY_DAYS_THRESHOLD; } @@ -277,7 +277,7 @@ private void reportAsSentryEvent( } } - final @NotNull SentryId sentryId = hub.captureEvent(event, hint); + final @NotNull SentryId sentryId = scopes.captureEvent(event, hint); final boolean isEventDropped = sentryId.equals(SentryId.EMPTY_ID); if (!isEventDropped) { // Block until the event is flushed to disk and the last_reported_anr marker is updated diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/AppComponentsBreadcrumbsIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/AppComponentsBreadcrumbsIntegration.java index eef4707683..0d20dc7a90 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/AppComponentsBreadcrumbsIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/AppComponentsBreadcrumbsIntegration.java @@ -8,7 +8,7 @@ import android.content.res.Configuration; import io.sentry.Breadcrumb; import io.sentry.Hint; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.Integration; import io.sentry.SentryLevel; import io.sentry.SentryOptions; @@ -25,7 +25,7 @@ public final class AppComponentsBreadcrumbsIntegration implements Integration, Closeable, ComponentCallbacks2 { private final @NotNull Context context; - private @Nullable IHub hub; + private @Nullable IScopes scopes; private @Nullable SentryAndroidOptions options; public AppComponentsBreadcrumbsIntegration(final @NotNull Context context) { @@ -33,8 +33,8 @@ public AppComponentsBreadcrumbsIntegration(final @NotNull Context context) { } @Override - public void register(final @NotNull IHub hub, final @NotNull SentryOptions options) { - this.hub = Objects.requireNonNull(hub, "Hub is required"); + public void register(final @NotNull IScopes scopes, final @NotNull SentryOptions options) { + this.scopes = Objects.requireNonNull(scopes, "Scopes are required"); this.options = Objects.requireNonNull( (options instanceof SentryAndroidOptions) ? (SentryAndroidOptions) options : null, @@ -84,7 +84,7 @@ public void close() throws IOException { @SuppressWarnings("deprecation") @Override public void onConfigurationChanged(@NotNull Configuration newConfig) { - if (hub != null) { + if (scopes != null) { final Device.DeviceOrientation deviceOrientation = DeviceOrientations.getOrientation(context.getResources().getConfiguration().orientation); @@ -104,7 +104,7 @@ public void onConfigurationChanged(@NotNull Configuration newConfig) { final Hint hint = new Hint(); hint.set(ANDROID_CONFIGURATION, newConfig); - hub.addBreadcrumb(breadcrumb, hint); + scopes.addBreadcrumb(breadcrumb, hint); } } @@ -119,7 +119,7 @@ public void onTrimMemory(final int level) { } private void createLowMemoryBreadcrumb(final @Nullable Integer level) { - if (hub != null) { + if (scopes != null) { final Breadcrumb breadcrumb = new Breadcrumb(); if (level != null) { // only add breadcrumb if TRIM_MEMORY_BACKGROUND, TRIM_MEMORY_MODERATE or @@ -143,7 +143,7 @@ private void createLowMemoryBreadcrumb(final @Nullable Integer level) { breadcrumb.setMessage("Low memory"); breadcrumb.setData("action", "LOW_MEMORY"); breadcrumb.setLevel(SentryLevel.WARNING); - hub.addBreadcrumb(breadcrumb); + scopes.addBreadcrumb(breadcrumb); } } } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/AppLifecycleIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/AppLifecycleIntegration.java index 3e8fe6383f..8614a60061 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/AppLifecycleIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/AppLifecycleIntegration.java @@ -3,7 +3,7 @@ import static io.sentry.util.IntegrationUtils.addIntegrationToSdkVersion; import androidx.lifecycle.ProcessLifecycleOwner; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.Integration; import io.sentry.SentryLevel; import io.sentry.SentryOptions; @@ -32,8 +32,8 @@ public AppLifecycleIntegration() { } @Override - public void register(final @NotNull IHub hub, final @NotNull SentryOptions options) { - Objects.requireNonNull(hub, "Hub is required"); + public void register(final @NotNull IScopes scopes, final @NotNull SentryOptions options) { + Objects.requireNonNull(scopes, "Scopes are required"); this.options = Objects.requireNonNull( (options instanceof SentryAndroidOptions) ? (SentryAndroidOptions) options : null, @@ -59,11 +59,11 @@ public void register(final @NotNull IHub hub, final @NotNull SentryOptions optio Class.forName("androidx.lifecycle.DefaultLifecycleObserver"); Class.forName("androidx.lifecycle.ProcessLifecycleOwner"); if (AndroidMainThreadChecker.getInstance().isMainThread()) { - addObserver(hub); + addObserver(scopes); } else { // some versions of the androidx lifecycle-process require this to be executed on the main // thread. - handler.post(() -> addObserver(hub)); + handler.post(() -> addObserver(scopes)); } } catch (ClassNotFoundException e) { options @@ -80,7 +80,7 @@ public void register(final @NotNull IHub hub, final @NotNull SentryOptions optio } } - private void addObserver(final @NotNull IHub hub) { + private void addObserver(final @NotNull IScopes scopes) { // this should never happen, check added to avoid warnings from NullAway if (this.options == null) { return; @@ -88,7 +88,7 @@ private void addObserver(final @NotNull IHub hub) { watcher = new LifecycleWatcher( - hub, + scopes, this.options.getSessionTrackingIntervalMillis(), this.options.isEnableAutoSessionTracking(), this.options.isEnableAppLifecycleBreadcrumbs()); diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/CurrentActivityIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/CurrentActivityIntegration.java index b4c5f1ed02..0b618636d3 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/CurrentActivityIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/CurrentActivityIntegration.java @@ -4,7 +4,7 @@ import android.app.Application; import android.os.Bundle; import androidx.annotation.NonNull; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.Integration; import io.sentry.SentryOptions; import io.sentry.util.Objects; @@ -25,7 +25,7 @@ public CurrentActivityIntegration(final @NotNull Application application) { } @Override - public void register(@NotNull IHub hub, @NotNull SentryOptions options) { + public void register(@NotNull IScopes scopes, @NotNull SentryOptions options) { application.registerActivityLifecycleCallbacks(this); } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/EnvelopeFileObserverIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/EnvelopeFileObserverIntegration.java index f99294584b..6e821e5be7 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/EnvelopeFileObserverIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/EnvelopeFileObserverIntegration.java @@ -1,7 +1,7 @@ package io.sentry.android.core; -import io.sentry.IHub; import io.sentry.ILogger; +import io.sentry.IScopes; import io.sentry.Integration; import io.sentry.OutboxSender; import io.sentry.SentryLevel; @@ -24,8 +24,8 @@ public abstract class EnvelopeFileObserverIntegration implements Integration, Cl } @Override - public final void register(final @NotNull IHub hub, final @NotNull SentryOptions options) { - Objects.requireNonNull(hub, "Hub is required"); + public final void register(final @NotNull IScopes scopes, final @NotNull SentryOptions options) { + Objects.requireNonNull(scopes, "Scopes are required"); Objects.requireNonNull(options, "SentryOptions is required"); logger = options.getLogger(); @@ -46,7 +46,7 @@ public final void register(final @NotNull IHub hub, final @NotNull SentryOptions () -> { synchronized (startLock) { if (!isClosed) { - startOutboxSender(hub, options, path); + startOutboxSender(scopes, options, path); } } }); @@ -60,10 +60,12 @@ public final void register(final @NotNull IHub hub, final @NotNull SentryOptions } private void startOutboxSender( - final @NotNull IHub hub, final @NotNull SentryOptions options, final @NotNull String path) { + final @NotNull IScopes scopes, + final @NotNull SentryOptions options, + final @NotNull String path) { final OutboxSender outboxSender = new OutboxSender( - hub, + scopes, options.getEnvelopeReader(), options.getSerializer(), options.getLogger(), diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/InternalSentrySdk.java b/sentry-android-core/src/main/java/io/sentry/android/core/InternalSentrySdk.java index 9bdbe86a77..692d8562f8 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/InternalSentrySdk.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/InternalSentrySdk.java @@ -4,12 +4,12 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import io.sentry.DateUtils; -import io.sentry.HubAdapter; -import io.sentry.IHub; import io.sentry.ILogger; import io.sentry.IScope; +import io.sentry.IScopes; import io.sentry.ISerializer; import io.sentry.ObjectWriter; +import io.sentry.ScopesAdapter; import io.sentry.SentryEnvelope; import io.sentry.SentryEnvelopeItem; import io.sentry.SentryEvent; @@ -39,12 +39,12 @@ public final class InternalSentrySdk { /** - * @return a copy of the current hub's topmost scope, or null in case the hub is disabled + * @return a copy of the current scopes's topmost scope, or null in case the scopes is disabled */ @Nullable public static IScope getCurrentScope() { final @NotNull AtomicReference scopeRef = new AtomicReference<>(); - HubAdapter.getInstance() + ScopesAdapter.getInstance() .configureScope( scope -> { scopeRef.set(scope.clone()); @@ -134,8 +134,8 @@ public static Map serializeScope( } /** - * Captures the provided envelope. Compared to {@link IHub#captureEvent(SentryEvent)} this method - *
+ * Captures the provided envelope. Compared to {@link IScopes#captureEvent(SentryEvent)} this + * method
* - will not enrich events with additional data (e.g. scope)
* - will not execute beforeSend: it's up to the caller to take care of this
* - will not perform any sampling: it's up to the caller to take care of this
@@ -147,8 +147,8 @@ public static Map serializeScope( */ @Nullable public static SentryId captureEnvelope(final @NotNull byte[] envelopeData) { - final @NotNull IHub hub = HubAdapter.getInstance(); - final @NotNull SentryOptions options = hub.getOptions(); + final @NotNull IScopes scopes = ScopesAdapter.getInstance(); + final @NotNull SentryOptions options = scopes.getOptions(); try (final InputStream envelopeInputStream = new ByteArrayInputStream(envelopeData)) { final @NotNull ISerializer serializer = options.getSerializer(); @@ -178,7 +178,7 @@ public static SentryId captureEnvelope(final @NotNull byte[] envelopeData) { } // update session and add it to envelope if necessary - final @Nullable Session session = updateSession(hub, options, status, crashedOrErrored); + final @Nullable Session session = updateSession(scopes, options, status, crashedOrErrored); if (session != null) { final SentryEnvelopeItem sessionItem = SentryEnvelopeItem.fromSession(serializer, session); envelopeItems.add(sessionItem); @@ -186,7 +186,7 @@ public static SentryId captureEnvelope(final @NotNull byte[] envelopeData) { final SentryEnvelope repackagedEnvelope = new SentryEnvelope(envelope.getHeader(), envelopeItems); - return hub.captureEnvelope(repackagedEnvelope); + return scopes.captureEnvelope(repackagedEnvelope); } catch (Throwable t) { options.getLogger().log(SentryLevel.ERROR, "Failed to capture envelope", t); } @@ -195,12 +195,12 @@ public static SentryId captureEnvelope(final @NotNull byte[] envelopeData) { @Nullable private static Session updateSession( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull SentryOptions options, final @Nullable Session.State status, final boolean crashedOrErrored) { final @NotNull AtomicReference sessionRef = new AtomicReference<>(); - hub.configureScope( + scopes.configureScope( scope -> { final @Nullable Session session = scope.getSession(); if (session != null) { diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/LifecycleWatcher.java b/sentry-android-core/src/main/java/io/sentry/android/core/LifecycleWatcher.java index 7b38bcd9c2..a32fa51d3f 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/LifecycleWatcher.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/LifecycleWatcher.java @@ -3,7 +3,7 @@ import androidx.lifecycle.DefaultLifecycleObserver; import androidx.lifecycle.LifecycleOwner; import io.sentry.Breadcrumb; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.SentryLevel; import io.sentry.Session; import io.sentry.android.core.internal.util.BreadcrumbFactory; @@ -25,19 +25,19 @@ final class LifecycleWatcher implements DefaultLifecycleObserver { private @Nullable TimerTask timerTask; private final @Nullable Timer timer; private final @NotNull Object timerLock = new Object(); - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final boolean enableSessionTracking; private final boolean enableAppLifecycleBreadcrumbs; private final @NotNull ICurrentDateProvider currentDateProvider; LifecycleWatcher( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final long sessionIntervalMillis, final boolean enableSessionTracking, final boolean enableAppLifecycleBreadcrumbs) { this( - hub, + scopes, sessionIntervalMillis, enableSessionTracking, enableAppLifecycleBreadcrumbs, @@ -45,7 +45,7 @@ final class LifecycleWatcher implements DefaultLifecycleObserver { } LifecycleWatcher( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final long sessionIntervalMillis, final boolean enableSessionTracking, final boolean enableAppLifecycleBreadcrumbs, @@ -53,7 +53,7 @@ final class LifecycleWatcher implements DefaultLifecycleObserver { this.sessionIntervalMillis = sessionIntervalMillis; this.enableSessionTracking = enableSessionTracking; this.enableAppLifecycleBreadcrumbs = enableAppLifecycleBreadcrumbs; - this.hub = hub; + this.scopes = scopes; this.currentDateProvider = currentDateProvider; if (enableSessionTracking) { timer = new Timer(true); @@ -79,7 +79,7 @@ private void startSession() { final long currentTimeMillis = currentDateProvider.getCurrentTimeMillis(); - hub.configureScope( + scopes.configureScope( scope -> { if (lastUpdatedSession.get() == 0L) { final @Nullable Session currentSession = scope.getSession(); @@ -93,7 +93,7 @@ private void startSession() { if (lastUpdatedSession == 0L || (lastUpdatedSession + sessionIntervalMillis) <= currentTimeMillis) { addSessionBreadcrumb("start"); - hub.startSession(); + scopes.startSession(); } this.lastUpdatedSession.set(currentTimeMillis); } @@ -123,7 +123,7 @@ private void scheduleEndSession() { @Override public void run() { addSessionBreadcrumb("end"); - hub.endSession(); + scopes.endSession(); } }; @@ -148,13 +148,13 @@ private void addAppBreadcrumb(final @NotNull String state) { breadcrumb.setData("state", state); breadcrumb.setCategory("app.lifecycle"); breadcrumb.setLevel(SentryLevel.INFO); - hub.addBreadcrumb(breadcrumb); + scopes.addBreadcrumb(breadcrumb); } } private void addSessionBreadcrumb(final @NotNull String state) { final Breadcrumb breadcrumb = BreadcrumbFactory.forSession(state); - hub.addBreadcrumb(breadcrumb); + scopes.addBreadcrumb(breadcrumb); } @TestOnly diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/NdkIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/NdkIntegration.java index 3a4a91498e..dc464303c6 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/NdkIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/NdkIntegration.java @@ -2,7 +2,7 @@ import static io.sentry.util.IntegrationUtils.addIntegrationToSdkVersion; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.Integration; import io.sentry.SentryLevel; import io.sentry.SentryOptions; @@ -28,8 +28,8 @@ public NdkIntegration(final @Nullable Class sentryNdkClass) { } @Override - public final void register(final @NotNull IHub hub, final @NotNull SentryOptions options) { - Objects.requireNonNull(hub, "Hub is required"); + public final void register(final @NotNull IScopes scopes, final @NotNull SentryOptions options) { + Objects.requireNonNull(scopes, "Scopes are required"); this.options = Objects.requireNonNull( (options instanceof SentryAndroidOptions) ? (SentryAndroidOptions) options : null, @@ -38,7 +38,8 @@ public final void register(final @NotNull IHub hub, final @NotNull SentryOptions final boolean enabled = this.options.isEnableNdk(); this.options.getLogger().log(SentryLevel.DEBUG, "NdkIntegration enabled: %s", enabled); - // Note: `hub` isn't used here because the NDK integration writes files to disk which are picked + // Note: `scopes` isn't used here because the NDK integration writes files to disk which are + // picked // up by another integration (EnvelopeFileObserverIntegration). if (enabled && sentryNdkClass != null) { final String cachedDir = this.options.getCacheDirPath(); diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/NetworkBreadcrumbsIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/NetworkBreadcrumbsIntegration.java index 1cd42e9dab..9f1dd3ecf6 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/NetworkBreadcrumbsIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/NetworkBreadcrumbsIntegration.java @@ -13,8 +13,8 @@ import io.sentry.Breadcrumb; import io.sentry.DateUtils; import io.sentry.Hint; -import io.sentry.IHub; import io.sentry.ILogger; +import io.sentry.IScopes; import io.sentry.Integration; import io.sentry.SentryDateProvider; import io.sentry.SentryLevel; @@ -50,8 +50,8 @@ public NetworkBreadcrumbsIntegration( @SuppressLint("NewApi") @Override - public void register(final @NotNull IHub hub, final @NotNull SentryOptions options) { - Objects.requireNonNull(hub, "Hub is required"); + public void register(final @NotNull IScopes scopes, final @NotNull SentryOptions options) { + Objects.requireNonNull(scopes, "Scopes are required"); SentryAndroidOptions androidOptions = Objects.requireNonNull( (options instanceof SentryAndroidOptions) ? (SentryAndroidOptions) options : null, @@ -72,7 +72,8 @@ public void register(final @NotNull IHub hub, final @NotNull SentryOptions optio } networkCallback = - new NetworkBreadcrumbsNetworkCallback(hub, buildInfoProvider, options.getDateProvider()); + new NetworkBreadcrumbsNetworkCallback( + scopes, buildInfoProvider, options.getDateProvider()); final boolean registered = AndroidConnectionStatusProvider.registerNetworkCallback( context, logger, buildInfoProvider, networkCallback); @@ -101,7 +102,7 @@ public void close() throws IOException { @SuppressLint("ObsoleteSdkInt") @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) static final class NetworkBreadcrumbsNetworkCallback extends ConnectivityManager.NetworkCallback { - final @NotNull IHub hub; + final @NotNull IScopes scopes; final @NotNull BuildInfoProvider buildInfoProvider; @Nullable Network currentNetwork = null; @@ -111,10 +112,10 @@ static final class NetworkBreadcrumbsNetworkCallback extends ConnectivityManager final @NotNull SentryDateProvider dateProvider; NetworkBreadcrumbsNetworkCallback( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull BuildInfoProvider buildInfoProvider, final @NotNull SentryDateProvider dateProvider) { - this.hub = Objects.requireNonNull(hub, "Hub is required"); + this.scopes = Objects.requireNonNull(scopes, "Scopes are required"); this.buildInfoProvider = Objects.requireNonNull(buildInfoProvider, "BuildInfoProvider is required"); this.dateProvider = Objects.requireNonNull(dateProvider, "SentryDateProvider is required"); @@ -126,7 +127,7 @@ public void onAvailable(final @NonNull Network network) { return; } final Breadcrumb breadcrumb = createBreadcrumb("NETWORK_AVAILABLE"); - hub.addBreadcrumb(breadcrumb); + scopes.addBreadcrumb(breadcrumb); currentNetwork = network; lastCapabilities = null; } @@ -156,7 +157,7 @@ public void onCapabilitiesChanged( } Hint hint = new Hint(); hint.set(TypeCheckHint.ANDROID_NETWORK_CAPABILITIES, connectionDetail); - hub.addBreadcrumb(breadcrumb, hint); + scopes.addBreadcrumb(breadcrumb, hint); } @Override @@ -165,7 +166,7 @@ public void onLost(final @NonNull Network network) { return; } final Breadcrumb breadcrumb = createBreadcrumb("NETWORK_LOST"); - hub.addBreadcrumb(breadcrumb); + scopes.addBreadcrumb(breadcrumb); currentNetwork = null; lastCapabilities = null; } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/PhoneStateBreadcrumbsIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/PhoneStateBreadcrumbsIntegration.java index c10d25b057..cae1492d3e 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/PhoneStateBreadcrumbsIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/PhoneStateBreadcrumbsIntegration.java @@ -6,7 +6,7 @@ import android.content.Context; import android.telephony.TelephonyManager; import io.sentry.Breadcrumb; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.Integration; import io.sentry.SentryLevel; import io.sentry.SentryOptions; @@ -32,8 +32,8 @@ public PhoneStateBreadcrumbsIntegration(final @NotNull Context context) { } @Override - public void register(final @NotNull IHub hub, final @NotNull SentryOptions options) { - Objects.requireNonNull(hub, "Hub is required"); + public void register(final @NotNull IScopes scopes, final @NotNull SentryOptions options) { + Objects.requireNonNull(scopes, "Scopes are required"); this.options = Objects.requireNonNull( (options instanceof SentryAndroidOptions) ? (SentryAndroidOptions) options : null, @@ -55,7 +55,7 @@ public void register(final @NotNull IHub hub, final @NotNull SentryOptions optio () -> { synchronized (startLock) { if (!isClosed) { - startTelephonyListener(hub, options); + startTelephonyListener(scopes, options); } } }); @@ -72,11 +72,11 @@ public void register(final @NotNull IHub hub, final @NotNull SentryOptions optio @SuppressWarnings("deprecation") private void startTelephonyListener( - final @NotNull IHub hub, final @NotNull SentryOptions options) { + final @NotNull IScopes scopes, final @NotNull SentryOptions options) { telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); if (telephonyManager != null) { try { - listener = new PhoneStateChangeListener(hub); + listener = new PhoneStateChangeListener(scopes); telephonyManager.listen(listener, android.telephony.PhoneStateListener.LISTEN_CALL_STATE); options.getLogger().log(SentryLevel.DEBUG, "PhoneStateBreadcrumbsIntegration installed."); @@ -110,10 +110,10 @@ public void close() throws IOException { @SuppressWarnings("deprecation") static final class PhoneStateChangeListener extends android.telephony.PhoneStateListener { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; - PhoneStateChangeListener(final @NotNull IHub hub) { - this.hub = hub; + PhoneStateChangeListener(final @NotNull IScopes scopes) { + this.scopes = scopes; } @SuppressWarnings("deprecation") @@ -128,7 +128,7 @@ public void onCallStateChanged(int state, String incomingNumber) { breadcrumb.setData("action", "CALL_STATE_RINGING"); breadcrumb.setMessage("Device ringing"); breadcrumb.setLevel(SentryLevel.INFO); - hub.addBreadcrumb(breadcrumb); + scopes.addBreadcrumb(breadcrumb); } } } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/SendCachedEnvelopeIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/SendCachedEnvelopeIntegration.java index 66e534bb7d..64f1cab362 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/SendCachedEnvelopeIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/SendCachedEnvelopeIntegration.java @@ -2,7 +2,7 @@ import io.sentry.DataCategory; import io.sentry.IConnectionStatusProvider; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.Integration; import io.sentry.SendCachedEnvelopeFireAndForgetIntegration; import io.sentry.SentryLevel; @@ -28,7 +28,7 @@ final class SendCachedEnvelopeIntegration private final @NotNull LazyEvaluator startupCrashMarkerEvaluator; private final AtomicBoolean startupCrashHandled = new AtomicBoolean(false); private @Nullable IConnectionStatusProvider connectionStatusProvider; - private @Nullable IHub hub; + private @Nullable IScopes scopes; private @Nullable SentryAndroidOptions options; private @Nullable SendCachedEnvelopeFireAndForgetIntegration.SendFireAndForget sender; private final AtomicBoolean isInitialized = new AtomicBoolean(false); @@ -42,8 +42,8 @@ public SendCachedEnvelopeIntegration( } @Override - public void register(@NotNull IHub hub, @NotNull SentryOptions options) { - this.hub = Objects.requireNonNull(hub, "Hub is required"); + public void register(@NotNull IScopes scopes, @NotNull SentryOptions options) { + this.scopes = Objects.requireNonNull(scopes, "Scopes are required"); this.options = Objects.requireNonNull( (options instanceof SentryAndroidOptions) ? (SentryAndroidOptions) options : null, @@ -55,7 +55,7 @@ public void register(@NotNull IHub hub, @NotNull SentryOptions options) { return; } - sendCachedEnvelopes(hub, this.options); + sendCachedEnvelopes(scopes, this.options); } @Override @@ -69,14 +69,14 @@ public void close() throws IOException { @Override public void onConnectionStatusChanged( final @NotNull IConnectionStatusProvider.ConnectionStatus status) { - if (hub != null && options != null) { - sendCachedEnvelopes(hub, options); + if (scopes != null && options != null) { + sendCachedEnvelopes(scopes, options); } } @SuppressWarnings({"NullAway"}) private synchronized void sendCachedEnvelopes( - final @NotNull IHub hub, final @NotNull SentryAndroidOptions options) { + final @NotNull IScopes scopes, final @NotNull SentryAndroidOptions options) { try { final Future future = options @@ -97,7 +97,7 @@ private synchronized void sendCachedEnvelopes( connectionStatusProvider = options.getConnectionStatusProvider(); connectionStatusProvider.addConnectionStatusObserver(this); - sender = factory.create(hub, options); + sender = factory.create(scopes, options); } if (connectionStatusProvider != null @@ -110,7 +110,7 @@ private synchronized void sendCachedEnvelopes( } // in case there's rate limiting active, skip processing - final @Nullable RateLimiter rateLimiter = hub.getRateLimiter(); + final @Nullable RateLimiter rateLimiter = scopes.getRateLimiter(); if (rateLimiter != null && rateLimiter.isActiveForCategory(DataCategory.All)) { options diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/SentryAndroid.java b/sentry-android-core/src/main/java/io/sentry/android/core/SentryAndroid.java index af68a026fb..424de4d82e 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/SentryAndroid.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/SentryAndroid.java @@ -4,8 +4,8 @@ import android.content.Context; import android.os.Process; import android.os.SystemClock; -import io.sentry.IHub; import io.sentry.ILogger; +import io.sentry.IScopes; import io.sentry.Integration; import io.sentry.OptionsContainer; import io.sentry.Sentry; @@ -144,10 +144,11 @@ public static synchronized void init( }, true); - final @NotNull IHub hub = Sentry.getCurrentHub(); - if (hub.getOptions().isEnableAutoSessionTracking() && ContextUtils.isForegroundImportance()) { - hub.addBreadcrumb(BreadcrumbFactory.forSession("session.start")); - hub.startSession(); + final @NotNull IScopes scopes = Sentry.getCurrentScopes(); + if (scopes.getOptions().isEnableAutoSessionTracking() + && ContextUtils.isForegroundImportance()) { + scopes.addBreadcrumb(BreadcrumbFactory.forSession("session.start")); + scopes.startSession(); } } catch (IllegalAccessException e) { logger.log(SentryLevel.FATAL, "Fatal error during SentryAndroid.init(...)", e); diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/SystemEventsBreadcrumbsIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/SystemEventsBreadcrumbsIntegration.java index 1c22a7dcc8..333ece2148 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/SystemEventsBreadcrumbsIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/SystemEventsBreadcrumbsIntegration.java @@ -40,8 +40,8 @@ import android.os.Bundle; import io.sentry.Breadcrumb; import io.sentry.Hint; -import io.sentry.IHub; import io.sentry.ILogger; +import io.sentry.IScopes; import io.sentry.Integration; import io.sentry.SentryLevel; import io.sentry.SentryOptions; @@ -80,8 +80,8 @@ public SystemEventsBreadcrumbsIntegration( } @Override - public void register(final @NotNull IHub hub, final @NotNull SentryOptions options) { - Objects.requireNonNull(hub, "Hub is required"); + public void register(final @NotNull IScopes scopes, final @NotNull SentryOptions options) { + Objects.requireNonNull(scopes, "Scopes are required"); this.options = Objects.requireNonNull( (options instanceof SentryAndroidOptions) ? (SentryAndroidOptions) options : null, @@ -103,7 +103,7 @@ public void register(final @NotNull IHub hub, final @NotNull SentryOptions optio () -> { synchronized (startLock) { if (!isClosed) { - startSystemEventsReceiver(hub, (SentryAndroidOptions) options); + startSystemEventsReceiver(scopes, (SentryAndroidOptions) options); } } }); @@ -119,8 +119,8 @@ public void register(final @NotNull IHub hub, final @NotNull SentryOptions optio } private void startSystemEventsReceiver( - final @NotNull IHub hub, final @NotNull SentryAndroidOptions options) { - receiver = new SystemEventsBroadcastReceiver(hub, options.getLogger()); + final @NotNull IScopes scopes, final @NotNull SentryAndroidOptions options) { + receiver = new SystemEventsBroadcastReceiver(scopes, options.getLogger()); final IntentFilter filter = new IntentFilter(); for (String item : actions) { filter.addAction(item); @@ -204,11 +204,11 @@ public void close() throws IOException { static final class SystemEventsBroadcastReceiver extends BroadcastReceiver { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @NotNull ILogger logger; - SystemEventsBroadcastReceiver(final @NotNull IHub hub, final @NotNull ILogger logger) { - this.hub = hub; + SystemEventsBroadcastReceiver(final @NotNull IScopes scopes, final @NotNull ILogger logger) { + this.scopes = scopes; this.logger = logger; } @@ -249,7 +249,7 @@ public void onReceive(Context context, Intent intent) { final Hint hint = new Hint(); hint.set(ANDROID_INTENT, intent); - hub.addBreadcrumb(breadcrumb, hint); + scopes.addBreadcrumb(breadcrumb, hint); } } } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/TempSensorBreadcrumbsIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/TempSensorBreadcrumbsIntegration.java index eaf5c64991..4d0e9c7e60 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/TempSensorBreadcrumbsIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/TempSensorBreadcrumbsIntegration.java @@ -11,7 +11,7 @@ import android.hardware.SensorManager; import io.sentry.Breadcrumb; import io.sentry.Hint; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.Integration; import io.sentry.SentryLevel; import io.sentry.SentryOptions; @@ -26,7 +26,7 @@ public final class TempSensorBreadcrumbsIntegration implements Integration, Closeable, SensorEventListener { private final @NotNull Context context; - private @Nullable IHub hub; + private @Nullable IScopes scopes; private @Nullable SentryAndroidOptions options; @TestOnly @Nullable SensorManager sensorManager; @@ -38,8 +38,8 @@ public TempSensorBreadcrumbsIntegration(final @NotNull Context context) { } @Override - public void register(final @NotNull IHub hub, final @NotNull SentryOptions options) { - this.hub = Objects.requireNonNull(hub, "Hub is required"); + public void register(final @NotNull IScopes scopes, final @NotNull SentryOptions options) { + this.scopes = Objects.requireNonNull(scopes, "Scopes are required"); this.options = Objects.requireNonNull( (options instanceof SentryAndroidOptions) ? (SentryAndroidOptions) options : null, @@ -121,7 +121,7 @@ public void onSensorChanged(final @NotNull SensorEvent event) { return; } - if (hub != null) { + if (scopes != null) { final Breadcrumb breadcrumb = new Breadcrumb(); breadcrumb.setType("system"); breadcrumb.setCategory("device.event"); @@ -134,7 +134,7 @@ public void onSensorChanged(final @NotNull SensorEvent event) { final Hint hint = new Hint(); hint.set(ANDROID_SENSOR_EVENT, event); - hub.addBreadcrumb(breadcrumb, hint); + scopes.addBreadcrumb(breadcrumb, hint); } } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/UserInteractionIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/UserInteractionIntegration.java index c361529671..712651b460 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/UserInteractionIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/UserInteractionIntegration.java @@ -6,7 +6,7 @@ import android.app.Application; import android.os.Bundle; import android.view.Window; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.Integration; import io.sentry.SentryLevel; import io.sentry.SentryOptions; @@ -23,7 +23,7 @@ public final class UserInteractionIntegration implements Integration, Closeable, Application.ActivityLifecycleCallbacks { private final @NotNull Application application; - private @Nullable IHub hub; + private @Nullable IScopes scopes; private @Nullable SentryAndroidOptions options; private final boolean isAndroidXAvailable; @@ -44,14 +44,14 @@ private void startTracking(final @NotNull Activity activity) { return; } - if (hub != null && options != null) { + if (scopes != null && options != null) { Window.Callback delegate = window.getCallback(); if (delegate == null) { delegate = new NoOpWindowCallback(); } final SentryGestureListener gestureListener = - new SentryGestureListener(activity, hub, options); + new SentryGestureListener(activity, scopes, options); window.setCallback(new SentryWindowCallback(delegate, activity, gestureListener, options)); } } @@ -102,13 +102,13 @@ public void onActivitySaveInstanceState(@NotNull Activity activity, @NotNull Bun public void onActivityDestroyed(@NotNull Activity activity) {} @Override - public void register(@NotNull IHub hub, @NotNull SentryOptions options) { + public void register(@NotNull IScopes scopes, @NotNull SentryOptions options) { this.options = Objects.requireNonNull( (options instanceof SentryAndroidOptions) ? (SentryAndroidOptions) options : null, "SentryAndroidOptions is required"); - this.hub = Objects.requireNonNull(hub, "Hub is required"); + this.scopes = Objects.requireNonNull(scopes, "Scopes are required"); final boolean integrationEnabled = this.options.isEnableUserInteractionBreadcrumbs() diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/internal/gestures/SentryGestureListener.java b/sentry-android-core/src/main/java/io/sentry/android/core/internal/gestures/SentryGestureListener.java index 0ec0d83258..9154f3e7c6 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/internal/gestures/SentryGestureListener.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/internal/gestures/SentryGestureListener.java @@ -10,8 +10,8 @@ import android.view.Window; import io.sentry.Breadcrumb; import io.sentry.Hint; -import io.sentry.IHub; import io.sentry.IScope; +import io.sentry.IScopes; import io.sentry.ITransaction; import io.sentry.SentryLevel; import io.sentry.SpanStatus; @@ -43,7 +43,7 @@ private enum GestureType { private static final String TRACE_ORIGIN = "auto.ui.gesture_listener"; private final @NotNull WeakReference activityRef; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @NotNull SentryAndroidOptions options; private @Nullable UiElement activeUiElement = null; @@ -54,10 +54,10 @@ private enum GestureType { public SentryGestureListener( final @NotNull Activity currentActivity, - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull SentryAndroidOptions options) { this.activityRef = new WeakReference<>(currentActivity); - this.hub = hub; + this.scopes = scopes; this.options = options; } @@ -185,7 +185,7 @@ private void addBreadcrumb( hint.set(ANDROID_MOTION_EVENT, motionEvent); hint.set(ANDROID_VIEW, target.getView()); - hub.addBreadcrumb( + scopes.addBreadcrumb( Breadcrumb.userInteraction( type, target.getResourceName(), target.getClassName(), target.getTag(), additionalData), hint); @@ -202,7 +202,7 @@ private void startTracing(final @NotNull UiElement target, final @NotNull Gestur if (!(options.isTracingEnabled() && options.isEnableUserInteractionTracing())) { if (isNewInteraction) { - TracingUtils.startNewTrace(hub); + TracingUtils.startNewTrace(scopes); activeUiElement = target; activeEventType = eventType; } @@ -253,12 +253,12 @@ private void startTracing(final @NotNull UiElement target, final @NotNull Gestur transactionOptions.setTrimEnd(true); final ITransaction transaction = - hub.startTransaction( + scopes.startTransaction( new TransactionContext(name, TransactionNameSource.COMPONENT, op), transactionOptions); transaction.getSpanContext().setOrigin(TRACE_ORIGIN + "." + target.getOrigin()); - hub.configureScope( + scopes.configureScope( scope -> { applyScope(scope, transaction); }); @@ -278,7 +278,7 @@ void stopTracing(final @NotNull SpanStatus status) { activeTransaction.finish(); } } - hub.configureScope( + scopes.configureScope( scope -> { // avoid method refs on Android due to some issues with older AGP setups // noinspection Convert2MethodRef diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/AndroidTransactionProfilerTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/AndroidTransactionProfilerTest.kt index 405aa6dc98..436c3ee6f9 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/AndroidTransactionProfilerTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/AndroidTransactionProfilerTest.kt @@ -5,8 +5,8 @@ import android.os.Build import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import io.sentry.CpuCollectionData -import io.sentry.IHub import io.sentry.ILogger +import io.sentry.IScopes import io.sentry.ISentryExecutorService import io.sentry.MemoryCollectionData import io.sentry.PerformanceCollectionData @@ -89,7 +89,7 @@ class AndroidTransactionProfilerTest { executorService = mockExecutorService } - val hub: IHub = mock() + val scopes: IScopes = mock() val frameMetricsCollector: SentryFrameMetricsCollector = mock() lateinit var transaction1: SentryTracer @@ -97,10 +97,10 @@ class AndroidTransactionProfilerTest { lateinit var transaction3: SentryTracer fun getSut(context: Context, buildInfoProvider: BuildInfoProvider = buildInfo): AndroidTransactionProfiler { - whenever(hub.options).thenReturn(options) - transaction1 = SentryTracer(TransactionContext("", ""), hub) - transaction2 = SentryTracer(TransactionContext("", ""), hub) - transaction3 = SentryTracer(TransactionContext("", ""), hub) + whenever(scopes.options).thenReturn(options) + transaction1 = SentryTracer(TransactionContext("", ""), scopes) + transaction2 = SentryTracer(TransactionContext("", ""), scopes) + transaction3 = SentryTracer(TransactionContext("", ""), scopes) return AndroidTransactionProfiler(context, options, buildInfoProvider, frameMetricsCollector) } } diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/AnrIntegrationTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/AnrIntegrationTest.kt index cceabc9774..1a74a47ae1 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/AnrIntegrationTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/AnrIntegrationTest.kt @@ -2,7 +2,7 @@ package io.sentry.android.core import android.content.Context import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryLevel import io.sentry.android.core.AnrIntegration.AnrHint import io.sentry.exception.ExceptionMechanismException @@ -24,7 +24,7 @@ class AnrIntegrationTest { private class Fixture { val context = mock() - val hub = mock() + val scopes = mock() var options: SentryAndroidOptions = SentryAndroidOptions().apply { setLogger(mock()) } @@ -49,7 +49,7 @@ class AnrIntegrationTest { fixture.options.executorService = ImmediateExecutorService() val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertNotNull(sut.anrWatchDog) assertTrue((sut.anrWatchDog as ANRWatchDog).isAlive) @@ -60,7 +60,7 @@ class AnrIntegrationTest { fixture.options.executorService = mock() val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertNull(sut.anrWatchDog) } @@ -70,7 +70,7 @@ class AnrIntegrationTest { val sut = fixture.getSut() fixture.options.isAnrEnabled = false - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertNull(sut.anrWatchDog) } @@ -79,9 +79,9 @@ class AnrIntegrationTest { fun `When ANR watch dog is triggered, it should capture an error event with AnrHint`() { val sut = fixture.getSut() - sut.reportANR(fixture.hub, fixture.options, getApplicationNotResponding()) + sut.reportANR(fixture.scopes, fixture.options, getApplicationNotResponding()) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { assertEquals(SentryLevel.ERROR, it.level) }, @@ -97,7 +97,7 @@ class AnrIntegrationTest { val sut = fixture.getSut() fixture.options.executorService = ImmediateExecutorService() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertNotNull(sut.anrWatchDog) @@ -107,11 +107,11 @@ class AnrIntegrationTest { } @Test - fun `when hub is closed right after start, integration is not registered`() { + fun `when scopes is closed right after start, integration is not registered`() { val deferredExecutorService = DeferredExecutorService() val sut = fixture.getSut() fixture.options.executorService = deferredExecutorService - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertNull(sut.anrWatchDog) sut.close() deferredExecutorService.runAll() @@ -122,9 +122,9 @@ class AnrIntegrationTest { fun `When ANR watch dog is triggered, constructs exception with proper mechanism and snapshot flag`() { val sut = fixture.getSut() - sut.reportANR(fixture.hub, fixture.options, getApplicationNotResponding()) + sut.reportANR(fixture.scopes, fixture.options, getApplicationNotResponding()) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { val ex = it.throwableMechanism as ExceptionMechanismException assertTrue(ex.isSnapshot) @@ -139,9 +139,9 @@ class AnrIntegrationTest { val sut = fixture.getSut() AppState.getInstance().setInBackground(true) - sut.reportANR(fixture.hub, fixture.options, getApplicationNotResponding()) + sut.reportANR(fixture.scopes, fixture.options, getApplicationNotResponding()) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { val message = it.throwable?.message assertTrue(message?.startsWith("Background") == true) diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/AnrV2IntegrationTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/AnrV2IntegrationTest.kt index 885ad22c8f..1abcd43719 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/AnrV2IntegrationTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/AnrV2IntegrationTest.kt @@ -6,8 +6,8 @@ import android.content.Context import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import io.sentry.Hint -import io.sentry.IHub import io.sentry.ILogger +import io.sentry.IScopes import io.sentry.SentryEnvelope import io.sentry.SentryLevel import io.sentry.android.core.AnrV2Integration.AnrV2Hint @@ -59,7 +59,7 @@ class AnrV2IntegrationTest { lateinit var lastReportedAnrFile: File val options = SentryAndroidOptions() - val hub = mock() + val scopes = mock() val logger = mock() fun getSut( @@ -93,7 +93,7 @@ class AnrV2IntegrationTest { lastReportedAnrFile = File(cacheDir, AndroidEnvelopeCache.LAST_ANR_REPORT) lastReportedAnrFile.writeText(lastReportedAnrTimestamp.toString()) } - whenever(hub.captureEvent(any(), anyOrNull())).thenReturn(lastEventId) + whenever(scopes.captureEvent(any(), anyOrNull())).thenReturn(lastEventId) return AnrV2Integration(context) } @@ -170,7 +170,7 @@ class AnrV2IntegrationTest { fun `when cacheDir is not set, does not process historical exits`() { val integration = fixture.getSut(null, useImmediateExecutorService = false) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) verify(fixture.options.executorService, never()).submit(any()) } @@ -180,7 +180,7 @@ class AnrV2IntegrationTest { val integration = fixture.getSut(tmpDir, isAnrEnabled = false, useImmediateExecutorService = false) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) verify(fixture.options.executorService, never()).submit(any()) } @@ -189,9 +189,9 @@ class AnrV2IntegrationTest { fun `when historical exit list is empty, does not process historical exits`() { val integration = fixture.getSut(tmpDir) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) - verify(fixture.hub, never()).captureEvent(any(), anyOrNull()) + verify(fixture.scopes, never()).captureEvent(any(), anyOrNull()) } @Test @@ -199,9 +199,9 @@ class AnrV2IntegrationTest { val integration = fixture.getSut(tmpDir) fixture.addAppExitInfo(reason = null) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) - verify(fixture.hub, never()).captureEvent(any(), anyOrNull()) + verify(fixture.scopes, never()).captureEvent(any(), anyOrNull()) } @Test @@ -212,9 +212,9 @@ class AnrV2IntegrationTest { val integration = fixture.getSut(tmpDir) fixture.addAppExitInfo(timestamp = oldTimestamp) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) - verify(fixture.hub, never()).captureEvent(any(), anyOrNull()) + verify(fixture.scopes, never()).captureEvent(any(), anyOrNull()) } @Test @@ -222,9 +222,9 @@ class AnrV2IntegrationTest { val integration = fixture.getSut(tmpDir, lastReportedAnrTimestamp = oldTimestamp) fixture.addAppExitInfo(timestamp = oldTimestamp) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) - verify(fixture.hub, never()).captureEvent(any(), anyOrNull()) + verify(fixture.scopes, never()).captureEvent(any(), anyOrNull()) } @Test @@ -232,9 +232,9 @@ class AnrV2IntegrationTest { val integration = fixture.getSut(tmpDir, lastReportedAnrTimestamp = null) fixture.addAppExitInfo(timestamp = oldTimestamp) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) - verify(fixture.hub).captureEvent(any(), anyOrNull()) + verify(fixture.scopes).captureEvent(any(), anyOrNull()) } @Test @@ -242,9 +242,9 @@ class AnrV2IntegrationTest { val integration = fixture.getSut(tmpDir, lastReportedAnrTimestamp = oldTimestamp) fixture.addAppExitInfo(timestamp = newTimestamp) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { assertEquals(newTimestamp, it.timestamp.time) assertEquals(SentryLevel.FATAL, it.level) @@ -291,9 +291,9 @@ class AnrV2IntegrationTest { importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND ) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( any(), argThat { val hint = HintUtils.getSentrySdkHint(this) @@ -311,7 +311,7 @@ class AnrV2IntegrationTest { ) fixture.addAppExitInfo(timestamp = newTimestamp) - whenever(fixture.hub.captureEvent(any(), any())).thenAnswer { invocation -> + whenever(fixture.scopes.captureEvent(any(), any())).thenAnswer { invocation -> val hint = HintUtils.getSentrySdkHint(invocation.getArgument(1)) as DiskFlushNotification thread { @@ -321,9 +321,9 @@ class AnrV2IntegrationTest { SentryId() } - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) - verify(fixture.hub).captureEvent(any(), anyOrNull()) + verify(fixture.scopes).captureEvent(any(), anyOrNull()) // shouldn't fall into timed out state, because we marked event as flushed on another thread verify(fixture.logger, never()).log( any(), @@ -341,9 +341,9 @@ class AnrV2IntegrationTest { ) fixture.addAppExitInfo(timestamp = newTimestamp) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) - verify(fixture.hub).captureEvent(any(), anyOrNull()) + verify(fixture.scopes).captureEvent(any(), anyOrNull()) // we do not call markFlushed, hence it should time out waiting for flush, but because // we drop the event, it should not even come to this if-check verify(fixture.logger, never()).log( @@ -360,9 +360,9 @@ class AnrV2IntegrationTest { fixture.addAppExitInfo(timestamp = newTimestamp - 1 * 60 * 1000) fixture.addAppExitInfo(timestamp = newTimestamp) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) - verify(fixture.hub, times(2)).captureEvent( + verify(fixture.scopes, times(2)).captureEvent( any(), argThat { val hint = HintUtils.getSentrySdkHint(this) @@ -382,10 +382,10 @@ class AnrV2IntegrationTest { fixture.addAppExitInfo(timestamp = newTimestamp - 1 * 60 * 1000) fixture.addAppExitInfo(timestamp = newTimestamp) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) // only the latest anr is reported which should be enrichable - verify(fixture.hub, atMost(1)).captureEvent( + verify(fixture.scopes, atMost(1)).captureEvent( any(), argThat { val hint = HintUtils.getSentrySdkHint(this) @@ -402,20 +402,20 @@ class AnrV2IntegrationTest { fixture.addAppExitInfo(timestamp = newTimestamp - TimeUnit.DAYS.toMillis(1)) fixture.addAppExitInfo(timestamp = newTimestamp) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) // the order is reverse here, so the oldest ANR will be reported first to keep track of // last reported ANR in a marker file - inOrder(fixture.hub) { - verify(fixture.hub).captureEvent( + inOrder(fixture.scopes) { + verify(fixture.scopes).captureEvent( argThat { timestamp.time == newTimestamp - TimeUnit.DAYS.toMillis(2) }, anyOrNull() ) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( argThat { timestamp.time == newTimestamp - TimeUnit.DAYS.toMillis(1) }, anyOrNull() ) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( argThat { timestamp.time == newTimestamp }, anyOrNull() ) @@ -427,9 +427,9 @@ class AnrV2IntegrationTest { val integration = fixture.getSut(tmpDir, lastReportedAnrTimestamp = oldTimestamp) fixture.addAppExitInfo(timestamp = newTimestamp) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( any(), argThat { val hint = HintUtils.getSentrySdkHint(this) @@ -443,9 +443,9 @@ class AnrV2IntegrationTest { val integration = fixture.getSut(tmpDir, lastReportedAnrTimestamp = oldTimestamp) fixture.addAppExitInfo(timestamp = newTimestamp) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( any(), argThat { val hint = HintUtils.getSentrySdkHint(this) @@ -472,7 +472,7 @@ class AnrV2IntegrationTest { ) } - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) // we store envelope with StartSessionHint on different thread after some delay, which // triggers the previous session flush, so no timeout @@ -493,14 +493,14 @@ class AnrV2IntegrationTest { ) fixture.addAppExitInfo(timestamp = newTimestamp) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) verify(fixture.logger, never()).log( any(), argThat { startsWith("Timed out waiting to flush previous session to its own file.") }, any() ) - verify(fixture.hub).captureEvent(any(), any()) + verify(fixture.scopes).captureEvent(any(), any()) } @Test @@ -512,7 +512,7 @@ class AnrV2IntegrationTest { ) fixture.addAppExitInfo(timestamp = newTimestamp) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) verify(fixture.logger).log( any(), @@ -532,9 +532,9 @@ class AnrV2IntegrationTest { ) fixture.addAppExitInfo(timestamp = newTimestamp) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( any(), check { assertNotNull(it.threadDump) @@ -547,8 +547,8 @@ class AnrV2IntegrationTest { val integration = fixture.getSut(tmpDir, lastReportedAnrTimestamp = oldTimestamp) fixture.addAppExitInfo(timestamp = newTimestamp, addTrace = false) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) - verify(fixture.hub, never()).captureEvent(any(), anyOrNull()) + verify(fixture.scopes, never()).captureEvent(any(), anyOrNull()) } } diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/AppComponentsBreadcrumbsIntegrationTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/AppComponentsBreadcrumbsIntegrationTest.kt index 15a6d690e5..5f8792c850 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/AppComponentsBreadcrumbsIntegrationTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/AppComponentsBreadcrumbsIntegrationTest.kt @@ -5,7 +5,7 @@ import android.content.Context import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import io.sentry.Breadcrumb -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryLevel import org.junit.runner.RunWith import org.mockito.kotlin.any @@ -37,8 +37,8 @@ class AppComponentsBreadcrumbsIntegrationTest { fun `When app components breadcrumb is enabled, it registers callback`() { val sut = fixture.getSut() val options = SentryAndroidOptions() - val hub = mock() - sut.register(hub, options) + val scopes = mock() + sut.register(scopes, options) verify(fixture.context).registerComponentCallbacks(any()) } @@ -46,10 +46,10 @@ class AppComponentsBreadcrumbsIntegrationTest { fun `When app components breadcrumb is enabled, but ComponentCallbacks is not ready, do not throw`() { val sut = fixture.getSut() val options = SentryAndroidOptions() - val hub = mock() - sut.register(hub, options) + val scopes = mock() + sut.register(scopes, options) whenever(fixture.context.registerComponentCallbacks(any())).thenThrow(NullPointerException()) - sut.register(hub, options) + sut.register(scopes, options) assertFalse(options.isEnableAppComponentBreadcrumbs) } @@ -59,8 +59,8 @@ class AppComponentsBreadcrumbsIntegrationTest { val options = SentryAndroidOptions().apply { isEnableAppComponentBreadcrumbs = false } - val hub = mock() - sut.register(hub, options) + val scopes = mock() + sut.register(scopes, options) verify(fixture.context, never()).registerComponentCallbacks(any()) } @@ -68,8 +68,8 @@ class AppComponentsBreadcrumbsIntegrationTest { fun `When AppComponentsBreadcrumbsIntegrationTest is closed, it should unregister the callback`() { val sut = fixture.getSut() val options = SentryAndroidOptions() - val hub = mock() - sut.register(hub, options) + val scopes = mock() + sut.register(scopes, options) sut.close() verify(fixture.context).unregisterComponentCallbacks(any()) } @@ -78,10 +78,10 @@ class AppComponentsBreadcrumbsIntegrationTest { fun `When app components breadcrumb is closed, but ComponentCallbacks is not ready, do not throw`() { val sut = fixture.getSut() val options = SentryAndroidOptions() - val hub = mock() + val scopes = mock() whenever(fixture.context.registerComponentCallbacks(any())).thenThrow(NullPointerException()) whenever(fixture.context.unregisterComponentCallbacks(any())).thenThrow(NullPointerException()) - sut.register(hub, options) + sut.register(scopes, options) sut.close() } @@ -89,10 +89,10 @@ class AppComponentsBreadcrumbsIntegrationTest { fun `When low memory event, a breadcrumb with type, category and level should be set`() { val sut = fixture.getSut() val options = SentryAndroidOptions() - val hub = mock() - sut.register(hub, options) + val scopes = mock() + sut.register(scopes, options) sut.onLowMemory() - verify(hub).addBreadcrumb( + verify(scopes).addBreadcrumb( check { assertEquals("device.event", it.category) assertEquals("system", it.type) @@ -105,10 +105,10 @@ class AppComponentsBreadcrumbsIntegrationTest { fun `When trim memory event with level, a breadcrumb with type, category and level should be set`() { val sut = fixture.getSut() val options = SentryAndroidOptions() - val hub = mock() - sut.register(hub, options) + val scopes = mock() + sut.register(scopes, options) sut.onTrimMemory(ComponentCallbacks2.TRIM_MEMORY_BACKGROUND) - verify(hub).addBreadcrumb( + verify(scopes).addBreadcrumb( check { assertEquals("device.event", it.category) assertEquals("system", it.type) @@ -121,20 +121,20 @@ class AppComponentsBreadcrumbsIntegrationTest { fun `When trim memory event with level not so high, do not add a breadcrumb`() { val sut = fixture.getSut() val options = SentryAndroidOptions() - val hub = mock() - sut.register(hub, options) + val scopes = mock() + sut.register(scopes, options) sut.onTrimMemory(ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL) - verify(hub, never()).addBreadcrumb(any()) + verify(scopes, never()).addBreadcrumb(any()) } @Test fun `When device orientation event, a breadcrumb with type, category and level should be set`() { val sut = AppComponentsBreadcrumbsIntegration(ApplicationProvider.getApplicationContext()) val options = SentryAndroidOptions() - val hub = mock() - sut.register(hub, options) + val scopes = mock() + sut.register(scopes, options) sut.onConfigurationChanged(mock()) - verify(hub).addBreadcrumb( + verify(scopes).addBreadcrumb( check { assertEquals("device.orientation", it.category) assertEquals("navigation", it.type) diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/AppLifecycleIntegrationTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/AppLifecycleIntegrationTest.kt index ed8d53227c..733aefa8d6 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/AppLifecycleIntegrationTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/AppLifecycleIntegrationTest.kt @@ -2,7 +2,7 @@ package io.sentry.android.core import android.os.Looper import androidx.test.ext.junit.runners.AndroidJUnit4 -import io.sentry.IHub +import io.sentry.IScopes import org.junit.runner.RunWith import org.mockito.kotlin.any import org.mockito.kotlin.mock @@ -17,7 +17,7 @@ import kotlin.test.assertNull class AppLifecycleIntegrationTest { private class Fixture { - val hub = mock() + val scopes = mock() lateinit var handler: MainLooperHandler val options = SentryAndroidOptions() @@ -33,7 +33,7 @@ class AppLifecycleIntegrationTest { fun `When AppLifecycleIntegration is added, lifecycle watcher should be started`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertNotNull(sut.watcher) } @@ -46,7 +46,7 @@ class AppLifecycleIntegrationTest { isEnableAutoSessionTracking = false } - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertNull(sut.watcher) } @@ -55,7 +55,7 @@ class AppLifecycleIntegrationTest { fun `When AppLifecycleIntegration is closed, lifecycle watcher should be closed`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertNotNull(sut.watcher) @@ -70,7 +70,7 @@ class AppLifecycleIntegrationTest { val latch = CountDownLatch(1) Thread { - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) latch.countDown() }.start() @@ -84,7 +84,7 @@ class AppLifecycleIntegrationTest { val sut = fixture.getSut() val latch = CountDownLatch(1) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertNotNull(sut.watcher) @@ -103,7 +103,7 @@ class AppLifecycleIntegrationTest { val sut = fixture.getSut(mockHandler = false) val latch = CountDownLatch(1) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertNotNull(sut.watcher) diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/CurrentActivityIntegrationTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/CurrentActivityIntegrationTest.kt index 6330623121..ecdbff5104 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/CurrentActivityIntegrationTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/CurrentActivityIntegrationTest.kt @@ -3,7 +3,7 @@ package io.sentry.android.core import android.app.Activity import android.app.Application import androidx.test.ext.junit.runners.AndroidJUnit4 -import io.sentry.IHub +import io.sentry.IScopes import org.junit.runner.RunWith import org.mockito.kotlin.any import org.mockito.kotlin.mock @@ -19,7 +19,7 @@ class CurrentActivityIntegrationTest { private class Fixture { val application = mock() val activity = mock() - val hub = mock() + val scopes = mock() val options = SentryAndroidOptions().apply { dsn = "https://key@sentry.io/proj" @@ -27,7 +27,7 @@ class CurrentActivityIntegrationTest { fun getSut(): CurrentActivityIntegration { val integration = CurrentActivityIntegration(application) - integration.register(hub, options) + integration.register(scopes, options) return integration } } diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/DefaultAndroidEventProcessorTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/DefaultAndroidEventProcessorTest.kt index 80954f67a5..c4fef01cc2 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/DefaultAndroidEventProcessorTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/DefaultAndroidEventProcessorTest.kt @@ -7,7 +7,7 @@ import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import io.sentry.DiagnosticLogger import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryEvent import io.sentry.SentryLevel import io.sentry.SentryTracer @@ -62,13 +62,13 @@ class DefaultAndroidEventProcessorTest { sdkVersion = SdkVersion("test", "1.2.3") } - val hub: IHub = mock() + val scopes: IScopes = mock() lateinit var sentryTracer: SentryTracer fun getSut(context: Context): DefaultAndroidEventProcessor { - whenever(hub.options).thenReturn(options) - sentryTracer = SentryTracer(TransactionContext("", ""), hub) + whenever(scopes.options).thenReturn(options) + sentryTracer = SentryTracer(TransactionContext("", ""), scopes) return DefaultAndroidEventProcessor(context, buildInfo, options) } } diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/EnvelopeFileObserverIntegrationTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/EnvelopeFileObserverIntegrationTest.kt index 699fa2d2f2..192565f101 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/EnvelopeFileObserverIntegrationTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/EnvelopeFileObserverIntegrationTest.kt @@ -2,8 +2,8 @@ package io.sentry.android.core import androidx.test.ext.junit.runners.AndroidJUnit4 import io.sentry.Hub -import io.sentry.IHub import io.sentry.ILogger +import io.sentry.IScopes import io.sentry.SentryLevel import io.sentry.SentryOptions import io.sentry.test.DeferredExecutorService @@ -24,7 +24,7 @@ import kotlin.test.assertEquals @RunWith(AndroidJUnit4::class) class EnvelopeFileObserverIntegrationTest { inner class Fixture { - val hub: IHub = mock() + val scopes: IScopes = mock() private lateinit var options: SentryAndroidOptions val logger = mock() @@ -33,7 +33,7 @@ class EnvelopeFileObserverIntegrationTest { options.setLogger(logger) options.isDebug = true optionConfiguration(options) - whenever(hub.options).thenReturn(options) + whenever(scopes.options).thenReturn(options) return object : EnvelopeFileObserverIntegration() { override fun getPath(options: SentryOptions): String? = file.absolutePath @@ -65,7 +65,7 @@ class EnvelopeFileObserverIntegrationTest { } @Test - fun `when hub is closed, integrations should be closed`() { + fun `when scopes is closed, integrations should be closed`() { val integrationMock = mock() val options = SentryOptions() options.dsn = "https://key@sentry.io/proj" @@ -73,19 +73,19 @@ class EnvelopeFileObserverIntegrationTest { options.addIntegration(integrationMock) options.setSerializer(mock()) // val expected = HubAdapter.getInstance() - val hub = Hub(options) + val scopes = Hub(options) // verify(integrationMock).register(expected, options) - hub.close() + scopes.close() verify(integrationMock).close() } @Test - fun `when hub is closed right after start, integration is not registered`() { + fun `when scopes is closed right after start, integration is not registered`() { val deferredExecutorService = DeferredExecutorService() val integration = fixture.getSut { it.executorService = deferredExecutorService } - integration.register(fixture.hub, fixture.hub.options) + integration.register(fixture.scopes, fixture.scopes.options) integration.close() deferredExecutorService.runAll() verify(fixture.logger, never()).log(eq(SentryLevel.DEBUG), eq("EnvelopeFileObserverIntegration installed.")) @@ -96,7 +96,7 @@ class EnvelopeFileObserverIntegrationTest { val integration = fixture.getSut { it.executorService = mock() } - integration.register(fixture.hub, fixture.hub.options) + integration.register(fixture.scopes, fixture.scopes.options) verify(fixture.logger).log( eq(SentryLevel.DEBUG), eq("Registering EnvelopeFileObserverIntegration for path: %s"), @@ -110,7 +110,7 @@ class EnvelopeFileObserverIntegrationTest { val integration = fixture.getSut { it.executorService = ImmediateExecutorService() } - integration.register(fixture.hub, fixture.hub.options) + integration.register(fixture.scopes, fixture.scopes.options) verify(fixture.logger).log( eq(SentryLevel.DEBUG), eq("Registering EnvelopeFileObserverIntegration for path: %s"), diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/LifecycleWatcherTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/LifecycleWatcherTest.kt index be30993142..73571a5ad4 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/LifecycleWatcherTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/LifecycleWatcherTest.kt @@ -3,8 +3,8 @@ package io.sentry.android.core import androidx.lifecycle.LifecycleOwner import io.sentry.Breadcrumb import io.sentry.DateUtils -import io.sentry.IHub import io.sentry.IScope +import io.sentry.IScopes import io.sentry.ScopeCallback import io.sentry.SentryLevel import io.sentry.Session @@ -32,7 +32,7 @@ class LifecycleWatcherTest { private class Fixture { val ownerMock = mock() - val hub = mock() + val scopes = mock() val dateProvider = mock() fun getSUT( @@ -44,12 +44,12 @@ class LifecycleWatcherTest { val argumentCaptor: ArgumentCaptor = ArgumentCaptor.forClass(ScopeCallback::class.java) val scope = mock() whenever(scope.session).thenReturn(session) - whenever(hub.configureScope(argumentCaptor.capture())).thenAnswer { + whenever(scopes.configureScope(argumentCaptor.capture())).thenAnswer { argumentCaptor.value.run(scope) } return LifecycleWatcher( - hub, + scopes, sessionIntervalMillis, enableAutoSessionTracking, enableAppLifecycleBreadcrumbs, @@ -69,7 +69,7 @@ class LifecycleWatcherTest { fun `if last started session is 0, start new session`() { val watcher = fixture.getSUT(enableAppLifecycleBreadcrumbs = false) watcher.onStart(fixture.ownerMock) - verify(fixture.hub).startSession() + verify(fixture.scopes).startSession() } @Test @@ -78,7 +78,7 @@ class LifecycleWatcherTest { whenever(fixture.dateProvider.currentTimeMillis).thenReturn(1L, 2L) watcher.onStart(fixture.ownerMock) watcher.onStart(fixture.ownerMock) - verify(fixture.hub, times(2)).startSession() + verify(fixture.scopes, times(2)).startSession() } @Test @@ -87,7 +87,7 @@ class LifecycleWatcherTest { whenever(fixture.dateProvider.currentTimeMillis).thenReturn(2L, 1L) watcher.onStart(fixture.ownerMock) watcher.onStart(fixture.ownerMock) - verify(fixture.hub).startSession() + verify(fixture.scopes).startSession() } @Test @@ -95,7 +95,7 @@ class LifecycleWatcherTest { val watcher = fixture.getSUT(enableAppLifecycleBreadcrumbs = false) watcher.onStart(fixture.ownerMock) watcher.onStop(fixture.ownerMock) - verify(fixture.hub, timeout(10000)).endSession() + verify(fixture.scopes, timeout(10000)).endSession() } @Test @@ -109,14 +109,14 @@ class LifecycleWatcherTest { watcher.onStart(fixture.ownerMock) assertNull(watcher.timerTask) - verify(fixture.hub, never()).endSession() + verify(fixture.scopes, never()).endSession() } @Test fun `When session tracking is disabled, do not start session`() { val watcher = fixture.getSUT(enableAutoSessionTracking = false, enableAppLifecycleBreadcrumbs = false) watcher.onStart(fixture.ownerMock) - verify(fixture.hub, never()).startSession() + verify(fixture.scopes, never()).startSession() } @Test @@ -124,14 +124,14 @@ class LifecycleWatcherTest { val watcher = fixture.getSUT(enableAutoSessionTracking = false, enableAppLifecycleBreadcrumbs = false) watcher.onStop(fixture.ownerMock) assertNull(watcher.timerTask) - verify(fixture.hub, never()).endSession() + verify(fixture.scopes, never()).endSession() } @Test fun `When session tracking is enabled, add breadcrumb on start`() { val watcher = fixture.getSUT(enableAppLifecycleBreadcrumbs = false) watcher.onStart(fixture.ownerMock) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("app.lifecycle", it.category) assertEquals("session", it.type) @@ -145,8 +145,8 @@ class LifecycleWatcherTest { fun `When session tracking is enabled, add breadcrumb on stop`() { val watcher = fixture.getSUT(enableAppLifecycleBreadcrumbs = false) watcher.onStop(fixture.ownerMock) - verify(fixture.hub, timeout(10000)).endSession() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes, timeout(10000)).endSession() + verify(fixture.scopes).addBreadcrumb( check { assertEquals("app.lifecycle", it.category) assertEquals("session", it.type) @@ -160,7 +160,7 @@ class LifecycleWatcherTest { fun `When session tracking is disabled, do not add breadcrumb on start`() { val watcher = fixture.getSUT(enableAutoSessionTracking = false, enableAppLifecycleBreadcrumbs = false) watcher.onStart(fixture.ownerMock) - verify(fixture.hub, never()).addBreadcrumb(any()) + verify(fixture.scopes, never()).addBreadcrumb(any()) } @Test @@ -168,14 +168,14 @@ class LifecycleWatcherTest { val watcher = fixture.getSUT(enableAutoSessionTracking = false, enableAppLifecycleBreadcrumbs = false) watcher.onStop(fixture.ownerMock) assertNull(watcher.timerTask) - verify(fixture.hub, never()).addBreadcrumb(any()) + verify(fixture.scopes, never()).addBreadcrumb(any()) } @Test fun `When app lifecycle breadcrumbs is enabled, add breadcrumb on start`() { val watcher = fixture.getSUT(enableAutoSessionTracking = false) watcher.onStart(fixture.ownerMock) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("app.lifecycle", it.category) assertEquals("navigation", it.type) @@ -189,14 +189,14 @@ class LifecycleWatcherTest { fun `When app lifecycle breadcrumbs is disabled, do not add breadcrumb on start`() { val watcher = fixture.getSUT(enableAutoSessionTracking = false, enableAppLifecycleBreadcrumbs = false) watcher.onStart(fixture.ownerMock) - verify(fixture.hub, never()).addBreadcrumb(any()) + verify(fixture.scopes, never()).addBreadcrumb(any()) } @Test fun `When app lifecycle breadcrumbs is enabled, add breadcrumb on stop`() { val watcher = fixture.getSUT(enableAutoSessionTracking = false) watcher.onStop(fixture.ownerMock) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("app.lifecycle", it.category) assertEquals("navigation", it.type) @@ -210,7 +210,7 @@ class LifecycleWatcherTest { fun `When app lifecycle breadcrumbs is disabled, do not add breadcrumb on stop`() { val watcher = fixture.getSUT(enableAutoSessionTracking = false, enableAppLifecycleBreadcrumbs = false) watcher.onStop(fixture.ownerMock) - verify(fixture.hub, never()).addBreadcrumb(any()) + verify(fixture.scopes, never()).addBreadcrumb(any()) } @Test @@ -226,7 +226,7 @@ class LifecycleWatcherTest { } @Test - fun `if the hub has already a fresh session running, don't start new one`() { + fun `if the scopes has already a fresh session running, don't start new one`() { val watcher = fixture.getSUT( enableAppLifecycleBreadcrumbs = false, session = Session( @@ -248,11 +248,11 @@ class LifecycleWatcherTest { ) watcher.onStart(fixture.ownerMock) - verify(fixture.hub, never()).startSession() + verify(fixture.scopes, never()).startSession() } @Test - fun `if the hub has a long running session, start new one`() { + fun `if the scopes has a long running session, start new one`() { val watcher = fixture.getSUT( enableAppLifecycleBreadcrumbs = false, session = Session( @@ -274,7 +274,7 @@ class LifecycleWatcherTest { ) watcher.onStart(fixture.ownerMock) - verify(fixture.hub).startSession() + verify(fixture.scopes).startSession() } @Test diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/NdkIntegrationTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/NdkIntegrationTest.kt index e86de06814..e282ad7141 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/NdkIntegrationTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/NdkIntegrationTest.kt @@ -1,7 +1,7 @@ package io.sentry.android.core -import io.sentry.IHub import io.sentry.ILogger +import io.sentry.IScopes import io.sentry.SentryLevel import org.mockito.kotlin.any import org.mockito.kotlin.eq @@ -15,7 +15,7 @@ import kotlin.test.assertTrue class NdkIntegrationTest { private class Fixture { - val hub = mock() + val scopes = mock() val logger = mock() fun getSut(clazz: Class<*>? = SentryNdk::class.java): NdkIntegration { @@ -31,7 +31,7 @@ class NdkIntegrationTest { val options = getOptions() - integration.register(fixture.hub, options) + integration.register(fixture.scopes, options) verify(fixture.logger, never()).log(eq(SentryLevel.ERROR), any(), any()) assertTrue(options.isEnableNdk) @@ -44,7 +44,7 @@ class NdkIntegrationTest { val options = getOptions() - integration.register(fixture.hub, options) + integration.register(fixture.scopes, options) assertTrue(options.isEnableNdk) assertTrue(options.isEnableScopeSync) @@ -62,7 +62,7 @@ class NdkIntegrationTest { val options = getOptions(enableNdk = false) - integration.register(fixture.hub, options) + integration.register(fixture.scopes, options) verify(fixture.logger, never()).log(eq(SentryLevel.ERROR), any(), any()) @@ -76,7 +76,7 @@ class NdkIntegrationTest { val options = getOptions() - integration.register(fixture.hub, options) + integration.register(fixture.scopes, options) verify(fixture.logger, never()).log(eq(SentryLevel.ERROR), any(), any()) @@ -90,7 +90,7 @@ class NdkIntegrationTest { val options = getOptions() - integration.register(fixture.hub, options) + integration.register(fixture.scopes, options) verify(fixture.logger).log(eq(SentryLevel.ERROR), any(), any()) @@ -104,7 +104,7 @@ class NdkIntegrationTest { val options = getOptions() - integration.register(fixture.hub, options) + integration.register(fixture.scopes, options) assertTrue(options.isEnableNdk) assertTrue(options.isEnableScopeSync) @@ -122,7 +122,7 @@ class NdkIntegrationTest { val options = getOptions() - integration.register(fixture.hub, options) + integration.register(fixture.scopes, options) verify(fixture.logger).log(eq(SentryLevel.ERROR), any(), any()) @@ -136,7 +136,7 @@ class NdkIntegrationTest { val options = getOptions(cacheDir = null) - integration.register(fixture.hub, options) + integration.register(fixture.scopes, options) verify(fixture.logger).log(eq(SentryLevel.ERROR), any()) @@ -150,7 +150,7 @@ class NdkIntegrationTest { val options = getOptions(cacheDir = "") - integration.register(fixture.hub, options) + integration.register(fixture.scopes, options) verify(fixture.logger).log(eq(SentryLevel.ERROR), any()) diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/NetworkBreadcrumbsIntegrationTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/NetworkBreadcrumbsIntegrationTest.kt index 146f229fdf..c28cf64085 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/NetworkBreadcrumbsIntegrationTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/NetworkBreadcrumbsIntegrationTest.kt @@ -8,7 +8,7 @@ import android.net.NetworkCapabilities import android.os.Build import io.sentry.Breadcrumb import io.sentry.DateUtils -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryDateProvider import io.sentry.SentryLevel import io.sentry.SentryNanotimeDate @@ -39,7 +39,7 @@ class NetworkBreadcrumbsIntegrationTest { private class Fixture { val context = mock() var options = SentryAndroidOptions() - val hub = mock() + val scopes = mock() val mockBuildInfoProvider = mock() val connectivityManager = mock() var nowMs: Long = 0 @@ -68,7 +68,7 @@ class NetworkBreadcrumbsIntegrationTest { fun `When network events breadcrumb is enabled, it registers callback`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.connectivityManager).registerDefaultNetworkCallback(any()) assertNotNull(sut.networkCallback) @@ -78,7 +78,7 @@ class NetworkBreadcrumbsIntegrationTest { fun `When system events breadcrumb is disabled, it doesn't register callback`() { val sut = fixture.getSut(enableNetworkEventBreadcrumbs = false) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.connectivityManager, never()).registerDefaultNetworkCallback(any()) assertNull(sut.networkCallback) @@ -90,7 +90,7 @@ class NetworkBreadcrumbsIntegrationTest { whenever(buildInfo.sdkInfoVersion).thenReturn(Build.VERSION_CODES.M) val sut = fixture.getSut(buildInfo = buildInfo) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.connectivityManager, never()).registerDefaultNetworkCallback(any()) assertNull(sut.networkCallback) @@ -100,7 +100,7 @@ class NetworkBreadcrumbsIntegrationTest { fun `When NetworkBreadcrumbsIntegration is closed, it should unregister the callback`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) sut.close() verify(fixture.connectivityManager).unregisterNetworkCallback(any()) @@ -114,7 +114,7 @@ class NetworkBreadcrumbsIntegrationTest { val sut = fixture.getSut(buildInfo = buildInfo) assertNull(sut.networkCallback) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) sut.close() verify(fixture.connectivityManager, never()).unregisterNetworkCallback(any()) @@ -124,12 +124,12 @@ class NetworkBreadcrumbsIntegrationTest { @Test fun `When connected to a new network, a breadcrumb is captured`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) callback.onAvailable(mock()) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("system", it.type) assertEquals("network.event", it.category) @@ -142,27 +142,27 @@ class NetworkBreadcrumbsIntegrationTest { @Test fun `When connected to the same network without disconnecting from the previous one, only one breadcrumb is captured`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) callback.onAvailable(fixture.network) callback.onAvailable(fixture.network) - verify(fixture.hub, times(1)).addBreadcrumb(any()) + verify(fixture.scopes, times(1)).addBreadcrumb(any()) } @Test fun `When disconnected from a network, a breadcrumb is captured`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) callback.onAvailable(fixture.network) - verify(fixture.hub).addBreadcrumb(any()) + verify(fixture.scopes).addBreadcrumb(any()) callback.onLost(fixture.network) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("system", it.type) assertEquals("network.event", it.category) @@ -175,12 +175,12 @@ class NetworkBreadcrumbsIntegrationTest { @Test fun `When disconnected from a network, a breadcrumb is captured only if previously connected to that network`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) // callback.onAvailable(network) was not called, so no breadcrumb should be captured callback.onLost(mock()) - verify(fixture.hub, never()).addBreadcrumb(any()) + verify(fixture.scopes, never()).addBreadcrumb(any()) } @Test @@ -188,7 +188,7 @@ class NetworkBreadcrumbsIntegrationTest { val buildInfo = mock() whenever(buildInfo.sdkInfoVersion).thenReturn(Build.VERSION_CODES.Q) val sut = fixture.getSut(buildInfo = buildInfo) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) callback.onAvailable(fixture.network) @@ -204,7 +204,7 @@ class NetworkBreadcrumbsIntegrationTest { isCellular = false ) ) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("system", it.type) assertEquals("network.event", it.category) @@ -223,18 +223,18 @@ class NetworkBreadcrumbsIntegrationTest { @Test fun `When a network connection detail changes, a breadcrumb is captured only if previously connected to that network`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) // callback.onAvailable(network) was not called, so no breadcrumb should be captured onCapabilitiesChanged(callback, mock()) - verify(fixture.hub, never()).addBreadcrumb(any(), anyOrNull()) + verify(fixture.scopes, never()).addBreadcrumb(any(), anyOrNull()) } @Test fun `When a network connection detail changes, a new breadcrumb is captured if vpn flag changes`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) callback.onAvailable(fixture.network) @@ -245,17 +245,17 @@ class NetworkBreadcrumbsIntegrationTest { onCapabilitiesChanged(callback, details1) onCapabilitiesChanged(callback, details2) onCapabilitiesChanged(callback, details3) - inOrder(fixture.hub) { + inOrder(fixture.scopes) { verifyBreadcrumbInOrder { assertFalse(it.isVpn) } verifyBreadcrumbInOrder { assertTrue(it.isVpn) } - verify(fixture.hub, never()).addBreadcrumb(any(), any()) + verify(fixture.scopes, never()).addBreadcrumb(any(), any()) } } @Test fun `When a network connection detail changes, a new breadcrumb is captured if type changes`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) callback.onAvailable(fixture.network) @@ -266,10 +266,10 @@ class NetworkBreadcrumbsIntegrationTest { onCapabilitiesChanged(callback, details1) onCapabilitiesChanged(callback, details2) onCapabilitiesChanged(callback, details3) - inOrder(fixture.hub) { + inOrder(fixture.scopes) { verifyBreadcrumbInOrder { assertEquals("wifi", it.type) } verifyBreadcrumbInOrder { assertEquals("cellular", it.type) } - verify(fixture.hub, never()).addBreadcrumb(any(), any()) + verify(fixture.scopes, never()).addBreadcrumb(any(), any()) } } @@ -278,7 +278,7 @@ class NetworkBreadcrumbsIntegrationTest { val buildInfo = mock() whenever(buildInfo.sdkInfoVersion).thenReturn(Build.VERSION_CODES.Q) val sut = fixture.getSut(buildInfo = buildInfo) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) callback.onAvailable(fixture.network) @@ -289,10 +289,10 @@ class NetworkBreadcrumbsIntegrationTest { // A change of signal strength of 5 doesn't trigger a new breadcrumb onCapabilitiesChanged(callback, details2) onCapabilitiesChanged(callback, details3) - inOrder(fixture.hub) { + inOrder(fixture.scopes) { verifyBreadcrumbInOrder { assertEquals(50, it.signalStrength) } verifyBreadcrumbInOrder { assertEquals(56, it.signalStrength) } - verify(fixture.hub, never()).addBreadcrumb(any(), any()) + verify(fixture.scopes, never()).addBreadcrumb(any(), any()) } } @@ -301,7 +301,7 @@ class NetworkBreadcrumbsIntegrationTest { val buildInfo = mock() whenever(buildInfo.sdkInfoVersion).thenReturn(Build.VERSION_CODES.Q) val sut = fixture.getSut(buildInfo = buildInfo) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) callback.onAvailable(fixture.network) @@ -317,11 +317,11 @@ class NetworkBreadcrumbsIntegrationTest { // A change of download bandwidth of 10% (more than 1000) doesn't trigger a new breadcrumb onCapabilitiesChanged(callback, details4) onCapabilitiesChanged(callback, details5) - inOrder(fixture.hub) { + inOrder(fixture.scopes) { verifyBreadcrumbInOrder { assertEquals(1000, it.downBandwidth) } verifyBreadcrumbInOrder { assertEquals(20000, it.downBandwidth) } verifyBreadcrumbInOrder { assertEquals(22001, it.downBandwidth) } - verify(fixture.hub, never()).addBreadcrumb(any(), any()) + verify(fixture.scopes, never()).addBreadcrumb(any(), any()) } } @@ -330,7 +330,7 @@ class NetworkBreadcrumbsIntegrationTest { val buildInfo = mock() whenever(buildInfo.sdkInfoVersion).thenReturn(Build.VERSION_CODES.Q) val sut = fixture.getSut(buildInfo = buildInfo) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) callback.onAvailable(fixture.network) @@ -346,18 +346,18 @@ class NetworkBreadcrumbsIntegrationTest { // A change of upload bandwidth of 10% (more than 1000) doesn't trigger a new breadcrumb onCapabilitiesChanged(callback, details4) onCapabilitiesChanged(callback, details5) - inOrder(fixture.hub) { + inOrder(fixture.scopes) { verifyBreadcrumbInOrder { assertEquals(1000, it.upBandwidth) } verifyBreadcrumbInOrder { assertEquals(20000, it.upBandwidth) } verifyBreadcrumbInOrder { assertEquals(22001, it.upBandwidth) } - verify(fixture.hub, never()).addBreadcrumb(any(), any()) + verify(fixture.scopes, never()).addBreadcrumb(any(), any()) } } @Test fun `signal strength is 0 if not on Android Q+`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) callback.onAvailable(fixture.network) @@ -371,7 +371,7 @@ class NetworkBreadcrumbsIntegrationTest { val buildInfo = mock() whenever(buildInfo.sdkInfoVersion).thenReturn(Build.VERSION_CODES.Q) val sut = fixture.getSut(buildInfo = buildInfo) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) callback.onAvailable(fixture.network) @@ -384,7 +384,7 @@ class NetworkBreadcrumbsIntegrationTest { @Test fun `A breadcrumb is captured when vpn status changes, regardless of the timestamp`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) callback.onAvailable(fixture.network) @@ -392,17 +392,17 @@ class NetworkBreadcrumbsIntegrationTest { val details2 = createConnectionDetail(isVpn = true) onCapabilitiesChanged(callback, details1, 0) onCapabilitiesChanged(callback, details2, 0) - inOrder(fixture.hub) { + inOrder(fixture.scopes) { verifyBreadcrumbInOrder { assertFalse(it.isVpn) } verifyBreadcrumbInOrder { assertTrue(it.isVpn) } - verify(fixture.hub, never()).addBreadcrumb(any(), any()) + verify(fixture.scopes, never()).addBreadcrumb(any(), any()) } } @Test fun `A breadcrumb is captured when connection type changes, regardless of the timestamp`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) callback.onAvailable(fixture.network) @@ -412,11 +412,11 @@ class NetworkBreadcrumbsIntegrationTest { onCapabilitiesChanged(callback, details1, 0) onCapabilitiesChanged(callback, details2, 0) onCapabilitiesChanged(callback, details3, 0) - inOrder(fixture.hub) { + inOrder(fixture.scopes) { verifyBreadcrumbInOrder { assertEquals("wifi", it.type) } verifyBreadcrumbInOrder { assertEquals("cellular", it.type) } verifyBreadcrumbInOrder { assertEquals("ethernet", it.type) } - verify(fixture.hub, never()).addBreadcrumb(any(), any()) + verify(fixture.scopes, never()).addBreadcrumb(any(), any()) } } @@ -425,7 +425,7 @@ class NetworkBreadcrumbsIntegrationTest { val buildInfo = mock() whenever(buildInfo.sdkInfoVersion).thenReturn(Build.VERSION_CODES.Q) val sut = fixture.getSut(buildInfo = buildInfo) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) callback.onAvailable(fixture.network) @@ -435,17 +435,17 @@ class NetworkBreadcrumbsIntegrationTest { onCapabilitiesChanged(callback, details1, 0) onCapabilitiesChanged(callback, details2, 0) onCapabilitiesChanged(callback, details3, 5000) - inOrder(fixture.hub) { + inOrder(fixture.scopes) { verifyBreadcrumbInOrder { assertEquals(1, it.signalStrength) } verifyBreadcrumbInOrder { assertEquals(51, it.signalStrength) } - verify(fixture.hub, never()).addBreadcrumb(any(), any()) + verify(fixture.scopes, never()).addBreadcrumb(any(), any()) } } @Test fun `A breadcrumb is captured when downBandwidth changes at most once every 5 seconds`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) callback.onAvailable(fixture.network) @@ -455,17 +455,17 @@ class NetworkBreadcrumbsIntegrationTest { onCapabilitiesChanged(callback, details1, 0) onCapabilitiesChanged(callback, details2, 0) onCapabilitiesChanged(callback, details3, 5000) - inOrder(fixture.hub) { + inOrder(fixture.scopes) { verifyBreadcrumbInOrder { assertEquals(1, it.downBandwidth) } verifyBreadcrumbInOrder { assertEquals(2001, it.downBandwidth) } - verify(fixture.hub, never()).addBreadcrumb(any(), any()) + verify(fixture.scopes, never()).addBreadcrumb(any(), any()) } } @Test fun `A breadcrumb is captured when upBandwidth changes at most once every 5 seconds`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) callback.onAvailable(fixture.network) @@ -475,15 +475,15 @@ class NetworkBreadcrumbsIntegrationTest { onCapabilitiesChanged(callback, details1, 0) onCapabilitiesChanged(callback, details2, 0) onCapabilitiesChanged(callback, details3, 5000) - inOrder(fixture.hub) { + inOrder(fixture.scopes) { verifyBreadcrumbInOrder { assertEquals(1, it.upBandwidth) } verifyBreadcrumbInOrder { assertEquals(2001, it.upBandwidth) } - verify(fixture.hub, never()).addBreadcrumb(any(), any()) + verify(fixture.scopes, never()).addBreadcrumb(any(), any()) } } private fun KInOrder.verifyBreadcrumbInOrder(check: (detail: NetworkBreadcrumbConnectionDetail) -> Unit) { - verify(fixture.hub, times(1)).addBreadcrumb( + verify(fixture.scopes, times(1)).addBreadcrumb( any(), check { val connectionDetail = it[TypeCheckHint.ANDROID_NETWORK_CAPABILITIES] as NetworkBreadcrumbConnectionDetail @@ -493,7 +493,7 @@ class NetworkBreadcrumbsIntegrationTest { } private fun verifyBreadcrumb(check: (detail: NetworkBreadcrumbConnectionDetail) -> Unit) { - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( any(), check { val connectionDetail = it[TypeCheckHint.ANDROID_NETWORK_CAPABILITIES] as NetworkBreadcrumbConnectionDetail diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/PerformanceAndroidEventProcessorTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/PerformanceAndroidEventProcessorTest.kt index 4c23691e63..e1593e600f 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/PerformanceAndroidEventProcessorTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/PerformanceAndroidEventProcessorTest.kt @@ -3,7 +3,7 @@ package io.sentry.android.core import android.content.ContentProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.MeasurementUnit import io.sentry.SentryTracer import io.sentry.SpanContext @@ -35,7 +35,7 @@ class PerformanceAndroidEventProcessorTest { private class Fixture { val options = SentryAndroidOptions() - val hub = mock() + val scopes = mock() val context = TransactionContext("name", "op", TracesSamplingDecision(true)) lateinit var tracer: SentryTracer val activityFramesTracker = mock() @@ -46,8 +46,8 @@ class PerformanceAndroidEventProcessorTest { ): PerformanceAndroidEventProcessor { options.tracesSampleRate = tracesSampleRate options.isEnablePerformanceV2 = enablePerformanceV2 - whenever(hub.options).thenReturn(options) - tracer = SentryTracer(context, hub) + whenever(scopes.options).thenReturn(options) + tracer = SentryTracer(context, scopes) return PerformanceAndroidEventProcessor(options, activityFramesTracker) } } @@ -181,7 +181,7 @@ class PerformanceAndroidEventProcessorTest { fun `add slow and frozen frames if auto transaction`() { val sut = fixture.getSut() val context = TransactionContext("Activity", UI_LOAD_OP) - val tracer = SentryTracer(context, fixture.hub) + val tracer = SentryTracer(context, fixture.scopes) var tr = SentryTransaction(tracer) val metrics = mapOf( @@ -227,7 +227,7 @@ class PerformanceAndroidEventProcessorTest { // when an activity transaction is created val sut = fixture.getSut(enablePerformanceV2 = true) val context = TransactionContext("Activity", UI_LOAD_OP) - val tracer = SentryTracer(context, fixture.hub) + val tracer = SentryTracer(context, fixture.scopes) var tr = SentryTransaction(tracer) // and it contains an app.start.cold span @@ -297,7 +297,7 @@ class PerformanceAndroidEventProcessorTest { // when an activity transaction is created val sut = fixture.getSut(enablePerformanceV2 = true) val context = TransactionContext("Activity", UI_LOAD_OP) - val tracer = SentryTracer(context, fixture.hub) + val tracer = SentryTracer(context, fixture.scopes) var tr = SentryTransaction(tracer) // then the app start metrics should not be attached @@ -326,7 +326,7 @@ class PerformanceAndroidEventProcessorTest { // when the first activity transaction is created val sut = fixture.getSut(enablePerformanceV2 = true) val context = TransactionContext("Activity", UI_LOAD_OP) - val tracer = SentryTracer(context, fixture.hub) + val tracer = SentryTracer(context, fixture.scopes) var tr = SentryTransaction(tracer) val appStartSpan = SentrySpan( 0.0, @@ -377,7 +377,7 @@ class PerformanceAndroidEventProcessorTest { val sut = fixture.getSut(enablePerformanceV2 = true) val context = TransactionContext("Activity", UI_LOAD_OP) - val tracer = SentryTracer(context, fixture.hub) + val tracer = SentryTracer(context, fixture.scopes) var tr = SentryTransaction(tracer) val appStartSpan = SentrySpan( 0.0, @@ -424,7 +424,7 @@ class PerformanceAndroidEventProcessorTest { val sut = fixture.getSut(enablePerformanceV2 = true) val context = TransactionContext("Activity", UI_LOAD_OP) - val tracer = SentryTracer(context, fixture.hub) + val tracer = SentryTracer(context, fixture.scopes) var tr = SentryTransaction(tracer) val appStartSpan = SentrySpan( 0.0, diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/PhoneStateBreadcrumbsIntegrationTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/PhoneStateBreadcrumbsIntegrationTest.kt index 2b6ca801da..c764d11c2d 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/PhoneStateBreadcrumbsIntegrationTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/PhoneStateBreadcrumbsIntegrationTest.kt @@ -4,7 +4,7 @@ import android.content.Context import android.telephony.PhoneStateListener import android.telephony.TelephonyManager import io.sentry.Breadcrumb -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ISentryExecutorService import io.sentry.SentryLevel import io.sentry.test.DeferredExecutorService @@ -41,8 +41,8 @@ class PhoneStateBreadcrumbsIntegrationTest { @Test fun `When system events breadcrumb is enabled, it registers callback`() { val sut = fixture.getSut() - val hub = mock() - sut.register(hub, fixture.options) + val scopes = mock() + sut.register(scopes, fixture.options) verify(fixture.manager).listen(any(), eq(PhoneStateListener.LISTEN_CALL_STATE)) assertNotNull(sut.listener) } @@ -50,8 +50,8 @@ class PhoneStateBreadcrumbsIntegrationTest { @Test fun `Phone state callback is registered in the executorService`() { val sut = fixture.getSut(mock()) - val hub = mock() - sut.register(hub, fixture.options) + val scopes = mock() + sut.register(scopes, fixture.options) assertNull(sut.listener) } @@ -59,9 +59,9 @@ class PhoneStateBreadcrumbsIntegrationTest { @Test fun `When system events breadcrumb is disabled, it doesn't register callback`() { val sut = fixture.getSut() - val hub = mock() + val scopes = mock() sut.register( - hub, + scopes, fixture.options.apply { isEnableSystemEventBreadcrumbs = false } @@ -73,15 +73,15 @@ class PhoneStateBreadcrumbsIntegrationTest { @Test fun `When ActivityBreadcrumbsIntegration is closed, it should unregister the callback`() { val sut = fixture.getSut() - val hub = mock() - sut.register(hub, fixture.options) + val scopes = mock() + sut.register(scopes, fixture.options) sut.close() verify(fixture.manager).listen(any(), eq(PhoneStateListener.LISTEN_NONE)) assertNull(sut.listener) } @Test - fun `when hub is closed right after start, integration is not registered`() { + fun `when scopes is closed right after start, integration is not registered`() { val deferredExecutorService = DeferredExecutorService() val sut = fixture.getSut(executorService = deferredExecutorService) sut.register(mock(), fixture.options) @@ -94,11 +94,11 @@ class PhoneStateBreadcrumbsIntegrationTest { @Test fun `When on call state received, added breadcrumb with type and category`() { val sut = fixture.getSut() - val hub = mock() - sut.register(hub, fixture.options) + val scopes = mock() + sut.register(scopes, fixture.options) sut.listener!!.onCallStateChanged(TelephonyManager.CALL_STATE_RINGING, null) - verify(hub).addBreadcrumb( + verify(scopes).addBreadcrumb( check { assertEquals("device.event", it.category) assertEquals("system", it.type) @@ -111,18 +111,18 @@ class PhoneStateBreadcrumbsIntegrationTest { @Test fun `When on idle state received, added breadcrumb with type and category`() { val sut = fixture.getSut() - val hub = mock() - sut.register(hub, fixture.options) + val scopes = mock() + sut.register(scopes, fixture.options) sut.listener!!.onCallStateChanged(TelephonyManager.CALL_STATE_IDLE, null) - verify(hub, never()).addBreadcrumb(any()) + verify(scopes, never()).addBreadcrumb(any()) } @Test fun `When on offhook state received, added breadcrumb with type and category`() { val sut = fixture.getSut() - val hub = mock() - sut.register(hub, fixture.options) + val scopes = mock() + sut.register(scopes, fixture.options) sut.listener!!.onCallStateChanged(TelephonyManager.CALL_STATE_OFFHOOK, null) - verify(hub, never()).addBreadcrumb(any()) + verify(scopes, never()).addBreadcrumb(any()) } } diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/SendCachedEnvelopeIntegrationTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/SendCachedEnvelopeIntegrationTest.kt index 403f40ee70..f1e345eefc 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/SendCachedEnvelopeIntegrationTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/SendCachedEnvelopeIntegrationTest.kt @@ -2,8 +2,8 @@ package io.sentry.android.core import io.sentry.IConnectionStatusProvider import io.sentry.IConnectionStatusProvider.ConnectionStatus -import io.sentry.IHub import io.sentry.ILogger +import io.sentry.IScopes import io.sentry.ISentryExecutorService import io.sentry.SendCachedEnvelopeFireAndForgetIntegration.SendFireAndForget import io.sentry.SendCachedEnvelopeFireAndForgetIntegration.SendFireAndForgetFactory @@ -28,7 +28,7 @@ import kotlin.test.Test class SendCachedEnvelopeIntegrationTest { private class Fixture { - val hub: IHub = mock() + val scopes: IScopes = mock() val options = SentryAndroidOptions() val logger = mock() val factory = mock() @@ -74,7 +74,7 @@ class SendCachedEnvelopeIntegrationTest { fun `when cacheDirPath is not set, does nothing`() { val sut = fixture.getSut(cacheDirPath = null) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.factory, never()).create(any(), any()) } @@ -83,7 +83,7 @@ class SendCachedEnvelopeIntegrationTest { fun `when factory returns null, does nothing`() { val sut = fixture.getSut(hasSender = false, mockExecutorService = ImmediateExecutorService()) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.factory).create(any(), any()) verify(fixture.sender, never()).send() @@ -93,7 +93,7 @@ class SendCachedEnvelopeIntegrationTest { fun `when has factory and cacheDirPath set, submits task into queue`() { val sut = fixture.getSut(mockExecutorService = ImmediateExecutorService()) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) await.untilFalse(fixture.flag) verify(fixture.sender).send() @@ -102,7 +102,7 @@ class SendCachedEnvelopeIntegrationTest { @Test fun `when executorService is fake, does nothing`() { val sut = fixture.getSut(mockExecutorService = mock()) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.factory, never()).create(any(), any()) verify(fixture.sender, never()).send() @@ -112,7 +112,7 @@ class SendCachedEnvelopeIntegrationTest { fun `when has startup crash marker, awaits the task on the calling thread`() { val sut = fixture.getSut(hasStartupCrashMarker = true) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) // we do not need to await here, because it's executed synchronously verify(fixture.sender).send() @@ -123,7 +123,7 @@ class SendCachedEnvelopeIntegrationTest { val sut = fixture.getSut(hasStartupCrashMarker = true, delaySend = 1000) fixture.options.startupCrashFlushTimeoutMillis = 100 - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) // first wait until synchronous send times out and check that the logger was hit in the catch block await.atLeast(500, MILLISECONDS) @@ -144,7 +144,7 @@ class SendCachedEnvelopeIntegrationTest { val connectionStatusProvider = mock() fixture.options.connectionStatusProvider = connectionStatusProvider - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(connectionStatusProvider).addConnectionStatusObserver(any()) } @@ -159,7 +159,7 @@ class SendCachedEnvelopeIntegrationTest { ConnectionStatus.DISCONNECTED ) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.sender, never()).send() } @@ -174,7 +174,7 @@ class SendCachedEnvelopeIntegrationTest { ConnectionStatus.UNKNOWN ) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.factory).create(any(), any()) } @@ -187,7 +187,7 @@ class SendCachedEnvelopeIntegrationTest { whenever(connectionStatusProvider.connectionStatus).thenReturn( ConnectionStatus.DISCONNECTED ) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) // when there's no connection no factory create call should be done verify(fixture.sender, never()).send() @@ -215,9 +215,9 @@ class SendCachedEnvelopeIntegrationTest { val rateLimiter = mock { whenever(mock.isActiveForCategory(any())).thenReturn(true) } - whenever(fixture.hub.rateLimiter).thenReturn(rateLimiter) + whenever(fixture.scopes.rateLimiter).thenReturn(rateLimiter) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) // no factory call should be done if there's rate limiting active verify(fixture.sender, never()).send() @@ -228,7 +228,7 @@ class SendCachedEnvelopeIntegrationTest { val deferredExecutorService = DeferredExecutorService() val sut = fixture.getSut(mockExecutorService = deferredExecutorService) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.sender, never()).send() sut.close() diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/SystemEventsBreadcrumbsIntegrationTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/SystemEventsBreadcrumbsIntegrationTest.kt index f8293f9b87..146abb617e 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/SystemEventsBreadcrumbsIntegrationTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/SystemEventsBreadcrumbsIntegrationTest.kt @@ -3,7 +3,7 @@ package io.sentry.android.core import android.content.Context import android.content.Intent import io.sentry.Breadcrumb -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ISentryExecutorService import io.sentry.SentryLevel import io.sentry.test.DeferredExecutorService @@ -26,7 +26,7 @@ class SystemEventsBreadcrumbsIntegrationTest { private class Fixture { val context = mock() var options = SentryAndroidOptions() - val hub = mock() + val scopes = mock() fun getSut(enableSystemEventBreadcrumbs: Boolean = true, executorService: ISentryExecutorService = ImmediateExecutorService()): SystemEventsBreadcrumbsIntegration { options = SentryAndroidOptions().apply { @@ -43,7 +43,7 @@ class SystemEventsBreadcrumbsIntegrationTest { fun `When system events breadcrumb is enabled, it registers callback`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.context).registerReceiver(any(), any()) assertNotNull(sut.receiver) @@ -52,8 +52,8 @@ class SystemEventsBreadcrumbsIntegrationTest { @Test fun `system events callback is registered in the executorService`() { val sut = fixture.getSut(executorService = mock()) - val hub = mock() - sut.register(hub, fixture.options) + val scopes = mock() + sut.register(scopes, fixture.options) assertNull(sut.receiver) } @@ -62,7 +62,7 @@ class SystemEventsBreadcrumbsIntegrationTest { fun `When system events breadcrumb is disabled, it doesn't register callback`() { val sut = fixture.getSut(enableSystemEventBreadcrumbs = false) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.context, never()).registerReceiver(any(), any()) assertNull(sut.receiver) @@ -72,7 +72,7 @@ class SystemEventsBreadcrumbsIntegrationTest { fun `When ActivityBreadcrumbsIntegration is closed, it should unregister the callback`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) sut.close() verify(fixture.context).unregisterReceiver(any()) @@ -80,10 +80,10 @@ class SystemEventsBreadcrumbsIntegrationTest { } @Test - fun `when hub is closed right after start, integration is not registered`() { + fun `when scopes is closed right after start, integration is not registered`() { val deferredExecutorService = DeferredExecutorService() val sut = fixture.getSut(executorService = deferredExecutorService) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertNull(sut.receiver) sut.close() deferredExecutorService.runAll() @@ -94,13 +94,13 @@ class SystemEventsBreadcrumbsIntegrationTest { fun `When broadcast received, added breadcrumb with type and category`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val intent = Intent().apply { action = Intent.ACTION_TIME_CHANGED } sut.receiver!!.onReceive(fixture.context, intent) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("device.event", it.category) assertEquals("system", it.type) @@ -116,7 +116,7 @@ class SystemEventsBreadcrumbsIntegrationTest { val sut = fixture.getSut() whenever(fixture.context.registerReceiver(any(), any())).thenThrow(SecurityException()) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertFalse(fixture.options.isEnableSystemEventBreadcrumbs) } diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/TempSensorBreadcrumbsIntegrationTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/TempSensorBreadcrumbsIntegrationTest.kt index d443b1e345..5d049e3dad 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/TempSensorBreadcrumbsIntegrationTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/TempSensorBreadcrumbsIntegrationTest.kt @@ -7,7 +7,7 @@ import android.hardware.SensorEventListener import android.hardware.SensorManager import io.sentry.Breadcrumb import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ISentryExecutorService import io.sentry.SentryLevel import io.sentry.TypeCheckHint @@ -47,8 +47,8 @@ class TempSensorBreadcrumbsIntegrationTest { @Test fun `When system events breadcrumb is enabled, it registers callback`() { val sut = fixture.getSut() - val hub = mock() - sut.register(hub, fixture.options) + val scopes = mock() + sut.register(scopes, fixture.options) verify(fixture.manager).registerListener(any(), any(), eq(SensorManager.SENSOR_DELAY_NORMAL)) assertNotNull(sut.sensorManager) } @@ -56,8 +56,8 @@ class TempSensorBreadcrumbsIntegrationTest { @Test fun `temp sensor listener is registered in the executorService`() { val sut = fixture.getSut(executorService = mock()) - val hub = mock() - sut.register(hub, fixture.options) + val scopes = mock() + sut.register(scopes, fixture.options) assertNull(sut.sensorManager) } @@ -65,9 +65,9 @@ class TempSensorBreadcrumbsIntegrationTest { @Test fun `When system events breadcrumb is disabled, it should not register a callback`() { val sut = fixture.getSut() - val hub = mock() + val scopes = mock() sut.register( - hub, + scopes, fixture.options.apply { isEnableSystemEventBreadcrumbs = false } @@ -79,15 +79,15 @@ class TempSensorBreadcrumbsIntegrationTest { @Test fun `When TempSensorBreadcrumbsIntegration is closed, it should unregister the callback`() { val sut = fixture.getSut() - val hub = mock() - sut.register(hub, fixture.options) + val scopes = mock() + sut.register(scopes, fixture.options) sut.close() verify(fixture.manager).unregisterListener(any()) assertNull(sut.sensorManager) } @Test - fun `when hub is closed right after start, integration is not registered`() { + fun `when scopes is closed right after start, integration is not registered`() { val deferredExecutorService = DeferredExecutorService() val sut = fixture.getSut(executorService = deferredExecutorService) sut.register(mock(), fixture.options) @@ -100,14 +100,14 @@ class TempSensorBreadcrumbsIntegrationTest { @Test fun `When onSensorChanged received, add a breadcrumb with type and category`() { val sut = fixture.getSut() - val hub = mock() - sut.register(hub, fixture.options) + val scopes = mock() + sut.register(scopes, fixture.options) val sensorCtor = "android.hardware.SensorEvent".getDeclaredCtor(emptyArray()) val sensorEvent: SensorEvent = sensorCtor.newInstance() as SensorEvent sensorEvent.injectForField("values", FloatArray(2) { 1F }) sut.onSensorChanged(sensorEvent) - verify(hub).addBreadcrumb( + verify(scopes).addBreadcrumb( check { assertEquals("device.event", it.category) assertEquals("system", it.type) @@ -122,12 +122,12 @@ class TempSensorBreadcrumbsIntegrationTest { @Test fun `When onSensorChanged received and null values, do not add a breadcrumb`() { val sut = fixture.getSut() - val hub = mock() - sut.register(hub, fixture.options) + val scopes = mock() + sut.register(scopes, fixture.options) val event = mock() assertNull(event.values) sut.onSensorChanged(event) - verify(hub, never()).addBreadcrumb(any()) + verify(scopes, never()).addBreadcrumb(any()) } } diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/SentryGestureListenerClickTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/SentryGestureListenerClickTest.kt index 1e6652276a..74edfb4302 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/SentryGestureListenerClickTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/SentryGestureListenerClickTest.kt @@ -10,8 +10,8 @@ import android.view.Window import android.widget.CheckBox import android.widget.RadioButton import io.sentry.Breadcrumb -import io.sentry.IHub import io.sentry.IScope +import io.sentry.IScopes import io.sentry.PropagationContext import io.sentry.Scope.IWithPropagationContext import io.sentry.ScopeCallback @@ -40,7 +40,7 @@ class SentryGestureListenerClickTest { gestureTargetLocators = listOf(AndroidViewGestureTargetLocator(true)) dsn = "https://key@sentry.io/proj" } - val hub = mock() + val scopes = mock() val scope = mock() val propagationContext = PropagationContext() lateinit var target: View @@ -86,11 +86,11 @@ class SentryGestureListenerClickTest { whenever(context.resources).thenReturn(resources) whenever(this.target.context).thenReturn(context) whenever(activity.window).thenReturn(window) - doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(hub).configureScope(any()) + doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(scopes).configureScope(any()) doAnswer { (it.arguments[0] as IWithPropagationContext).accept(propagationContext); propagationContext; }.whenever(scope).withPropagationContext(any()) return SentryGestureListener( activity, - hub, + scopes, options ) } @@ -123,7 +123,7 @@ class SentryGestureListenerClickTest { sut.onSingleTapUp(event) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("ui.click", it.category) assertEquals("user", it.type) @@ -146,7 +146,7 @@ class SentryGestureListenerClickTest { sut.onSingleTapUp(event) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("radio_button", it.data["view.id"]) assertEquals("android.widget.RadioButton", it.data["view.class"]) @@ -166,7 +166,7 @@ class SentryGestureListenerClickTest { sut.onSingleTapUp(event) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("check_box", it.data["view.id"]) assertEquals("android.widget.CheckBox", it.data["view.class"]) @@ -185,7 +185,7 @@ class SentryGestureListenerClickTest { sut.onSingleTapUp(event) - verify(fixture.hub, never()).addBreadcrumb(any()) + verify(fixture.scopes, never()).addBreadcrumb(any()) } @Test @@ -198,7 +198,7 @@ class SentryGestureListenerClickTest { val sut = fixture.getSut(event, "decor_view", targetOverride = decorView) sut.onSingleTapUp(event) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals(decorView.javaClass.canonicalName, it.data["view.class"]) assertEquals("decor_view", it.data["view.id"]) @@ -214,7 +214,7 @@ class SentryGestureListenerClickTest { sut.onSingleTapUp(event) - verify(fixture.hub, never()).addBreadcrumb(any()) + verify(fixture.scopes, never()).addBreadcrumb(any()) } @Test @@ -230,7 +230,7 @@ class SentryGestureListenerClickTest { sut.onSingleTapUp(event) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals(fixture.target.javaClass.simpleName, it.data["view.class"]) }, diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/SentryGestureListenerScrollTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/SentryGestureListenerScrollTest.kt index 5d39b64753..e5a9623c4d 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/SentryGestureListenerScrollTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/SentryGestureListenerScrollTest.kt @@ -11,8 +11,8 @@ import android.widget.AbsListView import android.widget.ListAdapter import androidx.core.view.ScrollingView import io.sentry.Breadcrumb -import io.sentry.IHub import io.sentry.IScope +import io.sentry.IScopes import io.sentry.PropagationContext import io.sentry.Scope import io.sentry.ScopeCallback @@ -44,7 +44,7 @@ class SentryGestureListenerScrollTest { isEnableUserInteractionTracing = true gestureTargetLocators = listOf(AndroidViewGestureTargetLocator(true)) } - val hub = mock() + val scopes = mock() val scope = mock() val propagationContext = PropagationContext() @@ -77,11 +77,11 @@ class SentryGestureListenerScrollTest { endEvent.mockDirection(firstEvent, direction) } whenever(activity.window).thenReturn(window) - doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(hub).configureScope(any()) + doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(scopes).configureScope(any()) doAnswer { (it.arguments[0] as Scope.IWithPropagationContext).accept(propagationContext); propagationContext }.whenever(scope).withPropagationContext(any()) return SentryGestureListener( activity, - hub, + scopes, options ) } @@ -99,7 +99,7 @@ class SentryGestureListenerScrollTest { } sut.onUp(fixture.endEvent) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("ui.scroll", it.category) assertEquals("user", it.type) @@ -122,7 +122,7 @@ class SentryGestureListenerScrollTest { } sut.onUp(fixture.endEvent) - verify(fixture.hub, never()).addBreadcrumb(any()) + verify(fixture.scopes, never()).addBreadcrumb(any()) } @Test @@ -143,8 +143,8 @@ class SentryGestureListenerScrollTest { sut.onFling(fixture.firstEvent, fixture.endEvent, 1.0f, 1.0f) sut.onUp(fixture.endEvent) - inOrder(fixture.hub) { - verify(fixture.hub).addBreadcrumb( + inOrder(fixture.scopes) { + verify(fixture.scopes).addBreadcrumb( check { assertEquals("ui.swipe", it.category) assertEquals("user", it.type) @@ -155,8 +155,8 @@ class SentryGestureListenerScrollTest { }, anyOrNull() ) - verify(fixture.hub).configureScope(anyOrNull()) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).configureScope(anyOrNull()) + verify(fixture.scopes).addBreadcrumb( check { assertEquals("ui.swipe", it.category) assertEquals("user", it.type) @@ -168,7 +168,7 @@ class SentryGestureListenerScrollTest { anyOrNull() ) } - verifyNoMoreInteractions(fixture.hub) + verifyNoMoreInteractions(fixture.scopes) } @Test @@ -177,7 +177,7 @@ class SentryGestureListenerScrollTest { sut.onUp(fixture.firstEvent) sut.onDown(fixture.endEvent) - verify(fixture.hub, never()).addBreadcrumb(any()) + verify(fixture.scopes, never()).addBreadcrumb(any()) } @Test @@ -190,7 +190,7 @@ class SentryGestureListenerScrollTest { } sut.onUp(fixture.endEvent) - verify(fixture.hub, never()).addBreadcrumb(any()) + verify(fixture.scopes, never()).addBreadcrumb(any()) } @Test diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/SentryGestureListenerTracingTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/SentryGestureListenerTracingTest.kt index c7ada69c88..d3f6647c2a 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/SentryGestureListenerTracingTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/SentryGestureListenerTracingTest.kt @@ -9,8 +9,8 @@ import android.view.ViewGroup import android.view.Window import android.widget.AbsListView import android.widget.ListAdapter -import io.sentry.IHub import io.sentry.IScope +import io.sentry.IScopes import io.sentry.Scope import io.sentry.ScopeCallback import io.sentry.SentryTracer @@ -46,7 +46,7 @@ class SentryGestureListenerTracingTest { val options = SentryAndroidOptions().apply { dsn = "https://key@sentry.io/proj" } - val hub = mock() + val scopes = mock() val event = mock() val scope = mock() lateinit var target: View @@ -64,9 +64,9 @@ class SentryGestureListenerTracingTest { options.isEnableUserInteractionBreadcrumbs = true options.gestureTargetLocators = listOf(AndroidViewGestureTargetLocator(true)) - whenever(hub.options).thenReturn(options) + whenever(scopes.options).thenReturn(options) - this.transaction = transaction ?: SentryTracer(TransactionContext("name", "op"), hub) + this.transaction = transaction ?: SentryTracer(TransactionContext("name", "op"), scopes) target = mockView(event = event, clickable = true, context = context) window.mockDecorView(event = event, context = context) { @@ -86,13 +86,13 @@ class SentryGestureListenerTracingTest { whenever(activity.window).thenReturn(window) - whenever(hub.startTransaction(any(), any())) + whenever(scopes.startTransaction(any(), any())) .thenReturn(this.transaction) - doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(hub).configureScope(any()) + doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(scopes).configureScope(any()) return SentryGestureListener( activity, - hub, + scopes, options ) } @@ -106,7 +106,7 @@ class SentryGestureListenerTracingTest { sut.onSingleTapUp(fixture.event) - verify(fixture.hub, never()).startTransaction( + verify(fixture.scopes, never()).startTransaction( any(), any() ) @@ -118,7 +118,7 @@ class SentryGestureListenerTracingTest { sut.onSingleTapUp(fixture.event) - verify(fixture.hub, never()).startTransaction( + verify(fixture.scopes, never()).startTransaction( any(), any() ) @@ -130,7 +130,7 @@ class SentryGestureListenerTracingTest { sut.onSingleTapUp(fixture.event) - verify(fixture.hub, never()).startTransaction( + verify(fixture.scopes, never()).startTransaction( any(), any() ) @@ -140,7 +140,7 @@ class SentryGestureListenerTracingTest { fun `when transaction is created, set transaction to the bound Scope`() { val sut = fixture.getSut() - whenever(fixture.hub.configureScope(any())).thenAnswer { + whenever(fixture.scopes.configureScope(any())).thenAnswer { val scope = Scope(fixture.options) sut.applyScope(scope, fixture.transaction) @@ -155,9 +155,9 @@ class SentryGestureListenerTracingTest { fun `when transaction is created, do not overwrite transaction already bound to the Scope`() { val sut = fixture.getSut() - whenever(fixture.hub.configureScope(any())).thenAnswer { + whenever(fixture.scopes.configureScope(any())).thenAnswer { val scope = Scope(fixture.options) - val previousTransaction = SentryTracer(TransactionContext("name", "op"), fixture.hub) + val previousTransaction = SentryTracer(TransactionContext("name", "op"), fixture.scopes) scope.transaction = previousTransaction sut.applyScope(scope, fixture.transaction) @@ -173,14 +173,14 @@ class SentryGestureListenerTracingTest { val sut = fixture.getSut() val expectedStatus = SpanStatus.CANCELLED - whenever(fixture.hub.configureScope(any())).thenAnswer { + whenever(fixture.scopes.configureScope(any())).thenAnswer { val scope = Scope(fixture.options) sut.applyScope(scope, fixture.transaction) } sut.onSingleTapUp(fixture.event) - whenever(fixture.hub.configureScope(any())).thenAnswer { + whenever(fixture.scopes.configureScope(any())).thenAnswer { val scope = Scope(fixture.options) scope.transaction = fixture.transaction @@ -199,7 +199,7 @@ class SentryGestureListenerTracingTest { sut.onSingleTapUp(fixture.event) - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( check { assertEquals("Activity.test_button", it.name) assertEquals(TransactionNameSource.COMPONENT, it.transactionNameSource) @@ -214,7 +214,7 @@ class SentryGestureListenerTracingTest { sut.onSingleTapUp(fixture.event) - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( any(), check { transactionOptions -> assertEquals(fixture.options.idleTimeout, transactionOptions.idleTimeout) @@ -232,7 +232,7 @@ class SentryGestureListenerTracingTest { sut.onSingleTapUp(fixture.event) - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( check { assertEquals("ui.action.click", it.operation) assertEquals(TransactionNameSource.COMPONENT, it.transactionNameSource) @@ -248,7 +248,7 @@ class SentryGestureListenerTracingTest { sut.onSingleTapUp(fixture.event) - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( check { assertEquals("Activity.test_button", it.name) assertEquals(TransactionNameSource.COMPONENT, it.transactionNameSource) @@ -256,7 +256,7 @@ class SentryGestureListenerTracingTest { any() ) - clearInvocations(fixture.hub) + clearInvocations(fixture.scopes) // second view interaction with another view val newTarget = mockView(event = fixture.event, clickable = true, context = fixture.context) val newContext = mock() @@ -269,16 +269,16 @@ class SentryGestureListenerTracingTest { whenever(it.getChildAt(0)).thenReturn(newTarget) } - whenever(fixture.hub.startTransaction(any(), any())) + whenever(fixture.scopes.startTransaction(any(), any())) .thenAnswer { // verify that the active transaction gets finished when a new one appears assertEquals(true, fixture.transaction.isFinished) - SentryTracer(TransactionContext("name", "op"), fixture.hub) + SentryTracer(TransactionContext("name", "op"), fixture.scopes) } sut.onSingleTapUp(fixture.event) - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( check { assertEquals("Activity.test_checkbox", it.name) assertEquals(TransactionNameSource.COMPONENT, it.transactionNameSource) @@ -293,7 +293,7 @@ class SentryGestureListenerTracingTest { sut.onSingleTapUp(fixture.event) - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( check { assertEquals("Activity.test_scroll_view", it.name) assertEquals("ui.action.click", it.operation) @@ -302,20 +302,20 @@ class SentryGestureListenerTracingTest { any() ) - clearInvocations(fixture.hub) + clearInvocations(fixture.scopes) // second view interaction with a different interaction type (scroll) - whenever(fixture.hub.startTransaction(any(), any())) + whenever(fixture.scopes.startTransaction(any(), any())) .thenAnswer { // verify that the active transaction gets finished when a new one appears assertEquals(true, fixture.transaction.isFinished) - SentryTracer(TransactionContext("name", "op"), fixture.hub) + SentryTracer(TransactionContext("name", "op"), fixture.scopes) } sut.onScroll(fixture.event, mock(), 10.0f, 0f) sut.onUp(mock()) - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( check { assertEquals("Activity.test_scroll_view", it.name) assertEquals("ui.action.scroll", it.operation) @@ -340,7 +340,7 @@ class SentryGestureListenerTracingTest { sut.onSingleTapUp(fixture.event) // then two transaction should be captured - verify(fixture.hub, times(2)).startTransaction( + verify(fixture.scopes, times(2)).startTransaction( check { assertEquals("Activity.test_button", it.name) assertEquals(TransactionNameSource.COMPONENT, it.transactionNameSource) diff --git a/sentry-android-fragment/api/sentry-android-fragment.api b/sentry-android-fragment/api/sentry-android-fragment.api index 4b3487c36e..f2f3334280 100644 --- a/sentry-android-fragment/api/sentry-android-fragment.api +++ b/sentry-android-fragment/api/sentry-android-fragment.api @@ -18,7 +18,7 @@ public final class io/sentry/android/fragment/FragmentLifecycleIntegration : and public fun onActivitySaveInstanceState (Landroid/app/Activity;Landroid/os/Bundle;)V public fun onActivityStarted (Landroid/app/Activity;)V public fun onActivityStopped (Landroid/app/Activity;)V - public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/android/fragment/FragmentLifecycleState : java/lang/Enum { @@ -40,9 +40,9 @@ public final class io/sentry/android/fragment/FragmentLifecycleState : java/lang public final class io/sentry/android/fragment/SentryFragmentLifecycleCallbacks : androidx/fragment/app/FragmentManager$FragmentLifecycleCallbacks { public static final field Companion Lio/sentry/android/fragment/SentryFragmentLifecycleCallbacks$Companion; public static final field FRAGMENT_LOAD_OP Ljava/lang/String; - public fun (Lio/sentry/IHub;Ljava/util/Set;Z)V - public synthetic fun (Lio/sentry/IHub;Ljava/util/Set;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V - public fun (Lio/sentry/IHub;ZZ)V + public fun (Lio/sentry/IScopes;Ljava/util/Set;Z)V + public synthetic fun (Lio/sentry/IScopes;Ljava/util/Set;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lio/sentry/IScopes;ZZ)V public fun (ZZ)V public synthetic fun (ZZILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun getEnableAutoFragmentLifecycleTracing ()Z diff --git a/sentry-android-fragment/src/main/java/io/sentry/android/fragment/FragmentLifecycleIntegration.kt b/sentry-android-fragment/src/main/java/io/sentry/android/fragment/FragmentLifecycleIntegration.kt index 4129ea4356..d2fd393200 100644 --- a/sentry-android-fragment/src/main/java/io/sentry/android/fragment/FragmentLifecycleIntegration.kt +++ b/sentry-android-fragment/src/main/java/io/sentry/android/fragment/FragmentLifecycleIntegration.kt @@ -5,7 +5,7 @@ import android.app.Application import android.app.Application.ActivityLifecycleCallbacks import android.os.Bundle import androidx.fragment.app.FragmentActivity -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.Integration import io.sentry.SentryIntegrationPackageStorage import io.sentry.SentryLevel.DEBUG @@ -40,11 +40,11 @@ class FragmentLifecycleIntegration( enableAutoFragmentLifecycleTracing = enableAutoFragmentLifecycleTracing ) - private lateinit var hub: IHub + private lateinit var scopes: IScopes private lateinit var options: SentryOptions - override fun register(hub: IHub, options: SentryOptions) { - this.hub = hub + override fun register(scopes: IScopes, options: SentryOptions) { + this.scopes = scopes this.options = options application.registerActivityLifecycleCallbacks(this) @@ -66,7 +66,7 @@ class FragmentLifecycleIntegration( ?.supportFragmentManager ?.registerFragmentLifecycleCallbacks( SentryFragmentLifecycleCallbacks( - hub = hub, + scopes = scopes, filterFragmentLifecycleBreadcrumbs = filterFragmentLifecycleBreadcrumbs, enableAutoFragmentLifecycleTracing = enableAutoFragmentLifecycleTracing ), diff --git a/sentry-android-fragment/src/main/java/io/sentry/android/fragment/SentryFragmentLifecycleCallbacks.kt b/sentry-android-fragment/src/main/java/io/sentry/android/fragment/SentryFragmentLifecycleCallbacks.kt index 78f45474e2..64ecb21d41 100644 --- a/sentry-android-fragment/src/main/java/io/sentry/android/fragment/SentryFragmentLifecycleCallbacks.kt +++ b/sentry-android-fragment/src/main/java/io/sentry/android/fragment/SentryFragmentLifecycleCallbacks.kt @@ -8,9 +8,9 @@ import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager.FragmentLifecycleCallbacks import io.sentry.Breadcrumb import io.sentry.Hint -import io.sentry.HubAdapter -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ISpan +import io.sentry.ScopesAdapter import io.sentry.SentryLevel.INFO import io.sentry.SpanStatus import io.sentry.TypeCheckHint.ANDROID_FRAGMENT @@ -20,17 +20,17 @@ private const val TRACE_ORIGIN = "auto.ui.fragment" @Suppress("TooManyFunctions") class SentryFragmentLifecycleCallbacks( - private val hub: IHub = HubAdapter.getInstance(), + private val scopes: IScopes = ScopesAdapter.getInstance(), val filterFragmentLifecycleBreadcrumbs: Set, val enableAutoFragmentLifecycleTracing: Boolean ) : FragmentLifecycleCallbacks() { constructor( - hub: IHub, + scopes: IScopes, enableFragmentLifecycleBreadcrumbs: Boolean, enableAutoFragmentLifecycleTracing: Boolean ) : this( - hub = hub, + scopes = scopes, filterFragmentLifecycleBreadcrumbs = FragmentLifecycleState.values().toSet() .takeIf { enableFragmentLifecycleBreadcrumbs } .orEmpty(), @@ -41,14 +41,14 @@ class SentryFragmentLifecycleCallbacks( enableFragmentLifecycleBreadcrumbs: Boolean = true, enableAutoFragmentLifecycleTracing: Boolean = false ) : this( - hub = HubAdapter.getInstance(), + scopes = ScopesAdapter.getInstance(), filterFragmentLifecycleBreadcrumbs = FragmentLifecycleState.values().toSet() .takeIf { enableFragmentLifecycleBreadcrumbs } .orEmpty(), enableAutoFragmentLifecycleTracing = enableAutoFragmentLifecycleTracing ) - private val isPerformanceEnabled get() = hub.options.isTracingEnabled && enableAutoFragmentLifecycleTracing + private val isPerformanceEnabled get() = scopes.options.isTracingEnabled && enableAutoFragmentLifecycleTracing private val fragmentsWithOngoingTransactions = WeakHashMap() @@ -141,7 +141,7 @@ class SentryFragmentLifecycleCallbacks( val hint = Hint() .also { it.set(ANDROID_FRAGMENT, fragment) } - hub.addBreadcrumb(breadcrumb, hint) + scopes.addBreadcrumb(breadcrumb, hint) } private fun getFragmentName(fragment: Fragment): String { @@ -157,7 +157,7 @@ class SentryFragmentLifecycleCallbacks( } var transaction: ISpan? = null - hub.configureScope { + scopes.configureScope { transaction = it.transaction } diff --git a/sentry-android-fragment/src/test/java/io/sentry/android/fragment/FragmentLifecycleIntegrationTest.kt b/sentry-android-fragment/src/test/java/io/sentry/android/fragment/FragmentLifecycleIntegrationTest.kt index 032aef58e1..84286503b9 100644 --- a/sentry-android-fragment/src/test/java/io/sentry/android/fragment/FragmentLifecycleIntegrationTest.kt +++ b/sentry-android-fragment/src/test/java/io/sentry/android/fragment/FragmentLifecycleIntegrationTest.kt @@ -4,7 +4,7 @@ import android.app.Activity import android.app.Application import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentManager -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryOptions import org.mockito.kotlin.check import org.mockito.kotlin.doReturn @@ -24,14 +24,14 @@ class FragmentLifecycleIntegrationTest { val fragmentActivity = mock { on { supportFragmentManager } doReturn fragmentManager } - val hub = mock() + val scopes = mock() val options = SentryOptions() fun getSut( enableFragmentLifecycleBreadcrumbs: Boolean = true, enableAutoFragmentLifecycleTracing: Boolean = false ): FragmentLifecycleIntegration { - whenever(hub.options).thenReturn(options) + whenever(scopes.options).thenReturn(options) return FragmentLifecycleIntegration( application = application, enableFragmentLifecycleBreadcrumbs = enableFragmentLifecycleBreadcrumbs, @@ -46,7 +46,7 @@ class FragmentLifecycleIntegrationTest { fun `When register, it should register activity lifecycle callbacks`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.application).registerActivityLifecycleCallbacks(sut) } @@ -55,7 +55,7 @@ class FragmentLifecycleIntegrationTest { fun `When close, it should unregister lifecycle callbacks`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) sut.close() verify(fixture.application).unregisterActivityLifecycleCallbacks(sut) @@ -69,7 +69,7 @@ class FragmentLifecycleIntegrationTest { on { supportFragmentManager } doReturn fragmentManager } - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) sut.onActivityCreated(fragmentActivity, savedInstanceState = null) verify(fragmentManager).registerFragmentLifecycleCallbacks( @@ -84,7 +84,7 @@ class FragmentLifecycleIntegrationTest { fun `When FragmentActivity is created, it should register fragment lifecycle callbacks with passed config`() { val sut = fixture.getSut(enableFragmentLifecycleBreadcrumbs = false, enableAutoFragmentLifecycleTracing = true) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) sut.onActivityCreated(fixture.fragmentActivity, savedInstanceState = null) verify(fixture.fragmentManager).registerFragmentLifecycleCallbacks( @@ -102,7 +102,7 @@ class FragmentLifecycleIntegrationTest { val sut = fixture.getSut() val activity = mock() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) sut.onActivityCreated(activity, savedInstanceState = null) } diff --git a/sentry-android-fragment/src/test/java/io/sentry/android/fragment/SentryFragmentLifecycleCallbacksTest.kt b/sentry-android-fragment/src/test/java/io/sentry/android/fragment/SentryFragmentLifecycleCallbacksTest.kt index 9b7fd5c5f2..26cb5b211a 100644 --- a/sentry-android-fragment/src/test/java/io/sentry/android/fragment/SentryFragmentLifecycleCallbacksTest.kt +++ b/sentry-android-fragment/src/test/java/io/sentry/android/fragment/SentryFragmentLifecycleCallbacksTest.kt @@ -5,8 +5,8 @@ import android.os.Bundle import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager import io.sentry.Breadcrumb -import io.sentry.Hub import io.sentry.IScope +import io.sentry.IScopes import io.sentry.ISpan import io.sentry.ITransaction import io.sentry.ScopeCallback @@ -32,7 +32,7 @@ class SentryFragmentLifecycleCallbacksTest { private class Fixture { val fragmentManager = mock() - val hub = mock() + val scopes = mock() val fragment = mock() val context = mock() val scope = mock() @@ -45,7 +45,7 @@ class SentryFragmentLifecycleCallbacksTest { tracesSampleRate: Double? = 1.0, isAdded: Boolean = true ): SentryFragmentLifecycleCallbacks { - whenever(hub.options).thenReturn( + whenever(scopes.options).thenReturn( SentryOptions().apply { setTracesSampleRate(tracesSampleRate) } @@ -55,12 +55,12 @@ class SentryFragmentLifecycleCallbacksTest { ) whenever(transaction.startChild(any(), any())).thenReturn(span) whenever(scope.transaction).thenReturn(transaction) - whenever(hub.configureScope(any())).thenAnswer { + whenever(scopes.configureScope(any())).thenAnswer { (it.arguments[0] as ScopeCallback).run(scope) } whenever(fragment.isAdded).thenReturn(isAdded) return SentryFragmentLifecycleCallbacks( - hub = hub, + scopes = scopes, filterFragmentLifecycleBreadcrumbs = loggedFragmentLifecycleStates, enableAutoFragmentLifecycleTracing = enableAutoFragmentLifecycleTracing ) @@ -272,7 +272,7 @@ class SentryFragmentLifecycleCallbacksTest { } private fun verifyBreadcrumbAdded(expectedState: String) { - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { breadcrumb: Breadcrumb -> assertEquals("ui.fragment.lifecycle", breadcrumb.category) assertEquals("navigation", breadcrumb.type) @@ -285,6 +285,6 @@ class SentryFragmentLifecycleCallbacksTest { } private fun verifyBreadcrumbAddedCount(count: Int) { - verify(fixture.hub, times(count)).addBreadcrumb(any(), anyOrNull()) + verify(fixture.scopes, times(count)).addBreadcrumb(any(), anyOrNull()) } } diff --git a/sentry-android-integration-tests/sentry-uitest-android/src/androidTest/java/io/sentry/uitest/android/mockservers/RelayAsserter.kt b/sentry-android-integration-tests/sentry-uitest-android/src/androidTest/java/io/sentry/uitest/android/mockservers/RelayAsserter.kt index e956978086..f685e84874 100644 --- a/sentry-android-integration-tests/sentry-uitest-android/src/androidTest/java/io/sentry/uitest/android/mockservers/RelayAsserter.kt +++ b/sentry-android-integration-tests/sentry-uitest-android/src/androidTest/java/io/sentry/uitest/android/mockservers/RelayAsserter.kt @@ -93,7 +93,7 @@ class RelayAsserter( /** Request parsed as envelope. */ val envelope: SentryEnvelope? by lazy { try { - EnvelopeReader(Sentry.getCurrentHub().options.serializer) + EnvelopeReader(Sentry.getCurrentScopes().options.serializer) .read(GZIPInputStream(request.body.inputStream())) } catch (e: IOException) { null diff --git a/sentry-android-navigation/api/sentry-android-navigation.api b/sentry-android-navigation/api/sentry-android-navigation.api index 79151bb3fb..03a46d8b87 100644 --- a/sentry-android-navigation/api/sentry-android-navigation.api +++ b/sentry-android-navigation/api/sentry-android-navigation.api @@ -10,11 +10,11 @@ public final class io/sentry/android/navigation/SentryNavigationListener : andro public static final field Companion Lio/sentry/android/navigation/SentryNavigationListener$Companion; public static final field NAVIGATION_OP Ljava/lang/String; public fun ()V - public fun (Lio/sentry/IHub;)V - public fun (Lio/sentry/IHub;Z)V - public fun (Lio/sentry/IHub;ZZ)V - public fun (Lio/sentry/IHub;ZZLjava/lang/String;)V - public synthetic fun (Lio/sentry/IHub;ZZLjava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lio/sentry/IScopes;)V + public fun (Lio/sentry/IScopes;Z)V + public fun (Lio/sentry/IScopes;ZZ)V + public fun (Lio/sentry/IScopes;ZZLjava/lang/String;)V + public synthetic fun (Lio/sentry/IScopes;ZZLjava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun onDestinationChanged (Landroidx/navigation/NavController;Landroidx/navigation/NavDestination;Landroid/os/Bundle;)V } diff --git a/sentry-android-navigation/src/main/java/io/sentry/android/navigation/SentryNavigationListener.kt b/sentry-android-navigation/src/main/java/io/sentry/android/navigation/SentryNavigationListener.kt index 8fdf8b0df8..bb06d66b3c 100644 --- a/sentry-android-navigation/src/main/java/io/sentry/android/navigation/SentryNavigationListener.kt +++ b/sentry-android-navigation/src/main/java/io/sentry/android/navigation/SentryNavigationListener.kt @@ -6,9 +6,9 @@ import androidx.navigation.NavController import androidx.navigation.NavDestination import io.sentry.Breadcrumb import io.sentry.Hint -import io.sentry.HubAdapter -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ITransaction +import io.sentry.ScopesAdapter import io.sentry.SentryIntegrationPackageStorage import io.sentry.SentryLevel.DEBUG import io.sentry.SentryLevel.INFO @@ -34,7 +34,7 @@ private const val TRACE_ORIGIN = "auto.navigation" * with [SentryOptions.idleTimeout] for navigation events. */ class SentryNavigationListener @JvmOverloads constructor( - private val hub: IHub = HubAdapter.getInstance(), + private val scopes: IScopes = ScopesAdapter.getInstance(), private val enableNavigationBreadcrumbs: Boolean = true, private val enableNavigationTracing: Boolean = true, private val traceOriginAppendix: String? = null @@ -43,7 +43,7 @@ class SentryNavigationListener @JvmOverloads constructor( private var previousDestinationRef: WeakReference? = null private var previousArgs: Bundle? = null - private val isPerformanceEnabled get() = hub.options.isTracingEnabled && enableNavigationTracing + private val isPerformanceEnabled get() = scopes.options.isTracingEnabled && enableNavigationTracing private var activeTransaction: ITransaction? = null @@ -91,7 +91,7 @@ class SentryNavigationListener @JvmOverloads constructor( } val hint = Hint() hint.set(TypeCheckHint.ANDROID_NAV_DESTINATION, destination) - hub.addBreadcrumb(breadcrumb, hint) + scopes.addBreadcrumb(breadcrumb, hint) } private fun startTracing( @@ -100,7 +100,7 @@ class SentryNavigationListener @JvmOverloads constructor( arguments: Map ) { if (!isPerformanceEnabled) { - TracingUtils.startNewTrace(hub) + TracingUtils.startNewTrace(scopes) return } @@ -111,7 +111,7 @@ class SentryNavigationListener @JvmOverloads constructor( if (destination.navigatorName == "activity") { // we do not trace navigation between activities to avoid clashing with activity lifecycle tracing - hub.options.logger.log( + scopes.options.logger.log( DEBUG, "Navigating to activity destination, no transaction captured." ) @@ -122,7 +122,7 @@ class SentryNavigationListener @JvmOverloads constructor( var name = destination.route ?: try { controller.context.resources.getResourceEntryName(destination.id) } catch (e: NotFoundException) { - hub.options.logger.log( + scopes.options.logger.log( DEBUG, "Destination id cannot be retrieved from Resources, no transaction captured." ) @@ -134,12 +134,12 @@ class SentryNavigationListener @JvmOverloads constructor( val transactionOptions = TransactionOptions().also { it.isWaitForChildren = true - it.idleTimeout = hub.options.idleTimeout + it.idleTimeout = scopes.options.idleTimeout it.deadlineTimeout = TransactionOptions.DEFAULT_DEADLINE_TIMEOUT_AUTO_TRANSACTION it.isTrimEnd = true } - val transaction = hub.startTransaction( + val transaction = scopes.startTransaction( TransactionContext(name, TransactionNameSource.ROUTE, NAVIGATION_OP), transactionOptions ) @@ -151,7 +151,7 @@ class SentryNavigationListener @JvmOverloads constructor( if (arguments.isNotEmpty()) { transaction.setData("arguments", arguments) } - hub.configureScope { scope -> + scopes.configureScope { scope -> scope.withTransaction { tx -> if (tx == null) { scope.transaction = transaction @@ -166,7 +166,7 @@ class SentryNavigationListener @JvmOverloads constructor( activeTransaction?.finish(status) // clear transaction from scope so others can bind to it - hub.configureScope { scope -> + scopes.configureScope { scope -> scope.withTransaction { tx -> if (tx == activeTransaction) { scope.clearTransaction() diff --git a/sentry-android-navigation/src/test/java/io/sentry/android/navigation/SentryNavigationListenerTest.kt b/sentry-android-navigation/src/test/java/io/sentry/android/navigation/SentryNavigationListenerTest.kt index 76c57159c3..7308b6b659 100644 --- a/sentry-android-navigation/src/test/java/io/sentry/android/navigation/SentryNavigationListenerTest.kt +++ b/sentry-android-navigation/src/test/java/io/sentry/android/navigation/SentryNavigationListenerTest.kt @@ -7,8 +7,8 @@ import androidx.navigation.NavController import androidx.navigation.NavDestination import androidx.test.ext.junit.runners.AndroidJUnit4 import io.sentry.Breadcrumb -import io.sentry.IHub import io.sentry.IScope +import io.sentry.IScopes import io.sentry.Scope import io.sentry.Scope.IWithTransaction import io.sentry.ScopeCallback @@ -39,7 +39,7 @@ import kotlin.test.assertNull class SentryNavigationListenerTest { class Fixture { - val hub = mock() + val scopes = mock() val destination = mock() val navController = mock() @@ -67,20 +67,20 @@ class SentryNavigationListenerTest { tracesSampleRate ) } - whenever(hub.options).thenReturn(options) + whenever(scopes.options).thenReturn(options) this.transaction = transaction ?: SentryTracer( TransactionContext( "/$toRoute", SentryNavigationListener.NAVIGATION_OP ), - hub + scopes ) - whenever(hub.startTransaction(any(), any())) + whenever(scopes.startTransaction(any(), any())) .thenReturn(this.transaction) - whenever(hub.configureScope(any())).thenAnswer { + whenever(scopes.configureScope(any())).thenAnswer { (it.arguments[0] as ScopeCallback).run(scope) } @@ -96,7 +96,7 @@ class SentryNavigationListenerTest { whenever(navController.context).thenReturn(context) whenever(destination.route).thenReturn(toRoute) return SentryNavigationListener( - hub, + scopes, enableBreadcrumbs, enableTracing, traceOriginAppendix @@ -112,7 +112,7 @@ class SentryNavigationListenerTest { sut.onDestinationChanged(fixture.navController, fixture.destination, null) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("navigation", it.type) assertEquals("navigation", it.category) @@ -133,7 +133,7 @@ class SentryNavigationListenerTest { bundleOf("arg1" to "foo", "arg2" to "bar") ) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("/route", it.data["to"]) assertEquals(mapOf("arg1" to "foo", "arg2" to "bar"), it.data["to_arguments"]) @@ -152,7 +152,7 @@ class SentryNavigationListenerTest { bundleOf() ) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("/route", it.data["to"]) assertNull(it.data["to_arguments"]) @@ -180,7 +180,7 @@ class SentryNavigationListenerTest { bundleOf("to_arg1" to "to_foo") ) val captor = argumentCaptor() - verify(fixture.hub, times(2)).addBreadcrumb(captor.capture(), any()) + verify(fixture.scopes, times(2)).addBreadcrumb(captor.capture(), any()) captor.secondValue.let { assertEquals("/route_from", it.data["from"]) assertEquals(mapOf("from_arg1" to "from_foo"), it.data["from_arguments"]) @@ -196,7 +196,7 @@ class SentryNavigationListenerTest { sut.onDestinationChanged(fixture.navController, fixture.destination, null) - verify(fixture.hub, never()).addBreadcrumb(any()) + verify(fixture.scopes, never()).addBreadcrumb(any()) } @Test @@ -205,7 +205,7 @@ class SentryNavigationListenerTest { sut.onDestinationChanged(fixture.navController, fixture.destination, null) - verify(fixture.hub, never()).startTransaction( + verify(fixture.scopes, never()).startTransaction( any(), any() ) @@ -217,7 +217,7 @@ class SentryNavigationListenerTest { sut.onDestinationChanged(fixture.navController, fixture.destination, null) - verify(fixture.hub, never()).startTransaction( + verify(fixture.scopes, never()).startTransaction( any(), any() ) @@ -230,7 +230,7 @@ class SentryNavigationListenerTest { sut.onDestinationChanged(fixture.navController, fixture.destination, null) - verify(fixture.hub, never()).startTransaction( + verify(fixture.scopes, never()).startTransaction( any(), any() ) @@ -242,7 +242,7 @@ class SentryNavigationListenerTest { sut.onDestinationChanged(fixture.navController, fixture.destination, null) - verify(fixture.hub, never()).startTransaction( + verify(fixture.scopes, never()).startTransaction( any(), any() ) @@ -254,7 +254,7 @@ class SentryNavigationListenerTest { sut.onDestinationChanged(fixture.navController, fixture.destination, null) - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( check { assertEquals("/route", it.name) assertEquals(SentryNavigationListener.NAVIGATION_OP, it.operation) @@ -266,13 +266,13 @@ class SentryNavigationListenerTest { @Test fun `onDestinationChanged strips out route parameters from transaction name`() { - val sut = fixture.getSut(toRoute = "github/{user_id}?per_page={per_page}") + val sut = fixture.getSut(toRoute = "gitscopes/{user_id}?per_page={per_page}") sut.onDestinationChanged(fixture.navController, fixture.destination, null) - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( check { - assertEquals("/github", it.name) + assertEquals("/gitscopes", it.name) assertEquals(TransactionNameSource.ROUTE, it.transactionNameSource) }, any() @@ -285,7 +285,7 @@ class SentryNavigationListenerTest { sut.onDestinationChanged(fixture.navController, fixture.destination, null) - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( check { assertEquals("/destination-id-1", it.name) assertEquals(TransactionNameSource.ROUTE, it.transactionNameSource) @@ -296,7 +296,7 @@ class SentryNavigationListenerTest { @Test fun `onDestinationChanged captures arguments as additional data for transaction`() { - val sut = fixture.getSut(toRoute = "github/{user_id}?per_page={per_page}") + val sut = fixture.getSut(toRoute = "gitscopes/{user_id}?per_page={per_page}") sut.onDestinationChanged( fixture.navController, @@ -304,9 +304,9 @@ class SentryNavigationListenerTest { bundleOf("user_id" to 123, "per_page" to 10) ) - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( check { - assertEquals("/github", it.name) + assertEquals("/gitscopes", it.name) assertEquals(TransactionNameSource.ROUTE, it.transactionNameSource) }, any() @@ -365,13 +365,13 @@ class SentryNavigationListenerTest { ArgumentCaptor.forClass(ScopeCallback::class.java) val scope = Scope(fixture.options) val propagationContextAtStart = scope.propagationContext - whenever(fixture.hub.configureScope(argumentCaptor.capture())).thenAnswer { + whenever(fixture.scopes.configureScope(argumentCaptor.capture())).thenAnswer { argumentCaptor.value.run(scope) } sut.onDestinationChanged(fixture.navController, fixture.destination, null) - verify(fixture.hub).configureScope(any()) + verify(fixture.scopes).configureScope(any()) assertNotSame(propagationContextAtStart, scope.propagationContext) } @@ -399,7 +399,7 @@ class SentryNavigationListenerTest { sut.onDestinationChanged(fixture.navController, fixture.destination, null) - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( any(), check { options -> assertEquals(TransactionOptions.DEFAULT_DEADLINE_TIMEOUT_AUTO_TRANSACTION, options.deadlineTimeout) diff --git a/sentry-android-okhttp/api/sentry-android-okhttp.api b/sentry-android-okhttp/api/sentry-android-okhttp.api index a1ad9114a2..35f42842dd 100644 --- a/sentry-android-okhttp/api/sentry-android-okhttp.api +++ b/sentry-android-okhttp/api/sentry-android-okhttp.api @@ -8,12 +8,12 @@ public final class io/sentry/android/okhttp/BuildConfig { public final class io/sentry/android/okhttp/SentryOkHttpEventListener : okhttp3/EventListener { public fun ()V - public fun (Lio/sentry/IHub;Lkotlin/jvm/functions/Function1;)V - public synthetic fun (Lio/sentry/IHub;Lkotlin/jvm/functions/Function1;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public fun (Lio/sentry/IHub;Lokhttp3/EventListener$Factory;)V - public synthetic fun (Lio/sentry/IHub;Lokhttp3/EventListener$Factory;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public fun (Lio/sentry/IHub;Lokhttp3/EventListener;)V - public synthetic fun (Lio/sentry/IHub;Lokhttp3/EventListener;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lio/sentry/IScopes;Lkotlin/jvm/functions/Function1;)V + public synthetic fun (Lio/sentry/IScopes;Lkotlin/jvm/functions/Function1;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lio/sentry/IScopes;Lokhttp3/EventListener$Factory;)V + public synthetic fun (Lio/sentry/IScopes;Lokhttp3/EventListener$Factory;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lio/sentry/IScopes;Lokhttp3/EventListener;)V + public synthetic fun (Lio/sentry/IScopes;Lokhttp3/EventListener;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun (Lokhttp3/EventListener$Factory;)V public fun (Lokhttp3/EventListener;)V public fun cacheConditionalHit (Lokhttp3/Call;Lokhttp3/Response;)V @@ -49,9 +49,9 @@ public final class io/sentry/android/okhttp/SentryOkHttpEventListener : okhttp3/ public final class io/sentry/android/okhttp/SentryOkHttpInterceptor : okhttp3/Interceptor { public fun ()V - public fun (Lio/sentry/IHub;)V - public fun (Lio/sentry/IHub;Lio/sentry/android/okhttp/SentryOkHttpInterceptor$BeforeSpanCallback;ZLjava/util/List;Ljava/util/List;)V - public synthetic fun (Lio/sentry/IHub;Lio/sentry/android/okhttp/SentryOkHttpInterceptor$BeforeSpanCallback;ZLjava/util/List;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lio/sentry/IScopes;)V + public fun (Lio/sentry/IScopes;Lio/sentry/android/okhttp/SentryOkHttpInterceptor$BeforeSpanCallback;ZLjava/util/List;Ljava/util/List;)V + public synthetic fun (Lio/sentry/IScopes;Lio/sentry/android/okhttp/SentryOkHttpInterceptor$BeforeSpanCallback;ZLjava/util/List;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun (Lio/sentry/android/okhttp/SentryOkHttpInterceptor$BeforeSpanCallback;)V public fun intercept (Lokhttp3/Interceptor$Chain;)Lokhttp3/Response; } diff --git a/sentry-android-okhttp/src/main/java/io/sentry/android/okhttp/SentryOkHttpEventListener.kt b/sentry-android-okhttp/src/main/java/io/sentry/android/okhttp/SentryOkHttpEventListener.kt index 7ca5313d8f..f99106e8d9 100644 --- a/sentry-android-okhttp/src/main/java/io/sentry/android/okhttp/SentryOkHttpEventListener.kt +++ b/sentry-android-okhttp/src/main/java/io/sentry/android/okhttp/SentryOkHttpEventListener.kt @@ -1,7 +1,7 @@ package io.sentry.android.okhttp -import io.sentry.HubAdapter -import io.sentry.IHub +import io.sentry.IScopes +import io.sentry.ScopesAdapter import okhttp3.Call import okhttp3.Connection import okhttp3.EventListener @@ -42,35 +42,35 @@ import java.net.Proxy ) @Suppress("TooManyFunctions") class SentryOkHttpEventListener( - hub: IHub = HubAdapter.getInstance(), + scopes: IScopes = ScopesAdapter.getInstance(), originalEventListenerCreator: ((call: Call) -> EventListener)? = null ) : EventListener() { constructor() : this( - HubAdapter.getInstance(), + ScopesAdapter.getInstance(), originalEventListenerCreator = null ) constructor(originalEventListener: EventListener) : this( - HubAdapter.getInstance(), + ScopesAdapter.getInstance(), originalEventListenerCreator = { originalEventListener } ) constructor(originalEventListenerFactory: Factory) : this( - HubAdapter.getInstance(), + ScopesAdapter.getInstance(), originalEventListenerCreator = { originalEventListenerFactory.create(it) } ) - constructor(hub: IHub = HubAdapter.getInstance(), originalEventListener: EventListener) : this( - hub, + constructor(scopes: IScopes = ScopesAdapter.getInstance(), originalEventListener: EventListener) : this( + scopes, originalEventListenerCreator = { originalEventListener } ) - constructor(hub: IHub = HubAdapter.getInstance(), originalEventListenerFactory: Factory) : this( - hub, + constructor(scopes: IScopes = ScopesAdapter.getInstance(), originalEventListenerFactory: Factory) : this( + scopes, originalEventListenerCreator = { originalEventListenerFactory.create(it) } ) - private val delegate = io.sentry.okhttp.SentryOkHttpEventListener(hub, originalEventListenerCreator) + private val delegate = io.sentry.okhttp.SentryOkHttpEventListener(scopes, originalEventListenerCreator) override fun cacheConditionalHit(call: Call, cachedResponse: Response) { delegate.cacheConditionalHit(call, cachedResponse) diff --git a/sentry-android-okhttp/src/main/java/io/sentry/android/okhttp/SentryOkHttpInterceptor.kt b/sentry-android-okhttp/src/main/java/io/sentry/android/okhttp/SentryOkHttpInterceptor.kt index 971af925ff..3c7e590fe1 100644 --- a/sentry-android-okhttp/src/main/java/io/sentry/android/okhttp/SentryOkHttpInterceptor.kt +++ b/sentry-android-okhttp/src/main/java/io/sentry/android/okhttp/SentryOkHttpInterceptor.kt @@ -1,9 +1,9 @@ package io.sentry.android.okhttp import io.sentry.HttpStatusCodeRange -import io.sentry.HubAdapter -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ISpan +import io.sentry.ScopesAdapter import io.sentry.SentryIntegrationPackageStorage import io.sentry.SentryOptions.DEFAULT_PROPAGATION_TARGETS import io.sentry.android.okhttp.SentryOkHttpInterceptor.BeforeSpanCallback @@ -17,7 +17,7 @@ import okhttp3.Response * out of the active span bound to the scope for each HTTP Request. * If [captureFailedRequests] is enabled, the SDK will capture HTTP Client errors as well. * - * @param hub The [IHub], internal and only used for testing. + * @param scopes The [IScopes], internal and only used for testing. * @param beforeSpan The [ISpan] can be customized or dropped with the [BeforeSpanCallback]. * @param captureFailedRequests The SDK will only capture HTTP Client errors if it is enabled, * Defaults to false. @@ -31,7 +31,7 @@ import okhttp3.Response ReplaceWith("SentryOkHttpInterceptor", "io.sentry.okhttp.SentryOkHttpInterceptor") ) class SentryOkHttpInterceptor( - private val hub: IHub = HubAdapter.getInstance(), + private val scopes: IScopes = ScopesAdapter.getInstance(), private val beforeSpan: BeforeSpanCallback? = null, private val captureFailedRequests: Boolean = true, private val failedRequestStatusCodes: List = listOf( @@ -39,7 +39,7 @@ class SentryOkHttpInterceptor( ), private val failedRequestTargets: List = listOf(DEFAULT_PROPAGATION_TARGETS) ) : Interceptor by io.sentry.okhttp.SentryOkHttpInterceptor( - hub, + scopes, { span, request, response -> beforeSpan ?: return@SentryOkHttpInterceptor span beforeSpan.execute(span, request, response) @@ -49,9 +49,9 @@ class SentryOkHttpInterceptor( failedRequestTargets ) { - constructor() : this(HubAdapter.getInstance()) - constructor(hub: IHub) : this(hub, null) - constructor(beforeSpan: BeforeSpanCallback) : this(HubAdapter.getInstance(), beforeSpan) + constructor() : this(ScopesAdapter.getInstance()) + constructor(scopes: IScopes) : this(scopes, null) + constructor(beforeSpan: BeforeSpanCallback) : this(ScopesAdapter.getInstance(), beforeSpan) init { addIntegrationToSdkVersion(javaClass) diff --git a/sentry-android-sqlite/src/main/java/io/sentry/android/sqlite/SQLiteSpanManager.kt b/sentry-android-sqlite/src/main/java/io/sentry/android/sqlite/SQLiteSpanManager.kt index 3bfa855d53..2e39bf76ec 100644 --- a/sentry-android-sqlite/src/main/java/io/sentry/android/sqlite/SQLiteSpanManager.kt +++ b/sentry-android-sqlite/src/main/java/io/sentry/android/sqlite/SQLiteSpanManager.kt @@ -1,8 +1,8 @@ package io.sentry.android.sqlite import android.database.SQLException -import io.sentry.HubAdapter -import io.sentry.IHub +import io.sentry.IScopes +import io.sentry.ScopesAdapter import io.sentry.SentryIntegrationPackageStorage import io.sentry.SentryStackTraceFactory import io.sentry.SpanDataConvention @@ -11,10 +11,10 @@ import io.sentry.SpanStatus private const val TRACE_ORIGIN = "auto.db.sqlite" internal class SQLiteSpanManager( - private val hub: IHub = HubAdapter.getInstance(), + private val scopes: IScopes = ScopesAdapter.getInstance(), private val databaseName: String? = null ) { - private val stackTraceFactory = SentryStackTraceFactory(hub.options) + private val stackTraceFactory = SentryStackTraceFactory(scopes.options) init { SentryIntegrationPackageStorage.getInstance().addIntegration("SQLite") @@ -30,7 +30,7 @@ internal class SQLiteSpanManager( @Suppress("TooGenericExceptionCaught") @Throws(SQLException::class) fun performSql(sql: String, operation: () -> T): T { - val span = hub.span?.startChild("db.sql.query", sql) + val span = scopes.span?.startChild("db.sql.query", sql) span?.spanContext?.origin = TRACE_ORIGIN return try { val result = operation() @@ -42,7 +42,7 @@ internal class SQLiteSpanManager( throw e } finally { span?.apply { - val isMainThread: Boolean = hub.options.mainThreadChecker.isMainThread + val isMainThread: Boolean = scopes.options.mainThreadChecker.isMainThread setData(SpanDataConvention.BLOCKED_MAIN_THREAD_KEY, isMainThread) if (isMainThread) { setData(SpanDataConvention.CALL_STACK_KEY, stackTraceFactory.inAppCallStack) diff --git a/sentry-android-sqlite/src/test/java/io/sentry/android/sqlite/SQLiteSpanManagerTest.kt b/sentry-android-sqlite/src/test/java/io/sentry/android/sqlite/SQLiteSpanManagerTest.kt index e2fa0c2e4d..9265cd260a 100644 --- a/sentry-android-sqlite/src/test/java/io/sentry/android/sqlite/SQLiteSpanManagerTest.kt +++ b/sentry-android-sqlite/src/test/java/io/sentry/android/sqlite/SQLiteSpanManagerTest.kt @@ -1,7 +1,7 @@ package io.sentry.android.sqlite import android.database.SQLException -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryIntegrationPackageStorage import io.sentry.SentryOptions import io.sentry.SentryTracer @@ -22,7 +22,7 @@ import kotlin.test.assertTrue class SQLiteSpanManagerTest { private class Fixture { - private val hub = mock() + private val scopes = mock() lateinit var sentryTracer: SentryTracer lateinit var options: SentryOptions @@ -30,13 +30,13 @@ class SQLiteSpanManagerTest { options = SentryOptions().apply { dsn = "https://key@sentry.io/proj" } - whenever(hub.options).thenReturn(options) - sentryTracer = SentryTracer(TransactionContext("name", "op"), hub) + whenever(scopes.options).thenReturn(options) + sentryTracer = SentryTracer(TransactionContext("name", "op"), scopes) if (isSpanActive) { - whenever(hub.span).thenReturn(sentryTracer) + whenever(scopes.span).thenReturn(sentryTracer) } - return SQLiteSpanManager(hub, databaseName) + return SQLiteSpanManager(scopes, databaseName) } } diff --git a/sentry-android-sqlite/src/test/java/io/sentry/android/sqlite/SentrySupportSQLiteDatabaseTest.kt b/sentry-android-sqlite/src/test/java/io/sentry/android/sqlite/SentrySupportSQLiteDatabaseTest.kt index cf22c3b0ec..99e1d5f4a0 100644 --- a/sentry-android-sqlite/src/test/java/io/sentry/android/sqlite/SentrySupportSQLiteDatabaseTest.kt +++ b/sentry-android-sqlite/src/test/java/io/sentry/android/sqlite/SentrySupportSQLiteDatabaseTest.kt @@ -3,7 +3,7 @@ package io.sentry.android.sqlite import android.database.Cursor import androidx.sqlite.db.SupportSQLiteDatabase import androidx.sqlite.db.SupportSQLiteQuery -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ISpan import io.sentry.SentryOptions import io.sentry.SentryTracer @@ -23,8 +23,8 @@ import kotlin.test.assertTrue class SentrySupportSQLiteDatabaseTest { private class Fixture { - private val hub = mock() - private val spanManager = SQLiteSpanManager(hub) + private val scopes = mock() + private val spanManager = SQLiteSpanManager(scopes) val mockDatabase = mock() lateinit var sentryTracer: SentryTracer lateinit var options: SentryOptions @@ -37,11 +37,11 @@ class SentrySupportSQLiteDatabaseTest { options = SentryOptions().apply { dsn = "https://key@sentry.io/proj" } - whenever(hub.options).thenReturn(options) - sentryTracer = SentryTracer(TransactionContext("name", "op"), hub) + whenever(scopes.options).thenReturn(options) + sentryTracer = SentryTracer(TransactionContext("name", "op"), scopes) if (isSpanActive) { - whenever(hub.span).thenReturn(sentryTracer) + whenever(scopes.span).thenReturn(sentryTracer) } return SentrySupportSQLiteDatabase(mockDatabase, spanManager) diff --git a/sentry-android-sqlite/src/test/java/io/sentry/android/sqlite/SentrySupportSQLiteStatementTest.kt b/sentry-android-sqlite/src/test/java/io/sentry/android/sqlite/SentrySupportSQLiteStatementTest.kt index 9078ba8b08..4b6292bd27 100644 --- a/sentry-android-sqlite/src/test/java/io/sentry/android/sqlite/SentrySupportSQLiteStatementTest.kt +++ b/sentry-android-sqlite/src/test/java/io/sentry/android/sqlite/SentrySupportSQLiteStatementTest.kt @@ -1,7 +1,7 @@ package io.sentry.android.sqlite import androidx.sqlite.db.SupportSQLiteStatement -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ISpan import io.sentry.SentryOptions import io.sentry.SentryTracer @@ -18,8 +18,8 @@ import kotlin.test.assertTrue class SentrySupportSQLiteStatementTest { private class Fixture { - private val hub = mock() - private val spanManager = SQLiteSpanManager(hub) + private val scopes = mock() + private val spanManager = SQLiteSpanManager(scopes) val mockStatement = mock() lateinit var sentryTracer: SentryTracer lateinit var options: SentryOptions @@ -28,11 +28,11 @@ class SentrySupportSQLiteStatementTest { options = SentryOptions().apply { dsn = "https://key@sentry.io/proj" } - whenever(hub.options).thenReturn(options) - sentryTracer = SentryTracer(TransactionContext("name", "op"), hub) + whenever(scopes.options).thenReturn(options) + sentryTracer = SentryTracer(TransactionContext("name", "op"), scopes) if (isSpanActive) { - whenever(hub.span).thenReturn(sentryTracer) + whenever(scopes.span).thenReturn(sentryTracer) } return SentrySupportSQLiteStatement(mockStatement, spanManager, sql) } diff --git a/sentry-android-timber/api/sentry-android-timber.api b/sentry-android-timber/api/sentry-android-timber.api index 808e91bf10..2d71f67570 100644 --- a/sentry-android-timber/api/sentry-android-timber.api +++ b/sentry-android-timber/api/sentry-android-timber.api @@ -14,11 +14,11 @@ public final class io/sentry/android/timber/SentryTimberIntegration : io/sentry/ public fun close ()V public final fun getMinBreadcrumbLevel ()Lio/sentry/SentryLevel; public final fun getMinEventLevel ()Lio/sentry/SentryLevel; - public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/android/timber/SentryTimberTree : timber/log/Timber$Tree { - public fun (Lio/sentry/IHub;Lio/sentry/SentryLevel;Lio/sentry/SentryLevel;)V + public fun (Lio/sentry/IScopes;Lio/sentry/SentryLevel;Lio/sentry/SentryLevel;)V public fun d (Ljava/lang/String;[Ljava/lang/Object;)V public fun d (Ljava/lang/Throwable;)V public fun d (Ljava/lang/Throwable;Ljava/lang/String;[Ljava/lang/Object;)V diff --git a/sentry-android-timber/src/main/java/io/sentry/android/timber/SentryTimberIntegration.kt b/sentry-android-timber/src/main/java/io/sentry/android/timber/SentryTimberIntegration.kt index d043faa5f6..334146a218 100644 --- a/sentry-android-timber/src/main/java/io/sentry/android/timber/SentryTimberIntegration.kt +++ b/sentry-android-timber/src/main/java/io/sentry/android/timber/SentryTimberIntegration.kt @@ -1,7 +1,7 @@ package io.sentry.android.timber -import io.sentry.IHub import io.sentry.ILogger +import io.sentry.IScopes import io.sentry.Integration import io.sentry.SentryIntegrationPackageStorage import io.sentry.SentryLevel @@ -21,10 +21,10 @@ class SentryTimberIntegration( private lateinit var tree: SentryTimberTree private lateinit var logger: ILogger - override fun register(hub: IHub, options: SentryOptions) { + override fun register(scopes: IScopes, options: SentryOptions) { logger = options.logger - tree = SentryTimberTree(hub, minEventLevel, minBreadcrumbLevel) + tree = SentryTimberTree(scopes, minEventLevel, minBreadcrumbLevel) Timber.plant(tree) logger.log(SentryLevel.DEBUG, "SentryTimberIntegration installed.") diff --git a/sentry-android-timber/src/main/java/io/sentry/android/timber/SentryTimberTree.kt b/sentry-android-timber/src/main/java/io/sentry/android/timber/SentryTimberTree.kt index f3a0f599a9..dddab75133 100644 --- a/sentry-android-timber/src/main/java/io/sentry/android/timber/SentryTimberTree.kt +++ b/sentry-android-timber/src/main/java/io/sentry/android/timber/SentryTimberTree.kt @@ -2,7 +2,7 @@ package io.sentry.android.timber import android.util.Log import io.sentry.Breadcrumb -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryEvent import io.sentry.SentryLevel import io.sentry.protocol.Message @@ -13,7 +13,7 @@ import timber.log.Timber */ @Suppress("TooManyFunctions") // we have to override all methods to be able to tweak logging class SentryTimberTree( - private val hub: IHub, + private val scopes: IScopes, private val minEventLevel: SentryLevel, private val minBreadcrumbLevel: SentryLevel ) : Timber.Tree() { @@ -269,7 +269,7 @@ class SentryTimberTree( logger = "Timber" } - hub.captureEvent(sentryEvent) + scopes.captureEvent(sentryEvent) } } @@ -296,7 +296,7 @@ class SentryTimberTree( else -> null } - breadCrumb?.let { hub.addBreadcrumb(it) } + breadCrumb?.let { scopes.addBreadcrumb(it) } } } diff --git a/sentry-android-timber/src/test/java/io/sentry/android/timber/SentryTimberIntegrationTest.kt b/sentry-android-timber/src/test/java/io/sentry/android/timber/SentryTimberIntegrationTest.kt index a57853e059..8bb85aa085 100644 --- a/sentry-android-timber/src/test/java/io/sentry/android/timber/SentryTimberIntegrationTest.kt +++ b/sentry-android-timber/src/test/java/io/sentry/android/timber/SentryTimberIntegrationTest.kt @@ -1,6 +1,6 @@ package io.sentry.android.timber -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryLevel import io.sentry.SentryOptions import io.sentry.protocol.SdkVersion @@ -16,7 +16,7 @@ import kotlin.test.assertTrue class SentryTimberIntegrationTest { private class Fixture { - val hub = mock() + val scopes = mock() val options = SentryOptions().apply { sdkVersion = SdkVersion("test", "1.2.3") } @@ -41,7 +41,7 @@ class SentryTimberIntegrationTest { @Test fun `Integrations plants a tree into Timber on register`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertEquals(1, Timber.treeCount()) @@ -53,16 +53,16 @@ class SentryTimberIntegrationTest { @Test fun `Integrations plants the SentryTimberTree tree`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) Timber.e(Throwable()) - verify(fixture.hub).captureEvent(any()) + verify(fixture.scopes).captureEvent(any()) } @Test fun `Integrations removes a tree from Timber on close integration`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertEquals(1, Timber.treeCount()) @@ -84,7 +84,7 @@ class SentryTimberIntegrationTest { minEventLevel = SentryLevel.INFO, minBreadcrumbLevel = SentryLevel.DEBUG ) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertEquals(sut.minEventLevel, SentryLevel.INFO) assertEquals(sut.minBreadcrumbLevel, SentryLevel.DEBUG) @@ -93,7 +93,7 @@ class SentryTimberIntegrationTest { @Test fun `Integration adds itself to the package list`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertTrue( fixture.options.sdkVersion!!.packageSet.any { @@ -106,7 +106,7 @@ class SentryTimberIntegrationTest { @Test fun `Integration adds itself to the integration list`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertTrue( fixture.options.sdkVersion!!.integrationSet.contains("Timber") diff --git a/sentry-android-timber/src/test/java/io/sentry/android/timber/SentryTimberTreeTest.kt b/sentry-android-timber/src/test/java/io/sentry/android/timber/SentryTimberTreeTest.kt index 3d82b139ec..2ab7ff64db 100644 --- a/sentry-android-timber/src/test/java/io/sentry/android/timber/SentryTimberTreeTest.kt +++ b/sentry-android-timber/src/test/java/io/sentry/android/timber/SentryTimberTreeTest.kt @@ -1,7 +1,7 @@ package io.sentry.android.timber import io.sentry.Breadcrumb -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryLevel import io.sentry.getExc import org.mockito.kotlin.any @@ -19,13 +19,13 @@ import kotlin.test.assertNull class SentryTimberTreeTest { private class Fixture { - val hub = mock() + val scopes = mock() fun getSut( minEventLevel: SentryLevel = SentryLevel.ERROR, minBreadcrumbLevel: SentryLevel = SentryLevel.INFO ): SentryTimberTree { - return SentryTimberTree(hub, minEventLevel, minBreadcrumbLevel) + return SentryTimberTree(scopes, minEventLevel, minBreadcrumbLevel) } } @@ -40,28 +40,28 @@ class SentryTimberTreeTest { fun `Tree captures an event if min level is equal`() { val sut = fixture.getSut() sut.e(Throwable()) - verify(fixture.hub).captureEvent(any()) + verify(fixture.scopes).captureEvent(any()) } @Test fun `Tree captures an event if min level is higher`() { val sut = fixture.getSut() sut.wtf(Throwable()) - verify(fixture.hub).captureEvent(any()) + verify(fixture.scopes).captureEvent(any()) } @Test fun `Tree won't capture an event if min level is lower`() { val sut = fixture.getSut() sut.d(Throwable()) - verify(fixture.hub, never()).captureEvent(any()) + verify(fixture.scopes, never()).captureEvent(any()) } @Test fun `Tree captures debug level event`() { val sut = fixture.getSut(SentryLevel.DEBUG) sut.d(Throwable()) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { assertEquals(SentryLevel.DEBUG, it.level) } @@ -72,7 +72,7 @@ class SentryTimberTreeTest { fun `Tree captures info level event`() { val sut = fixture.getSut(SentryLevel.DEBUG) sut.i(Throwable()) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { assertEquals(SentryLevel.INFO, it.level) } @@ -83,7 +83,7 @@ class SentryTimberTreeTest { fun `Tree captures warning level event`() { val sut = fixture.getSut(SentryLevel.DEBUG) sut.w(Throwable()) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { assertEquals(SentryLevel.WARNING, it.level) } @@ -94,7 +94,7 @@ class SentryTimberTreeTest { fun `Tree captures error level event`() { val sut = fixture.getSut(SentryLevel.DEBUG) sut.e(Throwable()) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { assertEquals(SentryLevel.ERROR, it.level) } @@ -105,7 +105,7 @@ class SentryTimberTreeTest { fun `Tree captures fatal level event`() { val sut = fixture.getSut(SentryLevel.DEBUG) sut.wtf(Throwable()) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { assertEquals(SentryLevel.FATAL, it.level) } @@ -116,7 +116,7 @@ class SentryTimberTreeTest { fun `Tree captures unknown as debug level event`() { val sut = fixture.getSut(SentryLevel.DEBUG) sut.log(15, Throwable()) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { assertEquals(SentryLevel.DEBUG, it.level) } @@ -128,7 +128,7 @@ class SentryTimberTreeTest { val sut = fixture.getSut() val throwable = Throwable() sut.e(throwable) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { assertEquals(throwable, it.getExc()) } @@ -139,7 +139,7 @@ class SentryTimberTreeTest { fun `Tree captures an event without an exception`() { val sut = fixture.getSut() sut.e("message") - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { assertNull(it.getExc()) } @@ -150,7 +150,7 @@ class SentryTimberTreeTest { fun `Tree captures an event and sets Timber as a logger`() { val sut = fixture.getSut() sut.e("message") - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { assertEquals("Timber", it.logger) } @@ -164,7 +164,7 @@ class SentryTimberTreeTest { // only available thru static class Timber.tag("tag") Timber.e("message") - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { assertEquals("tag", it.getTag("TimberTag")) } @@ -176,7 +176,7 @@ class SentryTimberTreeTest { val sut = fixture.getSut() Timber.plant(sut) Timber.e("message") - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { assertNull(it.getTag("TimberTag")) } @@ -187,7 +187,7 @@ class SentryTimberTreeTest { fun `Tree captures an event with given message`() { val sut = fixture.getSut() sut.e("message") - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { assertNotNull(it.message) { message -> assertEquals("message", message.message) @@ -200,7 +200,7 @@ class SentryTimberTreeTest { fun `Tree captures an event with formatted message and arguments, when provided`() { val sut = fixture.getSut() sut.e("test count: %d", 32) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { assertNotNull(it.message) { message -> assertEquals("test count: %d", message.message) @@ -216,7 +216,7 @@ class SentryTimberTreeTest { val sut = fixture.getSut() sut.e("test count: %d", 32) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("test count: 32", it.message) } @@ -227,28 +227,28 @@ class SentryTimberTreeTest { fun `Tree adds a breadcrumb if min level is equal`() { val sut = fixture.getSut() sut.i(Throwable("test")) - verify(fixture.hub).addBreadcrumb(any()) + verify(fixture.scopes).addBreadcrumb(any()) } @Test fun `Tree adds a breadcrumb if min level is higher`() { val sut = fixture.getSut() sut.e(Throwable("test")) - verify(fixture.hub).addBreadcrumb(any()) + verify(fixture.scopes).addBreadcrumb(any()) } @Test fun `Tree won't add a breadcrumb if min level is lower`() { val sut = fixture.getSut(minBreadcrumbLevel = SentryLevel.ERROR) sut.i(Throwable("test")) - verify(fixture.hub, never()).addBreadcrumb(any()) + verify(fixture.scopes, never()).addBreadcrumb(any()) } @Test fun `Tree adds an info breadcrumb`() { val sut = fixture.getSut() sut.i("message") - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("Timber", it.category) assertEquals(SentryLevel.INFO, it.level) @@ -261,7 +261,7 @@ class SentryTimberTreeTest { fun `Tree adds an error breadcrumb`() { val sut = fixture.getSut() sut.e(Throwable("test")) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("exception", it.category) assertEquals(SentryLevel.ERROR, it.level) @@ -274,7 +274,7 @@ class SentryTimberTreeTest { fun `Tree does not add a breadcrumb, if no message provided`() { val sut = fixture.getSut() sut.e(Throwable()) - verify(fixture.hub, never()).addBreadcrumb(any()) + verify(fixture.scopes, never()).addBreadcrumb(any()) } @Test diff --git a/sentry-apollo-3/api/sentry-apollo-3.api b/sentry-apollo-3/api/sentry-apollo-3.api index 1c80e1950b..e106585156 100644 --- a/sentry-apollo-3/api/sentry-apollo-3.api +++ b/sentry-apollo-3/api/sentry-apollo-3.api @@ -17,11 +17,11 @@ public final class io/sentry/apollo3/SentryApollo3HttpInterceptor : com/apollogr public static final field SENTRY_APOLLO_3_OPERATION_TYPE Ljava/lang/String; public static final field SENTRY_APOLLO_3_VARIABLES Ljava/lang/String; public fun ()V - public fun (Lio/sentry/IHub;)V - public fun (Lio/sentry/IHub;Lio/sentry/apollo3/SentryApollo3HttpInterceptor$BeforeSpanCallback;)V - public fun (Lio/sentry/IHub;Lio/sentry/apollo3/SentryApollo3HttpInterceptor$BeforeSpanCallback;Z)V - public fun (Lio/sentry/IHub;Lio/sentry/apollo3/SentryApollo3HttpInterceptor$BeforeSpanCallback;ZLjava/util/List;)V - public synthetic fun (Lio/sentry/IHub;Lio/sentry/apollo3/SentryApollo3HttpInterceptor$BeforeSpanCallback;ZLjava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lio/sentry/IScopes;)V + public fun (Lio/sentry/IScopes;Lio/sentry/apollo3/SentryApollo3HttpInterceptor$BeforeSpanCallback;)V + public fun (Lio/sentry/IScopes;Lio/sentry/apollo3/SentryApollo3HttpInterceptor$BeforeSpanCallback;Z)V + public fun (Lio/sentry/IScopes;Lio/sentry/apollo3/SentryApollo3HttpInterceptor$BeforeSpanCallback;ZLjava/util/List;)V + public synthetic fun (Lio/sentry/IScopes;Lio/sentry/apollo3/SentryApollo3HttpInterceptor$BeforeSpanCallback;ZLjava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun dispose ()V public fun intercept (Lcom/apollographql/apollo3/api/http/HttpRequest;Lcom/apollographql/apollo3/network/http/HttpInterceptorChain;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } @@ -40,12 +40,12 @@ public final class io/sentry/apollo3/SentryApollo3Interceptor : com/apollographq public final class io/sentry/apollo3/SentryApolloBuilderExtensionsKt { public static final fun sentryTracing (Lcom/apollographql/apollo3/ApolloClient$Builder;)Lcom/apollographql/apollo3/ApolloClient$Builder; - public static final fun sentryTracing (Lcom/apollographql/apollo3/ApolloClient$Builder;Lio/sentry/IHub;)Lcom/apollographql/apollo3/ApolloClient$Builder; - public static final fun sentryTracing (Lcom/apollographql/apollo3/ApolloClient$Builder;Lio/sentry/IHub;Z)Lcom/apollographql/apollo3/ApolloClient$Builder; - public static final fun sentryTracing (Lcom/apollographql/apollo3/ApolloClient$Builder;Lio/sentry/IHub;ZLjava/util/List;)Lcom/apollographql/apollo3/ApolloClient$Builder; - public static final fun sentryTracing (Lcom/apollographql/apollo3/ApolloClient$Builder;Lio/sentry/IHub;ZLjava/util/List;Lio/sentry/apollo3/SentryApollo3HttpInterceptor$BeforeSpanCallback;)Lcom/apollographql/apollo3/ApolloClient$Builder; + public static final fun sentryTracing (Lcom/apollographql/apollo3/ApolloClient$Builder;Lio/sentry/IScopes;)Lcom/apollographql/apollo3/ApolloClient$Builder; + public static final fun sentryTracing (Lcom/apollographql/apollo3/ApolloClient$Builder;Lio/sentry/IScopes;Z)Lcom/apollographql/apollo3/ApolloClient$Builder; + public static final fun sentryTracing (Lcom/apollographql/apollo3/ApolloClient$Builder;Lio/sentry/IScopes;ZLjava/util/List;)Lcom/apollographql/apollo3/ApolloClient$Builder; + public static final fun sentryTracing (Lcom/apollographql/apollo3/ApolloClient$Builder;Lio/sentry/IScopes;ZLjava/util/List;Lio/sentry/apollo3/SentryApollo3HttpInterceptor$BeforeSpanCallback;)Lcom/apollographql/apollo3/ApolloClient$Builder; public static final fun sentryTracing (Lcom/apollographql/apollo3/ApolloClient$Builder;ZLjava/util/List;Lio/sentry/apollo3/SentryApollo3HttpInterceptor$BeforeSpanCallback;)Lcom/apollographql/apollo3/ApolloClient$Builder; - public static synthetic fun sentryTracing$default (Lcom/apollographql/apollo3/ApolloClient$Builder;Lio/sentry/IHub;ZLjava/util/List;Lio/sentry/apollo3/SentryApollo3HttpInterceptor$BeforeSpanCallback;ILjava/lang/Object;)Lcom/apollographql/apollo3/ApolloClient$Builder; + public static synthetic fun sentryTracing$default (Lcom/apollographql/apollo3/ApolloClient$Builder;Lio/sentry/IScopes;ZLjava/util/List;Lio/sentry/apollo3/SentryApollo3HttpInterceptor$BeforeSpanCallback;ILjava/lang/Object;)Lcom/apollographql/apollo3/ApolloClient$Builder; public static synthetic fun sentryTracing$default (Lcom/apollographql/apollo3/ApolloClient$Builder;ZLjava/util/List;Lio/sentry/apollo3/SentryApollo3HttpInterceptor$BeforeSpanCallback;ILjava/lang/Object;)Lcom/apollographql/apollo3/ApolloClient$Builder; } diff --git a/sentry-apollo-3/src/main/java/io/sentry/apollo3/SentryApollo3HttpInterceptor.kt b/sentry-apollo-3/src/main/java/io/sentry/apollo3/SentryApollo3HttpInterceptor.kt index 08cab179a5..10e56ce7be 100644 --- a/sentry-apollo-3/src/main/java/io/sentry/apollo3/SentryApollo3HttpInterceptor.kt +++ b/sentry-apollo-3/src/main/java/io/sentry/apollo3/SentryApollo3HttpInterceptor.kt @@ -11,9 +11,9 @@ import com.apollographql.apollo3.network.http.HttpInterceptorChain import io.sentry.BaggageHeader import io.sentry.Breadcrumb import io.sentry.Hint -import io.sentry.HubAdapter -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ISpan +import io.sentry.ScopesAdapter import io.sentry.SentryEvent import io.sentry.SentryIntegrationPackageStorage import io.sentry.SentryLevel @@ -41,7 +41,7 @@ import java.util.Locale private const val TRACE_ORIGIN = "auto.graphql.apollo3" class SentryApollo3HttpInterceptor @JvmOverloads constructor( - @ApiStatus.Internal private val hub: IHub = HubAdapter.getInstance(), + @ApiStatus.Internal private val scopes: IScopes = ScopesAdapter.getInstance(), private val beforeSpan: BeforeSpanCallback? = null, private val captureFailedRequests: Boolean = DEFAULT_CAPTURE_FAILED_REQUESTS, private val failedRequestTargets: List = listOf(DEFAULT_PROPAGATION_TARGETS) @@ -65,7 +65,7 @@ class SentryApollo3HttpInterceptor @JvmOverloads constructor( request: HttpRequest, chain: HttpInterceptorChain ): HttpResponse { - val activeSpan = if (Platform.isAndroid()) hub.transaction else hub.span + val activeSpan = if (Platform.isAndroid()) scopes.transaction else scopes.span val operationName = getHeader(HEADER_APOLLO_OPERATION_NAME, request.headers) val operationType = decodeHeaderValue(request, SENTRY_APOLLO_3_OPERATION_TYPE) @@ -77,7 +77,7 @@ class SentryApollo3HttpInterceptor @JvmOverloads constructor( span = startChild(request, activeSpan, operationName, operationType, operationId) } - val modifiedRequest = maybeAddTracingHeaders(hub, request, span) + val modifiedRequest = maybeAddTracingHeaders(scopes, request, span) var httpResponse: HttpResponse? = null var statusCode: Int? = null @@ -91,7 +91,7 @@ class SentryApollo3HttpInterceptor @JvmOverloads constructor( return httpResponse } catch (e: Throwable) { - // https://github.com/apollographql/apollo-kotlin/issues/4711 will change error handling in v4 + // https://gitscopes.com/apollographql/apollo-kotlin/issues/4711 will change error handling in v4 when (e) { is ApolloHttpException -> { statusCode = e.statusCode @@ -117,10 +117,10 @@ class SentryApollo3HttpInterceptor @JvmOverloads constructor( } } - private fun maybeAddTracingHeaders(hub: IHub, request: HttpRequest, span: ISpan?): HttpRequest { + private fun maybeAddTracingHeaders(scopes: IScopes, request: HttpRequest, span: ISpan?): HttpRequest { var cleanedHeaders = removeSentryInternalHeaders(request.headers).toMutableList() - TracingUtils.traceIfAllowed(hub, request.url, request.headers.filter { it.name == BaggageHeader.BAGGAGE_HEADER }.map { it.value }, span)?.let { + TracingUtils.traceIfAllowed(scopes, request.url, request.headers.filter { it.name == BaggageHeader.BAGGAGE_HEADER }.map { it.value }, span)?.let { cleanedHeaders.add(HttpHeader(it.sentryTraceHeader.name, it.sentryTraceHeader.value)) it.baggageHeader?.let { baggageHeader -> cleanedHeaders = cleanedHeaders.filterNot { it.name == BaggageHeader.BAGGAGE_HEADER }.toMutableList().apply { @@ -179,7 +179,7 @@ class SentryApollo3HttpInterceptor @JvmOverloads constructor( try { String(Base64.decode(it, Base64.NO_WRAP)) } catch (e: Throwable) { - hub.options.logger.log( + scopes.options.logger.log( SentryLevel.ERROR, "Error decoding internal apolloHeader $headerName", e @@ -218,7 +218,7 @@ class SentryApollo3HttpInterceptor @JvmOverloads constructor( span.spanContext.sampled = false } } catch (e: Throwable) { - hub.options.logger.log( + scopes.options.logger.log( SentryLevel.ERROR, "An error occurred while executing beforeSpan on ApolloInterceptor", e @@ -256,7 +256,7 @@ class SentryApollo3HttpInterceptor @JvmOverloads constructor( hint.set(APOLLO_RESPONSE, httpResponse) } - hub.addBreadcrumb(breadcrumb, hint) + scopes.addBreadcrumb(breadcrumb, hint) } // Extensions @@ -273,7 +273,7 @@ class SentryApollo3HttpInterceptor @JvmOverloads constructor( private fun getHeaders(headers: List): MutableMap? { // Headers are only sent if isSendDefaultPii is enabled due to PII - if (!hub.options.isSendDefaultPii) { + if (!scopes.options.isSendDefaultPii) { return null } @@ -311,7 +311,7 @@ class SentryApollo3HttpInterceptor @JvmOverloads constructor( val body = try { response.body?.peek()?.readUtf8() ?: "" } catch (e: Throwable) { - hub.options.logger.log( + scopes.options.logger.log( SentryLevel.ERROR, "Error reading the response body.", e @@ -368,7 +368,7 @@ class SentryApollo3HttpInterceptor @JvmOverloads constructor( urlDetails.applyToRequest(this) // Cookie is only sent if isSendDefaultPii is enabled cookies = - if (hub.options.isSendDefaultPii) getHeader("Cookie", request.headers) else null + if (scopes.options.isSendDefaultPii) getHeader("Cookie", request.headers) else null method = request.method.name headers = getHeaders(request.headers) apiTarget = "graphql" @@ -382,7 +382,7 @@ class SentryApollo3HttpInterceptor @JvmOverloads constructor( it.writeTo(buffer) data = buffer.readUtf8() } catch (e: Throwable) { - hub.options.logger.log( + scopes.options.logger.log( SentryLevel.ERROR, "Error reading the request body.", e @@ -396,7 +396,7 @@ class SentryApollo3HttpInterceptor @JvmOverloads constructor( val sentryResponse = Response().apply { // Set-Cookie is only sent if isSendDefaultPii is enabled due to PII - cookies = if (hub.options.isSendDefaultPii) { + cookies = if (scopes.options.isSendDefaultPii) { getHeader( "Set-Cookie", response.headers @@ -419,9 +419,9 @@ class SentryApollo3HttpInterceptor @JvmOverloads constructor( event.contexts.setResponse(sentryResponse) event.fingerprints = fingerprints - hub.captureEvent(event, hint) + scopes.captureEvent(event, hint) } catch (e: Throwable) { - hub.options.logger.log( + scopes.options.logger.log( SentryLevel.ERROR, "Error capturing the GraphQL error.", e diff --git a/sentry-apollo-3/src/main/java/io/sentry/apollo3/SentryApolloBuilderExtensions.kt b/sentry-apollo-3/src/main/java/io/sentry/apollo3/SentryApolloBuilderExtensions.kt index 2cdbc148fb..b40b1c183d 100644 --- a/sentry-apollo-3/src/main/java/io/sentry/apollo3/SentryApolloBuilderExtensions.kt +++ b/sentry-apollo-3/src/main/java/io/sentry/apollo3/SentryApolloBuilderExtensions.kt @@ -1,14 +1,14 @@ package io.sentry.apollo3 import com.apollographql.apollo3.ApolloClient -import io.sentry.HubAdapter -import io.sentry.IHub +import io.sentry.IScopes +import io.sentry.ScopesAdapter import io.sentry.SentryOptions.DEFAULT_PROPAGATION_TARGETS import io.sentry.apollo3.SentryApollo3HttpInterceptor.Companion.DEFAULT_CAPTURE_FAILED_REQUESTS @JvmOverloads fun ApolloClient.Builder.sentryTracing( - hub: IHub = HubAdapter.getInstance(), + scopes: IScopes = ScopesAdapter.getInstance(), captureFailedRequests: Boolean = DEFAULT_CAPTURE_FAILED_REQUESTS, failedRequestTargets: List = listOf(DEFAULT_PROPAGATION_TARGETS), beforeSpan: SentryApollo3HttpInterceptor.BeforeSpanCallback? = null @@ -16,7 +16,7 @@ fun ApolloClient.Builder.sentryTracing( addInterceptor(SentryApollo3Interceptor()) addHttpInterceptor( SentryApollo3HttpInterceptor( - hub = hub, + scopes = scopes, captureFailedRequests = captureFailedRequests, failedRequestTargets = failedRequestTargets, beforeSpan = beforeSpan @@ -31,7 +31,7 @@ fun ApolloClient.Builder.sentryTracing( beforeSpan: SentryApollo3HttpInterceptor.BeforeSpanCallback? = null ): ApolloClient.Builder { return sentryTracing( - hub = HubAdapter.getInstance(), + scopes = ScopesAdapter.getInstance(), captureFailedRequests = captureFailedRequests, failedRequestTargets = failedRequestTargets, beforeSpan = beforeSpan diff --git a/sentry-apollo-3/src/test/java/io/sentry/apollo3/SentryApollo3InterceptorClientErrors.kt b/sentry-apollo-3/src/test/java/io/sentry/apollo3/SentryApollo3InterceptorClientErrors.kt index 40406b77b5..b3f8b6d57e 100644 --- a/sentry-apollo-3/src/test/java/io/sentry/apollo3/SentryApollo3InterceptorClientErrors.kt +++ b/sentry-apollo-3/src/test/java/io/sentry/apollo3/SentryApollo3InterceptorClientErrors.kt @@ -5,7 +5,7 @@ import com.apollographql.apollo3.api.http.HttpRequest import com.apollographql.apollo3.api.http.HttpResponse import com.apollographql.apollo3.exception.ApolloException import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryIntegrationPackageStorage import io.sentry.SentryOptions import io.sentry.SentryOptions.DEFAULT_PROPAGATION_TARGETS @@ -35,7 +35,7 @@ import kotlin.test.assertTrue class SentryApollo3InterceptorClientErrors { class Fixture { val server = MockWebServer() - lateinit var hub: IHub + lateinit var scopes: IScopes private val responseBodyOk = """{ @@ -75,7 +75,7 @@ class SentryApollo3InterceptorClientErrors { ): ApolloClient { SentryIntegrationPackageStorage.getInstance().clearStorage() - hub = mock().apply { + scopes = mock().apply { whenever(options).thenReturn( SentryOptions().apply { dsn = "https://key@sentry.io/proj" @@ -84,7 +84,7 @@ class SentryApollo3InterceptorClientErrors { } ) } - whenever(hub.captureEvent(any(), any())).thenReturn(SentryId.EMPTY_ID) + whenever(scopes.captureEvent(any(), any())).thenReturn(SentryId.EMPTY_ID) val response = MockResponse() .setBody(responseBody) @@ -102,7 +102,7 @@ class SentryApollo3InterceptorClientErrors { val builder = ApolloClient.Builder() .serverUrl(server.url("?myQuery=query#myFragment").toString()) .sentryTracing( - hub = hub, + scopes = scopes, captureFailedRequests = captureFailedRequests, failedRequestTargets = failedRequestTargets ) @@ -123,7 +123,7 @@ class SentryApollo3InterceptorClientErrors { val sut = fixture.getSut(captureFailedRequests = false, responseBody = fixture.responseBodyNotOk) executeQuery(sut) - verify(fixture.hub, never()).captureEvent(any(), any()) + verify(fixture.scopes, never()).captureEvent(any(), any()) } @Test @@ -132,7 +132,7 @@ class SentryApollo3InterceptorClientErrors { fixture.getSut(responseBody = fixture.responseBodyNotOk) executeQuery(sut) - verify(fixture.hub).captureEvent(any(), any()) + verify(fixture.scopes).captureEvent(any(), any()) } // endregion @@ -165,7 +165,7 @@ class SentryApollo3InterceptorClientErrors { ) executeQuery(sut) - verify(fixture.hub, never()).captureEvent(any(), any()) + verify(fixture.scopes, never()).captureEvent(any(), any()) } @Test @@ -174,7 +174,7 @@ class SentryApollo3InterceptorClientErrors { fixture.getSut(responseBody = fixture.responseBodyNotOk) executeQuery(sut) - verify(fixture.hub).captureEvent(any(), any()) + verify(fixture.scopes).captureEvent(any(), any()) } // endregion @@ -187,7 +187,7 @@ class SentryApollo3InterceptorClientErrors { fixture.getSut(responseBody = fixture.responseBodyNotOk) executeQuery(sut) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { val throwable = (it.throwableMechanism as ExceptionMechanismException) assertEquals("SentryApollo3Interceptor", throwable.exceptionMechanism.type) @@ -202,7 +202,7 @@ class SentryApollo3InterceptorClientErrors { fixture.getSut(responseBody = fixture.responseBodyNotOk) executeQuery(sut) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { val throwable = (it.throwableMechanism as ExceptionMechanismException) assertEquals("GraphQL Request failed, name: LaunchDetails, type: query", throwable.throwable.message) @@ -217,7 +217,7 @@ class SentryApollo3InterceptorClientErrors { fixture.getSut(responseBody = fixture.responseBodyNotOk) executeQuery(sut) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { val throwable = (it.throwableMechanism as ExceptionMechanismException) assertTrue(throwable.isSnapshot) @@ -238,7 +238,7 @@ class SentryApollo3InterceptorClientErrors { {"operationName":"LaunchDetails","variables":{"id":"83"},"query":"query LaunchDetails($escapeDolar: ID!) { launch(id: $escapeDolar) { id site mission { name missionPatch(size: LARGE) } rocket { name type } } }"} """.trimIndent() - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { val request = it.request!! @@ -262,7 +262,7 @@ class SentryApollo3InterceptorClientErrors { fixture.getSut(responseBody = fixture.responseBodyNotOk, sendDefaultPii = true) executeQuery(sut) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { val request = it.request!! @@ -280,7 +280,7 @@ class SentryApollo3InterceptorClientErrors { fixture.getSut(responseBody = fixture.responseBodyNotOk) executeQuery(sut) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { val response = it.contexts.response!! @@ -300,7 +300,7 @@ class SentryApollo3InterceptorClientErrors { fixture.getSut(responseBody = fixture.responseBodyNotOk, sendDefaultPii = true) executeQuery(sut) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { val response = it.contexts.response!! @@ -318,7 +318,7 @@ class SentryApollo3InterceptorClientErrors { fixture.getSut(responseBody = fixture.responseBodyNotOk) executeQuery(sut) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { assertEquals(listOf("LaunchDetails", "query", "200"), it.fingerprints) }, @@ -337,7 +337,7 @@ class SentryApollo3InterceptorClientErrors { executeQuery(sut) // HttpInterceptor does not throw for >= 400 - verify(fixture.hub).captureEvent(any(), any()) + verify(fixture.scopes).captureEvent(any(), any()) } @Test @@ -345,7 +345,7 @@ class SentryApollo3InterceptorClientErrors { val sut = fixture.getSut(responseBody = fixture.responseBodyNotOk) - whenever(fixture.hub.captureEvent(any(), any())).thenThrow(RuntimeException()) + whenever(fixture.scopes.captureEvent(any(), any())).thenThrow(RuntimeException()) executeQuery(sut) } @@ -360,7 +360,7 @@ class SentryApollo3InterceptorClientErrors { fixture.getSut(responseBody = fixture.responseBodyNotOk) executeQuery(sut) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( any(), check { val request = it.get(TypeCheckHint.APOLLO_REQUEST) diff --git a/sentry-apollo-3/src/test/java/io/sentry/apollo3/SentryApollo3InterceptorTest.kt b/sentry-apollo-3/src/test/java/io/sentry/apollo3/SentryApollo3InterceptorTest.kt index 44d8bfd624..3b836f45b9 100644 --- a/sentry-apollo-3/src/test/java/io/sentry/apollo3/SentryApollo3InterceptorTest.kt +++ b/sentry-apollo-3/src/test/java/io/sentry/apollo3/SentryApollo3InterceptorTest.kt @@ -9,7 +9,7 @@ import com.apollographql.apollo3.network.http.HttpInterceptor import com.apollographql.apollo3.network.http.HttpInterceptorChain import io.sentry.BaggageHeader import io.sentry.Breadcrumb -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ITransaction import io.sentry.Scope import io.sentry.ScopeCallback @@ -57,11 +57,11 @@ class SentryApollo3InterceptorTest { sdkVersion = SdkVersion("test", "1.2.3") } val scope = Scope(options) - val hub = mock().also { + val scopes = mock().also { whenever(it.options).thenReturn(options) doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(it).configureScope(any()) } - private var httpInterceptor = SentryApollo3HttpInterceptor(hub, captureFailedRequests = false) + private var httpInterceptor = SentryApollo3HttpInterceptor(scopes, captureFailedRequests = false) @SuppressWarnings("LongParameterList") fun getSut( @@ -93,7 +93,7 @@ class SentryApollo3InterceptorTest { ) if (beforeSpan != null) { - httpInterceptor = SentryApollo3HttpInterceptor(hub, beforeSpan, captureFailedRequests = false) + httpInterceptor = SentryApollo3HttpInterceptor(scopes, beforeSpan, captureFailedRequests = false) } val builder = ApolloClient.Builder() @@ -124,7 +124,7 @@ class SentryApollo3InterceptorTest { fun `creates a span around the successful request`() { executeQuery() - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertTransactionDetails(it, httpStatusCode = 200) assertEquals(SpanStatus.OK, it.spans.first().status) @@ -139,7 +139,7 @@ class SentryApollo3InterceptorTest { fun `creates a span around the failed request`() { executeQuery(fixture.getSut(httpStatusCode = 403)) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertTransactionDetails(it, httpStatusCode = 403) assertEquals(SpanStatus.PERMISSION_DENIED, it.spans.first().status) @@ -159,7 +159,7 @@ class SentryApollo3InterceptorTest { } executeQuery(fixture.getSut(interceptor = failingInterceptor)) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertTransactionDetails(it, httpStatusCode = 404, contentLength = null) assertEquals("POST", it.spans.first().data?.get(SpanDataConvention.HTTP_METHOD_KEY)) @@ -176,7 +176,7 @@ class SentryApollo3InterceptorTest { fun `creates a span around the request failing with network error`() { executeQuery(fixture.getSut(socketPolicy = SocketPolicy.DISCONNECT_DURING_REQUEST_BODY)) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertTransactionDetails(it, httpStatusCode = null, contentLength = null) assertEquals(SpanStatus.INTERNAL_ERROR, it.spans.first().status) @@ -241,7 +241,7 @@ class SentryApollo3InterceptorTest { ) ) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertEquals(1, it.spans.size) val httpClientSpan = it.spans.first() @@ -261,7 +261,7 @@ class SentryApollo3InterceptorTest { ) ) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertEquals(0, it.spans.size) }, @@ -281,7 +281,7 @@ class SentryApollo3InterceptorTest { ) ) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertEquals(1, it.spans.size) }, @@ -294,7 +294,7 @@ class SentryApollo3InterceptorTest { @Test fun `adds breadcrumb when http calls succeeds`() { executeQuery(fixture.getSut()) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) // response_body_size is added but mock webserver returns 0 always @@ -309,9 +309,9 @@ class SentryApollo3InterceptorTest { @Test fun `sets SDKVersion Info`() { - assertNotNull(fixture.hub.options.sdkVersion) - assert(fixture.hub.options.sdkVersion!!.integrationSet.contains("Apollo3")) - val packageInfo = fixture.hub.options.sdkVersion!!.packageSet.firstOrNull { pkg -> pkg.name == "maven:io.sentry:sentry-apollo-3" } + assertNotNull(fixture.scopes.options.sdkVersion) + assert(fixture.scopes.options.sdkVersion!!.integrationSet.contains("Apollo3")) + val packageInfo = fixture.scopes.options.sdkVersion!!.packageSet.firstOrNull { pkg -> pkg.name == "maven:io.sentry:sentry-apollo-3" } assertNotNull(packageInfo) assert(packageInfo.version == BuildConfig.VERSION_NAME) } @@ -320,14 +320,14 @@ class SentryApollo3InterceptorTest { fun `attaches to root transaction on Android`() { Apollo3PlatformTestManipulator.pretendIsAndroid(true) executeQuery(fixture.getSut()) - verify(fixture.hub).transaction + verify(fixture.scopes).transaction } @Test fun `attaches to child span on non-Android`() { Apollo3PlatformTestManipulator.pretendIsAndroid(false) executeQuery(fixture.getSut()) - verify(fixture.hub).span + verify(fixture.scopes).span } private fun assertTransactionDetails(it: SentryTransaction, httpStatusCode: Int? = 200, contentLength: Long? = 0L) { @@ -350,9 +350,9 @@ class SentryApollo3InterceptorTest { private fun executeQuery(sut: ApolloClient = fixture.getSut(), isSpanActive: Boolean = true, id: String = "83") = runBlocking { var tx: ITransaction? = null if (isSpanActive) { - tx = SentryTracer(TransactionContext("op", "desc", TracesSamplingDecision(true)), fixture.hub) - whenever(fixture.hub.transaction).thenReturn(tx) - whenever(fixture.hub.span).thenReturn(tx) + tx = SentryTracer(TransactionContext("op", "desc", TracesSamplingDecision(true)), fixture.scopes) + whenever(fixture.scopes.transaction).thenReturn(tx) + whenever(fixture.scopes.span).thenReturn(tx) } val coroutine = launch { diff --git a/sentry-apollo-3/src/test/java/io/sentry/apollo3/SentryApollo3InterceptorWithVariablesTest.kt b/sentry-apollo-3/src/test/java/io/sentry/apollo3/SentryApollo3InterceptorWithVariablesTest.kt index 81775efc18..3ac3d80d7d 100644 --- a/sentry-apollo-3/src/test/java/io/sentry/apollo3/SentryApollo3InterceptorWithVariablesTest.kt +++ b/sentry-apollo-3/src/test/java/io/sentry/apollo3/SentryApollo3InterceptorWithVariablesTest.kt @@ -3,7 +3,7 @@ package io.sentry.apollo3 import com.apollographql.apollo3.ApolloClient import com.apollographql.apollo3.exception.ApolloException import io.sentry.Breadcrumb -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ITransaction import io.sentry.SentryOptions import io.sentry.SentryTracer @@ -32,7 +32,7 @@ class SentryApollo3InterceptorWithVariablesTest { class Fixture { val server = MockWebServer() - val hub = mock() + val scopes = mock() @SuppressWarnings("LongParameterList") fun getSut( @@ -54,7 +54,7 @@ class SentryApollo3InterceptorWithVariablesTest { socketPolicy: SocketPolicy = SocketPolicy.KEEP_OPEN, beforeSpan: BeforeSpanCallback? = null ): ApolloClient { - whenever(hub.options).thenReturn( + whenever(scopes.options).thenReturn( SentryOptions().apply { dsn = "http://key@localhost/proj" } @@ -68,7 +68,7 @@ class SentryApollo3InterceptorWithVariablesTest { ) return ApolloClient.Builder().serverUrl(server.url("/").toString()) - .sentryTracing(hub = hub, beforeSpan = beforeSpan, captureFailedRequests = false) + .sentryTracing(scopes = scopes, beforeSpan = beforeSpan, captureFailedRequests = false) .build() } } @@ -79,7 +79,7 @@ class SentryApollo3InterceptorWithVariablesTest { fun `creates a span around the successful request`() { executeQuery() - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertTransactionDetails(it) assertEquals(SpanStatus.OK, it.spans.first().status) @@ -94,7 +94,7 @@ class SentryApollo3InterceptorWithVariablesTest { fun `creates a span around the failed request`() { executeQuery(fixture.getSut(httpStatusCode = 403)) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertTransactionDetails(it) assertEquals(SpanStatus.PERMISSION_DENIED, it.spans.first().status) @@ -109,7 +109,7 @@ class SentryApollo3InterceptorWithVariablesTest { fun `creates a span around the request failing with network error`() { executeQuery(fixture.getSut(socketPolicy = SocketPolicy.DISCONNECT_DURING_REQUEST_BODY)) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertTransactionDetails(it) assertEquals(SpanStatus.INTERNAL_ERROR, it.spans.first().status) @@ -124,7 +124,7 @@ class SentryApollo3InterceptorWithVariablesTest { fun `handles non-ascii header values correctly`() { executeQuery(id = "á") - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertTransactionDetails(it) assertEquals(SpanStatus.OK, it.spans.first().status) @@ -138,7 +138,7 @@ class SentryApollo3InterceptorWithVariablesTest { @Test fun `adds breadcrumb when http calls succeeds`() { executeQuery(fixture.getSut()) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) // response_body_size is added but mock webserver returns 0 always @@ -173,8 +173,8 @@ class SentryApollo3InterceptorWithVariablesTest { private fun executeQuery(sut: ApolloClient = fixture.getSut(), isSpanActive: Boolean = true, id: String = "83") = runBlocking { var tx: ITransaction? = null if (isSpanActive) { - tx = SentryTracer(TransactionContext("op", "desc", TracesSamplingDecision(true)), fixture.hub) - whenever(fixture.hub.span).thenReturn(tx) + tx = SentryTracer(TransactionContext("op", "desc", TracesSamplingDecision(true)), fixture.scopes) + whenever(fixture.scopes.span).thenReturn(tx) } val coroutine = launch { diff --git a/sentry-apollo/api/sentry-apollo.api b/sentry-apollo/api/sentry-apollo.api index 8c18bce06e..63eac6a193 100644 --- a/sentry-apollo/api/sentry-apollo.api +++ b/sentry-apollo/api/sentry-apollo.api @@ -5,9 +5,9 @@ public final class io/sentry/apollo/BuildConfig { public final class io/sentry/apollo/SentryApolloInterceptor : com/apollographql/apollo/interceptor/ApolloInterceptor { public fun ()V - public fun (Lio/sentry/IHub;)V - public fun (Lio/sentry/IHub;Lio/sentry/apollo/SentryApolloInterceptor$BeforeSpanCallback;)V - public synthetic fun (Lio/sentry/IHub;Lio/sentry/apollo/SentryApolloInterceptor$BeforeSpanCallback;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lio/sentry/IScopes;)V + public fun (Lio/sentry/IScopes;Lio/sentry/apollo/SentryApolloInterceptor$BeforeSpanCallback;)V + public synthetic fun (Lio/sentry/IScopes;Lio/sentry/apollo/SentryApolloInterceptor$BeforeSpanCallback;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun (Lio/sentry/apollo/SentryApolloInterceptor$BeforeSpanCallback;)V public fun dispose ()V public fun interceptAsync (Lcom/apollographql/apollo/interceptor/ApolloInterceptor$InterceptorRequest;Lcom/apollographql/apollo/interceptor/ApolloInterceptorChain;Ljava/util/concurrent/Executor;Lcom/apollographql/apollo/interceptor/ApolloInterceptor$CallBack;)V diff --git a/sentry-apollo/src/main/java/io/sentry/apollo/SentryApolloInterceptor.kt b/sentry-apollo/src/main/java/io/sentry/apollo/SentryApolloInterceptor.kt index faa8a549a9..fe5a6a4762 100644 --- a/sentry-apollo/src/main/java/io/sentry/apollo/SentryApolloInterceptor.kt +++ b/sentry-apollo/src/main/java/io/sentry/apollo/SentryApolloInterceptor.kt @@ -15,9 +15,9 @@ import com.apollographql.apollo.request.RequestHeaders import io.sentry.BaggageHeader import io.sentry.Breadcrumb import io.sentry.Hint -import io.sentry.HubAdapter -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ISpan +import io.sentry.ScopesAdapter import io.sentry.SentryIntegrationPackageStorage import io.sentry.SentryLevel import io.sentry.SpanDataConvention @@ -32,12 +32,12 @@ import java.util.concurrent.Executor private const val TRACE_ORIGIN = "auto.graphql.apollo" class SentryApolloInterceptor( - private val hub: IHub = HubAdapter.getInstance(), + private val scopes: IScopes = ScopesAdapter.getInstance(), private val beforeSpan: BeforeSpanCallback? = null ) : ApolloInterceptor { - constructor(hub: IHub) : this(hub, null) - constructor(beforeSpan: BeforeSpanCallback) : this(HubAdapter.getInstance(), beforeSpan) + constructor(scopes: IScopes) : this(scopes, null) + constructor(beforeSpan: BeforeSpanCallback) : this(ScopesAdapter.getInstance(), beforeSpan) init { addIntegrationToSdkVersion(javaClass) @@ -45,7 +45,7 @@ class SentryApolloInterceptor( } override fun interceptAsync(request: InterceptorRequest, chain: ApolloInterceptorChain, dispatcher: Executor, callBack: CallBack) { - val activeSpan = if (io.sentry.util.Platform.isAndroid()) hub.transaction else hub.span + val activeSpan = if (io.sentry.util.Platform.isAndroid()) scopes.transaction else scopes.span if (activeSpan == null) { val headers = addTracingHeaders(request, null) val modifiedRequest = request.toBuilder().requestHeaders(headers).build() @@ -115,10 +115,10 @@ class SentryApolloInterceptor( private fun addTracingHeaders(request: InterceptorRequest, span: ISpan?): RequestHeaders { val requestHeaderBuilder = request.requestHeaders.toBuilder() - if (hub.options.isTraceSampling) { + if (scopes.options.isTraceSampling) { // we have no access to URI, no way to verify tracing origins TracingUtils.trace( - hub, + scopes, listOf(request.requestHeaders.headerValue(BaggageHeader.BAGGAGE_HEADER)), span )?.let { tracingHeaders -> @@ -154,7 +154,7 @@ class SentryApolloInterceptor( try { newSpan = beforeSpan.execute(span, request, response) } catch (e: Exception) { - hub.options.logger.log(SentryLevel.ERROR, "An error occurred while executing beforeSpan on ApolloInterceptor", e) + scopes.options.logger.log(SentryLevel.ERROR, "An error occurred while executing beforeSpan on ApolloInterceptor", e) } } if (newSpan == null) { @@ -182,7 +182,7 @@ class SentryApolloInterceptor( set(APOLLO_REQUEST, httpRequest) set(APOLLO_RESPONSE, httpResponse) } - hub.addBreadcrumb(breadcrumb, hint) + scopes.addBreadcrumb(breadcrumb, hint) } } } diff --git a/sentry-apollo/src/test/java/io/sentry/apollo/SentryApolloInterceptorTest.kt b/sentry-apollo/src/test/java/io/sentry/apollo/SentryApolloInterceptorTest.kt index d22c2fd3e5..b1b118c334 100644 --- a/sentry-apollo/src/test/java/io/sentry/apollo/SentryApolloInterceptorTest.kt +++ b/sentry-apollo/src/test/java/io/sentry/apollo/SentryApolloInterceptorTest.kt @@ -5,7 +5,7 @@ import com.apollographql.apollo.coroutines.await import com.apollographql.apollo.exception.ApolloException import io.sentry.BaggageHeader import io.sentry.Breadcrumb -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ITransaction import io.sentry.Scope import io.sentry.ScopeCallback @@ -48,13 +48,13 @@ class SentryApolloInterceptorTest { sdkVersion = SdkVersion("test", "1.2.3") } val scope = Scope(options) - val hub = mock().also { + val scopes = mock().also { whenever(it.options).thenReturn(options) doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(it).configureScope( any() ) } - private var interceptor = SentryApolloInterceptor(hub) + private var interceptor = SentryApolloInterceptor(scopes) @SuppressWarnings("LongParameterList") fun getSut( @@ -84,7 +84,7 @@ class SentryApolloInterceptorTest { ) if (beforeSpan != null) { - interceptor = SentryApolloInterceptor(hub, beforeSpan) + interceptor = SentryApolloInterceptor(scopes, beforeSpan) } return ApolloClient.builder() .serverUrl(server.url("/")) @@ -104,7 +104,7 @@ class SentryApolloInterceptorTest { fun `creates a span around the successful request`() { executeQuery() - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertTransactionDetails(it) assertEquals(SpanStatus.OK, it.spans.first().status) @@ -120,7 +120,7 @@ class SentryApolloInterceptorTest { fun `creates a span around the failed request`() { executeQuery(fixture.getSut(httpStatusCode = 403)) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertTransactionDetails(it) assertEquals(SpanStatus.PERMISSION_DENIED, it.spans.first().status) @@ -138,7 +138,7 @@ class SentryApolloInterceptorTest { fun `creates a span around the request failing with network error`() { executeQuery(fixture.getSut(socketPolicy = SocketPolicy.DISCONNECT_DURING_REQUEST_BODY)) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertTransactionDetails(it) assertEquals(SpanStatus.INTERNAL_ERROR, it.spans.first().status) @@ -176,7 +176,7 @@ class SentryApolloInterceptorTest { } ) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertEquals(1, it.spans.size) val httpClientSpan = it.spans.first() @@ -196,7 +196,7 @@ class SentryApolloInterceptorTest { } ) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertTrue(it.spans.isEmpty()) }, @@ -212,7 +212,7 @@ class SentryApolloInterceptorTest { fixture.getSut { _, _, _ -> throw RuntimeException() } ) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertEquals(1, it.spans.size) }, @@ -225,7 +225,7 @@ class SentryApolloInterceptorTest { @Test fun `adds breadcrumb when http calls succeeds`() { executeQuery() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(280L, it.data["response_body_size"]) @@ -237,9 +237,9 @@ class SentryApolloInterceptorTest { @Test fun `sets SDKVersion Info`() { - assertNotNull(fixture.hub.options.sdkVersion) - assert(fixture.hub.options.sdkVersion!!.integrationSet.contains("Apollo")) - val packageInfo = fixture.hub.options.sdkVersion!!.packageSet.firstOrNull { pkg -> pkg.name == "maven:io.sentry:sentry-apollo" } + assertNotNull(fixture.scopes.options.sdkVersion) + assert(fixture.scopes.options.sdkVersion!!.integrationSet.contains("Apollo")) + val packageInfo = fixture.scopes.options.sdkVersion!!.packageSet.firstOrNull { pkg -> pkg.name == "maven:io.sentry:sentry-apollo" } assertNotNull(packageInfo) assert(packageInfo.version == BuildConfig.VERSION_NAME) } @@ -248,14 +248,14 @@ class SentryApolloInterceptorTest { fun `attaches to root transaction on Android`() { ApolloPlatformTestManipulator.pretendIsAndroid(true) executeQuery(fixture.getSut()) - verify(fixture.hub).transaction + verify(fixture.scopes).transaction } @Test fun `attaches to child span on non-Android`() { ApolloPlatformTestManipulator.pretendIsAndroid(false) executeQuery(fixture.getSut()) - verify(fixture.hub).span + verify(fixture.scopes).span } private fun assertTransactionDetails(it: SentryTransaction) { @@ -273,9 +273,9 @@ class SentryApolloInterceptorTest { private fun executeQuery(sut: ApolloClient = fixture.getSut(), isSpanActive: Boolean = true) = runBlocking { var tx: ITransaction? = null if (isSpanActive) { - tx = SentryTracer(TransactionContext("op", "desc", TracesSamplingDecision(true)), fixture.hub) - whenever(fixture.hub.transaction).thenReturn(tx) - whenever(fixture.hub.span).thenReturn(tx) + tx = SentryTracer(TransactionContext("op", "desc", TracesSamplingDecision(true)), fixture.scopes) + whenever(fixture.scopes.transaction).thenReturn(tx) + whenever(fixture.scopes.span).thenReturn(tx) } val coroutine = launch { diff --git a/sentry-graphql/api/sentry-graphql.api b/sentry-graphql/api/sentry-graphql.api index 57c253e23c..d119256010 100644 --- a/sentry-graphql/api/sentry-graphql.api +++ b/sentry-graphql/api/sentry-graphql.api @@ -9,10 +9,11 @@ public final class io/sentry/graphql/ExceptionReporter { } public final class io/sentry/graphql/ExceptionReporter$ExceptionDetails { - public fun (Lio/sentry/IHub;Lgraphql/execution/instrumentation/parameters/InstrumentationExecutionParameters;Z)V - public fun (Lio/sentry/IHub;Lgraphql/schema/DataFetchingEnvironment;Z)V - public fun getHub ()Lio/sentry/IHub; + public fun (Lio/sentry/IScopes;Lgraphql/execution/instrumentation/parameters/InstrumentationExecutionParameters;Z)V + public fun (Lio/sentry/IScopes;Lgraphql/schema/DataFetchingEnvironment;Z)V + public fun getHub ()Lio/sentry/IScopes; public fun getQuery ()Ljava/lang/String; + public fun getScopes ()Lio/sentry/IScopes; public fun getVariables ()Ljava/util/Map; public fun isSubscription ()Z } @@ -26,19 +27,19 @@ public final class io/sentry/graphql/GraphqlStringUtils { public final class io/sentry/graphql/NoOpSubscriptionHandler : io/sentry/graphql/SentrySubscriptionHandler { public static fun getInstance ()Lio/sentry/graphql/NoOpSubscriptionHandler; - public fun onSubscriptionResult (Ljava/lang/Object;Lio/sentry/IHub;Lio/sentry/graphql/ExceptionReporter;Lgraphql/execution/instrumentation/parameters/InstrumentationFieldFetchParameters;)Ljava/lang/Object; + public fun onSubscriptionResult (Ljava/lang/Object;Lio/sentry/IScopes;Lio/sentry/graphql/ExceptionReporter;Lgraphql/execution/instrumentation/parameters/InstrumentationFieldFetchParameters;)Ljava/lang/Object; } public final class io/sentry/graphql/SentryDataFetcherExceptionHandler : graphql/execution/DataFetcherExceptionHandler { public fun (Lgraphql/execution/DataFetcherExceptionHandler;)V - public fun (Lio/sentry/IHub;Lgraphql/execution/DataFetcherExceptionHandler;)V + public fun (Lio/sentry/IScopes;Lgraphql/execution/DataFetcherExceptionHandler;)V public fun handleException (Lgraphql/execution/DataFetcherExceptionHandlerParameters;)Ljava/util/concurrent/CompletableFuture; public fun onException (Lgraphql/execution/DataFetcherExceptionHandlerParameters;)Lgraphql/execution/DataFetcherExceptionHandlerResult; } public final class io/sentry/graphql/SentryGenericDataFetcherExceptionHandler : graphql/execution/DataFetcherExceptionHandler { public fun (Lgraphql/execution/DataFetcherExceptionHandler;)V - public fun (Lio/sentry/IHub;Lgraphql/execution/DataFetcherExceptionHandler;)V + public fun (Lio/sentry/IScopes;Lgraphql/execution/DataFetcherExceptionHandler;)V public fun handleException (Lgraphql/execution/DataFetcherExceptionHandlerParameters;)Ljava/util/concurrent/CompletableFuture; public fun onException (Lgraphql/execution/DataFetcherExceptionHandlerParameters;)Lgraphql/execution/DataFetcherExceptionHandlerResult; } @@ -51,9 +52,10 @@ public final class io/sentry/graphql/SentryGraphqlExceptionHandler { public final class io/sentry/graphql/SentryInstrumentation : graphql/execution/instrumentation/SimpleInstrumentation { public static final field SENTRY_EXCEPTIONS_CONTEXT_KEY Ljava/lang/String; public static final field SENTRY_HUB_CONTEXT_KEY Ljava/lang/String; + public static final field SENTRY_SCOPES_CONTEXT_KEY Ljava/lang/String; public fun ()V - public fun (Lio/sentry/IHub;)V - public fun (Lio/sentry/IHub;Lio/sentry/graphql/SentryInstrumentation$BeforeSpanCallback;)V + public fun (Lio/sentry/IScopes;)V + public fun (Lio/sentry/IScopes;Lio/sentry/graphql/SentryInstrumentation$BeforeSpanCallback;)V public fun (Lio/sentry/graphql/SentryInstrumentation$BeforeSpanCallback;)V public fun (Lio/sentry/graphql/SentryInstrumentation$BeforeSpanCallback;Lio/sentry/graphql/SentrySubscriptionHandler;Lio/sentry/graphql/ExceptionReporter;Ljava/util/List;)V public fun (Lio/sentry/graphql/SentryInstrumentation$BeforeSpanCallback;Lio/sentry/graphql/SentrySubscriptionHandler;Z)V @@ -71,6 +73,6 @@ public abstract interface class io/sentry/graphql/SentryInstrumentation$BeforeSp } public abstract interface class io/sentry/graphql/SentrySubscriptionHandler { - public abstract fun onSubscriptionResult (Ljava/lang/Object;Lio/sentry/IHub;Lio/sentry/graphql/ExceptionReporter;Lgraphql/execution/instrumentation/parameters/InstrumentationFieldFetchParameters;)Ljava/lang/Object; + public abstract fun onSubscriptionResult (Ljava/lang/Object;Lio/sentry/IScopes;Lio/sentry/graphql/ExceptionReporter;Lgraphql/execution/instrumentation/parameters/InstrumentationFieldFetchParameters;)Ljava/lang/Object; } diff --git a/sentry-graphql/src/main/java/io/sentry/graphql/ExceptionReporter.java b/sentry-graphql/src/main/java/io/sentry/graphql/ExceptionReporter.java index 30ccb21425..843ca77494 100644 --- a/sentry-graphql/src/main/java/io/sentry/graphql/ExceptionReporter.java +++ b/sentry-graphql/src/main/java/io/sentry/graphql/ExceptionReporter.java @@ -5,7 +5,7 @@ import graphql.language.AstPrinter; import graphql.schema.DataFetchingEnvironment; import io.sentry.Hint; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.SentryEvent; import io.sentry.SentryLevel; import io.sentry.SentryOptions; @@ -33,7 +33,7 @@ public void captureThrowable( final @NotNull Throwable throwable, final @NotNull ExceptionDetails exceptionDetails, final @Nullable ExecutionResult result) { - final @NotNull IHub hub = exceptionDetails.getHub(); + final @NotNull IScopes scopes = exceptionDetails.getScopes(); final @NotNull Mechanism mechanism = new Mechanism(); mechanism.setType(MECHANISM_TYPE); mechanism.setHandled(false); @@ -43,44 +43,44 @@ public void captureThrowable( event.setLevel(SentryLevel.FATAL); final @NotNull Hint hint = new Hint(); - setRequestDetailsOnEvent(hub, exceptionDetails, event); + setRequestDetailsOnEvent(scopes, exceptionDetails, event); - if (result != null && isAllowedToAttachBody(hub)) { + if (result != null && isAllowedToAttachBody(scopes)) { final @NotNull Response response = new Response(); final @NotNull Map responseBody = result.toSpecification(); response.setData(responseBody); event.getContexts().setResponse(response); } - hub.captureEvent(event, hint); + scopes.captureEvent(event, hint); } - private boolean isAllowedToAttachBody(final @NotNull IHub hub) { - final @NotNull SentryOptions options = hub.getOptions(); + private boolean isAllowedToAttachBody(final @NotNull IScopes scopes) { + final @NotNull SentryOptions options = scopes.getOptions(); return options.isSendDefaultPii() && !SentryOptions.RequestSize.NONE.equals(options.getMaxRequestBodySize()); } private void setRequestDetailsOnEvent( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull ExceptionDetails exceptionDetails, final @NotNull SentryEvent event) { - hub.configureScope( + scopes.configureScope( (scope) -> { final @Nullable Request scopeRequest = scope.getRequest(); final @NotNull Request request = scopeRequest == null ? new Request() : scopeRequest; - setDetailsOnRequest(hub, exceptionDetails, request); + setDetailsOnRequest(scopes, exceptionDetails, request); event.setRequest(request); }); } private void setDetailsOnRequest( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull ExceptionDetails exceptionDetails, final @NotNull Request request) { request.setApiTarget("graphql"); - if (isAllowedToAttachBody(hub) + if (isAllowedToAttachBody(scopes) && (exceptionDetails.isSubscription() || captureRequestBodyForNonSubscriptions)) { final @NotNull Map data = new HashMap<>(); @@ -99,27 +99,27 @@ private void setDetailsOnRequest( public static final class ExceptionDetails { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @Nullable InstrumentationExecutionParameters instrumentationExecutionParameters; private final @Nullable DataFetchingEnvironment dataFetchingEnvironment; private final boolean isSubscription; public ExceptionDetails( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @Nullable InstrumentationExecutionParameters instrumentationExecutionParameters, final boolean isSubscription) { - this.hub = hub; + this.scopes = scopes; this.instrumentationExecutionParameters = instrumentationExecutionParameters; dataFetchingEnvironment = null; this.isSubscription = isSubscription; } public ExceptionDetails( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @Nullable DataFetchingEnvironment dataFetchingEnvironment, final boolean isSubscription) { - this.hub = hub; + this.scopes = scopes; this.dataFetchingEnvironment = dataFetchingEnvironment; instrumentationExecutionParameters = null; this.isSubscription = isSubscription; @@ -149,8 +149,13 @@ public boolean isSubscription() { return isSubscription; } - public @NotNull IHub getHub() { - return hub; + @Deprecated + public @NotNull IScopes getHub() { + return scopes; + } + + public @NotNull IScopes getScopes() { + return scopes; } } } diff --git a/sentry-graphql/src/main/java/io/sentry/graphql/NoOpSubscriptionHandler.java b/sentry-graphql/src/main/java/io/sentry/graphql/NoOpSubscriptionHandler.java index df241ce35b..839f413719 100644 --- a/sentry-graphql/src/main/java/io/sentry/graphql/NoOpSubscriptionHandler.java +++ b/sentry-graphql/src/main/java/io/sentry/graphql/NoOpSubscriptionHandler.java @@ -1,7 +1,7 @@ package io.sentry.graphql; import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; -import io.sentry.IHub; +import io.sentry.IScopes; import org.jetbrains.annotations.NotNull; public final class NoOpSubscriptionHandler implements SentrySubscriptionHandler { @@ -17,7 +17,7 @@ private NoOpSubscriptionHandler() {} @Override public @NotNull Object onSubscriptionResult( @NotNull Object result, - @NotNull IHub hub, + @NotNull IScopes scopes, @NotNull ExceptionReporter exceptionReporter, @NotNull InstrumentationFieldFetchParameters parameters) { return result; diff --git a/sentry-graphql/src/main/java/io/sentry/graphql/SentryDataFetcherExceptionHandler.java b/sentry-graphql/src/main/java/io/sentry/graphql/SentryDataFetcherExceptionHandler.java index c0467c0089..0813aab851 100644 --- a/sentry-graphql/src/main/java/io/sentry/graphql/SentryDataFetcherExceptionHandler.java +++ b/sentry-graphql/src/main/java/io/sentry/graphql/SentryDataFetcherExceptionHandler.java @@ -6,8 +6,8 @@ import graphql.execution.DataFetcherExceptionHandlerParameters; import graphql.execution.DataFetcherExceptionHandlerResult; import io.sentry.Hint; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; +import io.sentry.ScopesAdapter; import io.sentry.SentryIntegrationPackageStorage; import io.sentry.util.Objects; import java.util.concurrent.CompletableFuture; @@ -24,18 +24,18 @@ */ @Deprecated public final class SentryDataFetcherExceptionHandler implements DataFetcherExceptionHandler { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @NotNull DataFetcherExceptionHandler delegate; public SentryDataFetcherExceptionHandler( - final @NotNull IHub hub, final @NotNull DataFetcherExceptionHandler delegate) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + final @NotNull IScopes scopes, final @NotNull DataFetcherExceptionHandler delegate) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); this.delegate = Objects.requireNonNull(delegate, "delegate is required"); SentryIntegrationPackageStorage.getInstance().addIntegration("GrahQLLegacyExceptionHandler"); } public SentryDataFetcherExceptionHandler(final @NotNull DataFetcherExceptionHandler delegate) { - this(HubAdapter.getInstance(), delegate); + this(ScopesAdapter.getInstance(), delegate); } @Override @@ -44,7 +44,7 @@ public CompletableFuture handleException( final Hint hint = new Hint(); hint.set(GRAPHQL_HANDLER_PARAMETERS, handlerParameters); - hub.captureException(handlerParameters.getException(), hint); + scopes.captureException(handlerParameters.getException(), hint); return delegate.handleException(handlerParameters); } diff --git a/sentry-graphql/src/main/java/io/sentry/graphql/SentryGenericDataFetcherExceptionHandler.java b/sentry-graphql/src/main/java/io/sentry/graphql/SentryGenericDataFetcherExceptionHandler.java index 6251d00779..1287d38caa 100644 --- a/sentry-graphql/src/main/java/io/sentry/graphql/SentryGenericDataFetcherExceptionHandler.java +++ b/sentry-graphql/src/main/java/io/sentry/graphql/SentryGenericDataFetcherExceptionHandler.java @@ -3,7 +3,7 @@ import graphql.execution.DataFetcherExceptionHandler; import graphql.execution.DataFetcherExceptionHandlerParameters; import graphql.execution.DataFetcherExceptionHandlerResult; -import io.sentry.IHub; +import io.sentry.IScopes; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import org.jetbrains.annotations.NotNull; @@ -17,7 +17,7 @@ public final class SentryGenericDataFetcherExceptionHandler implements DataFetch private final @NotNull SentryGraphqlExceptionHandler handler; public SentryGenericDataFetcherExceptionHandler( - final @Nullable IHub hub, final @NotNull DataFetcherExceptionHandler delegate) { + final @Nullable IScopes scopes, final @NotNull DataFetcherExceptionHandler delegate) { this.handler = new SentryGraphqlExceptionHandler(delegate); } diff --git a/sentry-graphql/src/main/java/io/sentry/graphql/SentryInstrumentation.java b/sentry-graphql/src/main/java/io/sentry/graphql/SentryInstrumentation.java index d2d62c99d8..e4f85d12a2 100644 --- a/sentry-graphql/src/main/java/io/sentry/graphql/SentryInstrumentation.java +++ b/sentry-graphql/src/main/java/io/sentry/graphql/SentryInstrumentation.java @@ -18,9 +18,9 @@ import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLOutputType; import io.sentry.Breadcrumb; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ISpan; -import io.sentry.NoOpHub; +import io.sentry.NoOpScopes; import io.sentry.Sentry; import io.sentry.SentryIntegrationPackageStorage; import io.sentry.SpanStatus; @@ -46,7 +46,11 @@ public final class SentryInstrumentation "INTERNAL", // Netflix DGS "DataFetchingException" // raw graphql-java ); - public static final @NotNull String SENTRY_HUB_CONTEXT_KEY = "sentry.hub"; + public static final @NotNull String SENTRY_SCOPES_CONTEXT_KEY = "sentry.scopes"; + + @Deprecated + public static final @NotNull String SENTRY_HUB_CONTEXT_KEY = SENTRY_SCOPES_CONTEXT_KEY; + public static final @NotNull String SENTRY_EXCEPTIONS_CONTEXT_KEY = "sentry.exceptions"; private static final String TRACE_ORIGIN = "auto.graphql.graphql"; private final @Nullable BeforeSpanCallback beforeSpan; @@ -70,7 +74,7 @@ public SentryInstrumentation() { */ @Deprecated @SuppressWarnings("InlineMeSuggester") - public SentryInstrumentation(final @Nullable IHub hub) { + public SentryInstrumentation(final @Nullable IScopes scopes) { this(null, NoOpSubscriptionHandler.getInstance(), true); } @@ -89,7 +93,7 @@ public SentryInstrumentation(final @Nullable BeforeSpanCallback beforeSpan) { @Deprecated @SuppressWarnings("InlineMeSuggester") public SentryInstrumentation( - final @Nullable IHub hub, final @Nullable BeforeSpanCallback beforeSpan) { + final @Nullable IScopes scopes, final @Nullable BeforeSpanCallback beforeSpan) { this(beforeSpan, NoOpSubscriptionHandler.getInstance(), true); } @@ -172,9 +176,9 @@ public SentryInstrumentation( public @NotNull InstrumentationContext beginExecution( final @NotNull InstrumentationExecutionParameters parameters) { final TracingState tracingState = parameters.getInstrumentationState(); - final @NotNull IHub currentHub = Sentry.getCurrentHub(); - tracingState.setTransaction(currentHub.getSpan()); - parameters.getGraphQLContext().put(SENTRY_HUB_CONTEXT_KEY, currentHub); + final @NotNull IScopes currentScopes = Sentry.getCurrentScopes(); + tracingState.setTransaction(currentScopes.getSpan()); + parameters.getGraphQLContext().put(SENTRY_SCOPES_CONTEXT_KEY, currentScopes); return super.beginExecution(parameters); } @@ -195,7 +199,7 @@ public CompletableFuture instrumentExecutionResult( exceptionReporter.captureThrowable( throwable, new ExceptionReporter.ExceptionDetails( - hubFromContext(graphQLContext), parameters, false), + scopesFromContext(graphQLContext), parameters, false), result); } } @@ -207,7 +211,7 @@ public CompletableFuture instrumentExecutionResult( exceptionReporter.captureThrowable( new RuntimeException(error.getMessage()), new ExceptionReporter.ExceptionDetails( - hubFromContext(graphQLContext), parameters, false), + scopesFromContext(graphQLContext), parameters, false), result); } } @@ -217,7 +221,7 @@ public CompletableFuture instrumentExecutionResult( exceptionReporter.captureThrowable( exception, new ExceptionReporter.ExceptionDetails( - hubFromContext(parameters.getGraphQLContext()), parameters, false), + scopesFromContext(parameters.getGraphQLContext()), parameters, false), null); } }); @@ -262,7 +266,7 @@ private boolean isIgnored(final @Nullable String errorType) { operationDefinition.getOperation(); final @Nullable String operationType = operation == null ? null : operation.name().toLowerCase(Locale.ROOT); - hubFromContext(parameters.getExecutionContext().getGraphQLContext()) + scopesFromContext(parameters.getExecutionContext().getGraphQLContext()) .addBreadcrumb( Breadcrumb.graphqlOperation( operationDefinition.getName(), @@ -273,11 +277,11 @@ private boolean isIgnored(final @Nullable String errorType) { return super.beginExecuteOperation(parameters); } - private @NotNull IHub hubFromContext(final @Nullable GraphQLContext context) { + private @NotNull IScopes scopesFromContext(final @Nullable GraphQLContext context) { if (context == null) { - return NoOpHub.getInstance(); + return NoOpScopes.getInstance(); } - return context.getOrDefault(SENTRY_HUB_CONTEXT_KEY, NoOpHub.getInstance()); + return context.getOrDefault(SENTRY_SCOPES_CONTEXT_KEY, NoOpScopes.getInstance()); } @Override @@ -293,7 +297,7 @@ private boolean isIgnored(final @Nullable String errorType) { return environment -> { final @Nullable ExecutionStepInfo executionStepInfo = environment.getExecutionStepInfo(); if (executionStepInfo != null) { - hubFromContext(parameters.getExecutionContext().getGraphQLContext()) + scopesFromContext(parameters.getExecutionContext().getGraphQLContext()) .addBreadcrumb( Breadcrumb.graphqlDataFetcher( StringUtils.toString(executionStepInfo.getPath()), @@ -351,7 +355,7 @@ private boolean isIgnored(final @Nullable String errorType) { environment.getOperationDefinition().getOperation())) { return subscriptionHandler.onSubscriptionResult( tmpResult, - hubFromContext(environment.getGraphQlContext()), + scopesFromContext(environment.getGraphQlContext()), exceptionReporter, parameters); } diff --git a/sentry-graphql/src/main/java/io/sentry/graphql/SentrySubscriptionHandler.java b/sentry-graphql/src/main/java/io/sentry/graphql/SentrySubscriptionHandler.java index bfc962b501..0a5538ce22 100644 --- a/sentry-graphql/src/main/java/io/sentry/graphql/SentrySubscriptionHandler.java +++ b/sentry-graphql/src/main/java/io/sentry/graphql/SentrySubscriptionHandler.java @@ -1,14 +1,14 @@ package io.sentry.graphql; import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; -import io.sentry.IHub; +import io.sentry.IScopes; import org.jetbrains.annotations.NotNull; public interface SentrySubscriptionHandler { @NotNull Object onSubscriptionResult( @NotNull Object result, - @NotNull IHub hub, + @NotNull IScopes scopes, @NotNull ExceptionReporter exceptionReporter, @NotNull InstrumentationFieldFetchParameters parameters); } diff --git a/sentry-graphql/src/test/kotlin/io/sentry/graphql/ExceptionReporterTest.kt b/sentry-graphql/src/test/kotlin/io/sentry/graphql/ExceptionReporterTest.kt index a2b2b0f101..3a798a2f86 100644 --- a/sentry-graphql/src/test/kotlin/io/sentry/graphql/ExceptionReporterTest.kt +++ b/sentry-graphql/src/test/kotlin/io/sentry/graphql/ExceptionReporterTest.kt @@ -12,8 +12,8 @@ import graphql.schema.GraphQLObjectType import graphql.schema.GraphQLScalarType import graphql.schema.GraphQLSchema import io.sentry.Hint -import io.sentry.IHub import io.sentry.IScope +import io.sentry.IScopes import io.sentry.Scope import io.sentry.ScopeCallback import io.sentry.SentryOptions @@ -39,7 +39,7 @@ class ExceptionReporterTest { it.maxRequestBodySize = SentryOptions.RequestSize.ALWAYS } val exception = IllegalStateException("some exception") - val hub = mock() + val scopes = mock() lateinit var instrumentationExecutionParameters: InstrumentationExecutionParameters lateinit var executionResult: ExecutionResult lateinit var scope: IScope @@ -47,7 +47,7 @@ class ExceptionReporterTest { val variables = mapOf("variableA" to "value a") fun getSut(options: SentryOptions = defaultOptions, captureRequestBodyForNonSubscriptions: Boolean = true): ExceptionReporter { - whenever(hub.options).thenReturn(options) + whenever(scopes.options).thenReturn(options) scope = Scope(options) val exceptionReporter = ExceptionReporter(captureRequestBodyForNonSubscriptions) executionResult = ExecutionResultImpl.newExecutionResult() @@ -77,7 +77,7 @@ class ExceptionReporterTest { ).build() val instrumentationState = SentryInstrumentation.TracingState() instrumentationExecutionParameters = InstrumentationExecutionParameters(executionInput, schema, instrumentationState) - doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(hub).configureScope(any()) + doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(scopes).configureScope(any()) return exceptionReporter } @@ -88,9 +88,9 @@ class ExceptionReporterTest { @Test fun `captures throwable`() { val exceptionReporter = fixture.getSut() - exceptionReporter.captureThrowable(fixture.exception, ExceptionReporter.ExceptionDetails(fixture.hub, fixture.instrumentationExecutionParameters, false), fixture.executionResult) + exceptionReporter.captureThrowable(fixture.exception, ExceptionReporter.ExceptionDetails(fixture.scopes, fixture.instrumentationExecutionParameters, false), fixture.executionResult) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( org.mockito.kotlin.check { val ex = it.throwableMechanism as ExceptionMechanismException assertFalse(ex.exceptionMechanism.isHandled!!) @@ -112,9 +112,9 @@ class ExceptionReporterTest { val exceptionReporter = fixture.getSut() val headers = mapOf("some-header" to "some-header-value") fixture.scope.request = Request().also { it.headers = headers } - exceptionReporter.captureThrowable(fixture.exception, ExceptionReporter.ExceptionDetails(fixture.hub, fixture.instrumentationExecutionParameters, false), fixture.executionResult) + exceptionReporter.captureThrowable(fixture.exception, ExceptionReporter.ExceptionDetails(fixture.scopes, fixture.instrumentationExecutionParameters, false), fixture.executionResult) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( org.mockito.kotlin.check { val ex = it.throwableMechanism as ExceptionMechanismException assertFalse(ex.exceptionMechanism.isHandled!!) @@ -136,9 +136,9 @@ class ExceptionReporterTest { @Test fun `does not attach query or variables if spring`() { val exceptionReporter = fixture.getSut(captureRequestBodyForNonSubscriptions = false) - exceptionReporter.captureThrowable(fixture.exception, ExceptionReporter.ExceptionDetails(fixture.hub, fixture.instrumentationExecutionParameters, false), fixture.executionResult) + exceptionReporter.captureThrowable(fixture.exception, ExceptionReporter.ExceptionDetails(fixture.scopes, fixture.instrumentationExecutionParameters, false), fixture.executionResult) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( org.mockito.kotlin.check { val ex = it.throwableMechanism as ExceptionMechanismException assertFalse(ex.exceptionMechanism.isHandled!!) @@ -156,9 +156,9 @@ class ExceptionReporterTest { @Test fun `does not attach query or variables if no max body size is set`() { val exceptionReporter = fixture.getSut(SentryOptions().also { it.isSendDefaultPii = true }, false) - exceptionReporter.captureThrowable(fixture.exception, ExceptionReporter.ExceptionDetails(fixture.hub, fixture.instrumentationExecutionParameters, false), fixture.executionResult) + exceptionReporter.captureThrowable(fixture.exception, ExceptionReporter.ExceptionDetails(fixture.scopes, fixture.instrumentationExecutionParameters, false), fixture.executionResult) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( org.mockito.kotlin.check { val ex = it.throwableMechanism as ExceptionMechanismException assertFalse(ex.exceptionMechanism.isHandled!!) @@ -176,9 +176,9 @@ class ExceptionReporterTest { @Test fun `does not attach query or variables if sendDefaultPii is false`() { val exceptionReporter = fixture.getSut(SentryOptions().also { it.maxRequestBodySize = SentryOptions.RequestSize.ALWAYS }, false) - exceptionReporter.captureThrowable(fixture.exception, ExceptionReporter.ExceptionDetails(fixture.hub, fixture.instrumentationExecutionParameters, false), fixture.executionResult) + exceptionReporter.captureThrowable(fixture.exception, ExceptionReporter.ExceptionDetails(fixture.scopes, fixture.instrumentationExecutionParameters, false), fixture.executionResult) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( org.mockito.kotlin.check { val ex = it.throwableMechanism as ExceptionMechanismException assertFalse(ex.exceptionMechanism.isHandled!!) @@ -196,9 +196,9 @@ class ExceptionReporterTest { @Test fun `attaches query and variables if spring and subscription`() { val exceptionReporter = fixture.getSut(captureRequestBodyForNonSubscriptions = false) - exceptionReporter.captureThrowable(fixture.exception, ExceptionReporter.ExceptionDetails(fixture.hub, fixture.instrumentationExecutionParameters, true), fixture.executionResult) + exceptionReporter.captureThrowable(fixture.exception, ExceptionReporter.ExceptionDetails(fixture.scopes, fixture.instrumentationExecutionParameters, true), fixture.executionResult) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( org.mockito.kotlin.check { val ex = it.throwableMechanism as ExceptionMechanismException assertFalse(ex.exceptionMechanism.isHandled!!) diff --git a/sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryDataFetcherExceptionHandlerTest.kt b/sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryDataFetcherExceptionHandlerTest.kt index b571fa8218..de51abac21 100644 --- a/sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryDataFetcherExceptionHandlerTest.kt +++ b/sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryDataFetcherExceptionHandlerTest.kt @@ -3,7 +3,7 @@ package io.sentry.graphql import graphql.execution.DataFetcherExceptionHandler import graphql.execution.DataFetcherExceptionHandlerParameters import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import org.mockito.kotlin.anyOrNull import org.mockito.kotlin.eq import org.mockito.kotlin.mock @@ -14,15 +14,15 @@ class SentryDataFetcherExceptionHandlerTest { @Test fun `passes exception to Sentry and invokes delegate`() { - val hub = mock() + val scopes = mock() val delegate = mock() - val handler = SentryDataFetcherExceptionHandler(hub, delegate) + val handler = SentryDataFetcherExceptionHandler(scopes, delegate) val exception = RuntimeException() val parameters = DataFetcherExceptionHandlerParameters.newExceptionParameters().exception(exception).build() handler.onException(parameters) - verify(hub).captureException(eq(exception), anyOrNull()) + verify(scopes).captureException(eq(exception), anyOrNull()) verify(delegate).handleException(parameters) } } diff --git a/sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryGenericDataFetcherExceptionHandlerTest.kt b/sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryGenericDataFetcherExceptionHandlerTest.kt index 6d643baf01..88e2f5df55 100644 --- a/sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryGenericDataFetcherExceptionHandlerTest.kt +++ b/sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryGenericDataFetcherExceptionHandlerTest.kt @@ -4,7 +4,7 @@ import graphql.GraphQLContext import graphql.execution.DataFetcherExceptionHandler import graphql.execution.DataFetcherExceptionHandlerParameters import graphql.schema.DataFetchingEnvironmentImpl -import io.sentry.IHub +import io.sentry.IScopes import org.mockito.kotlin.mock import org.mockito.kotlin.verify import kotlin.test.Test @@ -15,10 +15,10 @@ class SentryGenericDataFetcherExceptionHandlerTest { @Test fun `collects exception into GraphQLContext and invokes delegate`() { - val hub = mock() + val scopes = mock() val delegate = mock() val handler = SentryGenericDataFetcherExceptionHandler( - hub, + scopes, delegate ) diff --git a/sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryInstrumentationAnotherTest.kt b/sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryInstrumentationAnotherTest.kt index e30bbc9415..087a1dfa72 100644 --- a/sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryInstrumentationAnotherTest.kt +++ b/sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryInstrumentationAnotherTest.kt @@ -28,7 +28,8 @@ import graphql.schema.GraphQLObjectType import graphql.schema.GraphQLScalarType import graphql.schema.GraphQLSchema import io.sentry.Breadcrumb -import io.sentry.IHub +import io.sentry.HubScopesWrapper +import io.sentry.IScopes import io.sentry.Sentry import io.sentry.SentryOptions import io.sentry.SentryTracer @@ -52,7 +53,7 @@ import kotlin.test.assertSame class SentryInstrumentationAnotherTest { class Fixture { - val hub = mock() + val scopes = mock() lateinit var activeSpan: SentryTracer lateinit var dataFetcher: DataFetcher lateinit var fieldFetchParameters: InstrumentationFieldFetchParameters @@ -70,17 +71,17 @@ class SentryInstrumentationAnotherTest { val variables = mapOf("variableA" to "value a") fun getSut(isTransactionActive: Boolean = true, operation: OperationDefinition.Operation = OperationDefinition.Operation.QUERY, graphQLContextParam: Map? = null, addTransactionToTracingState: Boolean = true, ignoredErrors: List = emptyList()): SentryInstrumentation { - whenever(hub.options).thenReturn(SentryOptions()) - activeSpan = SentryTracer(TransactionContext("name", "op"), hub) + whenever(scopes.options).thenReturn(SentryOptions()) + activeSpan = SentryTracer(TransactionContext("name", "op"), scopes) if (isTransactionActive) { - whenever(hub.span).thenReturn(activeSpan) + whenever(scopes.span).thenReturn(activeSpan) } else { - whenever(hub.span).thenReturn(null) + whenever(scopes.span).thenReturn(null) } val defaultGraphQLContext = mapOf( - SentryInstrumentation.SENTRY_HUB_CONTEXT_KEY to hub + SentryInstrumentation.SENTRY_SCOPES_CONTEXT_KEY to scopes ) val mergedField = MergedField.newMergedField().addField(Field.newField("myFieldName").build()).build() @@ -165,7 +166,7 @@ class SentryInstrumentationAnotherTest { val result = instrumentedDataFetcher.get(fixture.environment) assertEquals("result modified by subscription handler", result) - verify(fixture.subscriptionHandler).onSubscriptionResult(eq("raw result"), same(fixture.hub), same(fixture.exceptionReporter), same(fixture.fieldFetchParameters)) + verify(fixture.subscriptionHandler).onSubscriptionResult(eq("raw result"), same(fixture.scopes), same(fixture.exceptionReporter), same(fixture.fieldFetchParameters)) } @Test @@ -175,7 +176,7 @@ class SentryInstrumentationAnotherTest { val result = instrumentedDataFetcher.get(fixture.environment) assertEquals("result modified by subscription handler", result) - verify(fixture.subscriptionHandler).onSubscriptionResult(eq("raw result"), same(fixture.hub), same(fixture.exceptionReporter), same(fixture.fieldFetchParameters)) + verify(fixture.subscriptionHandler).onSubscriptionResult(eq("raw result"), same(fixture.scopes), same(fixture.exceptionReporter), same(fixture.fieldFetchParameters)) } @Test @@ -222,7 +223,7 @@ class SentryInstrumentationAnotherTest { fun `adds a breadcrumb for operation`() { val instrumentation = fixture.getSut() instrumentation.beginExecuteOperation(fixture.instrumentationExecuteOperationParameters) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( org.mockito.kotlin.check { breadcrumb -> assertEquals("graphql", breadcrumb.type) assertEquals("query", breadcrumb.category) @@ -237,7 +238,7 @@ class SentryInstrumentationAnotherTest { fun `adds a breadcrumb for data fetcher`() { val instrumentation = fixture.getSut() instrumentation.instrumentDataFetcher(fixture.dataFetcher, fixture.fieldFetchParameters).get(fixture.environment) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( org.mockito.kotlin.check { breadcrumb -> assertEquals("graphql", breadcrumb.type) assertEquals("graphql.fetcher", breadcrumb.category) @@ -250,11 +251,11 @@ class SentryInstrumentationAnotherTest { } @Test - fun `stores hub in context and adds transaction to state`() { + fun `stores scopes in context and adds transaction to state`() { val instrumentation = fixture.getSut(isTransactionActive = true, operation = OperationDefinition.Operation.MUTATION, graphQLContextParam = emptyMap(), addTransactionToTracingState = false) - withMockHub { + withMockScopes { instrumentation.beginExecution(fixture.instrumentationExecutionParameters) - assertSame(fixture.hub, fixture.instrumentationExecutionParameters.graphQLContext.get(SentryInstrumentation.SENTRY_HUB_CONTEXT_KEY)) + assertSame(fixture.scopes, fixture.instrumentationExecutionParameters.graphQLContext.get(SentryInstrumentation.SENTRY_SCOPES_CONTEXT_KEY)) assertNotNull(fixture.instrumentationState.transaction) } } @@ -276,7 +277,7 @@ class SentryInstrumentationAnotherTest { assertEquals("exception message", it.message) }, org.mockito.kotlin.check { - assertSame(fixture.hub, it.hub) + assertSame(fixture.scopes, it.scopes) assertSame(fixture.query, it.query) assertEquals(false, it.isSubscription) assertEquals(fixture.variables, it.variables) @@ -293,7 +294,7 @@ class SentryInstrumentationAnotherTest { val instrumentation = fixture.getSut( graphQLContextParam = mapOf( SENTRY_EXCEPTIONS_CONTEXT_KEY to listOf(exception), - SentryInstrumentation.SENTRY_HUB_CONTEXT_KEY to fixture.hub + SentryInstrumentation.SENTRY_SCOPES_CONTEXT_KEY to fixture.scopes ) ) val executionResult = ExecutionResultImpl.newExecutionResult() @@ -305,7 +306,7 @@ class SentryInstrumentationAnotherTest { assertSame(exception, it) }, org.mockito.kotlin.check { - assertSame(fixture.hub, it.hub) + assertSame(fixture.scopes, it.scopes) assertSame(fixture.query, it.query) assertEquals(false, it.isSubscription) assertEquals(fixture.variables, it.variables) @@ -356,8 +357,9 @@ class SentryInstrumentationAnotherTest { assertSame(executionResult, result) } - fun withMockHub(closure: () -> Unit) = Mockito.mockStatic(Sentry::class.java).use { - it.`when` { Sentry.getCurrentHub() }.thenReturn(fixture.hub) + fun withMockScopes(closure: () -> Unit) = Mockito.mockStatic(Sentry::class.java).use { + it.`when` { Sentry.getCurrentHub() }.thenReturn(HubScopesWrapper(fixture.scopes)) + it.`when` { Sentry.getCurrentScopes() }.thenReturn(fixture.scopes) closure.invoke() } diff --git a/sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryInstrumentationTest.kt b/sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryInstrumentationTest.kt index 8a579e2687..2bb46f79fc 100644 --- a/sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryInstrumentationTest.kt +++ b/sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryInstrumentationTest.kt @@ -18,7 +18,8 @@ import graphql.schema.GraphQLScalarType import graphql.schema.idl.RuntimeWiring import graphql.schema.idl.SchemaGenerator import graphql.schema.idl.SchemaParser -import io.sentry.IHub +import io.sentry.HubScopesWrapper +import io.sentry.IScopes import io.sentry.Sentry import io.sentry.SentryOptions import io.sentry.SentryTracer @@ -39,12 +40,12 @@ import kotlin.test.assertTrue class SentryInstrumentationTest { class Fixture { - val hub = mock() + val scopes = mock() lateinit var activeSpan: SentryTracer fun getSut(isTransactionActive: Boolean = true, dataFetcherThrows: Boolean = false, beforeSpan: SentryInstrumentation.BeforeSpanCallback? = null): GraphQL { - whenever(hub.options).thenReturn(SentryOptions()) - activeSpan = SentryTracer(TransactionContext("name", "op"), hub) + whenever(scopes.options).thenReturn(SentryOptions()) + activeSpan = SentryTracer(TransactionContext("name", "op"), scopes) val schema = """ type Query { shows: [Show] @@ -61,9 +62,9 @@ class SentryInstrumentationTest { .build() if (isTransactionActive) { - whenever(hub.span).thenReturn(activeSpan) + whenever(scopes.span).thenReturn(activeSpan) } else { - whenever(hub.span).thenReturn(null) + whenever(scopes.span).thenReturn(null) } return graphQL @@ -87,7 +88,7 @@ class SentryInstrumentationTest { fun `when transaction is active, creates inner spans`() { val sut = fixture.getSut() - withMockHub { + withMockScopes { val result = sut.execute("{ shows { id } }") assertTrue(result.errors.isEmpty()) @@ -105,7 +106,7 @@ class SentryInstrumentationTest { fun `when transaction is active, and data fetcher throws, creates inner spans`() { val sut = fixture.getSut(dataFetcherThrows = true) - withMockHub { + withMockScopes { val result = sut.execute("{ shows { id } }") assertTrue(result.errors.isNotEmpty()) @@ -122,7 +123,7 @@ class SentryInstrumentationTest { fun `when transaction is not active, does not create spans`() { val sut = fixture.getSut(isTransactionActive = false) - withMockHub { + withMockScopes { val result = sut.execute("{ shows { id } }") assertTrue(result.errors.isEmpty()) @@ -134,7 +135,7 @@ class SentryInstrumentationTest { fun `beforeSpan can drop spans`() { val sut = fixture.getSut(beforeSpan = SentryInstrumentation.BeforeSpanCallback { _, _, _ -> null }) - withMockHub { + withMockScopes { val result = sut.execute("{ shows { id } }") assertTrue(result.errors.isEmpty()) @@ -152,7 +153,7 @@ class SentryInstrumentationTest { fun `beforeSpan can modify spans`() { val sut = fixture.getSut(beforeSpan = SentryInstrumentation.BeforeSpanCallback { span, _, _ -> span.apply { description = "changed" } }) - withMockHub { + withMockScopes { val result = sut.execute("{ shows { id } }") assertTrue(result.errors.isEmpty()) @@ -208,19 +209,20 @@ class SentryInstrumentationTest { @Test fun `Integration adds itself to integration and package list`() { - withMockHub { + withMockScopes { val sut = fixture.getSut() - assertNotNull(fixture.hub.options.sdkVersion) - assert(fixture.hub.options.sdkVersion!!.integrationSet.contains("GraphQL")) + assertNotNull(fixture.scopes.options.sdkVersion) + assert(fixture.scopes.options.sdkVersion!!.integrationSet.contains("GraphQL")) val packageInfo = - fixture.hub.options.sdkVersion!!.packageSet.firstOrNull { pkg -> pkg.name == "maven:io.sentry:sentry-graphql" } + fixture.scopes.options.sdkVersion!!.packageSet.firstOrNull { pkg -> pkg.name == "maven:io.sentry:sentry-graphql" } assertNotNull(packageInfo) assert(packageInfo.version == BuildConfig.VERSION_NAME) } } - fun withMockHub(closure: () -> Unit) = Mockito.mockStatic(Sentry::class.java).use { - it.`when` { Sentry.getCurrentHub() }.thenReturn(fixture.hub) + fun withMockScopes(closure: () -> Unit) = Mockito.mockStatic(Sentry::class.java).use { + it.`when` { Sentry.getCurrentHub() }.thenReturn(HubScopesWrapper(fixture.scopes)) + it.`when` { Sentry.getCurrentScopes() }.thenReturn(fixture.scopes) closure.invoke() } diff --git a/sentry-jdbc/api/sentry-jdbc.api b/sentry-jdbc/api/sentry-jdbc.api index cff0f37fd2..700cbb2d69 100644 --- a/sentry-jdbc/api/sentry-jdbc.api +++ b/sentry-jdbc/api/sentry-jdbc.api @@ -16,7 +16,7 @@ public final class io/sentry/jdbc/DatabaseUtils$DatabaseDetails { public class io/sentry/jdbc/SentryJdbcEventListener : com/p6spy/engine/event/SimpleJdbcEventListener { public fun ()V - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun onAfterAnyExecute (Lcom/p6spy/engine/common/StatementInformation;JLjava/sql/SQLException;)V public fun onBeforeAnyExecute (Lcom/p6spy/engine/common/StatementInformation;)V } diff --git a/sentry-jdbc/src/main/java/io/sentry/jdbc/SentryJdbcEventListener.java b/sentry-jdbc/src/main/java/io/sentry/jdbc/SentryJdbcEventListener.java index 0346d2d0b9..4cb21188e4 100644 --- a/sentry-jdbc/src/main/java/io/sentry/jdbc/SentryJdbcEventListener.java +++ b/sentry-jdbc/src/main/java/io/sentry/jdbc/SentryJdbcEventListener.java @@ -6,9 +6,9 @@ import com.jakewharton.nopen.annotation.Open; import com.p6spy.engine.common.StatementInformation; import com.p6spy.engine.event.SimpleJdbcEventListener; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ISpan; +import io.sentry.ScopesAdapter; import io.sentry.SentryIntegrationPackageStorage; import io.sentry.Span; import io.sentry.SpanStatus; @@ -21,24 +21,24 @@ @Open public class SentryJdbcEventListener extends SimpleJdbcEventListener { private static final String TRACE_ORIGIN = "auto.db.jdbc"; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private static final @NotNull ThreadLocal CURRENT_SPAN = new ThreadLocal<>(); private volatile @Nullable DatabaseUtils.DatabaseDetails cachedDatabaseDetails = null; private final @NotNull Object databaseDetailsLock = new Object(); - public SentryJdbcEventListener(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentryJdbcEventListener(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); addPackageAndIntegrationInfo(); } public SentryJdbcEventListener() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } @Override public void onBeforeAnyExecute(final @NotNull StatementInformation statementInformation) { - final ISpan parent = hub.getSpan(); + final ISpan parent = scopes.getSpan(); if (parent != null && !parent.isNoOp()) { final ISpan span = parent.startChild("db.query", statementInformation.getSql()); CURRENT_SPAN.set(span); diff --git a/sentry-jdbc/src/test/kotlin/io/sentry/jdbc/SentryJdbcEventListenerTest.kt b/sentry-jdbc/src/test/kotlin/io/sentry/jdbc/SentryJdbcEventListenerTest.kt index 78c5d4cf12..00ce03de41 100644 --- a/sentry-jdbc/src/test/kotlin/io/sentry/jdbc/SentryJdbcEventListenerTest.kt +++ b/sentry-jdbc/src/test/kotlin/io/sentry/jdbc/SentryJdbcEventListenerTest.kt @@ -2,7 +2,7 @@ package io.sentry.jdbc import com.p6spy.engine.common.StatementInformation import com.p6spy.engine.spy.P6DataSource -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryOptions import io.sentry.SentryTracer import io.sentry.SpanDataConvention.DB_NAME_KEY @@ -26,7 +26,7 @@ import kotlin.test.assertTrue class SentryJdbcEventListenerTest { class Fixture { - val hub = mock().apply { + val scopes = mock().apply { whenever(options).thenReturn( SentryOptions().apply { sdkVersion = SdkVersion("test", "1.2.3") @@ -37,9 +37,9 @@ class SentryJdbcEventListenerTest { val actualDataSource = JDBCDataSource() fun getSut(withRunningTransaction: Boolean = true, existingRow: Int? = null): DataSource { - tx = SentryTracer(TransactionContext("name", "op"), hub) + tx = SentryTracer(TransactionContext("name", "op"), scopes) if (withRunningTransaction) { - whenever(hub.span).thenReturn(tx) + whenever(scopes.span).thenReturn(tx) } actualDataSource.setURL("jdbc:hsqldb:mem:testdb") @@ -54,7 +54,7 @@ class SentryJdbcEventListenerTest { } } - val sentryQueryExecutionListener = SentryJdbcEventListener(hub) + val sentryQueryExecutionListener = SentryJdbcEventListener(scopes) val p6spyDataSource = P6DataSource(actualDataSource) p6spyDataSource.setJdbcEventListenerFactory { sentryQueryExecutionListener } return p6spyDataSource @@ -131,9 +131,9 @@ class SentryJdbcEventListenerTest { @Test fun `sets SDKVersion Info`() { val sut = fixture.getSut() - assertNotNull(fixture.hub.options.sdkVersion) - assert(fixture.hub.options.sdkVersion!!.integrationSet.contains("JDBC")) - val packageInfo = fixture.hub.options.sdkVersion!!.packageSet.firstOrNull { pkg -> pkg.name == "maven:io.sentry:sentry-jdbc" } + assertNotNull(fixture.scopes.options.sdkVersion) + assert(fixture.scopes.options.sdkVersion!!.integrationSet.contains("JDBC")) + val packageInfo = fixture.scopes.options.sdkVersion!!.packageSet.firstOrNull { pkg -> pkg.name == "maven:io.sentry:sentry-jdbc" } assertNotNull(packageInfo) assert(packageInfo.version == BuildConfig.VERSION_NAME) } diff --git a/sentry-jul/src/main/java/io/sentry/jul/SentryHandler.java b/sentry-jul/src/main/java/io/sentry/jul/SentryHandler.java index 2ca775572b..c52b4706f2 100644 --- a/sentry-jul/src/main/java/io/sentry/jul/SentryHandler.java +++ b/sentry-jul/src/main/java/io/sentry/jul/SentryHandler.java @@ -6,7 +6,7 @@ import com.jakewharton.nopen.annotation.Open; import io.sentry.Breadcrumb; import io.sentry.Hint; -import io.sentry.HubAdapter; +import io.sentry.ScopesAdapter; import io.sentry.Sentry; import io.sentry.SentryEvent; import io.sentry.SentryIntegrationPackageStorage; @@ -210,9 +210,9 @@ SentryEvent createEvent(final @NotNull LogRecord record) { mdcProperties = CollectionUtils.filterMapEntries(mdcProperties, entry -> entry.getValue() != null); if (!mdcProperties.isEmpty()) { - // get tags from HubAdapter options to allow getting the correct tags if Sentry has been + // get tags from ScopesAdapter options to allow getting the correct tags if Sentry has been // initialized somewhere else - final List contextTags = HubAdapter.getInstance().getOptions().getContextTags(); + final List contextTags = ScopesAdapter.getInstance().getOptions().getContextTags(); if (!contextTags.isEmpty()) { for (final String contextTag : contextTags) { // if mdc tag is listed in SentryOptions, apply as event tag diff --git a/sentry-kotlin-extensions/api/sentry-kotlin-extensions.api b/sentry-kotlin-extensions/api/sentry-kotlin-extensions.api index d501240a3a..7e3be67279 100644 --- a/sentry-kotlin-extensions/api/sentry-kotlin-extensions.api +++ b/sentry-kotlin-extensions/api/sentry-kotlin-extensions.api @@ -1,16 +1,16 @@ public final class io/sentry/kotlin/SentryContext : kotlin/coroutines/AbstractCoroutineContextElement, kotlinx/coroutines/CopyableThreadContextElement { public fun ()V - public fun (Lio/sentry/IHub;)V - public synthetic fun (Lio/sentry/IHub;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lio/sentry/IScopes;)V + public synthetic fun (Lio/sentry/IScopes;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun copyForChild ()Lkotlinx/coroutines/CopyableThreadContextElement; public fun fold (Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; public fun get (Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext$Element; public fun mergeForChild (Lkotlin/coroutines/CoroutineContext$Element;)Lkotlin/coroutines/CoroutineContext; public fun minusKey (Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext; public fun plus (Lkotlin/coroutines/CoroutineContext;)Lkotlin/coroutines/CoroutineContext; - public fun restoreThreadContext (Lkotlin/coroutines/CoroutineContext;Lio/sentry/IHub;)V + public fun restoreThreadContext (Lkotlin/coroutines/CoroutineContext;Lio/sentry/IScopes;)V public synthetic fun restoreThreadContext (Lkotlin/coroutines/CoroutineContext;Ljava/lang/Object;)V - public fun updateThreadContext (Lkotlin/coroutines/CoroutineContext;)Lio/sentry/IHub; + public fun updateThreadContext (Lkotlin/coroutines/CoroutineContext;)Lio/sentry/IScopes; public synthetic fun updateThreadContext (Lkotlin/coroutines/CoroutineContext;)Ljava/lang/Object; } diff --git a/sentry-kotlin-extensions/src/main/java/io/sentry/kotlin/SentryContext.kt b/sentry-kotlin-extensions/src/main/java/io/sentry/kotlin/SentryContext.kt index 3cf22a20da..4c814f2805 100644 --- a/sentry-kotlin-extensions/src/main/java/io/sentry/kotlin/SentryContext.kt +++ b/sentry-kotlin-extensions/src/main/java/io/sentry/kotlin/SentryContext.kt @@ -1,6 +1,6 @@ package io.sentry.kotlin -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.Sentry import kotlinx.coroutines.CopyableThreadContextElement import kotlin.coroutines.AbstractCoroutineContextElement @@ -9,26 +9,32 @@ import kotlin.coroutines.CoroutineContext /** * Sentry context element for [CoroutineContext]. */ -public class SentryContext(private val hub: IHub = Sentry.getCurrentHub().clone()) : - CopyableThreadContextElement, AbstractCoroutineContextElement(Key) { +@SuppressWarnings("deprecation") +// TODO fork instead +public class SentryContext(private val scopes: IScopes = Sentry.getCurrentScopes().clone()) : + CopyableThreadContextElement, AbstractCoroutineContextElement(Key) { private companion object Key : CoroutineContext.Key - override fun copyForChild(): CopyableThreadContextElement { - return SentryContext(hub.clone()) + @SuppressWarnings("deprecation") + override fun copyForChild(): CopyableThreadContextElement { + // TODO fork instead + return SentryContext(scopes.clone()) } + @SuppressWarnings("deprecation") override fun mergeForChild(overwritingElement: CoroutineContext.Element): CoroutineContext { - return overwritingElement[Key] ?: SentryContext(hub.clone()) + // TODO fork instead? + return overwritingElement[Key] ?: SentryContext(scopes.clone()) } - override fun updateThreadContext(context: CoroutineContext): IHub { - val oldState = Sentry.getCurrentHub() - Sentry.setCurrentHub(hub) + override fun updateThreadContext(context: CoroutineContext): IScopes { + val oldState = Sentry.getCurrentScopes() + Sentry.setCurrentScopes(scopes) return oldState } - override fun restoreThreadContext(context: CoroutineContext, oldState: IHub) { - Sentry.setCurrentHub(oldState) + override fun restoreThreadContext(context: CoroutineContext, oldState: IScopes) { + Sentry.setCurrentScopes(oldState) } } diff --git a/sentry-kotlin-extensions/src/test/java/io/sentry/kotlin/SentryContextTest.kt b/sentry-kotlin-extensions/src/test/java/io/sentry/kotlin/SentryContextTest.kt index b54ceabc51..578b610267 100644 --- a/sentry-kotlin-extensions/src/test/java/io/sentry/kotlin/SentryContextTest.kt +++ b/sentry-kotlin-extensions/src/test/java/io/sentry/kotlin/SentryContextTest.kt @@ -119,7 +119,7 @@ class SentryContextTest { val c2 = launch( SentryContext( - Sentry.getCurrentHub().clone().also { + Sentry.getCurrentScopes().clone().also { it.setTag("cloned", "clonedValue") } ) @@ -145,7 +145,7 @@ class SentryContextTest { @Test fun `mergeForChild returns copy of initial context if Key not present`() { val initialContextElement = SentryContext( - Sentry.getCurrentHub().clone().also { + Sentry.getCurrentScopes().clone().also { it.setTag("cloned", "clonedValue") } ) @@ -158,7 +158,7 @@ class SentryContextTest { @Test fun `mergeForChild returns passed context`() { val initialContextElement = SentryContext( - Sentry.getCurrentHub().clone().also { + Sentry.getCurrentScopes().clone().also { it.setTag("cloned", "clonedValue") } ) diff --git a/sentry-log4j2/api/sentry-log4j2.api b/sentry-log4j2/api/sentry-log4j2.api index 76aa3e823e..b7fe8b3273 100644 --- a/sentry-log4j2/api/sentry-log4j2.api +++ b/sentry-log4j2/api/sentry-log4j2.api @@ -5,7 +5,7 @@ public final class io/sentry/log4j2/BuildConfig { public class io/sentry/log4j2/SentryAppender : org/apache/logging/log4j/core/appender/AbstractAppender { public static final field MECHANISM_TYPE Ljava/lang/String; - public fun (Ljava/lang/String;Lorg/apache/logging/log4j/core/Filter;Ljava/lang/String;Lorg/apache/logging/log4j/Level;Lorg/apache/logging/log4j/Level;Ljava/lang/Boolean;Lio/sentry/ITransportFactory;Lio/sentry/IHub;[Ljava/lang/String;)V + public fun (Ljava/lang/String;Lorg/apache/logging/log4j/core/Filter;Ljava/lang/String;Lorg/apache/logging/log4j/Level;Lorg/apache/logging/log4j/Level;Ljava/lang/Boolean;Lio/sentry/ITransportFactory;Lio/sentry/IScopes;[Ljava/lang/String;)V public fun append (Lorg/apache/logging/log4j/core/LogEvent;)V public static fun createAppender (Ljava/lang/String;Lorg/apache/logging/log4j/Level;Lorg/apache/logging/log4j/Level;Ljava/lang/String;Ljava/lang/Boolean;Lorg/apache/logging/log4j/core/Filter;Ljava/lang/String;)Lio/sentry/log4j2/SentryAppender; protected fun createBreadcrumb (Lorg/apache/logging/log4j/core/LogEvent;)Lio/sentry/Breadcrumb; diff --git a/sentry-log4j2/src/main/java/io/sentry/log4j2/SentryAppender.java b/sentry-log4j2/src/main/java/io/sentry/log4j2/SentryAppender.java index 4cf4ad4a86..4ee07ab7b9 100644 --- a/sentry-log4j2/src/main/java/io/sentry/log4j2/SentryAppender.java +++ b/sentry-log4j2/src/main/java/io/sentry/log4j2/SentryAppender.java @@ -7,9 +7,9 @@ import io.sentry.Breadcrumb; import io.sentry.DateUtils; import io.sentry.Hint; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ITransportFactory; +import io.sentry.ScopesAdapter; import io.sentry.Sentry; import io.sentry.SentryEvent; import io.sentry.SentryIntegrationPackageStorage; @@ -50,7 +50,7 @@ public class SentryAppender extends AbstractAppender { private @NotNull Level minimumBreadcrumbLevel = Level.INFO; private @NotNull Level minimumEventLevel = Level.ERROR; private final @Nullable Boolean debug; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @Nullable List contextTags; public SentryAppender( @@ -61,7 +61,7 @@ public SentryAppender( final @Nullable Level minimumEventLevel, final @Nullable Boolean debug, final @Nullable ITransportFactory transportFactory, - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @Nullable String[] contextTags) { super(name, filter, null, true, null); this.dsn = dsn; @@ -73,7 +73,7 @@ public SentryAppender( } this.debug = debug; this.transportFactory = transportFactory; - this.hub = hub; + this.scopes = scopes; this.contextTags = contextTags != null ? Arrays.asList(contextTags) : null; } @@ -110,7 +110,7 @@ public SentryAppender( minimumEventLevel, debug, null, - HubAdapter.getInstance(), + ScopesAdapter.getInstance(), contextTags != null ? contextTags.split(",") : null); } @@ -149,13 +149,13 @@ public void append(final @NotNull LogEvent eventObject) { final Hint hint = new Hint(); hint.set(SENTRY_SYNTHETIC_EXCEPTION, eventObject); - hub.captureEvent(createEvent(eventObject), hint); + scopes.captureEvent(createEvent(eventObject), hint); } if (eventObject.getLevel().isMoreSpecificThan(minimumBreadcrumbLevel)) { final Hint hint = new Hint(); hint.set(LOG4J_LOG_EVENT, eventObject); - hub.addBreadcrumb(createBreadcrumb(eventObject), hint); + scopes.addBreadcrumb(createBreadcrumb(eventObject), hint); } } @@ -199,9 +199,9 @@ public void append(final @NotNull LogEvent eventObject) { CollectionUtils.filterMapEntries( loggingEvent.getContextData().toMap(), entry -> entry.getValue() != null); if (!contextData.isEmpty()) { - // get tags from HubAdapter options to allow getting the correct tags if Sentry has been + // get tags from ScopesAdapter options to allow getting the correct tags if Sentry has been // initialized somewhere else - final List contextTags = hub.getOptions().getContextTags(); + final List contextTags = scopes.getOptions().getContextTags(); if (contextTags != null && !contextTags.isEmpty()) { for (final String contextTag : contextTags) { // if mdc tag is listed in SentryOptions, apply as event tag diff --git a/sentry-log4j2/src/test/kotlin/io/sentry/log4j2/SentryAppenderTest.kt b/sentry-log4j2/src/test/kotlin/io/sentry/log4j2/SentryAppenderTest.kt index b6f004232c..3786555a61 100644 --- a/sentry-log4j2/src/test/kotlin/io/sentry/log4j2/SentryAppenderTest.kt +++ b/sentry-log4j2/src/test/kotlin/io/sentry/log4j2/SentryAppenderTest.kt @@ -1,7 +1,7 @@ package io.sentry.log4j2 -import io.sentry.HubAdapter import io.sentry.ITransportFactory +import io.sentry.ScopesAdapter import io.sentry.Sentry import io.sentry.SentryLevel import io.sentry.checkEvent @@ -49,7 +49,7 @@ class SentryAppenderTest { } loggerContext.start() val config: Configuration = loggerContext.configuration - val appender = SentryAppender("sentry", null, "http://key@localhost/proj", minimumBreadcrumbLevel, minimumEventLevel, debug, this.transportFactory, HubAdapter.getInstance(), contextTags?.toTypedArray()) + val appender = SentryAppender("sentry", null, "http://key@localhost/proj", minimumBreadcrumbLevel, minimumEventLevel, debug, this.transportFactory, ScopesAdapter.getInstance(), contextTags?.toTypedArray()) config.addAppender(appender) val ref = AppenderRef.createAppenderRef("sentry", null, null) @@ -445,6 +445,6 @@ class SentryAppenderTest { @Test fun `sets the debug mode`() { fixture.getSut(debug = true) - assertTrue(HubAdapter.getInstance().options.isDebug) + assertTrue(ScopesAdapter.getInstance().options.isDebug) } } diff --git a/sentry-logback/src/main/java/io/sentry/logback/SentryAppender.java b/sentry-logback/src/main/java/io/sentry/logback/SentryAppender.java index d0be108149..56db0b4dbc 100644 --- a/sentry-logback/src/main/java/io/sentry/logback/SentryAppender.java +++ b/sentry-logback/src/main/java/io/sentry/logback/SentryAppender.java @@ -12,8 +12,8 @@ import io.sentry.Breadcrumb; import io.sentry.DateUtils; import io.sentry.Hint; -import io.sentry.HubAdapter; import io.sentry.ITransportFactory; +import io.sentry.ScopesAdapter; import io.sentry.Sentry; import io.sentry.SentryEvent; import io.sentry.SentryIntegrationPackageStorage; @@ -134,9 +134,9 @@ protected void append(@NotNull ILoggingEvent eventObject) { CollectionUtils.filterMapEntries( loggingEvent.getMDCPropertyMap(), entry -> entry.getValue() != null); if (!mdcProperties.isEmpty()) { - // get tags from HubAdapter options to allow getting the correct tags if Sentry has been + // get tags from ScopesAdapter options to allow getting the correct tags if Sentry has been // initialized somewhere else - final List contextTags = HubAdapter.getInstance().getOptions().getContextTags(); + final List contextTags = ScopesAdapter.getInstance().getOptions().getContextTags(); if (!contextTags.isEmpty()) { for (final String contextTag : contextTags) { // if mdc tag is listed in SentryOptions, apply as event tag diff --git a/sentry-okhttp/api/sentry-okhttp.api b/sentry-okhttp/api/sentry-okhttp.api index 3095659c88..9cb875ff34 100644 --- a/sentry-okhttp/api/sentry-okhttp.api +++ b/sentry-okhttp/api/sentry-okhttp.api @@ -6,12 +6,12 @@ public final class io/sentry/okhttp/BuildConfig { public class io/sentry/okhttp/SentryOkHttpEventListener : okhttp3/EventListener { public static final field Companion Lio/sentry/okhttp/SentryOkHttpEventListener$Companion; public fun ()V - public fun (Lio/sentry/IHub;Lkotlin/jvm/functions/Function1;)V - public synthetic fun (Lio/sentry/IHub;Lkotlin/jvm/functions/Function1;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public fun (Lio/sentry/IHub;Lokhttp3/EventListener$Factory;)V - public synthetic fun (Lio/sentry/IHub;Lokhttp3/EventListener$Factory;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public fun (Lio/sentry/IHub;Lokhttp3/EventListener;)V - public synthetic fun (Lio/sentry/IHub;Lokhttp3/EventListener;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lio/sentry/IScopes;Lkotlin/jvm/functions/Function1;)V + public synthetic fun (Lio/sentry/IScopes;Lkotlin/jvm/functions/Function1;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lio/sentry/IScopes;Lokhttp3/EventListener$Factory;)V + public synthetic fun (Lio/sentry/IScopes;Lokhttp3/EventListener$Factory;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lio/sentry/IScopes;Lokhttp3/EventListener;)V + public synthetic fun (Lio/sentry/IScopes;Lokhttp3/EventListener;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun (Lokhttp3/EventListener$Factory;)V public fun (Lokhttp3/EventListener;)V public fun cacheConditionalHit (Lokhttp3/Call;Lokhttp3/Response;)V @@ -50,9 +50,9 @@ public final class io/sentry/okhttp/SentryOkHttpEventListener$Companion { public class io/sentry/okhttp/SentryOkHttpInterceptor : okhttp3/Interceptor { public fun ()V - public fun (Lio/sentry/IHub;)V - public fun (Lio/sentry/IHub;Lio/sentry/okhttp/SentryOkHttpInterceptor$BeforeSpanCallback;ZLjava/util/List;Ljava/util/List;)V - public synthetic fun (Lio/sentry/IHub;Lio/sentry/okhttp/SentryOkHttpInterceptor$BeforeSpanCallback;ZLjava/util/List;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lio/sentry/IScopes;)V + public fun (Lio/sentry/IScopes;Lio/sentry/okhttp/SentryOkHttpInterceptor$BeforeSpanCallback;ZLjava/util/List;Ljava/util/List;)V + public synthetic fun (Lio/sentry/IScopes;Lio/sentry/okhttp/SentryOkHttpInterceptor$BeforeSpanCallback;ZLjava/util/List;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun (Lio/sentry/okhttp/SentryOkHttpInterceptor$BeforeSpanCallback;)V public fun intercept (Lokhttp3/Interceptor$Chain;)Lokhttp3/Response; } diff --git a/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpEvent.kt b/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpEvent.kt index 00cc26e754..153499210c 100644 --- a/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpEvent.kt +++ b/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpEvent.kt @@ -2,7 +2,7 @@ package io.sentry.okhttp import io.sentry.Breadcrumb import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ISpan import io.sentry.SentryDate import io.sentry.SentryLevel @@ -30,7 +30,7 @@ private const val RESPONSE_BODY_TIMEOUT_MILLIS = 800L internal const val TRACE_ORIGIN = "auto.http.okhttp" @Suppress("TooManyFunctions") -internal class SentryOkHttpEvent(private val hub: IHub, private val request: Request) { +internal class SentryOkHttpEvent(private val scopes: IScopes, private val request: Request) { private val eventSpans: MutableMap = ConcurrentHashMap() private val breadcrumb: Breadcrumb internal val callRootSpan: ISpan? @@ -47,7 +47,7 @@ internal class SentryOkHttpEvent(private val hub: IHub, private val request: Req val method: String = request.method // We start the call span that will contain all the others - val parentSpan = if (Platform.isAndroid()) hub.transaction else hub.span + val parentSpan = if (Platform.isAndroid()) scopes.transaction else scopes.span callRootSpan = parentSpan?.startChild("http.client", "$method $url") callRootSpan?.spanContext?.origin = TRACE_ORIGIN urlDetails.applyToSpan(callRootSpan) @@ -149,13 +149,13 @@ internal class SentryOkHttpEvent(private val hub: IHub, private val request: Req response?.let { hint.set(TypeCheckHint.OKHTTP_RESPONSE, it) } // We send the breadcrumb even without spans. - hub.addBreadcrumb(breadcrumb, hint) + scopes.addBreadcrumb(breadcrumb, hint) // No span is created (e.g. no transaction is running) if (callRootSpan == null) { // We report the client error even without spans. clientErrorResponse?.let { - SentryOkHttpUtils.captureClientError(hub, it.request, it) + SentryOkHttpUtils.captureClientError(scopes, it.request, it) } return } @@ -173,7 +173,7 @@ internal class SentryOkHttpEvent(private val hub: IHub, private val request: Req // We report the client error here, after all sub-spans finished, so that it will be bound // to the root call span. clientErrorResponse?.let { - SentryOkHttpUtils.captureClientError(hub, it.request, it) + SentryOkHttpUtils.captureClientError(scopes, it.request, it) } if (finishDate != null) { callRootSpan.finish(callRootSpan.status, finishDate) @@ -204,7 +204,7 @@ internal class SentryOkHttpEvent(private val hub: IHub, private val request: Req fun scheduleFinish(timestamp: SentryDate) { try { - hub.options.executorService.schedule({ + scopes.options.executorService.schedule({ if (!isReadingResponseBody.get() && (eventSpans.values.all { it.isFinished } || callRootSpan?.isFinished != true) ) { @@ -212,7 +212,7 @@ internal class SentryOkHttpEvent(private val hub: IHub, private val request: Req } }, RESPONSE_BODY_TIMEOUT_MILLIS) } catch (e: RejectedExecutionException) { - hub.options + scopes.options .logger .log( SentryLevel.ERROR, diff --git a/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpEventListener.kt b/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpEventListener.kt index 67a8cd8b56..f20e2ef0cb 100644 --- a/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpEventListener.kt +++ b/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpEventListener.kt @@ -1,7 +1,7 @@ package io.sentry.okhttp -import io.sentry.HubAdapter -import io.sentry.IHub +import io.sentry.IScopes +import io.sentry.ScopesAdapter import io.sentry.SpanDataConvention import io.sentry.SpanStatus import okhttp3.Call @@ -41,7 +41,7 @@ import java.util.concurrent.ConcurrentHashMap */ @Suppress("TooManyFunctions") public open class SentryOkHttpEventListener( - private val hub: IHub = HubAdapter.getInstance(), + private val scopes: IScopes = ScopesAdapter.getInstance(), private val originalEventListenerCreator: ((call: Call) -> EventListener)? = null ) : EventListener() { @@ -62,27 +62,27 @@ public open class SentryOkHttpEventListener( } public constructor() : this( - HubAdapter.getInstance(), + ScopesAdapter.getInstance(), originalEventListenerCreator = null ) public constructor(originalEventListener: EventListener) : this( - HubAdapter.getInstance(), + ScopesAdapter.getInstance(), originalEventListenerCreator = { originalEventListener } ) public constructor(originalEventListenerFactory: Factory) : this( - HubAdapter.getInstance(), + ScopesAdapter.getInstance(), originalEventListenerCreator = { originalEventListenerFactory.create(it) } ) - public constructor(hub: IHub = HubAdapter.getInstance(), originalEventListener: EventListener) : this( - hub, + public constructor(scopes: IScopes = ScopesAdapter.getInstance(), originalEventListener: EventListener) : this( + scopes, originalEventListenerCreator = { originalEventListener } ) - public constructor(hub: IHub = HubAdapter.getInstance(), originalEventListenerFactory: Factory) : this( - hub, + public constructor(scopes: IScopes = ScopesAdapter.getInstance(), originalEventListenerFactory: Factory) : this( + scopes, originalEventListenerCreator = { originalEventListenerFactory.create(it) } ) @@ -92,7 +92,7 @@ public open class SentryOkHttpEventListener( // If the wrapped EventListener is ours, we can just delegate the calls, // without creating other events that would create duplicates if (canCreateEventSpan()) { - eventMap[call] = SentryOkHttpEvent(hub, call.request()) + eventMap[call] = SentryOkHttpEvent(scopes, call.request()) } } @@ -318,7 +318,7 @@ public open class SentryOkHttpEventListener( it.status = SpanStatus.fromHttpStatusCode(response.code) } } - okHttpEvent.scheduleFinish(responseHeadersSpan?.finishDate ?: hub.options.dateProvider.now()) + okHttpEvent.scheduleFinish(responseHeadersSpan?.finishDate ?: scopes.options.dateProvider.now()) } override fun responseBodyStart(call: Call) { diff --git a/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpInterceptor.kt b/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpInterceptor.kt index efa472963d..a079864612 100644 --- a/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpInterceptor.kt +++ b/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpInterceptor.kt @@ -4,9 +4,9 @@ import io.sentry.BaggageHeader import io.sentry.Breadcrumb import io.sentry.Hint import io.sentry.HttpStatusCodeRange -import io.sentry.HubAdapter -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ISpan +import io.sentry.ScopesAdapter import io.sentry.SentryIntegrationPackageStorage import io.sentry.SentryOptions.DEFAULT_PROPAGATION_TARGETS import io.sentry.SpanDataConvention @@ -29,7 +29,7 @@ import java.io.IOException * out of the active span bound to the scope for each HTTP Request. * If [captureFailedRequests] is enabled, the SDK will capture HTTP Client errors as well. * - * @param hub The [IHub], internal and only used for testing. + * @param scopes The [IScopes], internal and only used for testing. * @param beforeSpan The [ISpan] can be customized or dropped with the [BeforeSpanCallback]. * @param captureFailedRequests The SDK will only capture HTTP Client errors if it is enabled, * Defaults to false. @@ -39,7 +39,7 @@ import java.io.IOException * is a match for any of the defined targets. */ public open class SentryOkHttpInterceptor( - private val hub: IHub = HubAdapter.getInstance(), + private val scopes: IScopes = ScopesAdapter.getInstance(), private val beforeSpan: BeforeSpanCallback? = null, private val captureFailedRequests: Boolean = true, private val failedRequestStatusCodes: List = listOf( @@ -48,9 +48,9 @@ public open class SentryOkHttpInterceptor( private val failedRequestTargets: List = listOf(DEFAULT_PROPAGATION_TARGETS) ) : Interceptor { - public constructor() : this(HubAdapter.getInstance()) - public constructor(hub: IHub) : this(hub, null) - public constructor(beforeSpan: BeforeSpanCallback) : this(HubAdapter.getInstance(), beforeSpan) + public constructor() : this(ScopesAdapter.getInstance()) + public constructor(scopes: IScopes) : this(scopes, null) + public constructor(beforeSpan: BeforeSpanCallback) : this(ScopesAdapter.getInstance(), beforeSpan) init { addIntegrationToSdkVersion(javaClass) @@ -76,7 +76,7 @@ public open class SentryOkHttpInterceptor( } else { // read the span from the bound scope okHttpEvent = null - val parentSpan = if (Platform.isAndroid()) hub.transaction else hub.span + val parentSpan = if (Platform.isAndroid()) scopes.transaction else scopes.span span = parentSpan?.startChild("http.client", "$method $url") } @@ -92,7 +92,7 @@ public open class SentryOkHttpInterceptor( val requestBuilder = request.newBuilder() TracingUtils.traceIfAllowed( - hub, + scopes, request.url.toString(), request.headers(BaggageHeader.BAGGAGE_HEADER), span @@ -121,7 +121,7 @@ public open class SentryOkHttpInterceptor( if (isFromEventListener && okHttpEvent != null) { okHttpEvent.setClientErrorResponse(response) } else { - SentryOkHttpUtils.captureClientError(hub, request, response) + SentryOkHttpUtils.captureClientError(scopes, request, response) } } @@ -157,7 +157,7 @@ public open class SentryOkHttpInterceptor( hint[OKHTTP_RESPONSE] = it } - hub.addBreadcrumb(breadcrumb, hint) + scopes.addBreadcrumb(breadcrumb, hint) } private fun finishSpan(span: ISpan?, request: Request, response: Response?, isFromEventListener: Boolean) { diff --git a/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpUtils.kt b/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpUtils.kt index 0cfc1c5a75..eea35ca22e 100644 --- a/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpUtils.kt +++ b/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpUtils.kt @@ -1,7 +1,7 @@ package io.sentry.okhttp import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryEvent import io.sentry.TypeCheckHint import io.sentry.exception.ExceptionMechanismException @@ -15,7 +15,7 @@ import okhttp3.Response internal object SentryOkHttpUtils { - internal fun captureClientError(hub: IHub, request: Request, response: Response) { + internal fun captureClientError(scopes: IScopes, request: Request, response: Response) { // not possible to get a parameterized url, but we remove at least the // query string and the fragment. // url example: https://api.github.com/users/getsentry/repos/#fragment?query=query @@ -40,9 +40,9 @@ internal object SentryOkHttpUtils { val sentryRequest = io.sentry.protocol.Request().apply { urlDetails.applyToRequest(this) // Cookie is only sent if isSendDefaultPii is enabled - cookies = if (hub.options.isSendDefaultPii) request.headers["Cookie"] else null + cookies = if (scopes.options.isSendDefaultPii) request.headers["Cookie"] else null method = request.method - headers = getHeaders(hub, request.headers) + headers = getHeaders(scopes, request.headers) request.body?.contentLength().ifHasValidLength { bodySize = it @@ -51,8 +51,8 @@ internal object SentryOkHttpUtils { val sentryResponse = io.sentry.protocol.Response().apply { // Set-Cookie is only sent if isSendDefaultPii is enabled due to PII - cookies = if (hub.options.isSendDefaultPii) response.headers["Set-Cookie"] else null - headers = getHeaders(hub, response.headers) + cookies = if (scopes.options.isSendDefaultPii) response.headers["Set-Cookie"] else null + headers = getHeaders(scopes, response.headers) statusCode = response.code response.body?.contentLength().ifHasValidLength { @@ -63,7 +63,7 @@ internal object SentryOkHttpUtils { event.request = sentryRequest event.contexts.setResponse(sentryResponse) - hub.captureEvent(event, hint) + scopes.captureEvent(event, hint) } private fun Long?.ifHasValidLength(fn: (Long) -> Unit) { @@ -72,9 +72,9 @@ internal object SentryOkHttpUtils { } } - private fun getHeaders(hub: IHub, requestHeaders: Headers): MutableMap? { + private fun getHeaders(scopes: IScopes, requestHeaders: Headers): MutableMap? { // Headers are only sent if isSendDefaultPii is enabled due to PII - if (!hub.options.isSendDefaultPii) { + if (!scopes.options.isSendDefaultPii) { return null } diff --git a/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpEventListenerTest.kt b/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpEventListenerTest.kt index 1d90da70fe..3a90a4c05c 100644 --- a/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpEventListenerTest.kt +++ b/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpEventListenerTest.kt @@ -1,7 +1,7 @@ package io.sentry.okhttp import io.sentry.BaggageHeader -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryOptions import io.sentry.SentryTraceHeader import io.sentry.SentryTracer @@ -36,7 +36,7 @@ import kotlin.test.assertTrue class SentryOkHttpEventListenerTest { class Fixture { - val hub = mock() + val scopes = mock() val server = MockWebServer() val mockEventListener = mock() val mockEventListenerFactory = mock() @@ -63,12 +63,12 @@ class SentryOkHttpEventListenerTest { isSendDefaultPii = sendDefaultPii configureOptions(this) } - whenever(hub.options).thenReturn(options) + whenever(scopes.options).thenReturn(options) - sentryTracer = SentryTracer(TransactionContext("name", "op"), hub) + sentryTracer = SentryTracer(TransactionContext("name", "op"), scopes) if (isSpanActive) { - whenever(hub.span).thenReturn(sentryTracer) + whenever(scopes.span).thenReturn(sentryTracer) } server.enqueue( MockResponse() @@ -80,12 +80,12 @@ class SentryOkHttpEventListenerTest { val builder = OkHttpClient.Builder() if (useInterceptor) { - builder.addInterceptor(SentryOkHttpInterceptor(hub)) + builder.addInterceptor(SentryOkHttpInterceptor(scopes)) } sentryOkHttpEventListener = when { - eventListenerFactory != null -> SentryOkHttpEventListener(hub, eventListenerFactory) - eventListener != null -> SentryOkHttpEventListener(hub, eventListener) - else -> SentryOkHttpEventListener(hub) + eventListenerFactory != null -> SentryOkHttpEventListener(scopes, eventListenerFactory) + eventListener != null -> SentryOkHttpEventListener(scopes, eventListener) + else -> SentryOkHttpEventListener(scopes) } return builder.eventListener(sentryOkHttpEventListener).build() } @@ -276,7 +276,7 @@ class SentryOkHttpEventListenerTest { @Test fun `propagate all calls to the SentryOkHttpEventListener passed in the ctor`() { - val originalListener = spy(SentryOkHttpEventListener(fixture.hub, fixture.mockEventListener)) + val originalListener = spy(SentryOkHttpEventListener(fixture.scopes, fixture.mockEventListener)) val sut = fixture.getSut(eventListener = originalListener) val listener = fixture.sentryOkHttpEventListener val request = postRequest(body = "requestBody") @@ -288,7 +288,7 @@ class SentryOkHttpEventListenerTest { @Test fun `propagate all calls to the SentryOkHttpEventListener factory passed in the ctor`() { - val originalListener = spy(SentryOkHttpEventListener(fixture.hub, fixture.mockEventListener)) + val originalListener = spy(SentryOkHttpEventListener(fixture.scopes, fixture.mockEventListener)) val sut = fixture.getSut(eventListenerFactory = { originalListener }) val listener = fixture.sentryOkHttpEventListener val request = postRequest(body = "requestBody") @@ -300,7 +300,7 @@ class SentryOkHttpEventListenerTest { @Test fun `does not duplicated spans if an SentryOkHttpEventListener is passed in the ctor`() { - val originalListener = spy(SentryOkHttpEventListener(fixture.hub, fixture.mockEventListener)) + val originalListener = spy(SentryOkHttpEventListener(fixture.scopes, fixture.mockEventListener)) val sut = fixture.getSut(eventListener = originalListener) val request = postRequest(body = "requestBody") val call = sut.newCall(request) @@ -363,8 +363,8 @@ class SentryOkHttpEventListenerTest { @Test fun `responseHeadersEnd schedules event finish`() { - val listener = SentryOkHttpEventListener(fixture.hub, fixture.mockEventListener) - whenever(fixture.hub.options).thenReturn(SentryOptions()) + val listener = SentryOkHttpEventListener(fixture.scopes, fixture.mockEventListener) + whenever(fixture.scopes.options).thenReturn(SentryOptions()) val call = mock() whenever(call.request()).thenReturn(getRequest()) val okHttpEvent = mock() diff --git a/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpEventTest.kt b/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpEventTest.kt index 337f722848..4d9f005143 100644 --- a/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpEventTest.kt +++ b/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpEventTest.kt @@ -2,7 +2,7 @@ package io.sentry.okhttp import io.sentry.Breadcrumb import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ISentryExecutorService import io.sentry.ISpan import io.sentry.SentryDate @@ -50,14 +50,14 @@ import kotlin.test.assertTrue class SentryOkHttpEventTest { private class Fixture { - val hub = mock() + val scopes = mock() val server = MockWebServer() val span: ISpan val mockRequest: Request val response: Response init { - whenever(hub.options).thenReturn( + whenever(scopes.options).thenReturn( SentryOptions().apply { dsn = "https://key@sentry.io/proj" } @@ -65,8 +65,8 @@ class SentryOkHttpEventTest { span = Span( TransactionContext("name", "op", TracesSamplingDecision(true)), - SentryTracer(TransactionContext("name", "op", TracesSamplingDecision(true)), hub), - hub, + SentryTracer(TransactionContext("name", "op", TracesSamplingDecision(true)), scopes), + scopes, null, SpanOptions() ) @@ -86,7 +86,7 @@ class SentryOkHttpEventTest { } fun getSut(currentSpan: ISpan? = span, requestUrl: String ? = null): SentryOkHttpEvent { - whenever(hub.span).thenReturn(currentSpan) + whenever(scopes.span).thenReturn(currentSpan) val request = if (requestUrl == null) { mockRequest } else { @@ -96,7 +96,7 @@ class SentryOkHttpEventTest { .url(server.url(requestUrl)) .build() } - return SentryOkHttpEvent(hub, request) + return SentryOkHttpEvent(scopes, request) } } @@ -126,7 +126,7 @@ class SentryOkHttpEventTest { val sut = fixture.getSut(currentSpan = null) assertNull(sut.callRootSpan) sut.finishEvent() - verify(fixture.hub).addBreadcrumb(any(), anyOrNull()) + verify(fixture.scopes).addBreadcrumb(any(), anyOrNull()) } @Test @@ -240,7 +240,7 @@ class SentryOkHttpEventTest { fun `when finishEvent, a breadcrumb is captured with request in the hint`() { val sut = fixture.getSut() sut.finishEvent() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals(fixture.mockRequest.url.toString(), it.data["url"]) assertEquals(fixture.mockRequest.url.host, it.data["host"]) @@ -258,7 +258,7 @@ class SentryOkHttpEventTest { val sut = fixture.getSut() sut.finishEvent() sut.finishEvent() - verify(fixture.hub, times(1)).addBreadcrumb(any(), any()) + verify(fixture.scopes, times(1)).addBreadcrumb(any(), any()) } @Test @@ -283,7 +283,7 @@ class SentryOkHttpEventTest { assertEquals(fixture.response.code, sut.callRootSpan?.getData(SpanDataConvention.HTTP_STATUS_CODE_KEY)) sut.finishEvent() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals(fixture.response.protocol.name, it.data["protocol"]) assertEquals(fixture.response.code, it.data["status_code"]) @@ -300,7 +300,7 @@ class SentryOkHttpEventTest { sut.setProtocol("protocol") assertEquals("protocol", sut.callRootSpan?.getData("protocol")) sut.finishEvent() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("protocol", it.data["protocol"]) }, @@ -314,7 +314,7 @@ class SentryOkHttpEventTest { sut.setProtocol(null) assertNull(sut.callRootSpan?.getData("protocol")) sut.finishEvent() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertNull(it.data["protocol"]) }, @@ -328,7 +328,7 @@ class SentryOkHttpEventTest { sut.setRequestBodySize(10) assertEquals(10L, sut.callRootSpan?.getData("http.request_content_length")) sut.finishEvent() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals(10L, it.data["request_content_length"]) }, @@ -342,7 +342,7 @@ class SentryOkHttpEventTest { sut.setRequestBodySize(-1) assertNull(sut.callRootSpan?.getData("http.request_content_length")) sut.finishEvent() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertNull(it.data["request_content_length"]) }, @@ -356,7 +356,7 @@ class SentryOkHttpEventTest { sut.setResponseBodySize(10) assertEquals(10L, sut.callRootSpan?.getData(SpanDataConvention.HTTP_RESPONSE_CONTENT_LENGTH_KEY)) sut.finishEvent() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals(10L, it.data["response_content_length"]) }, @@ -370,7 +370,7 @@ class SentryOkHttpEventTest { sut.setResponseBodySize(-1) assertNull(sut.callRootSpan?.getData(SpanDataConvention.HTTP_RESPONSE_CONTENT_LENGTH_KEY)) sut.finishEvent() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertNull(it.data["response_content_length"]) }, @@ -384,7 +384,7 @@ class SentryOkHttpEventTest { sut.setError("errorMessage") assertEquals("errorMessage", sut.callRootSpan?.getData("error_message")) sut.finishEvent() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("errorMessage", it.data["error_message"]) }, @@ -399,7 +399,7 @@ class SentryOkHttpEventTest { assertNotNull(sut.callRootSpan) assertNull(sut.callRootSpan.getData("error_message")) sut.finishEvent() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertNull(it.data["error_message"]) }, @@ -532,7 +532,7 @@ class SentryOkHttpEventTest { @Test fun `scheduleFinish schedules finishEvent and finish running spans to specific timestamp`() { - fixture.hub.options.executorService = ImmediateExecutorService() + fixture.scopes.options.executorService = ImmediateExecutorService() val sut = spy(fixture.getSut()) val timestamp = mock() sut.startSpan(CONNECTION_EVENT) @@ -554,7 +554,7 @@ class SentryOkHttpEventTest { fun `scheduleFinish does not throw if executor is shut down`() { val executorService = mock() whenever(executorService.schedule(any(), any())).thenThrow(RejectedExecutionException()) - whenever(fixture.hub.options).thenReturn(SentryOptions().apply { this.executorService = executorService }) + whenever(fixture.scopes.options).thenReturn(SentryOptions().apply { this.executorService = executorService }) val sut = fixture.getSut() sut.scheduleFinish(mock()) } @@ -565,10 +565,10 @@ class SentryOkHttpEventTest { val clientErrorResponse = mock() whenever(clientErrorResponse.request).thenReturn(fixture.mockRequest) sut.setClientErrorResponse(clientErrorResponse) - verify(fixture.hub, never()).captureEvent(any(), any()) + verify(fixture.scopes, never()).captureEvent(any(), any()) sut.finishEvent() assertNotNull(sut.callRootSpan) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( argThat { throwable is SentryHttpClientException && throwable!!.message!!.startsWith("HTTP Client Error with status code: ") @@ -586,10 +586,10 @@ class SentryOkHttpEventTest { val clientErrorResponse = mock() whenever(clientErrorResponse.request).thenReturn(fixture.mockRequest) sut.setClientErrorResponse(clientErrorResponse) - verify(fixture.hub, never()).captureEvent(any(), any()) + verify(fixture.scopes, never()).captureEvent(any(), any()) sut.finishEvent() assertNull(sut.callRootSpan) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( argThat { throwable is SentryHttpClientException && throwable!!.message!!.startsWith("HTTP Client Error with status code: ") @@ -605,7 +605,7 @@ class SentryOkHttpEventTest { fun `when setClientErrorResponse is not called, no client error is captured`() { val sut = fixture.getSut() sut.finishEvent() - verify(fixture.hub, never()).captureEvent(any(), any()) + verify(fixture.scopes, never()).captureEvent(any(), any()) } /** Retrieve all the spans started in the event using reflection. */ diff --git a/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpInterceptorTest.kt b/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpInterceptorTest.kt index fce16d9220..f40b2c4cb5 100644 --- a/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpInterceptorTest.kt +++ b/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpInterceptorTest.kt @@ -6,8 +6,8 @@ import io.sentry.BaggageHeader import io.sentry.Breadcrumb import io.sentry.Hint import io.sentry.HttpStatusCodeRange -import io.sentry.IHub import io.sentry.IScope +import io.sentry.IScopes import io.sentry.Scope import io.sentry.ScopeCallback import io.sentry.SentryOptions @@ -47,7 +47,7 @@ import kotlin.test.fail class SentryOkHttpInterceptorTest { class Fixture { - val hub = mock() + val scopes = mock() val server = MockWebServer() lateinit var sentryTracer: SentryTracer lateinit var options: SentryOptions @@ -82,13 +82,13 @@ class SentryOkHttpInterceptorTest { isSendDefaultPii = sendDefaultPii } scope = Scope(options) - whenever(hub.options).thenReturn(options) - doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(hub).configureScope(any()) + whenever(scopes.options).thenReturn(options) + doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(scopes).configureScope(any()) - sentryTracer = SentryTracer(TransactionContext("name", "op"), hub) + sentryTracer = SentryTracer(TransactionContext("name", "op"), scopes) if (isSpanActive) { - whenever(hub.span).thenReturn(sentryTracer) + whenever(scopes.span).thenReturn(sentryTracer) } server.enqueue( MockResponse() @@ -100,14 +100,14 @@ class SentryOkHttpInterceptorTest { val interceptor = when (captureFailedRequests) { null -> SentryOkHttpInterceptor( - hub, + scopes, beforeSpan, failedRequestTargets = failedRequestTargets, failedRequestStatusCodes = failedRequestStatusCodes ) else -> SentryOkHttpInterceptor( - hub, + scopes, beforeSpan, captureFailedRequests = captureFailedRequests, failedRequestTargets = failedRequestTargets, @@ -281,7 +281,7 @@ class SentryOkHttpInterceptorTest { fun `adds breadcrumb when http calls succeeds`() { val sut = fixture.getSut(responseBody = "response body") sut.newCall(postRequest()).execute() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(13L, it.data[SpanDataConvention.HTTP_RESPONSE_CONTENT_LENGTH_KEY]) @@ -296,7 +296,7 @@ class SentryOkHttpInterceptorTest { fun `adds breadcrumb when http calls results in exception`() { // to setup mocks fixture.getSut() - val interceptor = SentryOkHttpInterceptor(fixture.hub) + val interceptor = SentryOkHttpInterceptor(fixture.scopes) val chain = mock() whenever(chain.call()).thenReturn(mock()) whenever(chain.proceed(any())).thenThrow(IOException()) @@ -308,7 +308,7 @@ class SentryOkHttpInterceptorTest { } catch (e: IOException) { // ignore me } - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) }, @@ -385,7 +385,7 @@ class SentryOkHttpInterceptorTest { ) sut.newCall(getRequest()).execute() - verify(fixture.hub).captureEvent(any(), any()) + verify(fixture.scopes).captureEvent(any(), any()) } @Test @@ -396,7 +396,7 @@ class SentryOkHttpInterceptorTest { ) sut.newCall(getRequest()).execute() - verify(fixture.hub).captureEvent(any(), any()) + verify(fixture.scopes).captureEvent(any(), any()) } @Test @@ -406,7 +406,7 @@ class SentryOkHttpInterceptorTest { ) sut.newCall(getRequest()).execute() - verify(fixture.hub, never()).captureEvent(any(), any()) + verify(fixture.scopes, never()).captureEvent(any(), any()) } @Test @@ -417,7 +417,7 @@ class SentryOkHttpInterceptorTest { ) sut.newCall(getRequest()).execute() - verify(fixture.hub, never()).captureEvent(any(), any()) + verify(fixture.scopes, never()).captureEvent(any(), any()) } @Test @@ -429,7 +429,7 @@ class SentryOkHttpInterceptorTest { ) sut.newCall(getRequest()).execute() - verify(fixture.hub, never()).captureEvent(any(), any()) + verify(fixture.scopes, never()).captureEvent(any(), any()) } @Test @@ -440,7 +440,7 @@ class SentryOkHttpInterceptorTest { ) sut.newCall(getRequest()).execute() - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( any(), check { assertNotNull(it.get(TypeCheckHint.OKHTTP_REQUEST)) @@ -462,7 +462,7 @@ class SentryOkHttpInterceptorTest { val request = getRequest(url = "/hello?myQuery=myValue#myFragment") val response = sut.newCall(request).execute() - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { val sentryRequest = it.request!! assertEquals("http://localhost:${fixture.server.port}/hello", sentryRequest.url) @@ -503,7 +503,7 @@ class SentryOkHttpInterceptorTest { sut.newCall(postRequest(body = body)).execute() - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { val sentryRequest = it.request!! assertEquals(body.contentLength(), sentryRequest.bodySize) @@ -522,7 +522,7 @@ class SentryOkHttpInterceptorTest { sut.newCall(getRequest()).execute() - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { val sentryRequest = it.request!! assertEquals("myValue", sentryRequest.headers!!["myHeader"]) @@ -540,7 +540,7 @@ class SentryOkHttpInterceptorTest { // to setup mocks fixture.getSut() val interceptor = SentryOkHttpInterceptor( - fixture.hub, + fixture.scopes, captureFailedRequests = true ) val chain = mock() @@ -554,7 +554,7 @@ class SentryOkHttpInterceptorTest { } catch (e: IOException) { // ignore me } - verify(fixture.hub, never()).captureEvent(any(), any()) + verify(fixture.scopes, never()).captureEvent(any(), any()) } @Test @@ -565,7 +565,7 @@ class SentryOkHttpInterceptorTest { call.execute() val httpClientSpan = fixture.sentryTracer.children.firstOrNull() assertNull(httpClientSpan) - verify(fixture.hub, never()).addBreadcrumb(any(), anyOrNull()) + verify(fixture.scopes, never()).addBreadcrumb(any(), anyOrNull()) } @Test @@ -573,7 +573,7 @@ class SentryOkHttpInterceptorTest { val sut = fixture.getSut(captureFailedRequests = true, httpStatusCode = 500) val call = sut.newCall(getRequest()) call.execute() - verify(fixture.hub).captureEvent(any(), any()) + verify(fixture.scopes).captureEvent(any(), any()) } @Test @@ -582,6 +582,6 @@ class SentryOkHttpInterceptorTest { val call = sut.newCall(getRequest()) SentryOkHttpEventListener.eventMap[call] = mock() call.execute() - verify(fixture.hub, never()).captureEvent(any(), any()) + verify(fixture.scopes, never()).captureEvent(any(), any()) } } diff --git a/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpUtilsTest.kt b/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpUtilsTest.kt index ec19454327..c7194e5994 100644 --- a/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpUtilsTest.kt +++ b/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpUtilsTest.kt @@ -1,7 +1,7 @@ package io.sentry.okhttp import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryOptions import io.sentry.SentryTracer import io.sentry.TransactionContext @@ -29,7 +29,7 @@ import kotlin.test.assertTrue class SentryOkHttpUtilsTest { class Fixture { - val hub = mock() + val scopes = mock() val server = MockWebServer() fun getSut( @@ -43,11 +43,11 @@ class SentryOkHttpUtilsTest { setTracePropagationTargets(listOf(server.hostName)) isSendDefaultPii = sendDefaultPii } - whenever(hub.options).thenReturn(options) + whenever(scopes.options).thenReturn(options) - val sentryTracer = SentryTracer(TransactionContext("name", "op"), hub) + val sentryTracer = SentryTracer(TransactionContext("name", "op"), scopes) - whenever(hub.span).thenReturn(sentryTracer) + whenever(scopes.span).thenReturn(sentryTracer) server.enqueue( MockResponse() @@ -78,8 +78,8 @@ class SentryOkHttpUtilsTest { val request = getRequest() val response = sut.newCall(request).execute() - SentryOkHttpUtils.captureClientError(fixture.hub, request, response) - verify(fixture.hub).captureEvent( + SentryOkHttpUtils.captureClientError(fixture.scopes, request, response) + verify(fixture.scopes).captureEvent( check { val req = it.request val resp = it.contexts.response @@ -103,8 +103,8 @@ class SentryOkHttpUtilsTest { val request = getRequest() val response = sut.newCall(request).execute() - SentryOkHttpUtils.captureClientError(fixture.hub, request, response) - verify(fixture.hub).captureEvent( + SentryOkHttpUtils.captureClientError(fixture.scopes, request, response) + verify(fixture.scopes).captureEvent( check { val req = it.request val resp = it.contexts.response @@ -127,8 +127,8 @@ class SentryOkHttpUtilsTest { val request = getRequest() val response = sut.newCall(request).execute() - SentryOkHttpUtils.captureClientError(fixture.hub, request, response) - verify(fixture.hub).captureEvent( + SentryOkHttpUtils.captureClientError(fixture.scopes, request, response) + verify(fixture.scopes).captureEvent( check { val req = it.request val resp = it.contexts.response diff --git a/sentry-openfeign/api/sentry-openfeign.api b/sentry-openfeign/api/sentry-openfeign.api index beb15c9e02..4ab65a5ca4 100644 --- a/sentry-openfeign/api/sentry-openfeign.api +++ b/sentry-openfeign/api/sentry-openfeign.api @@ -1,12 +1,12 @@ public final class io/sentry/openfeign/SentryCapability : feign/Capability { public fun ()V - public fun (Lio/sentry/IHub;Lio/sentry/openfeign/SentryFeignClient$BeforeSpanCallback;)V + public fun (Lio/sentry/IScopes;Lio/sentry/openfeign/SentryFeignClient$BeforeSpanCallback;)V public fun (Lio/sentry/openfeign/SentryFeignClient$BeforeSpanCallback;)V public fun enrich (Lfeign/Client;)Lfeign/Client; } public final class io/sentry/openfeign/SentryFeignClient : feign/Client { - public fun (Lfeign/Client;Lio/sentry/IHub;Lio/sentry/openfeign/SentryFeignClient$BeforeSpanCallback;)V + public fun (Lfeign/Client;Lio/sentry/IScopes;Lio/sentry/openfeign/SentryFeignClient$BeforeSpanCallback;)V public fun execute (Lfeign/Request;Lfeign/Request$Options;)Lfeign/Response; } diff --git a/sentry-openfeign/src/main/java/io/sentry/openfeign/SentryCapability.java b/sentry-openfeign/src/main/java/io/sentry/openfeign/SentryCapability.java index b65685c3fd..1ad6b1f274 100644 --- a/sentry-openfeign/src/main/java/io/sentry/openfeign/SentryCapability.java +++ b/sentry-openfeign/src/main/java/io/sentry/openfeign/SentryCapability.java @@ -2,33 +2,34 @@ import feign.Capability; import feign.Client; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; +import io.sentry.ScopesAdapter; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** Adds Sentry tracing capability to Feign clients. */ public final class SentryCapability implements Capability { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @Nullable SentryFeignClient.BeforeSpanCallback beforeSpan; public SentryCapability( - final @NotNull IHub hub, final @Nullable SentryFeignClient.BeforeSpanCallback beforeSpan) { - this.hub = hub; + final @NotNull IScopes scopes, + final @Nullable SentryFeignClient.BeforeSpanCallback beforeSpan) { + this.scopes = scopes; this.beforeSpan = beforeSpan; } public SentryCapability(final @Nullable SentryFeignClient.BeforeSpanCallback beforeSpan) { - this(HubAdapter.getInstance(), beforeSpan); + this(ScopesAdapter.getInstance(), beforeSpan); } public SentryCapability() { - this(HubAdapter.getInstance(), null); + this(ScopesAdapter.getInstance(), null); } @Override public @NotNull Client enrich(final @NotNull Client client) { - return new SentryFeignClient(client, hub, beforeSpan); + return new SentryFeignClient(client, scopes, beforeSpan); } } diff --git a/sentry-openfeign/src/main/java/io/sentry/openfeign/SentryFeignClient.java b/sentry-openfeign/src/main/java/io/sentry/openfeign/SentryFeignClient.java index cb8aa3d9e0..037768c7ad 100644 --- a/sentry-openfeign/src/main/java/io/sentry/openfeign/SentryFeignClient.java +++ b/sentry-openfeign/src/main/java/io/sentry/openfeign/SentryFeignClient.java @@ -9,7 +9,7 @@ import io.sentry.BaggageHeader; import io.sentry.Breadcrumb; import io.sentry.Hint; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ISpan; import io.sentry.SpanDataConvention; import io.sentry.SpanStatus; @@ -30,15 +30,15 @@ public final class SentryFeignClient implements Client { private static final String TRACE_ORIGIN = "auto.http.openfeign"; private final @NotNull Client delegate; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @Nullable BeforeSpanCallback beforeSpan; public SentryFeignClient( final @NotNull Client delegate, - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @Nullable BeforeSpanCallback beforeSpan) { this.delegate = Objects.requireNonNull(delegate, "delegate is required"); - this.hub = Objects.requireNonNull(hub, "hub is required"); + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); this.beforeSpan = beforeSpan; } @@ -47,7 +47,7 @@ public Response execute(final @NotNull Request request, final @NotNull Request.O throws IOException { Response response = null; try { - final ISpan activeSpan = hub.getSpan(); + final ISpan activeSpan = scopes.getSpan(); if (activeSpan == null) { final @NotNull Request modifiedRequest = maybeAddTracingHeaders(request, null); @@ -102,7 +102,7 @@ public Response execute(final @NotNull Request request, final @NotNull Request.O final @Nullable TracingUtils.TracingHeaders tracingHeaders = TracingUtils.traceIfAllowed( - hub, + scopes, request.url(), (requestBaggageHeaders != null ? new ArrayList<>(requestBaggageHeaders) : null), span); @@ -139,7 +139,7 @@ private void addBreadcrumb(final @NotNull Request request, final @Nullable Respo hint.set(OPEN_FEIGN_RESPONSE, response); } - hub.addBreadcrumb(breadcrumb, hint); + scopes.addBreadcrumb(breadcrumb, hint); } static final class RequestWrapper { diff --git a/sentry-openfeign/src/test/kotlin/io/sentry/openfeign/SentryFeignClientTest.kt b/sentry-openfeign/src/test/kotlin/io/sentry/openfeign/SentryFeignClientTest.kt index 65e56ab02b..959b890d46 100644 --- a/sentry-openfeign/src/test/kotlin/io/sentry/openfeign/SentryFeignClientTest.kt +++ b/sentry-openfeign/src/test/kotlin/io/sentry/openfeign/SentryFeignClientTest.kt @@ -7,7 +7,7 @@ import feign.HeaderMap import feign.RequestLine import io.sentry.BaggageHeader import io.sentry.Breadcrumb -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.Scope import io.sentry.ScopeCallback import io.sentry.SentryOptions @@ -37,7 +37,7 @@ import kotlin.test.fail class SentryFeignClientTest { class Fixture { - val hub = mock() + val scopes = mock() val server = MockWebServer() val sentryTracer: SentryTracer val sentryOptions = SentryOptions().apply { @@ -46,9 +46,9 @@ class SentryFeignClientTest { val scope = Scope(sentryOptions) init { - whenever(hub.options).thenReturn(sentryOptions) - doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(hub).configureScope(any()) - sentryTracer = SentryTracer(TransactionContext("name", "op"), hub) + whenever(scopes.options).thenReturn(sentryOptions) + doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(scopes).configureScope(any()) + sentryTracer = SentryTracer(TransactionContext("name", "op"), scopes) } fun getSut( @@ -59,7 +59,7 @@ class SentryFeignClientTest { beforeSpan: SentryFeignClient.BeforeSpanCallback? = null ): MockApi { if (isSpanActive) { - whenever(hub.span).thenReturn(sentryTracer) + whenever(scopes.span).thenReturn(sentryTracer) } server.enqueue( MockResponse() @@ -70,12 +70,12 @@ class SentryFeignClientTest { return if (!networkError) { Feign.builder() - .addCapability(SentryCapability(hub, beforeSpan)) + .addCapability(SentryCapability(scopes, beforeSpan)) } else { val mockClient = mock() whenever(mockClient.execute(any(), any())).thenThrow(RuntimeException::class.java) Feign.builder() - .client(SentryFeignClient(mockClient, hub, beforeSpan)) + .client(SentryFeignClient(mockClient, scopes, beforeSpan)) }.target(MockApi::class.java, server.url("/").toUrl().toString()) } } @@ -201,7 +201,7 @@ class SentryFeignClientTest { fun `adds breadcrumb when http calls succeeds`() { val sut = fixture.getSut(responseBody = "response body") sut.postWithBody("request-body") - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(13, it.data["response_body_size"]) @@ -215,7 +215,7 @@ class SentryFeignClientTest { fun `adds breadcrumb when http calls succeeds even though response body is null`() { val sut = fixture.getSut(responseBody = "") sut.postWithBody("request-body") - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(0, it.data["response_body_size"]) @@ -236,7 +236,7 @@ class SentryFeignClientTest { } catch (e: Exception) { // ignore me } - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) }, diff --git a/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/OpenTelemetryLinkErrorEventProcessor.java b/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/OpenTelemetryLinkErrorEventProcessor.java index 1e373ece9c..bfc4cd05f1 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/OpenTelemetryLinkErrorEventProcessor.java +++ b/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/OpenTelemetryLinkErrorEventProcessor.java @@ -5,10 +5,10 @@ import io.opentelemetry.api.trace.TraceId; import io.sentry.EventProcessor; import io.sentry.Hint; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ISpan; import io.sentry.Instrumenter; +import io.sentry.ScopesAdapter; import io.sentry.SentryEvent; import io.sentry.SentryLevel; import io.sentry.SentrySpanStorage; @@ -20,21 +20,21 @@ public final class OpenTelemetryLinkErrorEventProcessor implements EventProcessor { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @NotNull SentrySpanStorage spanStorage = SentrySpanStorage.getInstance(); public OpenTelemetryLinkErrorEventProcessor() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } @TestOnly - OpenTelemetryLinkErrorEventProcessor(final @NotNull IHub hub) { - this.hub = hub; + OpenTelemetryLinkErrorEventProcessor(final @NotNull IScopes scopes) { + this.scopes = scopes; } @Override public @Nullable SentryEvent process(final @NotNull SentryEvent event, final @NotNull Hint hint) { - final @NotNull Instrumenter instrumenter = hub.getOptions().getInstrumenter(); + final @NotNull Instrumenter instrumenter = scopes.getOptions().getInstrumenter(); if (Instrumenter.OTEL.equals(instrumenter)) { @NotNull final Span otelSpan = Span.current(); @NotNull final String traceId = otelSpan.getSpanContext().getTraceId(); @@ -55,7 +55,8 @@ public OpenTelemetryLinkErrorEventProcessor() { null); event.getContexts().setTrace(spanContext); - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -64,7 +65,8 @@ public OpenTelemetryLinkErrorEventProcessor() { spanId, traceId); } else { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -74,7 +76,8 @@ public OpenTelemetryLinkErrorEventProcessor() { traceId); } } else { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -84,7 +87,8 @@ public OpenTelemetryLinkErrorEventProcessor() { spanId); } } else { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, diff --git a/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/SentryPropagator.java b/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/SentryPropagator.java index 14ac12323b..ed3e243f4d 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/SentryPropagator.java +++ b/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/SentryPropagator.java @@ -10,9 +10,9 @@ import io.opentelemetry.context.propagation.TextMapSetter; import io.sentry.Baggage; import io.sentry.BaggageHeader; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ISpan; +import io.sentry.ScopesAdapter; import io.sentry.SentryLevel; import io.sentry.SentrySpanStorage; import io.sentry.SentryTraceHeader; @@ -29,14 +29,14 @@ public final class SentryPropagator implements TextMapPropagator { private static final @NotNull List FIELDS = Arrays.asList(SentryTraceHeader.SENTRY_TRACE_HEADER, BaggageHeader.BAGGAGE_HEADER); private final @NotNull SentrySpanStorage spanStorage = SentrySpanStorage.getInstance(); - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; public SentryPropagator() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } - SentryPropagator(final @NotNull IHub hub) { - this.hub = hub; + SentryPropagator(final @NotNull IScopes scopes) { + this.scopes = scopes; } @Override @@ -49,7 +49,8 @@ public void inject(final Context context, final C carrier, final TextMapSett final @NotNull Span otelSpan = Span.fromContext(context); final @NotNull SpanContext otelSpanContext = otelSpan.getSpanContext(); if (!otelSpanContext.isValid()) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -58,7 +59,8 @@ public void inject(final Context context, final C carrier, final TextMapSett } final @Nullable ISpan sentrySpan = spanStorage.get(otelSpanContext.getSpanId()); if (sentrySpan == null || sentrySpan.isNoOp()) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -106,13 +108,15 @@ public Context extract( Span wrappedSpan = Span.wrap(otelSpanContext); modifiedContext = modifiedContext.with(wrappedSpan); - hub.getOptions() + scopes + .getOptions() .getLogger() .log(SentryLevel.DEBUG, "Continuing Sentry trace %s", sentryTraceHeader.getTraceId()); return modifiedContext; } catch (InvalidSentryTraceHeaderException e) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.ERROR, diff --git a/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/SentrySpanProcessor.java b/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/SentrySpanProcessor.java index a9e70f66a0..6b7797153b 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/SentrySpanProcessor.java +++ b/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/SentrySpanProcessor.java @@ -13,12 +13,12 @@ import io.opentelemetry.semconv.SemanticAttributes; import io.sentry.Baggage; import io.sentry.DsnUtil; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ISpan; import io.sentry.ITransaction; import io.sentry.Instrumenter; import io.sentry.PropagationContext; +import io.sentry.ScopesAdapter; import io.sentry.SentryDate; import io.sentry.SentryLevel; import io.sentry.SentryLongDate; @@ -46,14 +46,14 @@ public final class SentrySpanProcessor implements SpanProcessor { private final @NotNull SpanDescriptionExtractor spanDescriptionExtractor = new SpanDescriptionExtractor(); private final @NotNull SentrySpanStorage spanStorage = SentrySpanStorage.getInstance(); - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; public SentrySpanProcessor() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } - SentrySpanProcessor(final @NotNull IHub hub) { - this.hub = hub; + SentrySpanProcessor(final @NotNull IScopes scopes) { + this.scopes = scopes; } @Override @@ -65,7 +65,8 @@ public void onStart(final @NotNull Context parentContext, final @NotNull ReadWri final @NotNull TraceData traceData = getTraceData(otelSpan, parentContext); if (isSentryRequest(otelSpan)) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -78,7 +79,8 @@ public void onStart(final @NotNull Context parentContext, final @NotNull ReadWri traceData.getParentSpanId() == null ? null : spanStorage.get(traceData.getParentSpanId()); if (sentryParentSpan != null) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -94,7 +96,8 @@ public void onStart(final @NotNull Context parentContext, final @NotNull ReadWri sentryChildSpan.getSpanContext().setOrigin(TRACE_ORIGN); spanStorage.store(traceData.getSpanId(), sentryChildSpan); } else { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -123,7 +126,7 @@ public void onStart(final @NotNull Context parentContext, final @NotNull ReadWri transactionOptions.setStartTimestamp( new SentryLongDate(otelSpan.toSpanData().getStartEpochNanos())); - ISpan sentryTransaction = hub.startTransaction(transactionContext, transactionOptions); + ISpan sentryTransaction = scopes.startTransaction(transactionContext, transactionOptions); sentryTransaction.getSpanContext().setOrigin(TRACE_ORIGN); spanStorage.store(traceData.getSpanId(), sentryTransaction); } @@ -144,7 +147,8 @@ public void onEnd(final @NotNull ReadableSpan otelSpan) { final @Nullable ISpan sentrySpan = spanStorage.removeAndGet(traceData.getSpanId()); if (sentrySpan == null) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -155,7 +159,8 @@ public void onEnd(final @NotNull ReadableSpan otelSpan) { } if (isSentryRequest(otelSpan)) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -168,7 +173,8 @@ public void onEnd(final @NotNull ReadableSpan otelSpan) { if (sentrySpan instanceof ITransaction) { final @NotNull ITransaction sentryTransaction = (ITransaction) sentrySpan; updateTransactionWithOtelData(sentryTransaction, otelSpan); - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -178,7 +184,8 @@ public void onEnd(final @NotNull ReadableSpan otelSpan) { traceData.getTraceId()); } else { updateSpanWithOtelData(sentrySpan, otelSpan); - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -201,7 +208,8 @@ public boolean isEndRequired() { private boolean ensurePrerequisites(final @NotNull ReadableSpan otelSpan) { if (!hasSentryBeenInitialized()) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -209,9 +217,10 @@ private boolean ensurePrerequisites(final @NotNull ReadableSpan otelSpan) { return false; } - final @NotNull Instrumenter instrumenter = hub.getOptions().getInstrumenter(); + final @NotNull Instrumenter instrumenter = scopes.getOptions().getInstrumenter(); if (!Instrumenter.OTEL.equals(instrumenter)) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -222,7 +231,8 @@ private boolean ensurePrerequisites(final @NotNull ReadableSpan otelSpan) { final @NotNull SpanContext otelSpanContext = otelSpan.getSpanContext(); if (!otelSpanContext.isValid()) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -241,7 +251,7 @@ private boolean isSentryRequest(final @NotNull ReadableSpan otelSpan) { } final @Nullable String httpUrl = otelSpan.getAttribute(SemanticAttributes.HTTP_URL); - return DsnUtil.urlContainsDsnHost(hub.getOptions(), httpUrl); + return DsnUtil.urlContainsDsnHost(scopes.getOptions(), httpUrl); } private @NotNull TraceData getTraceData( @@ -334,7 +344,7 @@ private SpanStatus mapOtelStatus(final @NotNull ReadableSpan otelSpan) { } private boolean hasSentryBeenInitialized() { - return hub.isEnabled(); + return scopes.isEnabled(); } private @NotNull Map toMapWithStringKeys(final @Nullable Attributes attributes) { diff --git a/sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/SentrySpanProcessorTest.kt b/sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/SentrySpanProcessorTest.kt index 5ed757ba16..625fd54004 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/SentrySpanProcessorTest.kt +++ b/sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/SentrySpanProcessorTest.kt @@ -21,7 +21,7 @@ import io.opentelemetry.semconv.SemanticAttributes import io.sentry.Baggage import io.sentry.BaggageHeader import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ISpan import io.sentry.ITransaction import io.sentry.Instrumenter @@ -65,7 +65,7 @@ class SentrySpanProcessorTest { it.dsn = "https://key@sentry.io/proj" it.instrumenter = Instrumenter.OTEL } - val hub = mock() + val scopes = mock() val transaction = mock() val span = mock() val spanContext = mock() @@ -75,9 +75,9 @@ class SentrySpanProcessorTest { val baggage = Baggage.fromHeader(BAGGAGE_HEADER_STRING) fun setup() { - whenever(hub.isEnabled).thenReturn(true) - whenever(hub.options).thenReturn(options) - whenever(hub.startTransaction(any(), any())).thenReturn(transaction) + whenever(scopes.isEnabled).thenReturn(true) + whenever(scopes.options).thenReturn(options) + whenever(scopes.startTransaction(any(), any())).thenReturn(transaction) whenever(spanContext.operation).thenReturn("spanContextOp") whenever(spanContext.parentSpanId).thenReturn(io.sentry.SpanId("cedf5b7571cb4972")) @@ -94,7 +94,7 @@ class SentrySpanProcessorTest { whenever(transaction.startChild(any(), anyOrNull(), anyOrNull(), eq(Instrumenter.OTEL))).thenReturn(span) val sdkTracerProvider = SdkTracerProvider.builder() - .addSpanProcessor(SentrySpanProcessor(hub)) + .addSpanProcessor(SentrySpanProcessor(scopes)) .build() openTelemetry = OpenTelemetrySdk.builder() @@ -146,13 +146,13 @@ class SentrySpanProcessorTest { val context = mock() val span = mock() - whenever(fixture.hub.isEnabled).thenReturn(false) + whenever(fixture.scopes.isEnabled).thenReturn(false) - SentrySpanProcessor(fixture.hub).onStart(context, span) + SentrySpanProcessor(fixture.scopes).onStart(context, span) - verify(fixture.hub).isEnabled - verify(fixture.hub).options - verifyNoMoreInteractions(fixture.hub) + verify(fixture.scopes).isEnabled + verify(fixture.scopes).options + verifyNoMoreInteractions(fixture.scopes) verifyNoInteractions(context, span) } @@ -161,13 +161,13 @@ class SentrySpanProcessorTest { fixture.setup() val span = mock() - whenever(fixture.hub.isEnabled).thenReturn(false) + whenever(fixture.scopes.isEnabled).thenReturn(false) - SentrySpanProcessor(fixture.hub).onEnd(span) + SentrySpanProcessor(fixture.scopes).onEnd(span) - verify(fixture.hub).isEnabled - verify(fixture.hub).options - verifyNoMoreInteractions(fixture.hub) + verify(fixture.scopes).isEnabled + verify(fixture.scopes).options + verifyNoMoreInteractions(fixture.scopes) verifyNoInteractions(span) } @@ -178,7 +178,7 @@ class SentrySpanProcessorTest { val mockSpanContext = mock() whenever(mockSpanContext.spanId).thenReturn(SpanId.getInvalid()) whenever(mockSpan.spanContext).thenReturn(mockSpanContext) - SentrySpanProcessor(fixture.hub).onStart(Context.current(), mockSpan) + SentrySpanProcessor(fixture.scopes).onStart(Context.current(), mockSpan) thenNoTransactionIsStarted() } @@ -190,7 +190,7 @@ class SentrySpanProcessorTest { whenever(mockSpanContext.spanId).thenReturn(SpanId.fromBytes("seed".toByteArray())) whenever(mockSpanContext.traceId).thenReturn(TraceId.getInvalid()) whenever(mockSpan.spanContext).thenReturn(mockSpanContext) - SentrySpanProcessor(fixture.hub).onStart(Context.current(), mockSpan) + SentrySpanProcessor(fixture.scopes).onStart(Context.current(), mockSpan) thenNoTransactionIsStarted() } @@ -303,7 +303,7 @@ class SentrySpanProcessorTest { thenChildSpanIsStarted() otelChildSpan.setStatus(StatusCode.ERROR) - otelChildSpan.setAttribute(SemanticAttributes.HTTP_URL, "http://github.com/getsentry/sentry-java") + otelChildSpan.setAttribute(SemanticAttributes.HTTP_URL, "http://gitscopes.com/getsentry/sentry-java") otelChildSpan.setAttribute(SemanticAttributes.HTTP_STATUS_CODE, 404L) otelChildSpan.end() @@ -342,7 +342,7 @@ class SentrySpanProcessorTest { thenTransactionIsStarted(otelSpan, isContinued = true) otelSpan.makeCurrent().use { _ -> - val processedEvent = OpenTelemetryLinkErrorEventProcessor(fixture.hub).process(SentryEvent(), Hint()) + val processedEvent = OpenTelemetryLinkErrorEventProcessor(fixture.scopes).process(SentryEvent(), Hint()) val traceContext = processedEvent!!.contexts.trace!! assertEquals("2722d9f6ec019ade60c776169d9a8904", traceContext.traceId.toString()) @@ -361,7 +361,7 @@ class SentrySpanProcessorTest { fixture.options.instrumenter = Instrumenter.SENTRY fixture.setup() - val processedEvent = OpenTelemetryLinkErrorEventProcessor(fixture.hub).process(SentryEvent(), Hint()) + val processedEvent = OpenTelemetryLinkErrorEventProcessor(fixture.scopes).process(SentryEvent(), Hint()) thenNoTraceContextHasBeenAddedToEvent(processedEvent) } @@ -393,7 +393,7 @@ class SentrySpanProcessorTest { private fun thenTransactionIsStarted(otelSpan: Span, isContinued: Boolean = false, continuesWithFilledBaggage: Boolean = true) { if (isContinued) { - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( check { assertEquals("testspan", it.name) assertEquals(TransactionNameSource.CUSTOM, it.transactionNameSource) @@ -423,7 +423,7 @@ class SentrySpanProcessorTest { } ) } else { - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( check { assertEquals("testspan", it.name) assertEquals(TransactionNameSource.CUSTOM, it.transactionNameSource) @@ -451,7 +451,7 @@ class SentrySpanProcessorTest { } private fun thenNoTransactionIsStarted() { - verify(fixture.hub, never()).startTransaction( + verify(fixture.scopes, never()).startTransaction( any(), any() ) diff --git a/sentry-quartz/api/sentry-quartz.api b/sentry-quartz/api/sentry-quartz.api index ff32280dc5..23fce49e7d 100644 --- a/sentry-quartz/api/sentry-quartz.api +++ b/sentry-quartz/api/sentry-quartz.api @@ -7,7 +7,7 @@ public final class io/sentry/quartz/SentryJobListener : org/quartz/JobListener { public static final field SENTRY_CHECK_IN_ID_KEY Ljava/lang/String; public static final field SENTRY_SLUG_KEY Ljava/lang/String; public fun ()V - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun getName ()Ljava/lang/String; public fun jobExecutionVetoed (Lorg/quartz/JobExecutionContext;)V public fun jobToBeExecuted (Lorg/quartz/JobExecutionContext;)V diff --git a/sentry-quartz/src/main/java/io/sentry/quartz/SentryJobListener.java b/sentry-quartz/src/main/java/io/sentry/quartz/SentryJobListener.java index 28a0e51200..f9c22022cc 100644 --- a/sentry-quartz/src/main/java/io/sentry/quartz/SentryJobListener.java +++ b/sentry-quartz/src/main/java/io/sentry/quartz/SentryJobListener.java @@ -3,8 +3,8 @@ import io.sentry.BuildConfig; import io.sentry.CheckIn; import io.sentry.CheckInStatus; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; +import io.sentry.ScopesAdapter; import io.sentry.SentryIntegrationPackageStorage; import io.sentry.SentryLevel; import io.sentry.protocol.SentryId; @@ -24,14 +24,14 @@ public final class SentryJobListener implements JobListener { public static final String SENTRY_CHECK_IN_ID_KEY = "sentry-checkin-id"; public static final String SENTRY_SLUG_KEY = "sentry-slug"; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; public SentryJobListener() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } - public SentryJobListener(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentryJobListener(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); SentryIntegrationPackageStorage.getInstance().addIntegration("Quartz"); SentryIntegrationPackageStorage.getInstance() .addPackage("maven:io.sentry:sentry-quartz", BuildConfig.VERSION_NAME); @@ -49,15 +49,16 @@ public void jobToBeExecuted(final @NotNull JobExecutionContext context) { if (maybeSlug == null) { return; } - hub.pushScope(); - TracingUtils.startNewTrace(hub); + scopes.pushScope(); + TracingUtils.startNewTrace(scopes); final @NotNull String slug = maybeSlug; final @NotNull CheckIn checkIn = new CheckIn(slug, CheckInStatus.IN_PROGRESS); - final @NotNull SentryId checkInId = hub.captureCheckIn(checkIn); + final @NotNull SentryId checkInId = scopes.captureCheckIn(checkIn); context.put(SENTRY_CHECK_IN_ID_KEY, checkInId); context.put(SENTRY_SLUG_KEY, slug); } catch (Throwable t) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log(SentryLevel.ERROR, "Unable to capture check-in in jobToBeExecuted.", t); } @@ -94,14 +95,15 @@ public void jobWasExecuted(JobExecutionContext context, JobExecutionException jo if (slug != null) { final boolean isFailed = jobException != null; final @NotNull CheckInStatus status = isFailed ? CheckInStatus.ERROR : CheckInStatus.OK; - hub.captureCheckIn(new CheckIn(checkInId, slug, status)); + scopes.captureCheckIn(new CheckIn(checkInId, slug, status)); } } catch (Throwable t) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log(SentryLevel.ERROR, "Unable to capture check-in in jobWasExecuted.", t); } finally { - hub.popScope(); + scopes.popScope(); } } } diff --git a/sentry-samples/sentry-samples-android/src/main/java/io/sentry/samples/android/ProfilingActivity.kt b/sentry-samples/sentry-samples-android/src/main/java/io/sentry/samples/android/ProfilingActivity.kt index 610fc1534d..a7004deb35 100644 --- a/sentry-samples/sentry-samples-android/src/main/java/io/sentry/samples/android/ProfilingActivity.kt +++ b/sentry-samples/sentry-samples-android/src/main/java/io/sentry/samples/android/ProfilingActivity.kt @@ -100,7 +100,7 @@ class ProfilingActivity : AppCompatActivity() { val traceData = ProfilingTraceData(profile, t) // Create envelope item from copied profile val item = - SentryEnvelopeItem.fromProfilingTrace(traceData, Long.MAX_VALUE, Sentry.getCurrentHub().options.serializer) + SentryEnvelopeItem.fromProfilingTrace(traceData, Long.MAX_VALUE, Sentry.getCurrentScopes().options.serializer) val itemData = item.data // Compress the envelope item using Gzip diff --git a/sentry-samples/sentry-samples-spring-jakarta/src/main/java/io/sentry/samples/spring/jakarta/AppConfig.java b/sentry-samples/sentry-samples-spring-jakarta/src/main/java/io/sentry/samples/spring/jakarta/AppConfig.java index f78c3f71d5..72ecb14e2f 100644 --- a/sentry-samples/sentry-samples-spring-jakarta/src/main/java/io/sentry/samples/spring/jakarta/AppConfig.java +++ b/sentry-samples/sentry-samples-spring-jakarta/src/main/java/io/sentry/samples/spring/jakarta/AppConfig.java @@ -1,6 +1,6 @@ package io.sentry.samples.spring.jakarta; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.spring.jakarta.SentryUserFilter; import io.sentry.spring.jakarta.SentryUserProvider; import java.util.List; @@ -14,7 +14,7 @@ public class AppConfig { @Bean SentryUserFilter sentryUserFilter( - final IHub hub, final List sentryUserProviders) { - return new SentryUserFilter(hub, sentryUserProviders); + final IScopes scopes, final List sentryUserProviders) { + return new SentryUserFilter(scopes, sentryUserProviders); } } diff --git a/sentry-samples/sentry-samples-spring-jakarta/src/main/java/io/sentry/samples/spring/jakarta/WebConfig.java b/sentry-samples/sentry-samples-spring-jakarta/src/main/java/io/sentry/samples/spring/jakarta/WebConfig.java index 92b48b138c..73d425b286 100644 --- a/sentry-samples/sentry-samples-spring-jakarta/src/main/java/io/sentry/samples/spring/jakarta/WebConfig.java +++ b/sentry-samples/sentry-samples-spring-jakarta/src/main/java/io/sentry/samples/spring/jakarta/WebConfig.java @@ -1,6 +1,6 @@ package io.sentry.samples.spring.jakarta; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.spring.jakarta.tracing.SentrySpanClientHttpRequestInterceptor; import java.util.Collections; import org.springframework.context.annotation.Bean; @@ -20,14 +20,14 @@ public class WebConfig { * Creates a {@link RestTemplate} which calls are intercepted with {@link * SentrySpanClientHttpRequestInterceptor} to create spans around HTTP calls. * - * @param hub - sentry hub + * @param scopes - sentry scopes * @return RestTemplate */ @Bean - RestTemplate restTemplate(IHub hub) { + RestTemplate restTemplate(IScopes scopes) { RestTemplate restTemplate = new RestTemplate(); SentrySpanClientHttpRequestInterceptor sentryRestTemplateInterceptor = - new SentrySpanClientHttpRequestInterceptor(hub); + new SentrySpanClientHttpRequestInterceptor(scopes); restTemplate.setInterceptors(Collections.singletonList(sentryRestTemplateInterceptor)); return restTemplate; } diff --git a/sentry-samples/sentry-samples-spring/src/main/java/io/sentry/samples/spring/AppConfig.java b/sentry-samples/sentry-samples-spring/src/main/java/io/sentry/samples/spring/AppConfig.java index 7d46f09fb9..89a968834a 100644 --- a/sentry-samples/sentry-samples-spring/src/main/java/io/sentry/samples/spring/AppConfig.java +++ b/sentry-samples/sentry-samples-spring/src/main/java/io/sentry/samples/spring/AppConfig.java @@ -1,6 +1,6 @@ package io.sentry.samples.spring; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.spring.SentryUserFilter; import io.sentry.spring.SentryUserProvider; import java.util.List; @@ -14,7 +14,7 @@ public class AppConfig { @Bean SentryUserFilter sentryUserFilter( - final IHub hub, final List sentryUserProviders) { - return new SentryUserFilter(hub, sentryUserProviders); + final IScopes scopes, final List sentryUserProviders) { + return new SentryUserFilter(scopes, sentryUserProviders); } } diff --git a/sentry-samples/sentry-samples-spring/src/main/java/io/sentry/samples/spring/WebConfig.java b/sentry-samples/sentry-samples-spring/src/main/java/io/sentry/samples/spring/WebConfig.java index e135cbe233..2990ba8a38 100644 --- a/sentry-samples/sentry-samples-spring/src/main/java/io/sentry/samples/spring/WebConfig.java +++ b/sentry-samples/sentry-samples-spring/src/main/java/io/sentry/samples/spring/WebConfig.java @@ -1,6 +1,6 @@ package io.sentry.samples.spring; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.spring.tracing.SentrySpanClientHttpRequestInterceptor; import java.util.Collections; import org.springframework.context.annotation.Bean; @@ -20,14 +20,14 @@ public class WebConfig { * Creates a {@link RestTemplate} which calls are intercepted with {@link * SentrySpanClientHttpRequestInterceptor} to create spans around HTTP calls. * - * @param hub - sentry hub + * @param scopes - sentry scopes * @return RestTemplate */ @Bean - RestTemplate restTemplate(IHub hub) { + RestTemplate restTemplate(IScopes scopes) { RestTemplate restTemplate = new RestTemplate(); SentrySpanClientHttpRequestInterceptor sentryRestTemplateInterceptor = - new SentrySpanClientHttpRequestInterceptor(hub); + new SentrySpanClientHttpRequestInterceptor(scopes); restTemplate.setInterceptors(Collections.singletonList(sentryRestTemplateInterceptor)); return restTemplate; } diff --git a/sentry-servlet-jakarta/api/sentry-servlet-jakarta.api b/sentry-servlet-jakarta/api/sentry-servlet-jakarta.api index d0367e5195..a5421e7453 100644 --- a/sentry-servlet-jakarta/api/sentry-servlet-jakarta.api +++ b/sentry-servlet-jakarta/api/sentry-servlet-jakarta.api @@ -10,7 +10,7 @@ public class io/sentry/servlet/jakarta/SentryServletContainerInitializer : jakar public class io/sentry/servlet/jakarta/SentryServletRequestListener : jakarta/servlet/ServletRequestListener { public fun ()V - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun requestDestroyed (Ljakarta/servlet/ServletRequestEvent;)V public fun requestInitialized (Ljakarta/servlet/ServletRequestEvent;)V } diff --git a/sentry-servlet-jakarta/src/main/java/io/sentry/servlet/jakarta/SentryServletRequestListener.java b/sentry-servlet-jakarta/src/main/java/io/sentry/servlet/jakarta/SentryServletRequestListener.java index e3811157f8..54775386fd 100644 --- a/sentry-servlet-jakarta/src/main/java/io/sentry/servlet/jakarta/SentryServletRequestListener.java +++ b/sentry-servlet-jakarta/src/main/java/io/sentry/servlet/jakarta/SentryServletRequestListener.java @@ -5,8 +5,8 @@ import com.jakewharton.nopen.annotation.Open; import io.sentry.Breadcrumb; import io.sentry.Hint; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; +import io.sentry.ScopesAdapter; import io.sentry.util.Objects; import jakarta.servlet.ServletRequest; import jakarta.servlet.ServletRequestEvent; @@ -21,24 +21,24 @@ @Open public class SentryServletRequestListener implements ServletRequestListener { - private final IHub hub; + private final IScopes scopes; - public SentryServletRequestListener(@NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentryServletRequestListener(@NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } public SentryServletRequestListener() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } @Override public void requestDestroyed(@NotNull ServletRequestEvent servletRequestEvent) { - hub.popScope(); + scopes.popScope(); } @Override public void requestInitialized(@NotNull ServletRequestEvent servletRequestEvent) { - hub.pushScope(); + scopes.pushScope(); final ServletRequest servletRequest = servletRequestEvent.getServletRequest(); if (servletRequest instanceof HttpServletRequest) { @@ -47,10 +47,10 @@ public void requestInitialized(@NotNull ServletRequestEvent servletRequestEvent) final Hint hint = new Hint(); hint.set(SERVLET_REQUEST, httpRequest); - hub.addBreadcrumb( + scopes.addBreadcrumb( Breadcrumb.http(httpRequest.getRequestURI(), httpRequest.getMethod()), hint); - hub.configureScope( + scopes.configureScope( scope -> { scope.addEventProcessor(new SentryRequestHttpServletRequestProcessor(httpRequest)); }); diff --git a/sentry-servlet-jakarta/src/test/kotlin/io/sentry/servlet/jakarta/SentryServletRequestListenerTest.kt b/sentry-servlet-jakarta/src/test/kotlin/io/sentry/servlet/jakarta/SentryServletRequestListenerTest.kt index b87ea218a2..3be76d1cd2 100644 --- a/sentry-servlet-jakarta/src/test/kotlin/io/sentry/servlet/jakarta/SentryServletRequestListenerTest.kt +++ b/sentry-servlet-jakarta/src/test/kotlin/io/sentry/servlet/jakarta/SentryServletRequestListenerTest.kt @@ -1,7 +1,7 @@ package io.sentry.servlet.jakarta import io.sentry.Breadcrumb -import io.sentry.IHub +import io.sentry.IScopes import jakarta.servlet.ServletRequestEvent import org.mockito.kotlin.anyOrNull import org.mockito.kotlin.check @@ -13,9 +13,9 @@ import kotlin.test.assertEquals class SentryServletRequestListenerTest { private class Fixture { - val hub = mock() + val scopes = mock() val listener = - SentryServletRequestListener(hub) + SentryServletRequestListener(scopes) val request = mockRequest( url = "http://localhost:8080/some-uri", method = "POST" @@ -33,14 +33,14 @@ class SentryServletRequestListenerTest { fun `pushes scope when request gets initialized`() { fixture.listener.requestInitialized(fixture.event) - verify(fixture.hub).pushScope() + verify(fixture.scopes).pushScope() } @Test fun `adds breadcrumb when request gets initialized`() { fixture.listener.requestInitialized(fixture.event) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { it: Breadcrumb -> assertEquals("/some-uri", it.getData("url")) assertEquals("POST", it.getData("method")) @@ -54,6 +54,6 @@ class SentryServletRequestListenerTest { fun `pops scope when request gets destroyed`() { fixture.listener.requestDestroyed(fixture.event) - verify(fixture.hub).popScope() + verify(fixture.scopes).popScope() } } diff --git a/sentry-servlet/api/sentry-servlet.api b/sentry-servlet/api/sentry-servlet.api index a0a2a1e0d2..fd7aee819b 100644 --- a/sentry-servlet/api/sentry-servlet.api +++ b/sentry-servlet/api/sentry-servlet.api @@ -10,7 +10,7 @@ public class io/sentry/servlet/SentryServletContainerInitializer : javax/servlet public class io/sentry/servlet/SentryServletRequestListener : javax/servlet/ServletRequestListener { public fun ()V - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun requestDestroyed (Ljavax/servlet/ServletRequestEvent;)V public fun requestInitialized (Ljavax/servlet/ServletRequestEvent;)V } diff --git a/sentry-servlet/src/main/java/io/sentry/servlet/SentryServletRequestListener.java b/sentry-servlet/src/main/java/io/sentry/servlet/SentryServletRequestListener.java index 9b981676c4..97c37e1133 100644 --- a/sentry-servlet/src/main/java/io/sentry/servlet/SentryServletRequestListener.java +++ b/sentry-servlet/src/main/java/io/sentry/servlet/SentryServletRequestListener.java @@ -5,8 +5,8 @@ import com.jakewharton.nopen.annotation.Open; import io.sentry.Breadcrumb; import io.sentry.Hint; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; +import io.sentry.ScopesAdapter; import io.sentry.util.Objects; import javax.servlet.ServletRequest; import javax.servlet.ServletRequestEvent; @@ -21,24 +21,24 @@ @Open public class SentryServletRequestListener implements ServletRequestListener { - private final IHub hub; + private final IScopes scopes; - public SentryServletRequestListener(@NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentryServletRequestListener(@NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } public SentryServletRequestListener() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } @Override public void requestDestroyed(@NotNull ServletRequestEvent servletRequestEvent) { - hub.popScope(); + scopes.popScope(); } @Override public void requestInitialized(@NotNull ServletRequestEvent servletRequestEvent) { - hub.pushScope(); + scopes.pushScope(); final ServletRequest servletRequest = servletRequestEvent.getServletRequest(); if (servletRequest instanceof HttpServletRequest) { @@ -47,10 +47,10 @@ public void requestInitialized(@NotNull ServletRequestEvent servletRequestEvent) final Hint hint = new Hint(); hint.set(SERVLET_REQUEST, httpRequest); - hub.addBreadcrumb( + scopes.addBreadcrumb( Breadcrumb.http(httpRequest.getRequestURI(), httpRequest.getMethod()), hint); - hub.configureScope( + scopes.configureScope( scope -> { scope.addEventProcessor(new SentryRequestHttpServletRequestProcessor(httpRequest)); }); diff --git a/sentry-servlet/src/test/kotlin/io/sentry/servlet/SentryServletRequestListenerTest.kt b/sentry-servlet/src/test/kotlin/io/sentry/servlet/SentryServletRequestListenerTest.kt index b94e73f2ef..bfa216f738 100644 --- a/sentry-servlet/src/test/kotlin/io/sentry/servlet/SentryServletRequestListenerTest.kt +++ b/sentry-servlet/src/test/kotlin/io/sentry/servlet/SentryServletRequestListenerTest.kt @@ -1,7 +1,7 @@ package io.sentry.servlet import io.sentry.Breadcrumb -import io.sentry.IHub +import io.sentry.IScopes import org.assertj.core.api.Assertions.assertThat import org.mockito.kotlin.anyOrNull import org.mockito.kotlin.check @@ -14,8 +14,8 @@ import kotlin.test.Test class SentryServletRequestListenerTest { private class Fixture { - val hub = mock() - val listener = SentryServletRequestListener(hub) + val scopes = mock() + val listener = SentryServletRequestListener(scopes) val request = MockHttpServletRequest() val event = mock() @@ -32,14 +32,14 @@ class SentryServletRequestListenerTest { fun `pushes scope when request gets initialized`() { fixture.listener.requestInitialized(fixture.event) - verify(fixture.hub).pushScope() + verify(fixture.scopes).pushScope() } @Test fun `adds breadcrumb when request gets initialized`() { fixture.listener.requestInitialized(fixture.event) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { it: Breadcrumb -> assertThat(it.getData("url")).isEqualTo("http://localhost:8080/some-uri") assertThat(it.getData("method")).isEqualTo("POST") @@ -53,6 +53,6 @@ class SentryServletRequestListenerTest { fun `pops scope when request gets destroyed`() { fixture.listener.requestDestroyed(fixture.event) - verify(fixture.hub).popScope() + verify(fixture.scopes).popScope() } } 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 a392ff75ee..009036082e 100644 --- a/sentry-spring-boot-jakarta/api/sentry-spring-boot-jakarta.api +++ b/sentry-spring-boot-jakarta/api/sentry-spring-boot-jakarta.api @@ -62,7 +62,7 @@ public class io/sentry/spring/boot/jakarta/SentryProperties$Reactive { public class io/sentry/spring/boot/jakarta/SentryWebfluxAutoConfiguration { public fun ()V - public fun sentryWebExceptionHandler (Lio/sentry/IHub;)Lio/sentry/spring/jakarta/webflux/SentryWebExceptionHandler; + public fun sentryWebExceptionHandler (Lio/sentry/IScopes;)Lio/sentry/spring/jakarta/webflux/SentryWebExceptionHandler; } public class io/sentry/spring/boot/jakarta/graphql/SentryGraphqlAutoConfiguration { diff --git a/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentryAutoConfiguration.java b/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentryAutoConfiguration.java index fbf3162280..b2c8df213c 100644 --- a/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentryAutoConfiguration.java +++ b/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentryAutoConfiguration.java @@ -3,10 +3,10 @@ import com.jakewharton.nopen.annotation.Open; import graphql.GraphQLError; import io.sentry.EventProcessor; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ITransportFactory; import io.sentry.Integration; +import io.sentry.ScopesAdapter; import io.sentry.Sentry; import io.sentry.SentryIntegrationPackageStorage; import io.sentry.SentryOptions; @@ -116,7 +116,7 @@ static class HubConfiguration { } @Bean - public @NotNull IHub sentryHub( + public @NotNull IScopes sentryHub( final @NotNull List> optionsConfigurations, final @NotNull SentryProperties options, final @NotNull ObjectProvider gitProperties) { @@ -139,7 +139,7 @@ static class HubConfiguration { // here we make sure that only classes that extend throwable are set on this field options.getIgnoredExceptionsForType().removeIf(it -> !Throwable.class.isAssignableFrom(it)); Sentry.init(options); - return HubAdapter.getInstance(); + return ScopesAdapter.getInstance(); } @Configuration(proxyBeanMethods = false) @@ -239,7 +239,7 @@ static class SentrySecurityConfiguration { * HttpServletRequest#getUserPrincipal()}. If Spring Security is auto-configured, its order is * set to run after Spring Security. * - * @param hub the Sentry hub + * @param scopes the Sentry scopes * @param sentryProperties the Sentry properties * @param sentryUserProvider the user provider * @return {@link SentryUserFilter} registration bean @@ -247,11 +247,11 @@ static class SentrySecurityConfiguration { @Bean @ConditionalOnBean(SentryUserProvider.class) public @NotNull FilterRegistrationBean sentryUserFilter( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull SentryProperties sentryProperties, final @NotNull List sentryUserProvider) { final FilterRegistrationBean filter = new FilterRegistrationBean<>(); - filter.setFilter(new SentryUserFilter(hub, sentryUserProvider)); + filter.setFilter(new SentryUserFilter(scopes, sentryUserProvider)); filter.setOrder(resolveUserFilterOrder(sentryProperties)); return filter; } @@ -263,8 +263,8 @@ static class SentrySecurityConfiguration { } @Bean - public @NotNull SentryRequestResolver sentryRequestResolver(final @NotNull IHub hub) { - return new SentryRequestResolver(hub); + public @NotNull SentryRequestResolver sentryRequestResolver(final @NotNull IScopes scopes) { + return new SentryRequestResolver(scopes); } @Bean @@ -276,12 +276,12 @@ static class SentrySecurityConfiguration { @Bean @ConditionalOnMissingBean(name = "sentrySpringFilter") public @NotNull FilterRegistrationBean sentrySpringFilter( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull SentryRequestResolver requestResolver, final @NotNull TransactionNameProvider transactionNameProvider) { FilterRegistrationBean filter = new FilterRegistrationBean<>( - new SentrySpringFilter(hub, requestResolver, transactionNameProvider)); + new SentrySpringFilter(scopes, requestResolver, transactionNameProvider)); filter.setOrder(SENTRY_SPRING_FILTER_PRECEDENCE); return filter; } @@ -289,9 +289,10 @@ static class SentrySecurityConfiguration { @Bean @ConditionalOnMissingBean(name = "sentryTracingFilter") public FilterRegistrationBean sentryTracingFilter( - final @NotNull IHub hub, final @NotNull TransactionNameProvider transactionNameProvider) { + final @NotNull IScopes scopes, + final @NotNull TransactionNameProvider transactionNameProvider) { FilterRegistrationBean filter = - new FilterRegistrationBean<>(new SentryTracingFilter(hub, transactionNameProvider)); + new FilterRegistrationBean<>(new SentryTracingFilter(scopes, transactionNameProvider)); filter.setOrder(SENTRY_SPRING_FILTER_PRECEDENCE + 1); // must run after SentrySpringFilter return filter; } @@ -300,11 +301,11 @@ public FilterRegistrationBean sentryTracingFilter( @ConditionalOnMissingBean @ConditionalOnClass(HandlerExceptionResolver.class) public @NotNull SentryExceptionResolver sentryExceptionResolver( - final @NotNull IHub sentryHub, + final @NotNull IScopes scopes, final @NotNull TransactionNameProvider transactionNameProvider, final @NotNull SentryProperties options) { return new SentryExceptionResolver( - sentryHub, transactionNameProvider, options.getExceptionResolverOrder()); + scopes, transactionNameProvider, options.getExceptionResolverOrder()); } } @@ -354,8 +355,8 @@ static class SentrySpanPointcutAutoConfiguration {} @Open static class SentryPerformanceRestTemplateConfiguration { @Bean - public SentrySpanRestTemplateCustomizer sentrySpanRestTemplateCustomizer(IHub hub) { - return new SentrySpanRestTemplateCustomizer(hub); + public SentrySpanRestTemplateCustomizer sentrySpanRestTemplateCustomizer(IScopes scopes) { + return new SentrySpanRestTemplateCustomizer(scopes); } } @@ -365,8 +366,8 @@ public SentrySpanRestTemplateCustomizer sentrySpanRestTemplateCustomizer(IHub hu @Open static class SentrySpanRestClientConfiguration { @Bean - public SentrySpanRestClientCustomizer sentrySpanRestClientCustomizer(IHub hub) { - return new SentrySpanRestClientCustomizer(hub); + public SentrySpanRestClientCustomizer sentrySpanRestClientCustomizer(IScopes scopes) { + return new SentrySpanRestClientCustomizer(scopes); } } @@ -376,8 +377,8 @@ public SentrySpanRestClientCustomizer sentrySpanRestClientCustomizer(IHub hub) { @Open static class SentryPerformanceWebClientConfiguration { @Bean - public SentrySpanWebClientCustomizer sentrySpanWebClientCustomizer(IHub hub) { - return new SentrySpanWebClientCustomizer(hub); + public SentrySpanWebClientCustomizer sentrySpanWebClientCustomizer(IScopes scopes) { + return new SentrySpanWebClientCustomizer(scopes); } } diff --git a/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentrySpanRestClientCustomizer.java b/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentrySpanRestClientCustomizer.java index 243a4d1f50..304fb6911e 100644 --- a/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentrySpanRestClientCustomizer.java +++ b/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentrySpanRestClientCustomizer.java @@ -1,7 +1,7 @@ package io.sentry.spring.boot.jakarta; import com.jakewharton.nopen.annotation.Open; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.spring.jakarta.tracing.SentrySpanClientHttpRequestInterceptor; import org.jetbrains.annotations.NotNull; import org.springframework.boot.web.client.RestClientCustomizer; @@ -11,8 +11,8 @@ class SentrySpanRestClientCustomizer implements RestClientCustomizer { private final @NotNull SentrySpanClientHttpRequestInterceptor interceptor; - public SentrySpanRestClientCustomizer(final @NotNull IHub hub) { - this.interceptor = new SentrySpanClientHttpRequestInterceptor(hub, false); + public SentrySpanRestClientCustomizer(final @NotNull IScopes scopes) { + this.interceptor = new SentrySpanClientHttpRequestInterceptor(scopes, false); } @Override diff --git a/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentrySpanRestTemplateCustomizer.java b/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentrySpanRestTemplateCustomizer.java index c1ded006e8..4a0faa9875 100644 --- a/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentrySpanRestTemplateCustomizer.java +++ b/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentrySpanRestTemplateCustomizer.java @@ -1,7 +1,7 @@ package io.sentry.spring.boot.jakarta; import com.jakewharton.nopen.annotation.Open; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.spring.jakarta.tracing.SentrySpanClientHttpRequestInterceptor; import java.util.ArrayList; import java.util.List; @@ -14,8 +14,8 @@ class SentrySpanRestTemplateCustomizer implements RestTemplateCustomizer { private final @NotNull SentrySpanClientHttpRequestInterceptor interceptor; - public SentrySpanRestTemplateCustomizer(final @NotNull IHub hub) { - this.interceptor = new SentrySpanClientHttpRequestInterceptor(hub); + public SentrySpanRestTemplateCustomizer(final @NotNull IScopes scopes) { + this.interceptor = new SentrySpanClientHttpRequestInterceptor(scopes); } @Override diff --git a/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentrySpanWebClientCustomizer.java b/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentrySpanWebClientCustomizer.java index afbe2eb6c4..d349ac4c6e 100644 --- a/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentrySpanWebClientCustomizer.java +++ b/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentrySpanWebClientCustomizer.java @@ -1,7 +1,7 @@ package io.sentry.spring.boot.jakarta; import com.jakewharton.nopen.annotation.Open; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.spring.jakarta.tracing.SentrySpanClientWebRequestFilter; import org.jetbrains.annotations.NotNull; import org.springframework.boot.web.reactive.function.client.WebClientCustomizer; @@ -11,8 +11,8 @@ class SentrySpanWebClientCustomizer implements WebClientCustomizer { private final @NotNull SentrySpanClientWebRequestFilter filter; - public SentrySpanWebClientCustomizer(final @NotNull IHub hub) { - this.filter = new SentrySpanClientWebRequestFilter(hub); + public SentrySpanWebClientCustomizer(final @NotNull IScopes scopes) { + this.filter = new SentrySpanClientWebRequestFilter(scopes); } @Override diff --git a/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentryWebfluxAutoConfiguration.java b/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentryWebfluxAutoConfiguration.java index d1cda8b4d2..2bc8bc87ed 100644 --- a/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentryWebfluxAutoConfiguration.java +++ b/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentryWebfluxAutoConfiguration.java @@ -1,8 +1,8 @@ package io.sentry.spring.boot.jakarta; import com.jakewharton.nopen.annotation.Open; -import io.sentry.IHub; import io.sentry.IScope; +import io.sentry.IScopes; import io.sentry.spring.jakarta.webflux.SentryScheduleHook; import io.sentry.spring.jakarta.webflux.SentryWebExceptionHandler; import io.sentry.spring.jakarta.webflux.SentryWebFilter; @@ -28,7 +28,7 @@ /** Configures Sentry integration for Spring Webflux and Project Reactor. */ @Configuration(proxyBeanMethods = false) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) -@ConditionalOnBean(IHub.class) +@ConditionalOnBean(IScopes.class) @ConditionalOnClass(Schedulers.class) @Open @ApiStatus.Experimental @@ -44,14 +44,14 @@ static class SentryWebfluxFilterThreadLocalAccessorConfiguration { * Configures a filter that sets up Sentry {@link IScope} for each request. * *

Makes use of newer reactor-core and context-propagation library feature - * ThreadLocalAccessor to propagate the Sentry hub. + * ThreadLocalAccessor to propagate the Sentry scopes. */ @Bean @Order(SENTRY_SPRING_FILTER_PRECEDENCE) public @NotNull SentryWebFilterWithThreadLocalAccessor sentryWebFilterWithContextPropagation( - final @NotNull IHub hub) { + final @NotNull IScopes scopes) { Hooks.enableAutomaticContextPropagation(); - return new SentryWebFilterWithThreadLocalAccessor(hub); + return new SentryWebFilterWithThreadLocalAccessor(scopes); } } @@ -60,7 +60,7 @@ static class SentryWebfluxFilterThreadLocalAccessorConfiguration { @Open static class SentryWebfluxFilterConfiguration { - /** Configures hook that sets correct hub on the executing thread. */ + /** Configures hook that sets correct scopes on the executing thread. */ @Bean public @NotNull ApplicationRunner sentryScheduleHookApplicationRunner() { return args -> { @@ -71,15 +71,16 @@ static class SentryWebfluxFilterConfiguration { /** Configures a filter that sets up Sentry {@link IScope} for each request. */ @Bean @Order(SENTRY_SPRING_FILTER_PRECEDENCE) - public @NotNull SentryWebFilter sentryWebFilter(final @NotNull IHub hub) { - return new SentryWebFilter(hub); + public @NotNull SentryWebFilter sentryWebFilter(final @NotNull IScopes scopes) { + return new SentryWebFilter(scopes); } } /** Configures exception handler that handles unhandled exceptions and sends them to Sentry. */ @Bean - public @NotNull SentryWebExceptionHandler sentryWebExceptionHandler(final @NotNull IHub hub) { - return new SentryWebExceptionHandler(hub); + public @NotNull SentryWebExceptionHandler sentryWebExceptionHandler( + final @NotNull IScopes scopes) { + return new SentryWebExceptionHandler(scopes); } static final class SentryLegacyFilterConfigurationCondition extends AnyNestedCondition { diff --git a/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentryAutoConfigurationTest.kt b/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentryAutoConfigurationTest.kt index aecb1b4712..df0fe96cf0 100644 --- a/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentryAutoConfigurationTest.kt +++ b/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentryAutoConfigurationTest.kt @@ -5,7 +5,7 @@ import io.sentry.AsyncHttpTransportFactory import io.sentry.Breadcrumb import io.sentry.EventProcessor import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ITransportFactory import io.sentry.Integration import io.sentry.NoOpTransportFactory @@ -77,18 +77,18 @@ class SentryAutoConfigurationTest { .withConfiguration(AutoConfigurations.of(SentryAutoConfiguration::class.java, WebMvcAutoConfiguration::class.java)) @Test - fun `hub is not created when auto-configuration dsn is not set`() { + fun `scopes is not created when auto-configuration dsn is not set`() { contextRunner .run { - assertThat(it).doesNotHaveBean(IHub::class.java) + assertThat(it).doesNotHaveBean(IScopes::class.java) } } @Test - fun `hub is created when dsn is provided`() { + fun `scopes is created when dsn is provided`() { contextRunner.withPropertyValues("sentry.dsn=http://key@localhost/proj") .run { - assertThat(it).hasSingleBean(IHub::class.java) + assertThat(it).hasSingleBean(IScopes::class.java) } } @@ -961,7 +961,7 @@ class SentryAutoConfigurationTest { } class CustomIntegration : Integration { - override fun register(hub: IHub, options: SentryOptions) {} + override fun register(scopes: IScopes, options: SentryOptions) {} } @Configuration(proxyBeanMethods = false) diff --git a/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanRestClientCustomizerTest.kt b/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanRestClientCustomizerTest.kt index f9f55ffede..9ba9bf57d2 100644 --- a/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanRestClientCustomizerTest.kt +++ b/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanRestClientCustomizerTest.kt @@ -2,7 +2,7 @@ package io.sentry.spring.boot.jakarta import io.sentry.BaggageHeader import io.sentry.Breadcrumb -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.Scope import io.sentry.ScopeCallback import io.sentry.SentryOptions @@ -36,18 +36,18 @@ import kotlin.test.assertTrue class SentrySpanRestClientCustomizerTest { class Fixture { val sentryOptions = SentryOptions() - val hub = mock() + val scopes = mock() val restClientBuilder = RestClient.builder() var mockServer = MockWebServer() val transaction: SentryTracer - internal val customizer = SentrySpanRestClientCustomizer(hub) + internal val customizer = SentrySpanRestClientCustomizer(scopes) val url = mockServer.url("/test/123").toString() val scope = Scope(sentryOptions) init { - whenever(hub.options).thenReturn(sentryOptions) - doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(hub).configureScope(any()) - transaction = SentryTracer(TransactionContext("aTransaction", "op", TracesSamplingDecision(true)), hub) + whenever(scopes.options).thenReturn(sentryOptions) + doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(scopes).configureScope(any()) + transaction = SentryTracer(TransactionContext("aTransaction", "op", TracesSamplingDecision(true)), scopes) } fun getSut( @@ -75,7 +75,7 @@ class SentrySpanRestClientCustomizerTest { ) if (isTransactionActive) { - whenever(hub.span).thenReturn(transaction) + whenever(scopes.span).thenReturn(transaction) } return restClientBuilder.apply { @@ -247,7 +247,7 @@ class SentrySpanRestClientCustomizerTest { .body("content") .retrieve() .toEntity(String::class.java) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(fixture.url, it.data["url"]) @@ -269,7 +269,7 @@ class SentrySpanRestClientCustomizerTest { .toEntity(String::class.java) } catch (e: Throwable) { } - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(fixture.url, it.data["url"]) @@ -287,7 +287,7 @@ class SentrySpanRestClientCustomizerTest { .body("content") .retrieve() .toEntity(String::class.java) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(fixture.url, it.data["url"]) @@ -309,7 +309,7 @@ class SentrySpanRestClientCustomizerTest { .toEntity(String::class.java) } catch (e: Throwable) { } - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(fixture.url, it.data["url"]) diff --git a/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanRestTemplateCustomizerTest.kt b/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanRestTemplateCustomizerTest.kt index db5b25de44..4ab3205b31 100644 --- a/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanRestTemplateCustomizerTest.kt +++ b/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanRestTemplateCustomizerTest.kt @@ -2,7 +2,7 @@ package io.sentry.spring.boot.jakarta import io.sentry.BaggageHeader import io.sentry.Breadcrumb -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.Scope import io.sentry.ScopeCallback import io.sentry.SentryOptions @@ -37,21 +37,21 @@ import kotlin.test.assertTrue class SentrySpanRestTemplateCustomizerTest { class Fixture { val sentryOptions = SentryOptions() - val hub = mock() + val scopes = mock() val restTemplate = RestTemplateBuilder() .setConnectTimeout(Duration.ofSeconds(2)) .setReadTimeout(Duration.ofSeconds(2)) .build() var mockServer = MockWebServer() val transaction: SentryTracer - internal val customizer = SentrySpanRestTemplateCustomizer(hub) + internal val customizer = SentrySpanRestTemplateCustomizer(scopes) val url = mockServer.url("/test/123").toString() val scope = Scope(sentryOptions) init { - whenever(hub.options).thenReturn(sentryOptions) - doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(hub).configureScope(any()) - transaction = SentryTracer(TransactionContext("aTransaction", "op", TracesSamplingDecision(true)), hub) + whenever(scopes.options).thenReturn(sentryOptions) + doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(scopes).configureScope(any()) + transaction = SentryTracer(TransactionContext("aTransaction", "op", TracesSamplingDecision(true)), scopes) } fun getSut(isTransactionActive: Boolean, status: HttpStatus = HttpStatus.OK, socketPolicy: SocketPolicy = SocketPolicy.KEEP_OPEN, includeMockServerInTracingOrigins: Boolean = true): RestTemplate { @@ -74,7 +74,7 @@ class SentrySpanRestTemplateCustomizerTest { ) if (isTransactionActive) { - whenever(hub.span).thenReturn(transaction) + whenever(scopes.span).thenReturn(transaction) } return restTemplate @@ -209,7 +209,7 @@ class SentrySpanRestTemplateCustomizerTest { @Test fun `when transaction is active adds breadcrumb when http calls succeeds`() { fixture.getSut(isTransactionActive = true).postForObject(fixture.url, "content", String::class.java) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(fixture.url, it.data["url"]) @@ -227,7 +227,7 @@ class SentrySpanRestTemplateCustomizerTest { fixture.getSut(isTransactionActive = true, status = HttpStatus.INTERNAL_SERVER_ERROR).getForObject(fixture.url, String::class.java) } catch (e: Throwable) { } - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(fixture.url, it.data["url"]) @@ -240,7 +240,7 @@ class SentrySpanRestTemplateCustomizerTest { @Test fun `when transaction is not active adds breadcrumb when http calls succeeds`() { fixture.getSut(isTransactionActive = false).postForObject(fixture.url, "content", String::class.java) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(fixture.url, it.data["url"]) @@ -258,7 +258,7 @@ class SentrySpanRestTemplateCustomizerTest { fixture.getSut(isTransactionActive = false, status = HttpStatus.INTERNAL_SERVER_ERROR).getForObject(fixture.url, String::class.java) } catch (e: Throwable) { } - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(fixture.url, it.data["url"]) diff --git a/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanWebClientCustomizerTest.kt b/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanWebClientCustomizerTest.kt index 51f0a6cb3d..d3fb5f7d31 100644 --- a/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanWebClientCustomizerTest.kt +++ b/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanWebClientCustomizerTest.kt @@ -2,8 +2,8 @@ package io.sentry.spring.boot.jakarta import io.sentry.BaggageHeader import io.sentry.Breadcrumb -import io.sentry.IHub import io.sentry.IScope +import io.sentry.IScopes import io.sentry.Scope import io.sentry.ScopeCallback import io.sentry.SentryOptions @@ -39,10 +39,10 @@ class SentrySpanWebClientCustomizerTest { class Fixture { lateinit var sentryOptions: SentryOptions lateinit var scope: IScope - val hub = mock() + val scopes = mock() var mockServer = MockWebServer() lateinit var transaction: SentryTracer - private val customizer = SentrySpanWebClientCustomizer(hub) + private val customizer = SentrySpanWebClientCustomizer(scopes) fun getSut(isTransactionActive: Boolean, status: HttpStatus = HttpStatus.OK, throwIOException: Boolean = false, includeMockServerInTracingOrigins: Boolean = true): WebClient { sentryOptions = SentryOptions().apply { @@ -54,9 +54,9 @@ class SentrySpanWebClientCustomizerTest { dsn = "http://key@localhost/proj" } scope = Scope(sentryOptions) - whenever(hub.options).thenReturn(sentryOptions) - doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(hub).configureScope(any()) - transaction = SentryTracer(TransactionContext("aTransaction", "op", TracesSamplingDecision(true)), hub) + whenever(scopes.options).thenReturn(sentryOptions) + doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(scopes).configureScope(any()) + transaction = SentryTracer(TransactionContext("aTransaction", "op", TracesSamplingDecision(true)), scopes) val webClientBuilder = WebClient.builder() customizer.customize(webClientBuilder) val webClient = webClientBuilder.build() @@ -64,7 +64,7 @@ class SentrySpanWebClientCustomizerTest { if (isTransactionActive) { val scope = Scope(sentryOptions) scope.transaction = transaction - whenever(hub.span).thenReturn(transaction) + whenever(scopes.span).thenReturn(transaction) } val dispatcher: Dispatcher = object : Dispatcher() { @@ -236,7 +236,7 @@ class SentrySpanWebClientCustomizerTest { .retrieve() .bodyToMono(String::class.java) .block() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(uri.toString(), it.data["url"]) @@ -259,7 +259,7 @@ class SentrySpanWebClientCustomizerTest { .block() } catch (e: Throwable) { } - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(uri.toString(), it.data["url"]) @@ -279,7 +279,7 @@ class SentrySpanWebClientCustomizerTest { .retrieve() .bodyToMono(String::class.java) .block() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(uri.toString(), it.data["url"]) @@ -302,7 +302,7 @@ class SentrySpanWebClientCustomizerTest { .block() } catch (e: Throwable) { } - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(uri.toString(), it.data["url"]) diff --git a/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/it/SentrySpringIntegrationTest.kt b/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/it/SentrySpringIntegrationTest.kt index 4b8a0c26be..13a207d8eb 100644 --- a/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/it/SentrySpringIntegrationTest.kt +++ b/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/it/SentrySpringIntegrationTest.kt @@ -1,6 +1,6 @@ package io.sentry.spring.boot.jakarta.it -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ITransportFactory import io.sentry.Sentry import io.sentry.checkEvent @@ -60,7 +60,7 @@ class SentrySpringIntegrationTest { lateinit var transport: ITransport @SpyBean - lateinit var hub: IHub + lateinit var scopes: IScopes @LocalServerPort var port: Int? = null @@ -188,7 +188,7 @@ class SentrySpringIntegrationTest { restTemplate.getForEntity("http://localhost:$port/throws-handled", String::class.java) - verify(hub, never()).captureEvent(any()) + verify(scopes, never()).captureEvent(any()) } @Test diff --git a/sentry-spring-boot/api/sentry-spring-boot.api b/sentry-spring-boot/api/sentry-spring-boot.api index 32d7cc8c60..d97e2e1111 100644 --- a/sentry-spring-boot/api/sentry-spring-boot.api +++ b/sentry-spring-boot/api/sentry-spring-boot.api @@ -53,8 +53,8 @@ public class io/sentry/spring/boot/SentryProperties$Logging { public class io/sentry/spring/boot/SentryWebfluxAutoConfiguration { public fun ()V public fun sentryScheduleHookApplicationRunner ()Lorg/springframework/boot/ApplicationRunner; - public fun sentryWebExceptionHandler (Lio/sentry/IHub;)Lio/sentry/spring/webflux/SentryWebExceptionHandler; - public fun sentryWebFilter (Lio/sentry/IHub;)Lio/sentry/spring/webflux/SentryWebFilter; + public fun sentryWebExceptionHandler (Lio/sentry/IScopes;)Lio/sentry/spring/webflux/SentryWebExceptionHandler; + public fun sentryWebFilter (Lio/sentry/IScopes;)Lio/sentry/spring/webflux/SentryWebFilter; } public class io/sentry/spring/boot/graphql/SentryGraphqlAutoConfiguration { diff --git a/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentryAutoConfiguration.java b/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentryAutoConfiguration.java index edbfee271d..7d6a6a6fc4 100644 --- a/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentryAutoConfiguration.java +++ b/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentryAutoConfiguration.java @@ -3,10 +3,10 @@ import com.jakewharton.nopen.annotation.Open; import graphql.GraphQLError; import io.sentry.EventProcessor; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ITransportFactory; import io.sentry.Integration; +import io.sentry.ScopesAdapter; import io.sentry.Sentry; import io.sentry.SentryIntegrationPackageStorage; import io.sentry.SentryOptions; @@ -114,7 +114,7 @@ static class HubConfiguration { } @Bean - public @NotNull IHub sentryHub( + public @NotNull IScopes sentryHub( final @NotNull List> optionsConfigurations, final @NotNull SentryProperties options, final @NotNull ObjectProvider gitProperties) { @@ -137,7 +137,7 @@ static class HubConfiguration { // here we make sure that only classes that extend throwable are set on this field options.getIgnoredExceptionsForType().removeIf(it -> !Throwable.class.isAssignableFrom(it)); Sentry.init(options); - return HubAdapter.getInstance(); + return ScopesAdapter.getInstance(); } @Configuration(proxyBeanMethods = false) @@ -237,7 +237,7 @@ static class SentrySecurityConfiguration { * HttpServletRequest#getUserPrincipal()}. If Spring Security is auto-configured, its order is * set to run after Spring Security. * - * @param hub the Sentry hub + * @param scopes the Sentry scopes * @param sentryProperties the Sentry properties * @param sentryUserProvider the user provider * @return {@link SentryUserFilter} registration bean @@ -245,11 +245,11 @@ static class SentrySecurityConfiguration { @Bean @ConditionalOnBean(SentryUserProvider.class) public @NotNull FilterRegistrationBean sentryUserFilter( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull SentryProperties sentryProperties, final @NotNull List sentryUserProvider) { final FilterRegistrationBean filter = new FilterRegistrationBean<>(); - filter.setFilter(new SentryUserFilter(hub, sentryUserProvider)); + filter.setFilter(new SentryUserFilter(scopes, sentryUserProvider)); filter.setOrder(resolveUserFilterOrder(sentryProperties)); return filter; } @@ -261,8 +261,8 @@ static class SentrySecurityConfiguration { } @Bean - public @NotNull SentryRequestResolver sentryRequestResolver(final @NotNull IHub hub) { - return new SentryRequestResolver(hub); + public @NotNull SentryRequestResolver sentryRequestResolver(final @NotNull IScopes scopes) { + return new SentryRequestResolver(scopes); } @Bean @@ -274,12 +274,12 @@ static class SentrySecurityConfiguration { @Bean @ConditionalOnMissingBean(name = "sentrySpringFilter") public @NotNull FilterRegistrationBean sentrySpringFilter( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull SentryRequestResolver requestResolver, final @NotNull TransactionNameProvider transactionNameProvider) { FilterRegistrationBean filter = new FilterRegistrationBean<>( - new SentrySpringFilter(hub, requestResolver, transactionNameProvider)); + new SentrySpringFilter(scopes, requestResolver, transactionNameProvider)); filter.setOrder(SENTRY_SPRING_FILTER_PRECEDENCE); return filter; } @@ -287,9 +287,10 @@ static class SentrySecurityConfiguration { @Bean @ConditionalOnMissingBean(name = "sentryTracingFilter") public FilterRegistrationBean sentryTracingFilter( - final @NotNull IHub hub, final @NotNull TransactionNameProvider transactionNameProvider) { + final @NotNull IScopes scopes, + final @NotNull TransactionNameProvider transactionNameProvider) { FilterRegistrationBean filter = - new FilterRegistrationBean<>(new SentryTracingFilter(hub, transactionNameProvider)); + new FilterRegistrationBean<>(new SentryTracingFilter(scopes, transactionNameProvider)); filter.setOrder(SENTRY_SPRING_FILTER_PRECEDENCE + 1); // must run after SentrySpringFilter return filter; } @@ -298,11 +299,11 @@ public FilterRegistrationBean sentryTracingFilter( @ConditionalOnMissingBean @ConditionalOnClass(HandlerExceptionResolver.class) public @NotNull SentryExceptionResolver sentryExceptionResolver( - final @NotNull IHub sentryHub, + final @NotNull IScopes scopes, final @NotNull TransactionNameProvider transactionNameProvider, final @NotNull SentryProperties options) { return new SentryExceptionResolver( - sentryHub, transactionNameProvider, options.getExceptionResolverOrder()); + scopes, transactionNameProvider, options.getExceptionResolverOrder()); } } @@ -348,8 +349,8 @@ static class SentrySpanPointcutAutoConfiguration {} @Open static class SentryPerformanceRestTemplateConfiguration { @Bean - public SentrySpanRestTemplateCustomizer sentrySpanRestTemplateCustomizer(IHub hub) { - return new SentrySpanRestTemplateCustomizer(hub); + public SentrySpanRestTemplateCustomizer sentrySpanRestTemplateCustomizer(IScopes scopes) { + return new SentrySpanRestTemplateCustomizer(scopes); } } @@ -359,8 +360,8 @@ public SentrySpanRestTemplateCustomizer sentrySpanRestTemplateCustomizer(IHub hu @Open static class SentryPerformanceWebClientConfiguration { @Bean - public SentrySpanWebClientCustomizer sentrySpanWebClientCustomizer(IHub hub) { - return new SentrySpanWebClientCustomizer(hub); + public SentrySpanWebClientCustomizer sentrySpanWebClientCustomizer(IScopes scopes) { + return new SentrySpanWebClientCustomizer(scopes); } } diff --git a/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentrySpanRestTemplateCustomizer.java b/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentrySpanRestTemplateCustomizer.java index bd311c55f1..2a5e4f1be5 100644 --- a/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentrySpanRestTemplateCustomizer.java +++ b/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentrySpanRestTemplateCustomizer.java @@ -1,7 +1,7 @@ package io.sentry.spring.boot; import com.jakewharton.nopen.annotation.Open; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.spring.tracing.SentrySpanClientHttpRequestInterceptor; import java.util.ArrayList; import java.util.List; @@ -14,8 +14,8 @@ class SentrySpanRestTemplateCustomizer implements RestTemplateCustomizer { private final @NotNull SentrySpanClientHttpRequestInterceptor interceptor; - public SentrySpanRestTemplateCustomizer(final @NotNull IHub hub) { - this.interceptor = new SentrySpanClientHttpRequestInterceptor(hub); + public SentrySpanRestTemplateCustomizer(final @NotNull IScopes scopes) { + this.interceptor = new SentrySpanClientHttpRequestInterceptor(scopes); } @Override diff --git a/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentrySpanWebClientCustomizer.java b/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentrySpanWebClientCustomizer.java index 0b8aa4055c..79e59f1cf0 100644 --- a/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentrySpanWebClientCustomizer.java +++ b/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentrySpanWebClientCustomizer.java @@ -1,7 +1,7 @@ package io.sentry.spring.boot; import com.jakewharton.nopen.annotation.Open; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.spring.tracing.SentrySpanClientWebRequestFilter; import org.jetbrains.annotations.NotNull; import org.springframework.boot.web.reactive.function.client.WebClientCustomizer; @@ -11,8 +11,8 @@ class SentrySpanWebClientCustomizer implements WebClientCustomizer { private final @NotNull SentrySpanClientWebRequestFilter filter; - public SentrySpanWebClientCustomizer(final @NotNull IHub hub) { - this.filter = new SentrySpanClientWebRequestFilter(hub); + public SentrySpanWebClientCustomizer(final @NotNull IScopes scopes) { + this.filter = new SentrySpanClientWebRequestFilter(scopes); } @Override diff --git a/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentryWebfluxAutoConfiguration.java b/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentryWebfluxAutoConfiguration.java index 3d507f1b6b..e7f6a444b8 100644 --- a/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentryWebfluxAutoConfiguration.java +++ b/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentryWebfluxAutoConfiguration.java @@ -1,8 +1,8 @@ package io.sentry.spring.boot; import com.jakewharton.nopen.annotation.Open; -import io.sentry.IHub; import io.sentry.IScope; +import io.sentry.IScopes; import io.sentry.spring.webflux.SentryScheduleHook; import io.sentry.spring.webflux.SentryWebExceptionHandler; import io.sentry.spring.webflux.SentryWebFilter; @@ -21,14 +21,14 @@ /** Configures Sentry integration for Spring Webflux and Project Reactor. */ @Configuration(proxyBeanMethods = false) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) -@ConditionalOnBean(IHub.class) +@ConditionalOnBean(IScopes.class) @ConditionalOnClass(Schedulers.class) @Open @ApiStatus.Experimental public class SentryWebfluxAutoConfiguration { private static final int SENTRY_SPRING_FILTER_PRECEDENCE = Ordered.HIGHEST_PRECEDENCE; - /** Configures hook that sets correct hub on the executing thread. */ + /** Configures hook that sets correct scopes on the executing thread. */ @Bean public @NotNull ApplicationRunner sentryScheduleHookApplicationRunner() { return args -> { @@ -39,13 +39,14 @@ public class SentryWebfluxAutoConfiguration { /** Configures a filter that sets up Sentry {@link IScope} for each request. */ @Bean @Order(SENTRY_SPRING_FILTER_PRECEDENCE) - public @NotNull SentryWebFilter sentryWebFilter(final @NotNull IHub hub) { - return new SentryWebFilter(hub); + public @NotNull SentryWebFilter sentryWebFilter(final @NotNull IScopes scopes) { + return new SentryWebFilter(scopes); } /** Configures exception handler that handles unhandled exceptions and sends them to Sentry. */ @Bean - public @NotNull SentryWebExceptionHandler sentryWebExceptionHandler(final @NotNull IHub hub) { - return new SentryWebExceptionHandler(hub); + public @NotNull SentryWebExceptionHandler sentryWebExceptionHandler( + final @NotNull IScopes scopes) { + return new SentryWebExceptionHandler(scopes); } } diff --git a/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentryAutoConfigurationTest.kt b/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentryAutoConfigurationTest.kt index c7fd177ec0..e1fe220aea 100644 --- a/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentryAutoConfigurationTest.kt +++ b/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentryAutoConfigurationTest.kt @@ -5,7 +5,7 @@ import io.sentry.AsyncHttpTransportFactory import io.sentry.Breadcrumb import io.sentry.EventProcessor import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ITransportFactory import io.sentry.Integration import io.sentry.NoOpTransportFactory @@ -76,18 +76,18 @@ class SentryAutoConfigurationTest { .withConfiguration(AutoConfigurations.of(SentryAutoConfiguration::class.java, WebMvcAutoConfiguration::class.java)) @Test - fun `hub is not created when auto-configuration dsn is not set`() { + fun `scopes is not created when auto-configuration dsn is not set`() { contextRunner .run { - assertThat(it).doesNotHaveBean(IHub::class.java) + assertThat(it).doesNotHaveBean(IScopes::class.java) } } @Test - fun `hub is created when dsn is provided`() { + fun `scopes is created when dsn is provided`() { contextRunner.withPropertyValues("sentry.dsn=http://key@localhost/proj") .run { - assertThat(it).hasSingleBean(IHub::class.java) + assertThat(it).hasSingleBean(IScopes::class.java) } } @@ -943,7 +943,7 @@ class SentryAutoConfigurationTest { } class CustomIntegration : Integration { - override fun register(hub: IHub, options: SentryOptions) {} + override fun register(scopes: IScopes, options: SentryOptions) {} } @Configuration(proxyBeanMethods = false) diff --git a/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentrySpanRestTemplateCustomizerTest.kt b/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentrySpanRestTemplateCustomizerTest.kt index 0d675b6841..33d7974d8a 100644 --- a/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentrySpanRestTemplateCustomizerTest.kt +++ b/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentrySpanRestTemplateCustomizerTest.kt @@ -2,7 +2,7 @@ package io.sentry.spring.boot import io.sentry.BaggageHeader import io.sentry.Breadcrumb -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.Scope import io.sentry.ScopeCallback import io.sentry.SentryOptions @@ -37,23 +37,23 @@ import kotlin.test.assertTrue class SentrySpanRestTemplateCustomizerTest { class Fixture { val sentryOptions = SentryOptions() - val hub = mock() + val scopes = mock() val restTemplate = RestTemplateBuilder() .setConnectTimeout(Duration.ofSeconds(2)) .setReadTimeout(Duration.ofSeconds(2)) .build() var mockServer = MockWebServer() val transaction: SentryTracer - internal val customizer = SentrySpanRestTemplateCustomizer(hub) + internal val customizer = SentrySpanRestTemplateCustomizer(scopes) val url = mockServer.url("/test/123").toString() val scope = Scope(sentryOptions) init { - whenever(hub.options).thenReturn(sentryOptions) - doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(hub).configureScope( + whenever(scopes.options).thenReturn(sentryOptions) + doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(scopes).configureScope( any() ) - transaction = SentryTracer(TransactionContext("aTransaction", "op", TracesSamplingDecision(true)), hub) + transaction = SentryTracer(TransactionContext("aTransaction", "op", TracesSamplingDecision(true)), scopes) } fun getSut(isTransactionActive: Boolean, status: HttpStatus = HttpStatus.OK, socketPolicy: SocketPolicy = SocketPolicy.KEEP_OPEN, includeMockServerInTracingOrigins: Boolean = true): RestTemplate { @@ -76,7 +76,7 @@ class SentrySpanRestTemplateCustomizerTest { ) if (isTransactionActive) { - whenever(hub.span).thenReturn(transaction) + whenever(scopes.span).thenReturn(transaction) } return restTemplate @@ -211,7 +211,7 @@ class SentrySpanRestTemplateCustomizerTest { @Test fun `when transaction is active adds breadcrumb when http calls succeeds`() { fixture.getSut(isTransactionActive = true).postForObject(fixture.url, "content", String::class.java) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(fixture.url, it.data["url"]) @@ -229,7 +229,7 @@ class SentrySpanRestTemplateCustomizerTest { fixture.getSut(isTransactionActive = true, status = HttpStatus.INTERNAL_SERVER_ERROR).getForObject(fixture.url, String::class.java) } catch (e: Throwable) { } - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(fixture.url, it.data["url"]) @@ -242,7 +242,7 @@ class SentrySpanRestTemplateCustomizerTest { @Test fun `when transaction is not active adds breadcrumb when http calls succeeds`() { fixture.getSut(isTransactionActive = false).postForObject(fixture.url, "content", String::class.java) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(fixture.url, it.data["url"]) @@ -260,7 +260,7 @@ class SentrySpanRestTemplateCustomizerTest { fixture.getSut(isTransactionActive = false, status = HttpStatus.INTERNAL_SERVER_ERROR).getForObject(fixture.url, String::class.java) } catch (e: Throwable) { } - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(fixture.url, it.data["url"]) diff --git a/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentrySpanWebClientCustomizerTest.kt b/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentrySpanWebClientCustomizerTest.kt index f925435fd3..4f1f70d75e 100644 --- a/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentrySpanWebClientCustomizerTest.kt +++ b/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentrySpanWebClientCustomizerTest.kt @@ -2,8 +2,8 @@ package io.sentry.spring.boot import io.sentry.BaggageHeader import io.sentry.Breadcrumb -import io.sentry.IHub import io.sentry.IScope +import io.sentry.IScopes import io.sentry.Scope import io.sentry.ScopeCallback import io.sentry.SentryOptions @@ -39,10 +39,10 @@ class SentrySpanWebClientCustomizerTest { class Fixture { lateinit var sentryOptions: SentryOptions lateinit var scope: IScope - val hub = mock() + val scopes = mock() var mockServer = MockWebServer() lateinit var transaction: SentryTracer - private val customizer = SentrySpanWebClientCustomizer(hub) + private val customizer = SentrySpanWebClientCustomizer(scopes) fun getSut(isTransactionActive: Boolean, status: HttpStatus = HttpStatus.OK, throwIOException: Boolean = false, includeMockServerInTracingOrigins: Boolean = true): WebClient { sentryOptions = SentryOptions().apply { @@ -54,11 +54,11 @@ class SentrySpanWebClientCustomizerTest { dsn = "http://key@localhost/proj" } scope = Scope(sentryOptions) - whenever(hub.options).thenReturn(sentryOptions) - doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(hub).configureScope( + whenever(scopes.options).thenReturn(sentryOptions) + doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(scopes).configureScope( any() ) - transaction = SentryTracer(TransactionContext("aTransaction", "op", TracesSamplingDecision(true)), hub) + transaction = SentryTracer(TransactionContext("aTransaction", "op", TracesSamplingDecision(true)), scopes) val webClientBuilder = WebClient.builder() customizer.customize(webClientBuilder) val webClient = webClientBuilder.build() @@ -66,7 +66,7 @@ class SentrySpanWebClientCustomizerTest { if (isTransactionActive) { val scope = Scope(sentryOptions) scope.transaction = transaction - whenever(hub.span).thenReturn(transaction) + whenever(scopes.span).thenReturn(transaction) } val dispatcher: Dispatcher = object : Dispatcher() { @@ -238,7 +238,7 @@ class SentrySpanWebClientCustomizerTest { .retrieve() .bodyToMono(String::class.java) .block() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(uri.toString(), it.data["url"]) @@ -261,7 +261,7 @@ class SentrySpanWebClientCustomizerTest { .block() } catch (e: Throwable) { } - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(uri.toString(), it.data["url"]) @@ -281,7 +281,7 @@ class SentrySpanWebClientCustomizerTest { .retrieve() .bodyToMono(String::class.java) .block() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(uri.toString(), it.data["url"]) @@ -304,7 +304,7 @@ class SentrySpanWebClientCustomizerTest { .block() } catch (e: Throwable) { } - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(uri.toString(), it.data["url"]) diff --git a/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/it/SentrySpringIntegrationTest.kt b/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/it/SentrySpringIntegrationTest.kt index eb6d159a7c..3bbcb2c3e7 100644 --- a/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/it/SentrySpringIntegrationTest.kt +++ b/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/it/SentrySpringIntegrationTest.kt @@ -1,6 +1,6 @@ package io.sentry.spring.boot.it -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ITransportFactory import io.sentry.Sentry import io.sentry.checkEvent @@ -60,7 +60,7 @@ class SentrySpringIntegrationTest { lateinit var transport: ITransport @SpyBean - lateinit var hub: IHub + lateinit var scopes: IScopes @LocalServerPort var port: Int? = null @@ -188,7 +188,7 @@ class SentrySpringIntegrationTest { restTemplate.getForEntity("http://localhost:$port/throws-handled", String::class.java) - verify(hub, never()).captureEvent(any()) + verify(scopes, never()).captureEvent(any()) } @Test diff --git a/sentry-spring-jakarta/api/sentry-spring-jakarta.api b/sentry-spring-jakarta/api/sentry-spring-jakarta.api index cebbd26b4f..13eb6033f9 100644 --- a/sentry-spring-jakarta/api/sentry-spring-jakarta.api +++ b/sentry-spring-jakarta/api/sentry-spring-jakarta.api @@ -22,7 +22,7 @@ public final class io/sentry/spring/jakarta/HttpServletRequestSentryUserProvider public class io/sentry/spring/jakarta/SentryExceptionResolver : org/springframework/core/Ordered, org/springframework/web/servlet/HandlerExceptionResolver { public static final field MECHANISM_TYPE Ljava/lang/String; - public fun (Lio/sentry/IHub;Lio/sentry/spring/jakarta/tracing/TransactionNameProvider;I)V + public fun (Lio/sentry/IScopes;Lio/sentry/spring/jakarta/tracing/TransactionNameProvider;I)V protected fun createEvent (Ljakarta/servlet/http/HttpServletRequest;Ljava/lang/Exception;)Lio/sentry/SentryEvent; protected fun createHint (Ljakarta/servlet/http/HttpServletRequest;Ljakarta/servlet/http/HttpServletResponse;)Lio/sentry/Hint; public fun getOrder ()I @@ -47,14 +47,14 @@ public class io/sentry/spring/jakarta/SentryRequestHttpServletRequestProcessor : } public class io/sentry/spring/jakarta/SentryRequestResolver { - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun resolveSentryRequest (Ljakarta/servlet/http/HttpServletRequest;)Lio/sentry/protocol/Request; } public class io/sentry/spring/jakarta/SentrySpringFilter : org/springframework/web/filter/OncePerRequestFilter { public fun ()V - public fun (Lio/sentry/IHub;)V - public fun (Lio/sentry/IHub;Lio/sentry/spring/jakarta/SentryRequestResolver;Lio/sentry/spring/jakarta/tracing/TransactionNameProvider;)V + public fun (Lio/sentry/IScopes;)V + public fun (Lio/sentry/IScopes;Lio/sentry/spring/jakarta/SentryRequestResolver;Lio/sentry/spring/jakarta/tracing/TransactionNameProvider;)V protected fun doFilterInternal (Ljakarta/servlet/http/HttpServletRequest;Ljakarta/servlet/http/HttpServletResponse;Ljakarta/servlet/FilterChain;)V } @@ -69,7 +69,7 @@ public final class io/sentry/spring/jakarta/SentryTaskDecorator : org/springfram } public class io/sentry/spring/jakarta/SentryUserFilter : org/springframework/web/filter/OncePerRequestFilter { - public fun (Lio/sentry/IHub;Ljava/util/List;)V + public fun (Lio/sentry/IScopes;Ljava/util/List;)V protected fun doFilterInternal (Ljakarta/servlet/http/HttpServletRequest;Ljakarta/servlet/http/HttpServletResponse;Ljakarta/servlet/FilterChain;)V public fun getSentryUserProviders ()Ljava/util/List; } @@ -96,7 +96,7 @@ public abstract interface annotation class io/sentry/spring/jakarta/checkin/Sent public class io/sentry/spring/jakarta/checkin/SentryCheckInAdvice : org/aopalliance/intercept/MethodInterceptor, org/springframework/context/EmbeddedValueResolverAware { public fun ()V - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun invoke (Lorg/aopalliance/intercept/MethodInvocation;)Ljava/lang/Object; public fun setEmbeddedValueResolver (Lorg/springframework/util/StringValueResolver;)V } @@ -127,7 +127,7 @@ public abstract interface annotation class io/sentry/spring/jakarta/exception/Se public class io/sentry/spring/jakarta/exception/SentryCaptureExceptionParameterAdvice : org/aopalliance/intercept/MethodInterceptor { public fun ()V - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun invoke (Lorg/aopalliance/intercept/MethodInvocation;)Ljava/lang/Object; } @@ -169,7 +169,7 @@ public final class io/sentry/spring/jakarta/graphql/SentryDataFetcherExceptionRe public final class io/sentry/spring/jakarta/graphql/SentryDgsSubscriptionHandler : io/sentry/graphql/SentrySubscriptionHandler { public fun ()V - public fun onSubscriptionResult (Ljava/lang/Object;Lio/sentry/IHub;Lio/sentry/graphql/ExceptionReporter;Lgraphql/execution/instrumentation/parameters/InstrumentationFieldFetchParameters;)Ljava/lang/Object; + public fun onSubscriptionResult (Ljava/lang/Object;Lio/sentry/IScopes;Lio/sentry/graphql/ExceptionReporter;Lgraphql/execution/instrumentation/parameters/InstrumentationFieldFetchParameters;)Ljava/lang/Object; } public final class io/sentry/spring/jakarta/graphql/SentryGraphqlBeanPostProcessor : org/springframework/beans/factory/config/BeanPostProcessor, org/springframework/core/PriorityOrdered { @@ -188,7 +188,7 @@ public class io/sentry/spring/jakarta/graphql/SentryGraphqlConfiguration { public final class io/sentry/spring/jakarta/graphql/SentrySpringSubscriptionHandler : io/sentry/graphql/SentrySubscriptionHandler { public fun ()V - public fun onSubscriptionResult (Ljava/lang/Object;Lio/sentry/IHub;Lio/sentry/graphql/ExceptionReporter;Lgraphql/execution/instrumentation/parameters/InstrumentationFieldFetchParameters;)Ljava/lang/Object; + public fun onSubscriptionResult (Ljava/lang/Object;Lio/sentry/IScopes;Lio/sentry/graphql/ExceptionReporter;Lgraphql/execution/instrumentation/parameters/InstrumentationFieldFetchParameters;)Ljava/lang/Object; } public class io/sentry/spring/jakarta/tracing/SentryAdviceConfiguration { @@ -207,18 +207,18 @@ public abstract interface annotation class io/sentry/spring/jakarta/tracing/Sent public class io/sentry/spring/jakarta/tracing/SentrySpanAdvice : org/aopalliance/intercept/MethodInterceptor { public fun ()V - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun invoke (Lorg/aopalliance/intercept/MethodInvocation;)Ljava/lang/Object; } public class io/sentry/spring/jakarta/tracing/SentrySpanClientHttpRequestInterceptor : org/springframework/http/client/ClientHttpRequestInterceptor { - public fun (Lio/sentry/IHub;)V - public fun (Lio/sentry/IHub;Z)V + public fun (Lio/sentry/IScopes;)V + public fun (Lio/sentry/IScopes;Z)V public fun intercept (Lorg/springframework/http/HttpRequest;[BLorg/springframework/http/client/ClientHttpRequestExecution;)Lorg/springframework/http/client/ClientHttpResponse; } public class io/sentry/spring/jakarta/tracing/SentrySpanClientWebRequestFilter : org/springframework/web/reactive/function/client/ExchangeFilterFunction { - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun filter (Lorg/springframework/web/reactive/function/client/ClientRequest;Lorg/springframework/web/reactive/function/client/ExchangeFunction;)Lreactor/core/publisher/Mono; } @@ -233,8 +233,8 @@ public class io/sentry/spring/jakarta/tracing/SentryTracingConfiguration { public class io/sentry/spring/jakarta/tracing/SentryTracingFilter : org/springframework/web/filter/OncePerRequestFilter { public fun ()V - public fun (Lio/sentry/IHub;)V - public fun (Lio/sentry/IHub;Lio/sentry/spring/jakarta/tracing/TransactionNameProvider;)V + public fun (Lio/sentry/IScopes;)V + public fun (Lio/sentry/IScopes;Lio/sentry/spring/jakarta/tracing/TransactionNameProvider;)V protected fun doFilterInternal (Ljakarta/servlet/http/HttpServletRequest;Ljakarta/servlet/http/HttpServletResponse;Ljakarta/servlet/FilterChain;)V } @@ -246,7 +246,7 @@ public abstract interface annotation class io/sentry/spring/jakarta/tracing/Sent public class io/sentry/spring/jakarta/tracing/SentryTransactionAdvice : org/aopalliance/intercept/MethodInterceptor { public fun ()V - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun invoke (Lorg/aopalliance/intercept/MethodInvocation;)Ljava/lang/Object; } @@ -268,21 +268,22 @@ public abstract interface class io/sentry/spring/jakarta/tracing/TransactionName public abstract class io/sentry/spring/jakarta/webflux/AbstractSentryWebFilter : org/springframework/web/server/WebFilter { public static final field SENTRY_HUB_KEY Ljava/lang/String; - public fun (Lio/sentry/IHub;)V - protected fun doFinally (Lorg/springframework/web/server/ServerWebExchange;Lio/sentry/IHub;Lio/sentry/ITransaction;)V - protected fun doFirst (Lorg/springframework/web/server/ServerWebExchange;Lio/sentry/IHub;)V + public static final field SENTRY_SCOPES_KEY Ljava/lang/String; + public fun (Lio/sentry/IScopes;)V + protected fun doFinally (Lorg/springframework/web/server/ServerWebExchange;Lio/sentry/IScopes;Lio/sentry/ITransaction;)V + protected fun doFirst (Lorg/springframework/web/server/ServerWebExchange;Lio/sentry/IScopes;)V protected fun doOnError (Lio/sentry/ITransaction;Ljava/lang/Throwable;)V - protected fun maybeStartTransaction (Lio/sentry/IHub;Lorg/springframework/http/server/reactive/ServerHttpRequest;)Lio/sentry/ITransaction; - protected fun shouldTraceRequest (Lio/sentry/IHub;Lorg/springframework/http/server/reactive/ServerHttpRequest;)Z - protected fun startTransaction (Lio/sentry/IHub;Lorg/springframework/http/server/reactive/ServerHttpRequest;Lio/sentry/TransactionContext;)Lio/sentry/ITransaction; + protected fun maybeStartTransaction (Lio/sentry/IScopes;Lorg/springframework/http/server/reactive/ServerHttpRequest;)Lio/sentry/ITransaction; + protected fun shouldTraceRequest (Lio/sentry/IScopes;Lorg/springframework/http/server/reactive/ServerHttpRequest;)Z + protected fun startTransaction (Lio/sentry/IScopes;Lorg/springframework/http/server/reactive/ServerHttpRequest;Lio/sentry/TransactionContext;)Lio/sentry/ITransaction; } public final class io/sentry/spring/jakarta/webflux/ReactorUtils { public fun ()V public static fun withSentry (Lreactor/core/publisher/Flux;)Lreactor/core/publisher/Flux; public static fun withSentry (Lreactor/core/publisher/Mono;)Lreactor/core/publisher/Mono; - public static fun withSentryHub (Lreactor/core/publisher/Flux;Lio/sentry/IHub;)Lreactor/core/publisher/Flux; - public static fun withSentryHub (Lreactor/core/publisher/Mono;Lio/sentry/IHub;)Lreactor/core/publisher/Mono; + public static fun withSentryHub (Lreactor/core/publisher/Flux;Lio/sentry/IScopes;)Lreactor/core/publisher/Flux; + public static fun withSentryHub (Lreactor/core/publisher/Mono;Lio/sentry/IScopes;)Lreactor/core/publisher/Mono; public static fun withSentryNewMainHubClone (Lreactor/core/publisher/Flux;)Lreactor/core/publisher/Flux; public static fun withSentryNewMainHubClone (Lreactor/core/publisher/Mono;)Lreactor/core/publisher/Mono; } @@ -290,16 +291,16 @@ public final class io/sentry/spring/jakarta/webflux/ReactorUtils { public final class io/sentry/spring/jakarta/webflux/SentryReactorThreadLocalAccessor : io/micrometer/context/ThreadLocalAccessor { public static final field KEY Ljava/lang/String; public fun ()V - public fun getValue ()Lio/sentry/IHub; + public fun getValue ()Lio/sentry/IScopes; public synthetic fun getValue ()Ljava/lang/Object; public fun key ()Ljava/lang/Object; public fun reset ()V - public fun setValue (Lio/sentry/IHub;)V + public fun setValue (Lio/sentry/IScopes;)V public synthetic fun setValue (Ljava/lang/Object;)V } public class io/sentry/spring/jakarta/webflux/SentryRequestResolver { - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun resolveSentryRequest (Lorg/springframework/http/server/reactive/ServerHttpRequest;)Lio/sentry/protocol/Request; } @@ -311,18 +312,18 @@ public final class io/sentry/spring/jakarta/webflux/SentryScheduleHook : java/ut public final class io/sentry/spring/jakarta/webflux/SentryWebExceptionHandler : org/springframework/web/server/WebExceptionHandler { public static final field MECHANISM_TYPE Ljava/lang/String; - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun handle (Lorg/springframework/web/server/ServerWebExchange;Ljava/lang/Throwable;)Lreactor/core/publisher/Mono; } public class io/sentry/spring/jakarta/webflux/SentryWebFilter : io/sentry/spring/jakarta/webflux/AbstractSentryWebFilter { - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun filter (Lorg/springframework/web/server/ServerWebExchange;Lorg/springframework/web/server/WebFilterChain;)Lreactor/core/publisher/Mono; } public final class io/sentry/spring/jakarta/webflux/SentryWebFilterWithThreadLocalAccessor : io/sentry/spring/jakarta/webflux/AbstractSentryWebFilter { public static final field TRACE_ORIGIN Ljava/lang/String; - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun filter (Lorg/springframework/web/server/ServerWebExchange;Lorg/springframework/web/server/WebFilterChain;)Lreactor/core/publisher/Mono; } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/EnableSentry.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/EnableSentry.java index 1395e035a1..e8cd91f3f4 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/EnableSentry.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/EnableSentry.java @@ -12,7 +12,7 @@ * *

    *
  • creates bean of type {@link io.sentry.SentryOptions} - *
  • registers {@link io.sentry.IHub} for sending Sentry events + *
  • registers {@link io.sentry.IScopes} for sending Sentry events *
  • registers {@link SentryExceptionResolver} to send Sentry event for any uncaught exception * in Spring MVC flow. *
diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryExceptionResolver.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryExceptionResolver.java index 6d4098d624..efa98ef581 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryExceptionResolver.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryExceptionResolver.java @@ -5,7 +5,7 @@ import com.jakewharton.nopen.annotation.Open; import io.sentry.Hint; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.SentryEvent; import io.sentry.SentryLevel; import io.sentry.exception.ExceptionMechanismException; @@ -29,15 +29,15 @@ public class SentryExceptionResolver implements HandlerExceptionResolver, Ordered { public static final String MECHANISM_TYPE = "Spring6ExceptionResolver"; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @NotNull TransactionNameProvider transactionNameProvider; private final int order; public SentryExceptionResolver( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull TransactionNameProvider transactionNameProvider, final int order) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); this.transactionNameProvider = Objects.requireNonNull(transactionNameProvider, "transactionNameProvider is required"); this.order = order; @@ -53,7 +53,7 @@ public SentryExceptionResolver( final SentryEvent event = createEvent(request, ex); final Hint hint = createHint(request, response); - hub.captureEvent(event, hint); + scopes.captureEvent(event, hint); // null = run other HandlerExceptionResolvers to actually handle the exception return null; diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryHubRegistrar.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryHubRegistrar.java index 4a8789c812..9598f0c926 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryHubRegistrar.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryHubRegistrar.java @@ -1,7 +1,7 @@ package io.sentry.spring.jakarta; import com.jakewharton.nopen.annotation.Open; -import io.sentry.HubAdapter; +import io.sentry.ScopesAdapter; import io.sentry.SentryIntegrationPackageStorage; import io.sentry.SentryOptions; import io.sentry.protocol.SdkVersion; @@ -60,7 +60,7 @@ private void registerSentryOptions( private void registerSentryHubBean(final @NotNull BeanDefinitionRegistry registry) { final BeanDefinitionBuilder builder = - BeanDefinitionBuilder.genericBeanDefinition(HubAdapter.class); + BeanDefinitionBuilder.genericBeanDefinition(ScopesAdapter.class); builder.setInitMethodName("getInstance"); registry.registerBeanDefinition("sentryHub", builder.getBeanDefinition()); diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryInitBeanPostProcessor.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryInitBeanPostProcessor.java index 9937bfbf1a..d33dfca8d8 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryInitBeanPostProcessor.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryInitBeanPostProcessor.java @@ -2,10 +2,10 @@ import com.jakewharton.nopen.annotation.Open; import io.sentry.EventProcessor; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ITransportFactory; import io.sentry.Integration; +import io.sentry.ScopesAdapter; import io.sentry.Sentry; import io.sentry.SentryOptions; import io.sentry.SentryOptions.TracesSamplerCallback; @@ -27,15 +27,15 @@ public class SentryInitBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware, DisposableBean { private @Nullable ApplicationContext applicationContext; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; public SentryInitBeanPostProcessor() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } - SentryInitBeanPostProcessor(final @NotNull IHub hub) { - Objects.requireNonNull(hub, "hub is required"); - this.hub = hub; + SentryInitBeanPostProcessor(final @NotNull IScopes scopes) { + Objects.requireNonNull(scopes, "Scopes are required"); + this.scopes = scopes; } @Override @@ -86,6 +86,6 @@ public void setApplicationContext(final @NotNull ApplicationContext applicationC @Override public void destroy() { - hub.close(); + scopes.close(); } } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryRequestResolver.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryRequestResolver.java index e1bc45ac64..71f9079f9f 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryRequestResolver.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryRequestResolver.java @@ -1,7 +1,7 @@ package io.sentry.spring.jakarta; import com.jakewharton.nopen.annotation.Open; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.SentryLevel; import io.sentry.protocol.Request; import io.sentry.util.HttpUtils; @@ -20,11 +20,11 @@ @Open public class SentryRequestResolver { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private volatile @Nullable List extraSecurityCookies; - public SentryRequestResolver(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "options is required"); + public SentryRequestResolver(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "options is required"); } // httpRequest.getRequestURL() returns StringBuffer which is considered an obsolete class. @@ -40,7 +40,7 @@ public SentryRequestResolver(final @NotNull IHub hub) { extractSecurityCookieNamesOrUseCached(httpRequest); sentryRequest.setHeaders(resolveHeadersMap(httpRequest, additionalSecurityCookieNames)); - if (hub.getOptions().isSendDefaultPii()) { + if (scopes.getOptions().isSendDefaultPii()) { String cookieName = HttpUtils.COOKIE_HEADER_NAME; final @Nullable List filteredHeaders = HttpUtils.filterOutSecurityCookiesFromHeader( @@ -57,7 +57,8 @@ Map resolveHeadersMap( final Map headersMap = new HashMap<>(); for (String headerName : Collections.list(request.getHeaderNames())) { // do not copy personal information identifiable headers - if (hub.getOptions().isSendDefaultPii() || !HttpUtils.containsSensitiveHeader(headerName)) { + if (scopes.getOptions().isSendDefaultPii() + || !HttpUtils.containsSensitiveHeader(headerName)) { final @Nullable List filteredHeaders = HttpUtils.filterOutSecurityCookiesFromHeader( request.getHeaders(headerName), headerName, additionalSecurityCookieNames); @@ -94,7 +95,8 @@ private List extractSecurityCookieNames(final @NotNull HttpServletReques } } } catch (Throwable t) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log(SentryLevel.WARNING, "Failed to extract session cookie name from request.", t); } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentrySpringFilter.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentrySpringFilter.java index 129ea739d6..be06d3d253 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentrySpringFilter.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentrySpringFilter.java @@ -8,8 +8,8 @@ import io.sentry.Breadcrumb; import io.sentry.EventProcessor; import io.sentry.Hint; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; +import io.sentry.ScopesAdapter; import io.sentry.SentryEvent; import io.sentry.SentryLevel; import io.sentry.SentryOptions; @@ -29,26 +29,26 @@ @Open public class SentrySpringFilter extends OncePerRequestFilter { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @NotNull SentryRequestResolver requestResolver; private final @NotNull TransactionNameProvider transactionNameProvider; public SentrySpringFilter( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull SentryRequestResolver requestResolver, final @NotNull TransactionNameProvider transactionNameProvider) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); this.requestResolver = Objects.requireNonNull(requestResolver, "requestResolver is required"); this.transactionNameProvider = Objects.requireNonNull(transactionNameProvider, "transactionNameProvider is required"); } - public SentrySpringFilter(final @NotNull IHub hub) { - this(hub, new SentryRequestResolver(hub), new SpringMvcTransactionNameProvider()); + public SentrySpringFilter(final @NotNull IScopes scopes) { + this(scopes, new SentryRequestResolver(scopes), new SpringMvcTransactionNameProvider()); } public SentrySpringFilter() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } @Override @@ -57,20 +57,20 @@ protected void doFilterInternal( final @NotNull HttpServletResponse response, final @NotNull FilterChain filterChain) throws ServletException, IOException { - if (hub.isEnabled()) { + if (scopes.isEnabled()) { // request may qualify for caching request body, if so resolve cached request final HttpServletRequest request = resolveHttpServletRequest(servletRequest); - hub.pushScope(); + scopes.pushScope(); try { final Hint hint = new Hint(); hint.set(SPRING_REQUEST_FILTER_REQUEST, servletRequest); hint.set(SPRING_REQUEST_FILTER_RESPONSE, response); - hub.addBreadcrumb(Breadcrumb.http(request.getRequestURI(), request.getMethod()), hint); + scopes.addBreadcrumb(Breadcrumb.http(request.getRequestURI(), request.getMethod()), hint); configureScope(request); filterChain.doFilter(request, response); } finally { - hub.popScope(); + scopes.popScope(); } } else { filterChain.doFilter(servletRequest, response); @@ -79,7 +79,7 @@ protected void doFilterInternal( private void configureScope(HttpServletRequest request) { try { - hub.configureScope( + scopes.configureScope( scope -> { // set basic request information on the scope scope.setRequest(requestResolver.resolveSentryRequest(request)); @@ -92,11 +92,12 @@ private void configureScope(HttpServletRequest request) { // request processing if (request instanceof CachedBodyHttpServletRequest) { scope.addEventProcessor( - new RequestBodyExtractingEventProcessor(request, hub.getOptions())); + new RequestBodyExtractingEventProcessor(request, scopes.getOptions())); } }); } catch (Throwable e) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log(SentryLevel.ERROR, "Failed to set scope for HTTP request", e); } @@ -104,12 +105,13 @@ private void configureScope(HttpServletRequest request) { private @NotNull HttpServletRequest resolveHttpServletRequest( final @NotNull HttpServletRequest request) { - if (hub.getOptions().isSendDefaultPii() - && qualifiesForCaching(request, hub.getOptions().getMaxRequestBodySize())) { + if (scopes.getOptions().isSendDefaultPii() + && qualifiesForCaching(request, scopes.getOptions().getMaxRequestBodySize())) { try { return new CachedBodyHttpServletRequest(request); } catch (IOException e) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.WARNING, diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryTaskDecorator.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryTaskDecorator.java index 5c4f37e521..c99abf3e21 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryTaskDecorator.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryTaskDecorator.java @@ -1,6 +1,6 @@ package io.sentry.spring.jakarta; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.Sentry; import java.util.concurrent.Callable; import org.jetbrains.annotations.NotNull; @@ -8,22 +8,24 @@ import org.springframework.scheduling.annotation.Async; /** - * Sets a current hub on a thread running a {@link Runnable} given by parameter. Used to propagate - * the current {@link IHub} on the thread executing async task - like MVC controller methods - * returning a {@link Callable} or Spring beans methods annotated with {@link Async}. + * Sets a current scopes on a thread running a {@link Runnable} given by parameter. Used to + * propagate the current {@link IScopes} on the thread executing async task - like MVC controller + * methods returning a {@link Callable} or Spring beans methods annotated with {@link Async}. */ public final class SentryTaskDecorator implements TaskDecorator { @Override + @SuppressWarnings("deprecation") public @NotNull Runnable decorate(final @NotNull Runnable runnable) { - final IHub newHub = Sentry.getCurrentHub().clone(); + // TODO fork + final IScopes newHub = Sentry.getCurrentScopes().clone(); return () -> { - final IHub oldState = Sentry.getCurrentHub(); - Sentry.setCurrentHub(newHub); + final IScopes oldState = Sentry.getCurrentScopes(); + Sentry.setCurrentScopes(newHub); try { runnable.run(); } finally { - Sentry.setCurrentHub(oldState); + Sentry.setCurrentScopes(oldState); } }; } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryUserFilter.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryUserFilter.java index f7b8bc62d6..31cc73a346 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryUserFilter.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryUserFilter.java @@ -1,8 +1,8 @@ package io.sentry.spring.jakarta; import com.jakewharton.nopen.annotation.Open; -import io.sentry.IHub; import io.sentry.IScope; +import io.sentry.IScopes; import io.sentry.IpAddressUtils; import io.sentry.protocol.User; import io.sentry.util.Objects; @@ -26,12 +26,12 @@ */ @Open public class SentryUserFilter extends OncePerRequestFilter { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @NotNull List sentryUserProviders; public SentryUserFilter( - final @NotNull IHub hub, final @NotNull List sentryUserProviders) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + final @NotNull IScopes scopes, final @NotNull List sentryUserProviders) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); this.sentryUserProviders = Objects.requireNonNull(sentryUserProviders, "sentryUserProviders list is required"); } @@ -46,13 +46,13 @@ protected void doFilterInternal( for (final SentryUserProvider provider : sentryUserProviders) { apply(user, provider.provideUser()); } - if (hub.getOptions().isSendDefaultPii()) { + if (scopes.getOptions().isSendDefaultPii()) { if (IpAddressUtils.isDefault(user.getIpAddress())) { // unset {{auto}} as it would set the server's ip address as a user ip address user.setIpAddress(null); } } - hub.setUser(user); + scopes.setUser(user); chain.doFilter(request, response); } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/checkin/SentryCheckInAdvice.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/checkin/SentryCheckInAdvice.java index 5a4e329fa8..4a366a8b01 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/checkin/SentryCheckInAdvice.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/checkin/SentryCheckInAdvice.java @@ -4,8 +4,8 @@ import io.sentry.CheckIn; import io.sentry.CheckInStatus; import io.sentry.DateUtils; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; +import io.sentry.ScopesAdapter; import io.sentry.SentryLevel; import io.sentry.protocol.SentryId; import io.sentry.util.Objects; @@ -30,16 +30,16 @@ @ApiStatus.Experimental @Open public class SentryCheckInAdvice implements MethodInterceptor, EmbeddedValueResolverAware { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private @Nullable StringValueResolver resolver; public SentryCheckInAdvice() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } - public SentryCheckInAdvice(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentryCheckInAdvice(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } @Override @@ -66,7 +66,8 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl // expressions. Testing shows this can also happen if properties cannot be resolved (without // an exception being thrown). Sentry should alert the user about missed checkins in this // case since the monitor slug won't match what is configured in Sentry. - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.WARNING, @@ -76,7 +77,8 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl } if (ObjectUtils.isEmpty(monitorSlug)) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.WARNING, @@ -84,8 +86,8 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl return invocation.proceed(); } - hub.pushScope(); - TracingUtils.startNewTrace(hub); + scopes.pushScope(); + TracingUtils.startNewTrace(scopes); @Nullable SentryId checkInId = null; final long startTime = System.currentTimeMillis(); @@ -93,7 +95,7 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl try { if (!isHeartbeatOnly) { - checkInId = hub.captureCheckIn(new CheckIn(monitorSlug, CheckInStatus.IN_PROGRESS)); + checkInId = scopes.captureCheckIn(new CheckIn(monitorSlug, CheckInStatus.IN_PROGRESS)); } return invocation.proceed(); } catch (Throwable e) { @@ -103,8 +105,8 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl final @NotNull CheckInStatus status = didError ? CheckInStatus.ERROR : CheckInStatus.OK; CheckIn checkIn = new CheckIn(checkInId, monitorSlug, status); checkIn.setDuration(DateUtils.millisToSeconds(System.currentTimeMillis() - startTime)); - hub.captureCheckIn(checkIn); - hub.popScope(); + scopes.captureCheckIn(checkIn); + scopes.popScope(); } } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/exception/SentryCaptureExceptionParameterAdvice.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/exception/SentryCaptureExceptionParameterAdvice.java index f989382045..c6537f853c 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/exception/SentryCaptureExceptionParameterAdvice.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/exception/SentryCaptureExceptionParameterAdvice.java @@ -1,8 +1,8 @@ package io.sentry.spring.jakarta.exception; import com.jakewharton.nopen.annotation.Open; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; +import io.sentry.ScopesAdapter; import io.sentry.exception.ExceptionMechanismException; import io.sentry.protocol.Mechanism; import io.sentry.util.Objects; @@ -22,14 +22,14 @@ @Open public class SentryCaptureExceptionParameterAdvice implements MethodInterceptor { private static final String MECHANISM_TYPE = "SentrySpring6CaptureExceptionParameterAdvice"; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; public SentryCaptureExceptionParameterAdvice() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } - public SentryCaptureExceptionParameterAdvice(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentryCaptureExceptionParameterAdvice(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } @Override @@ -58,6 +58,6 @@ private void captureException(final @NotNull Throwable throwable) { mechanism.setHandled(true); final Throwable mechanismException = new ExceptionMechanismException(mechanism, throwable, Thread.currentThread()); - hub.captureException(mechanismException); + scopes.captureException(mechanismException); } } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/graphql/SentryBatchLoaderRegistry.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/graphql/SentryBatchLoaderRegistry.java index 1d5576c596..3e2223b694 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/graphql/SentryBatchLoaderRegistry.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/graphql/SentryBatchLoaderRegistry.java @@ -1,11 +1,11 @@ package io.sentry.spring.jakarta.graphql; -import static io.sentry.graphql.SentryInstrumentation.SENTRY_HUB_CONTEXT_KEY; +import static io.sentry.graphql.SentryInstrumentation.SENTRY_SCOPES_CONTEXT_KEY; import graphql.GraphQLContext; import io.sentry.Breadcrumb; -import io.sentry.IHub; -import io.sentry.NoOpHub; +import io.sentry.IScopes; +import io.sentry.NoOpScopes; import java.util.List; import java.util.Map; import java.util.Set; @@ -89,7 +89,7 @@ public BatchLoaderRegistry.RegistrationSpec withOptions(DataLoaderOptions public void registerBatchLoader(BiFunction, BatchLoaderEnvironment, Flux> loader) { delegate.registerBatchLoader( (keys, batchLoaderEnvironment) -> { - hubFromContext(batchLoaderEnvironment) + scopesFromContext(batchLoaderEnvironment) .addBreadcrumb(Breadcrumb.graphqlDataLoader(keys, keyType, valueType, name)); return loader.apply(keys, batchLoaderEnvironment); }); @@ -100,20 +100,20 @@ public void registerMappedBatchLoader( BiFunction, BatchLoaderEnvironment, Mono>> loader) { delegate.registerMappedBatchLoader( (keys, batchLoaderEnvironment) -> { - hubFromContext(batchLoaderEnvironment) + scopesFromContext(batchLoaderEnvironment) .addBreadcrumb(Breadcrumb.graphqlDataLoader(keys, keyType, valueType, name)); return loader.apply(keys, batchLoaderEnvironment); }); } - private @NotNull IHub hubFromContext(final @NotNull BatchLoaderEnvironment environment) { + private @NotNull IScopes scopesFromContext(final @NotNull BatchLoaderEnvironment environment) { Object context = environment.getContext(); if (context instanceof GraphQLContext) { GraphQLContext graphqlContext = (GraphQLContext) context; - return graphqlContext.getOrDefault(SENTRY_HUB_CONTEXT_KEY, NoOpHub.getInstance()); + return graphqlContext.getOrDefault(SENTRY_SCOPES_CONTEXT_KEY, NoOpScopes.getInstance()); } - return NoOpHub.getInstance(); + return NoOpScopes.getInstance(); } } } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/graphql/SentryDgsSubscriptionHandler.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/graphql/SentryDgsSubscriptionHandler.java index 83a090954d..a7a6cccd3e 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/graphql/SentryDgsSubscriptionHandler.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/graphql/SentryDgsSubscriptionHandler.java @@ -1,7 +1,7 @@ package io.sentry.spring.jakarta.graphql; import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.SentryIntegrationPackageStorage; import io.sentry.graphql.ExceptionReporter; import io.sentry.graphql.SentrySubscriptionHandler; @@ -17,7 +17,7 @@ public SentryDgsSubscriptionHandler() { @Override public @NotNull Object onSubscriptionResult( final @NotNull Object result, - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull ExceptionReporter exceptionReporter, final @NotNull InstrumentationFieldFetchParameters parameters) { if (result instanceof Flux) { @@ -25,7 +25,7 @@ public SentryDgsSubscriptionHandler() { return flux.doOnError( throwable -> { final @NotNull ExceptionReporter.ExceptionDetails exceptionDetails = - new ExceptionReporter.ExceptionDetails(hub, parameters.getEnvironment(), true); + new ExceptionReporter.ExceptionDetails(scopes, parameters.getEnvironment(), true); exceptionReporter.captureThrowable(throwable, exceptionDetails, null); }); } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/graphql/SentrySpringSubscriptionHandler.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/graphql/SentrySpringSubscriptionHandler.java index 4c51981035..eec86f5e8b 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/graphql/SentrySpringSubscriptionHandler.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/graphql/SentrySpringSubscriptionHandler.java @@ -1,7 +1,7 @@ package io.sentry.spring.jakarta.graphql; import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.graphql.ExceptionReporter; import io.sentry.graphql.SentrySubscriptionHandler; import org.jetbrains.annotations.NotNull; @@ -13,7 +13,7 @@ public final class SentrySpringSubscriptionHandler implements SentrySubscription @Override public @NotNull Object onSubscriptionResult( final @NotNull Object result, - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull ExceptionReporter exceptionReporter, final @NotNull InstrumentationFieldFetchParameters parameters) { if (result instanceof Flux) { @@ -21,7 +21,7 @@ public final class SentrySpringSubscriptionHandler implements SentrySubscription return flux.doOnError( throwable -> { final @NotNull ExceptionReporter.ExceptionDetails exceptionDetails = - new ExceptionReporter.ExceptionDetails(hub, parameters.getEnvironment(), true); + new ExceptionReporter.ExceptionDetails(scopes, parameters.getEnvironment(), true); if (throwable instanceof SubscriptionPublisherException && throwable.getCause() != null) { exceptionReporter.captureThrowable(throwable.getCause(), exceptionDetails, null); diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentrySpanAdvice.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentrySpanAdvice.java index 5f345a4e02..e8de36487f 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentrySpanAdvice.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentrySpanAdvice.java @@ -1,9 +1,9 @@ package io.sentry.spring.jakarta.tracing; import com.jakewharton.nopen.annotation.Open; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ISpan; +import io.sentry.ScopesAdapter; import io.sentry.SpanStatus; import io.sentry.util.Objects; import java.lang.reflect.Method; @@ -22,20 +22,20 @@ @Open public class SentrySpanAdvice implements MethodInterceptor { private static final String TRACE_ORIGIN = "auto.function.spring_jakarta.advice"; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; public SentrySpanAdvice() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } - public SentrySpanAdvice(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentrySpanAdvice(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } @SuppressWarnings("deprecation") @Override public Object invoke(final @NotNull MethodInvocation invocation) throws Throwable { - final ISpan activeSpan = hub.getSpan(); + final ISpan activeSpan = scopes.getSpan(); if (activeSpan == null || activeSpan.isNoOp()) { // there is no active transaction, we do not start new span diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentrySpanClientHttpRequestInterceptor.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentrySpanClientHttpRequestInterceptor.java index 59c1926ff3..7a787fb29d 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentrySpanClientHttpRequestInterceptor.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentrySpanClientHttpRequestInterceptor.java @@ -8,7 +8,7 @@ import io.sentry.BaggageHeader; import io.sentry.Breadcrumb; import io.sentry.Hint; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ISpan; import io.sentry.SpanDataConvention; import io.sentry.SpanStatus; @@ -28,16 +28,16 @@ public class SentrySpanClientHttpRequestInterceptor implements ClientHttpRequestInterceptor { private static final String TRACE_ORIGIN_REST_TEMPLATE = "auto.http.spring_jakarta.resttemplate"; private static final String TRACE_ORIGIN_REST_CLIENT = "auto.http.spring_jakarta.restclient"; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @NotNull String traceOrigin; - public SentrySpanClientHttpRequestInterceptor(final @NotNull IHub hub) { - this(hub, true); + public SentrySpanClientHttpRequestInterceptor(final @NotNull IScopes scopes) { + this(scopes, true); } public SentrySpanClientHttpRequestInterceptor( - final @NotNull IHub hub, final @NotNull boolean isRestTemplate) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + final @NotNull IScopes scopes, final @NotNull boolean isRestTemplate) { + this.scopes = Objects.requireNonNull(scopes, "Scopes are required"); this.traceOrigin = isRestTemplate ? TRACE_ORIGIN_REST_TEMPLATE : TRACE_ORIGIN_REST_CLIENT; } @@ -50,7 +50,7 @@ public SentrySpanClientHttpRequestInterceptor( Integer responseStatusCode = null; ClientHttpResponse response = null; try { - final ISpan activeSpan = hub.getSpan(); + final ISpan activeSpan = scopes.getSpan(); if (activeSpan == null) { maybeAddTracingHeaders(request, null); return execution.execute(request, body); @@ -91,7 +91,7 @@ private void maybeAddTracingHeaders( final @NotNull HttpRequest request, final @Nullable ISpan span) { final @Nullable TracingUtils.TracingHeaders tracingHeaders = TracingUtils.traceIfAllowed( - hub, + scopes, request.getURI().toString(), request.getHeaders().get(BaggageHeader.BAGGAGE_HEADER), span); @@ -128,6 +128,6 @@ private void addBreadcrumb( hint.set(SPRING_REQUEST_INTERCEPTOR_RESPONSE, response); } - hub.addBreadcrumb(breadcrumb, hint); + scopes.addBreadcrumb(breadcrumb, hint); } } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentrySpanClientWebRequestFilter.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentrySpanClientWebRequestFilter.java index 4ac511721e..bc5c0edfab 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentrySpanClientWebRequestFilter.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentrySpanClientWebRequestFilter.java @@ -7,7 +7,7 @@ import io.sentry.BaggageHeader; import io.sentry.Breadcrumb; import io.sentry.Hint; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ISpan; import io.sentry.SpanDataConvention; import io.sentry.SpanStatus; @@ -25,16 +25,16 @@ @Open public class SentrySpanClientWebRequestFilter implements ExchangeFilterFunction { private static final String TRACE_ORIGIN = "auto.http.spring_jakarta.webclient"; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; - public SentrySpanClientWebRequestFilter(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentrySpanClientWebRequestFilter(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "Scopes are required"); } @Override public @NotNull Mono filter( final @NotNull ClientRequest request, final @NotNull ExchangeFunction next) { - final ISpan activeSpan = hub.getSpan(); + final ISpan activeSpan = scopes.getSpan(); if (activeSpan == null) { final @NotNull ClientRequest modifiedRequest = maybeAddTracingHeaders(request, null); addBreadcrumb(modifiedRequest, null); @@ -74,7 +74,7 @@ public SentrySpanClientWebRequestFilter(final @NotNull IHub hub) { final @Nullable TracingUtils.TracingHeaders tracingHeaders = TracingUtils.traceIfAllowed( - hub, + scopes, request.url().toString(), request.headers().get(BaggageHeader.BAGGAGE_HEADER), span); @@ -111,6 +111,6 @@ private void addBreadcrumb( hint.set(SPRING_EXCHANGE_FILTER_RESPONSE, response); } - hub.addBreadcrumb(breadcrumb, hint); + scopes.addBreadcrumb(breadcrumb, hint); } } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentryTracingFilter.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentryTracingFilter.java index ed91f85a29..097528ac44 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentryTracingFilter.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentryTracingFilter.java @@ -3,9 +3,9 @@ import com.jakewharton.nopen.annotation.Open; import io.sentry.BaggageHeader; import io.sentry.CustomSamplingContext; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ITransaction; +import io.sentry.ScopesAdapter; import io.sentry.SentryTraceHeader; import io.sentry.SpanStatus; import io.sentry.TransactionContext; @@ -38,7 +38,7 @@ public class SentryTracingFilter extends OncePerRequestFilter { private static final String TRACE_ORIGIN = "auto.http.spring_jakarta.webmvc"; private final @NotNull TransactionNameProvider transactionNameProvider; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; /** * Creates filter that resolves transaction name using {@link SpringMvcTransactionNameProvider}. @@ -49,25 +49,26 @@ public class SentryTracingFilter extends OncePerRequestFilter { * jakarta.servlet.Filter}. */ public SentryTracingFilter() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } /** * Creates filter that resolves transaction name using transaction name provider given by * parameter. * - * @param hub - the hub + * @param scopes - the scopes * @param transactionNameProvider - transaction name provider. */ public SentryTracingFilter( - final @NotNull IHub hub, final @NotNull TransactionNameProvider transactionNameProvider) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + final @NotNull IScopes scopes, + final @NotNull TransactionNameProvider transactionNameProvider) { + this.scopes = Objects.requireNonNull(scopes, "Scopes are required"); this.transactionNameProvider = Objects.requireNonNull(transactionNameProvider, "transactionNameProvider is required"); } - public SentryTracingFilter(final @NotNull IHub hub) { - this(hub, new SpringMvcTransactionNameProvider()); + public SentryTracingFilter(final @NotNull IScopes scopes) { + this(scopes, new SpringMvcTransactionNameProvider()); } @Override @@ -76,14 +77,14 @@ protected void doFilterInternal( final @NotNull HttpServletResponse httpResponse, final @NotNull FilterChain filterChain) throws ServletException, IOException { - if (hub.isEnabled()) { + if (scopes.isEnabled()) { final @Nullable String sentryTraceHeader = httpRequest.getHeader(SentryTraceHeader.SENTRY_TRACE_HEADER); final @Nullable List baggageHeader = Collections.list(httpRequest.getHeaders(BaggageHeader.BAGGAGE_HEADER)); final @Nullable TransactionContext transactionContext = - hub.continueTrace(sentryTraceHeader, baggageHeader); - if (hub.getOptions().isTracingEnabled() && shouldTraceRequest(httpRequest)) { + scopes.continueTrace(sentryTraceHeader, baggageHeader); + if (scopes.getOptions().isTracingEnabled() && shouldTraceRequest(httpRequest)) { doFilterWithTransaction(httpRequest, httpResponse, filterChain, transactionContext); } else { filterChain.doFilter(httpRequest, httpResponse); @@ -130,7 +131,7 @@ private void doFilterWithTransaction( } private boolean shouldTraceRequest(final @NotNull HttpServletRequest request) { - return hub.getOptions().isTraceOptionsRequests() + return scopes.getOptions().isTraceOptionsRequests() || !HttpMethod.OPTIONS.name().equals(request.getMethod()); } @@ -152,14 +153,14 @@ private ITransaction startTransaction( transactionOptions.setCustomSamplingContext(customSamplingContext); transactionOptions.setBindToScope(true); - return hub.startTransaction(transactionContext, transactionOptions); + return scopes.startTransaction(transactionContext, transactionOptions); } final TransactionOptions transactionOptions = new TransactionOptions(); transactionOptions.setCustomSamplingContext(customSamplingContext); transactionOptions.setBindToScope(true); - return hub.startTransaction( + return scopes.startTransaction( new TransactionContext(name, TransactionNameSource.URL, "http.server"), transactionOptions); } } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentryTransactionAdvice.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentryTransactionAdvice.java index 5b264defa4..f04b3dd7a6 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentryTransactionAdvice.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentryTransactionAdvice.java @@ -1,9 +1,9 @@ package io.sentry.spring.jakarta.tracing; import com.jakewharton.nopen.annotation.Open; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ITransaction; +import io.sentry.ScopesAdapter; import io.sentry.SpanStatus; import io.sentry.TransactionContext; import io.sentry.TransactionOptions; @@ -28,14 +28,14 @@ public class SentryTransactionAdvice implements MethodInterceptor { private static final String TRACE_ORIGIN = "auto.function.spring_jakarta.advice"; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; public SentryTransactionAdvice() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } - public SentryTransactionAdvice(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentryTransactionAdvice(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } @SuppressWarnings("deprecation") @@ -68,11 +68,11 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl } else { operation = "bean"; } - hub.pushScope(); + scopes.pushScope(); final TransactionOptions transactionOptions = new TransactionOptions(); transactionOptions.setBindToScope(true); final ITransaction transaction = - hub.startTransaction( + scopes.startTransaction( new TransactionContext(nameAndSource.name, nameAndSource.source, operation), transactionOptions); transaction.getSpanContext().setOrigin(TRACE_ORIGIN); @@ -86,7 +86,7 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl throw e; } finally { transaction.finish(); - hub.popScope(); + scopes.popScope(); } } } @@ -106,7 +106,7 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl } private boolean isTransactionActive() { - return hub.getSpan() != null; + return scopes.getSpan() != null; } private static class TransactionNameAndSource { diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/AbstractSentryWebFilter.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/AbstractSentryWebFilter.java index bf25aa5f49..3321874dd8 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/AbstractSentryWebFilter.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/AbstractSentryWebFilter.java @@ -7,10 +7,10 @@ import io.sentry.Breadcrumb; import io.sentry.CustomSamplingContext; import io.sentry.Hint; -import io.sentry.IHub; import io.sentry.IScope; +import io.sentry.IScopes; import io.sentry.ITransaction; -import io.sentry.NoOpHub; +import io.sentry.NoOpScopes; import io.sentry.Sentry; import io.sentry.SentryTraceHeader; import io.sentry.SpanStatus; @@ -34,16 +34,17 @@ @ApiStatus.Experimental public abstract class AbstractSentryWebFilter implements WebFilter { private final @NotNull SentryRequestResolver sentryRequestResolver; - public static final String SENTRY_HUB_KEY = "sentry-hub"; + public static final String SENTRY_SCOPES_KEY = "sentry-scopes"; + @Deprecated public static final String SENTRY_HUB_KEY = SENTRY_SCOPES_KEY; private static final String TRANSACTION_OP = "http.server"; - public AbstractSentryWebFilter(final @NotNull IHub hub) { - Objects.requireNonNull(hub, "hub is required"); - this.sentryRequestResolver = new SentryRequestResolver(hub); + public AbstractSentryWebFilter(final @NotNull IScopes scopes) { + Objects.requireNonNull(scopes, "scopes are required"); + this.sentryRequestResolver = new SentryRequestResolver(scopes); } protected @Nullable ITransaction maybeStartTransaction( - final @NotNull IHub requestHub, final @NotNull ServerHttpRequest request) { + final @NotNull IScopes requestHub, final @NotNull ServerHttpRequest request) { if (requestHub.isEnabled()) { final @NotNull HttpHeaders headers = request.getHeaders(); final @Nullable String sentryTraceHeader = @@ -62,21 +63,23 @@ public AbstractSentryWebFilter(final @NotNull IHub hub) { protected void doFinally( final @NotNull ServerWebExchange serverWebExchange, - final @NotNull IHub requestHub, + final @NotNull IScopes requestHub, final @Nullable ITransaction transaction) { if (transaction != null) { finishTransaction(serverWebExchange, transaction); } if (requestHub.isEnabled()) { + // TODO close lifecycle token instead of popscope requestHub.popScope(); } - Sentry.setCurrentHub(NoOpHub.getInstance()); + Sentry.setCurrentScopes(NoOpScopes.getInstance()); } protected void doFirst( - final @NotNull ServerWebExchange serverWebExchange, final @NotNull IHub requestHub) { + final @NotNull ServerWebExchange serverWebExchange, final @NotNull IScopes requestHub) { if (requestHub.isEnabled()) { - serverWebExchange.getAttributes().put(SENTRY_HUB_KEY, requestHub); + serverWebExchange.getAttributes().put(SENTRY_SCOPES_KEY, requestHub); + // TODO fork instead requestHub.pushScope(); final ServerHttpRequest request = serverWebExchange.getRequest(); final ServerHttpResponse response = serverWebExchange.getResponse(); @@ -100,8 +103,8 @@ protected void doOnError(final @Nullable ITransaction transaction, final @NotNul } protected boolean shouldTraceRequest( - final @NotNull IHub hub, final @NotNull ServerHttpRequest request) { - return hub.getOptions().isTraceOptionsRequests() + final @NotNull IScopes scopes, final @NotNull ServerHttpRequest request) { + return scopes.getOptions().isTraceOptionsRequests() || !HttpMethod.OPTIONS.equals(request.getMethod()); } @@ -130,7 +133,7 @@ private void finishTransaction(ServerWebExchange exchange, ITransaction transact } protected @NotNull ITransaction startTransaction( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull ServerHttpRequest request, final @Nullable TransactionContext transactionContext) { final @NotNull String name = request.getMethod() + " " + request.getURI().getPath(); @@ -146,10 +149,10 @@ private void finishTransaction(ServerWebExchange exchange, ITransaction transact transactionContext.setTransactionNameSource(TransactionNameSource.URL); transactionContext.setOperation(TRANSACTION_OP); - return hub.startTransaction(transactionContext, transactionOptions); + return scopes.startTransaction(transactionContext, transactionOptions); } - return hub.startTransaction( + return scopes.startTransaction( new TransactionContext(name, TransactionNameSource.URL, TRANSACTION_OP), transactionOptions); } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/ReactorUtils.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/ReactorUtils.java index 4af641af29..41dd2e4bc0 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/ReactorUtils.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/ReactorUtils.java @@ -1,6 +1,6 @@ package io.sentry.spring.jakarta.webflux; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.Sentry; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; @@ -8,11 +8,12 @@ import reactor.core.publisher.Mono; import reactor.util.context.Context; +// TODO deprecate and replace with "withSentryScopes" etc. @ApiStatus.Experimental public final class ReactorUtils { /** - * Writes the current Sentry {@link IHub} to the {@link Context} and uses {@link + * Writes the current Sentry {@link IScopes} to the {@link Context} and uses {@link * io.micrometer.context.ThreadLocalAccessor} to propagate it. * *

This requires - reactor.core.publisher.Hooks#enableAutomaticContextPropagation() to be @@ -20,14 +21,16 @@ public final class ReactorUtils { * having `io.projectreactor:reactor-core:3.5.3+` (provided by Spring Boot 3.0.3+) */ @ApiStatus.Experimental + @SuppressWarnings("deprecation") public static Mono withSentry(final @NotNull Mono mono) { - final @NotNull IHub oldHub = Sentry.getCurrentHub(); - final @NotNull IHub clonedHub = oldHub.clone(); + final @NotNull IScopes oldHub = Sentry.getCurrentScopes(); + // TODO fork + final @NotNull IScopes clonedHub = oldHub.clone(); return withSentryHub(mono, clonedHub); } /** - * Writes a new Sentry {@link IHub} cloned from the main hub to the {@link Context} and uses + * Writes a new Sentry {@link IScopes} cloned from the main hub to the {@link Context} and uses * {@link io.micrometer.context.ThreadLocalAccessor} to propagate it. * *

This requires - reactor.core.publisher.Hooks#enableAutomaticContextPropagation() to be @@ -36,12 +39,12 @@ public static Mono withSentry(final @NotNull Mono mono) { */ @ApiStatus.Experimental public static Mono withSentryNewMainHubClone(final @NotNull Mono mono) { - final @NotNull IHub hub = Sentry.cloneMainHub(); + final @NotNull IScopes hub = Sentry.cloneMainHub(); return withSentryHub(mono, hub); } /** - * Writes the given Sentry {@link IHub} to the {@link Context} and uses {@link + * Writes the given Sentry {@link IScopes} to the {@link Context} and uses {@link * io.micrometer.context.ThreadLocalAccessor} to propagate it. * *

This requires - reactor.core.publisher.Hooks#enableAutomaticContextPropagation() to be @@ -49,7 +52,7 @@ public static Mono withSentryNewMainHubClone(final @NotNull Mono mono) * having `io.projectreactor:reactor-core:3.5.3+` (provided by Spring Boot 3.0.3+) */ @ApiStatus.Experimental - public static Mono withSentryHub(final @NotNull Mono mono, final @NotNull IHub hub) { + public static Mono withSentryHub(final @NotNull Mono mono, final @NotNull IScopes hub) { /** * WARNING: Cannot set the hub as current. It would be used by others to clone again causing * shared hubs and scopes and thus leading to issues like unrelated breadcrumbs showing up in @@ -62,7 +65,7 @@ public static Mono withSentryHub(final @NotNull Mono mono, final @NotN } /** - * Writes the current Sentry {@link IHub} to the {@link Context} and uses {@link + * Writes the current Sentry {@link IScopes} to the {@link Context} and uses {@link * io.micrometer.context.ThreadLocalAccessor} to propagate it. * *

This requires - reactor.core.publisher.Hooks#enableAutomaticContextPropagation() to be @@ -70,15 +73,17 @@ public static Mono withSentryHub(final @NotNull Mono mono, final @NotN * having `io.projectreactor:reactor-core:3.5.3+` (provided by Spring Boot 3.0.3+) */ @ApiStatus.Experimental + @SuppressWarnings("deprecation") public static Flux withSentry(final @NotNull Flux flux) { - final @NotNull IHub oldHub = Sentry.getCurrentHub(); - final @NotNull IHub clonedHub = oldHub.clone(); + final @NotNull IScopes oldHub = Sentry.getCurrentScopes(); + // TODO fork + final @NotNull IScopes clonedHub = oldHub.clone(); return withSentryHub(flux, clonedHub); } /** - * Writes a new Sentry {@link IHub} cloned from the main hub to the {@link Context} and uses + * Writes a new Sentry {@link IScopes} cloned from the main hub to the {@link Context} and uses * {@link io.micrometer.context.ThreadLocalAccessor} to propagate it. * *

This requires - reactor.core.publisher.Hooks#enableAutomaticContextPropagation() to be @@ -87,12 +92,12 @@ public static Flux withSentry(final @NotNull Flux flux) { */ @ApiStatus.Experimental public static Flux withSentryNewMainHubClone(final @NotNull Flux flux) { - final @NotNull IHub hub = Sentry.cloneMainHub(); + final @NotNull IScopes hub = Sentry.cloneMainHub(); return withSentryHub(flux, hub); } /** - * Writes the given Sentry {@link IHub} to the {@link Context} and uses {@link + * Writes the given Sentry {@link IScopes} to the {@link Context} and uses {@link * io.micrometer.context.ThreadLocalAccessor} to propagate it. * *

This requires - reactor.core.publisher.Hooks#enableAutomaticContextPropagation() to be @@ -100,7 +105,7 @@ public static Flux withSentryNewMainHubClone(final @NotNull Flux flux) * having `io.projectreactor:reactor-core:3.5.3+` (provided by Spring Boot 3.0.3+) */ @ApiStatus.Experimental - public static Flux withSentryHub(final @NotNull Flux flux, final @NotNull IHub hub) { + public static Flux withSentryHub(final @NotNull Flux flux, final @NotNull IScopes hub) { /** * WARNING: Cannot set the hub as current. It would be used by others to clone again causing * shared hubs and scopes and thus leading to issues like unrelated breadcrumbs showing up in diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryReactorThreadLocalAccessor.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryReactorThreadLocalAccessor.java index c64cf3d634..9b7e51db73 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryReactorThreadLocalAccessor.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryReactorThreadLocalAccessor.java @@ -1,15 +1,15 @@ package io.sentry.spring.jakarta.webflux; import io.micrometer.context.ThreadLocalAccessor; -import io.sentry.IHub; -import io.sentry.NoOpHub; +import io.sentry.IScopes; +import io.sentry.NoOpScopes; import io.sentry.Sentry; import org.jetbrains.annotations.ApiStatus; @ApiStatus.Experimental -public final class SentryReactorThreadLocalAccessor implements ThreadLocalAccessor { +public final class SentryReactorThreadLocalAccessor implements ThreadLocalAccessor { - public static final String KEY = "sentry-hub"; + public static final String KEY = "sentry-scopes"; @Override public Object key() { @@ -17,18 +17,18 @@ public Object key() { } @Override - public IHub getValue() { - return Sentry.getCurrentHub(); + public IScopes getValue() { + return Sentry.getCurrentScopes(); } @Override - public void setValue(IHub value) { - Sentry.setCurrentHub(value); + public void setValue(IScopes value) { + Sentry.setCurrentScopes(value); } @Override @SuppressWarnings("deprecation") public void reset() { - Sentry.setCurrentHub(NoOpHub.getInstance()); + Sentry.setCurrentScopes(NoOpScopes.getInstance()); } } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryRequestResolver.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryRequestResolver.java index 2f41ba93ca..d58291ade6 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryRequestResolver.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryRequestResolver.java @@ -1,7 +1,7 @@ package io.sentry.spring.jakarta.webflux; import com.jakewharton.nopen.annotation.Open; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.protocol.Request; import io.sentry.util.HttpUtils; import io.sentry.util.Objects; @@ -20,10 +20,10 @@ @Open @ApiStatus.Experimental public class SentryRequestResolver { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; - public SentryRequestResolver(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "options is required"); + public SentryRequestResolver(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } public @NotNull Request resolveSentryRequest(final @NotNull ServerHttpRequest httpRequest) { @@ -36,7 +36,7 @@ public SentryRequestResolver(final @NotNull IHub hub) { urlDetails.applyToRequest(sentryRequest); sentryRequest.setHeaders(resolveHeadersMap(httpRequest.getHeaders())); - if (hub.getOptions().isSendDefaultPii()) { + if (scopes.getOptions().isSendDefaultPii()) { String headerName = HttpUtils.COOKIE_HEADER_NAME; sentryRequest.setCookies( toString( @@ -52,7 +52,8 @@ Map resolveHeadersMap(final HttpHeaders request) { for (Map.Entry> entry : request.entrySet()) { // do not copy personal information identifiable headers String headerName = entry.getKey(); - if (hub.getOptions().isSendDefaultPii() || !HttpUtils.containsSensitiveHeader(headerName)) { + if (scopes.getOptions().isSendDefaultPii() + || !HttpUtils.containsSensitiveHeader(headerName)) { headersMap.put( headerName, toString( diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryScheduleHook.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryScheduleHook.java index 2bf27f246d..882a0b268a 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryScheduleHook.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryScheduleHook.java @@ -1,6 +1,6 @@ package io.sentry.spring.jakarta.webflux; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.Sentry; import java.util.function.Function; import org.jetbrains.annotations.ApiStatus; @@ -13,16 +13,18 @@ @ApiStatus.Experimental public final class SentryScheduleHook implements Function { @Override + @SuppressWarnings("deprecation") public Runnable apply(final @NotNull Runnable runnable) { - final IHub newHub = Sentry.getCurrentHub().clone(); + // TODO fork instead + final IScopes newHub = Sentry.getCurrentScopes().clone(); return () -> { - final IHub oldState = Sentry.getCurrentHub(); - Sentry.setCurrentHub(newHub); + final IScopes oldState = Sentry.getCurrentScopes(); + Sentry.setCurrentScopes(newHub); try { runnable.run(); } finally { - Sentry.setCurrentHub(oldState); + Sentry.setCurrentScopes(oldState); } }; } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebExceptionHandler.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebExceptionHandler.java index 24439cd0e9..40b0ed4e87 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebExceptionHandler.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebExceptionHandler.java @@ -5,7 +5,7 @@ import static io.sentry.TypeCheckHint.WEBFLUX_EXCEPTION_HANDLER_RESPONSE; import io.sentry.Hint; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.SentryEvent; import io.sentry.SentryLevel; import io.sentry.exception.ExceptionMechanismException; @@ -27,18 +27,18 @@ @ApiStatus.Experimental public final class SentryWebExceptionHandler implements WebExceptionHandler { public static final String MECHANISM_TYPE = "Spring6WebFluxExceptionResolver"; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; - public SentryWebExceptionHandler(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentryWebExceptionHandler(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } @Override public @NotNull Mono handle( final @NotNull ServerWebExchange serverWebExchange, final @NotNull Throwable ex) { - final @Nullable IHub requestHub = - serverWebExchange.getAttributeOrDefault(SentryWebFilter.SENTRY_HUB_KEY, null); - final @NotNull IHub hubToUse = requestHub != null ? requestHub : hub; + final @Nullable IScopes requestScopes = + serverWebExchange.getAttributeOrDefault(SentryWebFilter.SENTRY_SCOPES_KEY, null); + final @NotNull IScopes scopesToUse = requestScopes != null ? requestScopes : scopes; return ReactorUtils.withSentryHub( Mono.just(ex) @@ -61,12 +61,12 @@ public SentryWebExceptionHandler(final @NotNull IHub hub) { WEBFLUX_EXCEPTION_HANDLER_RESPONSE, serverWebExchange.getResponse()); hint.set(WEBFLUX_EXCEPTION_HANDLER_EXCHANGE, serverWebExchange); - hub.captureEvent(event, hint); + scopes.captureEvent(event, hint); } return it; }), - hubToUse) + scopesToUse) .flatMap(it -> Mono.error(ex)); } } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebFilter.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebFilter.java index a57a389499..dab985eecf 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebFilter.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebFilter.java @@ -1,8 +1,8 @@ package io.sentry.spring.jakarta.webflux; import com.jakewharton.nopen.annotation.Open; -import io.sentry.IHub; import io.sentry.IScope; +import io.sentry.IScopes; import io.sentry.ITransaction; import io.sentry.Sentry; import org.jetbrains.annotations.ApiStatus; @@ -20,28 +20,28 @@ public class SentryWebFilter extends AbstractSentryWebFilter { private static final String TRACE_ORIGIN = "auto.spring_jakarta.webflux"; - public SentryWebFilter(final @NotNull IHub hub) { - super(hub); + public SentryWebFilter(final @NotNull IScopes scopes) { + super(scopes); } @Override public Mono filter( final @NotNull ServerWebExchange serverWebExchange, final @NotNull WebFilterChain webFilterChain) { - @NotNull IHub requestHub = Sentry.cloneMainHub(); + @NotNull IScopes requestScopes = Sentry.cloneMainHub(); final ServerHttpRequest request = serverWebExchange.getRequest(); - final @Nullable ITransaction transaction = maybeStartTransaction(requestHub, request); + final @Nullable ITransaction transaction = maybeStartTransaction(requestScopes, request); if (transaction != null) { transaction.getSpanContext().setOrigin(TRACE_ORIGIN); } return webFilterChain .filter(serverWebExchange) - .doFinally(__ -> doFinally(serverWebExchange, requestHub, transaction)) + .doFinally(__ -> doFinally(serverWebExchange, requestScopes, transaction)) .doOnError(e -> doOnError(transaction, e)) .doFirst( () -> { - Sentry.setCurrentHub(requestHub); - doFirst(serverWebExchange, requestHub); + Sentry.setCurrentScopes(requestScopes); + doFirst(serverWebExchange, requestScopes); }); } } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebFilterWithThreadLocalAccessor.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebFilterWithThreadLocalAccessor.java index 278c2b8e7e..e760ef8f3e 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebFilterWithThreadLocalAccessor.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebFilterWithThreadLocalAccessor.java @@ -1,7 +1,7 @@ package io.sentry.spring.jakarta.webflux; -import io.sentry.IHub; import io.sentry.IScope; +import io.sentry.IScopes; import io.sentry.ITransaction; import io.sentry.Sentry; import org.jetbrains.annotations.ApiStatus; @@ -17,8 +17,8 @@ public final class SentryWebFilterWithThreadLocalAccessor extends AbstractSentry public static final String TRACE_ORIGIN = "auto.spring_jakarta.webflux"; - public SentryWebFilterWithThreadLocalAccessor(final @NotNull IHub hub) { - super(hub); + public SentryWebFilterWithThreadLocalAccessor(final @NotNull IScopes scopes) { + super(scopes); } @Override @@ -33,14 +33,15 @@ public Mono filter( __ -> doFinally( serverWebExchange, - Sentry.getCurrentHub(), + Sentry.getCurrentScopes(), transactionContainer.transaction)) .doOnError(e -> doOnError(transactionContainer.transaction, e)) .doFirst( () -> { - doFirst(serverWebExchange, Sentry.getCurrentHub()); + doFirst(serverWebExchange, Sentry.getCurrentScopes()); final ITransaction transaction = - maybeStartTransaction(Sentry.getCurrentHub(), serverWebExchange.getRequest()); + maybeStartTransaction( + Sentry.getCurrentScopes(), serverWebExchange.getRequest()); transactionContainer.transaction = transaction; if (transaction != null) { transaction.getSpanContext().setOrigin(TRACE_ORIGIN); diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/EnableSentryTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/EnableSentryTest.kt index 7b51bbc1e7..37853c3101 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/EnableSentryTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/EnableSentryTest.kt @@ -1,7 +1,7 @@ package io.sentry.spring.jakarta import io.sentry.EventProcessor -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ITransportFactory import io.sentry.Integration import io.sentry.Sentry @@ -67,7 +67,7 @@ class EnableSentryTest { @Test fun `creates Sentry Hub`() { contextRunner.run { - assertThat(it).hasSingleBean(IHub::class.java) + assertThat(it).hasSingleBean(IScopes::class.java) } } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryCheckInAdviceTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryCheckInAdviceTest.kt index 05b97ba24c..5d093f50f1 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryCheckInAdviceTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryCheckInAdviceTest.kt @@ -2,7 +2,7 @@ package io.sentry.spring.jakarta import io.sentry.CheckIn import io.sentry.CheckInStatus -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.Sentry import io.sentry.SentryOptions import io.sentry.protocol.SentryId @@ -54,19 +54,19 @@ class SentryCheckInAdviceTest { lateinit var sampleServiceSpringProperties: SampleServiceSpringProperties @Autowired - lateinit var hub: IHub + lateinit var scopes: IScopes @BeforeTest fun setup() { - reset(hub) - whenever(hub.options).thenReturn(SentryOptions()) + reset(scopes) + whenever(scopes.options).thenReturn(SentryOptions()) } @Test fun `when method is annotated with @SentryCheckIn, every method call creates two check-ins`() { val checkInId = SentryId() val checkInCaptor = argumentCaptor() - whenever(hub.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) + whenever(scopes.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) val result = sampleService.hello() assertEquals(1, result) assertEquals(2, checkInCaptor.allValues.size) @@ -79,17 +79,17 @@ class SentryCheckInAdviceTest { assertEquals("monitor_slug_1", doneCheckIn.monitorSlug) assertEquals(CheckInStatus.OK.apiName(), doneCheckIn.status) - val order = inOrder(hub) - order.verify(hub).pushScope() - order.verify(hub, times(2)).captureCheckIn(any()) - order.verify(hub).popScope() + val order = inOrder(scopes) + order.verify(scopes).pushScope() + order.verify(scopes, times(2)).captureCheckIn(any()) + order.verify(scopes).popScope() } @Test fun `when method is annotated with @SentryCheckIn, every method call creates two check-ins error`() { val checkInId = SentryId() val checkInCaptor = argumentCaptor() - whenever(hub.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) + whenever(scopes.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) assertThrows { sampleService.oops() } @@ -103,17 +103,17 @@ class SentryCheckInAdviceTest { assertEquals("monitor_slug_1e", doneCheckIn.monitorSlug) assertEquals(CheckInStatus.ERROR.apiName(), doneCheckIn.status) - val order = inOrder(hub) - order.verify(hub).pushScope() - order.verify(hub, times(2)).captureCheckIn(any()) - order.verify(hub).popScope() + val order = inOrder(scopes) + order.verify(scopes).pushScope() + order.verify(scopes, times(2)).captureCheckIn(any()) + order.verify(scopes).popScope() } @Test fun `when method is annotated with @SentryCheckIn and heartbeat only, every method call creates only one check-in at the end`() { val checkInId = SentryId() val checkInCaptor = argumentCaptor() - whenever(hub.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) + whenever(scopes.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) val result = sampleServiceHeartbeat.hello() assertEquals(1, result) assertEquals(1, checkInCaptor.allValues.size) @@ -123,17 +123,17 @@ class SentryCheckInAdviceTest { assertEquals(CheckInStatus.OK.apiName(), doneCheckIn.status) assertNotNull(doneCheckIn.duration) - val order = inOrder(hub) - order.verify(hub).pushScope() - order.verify(hub).captureCheckIn(any()) - order.verify(hub).popScope() + val order = inOrder(scopes) + order.verify(scopes).pushScope() + order.verify(scopes).captureCheckIn(any()) + order.verify(scopes).popScope() } @Test fun `when method is annotated with @SentryCheckIn and heartbeat only, every method call creates only one check-in at the end with error`() { val checkInId = SentryId() val checkInCaptor = argumentCaptor() - whenever(hub.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) + whenever(scopes.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) assertThrows { sampleServiceHeartbeat.oops() } @@ -144,31 +144,31 @@ class SentryCheckInAdviceTest { assertEquals(CheckInStatus.ERROR.apiName(), doneCheckIn.status) assertNotNull(doneCheckIn.duration) - val order = inOrder(hub) - order.verify(hub).pushScope() - order.verify(hub).captureCheckIn(any()) - order.verify(hub).popScope() + val order = inOrder(scopes) + order.verify(scopes).pushScope() + order.verify(scopes).captureCheckIn(any()) + order.verify(scopes).popScope() } @Test fun `when method is annotated with @SentryCheckIn but slug is missing, does not create check-in`() { val checkInId = SentryId() val checkInCaptor = argumentCaptor() - whenever(hub.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) + whenever(scopes.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) val result = sampleServiceNoSlug.hello() assertEquals(1, result) assertEquals(0, checkInCaptor.allValues.size) - verify(hub, never()).pushScope() - verify(hub, never()).captureCheckIn(any()) - verify(hub, never()).popScope() + verify(scopes, never()).pushScope() + verify(scopes, never()).captureCheckIn(any()) + verify(scopes, never()).popScope() } @Test fun `when @SentryCheckIn is passed a spring property it is resolved correctly`() { val checkInId = SentryId() val checkInCaptor = argumentCaptor() - whenever(hub.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) + whenever(scopes.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) val result = sampleServiceSpringProperties.hello() assertEquals(1, result) assertEquals(1, checkInCaptor.allValues.size) @@ -178,17 +178,17 @@ class SentryCheckInAdviceTest { assertEquals(CheckInStatus.OK.apiName(), doneCheckIn.status) assertNotNull(doneCheckIn.duration) - val order = inOrder(hub) - order.verify(hub).pushScope() - order.verify(hub).captureCheckIn(any()) - order.verify(hub).popScope() + val order = inOrder(scopes) + order.verify(scopes).pushScope() + order.verify(scopes).captureCheckIn(any()) + order.verify(scopes).popScope() } @Test fun `when @SentryCheckIn is passed a spring property that does not exist, raw value is used`() { val checkInId = SentryId() val checkInCaptor = argumentCaptor() - whenever(hub.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) + whenever(scopes.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) val result = sampleServiceSpringProperties.helloUnresolvedProperty() assertEquals(1, result) assertEquals(1, checkInCaptor.allValues.size) @@ -198,17 +198,17 @@ class SentryCheckInAdviceTest { assertEquals(CheckInStatus.OK.apiName(), doneCheckIn.status) assertNotNull(doneCheckIn.duration) - val order = inOrder(hub) - order.verify(hub).pushScope() - order.verify(hub).captureCheckIn(any()) - order.verify(hub).popScope() + val order = inOrder(scopes) + order.verify(scopes).pushScope() + order.verify(scopes).captureCheckIn(any()) + order.verify(scopes).popScope() } @Test fun `when @SentryCheckIn is passed a spring property that causes an exception, raw value is used`() { val checkInId = SentryId() val checkInCaptor = argumentCaptor() - whenever(hub.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) + whenever(scopes.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) val result = sampleServiceSpringProperties.helloExceptionProperty() assertEquals(1, result) assertEquals(1, checkInCaptor.allValues.size) @@ -218,10 +218,10 @@ class SentryCheckInAdviceTest { assertEquals(CheckInStatus.OK.apiName(), doneCheckIn.status) assertNotNull(doneCheckIn.duration) - val order = inOrder(hub) - order.verify(hub).pushScope() - order.verify(hub).captureCheckIn(any()) - order.verify(hub).popScope() + val order = inOrder(scopes) + order.verify(scopes).pushScope() + order.verify(scopes).captureCheckIn(any()) + order.verify(scopes).popScope() } @Configuration @@ -242,10 +242,10 @@ class SentryCheckInAdviceTest { open fun sampleServiceSpringProperties() = SampleServiceSpringProperties() @Bean - open fun hub(): IHub { - val hub = mock() - Sentry.setCurrentHub(hub) - return hub + open fun scopes(): IScopes { + val scopes = mock() + Sentry.setCurrentScopes(scopes) + return scopes } companion object { diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryExceptionResolverTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryExceptionResolverTest.kt index 797d5aa5ac..431137aabd 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryExceptionResolverTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryExceptionResolverTest.kt @@ -1,7 +1,7 @@ package io.sentry.spring.jakarta import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryEvent import io.sentry.SentryLevel import io.sentry.exception.ExceptionMechanismException @@ -17,7 +17,7 @@ import org.mockito.kotlin.whenever import kotlin.test.Test class SentryExceptionResolverTest { - private val hub = mock() + private val scopes = mock() private val transactionNameProvider = mock() private val request = mock() @@ -26,10 +26,10 @@ class SentryExceptionResolverTest { @Test fun `when handles exception, sets wrapped exception for event`() { val eventCaptor = argumentCaptor() - whenever(hub.captureEvent(eventCaptor.capture(), any())).thenReturn(null) + whenever(scopes.captureEvent(eventCaptor.capture(), any())).thenReturn(null) val expectedCause = RuntimeException("test") - SentryExceptionResolver(hub, transactionNameProvider, 1) + SentryExceptionResolver(scopes, transactionNameProvider, 1) .resolveException(request, response, null, expectedCause) assertThat(eventCaptor.firstValue.throwable).isEqualTo(expectedCause) @@ -46,9 +46,9 @@ class SentryExceptionResolverTest { @Test fun `when handles exception, sets fatal level for event`() { val eventCaptor = argumentCaptor() - whenever(hub.captureEvent(eventCaptor.capture(), any())).thenReturn(null) + whenever(scopes.captureEvent(eventCaptor.capture(), any())).thenReturn(null) - SentryExceptionResolver(hub, transactionNameProvider, 1) + SentryExceptionResolver(scopes, transactionNameProvider, 1) .resolveException(request, response, null, RuntimeException("test")) assertThat(eventCaptor.firstValue.level).isEqualTo(SentryLevel.FATAL) @@ -59,9 +59,9 @@ class SentryExceptionResolverTest { val expectedTransactionName = "test-transaction" whenever(transactionNameProvider.provideTransactionName(any())).thenReturn(expectedTransactionName) val eventCaptor = argumentCaptor() - whenever(hub.captureEvent(eventCaptor.capture(), any())).thenReturn(null) + whenever(scopes.captureEvent(eventCaptor.capture(), any())).thenReturn(null) - SentryExceptionResolver(hub, transactionNameProvider, 1) + SentryExceptionResolver(scopes, transactionNameProvider, 1) .resolveException(request, response, null, RuntimeException("test")) assertThat(eventCaptor.firstValue.transaction).isEqualTo(expectedTransactionName) @@ -71,9 +71,9 @@ class SentryExceptionResolverTest { @Test fun `when handles exception, provides spring resolver hint`() { val hintCaptor = argumentCaptor() - whenever(hub.captureEvent(any(), hintCaptor.capture())).thenReturn(null) + whenever(scopes.captureEvent(any(), hintCaptor.capture())).thenReturn(null) - SentryExceptionResolver(hub, transactionNameProvider, 1) + SentryExceptionResolver(scopes, transactionNameProvider, 1) .resolveException(request, response, null, RuntimeException("test")) with(hintCaptor.firstValue) { @@ -86,8 +86,8 @@ class SentryExceptionResolverTest { fun `when custom create event method provided, uses it to capture event`() { val expectedEvent = SentryEvent() val eventCaptor = argumentCaptor() - whenever(hub.captureEvent(eventCaptor.capture(), any())).thenReturn(null) - val resolver = object : SentryExceptionResolver(hub, transactionNameProvider, 1) { + whenever(scopes.captureEvent(eventCaptor.capture(), any())).thenReturn(null) + val resolver = object : SentryExceptionResolver(scopes, transactionNameProvider, 1) { override fun createEvent(request: HttpServletRequest, ex: Exception) = expectedEvent } @@ -100,8 +100,8 @@ class SentryExceptionResolverTest { fun `when custom create hint method provided, uses it to capture event`() { val expectedHint = Hint() val hintCaptor = argumentCaptor() - whenever(hub.captureEvent(any(), hintCaptor.capture())).thenReturn(null) - val resolver = object : SentryExceptionResolver(hub, transactionNameProvider, 1) { + whenever(scopes.captureEvent(any(), hintCaptor.capture())).thenReturn(null) + val resolver = object : SentryExceptionResolver(scopes, transactionNameProvider, 1) { override fun createHint(request: HttpServletRequest, response: HttpServletResponse) = expectedHint } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryInitBeanPostProcessorTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryInitBeanPostProcessorTest.kt index 4168605823..54b6acb0f3 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryInitBeanPostProcessorTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryInitBeanPostProcessorTest.kt @@ -1,6 +1,6 @@ package io.sentry.spring.jakarta -import io.sentry.IHub +import io.sentry.IScopes import org.mockito.kotlin.mock import org.mockito.kotlin.verify import org.springframework.context.annotation.AnnotationConfigApplicationContext @@ -13,18 +13,18 @@ class SentryInitBeanPostProcessorTest { @Test fun closesSentryOnApplicationContextDestroy() { val ctx = AnnotationConfigApplicationContext(TestConfig::class.java) - val hub = ctx.getBean(IHub::class.java) + val scopes = ctx.getBean(IScopes::class.java) ctx.close() - verify(hub).close() + verify(scopes).close() } @Configuration open class TestConfig { @Bean(destroyMethod = "") - open fun hub() = mock() + open fun scopes() = mock() @Bean - open fun sentryInitBeanPostProcessor() = SentryInitBeanPostProcessor(hub()) + open fun sentryInitBeanPostProcessor() = SentryInitBeanPostProcessor(scopes()) } } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryRequestHttpServletRequestProcessorTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryRequestHttpServletRequestProcessorTest.kt index 279abce417..8faa243f83 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryRequestHttpServletRequestProcessorTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryRequestHttpServletRequestProcessorTest.kt @@ -1,7 +1,7 @@ package io.sentry.spring.jakarta import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryEvent import io.sentry.SentryOptions import io.sentry.spring.jakarta.tracing.SpringMvcTransactionNameProvider @@ -19,10 +19,10 @@ import kotlin.test.assertNotNull class SentryRequestHttpServletRequestProcessorTest { private class Fixture { - val hub = mock() + val scopes = mock() fun getSut(request: HttpServletRequest, options: SentryOptions = SentryOptions()): SentryRequestHttpServletRequestProcessor { - whenever(hub.options).thenReturn(options) + whenever(scopes.options).thenReturn(options) return SentryRequestHttpServletRequestProcessor(SpringMvcTransactionNameProvider(), request) } } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentrySpringFilterTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentrySpringFilterTest.kt index 4e1bbb0ee5..b6bce77a0b 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentrySpringFilterTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentrySpringFilterTest.kt @@ -1,8 +1,8 @@ package io.sentry.spring.jakarta import io.sentry.Breadcrumb -import io.sentry.IHub import io.sentry.IScope +import io.sentry.IScopes import io.sentry.Scope import io.sentry.ScopeCallback import io.sentry.SentryOptions @@ -37,7 +37,7 @@ import kotlin.test.fail class SentrySpringFilterTest { private class Fixture { - val hub = mock() + val scopes = mock() val response = MockHttpServletResponse() val chain = mock() lateinit var scope: IScope @@ -45,15 +45,15 @@ class SentrySpringFilterTest { fun getSut(request: HttpServletRequest? = null, options: SentryOptions = SentryOptions()): SentrySpringFilter { scope = Scope(options) - whenever(hub.options).thenReturn(options) - whenever(hub.isEnabled).thenReturn(true) - doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(hub).configureScope(any()) + whenever(scopes.options).thenReturn(options) + whenever(scopes.isEnabled).thenReturn(true) + doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(scopes).configureScope(any()) this.request = request ?: MockHttpServletRequest().apply { this.requestURI = "http://localhost:8080/some-uri" this.method = "post" } - return SentrySpringFilter(hub) + return SentrySpringFilter(scopes) } } @@ -64,7 +64,7 @@ class SentrySpringFilterTest { val listener = fixture.getSut() listener.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).pushScope() + verify(fixture.scopes).pushScope() } @Test @@ -72,7 +72,7 @@ class SentrySpringFilterTest { val listener = fixture.getSut() listener.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { it: Breadcrumb -> Assertions.assertThat(it.getData("url")).isEqualTo("http://localhost:8080/some-uri") Assertions.assertThat(it.getData("method")).isEqualTo("POST") @@ -87,7 +87,7 @@ class SentrySpringFilterTest { val listener = fixture.getSut() listener.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).popScope() + verify(fixture.scopes).popScope() } @Test @@ -99,7 +99,7 @@ class SentrySpringFilterTest { listener.doFilter(fixture.request, fixture.response, fixture.chain) fail() } catch (e: Exception) { - verify(fixture.hub).popScope() + verify(fixture.scopes).popScope() } } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryTaskDecoratorTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryTaskDecoratorTest.kt index aa809259d1..e5f8704b49 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryTaskDecoratorTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryTaskDecoratorTest.kt @@ -32,28 +32,28 @@ class SentryTaskDecoratorTest { val sut = SentryTaskDecorator() - val mainHub = Sentry.getCurrentHub() - val threadedHub = Sentry.getCurrentHub().clone() + val mainHub = Sentry.getCurrentScopes() + val threadedHub = Sentry.getCurrentScopes().clone() executor.submit { - Sentry.setCurrentHub(threadedHub) + Sentry.setCurrentScopes(threadedHub) }.get() - assertEquals(mainHub, Sentry.getCurrentHub()) + assertEquals(mainHub, Sentry.getCurrentScopes()) val callableFuture = executor.submit( sut.decorate { - assertNotEquals(mainHub, Sentry.getCurrentHub()) - assertNotEquals(threadedHub, Sentry.getCurrentHub()) + assertNotEquals(mainHub, Sentry.getCurrentScopes()) + assertNotEquals(threadedHub, Sentry.getCurrentScopes()) } ) callableFuture.get() executor.submit { - assertNotEquals(mainHub, Sentry.getCurrentHub()) - assertEquals(threadedHub, Sentry.getCurrentHub()) + assertNotEquals(mainHub, Sentry.getCurrentScopes()) + assertEquals(threadedHub, Sentry.getCurrentScopes()) }.get() } } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryUserFilterTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryUserFilterTest.kt index 2f128cc4bb..b30dc937e5 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryUserFilterTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryUserFilterTest.kt @@ -1,6 +1,6 @@ package io.sentry.spring.jakarta -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryOptions import io.sentry.protocol.User import jakarta.servlet.FilterChain @@ -16,7 +16,7 @@ import kotlin.test.assertNull class SentryUserFilterTest { class Fixture { - val hub = mock() + val scopes = mock() val request = MockHttpServletRequest() val response = MockHttpServletResponse() val chain = mock() @@ -25,8 +25,8 @@ class SentryUserFilterTest { val options = SentryOptions().apply { this.isSendDefaultPii = isSendDefaultPii } - whenever(hub.options).thenReturn(options) - return SentryUserFilter(hub, userProviders) + whenever(scopes.options).thenReturn(options) + return SentryUserFilter(scopes, userProviders) } } @@ -52,7 +52,7 @@ class SentryUserFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).setUser( + verify(fixture.scopes).setUser( check { assertEquals(sampleUser, it) } @@ -72,7 +72,7 @@ class SentryUserFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).setUser( + verify(fixture.scopes).setUser( check { assertEquals(sampleUser, it) } @@ -92,7 +92,7 @@ class SentryUserFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).setUser( + verify(fixture.scopes).setUser( check { assertEquals(sampleUser, it) } @@ -118,7 +118,7 @@ class SentryUserFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).setUser( + verify(fixture.scopes).setUser( check { assertEquals(mapOf("key" to "value", "new-key" to "new-value"), it.others) } @@ -140,7 +140,7 @@ class SentryUserFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).setUser( + verify(fixture.scopes).setUser( check { assertEquals("192.168.0.1", it.ipAddress) } @@ -162,7 +162,7 @@ class SentryUserFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).setUser( + verify(fixture.scopes).setUser( check { assertNull(it.ipAddress) } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/exception/SentryCaptureExceptionParameterAdviceTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/exception/SentryCaptureExceptionParameterAdviceTest.kt index 0da5047251..3f8371ca3d 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/exception/SentryCaptureExceptionParameterAdviceTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/exception/SentryCaptureExceptionParameterAdviceTest.kt @@ -1,7 +1,7 @@ package io.sentry.spring.jakarta.exception import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.Sentry import io.sentry.exception.ExceptionMechanismException import org.junit.runner.RunWith @@ -30,18 +30,18 @@ class SentryCaptureExceptionParameterAdviceTest { lateinit var sampleService: SampleService @Autowired - lateinit var hub: IHub + lateinit var scopes: IScopes @BeforeTest fun setup() { - reset(hub) + reset(scopes) } @Test fun `captures exception passed to method annotated with @SentryCaptureException`() { val exception = RuntimeException("test exception") sampleService.methodTakingAnException(exception) - verify(hub).captureException( + verify(scopes).captureException( check { assertTrue(it is ExceptionMechanismException) assertEquals(exception, it.throwable) @@ -60,10 +60,10 @@ class SentryCaptureExceptionParameterAdviceTest { open fun sampleService() = SampleService() @Bean - open fun hub(): IHub { - val hub = mock() - Sentry.setCurrentHub(hub) - return hub + open fun scopes(): IScopes { + val scopes = mock() + Sentry.setCurrentScopes(scopes) + return scopes } } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/graphql/SentrySpringSubscriptionHandlerTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/graphql/SentrySpringSubscriptionHandlerTest.kt index 3f71eaf23e..c2ebb95e48 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/graphql/SentrySpringSubscriptionHandlerTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/graphql/SentrySpringSubscriptionHandlerTest.kt @@ -4,7 +4,7 @@ import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchPar import graphql.language.Document import graphql.language.OperationDefinition import graphql.schema.DataFetchingEnvironment -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.graphql.ExceptionReporter import io.sentry.spring.jakarta.graphql.SentrySpringSubscriptionHandler import org.junit.jupiter.api.assertThrows @@ -24,7 +24,7 @@ class SentrySpringSubscriptionHandlerTest { @Test fun `reports exception`() { val exception = IllegalStateException("some exception") - val hub = mock() + val scopes = mock() val exceptionReporter = mock() val parameters = mock() val dataFetchingEnvironment = mock() @@ -33,7 +33,7 @@ class SentrySpringSubscriptionHandlerTest { .build() whenever(dataFetchingEnvironment.document).thenReturn(document) whenever(parameters.environment).thenReturn(dataFetchingEnvironment) - val resultObject = SentrySpringSubscriptionHandler().onSubscriptionResult(Flux.error(exception), hub, exceptionReporter, parameters) + val resultObject = SentrySpringSubscriptionHandler().onSubscriptionResult(Flux.error(exception), scopes, exceptionReporter, parameters) assertThrows { (resultObject as Flux).blockFirst() } @@ -42,7 +42,7 @@ class SentrySpringSubscriptionHandlerTest { same(exception), org.mockito.kotlin.check { assertEquals(true, it.isSubscription) - assertSame(hub, it.hub) + assertSame(scopes, it.scopes) assertEquals("query testQuery\n", it.query) }, anyOrNull() @@ -53,7 +53,7 @@ class SentrySpringSubscriptionHandlerTest { fun `unwraps SubscriptionPublisherException and reports cause`() { val exception = IllegalStateException("some exception") val wrappedException = SubscriptionPublisherException(emptyList(), exception) - val hub = mock() + val scopes = mock() val exceptionReporter = mock() val parameters = mock() val dataFetchingEnvironment = mock() @@ -62,7 +62,7 @@ class SentrySpringSubscriptionHandlerTest { .build() whenever(dataFetchingEnvironment.document).thenReturn(document) whenever(parameters.environment).thenReturn(dataFetchingEnvironment) - val resultObject = SentrySpringSubscriptionHandler().onSubscriptionResult(Flux.error(wrappedException), hub, exceptionReporter, parameters) + val resultObject = SentrySpringSubscriptionHandler().onSubscriptionResult(Flux.error(wrappedException), scopes, exceptionReporter, parameters) assertThrows { (resultObject as Flux).blockFirst() } @@ -71,7 +71,7 @@ class SentrySpringSubscriptionHandlerTest { same(exception), org.mockito.kotlin.check { assertEquals(true, it.isSubscription) - assertSame(hub, it.hub) + assertSame(scopes, it.scopes) assertEquals("query testQuery\n", it.query) }, anyOrNull() diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/mvc/SentrySpringIntegrationTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/mvc/SentrySpringIntegrationTest.kt index f472a75a65..0b4be869d0 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/mvc/SentrySpringIntegrationTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/mvc/SentrySpringIntegrationTest.kt @@ -1,6 +1,6 @@ package io.sentry.spring.jakarta.mvc -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ITransportFactory import io.sentry.Sentry import io.sentry.SentryOptions @@ -104,7 +104,7 @@ class SentrySpringIntegrationTest { lateinit var anotherService: AnotherService @Autowired - lateinit var hub: IHub + lateinit var scopes: IScopes @LocalServerPort var port: Int? = null @@ -260,7 +260,7 @@ class SentrySpringIntegrationTest { try { someService.aMethodThrowing() } catch (e: Exception) { - hub.captureException(e) + scopes.captureException(e) } verify(transport).send( checkEvent { @@ -276,7 +276,7 @@ class SentrySpringIntegrationTest { try { someService.aMethodWithInnerSpanThrowing() } catch (e: Exception) { - hub.captureException(e) + scopes.captureException(e) } verify(transport).send( checkEvent { @@ -370,20 +370,20 @@ open class App { open fun springSecuritySentryUserProvider(sentryOptions: SentryOptions) = SpringSecuritySentryUserProvider(sentryOptions) @Bean - open fun sentryUserFilter(hub: IHub, @Lazy sentryUserProviders: List) = FilterRegistrationBean().apply { - this.filter = SentryUserFilter(hub, sentryUserProviders) + open fun sentryUserFilter(scopes: IScopes, @Lazy sentryUserProviders: List) = FilterRegistrationBean().apply { + this.filter = SentryUserFilter(scopes, sentryUserProviders) this.order = Ordered.LOWEST_PRECEDENCE } @Bean - open fun sentrySpringFilter(hub: IHub) = FilterRegistrationBean().apply { - this.filter = SentrySpringFilter(hub) + open fun sentrySpringFilter(scopes: IScopes) = FilterRegistrationBean().apply { + this.filter = SentrySpringFilter(scopes) this.order = Ordered.HIGHEST_PRECEDENCE } @Bean - open fun sentryTracingFilter(hub: IHub) = FilterRegistrationBean().apply { - this.filter = SentryTracingFilter(hub) + open fun sentryTracingFilter(scopes: IScopes) = FilterRegistrationBean().apply { + this.filter = SentryTracingFilter(scopes) this.order = Ordered.HIGHEST_PRECEDENCE + 1 // must run after SentrySpringFilter } @@ -391,13 +391,13 @@ open class App { open fun sentryTaskDecorator() = SentryTaskDecorator() @Bean - open fun webClient(hub: IHub): WebClient { + open fun webClient(scopes: IScopes): WebClient { return WebClient.builder() .filter( ExchangeFilterFunctions .basicAuthentication("user", "password") ) - .filter(SentrySpanClientWebRequestFilter(hub)).build() + .filter(SentrySpanClientWebRequestFilter(scopes)).build() } } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/tracing/SentrySpanAdviceTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/tracing/SentrySpanAdviceTest.kt index 2910e7aac6..8b74b08fb1 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/tracing/SentrySpanAdviceTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/tracing/SentrySpanAdviceTest.kt @@ -1,6 +1,6 @@ package io.sentry.spring.jakarta.tracing -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.Scope import io.sentry.Sentry import io.sentry.SentryOptions @@ -37,20 +37,20 @@ class SentrySpanAdviceTest { lateinit var classAnnotatedWithOperationSampleService: ClassAnnotatedWithOperationSampleService @Autowired - lateinit var hub: IHub + lateinit var scopes: IScopes @BeforeTest fun setup() { - whenever(hub.options).thenReturn(SentryOptions()) + whenever(scopes.options).thenReturn(SentryOptions()) } @Test fun `when class is annotated with @SentrySpan, every method call attaches span to existing transaction`() { val scope = Scope(SentryOptions()) - val tx = SentryTracer(TransactionContext("aTransaction", "op"), hub) + val tx = SentryTracer(TransactionContext("aTransaction", "op"), scopes) scope.setTransaction(tx) - whenever(hub.span).thenReturn(tx) + whenever(scopes.span).thenReturn(tx) val result = classAnnotatedSampleService.hello() assertEquals(1, result) assertEquals(1, tx.spans.size) @@ -62,10 +62,10 @@ class SentrySpanAdviceTest { @Test fun `when class is annotated with @SentrySpan with operation set, every method call attaches span to existing transaction`() { val scope = Scope(SentryOptions()) - val tx = SentryTracer(TransactionContext("aTransaction", "op"), hub) + val tx = SentryTracer(TransactionContext("aTransaction", "op"), scopes) scope.setTransaction(tx) - whenever(hub.span).thenReturn(tx) + whenever(scopes.span).thenReturn(tx) val result = classAnnotatedWithOperationSampleService.hello() assertEquals(1, result) assertEquals(1, tx.spans.size) @@ -76,10 +76,10 @@ class SentrySpanAdviceTest { @Test fun `when method is annotated with @SentrySpan with properties set, attaches span to existing transaction`() { val scope = Scope(SentryOptions()) - val tx = SentryTracer(TransactionContext("aTransaction", "op"), hub) + val tx = SentryTracer(TransactionContext("aTransaction", "op"), scopes) scope.setTransaction(tx) - whenever(hub.span).thenReturn(tx) + whenever(scopes.span).thenReturn(tx) val result = sampleService.methodWithSpanDescriptionSet() assertEquals(1, result) assertEquals(1, tx.spans.size) @@ -90,10 +90,10 @@ class SentrySpanAdviceTest { @Test fun `when method is annotated with @SentrySpan without properties set, attaches span to existing transaction and sets Span description as className dot methodName`() { val scope = Scope(SentryOptions()) - val tx = SentryTracer(TransactionContext("aTransaction", "op"), hub) + val tx = SentryTracer(TransactionContext("aTransaction", "op"), scopes) scope.setTransaction(tx) - whenever(hub.span).thenReturn(tx) + whenever(scopes.span).thenReturn(tx) val result = sampleService.methodWithoutSpanDescriptionSet() assertEquals(2, result) assertEquals(1, tx.spans.size) @@ -104,10 +104,10 @@ class SentrySpanAdviceTest { @Test fun `when method is annotated with @SentrySpan and returns, attached span has status OK`() { val scope = Scope(SentryOptions()) - val tx = SentryTracer(TransactionContext("aTransaction", "op"), hub) + val tx = SentryTracer(TransactionContext("aTransaction", "op"), scopes) scope.setTransaction(tx) - whenever(hub.span).thenReturn(tx) + whenever(scopes.span).thenReturn(tx) sampleService.methodWithSpanDescriptionSet() assertEquals(SpanStatus.OK, tx.spans.first().status) } @@ -115,10 +115,10 @@ class SentrySpanAdviceTest { @Test fun `when method is annotated with @SentrySpan and throws exception, attached span has throwable set and INTERNAL_ERROR status`() { val scope = Scope(SentryOptions()) - val tx = SentryTracer(TransactionContext("aTransaction", "op"), hub) + val tx = SentryTracer(TransactionContext("aTransaction", "op"), scopes) scope.setTransaction(tx) - whenever(hub.span).thenReturn(tx) + whenever(scopes.span).thenReturn(tx) var throwable: Throwable? = null try { sampleService.methodThrowingException() @@ -131,7 +131,7 @@ class SentrySpanAdviceTest { @Test fun `when method is annotated with @SentrySpan and there is no active transaction, span is not created and method is executed`() { - whenever(hub.span).thenReturn(null) + whenever(scopes.span).thenReturn(null) val result = sampleService.methodWithSpanDescriptionSet() assertEquals(1, result) } @@ -151,10 +151,10 @@ class SentrySpanAdviceTest { open fun classAnnotatedWithOperationSampleService() = ClassAnnotatedWithOperationSampleService() @Bean - open fun hub(): IHub { - val hub = mock() - Sentry.setCurrentHub(hub) - return hub + open fun scopes(): IScopes { + val scopes = mock() + Sentry.setCurrentScopes(scopes) + return scopes } } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/tracing/SentryTracingFilterTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/tracing/SentryTracingFilterTest.kt index 0424696fad..265d607b70 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/tracing/SentryTracingFilterTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/tracing/SentryTracingFilterTest.kt @@ -1,7 +1,7 @@ package io.sentry.spring.jakarta.tracing -import io.sentry.IHub import io.sentry.ILogger +import io.sentry.IScopes import io.sentry.PropagationContext import io.sentry.SentryOptions import io.sentry.SentryTracer @@ -38,7 +38,7 @@ import kotlin.test.fail class SentryTracingFilterTest { private class Fixture { - val hub = mock() + val scopes = mock() val request = MockHttpServletRequest() val response = MockHttpServletResponse() val chain = mock() @@ -50,7 +50,7 @@ class SentryTracingFilterTest { val logger = mock() init { - whenever(hub.options).thenReturn(options) + whenever(scopes.options).thenReturn(options) } fun getSut(isEnabled: Boolean = true, status: Int = 200, sentryTraceHeader: String? = null, baggageHeaders: List? = null): SentryTracingFilter { @@ -61,16 +61,16 @@ class SentryTracingFilterTest { whenever(transactionNameProvider.provideTransactionSource()).thenReturn(TransactionNameSource.CUSTOM) if (sentryTraceHeader != null) { request.addHeader("sentry-trace", sentryTraceHeader) - whenever(hub.startTransaction(any(), check { it.isBindToScope })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, hub) } + whenever(scopes.startTransaction(any(), check { it.isBindToScope })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, scopes) } } if (baggageHeaders != null) { request.addHeader("baggage", baggageHeaders) } response.status = status - whenever(hub.startTransaction(any(), check { assertTrue(it.isBindToScope) })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, hub) } - whenever(hub.isEnabled).thenReturn(isEnabled) - whenever(hub.continueTrace(any(), any())).thenAnswer { TransactionContext.fromPropagationContext(PropagationContext.fromHeaders(logger, it.arguments[0] as String?, it.arguments[1] as List?)) } - return SentryTracingFilter(hub, transactionNameProvider) + whenever(scopes.startTransaction(any(), check { assertTrue(it.isBindToScope) })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, scopes) } + whenever(scopes.isEnabled).thenReturn(isEnabled) + whenever(scopes.continueTrace(any(), any())).thenAnswer { TransactionContext.fromPropagationContext(PropagationContext.fromHeaders(logger, it.arguments[0] as String?, it.arguments[1] as List?)) } + return SentryTracingFilter(scopes, transactionNameProvider) } } @@ -82,7 +82,7 @@ class SentryTracingFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( check { assertEquals("POST /product/12", it.name) assertEquals(TransactionNameSource.URL, it.transactionNameSource) @@ -95,7 +95,7 @@ class SentryTracingFilterTest { } ) verify(fixture.chain).doFilter(fixture.request, fixture.response) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.transaction).isEqualTo("POST /product/{id}") assertThat(it.contexts.trace!!.status).isEqualTo(SpanStatus.OK) @@ -114,7 +114,7 @@ class SentryTracingFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.status).isEqualTo(SpanStatus.INTERNAL_ERROR) }, @@ -130,7 +130,7 @@ class SentryTracingFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.status).isNull() }, @@ -146,7 +146,7 @@ class SentryTracingFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.parentSpanId).isNull() }, @@ -163,7 +163,7 @@ class SentryTracingFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.parentSpanId).isEqualTo(parentSpanId) }, @@ -174,15 +174,15 @@ class SentryTracingFilterTest { } @Test - fun `when hub is disabled, components are not invoked`() { + fun `when scopes is disabled, components are not invoked`() { val filter = fixture.getSut(isEnabled = false) filter.doFilter(fixture.request, fixture.response, fixture.chain) verify(fixture.chain).doFilter(fixture.request, fixture.response) - verify(fixture.hub).isEnabled - verifyNoMoreInteractions(fixture.hub) + verify(fixture.scopes).isEnabled + verifyNoMoreInteractions(fixture.scopes) verify(fixture.transactionNameProvider, never()).provideTransactionName(any()) } @@ -196,7 +196,7 @@ class SentryTracingFilterTest { fail("filter is expected to rethrow exception") } catch (_: Exception) { } - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.status).isEqualTo(SpanStatus.INTERNAL_ERROR) }, @@ -216,10 +216,10 @@ class SentryTracingFilterTest { verify(fixture.chain).doFilter(fixture.request, fixture.response) - verify(fixture.hub).isEnabled - verify(fixture.hub).continueTrace(anyOrNull(), anyOrNull()) - verify(fixture.hub, times(2)).options - verifyNoMoreInteractions(fixture.hub) + verify(fixture.scopes).isEnabled + verify(fixture.scopes).continueTrace(anyOrNull(), anyOrNull()) + verify(fixture.scopes, times(2)).options + verifyNoMoreInteractions(fixture.scopes) verify(fixture.transactionNameProvider, never()).provideTransactionName(any()) } @@ -233,7 +233,7 @@ class SentryTracingFilterTest { verify(fixture.chain).doFilter(fixture.request, fixture.response) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.parentSpanId).isNull() }, @@ -253,7 +253,7 @@ class SentryTracingFilterTest { verify(fixture.chain).doFilter(fixture.request, fixture.response) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.parentSpanId).isNull() }, @@ -275,9 +275,9 @@ class SentryTracingFilterTest { verify(fixture.chain).doFilter(fixture.request, fixture.response) - verify(fixture.hub).continueTrace(eq(sentryTraceHeaderString), eq(baggageHeaderStrings)) + verify(fixture.scopes).continueTrace(eq(sentryTraceHeaderString), eq(baggageHeaderStrings)) - verify(fixture.hub, never()).captureTransaction( + verify(fixture.scopes, never()).captureTransaction( anyOrNull(), anyOrNull(), anyOrNull(), diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/tracing/SentryTransactionAdviceTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/tracing/SentryTransactionAdviceTest.kt index 5d2863310f..390b4d8241 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/tracing/SentryTransactionAdviceTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/tracing/SentryTransactionAdviceTest.kt @@ -1,6 +1,6 @@ package io.sentry.spring.jakarta.tracing -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.Sentry import io.sentry.SentryOptions import io.sentry.SentryTracer @@ -44,13 +44,13 @@ class SentryTransactionAdviceTest { lateinit var classAnnotatedWithOperationSampleService: ClassAnnotatedWithOperationSampleService @Autowired - lateinit var hub: IHub + lateinit var scopes: IScopes @BeforeTest fun setup() { - reset(hub) - whenever(hub.startTransaction(any(), check { assertTrue(it.isBindToScope) })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, hub) } - whenever(hub.options).thenReturn( + reset(scopes) + whenever(scopes.startTransaction(any(), check { assertTrue(it.isBindToScope) })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, scopes) } + whenever(scopes.options).thenReturn( SentryOptions().apply { dsn = "https://key@sentry.io/proj" } @@ -60,7 +60,7 @@ class SentryTransactionAdviceTest { @Test fun `creates transaction around method annotated with @SentryTransaction`() { sampleService.methodWithTransactionNameSet() - verify(hub).captureTransaction( + verify(scopes).captureTransaction( check { assertThat(it.transaction).isEqualTo("customName") assertThat(it.contexts.trace!!.operation).isEqualTo("bean") @@ -76,7 +76,7 @@ class SentryTransactionAdviceTest { @Test fun `when method annotated with @SentryTransaction throws exception, sets error status on transaction`() { assertThrows { sampleService.methodThrowingException() } - verify(hub).captureTransaction( + verify(scopes).captureTransaction( check { assertThat(it.status).isEqualTo(SpanStatus.INTERNAL_ERROR) }, @@ -89,7 +89,7 @@ class SentryTransactionAdviceTest { @Test fun `when @SentryTransaction has no name set, sets transaction name as className dot methodName`() { sampleService.methodWithoutTransactionNameSet() - verify(hub).captureTransaction( + verify(scopes).captureTransaction( check { assertThat(it.transaction).isEqualTo("SampleService.methodWithoutTransactionNameSet") assertThat(it.contexts.trace!!.operation).isEqualTo("op") @@ -102,18 +102,18 @@ class SentryTransactionAdviceTest { @Test fun `when transaction is already active, does not start new transaction`() { - whenever(hub.options).thenReturn(SentryOptions()) - whenever(hub.span).then { SentryTracer(TransactionContext("aTransaction", "op"), hub) } + whenever(scopes.options).thenReturn(SentryOptions()) + whenever(scopes.span).then { SentryTracer(TransactionContext("aTransaction", "op"), scopes) } sampleService.methodWithTransactionNameSet() - verify(hub, times(0)).captureTransaction(any(), any()) + verify(scopes, times(0)).captureTransaction(any(), any()) } @Test fun `creates transaction around method in class annotated with @SentryTransaction`() { classAnnotatedSampleService.hello() - verify(hub).captureTransaction( + verify(scopes).captureTransaction( check { assertThat(it.transaction).isEqualTo("ClassAnnotatedSampleService.hello") assertThat(it.contexts.trace!!.operation).isEqualTo("op") @@ -127,7 +127,7 @@ class SentryTransactionAdviceTest { @Test fun `creates transaction with operation set around method in class annotated with @SentryTransaction`() { classAnnotatedWithOperationSampleService.hello() - verify(hub).captureTransaction( + verify(scopes).captureTransaction( check { assertThat(it.transaction).isEqualTo("ClassAnnotatedWithOperationSampleService.hello") assertThat(it.contexts.trace!!.operation).isEqualTo("my-op") @@ -141,13 +141,13 @@ class SentryTransactionAdviceTest { @Test fun `pushes the scope when advice starts`() { classAnnotatedSampleService.hello() - verify(hub).pushScope() + verify(scopes).pushScope() } @Test fun `pops the scope when advice finishes`() { classAnnotatedSampleService.hello() - verify(hub).popScope() + verify(scopes).popScope() } @Configuration @@ -165,10 +165,10 @@ class SentryTransactionAdviceTest { open fun classAnnotatedWithOperationSampleService() = ClassAnnotatedWithOperationSampleService() @Bean - open fun hub(): IHub { - val hub = mock() - Sentry.setCurrentHub(hub) - return hub + open fun scopes(): IScopes { + val scopes = mock() + Sentry.setCurrentScopes(scopes) + return scopes } } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/ReactorUtilsTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/ReactorUtilsTest.kt index ad335333ed..9c851cde11 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/ReactorUtilsTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/ReactorUtilsTest.kt @@ -1,7 +1,8 @@ package io.sentry.spring.jakarta.webflux import io.sentry.IHub -import io.sentry.NoOpHub +import io.sentry.IScopes +import io.sentry.NoOpScopes import io.sentry.Sentry import org.mockito.kotlin.mock import org.mockito.kotlin.verify @@ -26,18 +27,18 @@ class ReactorUtilsTest { @AfterTest fun teardown() { - Sentry.setCurrentHub(NoOpHub.getInstance()) + Sentry.setCurrentScopes(NoOpScopes.getInstance()) } @Test fun `propagates hub inside mono`() { - val hubToUse = mock() - var hubInside: IHub? = null + val hubToUse = mock() + var hubInside: IScopes? = null val mono = ReactorUtils.withSentryHub( Mono.just("hello") .publishOn(Schedulers.boundedElastic()) .map { it -> - hubInside = Sentry.getCurrentHub() + hubInside = Sentry.getCurrentScopes() it }, hubToUse @@ -49,13 +50,13 @@ class ReactorUtilsTest { @Test fun `propagates hub inside flux`() { - val hubToUse = mock() - var hubInside: IHub? = null + val hubToUse = mock() + var hubInside: IScopes? = null val flux = ReactorUtils.withSentryHub( Flux.just("hello") .publishOn(Schedulers.boundedElastic()) .map { it -> - hubInside = Sentry.getCurrentHub() + hubInside = Sentry.getCurrentScopes() it }, hubToUse @@ -67,12 +68,12 @@ class ReactorUtilsTest { @Test fun `without reactive utils hub is not propagated to mono`() { - val hubToUse = mock() - var hubInside: IHub? = null + val hubToUse = mock() + var hubInside: IScopes? = null val mono = Mono.just("hello") .publishOn(Schedulers.boundedElastic()) .map { it -> - hubInside = Sentry.getCurrentHub() + hubInside = Sentry.getCurrentScopes() it } @@ -82,12 +83,12 @@ class ReactorUtilsTest { @Test fun `without reactive utils hub is not propagated to flux`() { - val hubToUse = mock() - var hubInside: IHub? = null + val hubToUse = mock() + var hubInside: IScopes? = null val flux = Flux.just("hello") .publishOn(Schedulers.boundedElastic()) .map { it -> - hubInside = Sentry.getCurrentHub() + hubInside = Sentry.getCurrentScopes() it } @@ -97,21 +98,21 @@ class ReactorUtilsTest { @Test fun `clones hub for mono`() { - val mockHub = mock() - whenever(mockHub.clone()).thenReturn(mock()) - Sentry.setCurrentHub(mockHub) + val mockScopes = mock() + whenever(mockScopes.clone()).thenReturn(mock()) + Sentry.setCurrentScopes(mockScopes) ReactorUtils.withSentry(Mono.just("hello")).block() - verify(mockHub).clone() + verify(mockScopes).clone() } @Test fun `clones hub for flux`() { - val mockHub = mock() - whenever(mockHub.clone()).thenReturn(mock()) - Sentry.setCurrentHub(mockHub) + val mockScopes = mock() + whenever(mockScopes.clone()).thenReturn(mock()) + Sentry.setCurrentScopes(mockScopes) ReactorUtils.withSentry(Flux.just("hello")).blockFirst() - verify(mockHub).clone() + verify(mockScopes).clone() } } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryScheduleHookTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryScheduleHookTest.kt index 1eb06d0afe..5403caa7e0 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryScheduleHookTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryScheduleHookTest.kt @@ -33,28 +33,28 @@ class SentryScheduleHookTest { val sut = SentryScheduleHook() - val mainHub = Sentry.getCurrentHub() - val threadedHub = Sentry.getCurrentHub().clone() + val mainHub = Sentry.getCurrentScopes() + val threadedHub = Sentry.getCurrentScopes().clone() executor.submit { - Sentry.setCurrentHub(threadedHub) + Sentry.setCurrentScopes(threadedHub) }.get() - assertEquals(mainHub, Sentry.getCurrentHub()) + assertEquals(mainHub, Sentry.getCurrentScopes()) val callableFuture = executor.submit( sut.apply { - assertNotEquals(mainHub, Sentry.getCurrentHub()) - assertNotEquals(threadedHub, Sentry.getCurrentHub()) + assertNotEquals(mainHub, Sentry.getCurrentScopes()) + assertNotEquals(threadedHub, Sentry.getCurrentScopes()) } ) callableFuture.get() executor.submit { - assertNotEquals(mainHub, Sentry.getCurrentHub()) - assertEquals(threadedHub, Sentry.getCurrentHub()) + assertNotEquals(mainHub, Sentry.getCurrentScopes()) + assertEquals(threadedHub, Sentry.getCurrentScopes()) }.get() } } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryWebFluxTracingFilterTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryWebFluxTracingFilterTest.kt index eac0b9c60f..e936394039 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryWebFluxTracingFilterTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryWebFluxTracingFilterTest.kt @@ -2,8 +2,9 @@ package io.sentry.spring.jakarta.webflux import io.sentry.Breadcrumb import io.sentry.Hint -import io.sentry.IHub +import io.sentry.HubScopesWrapper import io.sentry.ILogger +import io.sentry.IScopes import io.sentry.PropagationContext import io.sentry.ScopeCallback import io.sentry.Sentry @@ -17,7 +18,7 @@ import io.sentry.TransactionOptions import io.sentry.protocol.SentryId import io.sentry.protocol.SentryTransaction import io.sentry.protocol.TransactionNameSource -import io.sentry.spring.jakarta.webflux.AbstractSentryWebFilter.SENTRY_HUB_KEY +import io.sentry.spring.jakarta.webflux.AbstractSentryWebFilter.SENTRY_SCOPES_KEY import org.assertj.core.api.Assertions.assertThat import org.mockito.Mockito import org.mockito.kotlin.any @@ -47,7 +48,7 @@ import kotlin.test.fail class SentryWebFluxTracingFilterTest { private class Fixture { - val hub = mock() + val scopes = mock() lateinit var request: MockServerHttpRequest lateinit var exchange: MockServerWebExchange val chain = mock() @@ -58,45 +59,47 @@ class SentryWebFluxTracingFilterTest { val logger = mock() init { - whenever(hub.options).thenReturn(options) + whenever(scopes.options).thenReturn(options) } fun getSut(isEnabled: Boolean = true, status: HttpStatus = HttpStatus.OK, sentryTraceHeader: String? = null, baggageHeaders: List? = null, method: HttpMethod = HttpMethod.POST): SentryWebFilter { var requestBuilder = MockServerHttpRequest.method(method, "/product/{id}", 12) if (sentryTraceHeader != null) { requestBuilder = requestBuilder.header("sentry-trace", sentryTraceHeader) - whenever(hub.startTransaction(any(), check { it.isBindToScope })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, hub) } + whenever(scopes.startTransaction(any(), check { it.isBindToScope })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, scopes) } } if (baggageHeaders != null) { requestBuilder = requestBuilder.header("baggage", *baggageHeaders.toTypedArray()) } request = requestBuilder.build() exchange = MockServerWebExchange.builder(request).build() - exchange.attributes.put(SENTRY_HUB_KEY, hub) + exchange.attributes.put(SENTRY_SCOPES_KEY, scopes) exchange.attributes.put(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE, PathPatternParser().parse("/product/{id}")) exchange.response.statusCode = status - whenever(hub.startTransaction(any(), check { assertTrue(it.isBindToScope) })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, hub) } - whenever(hub.isEnabled).thenReturn(isEnabled) + whenever(scopes.startTransaction(any(), check { assertTrue(it.isBindToScope) })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, scopes) } + whenever(scopes.isEnabled).thenReturn(isEnabled) whenever(chain.filter(any())).thenReturn(Mono.create { s -> s.success() }) - whenever(hub.continueTrace(anyOrNull(), anyOrNull())).thenAnswer { TransactionContext.fromPropagationContext(PropagationContext.fromHeaders(logger, it.arguments[0] as String?, it.arguments[1] as List?)) } - return SentryWebFilter(hub) + whenever(scopes.continueTrace(anyOrNull(), anyOrNull())).thenAnswer { TransactionContext.fromPropagationContext(PropagationContext.fromHeaders(logger, it.arguments[0] as String?, it.arguments[1] as List?)) } + return SentryWebFilter(scopes) } } private val fixture = Fixture() - fun withMockHub(closure: () -> Unit) = Mockito.mockStatic(Sentry::class.java).use { - it.`when` { Sentry.cloneMainHub() }.thenReturn(fixture.hub) + fun withMockScopes(closure: () -> Unit) = Mockito.mockStatic(Sentry::class.java).use { + it.`when` { Sentry.getCurrentHub() }.thenReturn(HubScopesWrapper(fixture.scopes)) + it.`when` { Sentry.getCurrentScopes() }.thenReturn(fixture.scopes) + it.`when` { Sentry.cloneMainHub() }.thenReturn(fixture.scopes) closure.invoke() } @Test fun `creates transaction around the request`() { val filter = fixture.getSut() - withMockHub { + withMockScopes { filter.filter(fixture.exchange, fixture.chain).block() - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( check { assertEquals("POST /product/12", it.name) assertEquals(TransactionNameSource.URL, it.transactionNameSource) @@ -109,7 +112,7 @@ class SentryWebFluxTracingFilterTest { } ) verify(fixture.chain).filter(fixture.exchange) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.transaction).isEqualTo("POST /product/{id}") assertThat(it.contexts.trace!!.status).isEqualTo(SpanStatus.OK) @@ -128,10 +131,10 @@ class SentryWebFluxTracingFilterTest { fun `sets correct span status based on the response status`() { val filter = fixture.getSut(status = HttpStatus.INTERNAL_SERVER_ERROR) - withMockHub { + withMockScopes { filter.filter(fixture.exchange, fixture.chain).block() - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.status).isEqualTo(SpanStatus.INTERNAL_ERROR) assertThat(it.contexts.response!!.statusCode).isEqualTo(500) @@ -147,10 +150,10 @@ class SentryWebFluxTracingFilterTest { fun `does not set span status for response status that dont match predefined span statuses`() { val filter = fixture.getSut(status = HttpStatus.FOUND) - withMockHub { + withMockScopes { filter.filter(fixture.exchange, fixture.chain).block() - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.status).isNull() }, @@ -165,10 +168,10 @@ class SentryWebFluxTracingFilterTest { fun `when sentry trace is not present, transaction does not have parentSpanId set`() { val filter = fixture.getSut() - withMockHub { + withMockScopes { filter.filter(fixture.exchange, fixture.chain).block() - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.parentSpanId).isNull() }, @@ -184,10 +187,10 @@ class SentryWebFluxTracingFilterTest { val parentSpanId = SpanId() val filter = fixture.getSut(sentryTraceHeader = "${SentryId()}-$parentSpanId-1") - withMockHub { + withMockScopes { filter.filter(fixture.exchange, fixture.chain).block() - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.parentSpanId).isEqualTo(parentSpanId) }, @@ -199,16 +202,16 @@ class SentryWebFluxTracingFilterTest { } @Test - fun `when hub is disabled, components are not invoked`() { + fun `when scopes is disabled, components are not invoked`() { val filter = fixture.getSut(isEnabled = false) - withMockHub { + withMockScopes { filter.filter(fixture.exchange, fixture.chain).block() verify(fixture.chain).filter(fixture.exchange) - verify(fixture.hub, times(3)).isEnabled - verifyNoMoreInteractions(fixture.hub) + verify(fixture.scopes, times(3)).isEnabled + verifyNoMoreInteractions(fixture.scopes) } } @@ -216,7 +219,7 @@ class SentryWebFluxTracingFilterTest { fun `sets status to internal server error when chain throws exception`() { val filter = fixture.getSut() - withMockHub { + withMockScopes { whenever(fixture.chain.filter(any())).thenReturn(Mono.error(RuntimeException("error"))) try { @@ -224,7 +227,7 @@ class SentryWebFluxTracingFilterTest { fail("filter is expected to rethrow exception") } catch (_: Exception) { } - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.status).isEqualTo(SpanStatus.INTERNAL_ERROR) }, @@ -239,21 +242,21 @@ class SentryWebFluxTracingFilterTest { fun `does not track OPTIONS request with traceOptionsRequests=false`() { val filter = fixture.getSut(method = HttpMethod.OPTIONS) - withMockHub { + withMockScopes { fixture.options.isTraceOptionsRequests = false filter.filter(fixture.exchange, fixture.chain).block() verify(fixture.chain).filter(fixture.exchange) - verify(fixture.hub, times(3)).isEnabled - verify(fixture.hub, times(2)).options - verify(fixture.hub).continueTrace(anyOrNull(), anyOrNull()) - verify(fixture.hub).pushScope() - verify(fixture.hub).addBreadcrumb(any(), any()) - verify(fixture.hub).configureScope(any()) - verify(fixture.hub).popScope() - verifyNoMoreInteractions(fixture.hub) + verify(fixture.scopes, times(3)).isEnabled + verify(fixture.scopes, times(2)).options + verify(fixture.scopes).continueTrace(anyOrNull(), anyOrNull()) + verify(fixture.scopes).pushScope() + verify(fixture.scopes).addBreadcrumb(any(), any()) + verify(fixture.scopes).configureScope(any()) + verify(fixture.scopes).popScope() + verifyNoMoreInteractions(fixture.scopes) } } @@ -261,14 +264,14 @@ class SentryWebFluxTracingFilterTest { fun `tracks OPTIONS request with traceOptionsRequests=true`() { val filter = fixture.getSut(method = HttpMethod.OPTIONS) - withMockHub { + withMockScopes { fixture.options.isTraceOptionsRequests = true filter.filter(fixture.exchange, fixture.chain).block() verify(fixture.chain).filter(fixture.exchange) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.parentSpanId).isNull() }, @@ -283,14 +286,14 @@ class SentryWebFluxTracingFilterTest { fun `tracks POST request with traceOptionsRequests=false`() { val filter = fixture.getSut(method = HttpMethod.POST) - withMockHub { + withMockScopes { fixture.options.isTraceOptionsRequests = false filter.filter(fixture.exchange, fixture.chain).block() verify(fixture.chain).filter(fixture.exchange) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.parentSpanId).isNull() }, @@ -309,19 +312,19 @@ class SentryWebFluxTracingFilterTest { fixture.options.enableTracing = false val filter = fixture.getSut(sentryTraceHeader = sentryTraceHeaderString, baggageHeaders = baggageHeaderStrings) - withMockHub { + withMockScopes { filter.filter(fixture.exchange, fixture.chain).block() verify(fixture.chain).filter(fixture.exchange) - verify(fixture.hub, never()).captureTransaction( + verify(fixture.scopes, never()).captureTransaction( anyOrNull(), anyOrNull(), anyOrNull(), anyOrNull() ) - verify(fixture.hub).continueTrace(eq(sentryTraceHeaderString), eq(baggageHeaderStrings)) + verify(fixture.scopes).continueTrace(eq(sentryTraceHeaderString), eq(baggageHeaderStrings)) } } } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryWebfluxIntegrationTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryWebfluxIntegrationTest.kt index 3f4628ea3c..59f9a700b6 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryWebfluxIntegrationTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryWebfluxIntegrationTest.kt @@ -1,8 +1,8 @@ package io.sentry.spring.jakarta.webflux -import io.sentry.HubAdapter -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ITransportFactory +import io.sentry.ScopesAdapter import io.sentry.Sentry import io.sentry.checkEvent import io.sentry.checkTransaction @@ -160,13 +160,13 @@ open class App { open fun mockTransport() = transport @Bean - open fun hub() = HubAdapter.getInstance() + open fun scopes() = ScopesAdapter.getInstance() @Bean - open fun sentryFilter(hub: IHub) = SentryWebFilter(hub) + open fun sentryFilter(scopes: IScopes) = SentryWebFilter(scopes) @Bean - open fun sentryWebExceptionHandler(hub: IHub) = SentryWebExceptionHandler(hub) + open fun sentryWebExceptionHandler(scopes: IScopes) = SentryWebExceptionHandler(scopes) @Bean open fun sentryScheduleHookRegistrar() = ApplicationRunner { diff --git a/sentry-spring/api/sentry-spring.api b/sentry-spring/api/sentry-spring.api index 9ef6b5bb3a..58de26098f 100644 --- a/sentry-spring/api/sentry-spring.api +++ b/sentry-spring/api/sentry-spring.api @@ -22,7 +22,7 @@ public final class io/sentry/spring/HttpServletRequestSentryUserProvider : io/se public class io/sentry/spring/SentryExceptionResolver : org/springframework/core/Ordered, org/springframework/web/servlet/HandlerExceptionResolver { public static final field MECHANISM_TYPE Ljava/lang/String; - public fun (Lio/sentry/IHub;Lio/sentry/spring/tracing/TransactionNameProvider;I)V + public fun (Lio/sentry/IScopes;Lio/sentry/spring/tracing/TransactionNameProvider;I)V protected fun createEvent (Ljavax/servlet/http/HttpServletRequest;Ljava/lang/Exception;)Lio/sentry/SentryEvent; protected fun createHint (Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)Lio/sentry/Hint; public fun getOrder ()I @@ -47,14 +47,14 @@ public class io/sentry/spring/SentryRequestHttpServletRequestProcessor : io/sent } public class io/sentry/spring/SentryRequestResolver { - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun resolveSentryRequest (Ljavax/servlet/http/HttpServletRequest;)Lio/sentry/protocol/Request; } public class io/sentry/spring/SentrySpringFilter : org/springframework/web/filter/OncePerRequestFilter { public fun ()V - public fun (Lio/sentry/IHub;)V - public fun (Lio/sentry/IHub;Lio/sentry/spring/SentryRequestResolver;Lio/sentry/spring/tracing/TransactionNameProvider;)V + public fun (Lio/sentry/IScopes;)V + public fun (Lio/sentry/IScopes;Lio/sentry/spring/SentryRequestResolver;Lio/sentry/spring/tracing/TransactionNameProvider;)V protected fun doFilterInternal (Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;Ljavax/servlet/FilterChain;)V } @@ -69,7 +69,7 @@ public final class io/sentry/spring/SentryTaskDecorator : org/springframework/co } public class io/sentry/spring/SentryUserFilter : org/springframework/web/filter/OncePerRequestFilter { - public fun (Lio/sentry/IHub;Ljava/util/List;)V + public fun (Lio/sentry/IScopes;Ljava/util/List;)V protected fun doFilterInternal (Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;Ljavax/servlet/FilterChain;)V public fun getSentryUserProviders ()Ljava/util/List; } @@ -96,7 +96,7 @@ public abstract interface annotation class io/sentry/spring/checkin/SentryCheckI public class io/sentry/spring/checkin/SentryCheckInAdvice : org/aopalliance/intercept/MethodInterceptor, org/springframework/context/EmbeddedValueResolverAware { public fun ()V - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun invoke (Lorg/aopalliance/intercept/MethodInvocation;)Ljava/lang/Object; public fun setEmbeddedValueResolver (Lorg/springframework/util/StringValueResolver;)V } @@ -127,7 +127,7 @@ public abstract interface annotation class io/sentry/spring/exception/SentryCapt public class io/sentry/spring/exception/SentryCaptureExceptionParameterAdvice : org/aopalliance/intercept/MethodInterceptor { public fun ()V - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun invoke (Lorg/aopalliance/intercept/MethodInvocation;)Ljava/lang/Object; } @@ -169,7 +169,7 @@ public final class io/sentry/spring/graphql/SentryDataFetcherExceptionResolverAd public final class io/sentry/spring/graphql/SentryDgsSubscriptionHandler : io/sentry/graphql/SentrySubscriptionHandler { public fun ()V - public fun onSubscriptionResult (Ljava/lang/Object;Lio/sentry/IHub;Lio/sentry/graphql/ExceptionReporter;Lgraphql/execution/instrumentation/parameters/InstrumentationFieldFetchParameters;)Ljava/lang/Object; + public fun onSubscriptionResult (Ljava/lang/Object;Lio/sentry/IScopes;Lio/sentry/graphql/ExceptionReporter;Lgraphql/execution/instrumentation/parameters/InstrumentationFieldFetchParameters;)Ljava/lang/Object; } public final class io/sentry/spring/graphql/SentryGraphqlBeanPostProcessor : org/springframework/beans/factory/config/BeanPostProcessor, org/springframework/core/PriorityOrdered { @@ -188,7 +188,7 @@ public class io/sentry/spring/graphql/SentryGraphqlConfiguration { public final class io/sentry/spring/graphql/SentrySpringSubscriptionHandler : io/sentry/graphql/SentrySubscriptionHandler { public fun ()V - public fun onSubscriptionResult (Ljava/lang/Object;Lio/sentry/IHub;Lio/sentry/graphql/ExceptionReporter;Lgraphql/execution/instrumentation/parameters/InstrumentationFieldFetchParameters;)Ljava/lang/Object; + public fun onSubscriptionResult (Ljava/lang/Object;Lio/sentry/IScopes;Lio/sentry/graphql/ExceptionReporter;Lgraphql/execution/instrumentation/parameters/InstrumentationFieldFetchParameters;)Ljava/lang/Object; } public class io/sentry/spring/tracing/SentryAdviceConfiguration { @@ -207,17 +207,17 @@ public abstract interface annotation class io/sentry/spring/tracing/SentrySpan : public class io/sentry/spring/tracing/SentrySpanAdvice : org/aopalliance/intercept/MethodInterceptor { public fun ()V - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun invoke (Lorg/aopalliance/intercept/MethodInvocation;)Ljava/lang/Object; } public class io/sentry/spring/tracing/SentrySpanClientHttpRequestInterceptor : org/springframework/http/client/ClientHttpRequestInterceptor { - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun intercept (Lorg/springframework/http/HttpRequest;[BLorg/springframework/http/client/ClientHttpRequestExecution;)Lorg/springframework/http/client/ClientHttpResponse; } public class io/sentry/spring/tracing/SentrySpanClientWebRequestFilter : org/springframework/web/reactive/function/client/ExchangeFilterFunction { - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun filter (Lorg/springframework/web/reactive/function/client/ClientRequest;Lorg/springframework/web/reactive/function/client/ExchangeFunction;)Lreactor/core/publisher/Mono; } @@ -232,8 +232,8 @@ public class io/sentry/spring/tracing/SentryTracingConfiguration { public class io/sentry/spring/tracing/SentryTracingFilter : org/springframework/web/filter/OncePerRequestFilter { public fun ()V - public fun (Lio/sentry/IHub;)V - public fun (Lio/sentry/IHub;Lio/sentry/spring/tracing/TransactionNameProvider;)V + public fun (Lio/sentry/IScopes;)V + public fun (Lio/sentry/IScopes;Lio/sentry/spring/tracing/TransactionNameProvider;)V protected fun doFilterInternal (Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;Ljavax/servlet/FilterChain;)V } @@ -245,7 +245,7 @@ public abstract interface annotation class io/sentry/spring/tracing/SentryTransa public class io/sentry/spring/tracing/SentryTransactionAdvice : org/aopalliance/intercept/MethodInterceptor { public fun ()V - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun invoke (Lorg/aopalliance/intercept/MethodInvocation;)Ljava/lang/Object; } @@ -266,7 +266,7 @@ public abstract interface class io/sentry/spring/tracing/TransactionNameProvider } public class io/sentry/spring/webflux/SentryRequestResolver { - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun resolveSentryRequest (Lorg/springframework/http/server/reactive/ServerHttpRequest;)Lio/sentry/protocol/Request; } @@ -278,13 +278,14 @@ public final class io/sentry/spring/webflux/SentryScheduleHook : java/util/funct public final class io/sentry/spring/webflux/SentryWebExceptionHandler : org/springframework/web/server/WebExceptionHandler { public static final field MECHANISM_TYPE Ljava/lang/String; - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun handle (Lorg/springframework/web/server/ServerWebExchange;Ljava/lang/Throwable;)Lreactor/core/publisher/Mono; } public final class io/sentry/spring/webflux/SentryWebFilter : org/springframework/web/server/WebFilter { public static final field SENTRY_HUB_KEY Ljava/lang/String; - public fun (Lio/sentry/IHub;)V + public static final field SENTRY_SCOPES_KEY Ljava/lang/String; + public fun (Lio/sentry/IScopes;)V public fun filter (Lorg/springframework/web/server/ServerWebExchange;Lorg/springframework/web/server/WebFilterChain;)Lreactor/core/publisher/Mono; } diff --git a/sentry-spring/src/main/java/io/sentry/spring/SentryExceptionResolver.java b/sentry-spring/src/main/java/io/sentry/spring/SentryExceptionResolver.java index fc9da87933..ba0586eade 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/SentryExceptionResolver.java +++ b/sentry-spring/src/main/java/io/sentry/spring/SentryExceptionResolver.java @@ -5,7 +5,7 @@ import com.jakewharton.nopen.annotation.Open; import io.sentry.Hint; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.SentryEvent; import io.sentry.SentryLevel; import io.sentry.exception.ExceptionMechanismException; @@ -29,15 +29,15 @@ public class SentryExceptionResolver implements HandlerExceptionResolver, Ordered { public static final String MECHANISM_TYPE = "Spring5ExceptionResolver"; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @NotNull TransactionNameProvider transactionNameProvider; private final int order; public SentryExceptionResolver( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull TransactionNameProvider transactionNameProvider, final int order) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); this.transactionNameProvider = Objects.requireNonNull(transactionNameProvider, "transactionNameProvider is required"); this.order = order; @@ -53,7 +53,7 @@ public SentryExceptionResolver( final SentryEvent event = createEvent(request, ex); final Hint hint = createHint(request, response); - hub.captureEvent(event, hint); + scopes.captureEvent(event, hint); // null = run other HandlerExceptionResolvers to actually handle the exception return null; diff --git a/sentry-spring/src/main/java/io/sentry/spring/SentryHubRegistrar.java b/sentry-spring/src/main/java/io/sentry/spring/SentryHubRegistrar.java index e597d175b6..195a88e277 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/SentryHubRegistrar.java +++ b/sentry-spring/src/main/java/io/sentry/spring/SentryHubRegistrar.java @@ -1,7 +1,7 @@ package io.sentry.spring; import com.jakewharton.nopen.annotation.Open; -import io.sentry.HubAdapter; +import io.sentry.ScopesAdapter; import io.sentry.SentryIntegrationPackageStorage; import io.sentry.SentryOptions; import io.sentry.protocol.SdkVersion; @@ -60,7 +60,7 @@ private void registerSentryOptions( private void registerSentryHubBean(final @NotNull BeanDefinitionRegistry registry) { final BeanDefinitionBuilder builder = - BeanDefinitionBuilder.genericBeanDefinition(HubAdapter.class); + BeanDefinitionBuilder.genericBeanDefinition(ScopesAdapter.class); builder.setInitMethodName("getInstance"); registry.registerBeanDefinition("sentryHub", builder.getBeanDefinition()); diff --git a/sentry-spring/src/main/java/io/sentry/spring/SentryInitBeanPostProcessor.java b/sentry-spring/src/main/java/io/sentry/spring/SentryInitBeanPostProcessor.java index 9e455dfb04..ca431aae14 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/SentryInitBeanPostProcessor.java +++ b/sentry-spring/src/main/java/io/sentry/spring/SentryInitBeanPostProcessor.java @@ -2,10 +2,10 @@ import com.jakewharton.nopen.annotation.Open; import io.sentry.EventProcessor; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ITransportFactory; import io.sentry.Integration; +import io.sentry.ScopesAdapter; import io.sentry.Sentry; import io.sentry.SentryOptions; import io.sentry.SentryOptions.TracesSamplerCallback; @@ -27,15 +27,15 @@ public class SentryInitBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware, DisposableBean { private @Nullable ApplicationContext applicationContext; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; public SentryInitBeanPostProcessor() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } - SentryInitBeanPostProcessor(final @NotNull IHub hub) { - Objects.requireNonNull(hub, "hub is required"); - this.hub = hub; + SentryInitBeanPostProcessor(final @NotNull IScopes scopes) { + Objects.requireNonNull(scopes, "scopes are required"); + this.scopes = scopes; } @Override @@ -86,6 +86,6 @@ public void setApplicationContext(final @NotNull ApplicationContext applicationC @Override public void destroy() { - hub.close(); + scopes.close(); } } diff --git a/sentry-spring/src/main/java/io/sentry/spring/SentryRequestResolver.java b/sentry-spring/src/main/java/io/sentry/spring/SentryRequestResolver.java index 442644fcac..2d9e2996f7 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/SentryRequestResolver.java +++ b/sentry-spring/src/main/java/io/sentry/spring/SentryRequestResolver.java @@ -1,7 +1,7 @@ package io.sentry.spring; import com.jakewharton.nopen.annotation.Open; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.SentryLevel; import io.sentry.protocol.Request; import io.sentry.util.HttpUtils; @@ -20,11 +20,11 @@ @Open public class SentryRequestResolver { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private volatile @Nullable List extraSecurityCookies; - public SentryRequestResolver(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "options is required"); + public SentryRequestResolver(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } // httpRequest.getRequestURL() returns StringBuffer which is considered an obsolete class. @@ -40,7 +40,7 @@ public SentryRequestResolver(final @NotNull IHub hub) { extractSecurityCookieNamesOrUseCached(httpRequest); sentryRequest.setHeaders(resolveHeadersMap(httpRequest, additionalSecurityCookieNames)); - if (hub.getOptions().isSendDefaultPii()) { + if (scopes.getOptions().isSendDefaultPii()) { String cookieName = HttpUtils.COOKIE_HEADER_NAME; final @Nullable List filteredHeaders = HttpUtils.filterOutSecurityCookiesFromHeader( @@ -57,7 +57,8 @@ Map resolveHeadersMap( final Map headersMap = new HashMap<>(); for (String headerName : Collections.list(request.getHeaderNames())) { // do not copy personal information identifiable headers - if (hub.getOptions().isSendDefaultPii() || !HttpUtils.containsSensitiveHeader(headerName)) { + if (scopes.getOptions().isSendDefaultPii() + || !HttpUtils.containsSensitiveHeader(headerName)) { final @Nullable List filteredHeaders = HttpUtils.filterOutSecurityCookiesFromHeader( request.getHeaders(headerName), headerName, additionalSecurityCookieNames); @@ -94,7 +95,8 @@ private List extractSecurityCookieNames(final @NotNull HttpServletReques } } } catch (Throwable t) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log(SentryLevel.WARNING, "Failed to extract session cookie name from request.", t); } diff --git a/sentry-spring/src/main/java/io/sentry/spring/SentrySpringFilter.java b/sentry-spring/src/main/java/io/sentry/spring/SentrySpringFilter.java index 8fd8180941..7695545f04 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/SentrySpringFilter.java +++ b/sentry-spring/src/main/java/io/sentry/spring/SentrySpringFilter.java @@ -8,8 +8,8 @@ import io.sentry.Breadcrumb; import io.sentry.EventProcessor; import io.sentry.Hint; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; +import io.sentry.ScopesAdapter; import io.sentry.SentryEvent; import io.sentry.SentryLevel; import io.sentry.SentryOptions; @@ -29,26 +29,26 @@ @Open public class SentrySpringFilter extends OncePerRequestFilter { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @NotNull SentryRequestResolver requestResolver; private final @NotNull TransactionNameProvider transactionNameProvider; public SentrySpringFilter( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull SentryRequestResolver requestResolver, final @NotNull TransactionNameProvider transactionNameProvider) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); this.requestResolver = Objects.requireNonNull(requestResolver, "requestResolver is required"); this.transactionNameProvider = Objects.requireNonNull(transactionNameProvider, "transactionNameProvider is required"); } - public SentrySpringFilter(final @NotNull IHub hub) { - this(hub, new SentryRequestResolver(hub), new SpringMvcTransactionNameProvider()); + public SentrySpringFilter(final @NotNull IScopes scopes) { + this(scopes, new SentryRequestResolver(scopes), new SpringMvcTransactionNameProvider()); } public SentrySpringFilter() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } @Override @@ -57,20 +57,20 @@ protected void doFilterInternal( final @NotNull HttpServletResponse response, final @NotNull FilterChain filterChain) throws ServletException, IOException { - if (hub.isEnabled()) { + if (scopes.isEnabled()) { // request may qualify for caching request body, if so resolve cached request final HttpServletRequest request = resolveHttpServletRequest(servletRequest); - hub.pushScope(); + scopes.pushScope(); try { final Hint hint = new Hint(); hint.set(SPRING_REQUEST_FILTER_REQUEST, servletRequest); hint.set(SPRING_REQUEST_FILTER_RESPONSE, response); - hub.addBreadcrumb(Breadcrumb.http(request.getRequestURI(), request.getMethod()), hint); + scopes.addBreadcrumb(Breadcrumb.http(request.getRequestURI(), request.getMethod()), hint); configureScope(request); filterChain.doFilter(request, response); } finally { - hub.popScope(); + scopes.popScope(); } } else { filterChain.doFilter(servletRequest, response); @@ -79,7 +79,7 @@ protected void doFilterInternal( private void configureScope(HttpServletRequest request) { try { - hub.configureScope( + scopes.configureScope( scope -> { // set basic request information on the scope scope.setRequest(requestResolver.resolveSentryRequest(request)); @@ -92,11 +92,12 @@ private void configureScope(HttpServletRequest request) { // request processing if (request instanceof CachedBodyHttpServletRequest) { scope.addEventProcessor( - new RequestBodyExtractingEventProcessor(request, hub.getOptions())); + new RequestBodyExtractingEventProcessor(request, scopes.getOptions())); } }); } catch (Throwable e) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log(SentryLevel.ERROR, "Failed to set scope for HTTP request", e); } @@ -104,12 +105,13 @@ private void configureScope(HttpServletRequest request) { private @NotNull HttpServletRequest resolveHttpServletRequest( final @NotNull HttpServletRequest request) { - if (hub.getOptions().isSendDefaultPii() - && qualifiesForCaching(request, hub.getOptions().getMaxRequestBodySize())) { + if (scopes.getOptions().isSendDefaultPii() + && qualifiesForCaching(request, scopes.getOptions().getMaxRequestBodySize())) { try { return new CachedBodyHttpServletRequest(request); } catch (IOException e) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.WARNING, diff --git a/sentry-spring/src/main/java/io/sentry/spring/SentryTaskDecorator.java b/sentry-spring/src/main/java/io/sentry/spring/SentryTaskDecorator.java index cb4a700696..88d205a57e 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/SentryTaskDecorator.java +++ b/sentry-spring/src/main/java/io/sentry/spring/SentryTaskDecorator.java @@ -1,6 +1,6 @@ package io.sentry.spring; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.Sentry; import java.util.concurrent.Callable; import org.jetbrains.annotations.NotNull; @@ -9,21 +9,23 @@ /** * Sets a current hub on a thread running a {@link Runnable} given by parameter. Used to propagate - * the current {@link IHub} on the thread executing async task - like MVC controller methods + * the current {@link IScopes} on the thread executing async task - like MVC controller methods * returning a {@link Callable} or Spring beans methods annotated with {@link Async}. */ public final class SentryTaskDecorator implements TaskDecorator { @Override + @SuppressWarnings("deprecation") public @NotNull Runnable decorate(final @NotNull Runnable runnable) { - final IHub newHub = Sentry.getCurrentHub().clone(); + // TODO fork instead + final IScopes newHub = Sentry.getCurrentScopes().clone(); return () -> { - final IHub oldState = Sentry.getCurrentHub(); - Sentry.setCurrentHub(newHub); + final IScopes oldState = Sentry.getCurrentScopes(); + Sentry.setCurrentScopes(newHub); try { runnable.run(); } finally { - Sentry.setCurrentHub(oldState); + Sentry.setCurrentScopes(oldState); } }; } diff --git a/sentry-spring/src/main/java/io/sentry/spring/SentryUserFilter.java b/sentry-spring/src/main/java/io/sentry/spring/SentryUserFilter.java index 55c5826d40..e0b4e9c1ba 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/SentryUserFilter.java +++ b/sentry-spring/src/main/java/io/sentry/spring/SentryUserFilter.java @@ -1,8 +1,8 @@ package io.sentry.spring; import com.jakewharton.nopen.annotation.Open; -import io.sentry.IHub; import io.sentry.IScope; +import io.sentry.IScopes; import io.sentry.IpAddressUtils; import io.sentry.protocol.User; import io.sentry.util.Objects; @@ -26,12 +26,12 @@ */ @Open public class SentryUserFilter extends OncePerRequestFilter { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @NotNull List sentryUserProviders; public SentryUserFilter( - final @NotNull IHub hub, final @NotNull List sentryUserProviders) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + final @NotNull IScopes scopes, final @NotNull List sentryUserProviders) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); this.sentryUserProviders = Objects.requireNonNull(sentryUserProviders, "sentryUserProviders list is required"); } @@ -46,13 +46,13 @@ protected void doFilterInternal( for (final SentryUserProvider provider : sentryUserProviders) { apply(user, provider.provideUser()); } - if (hub.getOptions().isSendDefaultPii()) { + if (scopes.getOptions().isSendDefaultPii()) { if (IpAddressUtils.isDefault(user.getIpAddress())) { // unset {{auto}} as it would set the server's ip address as a user ip address user.setIpAddress(null); } } - hub.setUser(user); + scopes.setUser(user); chain.doFilter(request, response); } diff --git a/sentry-spring/src/main/java/io/sentry/spring/checkin/SentryCheckInAdvice.java b/sentry-spring/src/main/java/io/sentry/spring/checkin/SentryCheckInAdvice.java index c29ad44900..edae74c2ac 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/checkin/SentryCheckInAdvice.java +++ b/sentry-spring/src/main/java/io/sentry/spring/checkin/SentryCheckInAdvice.java @@ -4,8 +4,8 @@ import io.sentry.CheckIn; import io.sentry.CheckInStatus; import io.sentry.DateUtils; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; +import io.sentry.ScopesAdapter; import io.sentry.SentryLevel; import io.sentry.protocol.SentryId; import io.sentry.util.Objects; @@ -30,16 +30,16 @@ @ApiStatus.Experimental @Open public class SentryCheckInAdvice implements MethodInterceptor, EmbeddedValueResolverAware { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private @Nullable StringValueResolver resolver; public SentryCheckInAdvice() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } - public SentryCheckInAdvice(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentryCheckInAdvice(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } @Override @@ -69,7 +69,8 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl // Sentry should alert the user about missed checkins in this case since the monitor slug // won't match // what is configured in Sentry. - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.WARNING, @@ -79,7 +80,8 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl } if (ObjectUtils.isEmpty(monitorSlug)) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.WARNING, @@ -87,8 +89,8 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl return invocation.proceed(); } - hub.pushScope(); - TracingUtils.startNewTrace(hub); + scopes.pushScope(); + TracingUtils.startNewTrace(scopes); @Nullable SentryId checkInId = null; final long startTime = System.currentTimeMillis(); @@ -96,7 +98,7 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl try { if (!isHeartbeatOnly) { - checkInId = hub.captureCheckIn(new CheckIn(monitorSlug, CheckInStatus.IN_PROGRESS)); + checkInId = scopes.captureCheckIn(new CheckIn(monitorSlug, CheckInStatus.IN_PROGRESS)); } return invocation.proceed(); } catch (Throwable e) { @@ -106,8 +108,8 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl final @NotNull CheckInStatus status = didError ? CheckInStatus.ERROR : CheckInStatus.OK; CheckIn checkIn = new CheckIn(checkInId, monitorSlug, status); checkIn.setDuration(DateUtils.millisToSeconds(System.currentTimeMillis() - startTime)); - hub.captureCheckIn(checkIn); - hub.popScope(); + scopes.captureCheckIn(checkIn); + scopes.popScope(); } } diff --git a/sentry-spring/src/main/java/io/sentry/spring/exception/SentryCaptureExceptionParameterAdvice.java b/sentry-spring/src/main/java/io/sentry/spring/exception/SentryCaptureExceptionParameterAdvice.java index bababbce77..119f39ba6c 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/exception/SentryCaptureExceptionParameterAdvice.java +++ b/sentry-spring/src/main/java/io/sentry/spring/exception/SentryCaptureExceptionParameterAdvice.java @@ -1,8 +1,8 @@ package io.sentry.spring.exception; import com.jakewharton.nopen.annotation.Open; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; +import io.sentry.ScopesAdapter; import io.sentry.exception.ExceptionMechanismException; import io.sentry.protocol.Mechanism; import io.sentry.util.Objects; @@ -22,14 +22,14 @@ @Open public class SentryCaptureExceptionParameterAdvice implements MethodInterceptor { private static final String MECHANISM_TYPE = "SentrySpring5CaptureExceptionParameterAdvice"; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; public SentryCaptureExceptionParameterAdvice() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } - public SentryCaptureExceptionParameterAdvice(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentryCaptureExceptionParameterAdvice(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } @Override @@ -58,6 +58,6 @@ private void captureException(final @NotNull Throwable throwable) { mechanism.setHandled(true); final Throwable mechanismException = new ExceptionMechanismException(mechanism, throwable, Thread.currentThread()); - hub.captureException(mechanismException); + scopes.captureException(mechanismException); } } diff --git a/sentry-spring/src/main/java/io/sentry/spring/graphql/SentryBatchLoaderRegistry.java b/sentry-spring/src/main/java/io/sentry/spring/graphql/SentryBatchLoaderRegistry.java index 62a8669f89..f1d8717598 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/graphql/SentryBatchLoaderRegistry.java +++ b/sentry-spring/src/main/java/io/sentry/spring/graphql/SentryBatchLoaderRegistry.java @@ -1,11 +1,11 @@ package io.sentry.spring.graphql; -import static io.sentry.graphql.SentryInstrumentation.SENTRY_HUB_CONTEXT_KEY; +import static io.sentry.graphql.SentryInstrumentation.SENTRY_SCOPES_CONTEXT_KEY; import graphql.GraphQLContext; import io.sentry.Breadcrumb; -import io.sentry.IHub; -import io.sentry.NoOpHub; +import io.sentry.IScopes; +import io.sentry.NoOpScopes; import java.util.List; import java.util.Map; import java.util.Set; @@ -89,7 +89,7 @@ public BatchLoaderRegistry.RegistrationSpec withOptions(DataLoaderOptions public void registerBatchLoader(BiFunction, BatchLoaderEnvironment, Flux> loader) { delegate.registerBatchLoader( (keys, batchLoaderEnvironment) -> { - hubFromContext(batchLoaderEnvironment) + scopesFromContext(batchLoaderEnvironment) .addBreadcrumb(Breadcrumb.graphqlDataLoader(keys, keyType, valueType, name)); return loader.apply(keys, batchLoaderEnvironment); }); @@ -100,20 +100,20 @@ public void registerMappedBatchLoader( BiFunction, BatchLoaderEnvironment, Mono>> loader) { delegate.registerMappedBatchLoader( (keys, batchLoaderEnvironment) -> { - hubFromContext(batchLoaderEnvironment) + scopesFromContext(batchLoaderEnvironment) .addBreadcrumb(Breadcrumb.graphqlDataLoader(keys, keyType, valueType, name)); return loader.apply(keys, batchLoaderEnvironment); }); } - private @NotNull IHub hubFromContext(final @NotNull BatchLoaderEnvironment environment) { + private @NotNull IScopes scopesFromContext(final @NotNull BatchLoaderEnvironment environment) { Object context = environment.getContext(); if (context instanceof GraphQLContext) { GraphQLContext graphqlContext = (GraphQLContext) context; - return graphqlContext.getOrDefault(SENTRY_HUB_CONTEXT_KEY, NoOpHub.getInstance()); + return graphqlContext.getOrDefault(SENTRY_SCOPES_CONTEXT_KEY, NoOpScopes.getInstance()); } - return NoOpHub.getInstance(); + return NoOpScopes.getInstance(); } } } diff --git a/sentry-spring/src/main/java/io/sentry/spring/graphql/SentryDgsSubscriptionHandler.java b/sentry-spring/src/main/java/io/sentry/spring/graphql/SentryDgsSubscriptionHandler.java index fb4e09e889..eef5fdae69 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/graphql/SentryDgsSubscriptionHandler.java +++ b/sentry-spring/src/main/java/io/sentry/spring/graphql/SentryDgsSubscriptionHandler.java @@ -1,7 +1,7 @@ package io.sentry.spring.graphql; import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.SentryIntegrationPackageStorage; import io.sentry.graphql.ExceptionReporter; import io.sentry.graphql.SentrySubscriptionHandler; @@ -17,7 +17,7 @@ public SentryDgsSubscriptionHandler() { @Override public @NotNull Object onSubscriptionResult( final @NotNull Object result, - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull ExceptionReporter exceptionReporter, final @NotNull InstrumentationFieldFetchParameters parameters) { if (result instanceof Flux) { @@ -25,7 +25,7 @@ public SentryDgsSubscriptionHandler() { return flux.doOnError( throwable -> { final @NotNull ExceptionReporter.ExceptionDetails exceptionDetails = - new ExceptionReporter.ExceptionDetails(hub, parameters.getEnvironment(), true); + new ExceptionReporter.ExceptionDetails(scopes, parameters.getEnvironment(), true); exceptionReporter.captureThrowable(throwable, exceptionDetails, null); }); } diff --git a/sentry-spring/src/main/java/io/sentry/spring/graphql/SentrySpringSubscriptionHandler.java b/sentry-spring/src/main/java/io/sentry/spring/graphql/SentrySpringSubscriptionHandler.java index a7809eb230..b3f0b9830e 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/graphql/SentrySpringSubscriptionHandler.java +++ b/sentry-spring/src/main/java/io/sentry/spring/graphql/SentrySpringSubscriptionHandler.java @@ -1,7 +1,7 @@ package io.sentry.spring.graphql; import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.graphql.ExceptionReporter; import io.sentry.graphql.SentrySubscriptionHandler; import org.jetbrains.annotations.NotNull; @@ -13,7 +13,7 @@ public final class SentrySpringSubscriptionHandler implements SentrySubscription @Override public @NotNull Object onSubscriptionResult( final @NotNull Object result, - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull ExceptionReporter exceptionReporter, final @NotNull InstrumentationFieldFetchParameters parameters) { if (result instanceof Flux) { @@ -21,7 +21,7 @@ public final class SentrySpringSubscriptionHandler implements SentrySubscription return flux.doOnError( throwable -> { final @NotNull ExceptionReporter.ExceptionDetails exceptionDetails = - new ExceptionReporter.ExceptionDetails(hub, parameters.getEnvironment(), true); + new ExceptionReporter.ExceptionDetails(scopes, parameters.getEnvironment(), true); if (throwable instanceof SubscriptionPublisherException && throwable.getCause() != null) { exceptionReporter.captureThrowable(throwable.getCause(), exceptionDetails, null); diff --git a/sentry-spring/src/main/java/io/sentry/spring/tracing/SentrySpanAdvice.java b/sentry-spring/src/main/java/io/sentry/spring/tracing/SentrySpanAdvice.java index 96c4275836..c1b7305d4f 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/tracing/SentrySpanAdvice.java +++ b/sentry-spring/src/main/java/io/sentry/spring/tracing/SentrySpanAdvice.java @@ -1,9 +1,9 @@ package io.sentry.spring.tracing; import com.jakewharton.nopen.annotation.Open; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ISpan; +import io.sentry.ScopesAdapter; import io.sentry.SpanStatus; import io.sentry.util.Objects; import java.lang.reflect.Method; @@ -22,20 +22,20 @@ @Open public class SentrySpanAdvice implements MethodInterceptor { private static final String TRACE_ORIGIN = "auto.function.spring.advice"; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; public SentrySpanAdvice() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } - public SentrySpanAdvice(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentrySpanAdvice(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } @SuppressWarnings("deprecation") @Override public Object invoke(final @NotNull MethodInvocation invocation) throws Throwable { - final ISpan activeSpan = hub.getSpan(); + final ISpan activeSpan = scopes.getSpan(); if (activeSpan == null || activeSpan.isNoOp()) { // there is no active transaction, we do not start new span diff --git a/sentry-spring/src/main/java/io/sentry/spring/tracing/SentrySpanClientHttpRequestInterceptor.java b/sentry-spring/src/main/java/io/sentry/spring/tracing/SentrySpanClientHttpRequestInterceptor.java index 4067c69c8c..bdf8417642 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/tracing/SentrySpanClientHttpRequestInterceptor.java +++ b/sentry-spring/src/main/java/io/sentry/spring/tracing/SentrySpanClientHttpRequestInterceptor.java @@ -8,7 +8,7 @@ import io.sentry.BaggageHeader; import io.sentry.Breadcrumb; import io.sentry.Hint; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ISpan; import io.sentry.SpanDataConvention; import io.sentry.SpanStatus; @@ -27,10 +27,10 @@ @Open public class SentrySpanClientHttpRequestInterceptor implements ClientHttpRequestInterceptor { private static final String TRACE_ORIGIN = "auto.http.spring.resttemplate"; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; - public SentrySpanClientHttpRequestInterceptor(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentrySpanClientHttpRequestInterceptor(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } @Override @@ -42,7 +42,7 @@ public SentrySpanClientHttpRequestInterceptor(final @NotNull IHub hub) { Integer responseStatusCode = null; ClientHttpResponse response = null; try { - final ISpan activeSpan = hub.getSpan(); + final ISpan activeSpan = scopes.getSpan(); if (activeSpan == null) { maybeAddTracingHeaders(request, null); return execution.execute(request, body); @@ -83,7 +83,7 @@ private void maybeAddTracingHeaders( final @NotNull HttpRequest request, final @Nullable ISpan span) { final @Nullable TracingUtils.TracingHeaders tracingHeaders = TracingUtils.traceIfAllowed( - hub, + scopes, request.getURI().toString(), request.getHeaders().get(BaggageHeader.BAGGAGE_HEADER), span); @@ -120,6 +120,6 @@ private void addBreadcrumb( hint.set(SPRING_REQUEST_INTERCEPTOR_RESPONSE, response); } - hub.addBreadcrumb(breadcrumb, hint); + scopes.addBreadcrumb(breadcrumb, hint); } } diff --git a/sentry-spring/src/main/java/io/sentry/spring/tracing/SentrySpanClientWebRequestFilter.java b/sentry-spring/src/main/java/io/sentry/spring/tracing/SentrySpanClientWebRequestFilter.java index 00ad91bbb0..c526cb64cc 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/tracing/SentrySpanClientWebRequestFilter.java +++ b/sentry-spring/src/main/java/io/sentry/spring/tracing/SentrySpanClientWebRequestFilter.java @@ -7,7 +7,7 @@ import io.sentry.BaggageHeader; import io.sentry.Breadcrumb; import io.sentry.Hint; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ISpan; import io.sentry.SpanDataConvention; import io.sentry.SpanStatus; @@ -26,16 +26,16 @@ @Open public class SentrySpanClientWebRequestFilter implements ExchangeFilterFunction { private static final String TRACE_ORIGIN = "auto.http.spring.webclient"; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; - public SentrySpanClientWebRequestFilter(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentrySpanClientWebRequestFilter(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } @Override public @NotNull Mono filter( final @NotNull ClientRequest request, final @NotNull ExchangeFunction next) { - final ISpan activeSpan = hub.getSpan(); + final ISpan activeSpan = scopes.getSpan(); if (activeSpan == null) { addBreadcrumb(request, null); return next.exchange(maybeAddHeaders(request, null)); @@ -76,7 +76,7 @@ private ClientRequest maybeAddHeaders( final @Nullable TracingUtils.TracingHeaders tracingHeaders = TracingUtils.traceIfAllowed( - hub, + scopes, request.url().toString(), request.headers().get(BaggageHeader.BAGGAGE_HEADER), span); @@ -113,6 +113,6 @@ private void addBreadcrumb( hint.set(SPRING_EXCHANGE_FILTER_RESPONSE, response); } - hub.addBreadcrumb(breadcrumb, hint); + scopes.addBreadcrumb(breadcrumb, hint); } } diff --git a/sentry-spring/src/main/java/io/sentry/spring/tracing/SentryTracingFilter.java b/sentry-spring/src/main/java/io/sentry/spring/tracing/SentryTracingFilter.java index 5af329f600..50cdb8dc3a 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/tracing/SentryTracingFilter.java +++ b/sentry-spring/src/main/java/io/sentry/spring/tracing/SentryTracingFilter.java @@ -3,9 +3,9 @@ import com.jakewharton.nopen.annotation.Open; import io.sentry.BaggageHeader; import io.sentry.CustomSamplingContext; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ITransaction; +import io.sentry.ScopesAdapter; import io.sentry.SentryTraceHeader; import io.sentry.SpanStatus; import io.sentry.TransactionContext; @@ -35,7 +35,7 @@ public class SentryTracingFilter extends OncePerRequestFilter { private static final String TRACE_ORIGIN = "auto.http.spring.webmvc"; private final @NotNull TransactionNameProvider transactionNameProvider; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; /** * Creates filter that resolves transaction name using {@link SpringMvcTransactionNameProvider}. @@ -46,25 +46,26 @@ public class SentryTracingFilter extends OncePerRequestFilter { * javax.servlet.Filter}. */ public SentryTracingFilter() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } /** * Creates filter that resolves transaction name using transaction name provider given by * parameter. * - * @param hub - the hub + * @param scopes - the scopes * @param transactionNameProvider - transaction name provider. */ public SentryTracingFilter( - final @NotNull IHub hub, final @NotNull TransactionNameProvider transactionNameProvider) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + final @NotNull IScopes scopes, + final @NotNull TransactionNameProvider transactionNameProvider) { + this.scopes = Objects.requireNonNull(scopes, "scopes is required"); this.transactionNameProvider = Objects.requireNonNull(transactionNameProvider, "transactionNameProvider is required"); } - public SentryTracingFilter(final @NotNull IHub hub) { - this(hub, new SpringMvcTransactionNameProvider()); + public SentryTracingFilter(final @NotNull IScopes scopes) { + this(scopes, new SpringMvcTransactionNameProvider()); } @Override @@ -74,15 +75,15 @@ protected void doFilterInternal( final @NotNull FilterChain filterChain) throws ServletException, IOException { - if (hub.isEnabled()) { + if (scopes.isEnabled()) { final @Nullable String sentryTraceHeader = httpRequest.getHeader(SentryTraceHeader.SENTRY_TRACE_HEADER); final @Nullable List baggageHeader = Collections.list(httpRequest.getHeaders(BaggageHeader.BAGGAGE_HEADER)); final @Nullable TransactionContext transactionContext = - hub.continueTrace(sentryTraceHeader, baggageHeader); + scopes.continueTrace(sentryTraceHeader, baggageHeader); - if (hub.getOptions().isTracingEnabled() && shouldTraceRequest(httpRequest)) { + if (scopes.getOptions().isTracingEnabled() && shouldTraceRequest(httpRequest)) { doFilterWithTransaction(httpRequest, httpResponse, filterChain, transactionContext); } else { filterChain.doFilter(httpRequest, httpResponse); @@ -129,7 +130,7 @@ private void doFilterWithTransaction( } private boolean shouldTraceRequest(final @NotNull HttpServletRequest request) { - return hub.getOptions().isTraceOptionsRequests() + return scopes.getOptions().isTraceOptionsRequests() || !HttpMethod.OPTIONS.name().equals(request.getMethod()); } @@ -151,14 +152,14 @@ private ITransaction startTransaction( transactionOptions.setCustomSamplingContext(customSamplingContext); transactionOptions.setBindToScope(true); - return hub.startTransaction(transactionContext, transactionOptions); + return scopes.startTransaction(transactionContext, transactionOptions); } final TransactionOptions transactionOptions = new TransactionOptions(); transactionOptions.setCustomSamplingContext(customSamplingContext); transactionOptions.setBindToScope(true); - return hub.startTransaction( + return scopes.startTransaction( new TransactionContext(name, TransactionNameSource.URL, "http.server"), transactionOptions); } } diff --git a/sentry-spring/src/main/java/io/sentry/spring/tracing/SentryTransactionAdvice.java b/sentry-spring/src/main/java/io/sentry/spring/tracing/SentryTransactionAdvice.java index c417f14a14..8f4f5bbdfc 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/tracing/SentryTransactionAdvice.java +++ b/sentry-spring/src/main/java/io/sentry/spring/tracing/SentryTransactionAdvice.java @@ -1,9 +1,9 @@ package io.sentry.spring.tracing; import com.jakewharton.nopen.annotation.Open; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ITransaction; +import io.sentry.ScopesAdapter; import io.sentry.SpanStatus; import io.sentry.TransactionContext; import io.sentry.TransactionOptions; @@ -27,14 +27,14 @@ @Open public class SentryTransactionAdvice implements MethodInterceptor { private static final String TRACE_ORIGIN = "auto.function.spring.advice"; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; public SentryTransactionAdvice() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } - public SentryTransactionAdvice(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentryTransactionAdvice(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } @SuppressWarnings("deprecation") @@ -67,11 +67,11 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl } else { operation = "bean"; } - hub.pushScope(); + scopes.pushScope(); final TransactionOptions transactionOptions = new TransactionOptions(); transactionOptions.setBindToScope(true); final ITransaction transaction = - hub.startTransaction( + scopes.startTransaction( new TransactionContext(nameAndSource.name, nameAndSource.source, operation), transactionOptions); transaction.getSpanContext().setOrigin(TRACE_ORIGIN); @@ -85,7 +85,7 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl throw e; } finally { transaction.finish(); - hub.popScope(); + scopes.popScope(); } } } @@ -105,7 +105,7 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl } private boolean isTransactionActive() { - return hub.getSpan() != null; + return scopes.getSpan() != null; } private static class TransactionNameAndSource { diff --git a/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryRequestResolver.java b/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryRequestResolver.java index a710438c46..76e50985e5 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryRequestResolver.java +++ b/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryRequestResolver.java @@ -1,7 +1,7 @@ package io.sentry.spring.webflux; import com.jakewharton.nopen.annotation.Open; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.protocol.Request; import io.sentry.util.HttpUtils; import io.sentry.util.Objects; @@ -20,10 +20,10 @@ @Open @ApiStatus.Experimental public class SentryRequestResolver { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; - public SentryRequestResolver(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "options is required"); + public SentryRequestResolver(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } public @NotNull Request resolveSentryRequest(final @NotNull ServerHttpRequest httpRequest) { @@ -36,7 +36,7 @@ public SentryRequestResolver(final @NotNull IHub hub) { urlDetails.applyToRequest(sentryRequest); sentryRequest.setHeaders(resolveHeadersMap(httpRequest.getHeaders())); - if (hub.getOptions().isSendDefaultPii()) { + if (scopes.getOptions().isSendDefaultPii()) { String headerName = HttpUtils.COOKIE_HEADER_NAME; sentryRequest.setCookies( toString( @@ -52,7 +52,8 @@ Map resolveHeadersMap(final HttpHeaders request) { for (Map.Entry> entry : request.entrySet()) { // do not copy personal information identifiable headers String headerName = entry.getKey(); - if (hub.getOptions().isSendDefaultPii() || !HttpUtils.containsSensitiveHeader(headerName)) { + if (scopes.getOptions().isSendDefaultPii() + || !HttpUtils.containsSensitiveHeader(headerName)) { headersMap.put( headerName, toString( diff --git a/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryScheduleHook.java b/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryScheduleHook.java index 7775d4e482..20f494168d 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryScheduleHook.java +++ b/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryScheduleHook.java @@ -1,6 +1,6 @@ package io.sentry.spring.webflux; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.Sentry; import java.util.function.Function; import org.jetbrains.annotations.ApiStatus; @@ -13,16 +13,18 @@ @ApiStatus.Experimental public final class SentryScheduleHook implements Function { @Override + @SuppressWarnings("deprecation") public Runnable apply(final @NotNull Runnable runnable) { - final IHub newHub = Sentry.getCurrentHub().clone(); + // TODO fork instead + final IScopes newHub = Sentry.getCurrentScopes().clone(); return () -> { - final IHub oldState = Sentry.getCurrentHub(); - Sentry.setCurrentHub(newHub); + final IScopes oldState = Sentry.getCurrentScopes(); + Sentry.setCurrentScopes(newHub); try { runnable.run(); } finally { - Sentry.setCurrentHub(oldState); + Sentry.setCurrentScopes(oldState); } }; } diff --git a/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryWebExceptionHandler.java b/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryWebExceptionHandler.java index 98d3855a04..042d1d48ec 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryWebExceptionHandler.java +++ b/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryWebExceptionHandler.java @@ -5,7 +5,7 @@ import static io.sentry.TypeCheckHint.WEBFLUX_EXCEPTION_HANDLER_RESPONSE; import io.sentry.Hint; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.SentryEvent; import io.sentry.SentryLevel; import io.sentry.exception.ExceptionMechanismException; @@ -26,10 +26,10 @@ @ApiStatus.Experimental public final class SentryWebExceptionHandler implements WebExceptionHandler { public static final String MECHANISM_TYPE = "Spring5WebFluxExceptionResolver"; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; - public SentryWebExceptionHandler(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentryWebExceptionHandler(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } @Override @@ -50,7 +50,7 @@ public SentryWebExceptionHandler(final @NotNull IHub hub) { hint.set(WEBFLUX_EXCEPTION_HANDLER_RESPONSE, serverWebExchange.getResponse()); hint.set(WEBFLUX_EXCEPTION_HANDLER_EXCHANGE, serverWebExchange); - hub.captureEvent(event, hint); + scopes.captureEvent(event, hint); } return Mono.error(ex); } diff --git a/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryWebFilter.java b/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryWebFilter.java index f68a87ae0f..3bb7de5ae4 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryWebFilter.java +++ b/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryWebFilter.java @@ -7,10 +7,10 @@ import io.sentry.Breadcrumb; import io.sentry.CustomSamplingContext; import io.sentry.Hint; -import io.sentry.IHub; import io.sentry.IScope; +import io.sentry.IScopes; import io.sentry.ITransaction; -import io.sentry.NoOpHub; +import io.sentry.NoOpScopes; import io.sentry.Sentry; import io.sentry.SentryTraceHeader; import io.sentry.SpanStatus; @@ -34,22 +34,24 @@ /** Manages {@link IScope} in Webflux request processing. */ @ApiStatus.Experimental public final class SentryWebFilter implements WebFilter { - public static final String SENTRY_HUB_KEY = "sentry-hub"; + public static final String SENTRY_SCOPES_KEY = "sentry-scopes"; + @Deprecated public static final String SENTRY_HUB_KEY = SENTRY_SCOPES_KEY; private static final String TRANSACTION_OP = "http.server"; private static final String TRACE_ORIGIN = "auto.spring.webflux"; private final @NotNull SentryRequestResolver sentryRequestResolver; - public SentryWebFilter(final @NotNull IHub hub) { - Objects.requireNonNull(hub, "hub is required"); - this.sentryRequestResolver = new SentryRequestResolver(hub); + public SentryWebFilter(final @NotNull IScopes scopes) { + Objects.requireNonNull(scopes, "scopes are required"); + this.sentryRequestResolver = new SentryRequestResolver(scopes); } @Override public Mono filter( final @NotNull ServerWebExchange serverWebExchange, final @NotNull WebFilterChain webFilterChain) { - @NotNull IHub requestHub = Sentry.cloneMainHub(); + @NotNull IScopes requestHub = Sentry.cloneMainHub(); + // TODO do not push / pop, use fork instead if (!requestHub.isEnabled()) { return webFilterChain.filter(serverWebExchange); } @@ -80,7 +82,8 @@ isTracingEnabled && shouldTraceRequest(requestHub, request) finishTransaction(serverWebExchange, transaction); } requestHub.popScope(); - Sentry.setCurrentHub(NoOpHub.getInstance()); + // TODO token based cleanup instead? + Sentry.setCurrentScopes(NoOpScopes.getInstance()); }) .doOnError( e -> { @@ -91,8 +94,8 @@ isTracingEnabled && shouldTraceRequest(requestHub, request) }) .doFirst( () -> { - serverWebExchange.getAttributes().put(SENTRY_HUB_KEY, requestHub); - Sentry.setCurrentHub(requestHub); + serverWebExchange.getAttributes().put(SENTRY_SCOPES_KEY, requestHub); + Sentry.setCurrentScopes(requestHub); requestHub.pushScope(); final ServerHttpResponse response = serverWebExchange.getResponse(); @@ -109,13 +112,13 @@ isTracingEnabled && shouldTraceRequest(requestHub, request) } private boolean shouldTraceRequest( - final @NotNull IHub hub, final @NotNull ServerHttpRequest request) { - return hub.getOptions().isTraceOptionsRequests() + final @NotNull IScopes scopes, final @NotNull ServerHttpRequest request) { + return scopes.getOptions().isTraceOptionsRequests() || !HttpMethod.OPTIONS.equals(request.getMethod()); } private @NotNull ITransaction startTransaction( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull ServerHttpRequest request, final @Nullable TransactionContext transactionContext) { final @NotNull String name = request.getMethod() + " " + request.getURI().getPath(); @@ -131,10 +134,10 @@ private boolean shouldTraceRequest( transactionContext.setTransactionNameSource(TransactionNameSource.URL); transactionContext.setOperation(TRANSACTION_OP); - return hub.startTransaction(transactionContext, transactionOptions); + return scopes.startTransaction(transactionContext, transactionOptions); } - return hub.startTransaction( + return scopes.startTransaction( new TransactionContext(name, TransactionNameSource.URL, TRANSACTION_OP), transactionOptions); } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/EnableSentryTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/EnableSentryTest.kt index 5a8fec3053..5182309416 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/EnableSentryTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/EnableSentryTest.kt @@ -1,7 +1,7 @@ package io.sentry.spring import io.sentry.EventProcessor -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ITransportFactory import io.sentry.Integration import io.sentry.Sentry @@ -65,9 +65,9 @@ class EnableSentryTest { } @Test - fun `creates Sentry Hub`() { + fun `creates Sentry Scopes`() { contextRunner.run { - assertThat(it).hasSingleBean(IHub::class.java) + assertThat(it).hasSingleBean(IScopes::class.java) } } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/SentryCheckInAdviceTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/SentryCheckInAdviceTest.kt index 4f94fd7ce0..23807e1fd9 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/SentryCheckInAdviceTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/SentryCheckInAdviceTest.kt @@ -2,7 +2,7 @@ package io.sentry.spring import io.sentry.CheckIn import io.sentry.CheckInStatus -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.Sentry import io.sentry.SentryOptions import io.sentry.protocol.SentryId @@ -55,19 +55,19 @@ class SentryCheckInAdviceTest { lateinit var sampleServiceSpringProperties: SampleServiceSpringProperties @Autowired - lateinit var hub: IHub + lateinit var scopes: IScopes @BeforeTest fun setup() { - reset(hub) - whenever(hub.options).thenReturn(SentryOptions()) + reset(scopes) + whenever(scopes.options).thenReturn(SentryOptions()) } @Test fun `when method is annotated with @SentryCheckIn, every method call creates two check-ins`() { val checkInId = SentryId() val checkInCaptor = argumentCaptor() - whenever(hub.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) + whenever(scopes.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) val result = sampleService.hello() assertEquals(1, result) assertEquals(2, checkInCaptor.allValues.size) @@ -80,17 +80,17 @@ class SentryCheckInAdviceTest { assertEquals("monitor_slug_1", doneCheckIn.monitorSlug) assertEquals(CheckInStatus.OK.apiName(), doneCheckIn.status) - val order = inOrder(hub) - order.verify(hub).pushScope() - order.verify(hub, times(2)).captureCheckIn(any()) - order.verify(hub).popScope() + val order = inOrder(scopes) + order.verify(scopes).pushScope() + order.verify(scopes, times(2)).captureCheckIn(any()) + order.verify(scopes).popScope() } @Test fun `when method is annotated with @SentryCheckIn, every method call creates two check-ins error`() { val checkInId = SentryId() val checkInCaptor = argumentCaptor() - whenever(hub.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) + whenever(scopes.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) assertThrows { sampleService.oops() } @@ -104,17 +104,17 @@ class SentryCheckInAdviceTest { assertEquals("monitor_slug_1e", doneCheckIn.monitorSlug) assertEquals(CheckInStatus.ERROR.apiName(), doneCheckIn.status) - val order = inOrder(hub) - order.verify(hub).pushScope() - order.verify(hub, times(2)).captureCheckIn(any()) - order.verify(hub).popScope() + val order = inOrder(scopes) + order.verify(scopes).pushScope() + order.verify(scopes, times(2)).captureCheckIn(any()) + order.verify(scopes).popScope() } @Test fun `when method is annotated with @SentryCheckIn and heartbeat only, every method call creates only one check-in at the end`() { val checkInId = SentryId() val checkInCaptor = argumentCaptor() - whenever(hub.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) + whenever(scopes.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) val result = sampleServiceHeartbeat.hello() assertEquals(1, result) assertEquals(1, checkInCaptor.allValues.size) @@ -124,17 +124,17 @@ class SentryCheckInAdviceTest { assertEquals(CheckInStatus.OK.apiName(), doneCheckIn.status) assertNotNull(doneCheckIn.duration) - val order = inOrder(hub) - order.verify(hub).pushScope() - order.verify(hub).captureCheckIn(any()) - order.verify(hub).popScope() + val order = inOrder(scopes) + order.verify(scopes).pushScope() + order.verify(scopes).captureCheckIn(any()) + order.verify(scopes).popScope() } @Test fun `when method is annotated with @SentryCheckIn and heartbeat only, every method call creates only one check-in at the end with error`() { val checkInId = SentryId() val checkInCaptor = argumentCaptor() - whenever(hub.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) + whenever(scopes.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) assertThrows { sampleServiceHeartbeat.oops() } @@ -145,31 +145,31 @@ class SentryCheckInAdviceTest { assertEquals(CheckInStatus.ERROR.apiName(), doneCheckIn.status) assertNotNull(doneCheckIn.duration) - val order = inOrder(hub) - order.verify(hub).pushScope() - order.verify(hub).captureCheckIn(any()) - order.verify(hub).popScope() + val order = inOrder(scopes) + order.verify(scopes).pushScope() + order.verify(scopes).captureCheckIn(any()) + order.verify(scopes).popScope() } @Test fun `when method is annotated with @SentryCheckIn but slug is missing, does not create check-in`() { val checkInId = SentryId() val checkInCaptor = argumentCaptor() - whenever(hub.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) + whenever(scopes.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) val result = sampleServiceNoSlug.hello() assertEquals(1, result) assertEquals(0, checkInCaptor.allValues.size) - verify(hub, never()).pushScope() - verify(hub, never()).captureCheckIn(any()) - verify(hub, never()).popScope() + verify(scopes, never()).pushScope() + verify(scopes, never()).captureCheckIn(any()) + verify(scopes, never()).popScope() } @Test fun `when @SentryCheckIn is passed a spring property it is resolved correctly`() { val checkInId = SentryId() val checkInCaptor = argumentCaptor() - whenever(hub.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) + whenever(scopes.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) val result = sampleServiceSpringProperties.hello() assertEquals(1, result) assertEquals(1, checkInCaptor.allValues.size) @@ -179,17 +179,17 @@ class SentryCheckInAdviceTest { assertEquals(CheckInStatus.OK.apiName(), doneCheckIn.status) assertNotNull(doneCheckIn.duration) - val order = inOrder(hub) - order.verify(hub).pushScope() - order.verify(hub).captureCheckIn(any()) - order.verify(hub).popScope() + val order = inOrder(scopes) + order.verify(scopes).pushScope() + order.verify(scopes).captureCheckIn(any()) + order.verify(scopes).popScope() } @Test fun `when @SentryCheckIn is passed a spring property that does not exist, raw value is used`() { val checkInId = SentryId() val checkInCaptor = argumentCaptor() - whenever(hub.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) + whenever(scopes.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) val result = sampleServiceSpringProperties.helloUnresolvedProperty() assertEquals(1, result) assertEquals(1, checkInCaptor.allValues.size) @@ -199,17 +199,17 @@ class SentryCheckInAdviceTest { assertEquals(CheckInStatus.OK.apiName(), doneCheckIn.status) assertNotNull(doneCheckIn.duration) - val order = inOrder(hub) - order.verify(hub).pushScope() - order.verify(hub).captureCheckIn(any()) - order.verify(hub).popScope() + val order = inOrder(scopes) + order.verify(scopes).pushScope() + order.verify(scopes).captureCheckIn(any()) + order.verify(scopes).popScope() } @Test fun `when @SentryCheckIn is passed a spring property that causes an exception, raw value is used`() { val checkInId = SentryId() val checkInCaptor = argumentCaptor() - whenever(hub.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) + whenever(scopes.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) val result = sampleServiceSpringProperties.helloExceptionProperty() assertEquals(1, result) assertEquals(1, checkInCaptor.allValues.size) @@ -219,10 +219,10 @@ class SentryCheckInAdviceTest { assertEquals(CheckInStatus.OK.apiName(), doneCheckIn.status) assertNotNull(doneCheckIn.duration) - val order = inOrder(hub) - order.verify(hub).pushScope() - order.verify(hub).captureCheckIn(any()) - order.verify(hub).popScope() + val order = inOrder(scopes) + order.verify(scopes).pushScope() + order.verify(scopes).captureCheckIn(any()) + order.verify(scopes).popScope() } @Configuration @@ -243,10 +243,10 @@ class SentryCheckInAdviceTest { open fun sampleServiceSpringProperties() = SampleServiceSpringProperties() @Bean - open fun hub(): IHub { - val hub = mock() - Sentry.setCurrentHub(hub) - return hub + open fun scopes(): IScopes { + val scopes = mock() + Sentry.setCurrentScopes(scopes) + return scopes } companion object { diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/SentryExceptionResolverTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/SentryExceptionResolverTest.kt index f3e4c32fb0..048166107b 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/SentryExceptionResolverTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/SentryExceptionResolverTest.kt @@ -1,7 +1,7 @@ package io.sentry.spring import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryEvent import io.sentry.SentryLevel import io.sentry.exception.ExceptionMechanismException @@ -17,7 +17,7 @@ import javax.servlet.http.HttpServletResponse import kotlin.test.Test class SentryExceptionResolverTest { - private val hub = mock() + private val scopes = mock() private val transactionNameProvider = mock() private val request = mock() @@ -26,10 +26,10 @@ class SentryExceptionResolverTest { @Test fun `when handles exception, sets wrapped exception for event`() { val eventCaptor = argumentCaptor() - whenever(hub.captureEvent(eventCaptor.capture(), any())).thenReturn(null) + whenever(scopes.captureEvent(eventCaptor.capture(), any())).thenReturn(null) val expectedCause = RuntimeException("test") - SentryExceptionResolver(hub, transactionNameProvider, 1) + SentryExceptionResolver(scopes, transactionNameProvider, 1) .resolveException(request, response, null, expectedCause) assertThat(eventCaptor.firstValue.throwable).isEqualTo(expectedCause) @@ -46,9 +46,9 @@ class SentryExceptionResolverTest { @Test fun `when handles exception, sets fatal level for event`() { val eventCaptor = argumentCaptor() - whenever(hub.captureEvent(eventCaptor.capture(), any())).thenReturn(null) + whenever(scopes.captureEvent(eventCaptor.capture(), any())).thenReturn(null) - SentryExceptionResolver(hub, transactionNameProvider, 1) + SentryExceptionResolver(scopes, transactionNameProvider, 1) .resolveException(request, response, null, RuntimeException("test")) assertThat(eventCaptor.firstValue.level).isEqualTo(SentryLevel.FATAL) @@ -59,9 +59,9 @@ class SentryExceptionResolverTest { val expectedTransactionName = "test-transaction" whenever(transactionNameProvider.provideTransactionName(any())).thenReturn(expectedTransactionName) val eventCaptor = argumentCaptor() - whenever(hub.captureEvent(eventCaptor.capture(), any())).thenReturn(null) + whenever(scopes.captureEvent(eventCaptor.capture(), any())).thenReturn(null) - SentryExceptionResolver(hub, transactionNameProvider, 1) + SentryExceptionResolver(scopes, transactionNameProvider, 1) .resolveException(request, response, null, RuntimeException("test")) assertThat(eventCaptor.firstValue.transaction).isEqualTo(expectedTransactionName) @@ -71,9 +71,9 @@ class SentryExceptionResolverTest { @Test fun `when handles exception, provides spring resolver hint`() { val hintCaptor = argumentCaptor() - whenever(hub.captureEvent(any(), hintCaptor.capture())).thenReturn(null) + whenever(scopes.captureEvent(any(), hintCaptor.capture())).thenReturn(null) - SentryExceptionResolver(hub, transactionNameProvider, 1) + SentryExceptionResolver(scopes, transactionNameProvider, 1) .resolveException(request, response, null, RuntimeException("test")) with(hintCaptor.firstValue) { @@ -86,8 +86,8 @@ class SentryExceptionResolverTest { fun `when custom create event method provided, uses it to capture event`() { val expectedEvent = SentryEvent() val eventCaptor = argumentCaptor() - whenever(hub.captureEvent(eventCaptor.capture(), any())).thenReturn(null) - val resolver = object : SentryExceptionResolver(hub, transactionNameProvider, 1) { + whenever(scopes.captureEvent(eventCaptor.capture(), any())).thenReturn(null) + val resolver = object : SentryExceptionResolver(scopes, transactionNameProvider, 1) { override fun createEvent(request: HttpServletRequest, ex: Exception) = expectedEvent } @@ -100,8 +100,8 @@ class SentryExceptionResolverTest { fun `when custom create hint method provided, uses it to capture event`() { val expectedHint = Hint() val hintCaptor = argumentCaptor() - whenever(hub.captureEvent(any(), hintCaptor.capture())).thenReturn(null) - val resolver = object : SentryExceptionResolver(hub, transactionNameProvider, 1) { + whenever(scopes.captureEvent(any(), hintCaptor.capture())).thenReturn(null) + val resolver = object : SentryExceptionResolver(scopes, transactionNameProvider, 1) { override fun createHint(request: HttpServletRequest, response: HttpServletResponse) = expectedHint } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/SentryInitBeanPostProcessorTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/SentryInitBeanPostProcessorTest.kt index 78ebf961c9..dc4a14e656 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/SentryInitBeanPostProcessorTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/SentryInitBeanPostProcessorTest.kt @@ -1,6 +1,6 @@ package io.sentry.spring -import io.sentry.IHub +import io.sentry.IScopes import org.mockito.kotlin.mock import org.mockito.kotlin.verify import org.springframework.context.annotation.AnnotationConfigApplicationContext @@ -13,18 +13,18 @@ class SentryInitBeanPostProcessorTest { @Test fun closesSentryOnApplicationContextDestroy() { val ctx = AnnotationConfigApplicationContext(TestConfig::class.java) - val hub = ctx.getBean(IHub::class.java) + val scopes = ctx.getBean(IScopes::class.java) ctx.close() - verify(hub).close() + verify(scopes).close() } @Configuration open class TestConfig { @Bean(destroyMethod = "") - open fun hub() = mock() + open fun scopes() = mock() @Bean - open fun sentryInitBeanPostProcessor() = SentryInitBeanPostProcessor(hub()) + open fun sentryInitBeanPostProcessor() = SentryInitBeanPostProcessor(scopes()) } } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/SentryRequestHttpServletRequestProcessorTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/SentryRequestHttpServletRequestProcessorTest.kt index 3fe9b60743..c7277a2240 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/SentryRequestHttpServletRequestProcessorTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/SentryRequestHttpServletRequestProcessorTest.kt @@ -1,7 +1,7 @@ package io.sentry.spring import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryEvent import io.sentry.SentryOptions import io.sentry.spring.tracing.SpringMvcTransactionNameProvider @@ -19,10 +19,10 @@ import kotlin.test.assertNotNull class SentryRequestHttpServletRequestProcessorTest { private class Fixture { - val hub = mock() + val scopes = mock() fun getSut(request: HttpServletRequest, options: SentryOptions = SentryOptions()): SentryRequestHttpServletRequestProcessor { - whenever(hub.options).thenReturn(options) + whenever(scopes.options).thenReturn(options) return SentryRequestHttpServletRequestProcessor(SpringMvcTransactionNameProvider(), request) } } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/SentrySpringFilterTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/SentrySpringFilterTest.kt index ce83c4b9b7..c6ac952531 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/SentrySpringFilterTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/SentrySpringFilterTest.kt @@ -1,8 +1,8 @@ package io.sentry.spring import io.sentry.Breadcrumb -import io.sentry.IHub import io.sentry.IScope +import io.sentry.IScopes import io.sentry.Scope import io.sentry.ScopeCallback import io.sentry.SentryOptions @@ -37,7 +37,7 @@ import kotlin.test.fail class SentrySpringFilterTest { private class Fixture { - val hub = mock() + val scopes = mock() val response = MockHttpServletResponse() val chain = mock() lateinit var scope: IScope @@ -45,15 +45,15 @@ class SentrySpringFilterTest { fun getSut(request: HttpServletRequest? = null, options: SentryOptions = SentryOptions()): SentrySpringFilter { scope = Scope(options) - whenever(hub.options).thenReturn(options) - whenever(hub.isEnabled).thenReturn(true) - doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(hub).configureScope(any()) + whenever(scopes.options).thenReturn(options) + whenever(scopes.isEnabled).thenReturn(true) + doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(scopes).configureScope(any()) this.request = request ?: MockHttpServletRequest().apply { this.requestURI = "http://localhost:8080/some-uri" this.method = "post" } - return SentrySpringFilter(hub) + return SentrySpringFilter(scopes) } } @@ -64,7 +64,7 @@ class SentrySpringFilterTest { val listener = fixture.getSut() listener.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).pushScope() + verify(fixture.scopes).pushScope() } @Test @@ -72,7 +72,7 @@ class SentrySpringFilterTest { val listener = fixture.getSut() listener.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { it: Breadcrumb -> Assertions.assertThat(it.getData("url")).isEqualTo("http://localhost:8080/some-uri") Assertions.assertThat(it.getData("method")).isEqualTo("POST") @@ -87,7 +87,7 @@ class SentrySpringFilterTest { val listener = fixture.getSut() listener.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).popScope() + verify(fixture.scopes).popScope() } @Test @@ -99,7 +99,7 @@ class SentrySpringFilterTest { listener.doFilter(fixture.request, fixture.response, fixture.chain) fail() } catch (e: Exception) { - verify(fixture.hub).popScope() + verify(fixture.scopes).popScope() } } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/SentryTaskDecoratorTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/SentryTaskDecoratorTest.kt index e202deca86..3f34ab9d9d 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/SentryTaskDecoratorTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/SentryTaskDecoratorTest.kt @@ -32,28 +32,28 @@ class SentryTaskDecoratorTest { val sut = SentryTaskDecorator() - val mainHub = Sentry.getCurrentHub() - val threadedHub = Sentry.getCurrentHub().clone() + val mainHub = Sentry.getCurrentScopes() + val threadedHub = Sentry.getCurrentScopes().clone() executor.submit { - Sentry.setCurrentHub(threadedHub) + Sentry.setCurrentScopes(threadedHub) }.get() - assertEquals(mainHub, Sentry.getCurrentHub()) + assertEquals(mainHub, Sentry.getCurrentScopes()) val callableFuture = executor.submit( sut.decorate { - assertNotEquals(mainHub, Sentry.getCurrentHub()) - assertNotEquals(threadedHub, Sentry.getCurrentHub()) + assertNotEquals(mainHub, Sentry.getCurrentScopes()) + assertNotEquals(threadedHub, Sentry.getCurrentScopes()) } ) callableFuture.get() executor.submit { - assertNotEquals(mainHub, Sentry.getCurrentHub()) - assertEquals(threadedHub, Sentry.getCurrentHub()) + assertNotEquals(mainHub, Sentry.getCurrentScopes()) + assertEquals(threadedHub, Sentry.getCurrentScopes()) }.get() } } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/SentryUserFilterTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/SentryUserFilterTest.kt index 2dac9a57ed..7f9be1ba8b 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/SentryUserFilterTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/SentryUserFilterTest.kt @@ -1,6 +1,6 @@ package io.sentry.spring -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryOptions import io.sentry.protocol.User import org.mockito.kotlin.check @@ -16,7 +16,7 @@ import kotlin.test.assertNull class SentryUserFilterTest { class Fixture { - val hub = mock() + val scopes = mock() val request = MockHttpServletRequest() val response = MockHttpServletResponse() val chain = mock() @@ -25,8 +25,8 @@ class SentryUserFilterTest { val options = SentryOptions().apply { this.isSendDefaultPii = isSendDefaultPii } - whenever(hub.options).thenReturn(options) - return SentryUserFilter(hub, userProviders) + whenever(scopes.options).thenReturn(options) + return SentryUserFilter(scopes, userProviders) } } @@ -52,7 +52,7 @@ class SentryUserFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).setUser( + verify(fixture.scopes).setUser( check { assertEquals(sampleUser, it) } @@ -72,7 +72,7 @@ class SentryUserFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).setUser( + verify(fixture.scopes).setUser( check { assertEquals(sampleUser, it) } @@ -92,7 +92,7 @@ class SentryUserFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).setUser( + verify(fixture.scopes).setUser( check { assertEquals(sampleUser, it) } @@ -118,7 +118,7 @@ class SentryUserFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).setUser( + verify(fixture.scopes).setUser( check { assertEquals(mapOf("key" to "value", "new-key" to "new-value"), it.others) } @@ -140,7 +140,7 @@ class SentryUserFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).setUser( + verify(fixture.scopes).setUser( check { assertEquals("192.168.0.1", it.ipAddress) } @@ -162,7 +162,7 @@ class SentryUserFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).setUser( + verify(fixture.scopes).setUser( check { assertNull(it.ipAddress) } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/exception/SentryCaptureExceptionParameterAdviceTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/exception/SentryCaptureExceptionParameterAdviceTest.kt index 39bc66fabb..dca1c4c592 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/exception/SentryCaptureExceptionParameterAdviceTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/exception/SentryCaptureExceptionParameterAdviceTest.kt @@ -1,7 +1,7 @@ package io.sentry.spring.exception import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.Sentry import io.sentry.exception.ExceptionMechanismException import org.junit.runner.RunWith @@ -30,18 +30,18 @@ class SentryCaptureExceptionParameterAdviceTest { lateinit var sampleService: SampleService @Autowired - lateinit var hub: IHub + lateinit var scopes: IScopes @BeforeTest fun setup() { - reset(hub) + reset(scopes) } @Test fun `captures exception passed to method annotated with @SentryCaptureException`() { val exception = RuntimeException("test exception") sampleService.methodTakingAnException(exception) - verify(hub).captureException( + verify(scopes).captureException( check { assertTrue(it is ExceptionMechanismException) assertEquals(exception, it.throwable) @@ -60,10 +60,10 @@ class SentryCaptureExceptionParameterAdviceTest { open fun sampleService() = SampleService() @Bean - open fun hub(): IHub { - val hub = mock() - Sentry.setCurrentHub(hub) - return hub + open fun scopes(): IScopes { + val scopes = mock() + Sentry.setCurrentScopes(scopes) + return scopes } } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/graphql/SentrySpringSubscriptionHandlerTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/graphql/SentrySpringSubscriptionHandlerTest.kt index df2df5b3ef..1aa97cd262 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/graphql/SentrySpringSubscriptionHandlerTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/graphql/SentrySpringSubscriptionHandlerTest.kt @@ -4,7 +4,7 @@ import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchPar import graphql.language.Document import graphql.language.OperationDefinition import graphql.schema.DataFetchingEnvironment -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.graphql.ExceptionReporter import org.junit.jupiter.api.assertThrows import org.mockito.kotlin.anyOrNull @@ -23,7 +23,7 @@ class SentrySpringSubscriptionHandlerTest { @Test fun `reports exception`() { val exception = IllegalStateException("some exception") - val hub = mock() + val scopes = mock() val exceptionReporter = mock() val parameters = mock() val dataFetchingEnvironment = mock() @@ -32,7 +32,7 @@ class SentrySpringSubscriptionHandlerTest { .build() whenever(dataFetchingEnvironment.document).thenReturn(document) whenever(parameters.environment).thenReturn(dataFetchingEnvironment) - val resultObject = SentrySpringSubscriptionHandler().onSubscriptionResult(Flux.error(exception), hub, exceptionReporter, parameters) + val resultObject = SentrySpringSubscriptionHandler().onSubscriptionResult(Flux.error(exception), scopes, exceptionReporter, parameters) assertThrows { (resultObject as Flux).blockFirst() } @@ -41,7 +41,7 @@ class SentrySpringSubscriptionHandlerTest { same(exception), org.mockito.kotlin.check { assertEquals(true, it.isSubscription) - assertSame(hub, it.hub) + assertSame(scopes, it.scopes) assertEquals("query testQuery\n", it.query) }, anyOrNull() @@ -52,7 +52,7 @@ class SentrySpringSubscriptionHandlerTest { fun `unwraps SubscriptionPublisherException and reports cause`() { val exception = IllegalStateException("some exception") val wrappedException = SubscriptionPublisherException(emptyList(), exception) - val hub = mock() + val scopes = mock() val exceptionReporter = mock() val parameters = mock() val dataFetchingEnvironment = mock() @@ -61,7 +61,7 @@ class SentrySpringSubscriptionHandlerTest { .build() whenever(dataFetchingEnvironment.document).thenReturn(document) whenever(parameters.environment).thenReturn(dataFetchingEnvironment) - val resultObject = SentrySpringSubscriptionHandler().onSubscriptionResult(Flux.error(wrappedException), hub, exceptionReporter, parameters) + val resultObject = SentrySpringSubscriptionHandler().onSubscriptionResult(Flux.error(wrappedException), scopes, exceptionReporter, parameters) assertThrows { (resultObject as Flux).blockFirst() } @@ -70,7 +70,7 @@ class SentrySpringSubscriptionHandlerTest { same(exception), org.mockito.kotlin.check { assertEquals(true, it.isSubscription) - assertSame(hub, it.hub) + assertSame(scopes, it.scopes) assertEquals("query testQuery\n", it.query) }, anyOrNull() diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/mvc/SentrySpringIntegrationTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/mvc/SentrySpringIntegrationTest.kt index 998b27c7e8..ad9734def6 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/mvc/SentrySpringIntegrationTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/mvc/SentrySpringIntegrationTest.kt @@ -1,6 +1,6 @@ package io.sentry.spring.mvc -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ITransportFactory import io.sentry.Sentry import io.sentry.SentryOptions @@ -104,7 +104,7 @@ class SentrySpringIntegrationTest { lateinit var anotherService: AnotherService @Autowired - lateinit var hub: IHub + lateinit var scopes: IScopes @LocalServerPort var port: Int? = null @@ -260,7 +260,7 @@ class SentrySpringIntegrationTest { try { someService.aMethodThrowing() } catch (e: Exception) { - hub.captureException(e) + scopes.captureException(e) } verify(transport).send( checkEvent { @@ -276,7 +276,7 @@ class SentrySpringIntegrationTest { try { someService.aMethodWithInnerSpanThrowing() } catch (e: Exception) { - hub.captureException(e) + scopes.captureException(e) } verify(transport).send( checkEvent { @@ -370,20 +370,20 @@ open class App { open fun springSecuritySentryUserProvider(sentryOptions: SentryOptions) = SpringSecuritySentryUserProvider(sentryOptions) @Bean - open fun sentryUserFilter(hub: IHub, @Lazy sentryUserProviders: List) = FilterRegistrationBean().apply { - this.filter = SentryUserFilter(hub, sentryUserProviders) + open fun sentryUserFilter(scopes: IScopes, @Lazy sentryUserProviders: List) = FilterRegistrationBean().apply { + this.filter = SentryUserFilter(scopes, sentryUserProviders) this.order = Ordered.LOWEST_PRECEDENCE } @Bean - open fun sentrySpringFilter(hub: IHub) = FilterRegistrationBean().apply { - this.filter = SentrySpringFilter(hub) + open fun sentrySpringFilter(scopes: IScopes) = FilterRegistrationBean().apply { + this.filter = SentrySpringFilter(scopes) this.order = Ordered.HIGHEST_PRECEDENCE } @Bean - open fun sentryTracingFilter(hub: IHub) = FilterRegistrationBean().apply { - this.filter = SentryTracingFilter(hub) + open fun sentryTracingFilter(scopes: IScopes) = FilterRegistrationBean().apply { + this.filter = SentryTracingFilter(scopes) this.order = Ordered.HIGHEST_PRECEDENCE + 1 // must run after SentrySpringFilter } @@ -391,13 +391,13 @@ open class App { open fun sentryTaskDecorator() = SentryTaskDecorator() @Bean - open fun webClient(hub: IHub): WebClient { + open fun webClient(scopes: IScopes): WebClient { return WebClient.builder() .filter( ExchangeFilterFunctions .basicAuthentication("user", "password") ) - .filter(SentrySpanClientWebRequestFilter(hub)).build() + .filter(SentrySpanClientWebRequestFilter(scopes)).build() } } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/tracing/SentrySpanAdviceTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/tracing/SentrySpanAdviceTest.kt index dc6f00eb46..a6f59971c9 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/tracing/SentrySpanAdviceTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/tracing/SentrySpanAdviceTest.kt @@ -1,6 +1,6 @@ package io.sentry.spring.tracing -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.Scope import io.sentry.Sentry import io.sentry.SentryOptions @@ -37,20 +37,20 @@ class SentrySpanAdviceTest { lateinit var classAnnotatedWithOperationSampleService: ClassAnnotatedWithOperationSampleService @Autowired - lateinit var hub: IHub + lateinit var scopes: IScopes @BeforeTest fun setup() { - whenever(hub.options).thenReturn(SentryOptions()) + whenever(scopes.options).thenReturn(SentryOptions()) } @Test fun `when class is annotated with @SentrySpan, every method call attaches span to existing transaction`() { val scope = Scope(SentryOptions()) - val tx = SentryTracer(TransactionContext("aTransaction", "op"), hub) + val tx = SentryTracer(TransactionContext("aTransaction", "op"), scopes) scope.setTransaction(tx) - whenever(hub.span).thenReturn(tx) + whenever(scopes.span).thenReturn(tx) val result = classAnnotatedSampleService.hello() assertEquals(1, result) assertEquals(1, tx.spans.size) @@ -62,10 +62,10 @@ class SentrySpanAdviceTest { @Test fun `when class is annotated with @SentrySpan with operation set, every method call attaches span to existing transaction`() { val scope = Scope(SentryOptions()) - val tx = SentryTracer(TransactionContext("aTransaction", "op"), hub) + val tx = SentryTracer(TransactionContext("aTransaction", "op"), scopes) scope.setTransaction(tx) - whenever(hub.span).thenReturn(tx) + whenever(scopes.span).thenReturn(tx) val result = classAnnotatedWithOperationSampleService.hello() assertEquals(1, result) assertEquals(1, tx.spans.size) @@ -76,10 +76,10 @@ class SentrySpanAdviceTest { @Test fun `when method is annotated with @SentrySpan with properties set, attaches span to existing transaction`() { val scope = Scope(SentryOptions()) - val tx = SentryTracer(TransactionContext("aTransaction", "op"), hub) + val tx = SentryTracer(TransactionContext("aTransaction", "op"), scopes) scope.setTransaction(tx) - whenever(hub.span).thenReturn(tx) + whenever(scopes.span).thenReturn(tx) val result = sampleService.methodWithSpanDescriptionSet() assertEquals(1, result) assertEquals(1, tx.spans.size) @@ -90,10 +90,10 @@ class SentrySpanAdviceTest { @Test fun `when method is annotated with @SentrySpan without properties set, attaches span to existing transaction and sets Span description as className dot methodName`() { val scope = Scope(SentryOptions()) - val tx = SentryTracer(TransactionContext("aTransaction", "op"), hub) + val tx = SentryTracer(TransactionContext("aTransaction", "op"), scopes) scope.setTransaction(tx) - whenever(hub.span).thenReturn(tx) + whenever(scopes.span).thenReturn(tx) val result = sampleService.methodWithoutSpanDescriptionSet() assertEquals(2, result) assertEquals(1, tx.spans.size) @@ -104,10 +104,10 @@ class SentrySpanAdviceTest { @Test fun `when method is annotated with @SentrySpan and returns, attached span has status OK`() { val scope = Scope(SentryOptions()) - val tx = SentryTracer(TransactionContext("aTransaction", "op"), hub) + val tx = SentryTracer(TransactionContext("aTransaction", "op"), scopes) scope.setTransaction(tx) - whenever(hub.span).thenReturn(tx) + whenever(scopes.span).thenReturn(tx) sampleService.methodWithSpanDescriptionSet() assertEquals(SpanStatus.OK, tx.spans.first().status) } @@ -115,10 +115,10 @@ class SentrySpanAdviceTest { @Test fun `when method is annotated with @SentrySpan and throws exception, attached span has throwable set and INTERNAL_ERROR status`() { val scope = Scope(SentryOptions()) - val tx = SentryTracer(TransactionContext("aTransaction", "op"), hub) + val tx = SentryTracer(TransactionContext("aTransaction", "op"), scopes) scope.setTransaction(tx) - whenever(hub.span).thenReturn(tx) + whenever(scopes.span).thenReturn(tx) var throwable: Throwable? = null try { sampleService.methodThrowingException() @@ -131,7 +131,7 @@ class SentrySpanAdviceTest { @Test fun `when method is annotated with @SentrySpan and there is no active transaction, span is not created and method is executed`() { - whenever(hub.span).thenReturn(null) + whenever(scopes.span).thenReturn(null) val result = sampleService.methodWithSpanDescriptionSet() assertEquals(1, result) } @@ -151,10 +151,10 @@ class SentrySpanAdviceTest { open fun classAnnotatedWithOperationSampleService() = ClassAnnotatedWithOperationSampleService() @Bean - open fun hub(): IHub { - val hub = mock() - Sentry.setCurrentHub(hub) - return hub + open fun scopes(): IScopes { + val scopes = mock() + Sentry.setCurrentScopes(scopes) + return scopes } } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/tracing/SentryTracingFilterTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/tracing/SentryTracingFilterTest.kt index 6c4c06ebff..aca54809cc 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/tracing/SentryTracingFilterTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/tracing/SentryTracingFilterTest.kt @@ -1,7 +1,7 @@ package io.sentry.spring.tracing -import io.sentry.IHub import io.sentry.ILogger +import io.sentry.IScopes import io.sentry.PropagationContext import io.sentry.SentryOptions import io.sentry.SentryTracer @@ -38,7 +38,7 @@ import kotlin.test.fail class SentryTracingFilterTest { private class Fixture { - val hub = mock() + val scopes = mock() val request = MockHttpServletRequest() val response = MockHttpServletResponse() val chain = mock() @@ -50,7 +50,7 @@ class SentryTracingFilterTest { val logger = mock() init { - whenever(hub.options).thenReturn(options) + whenever(scopes.options).thenReturn(options) } fun getSut(isEnabled: Boolean = true, status: Int = 200, sentryTraceHeader: String? = null, baggageHeaders: List? = null): SentryTracingFilter { @@ -61,16 +61,16 @@ class SentryTracingFilterTest { whenever(transactionNameProvider.provideTransactionSource()).thenReturn(TransactionNameSource.CUSTOM) if (sentryTraceHeader != null) { request.addHeader("sentry-trace", sentryTraceHeader) - whenever(hub.startTransaction(any(), check { it.isBindToScope })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, hub) } + whenever(scopes.startTransaction(any(), check { it.isBindToScope })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, scopes) } } if (baggageHeaders != null) { request.addHeader("baggage", baggageHeaders) } response.status = status - whenever(hub.startTransaction(any(), check { assertTrue(it.isBindToScope) })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, hub) } - whenever(hub.isEnabled).thenReturn(isEnabled) - whenever(hub.continueTrace(any(), any())).thenAnswer { TransactionContext.fromPropagationContext(PropagationContext.fromHeaders(logger, it.arguments[0] as String?, it.arguments[1] as List?)) } - return SentryTracingFilter(hub, transactionNameProvider) + whenever(scopes.startTransaction(any(), check { assertTrue(it.isBindToScope) })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, scopes) } + whenever(scopes.isEnabled).thenReturn(isEnabled) + whenever(scopes.continueTrace(any(), any())).thenAnswer { TransactionContext.fromPropagationContext(PropagationContext.fromHeaders(logger, it.arguments[0] as String?, it.arguments[1] as List?)) } + return SentryTracingFilter(scopes, transactionNameProvider) } } @@ -82,7 +82,7 @@ class SentryTracingFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( check { assertEquals("POST /product/12", it.name) assertEquals(TransactionNameSource.URL, it.transactionNameSource) @@ -95,7 +95,7 @@ class SentryTracingFilterTest { } ) verify(fixture.chain).doFilter(fixture.request, fixture.response) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.transaction).isEqualTo("POST /product/{id}") assertThat(it.contexts.trace!!.status).isEqualTo(SpanStatus.OK) @@ -114,7 +114,7 @@ class SentryTracingFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.status).isEqualTo(SpanStatus.INTERNAL_ERROR) }, @@ -130,7 +130,7 @@ class SentryTracingFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.status).isNull() }, @@ -146,7 +146,7 @@ class SentryTracingFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.parentSpanId).isNull() }, @@ -163,7 +163,7 @@ class SentryTracingFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.parentSpanId).isEqualTo(parentSpanId) }, @@ -174,15 +174,15 @@ class SentryTracingFilterTest { } @Test - fun `when hub is disabled, components are not invoked`() { + fun `when scopes is disabled, components are not invoked`() { val filter = fixture.getSut(isEnabled = false) filter.doFilter(fixture.request, fixture.response, fixture.chain) verify(fixture.chain).doFilter(fixture.request, fixture.response) - verify(fixture.hub).isEnabled - verifyNoMoreInteractions(fixture.hub) + verify(fixture.scopes).isEnabled + verifyNoMoreInteractions(fixture.scopes) verify(fixture.transactionNameProvider, never()).provideTransactionName(any()) } @@ -196,7 +196,7 @@ class SentryTracingFilterTest { fail("filter is expected to rethrow exception") } catch (_: Exception) { } - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.status).isEqualTo(SpanStatus.INTERNAL_ERROR) }, @@ -216,10 +216,10 @@ class SentryTracingFilterTest { verify(fixture.chain).doFilter(fixture.request, fixture.response) - verify(fixture.hub).isEnabled - verify(fixture.hub, times(2)).options - verify(fixture.hub).continueTrace(anyOrNull(), anyOrNull()) - verifyNoMoreInteractions(fixture.hub) + verify(fixture.scopes).isEnabled + verify(fixture.scopes, times(2)).options + verify(fixture.scopes).continueTrace(anyOrNull(), anyOrNull()) + verifyNoMoreInteractions(fixture.scopes) verify(fixture.transactionNameProvider, never()).provideTransactionName(any()) } @@ -233,7 +233,7 @@ class SentryTracingFilterTest { verify(fixture.chain).doFilter(fixture.request, fixture.response) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.parentSpanId).isNull() }, @@ -253,7 +253,7 @@ class SentryTracingFilterTest { verify(fixture.chain).doFilter(fixture.request, fixture.response) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.parentSpanId).isNull() }, @@ -275,9 +275,9 @@ class SentryTracingFilterTest { verify(fixture.chain).doFilter(fixture.request, fixture.response) - verify(fixture.hub).continueTrace(eq(sentryTraceHeaderString), eq(baggageHeaderStrings)) + verify(fixture.scopes).continueTrace(eq(sentryTraceHeaderString), eq(baggageHeaderStrings)) - verify(fixture.hub, never()).captureTransaction( + verify(fixture.scopes, never()).captureTransaction( anyOrNull(), anyOrNull(), anyOrNull(), diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/tracing/SentryTransactionAdviceTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/tracing/SentryTransactionAdviceTest.kt index 0fa9abbb29..f53acde8aa 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/tracing/SentryTransactionAdviceTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/tracing/SentryTransactionAdviceTest.kt @@ -1,6 +1,6 @@ package io.sentry.spring.tracing -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.Sentry import io.sentry.SentryOptions import io.sentry.SentryTracer @@ -44,13 +44,13 @@ class SentryTransactionAdviceTest { lateinit var classAnnotatedWithOperationSampleService: ClassAnnotatedWithOperationSampleService @Autowired - lateinit var hub: IHub + lateinit var scopes: IScopes @BeforeTest fun setup() { - reset(hub) - whenever(hub.startTransaction(any(), check { assertTrue(it.isBindToScope) })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, hub) } - whenever(hub.options).thenReturn( + reset(scopes) + whenever(scopes.startTransaction(any(), check { assertTrue(it.isBindToScope) })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, scopes) } + whenever(scopes.options).thenReturn( SentryOptions().apply { dsn = "https://key@sentry.io/proj" } @@ -60,7 +60,7 @@ class SentryTransactionAdviceTest { @Test fun `creates transaction around method annotated with @SentryTransaction`() { sampleService.methodWithTransactionNameSet() - verify(hub).captureTransaction( + verify(scopes).captureTransaction( check { assertThat(it.transaction).isEqualTo("customName") assertThat(it.contexts.trace!!.operation).isEqualTo("bean") @@ -76,7 +76,7 @@ class SentryTransactionAdviceTest { @Test fun `when method annotated with @SentryTransaction throws exception, sets error status on transaction`() { assertThrows { sampleService.methodThrowingException() } - verify(hub).captureTransaction( + verify(scopes).captureTransaction( check { assertThat(it.status).isEqualTo(SpanStatus.INTERNAL_ERROR) }, @@ -89,7 +89,7 @@ class SentryTransactionAdviceTest { @Test fun `when @SentryTransaction has no name set, sets transaction name as className dot methodName`() { sampleService.methodWithoutTransactionNameSet() - verify(hub).captureTransaction( + verify(scopes).captureTransaction( check { assertThat(it.transaction).isEqualTo("SampleService.methodWithoutTransactionNameSet") assertThat(it.contexts.trace!!.operation).isEqualTo("op") @@ -102,18 +102,18 @@ class SentryTransactionAdviceTest { @Test fun `when transaction is already active, does not start new transaction`() { - whenever(hub.options).thenReturn(SentryOptions()) - whenever(hub.span).then { SentryTracer(TransactionContext("aTransaction", "op"), hub) } + whenever(scopes.options).thenReturn(SentryOptions()) + whenever(scopes.span).then { SentryTracer(TransactionContext("aTransaction", "op"), scopes) } sampleService.methodWithTransactionNameSet() - verify(hub, times(0)).captureTransaction(any(), any()) + verify(scopes, times(0)).captureTransaction(any(), any()) } @Test fun `creates transaction around method in class annotated with @SentryTransaction`() { classAnnotatedSampleService.hello() - verify(hub).captureTransaction( + verify(scopes).captureTransaction( check { assertThat(it.transaction).isEqualTo("ClassAnnotatedSampleService.hello") assertThat(it.contexts.trace!!.operation).isEqualTo("op") @@ -127,7 +127,7 @@ class SentryTransactionAdviceTest { @Test fun `creates transaction with operation set around method in class annotated with @SentryTransaction`() { classAnnotatedWithOperationSampleService.hello() - verify(hub).captureTransaction( + verify(scopes).captureTransaction( check { assertThat(it.transaction).isEqualTo("ClassAnnotatedWithOperationSampleService.hello") assertThat(it.contexts.trace!!.operation).isEqualTo("my-op") @@ -141,13 +141,13 @@ class SentryTransactionAdviceTest { @Test fun `pushes the scope when advice starts`() { classAnnotatedSampleService.hello() - verify(hub).pushScope() + verify(scopes).pushScope() } @Test fun `pops the scope when advice finishes`() { classAnnotatedSampleService.hello() - verify(hub).popScope() + verify(scopes).popScope() } @Configuration @@ -165,10 +165,10 @@ class SentryTransactionAdviceTest { open fun classAnnotatedWithOperationSampleService() = ClassAnnotatedWithOperationSampleService() @Bean - open fun hub(): IHub { - val hub = mock() - Sentry.setCurrentHub(hub) - return hub + open fun scopes(): IScopes { + val scopes = mock() + Sentry.setCurrentScopes(scopes) + return scopes } } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryScheduleHookTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryScheduleHookTest.kt index b09011d544..7a8b2993f9 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryScheduleHookTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryScheduleHookTest.kt @@ -33,28 +33,28 @@ class SentryScheduleHookTest { val sut = SentryScheduleHook() - val mainHub = Sentry.getCurrentHub() - val threadedHub = Sentry.getCurrentHub().clone() + val mainHub = Sentry.getCurrentScopes() + val threadedHub = Sentry.getCurrentScopes().clone() executor.submit { Sentry.setCurrentHub(threadedHub) }.get() - assertEquals(mainHub, Sentry.getCurrentHub()) + assertEquals(mainHub, Sentry.getCurrentScopes()) val callableFuture = executor.submit( sut.apply { - assertNotEquals(mainHub, Sentry.getCurrentHub()) - assertNotEquals(threadedHub, Sentry.getCurrentHub()) + assertNotEquals(mainHub, Sentry.getCurrentScopes()) + assertNotEquals(threadedHub, Sentry.getCurrentScopes()) } ) callableFuture.get() executor.submit { - assertNotEquals(mainHub, Sentry.getCurrentHub()) - assertEquals(threadedHub, Sentry.getCurrentHub()) + assertNotEquals(mainHub, Sentry.getCurrentScopes()) + assertEquals(threadedHub, Sentry.getCurrentScopes()) }.get() } } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryWebFluxTracingFilterTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryWebFluxTracingFilterTest.kt index be56a8391d..2113c748ee 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryWebFluxTracingFilterTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryWebFluxTracingFilterTest.kt @@ -2,8 +2,9 @@ package io.sentry.spring.webflux import io.sentry.Breadcrumb import io.sentry.Hint -import io.sentry.IHub +import io.sentry.HubScopesWrapper import io.sentry.ILogger +import io.sentry.IScopes import io.sentry.PropagationContext import io.sentry.ScopeCallback import io.sentry.Sentry @@ -17,7 +18,7 @@ import io.sentry.TransactionOptions import io.sentry.protocol.SentryId import io.sentry.protocol.SentryTransaction import io.sentry.protocol.TransactionNameSource -import io.sentry.spring.webflux.SentryWebFilter.SENTRY_HUB_KEY +import io.sentry.spring.webflux.SentryWebFilter.SENTRY_SCOPES_KEY import org.assertj.core.api.Assertions.assertThat import org.mockito.Mockito import org.mockito.kotlin.any @@ -47,7 +48,7 @@ import kotlin.test.fail class SentryWebFluxTracingFilterTest { private class Fixture { - val hub = mock() + val scopes = mock() lateinit var request: MockServerHttpRequest lateinit var exchange: MockServerWebExchange val chain = mock() @@ -58,35 +59,37 @@ class SentryWebFluxTracingFilterTest { val logger = mock() init { - whenever(hub.options).thenReturn(options) + whenever(scopes.options).thenReturn(options) } fun getSut(isEnabled: Boolean = true, status: HttpStatus = HttpStatus.OK, sentryTraceHeader: String? = null, baggageHeaders: List? = null, method: HttpMethod = HttpMethod.POST): SentryWebFilter { var requestBuilder = MockServerHttpRequest.method(method, "/product/{id}", 12) if (sentryTraceHeader != null) { requestBuilder = requestBuilder.header("sentry-trace", sentryTraceHeader) - whenever(hub.startTransaction(any(), check { it.isBindToScope })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, hub) } + whenever(scopes.startTransaction(any(), check { it.isBindToScope })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, scopes) } } if (baggageHeaders != null) { requestBuilder = requestBuilder.header("baggage", *baggageHeaders.toTypedArray()) } request = requestBuilder.build() exchange = MockServerWebExchange.builder(request).build() - exchange.attributes.put(SENTRY_HUB_KEY, hub) + exchange.attributes.put(SENTRY_SCOPES_KEY, scopes) exchange.attributes.put(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE, PathPatternParser().parse("/product/{id}")) exchange.response.statusCode = status - whenever(hub.startTransaction(any(), check { assertTrue(it.isBindToScope) })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, hub) } - whenever(hub.isEnabled).thenReturn(isEnabled) + whenever(scopes.startTransaction(any(), check { assertTrue(it.isBindToScope) })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, scopes) } + whenever(scopes.isEnabled).thenReturn(isEnabled) whenever(chain.filter(any())).thenReturn(Mono.create { s -> s.success() }) - whenever(hub.continueTrace(anyOrNull(), anyOrNull())).thenAnswer { TransactionContext.fromPropagationContext(PropagationContext.fromHeaders(logger, it.arguments[0] as String?, it.arguments[1] as List?)) } - return SentryWebFilter(hub) + whenever(scopes.continueTrace(anyOrNull(), anyOrNull())).thenAnswer { TransactionContext.fromPropagationContext(PropagationContext.fromHeaders(logger, it.arguments[0] as String?, it.arguments[1] as List?)) } + return SentryWebFilter(scopes) } } private val fixture = Fixture() - fun withMockHub(closure: () -> Unit) = Mockito.mockStatic(Sentry::class.java).use { - it.`when` { Sentry.cloneMainHub() }.thenReturn(fixture.hub) + fun withMockScopes(closure: () -> Unit) = Mockito.mockStatic(Sentry::class.java).use { + it.`when` { Sentry.getCurrentHub() }.thenReturn(HubScopesWrapper(fixture.scopes)) + it.`when` { Sentry.getCurrentScopes() }.thenReturn(fixture.scopes) + it.`when` { Sentry.cloneMainHub() }.thenReturn(fixture.scopes) closure.invoke() } @@ -94,10 +97,10 @@ class SentryWebFluxTracingFilterTest { fun `creates transaction around the request`() { val filter = fixture.getSut() - withMockHub { + withMockScopes { filter.filter(fixture.exchange, fixture.chain).block() - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( check { assertEquals("POST /product/12", it.name) assertEquals(TransactionNameSource.URL, it.transactionNameSource) @@ -110,7 +113,7 @@ class SentryWebFluxTracingFilterTest { } ) verify(fixture.chain).filter(fixture.exchange) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.transaction).isEqualTo("POST /product/{id}") assertThat(it.contexts.trace!!.status).isEqualTo(SpanStatus.OK) @@ -129,10 +132,10 @@ class SentryWebFluxTracingFilterTest { fun `sets correct span status based on the response status`() { val filter = fixture.getSut(status = HttpStatus.INTERNAL_SERVER_ERROR) - withMockHub { + withMockScopes { filter.filter(fixture.exchange, fixture.chain).block() - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.status).isEqualTo(SpanStatus.INTERNAL_ERROR) assertThat(it.contexts.response!!.statusCode).isEqualTo(500) @@ -148,10 +151,10 @@ class SentryWebFluxTracingFilterTest { fun `does not set span status for response status that dont match predefined span statuses`() { val filter = fixture.getSut(status = HttpStatus.FOUND) - withMockHub { + withMockScopes { filter.filter(fixture.exchange, fixture.chain).block() - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.status).isNull() }, @@ -166,10 +169,10 @@ class SentryWebFluxTracingFilterTest { fun `when sentry trace is not present, transaction does not have parentSpanId set`() { val filter = fixture.getSut() - withMockHub { + withMockScopes { filter.filter(fixture.exchange, fixture.chain).block() - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.parentSpanId).isNull() }, @@ -185,10 +188,10 @@ class SentryWebFluxTracingFilterTest { val parentSpanId = SpanId() val filter = fixture.getSut(sentryTraceHeader = "${SentryId()}-$parentSpanId-1") - withMockHub { + withMockScopes { filter.filter(fixture.exchange, fixture.chain).block() - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.parentSpanId).isEqualTo(parentSpanId) }, @@ -200,16 +203,16 @@ class SentryWebFluxTracingFilterTest { } @Test - fun `when hub is disabled, components are not invoked`() { + fun `when scopes is disabled, components are not invoked`() { val filter = fixture.getSut(isEnabled = false) - withMockHub { + withMockScopes { filter.filter(fixture.exchange, fixture.chain).block() verify(fixture.chain).filter(fixture.exchange) - verify(fixture.hub).isEnabled - verifyNoMoreInteractions(fixture.hub) + verify(fixture.scopes).isEnabled + verifyNoMoreInteractions(fixture.scopes) } } @@ -217,7 +220,7 @@ class SentryWebFluxTracingFilterTest { fun `sets status to internal server error when chain throws exception`() { val filter = fixture.getSut() - withMockHub { + withMockScopes { whenever(fixture.chain.filter(any())).thenReturn(Mono.error(RuntimeException("error"))) try { @@ -225,7 +228,7 @@ class SentryWebFluxTracingFilterTest { fail("filter is expected to rethrow exception") } catch (_: Exception) { } - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.status).isEqualTo(SpanStatus.INTERNAL_ERROR) }, @@ -240,21 +243,21 @@ class SentryWebFluxTracingFilterTest { fun `does not track OPTIONS request with traceOptionsRequests=false`() { val filter = fixture.getSut(method = HttpMethod.OPTIONS) - withMockHub { + withMockScopes { fixture.options.isTraceOptionsRequests = false filter.filter(fixture.exchange, fixture.chain).block() verify(fixture.chain).filter(fixture.exchange) - verify(fixture.hub).isEnabled - verify(fixture.hub, times(2)).options - verify(fixture.hub).continueTrace(anyOrNull(), anyOrNull()) - verify(fixture.hub).pushScope() - verify(fixture.hub).addBreadcrumb(any(), any()) - verify(fixture.hub).configureScope(any()) - verify(fixture.hub).popScope() - verifyNoMoreInteractions(fixture.hub) + verify(fixture.scopes).isEnabled + verify(fixture.scopes, times(2)).options + verify(fixture.scopes).continueTrace(anyOrNull(), anyOrNull()) + verify(fixture.scopes).pushScope() + verify(fixture.scopes).addBreadcrumb(any(), any()) + verify(fixture.scopes).configureScope(any()) + verify(fixture.scopes).popScope() + verifyNoMoreInteractions(fixture.scopes) } } @@ -262,14 +265,14 @@ class SentryWebFluxTracingFilterTest { fun `tracks OPTIONS request with traceOptionsRequests=true`() { val filter = fixture.getSut(method = HttpMethod.OPTIONS) - withMockHub { + withMockScopes { fixture.options.isTraceOptionsRequests = true filter.filter(fixture.exchange, fixture.chain).block() verify(fixture.chain).filter(fixture.exchange) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.parentSpanId).isNull() }, @@ -284,14 +287,14 @@ class SentryWebFluxTracingFilterTest { fun `tracks POST request with traceOptionsRequests=false`() { val filter = fixture.getSut(method = HttpMethod.POST) - withMockHub { + withMockScopes { fixture.options.isTraceOptionsRequests = false filter.filter(fixture.exchange, fixture.chain).block() verify(fixture.chain).filter(fixture.exchange) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.parentSpanId).isNull() }, @@ -310,19 +313,19 @@ class SentryWebFluxTracingFilterTest { fixture.options.enableTracing = false val filter = fixture.getSut(sentryTraceHeader = sentryTraceHeaderString, baggageHeaders = baggageHeaderStrings) - withMockHub { + withMockScopes { filter.filter(fixture.exchange, fixture.chain).block() verify(fixture.chain).filter(fixture.exchange) - verify(fixture.hub, never()).captureTransaction( + verify(fixture.scopes, never()).captureTransaction( anyOrNull(), anyOrNull(), anyOrNull(), anyOrNull() ) - verify(fixture.hub).continueTrace(eq(sentryTraceHeaderString), eq(baggageHeaderStrings)) + verify(fixture.scopes).continueTrace(eq(sentryTraceHeaderString), eq(baggageHeaderStrings)) } } } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryWebfluxIntegrationTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryWebfluxIntegrationTest.kt index 0d4346c5ae..8c5aeb1c0a 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryWebfluxIntegrationTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryWebfluxIntegrationTest.kt @@ -1,8 +1,8 @@ package io.sentry.spring.webflux -import io.sentry.HubAdapter -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ITransportFactory +import io.sentry.ScopesAdapter import io.sentry.Sentry import io.sentry.checkEvent import io.sentry.checkTransaction @@ -160,13 +160,13 @@ open class App { open fun mockTransport() = transport @Bean - open fun hub() = HubAdapter.getInstance() + open fun scopes() = ScopesAdapter.getInstance() @Bean - open fun sentryFilter(hub: IHub) = SentryWebFilter(hub) + open fun sentryFilter(scopes: IScopes) = SentryWebFilter(scopes) @Bean - open fun sentryWebExceptionHandler(hub: IHub) = SentryWebExceptionHandler(hub) + open fun sentryWebExceptionHandler(scopes: IScopes) = SentryWebExceptionHandler(scopes) @Bean open fun sentryScheduleHookRegistrar() = ApplicationRunner { diff --git a/sentry-test-support/api/sentry-test-support.api b/sentry-test-support/api/sentry-test-support.api index ffce23a516..dd1a4b69d3 100644 --- a/sentry-test-support/api/sentry-test-support.api +++ b/sentry-test-support/api/sentry-test-support.api @@ -32,6 +32,7 @@ public final class io/sentry/test/ImmediateExecutorService : io/sentry/ISentryEx } public final class io/sentry/test/ReflectionKt { + public static final fun collectInterfaceHierarchy (Ljava/lang/Class;)Ljava/util/List; public static final fun containsMethod (Ljava/lang/Class;Ljava/lang/String;Ljava/lang/Class;)Z public static final fun containsMethod (Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/Class;)Z public static final fun getCtor (Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Constructor; diff --git a/sentry-test-support/src/main/kotlin/io/sentry/test/Reflection.kt b/sentry-test-support/src/main/kotlin/io/sentry/test/Reflection.kt index 690dcc8725..19d11676e1 100644 --- a/sentry-test-support/src/main/kotlin/io/sentry/test/Reflection.kt +++ b/sentry-test-support/src/main/kotlin/io/sentry/test/Reflection.kt @@ -12,16 +12,23 @@ inline fun T.callMethod(name: String, parameterTypes: Class<*> val declaredMethod = try { T::class.java.getDeclaredMethod(name, parameterTypes) } catch (e: NoSuchMethodException) { - T::class.java.interfaces.first { it.containsMethod(name, parameterTypes) }.getDeclaredMethod(name, parameterTypes) + collectInterfaceHierarchy(T::class.java).first { it.containsMethod(name, parameterTypes) }.getDeclaredMethod(name, parameterTypes) } return declaredMethod.invoke(this, value) } +fun collectInterfaceHierarchy(clazz: Class<*>): List> { + if (clazz.interfaces.isEmpty()) { + return listOf(clazz) + } + return clazz.interfaces.flatMap { iface -> collectInterfaceHierarchy(iface) }.also { it.toMutableList().add(clazz) } +} + inline fun T.callMethod(name: String, parameterTypes: Array>, vararg value: Any?): Any? { val declaredMethod = try { T::class.java.getDeclaredMethod(name, *parameterTypes) } catch (e: NoSuchMethodException) { - T::class.java.interfaces.first { it.containsMethod(name, parameterTypes) }.getDeclaredMethod(name, *parameterTypes) + collectInterfaceHierarchy(T::class.java).first { it.containsMethod(name, parameterTypes) }.getDeclaredMethod(name, *parameterTypes) } return declaredMethod.invoke(this, *value) } diff --git a/sentry/api/sentry.api b/sentry/api/sentry.api index bcfc1c9194..52eb5df888 100644 --- a/sentry/api/sentry.api +++ b/sentry/api/sentry.api @@ -293,7 +293,7 @@ public final class io/sentry/EnvelopeReader : io/sentry/IEnvelopeReader { } public final class io/sentry/EnvelopeSender : io/sentry/IEnvelopeSender { - public fun (Lio/sentry/IHub;Lio/sentry/ISerializer;Lio/sentry/ILogger;JI)V + public fun (Lio/sentry/IScopes;Lio/sentry/ISerializer;Lio/sentry/ILogger;JI)V public synthetic fun processDirectory (Ljava/io/File;)V public fun processEnvelopeFile (Ljava/lang/String;Lio/sentry/Hint;)V } @@ -520,6 +520,59 @@ public final class io/sentry/HubAdapter : io/sentry/IHub { public fun withScope (Lio/sentry/ScopeCallback;)V } +public final class io/sentry/HubScopesWrapper : io/sentry/IHub { + public fun (Lio/sentry/IScopes;)V + public fun addBreadcrumb (Lio/sentry/Breadcrumb;)V + public fun addBreadcrumb (Lio/sentry/Breadcrumb;Lio/sentry/Hint;)V + public fun bindClient (Lio/sentry/ISentryClient;)V + public fun captureCheckIn (Lio/sentry/CheckIn;)Lio/sentry/protocol/SentryId; + public fun captureEnvelope (Lio/sentry/SentryEnvelope;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; + public fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; + public fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public fun captureException (Ljava/lang/Throwable;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; + public fun captureException (Ljava/lang/Throwable;Lio/sentry/Hint;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;)Lio/sentry/protocol/SentryId; + public fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public fun captureTransaction (Lio/sentry/protocol/SentryTransaction;Lio/sentry/TraceContext;Lio/sentry/Hint;Lio/sentry/ProfilingTraceData;)Lio/sentry/protocol/SentryId; + public fun captureUserFeedback (Lio/sentry/UserFeedback;)V + public fun clearBreadcrumbs ()V + public fun clone ()Lio/sentry/IHub; + public synthetic fun clone ()Ljava/lang/Object; + public fun close ()V + public fun close (Z)V + public fun configureScope (Lio/sentry/ScopeCallback;)V + public fun continueTrace (Ljava/lang/String;Ljava/util/List;)Lio/sentry/TransactionContext; + public fun endSession ()V + public fun flush (J)V + public fun getBaggage ()Lio/sentry/BaggageHeader; + public fun getLastEventId ()Lio/sentry/protocol/SentryId; + public fun getOptions ()Lio/sentry/SentryOptions; + public fun getRateLimiter ()Lio/sentry/transport/RateLimiter; + public fun getSpan ()Lio/sentry/ISpan; + public fun getTraceparent ()Lio/sentry/SentryTraceHeader; + public fun getTransaction ()Lio/sentry/ITransaction; + public fun isCrashedLastRun ()Ljava/lang/Boolean; + public fun isEnabled ()Z + public fun isHealthy ()Z + public fun metrics ()Lio/sentry/metrics/MetricsApi; + public fun popScope ()V + public fun pushScope ()V + public fun removeExtra (Ljava/lang/String;)V + public fun removeTag (Ljava/lang/String;)V + public fun reportFullyDisplayed ()V + public fun setExtra (Ljava/lang/String;Ljava/lang/String;)V + public fun setFingerprint (Ljava/util/List;)V + public fun setLevel (Lio/sentry/SentryLevel;)V + public fun setSpanContext (Ljava/lang/Throwable;Lio/sentry/ISpan;Ljava/lang/String;)V + public fun setTag (Ljava/lang/String;Ljava/lang/String;)V + public fun setTransaction (Ljava/lang/String;)V + public fun setUser (Lio/sentry/protocol/User;)V + public fun startSession ()V + public fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction; + public fun traceHeaders ()Lio/sentry/SentryTraceHeader; + public fun withScope (Lio/sentry/ScopeCallback;)V +} + public abstract interface class io/sentry/IConnectionStatusProvider { public abstract fun addConnectionStatusObserver (Lio/sentry/IConnectionStatusProvider$IConnectionStatusObserver;)Z public abstract fun getConnectionStatus ()Lio/sentry/IConnectionStatusProvider$ConnectionStatus; @@ -548,71 +601,7 @@ public abstract interface class io/sentry/IEnvelopeSender { public abstract fun processEnvelopeFile (Ljava/lang/String;Lio/sentry/Hint;)V } -public abstract interface class io/sentry/IHub { - public abstract fun addBreadcrumb (Lio/sentry/Breadcrumb;)V - public abstract fun addBreadcrumb (Lio/sentry/Breadcrumb;Lio/sentry/Hint;)V - public fun addBreadcrumb (Ljava/lang/String;)V - public fun addBreadcrumb (Ljava/lang/String;Ljava/lang/String;)V - public abstract fun bindClient (Lio/sentry/ISentryClient;)V - public abstract fun captureCheckIn (Lio/sentry/CheckIn;)Lio/sentry/protocol/SentryId; - public fun captureEnvelope (Lio/sentry/SentryEnvelope;)Lio/sentry/protocol/SentryId; - public abstract fun captureEnvelope (Lio/sentry/SentryEnvelope;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; - public fun captureEvent (Lio/sentry/SentryEvent;)Lio/sentry/protocol/SentryId; - public abstract fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; - public abstract fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; - public fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; - public fun captureException (Ljava/lang/Throwable;)Lio/sentry/protocol/SentryId; - public abstract fun captureException (Ljava/lang/Throwable;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; - public abstract fun captureException (Ljava/lang/Throwable;Lio/sentry/Hint;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; - public fun captureException (Ljava/lang/Throwable;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; - public fun captureMessage (Ljava/lang/String;)Lio/sentry/protocol/SentryId; - public fun captureMessage (Ljava/lang/String;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; - public abstract fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;)Lio/sentry/protocol/SentryId; - public abstract fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; - public fun captureTransaction (Lio/sentry/protocol/SentryTransaction;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; - public fun captureTransaction (Lio/sentry/protocol/SentryTransaction;Lio/sentry/TraceContext;)Lio/sentry/protocol/SentryId; - public fun captureTransaction (Lio/sentry/protocol/SentryTransaction;Lio/sentry/TraceContext;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; - public abstract fun captureTransaction (Lio/sentry/protocol/SentryTransaction;Lio/sentry/TraceContext;Lio/sentry/Hint;Lio/sentry/ProfilingTraceData;)Lio/sentry/protocol/SentryId; - public abstract fun captureUserFeedback (Lio/sentry/UserFeedback;)V - public abstract fun clearBreadcrumbs ()V - public abstract fun clone ()Lio/sentry/IHub; - public abstract fun close ()V - public abstract fun close (Z)V - public abstract fun configureScope (Lio/sentry/ScopeCallback;)V - public abstract fun continueTrace (Ljava/lang/String;Ljava/util/List;)Lio/sentry/TransactionContext; - public abstract fun endSession ()V - public abstract fun flush (J)V - public abstract fun getBaggage ()Lio/sentry/BaggageHeader; - public abstract fun getLastEventId ()Lio/sentry/protocol/SentryId; - public abstract fun getOptions ()Lio/sentry/SentryOptions; - public abstract fun getRateLimiter ()Lio/sentry/transport/RateLimiter; - public abstract fun getSpan ()Lio/sentry/ISpan; - public abstract fun getTraceparent ()Lio/sentry/SentryTraceHeader; - public abstract fun getTransaction ()Lio/sentry/ITransaction; - public abstract fun isCrashedLastRun ()Ljava/lang/Boolean; - public abstract fun isEnabled ()Z - public abstract fun isHealthy ()Z - public abstract fun metrics ()Lio/sentry/metrics/MetricsApi; - public abstract fun popScope ()V - public abstract fun pushScope ()V - public abstract fun removeExtra (Ljava/lang/String;)V - public abstract fun removeTag (Ljava/lang/String;)V - public fun reportFullDisplayed ()V - public abstract fun reportFullyDisplayed ()V - public abstract fun setExtra (Ljava/lang/String;Ljava/lang/String;)V - public abstract fun setFingerprint (Ljava/util/List;)V - public abstract fun setLevel (Lio/sentry/SentryLevel;)V - public abstract fun setSpanContext (Ljava/lang/Throwable;Lio/sentry/ISpan;Ljava/lang/String;)V - public abstract fun setTag (Ljava/lang/String;Ljava/lang/String;)V - public abstract fun setTransaction (Ljava/lang/String;)V - public abstract fun setUser (Lio/sentry/protocol/User;)V - public abstract fun startSession ()V - public fun startTransaction (Lio/sentry/TransactionContext;)Lio/sentry/ITransaction; - public abstract fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction; - public fun startTransaction (Ljava/lang/String;Ljava/lang/String;)Lio/sentry/ITransaction; - public fun startTransaction (Ljava/lang/String;Ljava/lang/String;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction; - public abstract fun traceHeaders ()Lio/sentry/SentryTraceHeader; - public abstract fun withScope (Lio/sentry/ScopeCallback;)V +public abstract interface class io/sentry/IHub : io/sentry/IScopes { } public abstract interface class io/sentry/ILogger { @@ -731,6 +720,74 @@ public abstract interface class io/sentry/IScopeObserver { public abstract fun setUser (Lio/sentry/protocol/User;)V } +public abstract interface class io/sentry/IScopes { + public abstract fun addBreadcrumb (Lio/sentry/Breadcrumb;)V + public abstract fun addBreadcrumb (Lio/sentry/Breadcrumb;Lio/sentry/Hint;)V + public fun addBreadcrumb (Ljava/lang/String;)V + public fun addBreadcrumb (Ljava/lang/String;Ljava/lang/String;)V + public abstract fun bindClient (Lio/sentry/ISentryClient;)V + public abstract fun captureCheckIn (Lio/sentry/CheckIn;)Lio/sentry/protocol/SentryId; + public fun captureEnvelope (Lio/sentry/SentryEnvelope;)Lio/sentry/protocol/SentryId; + public abstract fun captureEnvelope (Lio/sentry/SentryEnvelope;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; + public fun captureEvent (Lio/sentry/SentryEvent;)Lio/sentry/protocol/SentryId; + public abstract fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; + public abstract fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public fun captureException (Ljava/lang/Throwable;)Lio/sentry/protocol/SentryId; + public abstract fun captureException (Ljava/lang/Throwable;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; + public abstract fun captureException (Ljava/lang/Throwable;Lio/sentry/Hint;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public fun captureException (Ljava/lang/Throwable;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public fun captureMessage (Ljava/lang/String;)Lio/sentry/protocol/SentryId; + public fun captureMessage (Ljava/lang/String;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public abstract fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;)Lio/sentry/protocol/SentryId; + public abstract fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public fun captureTransaction (Lio/sentry/protocol/SentryTransaction;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; + public fun captureTransaction (Lio/sentry/protocol/SentryTransaction;Lio/sentry/TraceContext;)Lio/sentry/protocol/SentryId; + public fun captureTransaction (Lio/sentry/protocol/SentryTransaction;Lio/sentry/TraceContext;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; + public abstract fun captureTransaction (Lio/sentry/protocol/SentryTransaction;Lio/sentry/TraceContext;Lio/sentry/Hint;Lio/sentry/ProfilingTraceData;)Lio/sentry/protocol/SentryId; + public abstract fun captureUserFeedback (Lio/sentry/UserFeedback;)V + public abstract fun clearBreadcrumbs ()V + public abstract fun clone ()Lio/sentry/IHub; + public abstract fun close ()V + public abstract fun close (Z)V + public abstract fun configureScope (Lio/sentry/ScopeCallback;)V + public abstract fun continueTrace (Ljava/lang/String;Ljava/util/List;)Lio/sentry/TransactionContext; + public abstract fun endSession ()V + public abstract fun flush (J)V + public abstract fun getBaggage ()Lio/sentry/BaggageHeader; + public abstract fun getLastEventId ()Lio/sentry/protocol/SentryId; + public abstract fun getOptions ()Lio/sentry/SentryOptions; + public abstract fun getRateLimiter ()Lio/sentry/transport/RateLimiter; + public abstract fun getSpan ()Lio/sentry/ISpan; + public abstract fun getTraceparent ()Lio/sentry/SentryTraceHeader; + public abstract fun getTransaction ()Lio/sentry/ITransaction; + public abstract fun isCrashedLastRun ()Ljava/lang/Boolean; + public abstract fun isEnabled ()Z + public abstract fun isHealthy ()Z + public fun isNoOp ()Z + public abstract fun metrics ()Lio/sentry/metrics/MetricsApi; + public abstract fun popScope ()V + public abstract fun pushScope ()V + public abstract fun removeExtra (Ljava/lang/String;)V + public abstract fun removeTag (Ljava/lang/String;)V + public fun reportFullDisplayed ()V + public abstract fun reportFullyDisplayed ()V + public abstract fun setExtra (Ljava/lang/String;Ljava/lang/String;)V + public abstract fun setFingerprint (Ljava/util/List;)V + public abstract fun setLevel (Lio/sentry/SentryLevel;)V + public abstract fun setSpanContext (Ljava/lang/Throwable;Lio/sentry/ISpan;Ljava/lang/String;)V + public abstract fun setTag (Ljava/lang/String;Ljava/lang/String;)V + public abstract fun setTransaction (Ljava/lang/String;)V + public abstract fun setUser (Lio/sentry/protocol/User;)V + public abstract fun startSession ()V + public fun startTransaction (Lio/sentry/TransactionContext;)Lio/sentry/ITransaction; + public abstract fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction; + public fun startTransaction (Ljava/lang/String;Ljava/lang/String;)Lio/sentry/ITransaction; + public fun startTransaction (Ljava/lang/String;Ljava/lang/String;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction; + public abstract fun traceHeaders ()Lio/sentry/SentryTraceHeader; + public abstract fun withScope (Lio/sentry/ScopeCallback;)V +} + public abstract interface class io/sentry/ISentryClient { public abstract fun captureCheckIn (Lio/sentry/CheckIn;Lio/sentry/IScope;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; public fun captureEnvelope (Lio/sentry/SentryEnvelope;)Lio/sentry/protocol/SentryId; @@ -853,7 +910,7 @@ public final class io/sentry/Instrumenter : java/lang/Enum { } public abstract interface class io/sentry/Integration { - public abstract fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public abstract fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/IpAddressUtils { @@ -1187,6 +1244,7 @@ public final class io/sentry/NoOpHub : io/sentry/IHub { public fun isCrashedLastRun ()Ljava/lang/Boolean; public fun isEnabled ()Z public fun isHealthy ()Z + public fun isNoOp ()Z public fun metrics ()Lio/sentry/metrics/MetricsApi; public fun popScope ()V public fun pushScope ()V @@ -1270,6 +1328,60 @@ public final class io/sentry/NoOpScope : io/sentry/IScope { public fun withTransaction (Lio/sentry/Scope$IWithTransaction;)V } +public final class io/sentry/NoOpScopes : io/sentry/IScopes { + public fun addBreadcrumb (Lio/sentry/Breadcrumb;)V + public fun addBreadcrumb (Lio/sentry/Breadcrumb;Lio/sentry/Hint;)V + public fun bindClient (Lio/sentry/ISentryClient;)V + public fun captureCheckIn (Lio/sentry/CheckIn;)Lio/sentry/protocol/SentryId; + public fun captureEnvelope (Lio/sentry/SentryEnvelope;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; + public fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; + public fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public fun captureException (Ljava/lang/Throwable;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; + public fun captureException (Ljava/lang/Throwable;Lio/sentry/Hint;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;)Lio/sentry/protocol/SentryId; + public fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public fun captureTransaction (Lio/sentry/protocol/SentryTransaction;Lio/sentry/TraceContext;Lio/sentry/Hint;Lio/sentry/ProfilingTraceData;)Lio/sentry/protocol/SentryId; + public fun captureUserFeedback (Lio/sentry/UserFeedback;)V + public fun clearBreadcrumbs ()V + public fun clone ()Lio/sentry/IHub; + public synthetic fun clone ()Ljava/lang/Object; + public fun close ()V + public fun close (Z)V + public fun configureScope (Lio/sentry/ScopeCallback;)V + public fun continueTrace (Ljava/lang/String;Ljava/util/List;)Lio/sentry/TransactionContext; + public fun endSession ()V + public fun flush (J)V + public fun getBaggage ()Lio/sentry/BaggageHeader; + public static fun getInstance ()Lio/sentry/NoOpScopes; + public fun getLastEventId ()Lio/sentry/protocol/SentryId; + public fun getOptions ()Lio/sentry/SentryOptions; + public fun getRateLimiter ()Lio/sentry/transport/RateLimiter; + public fun getSpan ()Lio/sentry/ISpan; + public fun getTraceparent ()Lio/sentry/SentryTraceHeader; + public fun getTransaction ()Lio/sentry/ITransaction; + public fun isCrashedLastRun ()Ljava/lang/Boolean; + public fun isEnabled ()Z + public fun isHealthy ()Z + public fun isNoOp ()Z + public fun metrics ()Lio/sentry/metrics/MetricsApi; + public fun popScope ()V + public fun pushScope ()V + public fun removeExtra (Ljava/lang/String;)V + public fun removeTag (Ljava/lang/String;)V + public fun reportFullyDisplayed ()V + public fun setExtra (Ljava/lang/String;Ljava/lang/String;)V + public fun setFingerprint (Ljava/util/List;)V + public fun setLevel (Lio/sentry/SentryLevel;)V + public fun setSpanContext (Ljava/lang/Throwable;Lio/sentry/ISpan;Ljava/lang/String;)V + public fun setTag (Ljava/lang/String;Ljava/lang/String;)V + public fun setTransaction (Ljava/lang/String;)V + public fun setUser (Lio/sentry/protocol/User;)V + public fun startSession ()V + public fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction; + public fun traceHeaders ()Lio/sentry/SentryTraceHeader; + public fun withScope (Lio/sentry/ScopeCallback;)V +} + public final class io/sentry/NoOpSpan : io/sentry/ISpan { public fun finish ()V public fun finish (Lio/sentry/SpanStatus;)V @@ -1403,7 +1515,7 @@ public final class io/sentry/OptionsContainer { } public final class io/sentry/OutboxSender : io/sentry/IEnvelopeSender { - public fun (Lio/sentry/IHub;Lio/sentry/IEnvelopeReader;Lio/sentry/ISerializer;Lio/sentry/ILogger;JI)V + public fun (Lio/sentry/IScopes;Lio/sentry/IEnvelopeReader;Lio/sentry/ISerializer;Lio/sentry/ILogger;JI)V public synthetic fun processDirectory (Ljava/io/File;)V public fun processEnvelopeFile (Ljava/lang/String;Lio/sentry/Hint;)V } @@ -1668,11 +1780,64 @@ public abstract class io/sentry/ScopeObserverAdapter : io/sentry/IScopeObserver public fun setUser (Lio/sentry/protocol/User;)V } +public final class io/sentry/ScopesAdapter : io/sentry/IScopes { + public fun addBreadcrumb (Lio/sentry/Breadcrumb;)V + public fun addBreadcrumb (Lio/sentry/Breadcrumb;Lio/sentry/Hint;)V + public fun bindClient (Lio/sentry/ISentryClient;)V + public fun captureCheckIn (Lio/sentry/CheckIn;)Lio/sentry/protocol/SentryId; + public fun captureEnvelope (Lio/sentry/SentryEnvelope;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; + public fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; + public fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public fun captureException (Ljava/lang/Throwable;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; + public fun captureException (Ljava/lang/Throwable;Lio/sentry/Hint;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;)Lio/sentry/protocol/SentryId; + public fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public fun captureTransaction (Lio/sentry/protocol/SentryTransaction;Lio/sentry/TraceContext;Lio/sentry/Hint;Lio/sentry/ProfilingTraceData;)Lio/sentry/protocol/SentryId; + public fun captureUserFeedback (Lio/sentry/UserFeedback;)V + public fun clearBreadcrumbs ()V + public fun clone ()Lio/sentry/IHub; + public synthetic fun clone ()Ljava/lang/Object; + public fun close ()V + public fun close (Z)V + public fun configureScope (Lio/sentry/ScopeCallback;)V + public fun continueTrace (Ljava/lang/String;Ljava/util/List;)Lio/sentry/TransactionContext; + public fun endSession ()V + public fun flush (J)V + public fun getBaggage ()Lio/sentry/BaggageHeader; + public static fun getInstance ()Lio/sentry/ScopesAdapter; + public fun getLastEventId ()Lio/sentry/protocol/SentryId; + public fun getOptions ()Lio/sentry/SentryOptions; + public fun getRateLimiter ()Lio/sentry/transport/RateLimiter; + public fun getSpan ()Lio/sentry/ISpan; + public fun getTraceparent ()Lio/sentry/SentryTraceHeader; + public fun getTransaction ()Lio/sentry/ITransaction; + public fun isCrashedLastRun ()Ljava/lang/Boolean; + public fun isEnabled ()Z + public fun isHealthy ()Z + public fun metrics ()Lio/sentry/metrics/MetricsApi; + public fun popScope ()V + public fun pushScope ()V + public fun removeExtra (Ljava/lang/String;)V + public fun removeTag (Ljava/lang/String;)V + public fun reportFullyDisplayed ()V + public fun setExtra (Ljava/lang/String;Ljava/lang/String;)V + public fun setFingerprint (Ljava/util/List;)V + public fun setLevel (Lio/sentry/SentryLevel;)V + public fun setSpanContext (Ljava/lang/Throwable;Lio/sentry/ISpan;Ljava/lang/String;)V + public fun setTag (Ljava/lang/String;Ljava/lang/String;)V + public fun setTransaction (Ljava/lang/String;)V + public fun setUser (Lio/sentry/protocol/User;)V + public fun startSession ()V + public fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction; + public fun traceHeaders ()Lio/sentry/SentryTraceHeader; + public fun withScope (Lio/sentry/ScopeCallback;)V +} + public final class io/sentry/SendCachedEnvelopeFireAndForgetIntegration : io/sentry/IConnectionStatusProvider$IConnectionStatusObserver, io/sentry/Integration, java/io/Closeable { public fun (Lio/sentry/SendCachedEnvelopeFireAndForgetIntegration$SendFireAndForgetFactory;)V public fun close ()V public fun onConnectionStatusChanged (Lio/sentry/IConnectionStatusProvider$ConnectionStatus;)V - public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public abstract interface class io/sentry/SendCachedEnvelopeFireAndForgetIntegration$SendFireAndForget { @@ -1684,19 +1849,19 @@ public abstract interface class io/sentry/SendCachedEnvelopeFireAndForgetIntegra } public abstract interface class io/sentry/SendCachedEnvelopeFireAndForgetIntegration$SendFireAndForgetFactory { - public abstract fun create (Lio/sentry/IHub;Lio/sentry/SentryOptions;)Lio/sentry/SendCachedEnvelopeFireAndForgetIntegration$SendFireAndForget; + public abstract fun create (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)Lio/sentry/SendCachedEnvelopeFireAndForgetIntegration$SendFireAndForget; public fun hasValidPath (Ljava/lang/String;Lio/sentry/ILogger;)Z public fun processDir (Lio/sentry/DirectoryProcessor;Ljava/lang/String;Lio/sentry/ILogger;)Lio/sentry/SendCachedEnvelopeFireAndForgetIntegration$SendFireAndForget; } public final class io/sentry/SendFireAndForgetEnvelopeSender : io/sentry/SendCachedEnvelopeFireAndForgetIntegration$SendFireAndForgetFactory { public fun (Lio/sentry/SendCachedEnvelopeFireAndForgetIntegration$SendFireAndForgetDirPath;)V - public fun create (Lio/sentry/IHub;Lio/sentry/SentryOptions;)Lio/sentry/SendCachedEnvelopeFireAndForgetIntegration$SendFireAndForget; + public fun create (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)Lio/sentry/SendCachedEnvelopeFireAndForgetIntegration$SendFireAndForget; } public final class io/sentry/SendFireAndForgetOutboxSender : io/sentry/SendCachedEnvelopeFireAndForgetIntegration$SendFireAndForgetFactory { public fun (Lio/sentry/SendCachedEnvelopeFireAndForgetIntegration$SendFireAndForgetDirPath;)V - public fun create (Lio/sentry/IHub;Lio/sentry/SentryOptions;)Lio/sentry/SendCachedEnvelopeFireAndForgetIntegration$SendFireAndForget; + public fun create (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)Lio/sentry/SendCachedEnvelopeFireAndForgetIntegration$SendFireAndForget; } public final class io/sentry/Sentry { @@ -1721,7 +1886,7 @@ public final class io/sentry/Sentry { public static fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; public static fun captureUserFeedback (Lio/sentry/UserFeedback;)V public static fun clearBreadcrumbs ()V - public static fun cloneMainHub ()Lio/sentry/IHub; + public static fun cloneMainHub ()Lio/sentry/IScopes; public static fun close ()V public static fun configureScope (Lio/sentry/ScopeCallback;)V public static fun continueTrace (Ljava/lang/String;Ljava/util/List;)Lio/sentry/TransactionContext; @@ -1729,6 +1894,7 @@ public final class io/sentry/Sentry { public static fun flush (J)V public static fun getBaggage ()Lio/sentry/BaggageHeader; public static fun getCurrentHub ()Lio/sentry/IHub; + public static fun getCurrentScopes ()Lio/sentry/IScopes; public static fun getLastEventId ()Lio/sentry/protocol/SentryId; public static fun getSpan ()Lio/sentry/ISpan; public static fun getTraceparent ()Lio/sentry/SentryTraceHeader; @@ -1750,6 +1916,7 @@ public final class io/sentry/Sentry { public static fun reportFullDisplayed ()V public static fun reportFullyDisplayed ()V public static fun setCurrentHub (Lio/sentry/IHub;)V + public static fun setCurrentScopes (Lio/sentry/IScopes;)V public static fun setExtra (Ljava/lang/String;Ljava/lang/String;)V public static fun setFingerprint (Ljava/util/List;)V public static fun setLevel (Lio/sentry/SentryLevel;)V @@ -2500,8 +2667,8 @@ public final class io/sentry/SentryTraceHeader { } public final class io/sentry/SentryTracer : io/sentry/ITransaction { - public fun (Lio/sentry/TransactionContext;Lio/sentry/IHub;)V - public fun (Lio/sentry/TransactionContext;Lio/sentry/IHub;Lio/sentry/TransactionOptions;)V + public fun (Lio/sentry/TransactionContext;Lio/sentry/IScopes;)V + public fun (Lio/sentry/TransactionContext;Lio/sentry/IScopes;Lio/sentry/TransactionOptions;)V public fun finish ()V public fun finish (Lio/sentry/SpanStatus;)V public fun finish (Lio/sentry/SpanStatus;Lio/sentry/SentryDate;)V @@ -2630,11 +2797,11 @@ public final class io/sentry/ShutdownHookIntegration : io/sentry/Integration, ja public fun ()V public fun (Ljava/lang/Runtime;)V public fun close ()V - public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/Span : io/sentry/ISpan { - public fun (Lio/sentry/TransactionContext;Lio/sentry/SentryTracer;Lio/sentry/IHub;Lio/sentry/SentryDate;Lio/sentry/SpanOptions;)V + public fun (Lio/sentry/TransactionContext;Lio/sentry/SentryTracer;Lio/sentry/IScopes;Lio/sentry/SentryDate;Lio/sentry/SpanOptions;)V public fun finish ()V public fun finish (Lio/sentry/SpanStatus;)V public fun finish (Lio/sentry/SpanStatus;Lio/sentry/SentryDate;)V @@ -2815,7 +2982,7 @@ public final class io/sentry/SpotlightIntegration : io/sentry/Integration, io/se public fun close ()V public fun execute (Lio/sentry/SentryEnvelope;Lio/sentry/Hint;)V public fun getSpotlightConnectionUrl ()Ljava/lang/String; - public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/SystemOutLogger : io/sentry/ILogger { @@ -2975,7 +3142,7 @@ public final class io/sentry/TypeCheckHint { public final class io/sentry/UncaughtExceptionHandlerIntegration : io/sentry/Integration, java/io/Closeable, java/lang/Thread$UncaughtExceptionHandler { public fun ()V public fun close ()V - public final fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public final fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V public fun uncaughtException (Ljava/lang/Thread;Ljava/lang/Throwable;)V } @@ -3016,7 +3183,7 @@ public final class io/sentry/UserFeedback$JsonKeys { } public final class io/sentry/backpressure/BackpressureMonitor : io/sentry/backpressure/IBackpressureMonitor, java/lang/Runnable { - public fun (Lio/sentry/SentryOptions;Lio/sentry/IHub;)V + public fun (Lio/sentry/SentryOptions;Lio/sentry/IScopes;)V public fun getDownsampleFactor ()I public fun run ()V public fun start ()V @@ -5102,9 +5269,9 @@ public final class io/sentry/util/StringUtils { public final class io/sentry/util/TracingUtils { public fun ()V public static fun maybeUpdateBaggage (Lio/sentry/IScope;Lio/sentry/SentryOptions;)Lio/sentry/PropagationContext; - public static fun startNewTrace (Lio/sentry/IHub;)V - public static fun trace (Lio/sentry/IHub;Ljava/util/List;Lio/sentry/ISpan;)Lio/sentry/util/TracingUtils$TracingHeaders; - public static fun traceIfAllowed (Lio/sentry/IHub;Ljava/lang/String;Ljava/util/List;Lio/sentry/ISpan;)Lio/sentry/util/TracingUtils$TracingHeaders; + public static fun startNewTrace (Lio/sentry/IScopes;)V + public static fun trace (Lio/sentry/IScopes;Ljava/util/List;Lio/sentry/ISpan;)Lio/sentry/util/TracingUtils$TracingHeaders; + public static fun traceIfAllowed (Lio/sentry/IScopes;Ljava/lang/String;Ljava/util/List;Lio/sentry/ISpan;)Lio/sentry/util/TracingUtils$TracingHeaders; } public final class io/sentry/util/TracingUtils$TracingHeaders { diff --git a/sentry/src/main/java/io/sentry/Baggage.java b/sentry/src/main/java/io/sentry/Baggage.java index 8e19fceaf8..4a637bacdf 100644 --- a/sentry/src/main/java/io/sentry/Baggage.java +++ b/sentry/src/main/java/io/sentry/Baggage.java @@ -39,13 +39,13 @@ public final class Baggage { @NotNull public static Baggage fromHeader(final @Nullable String headerValue) { return Baggage.fromHeader( - headerValue, false, HubAdapter.getInstance().getOptions().getLogger()); + headerValue, false, ScopesAdapter.getInstance().getOptions().getLogger()); } @NotNull public static Baggage fromHeader(final @Nullable List headerValues) { return Baggage.fromHeader( - headerValues, false, HubAdapter.getInstance().getOptions().getLogger()); + headerValues, false, ScopesAdapter.getInstance().getOptions().getLogger()); } @ApiStatus.Internal diff --git a/sentry/src/main/java/io/sentry/DirectoryProcessor.java b/sentry/src/main/java/io/sentry/DirectoryProcessor.java index 5d60feba60..a6bb258f30 100644 --- a/sentry/src/main/java/io/sentry/DirectoryProcessor.java +++ b/sentry/src/main/java/io/sentry/DirectoryProcessor.java @@ -19,17 +19,17 @@ abstract class DirectoryProcessor { private static final long ENVELOPE_PROCESSING_DELAY = 100L; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @NotNull ILogger logger; private final long flushTimeoutMillis; private final Queue processedEnvelopes; DirectoryProcessor( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull ILogger logger, final long flushTimeoutMillis, final int maxQueueSize) { - this.hub = hub; + this.scopes = scopes; this.logger = logger; this.flushTimeoutMillis = flushTimeoutMillis; this.processedEnvelopes = @@ -86,7 +86,7 @@ public void processDirectory(final @NotNull File directory) { } // in case there's rate limiting active, skip processing - final @Nullable RateLimiter rateLimiter = hub.getRateLimiter(); + final @Nullable RateLimiter rateLimiter = scopes.getRateLimiter(); if (rateLimiter != null && rateLimiter.isActiveForCategory(DataCategory.All)) { logger.log(SentryLevel.INFO, "DirectoryProcessor, rate limiting active."); return; diff --git a/sentry/src/main/java/io/sentry/EnvelopeSender.java b/sentry/src/main/java/io/sentry/EnvelopeSender.java index 598caad280..3a157f59d3 100644 --- a/sentry/src/main/java/io/sentry/EnvelopeSender.java +++ b/sentry/src/main/java/io/sentry/EnvelopeSender.java @@ -17,18 +17,18 @@ @ApiStatus.Internal public final class EnvelopeSender extends DirectoryProcessor implements IEnvelopeSender { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @NotNull ISerializer serializer; private final @NotNull ILogger logger; public EnvelopeSender( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull ISerializer serializer, final @NotNull ILogger logger, final long flushTimeoutMillis, final int maxQueueSize) { - super(hub, logger, flushTimeoutMillis, maxQueueSize); - this.hub = Objects.requireNonNull(hub, "Hub is required."); + super(scopes, logger, flushTimeoutMillis, maxQueueSize); + this.scopes = Objects.requireNonNull(scopes, "Hub is required."); this.serializer = Objects.requireNonNull(serializer, "Serializer is required."); this.logger = Objects.requireNonNull(logger, "Logger is required."); } @@ -60,7 +60,7 @@ protected void processFile(final @NotNull File file, final @NotNull Hint hint) { logger.log( SentryLevel.ERROR, "Failed to deserialize cached envelope %s", file.getAbsolutePath()); } else { - hub.captureEnvelope(envelope, hint); + scopes.captureEnvelope(envelope, hint); } HintUtils.runIfHasTypeLogIfNot( diff --git a/sentry/src/main/java/io/sentry/Hub.java b/sentry/src/main/java/io/sentry/Hub.java index 6b6da88f09..6a98bb2367 100644 --- a/sentry/src/main/java/io/sentry/Hub.java +++ b/sentry/src/main/java/io/sentry/Hub.java @@ -27,6 +27,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +@Deprecated public final class Hub implements IHub, MetricsApi.IMetricsInterface { private volatile @NotNull SentryId lastEventId; diff --git a/sentry/src/main/java/io/sentry/HubAdapter.java b/sentry/src/main/java/io/sentry/HubAdapter.java index b31d853192..746d51f0cc 100644 --- a/sentry/src/main/java/io/sentry/HubAdapter.java +++ b/sentry/src/main/java/io/sentry/HubAdapter.java @@ -10,6 +10,10 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +/** + * @deprecated use {@link ScopesAdapter} instead + */ +@Deprecated public final class HubAdapter implements IHub { private static final HubAdapter INSTANCE = new HubAdapter(); @@ -50,7 +54,7 @@ public boolean isEnabled() { @ApiStatus.Internal @Override public @NotNull SentryId captureEnvelope(@NotNull SentryEnvelope envelope, @Nullable Hint hint) { - return Sentry.getCurrentHub().captureEnvelope(envelope, hint); + return Sentry.getCurrentScopes().captureEnvelope(envelope, hint); } @Override @@ -186,7 +190,7 @@ public void flush(long timeoutMillis) { @Override public @NotNull IHub clone() { - return Sentry.getCurrentHub().clone(); + return Sentry.getCurrentScopes().clone(); } @Override @@ -195,7 +199,7 @@ public void flush(long timeoutMillis) { @Nullable TraceContext traceContext, @Nullable Hint hint, @Nullable ProfilingTraceData profilingTraceData) { - return Sentry.getCurrentHub() + return Sentry.getCurrentScopes() .captureTransaction(transaction, traceContext, hint, profilingTraceData); } @@ -217,23 +221,23 @@ public void setSpanContext( final @NotNull Throwable throwable, final @NotNull ISpan span, final @NotNull String transactionName) { - Sentry.getCurrentHub().setSpanContext(throwable, span, transactionName); + Sentry.getCurrentScopes().setSpanContext(throwable, span, transactionName); } @Override public @Nullable ISpan getSpan() { - return Sentry.getCurrentHub().getSpan(); + return Sentry.getCurrentScopes().getSpan(); } @Override @ApiStatus.Internal public @Nullable ITransaction getTransaction() { - return Sentry.getCurrentHub().getTransaction(); + return Sentry.getCurrentScopes().getTransaction(); } @Override public @NotNull SentryOptions getOptions() { - return Sentry.getCurrentHub().getOptions(); + return Sentry.getCurrentScopes().getOptions(); } @Override @@ -271,11 +275,11 @@ public void reportFullyDisplayed() { @ApiStatus.Internal @Override public @Nullable RateLimiter getRateLimiter() { - return Sentry.getCurrentHub().getRateLimiter(); + return Sentry.getCurrentScopes().getRateLimiter(); } @Override public @NotNull MetricsApi metrics() { - return Sentry.getCurrentHub().metrics(); + return Sentry.getCurrentScopes().metrics(); } } diff --git a/sentry/src/main/java/io/sentry/HubScopesWrapper.java b/sentry/src/main/java/io/sentry/HubScopesWrapper.java new file mode 100644 index 0000000000..9b294d05b7 --- /dev/null +++ b/sentry/src/main/java/io/sentry/HubScopesWrapper.java @@ -0,0 +1,279 @@ +package io.sentry; + +import io.sentry.metrics.MetricsApi; +import io.sentry.protocol.SentryId; +import io.sentry.protocol.SentryTransaction; +import io.sentry.protocol.User; +import io.sentry.transport.RateLimiter; +import java.util.List; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@SuppressWarnings("deprecation") +@Deprecated +public final class HubScopesWrapper implements IHub { + + private final IScopes scopes; + + public HubScopesWrapper(final @NotNull IScopes scopes) { + this.scopes = scopes; + } + + @Override + public boolean isEnabled() { + return scopes.isEnabled(); + } + + @Override + public @NotNull SentryId captureEvent(@NotNull SentryEvent event, @Nullable Hint hint) { + return scopes.captureEvent(event, hint); + } + + @Override + public @NotNull SentryId captureEvent( + @NotNull SentryEvent event, @Nullable Hint hint, @NotNull ScopeCallback callback) { + return scopes.captureEvent(event, hint, callback); + } + + @Override + public @NotNull SentryId captureMessage(@NotNull String message, @NotNull SentryLevel level) { + return scopes.captureMessage(message, level); + } + + @Override + public @NotNull SentryId captureMessage( + @NotNull String message, @NotNull SentryLevel level, @NotNull ScopeCallback callback) { + return scopes.captureMessage(message, level, callback); + } + + @Override + public @NotNull SentryId captureEnvelope(@NotNull SentryEnvelope envelope, @Nullable Hint hint) { + return scopes.captureEnvelope(envelope, hint); + } + + @Override + public @NotNull SentryId captureException(@NotNull Throwable throwable, @Nullable Hint hint) { + return scopes.captureException(throwable, hint); + } + + @Override + public @NotNull SentryId captureException( + @NotNull Throwable throwable, @Nullable Hint hint, @NotNull ScopeCallback callback) { + return scopes.captureException(throwable, hint, callback); + } + + @Override + public void captureUserFeedback(@NotNull UserFeedback userFeedback) { + scopes.captureUserFeedback(userFeedback); + } + + @Override + public void startSession() { + scopes.startSession(); + } + + @Override + public void endSession() { + scopes.endSession(); + } + + @Override + public void close() { + scopes.close(); + } + + @Override + public void close(boolean isRestarting) { + scopes.close(isRestarting); + } + + @Override + public void addBreadcrumb(@NotNull Breadcrumb breadcrumb, @Nullable Hint hint) { + scopes.addBreadcrumb(breadcrumb, hint); + } + + @Override + public void addBreadcrumb(@NotNull Breadcrumb breadcrumb) { + scopes.addBreadcrumb(breadcrumb); + } + + @Override + public void setLevel(@Nullable SentryLevel level) { + scopes.setLevel(level); + } + + @Override + public void setTransaction(@Nullable String transaction) { + scopes.setTransaction(transaction); + } + + @Override + public void setUser(@Nullable User user) { + scopes.setUser(user); + } + + @Override + public void setFingerprint(@NotNull List fingerprint) { + scopes.setFingerprint(fingerprint); + } + + @Override + public void clearBreadcrumbs() { + scopes.clearBreadcrumbs(); + } + + @Override + public void setTag(@NotNull String key, @NotNull String value) { + scopes.setTag(key, value); + } + + @Override + public void removeTag(@NotNull String key) { + scopes.removeTag(key); + } + + @Override + public void setExtra(@NotNull String key, @NotNull String value) { + scopes.setExtra(key, value); + } + + @Override + public void removeExtra(@NotNull String key) { + scopes.removeExtra(key); + } + + @Override + public @NotNull SentryId getLastEventId() { + return scopes.getLastEventId(); + } + + @Override + public void pushScope() { + scopes.pushScope(); + } + + @Override + public void popScope() { + scopes.popScope(); + } + + @Override + public void withScope(@NotNull ScopeCallback callback) { + scopes.withScope(callback); + } + + @Override + public void configureScope(@NotNull ScopeCallback callback) { + scopes.configureScope(callback); + } + + @Override + public void bindClient(@NotNull ISentryClient client) { + scopes.bindClient(client); + } + + @Override + public boolean isHealthy() { + return scopes.isHealthy(); + } + + @Override + public void flush(long timeoutMillis) { + scopes.flush(timeoutMillis); + } + + @Override + public @NotNull IHub clone() { + return scopes.clone(); + } + + @ApiStatus.Internal + @Override + public @NotNull SentryId captureTransaction( + @NotNull SentryTransaction transaction, + @Nullable TraceContext traceContext, + @Nullable Hint hint, + @Nullable ProfilingTraceData profilingTraceData) { + return scopes.captureTransaction(transaction, traceContext, hint, profilingTraceData); + } + + @Override + public @NotNull ITransaction startTransaction( + @NotNull TransactionContext transactionContext, + @NotNull TransactionOptions transactionOptions) { + return scopes.startTransaction(transactionContext, transactionOptions); + } + + @Override + public @Nullable SentryTraceHeader traceHeaders() { + return scopes.traceHeaders(); + } + + @ApiStatus.Internal + @Override + public void setSpanContext( + @NotNull Throwable throwable, @NotNull ISpan span, @NotNull String transactionName) { + scopes.setSpanContext(throwable, span, transactionName); + } + + @Override + public @Nullable ISpan getSpan() { + return scopes.getSpan(); + } + + @ApiStatus.Internal + @Override + public @Nullable ITransaction getTransaction() { + return scopes.getTransaction(); + } + + @Override + public @NotNull SentryOptions getOptions() { + return scopes.getOptions(); + } + + @Override + public @Nullable Boolean isCrashedLastRun() { + return scopes.isCrashedLastRun(); + } + + @Override + public void reportFullyDisplayed() { + scopes.reportFullyDisplayed(); + } + + @Override + public @Nullable TransactionContext continueTrace( + @Nullable String sentryTrace, @Nullable List baggageHeaders) { + return scopes.continueTrace(sentryTrace, baggageHeaders); + } + + @Override + public @Nullable SentryTraceHeader getTraceparent() { + return scopes.getTraceparent(); + } + + @Override + public @Nullable BaggageHeader getBaggage() { + return scopes.getBaggage(); + } + + @ApiStatus.Experimental + @Override + public @NotNull SentryId captureCheckIn(@NotNull CheckIn checkIn) { + return scopes.captureCheckIn(checkIn); + } + + @ApiStatus.Internal + @Override + public @Nullable RateLimiter getRateLimiter() { + return scopes.getRateLimiter(); + } + + @ApiStatus.Experimental + @Override + public @NotNull MetricsApi metrics() { + return scopes.metrics(); + } +} diff --git a/sentry/src/main/java/io/sentry/IHub.java b/sentry/src/main/java/io/sentry/IHub.java index 684d8ec528..23a7bed7de 100644 --- a/sentry/src/main/java/io/sentry/IHub.java +++ b/sentry/src/main/java/io/sentry/IHub.java @@ -1,590 +1,9 @@ package io.sentry; -import io.sentry.metrics.MetricsApi; -import io.sentry.protocol.SentryId; -import io.sentry.protocol.SentryTransaction; -import io.sentry.protocol.User; -import io.sentry.transport.RateLimiter; -import java.util.List; -import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** SDK API contract which combines a client and scope management */ -public interface IHub { - - /** - * Check if the Hub is enabled/active. - * - * @return true if its enabled or false otherwise. - */ - boolean isEnabled(); - - /** - * Captures the event. - * - * @param event the event - * @param hint SDK specific but provides high level information about the origin of the event - * @return The Id (SentryId object) of the event - */ - @NotNull - SentryId captureEvent(@NotNull SentryEvent event, @Nullable Hint hint); - - /** - * Captures the event. - * - * @param event the event - * @return The Id (SentryId object) of the event - */ - default @NotNull SentryId captureEvent(@NotNull SentryEvent event) { - return captureEvent(event, new Hint()); - } - - /** - * Captures the event. - * - * @param event the event - * @param callback The callback to configure the scope for a single invocation. - * @return The Id (SentryId object) of the event - */ - default @NotNull SentryId captureEvent( - @NotNull SentryEvent event, final @NotNull ScopeCallback callback) { - return captureEvent(event, new Hint(), callback); - } - - /** - * Captures the event. - * - * @param event the event - * @param hint SDK specific but provides high level information about the origin of the event - * @param callback The callback to configure the scope for a single invocation. - * @return The Id (SentryId object) of the event - */ - @NotNull - SentryId captureEvent( - final @NotNull SentryEvent event, - final @Nullable Hint hint, - final @NotNull ScopeCallback callback); - - /** - * Captures the message. - * - * @param message The message to send. - * @return The Id (SentryId object) of the event - */ - default @NotNull SentryId captureMessage(@NotNull String message) { - return captureMessage(message, SentryLevel.INFO); - } - - /** - * Captures the message. - * - * @param message The message to send. - * @param level The message level. - * @return The Id (SentryId object) of the event - */ - @NotNull - SentryId captureMessage(@NotNull String message, @NotNull SentryLevel level); - - /** - * Captures the message. - * - * @param message The message to send. - * @param level The message level. - * @param callback The callback to configure the scope for a single invocation. - * @return The Id (SentryId object) of the event - */ - @NotNull - SentryId captureMessage( - @NotNull String message, @NotNull SentryLevel level, @NotNull ScopeCallback callback); - - /** - * Captures the message. - * - * @param message The message to send. - * @param callback The callback to configure the scope for a single invocation. - * @return The Id (SentryId object) of the event - */ - default @NotNull SentryId captureMessage( - @NotNull String message, @NotNull ScopeCallback callback) { - return captureMessage(message, SentryLevel.INFO, callback); - } - - /** - * Captures an envelope. - * - * @param envelope the SentryEnvelope to send. - * @param hint SDK specific but provides high level information about the origin of the event - * @return The Id (SentryId object) of the event - */ - @NotNull - SentryId captureEnvelope(@NotNull SentryEnvelope envelope, @Nullable Hint hint); - - /** - * Captures an envelope. - * - * @param envelope the SentryEnvelope to send. - * @return The Id (SentryId object) of the event - */ - default @NotNull SentryId captureEnvelope(@NotNull SentryEnvelope envelope) { - return captureEnvelope(envelope, new Hint()); - } - - /** - * Captures the exception. - * - * @param throwable The exception. - * @param hint SDK specific but provides high level information about the origin of the event - * @return The Id (SentryId object) of the event - */ - @NotNull - SentryId captureException(@NotNull Throwable throwable, @Nullable Hint hint); - - /** - * Captures the exception. - * - * @param throwable The exception. - * @return The Id (SentryId object) of the event - */ - default @NotNull SentryId captureException(@NotNull Throwable throwable) { - return captureException(throwable, new Hint()); - } - - /** - * Captures the exception. - * - * @param throwable The exception. - * @param callback The callback to configure the scope for a single invocation. - * @return The Id (SentryId object) of the event - */ - default @NotNull SentryId captureException( - @NotNull Throwable throwable, final @NotNull ScopeCallback callback) { - return captureException(throwable, new Hint(), callback); - } - - /** - * Captures the exception. - * - * @param throwable The exception. - * @param hint SDK specific but provides high level information about the origin of the event - * @param callback The callback to configure the scope for a single invocation. - * @return The Id (SentryId object) of the event - */ - @NotNull - SentryId captureException( - final @NotNull Throwable throwable, - final @Nullable Hint hint, - final @NotNull ScopeCallback callback); - - /** - * Captures a manually created user feedback and sends it to Sentry. - * - * @param userFeedback The user feedback to send to Sentry. - */ - void captureUserFeedback(@NotNull UserFeedback userFeedback); - - /** Starts a new session. If there's a running session, it ends it before starting the new one. */ - void startSession(); - - /** Ends the current session */ - void endSession(); - - /** Flushes out the queue for up to timeout seconds and disable the Hub. */ - void close(); - - /** - * Flushes out the queue for up to timeout seconds and disable the Hub. - * - * @param isRestarting if true, avoids locking the main thread when finishing the queue. - */ - void close(boolean isRestarting); - - /** - * Adds a breadcrumb to the current Scope - * - * @param breadcrumb the breadcrumb - * @param hint SDK specific but provides high level information about the origin of the event - */ - void addBreadcrumb(@NotNull Breadcrumb breadcrumb, @Nullable Hint hint); - - /** - * Adds a breadcrumb to the current Scope - * - * @param breadcrumb the breadcrumb - */ - void addBreadcrumb(@NotNull Breadcrumb breadcrumb); - - /** - * Adds a breadcrumb to the current Scope - * - * @param message rendered as text and the whitespace is preserved. - */ - default void addBreadcrumb(@NotNull String message) { - addBreadcrumb(new Breadcrumb(message)); - } - - /** - * Adds a breadcrumb to the current Scope - * - * @param message rendered as text and the whitespace is preserved. - * @param category Categories are dotted strings that indicate what the crumb is or where it comes - * from. - */ - default void addBreadcrumb(@NotNull String message, @NotNull String category) { - Breadcrumb breadcrumb = new Breadcrumb(message); - breadcrumb.setCategory(category); - addBreadcrumb(breadcrumb); - } - - /** - * Sets the level of all events sent within current Scope - * - * @param level the Sentry level - */ - void setLevel(@Nullable SentryLevel level); - - /** - * Sets the name of the current transaction to the current Scope. - * - * @param transaction the transaction - */ - void setTransaction(@Nullable String transaction); - - /** - * Shallow merges user configuration (email, username, etc) to the current Scope. - * - * @param user the user - */ - void setUser(@Nullable User user); - - /** - * Sets the fingerprint to group specific events together to the current Scope. - * - * @param fingerprint the fingerprints - */ - void setFingerprint(@NotNull List fingerprint); - - /** Deletes current breadcrumbs from the current scope. */ - void clearBreadcrumbs(); - - /** - * Sets the tag to a string value to the current Scope, overwriting a potential previous value - * - * @param key the key - * @param value the value - */ - void setTag(@NotNull String key, @NotNull String value); - - /** - * Removes the tag to a string value to the current Scope - * - * @param key the key - */ - void removeTag(@NotNull String key); - - /** - * Sets the extra key to an arbitrary value to the current Scope, overwriting a potential previous - * value - * - * @param key the key - * @param value the value - */ - void setExtra(@NotNull String key, @NotNull String value); - - /** - * Removes the extra key to an arbitrary value to the current Scope - * - * @param key the key - */ - void removeExtra(@NotNull String key); - - /** - * Last event id recorded in the current scope - * - * @return last SentryId - */ - @NotNull - SentryId getLastEventId(); - - /** Pushes a new scope while inheriting the current scope's data. */ - void pushScope(); - - /** Removes the first scope */ - void popScope(); - - /** - * Runs the callback with a new scope which gets dropped at the end. If you're using the Sentry - * SDK in globalHubMode (defaults to true on Android) {@link - * Sentry#init(Sentry.OptionsConfiguration, boolean)} calling withScope is discouraged, as scope - * changes may be dropped when executed in parallel. Use {@link - * IHub#configureScope(ScopeCallback)} instead. - * - * @param callback the callback - */ - void withScope(@NotNull ScopeCallback callback); - - /** - * Configures the scope through the callback. - * - * @param callback The configure scope callback. - */ - void configureScope(@NotNull ScopeCallback callback); - - /** - * Binds a different client to the hub - * - * @param client the client. - */ - void bindClient(@NotNull ISentryClient client); - - /** - * Whether the transport is healthy. - * - * @return true if the transport is healthy - */ - boolean isHealthy(); - - /** - * Flushes events queued up, but keeps the Hub enabled. Not implemented yet. - * - * @param timeoutMillis time in milliseconds - */ - void flush(long timeoutMillis); - - /** - * Clones the Hub - * - * @return the cloned Hub - */ - @NotNull - IHub clone(); - - /** - * Captures the transaction and enqueues it for sending to Sentry server. - * - * @param transaction the transaction - * @param traceContext the trace context - * @param hint the hints - * @param profilingTraceData the profiling trace data - * @return transaction's id - */ - @ApiStatus.Internal - @NotNull - SentryId captureTransaction( - @NotNull SentryTransaction transaction, - @Nullable TraceContext traceContext, - @Nullable Hint hint, - @Nullable ProfilingTraceData profilingTraceData); - - /** - * Captures the transaction and enqueues it for sending to Sentry server. - * - * @param transaction the transaction - * @param traceContext the trace context - * @param hint the hints - * @return transaction's id - */ - @ApiStatus.Internal - @NotNull - default SentryId captureTransaction( - @NotNull SentryTransaction transaction, - @Nullable TraceContext traceContext, - @Nullable Hint hint) { - return captureTransaction(transaction, traceContext, hint, null); - } - - @ApiStatus.Internal - @NotNull - default SentryId captureTransaction(@NotNull SentryTransaction transaction, @Nullable Hint hint) { - return captureTransaction(transaction, null, hint); - } - - /** - * Captures the transaction and enqueues it for sending to Sentry server. - * - * @param transaction the transaction - * @param traceContext the trace context - * @return transaction's id - */ - @ApiStatus.Internal - default @NotNull SentryId captureTransaction( - @NotNull SentryTransaction transaction, @Nullable TraceContext traceContext) { - return captureTransaction(transaction, traceContext, null); - } - - /** - * Creates a Transaction and returns the instance. - * - * @param transactionContexts the transaction contexts - * @return created transaction - */ - default @NotNull ITransaction startTransaction(@NotNull TransactionContext transactionContexts) { - return startTransaction(transactionContexts, new TransactionOptions()); - } - - /** - * Creates a Transaction and returns the instance. Based on the {@link - * SentryOptions#getTracesSampleRate()} the decision if transaction is sampled will be taken by - * {@link TracesSampler}. - * - * @param name the transaction name - * @param operation the operation - * @return created transaction - */ - default @NotNull ITransaction startTransaction( - final @NotNull String name, final @NotNull String operation) { - return startTransaction(name, operation, new TransactionOptions()); - } - - /** - * Creates a Transaction and returns the instance. Based on the {@link - * SentryOptions#getTracesSampleRate()} the decision if transaction is sampled will be taken by - * {@link TracesSampler}. - * - * @param name the transaction name - * @param operation the operation - * @param transactionOptions the transaction options - * @return created transaction - */ - default @NotNull ITransaction startTransaction( - final @NotNull String name, - final @NotNull String operation, - final @NotNull TransactionOptions transactionOptions) { - return startTransaction(new TransactionContext(name, operation), transactionOptions); - } - - /** - * Creates a Transaction and returns the instance. Based on the passed transaction context and - * transaction options the decision if transaction is sampled will be taken by {@link - * TracesSampler}. - * - * @param transactionContext the transaction context - * @param transactionOptions the transaction options - * @return created transaction. - */ - @NotNull - ITransaction startTransaction( - final @NotNull TransactionContext transactionContext, - final @NotNull TransactionOptions transactionOptions); - - /** - * Returns the "sentry-trace" header that allows tracing across services. Can also be used in - * <meta> HTML tags. Also see {@link IHub#getBaggage()}. - * - * @deprecated please use {@link IHub#getTraceparent()} instead. - * @return sentry trace header or null - */ - @Deprecated - @Nullable - SentryTraceHeader traceHeaders(); - - /** - * Associates {@link ISpan} and the transaction name with the {@link Throwable}. Used to determine - * in which trace the exception has been thrown in framework integrations. - * - * @param throwable the throwable - * @param span the span context - * @param transactionName the transaction name - */ - @ApiStatus.Internal - void setSpanContext( - @NotNull Throwable throwable, @NotNull ISpan span, @NotNull String transactionName); - - /** - * Gets the current active transaction or span. - * - * @return the active span or null when no active transaction is running - */ - @Nullable - ISpan getSpan(); - - /** - * Returns the transaction. - * - * @return the transaction or null when no active transaction is running. - */ - @ApiStatus.Internal - @Nullable - ITransaction getTransaction(); - - /** - * Gets the {@link SentryOptions} attached to current scope. - * - * @return the options attached to current scope. - */ - @NotNull - SentryOptions getOptions(); - - /** - * Returns if the App has crashed (Process has terminated) during the last run. It only returns - * true or false if offline caching {{@link SentryOptions#getCacheDirPath()} } is set with a valid - * dir. - * - *

If the call to this method is early in the App lifecycle and the SDK could not check if the - * App has crashed in the background, the check is gonna do IO in the calling thread. - * - * @return true if App has crashed, false otherwise, and null if not evaluated yet - */ - @Nullable - Boolean isCrashedLastRun(); - - /** - * Report a screen has been fully loaded. That means all data needed by the UI was loaded. If - * time-to-full-display tracing {{@link SentryOptions#isEnableTimeToFullDisplayTracing()} } is - * disabled this call is ignored. - * - *

This method is safe to be called multiple times. If the time-to-full-display span is already - * finished, this call will be ignored. - */ - void reportFullyDisplayed(); - - /** - * @deprecated See {@link IHub#reportFullyDisplayed()}. - */ - @Deprecated - default void reportFullDisplayed() { - reportFullyDisplayed(); - } - - /** - * Continue a trace based on HTTP header values. If no "sentry-trace" header is provided a random - * trace ID and span ID is created. - * - * @param sentryTrace "sentry-trace" header - * @param baggageHeaders "baggage" headers - * @return a transaction context for starting a transaction or null if performance is disabled - */ - @Nullable - TransactionContext continueTrace( - final @Nullable String sentryTrace, final @Nullable List baggageHeaders); - - /** - * Returns the "sentry-trace" header that allows tracing across services. Can also be used in - * <meta> HTML tags. Also see {@link IHub#getBaggage()}. - * - * @return sentry trace header or null - */ - @Nullable - SentryTraceHeader getTraceparent(); - - /** - * Returns the "baggage" header that allows tracing across services. Can also be used in - * <meta> HTML tags. Also see {@link IHub#getTraceparent()}. - * - * @return baggage header or null - */ - @Nullable - BaggageHeader getBaggage(); - - @ApiStatus.Experimental - @NotNull - SentryId captureCheckIn(final @NotNull CheckIn checkIn); - - @ApiStatus.Internal - @Nullable - RateLimiter getRateLimiter(); - - @ApiStatus.Experimental - @NotNull - MetricsApi metrics(); -} +/** + * SDK API contract which combines a client and scope management + * + * @deprecated please use {@link IScopes} instead + */ +@Deprecated +public interface IHub extends IScopes {} diff --git a/sentry/src/main/java/io/sentry/IScopes.java b/sentry/src/main/java/io/sentry/IScopes.java new file mode 100644 index 0000000000..03662457e4 --- /dev/null +++ b/sentry/src/main/java/io/sentry/IScopes.java @@ -0,0 +1,594 @@ +package io.sentry; + +import io.sentry.metrics.MetricsApi; +import io.sentry.protocol.SentryId; +import io.sentry.protocol.SentryTransaction; +import io.sentry.protocol.User; +import io.sentry.transport.RateLimiter; +import java.util.List; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public interface IScopes { + + /** + * Check if the Hub is enabled/active. + * + * @return true if its enabled or false otherwise. + */ + boolean isEnabled(); + + /** + * Captures the event. + * + * @param event the event + * @param hint SDK specific but provides high level information about the origin of the event + * @return The Id (SentryId object) of the event + */ + @NotNull + SentryId captureEvent(@NotNull SentryEvent event, @Nullable Hint hint); + + /** + * Captures the event. + * + * @param event the event + * @return The Id (SentryId object) of the event + */ + default @NotNull SentryId captureEvent(@NotNull SentryEvent event) { + return captureEvent(event, new Hint()); + } + + /** + * Captures the event. + * + * @param event the event + * @param callback The callback to configure the scope for a single invocation. + * @return The Id (SentryId object) of the event + */ + default @NotNull SentryId captureEvent( + @NotNull SentryEvent event, final @NotNull ScopeCallback callback) { + return captureEvent(event, new Hint(), callback); + } + + /** + * Captures the event. + * + * @param event the event + * @param hint SDK specific but provides high level information about the origin of the event + * @param callback The callback to configure the scope for a single invocation. + * @return The Id (SentryId object) of the event + */ + @NotNull + SentryId captureEvent( + final @NotNull SentryEvent event, + final @Nullable Hint hint, + final @NotNull ScopeCallback callback); + + /** + * Captures the message. + * + * @param message The message to send. + * @return The Id (SentryId object) of the event + */ + default @NotNull SentryId captureMessage(@NotNull String message) { + return captureMessage(message, SentryLevel.INFO); + } + + /** + * Captures the message. + * + * @param message The message to send. + * @param level The message level. + * @return The Id (SentryId object) of the event + */ + @NotNull + SentryId captureMessage(@NotNull String message, @NotNull SentryLevel level); + + /** + * Captures the message. + * + * @param message The message to send. + * @param level The message level. + * @param callback The callback to configure the scope for a single invocation. + * @return The Id (SentryId object) of the event + */ + @NotNull + SentryId captureMessage( + @NotNull String message, @NotNull SentryLevel level, @NotNull ScopeCallback callback); + + /** + * Captures the message. + * + * @param message The message to send. + * @param callback The callback to configure the scope for a single invocation. + * @return The Id (SentryId object) of the event + */ + default @NotNull SentryId captureMessage( + @NotNull String message, @NotNull ScopeCallback callback) { + return captureMessage(message, SentryLevel.INFO, callback); + } + + /** + * Captures an envelope. + * + * @param envelope the SentryEnvelope to send. + * @param hint SDK specific but provides high level information about the origin of the event + * @return The Id (SentryId object) of the event + */ + @NotNull + SentryId captureEnvelope(@NotNull SentryEnvelope envelope, @Nullable Hint hint); + + /** + * Captures an envelope. + * + * @param envelope the SentryEnvelope to send. + * @return The Id (SentryId object) of the event + */ + default @NotNull SentryId captureEnvelope(@NotNull SentryEnvelope envelope) { + return captureEnvelope(envelope, new Hint()); + } + + /** + * Captures the exception. + * + * @param throwable The exception. + * @param hint SDK specific but provides high level information about the origin of the event + * @return The Id (SentryId object) of the event + */ + @NotNull + SentryId captureException(@NotNull Throwable throwable, @Nullable Hint hint); + + /** + * Captures the exception. + * + * @param throwable The exception. + * @return The Id (SentryId object) of the event + */ + default @NotNull SentryId captureException(@NotNull Throwable throwable) { + return captureException(throwable, new Hint()); + } + + /** + * Captures the exception. + * + * @param throwable The exception. + * @param callback The callback to configure the scope for a single invocation. + * @return The Id (SentryId object) of the event + */ + default @NotNull SentryId captureException( + @NotNull Throwable throwable, final @NotNull ScopeCallback callback) { + return captureException(throwable, new Hint(), callback); + } + + /** + * Captures the exception. + * + * @param throwable The exception. + * @param hint SDK specific but provides high level information about the origin of the event + * @param callback The callback to configure the scope for a single invocation. + * @return The Id (SentryId object) of the event + */ + @NotNull + SentryId captureException( + final @NotNull Throwable throwable, + final @Nullable Hint hint, + final @NotNull ScopeCallback callback); + + /** + * Captures a manually created user feedback and sends it to Sentry. + * + * @param userFeedback The user feedback to send to Sentry. + */ + void captureUserFeedback(@NotNull UserFeedback userFeedback); + + /** Starts a new session. If there's a running session, it ends it before starting the new one. */ + void startSession(); + + /** Ends the current session */ + void endSession(); + + /** Flushes out the queue for up to timeout seconds and disable the Hub. */ + void close(); + + /** + * Flushes out the queue for up to timeout seconds and disable the Hub. + * + * @param isRestarting if true, avoids locking the main thread when finishing the queue. + */ + void close(boolean isRestarting); + + /** + * Adds a breadcrumb to the current Scope + * + * @param breadcrumb the breadcrumb + * @param hint SDK specific but provides high level information about the origin of the event + */ + void addBreadcrumb(@NotNull Breadcrumb breadcrumb, @Nullable Hint hint); + + /** + * Adds a breadcrumb to the current Scope + * + * @param breadcrumb the breadcrumb + */ + void addBreadcrumb(@NotNull Breadcrumb breadcrumb); + + /** + * Adds a breadcrumb to the current Scope + * + * @param message rendered as text and the whitespace is preserved. + */ + default void addBreadcrumb(@NotNull String message) { + addBreadcrumb(new Breadcrumb(message)); + } + + /** + * Adds a breadcrumb to the current Scope + * + * @param message rendered as text and the whitespace is preserved. + * @param category Categories are dotted strings that indicate what the crumb is or where it comes + * from. + */ + default void addBreadcrumb(@NotNull String message, @NotNull String category) { + Breadcrumb breadcrumb = new Breadcrumb(message); + breadcrumb.setCategory(category); + addBreadcrumb(breadcrumb); + } + + /** + * Sets the level of all events sent within current Scope + * + * @param level the Sentry level + */ + void setLevel(@Nullable SentryLevel level); + + /** + * Sets the name of the current transaction to the current Scope. + * + * @param transaction the transaction + */ + void setTransaction(@Nullable String transaction); + + /** + * Shallow merges user configuration (email, username, etc) to the current Scope. + * + * @param user the user + */ + void setUser(@Nullable User user); + + /** + * Sets the fingerprint to group specific events together to the current Scope. + * + * @param fingerprint the fingerprints + */ + void setFingerprint(@NotNull List fingerprint); + + /** Deletes current breadcrumbs from the current scope. */ + void clearBreadcrumbs(); + + /** + * Sets the tag to a string value to the current Scope, overwriting a potential previous value + * + * @param key the key + * @param value the value + */ + void setTag(@NotNull String key, @NotNull String value); + + /** + * Removes the tag to a string value to the current Scope + * + * @param key the key + */ + void removeTag(@NotNull String key); + + /** + * Sets the extra key to an arbitrary value to the current Scope, overwriting a potential previous + * value + * + * @param key the key + * @param value the value + */ + void setExtra(@NotNull String key, @NotNull String value); + + /** + * Removes the extra key to an arbitrary value to the current Scope + * + * @param key the key + */ + void removeExtra(@NotNull String key); + + /** + * Last event id recorded in the current scope + * + * @return last SentryId + */ + @NotNull + SentryId getLastEventId(); + + /** Pushes a new scope while inheriting the current scope's data. */ + void pushScope(); + + /** Removes the first scope */ + void popScope(); + + /** + * Runs the callback with a new scope which gets dropped at the end. If you're using the Sentry + * SDK in globalHubMode (defaults to true on Android) {@link + * Sentry#init(Sentry.OptionsConfiguration, boolean)} calling withScope is discouraged, as scope + * changes may be dropped when executed in parallel. Use {@link + * IHub#configureScope(ScopeCallback)} instead. + * + * @param callback the callback + */ + void withScope(@NotNull ScopeCallback callback); + + /** + * Configures the scope through the callback. + * + * @param callback The configure scope callback. + */ + void configureScope(@NotNull ScopeCallback callback); + + /** + * Binds a different client to the hub + * + * @param client the client. + */ + void bindClient(@NotNull ISentryClient client); + + /** + * Whether the transport is healthy. + * + * @return true if the transport is healthy + */ + boolean isHealthy(); + + /** + * Flushes events queued up, but keeps the Hub enabled. Not implemented yet. + * + * @param timeoutMillis time in milliseconds + */ + void flush(long timeoutMillis); + + /** + * Clones the Hub + * + * @return the cloned Hub + */ + @NotNull + @Deprecated + IHub clone(); + + /** + * Captures the transaction and enqueues it for sending to Sentry server. + * + * @param transaction the transaction + * @param traceContext the trace context + * @param hint the hints + * @param profilingTraceData the profiling trace data + * @return transaction's id + */ + @ApiStatus.Internal + @NotNull + SentryId captureTransaction( + @NotNull SentryTransaction transaction, + @Nullable TraceContext traceContext, + @Nullable Hint hint, + @Nullable ProfilingTraceData profilingTraceData); + + /** + * Captures the transaction and enqueues it for sending to Sentry server. + * + * @param transaction the transaction + * @param traceContext the trace context + * @param hint the hints + * @return transaction's id + */ + @ApiStatus.Internal + @NotNull + default SentryId captureTransaction( + @NotNull SentryTransaction transaction, + @Nullable TraceContext traceContext, + @Nullable Hint hint) { + return captureTransaction(transaction, traceContext, hint, null); + } + + @ApiStatus.Internal + @NotNull + default SentryId captureTransaction(@NotNull SentryTransaction transaction, @Nullable Hint hint) { + return captureTransaction(transaction, null, hint); + } + + /** + * Captures the transaction and enqueues it for sending to Sentry server. + * + * @param transaction the transaction + * @param traceContext the trace context + * @return transaction's id + */ + @ApiStatus.Internal + default @NotNull SentryId captureTransaction( + @NotNull SentryTransaction transaction, @Nullable TraceContext traceContext) { + return captureTransaction(transaction, traceContext, null); + } + + /** + * Creates a Transaction and returns the instance. + * + * @param transactionContexts the transaction contexts + * @return created transaction + */ + default @NotNull ITransaction startTransaction(@NotNull TransactionContext transactionContexts) { + return startTransaction(transactionContexts, new TransactionOptions()); + } + + /** + * Creates a Transaction and returns the instance. Based on the {@link + * SentryOptions#getTracesSampleRate()} the decision if transaction is sampled will be taken by + * {@link TracesSampler}. + * + * @param name the transaction name + * @param operation the operation + * @return created transaction + */ + default @NotNull ITransaction startTransaction( + final @NotNull String name, final @NotNull String operation) { + return startTransaction(name, operation, new TransactionOptions()); + } + + /** + * Creates a Transaction and returns the instance. Based on the {@link + * SentryOptions#getTracesSampleRate()} the decision if transaction is sampled will be taken by + * {@link TracesSampler}. + * + * @param name the transaction name + * @param operation the operation + * @param transactionOptions the transaction options + * @return created transaction + */ + default @NotNull ITransaction startTransaction( + final @NotNull String name, + final @NotNull String operation, + final @NotNull TransactionOptions transactionOptions) { + return startTransaction(new TransactionContext(name, operation), transactionOptions); + } + + /** + * Creates a Transaction and returns the instance. Based on the passed transaction context and + * transaction options the decision if transaction is sampled will be taken by {@link + * TracesSampler}. + * + * @param transactionContext the transaction context + * @param transactionOptions the transaction options + * @return created transaction. + */ + @NotNull + ITransaction startTransaction( + final @NotNull TransactionContext transactionContext, + final @NotNull TransactionOptions transactionOptions); + + /** + * Returns the "sentry-trace" header that allows tracing across services. Can also be used in + * <meta> HTML tags. Also see {@link IHub#getBaggage()}. + * + * @deprecated please use {@link IHub#getTraceparent()} instead. + * @return sentry trace header or null + */ + @Deprecated + @Nullable + SentryTraceHeader traceHeaders(); + + /** + * Associates {@link ISpan} and the transaction name with the {@link Throwable}. Used to determine + * in which trace the exception has been thrown in framework integrations. + * + * @param throwable the throwable + * @param span the span context + * @param transactionName the transaction name + */ + @ApiStatus.Internal + void setSpanContext( + @NotNull Throwable throwable, @NotNull ISpan span, @NotNull String transactionName); + + /** + * Gets the current active transaction or span. + * + * @return the active span or null when no active transaction is running + */ + @Nullable + ISpan getSpan(); + + /** + * Returns the transaction. + * + * @return the transaction or null when no active transaction is running. + */ + @ApiStatus.Internal + @Nullable + ITransaction getTransaction(); + + /** + * Gets the {@link SentryOptions} attached to current scope. + * + * @return the options attached to current scope. + */ + @NotNull + SentryOptions getOptions(); + + /** + * Returns if the App has crashed (Process has terminated) during the last run. It only returns + * true or false if offline caching {{@link SentryOptions#getCacheDirPath()} } is set with a valid + * dir. + * + *

If the call to this method is early in the App lifecycle and the SDK could not check if the + * App has crashed in the background, the check is gonna do IO in the calling thread. + * + * @return true if App has crashed, false otherwise, and null if not evaluated yet + */ + @Nullable + Boolean isCrashedLastRun(); + + /** + * Report a screen has been fully loaded. That means all data needed by the UI was loaded. If + * time-to-full-display tracing {{@link SentryOptions#isEnableTimeToFullDisplayTracing()} } is + * disabled this call is ignored. + * + *

This method is safe to be called multiple times. If the time-to-full-display span is already + * finished, this call will be ignored. + */ + void reportFullyDisplayed(); + + /** + * @deprecated See {@link IHub#reportFullyDisplayed()}. + */ + @Deprecated + default void reportFullDisplayed() { + reportFullyDisplayed(); + } + + /** + * Continue a trace based on HTTP header values. If no "sentry-trace" header is provided a random + * trace ID and span ID is created. + * + * @param sentryTrace "sentry-trace" header + * @param baggageHeaders "baggage" headers + * @return a transaction context for starting a transaction or null if performance is disabled + */ + @Nullable + TransactionContext continueTrace( + final @Nullable String sentryTrace, final @Nullable List baggageHeaders); + + /** + * Returns the "sentry-trace" header that allows tracing across services. Can also be used in + * <meta> HTML tags. Also see {@link IHub#getBaggage()}. + * + * @return sentry trace header or null + */ + @Nullable + SentryTraceHeader getTraceparent(); + + /** + * Returns the "baggage" header that allows tracing across services. Can also be used in + * <meta> HTML tags. Also see {@link IHub#getTraceparent()}. + * + * @return baggage header or null + */ + @Nullable + BaggageHeader getBaggage(); + + @ApiStatus.Experimental + @NotNull + SentryId captureCheckIn(final @NotNull CheckIn checkIn); + + @ApiStatus.Internal + @Nullable + RateLimiter getRateLimiter(); + + @ApiStatus.Experimental + @NotNull + MetricsApi metrics(); + + default boolean isNoOp() { + return false; + } +} diff --git a/sentry/src/main/java/io/sentry/Integration.java b/sentry/src/main/java/io/sentry/Integration.java index 54b17e4d51..1b1a520473 100644 --- a/sentry/src/main/java/io/sentry/Integration.java +++ b/sentry/src/main/java/io/sentry/Integration.java @@ -10,8 +10,8 @@ public interface Integration { /** * Registers an integration * - * @param hub the Hub + * @param scopes the Scopes * @param options the options */ - void register(@NotNull IHub hub, @NotNull SentryOptions options); + void register(@NotNull IScopes scopes, @NotNull SentryOptions options); } diff --git a/sentry/src/main/java/io/sentry/MonitorConfig.java b/sentry/src/main/java/io/sentry/MonitorConfig.java index d954a50466..763e3b65a4 100644 --- a/sentry/src/main/java/io/sentry/MonitorConfig.java +++ b/sentry/src/main/java/io/sentry/MonitorConfig.java @@ -21,7 +21,7 @@ public final class MonitorConfig implements JsonUnknown, JsonSerializable { public MonitorConfig(final @NotNull MonitorSchedule schedule) { this.schedule = schedule; - final SentryOptions.Cron defaultCron = HubAdapter.getInstance().getOptions().getCron(); + final SentryOptions.Cron defaultCron = ScopesAdapter.getInstance().getOptions().getCron(); if (defaultCron != null) { this.checkinMargin = defaultCron.getDefaultCheckinMargin(); this.maxRuntime = defaultCron.getDefaultMaxRuntime(); diff --git a/sentry/src/main/java/io/sentry/NoOpHub.java b/sentry/src/main/java/io/sentry/NoOpHub.java index e51cea8d2d..704bd2b44a 100644 --- a/sentry/src/main/java/io/sentry/NoOpHub.java +++ b/sentry/src/main/java/io/sentry/NoOpHub.java @@ -11,6 +11,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +@Deprecated public final class NoOpHub implements IHub { private static final NoOpHub instance = new NoOpHub(); @@ -21,6 +22,7 @@ public final class NoOpHub implements IHub { private NoOpHub() {} + @Deprecated public static NoOpHub getInstance() { return instance; } @@ -234,4 +236,9 @@ public void reportFullyDisplayed() {} public @NotNull MetricsApi metrics() { return metricsApi; } + + @Override + public boolean isNoOp() { + return true; + } } diff --git a/sentry/src/main/java/io/sentry/NoOpScopes.java b/sentry/src/main/java/io/sentry/NoOpScopes.java new file mode 100644 index 0000000000..6fef262944 --- /dev/null +++ b/sentry/src/main/java/io/sentry/NoOpScopes.java @@ -0,0 +1,243 @@ +package io.sentry; + +import io.sentry.metrics.MetricsApi; +import io.sentry.metrics.NoopMetricsAggregator; +import io.sentry.protocol.SentryId; +import io.sentry.protocol.SentryTransaction; +import io.sentry.protocol.User; +import io.sentry.transport.RateLimiter; +import java.util.List; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public final class NoOpScopes implements IScopes { + + private static final NoOpScopes instance = new NoOpScopes(); + + private final @NotNull SentryOptions emptyOptions = SentryOptions.empty(); + private final @NotNull MetricsApi metricsApi = + new MetricsApi(NoopMetricsAggregator.getInstance()); + + private NoOpScopes() {} + + public static NoOpScopes getInstance() { + return instance; + } + + @Override + public boolean isEnabled() { + return false; + } + + @Override + public @NotNull SentryId captureEvent(@NotNull SentryEvent event, @Nullable Hint hint) { + return SentryId.EMPTY_ID; + } + + @Override + public @NotNull SentryId captureEvent( + @NotNull SentryEvent event, @Nullable Hint hint, @NotNull ScopeCallback callback) { + return SentryId.EMPTY_ID; + } + + @Override + public @NotNull SentryId captureMessage(@NotNull String message, @NotNull SentryLevel level) { + return SentryId.EMPTY_ID; + } + + @Override + public @NotNull SentryId captureMessage( + @NotNull String message, @NotNull SentryLevel level, @NotNull ScopeCallback callback) { + return SentryId.EMPTY_ID; + } + + @Override + public @NotNull SentryId captureEnvelope(@NotNull SentryEnvelope envelope, @Nullable Hint hint) { + return SentryId.EMPTY_ID; + } + + @Override + public @NotNull SentryId captureException(@NotNull Throwable throwable, @Nullable Hint hint) { + return SentryId.EMPTY_ID; + } + + @Override + public @NotNull SentryId captureException( + @NotNull Throwable throwable, @Nullable Hint hint, @NotNull ScopeCallback callback) { + return SentryId.EMPTY_ID; + } + + @Override + public void captureUserFeedback(@NotNull UserFeedback userFeedback) {} + + @Override + public void startSession() {} + + @Override + public void endSession() {} + + @Override + public void close() {} + + @Override + public void close(final boolean isRestarting) {} + + @Override + public void addBreadcrumb(@NotNull Breadcrumb breadcrumb, @Nullable Hint hint) {} + + @Override + public void addBreadcrumb(final @NotNull Breadcrumb breadcrumb) {} + + @Override + public void setLevel(@Nullable SentryLevel level) {} + + @Override + public void setTransaction(@Nullable String transaction) {} + + @Override + public void setUser(@Nullable User user) {} + + @Override + public void setFingerprint(@NotNull List fingerprint) {} + + @Override + public void clearBreadcrumbs() {} + + @Override + public void setTag(@NotNull String key, @NotNull String value) {} + + @Override + public void removeTag(@NotNull String key) {} + + @Override + public void setExtra(@NotNull String key, @NotNull String value) {} + + @Override + public void removeExtra(@NotNull String key) {} + + @Override + public @NotNull SentryId getLastEventId() { + return SentryId.EMPTY_ID; + } + + @Override + public void pushScope() {} + + @Override + public void popScope() {} + + @Override + public void withScope(@NotNull ScopeCallback callback) { + callback.run(NoOpScope.getInstance()); + } + + @Override + public void configureScope(@NotNull ScopeCallback callback) {} + + @Override + public void bindClient(@NotNull ISentryClient client) {} + + @Override + public boolean isHealthy() { + return true; + } + + @Override + public void flush(long timeoutMillis) {} + + @Deprecated + @Override + public @NotNull IHub clone() { + return NoOpHub.getInstance(); + } + + @Override + public @NotNull SentryId captureTransaction( + final @NotNull SentryTransaction transaction, + final @Nullable TraceContext traceContext, + final @Nullable Hint hint, + final @Nullable ProfilingTraceData profilingTraceData) { + return SentryId.EMPTY_ID; + } + + @Override + public @NotNull ITransaction startTransaction( + @NotNull TransactionContext transactionContext, + @NotNull TransactionOptions transactionOptions) { + return NoOpTransaction.getInstance(); + } + + @Override + @Deprecated + @SuppressWarnings("InlineMeSuggester") + public @NotNull SentryTraceHeader traceHeaders() { + return new SentryTraceHeader(SentryId.EMPTY_ID, SpanId.EMPTY_ID, true); + } + + @Override + public void setSpanContext( + final @NotNull Throwable throwable, + final @NotNull ISpan spanContext, + final @NotNull String transactionName) {} + + @Override + public @Nullable ISpan getSpan() { + return null; + } + + @Override + public @Nullable ITransaction getTransaction() { + return null; + } + + @Override + public @NotNull SentryOptions getOptions() { + return emptyOptions; + } + + @Override + public @Nullable Boolean isCrashedLastRun() { + return null; + } + + @Override + public void reportFullyDisplayed() {} + + @Override + public @Nullable TransactionContext continueTrace( + final @Nullable String sentryTrace, final @Nullable List baggageHeaders) { + return null; + } + + @Override + public @Nullable SentryTraceHeader getTraceparent() { + return null; + } + + @Override + public @Nullable BaggageHeader getBaggage() { + return null; + } + + @Override + @ApiStatus.Experimental + public @NotNull SentryId captureCheckIn(final @NotNull CheckIn checkIn) { + return SentryId.EMPTY_ID; + } + + @Override + public @Nullable RateLimiter getRateLimiter() { + return null; + } + + @Override + public @NotNull MetricsApi metrics() { + return metricsApi; + } + + @Override + public boolean isNoOp() { + return true; + } +} diff --git a/sentry/src/main/java/io/sentry/OutboxSender.java b/sentry/src/main/java/io/sentry/OutboxSender.java index 709cbb8580..f80bf030c8 100644 --- a/sentry/src/main/java/io/sentry/OutboxSender.java +++ b/sentry/src/main/java/io/sentry/OutboxSender.java @@ -36,20 +36,20 @@ public final class OutboxSender extends DirectoryProcessor implements IEnvelopeS @SuppressWarnings("CharsetObjectCanBeUsed") private static final Charset UTF_8 = Charset.forName("UTF-8"); - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @NotNull IEnvelopeReader envelopeReader; private final @NotNull ISerializer serializer; private final @NotNull ILogger logger; public OutboxSender( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull IEnvelopeReader envelopeReader, final @NotNull ISerializer serializer, final @NotNull ILogger logger, final long flushTimeoutMillis, final int maxQueueSize) { - super(hub, logger, flushTimeoutMillis, maxQueueSize); - this.hub = Objects.requireNonNull(hub, "Hub is required."); + super(scopes, logger, flushTimeoutMillis, maxQueueSize); + this.scopes = Objects.requireNonNull(scopes, "Hub is required."); this.envelopeReader = Objects.requireNonNull(envelopeReader, "Envelope reader is required."); this.serializer = Objects.requireNonNull(serializer, "Serializer is required."); this.logger = Objects.requireNonNull(logger, "Logger is required."); @@ -144,7 +144,7 @@ private void processEnvelope(final @NotNull SentryEnvelope envelope, final @NotN logUnexpectedEventId(envelope, event.getEventId(), currentItem); continue; } - hub.captureEvent(event, hint); + scopes.captureEvent(event, hint); logItemCaptured(currentItem); if (!waitFlush(hint)) { @@ -181,7 +181,7 @@ private void processEnvelope(final @NotNull SentryEnvelope envelope, final @NotN .getTrace() .setSamplingDecision(extractSamplingDecision(traceContext)); } - hub.captureTransaction(transaction, traceContext, hint); + scopes.captureTransaction(transaction, traceContext, hint); logItemCaptured(currentItem); if (!waitFlush(hint)) { @@ -197,7 +197,7 @@ private void processEnvelope(final @NotNull SentryEnvelope envelope, final @NotN final SentryEnvelope newEnvelope = new SentryEnvelope( envelope.getHeader().getEventId(), envelope.getHeader().getSdkVersion(), item); - hub.captureEnvelope(newEnvelope, hint); + scopes.captureEnvelope(newEnvelope, hint); logger.log( SentryLevel.DEBUG, "%s item %d is being captured.", diff --git a/sentry/src/main/java/io/sentry/PreviousSessionFinalizer.java b/sentry/src/main/java/io/sentry/PreviousSessionFinalizer.java index 458c6532ba..bda2a14477 100644 --- a/sentry/src/main/java/io/sentry/PreviousSessionFinalizer.java +++ b/sentry/src/main/java/io/sentry/PreviousSessionFinalizer.java @@ -33,11 +33,11 @@ final class PreviousSessionFinalizer implements Runnable { private final @NotNull SentryOptions options; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; - PreviousSessionFinalizer(final @NotNull SentryOptions options, final @NotNull IHub hub) { + PreviousSessionFinalizer(final @NotNull SentryOptions options, final @NotNull IScopes scopes) { this.options = options; - this.hub = hub; + this.scopes = scopes; } @Override @@ -116,7 +116,7 @@ public void run() { // SdkVersion will be outdated. final SentryEnvelope fromSession = SentryEnvelope.from(serializer, session, options.getSdkVersion()); - hub.captureEnvelope(fromSession); + scopes.captureEnvelope(fromSession); } } catch (Throwable e) { options.getLogger().log(SentryLevel.ERROR, "Error processing previous session.", e); diff --git a/sentry/src/main/java/io/sentry/ScopesAdapter.java b/sentry/src/main/java/io/sentry/ScopesAdapter.java new file mode 100644 index 0000000000..1ecd31e248 --- /dev/null +++ b/sentry/src/main/java/io/sentry/ScopesAdapter.java @@ -0,0 +1,286 @@ +package io.sentry; + +import io.sentry.metrics.MetricsApi; +import io.sentry.protocol.SentryId; +import io.sentry.protocol.SentryTransaction; +import io.sentry.protocol.User; +import io.sentry.transport.RateLimiter; +import java.util.List; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public final class ScopesAdapter implements IScopes { + + private static final ScopesAdapter INSTANCE = new ScopesAdapter(); + + private ScopesAdapter() {} + + public static ScopesAdapter getInstance() { + return INSTANCE; + } + + @Override + public boolean isEnabled() { + return Sentry.isEnabled(); + } + + @Override + public @NotNull SentryId captureEvent(@NotNull SentryEvent event, @Nullable Hint hint) { + return Sentry.captureEvent(event, hint); + } + + @Override + public @NotNull SentryId captureEvent( + @NotNull SentryEvent event, @Nullable Hint hint, @NotNull ScopeCallback callback) { + return Sentry.captureEvent(event, hint, callback); + } + + @Override + public @NotNull SentryId captureMessage(@NotNull String message, @NotNull SentryLevel level) { + return Sentry.captureMessage(message, level); + } + + @Override + public @NotNull SentryId captureMessage( + @NotNull String message, @NotNull SentryLevel level, @NotNull ScopeCallback callback) { + return Sentry.captureMessage(message, level, callback); + } + + @ApiStatus.Internal + @Override + public @NotNull SentryId captureEnvelope(@NotNull SentryEnvelope envelope, @Nullable Hint hint) { + return Sentry.getCurrentScopes().captureEnvelope(envelope, hint); + } + + @Override + public @NotNull SentryId captureException(@NotNull Throwable throwable, @Nullable Hint hint) { + return Sentry.captureException(throwable, hint); + } + + @Override + public @NotNull SentryId captureException( + @NotNull Throwable throwable, @Nullable Hint hint, @NotNull ScopeCallback callback) { + return Sentry.captureException(throwable, hint, callback); + } + + @Override + public void captureUserFeedback(@NotNull UserFeedback userFeedback) { + Sentry.captureUserFeedback(userFeedback); + } + + @Override + public void startSession() { + Sentry.startSession(); + } + + @Override + public void endSession() { + Sentry.endSession(); + } + + @Override + public void close(final boolean isRestarting) { + Sentry.close(); + } + + @Override + public void close() { + Sentry.close(); + } + + @Override + public void addBreadcrumb(@NotNull Breadcrumb breadcrumb, @Nullable Hint hint) { + Sentry.addBreadcrumb(breadcrumb, hint); + } + + @Override + public void addBreadcrumb(final @NotNull Breadcrumb breadcrumb) { + addBreadcrumb(breadcrumb, new Hint()); + } + + @Override + public void setLevel(@Nullable SentryLevel level) { + Sentry.setLevel(level); + } + + @Override + public void setTransaction(@Nullable String transaction) { + Sentry.setTransaction(transaction); + } + + @Override + public void setUser(@Nullable User user) { + Sentry.setUser(user); + } + + @Override + public void setFingerprint(@NotNull List fingerprint) { + Sentry.setFingerprint(fingerprint); + } + + @Override + public void clearBreadcrumbs() { + Sentry.clearBreadcrumbs(); + } + + @Override + public void setTag(@NotNull String key, @NotNull String value) { + Sentry.setTag(key, value); + } + + @Override + public void removeTag(@NotNull String key) { + Sentry.removeTag(key); + } + + @Override + public void setExtra(@NotNull String key, @NotNull String value) { + Sentry.setExtra(key, value); + } + + @Override + public void removeExtra(@NotNull String key) { + Sentry.removeExtra(key); + } + + @Override + public @NotNull SentryId getLastEventId() { + return Sentry.getLastEventId(); + } + + @Override + public void pushScope() { + Sentry.pushScope(); + } + + @Override + public void popScope() { + Sentry.popScope(); + } + + @Override + public void withScope(@NotNull ScopeCallback callback) { + Sentry.withScope(callback); + } + + @Override + public void configureScope(@NotNull ScopeCallback callback) { + Sentry.configureScope(callback); + } + + @Override + public void bindClient(@NotNull ISentryClient client) { + Sentry.bindClient(client); + } + + @Override + public boolean isHealthy() { + return Sentry.isHealthy(); + } + + @Override + public void flush(long timeoutMillis) { + Sentry.flush(timeoutMillis); + } + + @Override + @SuppressWarnings("deprecation") + public @NotNull IHub clone() { + return Sentry.getCurrentScopes().clone(); + } + + @ApiStatus.Internal + @Override + public @NotNull SentryId captureTransaction( + @NotNull SentryTransaction transaction, + @Nullable TraceContext traceContext, + @Nullable Hint hint, + @Nullable ProfilingTraceData profilingTraceData) { + return Sentry.getCurrentScopes() + .captureTransaction(transaction, traceContext, hint, profilingTraceData); + } + + @Override + public @NotNull ITransaction startTransaction( + @NotNull TransactionContext transactionContext, + @NotNull TransactionOptions transactionOptions) { + return Sentry.startTransaction(transactionContext, transactionOptions); + } + + @Deprecated + @Override + @SuppressWarnings("deprecation") + public @Nullable SentryTraceHeader traceHeaders() { + return Sentry.traceHeaders(); + } + + @ApiStatus.Internal + @Override + public void setSpanContext( + final @NotNull Throwable throwable, + final @NotNull ISpan span, + final @NotNull String transactionName) { + Sentry.getCurrentScopes().setSpanContext(throwable, span, transactionName); + } + + @Override + public @Nullable ISpan getSpan() { + return Sentry.getCurrentScopes().getSpan(); + } + + @Override + @ApiStatus.Internal + public @Nullable ITransaction getTransaction() { + return Sentry.getCurrentScopes().getTransaction(); + } + + @Override + public @NotNull SentryOptions getOptions() { + return Sentry.getCurrentScopes().getOptions(); + } + + @Override + public @Nullable Boolean isCrashedLastRun() { + return Sentry.isCrashedLastRun(); + } + + @Override + public void reportFullyDisplayed() { + Sentry.reportFullyDisplayed(); + } + + @Override + public @Nullable TransactionContext continueTrace( + final @Nullable String sentryTrace, final @Nullable List baggageHeaders) { + return Sentry.continueTrace(sentryTrace, baggageHeaders); + } + + @Override + public @Nullable SentryTraceHeader getTraceparent() { + return Sentry.getTraceparent(); + } + + @Override + public @Nullable BaggageHeader getBaggage() { + return Sentry.getBaggage(); + } + + @Override + @ApiStatus.Experimental + public @NotNull SentryId captureCheckIn(final @NotNull CheckIn checkIn) { + return Sentry.captureCheckIn(checkIn); + } + + @ApiStatus.Internal + @Override + public @Nullable RateLimiter getRateLimiter() { + return Sentry.getCurrentScopes().getRateLimiter(); + } + + @ApiStatus.Experimental + @Override + public @NotNull MetricsApi metrics() { + return Sentry.getCurrentScopes().metrics(); + } +} diff --git a/sentry/src/main/java/io/sentry/SendCachedEnvelopeFireAndForgetIntegration.java b/sentry/src/main/java/io/sentry/SendCachedEnvelopeFireAndForgetIntegration.java index bc813fdd1e..2160d1607e 100644 --- a/sentry/src/main/java/io/sentry/SendCachedEnvelopeFireAndForgetIntegration.java +++ b/sentry/src/main/java/io/sentry/SendCachedEnvelopeFireAndForgetIntegration.java @@ -18,7 +18,7 @@ public final class SendCachedEnvelopeFireAndForgetIntegration private final @NotNull SendFireAndForgetFactory factory; private @Nullable IConnectionStatusProvider connectionStatusProvider; - private @Nullable IHub hub; + private @Nullable IScopes scopes; private @Nullable SentryOptions options; private @Nullable SendFireAndForget sender; private final AtomicBoolean isInitialized = new AtomicBoolean(false); @@ -35,7 +35,7 @@ public interface SendFireAndForgetDirPath { public interface SendFireAndForgetFactory { @Nullable - SendFireAndForget create(@NotNull IHub hub, @NotNull SentryOptions options); + SendFireAndForget create(@NotNull IScopes scopes, @NotNull SentryOptions options); default boolean hasValidPath(final @Nullable String dirPath, final @NotNull ILogger logger) { if (dirPath == null || dirPath.isEmpty()) { @@ -66,8 +66,8 @@ public SendCachedEnvelopeFireAndForgetIntegration( } @Override - public void register(final @NotNull IHub hub, final @NotNull SentryOptions options) { - this.hub = Objects.requireNonNull(hub, "Hub is required"); + public void register(final @NotNull IScopes scopes, final @NotNull SentryOptions options) { + this.scopes = Objects.requireNonNull(scopes, "Hub is required"); this.options = Objects.requireNonNull(options, "SentryOptions is required"); final String cachedDir = options.getCacheDirPath(); @@ -81,7 +81,7 @@ public void register(final @NotNull IHub hub, final @NotNull SentryOptions optio .log(SentryLevel.DEBUG, "SendCachedEventFireAndForgetIntegration installed."); addIntegrationToSdkVersion(getClass()); - sendCachedEnvelopes(hub, options); + sendCachedEnvelopes(scopes, options); } @Override @@ -95,14 +95,14 @@ public void close() throws IOException { @Override public void onConnectionStatusChanged( final @NotNull IConnectionStatusProvider.ConnectionStatus status) { - if (hub != null && options != null) { - sendCachedEnvelopes(hub, options); + if (scopes != null && options != null) { + sendCachedEnvelopes(scopes, options); } } @SuppressWarnings({"FutureReturnValueIgnored", "NullAway"}) private synchronized void sendCachedEnvelopes( - final @NotNull IHub hub, final @NotNull SentryOptions options) { + final @NotNull IScopes scopes, final @NotNull SentryOptions options) { try { options .getExecutorService() @@ -122,7 +122,7 @@ private synchronized void sendCachedEnvelopes( connectionStatusProvider = options.getConnectionStatusProvider(); connectionStatusProvider.addConnectionStatusObserver(this); - sender = factory.create(hub, options); + sender = factory.create(scopes, options); } // skip run only if we're certainly disconnected @@ -138,7 +138,7 @@ private synchronized void sendCachedEnvelopes( } // in case there's rate limiting active, skip processing - final @Nullable RateLimiter rateLimiter = hub.getRateLimiter(); + final @Nullable RateLimiter rateLimiter = scopes.getRateLimiter(); if (rateLimiter != null && rateLimiter.isActiveForCategory(DataCategory.All)) { options .getLogger() diff --git a/sentry/src/main/java/io/sentry/SendFireAndForgetEnvelopeSender.java b/sentry/src/main/java/io/sentry/SendFireAndForgetEnvelopeSender.java index e44d18a8d6..155946b95a 100644 --- a/sentry/src/main/java/io/sentry/SendFireAndForgetEnvelopeSender.java +++ b/sentry/src/main/java/io/sentry/SendFireAndForgetEnvelopeSender.java @@ -21,8 +21,8 @@ public SendFireAndForgetEnvelopeSender( @Override public @Nullable SendCachedEnvelopeFireAndForgetIntegration.SendFireAndForget create( - final @NotNull IHub hub, final @NotNull SentryOptions options) { - Objects.requireNonNull(hub, "Hub is required"); + final @NotNull IScopes scopes, final @NotNull SentryOptions options) { + Objects.requireNonNull(scopes, "Hub is required"); Objects.requireNonNull(options, "SentryOptions is required"); final String dirPath = sendFireAndForgetDirPath.getDirPath(); @@ -33,7 +33,7 @@ public SendFireAndForgetEnvelopeSender( final EnvelopeSender envelopeSender = new EnvelopeSender( - hub, + scopes, options.getSerializer(), options.getLogger(), options.getFlushTimeoutMillis(), diff --git a/sentry/src/main/java/io/sentry/SendFireAndForgetOutboxSender.java b/sentry/src/main/java/io/sentry/SendFireAndForgetOutboxSender.java index fda41610fd..e7913b5b2f 100644 --- a/sentry/src/main/java/io/sentry/SendFireAndForgetOutboxSender.java +++ b/sentry/src/main/java/io/sentry/SendFireAndForgetOutboxSender.java @@ -21,8 +21,8 @@ public SendFireAndForgetOutboxSender( @Override public @Nullable SendCachedEnvelopeFireAndForgetIntegration.SendFireAndForget create( - final @NotNull IHub hub, final @NotNull SentryOptions options) { - Objects.requireNonNull(hub, "Hub is required"); + final @NotNull IScopes scopes, final @NotNull SentryOptions options) { + Objects.requireNonNull(scopes, "Hub is required"); Objects.requireNonNull(options, "SentryOptions is required"); final String dirPath = sendFireAndForgetDirPath.getDirPath(); @@ -33,7 +33,7 @@ public SendFireAndForgetOutboxSender( final OutboxSender outboxSender = new OutboxSender( - hub, + scopes, options.getEnvelopeReader(), options.getSerializer(), options.getLogger(), diff --git a/sentry/src/main/java/io/sentry/Sentry.java b/sentry/src/main/java/io/sentry/Sentry.java index 5196d0f31a..206ffd8d20 100644 --- a/sentry/src/main/java/io/sentry/Sentry.java +++ b/sentry/src/main/java/io/sentry/Sentry.java @@ -43,11 +43,11 @@ public final class Sentry { private Sentry() {} - /** Holds Hubs per thread or only mainHub if globalHubMode is enabled. */ - private static final @NotNull ThreadLocal currentHub = new ThreadLocal<>(); + /** Holds Hubs per thread or only mainScopes if globalHubMode is enabled. */ + private static final @NotNull ThreadLocal currentScopes = new ThreadLocal<>(); /** The Main Hub or NoOp if Sentry is disabled. */ - private static volatile @NotNull IHub mainHub = NoOpHub.getInstance(); + private static volatile @NotNull IScopes mainScopes = NoOpScopes.getInstance(); /** Default value for globalHubMode is false */ private static final boolean GLOBAL_HUB_DEFAULT_MODE = false; @@ -66,40 +66,58 @@ private Sentry() {} private static final long classCreationTimestamp = System.currentTimeMillis(); /** - * Returns the current (threads) hub, if none, clones the mainHub and returns it. + * Returns the current (threads) hub, if none, clones the mainScopes and returns it. * * @return the hub */ @ApiStatus.Internal // exposed for the coroutines integration in SentryContext + @SuppressWarnings("deprecation") + @Deprecated public static @NotNull IHub getCurrentHub() { + return new HubScopesWrapper(getCurrentScopes()); + } + + @ApiStatus.Internal // exposed for the coroutines integration in SentryContext + @SuppressWarnings("deprecation") + public static @NotNull IScopes getCurrentScopes() { if (globalHubMode) { - return mainHub; + return mainScopes; } - IHub hub = currentHub.get(); - if (hub == null || hub instanceof NoOpHub) { - hub = mainHub.clone(); - currentHub.set(hub); + IScopes hub = currentScopes.get(); + if (hub == null || hub.isNoOp()) { + // TODO fork instead + hub = mainScopes.clone(); + currentScopes.set(hub); } return hub; } /** - * Returns a new hub which is cloned from the mainHub. + * Returns a new hub which is cloned from the mainScopes. * * @return the hub */ @ApiStatus.Internal @ApiStatus.Experimental - public static @NotNull IHub cloneMainHub() { + @SuppressWarnings("deprecation") + public static @NotNull IScopes cloneMainHub() { if (globalHubMode) { - return mainHub; + return mainScopes; } - return mainHub.clone(); + // TODO fork instead + return mainScopes.clone(); } @ApiStatus.Internal // exposed for the coroutines integration in SentryContext + @Deprecated + @SuppressWarnings("deprecation") public static void setCurrentHub(final @NotNull IHub hub) { - currentHub.set(hub); + currentScopes.set(hub); + } + + @ApiStatus.Internal // exposed for the coroutines integration in SentryContext + public static void setCurrentScopes(final @NotNull IScopes scopes) { + currentScopes.set(scopes); } /** @@ -108,7 +126,7 @@ public static void setCurrentHub(final @NotNull IHub hub) { * @return true if its enabled or false otherwise. */ public static boolean isEnabled() { - return getCurrentHub().isEnabled(); + return getCurrentScopes().isEnabled(); } /** Initializes the SDK */ @@ -217,6 +235,7 @@ public static void init(final @NotNull SentryOptions options) { * @param options options the SentryOptions * @param globalHubMode the globalHubMode */ + @SuppressWarnings("deprecation") private static synchronized void init( final @NotNull SentryOptions options, final boolean globalHubMode) { if (isEnabled()) { @@ -234,10 +253,11 @@ private static synchronized void init( options.getLogger().log(SentryLevel.INFO, "GlobalHubMode: '%s'", String.valueOf(globalHubMode)); Sentry.globalHubMode = globalHubMode; - final IHub hub = getCurrentHub(); - mainHub = new Hub(options); + final IScopes hub = getCurrentScopes(); + // TODO new Scopes() + mainScopes = new Hub(options); - currentHub.set(mainHub); + currentScopes.set(mainScopes); hub.close(true); @@ -252,12 +272,12 @@ private static synchronized void init( // and hub was still NoOp. // Registering integrations here make sure that Hub is already created. for (final Integration integration : options.getIntegrations()) { - integration.register(HubAdapter.getInstance(), options); + integration.register(ScopesAdapter.getInstance(), options); } notifyOptionsObservers(options); - finalizePreviousSession(options, HubAdapter.getInstance()); + finalizePreviousSession(options, ScopesAdapter.getInstance()); handleAppStartProfilingConfig(options, options.getExecutorService()); } @@ -327,12 +347,12 @@ private static void handleAppStartProfilingConfig( @SuppressWarnings("FutureReturnValueIgnored") private static void finalizePreviousSession( - final @NotNull SentryOptions options, final @NotNull IHub hub) { + final @NotNull SentryOptions options, final @NotNull IScopes scopes) { // enqueue a task to finalize previous session. Since the executor // is single-threaded, this task will be enqueued sequentially after all integrations that have // to modify the previous session have done their work, even if they do that async. try { - options.getExecutorService().submit(new PreviousSessionFinalizer(options, hub)); + options.getExecutorService().submit(new PreviousSessionFinalizer(options, scopes)); } catch (Throwable e) { options.getLogger().log(SentryLevel.DEBUG, "Failed to finalize previous session.", e); } @@ -475,7 +495,7 @@ private static boolean initConfigurations(final @NotNull SentryOptions options) } if (options.isEnableBackpressureHandling()) { - options.setBackpressureMonitor(new BackpressureMonitor(options, HubAdapter.getInstance())); + options.setBackpressureMonitor(new BackpressureMonitor(options, ScopesAdapter.getInstance())); options.getBackpressureMonitor().start(); } @@ -484,11 +504,11 @@ private static boolean initConfigurations(final @NotNull SentryOptions options) /** Close the SDK */ public static synchronized void close() { - final IHub hub = getCurrentHub(); - mainHub = NoOpHub.getInstance(); + final IScopes scopes = getCurrentScopes(); + mainScopes = NoOpScopes.getInstance(); // remove thread local to avoid memory leak - currentHub.remove(); - hub.close(false); + currentScopes.remove(); + scopes.close(false); } /** @@ -498,7 +518,7 @@ public static synchronized void close() { * @return The Id (SentryId object) of the event */ public static @NotNull SentryId captureEvent(final @NotNull SentryEvent event) { - return getCurrentHub().captureEvent(event); + return getCurrentScopes().captureEvent(event); } /** @@ -510,7 +530,7 @@ public static synchronized void close() { */ public static @NotNull SentryId captureEvent( final @NotNull SentryEvent event, final @NotNull ScopeCallback callback) { - return getCurrentHub().captureEvent(event, callback); + return getCurrentScopes().captureEvent(event, callback); } /** @@ -522,7 +542,7 @@ public static synchronized void close() { */ public static @NotNull SentryId captureEvent( final @NotNull SentryEvent event, final @Nullable Hint hint) { - return getCurrentHub().captureEvent(event, hint); + return getCurrentScopes().captureEvent(event, hint); } /** @@ -537,7 +557,7 @@ public static synchronized void close() { final @NotNull SentryEvent event, final @Nullable Hint hint, final @NotNull ScopeCallback callback) { - return getCurrentHub().captureEvent(event, hint, callback); + return getCurrentScopes().captureEvent(event, hint, callback); } /** @@ -547,7 +567,7 @@ public static synchronized void close() { * @return The Id (SentryId object) of the event */ public static @NotNull SentryId captureMessage(final @NotNull String message) { - return getCurrentHub().captureMessage(message); + return getCurrentScopes().captureMessage(message); } /** @@ -559,7 +579,7 @@ public static synchronized void close() { */ public static @NotNull SentryId captureMessage( final @NotNull String message, final @NotNull ScopeCallback callback) { - return getCurrentHub().captureMessage(message, callback); + return getCurrentScopes().captureMessage(message, callback); } /** @@ -571,7 +591,7 @@ public static synchronized void close() { */ public static @NotNull SentryId captureMessage( final @NotNull String message, final @NotNull SentryLevel level) { - return getCurrentHub().captureMessage(message, level); + return getCurrentScopes().captureMessage(message, level); } /** @@ -586,7 +606,7 @@ public static synchronized void close() { final @NotNull String message, final @NotNull SentryLevel level, final @NotNull ScopeCallback callback) { - return getCurrentHub().captureMessage(message, level, callback); + return getCurrentScopes().captureMessage(message, level, callback); } /** @@ -596,7 +616,7 @@ public static synchronized void close() { * @return The Id (SentryId object) of the event */ public static @NotNull SentryId captureException(final @NotNull Throwable throwable) { - return getCurrentHub().captureException(throwable); + return getCurrentScopes().captureException(throwable); } /** @@ -608,7 +628,7 @@ public static synchronized void close() { */ public static @NotNull SentryId captureException( final @NotNull Throwable throwable, final @NotNull ScopeCallback callback) { - return getCurrentHub().captureException(throwable, callback); + return getCurrentScopes().captureException(throwable, callback); } /** @@ -620,7 +640,7 @@ public static synchronized void close() { */ public static @NotNull SentryId captureException( final @NotNull Throwable throwable, final @Nullable Hint hint) { - return getCurrentHub().captureException(throwable, hint); + return getCurrentScopes().captureException(throwable, hint); } /** @@ -635,7 +655,7 @@ public static synchronized void close() { final @NotNull Throwable throwable, final @Nullable Hint hint, final @NotNull ScopeCallback callback) { - return getCurrentHub().captureException(throwable, hint, callback); + return getCurrentScopes().captureException(throwable, hint, callback); } /** @@ -644,7 +664,7 @@ public static synchronized void close() { * @param userFeedback The user feedback to send to Sentry. */ public static void captureUserFeedback(final @NotNull UserFeedback userFeedback) { - getCurrentHub().captureUserFeedback(userFeedback); + getCurrentScopes().captureUserFeedback(userFeedback); } /** @@ -655,7 +675,7 @@ public static void captureUserFeedback(final @NotNull UserFeedback userFeedback) */ public static void addBreadcrumb( final @NotNull Breadcrumb breadcrumb, final @Nullable Hint hint) { - getCurrentHub().addBreadcrumb(breadcrumb, hint); + getCurrentScopes().addBreadcrumb(breadcrumb, hint); } /** @@ -664,7 +684,7 @@ public static void addBreadcrumb( * @param breadcrumb the breadcrumb */ public static void addBreadcrumb(final @NotNull Breadcrumb breadcrumb) { - getCurrentHub().addBreadcrumb(breadcrumb); + getCurrentScopes().addBreadcrumb(breadcrumb); } /** @@ -673,7 +693,7 @@ public static void addBreadcrumb(final @NotNull Breadcrumb breadcrumb) { * @param message rendered as text and the whitespace is preserved. */ public static void addBreadcrumb(final @NotNull String message) { - getCurrentHub().addBreadcrumb(message); + getCurrentScopes().addBreadcrumb(message); } /** @@ -684,7 +704,7 @@ public static void addBreadcrumb(final @NotNull String message) { * from. */ public static void addBreadcrumb(final @NotNull String message, final @NotNull String category) { - getCurrentHub().addBreadcrumb(message, category); + getCurrentScopes().addBreadcrumb(message, category); } /** @@ -693,7 +713,7 @@ public static void addBreadcrumb(final @NotNull String message, final @NotNull S * @param level the Sentry level */ public static void setLevel(final @Nullable SentryLevel level) { - getCurrentHub().setLevel(level); + getCurrentScopes().setLevel(level); } /** @@ -702,7 +722,7 @@ public static void setLevel(final @Nullable SentryLevel level) { * @param transaction the transaction */ public static void setTransaction(final @Nullable String transaction) { - getCurrentHub().setTransaction(transaction); + getCurrentScopes().setTransaction(transaction); } /** @@ -711,7 +731,7 @@ public static void setTransaction(final @Nullable String transaction) { * @param user the user */ public static void setUser(final @Nullable User user) { - getCurrentHub().setUser(user); + getCurrentScopes().setUser(user); } /** @@ -720,12 +740,12 @@ public static void setUser(final @Nullable User user) { * @param fingerprint the fingerprints */ public static void setFingerprint(final @NotNull List fingerprint) { - getCurrentHub().setFingerprint(fingerprint); + getCurrentScopes().setFingerprint(fingerprint); } /** Deletes current breadcrumbs from the current scope. */ public static void clearBreadcrumbs() { - getCurrentHub().clearBreadcrumbs(); + getCurrentScopes().clearBreadcrumbs(); } /** @@ -735,7 +755,7 @@ public static void clearBreadcrumbs() { * @param value the value */ public static void setTag(final @NotNull String key, final @NotNull String value) { - getCurrentHub().setTag(key, value); + getCurrentScopes().setTag(key, value); } /** @@ -744,7 +764,7 @@ public static void setTag(final @NotNull String key, final @NotNull String value * @param key the key */ public static void removeTag(final @NotNull String key) { - getCurrentHub().removeTag(key); + getCurrentScopes().removeTag(key); } /** @@ -755,7 +775,7 @@ public static void removeTag(final @NotNull String key) { * @param value the value */ public static void setExtra(final @NotNull String key, final @NotNull String value) { - getCurrentHub().setExtra(key, value); + getCurrentScopes().setExtra(key, value); } /** @@ -764,7 +784,7 @@ public static void setExtra(final @NotNull String key, final @NotNull String val * @param key the key */ public static void removeExtra(final @NotNull String key) { - getCurrentHub().removeExtra(key); + getCurrentScopes().removeExtra(key); } /** @@ -773,14 +793,14 @@ public static void removeExtra(final @NotNull String key) { * @return last SentryId */ public static @NotNull SentryId getLastEventId() { - return getCurrentHub().getLastEventId(); + return getCurrentScopes().getLastEventId(); } /** Pushes a new scope while inheriting the current scope's data. */ public static void pushScope() { // pushScope is no-op in global hub mode if (!globalHubMode) { - getCurrentHub().pushScope(); + getCurrentScopes().pushScope(); } } @@ -788,7 +808,7 @@ public static void pushScope() { public static void popScope() { // popScope is no-op in global hub mode if (!globalHubMode) { - getCurrentHub().popScope(); + getCurrentScopes().popScope(); } } @@ -798,7 +818,7 @@ public static void popScope() { * @param callback the callback */ public static void withScope(final @NotNull ScopeCallback callback) { - getCurrentHub().withScope(callback); + getCurrentScopes().withScope(callback); } /** @@ -807,7 +827,7 @@ public static void withScope(final @NotNull ScopeCallback callback) { * @param callback The configure scope callback. */ public static void configureScope(final @NotNull ScopeCallback callback) { - getCurrentHub().configureScope(callback); + getCurrentScopes().configureScope(callback); } /** @@ -816,11 +836,11 @@ public static void configureScope(final @NotNull ScopeCallback callback) { * @param client the client. */ public static void bindClient(final @NotNull ISentryClient client) { - getCurrentHub().bindClient(client); + getCurrentScopes().bindClient(client); } public static boolean isHealthy() { - return getCurrentHub().isHealthy(); + return getCurrentScopes().isHealthy(); } /** @@ -829,17 +849,17 @@ public static boolean isHealthy() { * @param timeoutMillis time in milliseconds */ public static void flush(final long timeoutMillis) { - getCurrentHub().flush(timeoutMillis); + getCurrentScopes().flush(timeoutMillis); } /** Starts a new session. If there's a running session, it ends it before starting the new one. */ public static void startSession() { - getCurrentHub().startSession(); + getCurrentScopes().startSession(); } /** Ends the current session */ public static void endSession() { - getCurrentHub().endSession(); + getCurrentScopes().endSession(); } /** @@ -851,7 +871,7 @@ public static void endSession() { */ public static @NotNull ITransaction startTransaction( final @NotNull String name, final @NotNull String operation) { - return getCurrentHub().startTransaction(name, operation); + return getCurrentScopes().startTransaction(name, operation); } /** @@ -866,7 +886,7 @@ public static void endSession() { final @NotNull String name, final @NotNull String operation, final @NotNull TransactionOptions transactionOptions) { - return getCurrentHub().startTransaction(name, operation, transactionOptions); + return getCurrentScopes().startTransaction(name, operation, transactionOptions); } /** @@ -884,7 +904,7 @@ public static void endSession() { final @Nullable String description, final @NotNull TransactionOptions transactionOptions) { final ITransaction transaction = - getCurrentHub().startTransaction(name, operation, transactionOptions); + getCurrentScopes().startTransaction(name, operation, transactionOptions); transaction.setDescription(description); return transaction; } @@ -897,7 +917,7 @@ public static void endSession() { */ public static @NotNull ITransaction startTransaction( final @NotNull TransactionContext transactionContexts) { - return getCurrentHub().startTransaction(transactionContexts); + return getCurrentScopes().startTransaction(transactionContexts); } /** @@ -910,7 +930,7 @@ public static void endSession() { public static @NotNull ITransaction startTransaction( final @NotNull TransactionContext transactionContext, final @NotNull TransactionOptions transactionOptions) { - return getCurrentHub().startTransaction(transactionContext, transactionOptions); + return getCurrentScopes().startTransaction(transactionContext, transactionOptions); } /** @@ -923,7 +943,7 @@ public static void endSession() { @Deprecated @SuppressWarnings("InlineMeSuggester") public static @Nullable SentryTraceHeader traceHeaders() { - return getCurrentHub().traceHeaders(); + return getCurrentScopes().traceHeaders(); } /** @@ -935,9 +955,9 @@ public static void endSession() { */ public static @Nullable ISpan getSpan() { if (globalHubMode && Platform.isAndroid()) { - return getCurrentHub().getTransaction(); + return getCurrentScopes().getTransaction(); } else { - return getCurrentHub().getSpan(); + return getCurrentScopes().getSpan(); } } @@ -952,7 +972,7 @@ public static void endSession() { * @return true if App has crashed, false otherwise, and null if not evaluated yet */ public static @Nullable Boolean isCrashedLastRun() { - return getCurrentHub().isCrashedLastRun(); + return getCurrentScopes().isCrashedLastRun(); } /** @@ -964,7 +984,7 @@ public static void endSession() { * finished, this call will be ignored. */ public static void reportFullyDisplayed() { - getCurrentHub().reportFullyDisplayed(); + getCurrentScopes().reportFullyDisplayed(); } /** @@ -980,7 +1000,7 @@ public static void reportFullDisplayed() { @NotNull @ApiStatus.Experimental public static MetricsApi metrics() { - return getCurrentHub().metrics(); + return getCurrentScopes().metrics(); } /** @@ -1009,7 +1029,7 @@ public interface OptionsConfiguration { // return TransactionContext (if performance enabled) or null (if performance disabled) public static @Nullable TransactionContext continueTrace( final @Nullable String sentryTrace, final @Nullable List baggageHeaders) { - return getCurrentHub().continueTrace(sentryTrace, baggageHeaders); + return getCurrentScopes().continueTrace(sentryTrace, baggageHeaders); } /** @@ -1019,7 +1039,7 @@ public interface OptionsConfiguration { * @return sentry trace header or null */ public static @Nullable SentryTraceHeader getTraceparent() { - return getCurrentHub().getTraceparent(); + return getCurrentScopes().getTraceparent(); } /** @@ -1029,11 +1049,11 @@ public interface OptionsConfiguration { * @return baggage header or null */ public static @Nullable BaggageHeader getBaggage() { - return getCurrentHub().getBaggage(); + return getCurrentScopes().getBaggage(); } @ApiStatus.Experimental public static @NotNull SentryId captureCheckIn(final @NotNull CheckIn checkIn) { - return getCurrentHub().captureCheckIn(checkIn); + return getCurrentScopes().captureCheckIn(checkIn); } } diff --git a/sentry/src/main/java/io/sentry/SentryTracer.java b/sentry/src/main/java/io/sentry/SentryTracer.java index bc3b5eb531..7d82bbbc4a 100644 --- a/sentry/src/main/java/io/sentry/SentryTracer.java +++ b/sentry/src/main/java/io/sentry/SentryTracer.java @@ -26,7 +26,7 @@ public final class SentryTracer implements ITransaction { private final @NotNull SentryId eventId = new SentryId(); private final @NotNull Span root; private final @NotNull List children = new CopyOnWriteArrayList<>(); - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private @NotNull String name; /** @@ -52,31 +52,31 @@ public final class SentryTracer implements ITransaction { private final @Nullable TransactionPerformanceCollector transactionPerformanceCollector; private final @NotNull TransactionOptions transactionOptions; - public SentryTracer(final @NotNull TransactionContext context, final @NotNull IHub hub) { - this(context, hub, new TransactionOptions(), null); + public SentryTracer(final @NotNull TransactionContext context, final @NotNull IScopes scopes) { + this(context, scopes, new TransactionOptions(), null); } public SentryTracer( final @NotNull TransactionContext context, - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull TransactionOptions transactionOptions) { - this(context, hub, transactionOptions, null); + this(context, scopes, transactionOptions, null); } SentryTracer( final @NotNull TransactionContext context, - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull TransactionOptions transactionOptions, final @Nullable TransactionPerformanceCollector transactionPerformanceCollector) { Objects.requireNonNull(context, "context is required"); - Objects.requireNonNull(hub, "hub is required"); + Objects.requireNonNull(scopes, "scopes are required"); this.root = - new Span(context, this, hub, transactionOptions.getStartTimestamp(), transactionOptions); + new Span(context, this, scopes, transactionOptions.getStartTimestamp(), transactionOptions); this.name = context.getName(); this.instrumenter = context.getInstrumenter(); - this.hub = hub; + this.scopes = scopes; this.transactionPerformanceCollector = transactionPerformanceCollector; this.transactionNameSource = context.getTransactionNameSource(); this.transactionOptions = transactionOptions; @@ -84,7 +84,7 @@ public SentryTracer( if (context.getBaggage() != null) { this.baggage = context.getBaggage(); } else { - this.baggage = new Baggage(hub.getOptions().getLogger()); + this.baggage = new Baggage(scopes.getOptions().getLogger()); } // We are currently sending the performance data only in profiles, so there's no point in @@ -122,7 +122,8 @@ public void run() { try { timer.schedule(idleTimeoutTask, idleTimeout); } catch (Throwable e) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log(SentryLevel.WARNING, "Failed to schedule finish timer", e); // if we failed to schedule the finish timer for some reason, we finish it here right @@ -156,7 +157,7 @@ private void onDeadlineTimeoutReached() { return; } - final @NotNull SentryDate finishTimestamp = hub.getOptions().getDateProvider().now(); + final @NotNull SentryDate finishTimestamp = scopes.getOptions().getDateProvider().now(); // abort all child-spans first, this ensures the transaction can be finished, // even if waitForChildren is true @@ -186,7 +187,7 @@ public void finish( // if it's not set -> fallback to the current time if (finishTimestamp == null) { - finishTimestamp = hub.getOptions().getDateProvider().now(); + finishTimestamp = scopes.getOptions().getDateProvider().now(); } // auto-finish any idle spans first @@ -207,9 +208,10 @@ public void finish( ProfilingTraceData profilingTraceData = null; if (Boolean.TRUE.equals(isSampled()) && Boolean.TRUE.equals(isProfileSampled())) { profilingTraceData = - hub.getOptions() + scopes + .getOptions() .getTransactionProfiler() - .onTransactionFinish(this, performanceCollectionData, hub.getOptions()); + .onTransactionFinish(this, performanceCollectionData, scopes.getOptions()); } if (performanceCollectionData != null) { performanceCollectionData.clear(); @@ -222,7 +224,7 @@ public void finish( root.finish(finishStatus.spanStatus, finishTimestamp); - hub.configureScope( + scopes.configureScope( scope -> { scope.withTransaction( transaction -> { @@ -251,7 +253,8 @@ public void finish( if (dropIfNoChildren && children.isEmpty() && transactionOptions.getIdleTimeout() != null) { // if it's an idle transaction which has no children, we drop it to save user's quota - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -261,7 +264,7 @@ public void finish( } transaction.getMeasurements().putAll(root.getMeasurements()); - hub.captureTransaction(transaction, traceContext(), hint, profilingTraceData); + scopes.captureTransaction(transaction, traceContext(), hint, profilingTraceData); } } @@ -292,7 +295,8 @@ public void run() { try { timer.schedule(deadlineTimeoutTask, deadlineTimeOut); } catch (Throwable e) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log(SentryLevel.WARNING, "Failed to schedule finish timer", e); // if we failed to schedule the finish timer for some reason, we finish it here right @@ -418,7 +422,7 @@ private ISpan createChild( return NoOpSpan.getInstance(); } - if (children.size() < hub.getOptions().getMaxSpans()) { + if (children.size() < scopes.getOptions().getMaxSpans()) { Objects.requireNonNull(parentSpanId, "parentSpanId is required"); Objects.requireNonNull(operation, "operation is required"); cancelIdleTimer(); @@ -428,7 +432,7 @@ private ISpan createChild( parentSpanId, this, operation, - this.hub, + this.scopes, timestamp, spanOptions, finishingSpan -> { @@ -451,7 +455,7 @@ private ISpan createChild( span.setData(SpanDataConvention.THREAD_ID, String.valueOf(Thread.currentThread().getId())); span.setData( SpanDataConvention.THREAD_NAME, - hub.getOptions().getMainThreadChecker().isMainThread() + scopes.getOptions().getMainThreadChecker().isMainThread() ? "main" : Thread.currentThread().getName()); this.children.add(span); @@ -460,7 +464,8 @@ private ISpan createChild( } return span; } else { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.WARNING, @@ -529,10 +534,11 @@ private ISpan createChild( return NoOpSpan.getInstance(); } - if (children.size() < hub.getOptions().getMaxSpans()) { + if (children.size() < scopes.getOptions().getMaxSpans()) { return root.startChild(operation, description, timestamp, instrumenter, spanOptions); } else { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.WARNING, @@ -567,7 +573,7 @@ public void finish(@Nullable SpanStatus status, @Nullable SentryDate finishDate) @Override public @Nullable TraceContext traceContext() { - if (hub.getOptions().isTraceSampling()) { + if (scopes.getOptions().isTraceSampling()) { updateBaggageValues(); return baggage.toTraceContext(); } else { @@ -579,12 +585,12 @@ private void updateBaggageValues() { synchronized (this) { if (baggage.isMutable()) { final AtomicReference userAtomicReference = new AtomicReference<>(); - hub.configureScope( + scopes.configureScope( scope -> { userAtomicReference.set(scope.getUser()); }); baggage.setValuesFromTransaction( - this, userAtomicReference.get(), hub.getOptions(), this.getSamplingDecision()); + this, userAtomicReference.get(), scopes.getOptions(), this.getSamplingDecision()); baggage.freeze(); } } @@ -592,7 +598,7 @@ private void updateBaggageValues() { @Override public @Nullable BaggageHeader toBaggageHeader(@Nullable List thirdPartyBaggageHeaders) { - if (hub.getOptions().isTraceSampling()) { + if (scopes.getOptions().isTraceSampling()) { updateBaggageValues(); return BaggageHeader.fromBaggageAndOutgoingHeader(baggage, thirdPartyBaggageHeaders); @@ -616,7 +622,8 @@ private boolean hasAllChildrenFinished() { @Override public void setOperation(final @NotNull String operation) { if (root.isFinished()) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -636,7 +643,8 @@ public void setOperation(final @NotNull String operation) { @Override public void setDescription(final @Nullable String description) { if (root.isFinished()) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -656,7 +664,8 @@ public void setDescription(final @Nullable String description) { @Override public void setStatus(final @Nullable SpanStatus status) { if (root.isFinished()) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -676,7 +685,8 @@ public void setStatus(final @Nullable SpanStatus status) { @Override public void setThrowable(final @Nullable Throwable throwable) { if (root.isFinished()) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log(SentryLevel.DEBUG, "The transaction is already finished. Throwable cannot be set"); return; @@ -698,7 +708,8 @@ public void setThrowable(final @Nullable Throwable throwable) { @Override public void setTag(final @NotNull String key, final @NotNull String value) { if (root.isFinished()) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log(SentryLevel.DEBUG, "The transaction is already finished. Tag %s cannot be set", key); return; @@ -720,7 +731,8 @@ public boolean isFinished() { @Override public void setData(@NotNull String key, @NotNull Object value) { if (root.isFinished()) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, "The transaction is already finished. Data %s cannot be set", key); @@ -795,7 +807,8 @@ public void setName(@NotNull String name) { @Override public void setName(@NotNull String name, @NotNull TransactionNameSource transactionNameSource) { if (root.isFinished()) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, diff --git a/sentry/src/main/java/io/sentry/SentryWrapper.java b/sentry/src/main/java/io/sentry/SentryWrapper.java index 1a39adee99..165ace7c83 100644 --- a/sentry/src/main/java/io/sentry/SentryWrapper.java +++ b/sentry/src/main/java/io/sentry/SentryWrapper.java @@ -27,16 +27,18 @@ public final class SentryWrapper { * @return the wrapped {@link Callable} * @param - the result type of the {@link Callable} */ + @SuppressWarnings("deprecation") public static Callable wrapCallable(final @NotNull Callable callable) { - final IHub newHub = Sentry.getCurrentHub().clone(); + // TODO replace with forking + final IScopes newHub = Sentry.getCurrentScopes().clone(); return () -> { - final IHub oldState = Sentry.getCurrentHub(); - Sentry.setCurrentHub(newHub); + final IScopes oldState = Sentry.getCurrentScopes(); + Sentry.setCurrentScopes(newHub); try { return callable.call(); } finally { - Sentry.setCurrentHub(oldState); + Sentry.setCurrentScopes(oldState); } }; } @@ -51,17 +53,18 @@ public static Callable wrapCallable(final @NotNull Callable callable) * @return the wrapped {@link Supplier} * @param - the result type of the {@link Supplier} */ + @SuppressWarnings("deprecation") public static Supplier wrapSupplier(final @NotNull Supplier supplier) { - - final IHub newHub = Sentry.getCurrentHub().clone(); + // TODO replace with forking + final IScopes newHub = Sentry.getCurrentScopes().clone(); return () -> { - final IHub oldState = Sentry.getCurrentHub(); - Sentry.setCurrentHub(newHub); + final IScopes oldState = Sentry.getCurrentScopes(); + Sentry.setCurrentScopes(newHub); try { return supplier.get(); } finally { - Sentry.setCurrentHub(oldState); + Sentry.setCurrentScopes(oldState); } }; } diff --git a/sentry/src/main/java/io/sentry/ShutdownHookIntegration.java b/sentry/src/main/java/io/sentry/ShutdownHookIntegration.java index b144f2d88a..d957a87ccf 100644 --- a/sentry/src/main/java/io/sentry/ShutdownHookIntegration.java +++ b/sentry/src/main/java/io/sentry/ShutdownHookIntegration.java @@ -27,12 +27,12 @@ public ShutdownHookIntegration() { } @Override - public void register(final @NotNull IHub hub, final @NotNull SentryOptions options) { - Objects.requireNonNull(hub, "Hub is required"); + public void register(final @NotNull IScopes scopes, final @NotNull SentryOptions options) { + Objects.requireNonNull(scopes, "Scopes are required"); Objects.requireNonNull(options, "SentryOptions is required"); if (options.isEnableShutdownHook()) { - thread = new Thread(() -> hub.flush(options.getFlushTimeoutMillis())); + thread = new Thread(() -> scopes.flush(options.getFlushTimeoutMillis())); runtime.addShutdownHook(thread); options.getLogger().log(SentryLevel.DEBUG, "ShutdownHookIntegration installed."); addIntegrationToSdkVersion(getClass()); diff --git a/sentry/src/main/java/io/sentry/Span.java b/sentry/src/main/java/io/sentry/Span.java index 850276dac3..1c9d180b29 100644 --- a/sentry/src/main/java/io/sentry/Span.java +++ b/sentry/src/main/java/io/sentry/Span.java @@ -35,7 +35,7 @@ public final class Span implements ISpan { /** A throwable thrown during the execution of the span. */ private @Nullable Throwable throwable; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @NotNull AtomicBoolean finished = new AtomicBoolean(false); @@ -55,8 +55,8 @@ public final class Span implements ISpan { final @Nullable SpanId parentSpanId, final @NotNull SentryTracer transaction, final @NotNull String operation, - final @NotNull IHub hub) { - this(traceId, parentSpanId, transaction, operation, hub, null, new SpanOptions(), null); + final @NotNull IScopes scopes) { + this(traceId, parentSpanId, transaction, operation, scopes, null, new SpanOptions(), null); } Span( @@ -64,7 +64,7 @@ public final class Span implements ISpan { final @Nullable SpanId parentSpanId, final @NotNull SentryTracer transaction, final @NotNull String operation, - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @Nullable SentryDate startTimestamp, final @NotNull SpanOptions options, final @Nullable SpanFinishedCallback spanFinishedCallback) { @@ -72,30 +72,30 @@ public final class Span implements ISpan { new SpanContext( traceId, new SpanId(), operation, parentSpanId, transaction.getSamplingDecision()); this.transaction = Objects.requireNonNull(transaction, "transaction is required"); - this.hub = Objects.requireNonNull(hub, "hub is required"); + this.scopes = Objects.requireNonNull(scopes, "Scopes are required"); this.options = options; this.spanFinishedCallback = spanFinishedCallback; if (startTimestamp != null) { this.startTimestamp = startTimestamp; } else { - this.startTimestamp = hub.getOptions().getDateProvider().now(); + this.startTimestamp = scopes.getOptions().getDateProvider().now(); } } public Span( final @NotNull TransactionContext context, final @NotNull SentryTracer sentryTracer, - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @Nullable SentryDate startTimestamp, final @NotNull SpanOptions options) { this.context = Objects.requireNonNull(context, "context is required"); this.transaction = Objects.requireNonNull(sentryTracer, "sentryTracer is required"); - this.hub = Objects.requireNonNull(hub, "hub is required"); + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); this.spanFinishedCallback = null; if (startTimestamp != null) { this.startTimestamp = startTimestamp; } else { - this.startTimestamp = hub.getOptions().getDateProvider().now(); + this.startTimestamp = scopes.getOptions().getDateProvider().now(); } this.options = options; } @@ -180,7 +180,7 @@ public void finish() { @Override public void finish(@Nullable SpanStatus status) { - finish(status, hub.getOptions().getDateProvider().now()); + finish(status, scopes.getOptions().getDateProvider().now()); } /** @@ -197,7 +197,7 @@ public void finish(final @Nullable SpanStatus status, final @Nullable SentryDate } this.context.setStatus(status); - this.timestamp = timestamp == null ? hub.getOptions().getDateProvider().now() : timestamp; + this.timestamp = timestamp == null ? scopes.getOptions().getDateProvider().now() : timestamp; if (options.isTrimStart() || options.isTrimEnd()) { @Nullable SentryDate minChildStart = null; @Nullable SentryDate maxChildEnd = null; @@ -230,7 +230,7 @@ public void finish(final @Nullable SpanStatus status, final @Nullable SentryDate } if (throwable != null) { - hub.setSpanContext(throwable, this, this.transaction.getName()); + scopes.setSpanContext(throwable, this, this.transaction.getName()); } if (spanFinishedCallback != null) { spanFinishedCallback.execute(this); @@ -343,7 +343,8 @@ public void setData(final @NotNull String key, final @NotNull Object value) { @Override public void setMeasurement(final @NotNull String name, final @NotNull Number value) { if (isFinished()) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -365,7 +366,8 @@ public void setMeasurement( final @NotNull Number value, final @NotNull MeasurementUnit unit) { if (isFinished()) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, diff --git a/sentry/src/main/java/io/sentry/SpotlightIntegration.java b/sentry/src/main/java/io/sentry/SpotlightIntegration.java index 6d488bcbce..0b69ae79be 100644 --- a/sentry/src/main/java/io/sentry/SpotlightIntegration.java +++ b/sentry/src/main/java/io/sentry/SpotlightIntegration.java @@ -26,7 +26,7 @@ public final class SpotlightIntegration private @NotNull ISentryExecutorService executorService = NoOpSentryExecutorService.getInstance(); @Override - public void register(@NotNull IHub hub, @NotNull SentryOptions options) { + public void register(@NotNull IScopes scopes, @NotNull SentryOptions options) { this.options = options; this.logger = options.getLogger(); diff --git a/sentry/src/main/java/io/sentry/UncaughtExceptionHandlerIntegration.java b/sentry/src/main/java/io/sentry/UncaughtExceptionHandlerIntegration.java index 33e1a4a815..47ceaa084e 100644 --- a/sentry/src/main/java/io/sentry/UncaughtExceptionHandlerIntegration.java +++ b/sentry/src/main/java/io/sentry/UncaughtExceptionHandlerIntegration.java @@ -28,7 +28,7 @@ public final class UncaughtExceptionHandlerIntegration /** Reference to the pre-existing uncaught exception handler. */ private @Nullable Thread.UncaughtExceptionHandler defaultExceptionHandler; - private @Nullable IHub hub; + private @Nullable IScopes scopes; private @Nullable SentryOptions options; private boolean registered = false; @@ -43,7 +43,7 @@ public UncaughtExceptionHandlerIntegration() { } @Override - public final void register(final @NotNull IHub hub, final @NotNull SentryOptions options) { + public final void register(final @NotNull IScopes scopes, final @NotNull SentryOptions options) { if (registered) { options .getLogger() @@ -54,7 +54,7 @@ public final void register(final @NotNull IHub hub, final @NotNull SentryOptions } registered = true; - this.hub = Objects.requireNonNull(hub, "Hub is required"); + this.scopes = Objects.requireNonNull(scopes, "Hub is required"); this.options = Objects.requireNonNull(options, "SentryOptions is required"); this.options @@ -89,7 +89,7 @@ public final void register(final @NotNull IHub hub, final @NotNull SentryOptions @Override public void uncaughtException(Thread thread, Throwable thrown) { - if (options != null && hub != null) { + if (options != null && scopes != null) { options.getLogger().log(SentryLevel.INFO, "Uncaught exception received."); try { @@ -99,14 +99,14 @@ public void uncaughtException(Thread thread, Throwable thrown) { final SentryEvent event = new SentryEvent(throwable); event.setLevel(SentryLevel.FATAL); - final ITransaction transaction = hub.getTransaction(); + final ITransaction transaction = scopes.getTransaction(); if (transaction == null && event.getEventId() != null) { // if there's no active transaction on scope, this event can trigger flush notification exceptionHint.setFlushable(event.getEventId()); } final Hint hint = HintUtils.createWithTypeCheckHint(exceptionHint); - final @NotNull SentryId sentryId = hub.captureEvent(event, hint); + final @NotNull SentryId sentryId = scopes.captureEvent(event, hint); final boolean isEventDropped = sentryId.equals(SentryId.EMPTY_ID); final EventDropReason eventDropReason = HintUtils.getEventDropReason(hint); // in case the event has been dropped by multithreaded deduplicator, the other threads will diff --git a/sentry/src/main/java/io/sentry/backpressure/BackpressureMonitor.java b/sentry/src/main/java/io/sentry/backpressure/BackpressureMonitor.java index 2008a38c76..6541a7586a 100644 --- a/sentry/src/main/java/io/sentry/backpressure/BackpressureMonitor.java +++ b/sentry/src/main/java/io/sentry/backpressure/BackpressureMonitor.java @@ -1,6 +1,6 @@ package io.sentry.backpressure; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ISentryExecutorService; import io.sentry.SentryLevel; import io.sentry.SentryOptions; @@ -12,12 +12,13 @@ public final class BackpressureMonitor implements IBackpressureMonitor, Runnable private static final int CHECK_INTERVAL_IN_MS = 10 * 1000; private final @NotNull SentryOptions sentryOptions; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private int downsampleFactor = 0; - public BackpressureMonitor(final @NotNull SentryOptions sentryOptions, final @NotNull IHub hub) { + public BackpressureMonitor( + final @NotNull SentryOptions sentryOptions, final @NotNull IScopes scopes) { this.sentryOptions = sentryOptions; - this.hub = hub; + this.scopes = scopes; } @Override @@ -66,6 +67,6 @@ private void reschedule(final int delay) { } private boolean isHealthy() { - return hub.isHealthy(); + return scopes.isHealthy(); } } diff --git a/sentry/src/main/java/io/sentry/instrumentation/file/FileIOSpanManager.java b/sentry/src/main/java/io/sentry/instrumentation/file/FileIOSpanManager.java index 956996ce04..52963413b6 100644 --- a/sentry/src/main/java/io/sentry/instrumentation/file/FileIOSpanManager.java +++ b/sentry/src/main/java/io/sentry/instrumentation/file/FileIOSpanManager.java @@ -1,6 +1,6 @@ package io.sentry.instrumentation.file; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ISpan; import io.sentry.SentryIntegrationPackageStorage; import io.sentry.SentryOptions; @@ -28,8 +28,8 @@ final class FileIOSpanManager { private final @NotNull SentryStackTraceFactory stackTraceFactory; - static @Nullable ISpan startSpan(final @NotNull IHub hub, final @NotNull String op) { - final ISpan parent = Platform.isAndroid() ? hub.getTransaction() : hub.getSpan(); + static @Nullable ISpan startSpan(final @NotNull IScopes scopes, final @NotNull String op) { + final ISpan parent = Platform.isAndroid() ? scopes.getTransaction() : scopes.getSpan(); return parent != null ? parent.startChild(op) : null; } diff --git a/sentry/src/main/java/io/sentry/instrumentation/file/SentryFileInputStream.java b/sentry/src/main/java/io/sentry/instrumentation/file/SentryFileInputStream.java index 04bb87ae7c..ea7d7f09a5 100644 --- a/sentry/src/main/java/io/sentry/instrumentation/file/SentryFileInputStream.java +++ b/sentry/src/main/java/io/sentry/instrumentation/file/SentryFileInputStream.java @@ -1,8 +1,8 @@ package io.sentry.instrumentation.file; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ISpan; +import io.sentry.ScopesAdapter; import java.io.File; import java.io.FileDescriptor; import java.io.FileInputStream; @@ -25,24 +25,24 @@ public final class SentryFileInputStream extends FileInputStream { private final @NotNull FileIOSpanManager spanManager; public SentryFileInputStream(final @Nullable String name) throws FileNotFoundException { - this(name != null ? new File(name) : null, HubAdapter.getInstance()); + this(name != null ? new File(name) : null, ScopesAdapter.getInstance()); } public SentryFileInputStream(final @Nullable File file) throws FileNotFoundException { - this(file, HubAdapter.getInstance()); + this(file, ScopesAdapter.getInstance()); } public SentryFileInputStream(final @NotNull FileDescriptor fdObj) { - this(fdObj, HubAdapter.getInstance()); + this(fdObj, ScopesAdapter.getInstance()); } - SentryFileInputStream(final @Nullable File file, final @NotNull IHub hub) + SentryFileInputStream(final @Nullable File file, final @NotNull IScopes scopes) throws FileNotFoundException { - this(init(file, null, hub)); + this(init(file, null, scopes)); } - SentryFileInputStream(final @NotNull FileDescriptor fdObj, final @NotNull IHub hub) { - this(init(fdObj, null, hub), fdObj); + SentryFileInputStream(final @NotNull FileDescriptor fdObj, final @NotNull IScopes scopes) { + this(init(fdObj, null, scopes), fdObj); } private SentryFileInputStream( @@ -60,24 +60,24 @@ private SentryFileInputStream(final @NotNull FileInputStreamInitData data) } private static FileInputStreamInitData init( - final @Nullable File file, @Nullable FileInputStream delegate, final @NotNull IHub hub) + final @Nullable File file, @Nullable FileInputStream delegate, final @NotNull IScopes scopes) throws FileNotFoundException { - final ISpan span = FileIOSpanManager.startSpan(hub, "file.read"); + final ISpan span = FileIOSpanManager.startSpan(scopes, "file.read"); if (delegate == null) { delegate = new FileInputStream(file); } - return new FileInputStreamInitData(file, span, delegate, hub.getOptions()); + return new FileInputStreamInitData(file, span, delegate, scopes.getOptions()); } private static FileInputStreamInitData init( final @NotNull FileDescriptor fd, @Nullable FileInputStream delegate, - final @NotNull IHub hub) { - final ISpan span = FileIOSpanManager.startSpan(hub, "file.read"); + final @NotNull IScopes scopes) { + final ISpan span = FileIOSpanManager.startSpan(scopes, "file.read"); if (delegate == null) { delegate = new FileInputStream(fd); } - return new FileInputStreamInitData(null, span, delegate, hub.getOptions()); + return new FileInputStreamInitData(null, span, delegate, scopes.getOptions()); } @Override @@ -128,25 +128,27 @@ public static FileInputStream create( final @NotNull FileInputStream delegate, final @Nullable String name) throws FileNotFoundException { return new SentryFileInputStream( - init(name != null ? new File(name) : null, delegate, HubAdapter.getInstance())); + init(name != null ? new File(name) : null, delegate, ScopesAdapter.getInstance())); } public static FileInputStream create( final @NotNull FileInputStream delegate, final @Nullable File file) throws FileNotFoundException { - return new SentryFileInputStream(init(file, delegate, HubAdapter.getInstance())); + return new SentryFileInputStream(init(file, delegate, ScopesAdapter.getInstance())); } public static FileInputStream create( final @NotNull FileInputStream delegate, final @NotNull FileDescriptor descriptor) { return new SentryFileInputStream( - init(descriptor, delegate, HubAdapter.getInstance()), descriptor); + init(descriptor, delegate, ScopesAdapter.getInstance()), descriptor); } static FileInputStream create( - final @NotNull FileInputStream delegate, final @Nullable File file, final @NotNull IHub hub) + final @NotNull FileInputStream delegate, + final @Nullable File file, + final @NotNull IScopes scopes) throws FileNotFoundException { - return new SentryFileInputStream(init(file, delegate, hub)); + return new SentryFileInputStream(init(file, delegate, scopes)); } } } diff --git a/sentry/src/main/java/io/sentry/instrumentation/file/SentryFileOutputStream.java b/sentry/src/main/java/io/sentry/instrumentation/file/SentryFileOutputStream.java index 9424710d71..4ef5022e1c 100644 --- a/sentry/src/main/java/io/sentry/instrumentation/file/SentryFileOutputStream.java +++ b/sentry/src/main/java/io/sentry/instrumentation/file/SentryFileOutputStream.java @@ -1,8 +1,8 @@ package io.sentry.instrumentation.file; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ISpan; +import io.sentry.ScopesAdapter; import java.io.File; import java.io.FileDescriptor; import java.io.FileNotFoundException; @@ -24,30 +24,31 @@ public final class SentryFileOutputStream extends FileOutputStream { private final @NotNull FileIOSpanManager spanManager; public SentryFileOutputStream(final @Nullable String name) throws FileNotFoundException { - this(name != null ? new File(name) : null, false, HubAdapter.getInstance()); + this(name != null ? new File(name) : null, false, ScopesAdapter.getInstance()); } public SentryFileOutputStream(final @Nullable String name, final boolean append) throws FileNotFoundException { - this(init(name != null ? new File(name) : null, append, null, HubAdapter.getInstance())); + this(init(name != null ? new File(name) : null, append, null, ScopesAdapter.getInstance())); } public SentryFileOutputStream(final @Nullable File file) throws FileNotFoundException { - this(file, false, HubAdapter.getInstance()); + this(file, false, ScopesAdapter.getInstance()); } public SentryFileOutputStream(final @Nullable File file, final boolean append) throws FileNotFoundException { - this(init(file, append, null, HubAdapter.getInstance())); + this(init(file, append, null, ScopesAdapter.getInstance())); } public SentryFileOutputStream(final @NotNull FileDescriptor fdObj) { - this(init(fdObj, null, HubAdapter.getInstance()), fdObj); + this(init(fdObj, null, ScopesAdapter.getInstance()), fdObj); } - SentryFileOutputStream(final @Nullable File file, final boolean append, final @NotNull IHub hub) + SentryFileOutputStream( + final @Nullable File file, final boolean append, final @NotNull IScopes scopes) throws FileNotFoundException { - this(init(file, append, null, hub)); + this(init(file, append, null, scopes)); } private SentryFileOutputStream( @@ -68,22 +69,24 @@ private static FileOutputStreamInitData init( final @Nullable File file, final boolean append, @Nullable FileOutputStream delegate, - @NotNull IHub hub) + @NotNull IScopes scopes) throws FileNotFoundException { - final ISpan span = FileIOSpanManager.startSpan(hub, "file.write"); + final ISpan span = FileIOSpanManager.startSpan(scopes, "file.write"); if (delegate == null) { delegate = new FileOutputStream(file, append); } - return new FileOutputStreamInitData(file, append, span, delegate, hub.getOptions()); + return new FileOutputStreamInitData(file, append, span, delegate, scopes.getOptions()); } private static FileOutputStreamInitData init( - final @NotNull FileDescriptor fd, @Nullable FileOutputStream delegate, @NotNull IHub hub) { - final ISpan span = FileIOSpanManager.startSpan(hub, "file.write"); + final @NotNull FileDescriptor fd, + @Nullable FileOutputStream delegate, + @NotNull IScopes scopes) { + final ISpan span = FileIOSpanManager.startSpan(scopes, "file.write"); if (delegate == null) { delegate = new FileOutputStream(fd); } - return new FileOutputStreamInitData(null, false, span, delegate, hub.getOptions()); + return new FileOutputStreamInitData(null, false, span, delegate, scopes.getOptions()); } @Override @@ -132,31 +135,32 @@ public static FileOutputStream create( final @NotNull FileOutputStream delegate, final @Nullable String name) throws FileNotFoundException { return new SentryFileOutputStream( - init(name != null ? new File(name) : null, false, delegate, HubAdapter.getInstance())); + init(name != null ? new File(name) : null, false, delegate, ScopesAdapter.getInstance())); } public static FileOutputStream create( final @NotNull FileOutputStream delegate, final @Nullable String name, final boolean append) throws FileNotFoundException { return new SentryFileOutputStream( - init(name != null ? new File(name) : null, append, delegate, HubAdapter.getInstance())); + init( + name != null ? new File(name) : null, append, delegate, ScopesAdapter.getInstance())); } public static FileOutputStream create( final @NotNull FileOutputStream delegate, final @Nullable File file) throws FileNotFoundException { - return new SentryFileOutputStream(init(file, false, delegate, HubAdapter.getInstance())); + return new SentryFileOutputStream(init(file, false, delegate, ScopesAdapter.getInstance())); } public static FileOutputStream create( final @NotNull FileOutputStream delegate, final @Nullable File file, final boolean append) throws FileNotFoundException { - return new SentryFileOutputStream(init(file, append, delegate, HubAdapter.getInstance())); + return new SentryFileOutputStream(init(file, append, delegate, ScopesAdapter.getInstance())); } public static FileOutputStream create( final @NotNull FileOutputStream delegate, final @NotNull FileDescriptor fdObj) { - return new SentryFileOutputStream(init(fdObj, delegate, HubAdapter.getInstance()), fdObj); + return new SentryFileOutputStream(init(fdObj, delegate, ScopesAdapter.getInstance()), fdObj); } } } diff --git a/sentry/src/main/java/io/sentry/instrumentation/file/SentryFileReader.java b/sentry/src/main/java/io/sentry/instrumentation/file/SentryFileReader.java index 0a225e65a5..38a83c7ff6 100644 --- a/sentry/src/main/java/io/sentry/instrumentation/file/SentryFileReader.java +++ b/sentry/src/main/java/io/sentry/instrumentation/file/SentryFileReader.java @@ -1,6 +1,6 @@ package io.sentry.instrumentation.file; -import io.sentry.IHub; +import io.sentry.IScopes; import java.io.File; import java.io.FileDescriptor; import java.io.FileNotFoundException; @@ -20,7 +20,8 @@ public SentryFileReader(final @NotNull FileDescriptor fd) { super(new SentryFileInputStream(fd)); } - SentryFileReader(final @NotNull File file, final @NotNull IHub hub) throws FileNotFoundException { - super(new SentryFileInputStream(file, hub)); + SentryFileReader(final @NotNull File file, final @NotNull IScopes scopes) + throws FileNotFoundException { + super(new SentryFileInputStream(file, scopes)); } } diff --git a/sentry/src/main/java/io/sentry/instrumentation/file/SentryFileWriter.java b/sentry/src/main/java/io/sentry/instrumentation/file/SentryFileWriter.java index 9588984612..93c901ec6c 100644 --- a/sentry/src/main/java/io/sentry/instrumentation/file/SentryFileWriter.java +++ b/sentry/src/main/java/io/sentry/instrumentation/file/SentryFileWriter.java @@ -1,6 +1,6 @@ package io.sentry.instrumentation.file; -import io.sentry.IHub; +import io.sentry.IScopes; import java.io.File; import java.io.FileDescriptor; import java.io.FileNotFoundException; @@ -30,8 +30,8 @@ public SentryFileWriter(final @NotNull FileDescriptor fd) { super(new SentryFileOutputStream(fd)); } - SentryFileWriter(final @NotNull File file, final boolean append, final @NotNull IHub hub) + SentryFileWriter(final @NotNull File file, final boolean append, final @NotNull IScopes scopes) throws FileNotFoundException { - super(new SentryFileOutputStream(file, append, hub)); + super(new SentryFileOutputStream(file, append, scopes)); } } diff --git a/sentry/src/main/java/io/sentry/util/CheckInUtils.java b/sentry/src/main/java/io/sentry/util/CheckInUtils.java index e15603adaf..6719e24839 100644 --- a/sentry/src/main/java/io/sentry/util/CheckInUtils.java +++ b/sentry/src/main/java/io/sentry/util/CheckInUtils.java @@ -3,7 +3,7 @@ import io.sentry.CheckIn; import io.sentry.CheckInStatus; import io.sentry.DateUtils; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.MonitorConfig; import io.sentry.Sentry; import io.sentry.protocol.SentryId; @@ -30,18 +30,19 @@ public static U withCheckIn( final @Nullable MonitorConfig monitorConfig, final @NotNull Callable callable) throws Exception { - final @NotNull IHub hub = Sentry.getCurrentHub(); + final @NotNull IScopes scopes = Sentry.getCurrentScopes(); final long startTime = System.currentTimeMillis(); boolean didError = false; - hub.pushScope(); - TracingUtils.startNewTrace(hub); + // TODO fork instead + scopes.pushScope(); + TracingUtils.startNewTrace(scopes); CheckIn inProgressCheckIn = new CheckIn(monitorSlug, CheckInStatus.IN_PROGRESS); if (monitorConfig != null) { inProgressCheckIn.setMonitorConfig(monitorConfig); } - @Nullable SentryId checkInId = hub.captureCheckIn(inProgressCheckIn); + @Nullable SentryId checkInId = scopes.captureCheckIn(inProgressCheckIn); try { return callable.call(); } catch (Throwable t) { @@ -51,8 +52,8 @@ public static U withCheckIn( final @NotNull CheckInStatus status = didError ? CheckInStatus.ERROR : CheckInStatus.OK; CheckIn checkIn = new CheckIn(checkInId, monitorSlug, status); checkIn.setDuration(DateUtils.millisToSeconds(System.currentTimeMillis() - startTime)); - hub.captureCheckIn(checkIn); - hub.popScope(); + scopes.captureCheckIn(checkIn); + scopes.popScope(); } } diff --git a/sentry/src/main/java/io/sentry/util/TracingUtils.java b/sentry/src/main/java/io/sentry/util/TracingUtils.java index 2aeb613f2d..67f6459660 100644 --- a/sentry/src/main/java/io/sentry/util/TracingUtils.java +++ b/sentry/src/main/java/io/sentry/util/TracingUtils.java @@ -2,8 +2,8 @@ import io.sentry.Baggage; import io.sentry.BaggageHeader; -import io.sentry.IHub; import io.sentry.IScope; +import io.sentry.IScopes; import io.sentry.ISpan; import io.sentry.PropagationContext; import io.sentry.SentryOptions; @@ -14,8 +14,8 @@ public final class TracingUtils { - public static void startNewTrace(final @NotNull IHub hub) { - hub.configureScope( + public static void startNewTrace(final @NotNull IScopes scopes) { + scopes.configureScope( scope -> { scope.withPropagationContext( propagationContext -> { @@ -25,30 +25,30 @@ public static void startNewTrace(final @NotNull IHub hub) { } public static @Nullable TracingHeaders traceIfAllowed( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull String requestUrl, @Nullable List thirdPartyBaggageHeaders, final @Nullable ISpan span) { - final @NotNull SentryOptions sentryOptions = hub.getOptions(); + final @NotNull SentryOptions sentryOptions = scopes.getOptions(); if (sentryOptions.isTraceSampling() && shouldAttachTracingHeaders(requestUrl, sentryOptions)) { - return trace(hub, thirdPartyBaggageHeaders, span); + return trace(scopes, thirdPartyBaggageHeaders, span); } return null; } public static @Nullable TracingHeaders trace( - final @NotNull IHub hub, + final @NotNull IScopes scopes, @Nullable List thirdPartyBaggageHeaders, final @Nullable ISpan span) { - final @NotNull SentryOptions sentryOptions = hub.getOptions(); + final @NotNull SentryOptions sentryOptions = scopes.getOptions(); if (span != null && !span.isNoOp()) { return new TracingHeaders( span.toSentryTrace(), span.toBaggageHeader(thirdPartyBaggageHeaders)); } else { final @NotNull PropagationContextHolder returnValue = new PropagationContextHolder(); - hub.configureScope( + scopes.configureScope( (scope) -> { returnValue.propagationContext = maybeUpdateBaggage(scope, sentryOptions); }); diff --git a/sentry/src/test/java/io/sentry/DefaultTransactionPerformanceCollectorTest.kt b/sentry/src/test/java/io/sentry/DefaultTransactionPerformanceCollectorTest.kt index c0445efb23..1416fbbe3f 100644 --- a/sentry/src/test/java/io/sentry/DefaultTransactionPerformanceCollectorTest.kt +++ b/sentry/src/test/java/io/sentry/DefaultTransactionPerformanceCollectorTest.kt @@ -33,7 +33,7 @@ class DefaultTransactionPerformanceCollectorTest { private class Fixture { lateinit var transaction1: ITransaction lateinit var transaction2: ITransaction - val hub: IHub = mock() + val scopes: IScopes = mock() val options = SentryOptions() var mockTimer: Timer? = null val deferredExecutorService = DeferredExecutorService() @@ -47,7 +47,7 @@ class DefaultTransactionPerformanceCollectorTest { } init { - whenever(hub.options).thenReturn(options) + whenever(scopes.options).thenReturn(options) } fun getSut(memoryCollector: IPerformanceSnapshotCollector? = JavaMemoryCollector(), cpuCollector: IPerformanceSnapshotCollector? = mockCpuCollector, executorService: ISentryExecutorService = deferredExecutorService): TransactionPerformanceCollector { @@ -59,8 +59,8 @@ class DefaultTransactionPerformanceCollectorTest { if (memoryCollector != null) { options.addPerformanceCollector(memoryCollector) } - transaction1 = SentryTracer(TransactionContext("", ""), hub) - transaction2 = SentryTracer(TransactionContext("", ""), hub) + transaction1 = SentryTracer(TransactionContext("", ""), scopes) + transaction2 = SentryTracer(TransactionContext("", ""), scopes) val collector = DefaultTransactionPerformanceCollector(options) val timer: Timer = collector.getProperty("timer") ?: Timer(true) mockTimer = spy(timer) diff --git a/sentry/src/test/java/io/sentry/DirectoryProcessorTest.kt b/sentry/src/test/java/io/sentry/DirectoryProcessorTest.kt index e87f4256d5..0507b8499d 100644 --- a/sentry/src/test/java/io/sentry/DirectoryProcessorTest.kt +++ b/sentry/src/test/java/io/sentry/DirectoryProcessorTest.kt @@ -27,7 +27,7 @@ class DirectoryProcessorTest { private class Fixture { - var hub: IHub = mock() + var scopes: IScopes = mock() var envelopeReader: IEnvelopeReader = mock() var serializer: ISerializer = mock() var logger: ILogger = mock() @@ -40,7 +40,7 @@ class DirectoryProcessorTest { fun getSut(isRetryable: Boolean = false, isRateLimitingActive: Boolean = false): OutboxSender { val hintCaptor = argumentCaptor() - whenever(hub.captureEvent(any(), hintCaptor.capture())).then { + whenever(scopes.captureEvent(any(), hintCaptor.capture())).then { HintUtils.runIfHasType( hintCaptor.firstValue, Enqueable::class.java @@ -52,7 +52,7 @@ class DirectoryProcessorTest { val rateLimiter = mock { whenever(mock.isActiveForCategory(any())).thenReturn(true) } - whenever(hub.rateLimiter).thenReturn(rateLimiter) + whenever(scopes.rateLimiter).thenReturn(rateLimiter) } } HintUtils.runIfHasType( @@ -62,7 +62,7 @@ class DirectoryProcessorTest { retryable.isRetry = isRetryable } } - return OutboxSender(hub, envelopeReader, serializer, logger, 500, 30) + return OutboxSender(scopes, envelopeReader, serializer, logger, 500, 30) } } @@ -91,7 +91,7 @@ class DirectoryProcessorTest { whenever(fixture.serializer.deserialize(any(), eq(SentryEvent::class.java))).thenReturn(event) fixture.getSut().processDirectory(file) - verify(fixture.hub).captureEvent(any(), argWhere { !HintUtils.hasType(it, ApplyScopeData::class.java) }) + verify(fixture.scopes).captureEvent(any(), argWhere { !HintUtils.hasType(it, ApplyScopeData::class.java) }) } @Test @@ -100,7 +100,7 @@ class DirectoryProcessorTest { dir.mkdirs() assertTrue(dir.exists()) // sanity check fixture.getSut().processDirectory(file) - verify(fixture.hub, never()).captureEnvelope(any(), any()) + verify(fixture.scopes, never()).captureEnvelope(any(), any()) } @Test @@ -121,7 +121,7 @@ class DirectoryProcessorTest { sut.processDirectory(file) // should only capture once - verify(fixture.hub).captureEvent(any(), anyOrNull()) + verify(fixture.scopes).captureEvent(any(), anyOrNull()) } @Test @@ -139,7 +139,7 @@ class DirectoryProcessorTest { sut.processDirectory(file) // should only capture once - verify(fixture.hub).captureEvent(any(), anyOrNull()) + verify(fixture.scopes).captureEvent(any(), anyOrNull()) } private fun getTempEnvelope(fileName: String): String { diff --git a/sentry/src/test/java/io/sentry/EnvelopeSenderTest.kt b/sentry/src/test/java/io/sentry/EnvelopeSenderTest.kt index 6f0ea9cb8a..d63ee81854 100644 --- a/sentry/src/test/java/io/sentry/EnvelopeSenderTest.kt +++ b/sentry/src/test/java/io/sentry/EnvelopeSenderTest.kt @@ -23,7 +23,7 @@ import kotlin.test.assertFalse class EnvelopeSenderTest { private class Fixture { - var hub: IHub? = mock() + var scopes: IScopes? = mock() var logger: ILogger? = mock() var serializer: ISerializer? = mock() var options = SentryOptions().noFlushTimeout() @@ -35,7 +35,7 @@ class EnvelopeSenderTest { fun getSut(): EnvelopeSender { return EnvelopeSender( - hub!!, + scopes!!, serializer!!, logger!!, options.flushTimeoutMillis, @@ -62,7 +62,7 @@ class EnvelopeSenderTest { val sut = fixture.getSut() sut.processDirectory(File("i don't exist")) verify(fixture.logger)!!.log(eq(SentryLevel.WARNING), eq("Directory '%s' doesn't exist. No cached events to send."), any()) - verifyNoMoreInteractions(fixture.hub) + verifyNoMoreInteractions(fixture.scopes) } @Test @@ -72,7 +72,7 @@ class EnvelopeSenderTest { testFile.deleteOnExit() sut.processDirectory(testFile) verify(fixture.logger)!!.log(eq(SentryLevel.ERROR), eq("Cache dir %s is not a directory."), any()) - verifyNoMoreInteractions(fixture.hub) + verifyNoMoreInteractions(fixture.scopes) } @Test @@ -82,11 +82,11 @@ class EnvelopeSenderTest { sut.processDirectory(File(tempDirectory.toUri())) testFile.deleteOnExit() verify(fixture.logger)!!.log(eq(SentryLevel.DEBUG), eq("File '%s' doesn't match extension expected."), any()) - verify(fixture.hub, never())!!.captureEnvelope(any(), anyOrNull()) + verify(fixture.scopes, never())!!.captureEnvelope(any(), anyOrNull()) } @Test - fun `when directory has event files, processDirectory captures with hub`() { + fun `when directory has event files, processDirectory captures with scopes`() { val event = SentryEvent() val envelope = SentryEnvelope.from(fixture.serializer!!, event, null) whenever(fixture.serializer!!.deserializeEnvelope(any())).thenReturn(envelope) @@ -94,7 +94,7 @@ class EnvelopeSenderTest { val testFile = File(Files.createTempFile(tempDirectory, "send-cached-event-test", EnvelopeCache.SUFFIX_ENVELOPE_FILE).toUri()) testFile.deleteOnExit() sut.processDirectory(File(tempDirectory.toUri())) - verify(fixture.hub)!!.captureEnvelope(eq(envelope), any()) + verify(fixture.scopes)!!.captureEnvelope(eq(envelope), any()) } @Test @@ -108,12 +108,12 @@ class EnvelopeSenderTest { val hints = HintUtils.createWithTypeCheckHint(mock()) sut.processFile(testFile, hints) verify(fixture.logger)!!.log(eq(SentryLevel.ERROR), eq(expected), eq("Failed to capture cached envelope %s"), eq(testFile.absolutePath)) - verifyNoMoreInteractions(fixture.hub) + verifyNoMoreInteractions(fixture.scopes) assertFalse(testFile.exists()) } @Test - fun `when hub throws, file gets deleted`() { + fun `when scopes throws, file gets deleted`() { val expected = RuntimeException() whenever(fixture.serializer!!.deserializeEnvelope(any())).doThrow(expected) val sut = fixture.getSut() @@ -121,6 +121,6 @@ class EnvelopeSenderTest { testFile.deleteOnExit() sut.processFile(testFile, Hint()) verify(fixture.logger)!!.log(eq(SentryLevel.ERROR), eq(expected), eq("Failed to capture cached envelope %s"), eq(testFile.absolutePath)) - verifyNoMoreInteractions(fixture.hub) + verifyNoMoreInteractions(fixture.scopes) } } diff --git a/sentry/src/test/java/io/sentry/HubAdapterTest.kt b/sentry/src/test/java/io/sentry/HubAdapterTest.kt index 9686250d20..0e7e1d0f77 100644 --- a/sentry/src/test/java/io/sentry/HubAdapterTest.kt +++ b/sentry/src/test/java/io/sentry/HubAdapterTest.kt @@ -13,11 +13,11 @@ import kotlin.test.Test class HubAdapterTest { - val hub: Hub = mock() + val scopes: IScopes = mock() @BeforeTest fun `set up`() { - Sentry.setCurrentHub(hub) + Sentry.setCurrentScopes(scopes) } @AfterTest @@ -27,7 +27,7 @@ class HubAdapterTest { @Test fun `isEnabled calls Hub`() { HubAdapter.getInstance().isEnabled - verify(hub).isEnabled + verify(scopes).isEnabled } @Test fun `captureEvent calls Hub`() { @@ -35,27 +35,27 @@ class HubAdapterTest { val hint = mock() val scopeCallback = mock() HubAdapter.getInstance().captureEvent(event, hint) - verify(hub).captureEvent(eq(event), eq(hint)) + verify(scopes).captureEvent(eq(event), eq(hint)) HubAdapter.getInstance().captureEvent(event, hint, scopeCallback) - verify(hub).captureEvent(eq(event), eq(hint), eq(scopeCallback)) + verify(scopes).captureEvent(eq(event), eq(hint), eq(scopeCallback)) } @Test fun `captureMessage calls Hub`() { val scopeCallback = mock() val sentryLevel = mock() HubAdapter.getInstance().captureMessage("message", sentryLevel) - verify(hub).captureMessage(eq("message"), eq(sentryLevel)) + verify(scopes).captureMessage(eq("message"), eq(sentryLevel)) HubAdapter.getInstance().captureMessage("message", sentryLevel, scopeCallback) - verify(hub).captureMessage(eq("message"), eq(sentryLevel), eq(scopeCallback)) + verify(scopes).captureMessage(eq("message"), eq(sentryLevel), eq(scopeCallback)) } @Test fun `captureEnvelope calls Hub`() { val envelope = mock() val hint = mock() HubAdapter.getInstance().captureEnvelope(envelope, hint) - verify(hub).captureEnvelope(eq(envelope), eq(hint)) + verify(scopes).captureEnvelope(eq(envelope), eq(hint)) } @Test fun `captureException calls Hub`() { @@ -63,145 +63,145 @@ class HubAdapterTest { val hint = mock() val scopeCallback = mock() HubAdapter.getInstance().captureException(throwable, hint) - verify(hub).captureException(eq(throwable), eq(hint)) + verify(scopes).captureException(eq(throwable), eq(hint)) HubAdapter.getInstance().captureException(throwable, hint, scopeCallback) - verify(hub).captureException(eq(throwable), eq(hint), eq(scopeCallback)) + verify(scopes).captureException(eq(throwable), eq(hint), eq(scopeCallback)) } @Test fun `captureUserFeedback calls Hub`() { val userFeedback = mock() HubAdapter.getInstance().captureUserFeedback(userFeedback) - verify(hub).captureUserFeedback(eq(userFeedback)) + verify(scopes).captureUserFeedback(eq(userFeedback)) } @Test fun `captureCheckIn calls Hub`() { val checkIn = mock() HubAdapter.getInstance().captureCheckIn(checkIn) - verify(hub).captureCheckIn(eq(checkIn)) + verify(scopes).captureCheckIn(eq(checkIn)) } @Test fun `startSession calls Hub`() { HubAdapter.getInstance().startSession() - verify(hub).startSession() + verify(scopes).startSession() } @Test fun `endSession calls Hub`() { HubAdapter.getInstance().endSession() - verify(hub).endSession() + verify(scopes).endSession() } @Test fun `close calls Hub`() { HubAdapter.getInstance().close() - verify(hub).close(false) + verify(scopes).close(false) } @Test fun `close with isRestarting true calls Hub with isRestarting false`() { HubAdapter.getInstance().close(true) - verify(hub).close(false) + verify(scopes).close(false) } @Test fun `close with isRestarting false calls Hub with isRestarting false`() { HubAdapter.getInstance().close(false) - verify(hub).close(false) + verify(scopes).close(false) } @Test fun `addBreadcrumb calls Hub`() { val breadcrumb = mock() val hint = mock() HubAdapter.getInstance().addBreadcrumb(breadcrumb, hint) - verify(hub).addBreadcrumb(eq(breadcrumb), eq(hint)) + verify(scopes).addBreadcrumb(eq(breadcrumb), eq(hint)) } @Test fun `setLevel calls Hub`() { val sentryLevel = mock() HubAdapter.getInstance().setLevel(sentryLevel) - verify(hub).setLevel(eq(sentryLevel)) + verify(scopes).setLevel(eq(sentryLevel)) } @Test fun `setTransaction calls Hub`() { HubAdapter.getInstance().setTransaction("transaction") - verify(hub).setTransaction(eq("transaction")) + verify(scopes).setTransaction(eq("transaction")) } @Test fun `setUser calls Hub`() { val user = mock() HubAdapter.getInstance().setUser(user) - verify(hub).setUser(eq(user)) + verify(scopes).setUser(eq(user)) } @Test fun `setFingerprint calls Hub`() { val fingerprint = ArrayList() HubAdapter.getInstance().setFingerprint(fingerprint) - verify(hub).setFingerprint(eq(fingerprint)) + verify(scopes).setFingerprint(eq(fingerprint)) } @Test fun `clearBreadcrumbs calls Hub`() { HubAdapter.getInstance().clearBreadcrumbs() - verify(hub).clearBreadcrumbs() + verify(scopes).clearBreadcrumbs() } @Test fun `setTag calls Hub`() { HubAdapter.getInstance().setTag("key", "value") - verify(hub).setTag(eq("key"), eq("value")) + verify(scopes).setTag(eq("key"), eq("value")) } @Test fun `removeTag calls Hub`() { HubAdapter.getInstance().removeTag("key") - verify(hub).removeTag(eq("key")) + verify(scopes).removeTag(eq("key")) } @Test fun `setExtra calls Hub`() { HubAdapter.getInstance().setExtra("key", "value") - verify(hub).setExtra(eq("key"), eq("value")) + verify(scopes).setExtra(eq("key"), eq("value")) } @Test fun `removeExtra calls Hub`() { HubAdapter.getInstance().removeExtra("key") - verify(hub).removeExtra(eq("key")) + verify(scopes).removeExtra(eq("key")) } @Test fun `getLastEventId calls Hub`() { HubAdapter.getInstance().lastEventId - verify(hub).lastEventId + verify(scopes).lastEventId } @Test fun `pushScope calls Hub`() { HubAdapter.getInstance().pushScope() - verify(hub).pushScope() + verify(scopes).pushScope() } @Test fun `popScope calls Hub`() { HubAdapter.getInstance().popScope() - verify(hub).popScope() + verify(scopes).popScope() } @Test fun `withScope calls Hub`() { val scopeCallback = mock() HubAdapter.getInstance().withScope(scopeCallback) - verify(hub).withScope(eq(scopeCallback)) + verify(scopes).withScope(eq(scopeCallback)) } @Test fun `configureScope calls Hub`() { val scopeCallback = mock() HubAdapter.getInstance().configureScope(scopeCallback) - verify(hub).configureScope(eq(scopeCallback)) + verify(scopes).configureScope(eq(scopeCallback)) } @Test fun `bindClient calls Hub`() { val client = mock() HubAdapter.getInstance().bindClient(client) - verify(hub).bindClient(eq(client)) + verify(scopes).bindClient(eq(client)) } @Test fun `flush calls Hub`() { HubAdapter.getInstance().flush(1) - verify(hub).flush(eq(1)) + verify(scopes).flush(eq(1)) } @Test fun `clone calls Hub`() { HubAdapter.getInstance().clone() - verify(hub).clone() + verify(scopes).clone() } @Test fun `captureTransaction calls Hub`() { @@ -210,7 +210,7 @@ class HubAdapterTest { val hint = mock() val profilingTraceData = mock() HubAdapter.getInstance().captureTransaction(transaction, traceContext, hint, profilingTraceData) - verify(hub).captureTransaction(eq(transaction), eq(traceContext), eq(hint), eq(profilingTraceData)) + verify(scopes).captureTransaction(eq(transaction), eq(traceContext), eq(hint), eq(profilingTraceData)) } @Test fun `startTransaction calls Hub`() { @@ -218,48 +218,48 @@ class HubAdapterTest { val samplingContext = mock() val transactionOptions = mock() HubAdapter.getInstance().startTransaction(transactionContext) - verify(hub).startTransaction(eq(transactionContext), any()) + verify(scopes).startTransaction(eq(transactionContext), any()) - reset(hub) + reset(scopes) HubAdapter.getInstance().startTransaction(transactionContext, transactionOptions) - verify(hub).startTransaction(eq(transactionContext), eq(transactionOptions)) + verify(scopes).startTransaction(eq(transactionContext), eq(transactionOptions)) } @Test fun `traceHeaders calls Hub`() { HubAdapter.getInstance().traceHeaders() - verify(hub).traceHeaders() + verify(scopes).traceHeaders() } @Test fun `setSpanContext calls Hub`() { val throwable = mock() val span = mock() HubAdapter.getInstance().setSpanContext(throwable, span, "transactionName") - verify(hub).setSpanContext(eq(throwable), eq(span), eq("transactionName")) + verify(scopes).setSpanContext(eq(throwable), eq(span), eq("transactionName")) } @Test fun `getSpan calls Hub`() { HubAdapter.getInstance().span - verify(hub).span + verify(scopes).span } @Test fun `getTransaction calls Hub`() { HubAdapter.getInstance().transaction - verify(hub).transaction + verify(scopes).transaction } @Test fun `getOptions calls Hub`() { HubAdapter.getInstance().options - verify(hub).options + verify(scopes).options } @Test fun `isCrashedLastRun calls Hub`() { HubAdapter.getInstance().isCrashedLastRun - verify(hub).isCrashedLastRun + verify(scopes).isCrashedLastRun } @Test fun `reportFullyDisplayed calls Hub`() { HubAdapter.getInstance().reportFullyDisplayed() - verify(hub).reportFullyDisplayed() + verify(scopes).reportFullyDisplayed() } } diff --git a/sentry/src/test/java/io/sentry/HubTest.kt b/sentry/src/test/java/io/sentry/HubTest.kt index 8fac963e70..f30fd0a966 100644 --- a/sentry/src/test/java/io/sentry/HubTest.kt +++ b/sentry/src/test/java/io/sentry/HubTest.kt @@ -72,7 +72,7 @@ class HubTest { } @Test - fun `when hub is cloned, integrations are not registered`() { + fun `when scopes is cloned, integrations are not registered`() { val integrationMock = mock() val options = SentryOptions() options.cacheDirPath = file.absolutePath @@ -80,36 +80,36 @@ class HubTest { options.setSerializer(mock()) options.addIntegration(integrationMock) // val expected = HubAdapter.getInstance() - val hub = Hub(options) + val scopes = Hub(options) // verify(integrationMock).register(expected, options) - hub.clone() + scopes.clone() verifyNoMoreInteractions(integrationMock) } @Test - fun `when hub is cloned, scope changes are isolated`() { + fun `when scopes is cloned, scope changes are isolated`() { val options = SentryOptions() options.cacheDirPath = file.absolutePath options.dsn = "https://key@sentry.io/proj" options.setSerializer(mock()) - val hub = Hub(options) + val scopes = Hub(options) var firstScope: IScope? = null - hub.configureScope { + scopes.configureScope { firstScope = it - it.setTag("hub", "a") + it.setTag("scopes", "a") } var cloneScope: IScope? = null - val clone = hub.clone() + val clone = scopes.clone() clone.configureScope { cloneScope = it - it.setTag("hub", "b") + it.setTag("scopes", "b") } - assertEquals("a", firstScope!!.tags["hub"]) - assertEquals("b", cloneScope!!.tags["hub"]) + assertEquals("a", firstScope!!.tags["scopes"]) + assertEquals("b", cloneScope!!.tags["scopes"]) } @Test - fun `when hub is initialized, breadcrumbs are capped as per options`() { + fun `when scopes is initialized, breadcrumbs are capped as per options`() { val options = SentryOptions() options.cacheDirPath = file.absolutePath options.maxBreadcrumbs = 5 @@ -288,7 +288,7 @@ class HubTest { } @Test - fun `when captureEvent is called on disabled hub, lastEventId does not get overwritten`() { + fun `when captureEvent is called on disabled scopes, lastEventId does not get overwritten`() { val (sut, mockClient) = getEnabledHub() whenever(mockClient.captureEvent(any(), any(), anyOrNull())).thenReturn(SentryId(UUID.randomUUID())) val event = SentryEvent() @@ -827,14 +827,14 @@ class HubTest { @Test fun `when withScope throws an exception then it should be caught`() { - val (hub, _, logger) = getEnabledHub() + val (scopes, _, logger) = getEnabledHub() val exception = Exception("scope callback exception") val scopeCallback = ScopeCallback { throw exception } - hub.withScope(scopeCallback) + scopes.withScope(scopeCallback) verify(logger).log(eq(SentryLevel.ERROR), any(), eq(exception)) } @@ -864,25 +864,25 @@ class HubTest { @Test fun `when configureScope throws an exception then it should be caught`() { - val (hub, _, logger) = getEnabledHub() + val (scopes, _, logger) = getEnabledHub() val exception = Exception("scope callback exception") val scopeCallback = ScopeCallback { throw exception } - hub.configureScope(scopeCallback) + scopes.configureScope(scopeCallback) verify(logger).log(eq(SentryLevel.ERROR), any(), eq(exception)) } //endregion @Test - fun `when integration is registered, hub is enabled`() { + fun `when integration is registered, scopes is enabled`() { val mock = mock() var options: SentryOptions? = null - // init main hub and make it enabled + // init main scopes and make it enabled Sentry.init { it.addIntegration(mock) it.dsn = "https://key@sentry.io/proj" @@ -892,8 +892,8 @@ class HubTest { } doAnswer { - val hub = it.arguments[0] as IHub - assertTrue(hub.isEnabled) + val scopes = it.arguments[0] as IScopes + assertTrue(scopes.isEnabled) }.whenever(mock).register(any(), eq(options!!)) verify(mock).register(any(), eq(options!!)) @@ -902,26 +902,26 @@ class HubTest { //region setLevel tests @Test fun `when setLevel is called on disabled client, do nothing`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } - hub.close() + scopes.close() - hub.setLevel(SentryLevel.INFO) + scopes.setLevel(SentryLevel.INFO) assertNull(scope?.level) } @Test fun `when setLevel is called, level is set`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } - hub.setLevel(SentryLevel.INFO) + scopes.setLevel(SentryLevel.INFO) assertEquals(SentryLevel.INFO, scope?.level) } //endregion @@ -929,74 +929,74 @@ class HubTest { //region setTransaction tests @Test fun `when setTransaction is called on disabled client, do nothing`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } - hub.close() + scopes.close() - hub.setTransaction("test") + scopes.setTransaction("test") assertNull(scope?.transactionName) } @Test fun `when setTransaction is called, and transaction is not set, transaction name is changed`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } - hub.setTransaction("test") + scopes.setTransaction("test") assertEquals("test", scope?.transactionName) } @Test fun `when setTransaction is called, and transaction is set, transaction name is changed`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } - val tx = hub.startTransaction("test", "op") - hub.configureScope { it.setTransaction(tx) } + val tx = scopes.startTransaction("test", "op") + scopes.configureScope { it.setTransaction(tx) } assertEquals("test", scope?.transactionName) } @Test fun `when startTransaction is called with different instrumenter, no-op is returned`() { - val hub = generateHub() + val scopes = generateHub() val transactionContext = TransactionContext("test", "op").also { it.instrumenter = Instrumenter.OTEL } val transactionOptions = TransactionOptions() - val tx = hub.startTransaction(transactionContext, transactionOptions) + val tx = scopes.startTransaction(transactionContext, transactionOptions) assertTrue(tx is NoOpTransaction) } @Test fun `when startTransaction is called with different instrumenter, no-op is returned 2`() { - val hub = generateHub() { + val scopes = generateHub() { it.instrumenter = Instrumenter.OTEL } - val tx = hub.startTransaction("test", "op") + val tx = scopes.startTransaction("test", "op") assertTrue(tx is NoOpTransaction) } @Test fun `when startTransaction is called with configured instrumenter, it works`() { - val hub = generateHub() { + val scopes = generateHub() { it.instrumenter = Instrumenter.OTEL } val transactionContext = TransactionContext("test", "op").also { it.instrumenter = Instrumenter.OTEL } val transactionOptions = TransactionOptions() - val tx = hub.startTransaction(transactionContext, transactionOptions) + val tx = scopes.startTransaction(transactionContext, transactionOptions) assertFalse(tx is NoOpTransaction) } @@ -1005,27 +1005,27 @@ class HubTest { //region setUser tests @Test fun `when setUser is called on disabled client, do nothing`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } - hub.close() + scopes.close() - hub.setUser(User()) + scopes.setUser(User()) assertNull(scope?.user) } @Test fun `when setUser is called, user is set`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } val user = User() - hub.setUser(user) + scopes.setUser(user) assertEquals(user, scope?.user) } //endregion @@ -1033,40 +1033,40 @@ class HubTest { //region setFingerprint tests @Test fun `when setFingerprint is called on disabled client, do nothing`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } - hub.close() + scopes.close() val fingerprint = listOf("abc") - hub.setFingerprint(fingerprint) + scopes.setFingerprint(fingerprint) assertEquals(0, scope?.fingerprint?.count()) } @Test fun `when setFingerprint is called with null parameter, do nothing`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } - hub.callMethod("setFingerprint", List::class.java, null) + scopes.callMethod("setFingerprint", List::class.java, null) assertEquals(0, scope?.fingerprint?.count()) } @Test fun `when setFingerprint is called, fingerprint is set`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } val fingerprint = listOf("abc") - hub.setFingerprint(fingerprint) + scopes.setFingerprint(fingerprint) assertEquals(1, scope?.fingerprint?.count()) } //endregion @@ -1074,30 +1074,30 @@ class HubTest { //region clearBreadcrumbs tests @Test fun `when clearBreadcrumbs is called on disabled client, do nothing`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } - hub.addBreadcrumb(Breadcrumb()) + scopes.addBreadcrumb(Breadcrumb()) assertEquals(1, scope?.breadcrumbs?.count()) - hub.close() + scopes.close() assertEquals(0, scope?.breadcrumbs?.count()) } @Test fun `when clearBreadcrumbs is called, clear breadcrumbs`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } - hub.addBreadcrumb(Breadcrumb()) + scopes.addBreadcrumb(Breadcrumb()) assertEquals(1, scope?.breadcrumbs?.count()) - hub.clearBreadcrumbs() + scopes.clearBreadcrumbs() assertEquals(0, scope?.breadcrumbs?.count()) } //endregion @@ -1105,38 +1105,38 @@ class HubTest { //region setTag tests @Test fun `when setTag is called on disabled client, do nothing`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } - hub.close() + scopes.close() - hub.setTag("test", "test") + scopes.setTag("test", "test") assertEquals(0, scope?.tags?.count()) } @Test fun `when setTag is called with null parameters, do nothing`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } - hub.callMethod("setTag", parameterTypes = arrayOf(String::class.java, String::class.java), null, null) + scopes.callMethod("setTag", parameterTypes = arrayOf(String::class.java, String::class.java), null, null) assertEquals(0, scope?.tags?.count()) } @Test fun `when setTag is called, tag is set`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } - hub.setTag("test", "test") + scopes.setTag("test", "test") assertEquals(1, scope?.tags?.count()) } //endregion @@ -1144,38 +1144,38 @@ class HubTest { //region setExtra tests @Test fun `when setExtra is called on disabled client, do nothing`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } - hub.close() + scopes.close() - hub.setExtra("test", "test") + scopes.setExtra("test", "test") assertEquals(0, scope?.extras?.count()) } @Test fun `when setExtra is called with null parameters, do nothing`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } - hub.callMethod("setExtra", parameterTypes = arrayOf(String::class.java, String::class.java), null, null) + scopes.callMethod("setExtra", parameterTypes = arrayOf(String::class.java, String::class.java), null, null) assertEquals(0, scope?.extras?.count()) } @Test fun `when setExtra is called, extra is set`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } - hub.setExtra("test", "test") + scopes.setExtra("test", "test") assertEquals(1, scope?.extras?.count()) } //endregion @@ -1488,19 +1488,19 @@ class HubTest { val mockTransactionProfiler = mock() val mockClient = mock() whenever(mockTransactionProfiler.onTransactionFinish(any(), anyOrNull(), anyOrNull())).thenAnswer { mockClient.captureEnvelope(mock()) } - val hub = generateHub { + val scopes = generateHub { it.setTransactionProfiler(mockTransactionProfiler) } - hub.bindClient(mockClient) + scopes.bindClient(mockClient) // Transaction is not sampled, so it should not be profiled val contexts = TransactionContext("name", "op", TracesSamplingDecision(false, null, true, null)) - val transaction = hub.startTransaction(contexts) + val transaction = scopes.startTransaction(contexts) transaction.finish() verify(mockClient, never()).captureEnvelope(any()) // Transaction is sampled, so it should be profiled val sampledContexts = TransactionContext("name", "op", TracesSamplingDecision(true, null, true, null)) - val sampledTransaction = hub.startTransaction(sampledContexts) + val sampledTransaction = scopes.startTransaction(sampledContexts) sampledTransaction.finish() verify(mockClient).captureEnvelope(any()) } @@ -1510,13 +1510,13 @@ class HubTest { val mockTransactionProfiler = mock() val mockClient = mock() whenever(mockTransactionProfiler.onTransactionFinish(any(), anyOrNull(), anyOrNull())).thenAnswer { mockClient.captureEnvelope(mock()) } - val hub = generateHub { + val scopes = generateHub { it.profilesSampleRate = 0.0 it.setTransactionProfiler(mockTransactionProfiler) } - hub.bindClient(mockClient) + scopes.bindClient(mockClient) val contexts = TransactionContext("name", "op") - val transaction = hub.startTransaction(contexts) + val transaction = scopes.startTransaction(contexts) transaction.finish() verify(mockClient, never()).captureEnvelope(any()) } @@ -1525,12 +1525,12 @@ class HubTest { fun `when profiler is running and isAppStartTransaction is false, startTransaction does not interact with profiler`() { val mockTransactionProfiler = mock() whenever(mockTransactionProfiler.isRunning).thenReturn(true) - val hub = generateHub { + val scopes = generateHub { it.profilesSampleRate = 1.0 it.setTransactionProfiler(mockTransactionProfiler) } val context = TransactionContext("name", "op") - hub.startTransaction(context, TransactionOptions().apply { isAppStartTransaction = false }) + scopes.startTransaction(context, TransactionOptions().apply { isAppStartTransaction = false }) verify(mockTransactionProfiler, never()).start() verify(mockTransactionProfiler, never()).bindTransaction(any()) } @@ -1539,12 +1539,12 @@ class HubTest { fun `when profiler is running and isAppStartTransaction is true, startTransaction binds current profile`() { val mockTransactionProfiler = mock() whenever(mockTransactionProfiler.isRunning).thenReturn(true) - val hub = generateHub { + val scopes = generateHub { it.profilesSampleRate = 1.0 it.setTransactionProfiler(mockTransactionProfiler) } val context = TransactionContext("name", "op") - val transaction = hub.startTransaction(context, TransactionOptions().apply { isAppStartTransaction = true }) + val transaction = scopes.startTransaction(context, TransactionOptions().apply { isAppStartTransaction = true }) verify(mockTransactionProfiler, never()).start() verify(mockTransactionProfiler).bindTransaction(eq(transaction)) } @@ -1553,12 +1553,12 @@ class HubTest { fun `when profiler is not running, startTransaction starts and binds current profile`() { val mockTransactionProfiler = mock() whenever(mockTransactionProfiler.isRunning).thenReturn(false) - val hub = generateHub { + val scopes = generateHub { it.profilesSampleRate = 1.0 it.setTransactionProfiler(mockTransactionProfiler) } val context = TransactionContext("name", "op") - val transaction = hub.startTransaction(context, TransactionOptions().apply { isAppStartTransaction = false }) + val transaction = scopes.startTransaction(context, TransactionOptions().apply { isAppStartTransaction = false }) verify(mockTransactionProfiler).start() verify(mockTransactionProfiler).bindTransaction(eq(transaction)) } @@ -1567,75 +1567,75 @@ class HubTest { //region startTransaction tests @Test fun `when startTransaction, creates transaction`() { - val hub = generateHub() + val scopes = generateHub() val contexts = TransactionContext("name", "op") - val transaction = hub.startTransaction(contexts) + val transaction = scopes.startTransaction(contexts) assertTrue(transaction is SentryTracer) assertEquals(contexts, transaction.root.spanContext) } @Test fun `when startTransaction with bindToScope set to false, transaction is not attached to the scope`() { - val hub = generateHub() + val scopes = generateHub() - hub.startTransaction("name", "op", TransactionOptions()) + scopes.startTransaction("name", "op", TransactionOptions()) - hub.configureScope { + scopes.configureScope { assertNull(it.span) } } @Test fun `when startTransaction without bindToScope set, transaction is not attached to the scope`() { - val hub = generateHub() + val scopes = generateHub() - hub.startTransaction("name", "op") + scopes.startTransaction("name", "op") - hub.configureScope { + scopes.configureScope { assertNull(it.span) } } @Test fun `when startTransaction with bindToScope set to true, transaction is attached to the scope`() { - val hub = generateHub() + val scopes = generateHub() - val transaction = hub.startTransaction("name", "op", TransactionOptions().also { it.isBindToScope = true }) + val transaction = scopes.startTransaction("name", "op", TransactionOptions().also { it.isBindToScope = true }) - hub.configureScope { + scopes.configureScope { assertEquals(transaction, it.span) } } @Test fun `when startTransaction and no tracing sampling is configured, event is not sampled`() { - val hub = generateHub { + val scopes = generateHub { it.tracesSampleRate = 0.0 } - val transaction = hub.startTransaction("name", "op") + val transaction = scopes.startTransaction("name", "op") assertFalse(transaction.isSampled!!) } @Test fun `when startTransaction and no profile sampling is configured, profile is not sampled`() { - val hub = generateHub { + val scopes = generateHub { it.tracesSampleRate = 1.0 it.profilesSampleRate = 0.0 } - val transaction = hub.startTransaction("name", "op") + val transaction = scopes.startTransaction("name", "op") assertTrue(transaction.isSampled!!) assertFalse(transaction.isProfileSampled!!) } @Test fun `when startTransaction with parent sampled and no traces sampler provided, transaction inherits sampling decision`() { - val hub = generateHub() + val scopes = generateHub() val transactionContext = TransactionContext("name", "op") transactionContext.parentSampled = true - val transaction = hub.startTransaction(transactionContext) + val transaction = scopes.startTransaction(transactionContext) assertNotNull(transaction) assertNotNull(transaction.isSampled) assertTrue(transaction.isSampled!!) @@ -1643,10 +1643,10 @@ class HubTest { @Test fun `when startTransaction with parent profile sampled and no profile sampler provided, transaction inherits profile sampling decision`() { - val hub = generateHub() + val scopes = generateHub() val transactionContext = TransactionContext("name", "op") transactionContext.setParentSampled(true, true) - val transaction = hub.startTransaction(transactionContext) + val transaction = scopes.startTransaction(transactionContext) assertTrue(transaction.isProfileSampled!!) } @@ -1717,11 +1717,11 @@ class HubTest { @Test fun `when tracesSampleRate and tracesSampler are not set on SentryOptions, startTransaction returns NoOp`() { - val hub = generateHub { + val scopes = generateHub { it.tracesSampleRate = null it.tracesSampler = null } - val transaction = hub.startTransaction(TransactionContext("name", "op", TracesSamplingDecision(true))) + val transaction = scopes.startTransaction(TransactionContext("name", "op", TracesSamplingDecision(true))) assertTrue(transaction is NoOpTransaction) } //endregion @@ -1729,81 +1729,81 @@ class HubTest { //region startTransaction tests @Test fun `when traceHeaders and no transaction is active, traceHeaders are generated from scope`() { - val hub = generateHub() + val scopes = generateHub() var spanId: SpanId? = null - hub.configureScope { spanId = it.propagationContext.spanId } + scopes.configureScope { spanId = it.propagationContext.spanId } - val traceHeader = hub.traceHeaders() + val traceHeader = scopes.traceHeaders() assertNotNull(traceHeader) assertEquals(spanId, traceHeader.spanId) } @Test fun `when traceHeaders and there is an active transaction, traceHeaders are not null`() { - val hub = generateHub() - val tx = hub.startTransaction("aTransaction", "op") - hub.configureScope { it.setTransaction(tx) } + val scopes = generateHub() + val tx = scopes.startTransaction("aTransaction", "op") + scopes.configureScope { it.setTransaction(tx) } - assertNotNull(hub.traceHeaders()) + assertNotNull(scopes.traceHeaders()) } //endregion //region getSpan tests @Test fun `when there is no active transaction, getSpan returns null`() { - val hub = generateHub() - assertNull(hub.span) + val scopes = generateHub() + assertNull(scopes.span) } @Test fun `when there is no active transaction, getTransaction returns null`() { - val hub = generateHub() - assertNull(hub.transaction) + val scopes = generateHub() + assertNull(scopes.transaction) } @Test fun `when there is active transaction bound to the scope, getTransaction and getSpan return active transaction`() { - val hub = generateHub() - val tx = hub.startTransaction("aTransaction", "op") - hub.configureScope { it.transaction = tx } + val scopes = generateHub() + val tx = scopes.startTransaction("aTransaction", "op") + scopes.configureScope { it.transaction = tx } - assertEquals(tx, hub.transaction) - assertEquals(tx, hub.span) + assertEquals(tx, scopes.transaction) + assertEquals(tx, scopes.span) } @Test - fun `when there is a transaction but the hub is closed, getTransaction returns null`() { - val hub = generateHub() - hub.startTransaction("name", "op") - hub.close() + fun `when there is a transaction but the scopes is closed, getTransaction returns null`() { + val scopes = generateHub() + scopes.startTransaction("name", "op") + scopes.close() - assertNull(hub.transaction) + assertNull(scopes.transaction) } @Test fun `when there is active span within a transaction bound to the scope, getSpan returns active span`() { - val hub = generateHub() - val tx = hub.startTransaction("aTransaction", "op") - hub.configureScope { it.setTransaction(tx) } - hub.configureScope { it.setTransaction(tx) } + val scopes = generateHub() + val tx = scopes.startTransaction("aTransaction", "op") + scopes.configureScope { it.setTransaction(tx) } + scopes.configureScope { it.setTransaction(tx) } val span = tx.startChild("op") - assertEquals(tx, hub.transaction) - assertEquals(span, hub.span) + assertEquals(tx, scopes.transaction) + assertEquals(span, scopes.span) } // endregion //region setSpanContext @Test fun `associates span context with throwable`() { - val (hub, mockClient) = getEnabledHub() - val transaction = hub.startTransaction("aTransaction", "op") + val (scopes, mockClient) = getEnabledHub() + val transaction = scopes.startTransaction("aTransaction", "op") val span = transaction.startChild("op") val exception = RuntimeException() - hub.setSpanContext(exception, span, "tx-name") - hub.captureEvent(SentryEvent(exception)) + scopes.setSpanContext(exception, span, "tx-name") + scopes.captureEvent(SentryEvent(exception)) verify(mockClient).captureEvent( check { @@ -1816,8 +1816,8 @@ class HubTest { @Test fun `returns null when no span context associated with throwable`() { - val hub = generateHub() as Hub - assertNull(hub.getSpanContext(RuntimeException())) + val scopes = generateHub() as Hub + assertNull(scopes.getSpanContext(RuntimeException())) } // endregion @@ -1826,9 +1826,9 @@ class HubTest { val nativeMarker = File(hashedFolder(), EnvelopeCache.NATIVE_CRASH_MARKER_FILE) nativeMarker.mkdirs() nativeMarker.createNewFile() - val hub = generateHub() as Hub + val scopes = generateHub() as Hub - assertTrue(hub.isCrashedLastRun!!) + assertTrue(scopes.isCrashedLastRun!!) assertTrue(nativeMarker.exists()) } @@ -1837,69 +1837,69 @@ class HubTest { val nativeMarker = File(hashedFolder(), EnvelopeCache.NATIVE_CRASH_MARKER_FILE) nativeMarker.mkdirs() nativeMarker.createNewFile() - val hub = generateHub { + val scopes = generateHub { it.isEnableAutoSessionTracking = false } - assertTrue(hub.isCrashedLastRun!!) + assertTrue(scopes.isCrashedLastRun!!) assertFalse(nativeMarker.exists()) } @Test fun `reportFullyDisplayed is ignored if TimeToFullDisplayTracing is disabled`() { var called = false - val hub = generateHub { + val scopes = generateHub { it.fullyDisplayedReporter.registerFullyDrawnListener { called = !called } } - hub.reportFullyDisplayed() + scopes.reportFullyDisplayed() assertFalse(called) } @Test fun `reportFullyDisplayed calls FullyDisplayedReporter if TimeToFullDisplayTracing is enabled`() { var called = false - val hub = generateHub { + val scopes = generateHub { it.isEnableTimeToFullDisplayTracing = true it.fullyDisplayedReporter.registerFullyDrawnListener { called = !called } } - hub.reportFullyDisplayed() + scopes.reportFullyDisplayed() assertTrue(called) } @Test fun `reportFullyDisplayed calls FullyDisplayedReporter only once`() { var called = false - val hub = generateHub { + val scopes = generateHub { it.isEnableTimeToFullDisplayTracing = true it.fullyDisplayedReporter.registerFullyDrawnListener { called = !called } } - hub.reportFullyDisplayed() + scopes.reportFullyDisplayed() assertTrue(called) - hub.reportFullyDisplayed() + scopes.reportFullyDisplayed() assertTrue(called) } @Test fun `reportFullDisplayed calls reportFullyDisplayed`() { - val hub = spy(generateHub()) - hub.reportFullDisplayed() - verify(hub).reportFullyDisplayed() + val scopes = spy(generateHub()) + scopes.reportFullDisplayed() + verify(scopes).reportFullyDisplayed() } @Test fun `continueTrace creates propagation context from headers and returns transaction context if performance enabled`() { - val hub = generateHub() + val scopes = generateHub() val traceId = SentryId() val parentSpanId = SpanId() - val transactionContext = hub.continueTrace("$traceId-$parentSpanId-1", listOf("sentry-public_key=502f25099c204a2fbf4cb16edc5975d1,sentry-sample_rate=1,sentry-trace_id=$traceId,sentry-transaction=HTTP%20GET")) + val transactionContext = scopes.continueTrace("$traceId-$parentSpanId-1", listOf("sentry-public_key=502f25099c204a2fbf4cb16edc5975d1,sentry-sample_rate=1,sentry-trace_id=$traceId,sentry-transaction=HTTP%20GET")) - hub.configureScope { scope -> + scopes.configureScope { scope -> assertEquals(traceId, scope.propagationContext.traceId) assertEquals(parentSpanId, scope.propagationContext.parentSpanId) } @@ -1910,16 +1910,16 @@ class HubTest { @Test fun `continueTrace creates new propagation context if header invalid and returns transaction context if performance enabled`() { - val hub = generateHub() + val scopes = generateHub() val traceId = SentryId() var propagationContextHolder = AtomicReference() - hub.configureScope { propagationContextHolder.set(it.propagationContext) } + scopes.configureScope { propagationContextHolder.set(it.propagationContext) } val propagationContextAtStart = propagationContextHolder.get()!! - val transactionContext = hub.continueTrace("invalid", listOf("sentry-public_key=502f25099c204a2fbf4cb16edc5975d1,sentry-sample_rate=1,sentry-trace_id=$traceId,sentry-transaction=HTTP%20GET")) + val transactionContext = scopes.continueTrace("invalid", listOf("sentry-public_key=502f25099c204a2fbf4cb16edc5975d1,sentry-sample_rate=1,sentry-trace_id=$traceId,sentry-transaction=HTTP%20GET")) - hub.configureScope { scope -> + scopes.configureScope { scope -> assertNotEquals(propagationContextAtStart.traceId, scope.propagationContext.traceId) assertNotEquals(propagationContextAtStart.parentSpanId, scope.propagationContext.parentSpanId) assertNotEquals(propagationContextAtStart.spanId, scope.propagationContext.spanId) @@ -1932,12 +1932,12 @@ class HubTest { @Test fun `continueTrace creates propagation context from headers and returns null if performance disabled`() { - val hub = generateHub { it.enableTracing = false } + val scopes = generateHub { it.enableTracing = false } val traceId = SentryId() val parentSpanId = SpanId() - val transactionContext = hub.continueTrace("$traceId-$parentSpanId-1", listOf("sentry-public_key=502f25099c204a2fbf4cb16edc5975d1,sentry-sample_rate=1,sentry-trace_id=$traceId,sentry-transaction=HTTP%20GET")) + val transactionContext = scopes.continueTrace("$traceId-$parentSpanId-1", listOf("sentry-public_key=502f25099c204a2fbf4cb16edc5975d1,sentry-sample_rate=1,sentry-trace_id=$traceId,sentry-transaction=HTTP%20GET")) - hub.configureScope { scope -> + scopes.configureScope { scope -> assertEquals(traceId, scope.propagationContext.traceId) assertEquals(parentSpanId, scope.propagationContext.parentSpanId) } @@ -1947,16 +1947,16 @@ class HubTest { @Test fun `continueTrace creates new propagation context if header invalid and returns null if performance disabled`() { - val hub = generateHub { it.enableTracing = false } + val scopes = generateHub { it.enableTracing = false } val traceId = SentryId() var propagationContextHolder = AtomicReference() - hub.configureScope { propagationContextHolder.set(it.propagationContext) } + scopes.configureScope { propagationContextHolder.set(it.propagationContext) } val propagationContextAtStart = propagationContextHolder.get()!! - val transactionContext = hub.continueTrace("invalid", listOf("sentry-public_key=502f25099c204a2fbf4cb16edc5975d1,sentry-sample_rate=1,sentry-trace_id=$traceId,sentry-transaction=HTTP%20GET")) + val transactionContext = scopes.continueTrace("invalid", listOf("sentry-public_key=502f25099c204a2fbf4cb16edc5975d1,sentry-sample_rate=1,sentry-trace_id=$traceId,sentry-transaction=HTTP%20GET")) - hub.configureScope { scope -> + scopes.configureScope { scope -> assertNotEquals(propagationContextAtStart.traceId, scope.propagationContext.traceId) assertNotEquals(propagationContextAtStart.parentSpanId, scope.propagationContext.parentSpanId) assertNotEquals(propagationContextAtStart.spanId, scope.propagationContext.spanId) @@ -1966,32 +1966,32 @@ class HubTest { } @Test - fun `hub provides no tags for metrics, if metric option is disabled`() { - val hub = generateHub { + fun `scopes provides no tags for metrics, if metric option is disabled`() { + val scopes = generateHub { it.isEnableMetrics = false it.isEnableDefaultTagsForMetrics = true } as Hub assertTrue( - hub.defaultTagsForMetrics.isEmpty() + scopes.defaultTagsForMetrics.isEmpty() ) } @Test - fun `hub provides no tags for metrics, if default tags option is disabled`() { - val hub = generateHub { + fun `scopes provides no tags for metrics, if default tags option is disabled`() { + val scopes = generateHub { it.isEnableMetrics = true it.isEnableDefaultTagsForMetrics = false } as Hub assertTrue( - hub.defaultTagsForMetrics.isEmpty() + scopes.defaultTagsForMetrics.isEmpty() ) } @Test - fun `hub provides minimum default tags for metrics, if nothing is set up`() { - val hub = generateHub { + fun `scopes provides minimum default tags for metrics, if nothing is set up`() { + val scopes = generateHub { it.isEnableMetrics = true it.isEnableDefaultTagsForMetrics = true } as Hub @@ -2000,19 +2000,19 @@ class HubTest { mapOf( "environment" to "production" ), - hub.defaultTagsForMetrics + scopes.defaultTagsForMetrics ) } @Test - fun `hub provides default tags for metrics, based on options and running transaction`() { - val hub = generateHub { + fun `scopes provides default tags for metrics, based on options and running transaction`() { + val scopes = generateHub { it.isEnableMetrics = true it.isEnableDefaultTagsForMetrics = true it.environment = "test" it.release = "1.0" } as Hub - hub.startTransaction( + scopes.startTransaction( "name", "op", TransactionOptions().apply { isBindToScope = true } @@ -2024,72 +2024,72 @@ class HubTest { "release" to "1.0", "transaction" to "name" ), - hub.defaultTagsForMetrics + scopes.defaultTagsForMetrics ) } @Test - fun `hub provides no local metric aggregator if metrics feature is disabled`() { - val hub = generateHub { + fun `scopes provides no local metric aggregator if metrics feature is disabled`() { + val scopes = generateHub { it.isEnableMetrics = false it.isEnableSpanLocalMetricAggregation = true } as Hub - hub.startTransaction( + scopes.startTransaction( "name", "op", TransactionOptions().apply { isBindToScope = true } ) - assertNull(hub.localMetricsAggregator) + assertNull(scopes.localMetricsAggregator) } @Test - fun `hub provides no local metric aggregator if local aggregation feature is disabled`() { - val hub = generateHub { + fun `scopes provides no local metric aggregator if local aggregation feature is disabled`() { + val scopes = generateHub { it.isEnableMetrics = true it.isEnableSpanLocalMetricAggregation = false } as Hub - hub.startTransaction( + scopes.startTransaction( "name", "op", TransactionOptions().apply { isBindToScope = true } ) - assertNull(hub.localMetricsAggregator) + assertNull(scopes.localMetricsAggregator) } @Test - fun `hub provides local metric aggregator if feature is enabled`() { - val hub = generateHub { + fun `scopes provides local metric aggregator if feature is enabled`() { + val scopes = generateHub { it.isEnableMetrics = true it.isEnableSpanLocalMetricAggregation = true } as Hub - hub.startTransaction( + scopes.startTransaction( "name", "op", TransactionOptions().apply { isBindToScope = true } ) - assertNotNull(hub.localMetricsAggregator) + assertNotNull(scopes.localMetricsAggregator) } @Test - fun `hub startSpanForMetric starts a child span`() { - val hub = generateHub { + fun `scopes startSpanForMetric starts a child span`() { + val scopes = generateHub { it.isEnableMetrics = true it.isEnableSpanLocalMetricAggregation = true it.sampleRate = 1.0 } as Hub - val txn = hub.startTransaction( + val txn = scopes.startTransaction( "name.txn", "op.txn", TransactionOptions().apply { isBindToScope = true } ) - val span = hub.startSpanForMetric("op", "key")!! + val span = scopes.startSpanForMetric("op", "key")!! assertEquals("op", span.spanContext.op) assertEquals("key", span.spanContext.description) @@ -2098,7 +2098,7 @@ class HubTest { private val dsnTest = "https://key@sentry.io/proj" - private fun generateHub(optionsConfiguration: Sentry.OptionsConfiguration? = null): IHub { + private fun generateHub(optionsConfiguration: Sentry.OptionsConfiguration? = null): IScopes { val options = SentryOptions().apply { dsn = dsnTest cacheDirPath = file.absolutePath diff --git a/sentry/src/test/java/io/sentry/JsonSerializerTest.kt b/sentry/src/test/java/io/sentry/JsonSerializerTest.kt index 8dc4f804bc..bd3a3c2cff 100644 --- a/sentry/src/test/java/io/sentry/JsonSerializerTest.kt +++ b/sentry/src/test/java/io/sentry/JsonSerializerTest.kt @@ -43,7 +43,7 @@ class JsonSerializerTest { private class Fixture { val logger: ILogger = mock() val serializer: ISerializer - val hub = mock() + val scopes = mock() val traceFile = Files.createTempFile("test", "here").toFile() val options = SentryOptions() @@ -51,7 +51,7 @@ class JsonSerializerTest { options.dsn = "https://key@sentry.io/proj" options.setLogger(logger) options.isDebug = true - whenever(hub.options).thenReturn(options) + whenever(scopes.options).thenReturn(options) serializer = JsonSerializer(options) options.setSerializer(serializer) options.setEnvelopeReader(EnvelopeReader(serializer)) @@ -830,7 +830,7 @@ class JsonSerializerTest { trace.status = SpanStatus.OK trace.setTag("myTag", "myValue") trace.sampled = true - val tracer = SentryTracer(trace, fixture.hub) + val tracer = SentryTracer(trace, fixture.scopes) tracer.setData("dataKey", "dataValue") val span = tracer.startChild("child") span.finish(SpanStatus.OK) @@ -1300,7 +1300,7 @@ class JsonSerializerTest { status = SpanStatus.OK setTag("myTag", "myValue") } - val tracer = SentryTracer(trace, fixture.hub) + val tracer = SentryTracer(trace, fixture.scopes) val span = tracer.startChild("child") span.setMeasurement("test_measurement", 1, MeasurementUnit.Custom("test")) span.finish(SpanStatus.OK) diff --git a/sentry/src/test/java/io/sentry/MainEventProcessorTest.kt b/sentry/src/test/java/io/sentry/MainEventProcessorTest.kt index ec932ebc86..682626f08c 100644 --- a/sentry/src/test/java/io/sentry/MainEventProcessorTest.kt +++ b/sentry/src/test/java/io/sentry/MainEventProcessorTest.kt @@ -33,7 +33,7 @@ class MainEventProcessorTest { dist = "dist" sdkVersion = SdkVersion("test", "1.2.3") } - val hub = mock() + val scopes = mock() val getLocalhost = mock() lateinit var sentryTracer: SentryTracer private val hostnameCacheMock = Mockito.mockStatic(HostnameCache::class.java) @@ -72,8 +72,8 @@ class MainEventProcessorTest { } host } - whenever(hub.options).thenReturn(sentryOptions) - sentryTracer = SentryTracer(TransactionContext("", ""), hub) + whenever(scopes.options).thenReturn(sentryOptions) + sentryTracer = SentryTracer(TransactionContext("", ""), scopes) val hostnameCache = HostnameCache(hostnameCacheDuration) { getLocalhost } hostnameCacheMock.`when` { HostnameCache.getInstance() }.thenReturn(hostnameCache) diff --git a/sentry/src/test/java/io/sentry/OutboxSenderTest.kt b/sentry/src/test/java/io/sentry/OutboxSenderTest.kt index ab50e054d0..9274ed4400 100644 --- a/sentry/src/test/java/io/sentry/OutboxSenderTest.kt +++ b/sentry/src/test/java/io/sentry/OutboxSenderTest.kt @@ -30,7 +30,7 @@ class OutboxSenderTest { private class Fixture { val options = mock() - val hub = mock() + val scopes = mock() var envelopeReader = mock() val serializer = mock() val logger = mock() @@ -39,11 +39,11 @@ class OutboxSenderTest { whenever(options.dsn).thenReturn("https://key@sentry.io/proj") whenever(options.dateProvider).thenReturn(SentryNanotimeDateProvider()) whenever(options.mainThreadChecker).thenReturn(NoOpMainThreadChecker.getInstance()) - whenever(hub.options).thenReturn(this.options) + whenever(scopes.options).thenReturn(this.options) } fun getSut(): OutboxSender { - return OutboxSender(hub, envelopeReader, serializer, logger, 15000, 30) + return OutboxSender(scopes, envelopeReader, serializer, logger, 15000, 30) } } @@ -83,7 +83,7 @@ class OutboxSenderTest { val hints = HintUtils.createWithTypeCheckHint(mock()) sut.processEnvelopeFile(path, hints) - verify(fixture.hub).captureEvent(eq(expected), any()) + verify(fixture.scopes).captureEvent(eq(expected), any()) assertFalse(File(path).exists()) // Additionally make sure we have no errors logged verify(fixture.logger, never()).log(eq(SentryLevel.ERROR), any(), any()) @@ -94,7 +94,7 @@ class OutboxSenderTest { fun `when parser is EnvelopeReader and serializer return SentryTransaction, transaction captured, transactions sampled, file is deleted`() { fixture.envelopeReader = EnvelopeReader(JsonSerializer(fixture.options)) whenever(fixture.options.maxSpans).thenReturn(1000) - whenever(fixture.hub.options).thenReturn(fixture.options) + whenever(fixture.scopes.options).thenReturn(fixture.options) whenever(fixture.options.transactionProfiler).thenReturn(NoOpTransactionProfiler.getInstance()) val transactionContext = TransactionContext("fixture-name", "http") @@ -102,7 +102,7 @@ class OutboxSenderTest { transactionContext.status = SpanStatus.OK transactionContext.setTag("fixture-tag", "fixture-value") - val sentryTracer = SentryTracer(transactionContext, fixture.hub) + val sentryTracer = SentryTracer(transactionContext, fixture.scopes) val span = sentryTracer.startChild("child") span.finish(SpanStatus.OK) sentryTracer.finish() @@ -120,7 +120,7 @@ class OutboxSenderTest { val hints = HintUtils.createWithTypeCheckHint(mock()) sut.processEnvelopeFile(path, hints) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertEquals(expected, it) assertTrue(it.isSampled) @@ -139,7 +139,7 @@ class OutboxSenderTest { fun `restores sampleRate`() { fixture.envelopeReader = EnvelopeReader(JsonSerializer(fixture.options)) whenever(fixture.options.maxSpans).thenReturn(1000) - whenever(fixture.hub.options).thenReturn(fixture.options) + whenever(fixture.scopes.options).thenReturn(fixture.options) whenever(fixture.options.transactionProfiler).thenReturn(NoOpTransactionProfiler.getInstance()) val transactionContext = TransactionContext("fixture-name", "http") @@ -148,7 +148,7 @@ class OutboxSenderTest { transactionContext.setTag("fixture-tag", "fixture-value") transactionContext.samplingDecision = TracesSamplingDecision(true, 0.00000021) - val sentryTracer = SentryTracer(transactionContext, fixture.hub) + val sentryTracer = SentryTracer(transactionContext, fixture.scopes) val span = sentryTracer.startChild("child") span.finish(SpanStatus.OK) sentryTracer.finish() @@ -166,7 +166,7 @@ class OutboxSenderTest { val hints = HintUtils.createWithTypeCheckHint(mock()) sut.processEnvelopeFile(path, hints) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertEquals(expected, it) assertTrue(it.isSampled) @@ -207,7 +207,7 @@ class OutboxSenderTest { val hints = HintUtils.createWithTypeCheckHint(mock()) sut.processEnvelopeFile(path, hints) - verify(fixture.hub).captureEvent(any(), any()) + verify(fixture.scopes).captureEvent(any(), any()) assertFalse(File(path).exists()) // Additionally make sure we have no errors logged verify(fixture.logger, never()).log(eq(SentryLevel.ERROR), any(), any()) @@ -225,7 +225,7 @@ class OutboxSenderTest { val hints = HintUtils.createWithTypeCheckHint(mock()) sut.processEnvelopeFile(path, hints) - verify(fixture.hub).captureEnvelope(any(), any()) + verify(fixture.scopes).captureEnvelope(any(), any()) assertFalse(File(path).exists()) // Additionally make sure we have no errors logged verify(fixture.logger, never()).log(eq(SentryLevel.ERROR), any(), any()) @@ -245,7 +245,7 @@ class OutboxSenderTest { // Additionally make sure we have no errors logged verify(fixture.logger).log(eq(SentryLevel.ERROR), any(), any()) - verify(fixture.hub, never()).captureEvent(any()) + verify(fixture.scopes, never()).captureEvent(any()) assertFalse(File(path).exists()) } @@ -263,7 +263,7 @@ class OutboxSenderTest { // Additionally make sure we have no errors logged verify(fixture.logger).log(eq(SentryLevel.ERROR), any(), any()) - verify(fixture.hub, never()).captureEvent(any()) + verify(fixture.scopes, never()).captureEvent(any()) assertFalse(File(path).exists()) } diff --git a/sentry/src/test/java/io/sentry/PreviousSessionFinalizerTest.kt b/sentry/src/test/java/io/sentry/PreviousSessionFinalizerTest.kt index 239e90905e..87aa5e6715 100644 --- a/sentry/src/test/java/io/sentry/PreviousSessionFinalizerTest.kt +++ b/sentry/src/test/java/io/sentry/PreviousSessionFinalizerTest.kt @@ -21,7 +21,7 @@ class PreviousSessionFinalizerTest { class Fixture { val options = SentryOptions() - val hub = mock() + val scopes = mock() val logger = mock() lateinit var sessionFile: File @@ -61,7 +61,7 @@ class PreviousSessionFinalizerTest { nativeCrashMarker.writeText(nativeCrashTimestamp.toString()) } } - return PreviousSessionFinalizer(options, hub) + return PreviousSessionFinalizer(options, scopes) } fun sessionFromEnvelope(envelope: SentryEnvelope): Session { @@ -80,7 +80,7 @@ class PreviousSessionFinalizerTest { val finalizer = fixture.getSut(null) finalizer.run() - verify(fixture.hub, never()).captureEnvelope(any()) + verify(fixture.scopes, never()).captureEnvelope(any()) } @Test @@ -88,7 +88,7 @@ class PreviousSessionFinalizerTest { val finalizer = fixture.getSut(tmpDir, sessionFileExists = false) finalizer.run() - verify(fixture.hub, never()).captureEnvelope(any()) + verify(fixture.scopes, never()).captureEnvelope(any()) } @Test @@ -96,7 +96,7 @@ class PreviousSessionFinalizerTest { val finalizer = fixture.getSut(tmpDir, sessionFileExists = true, session = null) finalizer.run() - verify(fixture.hub, never()).captureEnvelope(any()) + verify(fixture.scopes, never()).captureEnvelope(any()) } @Test @@ -107,7 +107,7 @@ class PreviousSessionFinalizerTest { ) finalizer.run() - verify(fixture.hub).captureEnvelope( + verify(fixture.scopes).captureEnvelope( argThat { val session = fixture.sessionFromEnvelope(this) session.release == "io.sentry.sample@1.0" && @@ -133,7 +133,7 @@ class PreviousSessionFinalizerTest { ) finalizer.run() - verify(fixture.hub).captureEnvelope( + verify(fixture.scopes).captureEnvelope( argThat { val session = fixture.sessionFromEnvelope(this) session.release == "io.sentry.sample@1.0" && @@ -156,7 +156,7 @@ class PreviousSessionFinalizerTest { ) finalizer.run() - verify(fixture.hub).captureEnvelope( + verify(fixture.scopes).captureEnvelope( argThat { val session = fixture.sessionFromEnvelope(this) session.release == "io.sentry.sample@1.0" && @@ -170,7 +170,7 @@ class PreviousSessionFinalizerTest { val finalizer = fixture.getSut(tmpDir, sessionFileExists = true) finalizer.run() - verify(fixture.hub, never()).captureEnvelope(any()) + verify(fixture.scopes, never()).captureEnvelope(any()) assertFalse(fixture.sessionFile.exists()) } @@ -189,7 +189,7 @@ class PreviousSessionFinalizerTest { argThat { startsWith("Timed out waiting to flush previous session to its own file in session finalizer.") }, any() ) - verify(fixture.hub, never()).captureEnvelope(any()) + verify(fixture.scopes, never()).captureEnvelope(any()) } @Test @@ -202,6 +202,6 @@ class PreviousSessionFinalizerTest { argThat { startsWith("Timed out waiting to flush previous session to its own file in session finalizer.") }, any() ) - verify(fixture.hub, never()).captureEnvelope(any()) + verify(fixture.scopes, never()).captureEnvelope(any()) } } diff --git a/sentry/src/test/java/io/sentry/ScopeTest.kt b/sentry/src/test/java/io/sentry/ScopeTest.kt index 906c897c62..86794d7b19 100644 --- a/sentry/src/test/java/io/sentry/ScopeTest.kt +++ b/sentry/src/test/java/io/sentry/ScopeTest.kt @@ -114,7 +114,7 @@ class ScopeTest { scope.setExtra("extra", "extra") val transaction = - SentryTracer(TransactionContext("transaction-name", "op"), NoOpHub.getInstance()) + SentryTracer(TransactionContext("transaction-name", "op"), NoOpScopes.getInstance()) scope.transaction = transaction val attachment = Attachment("path/log.txt") @@ -192,7 +192,7 @@ class ScopeTest { scope.setTransaction( SentryTracer( TransactionContext("newTransaction", "op"), - NoOpHub.getInstance() + NoOpScopes.getInstance() ) ) @@ -265,7 +265,7 @@ class ScopeTest { fun `clear scope resets scope to default state`() { val scope = Scope(SentryOptions()) scope.level = SentryLevel.WARNING - scope.setTransaction(SentryTracer(TransactionContext("", "op"), NoOpHub.getInstance())) + scope.setTransaction(SentryTracer(TransactionContext("", "op"), NoOpScopes.getInstance())) scope.user = User() scope.request = Request() scope.fingerprint = mutableListOf("finger") @@ -822,7 +822,7 @@ class ScopeTest { @Test fun `Scope getTransaction returns the transaction if there is no active span`() { val scope = Scope(SentryOptions()) - val transaction = SentryTracer(TransactionContext("name", "op"), NoOpHub.getInstance()) + val transaction = SentryTracer(TransactionContext("name", "op"), NoOpScopes.getInstance()) scope.transaction = transaction assertEquals(transaction, scope.span) } @@ -830,7 +830,7 @@ class ScopeTest { @Test fun `Scope getTransaction returns the current span if there is an unfinished span`() { val scope = Scope(SentryOptions()) - val transaction = SentryTracer(TransactionContext("name", "op"), NoOpHub.getInstance()) + val transaction = SentryTracer(TransactionContext("name", "op"), NoOpScopes.getInstance()) scope.transaction = transaction val span = transaction.startChild("op") assertEquals(span, scope.span) @@ -839,7 +839,7 @@ class ScopeTest { @Test fun `Scope getTransaction returns the current span if there is a finished span`() { val scope = Scope(SentryOptions()) - val transaction = SentryTracer(TransactionContext("name", "op"), NoOpHub.getInstance()) + val transaction = SentryTracer(TransactionContext("name", "op"), NoOpScopes.getInstance()) scope.transaction = transaction val span = transaction.startChild("op") span.finish() @@ -849,7 +849,7 @@ class ScopeTest { @Test fun `Scope getTransaction returns the latest span if there is a list of active span`() { val scope = Scope(SentryOptions()) - val transaction = SentryTracer(TransactionContext("name", "op"), NoOpHub.getInstance()) + val transaction = SentryTracer(TransactionContext("name", "op"), NoOpScopes.getInstance()) scope.transaction = transaction val span = transaction.startChild("op") val innerSpan = span.startChild("op") @@ -859,7 +859,7 @@ class ScopeTest { @Test fun `Scope setTransaction sets transaction name`() { val scope = Scope(SentryOptions()) - val transaction = SentryTracer(TransactionContext("name", "op"), NoOpHub.getInstance()) + val transaction = SentryTracer(TransactionContext("name", "op"), NoOpScopes.getInstance()) scope.transaction = transaction scope.setTransaction("new-name") assertNotNull(scope.transaction) { @@ -871,7 +871,7 @@ class ScopeTest { @Test fun `Scope setTransaction with null does not clear transaction`() { val scope = Scope(SentryOptions()) - val transaction = SentryTracer(TransactionContext("name", "op"), NoOpHub.getInstance()) + val transaction = SentryTracer(TransactionContext("name", "op"), NoOpScopes.getInstance()) scope.transaction = transaction scope.callMethod("setTransaction", String::class.java, null) assertNotNull(scope.transaction) @@ -936,7 +936,7 @@ class ScopeTest { fun `when transaction is started, sets transaction name on the transaction object`() { val scope = Scope(SentryOptions()) val sentryTransaction = - SentryTracer(TransactionContext("transaction-name", "op"), NoOpHub.getInstance()) + SentryTracer(TransactionContext("transaction-name", "op"), NoOpScopes.getInstance()) scope.transaction = sentryTransaction assertEquals("transaction-name", scope.transactionName) scope.setTransaction("new-name") @@ -950,7 +950,7 @@ class ScopeTest { val scope = Scope(SentryOptions()) scope.setTransaction("transaction-a") val sentryTransaction = - SentryTracer(TransactionContext("transaction-name", "op"), NoOpHub.getInstance()) + SentryTracer(TransactionContext("transaction-name", "op"), NoOpScopes.getInstance()) scope.setTransaction(sentryTransaction) assertEquals("transaction-name", scope.transactionName) scope.clearTransaction() @@ -961,7 +961,7 @@ class ScopeTest { fun `withTransaction returns the current Transaction bound to the Scope`() { val scope = Scope(SentryOptions()) val sentryTransaction = - SentryTracer(TransactionContext("transaction-name", "op"), NoOpHub.getInstance()) + SentryTracer(TransactionContext("transaction-name", "op"), NoOpScopes.getInstance()) scope.setTransaction(sentryTransaction) scope.withTransaction { diff --git a/sentry/src/test/java/io/sentry/ScopesAdapterTest.kt b/sentry/src/test/java/io/sentry/ScopesAdapterTest.kt new file mode 100644 index 0000000000..85a0b6ef75 --- /dev/null +++ b/sentry/src/test/java/io/sentry/ScopesAdapterTest.kt @@ -0,0 +1,265 @@ +package io.sentry + +import io.sentry.protocol.SentryTransaction +import io.sentry.protocol.User +import org.mockito.kotlin.any +import org.mockito.kotlin.eq +import org.mockito.kotlin.mock +import org.mockito.kotlin.reset +import org.mockito.kotlin.verify +import kotlin.test.AfterTest +import kotlin.test.BeforeTest +import kotlin.test.Test + +class ScopesAdapterTest { + + val scopes: IScopes = mock() + + @BeforeTest + fun `set up`() { + Sentry.setCurrentScopes(scopes) + } + + @AfterTest + fun shutdown() { + Sentry.close() + } + + @Test fun `isEnabled calls Hub`() { + ScopesAdapter.getInstance().isEnabled + verify(scopes).isEnabled + } + + @Test fun `captureEvent calls Hub`() { + val event = mock() + val hint = mock() + val scopeCallback = mock() + ScopesAdapter.getInstance().captureEvent(event, hint) + verify(scopes).captureEvent(eq(event), eq(hint)) + + ScopesAdapter.getInstance().captureEvent(event, hint, scopeCallback) + verify(scopes).captureEvent(eq(event), eq(hint), eq(scopeCallback)) + } + + @Test fun `captureMessage calls Hub`() { + val scopeCallback = mock() + val sentryLevel = mock() + ScopesAdapter.getInstance().captureMessage("message", sentryLevel) + verify(scopes).captureMessage(eq("message"), eq(sentryLevel)) + + ScopesAdapter.getInstance().captureMessage("message", sentryLevel, scopeCallback) + verify(scopes).captureMessage(eq("message"), eq(sentryLevel), eq(scopeCallback)) + } + + @Test fun `captureEnvelope calls Hub`() { + val envelope = mock() + val hint = mock() + ScopesAdapter.getInstance().captureEnvelope(envelope, hint) + verify(scopes).captureEnvelope(eq(envelope), eq(hint)) + } + + @Test fun `captureException calls Hub`() { + val throwable = mock() + val hint = mock() + val scopeCallback = mock() + ScopesAdapter.getInstance().captureException(throwable, hint) + verify(scopes).captureException(eq(throwable), eq(hint)) + + ScopesAdapter.getInstance().captureException(throwable, hint, scopeCallback) + verify(scopes).captureException(eq(throwable), eq(hint), eq(scopeCallback)) + } + + @Test fun `captureUserFeedback calls Hub`() { + val userFeedback = mock() + ScopesAdapter.getInstance().captureUserFeedback(userFeedback) + verify(scopes).captureUserFeedback(eq(userFeedback)) + } + + @Test fun `captureCheckIn calls Hub`() { + val checkIn = mock() + ScopesAdapter.getInstance().captureCheckIn(checkIn) + verify(scopes).captureCheckIn(eq(checkIn)) + } + + @Test fun `startSession calls Hub`() { + ScopesAdapter.getInstance().startSession() + verify(scopes).startSession() + } + + @Test fun `endSession calls Hub`() { + ScopesAdapter.getInstance().endSession() + verify(scopes).endSession() + } + + @Test fun `close calls Hub`() { + ScopesAdapter.getInstance().close() + verify(scopes).close(false) + } + + @Test fun `close with isRestarting true calls Hub with isRestarting false`() { + ScopesAdapter.getInstance().close(true) + verify(scopes).close(false) + } + + @Test fun `close with isRestarting false calls Hub with isRestarting false`() { + ScopesAdapter.getInstance().close(false) + verify(scopes).close(false) + } + + @Test fun `addBreadcrumb calls Hub`() { + val breadcrumb = mock() + val hint = mock() + ScopesAdapter.getInstance().addBreadcrumb(breadcrumb, hint) + verify(scopes).addBreadcrumb(eq(breadcrumb), eq(hint)) + } + + @Test fun `setLevel calls Hub`() { + val sentryLevel = mock() + ScopesAdapter.getInstance().setLevel(sentryLevel) + verify(scopes).setLevel(eq(sentryLevel)) + } + + @Test fun `setTransaction calls Hub`() { + ScopesAdapter.getInstance().setTransaction("transaction") + verify(scopes).setTransaction(eq("transaction")) + } + + @Test fun `setUser calls Hub`() { + val user = mock() + ScopesAdapter.getInstance().setUser(user) + verify(scopes).setUser(eq(user)) + } + + @Test fun `setFingerprint calls Hub`() { + val fingerprint = ArrayList() + ScopesAdapter.getInstance().setFingerprint(fingerprint) + verify(scopes).setFingerprint(eq(fingerprint)) + } + + @Test fun `clearBreadcrumbs calls Hub`() { + ScopesAdapter.getInstance().clearBreadcrumbs() + verify(scopes).clearBreadcrumbs() + } + + @Test fun `setTag calls Hub`() { + ScopesAdapter.getInstance().setTag("key", "value") + verify(scopes).setTag(eq("key"), eq("value")) + } + + @Test fun `removeTag calls Hub`() { + ScopesAdapter.getInstance().removeTag("key") + verify(scopes).removeTag(eq("key")) + } + + @Test fun `setExtra calls Hub`() { + ScopesAdapter.getInstance().setExtra("key", "value") + verify(scopes).setExtra(eq("key"), eq("value")) + } + + @Test fun `removeExtra calls Hub`() { + ScopesAdapter.getInstance().removeExtra("key") + verify(scopes).removeExtra(eq("key")) + } + + @Test fun `getLastEventId calls Hub`() { + ScopesAdapter.getInstance().lastEventId + verify(scopes).lastEventId + } + + @Test fun `pushScope calls Hub`() { + ScopesAdapter.getInstance().pushScope() + verify(scopes).pushScope() + } + + @Test fun `popScope calls Hub`() { + ScopesAdapter.getInstance().popScope() + verify(scopes).popScope() + } + + @Test fun `withScope calls Hub`() { + val scopeCallback = mock() + ScopesAdapter.getInstance().withScope(scopeCallback) + verify(scopes).withScope(eq(scopeCallback)) + } + + @Test fun `configureScope calls Hub`() { + val scopeCallback = mock() + ScopesAdapter.getInstance().configureScope(scopeCallback) + verify(scopes).configureScope(eq(scopeCallback)) + } + + @Test fun `bindClient calls Hub`() { + val client = mock() + ScopesAdapter.getInstance().bindClient(client) + verify(scopes).bindClient(eq(client)) + } + + @Test fun `flush calls Hub`() { + ScopesAdapter.getInstance().flush(1) + verify(scopes).flush(eq(1)) + } + + @Test fun `clone calls Hub`() { + ScopesAdapter.getInstance().clone() + verify(scopes).clone() + } + + @Test fun `captureTransaction calls Hub`() { + val transaction = mock() + val traceContext = mock() + val hint = mock() + val profilingTraceData = mock() + ScopesAdapter.getInstance().captureTransaction(transaction, traceContext, hint, profilingTraceData) + verify(scopes).captureTransaction(eq(transaction), eq(traceContext), eq(hint), eq(profilingTraceData)) + } + + @Test fun `startTransaction calls Hub`() { + val transactionContext = mock() + val samplingContext = mock() + val transactionOptions = mock() + ScopesAdapter.getInstance().startTransaction(transactionContext) + verify(scopes).startTransaction(eq(transactionContext), any()) + + reset(scopes) + + ScopesAdapter.getInstance().startTransaction(transactionContext, transactionOptions) + verify(scopes).startTransaction(eq(transactionContext), eq(transactionOptions)) + } + + @Test fun `traceHeaders calls Hub`() { + ScopesAdapter.getInstance().traceHeaders() + verify(scopes).traceHeaders() + } + + @Test fun `setSpanContext calls Hub`() { + val throwable = mock() + val span = mock() + ScopesAdapter.getInstance().setSpanContext(throwable, span, "transactionName") + verify(scopes).setSpanContext(eq(throwable), eq(span), eq("transactionName")) + } + + @Test fun `getSpan calls Hub`() { + ScopesAdapter.getInstance().span + verify(scopes).span + } + + @Test fun `getTransaction calls Hub`() { + ScopesAdapter.getInstance().transaction + verify(scopes).transaction + } + + @Test fun `getOptions calls Hub`() { + ScopesAdapter.getInstance().options + verify(scopes).options + } + + @Test fun `isCrashedLastRun calls Hub`() { + ScopesAdapter.getInstance().isCrashedLastRun + verify(scopes).isCrashedLastRun + } + + @Test fun `reportFullyDisplayed calls Hub`() { + ScopesAdapter.getInstance().reportFullyDisplayed() + verify(scopes).reportFullyDisplayed() + } +} diff --git a/sentry/src/test/java/io/sentry/SendCachedEnvelopeFireAndForgetIntegrationTest.kt b/sentry/src/test/java/io/sentry/SendCachedEnvelopeFireAndForgetIntegrationTest.kt index 78623f90a7..beed31a198 100644 --- a/sentry/src/test/java/io/sentry/SendCachedEnvelopeFireAndForgetIntegrationTest.kt +++ b/sentry/src/test/java/io/sentry/SendCachedEnvelopeFireAndForgetIntegrationTest.kt @@ -19,7 +19,7 @@ import kotlin.test.assertTrue class SendCachedEnvelopeFireAndForgetIntegrationTest { private class Fixture { - var hub: IHub = mock() + var scopes: IScopes = mock() var logger: ILogger = mock() var options = SentryOptions() val sender = mock() @@ -45,7 +45,7 @@ class SendCachedEnvelopeFireAndForgetIntegrationTest { fun `when cacheDirPath returns null, register logs and exit`() { fixture.options.cacheDirPath = null val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.logger).log(eq(SentryLevel.ERROR), eq("No cache dir path is defined in options.")) verify(fixture.sender, never()).send() } @@ -73,7 +73,7 @@ class SendCachedEnvelopeFireAndForgetIntegrationTest { val sut = SendCachedEnvelopeFireAndForgetIntegration(CustomFactory()) fixture.options.cacheDirPath = "abc" fixture.options.executorService = ImmediateExecutorService() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.logger).log(eq(SentryLevel.ERROR), eq("SendFireAndForget factory is null.")) verify(fixture.sender, never()).send() } @@ -85,7 +85,7 @@ class SendCachedEnvelopeFireAndForgetIntegrationTest { mock() ) val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertNotNull(fixture.options.sdkVersion) assert(fixture.options.sdkVersion!!.integrationSet.contains("SendCachedEnvelopeFireAndForget")) } @@ -96,7 +96,7 @@ class SendCachedEnvelopeFireAndForgetIntegrationTest { fixture.options.executorService.close(0) whenever(fixture.callback.create(any(), any())).thenReturn(mock()) val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.logger).log(eq(SentryLevel.ERROR), eq("Failed to call the executor. Cached events will not be sent. Did you call Sentry.close()?"), any()) } @@ -108,7 +108,7 @@ class SendCachedEnvelopeFireAndForgetIntegrationTest { fixture.options.cacheDirPath = "cache" val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(connectionStatusProvider).addConnectionStatusObserver(any()) } @@ -122,9 +122,9 @@ class SendCachedEnvelopeFireAndForgetIntegrationTest { fixture.options.cacheDirPath = "cache" val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.sender, never()).send() } @@ -139,7 +139,7 @@ class SendCachedEnvelopeFireAndForgetIntegrationTest { fixture.options.cacheDirPath = "cache" val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.sender).send() } @@ -155,7 +155,7 @@ class SendCachedEnvelopeFireAndForgetIntegrationTest { fixture.options.cacheDirPath = "cache" val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) // when there's no connection no factory create call should be done verify(fixture.sender, never()).send() @@ -183,9 +183,9 @@ class SendCachedEnvelopeFireAndForgetIntegrationTest { val rateLimiter = mock { whenever(mock.isActiveForCategory(any())).thenReturn(true) } - whenever(fixture.hub.rateLimiter).thenReturn(rateLimiter) + whenever(fixture.scopes.rateLimiter).thenReturn(rateLimiter) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) // no factory call should be done if there's rate limiting active verify(fixture.sender, never()).send() @@ -196,8 +196,8 @@ class SendCachedEnvelopeFireAndForgetIntegrationTest { fixture.options.executorService = ImmediateExecutorService() fixture.options.cacheDirPath = "cache" val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) - verify(fixture.callback).create(eq(fixture.hub), eq(fixture.options)) + sut.register(fixture.scopes, fixture.options) + verify(fixture.callback).create(eq(fixture.scopes), eq(fixture.options)) } @Test @@ -205,7 +205,7 @@ class SendCachedEnvelopeFireAndForgetIntegrationTest { fixture.options.executorService = mock() fixture.options.cacheDirPath = "cache" val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.callback, never()).create(any(), any()) } @@ -215,7 +215,7 @@ class SendCachedEnvelopeFireAndForgetIntegrationTest { fixture.options.executorService = deferredExecutorService val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.sender, never()).send() sut.close() @@ -224,7 +224,7 @@ class SendCachedEnvelopeFireAndForgetIntegrationTest { } private class CustomFactory : SendCachedEnvelopeFireAndForgetIntegration.SendFireAndForgetFactory { - override fun create(hub: IHub, options: SentryOptions): SendCachedEnvelopeFireAndForgetIntegration.SendFireAndForget? { + override fun create(scopes: IScopes, options: SentryOptions): SendCachedEnvelopeFireAndForgetIntegration.SendFireAndForget? { return null } } diff --git a/sentry/src/test/java/io/sentry/SentryClientTest.kt b/sentry/src/test/java/io/sentry/SentryClientTest.kt index de540bf90c..eac2b0be29 100644 --- a/sentry/src/test/java/io/sentry/SentryClientTest.kt +++ b/sentry/src/test/java/io/sentry/SentryClientTest.kt @@ -70,7 +70,7 @@ class SentryClientTest { var transport = mock() var factory = mock() val maxAttachmentSize: Long = (5 * 1024 * 1024).toLong() - val hub = mock() + val scopes = mock() val sentryTracer: SentryTracer var sentryOptions: SentryOptions = SentryOptions().apply { @@ -88,8 +88,8 @@ class SentryClientTest { init { whenever(factory.create(any(), any())).thenReturn(transport) - whenever(hub.options).thenReturn(sentryOptions) - sentryTracer = SentryTracer(TransactionContext("a-transaction", "op"), hub) + whenever(scopes.options).thenReturn(sentryOptions) + sentryTracer = SentryTracer(TransactionContext("a-transaction", "op"), scopes) } var attachment = Attachment("hello".toByteArray(), "hello.txt", "text/plain", true) @@ -1456,9 +1456,9 @@ class SentryClientTest { @Test fun `when captureTransaction with scope, transaction should use user data`() { - val hub: IHub = mock() - whenever(hub.options).thenReturn(SentryOptions()) - val transaction = SentryTransaction(SentryTracer(TransactionContext("tx", "op"), hub)) + val scopes: IScopes = mock() + whenever(scopes.options).thenReturn(SentryOptions()) + val transaction = SentryTransaction(SentryTracer(TransactionContext("tx", "op"), scopes)) val scope = createScope() val sut = fixture.getSut() @@ -1487,7 +1487,7 @@ class SentryClientTest { val event = SentryEvent() val sut = fixture.getSut() val scope = createScope() - val transaction = SentryTracer(TransactionContext("a-transaction", "op"), fixture.hub) + val transaction = SentryTracer(TransactionContext("a-transaction", "op"), fixture.scopes) scope.setTransaction(transaction) val span = transaction.startChild("op") sut.captureEvent(event, scope) @@ -1558,7 +1558,7 @@ class SentryClientTest { fixture.sentryOptions.release = "optionsRelease" fixture.sentryOptions.environment = "optionsEnvironment" val sut = fixture.getSut() - val sentryTracer = SentryTracer(TransactionContext("name", "op"), fixture.hub) + val sentryTracer = SentryTracer(TransactionContext("name", "op"), fixture.scopes) val transaction = SentryTransaction(sentryTracer) transaction.release = "transactionRelease" transaction.environment = "transactionEnvironment" @@ -1571,7 +1571,7 @@ class SentryClientTest { fun `when transaction does not have SDK version set, and the SDK version is set on options, options values are applied to transactions`() { fixture.sentryOptions.sdkVersion = SdkVersion("sdk.name", "version") val sut = fixture.getSut() - val sentryTracer = SentryTracer(TransactionContext("name", "op"), fixture.hub) + val sentryTracer = SentryTracer(TransactionContext("name", "op"), fixture.scopes) val transaction = SentryTransaction(sentryTracer) sut.captureTransaction(transaction, sentryTracer.traceContext()) assertEquals(fixture.sentryOptions.sdkVersion, transaction.sdk) @@ -1581,7 +1581,7 @@ class SentryClientTest { fun `when transaction has SDK version set, and the SDK version is set on options, options values are not applied to transactions`() { fixture.sentryOptions.sdkVersion = SdkVersion("sdk.name", "version") val sut = fixture.getSut() - val sentryTracer = SentryTracer(TransactionContext("name", "op"), fixture.hub) + val sentryTracer = SentryTracer(TransactionContext("name", "op"), fixture.scopes) val transaction = SentryTransaction(sentryTracer) val sdkVersion = SdkVersion("transaction.sdk.name", "version") transaction.sdk = sdkVersion @@ -1593,7 +1593,7 @@ class SentryClientTest { fun `when transaction does not have tags, and tags are set on options, options values are applied to transactions`() { fixture.sentryOptions.setTag("tag1", "value1") val sut = fixture.getSut() - val sentryTracer = SentryTracer(TransactionContext("name", "op"), fixture.hub) + val sentryTracer = SentryTracer(TransactionContext("name", "op"), fixture.scopes) val transaction = SentryTransaction(sentryTracer) sut.captureTransaction(transaction, sentryTracer.traceContext()) assertEquals(mapOf("tag1" to "value1"), transaction.tags) @@ -1604,7 +1604,7 @@ class SentryClientTest { fixture.sentryOptions.setTag("tag1", "value1") fixture.sentryOptions.setTag("tag2", "value2") val sut = fixture.getSut() - val sentryTracer = SentryTracer(TransactionContext("name", "op"), fixture.hub) + val sentryTracer = SentryTracer(TransactionContext("name", "op"), fixture.scopes) val transaction = SentryTransaction(sentryTracer) transaction.setTag("tag3", "value3") transaction.setTag("tag2", "transaction-tag") @@ -1618,7 +1618,7 @@ class SentryClientTest { @Test fun `captured transactions without a platform, have the default platform set`() { val sut = fixture.getSut() - val sentryTracer = SentryTracer(TransactionContext("name", "op"), fixture.hub) + val sentryTracer = SentryTracer(TransactionContext("name", "op"), fixture.scopes) val transaction = SentryTransaction(sentryTracer) sut.captureTransaction(transaction, sentryTracer.traceContext()) assertEquals("java", transaction.platform) @@ -1627,7 +1627,7 @@ class SentryClientTest { @Test fun `captured transactions with a platform, do not get the platform overwritten`() { val sut = fixture.getSut() - val sentryTracer = SentryTracer(TransactionContext("name", "op"), fixture.hub) + val sentryTracer = SentryTracer(TransactionContext("name", "op"), fixture.scopes) val transaction = SentryTransaction(sentryTracer) transaction.platform = "abc" sut.captureTransaction(transaction, sentryTracer.traceContext()) diff --git a/sentry/src/test/java/io/sentry/SentryTest.kt b/sentry/src/test/java/io/sentry/SentryTest.kt index 0f4966b44a..70728d2900 100644 --- a/sentry/src/test/java/io/sentry/SentryTest.kt +++ b/sentry/src/test/java/io/sentry/SentryTest.kt @@ -63,27 +63,27 @@ class SentryTest { } @Test - fun `init multiple times calls hub close with isRestarting true`() { - val hub = mock() + fun `init multiple times calls scopes close with isRestarting true`() { + val scopes = mock() Sentry.init { it.dsn = dsn } - Sentry.setCurrentHub(hub) + Sentry.setCurrentScopes(scopes) Sentry.init { it.dsn = dsn } - verify(hub).close(eq(true)) + verify(scopes).close(eq(true)) } @Test - fun `close calls hub close with isRestarting false`() { - val hub = mock() + fun `close calls scopes close with isRestarting false`() { + val scopes = mock() Sentry.init { it.dsn = dsn } - Sentry.setCurrentHub(hub) + Sentry.setCurrentScopes(scopes) Sentry.close() - verify(hub).close(eq(false)) + verify(scopes).close(eq(false)) } @Test @@ -213,7 +213,7 @@ class SentryTest { Sentry.init { it.isEnableExternalConfiguration = true } - assertTrue(HubAdapter.getInstance().isEnabled) + assertTrue(ScopesAdapter.getInstance().isEnabled) } finally { temporaryFolder.delete() } @@ -229,10 +229,10 @@ class SentryTest { Sentry.setTag("none", "shouldNotExist") var value: String? = null - Sentry.getCurrentHub().configureScope { + Sentry.getCurrentScopes().configureScope { value = it.tags[value] } - assertTrue(Sentry.getCurrentHub() is NoOpHub) + assertTrue(Sentry.getCurrentScopes().isNoOp) assertNull(value) } @@ -245,10 +245,10 @@ class SentryTest { Sentry.setTag("none", "shouldNotExist") var value: String? = null - Sentry.getCurrentHub().configureScope { + Sentry.getCurrentScopes().configureScope { value = it.tags[value] } - assertTrue(Sentry.getCurrentHub() is NoOpHub) + assertTrue(Sentry.getCurrentScopes().isNoOp) assertNull(value) } @@ -267,7 +267,7 @@ class SentryTest { Sentry.init { it.dsn = dsn } val client = mock() - Sentry.getCurrentHub().bindClient(client) + Sentry.getCurrentScopes().bindClient(client) val userFeedback = UserFeedback(SentryId.EMPTY_ID) Sentry.captureUserFeedback(userFeedback) @@ -369,11 +369,11 @@ class SentryTest { } @Test - fun `using sentry before calling init creates NoOpHub but after init Sentry uses a new clone`() { - // noop as not yet initialized, caches NoOpHub in ThreadLocal + fun `using sentry before calling init creates NoOpScopes but after init Sentry uses a new clone`() { + // noop as not yet initialized, caches NoOpScopes in ThreadLocal Sentry.captureMessage("noop caused") - assertTrue(Sentry.getCurrentHub() is NoOpHub) + assertTrue(Sentry.getCurrentScopes().isNoOp) // init Sentry in another thread val thread = Thread() { @@ -387,18 +387,18 @@ class SentryTest { Sentry.captureMessage("should work now") - val hub = Sentry.getCurrentHub() - assertNotNull(hub) - assertFalse(hub is NoOpHub) + val scopes = Sentry.getCurrentScopes() + assertNotNull(scopes) + assertFalse(scopes.isNoOp) } @Test - fun `main hub can be cloned and does not share scope with current hub`() { - // noop as not yet initialized, caches NoOpHub in ThreadLocal + fun `main scopes can be cloned and does not share scope with current scopes`() { + // noop as not yet initialized, caches NoOpScopes in ThreadLocal Sentry.addBreadcrumb("breadcrumbNoOp") Sentry.captureMessage("messageNoOp") - assertTrue(Sentry.getCurrentHub() is NoOpHub) + assertTrue(Sentry.getCurrentScopes().isNoOp) val capturedEvents = mutableListOf() @@ -418,14 +418,14 @@ class SentryTest { Sentry.addBreadcrumb("breadcrumbCurrent") - val hub = Sentry.getCurrentHub() - assertNotNull(hub) - assertFalse(hub is NoOpHub) + val scopes = Sentry.getCurrentScopes() + assertNotNull(scopes) + assertFalse(Sentry.getCurrentScopes().isNoOp) val newMainHubClone = Sentry.cloneMainHub() newMainHubClone.addBreadcrumb("breadcrumbMainClone") - hub.captureMessage("messageCurrent") + scopes.captureMessage("messageCurrent") newMainHubClone.captureMessage("messageMainClone") assertEquals(2, capturedEvents.size) @@ -444,12 +444,12 @@ class SentryTest { } @Test - fun `main hub is not cloned in global hub mode and shares scope with current hub`() { - // noop as not yet initialized, caches NoOpHub in ThreadLocal + fun `main scopes is not cloned in global scopes mode and shares scope with current scopes`() { + // noop as not yet initialized, caches NoOpScopes in ThreadLocal Sentry.addBreadcrumb("breadcrumbNoOp") Sentry.captureMessage("messageNoOp") - assertTrue(Sentry.getCurrentHub() is NoOpHub) + assertTrue(Sentry.getCurrentScopes().isNoOp) val capturedEvents = mutableListOf() @@ -469,14 +469,14 @@ class SentryTest { Sentry.addBreadcrumb("breadcrumbCurrent") - val hub = Sentry.getCurrentHub() - assertNotNull(hub) - assertFalse(hub is NoOpHub) + val scopes = Sentry.getCurrentScopes() + assertNotNull(scopes) + assertFalse(scopes.isNoOp) val newMainHubClone = Sentry.cloneMainHub() newMainHubClone.addBreadcrumb("breadcrumbMainClone") - hub.captureMessage("messageCurrent") + scopes.captureMessage("messageCurrent") newMainHubClone.captureMessage("messageMainClone") assertEquals(2, capturedEvents.size) @@ -669,25 +669,25 @@ class SentryTest { } @Test - fun `reportFullyDisplayed calls hub reportFullyDisplayed`() { - val hub = mock() + fun `reportFullyDisplayed calls scopes reportFullyDisplayed`() { + val scopes = mock() Sentry.init { it.dsn = dsn } - Sentry.setCurrentHub(hub) + Sentry.setCurrentScopes(scopes) Sentry.reportFullyDisplayed() - verify(hub).reportFullyDisplayed() + verify(scopes).reportFullyDisplayed() } @Test fun `reportFullDisplayed calls reportFullyDisplayed`() { - val hub = mock() + val scopes = mock() Sentry.init { it.dsn = dsn } - Sentry.setCurrentHub(hub) + Sentry.setCurrentScopes(scopes) Sentry.reportFullDisplayed() - verify(hub).reportFullyDisplayed() + verify(scopes).reportFullyDisplayed() } @Test @@ -806,11 +806,11 @@ class SentryTest { it.serializer.deserialize(previousSessionFile.bufferedReader(), Session::class.java)!!.environment ) - it.addIntegration { hub, _ -> + it.addIntegration { scopes, _ -> // this is just a hack to trigger the previousSessionFlush latch, so the finalizer // does not time out waiting. We have to do it as integration, because this is where - // the hub is already initialized - hub.startSession() + // the scopes is already initialized + scopes.startSession() } } @@ -861,7 +861,7 @@ class SentryTest { Sentry.init { it.dsn = dsn } val client = mock() - Sentry.getCurrentHub().bindClient(client) + Sentry.getCurrentScopes().bindClient(client) val checkIn = CheckIn("some_slug", CheckInStatus.OK) Sentry.captureCheckIn(checkIn) @@ -910,18 +910,18 @@ class SentryTest { } @Test - fun `getSpan calls hub getSpan`() { - val hub = mock() + fun `getSpan calls scopes getSpan`() { + val scopes = mock() Sentry.init({ it.dsn = dsn }, false) - Sentry.setCurrentHub(hub) + Sentry.setCurrentScopes(scopes) Sentry.getSpan() - verify(hub).span + verify(scopes).span } @Test - fun `getSpan calls returns root span if globalhub mode is enabled on Android`() { + fun `getSpan calls returns root span if globalscopes mode is enabled on Android`() { PlatformTestManipulator.pretendIsAndroid(true) Sentry.init({ it.dsn = dsn @@ -938,7 +938,7 @@ class SentryTest { } @Test - fun `getSpan calls returns child span if globalhub mode is enabled, but the platform is not Android`() { + fun `getSpan calls returns child span if globalscopes mode is enabled, but the platform is not Android`() { PlatformTestManipulator.pretendIsAndroid(false) Sentry.init({ it.dsn = dsn @@ -954,7 +954,7 @@ class SentryTest { } @Test - fun `getSpan calls returns child span if globalhub mode is disabled`() { + fun `getSpan calls returns child span if globalscopes mode is disabled`() { Sentry.init({ it.dsn = dsn it.enableTracing = true @@ -1140,15 +1140,15 @@ class SentryTest { } @Test - fun `metrics calls hub getMetrics`() { - val hub = mock() + fun `metrics calls scopes getMetrics`() { + val scopes = mock() Sentry.init({ it.dsn = dsn }, false) - Sentry.setCurrentHub(hub) + Sentry.setCurrentScopes(scopes) Sentry.metrics() - verify(hub).metrics() + verify(scopes).metrics() } private class InMemoryOptionsObserver : IOptionsObserver { diff --git a/sentry/src/test/java/io/sentry/SentryWrapperTest.kt b/sentry/src/test/java/io/sentry/SentryWrapperTest.kt index 7f6d449eac..2fb9b38566 100644 --- a/sentry/src/test/java/io/sentry/SentryWrapperTest.kt +++ b/sentry/src/test/java/io/sentry/SentryWrapperTest.kt @@ -35,20 +35,20 @@ class SentryWrapperTest { } } - val mainHub = Sentry.getCurrentHub() - val threadedHub = Sentry.getCurrentHub().clone() + val mainHub = Sentry.getCurrentScopes() + val threadedHub = Sentry.getCurrentScopes().clone() executor.submit { - Sentry.setCurrentHub(threadedHub) + Sentry.setCurrentScopes(threadedHub) }.get() - assertEquals(mainHub, Sentry.getCurrentHub()) + assertEquals(mainHub, Sentry.getCurrentScopes()) val callableFuture = CompletableFuture.supplyAsync( SentryWrapper.wrapSupplier { - assertNotEquals(mainHub, Sentry.getCurrentHub()) - assertNotEquals(threadedHub, Sentry.getCurrentHub()) + assertNotEquals(mainHub, Sentry.getCurrentScopes()) + assertNotEquals(threadedHub, Sentry.getCurrentScopes()) "Result 1" }, executor @@ -57,8 +57,8 @@ class SentryWrapperTest { callableFuture.join() executor.submit { - assertNotEquals(mainHub, Sentry.getCurrentHub()) - assertEquals(threadedHub, Sentry.getCurrentHub()) + assertNotEquals(mainHub, Sentry.getCurrentScopes()) + assertEquals(threadedHub, Sentry.getCurrentScopes()) }.get() } @@ -169,20 +169,20 @@ class SentryWrapperTest { it.dsn = dsn } - val mainHub = Sentry.getCurrentHub() - val threadedHub = Sentry.getCurrentHub().clone() + val mainHub = Sentry.getCurrentScopes() + val threadedHub = Sentry.getCurrentScopes().clone() executor.submit { - Sentry.setCurrentHub(threadedHub) + Sentry.setCurrentScopes(threadedHub) }.get() - assertEquals(mainHub, Sentry.getCurrentHub()) + assertEquals(mainHub, Sentry.getCurrentScopes()) val callableFuture = executor.submit( SentryWrapper.wrapCallable { - assertNotEquals(mainHub, Sentry.getCurrentHub()) - assertNotEquals(threadedHub, Sentry.getCurrentHub()) + assertNotEquals(mainHub, Sentry.getCurrentScopes()) + assertNotEquals(threadedHub, Sentry.getCurrentScopes()) "Result 1" } ) @@ -190,8 +190,8 @@ class SentryWrapperTest { callableFuture.get() executor.submit { - assertNotEquals(mainHub, Sentry.getCurrentHub()) - assertEquals(threadedHub, Sentry.getCurrentHub()) + assertNotEquals(mainHub, Sentry.getCurrentScopes()) + assertEquals(threadedHub, Sentry.getCurrentScopes()) }.get() } } diff --git a/sentry/src/test/java/io/sentry/ShutdownHookIntegrationTest.kt b/sentry/src/test/java/io/sentry/ShutdownHookIntegrationTest.kt index d6ce0ff043..428a34635f 100644 --- a/sentry/src/test/java/io/sentry/ShutdownHookIntegrationTest.kt +++ b/sentry/src/test/java/io/sentry/ShutdownHookIntegrationTest.kt @@ -16,7 +16,7 @@ class ShutdownHookIntegrationTest { private class Fixture { val runtime = mock() val options = SentryOptions() - val hub = mock() + val scopes = mock() fun getSut(): ShutdownHookIntegration { return ShutdownHookIntegration(runtime) @@ -29,7 +29,7 @@ class ShutdownHookIntegrationTest { fun `registration attaches shutdown hook to runtime`() { val integration = fixture.getSut() - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) verify(fixture.runtime).addShutdownHook(any()) } @@ -39,7 +39,7 @@ class ShutdownHookIntegrationTest { val integration = fixture.getSut() fixture.options.isEnableShutdownHook = false - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) verify(fixture.runtime, never()).addShutdownHook(any()) } @@ -48,7 +48,7 @@ class ShutdownHookIntegrationTest { fun `registration removes shutdown hook from runtime`() { val integration = fixture.getSut() - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) integration.close() verify(fixture.runtime).removeShutdownHook(any()) @@ -58,13 +58,13 @@ class ShutdownHookIntegrationTest { fun `hook calls flush`() { val integration = fixture.getSut() - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) assertNotNull(integration.hook) { it.start() it.join() } - verify(fixture.hub).flush(any()) + verify(fixture.scopes).flush(any()) } @Test @@ -72,13 +72,13 @@ class ShutdownHookIntegrationTest { val integration = fixture.getSut() fixture.options.flushTimeoutMillis = 10000 - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) assertNotNull(integration.hook) { it.start() it.join() } - verify(fixture.hub).flush(eq(10000)) + verify(fixture.scopes).flush(eq(10000)) } @Test @@ -86,7 +86,7 @@ class ShutdownHookIntegrationTest { val integration = fixture.getSut() whenever(fixture.runtime.removeShutdownHook(any())).thenThrow(java.lang.IllegalStateException("Shutdown in progress")) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) integration.close() verify(fixture.runtime).removeShutdownHook(any()) @@ -97,7 +97,7 @@ class ShutdownHookIntegrationTest { val integration = fixture.getSut() whenever(fixture.runtime.removeShutdownHook(any())).thenThrow(java.lang.IllegalStateException()) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) assertFails { integration.close() @@ -110,7 +110,7 @@ class ShutdownHookIntegrationTest { fun `Integration adds itself to integration list`() { val integration = fixture.getSut() - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) assertTrue( fixture.options.sdkVersion!!.integrationSet.contains("ShutdownHook") diff --git a/sentry/src/test/java/io/sentry/SpanTest.kt b/sentry/src/test/java/io/sentry/SpanTest.kt index ae9d9bd07f..fd36c31933 100644 --- a/sentry/src/test/java/io/sentry/SpanTest.kt +++ b/sentry/src/test/java/io/sentry/SpanTest.kt @@ -21,10 +21,10 @@ import kotlin.test.assertTrue class SpanTest { private class Fixture { - val hub = mock() + val scopes = mock() init { - whenever(hub.options).thenReturn( + whenever(scopes.options).thenReturn( SentryOptions().apply { dsn = "https://key@sentry.io/proj" isTraceSampling = true @@ -36,9 +36,9 @@ class SpanTest { return Span( SentryId(), SpanId(), - SentryTracer(TransactionContext("name", "op"), hub), + SentryTracer(TransactionContext("name", "op"), scopes), "op", - hub, + scopes, null, options, null @@ -46,7 +46,7 @@ class SpanTest { } fun getRootSut(options: TransactionOptions = TransactionOptions()): Span { - return SentryTracer(TransactionContext("name", "op"), hub, options).root + return SentryTracer(TransactionContext("name", "op"), scopes, options).root } } @@ -106,10 +106,10 @@ class SpanTest { parentSpanId, SentryTracer( TransactionContext("name", "op", TracesSamplingDecision(true)), - fixture.hub + fixture.scopes ), "op", - fixture.hub + fixture.scopes ) val sentryTrace = span.toSentryTrace() @@ -163,17 +163,17 @@ class SpanTest { } @Test - fun `when span has throwable set set, it assigns itself to throwable on the Hub`() { + fun `when span has throwable set set, it assigns itself to throwable on the Scopes`() { val transaction = SentryTracer( TransactionContext("name", "op"), - fixture.hub + fixture.scopes ) val span = transaction.startChild("op") val ex = RuntimeException() span.throwable = ex span.finish() - verify(fixture.hub).setSpanContext(ex, span, "name") + verify(fixture.scopes).setSpanContext(ex, span, "name") } @Test @@ -188,7 +188,7 @@ class SpanTest { span.finish(SpanStatus.UNKNOWN_ERROR) // call only once - verify(fixture.hub).setSpanContext(any(), any(), any()) + verify(fixture.scopes).setSpanContext(any(), any(), any()) assertEquals(SpanStatus.OK, span.status) assertEquals(timestamp, span.finishDate) } @@ -496,7 +496,7 @@ class SpanTest { } private fun getTransaction(transactionContext: TransactionContext = TransactionContext("name", "op")): SentryTracer { - return SentryTracer(transactionContext, fixture.hub) + return SentryTracer(transactionContext, fixture.scopes) } private fun startChildFromSpan(): Span { diff --git a/sentry/src/test/java/io/sentry/TraceContextSerializationTest.kt b/sentry/src/test/java/io/sentry/TraceContextSerializationTest.kt index e79e5ebf8c..0847c9448f 100644 --- a/sentry/src/test/java/io/sentry/TraceContextSerializationTest.kt +++ b/sentry/src/test/java/io/sentry/TraceContextSerializationTest.kt @@ -54,10 +54,10 @@ class TraceContextSerializationTest { private fun createTraceContext(sRate: Double): TraceContext { val baggage = Baggage(fixture.logger) - val hub: IHub = mock() - whenever(hub.options).thenReturn(SentryOptions()) + val scopes: IScopes = mock() + whenever(scopes.options).thenReturn(SentryOptions()) baggage.setValuesFromTransaction( - SentryTracer(TransactionContext("name", "op"), hub), + SentryTracer(TransactionContext("name", "op"), scopes), User().apply { id = "user-id" others = mapOf("segment" to "pro") diff --git a/sentry/src/test/java/io/sentry/UncaughtExceptionHandlerIntegrationTest.kt b/sentry/src/test/java/io/sentry/UncaughtExceptionHandlerIntegrationTest.kt index 01353d5ac0..ec366e1901 100644 --- a/sentry/src/test/java/io/sentry/UncaughtExceptionHandlerIntegrationTest.kt +++ b/sentry/src/test/java/io/sentry/UncaughtExceptionHandlerIntegrationTest.kt @@ -30,7 +30,7 @@ class UncaughtExceptionHandlerIntegrationTest { val defaultHandler = mock() val thread = mock() val throwable = Throwable("test") - val hub = mock() + val scopes = mock() val options = SentryOptions() val logger = mock() @@ -63,17 +63,17 @@ class UncaughtExceptionHandlerIntegrationTest { fun `when uncaughtException is called, sentry captures exception`() { val sut = fixture.getSut(isPrintUncaughtStackTrace = false) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) sut.uncaughtException(fixture.thread, fixture.throwable) - verify(fixture.hub).captureEvent(any(), any()) + verify(fixture.scopes).captureEvent(any(), any()) } @Test fun `when register is called, current handler is not lost`() { val sut = fixture.getSut(hasDefaultHandler = true, isPrintUncaughtStackTrace = false) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) sut.uncaughtException(fixture.thread, fixture.throwable) verify(fixture.defaultHandler).uncaughtException(fixture.thread, fixture.throwable) @@ -81,7 +81,7 @@ class UncaughtExceptionHandlerIntegrationTest { @Test fun `when uncaughtException is called, exception captured has handled=false`() { - whenever(fixture.hub.captureException(any())).thenAnswer { invocation -> + whenever(fixture.scopes.captureException(any())).thenAnswer { invocation -> val e = invocation.getArgument(1) assertNotNull(e) assertNotNull(e.exceptionMechanism) @@ -91,22 +91,22 @@ class UncaughtExceptionHandlerIntegrationTest { val sut = fixture.getSut(isPrintUncaughtStackTrace = false) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) sut.uncaughtException(fixture.thread, fixture.throwable) - verify(fixture.hub).captureEvent(any(), any()) + verify(fixture.scopes).captureEvent(any(), any()) } @Test - fun `when hub is closed, integrations should be closed`() { + fun `when scopes is closed, integrations should be closed`() { val integrationMock = mock() val options = SentryOptions() options.dsn = "https://key@sentry.io/proj" options.addIntegration(integrationMock) options.cacheDirPath = fixture.file.absolutePath options.setSerializer(mock()) - val hub = Hub(options) - hub.close() + val scopes = Hub(options) + scopes.close() verify(integrationMock).close() } @@ -117,7 +117,7 @@ class UncaughtExceptionHandlerIntegrationTest { isPrintUncaughtStackTrace = false ) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.handler, never()).defaultUncaughtExceptionHandler = any() } @@ -126,7 +126,7 @@ class UncaughtExceptionHandlerIntegrationTest { fun `When defaultUncaughtExceptionHandler is enabled, should install Sentry UncaughtExceptionHandler`() { val sut = fixture.getSut(isPrintUncaughtStackTrace = false) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.handler).defaultUncaughtExceptionHandler = argWhere { it is UncaughtExceptionHandlerIntegration } @@ -136,7 +136,7 @@ class UncaughtExceptionHandlerIntegrationTest { fun `When defaultUncaughtExceptionHandler is set and integration is closed, default uncaught exception handler is reset to previous handler`() { val sut = fixture.getSut(hasDefaultHandler = true, isPrintUncaughtStackTrace = false) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) whenever(fixture.handler.defaultUncaughtExceptionHandler) .thenReturn(sut) sut.close() @@ -148,7 +148,7 @@ class UncaughtExceptionHandlerIntegrationTest { fun `When defaultUncaughtExceptionHandler is not set and integration is closed, default uncaught exception handler is reset to null`() { val sut = fixture.getSut(isPrintUncaughtStackTrace = false) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) whenever(fixture.handler.defaultUncaughtExceptionHandler) .thenReturn(sut) sut.close() @@ -165,7 +165,7 @@ class UncaughtExceptionHandlerIntegrationTest { val sut = fixture.getSut(isPrintUncaughtStackTrace = true) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) sut.uncaughtException(fixture.thread, RuntimeException("This should be printed!")) assertTrue( @@ -185,7 +185,7 @@ class UncaughtExceptionHandlerIntegrationTest { fun `waits for event to flush on disk`() { val capturedEventId = SentryId() - whenever(fixture.hub.captureEvent(any(), any())).thenAnswer { invocation -> + whenever(fixture.scopes.captureEvent(any(), any())).thenAnswer { invocation -> val hint = HintUtils.getSentrySdkHint(invocation.getArgument(1)) as DiskFlushNotification thread { @@ -197,10 +197,10 @@ class UncaughtExceptionHandlerIntegrationTest { val sut = fixture.getSut(flushTimeoutMillis = 5000) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) sut.uncaughtException(fixture.thread, fixture.throwable) - verify(fixture.hub).captureEvent(any(), any()) + verify(fixture.scopes).captureEvent(any(), any()) // shouldn't fall into timed out state, because we marked event as flushed on another thread verify(fixture.logger, never()).log( any(), @@ -211,14 +211,14 @@ class UncaughtExceptionHandlerIntegrationTest { @Test fun `does not block flushing when the event was dropped`() { - whenever(fixture.hub.captureEvent(any(), any())).thenReturn(SentryId.EMPTY_ID) + whenever(fixture.scopes.captureEvent(any(), any())).thenReturn(SentryId.EMPTY_ID) val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) sut.uncaughtException(fixture.thread, fixture.throwable) - verify(fixture.hub).captureEvent(any(), any()) + verify(fixture.scopes).captureEvent(any(), any()) // we do not call markFlushed, hence it should time out waiting for flush, but because // we drop the event, it should not even come to this if-check verify(fixture.logger, never()).log( @@ -231,17 +231,17 @@ class UncaughtExceptionHandlerIntegrationTest { @Test fun `waits for event to flush on disk if it was dropped by multithreaded deduplicator`() { val hintCaptor = argumentCaptor() - whenever(fixture.hub.captureEvent(any(), hintCaptor.capture())).thenAnswer { + whenever(fixture.scopes.captureEvent(any(), hintCaptor.capture())).thenAnswer { HintUtils.setEventDropReason(hintCaptor.firstValue, MULTITHREADED_DEDUPLICATION) return@thenAnswer SentryId.EMPTY_ID } val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) sut.uncaughtException(fixture.thread, fixture.throwable) - verify(fixture.hub).captureEvent(any(), any()) + verify(fixture.scopes).captureEvent(any(), any()) // we do not call markFlushed, even though we dropped the event, the reason was // MULTITHREADED_DEDUPLICATION, so it should time out verify(fixture.logger).log( @@ -254,15 +254,15 @@ class UncaughtExceptionHandlerIntegrationTest { @Test fun `when there is no active transaction on scope, sets current event id as flushable`() { val eventCaptor = argumentCaptor() - whenever(fixture.hub.captureEvent(eventCaptor.capture(), any())) + whenever(fixture.scopes.captureEvent(eventCaptor.capture(), any())) .thenReturn(SentryId.EMPTY_ID) val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) sut.uncaughtException(fixture.thread, fixture.throwable) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( any(), argThat { (HintUtils.getSentrySdkHint(this) as UncaughtExceptionHint) @@ -274,16 +274,16 @@ class UncaughtExceptionHandlerIntegrationTest { @Test fun `when there is active transaction on scope, does not set current event id as flushable`() { val eventCaptor = argumentCaptor() - whenever(fixture.hub.transaction).thenReturn(mock()) - whenever(fixture.hub.captureEvent(eventCaptor.capture(), any())) + whenever(fixture.scopes.transaction).thenReturn(mock()) + whenever(fixture.scopes.captureEvent(eventCaptor.capture(), any())) .thenReturn(SentryId.EMPTY_ID) val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) sut.uncaughtException(fixture.thread, fixture.throwable) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( any(), argThat { !(HintUtils.getSentrySdkHint(this) as UncaughtExceptionHint) diff --git a/sentry/src/test/java/io/sentry/backpressure/BackpressureMonitorTest.kt b/sentry/src/test/java/io/sentry/backpressure/BackpressureMonitorTest.kt index c010c97238..cf234574bf 100644 --- a/sentry/src/test/java/io/sentry/backpressure/BackpressureMonitorTest.kt +++ b/sentry/src/test/java/io/sentry/backpressure/BackpressureMonitorTest.kt @@ -1,6 +1,6 @@ package io.sentry.backpressure -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ISentryExecutorService import io.sentry.SentryOptions import io.sentry.backpressure.BackpressureMonitor.MAX_DOWNSAMPLE_FACTOR @@ -17,13 +17,13 @@ class BackpressureMonitorTest { class Fixture { val options = SentryOptions() - val hub = mock() + val scopes = mock() val executor = mock() fun getSut(): BackpressureMonitor { options.executorService = executor whenever(executor.isClosed).thenReturn(false) whenever(executor.schedule(any(), any())).thenReturn(mock>()) - return BackpressureMonitor(options, hub) + return BackpressureMonitor(options, scopes) } } @@ -38,7 +38,7 @@ class BackpressureMonitorTest { @Test fun `downsampleFactor increases with negative health checks up to max`() { val sut = fixture.getSut() - whenever(fixture.hub.isHealthy).thenReturn(false) + whenever(fixture.scopes.isHealthy).thenReturn(false) assertEquals(0, sut.downsampleFactor) (1..MAX_DOWNSAMPLE_FACTOR).forEach { i -> @@ -54,13 +54,13 @@ class BackpressureMonitorTest { @Test fun `downsampleFactor goes back to 0 after positive health check`() { val sut = fixture.getSut() - whenever(fixture.hub.isHealthy).thenReturn(false) + whenever(fixture.scopes.isHealthy).thenReturn(false) assertEquals(0, sut.downsampleFactor) sut.checkHealth() assertEquals(1, sut.downsampleFactor) - whenever(fixture.hub.isHealthy).thenReturn(true) + whenever(fixture.scopes.isHealthy).thenReturn(true) sut.checkHealth() assertEquals(0, sut.downsampleFactor) } diff --git a/sentry/src/test/java/io/sentry/clientreport/ClientReportTest.kt b/sentry/src/test/java/io/sentry/clientreport/ClientReportTest.kt index b4615cac76..d27e5c0228 100644 --- a/sentry/src/test/java/io/sentry/clientreport/ClientReportTest.kt +++ b/sentry/src/test/java/io/sentry/clientreport/ClientReportTest.kt @@ -7,7 +7,7 @@ import io.sentry.DataCategory import io.sentry.DateUtils import io.sentry.EventProcessor import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.NoOpLogger import io.sentry.ProfilingTraceData import io.sentry.Sentry @@ -47,9 +47,9 @@ class ClientReportTest { @Test fun `lost envelope can be recorded`() { givenClientReportRecorder() - val hub = mock() - whenever(hub.options).thenReturn(opts) - val transaction = SentryTracer(TransactionContext("name", "op"), hub) + val scopes = mock() + whenever(scopes.options).thenReturn(opts) + val transaction = SentryTracer(TransactionContext("name", "op"), scopes) val lostClientReport = ClientReport( DateUtils.getCurrentDateTime(), diff --git a/sentry/src/test/java/io/sentry/instrumentation/file/FileIOSpanManagerTest.kt b/sentry/src/test/java/io/sentry/instrumentation/file/FileIOSpanManagerTest.kt index 00c89f27be..f6271b5b5e 100644 --- a/sentry/src/test/java/io/sentry/instrumentation/file/FileIOSpanManagerTest.kt +++ b/sentry/src/test/java/io/sentry/instrumentation/file/FileIOSpanManagerTest.kt @@ -1,6 +1,6 @@ package io.sentry.instrumentation.file -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ISpan import io.sentry.ITransaction import io.sentry.util.PlatformTestManipulator @@ -20,25 +20,25 @@ class FileIOSpanManagerTest { @Test fun `startSpan uses transaction on Android platform`() { - val hub = mock() + val scopes = mock() val transaction = mock() - whenever(hub.transaction).thenReturn(transaction) + whenever(scopes.transaction).thenReturn(transaction) PlatformTestManipulator.pretendIsAndroid(true) - FileIOSpanManager.startSpan(hub, "op.read") + FileIOSpanManager.startSpan(scopes, "op.read") verify(transaction).startChild(any()) } @Test fun `startSpan uses last span on non-Android platforms`() { - val hub = mock() + val scopes = mock() val span = mock() - whenever(hub.span).thenReturn(span) + whenever(scopes.span).thenReturn(span) PlatformTestManipulator.pretendIsAndroid(false) - FileIOSpanManager.startSpan(hub, "op.read") + FileIOSpanManager.startSpan(scopes, "op.read") verify(span).startChild(any()) } } diff --git a/sentry/src/test/java/io/sentry/instrumentation/file/SentryFileInputStreamTest.kt b/sentry/src/test/java/io/sentry/instrumentation/file/SentryFileInputStreamTest.kt index 5e27eb451d..063b6d6428 100644 --- a/sentry/src/test/java/io/sentry/instrumentation/file/SentryFileInputStreamTest.kt +++ b/sentry/src/test/java/io/sentry/instrumentation/file/SentryFileInputStreamTest.kt @@ -1,6 +1,6 @@ package io.sentry.instrumentation.file -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryOptions import io.sentry.SentryTracer import io.sentry.SpanDataConvention @@ -29,7 +29,7 @@ import kotlin.test.assertTrue class SentryFileInputStreamTest { class Fixture { - val hub = mock() + val scopes = mock() lateinit var sentryTracer: SentryTracer private val options = SentryOptions() @@ -40,21 +40,21 @@ class SentryFileInputStreamTest { sendDefaultPii: Boolean = false ): SentryFileInputStream { tmpFile?.writeText("Text") - whenever(hub.options).thenReturn( + whenever(scopes.options).thenReturn( options.apply { isSendDefaultPii = sendDefaultPii mainThreadChecker = MainThreadChecker.getInstance() addInAppInclude("org.junit") } ) - sentryTracer = SentryTracer(TransactionContext("name", "op"), hub) + sentryTracer = SentryTracer(TransactionContext("name", "op"), scopes) if (activeTransaction) { - whenever(hub.span).thenReturn(sentryTracer) + whenever(scopes.span).thenReturn(sentryTracer) } return if (fileDescriptor == null) { - SentryFileInputStream(tmpFile, hub) + SentryFileInputStream(tmpFile, scopes) } else { - SentryFileInputStream(fileDescriptor, hub) + SentryFileInputStream(fileDescriptor, scopes) } } @@ -62,13 +62,13 @@ class SentryFileInputStreamTest { tmpFile: File? = null, delegate: FileInputStream ): SentryFileInputStream { - whenever(hub.options).thenReturn(options) - sentryTracer = SentryTracer(TransactionContext("name", "op"), hub) - whenever(hub.span).thenReturn(sentryTracer) + whenever(scopes.options).thenReturn(options) + sentryTracer = SentryTracer(TransactionContext("name", "op"), scopes) + whenever(scopes.span).thenReturn(sentryTracer) return SentryFileInputStream.Factory.create( delegate, tmpFile, - hub + scopes ) as SentryFileInputStream } } diff --git a/sentry/src/test/java/io/sentry/instrumentation/file/SentryFileOutputStreamTest.kt b/sentry/src/test/java/io/sentry/instrumentation/file/SentryFileOutputStreamTest.kt index f6a09830c2..8b175adc2d 100644 --- a/sentry/src/test/java/io/sentry/instrumentation/file/SentryFileOutputStreamTest.kt +++ b/sentry/src/test/java/io/sentry/instrumentation/file/SentryFileOutputStreamTest.kt @@ -1,6 +1,6 @@ package io.sentry.instrumentation.file -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryOptions import io.sentry.SentryTracer import io.sentry.SpanDataConvention @@ -24,7 +24,7 @@ import kotlin.test.assertTrue class SentryFileOutputStreamTest { class Fixture { - val hub = mock() + val scopes = mock() lateinit var sentryTracer: SentryTracer internal fun getSut( @@ -32,17 +32,17 @@ class SentryFileOutputStreamTest { activeTransaction: Boolean = true, append: Boolean = false ): SentryFileOutputStream { - whenever(hub.options).thenReturn( + whenever(scopes.options).thenReturn( SentryOptions().apply { mainThreadChecker = MainThreadChecker.getInstance() addInAppInclude("org.junit") } ) - sentryTracer = SentryTracer(TransactionContext("name", "op"), hub) + sentryTracer = SentryTracer(TransactionContext("name", "op"), scopes) if (activeTransaction) { - whenever(hub.span).thenReturn(sentryTracer) + whenever(scopes.span).thenReturn(sentryTracer) } - return SentryFileOutputStream(tmpFile, append, hub) + return SentryFileOutputStream(tmpFile, append, scopes) } } diff --git a/sentry/src/test/java/io/sentry/instrumentation/file/SentryFileReaderTest.kt b/sentry/src/test/java/io/sentry/instrumentation/file/SentryFileReaderTest.kt index 2485579e7a..38781d718b 100644 --- a/sentry/src/test/java/io/sentry/instrumentation/file/SentryFileReaderTest.kt +++ b/sentry/src/test/java/io/sentry/instrumentation/file/SentryFileReaderTest.kt @@ -1,6 +1,6 @@ package io.sentry.instrumentation.file -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryOptions import io.sentry.SentryTracer import io.sentry.SpanDataConvention @@ -17,7 +17,7 @@ import kotlin.test.assertEquals class SentryFileReaderTest { class Fixture { - val hub = mock() + val scopes = mock() lateinit var sentryTracer: SentryTracer internal fun getSut( @@ -25,16 +25,16 @@ class SentryFileReaderTest { activeTransaction: Boolean = true ): SentryFileReader { tmpFile.writeText("TEXT") - whenever(hub.options).thenReturn( + whenever(scopes.options).thenReturn( SentryOptions().apply { mainThreadChecker = MainThreadChecker.getInstance() } ) - sentryTracer = SentryTracer(TransactionContext("name", "op"), hub) + sentryTracer = SentryTracer(TransactionContext("name", "op"), scopes) if (activeTransaction) { - whenever(hub.span).thenReturn(sentryTracer) + whenever(scopes.span).thenReturn(sentryTracer) } - return SentryFileReader(tmpFile, hub) + return SentryFileReader(tmpFile, scopes) } } diff --git a/sentry/src/test/java/io/sentry/instrumentation/file/SentryFileWriterTest.kt b/sentry/src/test/java/io/sentry/instrumentation/file/SentryFileWriterTest.kt index f0738d8725..8f3d96b4d7 100644 --- a/sentry/src/test/java/io/sentry/instrumentation/file/SentryFileWriterTest.kt +++ b/sentry/src/test/java/io/sentry/instrumentation/file/SentryFileWriterTest.kt @@ -1,6 +1,6 @@ package io.sentry.instrumentation.file -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryOptions import io.sentry.SentryTracer import io.sentry.SpanDataConvention @@ -17,7 +17,7 @@ import kotlin.test.assertEquals class SentryFileWriterTest { class Fixture { - val hub = mock() + val scopes = mock() lateinit var sentryTracer: SentryTracer internal fun getSut( @@ -25,16 +25,16 @@ class SentryFileWriterTest { activeTransaction: Boolean = true, append: Boolean = false ): SentryFileWriter { - whenever(hub.options).thenReturn( + whenever(scopes.options).thenReturn( SentryOptions().apply { mainThreadChecker = MainThreadChecker.getInstance() } ) - sentryTracer = SentryTracer(TransactionContext("name", "op"), hub) + sentryTracer = SentryTracer(TransactionContext("name", "op"), scopes) if (activeTransaction) { - whenever(hub.span).thenReturn(sentryTracer) + whenever(scopes.span).thenReturn(sentryTracer) } - return SentryFileWriter(tmpFile, append, hub) + return SentryFileWriter(tmpFile, append, scopes) } } diff --git a/sentry/src/test/java/io/sentry/internal/SpotlightIntegrationTest.kt b/sentry/src/test/java/io/sentry/internal/SpotlightIntegrationTest.kt index 73aa339f26..0a91bec562 100644 --- a/sentry/src/test/java/io/sentry/internal/SpotlightIntegrationTest.kt +++ b/sentry/src/test/java/io/sentry/internal/SpotlightIntegrationTest.kt @@ -1,6 +1,6 @@ package io.sentry.internal -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryOptions import io.sentry.SentryOptions.BeforeEnvelopeCallback import io.sentry.SpotlightIntegration @@ -19,7 +19,7 @@ class SpotlightIntegrationTest { } val spotlight = SpotlightIntegration() - spotlight.register(mock(), options) + spotlight.register(mock(), options) assertNull(options.beforeEnvelopeCallback) } @@ -33,7 +33,7 @@ class SpotlightIntegrationTest { } val spotlight = SpotlightIntegration() - spotlight.register(mock(), options) + spotlight.register(mock(), options) assertEquals(envelopeCallback, options.beforeEnvelopeCallback) } @@ -45,7 +45,7 @@ class SpotlightIntegrationTest { } val spotlight = SpotlightIntegration() - spotlight.register(mock(), options) + spotlight.register(mock(), options) assertEquals(options.beforeEnvelopeCallback, spotlight) spotlight.close() @@ -71,7 +71,7 @@ class SpotlightIntegrationTest { } val spotlight = SpotlightIntegration() - spotlight.register(mock(), options) + spotlight.register(mock(), options) assertEquals("http://example.com:1234/stream", spotlight.spotlightConnectionUrl) } diff --git a/sentry/src/test/java/io/sentry/protocol/SentrySpanTest.kt b/sentry/src/test/java/io/sentry/protocol/SentrySpanTest.kt index 27499be0a0..d67b0186be 100644 --- a/sentry/src/test/java/io/sentry/protocol/SentrySpanTest.kt +++ b/sentry/src/test/java/io/sentry/protocol/SentrySpanTest.kt @@ -1,6 +1,6 @@ package io.sentry.protocol -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryLongDate import io.sentry.SentryTracer import io.sentry.Span @@ -19,7 +19,7 @@ class SentrySpanTest { val span = Span( TransactionContext("name", "op"), mock(), - mock(), + mock(), SentryLongDate(1000000), SpanOptions() ) diff --git a/sentry/src/test/java/io/sentry/transport/RateLimiterTest.kt b/sentry/src/test/java/io/sentry/transport/RateLimiterTest.kt index d9e217b0ac..2b1be98611 100644 --- a/sentry/src/test/java/io/sentry/transport/RateLimiterTest.kt +++ b/sentry/src/test/java/io/sentry/transport/RateLimiterTest.kt @@ -4,7 +4,7 @@ import io.sentry.Attachment import io.sentry.CheckIn import io.sentry.CheckInStatus import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ISerializer import io.sentry.NoOpLogger import io.sentry.ProfilingTraceData @@ -80,10 +80,10 @@ class RateLimiterTest { fun `parse X-Sentry-Rate-Limit and set its values and retry after should be true`() { val rateLimiter = fixture.getSUT() whenever(fixture.currentDateProvider.currentTimeMillis).thenReturn(0) - val hub: IHub = mock() - whenever(hub.options).thenReturn(SentryOptions()) + val scopes: IScopes = mock() + whenever(scopes.options).thenReturn(SentryOptions()) val eventItem = SentryEnvelopeItem.fromEvent(fixture.serializer, SentryEvent()) - val transaction = SentryTransaction(SentryTracer(TransactionContext("name", "op"), hub)) + val transaction = SentryTransaction(SentryTracer(TransactionContext("name", "op"), scopes)) val transactionItem = SentryEnvelopeItem.fromEvent(fixture.serializer, transaction) val envelope = SentryEnvelope(SentryEnvelopeHeader(), arrayListOf(eventItem, transactionItem)) @@ -97,10 +97,10 @@ class RateLimiterTest { fun `parse X-Sentry-Rate-Limit and set its values and retry after should be false`() { val rateLimiter = fixture.getSUT() whenever(fixture.currentDateProvider.currentTimeMillis).thenReturn(0, 0, 1001) - val hub: IHub = mock() - whenever(hub.options).thenReturn(SentryOptions()) + val scopes: IScopes = mock() + whenever(scopes.options).thenReturn(SentryOptions()) val eventItem = SentryEnvelopeItem.fromEvent(fixture.serializer, SentryEvent()) - val transaction = SentryTransaction(SentryTracer(TransactionContext("name", "op"), hub)) + val transaction = SentryTransaction(SentryTracer(TransactionContext("name", "op"), scopes)) val transactionItem = SentryEnvelopeItem.fromEvent(fixture.serializer, transaction) val envelope = SentryEnvelope(SentryEnvelopeHeader(), arrayListOf(eventItem, transactionItem)) @@ -191,9 +191,9 @@ class RateLimiterTest { it.setName("John Me") } ) - val hub = mock() - whenever(hub.options).thenReturn(SentryOptions()) - val transaction = SentryTracer(TransactionContext("name", "op"), hub) + val scopes = mock() + whenever(scopes.options).thenReturn(SentryOptions()) + val transaction = SentryTracer(TransactionContext("name", "op"), scopes) val sessionItem = SentryEnvelopeItem.fromSession(fixture.serializer, Session("123", User(), "env", "release")) val attachmentItem = SentryEnvelopeItem.fromAttachment(fixture.serializer, NoOpLogger.getInstance(), Attachment("{ \"number\": 10 }".toByteArray(), "log.json"), 1000) @@ -219,8 +219,8 @@ class RateLimiterTest { @Test fun `records only dropped items as lost`() { val rateLimiter = fixture.getSUT() - val hub = mock() - whenever(hub.options).thenReturn(SentryOptions()) + val scopes = mock() + whenever(scopes.options).thenReturn(SentryOptions()) val eventItem = SentryEnvelopeItem.fromEvent(fixture.serializer, SentryEvent()) val userFeedbackItem = SentryEnvelopeItem.fromUserFeedback( @@ -233,7 +233,7 @@ class RateLimiterTest { it.setName("John Me") } ) - val transaction = SentryTracer(TransactionContext("name", "op"), hub) + val transaction = SentryTracer(TransactionContext("name", "op"), scopes) val profileItem = SentryEnvelopeItem.fromProfilingTrace(ProfilingTraceData(File(""), transaction), 1000, fixture.serializer) val sessionItem = SentryEnvelopeItem.fromSession(fixture.serializer, Session("123", User(), "env", "release")) val attachmentItem = SentryEnvelopeItem.fromAttachment(fixture.serializer, NoOpLogger.getInstance(), Attachment("{ \"number\": 10 }".toByteArray(), "log.json"), 1000) @@ -253,12 +253,12 @@ class RateLimiterTest { @Test fun `drop profile items as lost`() { val rateLimiter = fixture.getSUT() - val hub = mock() - whenever(hub.options).thenReturn(SentryOptions()) + val scopes = mock() + whenever(scopes.options).thenReturn(SentryOptions()) val eventItem = SentryEnvelopeItem.fromEvent(fixture.serializer, SentryEvent()) val f = File.createTempFile("test", "trace") - val transaction = SentryTracer(TransactionContext("name", "op"), hub) + val transaction = SentryTracer(TransactionContext("name", "op"), scopes) val profileItem = SentryEnvelopeItem.fromProfilingTrace(ProfilingTraceData(f, transaction), 1000, fixture.serializer) val envelope = SentryEnvelope(SentryEnvelopeHeader(), arrayListOf(eventItem, profileItem)) diff --git a/sentry/src/test/java/io/sentry/util/CheckInUtilsTest.kt b/sentry/src/test/java/io/sentry/util/CheckInUtilsTest.kt index a285cd5832..9f330348b0 100644 --- a/sentry/src/test/java/io/sentry/util/CheckInUtilsTest.kt +++ b/sentry/src/test/java/io/sentry/util/CheckInUtilsTest.kt @@ -1,7 +1,8 @@ package io.sentry.util import io.sentry.CheckInStatus -import io.sentry.IHub +import io.sentry.HubScopesWrapper +import io.sentry.IScopes import io.sentry.MonitorConfig import io.sentry.MonitorSchedule import io.sentry.MonitorScheduleUnit @@ -56,30 +57,31 @@ class CheckInUtilsTest { @Test fun `sends check-in for wrapped supplier`() { Mockito.mockStatic(Sentry::class.java).use { sentry -> - val hub = mock() - sentry.`when` { Sentry.getCurrentHub() }.thenReturn(hub) - whenever(hub.options).thenReturn(SentryOptions()) + val scopes = mock() + sentry.`when` { Sentry.getCurrentScopes() }.thenReturn(scopes) + sentry.`when` { Sentry.getCurrentHub() }.thenReturn(HubScopesWrapper(scopes)) + whenever(scopes.options).thenReturn(SentryOptions()) val returnValue = CheckInUtils.withCheckIn("monitor-1") { return@withCheckIn "test1" } assertEquals("test1", returnValue) - inOrder(hub) { - verify(hub).pushScope() - verify(hub).configureScope(any()) - verify(hub).captureCheckIn( + inOrder(scopes) { + verify(scopes).pushScope() + verify(scopes).configureScope(any()) + verify(scopes).captureCheckIn( check { assertEquals("monitor-1", it.monitorSlug) assertEquals(CheckInStatus.IN_PROGRESS.apiName(), it.status) } ) - verify(hub).captureCheckIn( + verify(scopes).captureCheckIn( check { assertEquals("monitor-1", it.monitorSlug) assertEquals(CheckInStatus.OK.apiName(), it.status) } ) - verify(hub).popScope() + verify(scopes).popScope() } } } @@ -87,8 +89,9 @@ class CheckInUtilsTest { @Test fun `sends check-in for wrapped supplier with exception`() { Mockito.mockStatic(Sentry::class.java).use { sentry -> - val hub = mock() - sentry.`when` { Sentry.getCurrentHub() }.thenReturn(hub) + val scopes = mock() + sentry.`when` { Sentry.getCurrentScopes() }.thenReturn(scopes) + sentry.`when` { Sentry.getCurrentHub() }.thenReturn(HubScopesWrapper(scopes)) try { CheckInUtils.withCheckIn("monitor-1") { @@ -99,22 +102,22 @@ class CheckInUtilsTest { assertEquals("thrown on purpose", e.message) } - inOrder(hub) { - verify(hub).pushScope() - verify(hub).configureScope(any()) - verify(hub).captureCheckIn( + inOrder(scopes) { + verify(scopes).pushScope() + verify(scopes).configureScope(any()) + verify(scopes).captureCheckIn( check { assertEquals("monitor-1", it.monitorSlug) assertEquals(CheckInStatus.IN_PROGRESS.apiName(), it.status) } ) - verify(hub).captureCheckIn( + verify(scopes).captureCheckIn( check { assertEquals("monitor-1", it.monitorSlug) assertEquals(CheckInStatus.ERROR.apiName(), it.status) } ) - verify(hub).popScope() + verify(scopes).popScope() } } } @@ -122,32 +125,33 @@ class CheckInUtilsTest { @Test fun `sends check-in for wrapped supplier with upsert`() { Mockito.mockStatic(Sentry::class.java).use { sentry -> - val hub = mock() - sentry.`when` { Sentry.getCurrentHub() }.thenReturn(hub) - whenever(hub.options).thenReturn(SentryOptions()) + val scopes = mock() + sentry.`when` { Sentry.getCurrentScopes() }.thenReturn(scopes) + sentry.`when` { Sentry.getCurrentHub() }.thenReturn(HubScopesWrapper(scopes)) + whenever(scopes.options).thenReturn(SentryOptions()) val monitorConfig = MonitorConfig(MonitorSchedule.interval(7, MonitorScheduleUnit.DAY)) val returnValue = CheckInUtils.withCheckIn("monitor-1", monitorConfig) { "test1" } assertEquals("test1", returnValue) - inOrder(hub) { - verify(hub).pushScope() - verify(hub).configureScope(any()) - verify(hub).captureCheckIn( + inOrder(scopes) { + verify(scopes).pushScope() + verify(scopes).configureScope(any()) + verify(scopes).captureCheckIn( check { assertEquals("monitor-1", it.monitorSlug) assertSame(monitorConfig, it.monitorConfig) assertEquals(CheckInStatus.IN_PROGRESS.apiName(), it.status) } ) - verify(hub).captureCheckIn( + verify(scopes).captureCheckIn( check { assertEquals("monitor-1", it.monitorSlug) assertEquals(CheckInStatus.OK.apiName(), it.status) } ) - verify(hub).popScope() + verify(scopes).popScope() } } } @@ -155,9 +159,10 @@ class CheckInUtilsTest { @Test fun `sends check-in for wrapped supplier with upsert and thresholds`() { Mockito.mockStatic(Sentry::class.java).use { sentry -> - val hub = mock() - sentry.`when` { Sentry.getCurrentHub() }.thenReturn(hub) - whenever(hub.options).thenReturn(SentryOptions()) + val scopes = mock() + sentry.`when` { Sentry.getCurrentScopes() }.thenReturn(scopes) + sentry.`when` { Sentry.getCurrentHub() }.thenReturn(HubScopesWrapper(scopes)) + whenever(scopes.options).thenReturn(SentryOptions()) val monitorConfig = MonitorConfig(MonitorSchedule.interval(7, MonitorScheduleUnit.DAY)).apply { failureIssueThreshold = 10 recoveryThreshold = 20 @@ -167,23 +172,23 @@ class CheckInUtilsTest { } assertEquals("test1", returnValue) - inOrder(hub) { - verify(hub).pushScope() - verify(hub).configureScope(any()) - verify(hub).captureCheckIn( + inOrder(scopes) { + verify(scopes).pushScope() + verify(scopes).configureScope(any()) + verify(scopes).captureCheckIn( check { assertEquals("monitor-1", it.monitorSlug) assertSame(monitorConfig, it.monitorConfig) assertEquals(CheckInStatus.IN_PROGRESS.apiName(), it.status) } ) - verify(hub).captureCheckIn( + verify(scopes).captureCheckIn( check { assertEquals("monitor-1", it.monitorSlug) assertEquals(CheckInStatus.OK.apiName(), it.status) } ) - verify(hub).popScope() + verify(scopes).popScope() } } } @@ -191,9 +196,10 @@ class CheckInUtilsTest { @Test fun `sets defaults for MonitorConfig from SentryOptions`() { Mockito.mockStatic(Sentry::class.java).use { sentry -> - val hub = mock() - sentry.`when` { Sentry.getCurrentHub() }.thenReturn(hub) - whenever(hub.options).thenReturn( + val scopes = mock() + sentry.`when` { Sentry.getCurrentScopes() }.thenReturn(scopes) + sentry.`when` { Sentry.getCurrentHub() }.thenReturn(HubScopesWrapper(scopes)) + whenever(scopes.options).thenReturn( SentryOptions().apply { cron = SentryOptions.Cron().apply { defaultCheckinMargin = 20 @@ -218,9 +224,10 @@ class CheckInUtilsTest { @Test fun `defaults for MonitorConfig from SentryOptions can be overridden`() { Mockito.mockStatic(Sentry::class.java).use { sentry -> - val hub = mock() - sentry.`when` { Sentry.getCurrentHub() }.thenReturn(hub) - whenever(hub.options).thenReturn( + val scopes = mock() + sentry.`when` { Sentry.getCurrentScopes() }.thenReturn(scopes) + sentry.`when` { Sentry.getCurrentHub() }.thenReturn(HubScopesWrapper(scopes)) + whenever(scopes.options).thenReturn( SentryOptions().apply { cron = SentryOptions.Cron().apply { defaultCheckinMargin = 20 diff --git a/sentry/src/test/java/io/sentry/util/TracingUtilsTest.kt b/sentry/src/test/java/io/sentry/util/TracingUtilsTest.kt index e38410641e..b3f640aeec 100644 --- a/sentry/src/test/java/io/sentry/util/TracingUtilsTest.kt +++ b/sentry/src/test/java/io/sentry/util/TracingUtilsTest.kt @@ -1,7 +1,7 @@ package io.sentry.util import io.sentry.Baggage -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.NoOpSpan import io.sentry.Scope import io.sentry.ScopeCallback @@ -29,18 +29,18 @@ class TracingUtilsTest { val options = SentryOptions().apply { dsn = "https://key@sentry.io/proj" } - val hub = mock() + val scopes = mock() val scope = Scope(options) lateinit var span: Span val preExistingBaggage = listOf("some-baggage-key=some-baggage-value") fun setup() { - whenever(hub.options).thenReturn(options) - doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(hub).configureScope(any()) + whenever(scopes.options).thenReturn(options) + doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(scopes).configureScope(any()) span = Span( TransactionContext("name", "op", TracesSamplingDecision(true)), - SentryTracer(TransactionContext("name", "op", TracesSamplingDecision(true)), hub), - hub, + SentryTracer(TransactionContext("name", "op", TracesSamplingDecision(true)), scopes), + scopes, null, SpanOptions() ) @@ -53,7 +53,7 @@ class TracingUtilsTest { fun `returns headers if allowed from scope without span`() { fixture.setup() - val headers = TracingUtils.traceIfAllowed(fixture.hub, "https://sentry.io/hello", fixture.preExistingBaggage, null) + val headers = TracingUtils.traceIfAllowed(fixture.scopes, "https://sentry.io/hello", fixture.preExistingBaggage, null) assertNotNull(headers) assertNotNull(headers.baggageHeader) @@ -68,7 +68,7 @@ class TracingUtilsTest { fun `returns headers if allowed from scope if span is noop`() { fixture.setup() - val headers = TracingUtils.traceIfAllowed(fixture.hub, "https://sentry.io/hello", fixture.preExistingBaggage, NoOpSpan.getInstance()) + val headers = TracingUtils.traceIfAllowed(fixture.scopes, "https://sentry.io/hello", fixture.preExistingBaggage, NoOpSpan.getInstance()) assertNotNull(headers) assertNotNull(headers.baggageHeader) @@ -83,7 +83,7 @@ class TracingUtilsTest { fixture.scope.propagationContext.baggage = Baggage.fromHeader("sentry-public_key=502f25099c204a2fbf4cb16edc5975d1,sentry-sample_rate=1,sentry-trace_id=2722d9f6ec019ade60c776169d9a8904,sentry-transaction=HTTP%20GET").also { it.freeze() } fixture.setup() - val headers = TracingUtils.traceIfAllowed(fixture.hub, "https://sentry.io/hello", fixture.preExistingBaggage, null) + val headers = TracingUtils.traceIfAllowed(fixture.scopes, "https://sentry.io/hello", fixture.preExistingBaggage, null) assertNotNull(headers) assertNotNull(headers.baggageHeader) @@ -98,7 +98,7 @@ class TracingUtilsTest { fun `returns headers if allowed from span`() { fixture.setup() - val headers = TracingUtils.traceIfAllowed(fixture.hub, "https://sentry.io/hello", fixture.preExistingBaggage, fixture.span) + val headers = TracingUtils.traceIfAllowed(fixture.scopes, "https://sentry.io/hello", fixture.preExistingBaggage, fixture.span) assertNotNull(headers) assertNotNull(headers.baggageHeader) @@ -112,7 +112,7 @@ class TracingUtilsTest { fixture.options.isTraceSampling = false fixture.setup() - val headers = TracingUtils.traceIfAllowed(fixture.hub, "https://sentry.io/hello", fixture.preExistingBaggage, null) + val headers = TracingUtils.traceIfAllowed(fixture.scopes, "https://sentry.io/hello", fixture.preExistingBaggage, null) assertNull(headers) } @@ -122,7 +122,7 @@ class TracingUtilsTest { fixture.options.isTraceSampling = false fixture.setup() - val headers = TracingUtils.traceIfAllowed(fixture.hub, "https://sentry.io/hello", fixture.preExistingBaggage, fixture.span) + val headers = TracingUtils.traceIfAllowed(fixture.scopes, "https://sentry.io/hello", fixture.preExistingBaggage, fixture.span) assertNull(headers) } @@ -132,7 +132,7 @@ class TracingUtilsTest { fixture.options.setTracePropagationTargets(listOf("some-host-that-does-not-exist")) fixture.setup() - val headers = TracingUtils.traceIfAllowed(fixture.hub, "https://sentry.io/hello", fixture.preExistingBaggage, null) + val headers = TracingUtils.traceIfAllowed(fixture.scopes, "https://sentry.io/hello", fixture.preExistingBaggage, null) assertNull(headers) } @@ -142,7 +142,7 @@ class TracingUtilsTest { fixture.options.setTracePropagationTargets(listOf("some-host-that-does-not-exist")) fixture.setup() - val headers = TracingUtils.traceIfAllowed(fixture.hub, "https://sentry.io/hello", fixture.preExistingBaggage, fixture.span) + val headers = TracingUtils.traceIfAllowed(fixture.scopes, "https://sentry.io/hello", fixture.preExistingBaggage, fixture.span) assertNull(headers) } @@ -153,7 +153,7 @@ class TracingUtilsTest { val propagationContextBefore = fixture.scope.propagationContext - TracingUtils.startNewTrace(fixture.hub) + TracingUtils.startNewTrace(fixture.scopes) assertNotEquals(propagationContextBefore.traceId, fixture.scope.propagationContext.traceId) assertNotEquals(propagationContextBefore.spanId, fixture.scope.propagationContext.spanId) From 95f5e1b1cd14bde66225c89446d89e7b9cde7156 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Tue, 2 Apr 2024 13:53:29 +0200 Subject: [PATCH 02/28] Add Scopes --- sentry/api/sentry.api | 76 ++ sentry/src/main/java/io/sentry/IScope.java | 11 + sentry/src/main/java/io/sentry/NoOpScope.java | 17 + sentry/src/main/java/io/sentry/Scope.java | 28 + sentry/src/main/java/io/sentry/Scopes.java | 1093 +++++++++++++++++ sentry/src/main/java/io/sentry/Sentry.java | 8 +- 6 files changed, 1231 insertions(+), 2 deletions(-) create mode 100644 sentry/src/main/java/io/sentry/Scopes.java diff --git a/sentry/api/sentry.api b/sentry/api/sentry.api index 52eb5df888..24935be274 100644 --- a/sentry/api/sentry.api +++ b/sentry/api/sentry.api @@ -661,10 +661,12 @@ public abstract interface class io/sentry/IScope { public abstract fun endSession ()Lio/sentry/Session; public abstract fun getAttachments ()Ljava/util/List; public abstract fun getBreadcrumbs ()Ljava/util/Queue; + public abstract fun getClient ()Lio/sentry/ISentryClient; public abstract fun getContexts ()Lio/sentry/protocol/Contexts; public abstract fun getEventProcessors ()Ljava/util/List; public abstract fun getExtras ()Ljava/util/Map; public abstract fun getFingerprint ()Ljava/util/List; + public abstract fun getLastEventId ()Lio/sentry/protocol/SentryId; public abstract fun getLevel ()Lio/sentry/SentryLevel; public abstract fun getOptions ()Lio/sentry/SentryOptions; public abstract fun getPropagationContext ()Lio/sentry/PropagationContext; @@ -679,6 +681,7 @@ public abstract interface class io/sentry/IScope { public abstract fun removeContexts (Ljava/lang/String;)V public abstract fun removeExtra (Ljava/lang/String;)V public abstract fun removeTag (Ljava/lang/String;)V + public abstract fun setClient (Lio/sentry/ISentryClient;)V public abstract fun setContexts (Ljava/lang/String;Ljava/lang/Boolean;)V public abstract fun setContexts (Ljava/lang/String;Ljava/lang/Character;)V public abstract fun setContexts (Ljava/lang/String;Ljava/lang/Number;)V @@ -688,6 +691,7 @@ public abstract interface class io/sentry/IScope { public abstract fun setContexts (Ljava/lang/String;[Ljava/lang/Object;)V public abstract fun setExtra (Ljava/lang/String;Ljava/lang/String;)V public abstract fun setFingerprint (Ljava/util/List;)V + public abstract fun setLastEventId (Lio/sentry/protocol/SentryId;)V public abstract fun setLevel (Lio/sentry/SentryLevel;)V public abstract fun setPropagationContext (Lio/sentry/PropagationContext;)V public abstract fun setRequest (Lio/sentry/protocol/Request;)V @@ -1286,11 +1290,13 @@ public final class io/sentry/NoOpScope : io/sentry/IScope { public fun endSession ()Lio/sentry/Session; public fun getAttachments ()Ljava/util/List; public fun getBreadcrumbs ()Ljava/util/Queue; + public fun getClient ()Lio/sentry/ISentryClient; public fun getContexts ()Lio/sentry/protocol/Contexts; public fun getEventProcessors ()Ljava/util/List; public fun getExtras ()Ljava/util/Map; public fun getFingerprint ()Ljava/util/List; public static fun getInstance ()Lio/sentry/NoOpScope; + public fun getLastEventId ()Lio/sentry/protocol/SentryId; public fun getLevel ()Lio/sentry/SentryLevel; public fun getOptions ()Lio/sentry/SentryOptions; public fun getPropagationContext ()Lio/sentry/PropagationContext; @@ -1305,6 +1311,7 @@ public final class io/sentry/NoOpScope : io/sentry/IScope { public fun removeContexts (Ljava/lang/String;)V public fun removeExtra (Ljava/lang/String;)V public fun removeTag (Ljava/lang/String;)V + public fun setClient (Lio/sentry/ISentryClient;)V public fun setContexts (Ljava/lang/String;Ljava/lang/Boolean;)V public fun setContexts (Ljava/lang/String;Ljava/lang/Character;)V public fun setContexts (Ljava/lang/String;Ljava/lang/Number;)V @@ -1314,6 +1321,7 @@ public final class io/sentry/NoOpScope : io/sentry/IScope { public fun setContexts (Ljava/lang/String;[Ljava/lang/Object;)V public fun setExtra (Ljava/lang/String;Ljava/lang/String;)V public fun setFingerprint (Ljava/util/List;)V + public fun setLastEventId (Lio/sentry/protocol/SentryId;)V public fun setLevel (Lio/sentry/SentryLevel;)V public fun setPropagationContext (Lio/sentry/PropagationContext;)V public fun setRequest (Lio/sentry/protocol/Request;)V @@ -1708,10 +1716,12 @@ public final class io/sentry/Scope : io/sentry/IScope { public fun endSession ()Lio/sentry/Session; public fun getAttachments ()Ljava/util/List; public fun getBreadcrumbs ()Ljava/util/Queue; + public fun getClient ()Lio/sentry/ISentryClient; public fun getContexts ()Lio/sentry/protocol/Contexts; public fun getEventProcessors ()Ljava/util/List; public fun getExtras ()Ljava/util/Map; public fun getFingerprint ()Ljava/util/List; + public fun getLastEventId ()Lio/sentry/protocol/SentryId; public fun getLevel ()Lio/sentry/SentryLevel; public fun getOptions ()Lio/sentry/SentryOptions; public fun getPropagationContext ()Lio/sentry/PropagationContext; @@ -1726,6 +1736,7 @@ public final class io/sentry/Scope : io/sentry/IScope { public fun removeContexts (Ljava/lang/String;)V public fun removeExtra (Ljava/lang/String;)V public fun removeTag (Ljava/lang/String;)V + public fun setClient (Lio/sentry/ISentryClient;)V public fun setContexts (Ljava/lang/String;Ljava/lang/Boolean;)V public fun setContexts (Ljava/lang/String;Ljava/lang/Character;)V public fun setContexts (Ljava/lang/String;Ljava/lang/Number;)V @@ -1735,6 +1746,7 @@ public final class io/sentry/Scope : io/sentry/IScope { public fun setContexts (Ljava/lang/String;[Ljava/lang/Object;)V public fun setExtra (Ljava/lang/String;Ljava/lang/String;)V public fun setFingerprint (Ljava/util/List;)V + public fun setLastEventId (Lio/sentry/protocol/SentryId;)V public fun setLevel (Lio/sentry/SentryLevel;)V public fun setPropagationContext (Lio/sentry/PropagationContext;)V public fun setRequest (Lio/sentry/protocol/Request;)V @@ -1780,6 +1792,70 @@ public abstract class io/sentry/ScopeObserverAdapter : io/sentry/IScopeObserver public fun setUser (Lio/sentry/protocol/User;)V } +public final class io/sentry/Scopes : io/sentry/IScopes, io/sentry/metrics/MetricsApi$IMetricsInterface { + public fun addBreadcrumb (Lio/sentry/Breadcrumb;)V + public fun addBreadcrumb (Lio/sentry/Breadcrumb;Lio/sentry/Hint;)V + public fun bindClient (Lio/sentry/ISentryClient;)V + public fun captureCheckIn (Lio/sentry/CheckIn;)Lio/sentry/protocol/SentryId; + public fun captureEnvelope (Lio/sentry/SentryEnvelope;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; + public fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; + public fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public fun captureException (Ljava/lang/Throwable;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; + public fun captureException (Ljava/lang/Throwable;Lio/sentry/Hint;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;)Lio/sentry/protocol/SentryId; + public fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public fun captureTransaction (Lio/sentry/protocol/SentryTransaction;Lio/sentry/TraceContext;Lio/sentry/Hint;Lio/sentry/ProfilingTraceData;)Lio/sentry/protocol/SentryId; + public fun captureUserFeedback (Lio/sentry/UserFeedback;)V + public fun clearBreadcrumbs ()V + public fun clone ()Lio/sentry/IHub; + public synthetic fun clone ()Ljava/lang/Object; + public fun close ()V + public fun close (Z)V + public fun configureScope (Lio/sentry/ScopeCallback;)V + public fun continueTrace (Ljava/lang/String;Ljava/util/List;)Lio/sentry/TransactionContext; + public fun endSession ()V + public fun flush (J)V + public fun forkedCurrentScope (Ljava/lang/String;)Lio/sentry/Scopes; + public fun forkedScopes (Ljava/lang/String;)Lio/sentry/Scopes; + public fun getBaggage ()Lio/sentry/BaggageHeader; + public fun getCreator ()Ljava/lang/String; + public fun getDefaultTagsForMetrics ()Ljava/util/Map; + public fun getGlobalScope ()Lio/sentry/IScope; + public fun getIsolationScope ()Lio/sentry/IScope; + public fun getLastEventId ()Lio/sentry/protocol/SentryId; + public fun getLocalMetricsAggregator ()Lio/sentry/metrics/LocalMetricsAggregator; + public fun getMetricsAggregator ()Lio/sentry/IMetricsAggregator; + public fun getOptions ()Lio/sentry/SentryOptions; + public fun getParent ()Lio/sentry/Scopes; + public fun getRateLimiter ()Lio/sentry/transport/RateLimiter; + public fun getScope ()Lio/sentry/IScope; + public fun getSpan ()Lio/sentry/ISpan; + public fun getTraceparent ()Lio/sentry/SentryTraceHeader; + public fun getTransaction ()Lio/sentry/ITransaction; + public fun isAncestorOf (Lio/sentry/Scopes;)Z + public fun isCrashedLastRun ()Ljava/lang/Boolean; + public fun isEnabled ()Z + public fun isHealthy ()Z + public fun metrics ()Lio/sentry/metrics/MetricsApi; + public fun popScope ()V + public fun pushScope ()V + public fun removeExtra (Ljava/lang/String;)V + public fun removeTag (Ljava/lang/String;)V + public fun reportFullyDisplayed ()V + public fun setExtra (Ljava/lang/String;Ljava/lang/String;)V + public fun setFingerprint (Ljava/util/List;)V + public fun setLevel (Lio/sentry/SentryLevel;)V + public fun setSpanContext (Ljava/lang/Throwable;Lio/sentry/ISpan;Ljava/lang/String;)V + public fun setTag (Ljava/lang/String;Ljava/lang/String;)V + public fun setTransaction (Ljava/lang/String;)V + public fun setUser (Lio/sentry/protocol/User;)V + public fun startSession ()V + public fun startSpanForMetric (Ljava/lang/String;Ljava/lang/String;)Lio/sentry/ISpan; + public fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction; + public fun traceHeaders ()Lio/sentry/SentryTraceHeader; + public fun withScope (Lio/sentry/ScopeCallback;)V +} + public final class io/sentry/ScopesAdapter : io/sentry/IScopes { public fun addBreadcrumb (Lio/sentry/Breadcrumb;)V public fun addBreadcrumb (Lio/sentry/Breadcrumb;Lio/sentry/Hint;)V diff --git a/sentry/src/main/java/io/sentry/IScope.java b/sentry/src/main/java/io/sentry/IScope.java index 3842fb2c3a..3bc25ce8e9 100644 --- a/sentry/src/main/java/io/sentry/IScope.java +++ b/sentry/src/main/java/io/sentry/IScope.java @@ -2,6 +2,7 @@ import io.sentry.protocol.Contexts; import io.sentry.protocol.Request; +import io.sentry.protocol.SentryId; import io.sentry.protocol.User; import java.util.Collection; import java.util.List; @@ -370,4 +371,14 @@ public interface IScope { */ @NotNull IScope clone(); + + void setLastEventId(final @NotNull SentryId lastEventId); + + @NotNull + SentryId getLastEventId(); + + void setClient(final @NotNull ISentryClient client); + + @NotNull + ISentryClient getClient(); } diff --git a/sentry/src/main/java/io/sentry/NoOpScope.java b/sentry/src/main/java/io/sentry/NoOpScope.java index c756fb49a3..f7336d6edb 100644 --- a/sentry/src/main/java/io/sentry/NoOpScope.java +++ b/sentry/src/main/java/io/sentry/NoOpScope.java @@ -2,6 +2,7 @@ import io.sentry.protocol.Contexts; import io.sentry.protocol.Request; +import io.sentry.protocol.SentryId; import io.sentry.protocol.User; import java.util.ArrayDeque; import java.util.ArrayList; @@ -236,6 +237,9 @@ public void setPropagationContext(@NotNull PropagationContext propagationContext return new PropagationContext(); } + @Override + public void setLastEventId(@NotNull SentryId lastEventId) {} + /** * Clones the Scope * @@ -245,4 +249,17 @@ public void setPropagationContext(@NotNull PropagationContext propagationContext public @NotNull IScope clone() { return NoOpScope.getInstance(); } + + @Override + public @NotNull SentryId getLastEventId() { + return SentryId.EMPTY_ID; + } + + @Override + public void setClient(@NotNull ISentryClient client) {} + + @Override + public @NotNull ISentryClient getClient() { + return NoOpSentryClient.getInstance(); + } } diff --git a/sentry/src/main/java/io/sentry/Scope.java b/sentry/src/main/java/io/sentry/Scope.java index 91c9fcd8cf..aa35ccfd7a 100644 --- a/sentry/src/main/java/io/sentry/Scope.java +++ b/sentry/src/main/java/io/sentry/Scope.java @@ -3,6 +3,7 @@ import io.sentry.protocol.App; import io.sentry.protocol.Contexts; import io.sentry.protocol.Request; +import io.sentry.protocol.SentryId; import io.sentry.protocol.TransactionNameSource; import io.sentry.protocol.User; import io.sentry.util.CollectionUtils; @@ -22,6 +23,8 @@ /** Scope data to be sent with the event */ public final class Scope implements IScope { + private volatile @NotNull SentryId lastEventId; + /** Scope's SentryLevel */ private @Nullable SentryLevel level; @@ -80,6 +83,8 @@ public final class Scope implements IScope { private @NotNull PropagationContext propagationContext; + private @NotNull ISentryClient client = NoOpSentryClient.getInstance(); + /** * Scope's ctor * @@ -89,6 +94,7 @@ public Scope(final @NotNull SentryOptions options) { this.options = Objects.requireNonNull(options, "SentryOptions is required."); this.breadcrumbs = createBreadcrumbsList(this.options.getMaxBreadcrumbs()); this.propagationContext = new PropagationContext(); + this.lastEventId = SentryId.EMPTY_ID; } private Scope(final @NotNull Scope scope) { @@ -97,6 +103,8 @@ private Scope(final @NotNull Scope scope) { this.session = scope.session; this.options = scope.options; this.level = scope.level; + // TODO should we do this? didn't do it for Hub + this.lastEventId = scope.getLastEventId(); final User userRef = scope.user; this.user = userRef != null ? new User(userRef) : null; @@ -945,6 +953,26 @@ public void setPropagationContext(final @NotNull PropagationContext propagationC return new Scope(this); } + @Override + public void setLastEventId(@NotNull SentryId lastEventId) { + this.lastEventId = lastEventId; + } + + @Override + public @NotNull SentryId getLastEventId() { + return lastEventId; + } + + @Override + public void setClient(@NotNull ISentryClient client) { + this.client = client; + } + + @Override + public @NotNull ISentryClient getClient() { + return client; + } + /** The IWithTransaction callback */ @ApiStatus.Internal public interface IWithTransaction { diff --git a/sentry/src/main/java/io/sentry/Scopes.java b/sentry/src/main/java/io/sentry/Scopes.java new file mode 100644 index 0000000000..618864b649 --- /dev/null +++ b/sentry/src/main/java/io/sentry/Scopes.java @@ -0,0 +1,1093 @@ +package io.sentry; + +import io.sentry.clientreport.DiscardReason; +import io.sentry.hints.SessionEndHint; +import io.sentry.hints.SessionStartHint; +import io.sentry.metrics.LocalMetricsAggregator; +import io.sentry.metrics.MetricsApi; +import io.sentry.protocol.SentryId; +import io.sentry.protocol.SentryTransaction; +import io.sentry.protocol.User; +import io.sentry.transport.RateLimiter; +import io.sentry.util.ExceptionUtils; +import io.sentry.util.HintUtils; +import io.sentry.util.Objects; +import io.sentry.util.Pair; +import io.sentry.util.TracingUtils; +import java.io.Closeable; +import java.io.IOException; +import java.lang.ref.WeakReference; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.WeakHashMap; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public final class Scopes implements IScopes, MetricsApi.IMetricsInterface { + + private final @NotNull IScope scope; + private final @NotNull IScope isolationScope; + // TODO just for debugging + @SuppressWarnings("UnusedVariable") + private final @Nullable Scopes parentScopes; + + private final @NotNull String creator; + + // TODO should this be set on all scopes (global, isolation, current)? + private final @NotNull SentryOptions options; + private volatile boolean isEnabled; + private final @NotNull TracesSampler tracesSampler; + + // TODO should this go on global scope? + private final @NotNull Map, String>> throwableToSpan = + Collections.synchronizedMap(new WeakHashMap<>()); + private final @NotNull TransactionPerformanceCollector transactionPerformanceCollector; + private final @NotNull MetricsApi metricsApi; + + Scopes( + final @NotNull IScope scope, + final @NotNull IScope isolationScope, + final @NotNull SentryOptions options, + final @NotNull String creator) { + this(scope, isolationScope, null, options, creator); + } + + private Scopes( + final @NotNull IScope scope, + final @NotNull IScope isolationScope, + final @Nullable Scopes parentScopes, + final @NotNull SentryOptions options, + final @NotNull String creator) { + validateOptions(options); + + this.scope = scope; + this.isolationScope = isolationScope; + this.parentScopes = parentScopes; + this.creator = creator; + this.options = options; + this.tracesSampler = new TracesSampler(options); + this.transactionPerformanceCollector = options.getTransactionPerformanceCollector(); + + this.isEnabled = true; + + this.metricsApi = new MetricsApi(this); + } + + public @NotNull String getCreator() { + return creator; + } + + // TODO add to IScopes interface + public @NotNull IScope getScope() { + return scope; + } + + // TODO add to IScopes interface + public @NotNull IScope getIsolationScope() { + return isolationScope; + } + + // TODO add to IScopes interface? + public @Nullable Scopes getParent() { + return parentScopes; + } + + // TODO add to IScopes interface? + public boolean isAncestorOf(final @Nullable Scopes otherScopes) { + if (otherScopes == null) { + return false; + } + + if (this == otherScopes) { + return true; + } + + final @Nullable Scopes parent = otherScopes.getParent(); + if (parent != null) { + return isAncestorOf(parent); + } + + return false; + } + + // TODO add to IScopes interface + public @NotNull Scopes forkedScopes(final @NotNull String creator) { + return new Scopes(scope.clone(), isolationScope.clone(), this, options, creator); + } + + // TODO add to IScopes interface + public @NotNull Scopes forkedCurrentScope(final @NotNull String creator) { + return new Scopes(scope.clone(), isolationScope, this, options, creator); + } + + // // TODO in Sentry.init? + // public static Scopes forkedRoots(final @NotNull SentryOptions options, final @NotNull String + // creator) { + // return new Scopes(ROOT_SCOPE.clone(), ROOT_ISOLATION_SCOPE.clone(), options, creator); + // } + + // TODO always read from root scope? + @Override + public boolean isEnabled() { + return isEnabled; + } + + @Override + public @NotNull SentryId captureEvent(@NotNull SentryEvent event, @Nullable Hint hint) { + return captureEventInternal(event, hint, null); + } + + @Override + public @NotNull SentryId captureEvent( + @NotNull SentryEvent event, @Nullable Hint hint, @NotNull ScopeCallback callback) { + return captureEventInternal(event, hint, callback); + } + + private @NotNull SentryId captureEventInternal( + final @NotNull SentryEvent event, + final @Nullable Hint hint, + final @Nullable ScopeCallback scopeCallback) { + SentryId sentryId = SentryId.EMPTY_ID; + if (!isEnabled()) { + options + .getLogger() + .log( + SentryLevel.WARNING, "Instance is disabled and this 'captureEvent' call is a no-op."); + } else if (event == null) { + options.getLogger().log(SentryLevel.WARNING, "captureEvent called with null parameter."); + } else { + try { + assignTraceContext(event); + final IScope localScope = buildLocalScope(getCombinedScopeView(), scopeCallback); + + sentryId = getClient().captureEvent(event, localScope, hint); + updateLastEventId(sentryId); + } catch (Throwable e) { + options + .getLogger() + .log( + SentryLevel.ERROR, "Error while capturing event with id: " + event.getEventId(), e); + } + } + return sentryId; + } + + private @NotNull ISentryClient getClient() { + return getCombinedScopeView().getClient(); + } + + private void assignTraceContext(final @NotNull SentryEvent event) { + if (options.isTracingEnabled() && event.getThrowable() != null) { + final Pair, String> pair = + throwableToSpan.get(ExceptionUtils.findRootCause(event.getThrowable())); + if (pair != null) { + final WeakReference spanWeakRef = pair.getFirst(); + if (event.getContexts().getTrace() == null && spanWeakRef != null) { + final ISpan span = spanWeakRef.get(); + if (span != null) { + event.getContexts().setTrace(span.getSpanContext()); + } + } + final String transactionName = pair.getSecond(); + if (event.getTransaction() == null && transactionName != null) { + event.setTransaction(transactionName); + } + } + } + } + + private IScope buildLocalScope( + final @NotNull IScope parentScope, final @Nullable ScopeCallback callback) { + if (callback != null) { + try { + final IScope localScope = parentScope.clone(); + callback.run(localScope); + return localScope; + } catch (Throwable t) { + options.getLogger().log(SentryLevel.ERROR, "Error in the 'ScopeCallback' callback.", t); + } + } + return parentScope; + } + + @Override + public @NotNull SentryId captureMessage( + final @NotNull String message, final @NotNull SentryLevel level) { + return captureMessageInternal(message, level, null); + } + + @Override + public @NotNull SentryId captureMessage( + final @NotNull String message, + final @NotNull SentryLevel level, + final @NotNull ScopeCallback callback) { + return captureMessageInternal(message, level, callback); + } + + private @NotNull SentryId captureMessageInternal( + final @NotNull String message, + final @NotNull SentryLevel level, + final @Nullable ScopeCallback scopeCallback) { + SentryId sentryId = SentryId.EMPTY_ID; + if (!isEnabled()) { + options + .getLogger() + .log( + SentryLevel.WARNING, + "Instance is disabled and this 'captureMessage' call is a no-op."); + } else if (message == null) { + options.getLogger().log(SentryLevel.WARNING, "captureMessage called with null parameter."); + } else { + try { + final IScope localScope = buildLocalScope(getCombinedScopeView(), scopeCallback); + + sentryId = getClient().captureMessage(message, level, localScope); + } catch (Throwable e) { + options.getLogger().log(SentryLevel.ERROR, "Error while capturing message: " + message, e); + } + } + updateLastEventId(sentryId); + return sentryId; + } + + @ApiStatus.Internal + @Override + public @NotNull SentryId captureEnvelope( + final @NotNull SentryEnvelope envelope, final @Nullable Hint hint) { + Objects.requireNonNull(envelope, "SentryEnvelope is required."); + + SentryId sentryId = SentryId.EMPTY_ID; + if (!isEnabled()) { + options + .getLogger() + .log( + SentryLevel.WARNING, + "Instance is disabled and this 'captureEnvelope' call is a no-op."); + } else { + try { + final SentryId capturedEnvelopeId = getClient().captureEnvelope(envelope, hint); + if (capturedEnvelopeId != null) { + sentryId = capturedEnvelopeId; + } + } catch (Throwable e) { + options.getLogger().log(SentryLevel.ERROR, "Error while capturing envelope.", e); + } + } + return sentryId; + } + + @Override + public @NotNull SentryId captureException( + final @NotNull Throwable throwable, final @Nullable Hint hint) { + return captureExceptionInternal(throwable, hint, null); + } + + @Override + public @NotNull SentryId captureException( + final @NotNull Throwable throwable, + final @Nullable Hint hint, + final @NotNull ScopeCallback callback) { + + return captureExceptionInternal(throwable, hint, callback); + } + + private @NotNull SentryId captureExceptionInternal( + final @NotNull Throwable throwable, + final @Nullable Hint hint, + final @Nullable ScopeCallback scopeCallback) { + SentryId sentryId = SentryId.EMPTY_ID; + if (!isEnabled()) { + options + .getLogger() + .log( + SentryLevel.WARNING, + "Instance is disabled and this 'captureException' call is a no-op."); + } else if (throwable == null) { + options.getLogger().log(SentryLevel.WARNING, "captureException called with null parameter."); + } else { + try { + final SentryEvent event = new SentryEvent(throwable); + assignTraceContext(event); + + final IScope localScope = buildLocalScope(getCombinedScopeView(), scopeCallback); + + sentryId = getClient().captureEvent(event, localScope, hint); + } catch (Throwable e) { + options + .getLogger() + .log( + SentryLevel.ERROR, "Error while capturing exception: " + throwable.getMessage(), e); + } + } + updateLastEventId(sentryId); + return sentryId; + } + + @Override + public void captureUserFeedback(final @NotNull UserFeedback userFeedback) { + if (!isEnabled()) { + options + .getLogger() + .log( + SentryLevel.WARNING, + "Instance is disabled and this 'captureUserFeedback' call is a no-op."); + } else { + try { + getClient().captureUserFeedback(userFeedback); + } catch (Throwable e) { + options + .getLogger() + .log( + SentryLevel.ERROR, + "Error while capturing captureUserFeedback: " + userFeedback.toString(), + e); + } + } + } + + @Override + public void startSession() { + if (!isEnabled()) { + options + .getLogger() + .log( + SentryLevel.WARNING, "Instance is disabled and this 'startSession' call is a no-op."); + } else { + final Scope.SessionPair pair = getCombinedScopeView().startSession(); + if (pair != null) { + // TODO: add helper overload `captureSessions` to pass a list of sessions and submit a + // single envelope + // Or create the envelope here with both items and call `captureEnvelope` + if (pair.getPrevious() != null) { + final Hint hint = HintUtils.createWithTypeCheckHint(new SessionEndHint()); + + getClient().captureSession(pair.getPrevious(), hint); + } + + final Hint hint = HintUtils.createWithTypeCheckHint(new SessionStartHint()); + + getClient().captureSession(pair.getCurrent(), hint); + } else { + options.getLogger().log(SentryLevel.WARNING, "Session could not be started."); + } + } + } + + @Override + public void endSession() { + if (!isEnabled()) { + options + .getLogger() + .log(SentryLevel.WARNING, "Instance is disabled and this 'endSession' call is a no-op."); + } else { + final Session previousSession = getCombinedScopeView().endSession(); + if (previousSession != null) { + final Hint hint = HintUtils.createWithTypeCheckHint(new SessionEndHint()); + + getClient().captureSession(previousSession, hint); + } + } + } + + private IScope getCombinedScopeView() { + // TODO combine global, isolation and current scope + return scope; + } + + @Override + public void close() { + close(false); + } + + @Override + @SuppressWarnings("FutureReturnValueIgnored") + public void close(final boolean isRestarting) { + if (!isEnabled()) { + options + .getLogger() + .log(SentryLevel.WARNING, "Instance is disabled and this 'close' call is a no-op."); + } else { + try { + for (Integration integration : options.getIntegrations()) { + if (integration instanceof Closeable) { + try { + ((Closeable) integration).close(); + } catch (IOException e) { + options + .getLogger() + .log(SentryLevel.WARNING, "Failed to close the integration {}.", integration, e); + } + } + } + + // TODO which scopes do we call this on? isolation and current scope? + configureScope(scope -> scope.clear()); + options.getTransactionProfiler().close(); + options.getTransactionPerformanceCollector().close(); + final @NotNull ISentryExecutorService executorService = options.getExecutorService(); + if (isRestarting) { + executorService.submit(() -> executorService.close(options.getShutdownTimeoutMillis())); + } else { + executorService.close(options.getShutdownTimeoutMillis()); + } + + // TODO: should we end session before closing client? + getClient().close(isRestarting); + } catch (Throwable e) { + options.getLogger().log(SentryLevel.ERROR, "Error while closing the Hub.", e); + } + isEnabled = false; + } + } + + @Override + public void addBreadcrumb(final @NotNull Breadcrumb breadcrumb, final @Nullable Hint hint) { + if (!isEnabled()) { + options + .getLogger() + .log( + SentryLevel.WARNING, + "Instance is disabled and this 'addBreadcrumb' call is a no-op."); + } else if (breadcrumb == null) { + options.getLogger().log(SentryLevel.WARNING, "addBreadcrumb called with null parameter."); + } else { + getDefaultWriteScope().addBreadcrumb(breadcrumb, hint); + } + } + + private IScope getDefaultConfigureScope() { + // TODO configurable default scope via SentryOptions, Android = global or isolation, backend = + // isolation + return scope; + } + + private IScope getDefaultWriteScope() { + // TODO configurable default scope via SentryOptions, Android = global or isolation, backend = + // isolation + return getIsolationScope(); + } + + @Override + public void addBreadcrumb(final @NotNull Breadcrumb breadcrumb) { + addBreadcrumb(breadcrumb, new Hint()); + } + + @Override + public void setLevel(final @Nullable SentryLevel level) { + if (!isEnabled()) { + options + .getLogger() + .log(SentryLevel.WARNING, "Instance is disabled and this 'setLevel' call is a no-op."); + } else { + getDefaultWriteScope().setLevel(level); + } + } + + @Override + public void setTransaction(final @Nullable String transaction) { + if (!isEnabled()) { + options + .getLogger() + .log( + SentryLevel.WARNING, + "Instance is disabled and this 'setTransaction' call is a no-op."); + } else if (transaction != null) { + getDefaultWriteScope().setTransaction(transaction); + } else { + options.getLogger().log(SentryLevel.WARNING, "Transaction cannot be null"); + } + } + + @Override + public void setUser(final @Nullable User user) { + if (!isEnabled()) { + options + .getLogger() + .log(SentryLevel.WARNING, "Instance is disabled and this 'setUser' call is a no-op."); + } else { + getDefaultWriteScope().setUser(user); + } + } + + @Override + public void setFingerprint(final @NotNull List fingerprint) { + if (!isEnabled()) { + options + .getLogger() + .log( + SentryLevel.WARNING, + "Instance is disabled and this 'setFingerprint' call is a no-op."); + } else if (fingerprint == null) { + options.getLogger().log(SentryLevel.WARNING, "setFingerprint called with null parameter."); + } else { + getDefaultWriteScope().setFingerprint(fingerprint); + } + } + + @Override + public void clearBreadcrumbs() { + if (!isEnabled()) { + options + .getLogger() + .log( + SentryLevel.WARNING, + "Instance is disabled and this 'clearBreadcrumbs' call is a no-op."); + } else { + getDefaultWriteScope().clearBreadcrumbs(); + } + } + + @Override + public void setTag(final @NotNull String key, final @NotNull String value) { + if (!isEnabled()) { + options + .getLogger() + .log(SentryLevel.WARNING, "Instance is disabled and this 'setTag' call is a no-op."); + } else if (key == null || value == null) { + options.getLogger().log(SentryLevel.WARNING, "setTag called with null parameter."); + } else { + getDefaultWriteScope().setTag(key, value); + } + } + + @Override + public void removeTag(final @NotNull String key) { + if (!isEnabled()) { + options + .getLogger() + .log(SentryLevel.WARNING, "Instance is disabled and this 'removeTag' call is a no-op."); + } else if (key == null) { + options.getLogger().log(SentryLevel.WARNING, "removeTag called with null parameter."); + } else { + getDefaultWriteScope().removeTag(key); + } + } + + @Override + public void setExtra(final @NotNull String key, final @NotNull String value) { + if (!isEnabled()) { + options + .getLogger() + .log(SentryLevel.WARNING, "Instance is disabled and this 'setExtra' call is a no-op."); + } else if (key == null || value == null) { + options.getLogger().log(SentryLevel.WARNING, "setExtra called with null parameter."); + } else { + getDefaultWriteScope().setExtra(key, value); + } + } + + @Override + public void removeExtra(final @NotNull String key) { + if (!isEnabled()) { + options + .getLogger() + .log(SentryLevel.WARNING, "Instance is disabled and this 'removeExtra' call is a no-op."); + } else if (key == null) { + options.getLogger().log(SentryLevel.WARNING, "removeExtra called with null parameter."); + } else { + getDefaultWriteScope().removeExtra(key); + } + } + + private void updateLastEventId(final @NotNull SentryId lastEventId) { + scope.setLastEventId(lastEventId); + isolationScope.setLastEventId(lastEventId); + getGlobalScope().setLastEventId(lastEventId); + } + + // TODO add to IScopes interface + public @NotNull IScope getGlobalScope() { + // TODO return singleton global scope here + return scope; + } + + @Override + public @NotNull SentryId getLastEventId() { + // TODO read all scopes here / read default scope? + // returning scope.lastEventId isn't ideal because changed to child scope are not stored in + // there + return getGlobalScope().getLastEventId(); + } + + // TODO needs to be deprecated because there's no more stack + // TODO needs to return a lifecycle token + @Override + public void pushScope() { + if (!isEnabled()) { + options + .getLogger() + .log(SentryLevel.WARNING, "Instance is disabled and this 'pushScope' call is a no-op."); + } else { + // Scopes scopes = this.forkedScopes("pushScope"); + // return scopes.makeCurrent(); + } + } + + // public SentryLifecycleToken makeCurrent() { + // // TODO store.set(this); + // } + + // TODO needs to be deprecated because there's no more stack + @Override + public void popScope() { + if (!isEnabled()) { + options + .getLogger() + .log(SentryLevel.WARNING, "Instance is disabled and this 'popScope' call is a no-op."); + } else { + // TODO how to remove fork? + // TODO getParentScopes().makeCurrent()? + } + } + + // TODO lots of testing required to see how ThreadLocal is affected + @Override + public void withScope(final @NotNull ScopeCallback callback) { + if (!isEnabled()) { + try { + callback.run(NoOpScope.getInstance()); + } catch (Throwable e) { + options.getLogger().log(SentryLevel.ERROR, "Error in the 'withScope' callback.", e); + } + + } else { + Scopes forkedScopes = forkedScopes("withScope"); + // TODO should forkedScopes be made current inside callback? + // TODO forkedScopes.makeCurrent()? + try { + callback.run(forkedScopes.getScope()); + } catch (Throwable e) { + options.getLogger().log(SentryLevel.ERROR, "Error in the 'withScope' callback.", e); + } + } + } + + @Override + public void configureScope(final @NotNull ScopeCallback callback) { + if (!isEnabled()) { + options + .getLogger() + .log( + SentryLevel.WARNING, + "Instance is disabled and this 'configureScope' call is a no-op."); + } else { + try { + callback.run(getDefaultConfigureScope()); + } catch (Throwable e) { + options.getLogger().log(SentryLevel.ERROR, "Error in the 'configureScope' callback.", e); + } + } + } + + @Override + public void bindClient(final @NotNull ISentryClient client) { + if (!isEnabled()) { + options + .getLogger() + .log(SentryLevel.WARNING, "Instance is disabled and this 'bindClient' call is a no-op."); + } else { + if (client != null) { + options.getLogger().log(SentryLevel.DEBUG, "New client bound to scope."); + getDefaultWriteScope().setClient(client); + } else { + options.getLogger().log(SentryLevel.DEBUG, "NoOp client bound to scope."); + getDefaultWriteScope().setClient(NoOpSentryClient.getInstance()); + } + } + } + + @Override + public boolean isHealthy() { + return getClient().isHealthy(); + } + + @Override + public void flush(long timeoutMillis) { + if (!isEnabled()) { + options + .getLogger() + .log(SentryLevel.WARNING, "Instance is disabled and this 'flush' call is a no-op."); + } else { + try { + getClient().flush(timeoutMillis); + } catch (Throwable e) { + options.getLogger().log(SentryLevel.ERROR, "Error in the 'client.flush'.", e); + } + } + } + + @Override + @SuppressWarnings("deprecation") + public @NotNull IHub clone() { + if (!isEnabled()) { + options.getLogger().log(SentryLevel.WARNING, "Disabled Hub cloned."); + } + return new HubScopesWrapper(forkedScopes("scopes clone")); + } + + @ApiStatus.Internal + @Override + public @NotNull SentryId captureTransaction( + final @NotNull SentryTransaction transaction, + final @Nullable TraceContext traceContext, + final @Nullable Hint hint, + final @Nullable ProfilingTraceData profilingTraceData) { + Objects.requireNonNull(transaction, "transaction is required"); + + SentryId sentryId = SentryId.EMPTY_ID; + if (!isEnabled()) { + options + .getLogger() + .log( + SentryLevel.WARNING, + "Instance is disabled and this 'captureTransaction' call is a no-op."); + } else { + if (!transaction.isFinished()) { + options + .getLogger() + .log( + SentryLevel.WARNING, + "Transaction: %s is not finished and this 'captureTransaction' call is a no-op.", + transaction.getEventId()); + } else { + if (!Boolean.TRUE.equals(transaction.isSampled())) { + options + .getLogger() + .log( + SentryLevel.DEBUG, + "Transaction %s was dropped due to sampling decision.", + transaction.getEventId()); + if (options.getBackpressureMonitor().getDownsampleFactor() > 0) { + options + .getClientReportRecorder() + .recordLostEvent(DiscardReason.BACKPRESSURE, DataCategory.Transaction); + } else { + options + .getClientReportRecorder() + .recordLostEvent(DiscardReason.SAMPLE_RATE, DataCategory.Transaction); + } + } else { + try { + sentryId = + getClient() + .captureTransaction( + transaction, + traceContext, + getCombinedScopeView(), + hint, + profilingTraceData); + } catch (Throwable e) { + options + .getLogger() + .log( + SentryLevel.ERROR, + "Error while capturing transaction with id: " + transaction.getEventId(), + e); + } + } + } + } + return sentryId; + } + + @Override + public @NotNull ITransaction startTransaction( + final @NotNull TransactionContext transactionContext, + final @NotNull TransactionOptions transactionOptions) { + return createTransaction(transactionContext, transactionOptions); + } + + private @NotNull ITransaction createTransaction( + final @NotNull TransactionContext transactionContext, + final @NotNull TransactionOptions transactionOptions) { + Objects.requireNonNull(transactionContext, "transactionContext is required"); + + ITransaction transaction; + if (!isEnabled()) { + options + .getLogger() + .log( + SentryLevel.WARNING, + "Instance is disabled and this 'startTransaction' returns a no-op."); + transaction = NoOpTransaction.getInstance(); + } else if (!options.getInstrumenter().equals(transactionContext.getInstrumenter())) { + options + .getLogger() + .log( + SentryLevel.DEBUG, + "Returning no-op for instrumenter %s as the SDK has been configured to use instrumenter %s", + transactionContext.getInstrumenter(), + options.getInstrumenter()); + transaction = NoOpTransaction.getInstance(); + } else if (!options.isTracingEnabled()) { + options + .getLogger() + .log( + SentryLevel.INFO, "Tracing is disabled and this 'startTransaction' returns a no-op."); + transaction = NoOpTransaction.getInstance(); + } else { + final SamplingContext samplingContext = + new SamplingContext(transactionContext, transactionOptions.getCustomSamplingContext()); + @NotNull TracesSamplingDecision samplingDecision = tracesSampler.sample(samplingContext); + transactionContext.setSamplingDecision(samplingDecision); + + transaction = + new SentryTracer( + transactionContext, this, transactionOptions, transactionPerformanceCollector); + + // The listener is called only if the transaction exists, as the transaction is needed to + // stop it + if (samplingDecision.getSampled() && samplingDecision.getProfileSampled()) { + final ITransactionProfiler transactionProfiler = options.getTransactionProfiler(); + // If the profiler is not running, we start and bind it here. + if (!transactionProfiler.isRunning()) { + transactionProfiler.start(); + transactionProfiler.bindTransaction(transaction); + } else if (transactionOptions.isAppStartTransaction()) { + // If the profiler is running and the current transaction is the app start, we bind it. + transactionProfiler.bindTransaction(transaction); + } + } + } + if (transactionOptions.isBindToScope()) { + configureScope(scope -> scope.setTransaction(transaction)); + } + return transaction; + } + + @Deprecated + @SuppressWarnings("InlineMeSuggester") + @Override + public @Nullable SentryTraceHeader traceHeaders() { + return getTraceparent(); + } + + @Override + @ApiStatus.Internal + public void setSpanContext( + final @NotNull Throwable throwable, + final @NotNull ISpan span, + final @NotNull String transactionName) { + Objects.requireNonNull(throwable, "throwable is required"); + Objects.requireNonNull(span, "span is required"); + Objects.requireNonNull(transactionName, "transactionName is required"); + // to match any cause, span context is always attached to the root cause of the exception + final Throwable rootCause = ExceptionUtils.findRootCause(throwable); + // the most inner span should be assigned to a throwable + if (!throwableToSpan.containsKey(rootCause)) { + throwableToSpan.put(rootCause, new Pair<>(new WeakReference<>(span), transactionName)); + } + } + + // TODO this seems unused + @Nullable + SpanContext getSpanContext(final @NotNull Throwable throwable) { + Objects.requireNonNull(throwable, "throwable is required"); + final Throwable rootCause = ExceptionUtils.findRootCause(throwable); + final Pair, String> pair = this.throwableToSpan.get(rootCause); + if (pair != null) { + final WeakReference spanWeakRef = pair.getFirst(); + if (spanWeakRef != null) { + final ISpan span = spanWeakRef.get(); + if (span != null) { + return span.getSpanContext(); + } + } + } + return null; + } + + @Override + public @Nullable ISpan getSpan() { + ISpan span = null; + if (!isEnabled()) { + options + .getLogger() + .log(SentryLevel.WARNING, "Instance is disabled and this 'getSpan' call is a no-op."); + } else { + span = getScope().getSpan(); + } + return span; + } + + @Override + @ApiStatus.Internal + public @Nullable ITransaction getTransaction() { + ITransaction span = null; + if (!isEnabled()) { + options + .getLogger() + .log( + SentryLevel.WARNING, + "Instance is disabled and this 'getTransaction' call is a no-op."); + } else { + span = getScope().getTransaction(); + } + return span; + } + + @Override + public @NotNull SentryOptions getOptions() { + return options; + } + + @Override + public @Nullable Boolean isCrashedLastRun() { + return SentryCrashLastRunState.getInstance() + .isCrashedLastRun(options.getCacheDirPath(), !options.isEnableAutoSessionTracking()); + } + + @Override + public void reportFullyDisplayed() { + if (options.isEnableTimeToFullDisplayTracing()) { + options.getFullyDisplayedReporter().reportFullyDrawn(); + } + } + + @Override + public @Nullable TransactionContext continueTrace( + final @Nullable String sentryTrace, final @Nullable List baggageHeaders) { + @NotNull + PropagationContext propagationContext = + PropagationContext.fromHeaders(getOptions().getLogger(), sentryTrace, baggageHeaders); + // TODO should this go on isolation scope? + configureScope( + (scope) -> { + scope.setPropagationContext(propagationContext); + }); + if (options.isTracingEnabled()) { + return TransactionContext.fromPropagationContext(propagationContext); + } else { + return null; + } + } + + @Override + public @Nullable SentryTraceHeader getTraceparent() { + if (!isEnabled()) { + options + .getLogger() + .log( + SentryLevel.WARNING, + "Instance is disabled and this 'getTraceparent' call is a no-op."); + } else { + final @Nullable TracingUtils.TracingHeaders headers = + TracingUtils.trace(this, null, getSpan()); + if (headers != null) { + return headers.getSentryTraceHeader(); + } + } + + return null; + } + + @Override + public @Nullable BaggageHeader getBaggage() { + if (!isEnabled()) { + options + .getLogger() + .log(SentryLevel.WARNING, "Instance is disabled and this 'getBaggage' call is a no-op."); + } else { + final @Nullable TracingUtils.TracingHeaders headers = + TracingUtils.trace(this, null, getSpan()); + if (headers != null) { + return headers.getBaggageHeader(); + } + } + + return null; + } + + @Override + @ApiStatus.Experimental + public @NotNull SentryId captureCheckIn(final @NotNull CheckIn checkIn) { + SentryId sentryId = SentryId.EMPTY_ID; + if (!isEnabled()) { + options + .getLogger() + .log( + SentryLevel.WARNING, + "Instance is disabled and this 'captureCheckIn' call is a no-op."); + } else { + try { + sentryId = getClient().captureCheckIn(checkIn, getCombinedScopeView(), null); + } catch (Throwable e) { + options.getLogger().log(SentryLevel.ERROR, "Error while capturing check-in for slug", e); + } + } + updateLastEventId(sentryId); + return sentryId; + } + + @ApiStatus.Internal + @Override + public @Nullable RateLimiter getRateLimiter() { + return getClient().getRateLimiter(); + } + + @Override + public @NotNull MetricsApi metrics() { + return metricsApi; + } + + @Override + public @NotNull IMetricsAggregator getMetricsAggregator() { + return getClient().getMetricsAggregator(); + } + + @Override + public @NotNull Map getDefaultTagsForMetrics() { + if (!options.isEnableDefaultTagsForMetrics()) { + return Collections.emptyMap(); + } + + final @NotNull Map tags = new HashMap<>(); + final @Nullable String release = options.getRelease(); + if (release != null) { + tags.put("release", release); + } + + final @Nullable String environment = options.getEnvironment(); + if (environment != null) { + tags.put("environment", environment); + } + + final @Nullable String txnName = getCombinedScopeView().getTransactionName(); + if (txnName != null) { + tags.put("transaction", txnName); + } + return Collections.unmodifiableMap(tags); + } + + @Override + public @Nullable ISpan startSpanForMetric(@NotNull String op, @NotNull String description) { + final @Nullable ISpan span = getSpan(); + if (span != null) { + return span.startChild(op, description); + } + return null; + } + + @Override + public @Nullable LocalMetricsAggregator getLocalMetricsAggregator() { + if (!options.isEnableSpanLocalMetricAggregation()) { + return null; + } + final @Nullable ISpan span = getSpan(); + if (span != null) { + return span.getLocalMetricsAggregator(); + } + return null; + } + + private static void validateOptions(final @NotNull SentryOptions options) { + Objects.requireNonNull(options, "SentryOptions is required."); + if (options.getDsn() == null || options.getDsn().isEmpty()) { + throw new IllegalArgumentException( + "Hub requires a DSN to be instantiated. Considering using the NoOpHub if no DSN is available."); + } + } +} diff --git a/sentry/src/main/java/io/sentry/Sentry.java b/sentry/src/main/java/io/sentry/Sentry.java index 206ffd8d20..f4996bb8ad 100644 --- a/sentry/src/main/java/io/sentry/Sentry.java +++ b/sentry/src/main/java/io/sentry/Sentry.java @@ -254,8 +254,9 @@ private static synchronized void init( Sentry.globalHubMode = globalHubMode; final IScopes hub = getCurrentScopes(); - // TODO new Scopes() - mainScopes = new Hub(options); + final IScope rootScope = new Scope(options); + final IScope rootIsolationScope = new Scope(options); + mainScopes = new Scopes(rootScope, rootIsolationScope, options, "Sentry.init"); currentScopes.set(mainScopes); @@ -800,6 +801,7 @@ public static void removeExtra(final @NotNull String key) { public static void pushScope() { // pushScope is no-op in global hub mode if (!globalHubMode) { + // TODO this might have to behave differently from Scopes.pushScope getCurrentScopes().pushScope(); } } @@ -808,6 +810,7 @@ public static void pushScope() { public static void popScope() { // popScope is no-op in global hub mode if (!globalHubMode) { + // TODO this might have to behave differently from Scopes.popScope getCurrentScopes().popScope(); } } @@ -818,6 +821,7 @@ public static void popScope() { * @param callback the callback */ public static void withScope(final @NotNull ScopeCallback callback) { + // TODO this might have to behave differently from Scopes.withScope getCurrentScopes().withScope(callback); } From 27f2398fd678b0d5554e171d729a69f9b93a33d3 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Tue, 2 Apr 2024 14:00:21 +0200 Subject: [PATCH 03/28] Introduce `IScopes` interface. --- sentry/api/sentry.api | 333 +++++++--- sentry/src/main/java/io/sentry/Hub.java | 1 + .../src/main/java/io/sentry/HubAdapter.java | 22 +- .../main/java/io/sentry/HubScopesWrapper.java | 279 ++++++++ sentry/src/main/java/io/sentry/IHub.java | 595 +----------------- sentry/src/main/java/io/sentry/IScopes.java | 594 +++++++++++++++++ sentry/src/main/java/io/sentry/NoOpHub.java | 7 + .../src/main/java/io/sentry/NoOpScopes.java | 243 +++++++ .../main/java/io/sentry/ScopesAdapter.java | 286 +++++++++ sentry/src/main/java/io/sentry/Sentry.java | 176 +++--- 10 files changed, 1778 insertions(+), 758 deletions(-) create mode 100644 sentry/src/main/java/io/sentry/HubScopesWrapper.java create mode 100644 sentry/src/main/java/io/sentry/IScopes.java create mode 100644 sentry/src/main/java/io/sentry/NoOpScopes.java create mode 100644 sentry/src/main/java/io/sentry/ScopesAdapter.java diff --git a/sentry/api/sentry.api b/sentry/api/sentry.api index bcfc1c9194..52eb5df888 100644 --- a/sentry/api/sentry.api +++ b/sentry/api/sentry.api @@ -293,7 +293,7 @@ public final class io/sentry/EnvelopeReader : io/sentry/IEnvelopeReader { } public final class io/sentry/EnvelopeSender : io/sentry/IEnvelopeSender { - public fun (Lio/sentry/IHub;Lio/sentry/ISerializer;Lio/sentry/ILogger;JI)V + public fun (Lio/sentry/IScopes;Lio/sentry/ISerializer;Lio/sentry/ILogger;JI)V public synthetic fun processDirectory (Ljava/io/File;)V public fun processEnvelopeFile (Ljava/lang/String;Lio/sentry/Hint;)V } @@ -520,6 +520,59 @@ public final class io/sentry/HubAdapter : io/sentry/IHub { public fun withScope (Lio/sentry/ScopeCallback;)V } +public final class io/sentry/HubScopesWrapper : io/sentry/IHub { + public fun (Lio/sentry/IScopes;)V + public fun addBreadcrumb (Lio/sentry/Breadcrumb;)V + public fun addBreadcrumb (Lio/sentry/Breadcrumb;Lio/sentry/Hint;)V + public fun bindClient (Lio/sentry/ISentryClient;)V + public fun captureCheckIn (Lio/sentry/CheckIn;)Lio/sentry/protocol/SentryId; + public fun captureEnvelope (Lio/sentry/SentryEnvelope;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; + public fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; + public fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public fun captureException (Ljava/lang/Throwable;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; + public fun captureException (Ljava/lang/Throwable;Lio/sentry/Hint;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;)Lio/sentry/protocol/SentryId; + public fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public fun captureTransaction (Lio/sentry/protocol/SentryTransaction;Lio/sentry/TraceContext;Lio/sentry/Hint;Lio/sentry/ProfilingTraceData;)Lio/sentry/protocol/SentryId; + public fun captureUserFeedback (Lio/sentry/UserFeedback;)V + public fun clearBreadcrumbs ()V + public fun clone ()Lio/sentry/IHub; + public synthetic fun clone ()Ljava/lang/Object; + public fun close ()V + public fun close (Z)V + public fun configureScope (Lio/sentry/ScopeCallback;)V + public fun continueTrace (Ljava/lang/String;Ljava/util/List;)Lio/sentry/TransactionContext; + public fun endSession ()V + public fun flush (J)V + public fun getBaggage ()Lio/sentry/BaggageHeader; + public fun getLastEventId ()Lio/sentry/protocol/SentryId; + public fun getOptions ()Lio/sentry/SentryOptions; + public fun getRateLimiter ()Lio/sentry/transport/RateLimiter; + public fun getSpan ()Lio/sentry/ISpan; + public fun getTraceparent ()Lio/sentry/SentryTraceHeader; + public fun getTransaction ()Lio/sentry/ITransaction; + public fun isCrashedLastRun ()Ljava/lang/Boolean; + public fun isEnabled ()Z + public fun isHealthy ()Z + public fun metrics ()Lio/sentry/metrics/MetricsApi; + public fun popScope ()V + public fun pushScope ()V + public fun removeExtra (Ljava/lang/String;)V + public fun removeTag (Ljava/lang/String;)V + public fun reportFullyDisplayed ()V + public fun setExtra (Ljava/lang/String;Ljava/lang/String;)V + public fun setFingerprint (Ljava/util/List;)V + public fun setLevel (Lio/sentry/SentryLevel;)V + public fun setSpanContext (Ljava/lang/Throwable;Lio/sentry/ISpan;Ljava/lang/String;)V + public fun setTag (Ljava/lang/String;Ljava/lang/String;)V + public fun setTransaction (Ljava/lang/String;)V + public fun setUser (Lio/sentry/protocol/User;)V + public fun startSession ()V + public fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction; + public fun traceHeaders ()Lio/sentry/SentryTraceHeader; + public fun withScope (Lio/sentry/ScopeCallback;)V +} + public abstract interface class io/sentry/IConnectionStatusProvider { public abstract fun addConnectionStatusObserver (Lio/sentry/IConnectionStatusProvider$IConnectionStatusObserver;)Z public abstract fun getConnectionStatus ()Lio/sentry/IConnectionStatusProvider$ConnectionStatus; @@ -548,71 +601,7 @@ public abstract interface class io/sentry/IEnvelopeSender { public abstract fun processEnvelopeFile (Ljava/lang/String;Lio/sentry/Hint;)V } -public abstract interface class io/sentry/IHub { - public abstract fun addBreadcrumb (Lio/sentry/Breadcrumb;)V - public abstract fun addBreadcrumb (Lio/sentry/Breadcrumb;Lio/sentry/Hint;)V - public fun addBreadcrumb (Ljava/lang/String;)V - public fun addBreadcrumb (Ljava/lang/String;Ljava/lang/String;)V - public abstract fun bindClient (Lio/sentry/ISentryClient;)V - public abstract fun captureCheckIn (Lio/sentry/CheckIn;)Lio/sentry/protocol/SentryId; - public fun captureEnvelope (Lio/sentry/SentryEnvelope;)Lio/sentry/protocol/SentryId; - public abstract fun captureEnvelope (Lio/sentry/SentryEnvelope;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; - public fun captureEvent (Lio/sentry/SentryEvent;)Lio/sentry/protocol/SentryId; - public abstract fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; - public abstract fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; - public fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; - public fun captureException (Ljava/lang/Throwable;)Lio/sentry/protocol/SentryId; - public abstract fun captureException (Ljava/lang/Throwable;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; - public abstract fun captureException (Ljava/lang/Throwable;Lio/sentry/Hint;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; - public fun captureException (Ljava/lang/Throwable;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; - public fun captureMessage (Ljava/lang/String;)Lio/sentry/protocol/SentryId; - public fun captureMessage (Ljava/lang/String;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; - public abstract fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;)Lio/sentry/protocol/SentryId; - public abstract fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; - public fun captureTransaction (Lio/sentry/protocol/SentryTransaction;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; - public fun captureTransaction (Lio/sentry/protocol/SentryTransaction;Lio/sentry/TraceContext;)Lio/sentry/protocol/SentryId; - public fun captureTransaction (Lio/sentry/protocol/SentryTransaction;Lio/sentry/TraceContext;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; - public abstract fun captureTransaction (Lio/sentry/protocol/SentryTransaction;Lio/sentry/TraceContext;Lio/sentry/Hint;Lio/sentry/ProfilingTraceData;)Lio/sentry/protocol/SentryId; - public abstract fun captureUserFeedback (Lio/sentry/UserFeedback;)V - public abstract fun clearBreadcrumbs ()V - public abstract fun clone ()Lio/sentry/IHub; - public abstract fun close ()V - public abstract fun close (Z)V - public abstract fun configureScope (Lio/sentry/ScopeCallback;)V - public abstract fun continueTrace (Ljava/lang/String;Ljava/util/List;)Lio/sentry/TransactionContext; - public abstract fun endSession ()V - public abstract fun flush (J)V - public abstract fun getBaggage ()Lio/sentry/BaggageHeader; - public abstract fun getLastEventId ()Lio/sentry/protocol/SentryId; - public abstract fun getOptions ()Lio/sentry/SentryOptions; - public abstract fun getRateLimiter ()Lio/sentry/transport/RateLimiter; - public abstract fun getSpan ()Lio/sentry/ISpan; - public abstract fun getTraceparent ()Lio/sentry/SentryTraceHeader; - public abstract fun getTransaction ()Lio/sentry/ITransaction; - public abstract fun isCrashedLastRun ()Ljava/lang/Boolean; - public abstract fun isEnabled ()Z - public abstract fun isHealthy ()Z - public abstract fun metrics ()Lio/sentry/metrics/MetricsApi; - public abstract fun popScope ()V - public abstract fun pushScope ()V - public abstract fun removeExtra (Ljava/lang/String;)V - public abstract fun removeTag (Ljava/lang/String;)V - public fun reportFullDisplayed ()V - public abstract fun reportFullyDisplayed ()V - public abstract fun setExtra (Ljava/lang/String;Ljava/lang/String;)V - public abstract fun setFingerprint (Ljava/util/List;)V - public abstract fun setLevel (Lio/sentry/SentryLevel;)V - public abstract fun setSpanContext (Ljava/lang/Throwable;Lio/sentry/ISpan;Ljava/lang/String;)V - public abstract fun setTag (Ljava/lang/String;Ljava/lang/String;)V - public abstract fun setTransaction (Ljava/lang/String;)V - public abstract fun setUser (Lio/sentry/protocol/User;)V - public abstract fun startSession ()V - public fun startTransaction (Lio/sentry/TransactionContext;)Lio/sentry/ITransaction; - public abstract fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction; - public fun startTransaction (Ljava/lang/String;Ljava/lang/String;)Lio/sentry/ITransaction; - public fun startTransaction (Ljava/lang/String;Ljava/lang/String;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction; - public abstract fun traceHeaders ()Lio/sentry/SentryTraceHeader; - public abstract fun withScope (Lio/sentry/ScopeCallback;)V +public abstract interface class io/sentry/IHub : io/sentry/IScopes { } public abstract interface class io/sentry/ILogger { @@ -731,6 +720,74 @@ public abstract interface class io/sentry/IScopeObserver { public abstract fun setUser (Lio/sentry/protocol/User;)V } +public abstract interface class io/sentry/IScopes { + public abstract fun addBreadcrumb (Lio/sentry/Breadcrumb;)V + public abstract fun addBreadcrumb (Lio/sentry/Breadcrumb;Lio/sentry/Hint;)V + public fun addBreadcrumb (Ljava/lang/String;)V + public fun addBreadcrumb (Ljava/lang/String;Ljava/lang/String;)V + public abstract fun bindClient (Lio/sentry/ISentryClient;)V + public abstract fun captureCheckIn (Lio/sentry/CheckIn;)Lio/sentry/protocol/SentryId; + public fun captureEnvelope (Lio/sentry/SentryEnvelope;)Lio/sentry/protocol/SentryId; + public abstract fun captureEnvelope (Lio/sentry/SentryEnvelope;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; + public fun captureEvent (Lio/sentry/SentryEvent;)Lio/sentry/protocol/SentryId; + public abstract fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; + public abstract fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public fun captureException (Ljava/lang/Throwable;)Lio/sentry/protocol/SentryId; + public abstract fun captureException (Ljava/lang/Throwable;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; + public abstract fun captureException (Ljava/lang/Throwable;Lio/sentry/Hint;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public fun captureException (Ljava/lang/Throwable;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public fun captureMessage (Ljava/lang/String;)Lio/sentry/protocol/SentryId; + public fun captureMessage (Ljava/lang/String;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public abstract fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;)Lio/sentry/protocol/SentryId; + public abstract fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public fun captureTransaction (Lio/sentry/protocol/SentryTransaction;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; + public fun captureTransaction (Lio/sentry/protocol/SentryTransaction;Lio/sentry/TraceContext;)Lio/sentry/protocol/SentryId; + public fun captureTransaction (Lio/sentry/protocol/SentryTransaction;Lio/sentry/TraceContext;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; + public abstract fun captureTransaction (Lio/sentry/protocol/SentryTransaction;Lio/sentry/TraceContext;Lio/sentry/Hint;Lio/sentry/ProfilingTraceData;)Lio/sentry/protocol/SentryId; + public abstract fun captureUserFeedback (Lio/sentry/UserFeedback;)V + public abstract fun clearBreadcrumbs ()V + public abstract fun clone ()Lio/sentry/IHub; + public abstract fun close ()V + public abstract fun close (Z)V + public abstract fun configureScope (Lio/sentry/ScopeCallback;)V + public abstract fun continueTrace (Ljava/lang/String;Ljava/util/List;)Lio/sentry/TransactionContext; + public abstract fun endSession ()V + public abstract fun flush (J)V + public abstract fun getBaggage ()Lio/sentry/BaggageHeader; + public abstract fun getLastEventId ()Lio/sentry/protocol/SentryId; + public abstract fun getOptions ()Lio/sentry/SentryOptions; + public abstract fun getRateLimiter ()Lio/sentry/transport/RateLimiter; + public abstract fun getSpan ()Lio/sentry/ISpan; + public abstract fun getTraceparent ()Lio/sentry/SentryTraceHeader; + public abstract fun getTransaction ()Lio/sentry/ITransaction; + public abstract fun isCrashedLastRun ()Ljava/lang/Boolean; + public abstract fun isEnabled ()Z + public abstract fun isHealthy ()Z + public fun isNoOp ()Z + public abstract fun metrics ()Lio/sentry/metrics/MetricsApi; + public abstract fun popScope ()V + public abstract fun pushScope ()V + public abstract fun removeExtra (Ljava/lang/String;)V + public abstract fun removeTag (Ljava/lang/String;)V + public fun reportFullDisplayed ()V + public abstract fun reportFullyDisplayed ()V + public abstract fun setExtra (Ljava/lang/String;Ljava/lang/String;)V + public abstract fun setFingerprint (Ljava/util/List;)V + public abstract fun setLevel (Lio/sentry/SentryLevel;)V + public abstract fun setSpanContext (Ljava/lang/Throwable;Lio/sentry/ISpan;Ljava/lang/String;)V + public abstract fun setTag (Ljava/lang/String;Ljava/lang/String;)V + public abstract fun setTransaction (Ljava/lang/String;)V + public abstract fun setUser (Lio/sentry/protocol/User;)V + public abstract fun startSession ()V + public fun startTransaction (Lio/sentry/TransactionContext;)Lio/sentry/ITransaction; + public abstract fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction; + public fun startTransaction (Ljava/lang/String;Ljava/lang/String;)Lio/sentry/ITransaction; + public fun startTransaction (Ljava/lang/String;Ljava/lang/String;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction; + public abstract fun traceHeaders ()Lio/sentry/SentryTraceHeader; + public abstract fun withScope (Lio/sentry/ScopeCallback;)V +} + public abstract interface class io/sentry/ISentryClient { public abstract fun captureCheckIn (Lio/sentry/CheckIn;Lio/sentry/IScope;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; public fun captureEnvelope (Lio/sentry/SentryEnvelope;)Lio/sentry/protocol/SentryId; @@ -853,7 +910,7 @@ public final class io/sentry/Instrumenter : java/lang/Enum { } public abstract interface class io/sentry/Integration { - public abstract fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public abstract fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/IpAddressUtils { @@ -1187,6 +1244,7 @@ public final class io/sentry/NoOpHub : io/sentry/IHub { public fun isCrashedLastRun ()Ljava/lang/Boolean; public fun isEnabled ()Z public fun isHealthy ()Z + public fun isNoOp ()Z public fun metrics ()Lio/sentry/metrics/MetricsApi; public fun popScope ()V public fun pushScope ()V @@ -1270,6 +1328,60 @@ public final class io/sentry/NoOpScope : io/sentry/IScope { public fun withTransaction (Lio/sentry/Scope$IWithTransaction;)V } +public final class io/sentry/NoOpScopes : io/sentry/IScopes { + public fun addBreadcrumb (Lio/sentry/Breadcrumb;)V + public fun addBreadcrumb (Lio/sentry/Breadcrumb;Lio/sentry/Hint;)V + public fun bindClient (Lio/sentry/ISentryClient;)V + public fun captureCheckIn (Lio/sentry/CheckIn;)Lio/sentry/protocol/SentryId; + public fun captureEnvelope (Lio/sentry/SentryEnvelope;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; + public fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; + public fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public fun captureException (Ljava/lang/Throwable;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; + public fun captureException (Ljava/lang/Throwable;Lio/sentry/Hint;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;)Lio/sentry/protocol/SentryId; + public fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public fun captureTransaction (Lio/sentry/protocol/SentryTransaction;Lio/sentry/TraceContext;Lio/sentry/Hint;Lio/sentry/ProfilingTraceData;)Lio/sentry/protocol/SentryId; + public fun captureUserFeedback (Lio/sentry/UserFeedback;)V + public fun clearBreadcrumbs ()V + public fun clone ()Lio/sentry/IHub; + public synthetic fun clone ()Ljava/lang/Object; + public fun close ()V + public fun close (Z)V + public fun configureScope (Lio/sentry/ScopeCallback;)V + public fun continueTrace (Ljava/lang/String;Ljava/util/List;)Lio/sentry/TransactionContext; + public fun endSession ()V + public fun flush (J)V + public fun getBaggage ()Lio/sentry/BaggageHeader; + public static fun getInstance ()Lio/sentry/NoOpScopes; + public fun getLastEventId ()Lio/sentry/protocol/SentryId; + public fun getOptions ()Lio/sentry/SentryOptions; + public fun getRateLimiter ()Lio/sentry/transport/RateLimiter; + public fun getSpan ()Lio/sentry/ISpan; + public fun getTraceparent ()Lio/sentry/SentryTraceHeader; + public fun getTransaction ()Lio/sentry/ITransaction; + public fun isCrashedLastRun ()Ljava/lang/Boolean; + public fun isEnabled ()Z + public fun isHealthy ()Z + public fun isNoOp ()Z + public fun metrics ()Lio/sentry/metrics/MetricsApi; + public fun popScope ()V + public fun pushScope ()V + public fun removeExtra (Ljava/lang/String;)V + public fun removeTag (Ljava/lang/String;)V + public fun reportFullyDisplayed ()V + public fun setExtra (Ljava/lang/String;Ljava/lang/String;)V + public fun setFingerprint (Ljava/util/List;)V + public fun setLevel (Lio/sentry/SentryLevel;)V + public fun setSpanContext (Ljava/lang/Throwable;Lio/sentry/ISpan;Ljava/lang/String;)V + public fun setTag (Ljava/lang/String;Ljava/lang/String;)V + public fun setTransaction (Ljava/lang/String;)V + public fun setUser (Lio/sentry/protocol/User;)V + public fun startSession ()V + public fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction; + public fun traceHeaders ()Lio/sentry/SentryTraceHeader; + public fun withScope (Lio/sentry/ScopeCallback;)V +} + public final class io/sentry/NoOpSpan : io/sentry/ISpan { public fun finish ()V public fun finish (Lio/sentry/SpanStatus;)V @@ -1403,7 +1515,7 @@ public final class io/sentry/OptionsContainer { } public final class io/sentry/OutboxSender : io/sentry/IEnvelopeSender { - public fun (Lio/sentry/IHub;Lio/sentry/IEnvelopeReader;Lio/sentry/ISerializer;Lio/sentry/ILogger;JI)V + public fun (Lio/sentry/IScopes;Lio/sentry/IEnvelopeReader;Lio/sentry/ISerializer;Lio/sentry/ILogger;JI)V public synthetic fun processDirectory (Ljava/io/File;)V public fun processEnvelopeFile (Ljava/lang/String;Lio/sentry/Hint;)V } @@ -1668,11 +1780,64 @@ public abstract class io/sentry/ScopeObserverAdapter : io/sentry/IScopeObserver public fun setUser (Lio/sentry/protocol/User;)V } +public final class io/sentry/ScopesAdapter : io/sentry/IScopes { + public fun addBreadcrumb (Lio/sentry/Breadcrumb;)V + public fun addBreadcrumb (Lio/sentry/Breadcrumb;Lio/sentry/Hint;)V + public fun bindClient (Lio/sentry/ISentryClient;)V + public fun captureCheckIn (Lio/sentry/CheckIn;)Lio/sentry/protocol/SentryId; + public fun captureEnvelope (Lio/sentry/SentryEnvelope;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; + public fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; + public fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public fun captureException (Ljava/lang/Throwable;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; + public fun captureException (Ljava/lang/Throwable;Lio/sentry/Hint;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;)Lio/sentry/protocol/SentryId; + public fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; + public fun captureTransaction (Lio/sentry/protocol/SentryTransaction;Lio/sentry/TraceContext;Lio/sentry/Hint;Lio/sentry/ProfilingTraceData;)Lio/sentry/protocol/SentryId; + public fun captureUserFeedback (Lio/sentry/UserFeedback;)V + public fun clearBreadcrumbs ()V + public fun clone ()Lio/sentry/IHub; + public synthetic fun clone ()Ljava/lang/Object; + public fun close ()V + public fun close (Z)V + public fun configureScope (Lio/sentry/ScopeCallback;)V + public fun continueTrace (Ljava/lang/String;Ljava/util/List;)Lio/sentry/TransactionContext; + public fun endSession ()V + public fun flush (J)V + public fun getBaggage ()Lio/sentry/BaggageHeader; + public static fun getInstance ()Lio/sentry/ScopesAdapter; + public fun getLastEventId ()Lio/sentry/protocol/SentryId; + public fun getOptions ()Lio/sentry/SentryOptions; + public fun getRateLimiter ()Lio/sentry/transport/RateLimiter; + public fun getSpan ()Lio/sentry/ISpan; + public fun getTraceparent ()Lio/sentry/SentryTraceHeader; + public fun getTransaction ()Lio/sentry/ITransaction; + public fun isCrashedLastRun ()Ljava/lang/Boolean; + public fun isEnabled ()Z + public fun isHealthy ()Z + public fun metrics ()Lio/sentry/metrics/MetricsApi; + public fun popScope ()V + public fun pushScope ()V + public fun removeExtra (Ljava/lang/String;)V + public fun removeTag (Ljava/lang/String;)V + public fun reportFullyDisplayed ()V + public fun setExtra (Ljava/lang/String;Ljava/lang/String;)V + public fun setFingerprint (Ljava/util/List;)V + public fun setLevel (Lio/sentry/SentryLevel;)V + public fun setSpanContext (Ljava/lang/Throwable;Lio/sentry/ISpan;Ljava/lang/String;)V + public fun setTag (Ljava/lang/String;Ljava/lang/String;)V + public fun setTransaction (Ljava/lang/String;)V + public fun setUser (Lio/sentry/protocol/User;)V + public fun startSession ()V + public fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction; + public fun traceHeaders ()Lio/sentry/SentryTraceHeader; + public fun withScope (Lio/sentry/ScopeCallback;)V +} + public final class io/sentry/SendCachedEnvelopeFireAndForgetIntegration : io/sentry/IConnectionStatusProvider$IConnectionStatusObserver, io/sentry/Integration, java/io/Closeable { public fun (Lio/sentry/SendCachedEnvelopeFireAndForgetIntegration$SendFireAndForgetFactory;)V public fun close ()V public fun onConnectionStatusChanged (Lio/sentry/IConnectionStatusProvider$ConnectionStatus;)V - public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public abstract interface class io/sentry/SendCachedEnvelopeFireAndForgetIntegration$SendFireAndForget { @@ -1684,19 +1849,19 @@ public abstract interface class io/sentry/SendCachedEnvelopeFireAndForgetIntegra } public abstract interface class io/sentry/SendCachedEnvelopeFireAndForgetIntegration$SendFireAndForgetFactory { - public abstract fun create (Lio/sentry/IHub;Lio/sentry/SentryOptions;)Lio/sentry/SendCachedEnvelopeFireAndForgetIntegration$SendFireAndForget; + public abstract fun create (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)Lio/sentry/SendCachedEnvelopeFireAndForgetIntegration$SendFireAndForget; public fun hasValidPath (Ljava/lang/String;Lio/sentry/ILogger;)Z public fun processDir (Lio/sentry/DirectoryProcessor;Ljava/lang/String;Lio/sentry/ILogger;)Lio/sentry/SendCachedEnvelopeFireAndForgetIntegration$SendFireAndForget; } public final class io/sentry/SendFireAndForgetEnvelopeSender : io/sentry/SendCachedEnvelopeFireAndForgetIntegration$SendFireAndForgetFactory { public fun (Lio/sentry/SendCachedEnvelopeFireAndForgetIntegration$SendFireAndForgetDirPath;)V - public fun create (Lio/sentry/IHub;Lio/sentry/SentryOptions;)Lio/sentry/SendCachedEnvelopeFireAndForgetIntegration$SendFireAndForget; + public fun create (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)Lio/sentry/SendCachedEnvelopeFireAndForgetIntegration$SendFireAndForget; } public final class io/sentry/SendFireAndForgetOutboxSender : io/sentry/SendCachedEnvelopeFireAndForgetIntegration$SendFireAndForgetFactory { public fun (Lio/sentry/SendCachedEnvelopeFireAndForgetIntegration$SendFireAndForgetDirPath;)V - public fun create (Lio/sentry/IHub;Lio/sentry/SentryOptions;)Lio/sentry/SendCachedEnvelopeFireAndForgetIntegration$SendFireAndForget; + public fun create (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)Lio/sentry/SendCachedEnvelopeFireAndForgetIntegration$SendFireAndForget; } public final class io/sentry/Sentry { @@ -1721,7 +1886,7 @@ public final class io/sentry/Sentry { public static fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;Lio/sentry/ScopeCallback;)Lio/sentry/protocol/SentryId; public static fun captureUserFeedback (Lio/sentry/UserFeedback;)V public static fun clearBreadcrumbs ()V - public static fun cloneMainHub ()Lio/sentry/IHub; + public static fun cloneMainHub ()Lio/sentry/IScopes; public static fun close ()V public static fun configureScope (Lio/sentry/ScopeCallback;)V public static fun continueTrace (Ljava/lang/String;Ljava/util/List;)Lio/sentry/TransactionContext; @@ -1729,6 +1894,7 @@ public final class io/sentry/Sentry { public static fun flush (J)V public static fun getBaggage ()Lio/sentry/BaggageHeader; public static fun getCurrentHub ()Lio/sentry/IHub; + public static fun getCurrentScopes ()Lio/sentry/IScopes; public static fun getLastEventId ()Lio/sentry/protocol/SentryId; public static fun getSpan ()Lio/sentry/ISpan; public static fun getTraceparent ()Lio/sentry/SentryTraceHeader; @@ -1750,6 +1916,7 @@ public final class io/sentry/Sentry { public static fun reportFullDisplayed ()V public static fun reportFullyDisplayed ()V public static fun setCurrentHub (Lio/sentry/IHub;)V + public static fun setCurrentScopes (Lio/sentry/IScopes;)V public static fun setExtra (Ljava/lang/String;Ljava/lang/String;)V public static fun setFingerprint (Ljava/util/List;)V public static fun setLevel (Lio/sentry/SentryLevel;)V @@ -2500,8 +2667,8 @@ public final class io/sentry/SentryTraceHeader { } public final class io/sentry/SentryTracer : io/sentry/ITransaction { - public fun (Lio/sentry/TransactionContext;Lio/sentry/IHub;)V - public fun (Lio/sentry/TransactionContext;Lio/sentry/IHub;Lio/sentry/TransactionOptions;)V + public fun (Lio/sentry/TransactionContext;Lio/sentry/IScopes;)V + public fun (Lio/sentry/TransactionContext;Lio/sentry/IScopes;Lio/sentry/TransactionOptions;)V public fun finish ()V public fun finish (Lio/sentry/SpanStatus;)V public fun finish (Lio/sentry/SpanStatus;Lio/sentry/SentryDate;)V @@ -2630,11 +2797,11 @@ public final class io/sentry/ShutdownHookIntegration : io/sentry/Integration, ja public fun ()V public fun (Ljava/lang/Runtime;)V public fun close ()V - public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/Span : io/sentry/ISpan { - public fun (Lio/sentry/TransactionContext;Lio/sentry/SentryTracer;Lio/sentry/IHub;Lio/sentry/SentryDate;Lio/sentry/SpanOptions;)V + public fun (Lio/sentry/TransactionContext;Lio/sentry/SentryTracer;Lio/sentry/IScopes;Lio/sentry/SentryDate;Lio/sentry/SpanOptions;)V public fun finish ()V public fun finish (Lio/sentry/SpanStatus;)V public fun finish (Lio/sentry/SpanStatus;Lio/sentry/SentryDate;)V @@ -2815,7 +2982,7 @@ public final class io/sentry/SpotlightIntegration : io/sentry/Integration, io/se public fun close ()V public fun execute (Lio/sentry/SentryEnvelope;Lio/sentry/Hint;)V public fun getSpotlightConnectionUrl ()Ljava/lang/String; - public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/SystemOutLogger : io/sentry/ILogger { @@ -2975,7 +3142,7 @@ public final class io/sentry/TypeCheckHint { public final class io/sentry/UncaughtExceptionHandlerIntegration : io/sentry/Integration, java/io/Closeable, java/lang/Thread$UncaughtExceptionHandler { public fun ()V public fun close ()V - public final fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public final fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V public fun uncaughtException (Ljava/lang/Thread;Ljava/lang/Throwable;)V } @@ -3016,7 +3183,7 @@ public final class io/sentry/UserFeedback$JsonKeys { } public final class io/sentry/backpressure/BackpressureMonitor : io/sentry/backpressure/IBackpressureMonitor, java/lang/Runnable { - public fun (Lio/sentry/SentryOptions;Lio/sentry/IHub;)V + public fun (Lio/sentry/SentryOptions;Lio/sentry/IScopes;)V public fun getDownsampleFactor ()I public fun run ()V public fun start ()V @@ -5102,9 +5269,9 @@ public final class io/sentry/util/StringUtils { public final class io/sentry/util/TracingUtils { public fun ()V public static fun maybeUpdateBaggage (Lio/sentry/IScope;Lio/sentry/SentryOptions;)Lio/sentry/PropagationContext; - public static fun startNewTrace (Lio/sentry/IHub;)V - public static fun trace (Lio/sentry/IHub;Ljava/util/List;Lio/sentry/ISpan;)Lio/sentry/util/TracingUtils$TracingHeaders; - public static fun traceIfAllowed (Lio/sentry/IHub;Ljava/lang/String;Ljava/util/List;Lio/sentry/ISpan;)Lio/sentry/util/TracingUtils$TracingHeaders; + public static fun startNewTrace (Lio/sentry/IScopes;)V + public static fun trace (Lio/sentry/IScopes;Ljava/util/List;Lio/sentry/ISpan;)Lio/sentry/util/TracingUtils$TracingHeaders; + public static fun traceIfAllowed (Lio/sentry/IScopes;Ljava/lang/String;Ljava/util/List;Lio/sentry/ISpan;)Lio/sentry/util/TracingUtils$TracingHeaders; } public final class io/sentry/util/TracingUtils$TracingHeaders { diff --git a/sentry/src/main/java/io/sentry/Hub.java b/sentry/src/main/java/io/sentry/Hub.java index 6b6da88f09..6a98bb2367 100644 --- a/sentry/src/main/java/io/sentry/Hub.java +++ b/sentry/src/main/java/io/sentry/Hub.java @@ -27,6 +27,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +@Deprecated public final class Hub implements IHub, MetricsApi.IMetricsInterface { private volatile @NotNull SentryId lastEventId; diff --git a/sentry/src/main/java/io/sentry/HubAdapter.java b/sentry/src/main/java/io/sentry/HubAdapter.java index b31d853192..746d51f0cc 100644 --- a/sentry/src/main/java/io/sentry/HubAdapter.java +++ b/sentry/src/main/java/io/sentry/HubAdapter.java @@ -10,6 +10,10 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +/** + * @deprecated use {@link ScopesAdapter} instead + */ +@Deprecated public final class HubAdapter implements IHub { private static final HubAdapter INSTANCE = new HubAdapter(); @@ -50,7 +54,7 @@ public boolean isEnabled() { @ApiStatus.Internal @Override public @NotNull SentryId captureEnvelope(@NotNull SentryEnvelope envelope, @Nullable Hint hint) { - return Sentry.getCurrentHub().captureEnvelope(envelope, hint); + return Sentry.getCurrentScopes().captureEnvelope(envelope, hint); } @Override @@ -186,7 +190,7 @@ public void flush(long timeoutMillis) { @Override public @NotNull IHub clone() { - return Sentry.getCurrentHub().clone(); + return Sentry.getCurrentScopes().clone(); } @Override @@ -195,7 +199,7 @@ public void flush(long timeoutMillis) { @Nullable TraceContext traceContext, @Nullable Hint hint, @Nullable ProfilingTraceData profilingTraceData) { - return Sentry.getCurrentHub() + return Sentry.getCurrentScopes() .captureTransaction(transaction, traceContext, hint, profilingTraceData); } @@ -217,23 +221,23 @@ public void setSpanContext( final @NotNull Throwable throwable, final @NotNull ISpan span, final @NotNull String transactionName) { - Sentry.getCurrentHub().setSpanContext(throwable, span, transactionName); + Sentry.getCurrentScopes().setSpanContext(throwable, span, transactionName); } @Override public @Nullable ISpan getSpan() { - return Sentry.getCurrentHub().getSpan(); + return Sentry.getCurrentScopes().getSpan(); } @Override @ApiStatus.Internal public @Nullable ITransaction getTransaction() { - return Sentry.getCurrentHub().getTransaction(); + return Sentry.getCurrentScopes().getTransaction(); } @Override public @NotNull SentryOptions getOptions() { - return Sentry.getCurrentHub().getOptions(); + return Sentry.getCurrentScopes().getOptions(); } @Override @@ -271,11 +275,11 @@ public void reportFullyDisplayed() { @ApiStatus.Internal @Override public @Nullable RateLimiter getRateLimiter() { - return Sentry.getCurrentHub().getRateLimiter(); + return Sentry.getCurrentScopes().getRateLimiter(); } @Override public @NotNull MetricsApi metrics() { - return Sentry.getCurrentHub().metrics(); + return Sentry.getCurrentScopes().metrics(); } } diff --git a/sentry/src/main/java/io/sentry/HubScopesWrapper.java b/sentry/src/main/java/io/sentry/HubScopesWrapper.java new file mode 100644 index 0000000000..9b294d05b7 --- /dev/null +++ b/sentry/src/main/java/io/sentry/HubScopesWrapper.java @@ -0,0 +1,279 @@ +package io.sentry; + +import io.sentry.metrics.MetricsApi; +import io.sentry.protocol.SentryId; +import io.sentry.protocol.SentryTransaction; +import io.sentry.protocol.User; +import io.sentry.transport.RateLimiter; +import java.util.List; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@SuppressWarnings("deprecation") +@Deprecated +public final class HubScopesWrapper implements IHub { + + private final IScopes scopes; + + public HubScopesWrapper(final @NotNull IScopes scopes) { + this.scopes = scopes; + } + + @Override + public boolean isEnabled() { + return scopes.isEnabled(); + } + + @Override + public @NotNull SentryId captureEvent(@NotNull SentryEvent event, @Nullable Hint hint) { + return scopes.captureEvent(event, hint); + } + + @Override + public @NotNull SentryId captureEvent( + @NotNull SentryEvent event, @Nullable Hint hint, @NotNull ScopeCallback callback) { + return scopes.captureEvent(event, hint, callback); + } + + @Override + public @NotNull SentryId captureMessage(@NotNull String message, @NotNull SentryLevel level) { + return scopes.captureMessage(message, level); + } + + @Override + public @NotNull SentryId captureMessage( + @NotNull String message, @NotNull SentryLevel level, @NotNull ScopeCallback callback) { + return scopes.captureMessage(message, level, callback); + } + + @Override + public @NotNull SentryId captureEnvelope(@NotNull SentryEnvelope envelope, @Nullable Hint hint) { + return scopes.captureEnvelope(envelope, hint); + } + + @Override + public @NotNull SentryId captureException(@NotNull Throwable throwable, @Nullable Hint hint) { + return scopes.captureException(throwable, hint); + } + + @Override + public @NotNull SentryId captureException( + @NotNull Throwable throwable, @Nullable Hint hint, @NotNull ScopeCallback callback) { + return scopes.captureException(throwable, hint, callback); + } + + @Override + public void captureUserFeedback(@NotNull UserFeedback userFeedback) { + scopes.captureUserFeedback(userFeedback); + } + + @Override + public void startSession() { + scopes.startSession(); + } + + @Override + public void endSession() { + scopes.endSession(); + } + + @Override + public void close() { + scopes.close(); + } + + @Override + public void close(boolean isRestarting) { + scopes.close(isRestarting); + } + + @Override + public void addBreadcrumb(@NotNull Breadcrumb breadcrumb, @Nullable Hint hint) { + scopes.addBreadcrumb(breadcrumb, hint); + } + + @Override + public void addBreadcrumb(@NotNull Breadcrumb breadcrumb) { + scopes.addBreadcrumb(breadcrumb); + } + + @Override + public void setLevel(@Nullable SentryLevel level) { + scopes.setLevel(level); + } + + @Override + public void setTransaction(@Nullable String transaction) { + scopes.setTransaction(transaction); + } + + @Override + public void setUser(@Nullable User user) { + scopes.setUser(user); + } + + @Override + public void setFingerprint(@NotNull List fingerprint) { + scopes.setFingerprint(fingerprint); + } + + @Override + public void clearBreadcrumbs() { + scopes.clearBreadcrumbs(); + } + + @Override + public void setTag(@NotNull String key, @NotNull String value) { + scopes.setTag(key, value); + } + + @Override + public void removeTag(@NotNull String key) { + scopes.removeTag(key); + } + + @Override + public void setExtra(@NotNull String key, @NotNull String value) { + scopes.setExtra(key, value); + } + + @Override + public void removeExtra(@NotNull String key) { + scopes.removeExtra(key); + } + + @Override + public @NotNull SentryId getLastEventId() { + return scopes.getLastEventId(); + } + + @Override + public void pushScope() { + scopes.pushScope(); + } + + @Override + public void popScope() { + scopes.popScope(); + } + + @Override + public void withScope(@NotNull ScopeCallback callback) { + scopes.withScope(callback); + } + + @Override + public void configureScope(@NotNull ScopeCallback callback) { + scopes.configureScope(callback); + } + + @Override + public void bindClient(@NotNull ISentryClient client) { + scopes.bindClient(client); + } + + @Override + public boolean isHealthy() { + return scopes.isHealthy(); + } + + @Override + public void flush(long timeoutMillis) { + scopes.flush(timeoutMillis); + } + + @Override + public @NotNull IHub clone() { + return scopes.clone(); + } + + @ApiStatus.Internal + @Override + public @NotNull SentryId captureTransaction( + @NotNull SentryTransaction transaction, + @Nullable TraceContext traceContext, + @Nullable Hint hint, + @Nullable ProfilingTraceData profilingTraceData) { + return scopes.captureTransaction(transaction, traceContext, hint, profilingTraceData); + } + + @Override + public @NotNull ITransaction startTransaction( + @NotNull TransactionContext transactionContext, + @NotNull TransactionOptions transactionOptions) { + return scopes.startTransaction(transactionContext, transactionOptions); + } + + @Override + public @Nullable SentryTraceHeader traceHeaders() { + return scopes.traceHeaders(); + } + + @ApiStatus.Internal + @Override + public void setSpanContext( + @NotNull Throwable throwable, @NotNull ISpan span, @NotNull String transactionName) { + scopes.setSpanContext(throwable, span, transactionName); + } + + @Override + public @Nullable ISpan getSpan() { + return scopes.getSpan(); + } + + @ApiStatus.Internal + @Override + public @Nullable ITransaction getTransaction() { + return scopes.getTransaction(); + } + + @Override + public @NotNull SentryOptions getOptions() { + return scopes.getOptions(); + } + + @Override + public @Nullable Boolean isCrashedLastRun() { + return scopes.isCrashedLastRun(); + } + + @Override + public void reportFullyDisplayed() { + scopes.reportFullyDisplayed(); + } + + @Override + public @Nullable TransactionContext continueTrace( + @Nullable String sentryTrace, @Nullable List baggageHeaders) { + return scopes.continueTrace(sentryTrace, baggageHeaders); + } + + @Override + public @Nullable SentryTraceHeader getTraceparent() { + return scopes.getTraceparent(); + } + + @Override + public @Nullable BaggageHeader getBaggage() { + return scopes.getBaggage(); + } + + @ApiStatus.Experimental + @Override + public @NotNull SentryId captureCheckIn(@NotNull CheckIn checkIn) { + return scopes.captureCheckIn(checkIn); + } + + @ApiStatus.Internal + @Override + public @Nullable RateLimiter getRateLimiter() { + return scopes.getRateLimiter(); + } + + @ApiStatus.Experimental + @Override + public @NotNull MetricsApi metrics() { + return scopes.metrics(); + } +} diff --git a/sentry/src/main/java/io/sentry/IHub.java b/sentry/src/main/java/io/sentry/IHub.java index 684d8ec528..23a7bed7de 100644 --- a/sentry/src/main/java/io/sentry/IHub.java +++ b/sentry/src/main/java/io/sentry/IHub.java @@ -1,590 +1,9 @@ package io.sentry; -import io.sentry.metrics.MetricsApi; -import io.sentry.protocol.SentryId; -import io.sentry.protocol.SentryTransaction; -import io.sentry.protocol.User; -import io.sentry.transport.RateLimiter; -import java.util.List; -import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** SDK API contract which combines a client and scope management */ -public interface IHub { - - /** - * Check if the Hub is enabled/active. - * - * @return true if its enabled or false otherwise. - */ - boolean isEnabled(); - - /** - * Captures the event. - * - * @param event the event - * @param hint SDK specific but provides high level information about the origin of the event - * @return The Id (SentryId object) of the event - */ - @NotNull - SentryId captureEvent(@NotNull SentryEvent event, @Nullable Hint hint); - - /** - * Captures the event. - * - * @param event the event - * @return The Id (SentryId object) of the event - */ - default @NotNull SentryId captureEvent(@NotNull SentryEvent event) { - return captureEvent(event, new Hint()); - } - - /** - * Captures the event. - * - * @param event the event - * @param callback The callback to configure the scope for a single invocation. - * @return The Id (SentryId object) of the event - */ - default @NotNull SentryId captureEvent( - @NotNull SentryEvent event, final @NotNull ScopeCallback callback) { - return captureEvent(event, new Hint(), callback); - } - - /** - * Captures the event. - * - * @param event the event - * @param hint SDK specific but provides high level information about the origin of the event - * @param callback The callback to configure the scope for a single invocation. - * @return The Id (SentryId object) of the event - */ - @NotNull - SentryId captureEvent( - final @NotNull SentryEvent event, - final @Nullable Hint hint, - final @NotNull ScopeCallback callback); - - /** - * Captures the message. - * - * @param message The message to send. - * @return The Id (SentryId object) of the event - */ - default @NotNull SentryId captureMessage(@NotNull String message) { - return captureMessage(message, SentryLevel.INFO); - } - - /** - * Captures the message. - * - * @param message The message to send. - * @param level The message level. - * @return The Id (SentryId object) of the event - */ - @NotNull - SentryId captureMessage(@NotNull String message, @NotNull SentryLevel level); - - /** - * Captures the message. - * - * @param message The message to send. - * @param level The message level. - * @param callback The callback to configure the scope for a single invocation. - * @return The Id (SentryId object) of the event - */ - @NotNull - SentryId captureMessage( - @NotNull String message, @NotNull SentryLevel level, @NotNull ScopeCallback callback); - - /** - * Captures the message. - * - * @param message The message to send. - * @param callback The callback to configure the scope for a single invocation. - * @return The Id (SentryId object) of the event - */ - default @NotNull SentryId captureMessage( - @NotNull String message, @NotNull ScopeCallback callback) { - return captureMessage(message, SentryLevel.INFO, callback); - } - - /** - * Captures an envelope. - * - * @param envelope the SentryEnvelope to send. - * @param hint SDK specific but provides high level information about the origin of the event - * @return The Id (SentryId object) of the event - */ - @NotNull - SentryId captureEnvelope(@NotNull SentryEnvelope envelope, @Nullable Hint hint); - - /** - * Captures an envelope. - * - * @param envelope the SentryEnvelope to send. - * @return The Id (SentryId object) of the event - */ - default @NotNull SentryId captureEnvelope(@NotNull SentryEnvelope envelope) { - return captureEnvelope(envelope, new Hint()); - } - - /** - * Captures the exception. - * - * @param throwable The exception. - * @param hint SDK specific but provides high level information about the origin of the event - * @return The Id (SentryId object) of the event - */ - @NotNull - SentryId captureException(@NotNull Throwable throwable, @Nullable Hint hint); - - /** - * Captures the exception. - * - * @param throwable The exception. - * @return The Id (SentryId object) of the event - */ - default @NotNull SentryId captureException(@NotNull Throwable throwable) { - return captureException(throwable, new Hint()); - } - - /** - * Captures the exception. - * - * @param throwable The exception. - * @param callback The callback to configure the scope for a single invocation. - * @return The Id (SentryId object) of the event - */ - default @NotNull SentryId captureException( - @NotNull Throwable throwable, final @NotNull ScopeCallback callback) { - return captureException(throwable, new Hint(), callback); - } - - /** - * Captures the exception. - * - * @param throwable The exception. - * @param hint SDK specific but provides high level information about the origin of the event - * @param callback The callback to configure the scope for a single invocation. - * @return The Id (SentryId object) of the event - */ - @NotNull - SentryId captureException( - final @NotNull Throwable throwable, - final @Nullable Hint hint, - final @NotNull ScopeCallback callback); - - /** - * Captures a manually created user feedback and sends it to Sentry. - * - * @param userFeedback The user feedback to send to Sentry. - */ - void captureUserFeedback(@NotNull UserFeedback userFeedback); - - /** Starts a new session. If there's a running session, it ends it before starting the new one. */ - void startSession(); - - /** Ends the current session */ - void endSession(); - - /** Flushes out the queue for up to timeout seconds and disable the Hub. */ - void close(); - - /** - * Flushes out the queue for up to timeout seconds and disable the Hub. - * - * @param isRestarting if true, avoids locking the main thread when finishing the queue. - */ - void close(boolean isRestarting); - - /** - * Adds a breadcrumb to the current Scope - * - * @param breadcrumb the breadcrumb - * @param hint SDK specific but provides high level information about the origin of the event - */ - void addBreadcrumb(@NotNull Breadcrumb breadcrumb, @Nullable Hint hint); - - /** - * Adds a breadcrumb to the current Scope - * - * @param breadcrumb the breadcrumb - */ - void addBreadcrumb(@NotNull Breadcrumb breadcrumb); - - /** - * Adds a breadcrumb to the current Scope - * - * @param message rendered as text and the whitespace is preserved. - */ - default void addBreadcrumb(@NotNull String message) { - addBreadcrumb(new Breadcrumb(message)); - } - - /** - * Adds a breadcrumb to the current Scope - * - * @param message rendered as text and the whitespace is preserved. - * @param category Categories are dotted strings that indicate what the crumb is or where it comes - * from. - */ - default void addBreadcrumb(@NotNull String message, @NotNull String category) { - Breadcrumb breadcrumb = new Breadcrumb(message); - breadcrumb.setCategory(category); - addBreadcrumb(breadcrumb); - } - - /** - * Sets the level of all events sent within current Scope - * - * @param level the Sentry level - */ - void setLevel(@Nullable SentryLevel level); - - /** - * Sets the name of the current transaction to the current Scope. - * - * @param transaction the transaction - */ - void setTransaction(@Nullable String transaction); - - /** - * Shallow merges user configuration (email, username, etc) to the current Scope. - * - * @param user the user - */ - void setUser(@Nullable User user); - - /** - * Sets the fingerprint to group specific events together to the current Scope. - * - * @param fingerprint the fingerprints - */ - void setFingerprint(@NotNull List fingerprint); - - /** Deletes current breadcrumbs from the current scope. */ - void clearBreadcrumbs(); - - /** - * Sets the tag to a string value to the current Scope, overwriting a potential previous value - * - * @param key the key - * @param value the value - */ - void setTag(@NotNull String key, @NotNull String value); - - /** - * Removes the tag to a string value to the current Scope - * - * @param key the key - */ - void removeTag(@NotNull String key); - - /** - * Sets the extra key to an arbitrary value to the current Scope, overwriting a potential previous - * value - * - * @param key the key - * @param value the value - */ - void setExtra(@NotNull String key, @NotNull String value); - - /** - * Removes the extra key to an arbitrary value to the current Scope - * - * @param key the key - */ - void removeExtra(@NotNull String key); - - /** - * Last event id recorded in the current scope - * - * @return last SentryId - */ - @NotNull - SentryId getLastEventId(); - - /** Pushes a new scope while inheriting the current scope's data. */ - void pushScope(); - - /** Removes the first scope */ - void popScope(); - - /** - * Runs the callback with a new scope which gets dropped at the end. If you're using the Sentry - * SDK in globalHubMode (defaults to true on Android) {@link - * Sentry#init(Sentry.OptionsConfiguration, boolean)} calling withScope is discouraged, as scope - * changes may be dropped when executed in parallel. Use {@link - * IHub#configureScope(ScopeCallback)} instead. - * - * @param callback the callback - */ - void withScope(@NotNull ScopeCallback callback); - - /** - * Configures the scope through the callback. - * - * @param callback The configure scope callback. - */ - void configureScope(@NotNull ScopeCallback callback); - - /** - * Binds a different client to the hub - * - * @param client the client. - */ - void bindClient(@NotNull ISentryClient client); - - /** - * Whether the transport is healthy. - * - * @return true if the transport is healthy - */ - boolean isHealthy(); - - /** - * Flushes events queued up, but keeps the Hub enabled. Not implemented yet. - * - * @param timeoutMillis time in milliseconds - */ - void flush(long timeoutMillis); - - /** - * Clones the Hub - * - * @return the cloned Hub - */ - @NotNull - IHub clone(); - - /** - * Captures the transaction and enqueues it for sending to Sentry server. - * - * @param transaction the transaction - * @param traceContext the trace context - * @param hint the hints - * @param profilingTraceData the profiling trace data - * @return transaction's id - */ - @ApiStatus.Internal - @NotNull - SentryId captureTransaction( - @NotNull SentryTransaction transaction, - @Nullable TraceContext traceContext, - @Nullable Hint hint, - @Nullable ProfilingTraceData profilingTraceData); - - /** - * Captures the transaction and enqueues it for sending to Sentry server. - * - * @param transaction the transaction - * @param traceContext the trace context - * @param hint the hints - * @return transaction's id - */ - @ApiStatus.Internal - @NotNull - default SentryId captureTransaction( - @NotNull SentryTransaction transaction, - @Nullable TraceContext traceContext, - @Nullable Hint hint) { - return captureTransaction(transaction, traceContext, hint, null); - } - - @ApiStatus.Internal - @NotNull - default SentryId captureTransaction(@NotNull SentryTransaction transaction, @Nullable Hint hint) { - return captureTransaction(transaction, null, hint); - } - - /** - * Captures the transaction and enqueues it for sending to Sentry server. - * - * @param transaction the transaction - * @param traceContext the trace context - * @return transaction's id - */ - @ApiStatus.Internal - default @NotNull SentryId captureTransaction( - @NotNull SentryTransaction transaction, @Nullable TraceContext traceContext) { - return captureTransaction(transaction, traceContext, null); - } - - /** - * Creates a Transaction and returns the instance. - * - * @param transactionContexts the transaction contexts - * @return created transaction - */ - default @NotNull ITransaction startTransaction(@NotNull TransactionContext transactionContexts) { - return startTransaction(transactionContexts, new TransactionOptions()); - } - - /** - * Creates a Transaction and returns the instance. Based on the {@link - * SentryOptions#getTracesSampleRate()} the decision if transaction is sampled will be taken by - * {@link TracesSampler}. - * - * @param name the transaction name - * @param operation the operation - * @return created transaction - */ - default @NotNull ITransaction startTransaction( - final @NotNull String name, final @NotNull String operation) { - return startTransaction(name, operation, new TransactionOptions()); - } - - /** - * Creates a Transaction and returns the instance. Based on the {@link - * SentryOptions#getTracesSampleRate()} the decision if transaction is sampled will be taken by - * {@link TracesSampler}. - * - * @param name the transaction name - * @param operation the operation - * @param transactionOptions the transaction options - * @return created transaction - */ - default @NotNull ITransaction startTransaction( - final @NotNull String name, - final @NotNull String operation, - final @NotNull TransactionOptions transactionOptions) { - return startTransaction(new TransactionContext(name, operation), transactionOptions); - } - - /** - * Creates a Transaction and returns the instance. Based on the passed transaction context and - * transaction options the decision if transaction is sampled will be taken by {@link - * TracesSampler}. - * - * @param transactionContext the transaction context - * @param transactionOptions the transaction options - * @return created transaction. - */ - @NotNull - ITransaction startTransaction( - final @NotNull TransactionContext transactionContext, - final @NotNull TransactionOptions transactionOptions); - - /** - * Returns the "sentry-trace" header that allows tracing across services. Can also be used in - * <meta> HTML tags. Also see {@link IHub#getBaggage()}. - * - * @deprecated please use {@link IHub#getTraceparent()} instead. - * @return sentry trace header or null - */ - @Deprecated - @Nullable - SentryTraceHeader traceHeaders(); - - /** - * Associates {@link ISpan} and the transaction name with the {@link Throwable}. Used to determine - * in which trace the exception has been thrown in framework integrations. - * - * @param throwable the throwable - * @param span the span context - * @param transactionName the transaction name - */ - @ApiStatus.Internal - void setSpanContext( - @NotNull Throwable throwable, @NotNull ISpan span, @NotNull String transactionName); - - /** - * Gets the current active transaction or span. - * - * @return the active span or null when no active transaction is running - */ - @Nullable - ISpan getSpan(); - - /** - * Returns the transaction. - * - * @return the transaction or null when no active transaction is running. - */ - @ApiStatus.Internal - @Nullable - ITransaction getTransaction(); - - /** - * Gets the {@link SentryOptions} attached to current scope. - * - * @return the options attached to current scope. - */ - @NotNull - SentryOptions getOptions(); - - /** - * Returns if the App has crashed (Process has terminated) during the last run. It only returns - * true or false if offline caching {{@link SentryOptions#getCacheDirPath()} } is set with a valid - * dir. - * - *

If the call to this method is early in the App lifecycle and the SDK could not check if the - * App has crashed in the background, the check is gonna do IO in the calling thread. - * - * @return true if App has crashed, false otherwise, and null if not evaluated yet - */ - @Nullable - Boolean isCrashedLastRun(); - - /** - * Report a screen has been fully loaded. That means all data needed by the UI was loaded. If - * time-to-full-display tracing {{@link SentryOptions#isEnableTimeToFullDisplayTracing()} } is - * disabled this call is ignored. - * - *

This method is safe to be called multiple times. If the time-to-full-display span is already - * finished, this call will be ignored. - */ - void reportFullyDisplayed(); - - /** - * @deprecated See {@link IHub#reportFullyDisplayed()}. - */ - @Deprecated - default void reportFullDisplayed() { - reportFullyDisplayed(); - } - - /** - * Continue a trace based on HTTP header values. If no "sentry-trace" header is provided a random - * trace ID and span ID is created. - * - * @param sentryTrace "sentry-trace" header - * @param baggageHeaders "baggage" headers - * @return a transaction context for starting a transaction or null if performance is disabled - */ - @Nullable - TransactionContext continueTrace( - final @Nullable String sentryTrace, final @Nullable List baggageHeaders); - - /** - * Returns the "sentry-trace" header that allows tracing across services. Can also be used in - * <meta> HTML tags. Also see {@link IHub#getBaggage()}. - * - * @return sentry trace header or null - */ - @Nullable - SentryTraceHeader getTraceparent(); - - /** - * Returns the "baggage" header that allows tracing across services. Can also be used in - * <meta> HTML tags. Also see {@link IHub#getTraceparent()}. - * - * @return baggage header or null - */ - @Nullable - BaggageHeader getBaggage(); - - @ApiStatus.Experimental - @NotNull - SentryId captureCheckIn(final @NotNull CheckIn checkIn); - - @ApiStatus.Internal - @Nullable - RateLimiter getRateLimiter(); - - @ApiStatus.Experimental - @NotNull - MetricsApi metrics(); -} +/** + * SDK API contract which combines a client and scope management + * + * @deprecated please use {@link IScopes} instead + */ +@Deprecated +public interface IHub extends IScopes {} diff --git a/sentry/src/main/java/io/sentry/IScopes.java b/sentry/src/main/java/io/sentry/IScopes.java new file mode 100644 index 0000000000..03662457e4 --- /dev/null +++ b/sentry/src/main/java/io/sentry/IScopes.java @@ -0,0 +1,594 @@ +package io.sentry; + +import io.sentry.metrics.MetricsApi; +import io.sentry.protocol.SentryId; +import io.sentry.protocol.SentryTransaction; +import io.sentry.protocol.User; +import io.sentry.transport.RateLimiter; +import java.util.List; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public interface IScopes { + + /** + * Check if the Hub is enabled/active. + * + * @return true if its enabled or false otherwise. + */ + boolean isEnabled(); + + /** + * Captures the event. + * + * @param event the event + * @param hint SDK specific but provides high level information about the origin of the event + * @return The Id (SentryId object) of the event + */ + @NotNull + SentryId captureEvent(@NotNull SentryEvent event, @Nullable Hint hint); + + /** + * Captures the event. + * + * @param event the event + * @return The Id (SentryId object) of the event + */ + default @NotNull SentryId captureEvent(@NotNull SentryEvent event) { + return captureEvent(event, new Hint()); + } + + /** + * Captures the event. + * + * @param event the event + * @param callback The callback to configure the scope for a single invocation. + * @return The Id (SentryId object) of the event + */ + default @NotNull SentryId captureEvent( + @NotNull SentryEvent event, final @NotNull ScopeCallback callback) { + return captureEvent(event, new Hint(), callback); + } + + /** + * Captures the event. + * + * @param event the event + * @param hint SDK specific but provides high level information about the origin of the event + * @param callback The callback to configure the scope for a single invocation. + * @return The Id (SentryId object) of the event + */ + @NotNull + SentryId captureEvent( + final @NotNull SentryEvent event, + final @Nullable Hint hint, + final @NotNull ScopeCallback callback); + + /** + * Captures the message. + * + * @param message The message to send. + * @return The Id (SentryId object) of the event + */ + default @NotNull SentryId captureMessage(@NotNull String message) { + return captureMessage(message, SentryLevel.INFO); + } + + /** + * Captures the message. + * + * @param message The message to send. + * @param level The message level. + * @return The Id (SentryId object) of the event + */ + @NotNull + SentryId captureMessage(@NotNull String message, @NotNull SentryLevel level); + + /** + * Captures the message. + * + * @param message The message to send. + * @param level The message level. + * @param callback The callback to configure the scope for a single invocation. + * @return The Id (SentryId object) of the event + */ + @NotNull + SentryId captureMessage( + @NotNull String message, @NotNull SentryLevel level, @NotNull ScopeCallback callback); + + /** + * Captures the message. + * + * @param message The message to send. + * @param callback The callback to configure the scope for a single invocation. + * @return The Id (SentryId object) of the event + */ + default @NotNull SentryId captureMessage( + @NotNull String message, @NotNull ScopeCallback callback) { + return captureMessage(message, SentryLevel.INFO, callback); + } + + /** + * Captures an envelope. + * + * @param envelope the SentryEnvelope to send. + * @param hint SDK specific but provides high level information about the origin of the event + * @return The Id (SentryId object) of the event + */ + @NotNull + SentryId captureEnvelope(@NotNull SentryEnvelope envelope, @Nullable Hint hint); + + /** + * Captures an envelope. + * + * @param envelope the SentryEnvelope to send. + * @return The Id (SentryId object) of the event + */ + default @NotNull SentryId captureEnvelope(@NotNull SentryEnvelope envelope) { + return captureEnvelope(envelope, new Hint()); + } + + /** + * Captures the exception. + * + * @param throwable The exception. + * @param hint SDK specific but provides high level information about the origin of the event + * @return The Id (SentryId object) of the event + */ + @NotNull + SentryId captureException(@NotNull Throwable throwable, @Nullable Hint hint); + + /** + * Captures the exception. + * + * @param throwable The exception. + * @return The Id (SentryId object) of the event + */ + default @NotNull SentryId captureException(@NotNull Throwable throwable) { + return captureException(throwable, new Hint()); + } + + /** + * Captures the exception. + * + * @param throwable The exception. + * @param callback The callback to configure the scope for a single invocation. + * @return The Id (SentryId object) of the event + */ + default @NotNull SentryId captureException( + @NotNull Throwable throwable, final @NotNull ScopeCallback callback) { + return captureException(throwable, new Hint(), callback); + } + + /** + * Captures the exception. + * + * @param throwable The exception. + * @param hint SDK specific but provides high level information about the origin of the event + * @param callback The callback to configure the scope for a single invocation. + * @return The Id (SentryId object) of the event + */ + @NotNull + SentryId captureException( + final @NotNull Throwable throwable, + final @Nullable Hint hint, + final @NotNull ScopeCallback callback); + + /** + * Captures a manually created user feedback and sends it to Sentry. + * + * @param userFeedback The user feedback to send to Sentry. + */ + void captureUserFeedback(@NotNull UserFeedback userFeedback); + + /** Starts a new session. If there's a running session, it ends it before starting the new one. */ + void startSession(); + + /** Ends the current session */ + void endSession(); + + /** Flushes out the queue for up to timeout seconds and disable the Hub. */ + void close(); + + /** + * Flushes out the queue for up to timeout seconds and disable the Hub. + * + * @param isRestarting if true, avoids locking the main thread when finishing the queue. + */ + void close(boolean isRestarting); + + /** + * Adds a breadcrumb to the current Scope + * + * @param breadcrumb the breadcrumb + * @param hint SDK specific but provides high level information about the origin of the event + */ + void addBreadcrumb(@NotNull Breadcrumb breadcrumb, @Nullable Hint hint); + + /** + * Adds a breadcrumb to the current Scope + * + * @param breadcrumb the breadcrumb + */ + void addBreadcrumb(@NotNull Breadcrumb breadcrumb); + + /** + * Adds a breadcrumb to the current Scope + * + * @param message rendered as text and the whitespace is preserved. + */ + default void addBreadcrumb(@NotNull String message) { + addBreadcrumb(new Breadcrumb(message)); + } + + /** + * Adds a breadcrumb to the current Scope + * + * @param message rendered as text and the whitespace is preserved. + * @param category Categories are dotted strings that indicate what the crumb is or where it comes + * from. + */ + default void addBreadcrumb(@NotNull String message, @NotNull String category) { + Breadcrumb breadcrumb = new Breadcrumb(message); + breadcrumb.setCategory(category); + addBreadcrumb(breadcrumb); + } + + /** + * Sets the level of all events sent within current Scope + * + * @param level the Sentry level + */ + void setLevel(@Nullable SentryLevel level); + + /** + * Sets the name of the current transaction to the current Scope. + * + * @param transaction the transaction + */ + void setTransaction(@Nullable String transaction); + + /** + * Shallow merges user configuration (email, username, etc) to the current Scope. + * + * @param user the user + */ + void setUser(@Nullable User user); + + /** + * Sets the fingerprint to group specific events together to the current Scope. + * + * @param fingerprint the fingerprints + */ + void setFingerprint(@NotNull List fingerprint); + + /** Deletes current breadcrumbs from the current scope. */ + void clearBreadcrumbs(); + + /** + * Sets the tag to a string value to the current Scope, overwriting a potential previous value + * + * @param key the key + * @param value the value + */ + void setTag(@NotNull String key, @NotNull String value); + + /** + * Removes the tag to a string value to the current Scope + * + * @param key the key + */ + void removeTag(@NotNull String key); + + /** + * Sets the extra key to an arbitrary value to the current Scope, overwriting a potential previous + * value + * + * @param key the key + * @param value the value + */ + void setExtra(@NotNull String key, @NotNull String value); + + /** + * Removes the extra key to an arbitrary value to the current Scope + * + * @param key the key + */ + void removeExtra(@NotNull String key); + + /** + * Last event id recorded in the current scope + * + * @return last SentryId + */ + @NotNull + SentryId getLastEventId(); + + /** Pushes a new scope while inheriting the current scope's data. */ + void pushScope(); + + /** Removes the first scope */ + void popScope(); + + /** + * Runs the callback with a new scope which gets dropped at the end. If you're using the Sentry + * SDK in globalHubMode (defaults to true on Android) {@link + * Sentry#init(Sentry.OptionsConfiguration, boolean)} calling withScope is discouraged, as scope + * changes may be dropped when executed in parallel. Use {@link + * IHub#configureScope(ScopeCallback)} instead. + * + * @param callback the callback + */ + void withScope(@NotNull ScopeCallback callback); + + /** + * Configures the scope through the callback. + * + * @param callback The configure scope callback. + */ + void configureScope(@NotNull ScopeCallback callback); + + /** + * Binds a different client to the hub + * + * @param client the client. + */ + void bindClient(@NotNull ISentryClient client); + + /** + * Whether the transport is healthy. + * + * @return true if the transport is healthy + */ + boolean isHealthy(); + + /** + * Flushes events queued up, but keeps the Hub enabled. Not implemented yet. + * + * @param timeoutMillis time in milliseconds + */ + void flush(long timeoutMillis); + + /** + * Clones the Hub + * + * @return the cloned Hub + */ + @NotNull + @Deprecated + IHub clone(); + + /** + * Captures the transaction and enqueues it for sending to Sentry server. + * + * @param transaction the transaction + * @param traceContext the trace context + * @param hint the hints + * @param profilingTraceData the profiling trace data + * @return transaction's id + */ + @ApiStatus.Internal + @NotNull + SentryId captureTransaction( + @NotNull SentryTransaction transaction, + @Nullable TraceContext traceContext, + @Nullable Hint hint, + @Nullable ProfilingTraceData profilingTraceData); + + /** + * Captures the transaction and enqueues it for sending to Sentry server. + * + * @param transaction the transaction + * @param traceContext the trace context + * @param hint the hints + * @return transaction's id + */ + @ApiStatus.Internal + @NotNull + default SentryId captureTransaction( + @NotNull SentryTransaction transaction, + @Nullable TraceContext traceContext, + @Nullable Hint hint) { + return captureTransaction(transaction, traceContext, hint, null); + } + + @ApiStatus.Internal + @NotNull + default SentryId captureTransaction(@NotNull SentryTransaction transaction, @Nullable Hint hint) { + return captureTransaction(transaction, null, hint); + } + + /** + * Captures the transaction and enqueues it for sending to Sentry server. + * + * @param transaction the transaction + * @param traceContext the trace context + * @return transaction's id + */ + @ApiStatus.Internal + default @NotNull SentryId captureTransaction( + @NotNull SentryTransaction transaction, @Nullable TraceContext traceContext) { + return captureTransaction(transaction, traceContext, null); + } + + /** + * Creates a Transaction and returns the instance. + * + * @param transactionContexts the transaction contexts + * @return created transaction + */ + default @NotNull ITransaction startTransaction(@NotNull TransactionContext transactionContexts) { + return startTransaction(transactionContexts, new TransactionOptions()); + } + + /** + * Creates a Transaction and returns the instance. Based on the {@link + * SentryOptions#getTracesSampleRate()} the decision if transaction is sampled will be taken by + * {@link TracesSampler}. + * + * @param name the transaction name + * @param operation the operation + * @return created transaction + */ + default @NotNull ITransaction startTransaction( + final @NotNull String name, final @NotNull String operation) { + return startTransaction(name, operation, new TransactionOptions()); + } + + /** + * Creates a Transaction and returns the instance. Based on the {@link + * SentryOptions#getTracesSampleRate()} the decision if transaction is sampled will be taken by + * {@link TracesSampler}. + * + * @param name the transaction name + * @param operation the operation + * @param transactionOptions the transaction options + * @return created transaction + */ + default @NotNull ITransaction startTransaction( + final @NotNull String name, + final @NotNull String operation, + final @NotNull TransactionOptions transactionOptions) { + return startTransaction(new TransactionContext(name, operation), transactionOptions); + } + + /** + * Creates a Transaction and returns the instance. Based on the passed transaction context and + * transaction options the decision if transaction is sampled will be taken by {@link + * TracesSampler}. + * + * @param transactionContext the transaction context + * @param transactionOptions the transaction options + * @return created transaction. + */ + @NotNull + ITransaction startTransaction( + final @NotNull TransactionContext transactionContext, + final @NotNull TransactionOptions transactionOptions); + + /** + * Returns the "sentry-trace" header that allows tracing across services. Can also be used in + * <meta> HTML tags. Also see {@link IHub#getBaggage()}. + * + * @deprecated please use {@link IHub#getTraceparent()} instead. + * @return sentry trace header or null + */ + @Deprecated + @Nullable + SentryTraceHeader traceHeaders(); + + /** + * Associates {@link ISpan} and the transaction name with the {@link Throwable}. Used to determine + * in which trace the exception has been thrown in framework integrations. + * + * @param throwable the throwable + * @param span the span context + * @param transactionName the transaction name + */ + @ApiStatus.Internal + void setSpanContext( + @NotNull Throwable throwable, @NotNull ISpan span, @NotNull String transactionName); + + /** + * Gets the current active transaction or span. + * + * @return the active span or null when no active transaction is running + */ + @Nullable + ISpan getSpan(); + + /** + * Returns the transaction. + * + * @return the transaction or null when no active transaction is running. + */ + @ApiStatus.Internal + @Nullable + ITransaction getTransaction(); + + /** + * Gets the {@link SentryOptions} attached to current scope. + * + * @return the options attached to current scope. + */ + @NotNull + SentryOptions getOptions(); + + /** + * Returns if the App has crashed (Process has terminated) during the last run. It only returns + * true or false if offline caching {{@link SentryOptions#getCacheDirPath()} } is set with a valid + * dir. + * + *

If the call to this method is early in the App lifecycle and the SDK could not check if the + * App has crashed in the background, the check is gonna do IO in the calling thread. + * + * @return true if App has crashed, false otherwise, and null if not evaluated yet + */ + @Nullable + Boolean isCrashedLastRun(); + + /** + * Report a screen has been fully loaded. That means all data needed by the UI was loaded. If + * time-to-full-display tracing {{@link SentryOptions#isEnableTimeToFullDisplayTracing()} } is + * disabled this call is ignored. + * + *

This method is safe to be called multiple times. If the time-to-full-display span is already + * finished, this call will be ignored. + */ + void reportFullyDisplayed(); + + /** + * @deprecated See {@link IHub#reportFullyDisplayed()}. + */ + @Deprecated + default void reportFullDisplayed() { + reportFullyDisplayed(); + } + + /** + * Continue a trace based on HTTP header values. If no "sentry-trace" header is provided a random + * trace ID and span ID is created. + * + * @param sentryTrace "sentry-trace" header + * @param baggageHeaders "baggage" headers + * @return a transaction context for starting a transaction or null if performance is disabled + */ + @Nullable + TransactionContext continueTrace( + final @Nullable String sentryTrace, final @Nullable List baggageHeaders); + + /** + * Returns the "sentry-trace" header that allows tracing across services. Can also be used in + * <meta> HTML tags. Also see {@link IHub#getBaggage()}. + * + * @return sentry trace header or null + */ + @Nullable + SentryTraceHeader getTraceparent(); + + /** + * Returns the "baggage" header that allows tracing across services. Can also be used in + * <meta> HTML tags. Also see {@link IHub#getTraceparent()}. + * + * @return baggage header or null + */ + @Nullable + BaggageHeader getBaggage(); + + @ApiStatus.Experimental + @NotNull + SentryId captureCheckIn(final @NotNull CheckIn checkIn); + + @ApiStatus.Internal + @Nullable + RateLimiter getRateLimiter(); + + @ApiStatus.Experimental + @NotNull + MetricsApi metrics(); + + default boolean isNoOp() { + return false; + } +} diff --git a/sentry/src/main/java/io/sentry/NoOpHub.java b/sentry/src/main/java/io/sentry/NoOpHub.java index e51cea8d2d..704bd2b44a 100644 --- a/sentry/src/main/java/io/sentry/NoOpHub.java +++ b/sentry/src/main/java/io/sentry/NoOpHub.java @@ -11,6 +11,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +@Deprecated public final class NoOpHub implements IHub { private static final NoOpHub instance = new NoOpHub(); @@ -21,6 +22,7 @@ public final class NoOpHub implements IHub { private NoOpHub() {} + @Deprecated public static NoOpHub getInstance() { return instance; } @@ -234,4 +236,9 @@ public void reportFullyDisplayed() {} public @NotNull MetricsApi metrics() { return metricsApi; } + + @Override + public boolean isNoOp() { + return true; + } } diff --git a/sentry/src/main/java/io/sentry/NoOpScopes.java b/sentry/src/main/java/io/sentry/NoOpScopes.java new file mode 100644 index 0000000000..6fef262944 --- /dev/null +++ b/sentry/src/main/java/io/sentry/NoOpScopes.java @@ -0,0 +1,243 @@ +package io.sentry; + +import io.sentry.metrics.MetricsApi; +import io.sentry.metrics.NoopMetricsAggregator; +import io.sentry.protocol.SentryId; +import io.sentry.protocol.SentryTransaction; +import io.sentry.protocol.User; +import io.sentry.transport.RateLimiter; +import java.util.List; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public final class NoOpScopes implements IScopes { + + private static final NoOpScopes instance = new NoOpScopes(); + + private final @NotNull SentryOptions emptyOptions = SentryOptions.empty(); + private final @NotNull MetricsApi metricsApi = + new MetricsApi(NoopMetricsAggregator.getInstance()); + + private NoOpScopes() {} + + public static NoOpScopes getInstance() { + return instance; + } + + @Override + public boolean isEnabled() { + return false; + } + + @Override + public @NotNull SentryId captureEvent(@NotNull SentryEvent event, @Nullable Hint hint) { + return SentryId.EMPTY_ID; + } + + @Override + public @NotNull SentryId captureEvent( + @NotNull SentryEvent event, @Nullable Hint hint, @NotNull ScopeCallback callback) { + return SentryId.EMPTY_ID; + } + + @Override + public @NotNull SentryId captureMessage(@NotNull String message, @NotNull SentryLevel level) { + return SentryId.EMPTY_ID; + } + + @Override + public @NotNull SentryId captureMessage( + @NotNull String message, @NotNull SentryLevel level, @NotNull ScopeCallback callback) { + return SentryId.EMPTY_ID; + } + + @Override + public @NotNull SentryId captureEnvelope(@NotNull SentryEnvelope envelope, @Nullable Hint hint) { + return SentryId.EMPTY_ID; + } + + @Override + public @NotNull SentryId captureException(@NotNull Throwable throwable, @Nullable Hint hint) { + return SentryId.EMPTY_ID; + } + + @Override + public @NotNull SentryId captureException( + @NotNull Throwable throwable, @Nullable Hint hint, @NotNull ScopeCallback callback) { + return SentryId.EMPTY_ID; + } + + @Override + public void captureUserFeedback(@NotNull UserFeedback userFeedback) {} + + @Override + public void startSession() {} + + @Override + public void endSession() {} + + @Override + public void close() {} + + @Override + public void close(final boolean isRestarting) {} + + @Override + public void addBreadcrumb(@NotNull Breadcrumb breadcrumb, @Nullable Hint hint) {} + + @Override + public void addBreadcrumb(final @NotNull Breadcrumb breadcrumb) {} + + @Override + public void setLevel(@Nullable SentryLevel level) {} + + @Override + public void setTransaction(@Nullable String transaction) {} + + @Override + public void setUser(@Nullable User user) {} + + @Override + public void setFingerprint(@NotNull List fingerprint) {} + + @Override + public void clearBreadcrumbs() {} + + @Override + public void setTag(@NotNull String key, @NotNull String value) {} + + @Override + public void removeTag(@NotNull String key) {} + + @Override + public void setExtra(@NotNull String key, @NotNull String value) {} + + @Override + public void removeExtra(@NotNull String key) {} + + @Override + public @NotNull SentryId getLastEventId() { + return SentryId.EMPTY_ID; + } + + @Override + public void pushScope() {} + + @Override + public void popScope() {} + + @Override + public void withScope(@NotNull ScopeCallback callback) { + callback.run(NoOpScope.getInstance()); + } + + @Override + public void configureScope(@NotNull ScopeCallback callback) {} + + @Override + public void bindClient(@NotNull ISentryClient client) {} + + @Override + public boolean isHealthy() { + return true; + } + + @Override + public void flush(long timeoutMillis) {} + + @Deprecated + @Override + public @NotNull IHub clone() { + return NoOpHub.getInstance(); + } + + @Override + public @NotNull SentryId captureTransaction( + final @NotNull SentryTransaction transaction, + final @Nullable TraceContext traceContext, + final @Nullable Hint hint, + final @Nullable ProfilingTraceData profilingTraceData) { + return SentryId.EMPTY_ID; + } + + @Override + public @NotNull ITransaction startTransaction( + @NotNull TransactionContext transactionContext, + @NotNull TransactionOptions transactionOptions) { + return NoOpTransaction.getInstance(); + } + + @Override + @Deprecated + @SuppressWarnings("InlineMeSuggester") + public @NotNull SentryTraceHeader traceHeaders() { + return new SentryTraceHeader(SentryId.EMPTY_ID, SpanId.EMPTY_ID, true); + } + + @Override + public void setSpanContext( + final @NotNull Throwable throwable, + final @NotNull ISpan spanContext, + final @NotNull String transactionName) {} + + @Override + public @Nullable ISpan getSpan() { + return null; + } + + @Override + public @Nullable ITransaction getTransaction() { + return null; + } + + @Override + public @NotNull SentryOptions getOptions() { + return emptyOptions; + } + + @Override + public @Nullable Boolean isCrashedLastRun() { + return null; + } + + @Override + public void reportFullyDisplayed() {} + + @Override + public @Nullable TransactionContext continueTrace( + final @Nullable String sentryTrace, final @Nullable List baggageHeaders) { + return null; + } + + @Override + public @Nullable SentryTraceHeader getTraceparent() { + return null; + } + + @Override + public @Nullable BaggageHeader getBaggage() { + return null; + } + + @Override + @ApiStatus.Experimental + public @NotNull SentryId captureCheckIn(final @NotNull CheckIn checkIn) { + return SentryId.EMPTY_ID; + } + + @Override + public @Nullable RateLimiter getRateLimiter() { + return null; + } + + @Override + public @NotNull MetricsApi metrics() { + return metricsApi; + } + + @Override + public boolean isNoOp() { + return true; + } +} diff --git a/sentry/src/main/java/io/sentry/ScopesAdapter.java b/sentry/src/main/java/io/sentry/ScopesAdapter.java new file mode 100644 index 0000000000..1ecd31e248 --- /dev/null +++ b/sentry/src/main/java/io/sentry/ScopesAdapter.java @@ -0,0 +1,286 @@ +package io.sentry; + +import io.sentry.metrics.MetricsApi; +import io.sentry.protocol.SentryId; +import io.sentry.protocol.SentryTransaction; +import io.sentry.protocol.User; +import io.sentry.transport.RateLimiter; +import java.util.List; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public final class ScopesAdapter implements IScopes { + + private static final ScopesAdapter INSTANCE = new ScopesAdapter(); + + private ScopesAdapter() {} + + public static ScopesAdapter getInstance() { + return INSTANCE; + } + + @Override + public boolean isEnabled() { + return Sentry.isEnabled(); + } + + @Override + public @NotNull SentryId captureEvent(@NotNull SentryEvent event, @Nullable Hint hint) { + return Sentry.captureEvent(event, hint); + } + + @Override + public @NotNull SentryId captureEvent( + @NotNull SentryEvent event, @Nullable Hint hint, @NotNull ScopeCallback callback) { + return Sentry.captureEvent(event, hint, callback); + } + + @Override + public @NotNull SentryId captureMessage(@NotNull String message, @NotNull SentryLevel level) { + return Sentry.captureMessage(message, level); + } + + @Override + public @NotNull SentryId captureMessage( + @NotNull String message, @NotNull SentryLevel level, @NotNull ScopeCallback callback) { + return Sentry.captureMessage(message, level, callback); + } + + @ApiStatus.Internal + @Override + public @NotNull SentryId captureEnvelope(@NotNull SentryEnvelope envelope, @Nullable Hint hint) { + return Sentry.getCurrentScopes().captureEnvelope(envelope, hint); + } + + @Override + public @NotNull SentryId captureException(@NotNull Throwable throwable, @Nullable Hint hint) { + return Sentry.captureException(throwable, hint); + } + + @Override + public @NotNull SentryId captureException( + @NotNull Throwable throwable, @Nullable Hint hint, @NotNull ScopeCallback callback) { + return Sentry.captureException(throwable, hint, callback); + } + + @Override + public void captureUserFeedback(@NotNull UserFeedback userFeedback) { + Sentry.captureUserFeedback(userFeedback); + } + + @Override + public void startSession() { + Sentry.startSession(); + } + + @Override + public void endSession() { + Sentry.endSession(); + } + + @Override + public void close(final boolean isRestarting) { + Sentry.close(); + } + + @Override + public void close() { + Sentry.close(); + } + + @Override + public void addBreadcrumb(@NotNull Breadcrumb breadcrumb, @Nullable Hint hint) { + Sentry.addBreadcrumb(breadcrumb, hint); + } + + @Override + public void addBreadcrumb(final @NotNull Breadcrumb breadcrumb) { + addBreadcrumb(breadcrumb, new Hint()); + } + + @Override + public void setLevel(@Nullable SentryLevel level) { + Sentry.setLevel(level); + } + + @Override + public void setTransaction(@Nullable String transaction) { + Sentry.setTransaction(transaction); + } + + @Override + public void setUser(@Nullable User user) { + Sentry.setUser(user); + } + + @Override + public void setFingerprint(@NotNull List fingerprint) { + Sentry.setFingerprint(fingerprint); + } + + @Override + public void clearBreadcrumbs() { + Sentry.clearBreadcrumbs(); + } + + @Override + public void setTag(@NotNull String key, @NotNull String value) { + Sentry.setTag(key, value); + } + + @Override + public void removeTag(@NotNull String key) { + Sentry.removeTag(key); + } + + @Override + public void setExtra(@NotNull String key, @NotNull String value) { + Sentry.setExtra(key, value); + } + + @Override + public void removeExtra(@NotNull String key) { + Sentry.removeExtra(key); + } + + @Override + public @NotNull SentryId getLastEventId() { + return Sentry.getLastEventId(); + } + + @Override + public void pushScope() { + Sentry.pushScope(); + } + + @Override + public void popScope() { + Sentry.popScope(); + } + + @Override + public void withScope(@NotNull ScopeCallback callback) { + Sentry.withScope(callback); + } + + @Override + public void configureScope(@NotNull ScopeCallback callback) { + Sentry.configureScope(callback); + } + + @Override + public void bindClient(@NotNull ISentryClient client) { + Sentry.bindClient(client); + } + + @Override + public boolean isHealthy() { + return Sentry.isHealthy(); + } + + @Override + public void flush(long timeoutMillis) { + Sentry.flush(timeoutMillis); + } + + @Override + @SuppressWarnings("deprecation") + public @NotNull IHub clone() { + return Sentry.getCurrentScopes().clone(); + } + + @ApiStatus.Internal + @Override + public @NotNull SentryId captureTransaction( + @NotNull SentryTransaction transaction, + @Nullable TraceContext traceContext, + @Nullable Hint hint, + @Nullable ProfilingTraceData profilingTraceData) { + return Sentry.getCurrentScopes() + .captureTransaction(transaction, traceContext, hint, profilingTraceData); + } + + @Override + public @NotNull ITransaction startTransaction( + @NotNull TransactionContext transactionContext, + @NotNull TransactionOptions transactionOptions) { + return Sentry.startTransaction(transactionContext, transactionOptions); + } + + @Deprecated + @Override + @SuppressWarnings("deprecation") + public @Nullable SentryTraceHeader traceHeaders() { + return Sentry.traceHeaders(); + } + + @ApiStatus.Internal + @Override + public void setSpanContext( + final @NotNull Throwable throwable, + final @NotNull ISpan span, + final @NotNull String transactionName) { + Sentry.getCurrentScopes().setSpanContext(throwable, span, transactionName); + } + + @Override + public @Nullable ISpan getSpan() { + return Sentry.getCurrentScopes().getSpan(); + } + + @Override + @ApiStatus.Internal + public @Nullable ITransaction getTransaction() { + return Sentry.getCurrentScopes().getTransaction(); + } + + @Override + public @NotNull SentryOptions getOptions() { + return Sentry.getCurrentScopes().getOptions(); + } + + @Override + public @Nullable Boolean isCrashedLastRun() { + return Sentry.isCrashedLastRun(); + } + + @Override + public void reportFullyDisplayed() { + Sentry.reportFullyDisplayed(); + } + + @Override + public @Nullable TransactionContext continueTrace( + final @Nullable String sentryTrace, final @Nullable List baggageHeaders) { + return Sentry.continueTrace(sentryTrace, baggageHeaders); + } + + @Override + public @Nullable SentryTraceHeader getTraceparent() { + return Sentry.getTraceparent(); + } + + @Override + public @Nullable BaggageHeader getBaggage() { + return Sentry.getBaggage(); + } + + @Override + @ApiStatus.Experimental + public @NotNull SentryId captureCheckIn(final @NotNull CheckIn checkIn) { + return Sentry.captureCheckIn(checkIn); + } + + @ApiStatus.Internal + @Override + public @Nullable RateLimiter getRateLimiter() { + return Sentry.getCurrentScopes().getRateLimiter(); + } + + @ApiStatus.Experimental + @Override + public @NotNull MetricsApi metrics() { + return Sentry.getCurrentScopes().metrics(); + } +} diff --git a/sentry/src/main/java/io/sentry/Sentry.java b/sentry/src/main/java/io/sentry/Sentry.java index 5196d0f31a..206ffd8d20 100644 --- a/sentry/src/main/java/io/sentry/Sentry.java +++ b/sentry/src/main/java/io/sentry/Sentry.java @@ -43,11 +43,11 @@ public final class Sentry { private Sentry() {} - /** Holds Hubs per thread or only mainHub if globalHubMode is enabled. */ - private static final @NotNull ThreadLocal currentHub = new ThreadLocal<>(); + /** Holds Hubs per thread or only mainScopes if globalHubMode is enabled. */ + private static final @NotNull ThreadLocal currentScopes = new ThreadLocal<>(); /** The Main Hub or NoOp if Sentry is disabled. */ - private static volatile @NotNull IHub mainHub = NoOpHub.getInstance(); + private static volatile @NotNull IScopes mainScopes = NoOpScopes.getInstance(); /** Default value for globalHubMode is false */ private static final boolean GLOBAL_HUB_DEFAULT_MODE = false; @@ -66,40 +66,58 @@ private Sentry() {} private static final long classCreationTimestamp = System.currentTimeMillis(); /** - * Returns the current (threads) hub, if none, clones the mainHub and returns it. + * Returns the current (threads) hub, if none, clones the mainScopes and returns it. * * @return the hub */ @ApiStatus.Internal // exposed for the coroutines integration in SentryContext + @SuppressWarnings("deprecation") + @Deprecated public static @NotNull IHub getCurrentHub() { + return new HubScopesWrapper(getCurrentScopes()); + } + + @ApiStatus.Internal // exposed for the coroutines integration in SentryContext + @SuppressWarnings("deprecation") + public static @NotNull IScopes getCurrentScopes() { if (globalHubMode) { - return mainHub; + return mainScopes; } - IHub hub = currentHub.get(); - if (hub == null || hub instanceof NoOpHub) { - hub = mainHub.clone(); - currentHub.set(hub); + IScopes hub = currentScopes.get(); + if (hub == null || hub.isNoOp()) { + // TODO fork instead + hub = mainScopes.clone(); + currentScopes.set(hub); } return hub; } /** - * Returns a new hub which is cloned from the mainHub. + * Returns a new hub which is cloned from the mainScopes. * * @return the hub */ @ApiStatus.Internal @ApiStatus.Experimental - public static @NotNull IHub cloneMainHub() { + @SuppressWarnings("deprecation") + public static @NotNull IScopes cloneMainHub() { if (globalHubMode) { - return mainHub; + return mainScopes; } - return mainHub.clone(); + // TODO fork instead + return mainScopes.clone(); } @ApiStatus.Internal // exposed for the coroutines integration in SentryContext + @Deprecated + @SuppressWarnings("deprecation") public static void setCurrentHub(final @NotNull IHub hub) { - currentHub.set(hub); + currentScopes.set(hub); + } + + @ApiStatus.Internal // exposed for the coroutines integration in SentryContext + public static void setCurrentScopes(final @NotNull IScopes scopes) { + currentScopes.set(scopes); } /** @@ -108,7 +126,7 @@ public static void setCurrentHub(final @NotNull IHub hub) { * @return true if its enabled or false otherwise. */ public static boolean isEnabled() { - return getCurrentHub().isEnabled(); + return getCurrentScopes().isEnabled(); } /** Initializes the SDK */ @@ -217,6 +235,7 @@ public static void init(final @NotNull SentryOptions options) { * @param options options the SentryOptions * @param globalHubMode the globalHubMode */ + @SuppressWarnings("deprecation") private static synchronized void init( final @NotNull SentryOptions options, final boolean globalHubMode) { if (isEnabled()) { @@ -234,10 +253,11 @@ private static synchronized void init( options.getLogger().log(SentryLevel.INFO, "GlobalHubMode: '%s'", String.valueOf(globalHubMode)); Sentry.globalHubMode = globalHubMode; - final IHub hub = getCurrentHub(); - mainHub = new Hub(options); + final IScopes hub = getCurrentScopes(); + // TODO new Scopes() + mainScopes = new Hub(options); - currentHub.set(mainHub); + currentScopes.set(mainScopes); hub.close(true); @@ -252,12 +272,12 @@ private static synchronized void init( // and hub was still NoOp. // Registering integrations here make sure that Hub is already created. for (final Integration integration : options.getIntegrations()) { - integration.register(HubAdapter.getInstance(), options); + integration.register(ScopesAdapter.getInstance(), options); } notifyOptionsObservers(options); - finalizePreviousSession(options, HubAdapter.getInstance()); + finalizePreviousSession(options, ScopesAdapter.getInstance()); handleAppStartProfilingConfig(options, options.getExecutorService()); } @@ -327,12 +347,12 @@ private static void handleAppStartProfilingConfig( @SuppressWarnings("FutureReturnValueIgnored") private static void finalizePreviousSession( - final @NotNull SentryOptions options, final @NotNull IHub hub) { + final @NotNull SentryOptions options, final @NotNull IScopes scopes) { // enqueue a task to finalize previous session. Since the executor // is single-threaded, this task will be enqueued sequentially after all integrations that have // to modify the previous session have done their work, even if they do that async. try { - options.getExecutorService().submit(new PreviousSessionFinalizer(options, hub)); + options.getExecutorService().submit(new PreviousSessionFinalizer(options, scopes)); } catch (Throwable e) { options.getLogger().log(SentryLevel.DEBUG, "Failed to finalize previous session.", e); } @@ -475,7 +495,7 @@ private static boolean initConfigurations(final @NotNull SentryOptions options) } if (options.isEnableBackpressureHandling()) { - options.setBackpressureMonitor(new BackpressureMonitor(options, HubAdapter.getInstance())); + options.setBackpressureMonitor(new BackpressureMonitor(options, ScopesAdapter.getInstance())); options.getBackpressureMonitor().start(); } @@ -484,11 +504,11 @@ private static boolean initConfigurations(final @NotNull SentryOptions options) /** Close the SDK */ public static synchronized void close() { - final IHub hub = getCurrentHub(); - mainHub = NoOpHub.getInstance(); + final IScopes scopes = getCurrentScopes(); + mainScopes = NoOpScopes.getInstance(); // remove thread local to avoid memory leak - currentHub.remove(); - hub.close(false); + currentScopes.remove(); + scopes.close(false); } /** @@ -498,7 +518,7 @@ public static synchronized void close() { * @return The Id (SentryId object) of the event */ public static @NotNull SentryId captureEvent(final @NotNull SentryEvent event) { - return getCurrentHub().captureEvent(event); + return getCurrentScopes().captureEvent(event); } /** @@ -510,7 +530,7 @@ public static synchronized void close() { */ public static @NotNull SentryId captureEvent( final @NotNull SentryEvent event, final @NotNull ScopeCallback callback) { - return getCurrentHub().captureEvent(event, callback); + return getCurrentScopes().captureEvent(event, callback); } /** @@ -522,7 +542,7 @@ public static synchronized void close() { */ public static @NotNull SentryId captureEvent( final @NotNull SentryEvent event, final @Nullable Hint hint) { - return getCurrentHub().captureEvent(event, hint); + return getCurrentScopes().captureEvent(event, hint); } /** @@ -537,7 +557,7 @@ public static synchronized void close() { final @NotNull SentryEvent event, final @Nullable Hint hint, final @NotNull ScopeCallback callback) { - return getCurrentHub().captureEvent(event, hint, callback); + return getCurrentScopes().captureEvent(event, hint, callback); } /** @@ -547,7 +567,7 @@ public static synchronized void close() { * @return The Id (SentryId object) of the event */ public static @NotNull SentryId captureMessage(final @NotNull String message) { - return getCurrentHub().captureMessage(message); + return getCurrentScopes().captureMessage(message); } /** @@ -559,7 +579,7 @@ public static synchronized void close() { */ public static @NotNull SentryId captureMessage( final @NotNull String message, final @NotNull ScopeCallback callback) { - return getCurrentHub().captureMessage(message, callback); + return getCurrentScopes().captureMessage(message, callback); } /** @@ -571,7 +591,7 @@ public static synchronized void close() { */ public static @NotNull SentryId captureMessage( final @NotNull String message, final @NotNull SentryLevel level) { - return getCurrentHub().captureMessage(message, level); + return getCurrentScopes().captureMessage(message, level); } /** @@ -586,7 +606,7 @@ public static synchronized void close() { final @NotNull String message, final @NotNull SentryLevel level, final @NotNull ScopeCallback callback) { - return getCurrentHub().captureMessage(message, level, callback); + return getCurrentScopes().captureMessage(message, level, callback); } /** @@ -596,7 +616,7 @@ public static synchronized void close() { * @return The Id (SentryId object) of the event */ public static @NotNull SentryId captureException(final @NotNull Throwable throwable) { - return getCurrentHub().captureException(throwable); + return getCurrentScopes().captureException(throwable); } /** @@ -608,7 +628,7 @@ public static synchronized void close() { */ public static @NotNull SentryId captureException( final @NotNull Throwable throwable, final @NotNull ScopeCallback callback) { - return getCurrentHub().captureException(throwable, callback); + return getCurrentScopes().captureException(throwable, callback); } /** @@ -620,7 +640,7 @@ public static synchronized void close() { */ public static @NotNull SentryId captureException( final @NotNull Throwable throwable, final @Nullable Hint hint) { - return getCurrentHub().captureException(throwable, hint); + return getCurrentScopes().captureException(throwable, hint); } /** @@ -635,7 +655,7 @@ public static synchronized void close() { final @NotNull Throwable throwable, final @Nullable Hint hint, final @NotNull ScopeCallback callback) { - return getCurrentHub().captureException(throwable, hint, callback); + return getCurrentScopes().captureException(throwable, hint, callback); } /** @@ -644,7 +664,7 @@ public static synchronized void close() { * @param userFeedback The user feedback to send to Sentry. */ public static void captureUserFeedback(final @NotNull UserFeedback userFeedback) { - getCurrentHub().captureUserFeedback(userFeedback); + getCurrentScopes().captureUserFeedback(userFeedback); } /** @@ -655,7 +675,7 @@ public static void captureUserFeedback(final @NotNull UserFeedback userFeedback) */ public static void addBreadcrumb( final @NotNull Breadcrumb breadcrumb, final @Nullable Hint hint) { - getCurrentHub().addBreadcrumb(breadcrumb, hint); + getCurrentScopes().addBreadcrumb(breadcrumb, hint); } /** @@ -664,7 +684,7 @@ public static void addBreadcrumb( * @param breadcrumb the breadcrumb */ public static void addBreadcrumb(final @NotNull Breadcrumb breadcrumb) { - getCurrentHub().addBreadcrumb(breadcrumb); + getCurrentScopes().addBreadcrumb(breadcrumb); } /** @@ -673,7 +693,7 @@ public static void addBreadcrumb(final @NotNull Breadcrumb breadcrumb) { * @param message rendered as text and the whitespace is preserved. */ public static void addBreadcrumb(final @NotNull String message) { - getCurrentHub().addBreadcrumb(message); + getCurrentScopes().addBreadcrumb(message); } /** @@ -684,7 +704,7 @@ public static void addBreadcrumb(final @NotNull String message) { * from. */ public static void addBreadcrumb(final @NotNull String message, final @NotNull String category) { - getCurrentHub().addBreadcrumb(message, category); + getCurrentScopes().addBreadcrumb(message, category); } /** @@ -693,7 +713,7 @@ public static void addBreadcrumb(final @NotNull String message, final @NotNull S * @param level the Sentry level */ public static void setLevel(final @Nullable SentryLevel level) { - getCurrentHub().setLevel(level); + getCurrentScopes().setLevel(level); } /** @@ -702,7 +722,7 @@ public static void setLevel(final @Nullable SentryLevel level) { * @param transaction the transaction */ public static void setTransaction(final @Nullable String transaction) { - getCurrentHub().setTransaction(transaction); + getCurrentScopes().setTransaction(transaction); } /** @@ -711,7 +731,7 @@ public static void setTransaction(final @Nullable String transaction) { * @param user the user */ public static void setUser(final @Nullable User user) { - getCurrentHub().setUser(user); + getCurrentScopes().setUser(user); } /** @@ -720,12 +740,12 @@ public static void setUser(final @Nullable User user) { * @param fingerprint the fingerprints */ public static void setFingerprint(final @NotNull List fingerprint) { - getCurrentHub().setFingerprint(fingerprint); + getCurrentScopes().setFingerprint(fingerprint); } /** Deletes current breadcrumbs from the current scope. */ public static void clearBreadcrumbs() { - getCurrentHub().clearBreadcrumbs(); + getCurrentScopes().clearBreadcrumbs(); } /** @@ -735,7 +755,7 @@ public static void clearBreadcrumbs() { * @param value the value */ public static void setTag(final @NotNull String key, final @NotNull String value) { - getCurrentHub().setTag(key, value); + getCurrentScopes().setTag(key, value); } /** @@ -744,7 +764,7 @@ public static void setTag(final @NotNull String key, final @NotNull String value * @param key the key */ public static void removeTag(final @NotNull String key) { - getCurrentHub().removeTag(key); + getCurrentScopes().removeTag(key); } /** @@ -755,7 +775,7 @@ public static void removeTag(final @NotNull String key) { * @param value the value */ public static void setExtra(final @NotNull String key, final @NotNull String value) { - getCurrentHub().setExtra(key, value); + getCurrentScopes().setExtra(key, value); } /** @@ -764,7 +784,7 @@ public static void setExtra(final @NotNull String key, final @NotNull String val * @param key the key */ public static void removeExtra(final @NotNull String key) { - getCurrentHub().removeExtra(key); + getCurrentScopes().removeExtra(key); } /** @@ -773,14 +793,14 @@ public static void removeExtra(final @NotNull String key) { * @return last SentryId */ public static @NotNull SentryId getLastEventId() { - return getCurrentHub().getLastEventId(); + return getCurrentScopes().getLastEventId(); } /** Pushes a new scope while inheriting the current scope's data. */ public static void pushScope() { // pushScope is no-op in global hub mode if (!globalHubMode) { - getCurrentHub().pushScope(); + getCurrentScopes().pushScope(); } } @@ -788,7 +808,7 @@ public static void pushScope() { public static void popScope() { // popScope is no-op in global hub mode if (!globalHubMode) { - getCurrentHub().popScope(); + getCurrentScopes().popScope(); } } @@ -798,7 +818,7 @@ public static void popScope() { * @param callback the callback */ public static void withScope(final @NotNull ScopeCallback callback) { - getCurrentHub().withScope(callback); + getCurrentScopes().withScope(callback); } /** @@ -807,7 +827,7 @@ public static void withScope(final @NotNull ScopeCallback callback) { * @param callback The configure scope callback. */ public static void configureScope(final @NotNull ScopeCallback callback) { - getCurrentHub().configureScope(callback); + getCurrentScopes().configureScope(callback); } /** @@ -816,11 +836,11 @@ public static void configureScope(final @NotNull ScopeCallback callback) { * @param client the client. */ public static void bindClient(final @NotNull ISentryClient client) { - getCurrentHub().bindClient(client); + getCurrentScopes().bindClient(client); } public static boolean isHealthy() { - return getCurrentHub().isHealthy(); + return getCurrentScopes().isHealthy(); } /** @@ -829,17 +849,17 @@ public static boolean isHealthy() { * @param timeoutMillis time in milliseconds */ public static void flush(final long timeoutMillis) { - getCurrentHub().flush(timeoutMillis); + getCurrentScopes().flush(timeoutMillis); } /** Starts a new session. If there's a running session, it ends it before starting the new one. */ public static void startSession() { - getCurrentHub().startSession(); + getCurrentScopes().startSession(); } /** Ends the current session */ public static void endSession() { - getCurrentHub().endSession(); + getCurrentScopes().endSession(); } /** @@ -851,7 +871,7 @@ public static void endSession() { */ public static @NotNull ITransaction startTransaction( final @NotNull String name, final @NotNull String operation) { - return getCurrentHub().startTransaction(name, operation); + return getCurrentScopes().startTransaction(name, operation); } /** @@ -866,7 +886,7 @@ public static void endSession() { final @NotNull String name, final @NotNull String operation, final @NotNull TransactionOptions transactionOptions) { - return getCurrentHub().startTransaction(name, operation, transactionOptions); + return getCurrentScopes().startTransaction(name, operation, transactionOptions); } /** @@ -884,7 +904,7 @@ public static void endSession() { final @Nullable String description, final @NotNull TransactionOptions transactionOptions) { final ITransaction transaction = - getCurrentHub().startTransaction(name, operation, transactionOptions); + getCurrentScopes().startTransaction(name, operation, transactionOptions); transaction.setDescription(description); return transaction; } @@ -897,7 +917,7 @@ public static void endSession() { */ public static @NotNull ITransaction startTransaction( final @NotNull TransactionContext transactionContexts) { - return getCurrentHub().startTransaction(transactionContexts); + return getCurrentScopes().startTransaction(transactionContexts); } /** @@ -910,7 +930,7 @@ public static void endSession() { public static @NotNull ITransaction startTransaction( final @NotNull TransactionContext transactionContext, final @NotNull TransactionOptions transactionOptions) { - return getCurrentHub().startTransaction(transactionContext, transactionOptions); + return getCurrentScopes().startTransaction(transactionContext, transactionOptions); } /** @@ -923,7 +943,7 @@ public static void endSession() { @Deprecated @SuppressWarnings("InlineMeSuggester") public static @Nullable SentryTraceHeader traceHeaders() { - return getCurrentHub().traceHeaders(); + return getCurrentScopes().traceHeaders(); } /** @@ -935,9 +955,9 @@ public static void endSession() { */ public static @Nullable ISpan getSpan() { if (globalHubMode && Platform.isAndroid()) { - return getCurrentHub().getTransaction(); + return getCurrentScopes().getTransaction(); } else { - return getCurrentHub().getSpan(); + return getCurrentScopes().getSpan(); } } @@ -952,7 +972,7 @@ public static void endSession() { * @return true if App has crashed, false otherwise, and null if not evaluated yet */ public static @Nullable Boolean isCrashedLastRun() { - return getCurrentHub().isCrashedLastRun(); + return getCurrentScopes().isCrashedLastRun(); } /** @@ -964,7 +984,7 @@ public static void endSession() { * finished, this call will be ignored. */ public static void reportFullyDisplayed() { - getCurrentHub().reportFullyDisplayed(); + getCurrentScopes().reportFullyDisplayed(); } /** @@ -980,7 +1000,7 @@ public static void reportFullDisplayed() { @NotNull @ApiStatus.Experimental public static MetricsApi metrics() { - return getCurrentHub().metrics(); + return getCurrentScopes().metrics(); } /** @@ -1009,7 +1029,7 @@ public interface OptionsConfiguration { // return TransactionContext (if performance enabled) or null (if performance disabled) public static @Nullable TransactionContext continueTrace( final @Nullable String sentryTrace, final @Nullable List baggageHeaders) { - return getCurrentHub().continueTrace(sentryTrace, baggageHeaders); + return getCurrentScopes().continueTrace(sentryTrace, baggageHeaders); } /** @@ -1019,7 +1039,7 @@ public interface OptionsConfiguration { * @return sentry trace header or null */ public static @Nullable SentryTraceHeader getTraceparent() { - return getCurrentHub().getTraceparent(); + return getCurrentScopes().getTraceparent(); } /** @@ -1029,11 +1049,11 @@ public interface OptionsConfiguration { * @return baggage header or null */ public static @Nullable BaggageHeader getBaggage() { - return getCurrentHub().getBaggage(); + return getCurrentScopes().getBaggage(); } @ApiStatus.Experimental public static @NotNull SentryId captureCheckIn(final @NotNull CheckIn checkIn) { - return getCurrentHub().captureCheckIn(checkIn); + return getCurrentScopes().captureCheckIn(checkIn); } } From ce3c14f33bbba4c19caa82d82c7c2749facbc626 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Tue, 2 Apr 2024 14:11:40 +0200 Subject: [PATCH 04/28] Replace `IHub` with `IScopes` in core --- sentry/src/main/java/io/sentry/Baggage.java | 4 +- .../java/io/sentry/DirectoryProcessor.java | 8 +- .../main/java/io/sentry/EnvelopeSender.java | 10 +- .../src/main/java/io/sentry/Integration.java | 4 +- .../main/java/io/sentry/MonitorConfig.java | 2 +- .../src/main/java/io/sentry/OutboxSender.java | 14 +- .../io/sentry/PreviousSessionFinalizer.java | 8 +- ...achedEnvelopeFireAndForgetIntegration.java | 20 +- .../SendFireAndForgetEnvelopeSender.java | 6 +- .../sentry/SendFireAndForgetOutboxSender.java | 6 +- .../src/main/java/io/sentry/SentryTracer.java | 85 ++-- .../main/java/io/sentry/SentryWrapper.java | 21 +- .../io/sentry/ShutdownHookIntegration.java | 6 +- sentry/src/main/java/io/sentry/Span.java | 30 +- .../java/io/sentry/SpotlightIntegration.java | 2 +- .../UncaughtExceptionHandlerIntegration.java | 12 +- .../backpressure/BackpressureMonitor.java | 11 +- .../file/FileIOSpanManager.java | 6 +- .../file/SentryFileInputStream.java | 42 +- .../file/SentryFileOutputStream.java | 44 +- .../file/SentryFileReader.java | 7 +- .../file/SentryFileWriter.java | 6 +- .../java/io/sentry/util/CheckInUtils.java | 15 +- .../java/io/sentry/util/TracingUtils.java | 18 +- ...aultTransactionPerformanceCollectorTest.kt | 8 +- .../java/io/sentry/DirectoryProcessorTest.kt | 16 +- .../test/java/io/sentry/EnvelopeSenderTest.kt | 20 +- .../src/test/java/io/sentry/HubAdapterTest.kt | 92 ++-- sentry/src/test/java/io/sentry/HubTest.kt | 430 +++++++++--------- .../test/java/io/sentry/JsonSerializerTest.kt | 8 +- .../java/io/sentry/MainEventProcessorTest.kt | 6 +- .../test/java/io/sentry/OutboxSenderTest.kt | 28 +- .../io/sentry/PreviousSessionFinalizerTest.kt | 22 +- sentry/src/test/java/io/sentry/ScopeTest.kt | 24 +- .../test/java/io/sentry/ScopesAdapterTest.kt | 265 +++++++++++ ...hedEnvelopeFireAndForgetIntegrationTest.kt | 34 +- .../test/java/io/sentry/SentryClientTest.kt | 28 +- sentry/src/test/java/io/sentry/SentryTest.kt | 112 ++--- .../test/java/io/sentry/SentryWrapperTest.kt | 32 +- .../io/sentry/ShutdownHookIntegrationTest.kt | 22 +- sentry/src/test/java/io/sentry/SpanTest.kt | 24 +- .../sentry/TraceContextSerializationTest.kt | 6 +- ...UncaughtExceptionHandlerIntegrationTest.kt | 62 +-- .../backpressure/BackpressureMonitorTest.kt | 12 +- .../sentry/clientreport/ClientReportTest.kt | 8 +- .../file/FileIOSpanManagerTest.kt | 14 +- .../file/SentryFileInputStreamTest.kt | 22 +- .../file/SentryFileOutputStreamTest.kt | 12 +- .../file/SentryFileReaderTest.kt | 12 +- .../file/SentryFileWriterTest.kt | 12 +- .../internal/SpotlightIntegrationTest.kt | 10 +- .../java/io/sentry/protocol/SentrySpanTest.kt | 4 +- .../io/sentry/transport/RateLimiterTest.kt | 32 +- .../java/io/sentry/util/CheckInUtilsTest.kt | 91 ++-- .../java/io/sentry/util/TracingUtilsTest.kt | 30 +- 55 files changed, 1092 insertions(+), 793 deletions(-) create mode 100644 sentry/src/test/java/io/sentry/ScopesAdapterTest.kt diff --git a/sentry/src/main/java/io/sentry/Baggage.java b/sentry/src/main/java/io/sentry/Baggage.java index 8e19fceaf8..4a637bacdf 100644 --- a/sentry/src/main/java/io/sentry/Baggage.java +++ b/sentry/src/main/java/io/sentry/Baggage.java @@ -39,13 +39,13 @@ public final class Baggage { @NotNull public static Baggage fromHeader(final @Nullable String headerValue) { return Baggage.fromHeader( - headerValue, false, HubAdapter.getInstance().getOptions().getLogger()); + headerValue, false, ScopesAdapter.getInstance().getOptions().getLogger()); } @NotNull public static Baggage fromHeader(final @Nullable List headerValues) { return Baggage.fromHeader( - headerValues, false, HubAdapter.getInstance().getOptions().getLogger()); + headerValues, false, ScopesAdapter.getInstance().getOptions().getLogger()); } @ApiStatus.Internal diff --git a/sentry/src/main/java/io/sentry/DirectoryProcessor.java b/sentry/src/main/java/io/sentry/DirectoryProcessor.java index 5d60feba60..a6bb258f30 100644 --- a/sentry/src/main/java/io/sentry/DirectoryProcessor.java +++ b/sentry/src/main/java/io/sentry/DirectoryProcessor.java @@ -19,17 +19,17 @@ abstract class DirectoryProcessor { private static final long ENVELOPE_PROCESSING_DELAY = 100L; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @NotNull ILogger logger; private final long flushTimeoutMillis; private final Queue processedEnvelopes; DirectoryProcessor( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull ILogger logger, final long flushTimeoutMillis, final int maxQueueSize) { - this.hub = hub; + this.scopes = scopes; this.logger = logger; this.flushTimeoutMillis = flushTimeoutMillis; this.processedEnvelopes = @@ -86,7 +86,7 @@ public void processDirectory(final @NotNull File directory) { } // in case there's rate limiting active, skip processing - final @Nullable RateLimiter rateLimiter = hub.getRateLimiter(); + final @Nullable RateLimiter rateLimiter = scopes.getRateLimiter(); if (rateLimiter != null && rateLimiter.isActiveForCategory(DataCategory.All)) { logger.log(SentryLevel.INFO, "DirectoryProcessor, rate limiting active."); return; diff --git a/sentry/src/main/java/io/sentry/EnvelopeSender.java b/sentry/src/main/java/io/sentry/EnvelopeSender.java index 598caad280..3a157f59d3 100644 --- a/sentry/src/main/java/io/sentry/EnvelopeSender.java +++ b/sentry/src/main/java/io/sentry/EnvelopeSender.java @@ -17,18 +17,18 @@ @ApiStatus.Internal public final class EnvelopeSender extends DirectoryProcessor implements IEnvelopeSender { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @NotNull ISerializer serializer; private final @NotNull ILogger logger; public EnvelopeSender( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull ISerializer serializer, final @NotNull ILogger logger, final long flushTimeoutMillis, final int maxQueueSize) { - super(hub, logger, flushTimeoutMillis, maxQueueSize); - this.hub = Objects.requireNonNull(hub, "Hub is required."); + super(scopes, logger, flushTimeoutMillis, maxQueueSize); + this.scopes = Objects.requireNonNull(scopes, "Hub is required."); this.serializer = Objects.requireNonNull(serializer, "Serializer is required."); this.logger = Objects.requireNonNull(logger, "Logger is required."); } @@ -60,7 +60,7 @@ protected void processFile(final @NotNull File file, final @NotNull Hint hint) { logger.log( SentryLevel.ERROR, "Failed to deserialize cached envelope %s", file.getAbsolutePath()); } else { - hub.captureEnvelope(envelope, hint); + scopes.captureEnvelope(envelope, hint); } HintUtils.runIfHasTypeLogIfNot( diff --git a/sentry/src/main/java/io/sentry/Integration.java b/sentry/src/main/java/io/sentry/Integration.java index 54b17e4d51..1b1a520473 100644 --- a/sentry/src/main/java/io/sentry/Integration.java +++ b/sentry/src/main/java/io/sentry/Integration.java @@ -10,8 +10,8 @@ public interface Integration { /** * Registers an integration * - * @param hub the Hub + * @param scopes the Scopes * @param options the options */ - void register(@NotNull IHub hub, @NotNull SentryOptions options); + void register(@NotNull IScopes scopes, @NotNull SentryOptions options); } diff --git a/sentry/src/main/java/io/sentry/MonitorConfig.java b/sentry/src/main/java/io/sentry/MonitorConfig.java index d954a50466..763e3b65a4 100644 --- a/sentry/src/main/java/io/sentry/MonitorConfig.java +++ b/sentry/src/main/java/io/sentry/MonitorConfig.java @@ -21,7 +21,7 @@ public final class MonitorConfig implements JsonUnknown, JsonSerializable { public MonitorConfig(final @NotNull MonitorSchedule schedule) { this.schedule = schedule; - final SentryOptions.Cron defaultCron = HubAdapter.getInstance().getOptions().getCron(); + final SentryOptions.Cron defaultCron = ScopesAdapter.getInstance().getOptions().getCron(); if (defaultCron != null) { this.checkinMargin = defaultCron.getDefaultCheckinMargin(); this.maxRuntime = defaultCron.getDefaultMaxRuntime(); diff --git a/sentry/src/main/java/io/sentry/OutboxSender.java b/sentry/src/main/java/io/sentry/OutboxSender.java index 709cbb8580..f80bf030c8 100644 --- a/sentry/src/main/java/io/sentry/OutboxSender.java +++ b/sentry/src/main/java/io/sentry/OutboxSender.java @@ -36,20 +36,20 @@ public final class OutboxSender extends DirectoryProcessor implements IEnvelopeS @SuppressWarnings("CharsetObjectCanBeUsed") private static final Charset UTF_8 = Charset.forName("UTF-8"); - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @NotNull IEnvelopeReader envelopeReader; private final @NotNull ISerializer serializer; private final @NotNull ILogger logger; public OutboxSender( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull IEnvelopeReader envelopeReader, final @NotNull ISerializer serializer, final @NotNull ILogger logger, final long flushTimeoutMillis, final int maxQueueSize) { - super(hub, logger, flushTimeoutMillis, maxQueueSize); - this.hub = Objects.requireNonNull(hub, "Hub is required."); + super(scopes, logger, flushTimeoutMillis, maxQueueSize); + this.scopes = Objects.requireNonNull(scopes, "Hub is required."); this.envelopeReader = Objects.requireNonNull(envelopeReader, "Envelope reader is required."); this.serializer = Objects.requireNonNull(serializer, "Serializer is required."); this.logger = Objects.requireNonNull(logger, "Logger is required."); @@ -144,7 +144,7 @@ private void processEnvelope(final @NotNull SentryEnvelope envelope, final @NotN logUnexpectedEventId(envelope, event.getEventId(), currentItem); continue; } - hub.captureEvent(event, hint); + scopes.captureEvent(event, hint); logItemCaptured(currentItem); if (!waitFlush(hint)) { @@ -181,7 +181,7 @@ private void processEnvelope(final @NotNull SentryEnvelope envelope, final @NotN .getTrace() .setSamplingDecision(extractSamplingDecision(traceContext)); } - hub.captureTransaction(transaction, traceContext, hint); + scopes.captureTransaction(transaction, traceContext, hint); logItemCaptured(currentItem); if (!waitFlush(hint)) { @@ -197,7 +197,7 @@ private void processEnvelope(final @NotNull SentryEnvelope envelope, final @NotN final SentryEnvelope newEnvelope = new SentryEnvelope( envelope.getHeader().getEventId(), envelope.getHeader().getSdkVersion(), item); - hub.captureEnvelope(newEnvelope, hint); + scopes.captureEnvelope(newEnvelope, hint); logger.log( SentryLevel.DEBUG, "%s item %d is being captured.", diff --git a/sentry/src/main/java/io/sentry/PreviousSessionFinalizer.java b/sentry/src/main/java/io/sentry/PreviousSessionFinalizer.java index 458c6532ba..bda2a14477 100644 --- a/sentry/src/main/java/io/sentry/PreviousSessionFinalizer.java +++ b/sentry/src/main/java/io/sentry/PreviousSessionFinalizer.java @@ -33,11 +33,11 @@ final class PreviousSessionFinalizer implements Runnable { private final @NotNull SentryOptions options; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; - PreviousSessionFinalizer(final @NotNull SentryOptions options, final @NotNull IHub hub) { + PreviousSessionFinalizer(final @NotNull SentryOptions options, final @NotNull IScopes scopes) { this.options = options; - this.hub = hub; + this.scopes = scopes; } @Override @@ -116,7 +116,7 @@ public void run() { // SdkVersion will be outdated. final SentryEnvelope fromSession = SentryEnvelope.from(serializer, session, options.getSdkVersion()); - hub.captureEnvelope(fromSession); + scopes.captureEnvelope(fromSession); } } catch (Throwable e) { options.getLogger().log(SentryLevel.ERROR, "Error processing previous session.", e); diff --git a/sentry/src/main/java/io/sentry/SendCachedEnvelopeFireAndForgetIntegration.java b/sentry/src/main/java/io/sentry/SendCachedEnvelopeFireAndForgetIntegration.java index bc813fdd1e..2160d1607e 100644 --- a/sentry/src/main/java/io/sentry/SendCachedEnvelopeFireAndForgetIntegration.java +++ b/sentry/src/main/java/io/sentry/SendCachedEnvelopeFireAndForgetIntegration.java @@ -18,7 +18,7 @@ public final class SendCachedEnvelopeFireAndForgetIntegration private final @NotNull SendFireAndForgetFactory factory; private @Nullable IConnectionStatusProvider connectionStatusProvider; - private @Nullable IHub hub; + private @Nullable IScopes scopes; private @Nullable SentryOptions options; private @Nullable SendFireAndForget sender; private final AtomicBoolean isInitialized = new AtomicBoolean(false); @@ -35,7 +35,7 @@ public interface SendFireAndForgetDirPath { public interface SendFireAndForgetFactory { @Nullable - SendFireAndForget create(@NotNull IHub hub, @NotNull SentryOptions options); + SendFireAndForget create(@NotNull IScopes scopes, @NotNull SentryOptions options); default boolean hasValidPath(final @Nullable String dirPath, final @NotNull ILogger logger) { if (dirPath == null || dirPath.isEmpty()) { @@ -66,8 +66,8 @@ public SendCachedEnvelopeFireAndForgetIntegration( } @Override - public void register(final @NotNull IHub hub, final @NotNull SentryOptions options) { - this.hub = Objects.requireNonNull(hub, "Hub is required"); + public void register(final @NotNull IScopes scopes, final @NotNull SentryOptions options) { + this.scopes = Objects.requireNonNull(scopes, "Hub is required"); this.options = Objects.requireNonNull(options, "SentryOptions is required"); final String cachedDir = options.getCacheDirPath(); @@ -81,7 +81,7 @@ public void register(final @NotNull IHub hub, final @NotNull SentryOptions optio .log(SentryLevel.DEBUG, "SendCachedEventFireAndForgetIntegration installed."); addIntegrationToSdkVersion(getClass()); - sendCachedEnvelopes(hub, options); + sendCachedEnvelopes(scopes, options); } @Override @@ -95,14 +95,14 @@ public void close() throws IOException { @Override public void onConnectionStatusChanged( final @NotNull IConnectionStatusProvider.ConnectionStatus status) { - if (hub != null && options != null) { - sendCachedEnvelopes(hub, options); + if (scopes != null && options != null) { + sendCachedEnvelopes(scopes, options); } } @SuppressWarnings({"FutureReturnValueIgnored", "NullAway"}) private synchronized void sendCachedEnvelopes( - final @NotNull IHub hub, final @NotNull SentryOptions options) { + final @NotNull IScopes scopes, final @NotNull SentryOptions options) { try { options .getExecutorService() @@ -122,7 +122,7 @@ private synchronized void sendCachedEnvelopes( connectionStatusProvider = options.getConnectionStatusProvider(); connectionStatusProvider.addConnectionStatusObserver(this); - sender = factory.create(hub, options); + sender = factory.create(scopes, options); } // skip run only if we're certainly disconnected @@ -138,7 +138,7 @@ private synchronized void sendCachedEnvelopes( } // in case there's rate limiting active, skip processing - final @Nullable RateLimiter rateLimiter = hub.getRateLimiter(); + final @Nullable RateLimiter rateLimiter = scopes.getRateLimiter(); if (rateLimiter != null && rateLimiter.isActiveForCategory(DataCategory.All)) { options .getLogger() diff --git a/sentry/src/main/java/io/sentry/SendFireAndForgetEnvelopeSender.java b/sentry/src/main/java/io/sentry/SendFireAndForgetEnvelopeSender.java index e44d18a8d6..155946b95a 100644 --- a/sentry/src/main/java/io/sentry/SendFireAndForgetEnvelopeSender.java +++ b/sentry/src/main/java/io/sentry/SendFireAndForgetEnvelopeSender.java @@ -21,8 +21,8 @@ public SendFireAndForgetEnvelopeSender( @Override public @Nullable SendCachedEnvelopeFireAndForgetIntegration.SendFireAndForget create( - final @NotNull IHub hub, final @NotNull SentryOptions options) { - Objects.requireNonNull(hub, "Hub is required"); + final @NotNull IScopes scopes, final @NotNull SentryOptions options) { + Objects.requireNonNull(scopes, "Hub is required"); Objects.requireNonNull(options, "SentryOptions is required"); final String dirPath = sendFireAndForgetDirPath.getDirPath(); @@ -33,7 +33,7 @@ public SendFireAndForgetEnvelopeSender( final EnvelopeSender envelopeSender = new EnvelopeSender( - hub, + scopes, options.getSerializer(), options.getLogger(), options.getFlushTimeoutMillis(), diff --git a/sentry/src/main/java/io/sentry/SendFireAndForgetOutboxSender.java b/sentry/src/main/java/io/sentry/SendFireAndForgetOutboxSender.java index fda41610fd..e7913b5b2f 100644 --- a/sentry/src/main/java/io/sentry/SendFireAndForgetOutboxSender.java +++ b/sentry/src/main/java/io/sentry/SendFireAndForgetOutboxSender.java @@ -21,8 +21,8 @@ public SendFireAndForgetOutboxSender( @Override public @Nullable SendCachedEnvelopeFireAndForgetIntegration.SendFireAndForget create( - final @NotNull IHub hub, final @NotNull SentryOptions options) { - Objects.requireNonNull(hub, "Hub is required"); + final @NotNull IScopes scopes, final @NotNull SentryOptions options) { + Objects.requireNonNull(scopes, "Hub is required"); Objects.requireNonNull(options, "SentryOptions is required"); final String dirPath = sendFireAndForgetDirPath.getDirPath(); @@ -33,7 +33,7 @@ public SendFireAndForgetOutboxSender( final OutboxSender outboxSender = new OutboxSender( - hub, + scopes, options.getEnvelopeReader(), options.getSerializer(), options.getLogger(), diff --git a/sentry/src/main/java/io/sentry/SentryTracer.java b/sentry/src/main/java/io/sentry/SentryTracer.java index bc3b5eb531..7d82bbbc4a 100644 --- a/sentry/src/main/java/io/sentry/SentryTracer.java +++ b/sentry/src/main/java/io/sentry/SentryTracer.java @@ -26,7 +26,7 @@ public final class SentryTracer implements ITransaction { private final @NotNull SentryId eventId = new SentryId(); private final @NotNull Span root; private final @NotNull List children = new CopyOnWriteArrayList<>(); - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private @NotNull String name; /** @@ -52,31 +52,31 @@ public final class SentryTracer implements ITransaction { private final @Nullable TransactionPerformanceCollector transactionPerformanceCollector; private final @NotNull TransactionOptions transactionOptions; - public SentryTracer(final @NotNull TransactionContext context, final @NotNull IHub hub) { - this(context, hub, new TransactionOptions(), null); + public SentryTracer(final @NotNull TransactionContext context, final @NotNull IScopes scopes) { + this(context, scopes, new TransactionOptions(), null); } public SentryTracer( final @NotNull TransactionContext context, - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull TransactionOptions transactionOptions) { - this(context, hub, transactionOptions, null); + this(context, scopes, transactionOptions, null); } SentryTracer( final @NotNull TransactionContext context, - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull TransactionOptions transactionOptions, final @Nullable TransactionPerformanceCollector transactionPerformanceCollector) { Objects.requireNonNull(context, "context is required"); - Objects.requireNonNull(hub, "hub is required"); + Objects.requireNonNull(scopes, "scopes are required"); this.root = - new Span(context, this, hub, transactionOptions.getStartTimestamp(), transactionOptions); + new Span(context, this, scopes, transactionOptions.getStartTimestamp(), transactionOptions); this.name = context.getName(); this.instrumenter = context.getInstrumenter(); - this.hub = hub; + this.scopes = scopes; this.transactionPerformanceCollector = transactionPerformanceCollector; this.transactionNameSource = context.getTransactionNameSource(); this.transactionOptions = transactionOptions; @@ -84,7 +84,7 @@ public SentryTracer( if (context.getBaggage() != null) { this.baggage = context.getBaggage(); } else { - this.baggage = new Baggage(hub.getOptions().getLogger()); + this.baggage = new Baggage(scopes.getOptions().getLogger()); } // We are currently sending the performance data only in profiles, so there's no point in @@ -122,7 +122,8 @@ public void run() { try { timer.schedule(idleTimeoutTask, idleTimeout); } catch (Throwable e) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log(SentryLevel.WARNING, "Failed to schedule finish timer", e); // if we failed to schedule the finish timer for some reason, we finish it here right @@ -156,7 +157,7 @@ private void onDeadlineTimeoutReached() { return; } - final @NotNull SentryDate finishTimestamp = hub.getOptions().getDateProvider().now(); + final @NotNull SentryDate finishTimestamp = scopes.getOptions().getDateProvider().now(); // abort all child-spans first, this ensures the transaction can be finished, // even if waitForChildren is true @@ -186,7 +187,7 @@ public void finish( // if it's not set -> fallback to the current time if (finishTimestamp == null) { - finishTimestamp = hub.getOptions().getDateProvider().now(); + finishTimestamp = scopes.getOptions().getDateProvider().now(); } // auto-finish any idle spans first @@ -207,9 +208,10 @@ public void finish( ProfilingTraceData profilingTraceData = null; if (Boolean.TRUE.equals(isSampled()) && Boolean.TRUE.equals(isProfileSampled())) { profilingTraceData = - hub.getOptions() + scopes + .getOptions() .getTransactionProfiler() - .onTransactionFinish(this, performanceCollectionData, hub.getOptions()); + .onTransactionFinish(this, performanceCollectionData, scopes.getOptions()); } if (performanceCollectionData != null) { performanceCollectionData.clear(); @@ -222,7 +224,7 @@ public void finish( root.finish(finishStatus.spanStatus, finishTimestamp); - hub.configureScope( + scopes.configureScope( scope -> { scope.withTransaction( transaction -> { @@ -251,7 +253,8 @@ public void finish( if (dropIfNoChildren && children.isEmpty() && transactionOptions.getIdleTimeout() != null) { // if it's an idle transaction which has no children, we drop it to save user's quota - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -261,7 +264,7 @@ public void finish( } transaction.getMeasurements().putAll(root.getMeasurements()); - hub.captureTransaction(transaction, traceContext(), hint, profilingTraceData); + scopes.captureTransaction(transaction, traceContext(), hint, profilingTraceData); } } @@ -292,7 +295,8 @@ public void run() { try { timer.schedule(deadlineTimeoutTask, deadlineTimeOut); } catch (Throwable e) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log(SentryLevel.WARNING, "Failed to schedule finish timer", e); // if we failed to schedule the finish timer for some reason, we finish it here right @@ -418,7 +422,7 @@ private ISpan createChild( return NoOpSpan.getInstance(); } - if (children.size() < hub.getOptions().getMaxSpans()) { + if (children.size() < scopes.getOptions().getMaxSpans()) { Objects.requireNonNull(parentSpanId, "parentSpanId is required"); Objects.requireNonNull(operation, "operation is required"); cancelIdleTimer(); @@ -428,7 +432,7 @@ private ISpan createChild( parentSpanId, this, operation, - this.hub, + this.scopes, timestamp, spanOptions, finishingSpan -> { @@ -451,7 +455,7 @@ private ISpan createChild( span.setData(SpanDataConvention.THREAD_ID, String.valueOf(Thread.currentThread().getId())); span.setData( SpanDataConvention.THREAD_NAME, - hub.getOptions().getMainThreadChecker().isMainThread() + scopes.getOptions().getMainThreadChecker().isMainThread() ? "main" : Thread.currentThread().getName()); this.children.add(span); @@ -460,7 +464,8 @@ private ISpan createChild( } return span; } else { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.WARNING, @@ -529,10 +534,11 @@ private ISpan createChild( return NoOpSpan.getInstance(); } - if (children.size() < hub.getOptions().getMaxSpans()) { + if (children.size() < scopes.getOptions().getMaxSpans()) { return root.startChild(operation, description, timestamp, instrumenter, spanOptions); } else { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.WARNING, @@ -567,7 +573,7 @@ public void finish(@Nullable SpanStatus status, @Nullable SentryDate finishDate) @Override public @Nullable TraceContext traceContext() { - if (hub.getOptions().isTraceSampling()) { + if (scopes.getOptions().isTraceSampling()) { updateBaggageValues(); return baggage.toTraceContext(); } else { @@ -579,12 +585,12 @@ private void updateBaggageValues() { synchronized (this) { if (baggage.isMutable()) { final AtomicReference userAtomicReference = new AtomicReference<>(); - hub.configureScope( + scopes.configureScope( scope -> { userAtomicReference.set(scope.getUser()); }); baggage.setValuesFromTransaction( - this, userAtomicReference.get(), hub.getOptions(), this.getSamplingDecision()); + this, userAtomicReference.get(), scopes.getOptions(), this.getSamplingDecision()); baggage.freeze(); } } @@ -592,7 +598,7 @@ private void updateBaggageValues() { @Override public @Nullable BaggageHeader toBaggageHeader(@Nullable List thirdPartyBaggageHeaders) { - if (hub.getOptions().isTraceSampling()) { + if (scopes.getOptions().isTraceSampling()) { updateBaggageValues(); return BaggageHeader.fromBaggageAndOutgoingHeader(baggage, thirdPartyBaggageHeaders); @@ -616,7 +622,8 @@ private boolean hasAllChildrenFinished() { @Override public void setOperation(final @NotNull String operation) { if (root.isFinished()) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -636,7 +643,8 @@ public void setOperation(final @NotNull String operation) { @Override public void setDescription(final @Nullable String description) { if (root.isFinished()) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -656,7 +664,8 @@ public void setDescription(final @Nullable String description) { @Override public void setStatus(final @Nullable SpanStatus status) { if (root.isFinished()) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -676,7 +685,8 @@ public void setStatus(final @Nullable SpanStatus status) { @Override public void setThrowable(final @Nullable Throwable throwable) { if (root.isFinished()) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log(SentryLevel.DEBUG, "The transaction is already finished. Throwable cannot be set"); return; @@ -698,7 +708,8 @@ public void setThrowable(final @Nullable Throwable throwable) { @Override public void setTag(final @NotNull String key, final @NotNull String value) { if (root.isFinished()) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log(SentryLevel.DEBUG, "The transaction is already finished. Tag %s cannot be set", key); return; @@ -720,7 +731,8 @@ public boolean isFinished() { @Override public void setData(@NotNull String key, @NotNull Object value) { if (root.isFinished()) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, "The transaction is already finished. Data %s cannot be set", key); @@ -795,7 +807,8 @@ public void setName(@NotNull String name) { @Override public void setName(@NotNull String name, @NotNull TransactionNameSource transactionNameSource) { if (root.isFinished()) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, diff --git a/sentry/src/main/java/io/sentry/SentryWrapper.java b/sentry/src/main/java/io/sentry/SentryWrapper.java index 1a39adee99..165ace7c83 100644 --- a/sentry/src/main/java/io/sentry/SentryWrapper.java +++ b/sentry/src/main/java/io/sentry/SentryWrapper.java @@ -27,16 +27,18 @@ public final class SentryWrapper { * @return the wrapped {@link Callable} * @param - the result type of the {@link Callable} */ + @SuppressWarnings("deprecation") public static Callable wrapCallable(final @NotNull Callable callable) { - final IHub newHub = Sentry.getCurrentHub().clone(); + // TODO replace with forking + final IScopes newHub = Sentry.getCurrentScopes().clone(); return () -> { - final IHub oldState = Sentry.getCurrentHub(); - Sentry.setCurrentHub(newHub); + final IScopes oldState = Sentry.getCurrentScopes(); + Sentry.setCurrentScopes(newHub); try { return callable.call(); } finally { - Sentry.setCurrentHub(oldState); + Sentry.setCurrentScopes(oldState); } }; } @@ -51,17 +53,18 @@ public static Callable wrapCallable(final @NotNull Callable callable) * @return the wrapped {@link Supplier} * @param - the result type of the {@link Supplier} */ + @SuppressWarnings("deprecation") public static Supplier wrapSupplier(final @NotNull Supplier supplier) { - - final IHub newHub = Sentry.getCurrentHub().clone(); + // TODO replace with forking + final IScopes newHub = Sentry.getCurrentScopes().clone(); return () -> { - final IHub oldState = Sentry.getCurrentHub(); - Sentry.setCurrentHub(newHub); + final IScopes oldState = Sentry.getCurrentScopes(); + Sentry.setCurrentScopes(newHub); try { return supplier.get(); } finally { - Sentry.setCurrentHub(oldState); + Sentry.setCurrentScopes(oldState); } }; } diff --git a/sentry/src/main/java/io/sentry/ShutdownHookIntegration.java b/sentry/src/main/java/io/sentry/ShutdownHookIntegration.java index b144f2d88a..d957a87ccf 100644 --- a/sentry/src/main/java/io/sentry/ShutdownHookIntegration.java +++ b/sentry/src/main/java/io/sentry/ShutdownHookIntegration.java @@ -27,12 +27,12 @@ public ShutdownHookIntegration() { } @Override - public void register(final @NotNull IHub hub, final @NotNull SentryOptions options) { - Objects.requireNonNull(hub, "Hub is required"); + public void register(final @NotNull IScopes scopes, final @NotNull SentryOptions options) { + Objects.requireNonNull(scopes, "Scopes are required"); Objects.requireNonNull(options, "SentryOptions is required"); if (options.isEnableShutdownHook()) { - thread = new Thread(() -> hub.flush(options.getFlushTimeoutMillis())); + thread = new Thread(() -> scopes.flush(options.getFlushTimeoutMillis())); runtime.addShutdownHook(thread); options.getLogger().log(SentryLevel.DEBUG, "ShutdownHookIntegration installed."); addIntegrationToSdkVersion(getClass()); diff --git a/sentry/src/main/java/io/sentry/Span.java b/sentry/src/main/java/io/sentry/Span.java index 850276dac3..1c9d180b29 100644 --- a/sentry/src/main/java/io/sentry/Span.java +++ b/sentry/src/main/java/io/sentry/Span.java @@ -35,7 +35,7 @@ public final class Span implements ISpan { /** A throwable thrown during the execution of the span. */ private @Nullable Throwable throwable; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @NotNull AtomicBoolean finished = new AtomicBoolean(false); @@ -55,8 +55,8 @@ public final class Span implements ISpan { final @Nullable SpanId parentSpanId, final @NotNull SentryTracer transaction, final @NotNull String operation, - final @NotNull IHub hub) { - this(traceId, parentSpanId, transaction, operation, hub, null, new SpanOptions(), null); + final @NotNull IScopes scopes) { + this(traceId, parentSpanId, transaction, operation, scopes, null, new SpanOptions(), null); } Span( @@ -64,7 +64,7 @@ public final class Span implements ISpan { final @Nullable SpanId parentSpanId, final @NotNull SentryTracer transaction, final @NotNull String operation, - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @Nullable SentryDate startTimestamp, final @NotNull SpanOptions options, final @Nullable SpanFinishedCallback spanFinishedCallback) { @@ -72,30 +72,30 @@ public final class Span implements ISpan { new SpanContext( traceId, new SpanId(), operation, parentSpanId, transaction.getSamplingDecision()); this.transaction = Objects.requireNonNull(transaction, "transaction is required"); - this.hub = Objects.requireNonNull(hub, "hub is required"); + this.scopes = Objects.requireNonNull(scopes, "Scopes are required"); this.options = options; this.spanFinishedCallback = spanFinishedCallback; if (startTimestamp != null) { this.startTimestamp = startTimestamp; } else { - this.startTimestamp = hub.getOptions().getDateProvider().now(); + this.startTimestamp = scopes.getOptions().getDateProvider().now(); } } public Span( final @NotNull TransactionContext context, final @NotNull SentryTracer sentryTracer, - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @Nullable SentryDate startTimestamp, final @NotNull SpanOptions options) { this.context = Objects.requireNonNull(context, "context is required"); this.transaction = Objects.requireNonNull(sentryTracer, "sentryTracer is required"); - this.hub = Objects.requireNonNull(hub, "hub is required"); + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); this.spanFinishedCallback = null; if (startTimestamp != null) { this.startTimestamp = startTimestamp; } else { - this.startTimestamp = hub.getOptions().getDateProvider().now(); + this.startTimestamp = scopes.getOptions().getDateProvider().now(); } this.options = options; } @@ -180,7 +180,7 @@ public void finish() { @Override public void finish(@Nullable SpanStatus status) { - finish(status, hub.getOptions().getDateProvider().now()); + finish(status, scopes.getOptions().getDateProvider().now()); } /** @@ -197,7 +197,7 @@ public void finish(final @Nullable SpanStatus status, final @Nullable SentryDate } this.context.setStatus(status); - this.timestamp = timestamp == null ? hub.getOptions().getDateProvider().now() : timestamp; + this.timestamp = timestamp == null ? scopes.getOptions().getDateProvider().now() : timestamp; if (options.isTrimStart() || options.isTrimEnd()) { @Nullable SentryDate minChildStart = null; @Nullable SentryDate maxChildEnd = null; @@ -230,7 +230,7 @@ public void finish(final @Nullable SpanStatus status, final @Nullable SentryDate } if (throwable != null) { - hub.setSpanContext(throwable, this, this.transaction.getName()); + scopes.setSpanContext(throwable, this, this.transaction.getName()); } if (spanFinishedCallback != null) { spanFinishedCallback.execute(this); @@ -343,7 +343,8 @@ public void setData(final @NotNull String key, final @NotNull Object value) { @Override public void setMeasurement(final @NotNull String name, final @NotNull Number value) { if (isFinished()) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -365,7 +366,8 @@ public void setMeasurement( final @NotNull Number value, final @NotNull MeasurementUnit unit) { if (isFinished()) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, diff --git a/sentry/src/main/java/io/sentry/SpotlightIntegration.java b/sentry/src/main/java/io/sentry/SpotlightIntegration.java index 6d488bcbce..0b69ae79be 100644 --- a/sentry/src/main/java/io/sentry/SpotlightIntegration.java +++ b/sentry/src/main/java/io/sentry/SpotlightIntegration.java @@ -26,7 +26,7 @@ public final class SpotlightIntegration private @NotNull ISentryExecutorService executorService = NoOpSentryExecutorService.getInstance(); @Override - public void register(@NotNull IHub hub, @NotNull SentryOptions options) { + public void register(@NotNull IScopes scopes, @NotNull SentryOptions options) { this.options = options; this.logger = options.getLogger(); diff --git a/sentry/src/main/java/io/sentry/UncaughtExceptionHandlerIntegration.java b/sentry/src/main/java/io/sentry/UncaughtExceptionHandlerIntegration.java index 33e1a4a815..47ceaa084e 100644 --- a/sentry/src/main/java/io/sentry/UncaughtExceptionHandlerIntegration.java +++ b/sentry/src/main/java/io/sentry/UncaughtExceptionHandlerIntegration.java @@ -28,7 +28,7 @@ public final class UncaughtExceptionHandlerIntegration /** Reference to the pre-existing uncaught exception handler. */ private @Nullable Thread.UncaughtExceptionHandler defaultExceptionHandler; - private @Nullable IHub hub; + private @Nullable IScopes scopes; private @Nullable SentryOptions options; private boolean registered = false; @@ -43,7 +43,7 @@ public UncaughtExceptionHandlerIntegration() { } @Override - public final void register(final @NotNull IHub hub, final @NotNull SentryOptions options) { + public final void register(final @NotNull IScopes scopes, final @NotNull SentryOptions options) { if (registered) { options .getLogger() @@ -54,7 +54,7 @@ public final void register(final @NotNull IHub hub, final @NotNull SentryOptions } registered = true; - this.hub = Objects.requireNonNull(hub, "Hub is required"); + this.scopes = Objects.requireNonNull(scopes, "Hub is required"); this.options = Objects.requireNonNull(options, "SentryOptions is required"); this.options @@ -89,7 +89,7 @@ public final void register(final @NotNull IHub hub, final @NotNull SentryOptions @Override public void uncaughtException(Thread thread, Throwable thrown) { - if (options != null && hub != null) { + if (options != null && scopes != null) { options.getLogger().log(SentryLevel.INFO, "Uncaught exception received."); try { @@ -99,14 +99,14 @@ public void uncaughtException(Thread thread, Throwable thrown) { final SentryEvent event = new SentryEvent(throwable); event.setLevel(SentryLevel.FATAL); - final ITransaction transaction = hub.getTransaction(); + final ITransaction transaction = scopes.getTransaction(); if (transaction == null && event.getEventId() != null) { // if there's no active transaction on scope, this event can trigger flush notification exceptionHint.setFlushable(event.getEventId()); } final Hint hint = HintUtils.createWithTypeCheckHint(exceptionHint); - final @NotNull SentryId sentryId = hub.captureEvent(event, hint); + final @NotNull SentryId sentryId = scopes.captureEvent(event, hint); final boolean isEventDropped = sentryId.equals(SentryId.EMPTY_ID); final EventDropReason eventDropReason = HintUtils.getEventDropReason(hint); // in case the event has been dropped by multithreaded deduplicator, the other threads will diff --git a/sentry/src/main/java/io/sentry/backpressure/BackpressureMonitor.java b/sentry/src/main/java/io/sentry/backpressure/BackpressureMonitor.java index 2008a38c76..6541a7586a 100644 --- a/sentry/src/main/java/io/sentry/backpressure/BackpressureMonitor.java +++ b/sentry/src/main/java/io/sentry/backpressure/BackpressureMonitor.java @@ -1,6 +1,6 @@ package io.sentry.backpressure; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ISentryExecutorService; import io.sentry.SentryLevel; import io.sentry.SentryOptions; @@ -12,12 +12,13 @@ public final class BackpressureMonitor implements IBackpressureMonitor, Runnable private static final int CHECK_INTERVAL_IN_MS = 10 * 1000; private final @NotNull SentryOptions sentryOptions; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private int downsampleFactor = 0; - public BackpressureMonitor(final @NotNull SentryOptions sentryOptions, final @NotNull IHub hub) { + public BackpressureMonitor( + final @NotNull SentryOptions sentryOptions, final @NotNull IScopes scopes) { this.sentryOptions = sentryOptions; - this.hub = hub; + this.scopes = scopes; } @Override @@ -66,6 +67,6 @@ private void reschedule(final int delay) { } private boolean isHealthy() { - return hub.isHealthy(); + return scopes.isHealthy(); } } diff --git a/sentry/src/main/java/io/sentry/instrumentation/file/FileIOSpanManager.java b/sentry/src/main/java/io/sentry/instrumentation/file/FileIOSpanManager.java index 956996ce04..52963413b6 100644 --- a/sentry/src/main/java/io/sentry/instrumentation/file/FileIOSpanManager.java +++ b/sentry/src/main/java/io/sentry/instrumentation/file/FileIOSpanManager.java @@ -1,6 +1,6 @@ package io.sentry.instrumentation.file; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ISpan; import io.sentry.SentryIntegrationPackageStorage; import io.sentry.SentryOptions; @@ -28,8 +28,8 @@ final class FileIOSpanManager { private final @NotNull SentryStackTraceFactory stackTraceFactory; - static @Nullable ISpan startSpan(final @NotNull IHub hub, final @NotNull String op) { - final ISpan parent = Platform.isAndroid() ? hub.getTransaction() : hub.getSpan(); + static @Nullable ISpan startSpan(final @NotNull IScopes scopes, final @NotNull String op) { + final ISpan parent = Platform.isAndroid() ? scopes.getTransaction() : scopes.getSpan(); return parent != null ? parent.startChild(op) : null; } diff --git a/sentry/src/main/java/io/sentry/instrumentation/file/SentryFileInputStream.java b/sentry/src/main/java/io/sentry/instrumentation/file/SentryFileInputStream.java index 04bb87ae7c..ea7d7f09a5 100644 --- a/sentry/src/main/java/io/sentry/instrumentation/file/SentryFileInputStream.java +++ b/sentry/src/main/java/io/sentry/instrumentation/file/SentryFileInputStream.java @@ -1,8 +1,8 @@ package io.sentry.instrumentation.file; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ISpan; +import io.sentry.ScopesAdapter; import java.io.File; import java.io.FileDescriptor; import java.io.FileInputStream; @@ -25,24 +25,24 @@ public final class SentryFileInputStream extends FileInputStream { private final @NotNull FileIOSpanManager spanManager; public SentryFileInputStream(final @Nullable String name) throws FileNotFoundException { - this(name != null ? new File(name) : null, HubAdapter.getInstance()); + this(name != null ? new File(name) : null, ScopesAdapter.getInstance()); } public SentryFileInputStream(final @Nullable File file) throws FileNotFoundException { - this(file, HubAdapter.getInstance()); + this(file, ScopesAdapter.getInstance()); } public SentryFileInputStream(final @NotNull FileDescriptor fdObj) { - this(fdObj, HubAdapter.getInstance()); + this(fdObj, ScopesAdapter.getInstance()); } - SentryFileInputStream(final @Nullable File file, final @NotNull IHub hub) + SentryFileInputStream(final @Nullable File file, final @NotNull IScopes scopes) throws FileNotFoundException { - this(init(file, null, hub)); + this(init(file, null, scopes)); } - SentryFileInputStream(final @NotNull FileDescriptor fdObj, final @NotNull IHub hub) { - this(init(fdObj, null, hub), fdObj); + SentryFileInputStream(final @NotNull FileDescriptor fdObj, final @NotNull IScopes scopes) { + this(init(fdObj, null, scopes), fdObj); } private SentryFileInputStream( @@ -60,24 +60,24 @@ private SentryFileInputStream(final @NotNull FileInputStreamInitData data) } private static FileInputStreamInitData init( - final @Nullable File file, @Nullable FileInputStream delegate, final @NotNull IHub hub) + final @Nullable File file, @Nullable FileInputStream delegate, final @NotNull IScopes scopes) throws FileNotFoundException { - final ISpan span = FileIOSpanManager.startSpan(hub, "file.read"); + final ISpan span = FileIOSpanManager.startSpan(scopes, "file.read"); if (delegate == null) { delegate = new FileInputStream(file); } - return new FileInputStreamInitData(file, span, delegate, hub.getOptions()); + return new FileInputStreamInitData(file, span, delegate, scopes.getOptions()); } private static FileInputStreamInitData init( final @NotNull FileDescriptor fd, @Nullable FileInputStream delegate, - final @NotNull IHub hub) { - final ISpan span = FileIOSpanManager.startSpan(hub, "file.read"); + final @NotNull IScopes scopes) { + final ISpan span = FileIOSpanManager.startSpan(scopes, "file.read"); if (delegate == null) { delegate = new FileInputStream(fd); } - return new FileInputStreamInitData(null, span, delegate, hub.getOptions()); + return new FileInputStreamInitData(null, span, delegate, scopes.getOptions()); } @Override @@ -128,25 +128,27 @@ public static FileInputStream create( final @NotNull FileInputStream delegate, final @Nullable String name) throws FileNotFoundException { return new SentryFileInputStream( - init(name != null ? new File(name) : null, delegate, HubAdapter.getInstance())); + init(name != null ? new File(name) : null, delegate, ScopesAdapter.getInstance())); } public static FileInputStream create( final @NotNull FileInputStream delegate, final @Nullable File file) throws FileNotFoundException { - return new SentryFileInputStream(init(file, delegate, HubAdapter.getInstance())); + return new SentryFileInputStream(init(file, delegate, ScopesAdapter.getInstance())); } public static FileInputStream create( final @NotNull FileInputStream delegate, final @NotNull FileDescriptor descriptor) { return new SentryFileInputStream( - init(descriptor, delegate, HubAdapter.getInstance()), descriptor); + init(descriptor, delegate, ScopesAdapter.getInstance()), descriptor); } static FileInputStream create( - final @NotNull FileInputStream delegate, final @Nullable File file, final @NotNull IHub hub) + final @NotNull FileInputStream delegate, + final @Nullable File file, + final @NotNull IScopes scopes) throws FileNotFoundException { - return new SentryFileInputStream(init(file, delegate, hub)); + return new SentryFileInputStream(init(file, delegate, scopes)); } } } diff --git a/sentry/src/main/java/io/sentry/instrumentation/file/SentryFileOutputStream.java b/sentry/src/main/java/io/sentry/instrumentation/file/SentryFileOutputStream.java index 9424710d71..4ef5022e1c 100644 --- a/sentry/src/main/java/io/sentry/instrumentation/file/SentryFileOutputStream.java +++ b/sentry/src/main/java/io/sentry/instrumentation/file/SentryFileOutputStream.java @@ -1,8 +1,8 @@ package io.sentry.instrumentation.file; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ISpan; +import io.sentry.ScopesAdapter; import java.io.File; import java.io.FileDescriptor; import java.io.FileNotFoundException; @@ -24,30 +24,31 @@ public final class SentryFileOutputStream extends FileOutputStream { private final @NotNull FileIOSpanManager spanManager; public SentryFileOutputStream(final @Nullable String name) throws FileNotFoundException { - this(name != null ? new File(name) : null, false, HubAdapter.getInstance()); + this(name != null ? new File(name) : null, false, ScopesAdapter.getInstance()); } public SentryFileOutputStream(final @Nullable String name, final boolean append) throws FileNotFoundException { - this(init(name != null ? new File(name) : null, append, null, HubAdapter.getInstance())); + this(init(name != null ? new File(name) : null, append, null, ScopesAdapter.getInstance())); } public SentryFileOutputStream(final @Nullable File file) throws FileNotFoundException { - this(file, false, HubAdapter.getInstance()); + this(file, false, ScopesAdapter.getInstance()); } public SentryFileOutputStream(final @Nullable File file, final boolean append) throws FileNotFoundException { - this(init(file, append, null, HubAdapter.getInstance())); + this(init(file, append, null, ScopesAdapter.getInstance())); } public SentryFileOutputStream(final @NotNull FileDescriptor fdObj) { - this(init(fdObj, null, HubAdapter.getInstance()), fdObj); + this(init(fdObj, null, ScopesAdapter.getInstance()), fdObj); } - SentryFileOutputStream(final @Nullable File file, final boolean append, final @NotNull IHub hub) + SentryFileOutputStream( + final @Nullable File file, final boolean append, final @NotNull IScopes scopes) throws FileNotFoundException { - this(init(file, append, null, hub)); + this(init(file, append, null, scopes)); } private SentryFileOutputStream( @@ -68,22 +69,24 @@ private static FileOutputStreamInitData init( final @Nullable File file, final boolean append, @Nullable FileOutputStream delegate, - @NotNull IHub hub) + @NotNull IScopes scopes) throws FileNotFoundException { - final ISpan span = FileIOSpanManager.startSpan(hub, "file.write"); + final ISpan span = FileIOSpanManager.startSpan(scopes, "file.write"); if (delegate == null) { delegate = new FileOutputStream(file, append); } - return new FileOutputStreamInitData(file, append, span, delegate, hub.getOptions()); + return new FileOutputStreamInitData(file, append, span, delegate, scopes.getOptions()); } private static FileOutputStreamInitData init( - final @NotNull FileDescriptor fd, @Nullable FileOutputStream delegate, @NotNull IHub hub) { - final ISpan span = FileIOSpanManager.startSpan(hub, "file.write"); + final @NotNull FileDescriptor fd, + @Nullable FileOutputStream delegate, + @NotNull IScopes scopes) { + final ISpan span = FileIOSpanManager.startSpan(scopes, "file.write"); if (delegate == null) { delegate = new FileOutputStream(fd); } - return new FileOutputStreamInitData(null, false, span, delegate, hub.getOptions()); + return new FileOutputStreamInitData(null, false, span, delegate, scopes.getOptions()); } @Override @@ -132,31 +135,32 @@ public static FileOutputStream create( final @NotNull FileOutputStream delegate, final @Nullable String name) throws FileNotFoundException { return new SentryFileOutputStream( - init(name != null ? new File(name) : null, false, delegate, HubAdapter.getInstance())); + init(name != null ? new File(name) : null, false, delegate, ScopesAdapter.getInstance())); } public static FileOutputStream create( final @NotNull FileOutputStream delegate, final @Nullable String name, final boolean append) throws FileNotFoundException { return new SentryFileOutputStream( - init(name != null ? new File(name) : null, append, delegate, HubAdapter.getInstance())); + init( + name != null ? new File(name) : null, append, delegate, ScopesAdapter.getInstance())); } public static FileOutputStream create( final @NotNull FileOutputStream delegate, final @Nullable File file) throws FileNotFoundException { - return new SentryFileOutputStream(init(file, false, delegate, HubAdapter.getInstance())); + return new SentryFileOutputStream(init(file, false, delegate, ScopesAdapter.getInstance())); } public static FileOutputStream create( final @NotNull FileOutputStream delegate, final @Nullable File file, final boolean append) throws FileNotFoundException { - return new SentryFileOutputStream(init(file, append, delegate, HubAdapter.getInstance())); + return new SentryFileOutputStream(init(file, append, delegate, ScopesAdapter.getInstance())); } public static FileOutputStream create( final @NotNull FileOutputStream delegate, final @NotNull FileDescriptor fdObj) { - return new SentryFileOutputStream(init(fdObj, delegate, HubAdapter.getInstance()), fdObj); + return new SentryFileOutputStream(init(fdObj, delegate, ScopesAdapter.getInstance()), fdObj); } } } diff --git a/sentry/src/main/java/io/sentry/instrumentation/file/SentryFileReader.java b/sentry/src/main/java/io/sentry/instrumentation/file/SentryFileReader.java index 0a225e65a5..38a83c7ff6 100644 --- a/sentry/src/main/java/io/sentry/instrumentation/file/SentryFileReader.java +++ b/sentry/src/main/java/io/sentry/instrumentation/file/SentryFileReader.java @@ -1,6 +1,6 @@ package io.sentry.instrumentation.file; -import io.sentry.IHub; +import io.sentry.IScopes; import java.io.File; import java.io.FileDescriptor; import java.io.FileNotFoundException; @@ -20,7 +20,8 @@ public SentryFileReader(final @NotNull FileDescriptor fd) { super(new SentryFileInputStream(fd)); } - SentryFileReader(final @NotNull File file, final @NotNull IHub hub) throws FileNotFoundException { - super(new SentryFileInputStream(file, hub)); + SentryFileReader(final @NotNull File file, final @NotNull IScopes scopes) + throws FileNotFoundException { + super(new SentryFileInputStream(file, scopes)); } } diff --git a/sentry/src/main/java/io/sentry/instrumentation/file/SentryFileWriter.java b/sentry/src/main/java/io/sentry/instrumentation/file/SentryFileWriter.java index 9588984612..93c901ec6c 100644 --- a/sentry/src/main/java/io/sentry/instrumentation/file/SentryFileWriter.java +++ b/sentry/src/main/java/io/sentry/instrumentation/file/SentryFileWriter.java @@ -1,6 +1,6 @@ package io.sentry.instrumentation.file; -import io.sentry.IHub; +import io.sentry.IScopes; import java.io.File; import java.io.FileDescriptor; import java.io.FileNotFoundException; @@ -30,8 +30,8 @@ public SentryFileWriter(final @NotNull FileDescriptor fd) { super(new SentryFileOutputStream(fd)); } - SentryFileWriter(final @NotNull File file, final boolean append, final @NotNull IHub hub) + SentryFileWriter(final @NotNull File file, final boolean append, final @NotNull IScopes scopes) throws FileNotFoundException { - super(new SentryFileOutputStream(file, append, hub)); + super(new SentryFileOutputStream(file, append, scopes)); } } diff --git a/sentry/src/main/java/io/sentry/util/CheckInUtils.java b/sentry/src/main/java/io/sentry/util/CheckInUtils.java index e15603adaf..6719e24839 100644 --- a/sentry/src/main/java/io/sentry/util/CheckInUtils.java +++ b/sentry/src/main/java/io/sentry/util/CheckInUtils.java @@ -3,7 +3,7 @@ import io.sentry.CheckIn; import io.sentry.CheckInStatus; import io.sentry.DateUtils; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.MonitorConfig; import io.sentry.Sentry; import io.sentry.protocol.SentryId; @@ -30,18 +30,19 @@ public static U withCheckIn( final @Nullable MonitorConfig monitorConfig, final @NotNull Callable callable) throws Exception { - final @NotNull IHub hub = Sentry.getCurrentHub(); + final @NotNull IScopes scopes = Sentry.getCurrentScopes(); final long startTime = System.currentTimeMillis(); boolean didError = false; - hub.pushScope(); - TracingUtils.startNewTrace(hub); + // TODO fork instead + scopes.pushScope(); + TracingUtils.startNewTrace(scopes); CheckIn inProgressCheckIn = new CheckIn(monitorSlug, CheckInStatus.IN_PROGRESS); if (monitorConfig != null) { inProgressCheckIn.setMonitorConfig(monitorConfig); } - @Nullable SentryId checkInId = hub.captureCheckIn(inProgressCheckIn); + @Nullable SentryId checkInId = scopes.captureCheckIn(inProgressCheckIn); try { return callable.call(); } catch (Throwable t) { @@ -51,8 +52,8 @@ public static U withCheckIn( final @NotNull CheckInStatus status = didError ? CheckInStatus.ERROR : CheckInStatus.OK; CheckIn checkIn = new CheckIn(checkInId, monitorSlug, status); checkIn.setDuration(DateUtils.millisToSeconds(System.currentTimeMillis() - startTime)); - hub.captureCheckIn(checkIn); - hub.popScope(); + scopes.captureCheckIn(checkIn); + scopes.popScope(); } } diff --git a/sentry/src/main/java/io/sentry/util/TracingUtils.java b/sentry/src/main/java/io/sentry/util/TracingUtils.java index 2aeb613f2d..67f6459660 100644 --- a/sentry/src/main/java/io/sentry/util/TracingUtils.java +++ b/sentry/src/main/java/io/sentry/util/TracingUtils.java @@ -2,8 +2,8 @@ import io.sentry.Baggage; import io.sentry.BaggageHeader; -import io.sentry.IHub; import io.sentry.IScope; +import io.sentry.IScopes; import io.sentry.ISpan; import io.sentry.PropagationContext; import io.sentry.SentryOptions; @@ -14,8 +14,8 @@ public final class TracingUtils { - public static void startNewTrace(final @NotNull IHub hub) { - hub.configureScope( + public static void startNewTrace(final @NotNull IScopes scopes) { + scopes.configureScope( scope -> { scope.withPropagationContext( propagationContext -> { @@ -25,30 +25,30 @@ public static void startNewTrace(final @NotNull IHub hub) { } public static @Nullable TracingHeaders traceIfAllowed( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull String requestUrl, @Nullable List thirdPartyBaggageHeaders, final @Nullable ISpan span) { - final @NotNull SentryOptions sentryOptions = hub.getOptions(); + final @NotNull SentryOptions sentryOptions = scopes.getOptions(); if (sentryOptions.isTraceSampling() && shouldAttachTracingHeaders(requestUrl, sentryOptions)) { - return trace(hub, thirdPartyBaggageHeaders, span); + return trace(scopes, thirdPartyBaggageHeaders, span); } return null; } public static @Nullable TracingHeaders trace( - final @NotNull IHub hub, + final @NotNull IScopes scopes, @Nullable List thirdPartyBaggageHeaders, final @Nullable ISpan span) { - final @NotNull SentryOptions sentryOptions = hub.getOptions(); + final @NotNull SentryOptions sentryOptions = scopes.getOptions(); if (span != null && !span.isNoOp()) { return new TracingHeaders( span.toSentryTrace(), span.toBaggageHeader(thirdPartyBaggageHeaders)); } else { final @NotNull PropagationContextHolder returnValue = new PropagationContextHolder(); - hub.configureScope( + scopes.configureScope( (scope) -> { returnValue.propagationContext = maybeUpdateBaggage(scope, sentryOptions); }); diff --git a/sentry/src/test/java/io/sentry/DefaultTransactionPerformanceCollectorTest.kt b/sentry/src/test/java/io/sentry/DefaultTransactionPerformanceCollectorTest.kt index c0445efb23..1416fbbe3f 100644 --- a/sentry/src/test/java/io/sentry/DefaultTransactionPerformanceCollectorTest.kt +++ b/sentry/src/test/java/io/sentry/DefaultTransactionPerformanceCollectorTest.kt @@ -33,7 +33,7 @@ class DefaultTransactionPerformanceCollectorTest { private class Fixture { lateinit var transaction1: ITransaction lateinit var transaction2: ITransaction - val hub: IHub = mock() + val scopes: IScopes = mock() val options = SentryOptions() var mockTimer: Timer? = null val deferredExecutorService = DeferredExecutorService() @@ -47,7 +47,7 @@ class DefaultTransactionPerformanceCollectorTest { } init { - whenever(hub.options).thenReturn(options) + whenever(scopes.options).thenReturn(options) } fun getSut(memoryCollector: IPerformanceSnapshotCollector? = JavaMemoryCollector(), cpuCollector: IPerformanceSnapshotCollector? = mockCpuCollector, executorService: ISentryExecutorService = deferredExecutorService): TransactionPerformanceCollector { @@ -59,8 +59,8 @@ class DefaultTransactionPerformanceCollectorTest { if (memoryCollector != null) { options.addPerformanceCollector(memoryCollector) } - transaction1 = SentryTracer(TransactionContext("", ""), hub) - transaction2 = SentryTracer(TransactionContext("", ""), hub) + transaction1 = SentryTracer(TransactionContext("", ""), scopes) + transaction2 = SentryTracer(TransactionContext("", ""), scopes) val collector = DefaultTransactionPerformanceCollector(options) val timer: Timer = collector.getProperty("timer") ?: Timer(true) mockTimer = spy(timer) diff --git a/sentry/src/test/java/io/sentry/DirectoryProcessorTest.kt b/sentry/src/test/java/io/sentry/DirectoryProcessorTest.kt index e87f4256d5..0507b8499d 100644 --- a/sentry/src/test/java/io/sentry/DirectoryProcessorTest.kt +++ b/sentry/src/test/java/io/sentry/DirectoryProcessorTest.kt @@ -27,7 +27,7 @@ class DirectoryProcessorTest { private class Fixture { - var hub: IHub = mock() + var scopes: IScopes = mock() var envelopeReader: IEnvelopeReader = mock() var serializer: ISerializer = mock() var logger: ILogger = mock() @@ -40,7 +40,7 @@ class DirectoryProcessorTest { fun getSut(isRetryable: Boolean = false, isRateLimitingActive: Boolean = false): OutboxSender { val hintCaptor = argumentCaptor() - whenever(hub.captureEvent(any(), hintCaptor.capture())).then { + whenever(scopes.captureEvent(any(), hintCaptor.capture())).then { HintUtils.runIfHasType( hintCaptor.firstValue, Enqueable::class.java @@ -52,7 +52,7 @@ class DirectoryProcessorTest { val rateLimiter = mock { whenever(mock.isActiveForCategory(any())).thenReturn(true) } - whenever(hub.rateLimiter).thenReturn(rateLimiter) + whenever(scopes.rateLimiter).thenReturn(rateLimiter) } } HintUtils.runIfHasType( @@ -62,7 +62,7 @@ class DirectoryProcessorTest { retryable.isRetry = isRetryable } } - return OutboxSender(hub, envelopeReader, serializer, logger, 500, 30) + return OutboxSender(scopes, envelopeReader, serializer, logger, 500, 30) } } @@ -91,7 +91,7 @@ class DirectoryProcessorTest { whenever(fixture.serializer.deserialize(any(), eq(SentryEvent::class.java))).thenReturn(event) fixture.getSut().processDirectory(file) - verify(fixture.hub).captureEvent(any(), argWhere { !HintUtils.hasType(it, ApplyScopeData::class.java) }) + verify(fixture.scopes).captureEvent(any(), argWhere { !HintUtils.hasType(it, ApplyScopeData::class.java) }) } @Test @@ -100,7 +100,7 @@ class DirectoryProcessorTest { dir.mkdirs() assertTrue(dir.exists()) // sanity check fixture.getSut().processDirectory(file) - verify(fixture.hub, never()).captureEnvelope(any(), any()) + verify(fixture.scopes, never()).captureEnvelope(any(), any()) } @Test @@ -121,7 +121,7 @@ class DirectoryProcessorTest { sut.processDirectory(file) // should only capture once - verify(fixture.hub).captureEvent(any(), anyOrNull()) + verify(fixture.scopes).captureEvent(any(), anyOrNull()) } @Test @@ -139,7 +139,7 @@ class DirectoryProcessorTest { sut.processDirectory(file) // should only capture once - verify(fixture.hub).captureEvent(any(), anyOrNull()) + verify(fixture.scopes).captureEvent(any(), anyOrNull()) } private fun getTempEnvelope(fileName: String): String { diff --git a/sentry/src/test/java/io/sentry/EnvelopeSenderTest.kt b/sentry/src/test/java/io/sentry/EnvelopeSenderTest.kt index 6f0ea9cb8a..d63ee81854 100644 --- a/sentry/src/test/java/io/sentry/EnvelopeSenderTest.kt +++ b/sentry/src/test/java/io/sentry/EnvelopeSenderTest.kt @@ -23,7 +23,7 @@ import kotlin.test.assertFalse class EnvelopeSenderTest { private class Fixture { - var hub: IHub? = mock() + var scopes: IScopes? = mock() var logger: ILogger? = mock() var serializer: ISerializer? = mock() var options = SentryOptions().noFlushTimeout() @@ -35,7 +35,7 @@ class EnvelopeSenderTest { fun getSut(): EnvelopeSender { return EnvelopeSender( - hub!!, + scopes!!, serializer!!, logger!!, options.flushTimeoutMillis, @@ -62,7 +62,7 @@ class EnvelopeSenderTest { val sut = fixture.getSut() sut.processDirectory(File("i don't exist")) verify(fixture.logger)!!.log(eq(SentryLevel.WARNING), eq("Directory '%s' doesn't exist. No cached events to send."), any()) - verifyNoMoreInteractions(fixture.hub) + verifyNoMoreInteractions(fixture.scopes) } @Test @@ -72,7 +72,7 @@ class EnvelopeSenderTest { testFile.deleteOnExit() sut.processDirectory(testFile) verify(fixture.logger)!!.log(eq(SentryLevel.ERROR), eq("Cache dir %s is not a directory."), any()) - verifyNoMoreInteractions(fixture.hub) + verifyNoMoreInteractions(fixture.scopes) } @Test @@ -82,11 +82,11 @@ class EnvelopeSenderTest { sut.processDirectory(File(tempDirectory.toUri())) testFile.deleteOnExit() verify(fixture.logger)!!.log(eq(SentryLevel.DEBUG), eq("File '%s' doesn't match extension expected."), any()) - verify(fixture.hub, never())!!.captureEnvelope(any(), anyOrNull()) + verify(fixture.scopes, never())!!.captureEnvelope(any(), anyOrNull()) } @Test - fun `when directory has event files, processDirectory captures with hub`() { + fun `when directory has event files, processDirectory captures with scopes`() { val event = SentryEvent() val envelope = SentryEnvelope.from(fixture.serializer!!, event, null) whenever(fixture.serializer!!.deserializeEnvelope(any())).thenReturn(envelope) @@ -94,7 +94,7 @@ class EnvelopeSenderTest { val testFile = File(Files.createTempFile(tempDirectory, "send-cached-event-test", EnvelopeCache.SUFFIX_ENVELOPE_FILE).toUri()) testFile.deleteOnExit() sut.processDirectory(File(tempDirectory.toUri())) - verify(fixture.hub)!!.captureEnvelope(eq(envelope), any()) + verify(fixture.scopes)!!.captureEnvelope(eq(envelope), any()) } @Test @@ -108,12 +108,12 @@ class EnvelopeSenderTest { val hints = HintUtils.createWithTypeCheckHint(mock()) sut.processFile(testFile, hints) verify(fixture.logger)!!.log(eq(SentryLevel.ERROR), eq(expected), eq("Failed to capture cached envelope %s"), eq(testFile.absolutePath)) - verifyNoMoreInteractions(fixture.hub) + verifyNoMoreInteractions(fixture.scopes) assertFalse(testFile.exists()) } @Test - fun `when hub throws, file gets deleted`() { + fun `when scopes throws, file gets deleted`() { val expected = RuntimeException() whenever(fixture.serializer!!.deserializeEnvelope(any())).doThrow(expected) val sut = fixture.getSut() @@ -121,6 +121,6 @@ class EnvelopeSenderTest { testFile.deleteOnExit() sut.processFile(testFile, Hint()) verify(fixture.logger)!!.log(eq(SentryLevel.ERROR), eq(expected), eq("Failed to capture cached envelope %s"), eq(testFile.absolutePath)) - verifyNoMoreInteractions(fixture.hub) + verifyNoMoreInteractions(fixture.scopes) } } diff --git a/sentry/src/test/java/io/sentry/HubAdapterTest.kt b/sentry/src/test/java/io/sentry/HubAdapterTest.kt index 9686250d20..0e7e1d0f77 100644 --- a/sentry/src/test/java/io/sentry/HubAdapterTest.kt +++ b/sentry/src/test/java/io/sentry/HubAdapterTest.kt @@ -13,11 +13,11 @@ import kotlin.test.Test class HubAdapterTest { - val hub: Hub = mock() + val scopes: IScopes = mock() @BeforeTest fun `set up`() { - Sentry.setCurrentHub(hub) + Sentry.setCurrentScopes(scopes) } @AfterTest @@ -27,7 +27,7 @@ class HubAdapterTest { @Test fun `isEnabled calls Hub`() { HubAdapter.getInstance().isEnabled - verify(hub).isEnabled + verify(scopes).isEnabled } @Test fun `captureEvent calls Hub`() { @@ -35,27 +35,27 @@ class HubAdapterTest { val hint = mock() val scopeCallback = mock() HubAdapter.getInstance().captureEvent(event, hint) - verify(hub).captureEvent(eq(event), eq(hint)) + verify(scopes).captureEvent(eq(event), eq(hint)) HubAdapter.getInstance().captureEvent(event, hint, scopeCallback) - verify(hub).captureEvent(eq(event), eq(hint), eq(scopeCallback)) + verify(scopes).captureEvent(eq(event), eq(hint), eq(scopeCallback)) } @Test fun `captureMessage calls Hub`() { val scopeCallback = mock() val sentryLevel = mock() HubAdapter.getInstance().captureMessage("message", sentryLevel) - verify(hub).captureMessage(eq("message"), eq(sentryLevel)) + verify(scopes).captureMessage(eq("message"), eq(sentryLevel)) HubAdapter.getInstance().captureMessage("message", sentryLevel, scopeCallback) - verify(hub).captureMessage(eq("message"), eq(sentryLevel), eq(scopeCallback)) + verify(scopes).captureMessage(eq("message"), eq(sentryLevel), eq(scopeCallback)) } @Test fun `captureEnvelope calls Hub`() { val envelope = mock() val hint = mock() HubAdapter.getInstance().captureEnvelope(envelope, hint) - verify(hub).captureEnvelope(eq(envelope), eq(hint)) + verify(scopes).captureEnvelope(eq(envelope), eq(hint)) } @Test fun `captureException calls Hub`() { @@ -63,145 +63,145 @@ class HubAdapterTest { val hint = mock() val scopeCallback = mock() HubAdapter.getInstance().captureException(throwable, hint) - verify(hub).captureException(eq(throwable), eq(hint)) + verify(scopes).captureException(eq(throwable), eq(hint)) HubAdapter.getInstance().captureException(throwable, hint, scopeCallback) - verify(hub).captureException(eq(throwable), eq(hint), eq(scopeCallback)) + verify(scopes).captureException(eq(throwable), eq(hint), eq(scopeCallback)) } @Test fun `captureUserFeedback calls Hub`() { val userFeedback = mock() HubAdapter.getInstance().captureUserFeedback(userFeedback) - verify(hub).captureUserFeedback(eq(userFeedback)) + verify(scopes).captureUserFeedback(eq(userFeedback)) } @Test fun `captureCheckIn calls Hub`() { val checkIn = mock() HubAdapter.getInstance().captureCheckIn(checkIn) - verify(hub).captureCheckIn(eq(checkIn)) + verify(scopes).captureCheckIn(eq(checkIn)) } @Test fun `startSession calls Hub`() { HubAdapter.getInstance().startSession() - verify(hub).startSession() + verify(scopes).startSession() } @Test fun `endSession calls Hub`() { HubAdapter.getInstance().endSession() - verify(hub).endSession() + verify(scopes).endSession() } @Test fun `close calls Hub`() { HubAdapter.getInstance().close() - verify(hub).close(false) + verify(scopes).close(false) } @Test fun `close with isRestarting true calls Hub with isRestarting false`() { HubAdapter.getInstance().close(true) - verify(hub).close(false) + verify(scopes).close(false) } @Test fun `close with isRestarting false calls Hub with isRestarting false`() { HubAdapter.getInstance().close(false) - verify(hub).close(false) + verify(scopes).close(false) } @Test fun `addBreadcrumb calls Hub`() { val breadcrumb = mock() val hint = mock() HubAdapter.getInstance().addBreadcrumb(breadcrumb, hint) - verify(hub).addBreadcrumb(eq(breadcrumb), eq(hint)) + verify(scopes).addBreadcrumb(eq(breadcrumb), eq(hint)) } @Test fun `setLevel calls Hub`() { val sentryLevel = mock() HubAdapter.getInstance().setLevel(sentryLevel) - verify(hub).setLevel(eq(sentryLevel)) + verify(scopes).setLevel(eq(sentryLevel)) } @Test fun `setTransaction calls Hub`() { HubAdapter.getInstance().setTransaction("transaction") - verify(hub).setTransaction(eq("transaction")) + verify(scopes).setTransaction(eq("transaction")) } @Test fun `setUser calls Hub`() { val user = mock() HubAdapter.getInstance().setUser(user) - verify(hub).setUser(eq(user)) + verify(scopes).setUser(eq(user)) } @Test fun `setFingerprint calls Hub`() { val fingerprint = ArrayList() HubAdapter.getInstance().setFingerprint(fingerprint) - verify(hub).setFingerprint(eq(fingerprint)) + verify(scopes).setFingerprint(eq(fingerprint)) } @Test fun `clearBreadcrumbs calls Hub`() { HubAdapter.getInstance().clearBreadcrumbs() - verify(hub).clearBreadcrumbs() + verify(scopes).clearBreadcrumbs() } @Test fun `setTag calls Hub`() { HubAdapter.getInstance().setTag("key", "value") - verify(hub).setTag(eq("key"), eq("value")) + verify(scopes).setTag(eq("key"), eq("value")) } @Test fun `removeTag calls Hub`() { HubAdapter.getInstance().removeTag("key") - verify(hub).removeTag(eq("key")) + verify(scopes).removeTag(eq("key")) } @Test fun `setExtra calls Hub`() { HubAdapter.getInstance().setExtra("key", "value") - verify(hub).setExtra(eq("key"), eq("value")) + verify(scopes).setExtra(eq("key"), eq("value")) } @Test fun `removeExtra calls Hub`() { HubAdapter.getInstance().removeExtra("key") - verify(hub).removeExtra(eq("key")) + verify(scopes).removeExtra(eq("key")) } @Test fun `getLastEventId calls Hub`() { HubAdapter.getInstance().lastEventId - verify(hub).lastEventId + verify(scopes).lastEventId } @Test fun `pushScope calls Hub`() { HubAdapter.getInstance().pushScope() - verify(hub).pushScope() + verify(scopes).pushScope() } @Test fun `popScope calls Hub`() { HubAdapter.getInstance().popScope() - verify(hub).popScope() + verify(scopes).popScope() } @Test fun `withScope calls Hub`() { val scopeCallback = mock() HubAdapter.getInstance().withScope(scopeCallback) - verify(hub).withScope(eq(scopeCallback)) + verify(scopes).withScope(eq(scopeCallback)) } @Test fun `configureScope calls Hub`() { val scopeCallback = mock() HubAdapter.getInstance().configureScope(scopeCallback) - verify(hub).configureScope(eq(scopeCallback)) + verify(scopes).configureScope(eq(scopeCallback)) } @Test fun `bindClient calls Hub`() { val client = mock() HubAdapter.getInstance().bindClient(client) - verify(hub).bindClient(eq(client)) + verify(scopes).bindClient(eq(client)) } @Test fun `flush calls Hub`() { HubAdapter.getInstance().flush(1) - verify(hub).flush(eq(1)) + verify(scopes).flush(eq(1)) } @Test fun `clone calls Hub`() { HubAdapter.getInstance().clone() - verify(hub).clone() + verify(scopes).clone() } @Test fun `captureTransaction calls Hub`() { @@ -210,7 +210,7 @@ class HubAdapterTest { val hint = mock() val profilingTraceData = mock() HubAdapter.getInstance().captureTransaction(transaction, traceContext, hint, profilingTraceData) - verify(hub).captureTransaction(eq(transaction), eq(traceContext), eq(hint), eq(profilingTraceData)) + verify(scopes).captureTransaction(eq(transaction), eq(traceContext), eq(hint), eq(profilingTraceData)) } @Test fun `startTransaction calls Hub`() { @@ -218,48 +218,48 @@ class HubAdapterTest { val samplingContext = mock() val transactionOptions = mock() HubAdapter.getInstance().startTransaction(transactionContext) - verify(hub).startTransaction(eq(transactionContext), any()) + verify(scopes).startTransaction(eq(transactionContext), any()) - reset(hub) + reset(scopes) HubAdapter.getInstance().startTransaction(transactionContext, transactionOptions) - verify(hub).startTransaction(eq(transactionContext), eq(transactionOptions)) + verify(scopes).startTransaction(eq(transactionContext), eq(transactionOptions)) } @Test fun `traceHeaders calls Hub`() { HubAdapter.getInstance().traceHeaders() - verify(hub).traceHeaders() + verify(scopes).traceHeaders() } @Test fun `setSpanContext calls Hub`() { val throwable = mock() val span = mock() HubAdapter.getInstance().setSpanContext(throwable, span, "transactionName") - verify(hub).setSpanContext(eq(throwable), eq(span), eq("transactionName")) + verify(scopes).setSpanContext(eq(throwable), eq(span), eq("transactionName")) } @Test fun `getSpan calls Hub`() { HubAdapter.getInstance().span - verify(hub).span + verify(scopes).span } @Test fun `getTransaction calls Hub`() { HubAdapter.getInstance().transaction - verify(hub).transaction + verify(scopes).transaction } @Test fun `getOptions calls Hub`() { HubAdapter.getInstance().options - verify(hub).options + verify(scopes).options } @Test fun `isCrashedLastRun calls Hub`() { HubAdapter.getInstance().isCrashedLastRun - verify(hub).isCrashedLastRun + verify(scopes).isCrashedLastRun } @Test fun `reportFullyDisplayed calls Hub`() { HubAdapter.getInstance().reportFullyDisplayed() - verify(hub).reportFullyDisplayed() + verify(scopes).reportFullyDisplayed() } } diff --git a/sentry/src/test/java/io/sentry/HubTest.kt b/sentry/src/test/java/io/sentry/HubTest.kt index 8fac963e70..f30fd0a966 100644 --- a/sentry/src/test/java/io/sentry/HubTest.kt +++ b/sentry/src/test/java/io/sentry/HubTest.kt @@ -72,7 +72,7 @@ class HubTest { } @Test - fun `when hub is cloned, integrations are not registered`() { + fun `when scopes is cloned, integrations are not registered`() { val integrationMock = mock() val options = SentryOptions() options.cacheDirPath = file.absolutePath @@ -80,36 +80,36 @@ class HubTest { options.setSerializer(mock()) options.addIntegration(integrationMock) // val expected = HubAdapter.getInstance() - val hub = Hub(options) + val scopes = Hub(options) // verify(integrationMock).register(expected, options) - hub.clone() + scopes.clone() verifyNoMoreInteractions(integrationMock) } @Test - fun `when hub is cloned, scope changes are isolated`() { + fun `when scopes is cloned, scope changes are isolated`() { val options = SentryOptions() options.cacheDirPath = file.absolutePath options.dsn = "https://key@sentry.io/proj" options.setSerializer(mock()) - val hub = Hub(options) + val scopes = Hub(options) var firstScope: IScope? = null - hub.configureScope { + scopes.configureScope { firstScope = it - it.setTag("hub", "a") + it.setTag("scopes", "a") } var cloneScope: IScope? = null - val clone = hub.clone() + val clone = scopes.clone() clone.configureScope { cloneScope = it - it.setTag("hub", "b") + it.setTag("scopes", "b") } - assertEquals("a", firstScope!!.tags["hub"]) - assertEquals("b", cloneScope!!.tags["hub"]) + assertEquals("a", firstScope!!.tags["scopes"]) + assertEquals("b", cloneScope!!.tags["scopes"]) } @Test - fun `when hub is initialized, breadcrumbs are capped as per options`() { + fun `when scopes is initialized, breadcrumbs are capped as per options`() { val options = SentryOptions() options.cacheDirPath = file.absolutePath options.maxBreadcrumbs = 5 @@ -288,7 +288,7 @@ class HubTest { } @Test - fun `when captureEvent is called on disabled hub, lastEventId does not get overwritten`() { + fun `when captureEvent is called on disabled scopes, lastEventId does not get overwritten`() { val (sut, mockClient) = getEnabledHub() whenever(mockClient.captureEvent(any(), any(), anyOrNull())).thenReturn(SentryId(UUID.randomUUID())) val event = SentryEvent() @@ -827,14 +827,14 @@ class HubTest { @Test fun `when withScope throws an exception then it should be caught`() { - val (hub, _, logger) = getEnabledHub() + val (scopes, _, logger) = getEnabledHub() val exception = Exception("scope callback exception") val scopeCallback = ScopeCallback { throw exception } - hub.withScope(scopeCallback) + scopes.withScope(scopeCallback) verify(logger).log(eq(SentryLevel.ERROR), any(), eq(exception)) } @@ -864,25 +864,25 @@ class HubTest { @Test fun `when configureScope throws an exception then it should be caught`() { - val (hub, _, logger) = getEnabledHub() + val (scopes, _, logger) = getEnabledHub() val exception = Exception("scope callback exception") val scopeCallback = ScopeCallback { throw exception } - hub.configureScope(scopeCallback) + scopes.configureScope(scopeCallback) verify(logger).log(eq(SentryLevel.ERROR), any(), eq(exception)) } //endregion @Test - fun `when integration is registered, hub is enabled`() { + fun `when integration is registered, scopes is enabled`() { val mock = mock() var options: SentryOptions? = null - // init main hub and make it enabled + // init main scopes and make it enabled Sentry.init { it.addIntegration(mock) it.dsn = "https://key@sentry.io/proj" @@ -892,8 +892,8 @@ class HubTest { } doAnswer { - val hub = it.arguments[0] as IHub - assertTrue(hub.isEnabled) + val scopes = it.arguments[0] as IScopes + assertTrue(scopes.isEnabled) }.whenever(mock).register(any(), eq(options!!)) verify(mock).register(any(), eq(options!!)) @@ -902,26 +902,26 @@ class HubTest { //region setLevel tests @Test fun `when setLevel is called on disabled client, do nothing`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } - hub.close() + scopes.close() - hub.setLevel(SentryLevel.INFO) + scopes.setLevel(SentryLevel.INFO) assertNull(scope?.level) } @Test fun `when setLevel is called, level is set`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } - hub.setLevel(SentryLevel.INFO) + scopes.setLevel(SentryLevel.INFO) assertEquals(SentryLevel.INFO, scope?.level) } //endregion @@ -929,74 +929,74 @@ class HubTest { //region setTransaction tests @Test fun `when setTransaction is called on disabled client, do nothing`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } - hub.close() + scopes.close() - hub.setTransaction("test") + scopes.setTransaction("test") assertNull(scope?.transactionName) } @Test fun `when setTransaction is called, and transaction is not set, transaction name is changed`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } - hub.setTransaction("test") + scopes.setTransaction("test") assertEquals("test", scope?.transactionName) } @Test fun `when setTransaction is called, and transaction is set, transaction name is changed`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } - val tx = hub.startTransaction("test", "op") - hub.configureScope { it.setTransaction(tx) } + val tx = scopes.startTransaction("test", "op") + scopes.configureScope { it.setTransaction(tx) } assertEquals("test", scope?.transactionName) } @Test fun `when startTransaction is called with different instrumenter, no-op is returned`() { - val hub = generateHub() + val scopes = generateHub() val transactionContext = TransactionContext("test", "op").also { it.instrumenter = Instrumenter.OTEL } val transactionOptions = TransactionOptions() - val tx = hub.startTransaction(transactionContext, transactionOptions) + val tx = scopes.startTransaction(transactionContext, transactionOptions) assertTrue(tx is NoOpTransaction) } @Test fun `when startTransaction is called with different instrumenter, no-op is returned 2`() { - val hub = generateHub() { + val scopes = generateHub() { it.instrumenter = Instrumenter.OTEL } - val tx = hub.startTransaction("test", "op") + val tx = scopes.startTransaction("test", "op") assertTrue(tx is NoOpTransaction) } @Test fun `when startTransaction is called with configured instrumenter, it works`() { - val hub = generateHub() { + val scopes = generateHub() { it.instrumenter = Instrumenter.OTEL } val transactionContext = TransactionContext("test", "op").also { it.instrumenter = Instrumenter.OTEL } val transactionOptions = TransactionOptions() - val tx = hub.startTransaction(transactionContext, transactionOptions) + val tx = scopes.startTransaction(transactionContext, transactionOptions) assertFalse(tx is NoOpTransaction) } @@ -1005,27 +1005,27 @@ class HubTest { //region setUser tests @Test fun `when setUser is called on disabled client, do nothing`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } - hub.close() + scopes.close() - hub.setUser(User()) + scopes.setUser(User()) assertNull(scope?.user) } @Test fun `when setUser is called, user is set`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } val user = User() - hub.setUser(user) + scopes.setUser(user) assertEquals(user, scope?.user) } //endregion @@ -1033,40 +1033,40 @@ class HubTest { //region setFingerprint tests @Test fun `when setFingerprint is called on disabled client, do nothing`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } - hub.close() + scopes.close() val fingerprint = listOf("abc") - hub.setFingerprint(fingerprint) + scopes.setFingerprint(fingerprint) assertEquals(0, scope?.fingerprint?.count()) } @Test fun `when setFingerprint is called with null parameter, do nothing`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } - hub.callMethod("setFingerprint", List::class.java, null) + scopes.callMethod("setFingerprint", List::class.java, null) assertEquals(0, scope?.fingerprint?.count()) } @Test fun `when setFingerprint is called, fingerprint is set`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } val fingerprint = listOf("abc") - hub.setFingerprint(fingerprint) + scopes.setFingerprint(fingerprint) assertEquals(1, scope?.fingerprint?.count()) } //endregion @@ -1074,30 +1074,30 @@ class HubTest { //region clearBreadcrumbs tests @Test fun `when clearBreadcrumbs is called on disabled client, do nothing`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } - hub.addBreadcrumb(Breadcrumb()) + scopes.addBreadcrumb(Breadcrumb()) assertEquals(1, scope?.breadcrumbs?.count()) - hub.close() + scopes.close() assertEquals(0, scope?.breadcrumbs?.count()) } @Test fun `when clearBreadcrumbs is called, clear breadcrumbs`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } - hub.addBreadcrumb(Breadcrumb()) + scopes.addBreadcrumb(Breadcrumb()) assertEquals(1, scope?.breadcrumbs?.count()) - hub.clearBreadcrumbs() + scopes.clearBreadcrumbs() assertEquals(0, scope?.breadcrumbs?.count()) } //endregion @@ -1105,38 +1105,38 @@ class HubTest { //region setTag tests @Test fun `when setTag is called on disabled client, do nothing`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } - hub.close() + scopes.close() - hub.setTag("test", "test") + scopes.setTag("test", "test") assertEquals(0, scope?.tags?.count()) } @Test fun `when setTag is called with null parameters, do nothing`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } - hub.callMethod("setTag", parameterTypes = arrayOf(String::class.java, String::class.java), null, null) + scopes.callMethod("setTag", parameterTypes = arrayOf(String::class.java, String::class.java), null, null) assertEquals(0, scope?.tags?.count()) } @Test fun `when setTag is called, tag is set`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } - hub.setTag("test", "test") + scopes.setTag("test", "test") assertEquals(1, scope?.tags?.count()) } //endregion @@ -1144,38 +1144,38 @@ class HubTest { //region setExtra tests @Test fun `when setExtra is called on disabled client, do nothing`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } - hub.close() + scopes.close() - hub.setExtra("test", "test") + scopes.setExtra("test", "test") assertEquals(0, scope?.extras?.count()) } @Test fun `when setExtra is called with null parameters, do nothing`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } - hub.callMethod("setExtra", parameterTypes = arrayOf(String::class.java, String::class.java), null, null) + scopes.callMethod("setExtra", parameterTypes = arrayOf(String::class.java, String::class.java), null, null) assertEquals(0, scope?.extras?.count()) } @Test fun `when setExtra is called, extra is set`() { - val hub = generateHub() + val scopes = generateHub() var scope: IScope? = null - hub.configureScope { + scopes.configureScope { scope = it } - hub.setExtra("test", "test") + scopes.setExtra("test", "test") assertEquals(1, scope?.extras?.count()) } //endregion @@ -1488,19 +1488,19 @@ class HubTest { val mockTransactionProfiler = mock() val mockClient = mock() whenever(mockTransactionProfiler.onTransactionFinish(any(), anyOrNull(), anyOrNull())).thenAnswer { mockClient.captureEnvelope(mock()) } - val hub = generateHub { + val scopes = generateHub { it.setTransactionProfiler(mockTransactionProfiler) } - hub.bindClient(mockClient) + scopes.bindClient(mockClient) // Transaction is not sampled, so it should not be profiled val contexts = TransactionContext("name", "op", TracesSamplingDecision(false, null, true, null)) - val transaction = hub.startTransaction(contexts) + val transaction = scopes.startTransaction(contexts) transaction.finish() verify(mockClient, never()).captureEnvelope(any()) // Transaction is sampled, so it should be profiled val sampledContexts = TransactionContext("name", "op", TracesSamplingDecision(true, null, true, null)) - val sampledTransaction = hub.startTransaction(sampledContexts) + val sampledTransaction = scopes.startTransaction(sampledContexts) sampledTransaction.finish() verify(mockClient).captureEnvelope(any()) } @@ -1510,13 +1510,13 @@ class HubTest { val mockTransactionProfiler = mock() val mockClient = mock() whenever(mockTransactionProfiler.onTransactionFinish(any(), anyOrNull(), anyOrNull())).thenAnswer { mockClient.captureEnvelope(mock()) } - val hub = generateHub { + val scopes = generateHub { it.profilesSampleRate = 0.0 it.setTransactionProfiler(mockTransactionProfiler) } - hub.bindClient(mockClient) + scopes.bindClient(mockClient) val contexts = TransactionContext("name", "op") - val transaction = hub.startTransaction(contexts) + val transaction = scopes.startTransaction(contexts) transaction.finish() verify(mockClient, never()).captureEnvelope(any()) } @@ -1525,12 +1525,12 @@ class HubTest { fun `when profiler is running and isAppStartTransaction is false, startTransaction does not interact with profiler`() { val mockTransactionProfiler = mock() whenever(mockTransactionProfiler.isRunning).thenReturn(true) - val hub = generateHub { + val scopes = generateHub { it.profilesSampleRate = 1.0 it.setTransactionProfiler(mockTransactionProfiler) } val context = TransactionContext("name", "op") - hub.startTransaction(context, TransactionOptions().apply { isAppStartTransaction = false }) + scopes.startTransaction(context, TransactionOptions().apply { isAppStartTransaction = false }) verify(mockTransactionProfiler, never()).start() verify(mockTransactionProfiler, never()).bindTransaction(any()) } @@ -1539,12 +1539,12 @@ class HubTest { fun `when profiler is running and isAppStartTransaction is true, startTransaction binds current profile`() { val mockTransactionProfiler = mock() whenever(mockTransactionProfiler.isRunning).thenReturn(true) - val hub = generateHub { + val scopes = generateHub { it.profilesSampleRate = 1.0 it.setTransactionProfiler(mockTransactionProfiler) } val context = TransactionContext("name", "op") - val transaction = hub.startTransaction(context, TransactionOptions().apply { isAppStartTransaction = true }) + val transaction = scopes.startTransaction(context, TransactionOptions().apply { isAppStartTransaction = true }) verify(mockTransactionProfiler, never()).start() verify(mockTransactionProfiler).bindTransaction(eq(transaction)) } @@ -1553,12 +1553,12 @@ class HubTest { fun `when profiler is not running, startTransaction starts and binds current profile`() { val mockTransactionProfiler = mock() whenever(mockTransactionProfiler.isRunning).thenReturn(false) - val hub = generateHub { + val scopes = generateHub { it.profilesSampleRate = 1.0 it.setTransactionProfiler(mockTransactionProfiler) } val context = TransactionContext("name", "op") - val transaction = hub.startTransaction(context, TransactionOptions().apply { isAppStartTransaction = false }) + val transaction = scopes.startTransaction(context, TransactionOptions().apply { isAppStartTransaction = false }) verify(mockTransactionProfiler).start() verify(mockTransactionProfiler).bindTransaction(eq(transaction)) } @@ -1567,75 +1567,75 @@ class HubTest { //region startTransaction tests @Test fun `when startTransaction, creates transaction`() { - val hub = generateHub() + val scopes = generateHub() val contexts = TransactionContext("name", "op") - val transaction = hub.startTransaction(contexts) + val transaction = scopes.startTransaction(contexts) assertTrue(transaction is SentryTracer) assertEquals(contexts, transaction.root.spanContext) } @Test fun `when startTransaction with bindToScope set to false, transaction is not attached to the scope`() { - val hub = generateHub() + val scopes = generateHub() - hub.startTransaction("name", "op", TransactionOptions()) + scopes.startTransaction("name", "op", TransactionOptions()) - hub.configureScope { + scopes.configureScope { assertNull(it.span) } } @Test fun `when startTransaction without bindToScope set, transaction is not attached to the scope`() { - val hub = generateHub() + val scopes = generateHub() - hub.startTransaction("name", "op") + scopes.startTransaction("name", "op") - hub.configureScope { + scopes.configureScope { assertNull(it.span) } } @Test fun `when startTransaction with bindToScope set to true, transaction is attached to the scope`() { - val hub = generateHub() + val scopes = generateHub() - val transaction = hub.startTransaction("name", "op", TransactionOptions().also { it.isBindToScope = true }) + val transaction = scopes.startTransaction("name", "op", TransactionOptions().also { it.isBindToScope = true }) - hub.configureScope { + scopes.configureScope { assertEquals(transaction, it.span) } } @Test fun `when startTransaction and no tracing sampling is configured, event is not sampled`() { - val hub = generateHub { + val scopes = generateHub { it.tracesSampleRate = 0.0 } - val transaction = hub.startTransaction("name", "op") + val transaction = scopes.startTransaction("name", "op") assertFalse(transaction.isSampled!!) } @Test fun `when startTransaction and no profile sampling is configured, profile is not sampled`() { - val hub = generateHub { + val scopes = generateHub { it.tracesSampleRate = 1.0 it.profilesSampleRate = 0.0 } - val transaction = hub.startTransaction("name", "op") + val transaction = scopes.startTransaction("name", "op") assertTrue(transaction.isSampled!!) assertFalse(transaction.isProfileSampled!!) } @Test fun `when startTransaction with parent sampled and no traces sampler provided, transaction inherits sampling decision`() { - val hub = generateHub() + val scopes = generateHub() val transactionContext = TransactionContext("name", "op") transactionContext.parentSampled = true - val transaction = hub.startTransaction(transactionContext) + val transaction = scopes.startTransaction(transactionContext) assertNotNull(transaction) assertNotNull(transaction.isSampled) assertTrue(transaction.isSampled!!) @@ -1643,10 +1643,10 @@ class HubTest { @Test fun `when startTransaction with parent profile sampled and no profile sampler provided, transaction inherits profile sampling decision`() { - val hub = generateHub() + val scopes = generateHub() val transactionContext = TransactionContext("name", "op") transactionContext.setParentSampled(true, true) - val transaction = hub.startTransaction(transactionContext) + val transaction = scopes.startTransaction(transactionContext) assertTrue(transaction.isProfileSampled!!) } @@ -1717,11 +1717,11 @@ class HubTest { @Test fun `when tracesSampleRate and tracesSampler are not set on SentryOptions, startTransaction returns NoOp`() { - val hub = generateHub { + val scopes = generateHub { it.tracesSampleRate = null it.tracesSampler = null } - val transaction = hub.startTransaction(TransactionContext("name", "op", TracesSamplingDecision(true))) + val transaction = scopes.startTransaction(TransactionContext("name", "op", TracesSamplingDecision(true))) assertTrue(transaction is NoOpTransaction) } //endregion @@ -1729,81 +1729,81 @@ class HubTest { //region startTransaction tests @Test fun `when traceHeaders and no transaction is active, traceHeaders are generated from scope`() { - val hub = generateHub() + val scopes = generateHub() var spanId: SpanId? = null - hub.configureScope { spanId = it.propagationContext.spanId } + scopes.configureScope { spanId = it.propagationContext.spanId } - val traceHeader = hub.traceHeaders() + val traceHeader = scopes.traceHeaders() assertNotNull(traceHeader) assertEquals(spanId, traceHeader.spanId) } @Test fun `when traceHeaders and there is an active transaction, traceHeaders are not null`() { - val hub = generateHub() - val tx = hub.startTransaction("aTransaction", "op") - hub.configureScope { it.setTransaction(tx) } + val scopes = generateHub() + val tx = scopes.startTransaction("aTransaction", "op") + scopes.configureScope { it.setTransaction(tx) } - assertNotNull(hub.traceHeaders()) + assertNotNull(scopes.traceHeaders()) } //endregion //region getSpan tests @Test fun `when there is no active transaction, getSpan returns null`() { - val hub = generateHub() - assertNull(hub.span) + val scopes = generateHub() + assertNull(scopes.span) } @Test fun `when there is no active transaction, getTransaction returns null`() { - val hub = generateHub() - assertNull(hub.transaction) + val scopes = generateHub() + assertNull(scopes.transaction) } @Test fun `when there is active transaction bound to the scope, getTransaction and getSpan return active transaction`() { - val hub = generateHub() - val tx = hub.startTransaction("aTransaction", "op") - hub.configureScope { it.transaction = tx } + val scopes = generateHub() + val tx = scopes.startTransaction("aTransaction", "op") + scopes.configureScope { it.transaction = tx } - assertEquals(tx, hub.transaction) - assertEquals(tx, hub.span) + assertEquals(tx, scopes.transaction) + assertEquals(tx, scopes.span) } @Test - fun `when there is a transaction but the hub is closed, getTransaction returns null`() { - val hub = generateHub() - hub.startTransaction("name", "op") - hub.close() + fun `when there is a transaction but the scopes is closed, getTransaction returns null`() { + val scopes = generateHub() + scopes.startTransaction("name", "op") + scopes.close() - assertNull(hub.transaction) + assertNull(scopes.transaction) } @Test fun `when there is active span within a transaction bound to the scope, getSpan returns active span`() { - val hub = generateHub() - val tx = hub.startTransaction("aTransaction", "op") - hub.configureScope { it.setTransaction(tx) } - hub.configureScope { it.setTransaction(tx) } + val scopes = generateHub() + val tx = scopes.startTransaction("aTransaction", "op") + scopes.configureScope { it.setTransaction(tx) } + scopes.configureScope { it.setTransaction(tx) } val span = tx.startChild("op") - assertEquals(tx, hub.transaction) - assertEquals(span, hub.span) + assertEquals(tx, scopes.transaction) + assertEquals(span, scopes.span) } // endregion //region setSpanContext @Test fun `associates span context with throwable`() { - val (hub, mockClient) = getEnabledHub() - val transaction = hub.startTransaction("aTransaction", "op") + val (scopes, mockClient) = getEnabledHub() + val transaction = scopes.startTransaction("aTransaction", "op") val span = transaction.startChild("op") val exception = RuntimeException() - hub.setSpanContext(exception, span, "tx-name") - hub.captureEvent(SentryEvent(exception)) + scopes.setSpanContext(exception, span, "tx-name") + scopes.captureEvent(SentryEvent(exception)) verify(mockClient).captureEvent( check { @@ -1816,8 +1816,8 @@ class HubTest { @Test fun `returns null when no span context associated with throwable`() { - val hub = generateHub() as Hub - assertNull(hub.getSpanContext(RuntimeException())) + val scopes = generateHub() as Hub + assertNull(scopes.getSpanContext(RuntimeException())) } // endregion @@ -1826,9 +1826,9 @@ class HubTest { val nativeMarker = File(hashedFolder(), EnvelopeCache.NATIVE_CRASH_MARKER_FILE) nativeMarker.mkdirs() nativeMarker.createNewFile() - val hub = generateHub() as Hub + val scopes = generateHub() as Hub - assertTrue(hub.isCrashedLastRun!!) + assertTrue(scopes.isCrashedLastRun!!) assertTrue(nativeMarker.exists()) } @@ -1837,69 +1837,69 @@ class HubTest { val nativeMarker = File(hashedFolder(), EnvelopeCache.NATIVE_CRASH_MARKER_FILE) nativeMarker.mkdirs() nativeMarker.createNewFile() - val hub = generateHub { + val scopes = generateHub { it.isEnableAutoSessionTracking = false } - assertTrue(hub.isCrashedLastRun!!) + assertTrue(scopes.isCrashedLastRun!!) assertFalse(nativeMarker.exists()) } @Test fun `reportFullyDisplayed is ignored if TimeToFullDisplayTracing is disabled`() { var called = false - val hub = generateHub { + val scopes = generateHub { it.fullyDisplayedReporter.registerFullyDrawnListener { called = !called } } - hub.reportFullyDisplayed() + scopes.reportFullyDisplayed() assertFalse(called) } @Test fun `reportFullyDisplayed calls FullyDisplayedReporter if TimeToFullDisplayTracing is enabled`() { var called = false - val hub = generateHub { + val scopes = generateHub { it.isEnableTimeToFullDisplayTracing = true it.fullyDisplayedReporter.registerFullyDrawnListener { called = !called } } - hub.reportFullyDisplayed() + scopes.reportFullyDisplayed() assertTrue(called) } @Test fun `reportFullyDisplayed calls FullyDisplayedReporter only once`() { var called = false - val hub = generateHub { + val scopes = generateHub { it.isEnableTimeToFullDisplayTracing = true it.fullyDisplayedReporter.registerFullyDrawnListener { called = !called } } - hub.reportFullyDisplayed() + scopes.reportFullyDisplayed() assertTrue(called) - hub.reportFullyDisplayed() + scopes.reportFullyDisplayed() assertTrue(called) } @Test fun `reportFullDisplayed calls reportFullyDisplayed`() { - val hub = spy(generateHub()) - hub.reportFullDisplayed() - verify(hub).reportFullyDisplayed() + val scopes = spy(generateHub()) + scopes.reportFullDisplayed() + verify(scopes).reportFullyDisplayed() } @Test fun `continueTrace creates propagation context from headers and returns transaction context if performance enabled`() { - val hub = generateHub() + val scopes = generateHub() val traceId = SentryId() val parentSpanId = SpanId() - val transactionContext = hub.continueTrace("$traceId-$parentSpanId-1", listOf("sentry-public_key=502f25099c204a2fbf4cb16edc5975d1,sentry-sample_rate=1,sentry-trace_id=$traceId,sentry-transaction=HTTP%20GET")) + val transactionContext = scopes.continueTrace("$traceId-$parentSpanId-1", listOf("sentry-public_key=502f25099c204a2fbf4cb16edc5975d1,sentry-sample_rate=1,sentry-trace_id=$traceId,sentry-transaction=HTTP%20GET")) - hub.configureScope { scope -> + scopes.configureScope { scope -> assertEquals(traceId, scope.propagationContext.traceId) assertEquals(parentSpanId, scope.propagationContext.parentSpanId) } @@ -1910,16 +1910,16 @@ class HubTest { @Test fun `continueTrace creates new propagation context if header invalid and returns transaction context if performance enabled`() { - val hub = generateHub() + val scopes = generateHub() val traceId = SentryId() var propagationContextHolder = AtomicReference() - hub.configureScope { propagationContextHolder.set(it.propagationContext) } + scopes.configureScope { propagationContextHolder.set(it.propagationContext) } val propagationContextAtStart = propagationContextHolder.get()!! - val transactionContext = hub.continueTrace("invalid", listOf("sentry-public_key=502f25099c204a2fbf4cb16edc5975d1,sentry-sample_rate=1,sentry-trace_id=$traceId,sentry-transaction=HTTP%20GET")) + val transactionContext = scopes.continueTrace("invalid", listOf("sentry-public_key=502f25099c204a2fbf4cb16edc5975d1,sentry-sample_rate=1,sentry-trace_id=$traceId,sentry-transaction=HTTP%20GET")) - hub.configureScope { scope -> + scopes.configureScope { scope -> assertNotEquals(propagationContextAtStart.traceId, scope.propagationContext.traceId) assertNotEquals(propagationContextAtStart.parentSpanId, scope.propagationContext.parentSpanId) assertNotEquals(propagationContextAtStart.spanId, scope.propagationContext.spanId) @@ -1932,12 +1932,12 @@ class HubTest { @Test fun `continueTrace creates propagation context from headers and returns null if performance disabled`() { - val hub = generateHub { it.enableTracing = false } + val scopes = generateHub { it.enableTracing = false } val traceId = SentryId() val parentSpanId = SpanId() - val transactionContext = hub.continueTrace("$traceId-$parentSpanId-1", listOf("sentry-public_key=502f25099c204a2fbf4cb16edc5975d1,sentry-sample_rate=1,sentry-trace_id=$traceId,sentry-transaction=HTTP%20GET")) + val transactionContext = scopes.continueTrace("$traceId-$parentSpanId-1", listOf("sentry-public_key=502f25099c204a2fbf4cb16edc5975d1,sentry-sample_rate=1,sentry-trace_id=$traceId,sentry-transaction=HTTP%20GET")) - hub.configureScope { scope -> + scopes.configureScope { scope -> assertEquals(traceId, scope.propagationContext.traceId) assertEquals(parentSpanId, scope.propagationContext.parentSpanId) } @@ -1947,16 +1947,16 @@ class HubTest { @Test fun `continueTrace creates new propagation context if header invalid and returns null if performance disabled`() { - val hub = generateHub { it.enableTracing = false } + val scopes = generateHub { it.enableTracing = false } val traceId = SentryId() var propagationContextHolder = AtomicReference() - hub.configureScope { propagationContextHolder.set(it.propagationContext) } + scopes.configureScope { propagationContextHolder.set(it.propagationContext) } val propagationContextAtStart = propagationContextHolder.get()!! - val transactionContext = hub.continueTrace("invalid", listOf("sentry-public_key=502f25099c204a2fbf4cb16edc5975d1,sentry-sample_rate=1,sentry-trace_id=$traceId,sentry-transaction=HTTP%20GET")) + val transactionContext = scopes.continueTrace("invalid", listOf("sentry-public_key=502f25099c204a2fbf4cb16edc5975d1,sentry-sample_rate=1,sentry-trace_id=$traceId,sentry-transaction=HTTP%20GET")) - hub.configureScope { scope -> + scopes.configureScope { scope -> assertNotEquals(propagationContextAtStart.traceId, scope.propagationContext.traceId) assertNotEquals(propagationContextAtStart.parentSpanId, scope.propagationContext.parentSpanId) assertNotEquals(propagationContextAtStart.spanId, scope.propagationContext.spanId) @@ -1966,32 +1966,32 @@ class HubTest { } @Test - fun `hub provides no tags for metrics, if metric option is disabled`() { - val hub = generateHub { + fun `scopes provides no tags for metrics, if metric option is disabled`() { + val scopes = generateHub { it.isEnableMetrics = false it.isEnableDefaultTagsForMetrics = true } as Hub assertTrue( - hub.defaultTagsForMetrics.isEmpty() + scopes.defaultTagsForMetrics.isEmpty() ) } @Test - fun `hub provides no tags for metrics, if default tags option is disabled`() { - val hub = generateHub { + fun `scopes provides no tags for metrics, if default tags option is disabled`() { + val scopes = generateHub { it.isEnableMetrics = true it.isEnableDefaultTagsForMetrics = false } as Hub assertTrue( - hub.defaultTagsForMetrics.isEmpty() + scopes.defaultTagsForMetrics.isEmpty() ) } @Test - fun `hub provides minimum default tags for metrics, if nothing is set up`() { - val hub = generateHub { + fun `scopes provides minimum default tags for metrics, if nothing is set up`() { + val scopes = generateHub { it.isEnableMetrics = true it.isEnableDefaultTagsForMetrics = true } as Hub @@ -2000,19 +2000,19 @@ class HubTest { mapOf( "environment" to "production" ), - hub.defaultTagsForMetrics + scopes.defaultTagsForMetrics ) } @Test - fun `hub provides default tags for metrics, based on options and running transaction`() { - val hub = generateHub { + fun `scopes provides default tags for metrics, based on options and running transaction`() { + val scopes = generateHub { it.isEnableMetrics = true it.isEnableDefaultTagsForMetrics = true it.environment = "test" it.release = "1.0" } as Hub - hub.startTransaction( + scopes.startTransaction( "name", "op", TransactionOptions().apply { isBindToScope = true } @@ -2024,72 +2024,72 @@ class HubTest { "release" to "1.0", "transaction" to "name" ), - hub.defaultTagsForMetrics + scopes.defaultTagsForMetrics ) } @Test - fun `hub provides no local metric aggregator if metrics feature is disabled`() { - val hub = generateHub { + fun `scopes provides no local metric aggregator if metrics feature is disabled`() { + val scopes = generateHub { it.isEnableMetrics = false it.isEnableSpanLocalMetricAggregation = true } as Hub - hub.startTransaction( + scopes.startTransaction( "name", "op", TransactionOptions().apply { isBindToScope = true } ) - assertNull(hub.localMetricsAggregator) + assertNull(scopes.localMetricsAggregator) } @Test - fun `hub provides no local metric aggregator if local aggregation feature is disabled`() { - val hub = generateHub { + fun `scopes provides no local metric aggregator if local aggregation feature is disabled`() { + val scopes = generateHub { it.isEnableMetrics = true it.isEnableSpanLocalMetricAggregation = false } as Hub - hub.startTransaction( + scopes.startTransaction( "name", "op", TransactionOptions().apply { isBindToScope = true } ) - assertNull(hub.localMetricsAggregator) + assertNull(scopes.localMetricsAggregator) } @Test - fun `hub provides local metric aggregator if feature is enabled`() { - val hub = generateHub { + fun `scopes provides local metric aggregator if feature is enabled`() { + val scopes = generateHub { it.isEnableMetrics = true it.isEnableSpanLocalMetricAggregation = true } as Hub - hub.startTransaction( + scopes.startTransaction( "name", "op", TransactionOptions().apply { isBindToScope = true } ) - assertNotNull(hub.localMetricsAggregator) + assertNotNull(scopes.localMetricsAggregator) } @Test - fun `hub startSpanForMetric starts a child span`() { - val hub = generateHub { + fun `scopes startSpanForMetric starts a child span`() { + val scopes = generateHub { it.isEnableMetrics = true it.isEnableSpanLocalMetricAggregation = true it.sampleRate = 1.0 } as Hub - val txn = hub.startTransaction( + val txn = scopes.startTransaction( "name.txn", "op.txn", TransactionOptions().apply { isBindToScope = true } ) - val span = hub.startSpanForMetric("op", "key")!! + val span = scopes.startSpanForMetric("op", "key")!! assertEquals("op", span.spanContext.op) assertEquals("key", span.spanContext.description) @@ -2098,7 +2098,7 @@ class HubTest { private val dsnTest = "https://key@sentry.io/proj" - private fun generateHub(optionsConfiguration: Sentry.OptionsConfiguration? = null): IHub { + private fun generateHub(optionsConfiguration: Sentry.OptionsConfiguration? = null): IScopes { val options = SentryOptions().apply { dsn = dsnTest cacheDirPath = file.absolutePath diff --git a/sentry/src/test/java/io/sentry/JsonSerializerTest.kt b/sentry/src/test/java/io/sentry/JsonSerializerTest.kt index 8dc4f804bc..bd3a3c2cff 100644 --- a/sentry/src/test/java/io/sentry/JsonSerializerTest.kt +++ b/sentry/src/test/java/io/sentry/JsonSerializerTest.kt @@ -43,7 +43,7 @@ class JsonSerializerTest { private class Fixture { val logger: ILogger = mock() val serializer: ISerializer - val hub = mock() + val scopes = mock() val traceFile = Files.createTempFile("test", "here").toFile() val options = SentryOptions() @@ -51,7 +51,7 @@ class JsonSerializerTest { options.dsn = "https://key@sentry.io/proj" options.setLogger(logger) options.isDebug = true - whenever(hub.options).thenReturn(options) + whenever(scopes.options).thenReturn(options) serializer = JsonSerializer(options) options.setSerializer(serializer) options.setEnvelopeReader(EnvelopeReader(serializer)) @@ -830,7 +830,7 @@ class JsonSerializerTest { trace.status = SpanStatus.OK trace.setTag("myTag", "myValue") trace.sampled = true - val tracer = SentryTracer(trace, fixture.hub) + val tracer = SentryTracer(trace, fixture.scopes) tracer.setData("dataKey", "dataValue") val span = tracer.startChild("child") span.finish(SpanStatus.OK) @@ -1300,7 +1300,7 @@ class JsonSerializerTest { status = SpanStatus.OK setTag("myTag", "myValue") } - val tracer = SentryTracer(trace, fixture.hub) + val tracer = SentryTracer(trace, fixture.scopes) val span = tracer.startChild("child") span.setMeasurement("test_measurement", 1, MeasurementUnit.Custom("test")) span.finish(SpanStatus.OK) diff --git a/sentry/src/test/java/io/sentry/MainEventProcessorTest.kt b/sentry/src/test/java/io/sentry/MainEventProcessorTest.kt index ec932ebc86..682626f08c 100644 --- a/sentry/src/test/java/io/sentry/MainEventProcessorTest.kt +++ b/sentry/src/test/java/io/sentry/MainEventProcessorTest.kt @@ -33,7 +33,7 @@ class MainEventProcessorTest { dist = "dist" sdkVersion = SdkVersion("test", "1.2.3") } - val hub = mock() + val scopes = mock() val getLocalhost = mock() lateinit var sentryTracer: SentryTracer private val hostnameCacheMock = Mockito.mockStatic(HostnameCache::class.java) @@ -72,8 +72,8 @@ class MainEventProcessorTest { } host } - whenever(hub.options).thenReturn(sentryOptions) - sentryTracer = SentryTracer(TransactionContext("", ""), hub) + whenever(scopes.options).thenReturn(sentryOptions) + sentryTracer = SentryTracer(TransactionContext("", ""), scopes) val hostnameCache = HostnameCache(hostnameCacheDuration) { getLocalhost } hostnameCacheMock.`when` { HostnameCache.getInstance() }.thenReturn(hostnameCache) diff --git a/sentry/src/test/java/io/sentry/OutboxSenderTest.kt b/sentry/src/test/java/io/sentry/OutboxSenderTest.kt index ab50e054d0..9274ed4400 100644 --- a/sentry/src/test/java/io/sentry/OutboxSenderTest.kt +++ b/sentry/src/test/java/io/sentry/OutboxSenderTest.kt @@ -30,7 +30,7 @@ class OutboxSenderTest { private class Fixture { val options = mock() - val hub = mock() + val scopes = mock() var envelopeReader = mock() val serializer = mock() val logger = mock() @@ -39,11 +39,11 @@ class OutboxSenderTest { whenever(options.dsn).thenReturn("https://key@sentry.io/proj") whenever(options.dateProvider).thenReturn(SentryNanotimeDateProvider()) whenever(options.mainThreadChecker).thenReturn(NoOpMainThreadChecker.getInstance()) - whenever(hub.options).thenReturn(this.options) + whenever(scopes.options).thenReturn(this.options) } fun getSut(): OutboxSender { - return OutboxSender(hub, envelopeReader, serializer, logger, 15000, 30) + return OutboxSender(scopes, envelopeReader, serializer, logger, 15000, 30) } } @@ -83,7 +83,7 @@ class OutboxSenderTest { val hints = HintUtils.createWithTypeCheckHint(mock()) sut.processEnvelopeFile(path, hints) - verify(fixture.hub).captureEvent(eq(expected), any()) + verify(fixture.scopes).captureEvent(eq(expected), any()) assertFalse(File(path).exists()) // Additionally make sure we have no errors logged verify(fixture.logger, never()).log(eq(SentryLevel.ERROR), any(), any()) @@ -94,7 +94,7 @@ class OutboxSenderTest { fun `when parser is EnvelopeReader and serializer return SentryTransaction, transaction captured, transactions sampled, file is deleted`() { fixture.envelopeReader = EnvelopeReader(JsonSerializer(fixture.options)) whenever(fixture.options.maxSpans).thenReturn(1000) - whenever(fixture.hub.options).thenReturn(fixture.options) + whenever(fixture.scopes.options).thenReturn(fixture.options) whenever(fixture.options.transactionProfiler).thenReturn(NoOpTransactionProfiler.getInstance()) val transactionContext = TransactionContext("fixture-name", "http") @@ -102,7 +102,7 @@ class OutboxSenderTest { transactionContext.status = SpanStatus.OK transactionContext.setTag("fixture-tag", "fixture-value") - val sentryTracer = SentryTracer(transactionContext, fixture.hub) + val sentryTracer = SentryTracer(transactionContext, fixture.scopes) val span = sentryTracer.startChild("child") span.finish(SpanStatus.OK) sentryTracer.finish() @@ -120,7 +120,7 @@ class OutboxSenderTest { val hints = HintUtils.createWithTypeCheckHint(mock()) sut.processEnvelopeFile(path, hints) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertEquals(expected, it) assertTrue(it.isSampled) @@ -139,7 +139,7 @@ class OutboxSenderTest { fun `restores sampleRate`() { fixture.envelopeReader = EnvelopeReader(JsonSerializer(fixture.options)) whenever(fixture.options.maxSpans).thenReturn(1000) - whenever(fixture.hub.options).thenReturn(fixture.options) + whenever(fixture.scopes.options).thenReturn(fixture.options) whenever(fixture.options.transactionProfiler).thenReturn(NoOpTransactionProfiler.getInstance()) val transactionContext = TransactionContext("fixture-name", "http") @@ -148,7 +148,7 @@ class OutboxSenderTest { transactionContext.setTag("fixture-tag", "fixture-value") transactionContext.samplingDecision = TracesSamplingDecision(true, 0.00000021) - val sentryTracer = SentryTracer(transactionContext, fixture.hub) + val sentryTracer = SentryTracer(transactionContext, fixture.scopes) val span = sentryTracer.startChild("child") span.finish(SpanStatus.OK) sentryTracer.finish() @@ -166,7 +166,7 @@ class OutboxSenderTest { val hints = HintUtils.createWithTypeCheckHint(mock()) sut.processEnvelopeFile(path, hints) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertEquals(expected, it) assertTrue(it.isSampled) @@ -207,7 +207,7 @@ class OutboxSenderTest { val hints = HintUtils.createWithTypeCheckHint(mock()) sut.processEnvelopeFile(path, hints) - verify(fixture.hub).captureEvent(any(), any()) + verify(fixture.scopes).captureEvent(any(), any()) assertFalse(File(path).exists()) // Additionally make sure we have no errors logged verify(fixture.logger, never()).log(eq(SentryLevel.ERROR), any(), any()) @@ -225,7 +225,7 @@ class OutboxSenderTest { val hints = HintUtils.createWithTypeCheckHint(mock()) sut.processEnvelopeFile(path, hints) - verify(fixture.hub).captureEnvelope(any(), any()) + verify(fixture.scopes).captureEnvelope(any(), any()) assertFalse(File(path).exists()) // Additionally make sure we have no errors logged verify(fixture.logger, never()).log(eq(SentryLevel.ERROR), any(), any()) @@ -245,7 +245,7 @@ class OutboxSenderTest { // Additionally make sure we have no errors logged verify(fixture.logger).log(eq(SentryLevel.ERROR), any(), any()) - verify(fixture.hub, never()).captureEvent(any()) + verify(fixture.scopes, never()).captureEvent(any()) assertFalse(File(path).exists()) } @@ -263,7 +263,7 @@ class OutboxSenderTest { // Additionally make sure we have no errors logged verify(fixture.logger).log(eq(SentryLevel.ERROR), any(), any()) - verify(fixture.hub, never()).captureEvent(any()) + verify(fixture.scopes, never()).captureEvent(any()) assertFalse(File(path).exists()) } diff --git a/sentry/src/test/java/io/sentry/PreviousSessionFinalizerTest.kt b/sentry/src/test/java/io/sentry/PreviousSessionFinalizerTest.kt index 239e90905e..87aa5e6715 100644 --- a/sentry/src/test/java/io/sentry/PreviousSessionFinalizerTest.kt +++ b/sentry/src/test/java/io/sentry/PreviousSessionFinalizerTest.kt @@ -21,7 +21,7 @@ class PreviousSessionFinalizerTest { class Fixture { val options = SentryOptions() - val hub = mock() + val scopes = mock() val logger = mock() lateinit var sessionFile: File @@ -61,7 +61,7 @@ class PreviousSessionFinalizerTest { nativeCrashMarker.writeText(nativeCrashTimestamp.toString()) } } - return PreviousSessionFinalizer(options, hub) + return PreviousSessionFinalizer(options, scopes) } fun sessionFromEnvelope(envelope: SentryEnvelope): Session { @@ -80,7 +80,7 @@ class PreviousSessionFinalizerTest { val finalizer = fixture.getSut(null) finalizer.run() - verify(fixture.hub, never()).captureEnvelope(any()) + verify(fixture.scopes, never()).captureEnvelope(any()) } @Test @@ -88,7 +88,7 @@ class PreviousSessionFinalizerTest { val finalizer = fixture.getSut(tmpDir, sessionFileExists = false) finalizer.run() - verify(fixture.hub, never()).captureEnvelope(any()) + verify(fixture.scopes, never()).captureEnvelope(any()) } @Test @@ -96,7 +96,7 @@ class PreviousSessionFinalizerTest { val finalizer = fixture.getSut(tmpDir, sessionFileExists = true, session = null) finalizer.run() - verify(fixture.hub, never()).captureEnvelope(any()) + verify(fixture.scopes, never()).captureEnvelope(any()) } @Test @@ -107,7 +107,7 @@ class PreviousSessionFinalizerTest { ) finalizer.run() - verify(fixture.hub).captureEnvelope( + verify(fixture.scopes).captureEnvelope( argThat { val session = fixture.sessionFromEnvelope(this) session.release == "io.sentry.sample@1.0" && @@ -133,7 +133,7 @@ class PreviousSessionFinalizerTest { ) finalizer.run() - verify(fixture.hub).captureEnvelope( + verify(fixture.scopes).captureEnvelope( argThat { val session = fixture.sessionFromEnvelope(this) session.release == "io.sentry.sample@1.0" && @@ -156,7 +156,7 @@ class PreviousSessionFinalizerTest { ) finalizer.run() - verify(fixture.hub).captureEnvelope( + verify(fixture.scopes).captureEnvelope( argThat { val session = fixture.sessionFromEnvelope(this) session.release == "io.sentry.sample@1.0" && @@ -170,7 +170,7 @@ class PreviousSessionFinalizerTest { val finalizer = fixture.getSut(tmpDir, sessionFileExists = true) finalizer.run() - verify(fixture.hub, never()).captureEnvelope(any()) + verify(fixture.scopes, never()).captureEnvelope(any()) assertFalse(fixture.sessionFile.exists()) } @@ -189,7 +189,7 @@ class PreviousSessionFinalizerTest { argThat { startsWith("Timed out waiting to flush previous session to its own file in session finalizer.") }, any() ) - verify(fixture.hub, never()).captureEnvelope(any()) + verify(fixture.scopes, never()).captureEnvelope(any()) } @Test @@ -202,6 +202,6 @@ class PreviousSessionFinalizerTest { argThat { startsWith("Timed out waiting to flush previous session to its own file in session finalizer.") }, any() ) - verify(fixture.hub, never()).captureEnvelope(any()) + verify(fixture.scopes, never()).captureEnvelope(any()) } } diff --git a/sentry/src/test/java/io/sentry/ScopeTest.kt b/sentry/src/test/java/io/sentry/ScopeTest.kt index 906c897c62..86794d7b19 100644 --- a/sentry/src/test/java/io/sentry/ScopeTest.kt +++ b/sentry/src/test/java/io/sentry/ScopeTest.kt @@ -114,7 +114,7 @@ class ScopeTest { scope.setExtra("extra", "extra") val transaction = - SentryTracer(TransactionContext("transaction-name", "op"), NoOpHub.getInstance()) + SentryTracer(TransactionContext("transaction-name", "op"), NoOpScopes.getInstance()) scope.transaction = transaction val attachment = Attachment("path/log.txt") @@ -192,7 +192,7 @@ class ScopeTest { scope.setTransaction( SentryTracer( TransactionContext("newTransaction", "op"), - NoOpHub.getInstance() + NoOpScopes.getInstance() ) ) @@ -265,7 +265,7 @@ class ScopeTest { fun `clear scope resets scope to default state`() { val scope = Scope(SentryOptions()) scope.level = SentryLevel.WARNING - scope.setTransaction(SentryTracer(TransactionContext("", "op"), NoOpHub.getInstance())) + scope.setTransaction(SentryTracer(TransactionContext("", "op"), NoOpScopes.getInstance())) scope.user = User() scope.request = Request() scope.fingerprint = mutableListOf("finger") @@ -822,7 +822,7 @@ class ScopeTest { @Test fun `Scope getTransaction returns the transaction if there is no active span`() { val scope = Scope(SentryOptions()) - val transaction = SentryTracer(TransactionContext("name", "op"), NoOpHub.getInstance()) + val transaction = SentryTracer(TransactionContext("name", "op"), NoOpScopes.getInstance()) scope.transaction = transaction assertEquals(transaction, scope.span) } @@ -830,7 +830,7 @@ class ScopeTest { @Test fun `Scope getTransaction returns the current span if there is an unfinished span`() { val scope = Scope(SentryOptions()) - val transaction = SentryTracer(TransactionContext("name", "op"), NoOpHub.getInstance()) + val transaction = SentryTracer(TransactionContext("name", "op"), NoOpScopes.getInstance()) scope.transaction = transaction val span = transaction.startChild("op") assertEquals(span, scope.span) @@ -839,7 +839,7 @@ class ScopeTest { @Test fun `Scope getTransaction returns the current span if there is a finished span`() { val scope = Scope(SentryOptions()) - val transaction = SentryTracer(TransactionContext("name", "op"), NoOpHub.getInstance()) + val transaction = SentryTracer(TransactionContext("name", "op"), NoOpScopes.getInstance()) scope.transaction = transaction val span = transaction.startChild("op") span.finish() @@ -849,7 +849,7 @@ class ScopeTest { @Test fun `Scope getTransaction returns the latest span if there is a list of active span`() { val scope = Scope(SentryOptions()) - val transaction = SentryTracer(TransactionContext("name", "op"), NoOpHub.getInstance()) + val transaction = SentryTracer(TransactionContext("name", "op"), NoOpScopes.getInstance()) scope.transaction = transaction val span = transaction.startChild("op") val innerSpan = span.startChild("op") @@ -859,7 +859,7 @@ class ScopeTest { @Test fun `Scope setTransaction sets transaction name`() { val scope = Scope(SentryOptions()) - val transaction = SentryTracer(TransactionContext("name", "op"), NoOpHub.getInstance()) + val transaction = SentryTracer(TransactionContext("name", "op"), NoOpScopes.getInstance()) scope.transaction = transaction scope.setTransaction("new-name") assertNotNull(scope.transaction) { @@ -871,7 +871,7 @@ class ScopeTest { @Test fun `Scope setTransaction with null does not clear transaction`() { val scope = Scope(SentryOptions()) - val transaction = SentryTracer(TransactionContext("name", "op"), NoOpHub.getInstance()) + val transaction = SentryTracer(TransactionContext("name", "op"), NoOpScopes.getInstance()) scope.transaction = transaction scope.callMethod("setTransaction", String::class.java, null) assertNotNull(scope.transaction) @@ -936,7 +936,7 @@ class ScopeTest { fun `when transaction is started, sets transaction name on the transaction object`() { val scope = Scope(SentryOptions()) val sentryTransaction = - SentryTracer(TransactionContext("transaction-name", "op"), NoOpHub.getInstance()) + SentryTracer(TransactionContext("transaction-name", "op"), NoOpScopes.getInstance()) scope.transaction = sentryTransaction assertEquals("transaction-name", scope.transactionName) scope.setTransaction("new-name") @@ -950,7 +950,7 @@ class ScopeTest { val scope = Scope(SentryOptions()) scope.setTransaction("transaction-a") val sentryTransaction = - SentryTracer(TransactionContext("transaction-name", "op"), NoOpHub.getInstance()) + SentryTracer(TransactionContext("transaction-name", "op"), NoOpScopes.getInstance()) scope.setTransaction(sentryTransaction) assertEquals("transaction-name", scope.transactionName) scope.clearTransaction() @@ -961,7 +961,7 @@ class ScopeTest { fun `withTransaction returns the current Transaction bound to the Scope`() { val scope = Scope(SentryOptions()) val sentryTransaction = - SentryTracer(TransactionContext("transaction-name", "op"), NoOpHub.getInstance()) + SentryTracer(TransactionContext("transaction-name", "op"), NoOpScopes.getInstance()) scope.setTransaction(sentryTransaction) scope.withTransaction { diff --git a/sentry/src/test/java/io/sentry/ScopesAdapterTest.kt b/sentry/src/test/java/io/sentry/ScopesAdapterTest.kt new file mode 100644 index 0000000000..85a0b6ef75 --- /dev/null +++ b/sentry/src/test/java/io/sentry/ScopesAdapterTest.kt @@ -0,0 +1,265 @@ +package io.sentry + +import io.sentry.protocol.SentryTransaction +import io.sentry.protocol.User +import org.mockito.kotlin.any +import org.mockito.kotlin.eq +import org.mockito.kotlin.mock +import org.mockito.kotlin.reset +import org.mockito.kotlin.verify +import kotlin.test.AfterTest +import kotlin.test.BeforeTest +import kotlin.test.Test + +class ScopesAdapterTest { + + val scopes: IScopes = mock() + + @BeforeTest + fun `set up`() { + Sentry.setCurrentScopes(scopes) + } + + @AfterTest + fun shutdown() { + Sentry.close() + } + + @Test fun `isEnabled calls Hub`() { + ScopesAdapter.getInstance().isEnabled + verify(scopes).isEnabled + } + + @Test fun `captureEvent calls Hub`() { + val event = mock() + val hint = mock() + val scopeCallback = mock() + ScopesAdapter.getInstance().captureEvent(event, hint) + verify(scopes).captureEvent(eq(event), eq(hint)) + + ScopesAdapter.getInstance().captureEvent(event, hint, scopeCallback) + verify(scopes).captureEvent(eq(event), eq(hint), eq(scopeCallback)) + } + + @Test fun `captureMessage calls Hub`() { + val scopeCallback = mock() + val sentryLevel = mock() + ScopesAdapter.getInstance().captureMessage("message", sentryLevel) + verify(scopes).captureMessage(eq("message"), eq(sentryLevel)) + + ScopesAdapter.getInstance().captureMessage("message", sentryLevel, scopeCallback) + verify(scopes).captureMessage(eq("message"), eq(sentryLevel), eq(scopeCallback)) + } + + @Test fun `captureEnvelope calls Hub`() { + val envelope = mock() + val hint = mock() + ScopesAdapter.getInstance().captureEnvelope(envelope, hint) + verify(scopes).captureEnvelope(eq(envelope), eq(hint)) + } + + @Test fun `captureException calls Hub`() { + val throwable = mock() + val hint = mock() + val scopeCallback = mock() + ScopesAdapter.getInstance().captureException(throwable, hint) + verify(scopes).captureException(eq(throwable), eq(hint)) + + ScopesAdapter.getInstance().captureException(throwable, hint, scopeCallback) + verify(scopes).captureException(eq(throwable), eq(hint), eq(scopeCallback)) + } + + @Test fun `captureUserFeedback calls Hub`() { + val userFeedback = mock() + ScopesAdapter.getInstance().captureUserFeedback(userFeedback) + verify(scopes).captureUserFeedback(eq(userFeedback)) + } + + @Test fun `captureCheckIn calls Hub`() { + val checkIn = mock() + ScopesAdapter.getInstance().captureCheckIn(checkIn) + verify(scopes).captureCheckIn(eq(checkIn)) + } + + @Test fun `startSession calls Hub`() { + ScopesAdapter.getInstance().startSession() + verify(scopes).startSession() + } + + @Test fun `endSession calls Hub`() { + ScopesAdapter.getInstance().endSession() + verify(scopes).endSession() + } + + @Test fun `close calls Hub`() { + ScopesAdapter.getInstance().close() + verify(scopes).close(false) + } + + @Test fun `close with isRestarting true calls Hub with isRestarting false`() { + ScopesAdapter.getInstance().close(true) + verify(scopes).close(false) + } + + @Test fun `close with isRestarting false calls Hub with isRestarting false`() { + ScopesAdapter.getInstance().close(false) + verify(scopes).close(false) + } + + @Test fun `addBreadcrumb calls Hub`() { + val breadcrumb = mock() + val hint = mock() + ScopesAdapter.getInstance().addBreadcrumb(breadcrumb, hint) + verify(scopes).addBreadcrumb(eq(breadcrumb), eq(hint)) + } + + @Test fun `setLevel calls Hub`() { + val sentryLevel = mock() + ScopesAdapter.getInstance().setLevel(sentryLevel) + verify(scopes).setLevel(eq(sentryLevel)) + } + + @Test fun `setTransaction calls Hub`() { + ScopesAdapter.getInstance().setTransaction("transaction") + verify(scopes).setTransaction(eq("transaction")) + } + + @Test fun `setUser calls Hub`() { + val user = mock() + ScopesAdapter.getInstance().setUser(user) + verify(scopes).setUser(eq(user)) + } + + @Test fun `setFingerprint calls Hub`() { + val fingerprint = ArrayList() + ScopesAdapter.getInstance().setFingerprint(fingerprint) + verify(scopes).setFingerprint(eq(fingerprint)) + } + + @Test fun `clearBreadcrumbs calls Hub`() { + ScopesAdapter.getInstance().clearBreadcrumbs() + verify(scopes).clearBreadcrumbs() + } + + @Test fun `setTag calls Hub`() { + ScopesAdapter.getInstance().setTag("key", "value") + verify(scopes).setTag(eq("key"), eq("value")) + } + + @Test fun `removeTag calls Hub`() { + ScopesAdapter.getInstance().removeTag("key") + verify(scopes).removeTag(eq("key")) + } + + @Test fun `setExtra calls Hub`() { + ScopesAdapter.getInstance().setExtra("key", "value") + verify(scopes).setExtra(eq("key"), eq("value")) + } + + @Test fun `removeExtra calls Hub`() { + ScopesAdapter.getInstance().removeExtra("key") + verify(scopes).removeExtra(eq("key")) + } + + @Test fun `getLastEventId calls Hub`() { + ScopesAdapter.getInstance().lastEventId + verify(scopes).lastEventId + } + + @Test fun `pushScope calls Hub`() { + ScopesAdapter.getInstance().pushScope() + verify(scopes).pushScope() + } + + @Test fun `popScope calls Hub`() { + ScopesAdapter.getInstance().popScope() + verify(scopes).popScope() + } + + @Test fun `withScope calls Hub`() { + val scopeCallback = mock() + ScopesAdapter.getInstance().withScope(scopeCallback) + verify(scopes).withScope(eq(scopeCallback)) + } + + @Test fun `configureScope calls Hub`() { + val scopeCallback = mock() + ScopesAdapter.getInstance().configureScope(scopeCallback) + verify(scopes).configureScope(eq(scopeCallback)) + } + + @Test fun `bindClient calls Hub`() { + val client = mock() + ScopesAdapter.getInstance().bindClient(client) + verify(scopes).bindClient(eq(client)) + } + + @Test fun `flush calls Hub`() { + ScopesAdapter.getInstance().flush(1) + verify(scopes).flush(eq(1)) + } + + @Test fun `clone calls Hub`() { + ScopesAdapter.getInstance().clone() + verify(scopes).clone() + } + + @Test fun `captureTransaction calls Hub`() { + val transaction = mock() + val traceContext = mock() + val hint = mock() + val profilingTraceData = mock() + ScopesAdapter.getInstance().captureTransaction(transaction, traceContext, hint, profilingTraceData) + verify(scopes).captureTransaction(eq(transaction), eq(traceContext), eq(hint), eq(profilingTraceData)) + } + + @Test fun `startTransaction calls Hub`() { + val transactionContext = mock() + val samplingContext = mock() + val transactionOptions = mock() + ScopesAdapter.getInstance().startTransaction(transactionContext) + verify(scopes).startTransaction(eq(transactionContext), any()) + + reset(scopes) + + ScopesAdapter.getInstance().startTransaction(transactionContext, transactionOptions) + verify(scopes).startTransaction(eq(transactionContext), eq(transactionOptions)) + } + + @Test fun `traceHeaders calls Hub`() { + ScopesAdapter.getInstance().traceHeaders() + verify(scopes).traceHeaders() + } + + @Test fun `setSpanContext calls Hub`() { + val throwable = mock() + val span = mock() + ScopesAdapter.getInstance().setSpanContext(throwable, span, "transactionName") + verify(scopes).setSpanContext(eq(throwable), eq(span), eq("transactionName")) + } + + @Test fun `getSpan calls Hub`() { + ScopesAdapter.getInstance().span + verify(scopes).span + } + + @Test fun `getTransaction calls Hub`() { + ScopesAdapter.getInstance().transaction + verify(scopes).transaction + } + + @Test fun `getOptions calls Hub`() { + ScopesAdapter.getInstance().options + verify(scopes).options + } + + @Test fun `isCrashedLastRun calls Hub`() { + ScopesAdapter.getInstance().isCrashedLastRun + verify(scopes).isCrashedLastRun + } + + @Test fun `reportFullyDisplayed calls Hub`() { + ScopesAdapter.getInstance().reportFullyDisplayed() + verify(scopes).reportFullyDisplayed() + } +} diff --git a/sentry/src/test/java/io/sentry/SendCachedEnvelopeFireAndForgetIntegrationTest.kt b/sentry/src/test/java/io/sentry/SendCachedEnvelopeFireAndForgetIntegrationTest.kt index 78623f90a7..beed31a198 100644 --- a/sentry/src/test/java/io/sentry/SendCachedEnvelopeFireAndForgetIntegrationTest.kt +++ b/sentry/src/test/java/io/sentry/SendCachedEnvelopeFireAndForgetIntegrationTest.kt @@ -19,7 +19,7 @@ import kotlin.test.assertTrue class SendCachedEnvelopeFireAndForgetIntegrationTest { private class Fixture { - var hub: IHub = mock() + var scopes: IScopes = mock() var logger: ILogger = mock() var options = SentryOptions() val sender = mock() @@ -45,7 +45,7 @@ class SendCachedEnvelopeFireAndForgetIntegrationTest { fun `when cacheDirPath returns null, register logs and exit`() { fixture.options.cacheDirPath = null val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.logger).log(eq(SentryLevel.ERROR), eq("No cache dir path is defined in options.")) verify(fixture.sender, never()).send() } @@ -73,7 +73,7 @@ class SendCachedEnvelopeFireAndForgetIntegrationTest { val sut = SendCachedEnvelopeFireAndForgetIntegration(CustomFactory()) fixture.options.cacheDirPath = "abc" fixture.options.executorService = ImmediateExecutorService() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.logger).log(eq(SentryLevel.ERROR), eq("SendFireAndForget factory is null.")) verify(fixture.sender, never()).send() } @@ -85,7 +85,7 @@ class SendCachedEnvelopeFireAndForgetIntegrationTest { mock() ) val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertNotNull(fixture.options.sdkVersion) assert(fixture.options.sdkVersion!!.integrationSet.contains("SendCachedEnvelopeFireAndForget")) } @@ -96,7 +96,7 @@ class SendCachedEnvelopeFireAndForgetIntegrationTest { fixture.options.executorService.close(0) whenever(fixture.callback.create(any(), any())).thenReturn(mock()) val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.logger).log(eq(SentryLevel.ERROR), eq("Failed to call the executor. Cached events will not be sent. Did you call Sentry.close()?"), any()) } @@ -108,7 +108,7 @@ class SendCachedEnvelopeFireAndForgetIntegrationTest { fixture.options.cacheDirPath = "cache" val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(connectionStatusProvider).addConnectionStatusObserver(any()) } @@ -122,9 +122,9 @@ class SendCachedEnvelopeFireAndForgetIntegrationTest { fixture.options.cacheDirPath = "cache" val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.sender, never()).send() } @@ -139,7 +139,7 @@ class SendCachedEnvelopeFireAndForgetIntegrationTest { fixture.options.cacheDirPath = "cache" val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.sender).send() } @@ -155,7 +155,7 @@ class SendCachedEnvelopeFireAndForgetIntegrationTest { fixture.options.cacheDirPath = "cache" val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) // when there's no connection no factory create call should be done verify(fixture.sender, never()).send() @@ -183,9 +183,9 @@ class SendCachedEnvelopeFireAndForgetIntegrationTest { val rateLimiter = mock { whenever(mock.isActiveForCategory(any())).thenReturn(true) } - whenever(fixture.hub.rateLimiter).thenReturn(rateLimiter) + whenever(fixture.scopes.rateLimiter).thenReturn(rateLimiter) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) // no factory call should be done if there's rate limiting active verify(fixture.sender, never()).send() @@ -196,8 +196,8 @@ class SendCachedEnvelopeFireAndForgetIntegrationTest { fixture.options.executorService = ImmediateExecutorService() fixture.options.cacheDirPath = "cache" val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) - verify(fixture.callback).create(eq(fixture.hub), eq(fixture.options)) + sut.register(fixture.scopes, fixture.options) + verify(fixture.callback).create(eq(fixture.scopes), eq(fixture.options)) } @Test @@ -205,7 +205,7 @@ class SendCachedEnvelopeFireAndForgetIntegrationTest { fixture.options.executorService = mock() fixture.options.cacheDirPath = "cache" val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.callback, never()).create(any(), any()) } @@ -215,7 +215,7 @@ class SendCachedEnvelopeFireAndForgetIntegrationTest { fixture.options.executorService = deferredExecutorService val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.sender, never()).send() sut.close() @@ -224,7 +224,7 @@ class SendCachedEnvelopeFireAndForgetIntegrationTest { } private class CustomFactory : SendCachedEnvelopeFireAndForgetIntegration.SendFireAndForgetFactory { - override fun create(hub: IHub, options: SentryOptions): SendCachedEnvelopeFireAndForgetIntegration.SendFireAndForget? { + override fun create(scopes: IScopes, options: SentryOptions): SendCachedEnvelopeFireAndForgetIntegration.SendFireAndForget? { return null } } diff --git a/sentry/src/test/java/io/sentry/SentryClientTest.kt b/sentry/src/test/java/io/sentry/SentryClientTest.kt index de540bf90c..eac2b0be29 100644 --- a/sentry/src/test/java/io/sentry/SentryClientTest.kt +++ b/sentry/src/test/java/io/sentry/SentryClientTest.kt @@ -70,7 +70,7 @@ class SentryClientTest { var transport = mock() var factory = mock() val maxAttachmentSize: Long = (5 * 1024 * 1024).toLong() - val hub = mock() + val scopes = mock() val sentryTracer: SentryTracer var sentryOptions: SentryOptions = SentryOptions().apply { @@ -88,8 +88,8 @@ class SentryClientTest { init { whenever(factory.create(any(), any())).thenReturn(transport) - whenever(hub.options).thenReturn(sentryOptions) - sentryTracer = SentryTracer(TransactionContext("a-transaction", "op"), hub) + whenever(scopes.options).thenReturn(sentryOptions) + sentryTracer = SentryTracer(TransactionContext("a-transaction", "op"), scopes) } var attachment = Attachment("hello".toByteArray(), "hello.txt", "text/plain", true) @@ -1456,9 +1456,9 @@ class SentryClientTest { @Test fun `when captureTransaction with scope, transaction should use user data`() { - val hub: IHub = mock() - whenever(hub.options).thenReturn(SentryOptions()) - val transaction = SentryTransaction(SentryTracer(TransactionContext("tx", "op"), hub)) + val scopes: IScopes = mock() + whenever(scopes.options).thenReturn(SentryOptions()) + val transaction = SentryTransaction(SentryTracer(TransactionContext("tx", "op"), scopes)) val scope = createScope() val sut = fixture.getSut() @@ -1487,7 +1487,7 @@ class SentryClientTest { val event = SentryEvent() val sut = fixture.getSut() val scope = createScope() - val transaction = SentryTracer(TransactionContext("a-transaction", "op"), fixture.hub) + val transaction = SentryTracer(TransactionContext("a-transaction", "op"), fixture.scopes) scope.setTransaction(transaction) val span = transaction.startChild("op") sut.captureEvent(event, scope) @@ -1558,7 +1558,7 @@ class SentryClientTest { fixture.sentryOptions.release = "optionsRelease" fixture.sentryOptions.environment = "optionsEnvironment" val sut = fixture.getSut() - val sentryTracer = SentryTracer(TransactionContext("name", "op"), fixture.hub) + val sentryTracer = SentryTracer(TransactionContext("name", "op"), fixture.scopes) val transaction = SentryTransaction(sentryTracer) transaction.release = "transactionRelease" transaction.environment = "transactionEnvironment" @@ -1571,7 +1571,7 @@ class SentryClientTest { fun `when transaction does not have SDK version set, and the SDK version is set on options, options values are applied to transactions`() { fixture.sentryOptions.sdkVersion = SdkVersion("sdk.name", "version") val sut = fixture.getSut() - val sentryTracer = SentryTracer(TransactionContext("name", "op"), fixture.hub) + val sentryTracer = SentryTracer(TransactionContext("name", "op"), fixture.scopes) val transaction = SentryTransaction(sentryTracer) sut.captureTransaction(transaction, sentryTracer.traceContext()) assertEquals(fixture.sentryOptions.sdkVersion, transaction.sdk) @@ -1581,7 +1581,7 @@ class SentryClientTest { fun `when transaction has SDK version set, and the SDK version is set on options, options values are not applied to transactions`() { fixture.sentryOptions.sdkVersion = SdkVersion("sdk.name", "version") val sut = fixture.getSut() - val sentryTracer = SentryTracer(TransactionContext("name", "op"), fixture.hub) + val sentryTracer = SentryTracer(TransactionContext("name", "op"), fixture.scopes) val transaction = SentryTransaction(sentryTracer) val sdkVersion = SdkVersion("transaction.sdk.name", "version") transaction.sdk = sdkVersion @@ -1593,7 +1593,7 @@ class SentryClientTest { fun `when transaction does not have tags, and tags are set on options, options values are applied to transactions`() { fixture.sentryOptions.setTag("tag1", "value1") val sut = fixture.getSut() - val sentryTracer = SentryTracer(TransactionContext("name", "op"), fixture.hub) + val sentryTracer = SentryTracer(TransactionContext("name", "op"), fixture.scopes) val transaction = SentryTransaction(sentryTracer) sut.captureTransaction(transaction, sentryTracer.traceContext()) assertEquals(mapOf("tag1" to "value1"), transaction.tags) @@ -1604,7 +1604,7 @@ class SentryClientTest { fixture.sentryOptions.setTag("tag1", "value1") fixture.sentryOptions.setTag("tag2", "value2") val sut = fixture.getSut() - val sentryTracer = SentryTracer(TransactionContext("name", "op"), fixture.hub) + val sentryTracer = SentryTracer(TransactionContext("name", "op"), fixture.scopes) val transaction = SentryTransaction(sentryTracer) transaction.setTag("tag3", "value3") transaction.setTag("tag2", "transaction-tag") @@ -1618,7 +1618,7 @@ class SentryClientTest { @Test fun `captured transactions without a platform, have the default platform set`() { val sut = fixture.getSut() - val sentryTracer = SentryTracer(TransactionContext("name", "op"), fixture.hub) + val sentryTracer = SentryTracer(TransactionContext("name", "op"), fixture.scopes) val transaction = SentryTransaction(sentryTracer) sut.captureTransaction(transaction, sentryTracer.traceContext()) assertEquals("java", transaction.platform) @@ -1627,7 +1627,7 @@ class SentryClientTest { @Test fun `captured transactions with a platform, do not get the platform overwritten`() { val sut = fixture.getSut() - val sentryTracer = SentryTracer(TransactionContext("name", "op"), fixture.hub) + val sentryTracer = SentryTracer(TransactionContext("name", "op"), fixture.scopes) val transaction = SentryTransaction(sentryTracer) transaction.platform = "abc" sut.captureTransaction(transaction, sentryTracer.traceContext()) diff --git a/sentry/src/test/java/io/sentry/SentryTest.kt b/sentry/src/test/java/io/sentry/SentryTest.kt index 0f4966b44a..70728d2900 100644 --- a/sentry/src/test/java/io/sentry/SentryTest.kt +++ b/sentry/src/test/java/io/sentry/SentryTest.kt @@ -63,27 +63,27 @@ class SentryTest { } @Test - fun `init multiple times calls hub close with isRestarting true`() { - val hub = mock() + fun `init multiple times calls scopes close with isRestarting true`() { + val scopes = mock() Sentry.init { it.dsn = dsn } - Sentry.setCurrentHub(hub) + Sentry.setCurrentScopes(scopes) Sentry.init { it.dsn = dsn } - verify(hub).close(eq(true)) + verify(scopes).close(eq(true)) } @Test - fun `close calls hub close with isRestarting false`() { - val hub = mock() + fun `close calls scopes close with isRestarting false`() { + val scopes = mock() Sentry.init { it.dsn = dsn } - Sentry.setCurrentHub(hub) + Sentry.setCurrentScopes(scopes) Sentry.close() - verify(hub).close(eq(false)) + verify(scopes).close(eq(false)) } @Test @@ -213,7 +213,7 @@ class SentryTest { Sentry.init { it.isEnableExternalConfiguration = true } - assertTrue(HubAdapter.getInstance().isEnabled) + assertTrue(ScopesAdapter.getInstance().isEnabled) } finally { temporaryFolder.delete() } @@ -229,10 +229,10 @@ class SentryTest { Sentry.setTag("none", "shouldNotExist") var value: String? = null - Sentry.getCurrentHub().configureScope { + Sentry.getCurrentScopes().configureScope { value = it.tags[value] } - assertTrue(Sentry.getCurrentHub() is NoOpHub) + assertTrue(Sentry.getCurrentScopes().isNoOp) assertNull(value) } @@ -245,10 +245,10 @@ class SentryTest { Sentry.setTag("none", "shouldNotExist") var value: String? = null - Sentry.getCurrentHub().configureScope { + Sentry.getCurrentScopes().configureScope { value = it.tags[value] } - assertTrue(Sentry.getCurrentHub() is NoOpHub) + assertTrue(Sentry.getCurrentScopes().isNoOp) assertNull(value) } @@ -267,7 +267,7 @@ class SentryTest { Sentry.init { it.dsn = dsn } val client = mock() - Sentry.getCurrentHub().bindClient(client) + Sentry.getCurrentScopes().bindClient(client) val userFeedback = UserFeedback(SentryId.EMPTY_ID) Sentry.captureUserFeedback(userFeedback) @@ -369,11 +369,11 @@ class SentryTest { } @Test - fun `using sentry before calling init creates NoOpHub but after init Sentry uses a new clone`() { - // noop as not yet initialized, caches NoOpHub in ThreadLocal + fun `using sentry before calling init creates NoOpScopes but after init Sentry uses a new clone`() { + // noop as not yet initialized, caches NoOpScopes in ThreadLocal Sentry.captureMessage("noop caused") - assertTrue(Sentry.getCurrentHub() is NoOpHub) + assertTrue(Sentry.getCurrentScopes().isNoOp) // init Sentry in another thread val thread = Thread() { @@ -387,18 +387,18 @@ class SentryTest { Sentry.captureMessage("should work now") - val hub = Sentry.getCurrentHub() - assertNotNull(hub) - assertFalse(hub is NoOpHub) + val scopes = Sentry.getCurrentScopes() + assertNotNull(scopes) + assertFalse(scopes.isNoOp) } @Test - fun `main hub can be cloned and does not share scope with current hub`() { - // noop as not yet initialized, caches NoOpHub in ThreadLocal + fun `main scopes can be cloned and does not share scope with current scopes`() { + // noop as not yet initialized, caches NoOpScopes in ThreadLocal Sentry.addBreadcrumb("breadcrumbNoOp") Sentry.captureMessage("messageNoOp") - assertTrue(Sentry.getCurrentHub() is NoOpHub) + assertTrue(Sentry.getCurrentScopes().isNoOp) val capturedEvents = mutableListOf() @@ -418,14 +418,14 @@ class SentryTest { Sentry.addBreadcrumb("breadcrumbCurrent") - val hub = Sentry.getCurrentHub() - assertNotNull(hub) - assertFalse(hub is NoOpHub) + val scopes = Sentry.getCurrentScopes() + assertNotNull(scopes) + assertFalse(Sentry.getCurrentScopes().isNoOp) val newMainHubClone = Sentry.cloneMainHub() newMainHubClone.addBreadcrumb("breadcrumbMainClone") - hub.captureMessage("messageCurrent") + scopes.captureMessage("messageCurrent") newMainHubClone.captureMessage("messageMainClone") assertEquals(2, capturedEvents.size) @@ -444,12 +444,12 @@ class SentryTest { } @Test - fun `main hub is not cloned in global hub mode and shares scope with current hub`() { - // noop as not yet initialized, caches NoOpHub in ThreadLocal + fun `main scopes is not cloned in global scopes mode and shares scope with current scopes`() { + // noop as not yet initialized, caches NoOpScopes in ThreadLocal Sentry.addBreadcrumb("breadcrumbNoOp") Sentry.captureMessage("messageNoOp") - assertTrue(Sentry.getCurrentHub() is NoOpHub) + assertTrue(Sentry.getCurrentScopes().isNoOp) val capturedEvents = mutableListOf() @@ -469,14 +469,14 @@ class SentryTest { Sentry.addBreadcrumb("breadcrumbCurrent") - val hub = Sentry.getCurrentHub() - assertNotNull(hub) - assertFalse(hub is NoOpHub) + val scopes = Sentry.getCurrentScopes() + assertNotNull(scopes) + assertFalse(scopes.isNoOp) val newMainHubClone = Sentry.cloneMainHub() newMainHubClone.addBreadcrumb("breadcrumbMainClone") - hub.captureMessage("messageCurrent") + scopes.captureMessage("messageCurrent") newMainHubClone.captureMessage("messageMainClone") assertEquals(2, capturedEvents.size) @@ -669,25 +669,25 @@ class SentryTest { } @Test - fun `reportFullyDisplayed calls hub reportFullyDisplayed`() { - val hub = mock() + fun `reportFullyDisplayed calls scopes reportFullyDisplayed`() { + val scopes = mock() Sentry.init { it.dsn = dsn } - Sentry.setCurrentHub(hub) + Sentry.setCurrentScopes(scopes) Sentry.reportFullyDisplayed() - verify(hub).reportFullyDisplayed() + verify(scopes).reportFullyDisplayed() } @Test fun `reportFullDisplayed calls reportFullyDisplayed`() { - val hub = mock() + val scopes = mock() Sentry.init { it.dsn = dsn } - Sentry.setCurrentHub(hub) + Sentry.setCurrentScopes(scopes) Sentry.reportFullDisplayed() - verify(hub).reportFullyDisplayed() + verify(scopes).reportFullyDisplayed() } @Test @@ -806,11 +806,11 @@ class SentryTest { it.serializer.deserialize(previousSessionFile.bufferedReader(), Session::class.java)!!.environment ) - it.addIntegration { hub, _ -> + it.addIntegration { scopes, _ -> // this is just a hack to trigger the previousSessionFlush latch, so the finalizer // does not time out waiting. We have to do it as integration, because this is where - // the hub is already initialized - hub.startSession() + // the scopes is already initialized + scopes.startSession() } } @@ -861,7 +861,7 @@ class SentryTest { Sentry.init { it.dsn = dsn } val client = mock() - Sentry.getCurrentHub().bindClient(client) + Sentry.getCurrentScopes().bindClient(client) val checkIn = CheckIn("some_slug", CheckInStatus.OK) Sentry.captureCheckIn(checkIn) @@ -910,18 +910,18 @@ class SentryTest { } @Test - fun `getSpan calls hub getSpan`() { - val hub = mock() + fun `getSpan calls scopes getSpan`() { + val scopes = mock() Sentry.init({ it.dsn = dsn }, false) - Sentry.setCurrentHub(hub) + Sentry.setCurrentScopes(scopes) Sentry.getSpan() - verify(hub).span + verify(scopes).span } @Test - fun `getSpan calls returns root span if globalhub mode is enabled on Android`() { + fun `getSpan calls returns root span if globalscopes mode is enabled on Android`() { PlatformTestManipulator.pretendIsAndroid(true) Sentry.init({ it.dsn = dsn @@ -938,7 +938,7 @@ class SentryTest { } @Test - fun `getSpan calls returns child span if globalhub mode is enabled, but the platform is not Android`() { + fun `getSpan calls returns child span if globalscopes mode is enabled, but the platform is not Android`() { PlatformTestManipulator.pretendIsAndroid(false) Sentry.init({ it.dsn = dsn @@ -954,7 +954,7 @@ class SentryTest { } @Test - fun `getSpan calls returns child span if globalhub mode is disabled`() { + fun `getSpan calls returns child span if globalscopes mode is disabled`() { Sentry.init({ it.dsn = dsn it.enableTracing = true @@ -1140,15 +1140,15 @@ class SentryTest { } @Test - fun `metrics calls hub getMetrics`() { - val hub = mock() + fun `metrics calls scopes getMetrics`() { + val scopes = mock() Sentry.init({ it.dsn = dsn }, false) - Sentry.setCurrentHub(hub) + Sentry.setCurrentScopes(scopes) Sentry.metrics() - verify(hub).metrics() + verify(scopes).metrics() } private class InMemoryOptionsObserver : IOptionsObserver { diff --git a/sentry/src/test/java/io/sentry/SentryWrapperTest.kt b/sentry/src/test/java/io/sentry/SentryWrapperTest.kt index 7f6d449eac..2fb9b38566 100644 --- a/sentry/src/test/java/io/sentry/SentryWrapperTest.kt +++ b/sentry/src/test/java/io/sentry/SentryWrapperTest.kt @@ -35,20 +35,20 @@ class SentryWrapperTest { } } - val mainHub = Sentry.getCurrentHub() - val threadedHub = Sentry.getCurrentHub().clone() + val mainHub = Sentry.getCurrentScopes() + val threadedHub = Sentry.getCurrentScopes().clone() executor.submit { - Sentry.setCurrentHub(threadedHub) + Sentry.setCurrentScopes(threadedHub) }.get() - assertEquals(mainHub, Sentry.getCurrentHub()) + assertEquals(mainHub, Sentry.getCurrentScopes()) val callableFuture = CompletableFuture.supplyAsync( SentryWrapper.wrapSupplier { - assertNotEquals(mainHub, Sentry.getCurrentHub()) - assertNotEquals(threadedHub, Sentry.getCurrentHub()) + assertNotEquals(mainHub, Sentry.getCurrentScopes()) + assertNotEquals(threadedHub, Sentry.getCurrentScopes()) "Result 1" }, executor @@ -57,8 +57,8 @@ class SentryWrapperTest { callableFuture.join() executor.submit { - assertNotEquals(mainHub, Sentry.getCurrentHub()) - assertEquals(threadedHub, Sentry.getCurrentHub()) + assertNotEquals(mainHub, Sentry.getCurrentScopes()) + assertEquals(threadedHub, Sentry.getCurrentScopes()) }.get() } @@ -169,20 +169,20 @@ class SentryWrapperTest { it.dsn = dsn } - val mainHub = Sentry.getCurrentHub() - val threadedHub = Sentry.getCurrentHub().clone() + val mainHub = Sentry.getCurrentScopes() + val threadedHub = Sentry.getCurrentScopes().clone() executor.submit { - Sentry.setCurrentHub(threadedHub) + Sentry.setCurrentScopes(threadedHub) }.get() - assertEquals(mainHub, Sentry.getCurrentHub()) + assertEquals(mainHub, Sentry.getCurrentScopes()) val callableFuture = executor.submit( SentryWrapper.wrapCallable { - assertNotEquals(mainHub, Sentry.getCurrentHub()) - assertNotEquals(threadedHub, Sentry.getCurrentHub()) + assertNotEquals(mainHub, Sentry.getCurrentScopes()) + assertNotEquals(threadedHub, Sentry.getCurrentScopes()) "Result 1" } ) @@ -190,8 +190,8 @@ class SentryWrapperTest { callableFuture.get() executor.submit { - assertNotEquals(mainHub, Sentry.getCurrentHub()) - assertEquals(threadedHub, Sentry.getCurrentHub()) + assertNotEquals(mainHub, Sentry.getCurrentScopes()) + assertEquals(threadedHub, Sentry.getCurrentScopes()) }.get() } } diff --git a/sentry/src/test/java/io/sentry/ShutdownHookIntegrationTest.kt b/sentry/src/test/java/io/sentry/ShutdownHookIntegrationTest.kt index d6ce0ff043..428a34635f 100644 --- a/sentry/src/test/java/io/sentry/ShutdownHookIntegrationTest.kt +++ b/sentry/src/test/java/io/sentry/ShutdownHookIntegrationTest.kt @@ -16,7 +16,7 @@ class ShutdownHookIntegrationTest { private class Fixture { val runtime = mock() val options = SentryOptions() - val hub = mock() + val scopes = mock() fun getSut(): ShutdownHookIntegration { return ShutdownHookIntegration(runtime) @@ -29,7 +29,7 @@ class ShutdownHookIntegrationTest { fun `registration attaches shutdown hook to runtime`() { val integration = fixture.getSut() - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) verify(fixture.runtime).addShutdownHook(any()) } @@ -39,7 +39,7 @@ class ShutdownHookIntegrationTest { val integration = fixture.getSut() fixture.options.isEnableShutdownHook = false - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) verify(fixture.runtime, never()).addShutdownHook(any()) } @@ -48,7 +48,7 @@ class ShutdownHookIntegrationTest { fun `registration removes shutdown hook from runtime`() { val integration = fixture.getSut() - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) integration.close() verify(fixture.runtime).removeShutdownHook(any()) @@ -58,13 +58,13 @@ class ShutdownHookIntegrationTest { fun `hook calls flush`() { val integration = fixture.getSut() - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) assertNotNull(integration.hook) { it.start() it.join() } - verify(fixture.hub).flush(any()) + verify(fixture.scopes).flush(any()) } @Test @@ -72,13 +72,13 @@ class ShutdownHookIntegrationTest { val integration = fixture.getSut() fixture.options.flushTimeoutMillis = 10000 - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) assertNotNull(integration.hook) { it.start() it.join() } - verify(fixture.hub).flush(eq(10000)) + verify(fixture.scopes).flush(eq(10000)) } @Test @@ -86,7 +86,7 @@ class ShutdownHookIntegrationTest { val integration = fixture.getSut() whenever(fixture.runtime.removeShutdownHook(any())).thenThrow(java.lang.IllegalStateException("Shutdown in progress")) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) integration.close() verify(fixture.runtime).removeShutdownHook(any()) @@ -97,7 +97,7 @@ class ShutdownHookIntegrationTest { val integration = fixture.getSut() whenever(fixture.runtime.removeShutdownHook(any())).thenThrow(java.lang.IllegalStateException()) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) assertFails { integration.close() @@ -110,7 +110,7 @@ class ShutdownHookIntegrationTest { fun `Integration adds itself to integration list`() { val integration = fixture.getSut() - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) assertTrue( fixture.options.sdkVersion!!.integrationSet.contains("ShutdownHook") diff --git a/sentry/src/test/java/io/sentry/SpanTest.kt b/sentry/src/test/java/io/sentry/SpanTest.kt index ae9d9bd07f..fd36c31933 100644 --- a/sentry/src/test/java/io/sentry/SpanTest.kt +++ b/sentry/src/test/java/io/sentry/SpanTest.kt @@ -21,10 +21,10 @@ import kotlin.test.assertTrue class SpanTest { private class Fixture { - val hub = mock() + val scopes = mock() init { - whenever(hub.options).thenReturn( + whenever(scopes.options).thenReturn( SentryOptions().apply { dsn = "https://key@sentry.io/proj" isTraceSampling = true @@ -36,9 +36,9 @@ class SpanTest { return Span( SentryId(), SpanId(), - SentryTracer(TransactionContext("name", "op"), hub), + SentryTracer(TransactionContext("name", "op"), scopes), "op", - hub, + scopes, null, options, null @@ -46,7 +46,7 @@ class SpanTest { } fun getRootSut(options: TransactionOptions = TransactionOptions()): Span { - return SentryTracer(TransactionContext("name", "op"), hub, options).root + return SentryTracer(TransactionContext("name", "op"), scopes, options).root } } @@ -106,10 +106,10 @@ class SpanTest { parentSpanId, SentryTracer( TransactionContext("name", "op", TracesSamplingDecision(true)), - fixture.hub + fixture.scopes ), "op", - fixture.hub + fixture.scopes ) val sentryTrace = span.toSentryTrace() @@ -163,17 +163,17 @@ class SpanTest { } @Test - fun `when span has throwable set set, it assigns itself to throwable on the Hub`() { + fun `when span has throwable set set, it assigns itself to throwable on the Scopes`() { val transaction = SentryTracer( TransactionContext("name", "op"), - fixture.hub + fixture.scopes ) val span = transaction.startChild("op") val ex = RuntimeException() span.throwable = ex span.finish() - verify(fixture.hub).setSpanContext(ex, span, "name") + verify(fixture.scopes).setSpanContext(ex, span, "name") } @Test @@ -188,7 +188,7 @@ class SpanTest { span.finish(SpanStatus.UNKNOWN_ERROR) // call only once - verify(fixture.hub).setSpanContext(any(), any(), any()) + verify(fixture.scopes).setSpanContext(any(), any(), any()) assertEquals(SpanStatus.OK, span.status) assertEquals(timestamp, span.finishDate) } @@ -496,7 +496,7 @@ class SpanTest { } private fun getTransaction(transactionContext: TransactionContext = TransactionContext("name", "op")): SentryTracer { - return SentryTracer(transactionContext, fixture.hub) + return SentryTracer(transactionContext, fixture.scopes) } private fun startChildFromSpan(): Span { diff --git a/sentry/src/test/java/io/sentry/TraceContextSerializationTest.kt b/sentry/src/test/java/io/sentry/TraceContextSerializationTest.kt index e79e5ebf8c..0847c9448f 100644 --- a/sentry/src/test/java/io/sentry/TraceContextSerializationTest.kt +++ b/sentry/src/test/java/io/sentry/TraceContextSerializationTest.kt @@ -54,10 +54,10 @@ class TraceContextSerializationTest { private fun createTraceContext(sRate: Double): TraceContext { val baggage = Baggage(fixture.logger) - val hub: IHub = mock() - whenever(hub.options).thenReturn(SentryOptions()) + val scopes: IScopes = mock() + whenever(scopes.options).thenReturn(SentryOptions()) baggage.setValuesFromTransaction( - SentryTracer(TransactionContext("name", "op"), hub), + SentryTracer(TransactionContext("name", "op"), scopes), User().apply { id = "user-id" others = mapOf("segment" to "pro") diff --git a/sentry/src/test/java/io/sentry/UncaughtExceptionHandlerIntegrationTest.kt b/sentry/src/test/java/io/sentry/UncaughtExceptionHandlerIntegrationTest.kt index 01353d5ac0..ec366e1901 100644 --- a/sentry/src/test/java/io/sentry/UncaughtExceptionHandlerIntegrationTest.kt +++ b/sentry/src/test/java/io/sentry/UncaughtExceptionHandlerIntegrationTest.kt @@ -30,7 +30,7 @@ class UncaughtExceptionHandlerIntegrationTest { val defaultHandler = mock() val thread = mock() val throwable = Throwable("test") - val hub = mock() + val scopes = mock() val options = SentryOptions() val logger = mock() @@ -63,17 +63,17 @@ class UncaughtExceptionHandlerIntegrationTest { fun `when uncaughtException is called, sentry captures exception`() { val sut = fixture.getSut(isPrintUncaughtStackTrace = false) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) sut.uncaughtException(fixture.thread, fixture.throwable) - verify(fixture.hub).captureEvent(any(), any()) + verify(fixture.scopes).captureEvent(any(), any()) } @Test fun `when register is called, current handler is not lost`() { val sut = fixture.getSut(hasDefaultHandler = true, isPrintUncaughtStackTrace = false) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) sut.uncaughtException(fixture.thread, fixture.throwable) verify(fixture.defaultHandler).uncaughtException(fixture.thread, fixture.throwable) @@ -81,7 +81,7 @@ class UncaughtExceptionHandlerIntegrationTest { @Test fun `when uncaughtException is called, exception captured has handled=false`() { - whenever(fixture.hub.captureException(any())).thenAnswer { invocation -> + whenever(fixture.scopes.captureException(any())).thenAnswer { invocation -> val e = invocation.getArgument(1) assertNotNull(e) assertNotNull(e.exceptionMechanism) @@ -91,22 +91,22 @@ class UncaughtExceptionHandlerIntegrationTest { val sut = fixture.getSut(isPrintUncaughtStackTrace = false) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) sut.uncaughtException(fixture.thread, fixture.throwable) - verify(fixture.hub).captureEvent(any(), any()) + verify(fixture.scopes).captureEvent(any(), any()) } @Test - fun `when hub is closed, integrations should be closed`() { + fun `when scopes is closed, integrations should be closed`() { val integrationMock = mock() val options = SentryOptions() options.dsn = "https://key@sentry.io/proj" options.addIntegration(integrationMock) options.cacheDirPath = fixture.file.absolutePath options.setSerializer(mock()) - val hub = Hub(options) - hub.close() + val scopes = Hub(options) + scopes.close() verify(integrationMock).close() } @@ -117,7 +117,7 @@ class UncaughtExceptionHandlerIntegrationTest { isPrintUncaughtStackTrace = false ) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.handler, never()).defaultUncaughtExceptionHandler = any() } @@ -126,7 +126,7 @@ class UncaughtExceptionHandlerIntegrationTest { fun `When defaultUncaughtExceptionHandler is enabled, should install Sentry UncaughtExceptionHandler`() { val sut = fixture.getSut(isPrintUncaughtStackTrace = false) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.handler).defaultUncaughtExceptionHandler = argWhere { it is UncaughtExceptionHandlerIntegration } @@ -136,7 +136,7 @@ class UncaughtExceptionHandlerIntegrationTest { fun `When defaultUncaughtExceptionHandler is set and integration is closed, default uncaught exception handler is reset to previous handler`() { val sut = fixture.getSut(hasDefaultHandler = true, isPrintUncaughtStackTrace = false) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) whenever(fixture.handler.defaultUncaughtExceptionHandler) .thenReturn(sut) sut.close() @@ -148,7 +148,7 @@ class UncaughtExceptionHandlerIntegrationTest { fun `When defaultUncaughtExceptionHandler is not set and integration is closed, default uncaught exception handler is reset to null`() { val sut = fixture.getSut(isPrintUncaughtStackTrace = false) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) whenever(fixture.handler.defaultUncaughtExceptionHandler) .thenReturn(sut) sut.close() @@ -165,7 +165,7 @@ class UncaughtExceptionHandlerIntegrationTest { val sut = fixture.getSut(isPrintUncaughtStackTrace = true) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) sut.uncaughtException(fixture.thread, RuntimeException("This should be printed!")) assertTrue( @@ -185,7 +185,7 @@ class UncaughtExceptionHandlerIntegrationTest { fun `waits for event to flush on disk`() { val capturedEventId = SentryId() - whenever(fixture.hub.captureEvent(any(), any())).thenAnswer { invocation -> + whenever(fixture.scopes.captureEvent(any(), any())).thenAnswer { invocation -> val hint = HintUtils.getSentrySdkHint(invocation.getArgument(1)) as DiskFlushNotification thread { @@ -197,10 +197,10 @@ class UncaughtExceptionHandlerIntegrationTest { val sut = fixture.getSut(flushTimeoutMillis = 5000) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) sut.uncaughtException(fixture.thread, fixture.throwable) - verify(fixture.hub).captureEvent(any(), any()) + verify(fixture.scopes).captureEvent(any(), any()) // shouldn't fall into timed out state, because we marked event as flushed on another thread verify(fixture.logger, never()).log( any(), @@ -211,14 +211,14 @@ class UncaughtExceptionHandlerIntegrationTest { @Test fun `does not block flushing when the event was dropped`() { - whenever(fixture.hub.captureEvent(any(), any())).thenReturn(SentryId.EMPTY_ID) + whenever(fixture.scopes.captureEvent(any(), any())).thenReturn(SentryId.EMPTY_ID) val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) sut.uncaughtException(fixture.thread, fixture.throwable) - verify(fixture.hub).captureEvent(any(), any()) + verify(fixture.scopes).captureEvent(any(), any()) // we do not call markFlushed, hence it should time out waiting for flush, but because // we drop the event, it should not even come to this if-check verify(fixture.logger, never()).log( @@ -231,17 +231,17 @@ class UncaughtExceptionHandlerIntegrationTest { @Test fun `waits for event to flush on disk if it was dropped by multithreaded deduplicator`() { val hintCaptor = argumentCaptor() - whenever(fixture.hub.captureEvent(any(), hintCaptor.capture())).thenAnswer { + whenever(fixture.scopes.captureEvent(any(), hintCaptor.capture())).thenAnswer { HintUtils.setEventDropReason(hintCaptor.firstValue, MULTITHREADED_DEDUPLICATION) return@thenAnswer SentryId.EMPTY_ID } val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) sut.uncaughtException(fixture.thread, fixture.throwable) - verify(fixture.hub).captureEvent(any(), any()) + verify(fixture.scopes).captureEvent(any(), any()) // we do not call markFlushed, even though we dropped the event, the reason was // MULTITHREADED_DEDUPLICATION, so it should time out verify(fixture.logger).log( @@ -254,15 +254,15 @@ class UncaughtExceptionHandlerIntegrationTest { @Test fun `when there is no active transaction on scope, sets current event id as flushable`() { val eventCaptor = argumentCaptor() - whenever(fixture.hub.captureEvent(eventCaptor.capture(), any())) + whenever(fixture.scopes.captureEvent(eventCaptor.capture(), any())) .thenReturn(SentryId.EMPTY_ID) val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) sut.uncaughtException(fixture.thread, fixture.throwable) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( any(), argThat { (HintUtils.getSentrySdkHint(this) as UncaughtExceptionHint) @@ -274,16 +274,16 @@ class UncaughtExceptionHandlerIntegrationTest { @Test fun `when there is active transaction on scope, does not set current event id as flushable`() { val eventCaptor = argumentCaptor() - whenever(fixture.hub.transaction).thenReturn(mock()) - whenever(fixture.hub.captureEvent(eventCaptor.capture(), any())) + whenever(fixture.scopes.transaction).thenReturn(mock()) + whenever(fixture.scopes.captureEvent(eventCaptor.capture(), any())) .thenReturn(SentryId.EMPTY_ID) val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) sut.uncaughtException(fixture.thread, fixture.throwable) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( any(), argThat { !(HintUtils.getSentrySdkHint(this) as UncaughtExceptionHint) diff --git a/sentry/src/test/java/io/sentry/backpressure/BackpressureMonitorTest.kt b/sentry/src/test/java/io/sentry/backpressure/BackpressureMonitorTest.kt index c010c97238..cf234574bf 100644 --- a/sentry/src/test/java/io/sentry/backpressure/BackpressureMonitorTest.kt +++ b/sentry/src/test/java/io/sentry/backpressure/BackpressureMonitorTest.kt @@ -1,6 +1,6 @@ package io.sentry.backpressure -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ISentryExecutorService import io.sentry.SentryOptions import io.sentry.backpressure.BackpressureMonitor.MAX_DOWNSAMPLE_FACTOR @@ -17,13 +17,13 @@ class BackpressureMonitorTest { class Fixture { val options = SentryOptions() - val hub = mock() + val scopes = mock() val executor = mock() fun getSut(): BackpressureMonitor { options.executorService = executor whenever(executor.isClosed).thenReturn(false) whenever(executor.schedule(any(), any())).thenReturn(mock>()) - return BackpressureMonitor(options, hub) + return BackpressureMonitor(options, scopes) } } @@ -38,7 +38,7 @@ class BackpressureMonitorTest { @Test fun `downsampleFactor increases with negative health checks up to max`() { val sut = fixture.getSut() - whenever(fixture.hub.isHealthy).thenReturn(false) + whenever(fixture.scopes.isHealthy).thenReturn(false) assertEquals(0, sut.downsampleFactor) (1..MAX_DOWNSAMPLE_FACTOR).forEach { i -> @@ -54,13 +54,13 @@ class BackpressureMonitorTest { @Test fun `downsampleFactor goes back to 0 after positive health check`() { val sut = fixture.getSut() - whenever(fixture.hub.isHealthy).thenReturn(false) + whenever(fixture.scopes.isHealthy).thenReturn(false) assertEquals(0, sut.downsampleFactor) sut.checkHealth() assertEquals(1, sut.downsampleFactor) - whenever(fixture.hub.isHealthy).thenReturn(true) + whenever(fixture.scopes.isHealthy).thenReturn(true) sut.checkHealth() assertEquals(0, sut.downsampleFactor) } diff --git a/sentry/src/test/java/io/sentry/clientreport/ClientReportTest.kt b/sentry/src/test/java/io/sentry/clientreport/ClientReportTest.kt index b4615cac76..d27e5c0228 100644 --- a/sentry/src/test/java/io/sentry/clientreport/ClientReportTest.kt +++ b/sentry/src/test/java/io/sentry/clientreport/ClientReportTest.kt @@ -7,7 +7,7 @@ import io.sentry.DataCategory import io.sentry.DateUtils import io.sentry.EventProcessor import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.NoOpLogger import io.sentry.ProfilingTraceData import io.sentry.Sentry @@ -47,9 +47,9 @@ class ClientReportTest { @Test fun `lost envelope can be recorded`() { givenClientReportRecorder() - val hub = mock() - whenever(hub.options).thenReturn(opts) - val transaction = SentryTracer(TransactionContext("name", "op"), hub) + val scopes = mock() + whenever(scopes.options).thenReturn(opts) + val transaction = SentryTracer(TransactionContext("name", "op"), scopes) val lostClientReport = ClientReport( DateUtils.getCurrentDateTime(), diff --git a/sentry/src/test/java/io/sentry/instrumentation/file/FileIOSpanManagerTest.kt b/sentry/src/test/java/io/sentry/instrumentation/file/FileIOSpanManagerTest.kt index 00c89f27be..f6271b5b5e 100644 --- a/sentry/src/test/java/io/sentry/instrumentation/file/FileIOSpanManagerTest.kt +++ b/sentry/src/test/java/io/sentry/instrumentation/file/FileIOSpanManagerTest.kt @@ -1,6 +1,6 @@ package io.sentry.instrumentation.file -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ISpan import io.sentry.ITransaction import io.sentry.util.PlatformTestManipulator @@ -20,25 +20,25 @@ class FileIOSpanManagerTest { @Test fun `startSpan uses transaction on Android platform`() { - val hub = mock() + val scopes = mock() val transaction = mock() - whenever(hub.transaction).thenReturn(transaction) + whenever(scopes.transaction).thenReturn(transaction) PlatformTestManipulator.pretendIsAndroid(true) - FileIOSpanManager.startSpan(hub, "op.read") + FileIOSpanManager.startSpan(scopes, "op.read") verify(transaction).startChild(any()) } @Test fun `startSpan uses last span on non-Android platforms`() { - val hub = mock() + val scopes = mock() val span = mock() - whenever(hub.span).thenReturn(span) + whenever(scopes.span).thenReturn(span) PlatformTestManipulator.pretendIsAndroid(false) - FileIOSpanManager.startSpan(hub, "op.read") + FileIOSpanManager.startSpan(scopes, "op.read") verify(span).startChild(any()) } } diff --git a/sentry/src/test/java/io/sentry/instrumentation/file/SentryFileInputStreamTest.kt b/sentry/src/test/java/io/sentry/instrumentation/file/SentryFileInputStreamTest.kt index 5e27eb451d..063b6d6428 100644 --- a/sentry/src/test/java/io/sentry/instrumentation/file/SentryFileInputStreamTest.kt +++ b/sentry/src/test/java/io/sentry/instrumentation/file/SentryFileInputStreamTest.kt @@ -1,6 +1,6 @@ package io.sentry.instrumentation.file -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryOptions import io.sentry.SentryTracer import io.sentry.SpanDataConvention @@ -29,7 +29,7 @@ import kotlin.test.assertTrue class SentryFileInputStreamTest { class Fixture { - val hub = mock() + val scopes = mock() lateinit var sentryTracer: SentryTracer private val options = SentryOptions() @@ -40,21 +40,21 @@ class SentryFileInputStreamTest { sendDefaultPii: Boolean = false ): SentryFileInputStream { tmpFile?.writeText("Text") - whenever(hub.options).thenReturn( + whenever(scopes.options).thenReturn( options.apply { isSendDefaultPii = sendDefaultPii mainThreadChecker = MainThreadChecker.getInstance() addInAppInclude("org.junit") } ) - sentryTracer = SentryTracer(TransactionContext("name", "op"), hub) + sentryTracer = SentryTracer(TransactionContext("name", "op"), scopes) if (activeTransaction) { - whenever(hub.span).thenReturn(sentryTracer) + whenever(scopes.span).thenReturn(sentryTracer) } return if (fileDescriptor == null) { - SentryFileInputStream(tmpFile, hub) + SentryFileInputStream(tmpFile, scopes) } else { - SentryFileInputStream(fileDescriptor, hub) + SentryFileInputStream(fileDescriptor, scopes) } } @@ -62,13 +62,13 @@ class SentryFileInputStreamTest { tmpFile: File? = null, delegate: FileInputStream ): SentryFileInputStream { - whenever(hub.options).thenReturn(options) - sentryTracer = SentryTracer(TransactionContext("name", "op"), hub) - whenever(hub.span).thenReturn(sentryTracer) + whenever(scopes.options).thenReturn(options) + sentryTracer = SentryTracer(TransactionContext("name", "op"), scopes) + whenever(scopes.span).thenReturn(sentryTracer) return SentryFileInputStream.Factory.create( delegate, tmpFile, - hub + scopes ) as SentryFileInputStream } } diff --git a/sentry/src/test/java/io/sentry/instrumentation/file/SentryFileOutputStreamTest.kt b/sentry/src/test/java/io/sentry/instrumentation/file/SentryFileOutputStreamTest.kt index f6a09830c2..8b175adc2d 100644 --- a/sentry/src/test/java/io/sentry/instrumentation/file/SentryFileOutputStreamTest.kt +++ b/sentry/src/test/java/io/sentry/instrumentation/file/SentryFileOutputStreamTest.kt @@ -1,6 +1,6 @@ package io.sentry.instrumentation.file -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryOptions import io.sentry.SentryTracer import io.sentry.SpanDataConvention @@ -24,7 +24,7 @@ import kotlin.test.assertTrue class SentryFileOutputStreamTest { class Fixture { - val hub = mock() + val scopes = mock() lateinit var sentryTracer: SentryTracer internal fun getSut( @@ -32,17 +32,17 @@ class SentryFileOutputStreamTest { activeTransaction: Boolean = true, append: Boolean = false ): SentryFileOutputStream { - whenever(hub.options).thenReturn( + whenever(scopes.options).thenReturn( SentryOptions().apply { mainThreadChecker = MainThreadChecker.getInstance() addInAppInclude("org.junit") } ) - sentryTracer = SentryTracer(TransactionContext("name", "op"), hub) + sentryTracer = SentryTracer(TransactionContext("name", "op"), scopes) if (activeTransaction) { - whenever(hub.span).thenReturn(sentryTracer) + whenever(scopes.span).thenReturn(sentryTracer) } - return SentryFileOutputStream(tmpFile, append, hub) + return SentryFileOutputStream(tmpFile, append, scopes) } } diff --git a/sentry/src/test/java/io/sentry/instrumentation/file/SentryFileReaderTest.kt b/sentry/src/test/java/io/sentry/instrumentation/file/SentryFileReaderTest.kt index 2485579e7a..38781d718b 100644 --- a/sentry/src/test/java/io/sentry/instrumentation/file/SentryFileReaderTest.kt +++ b/sentry/src/test/java/io/sentry/instrumentation/file/SentryFileReaderTest.kt @@ -1,6 +1,6 @@ package io.sentry.instrumentation.file -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryOptions import io.sentry.SentryTracer import io.sentry.SpanDataConvention @@ -17,7 +17,7 @@ import kotlin.test.assertEquals class SentryFileReaderTest { class Fixture { - val hub = mock() + val scopes = mock() lateinit var sentryTracer: SentryTracer internal fun getSut( @@ -25,16 +25,16 @@ class SentryFileReaderTest { activeTransaction: Boolean = true ): SentryFileReader { tmpFile.writeText("TEXT") - whenever(hub.options).thenReturn( + whenever(scopes.options).thenReturn( SentryOptions().apply { mainThreadChecker = MainThreadChecker.getInstance() } ) - sentryTracer = SentryTracer(TransactionContext("name", "op"), hub) + sentryTracer = SentryTracer(TransactionContext("name", "op"), scopes) if (activeTransaction) { - whenever(hub.span).thenReturn(sentryTracer) + whenever(scopes.span).thenReturn(sentryTracer) } - return SentryFileReader(tmpFile, hub) + return SentryFileReader(tmpFile, scopes) } } diff --git a/sentry/src/test/java/io/sentry/instrumentation/file/SentryFileWriterTest.kt b/sentry/src/test/java/io/sentry/instrumentation/file/SentryFileWriterTest.kt index f0738d8725..8f3d96b4d7 100644 --- a/sentry/src/test/java/io/sentry/instrumentation/file/SentryFileWriterTest.kt +++ b/sentry/src/test/java/io/sentry/instrumentation/file/SentryFileWriterTest.kt @@ -1,6 +1,6 @@ package io.sentry.instrumentation.file -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryOptions import io.sentry.SentryTracer import io.sentry.SpanDataConvention @@ -17,7 +17,7 @@ import kotlin.test.assertEquals class SentryFileWriterTest { class Fixture { - val hub = mock() + val scopes = mock() lateinit var sentryTracer: SentryTracer internal fun getSut( @@ -25,16 +25,16 @@ class SentryFileWriterTest { activeTransaction: Boolean = true, append: Boolean = false ): SentryFileWriter { - whenever(hub.options).thenReturn( + whenever(scopes.options).thenReturn( SentryOptions().apply { mainThreadChecker = MainThreadChecker.getInstance() } ) - sentryTracer = SentryTracer(TransactionContext("name", "op"), hub) + sentryTracer = SentryTracer(TransactionContext("name", "op"), scopes) if (activeTransaction) { - whenever(hub.span).thenReturn(sentryTracer) + whenever(scopes.span).thenReturn(sentryTracer) } - return SentryFileWriter(tmpFile, append, hub) + return SentryFileWriter(tmpFile, append, scopes) } } diff --git a/sentry/src/test/java/io/sentry/internal/SpotlightIntegrationTest.kt b/sentry/src/test/java/io/sentry/internal/SpotlightIntegrationTest.kt index 73aa339f26..0a91bec562 100644 --- a/sentry/src/test/java/io/sentry/internal/SpotlightIntegrationTest.kt +++ b/sentry/src/test/java/io/sentry/internal/SpotlightIntegrationTest.kt @@ -1,6 +1,6 @@ package io.sentry.internal -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryOptions import io.sentry.SentryOptions.BeforeEnvelopeCallback import io.sentry.SpotlightIntegration @@ -19,7 +19,7 @@ class SpotlightIntegrationTest { } val spotlight = SpotlightIntegration() - spotlight.register(mock(), options) + spotlight.register(mock(), options) assertNull(options.beforeEnvelopeCallback) } @@ -33,7 +33,7 @@ class SpotlightIntegrationTest { } val spotlight = SpotlightIntegration() - spotlight.register(mock(), options) + spotlight.register(mock(), options) assertEquals(envelopeCallback, options.beforeEnvelopeCallback) } @@ -45,7 +45,7 @@ class SpotlightIntegrationTest { } val spotlight = SpotlightIntegration() - spotlight.register(mock(), options) + spotlight.register(mock(), options) assertEquals(options.beforeEnvelopeCallback, spotlight) spotlight.close() @@ -71,7 +71,7 @@ class SpotlightIntegrationTest { } val spotlight = SpotlightIntegration() - spotlight.register(mock(), options) + spotlight.register(mock(), options) assertEquals("http://example.com:1234/stream", spotlight.spotlightConnectionUrl) } diff --git a/sentry/src/test/java/io/sentry/protocol/SentrySpanTest.kt b/sentry/src/test/java/io/sentry/protocol/SentrySpanTest.kt index 27499be0a0..d67b0186be 100644 --- a/sentry/src/test/java/io/sentry/protocol/SentrySpanTest.kt +++ b/sentry/src/test/java/io/sentry/protocol/SentrySpanTest.kt @@ -1,6 +1,6 @@ package io.sentry.protocol -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryLongDate import io.sentry.SentryTracer import io.sentry.Span @@ -19,7 +19,7 @@ class SentrySpanTest { val span = Span( TransactionContext("name", "op"), mock(), - mock(), + mock(), SentryLongDate(1000000), SpanOptions() ) diff --git a/sentry/src/test/java/io/sentry/transport/RateLimiterTest.kt b/sentry/src/test/java/io/sentry/transport/RateLimiterTest.kt index d9e217b0ac..2b1be98611 100644 --- a/sentry/src/test/java/io/sentry/transport/RateLimiterTest.kt +++ b/sentry/src/test/java/io/sentry/transport/RateLimiterTest.kt @@ -4,7 +4,7 @@ import io.sentry.Attachment import io.sentry.CheckIn import io.sentry.CheckInStatus import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ISerializer import io.sentry.NoOpLogger import io.sentry.ProfilingTraceData @@ -80,10 +80,10 @@ class RateLimiterTest { fun `parse X-Sentry-Rate-Limit and set its values and retry after should be true`() { val rateLimiter = fixture.getSUT() whenever(fixture.currentDateProvider.currentTimeMillis).thenReturn(0) - val hub: IHub = mock() - whenever(hub.options).thenReturn(SentryOptions()) + val scopes: IScopes = mock() + whenever(scopes.options).thenReturn(SentryOptions()) val eventItem = SentryEnvelopeItem.fromEvent(fixture.serializer, SentryEvent()) - val transaction = SentryTransaction(SentryTracer(TransactionContext("name", "op"), hub)) + val transaction = SentryTransaction(SentryTracer(TransactionContext("name", "op"), scopes)) val transactionItem = SentryEnvelopeItem.fromEvent(fixture.serializer, transaction) val envelope = SentryEnvelope(SentryEnvelopeHeader(), arrayListOf(eventItem, transactionItem)) @@ -97,10 +97,10 @@ class RateLimiterTest { fun `parse X-Sentry-Rate-Limit and set its values and retry after should be false`() { val rateLimiter = fixture.getSUT() whenever(fixture.currentDateProvider.currentTimeMillis).thenReturn(0, 0, 1001) - val hub: IHub = mock() - whenever(hub.options).thenReturn(SentryOptions()) + val scopes: IScopes = mock() + whenever(scopes.options).thenReturn(SentryOptions()) val eventItem = SentryEnvelopeItem.fromEvent(fixture.serializer, SentryEvent()) - val transaction = SentryTransaction(SentryTracer(TransactionContext("name", "op"), hub)) + val transaction = SentryTransaction(SentryTracer(TransactionContext("name", "op"), scopes)) val transactionItem = SentryEnvelopeItem.fromEvent(fixture.serializer, transaction) val envelope = SentryEnvelope(SentryEnvelopeHeader(), arrayListOf(eventItem, transactionItem)) @@ -191,9 +191,9 @@ class RateLimiterTest { it.setName("John Me") } ) - val hub = mock() - whenever(hub.options).thenReturn(SentryOptions()) - val transaction = SentryTracer(TransactionContext("name", "op"), hub) + val scopes = mock() + whenever(scopes.options).thenReturn(SentryOptions()) + val transaction = SentryTracer(TransactionContext("name", "op"), scopes) val sessionItem = SentryEnvelopeItem.fromSession(fixture.serializer, Session("123", User(), "env", "release")) val attachmentItem = SentryEnvelopeItem.fromAttachment(fixture.serializer, NoOpLogger.getInstance(), Attachment("{ \"number\": 10 }".toByteArray(), "log.json"), 1000) @@ -219,8 +219,8 @@ class RateLimiterTest { @Test fun `records only dropped items as lost`() { val rateLimiter = fixture.getSUT() - val hub = mock() - whenever(hub.options).thenReturn(SentryOptions()) + val scopes = mock() + whenever(scopes.options).thenReturn(SentryOptions()) val eventItem = SentryEnvelopeItem.fromEvent(fixture.serializer, SentryEvent()) val userFeedbackItem = SentryEnvelopeItem.fromUserFeedback( @@ -233,7 +233,7 @@ class RateLimiterTest { it.setName("John Me") } ) - val transaction = SentryTracer(TransactionContext("name", "op"), hub) + val transaction = SentryTracer(TransactionContext("name", "op"), scopes) val profileItem = SentryEnvelopeItem.fromProfilingTrace(ProfilingTraceData(File(""), transaction), 1000, fixture.serializer) val sessionItem = SentryEnvelopeItem.fromSession(fixture.serializer, Session("123", User(), "env", "release")) val attachmentItem = SentryEnvelopeItem.fromAttachment(fixture.serializer, NoOpLogger.getInstance(), Attachment("{ \"number\": 10 }".toByteArray(), "log.json"), 1000) @@ -253,12 +253,12 @@ class RateLimiterTest { @Test fun `drop profile items as lost`() { val rateLimiter = fixture.getSUT() - val hub = mock() - whenever(hub.options).thenReturn(SentryOptions()) + val scopes = mock() + whenever(scopes.options).thenReturn(SentryOptions()) val eventItem = SentryEnvelopeItem.fromEvent(fixture.serializer, SentryEvent()) val f = File.createTempFile("test", "trace") - val transaction = SentryTracer(TransactionContext("name", "op"), hub) + val transaction = SentryTracer(TransactionContext("name", "op"), scopes) val profileItem = SentryEnvelopeItem.fromProfilingTrace(ProfilingTraceData(f, transaction), 1000, fixture.serializer) val envelope = SentryEnvelope(SentryEnvelopeHeader(), arrayListOf(eventItem, profileItem)) diff --git a/sentry/src/test/java/io/sentry/util/CheckInUtilsTest.kt b/sentry/src/test/java/io/sentry/util/CheckInUtilsTest.kt index a285cd5832..9f330348b0 100644 --- a/sentry/src/test/java/io/sentry/util/CheckInUtilsTest.kt +++ b/sentry/src/test/java/io/sentry/util/CheckInUtilsTest.kt @@ -1,7 +1,8 @@ package io.sentry.util import io.sentry.CheckInStatus -import io.sentry.IHub +import io.sentry.HubScopesWrapper +import io.sentry.IScopes import io.sentry.MonitorConfig import io.sentry.MonitorSchedule import io.sentry.MonitorScheduleUnit @@ -56,30 +57,31 @@ class CheckInUtilsTest { @Test fun `sends check-in for wrapped supplier`() { Mockito.mockStatic(Sentry::class.java).use { sentry -> - val hub = mock() - sentry.`when` { Sentry.getCurrentHub() }.thenReturn(hub) - whenever(hub.options).thenReturn(SentryOptions()) + val scopes = mock() + sentry.`when` { Sentry.getCurrentScopes() }.thenReturn(scopes) + sentry.`when` { Sentry.getCurrentHub() }.thenReturn(HubScopesWrapper(scopes)) + whenever(scopes.options).thenReturn(SentryOptions()) val returnValue = CheckInUtils.withCheckIn("monitor-1") { return@withCheckIn "test1" } assertEquals("test1", returnValue) - inOrder(hub) { - verify(hub).pushScope() - verify(hub).configureScope(any()) - verify(hub).captureCheckIn( + inOrder(scopes) { + verify(scopes).pushScope() + verify(scopes).configureScope(any()) + verify(scopes).captureCheckIn( check { assertEquals("monitor-1", it.monitorSlug) assertEquals(CheckInStatus.IN_PROGRESS.apiName(), it.status) } ) - verify(hub).captureCheckIn( + verify(scopes).captureCheckIn( check { assertEquals("monitor-1", it.monitorSlug) assertEquals(CheckInStatus.OK.apiName(), it.status) } ) - verify(hub).popScope() + verify(scopes).popScope() } } } @@ -87,8 +89,9 @@ class CheckInUtilsTest { @Test fun `sends check-in for wrapped supplier with exception`() { Mockito.mockStatic(Sentry::class.java).use { sentry -> - val hub = mock() - sentry.`when` { Sentry.getCurrentHub() }.thenReturn(hub) + val scopes = mock() + sentry.`when` { Sentry.getCurrentScopes() }.thenReturn(scopes) + sentry.`when` { Sentry.getCurrentHub() }.thenReturn(HubScopesWrapper(scopes)) try { CheckInUtils.withCheckIn("monitor-1") { @@ -99,22 +102,22 @@ class CheckInUtilsTest { assertEquals("thrown on purpose", e.message) } - inOrder(hub) { - verify(hub).pushScope() - verify(hub).configureScope(any()) - verify(hub).captureCheckIn( + inOrder(scopes) { + verify(scopes).pushScope() + verify(scopes).configureScope(any()) + verify(scopes).captureCheckIn( check { assertEquals("monitor-1", it.monitorSlug) assertEquals(CheckInStatus.IN_PROGRESS.apiName(), it.status) } ) - verify(hub).captureCheckIn( + verify(scopes).captureCheckIn( check { assertEquals("monitor-1", it.monitorSlug) assertEquals(CheckInStatus.ERROR.apiName(), it.status) } ) - verify(hub).popScope() + verify(scopes).popScope() } } } @@ -122,32 +125,33 @@ class CheckInUtilsTest { @Test fun `sends check-in for wrapped supplier with upsert`() { Mockito.mockStatic(Sentry::class.java).use { sentry -> - val hub = mock() - sentry.`when` { Sentry.getCurrentHub() }.thenReturn(hub) - whenever(hub.options).thenReturn(SentryOptions()) + val scopes = mock() + sentry.`when` { Sentry.getCurrentScopes() }.thenReturn(scopes) + sentry.`when` { Sentry.getCurrentHub() }.thenReturn(HubScopesWrapper(scopes)) + whenever(scopes.options).thenReturn(SentryOptions()) val monitorConfig = MonitorConfig(MonitorSchedule.interval(7, MonitorScheduleUnit.DAY)) val returnValue = CheckInUtils.withCheckIn("monitor-1", monitorConfig) { "test1" } assertEquals("test1", returnValue) - inOrder(hub) { - verify(hub).pushScope() - verify(hub).configureScope(any()) - verify(hub).captureCheckIn( + inOrder(scopes) { + verify(scopes).pushScope() + verify(scopes).configureScope(any()) + verify(scopes).captureCheckIn( check { assertEquals("monitor-1", it.monitorSlug) assertSame(monitorConfig, it.monitorConfig) assertEquals(CheckInStatus.IN_PROGRESS.apiName(), it.status) } ) - verify(hub).captureCheckIn( + verify(scopes).captureCheckIn( check { assertEquals("monitor-1", it.monitorSlug) assertEquals(CheckInStatus.OK.apiName(), it.status) } ) - verify(hub).popScope() + verify(scopes).popScope() } } } @@ -155,9 +159,10 @@ class CheckInUtilsTest { @Test fun `sends check-in for wrapped supplier with upsert and thresholds`() { Mockito.mockStatic(Sentry::class.java).use { sentry -> - val hub = mock() - sentry.`when` { Sentry.getCurrentHub() }.thenReturn(hub) - whenever(hub.options).thenReturn(SentryOptions()) + val scopes = mock() + sentry.`when` { Sentry.getCurrentScopes() }.thenReturn(scopes) + sentry.`when` { Sentry.getCurrentHub() }.thenReturn(HubScopesWrapper(scopes)) + whenever(scopes.options).thenReturn(SentryOptions()) val monitorConfig = MonitorConfig(MonitorSchedule.interval(7, MonitorScheduleUnit.DAY)).apply { failureIssueThreshold = 10 recoveryThreshold = 20 @@ -167,23 +172,23 @@ class CheckInUtilsTest { } assertEquals("test1", returnValue) - inOrder(hub) { - verify(hub).pushScope() - verify(hub).configureScope(any()) - verify(hub).captureCheckIn( + inOrder(scopes) { + verify(scopes).pushScope() + verify(scopes).configureScope(any()) + verify(scopes).captureCheckIn( check { assertEquals("monitor-1", it.monitorSlug) assertSame(monitorConfig, it.monitorConfig) assertEquals(CheckInStatus.IN_PROGRESS.apiName(), it.status) } ) - verify(hub).captureCheckIn( + verify(scopes).captureCheckIn( check { assertEquals("monitor-1", it.monitorSlug) assertEquals(CheckInStatus.OK.apiName(), it.status) } ) - verify(hub).popScope() + verify(scopes).popScope() } } } @@ -191,9 +196,10 @@ class CheckInUtilsTest { @Test fun `sets defaults for MonitorConfig from SentryOptions`() { Mockito.mockStatic(Sentry::class.java).use { sentry -> - val hub = mock() - sentry.`when` { Sentry.getCurrentHub() }.thenReturn(hub) - whenever(hub.options).thenReturn( + val scopes = mock() + sentry.`when` { Sentry.getCurrentScopes() }.thenReturn(scopes) + sentry.`when` { Sentry.getCurrentHub() }.thenReturn(HubScopesWrapper(scopes)) + whenever(scopes.options).thenReturn( SentryOptions().apply { cron = SentryOptions.Cron().apply { defaultCheckinMargin = 20 @@ -218,9 +224,10 @@ class CheckInUtilsTest { @Test fun `defaults for MonitorConfig from SentryOptions can be overridden`() { Mockito.mockStatic(Sentry::class.java).use { sentry -> - val hub = mock() - sentry.`when` { Sentry.getCurrentHub() }.thenReturn(hub) - whenever(hub.options).thenReturn( + val scopes = mock() + sentry.`when` { Sentry.getCurrentScopes() }.thenReturn(scopes) + sentry.`when` { Sentry.getCurrentHub() }.thenReturn(HubScopesWrapper(scopes)) + whenever(scopes.options).thenReturn( SentryOptions().apply { cron = SentryOptions.Cron().apply { defaultCheckinMargin = 20 diff --git a/sentry/src/test/java/io/sentry/util/TracingUtilsTest.kt b/sentry/src/test/java/io/sentry/util/TracingUtilsTest.kt index e38410641e..b3f640aeec 100644 --- a/sentry/src/test/java/io/sentry/util/TracingUtilsTest.kt +++ b/sentry/src/test/java/io/sentry/util/TracingUtilsTest.kt @@ -1,7 +1,7 @@ package io.sentry.util import io.sentry.Baggage -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.NoOpSpan import io.sentry.Scope import io.sentry.ScopeCallback @@ -29,18 +29,18 @@ class TracingUtilsTest { val options = SentryOptions().apply { dsn = "https://key@sentry.io/proj" } - val hub = mock() + val scopes = mock() val scope = Scope(options) lateinit var span: Span val preExistingBaggage = listOf("some-baggage-key=some-baggage-value") fun setup() { - whenever(hub.options).thenReturn(options) - doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(hub).configureScope(any()) + whenever(scopes.options).thenReturn(options) + doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(scopes).configureScope(any()) span = Span( TransactionContext("name", "op", TracesSamplingDecision(true)), - SentryTracer(TransactionContext("name", "op", TracesSamplingDecision(true)), hub), - hub, + SentryTracer(TransactionContext("name", "op", TracesSamplingDecision(true)), scopes), + scopes, null, SpanOptions() ) @@ -53,7 +53,7 @@ class TracingUtilsTest { fun `returns headers if allowed from scope without span`() { fixture.setup() - val headers = TracingUtils.traceIfAllowed(fixture.hub, "https://sentry.io/hello", fixture.preExistingBaggage, null) + val headers = TracingUtils.traceIfAllowed(fixture.scopes, "https://sentry.io/hello", fixture.preExistingBaggage, null) assertNotNull(headers) assertNotNull(headers.baggageHeader) @@ -68,7 +68,7 @@ class TracingUtilsTest { fun `returns headers if allowed from scope if span is noop`() { fixture.setup() - val headers = TracingUtils.traceIfAllowed(fixture.hub, "https://sentry.io/hello", fixture.preExistingBaggage, NoOpSpan.getInstance()) + val headers = TracingUtils.traceIfAllowed(fixture.scopes, "https://sentry.io/hello", fixture.preExistingBaggage, NoOpSpan.getInstance()) assertNotNull(headers) assertNotNull(headers.baggageHeader) @@ -83,7 +83,7 @@ class TracingUtilsTest { fixture.scope.propagationContext.baggage = Baggage.fromHeader("sentry-public_key=502f25099c204a2fbf4cb16edc5975d1,sentry-sample_rate=1,sentry-trace_id=2722d9f6ec019ade60c776169d9a8904,sentry-transaction=HTTP%20GET").also { it.freeze() } fixture.setup() - val headers = TracingUtils.traceIfAllowed(fixture.hub, "https://sentry.io/hello", fixture.preExistingBaggage, null) + val headers = TracingUtils.traceIfAllowed(fixture.scopes, "https://sentry.io/hello", fixture.preExistingBaggage, null) assertNotNull(headers) assertNotNull(headers.baggageHeader) @@ -98,7 +98,7 @@ class TracingUtilsTest { fun `returns headers if allowed from span`() { fixture.setup() - val headers = TracingUtils.traceIfAllowed(fixture.hub, "https://sentry.io/hello", fixture.preExistingBaggage, fixture.span) + val headers = TracingUtils.traceIfAllowed(fixture.scopes, "https://sentry.io/hello", fixture.preExistingBaggage, fixture.span) assertNotNull(headers) assertNotNull(headers.baggageHeader) @@ -112,7 +112,7 @@ class TracingUtilsTest { fixture.options.isTraceSampling = false fixture.setup() - val headers = TracingUtils.traceIfAllowed(fixture.hub, "https://sentry.io/hello", fixture.preExistingBaggage, null) + val headers = TracingUtils.traceIfAllowed(fixture.scopes, "https://sentry.io/hello", fixture.preExistingBaggage, null) assertNull(headers) } @@ -122,7 +122,7 @@ class TracingUtilsTest { fixture.options.isTraceSampling = false fixture.setup() - val headers = TracingUtils.traceIfAllowed(fixture.hub, "https://sentry.io/hello", fixture.preExistingBaggage, fixture.span) + val headers = TracingUtils.traceIfAllowed(fixture.scopes, "https://sentry.io/hello", fixture.preExistingBaggage, fixture.span) assertNull(headers) } @@ -132,7 +132,7 @@ class TracingUtilsTest { fixture.options.setTracePropagationTargets(listOf("some-host-that-does-not-exist")) fixture.setup() - val headers = TracingUtils.traceIfAllowed(fixture.hub, "https://sentry.io/hello", fixture.preExistingBaggage, null) + val headers = TracingUtils.traceIfAllowed(fixture.scopes, "https://sentry.io/hello", fixture.preExistingBaggage, null) assertNull(headers) } @@ -142,7 +142,7 @@ class TracingUtilsTest { fixture.options.setTracePropagationTargets(listOf("some-host-that-does-not-exist")) fixture.setup() - val headers = TracingUtils.traceIfAllowed(fixture.hub, "https://sentry.io/hello", fixture.preExistingBaggage, fixture.span) + val headers = TracingUtils.traceIfAllowed(fixture.scopes, "https://sentry.io/hello", fixture.preExistingBaggage, fixture.span) assertNull(headers) } @@ -153,7 +153,7 @@ class TracingUtilsTest { val propagationContextBefore = fixture.scope.propagationContext - TracingUtils.startNewTrace(fixture.hub) + TracingUtils.startNewTrace(fixture.scopes) assertNotEquals(propagationContextBefore.traceId, fixture.scope.propagationContext.traceId) assertNotEquals(propagationContextBefore.spanId, fixture.scope.propagationContext.spanId) From ce615f4274bb37d731af4acf68e9d92a56660489 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Tue, 2 Apr 2024 14:15:56 +0200 Subject: [PATCH 05/28] Replace `IHub` with `IScopes` in android core --- .../api/sentry-android-core.api | 28 ++--- .../core/ActivityBreadcrumbsIntegration.java | 17 +-- .../core/ActivityLifecycleIntegration.java | 32 +++--- .../core/AndroidTransactionProfiler.java | 12 +- .../sentry/android/core/AnrIntegration.java | 19 +-- .../sentry/android/core/AnrV2Integration.java | 14 +-- .../AppComponentsBreadcrumbsIntegration.java | 16 +-- .../android/core/AppLifecycleIntegration.java | 14 +-- .../core/CurrentActivityIntegration.java | 4 +- .../core/EnvelopeFileObserverIntegration.java | 14 ++- .../android/core/InternalSentrySdk.java | 24 ++-- .../sentry/android/core/LifecycleWatcher.java | 22 ++-- .../sentry/android/core/NdkIntegration.java | 9 +- .../core/NetworkBreadcrumbsIntegration.java | 21 ++-- .../PhoneStateBreadcrumbsIntegration.java | 20 ++-- .../core/SendCachedEnvelopeIntegration.java | 20 ++-- .../io/sentry/android/core/SentryAndroid.java | 11 +- .../SystemEventsBreadcrumbsIntegration.java | 20 ++-- .../TempSensorBreadcrumbsIntegration.java | 12 +- .../core/UserInteractionIntegration.java | 12 +- .../gestures/SentryGestureListener.java | 18 +-- .../core/AndroidTransactionProfilerTest.kt | 12 +- .../sentry/android/core/AnrIntegrationTest.kt | 28 ++--- .../android/core/AnrV2IntegrationTest.kt | 90 +++++++-------- ...AppComponentsBreadcrumbsIntegrationTest.kt | 48 ++++---- .../core/AppLifecycleIntegrationTest.kt | 16 +-- .../core/CurrentActivityIntegrationTest.kt | 6 +- .../core/DefaultAndroidEventProcessorTest.kt | 8 +- .../EnvelopeFileObserverIntegrationTest.kt | 20 ++-- .../android/core/LifecycleWatcherTest.kt | 48 ++++---- .../sentry/android/core/NdkIntegrationTest.kt | 22 ++-- .../core/NetworkBreadcrumbsIntegrationTest.kt | 108 +++++++++--------- .../PerformanceAndroidEventProcessorTest.kt | 20 ++-- .../PhoneStateBreadcrumbsIntegrationTest.kt | 38 +++--- .../core/SendCachedEnvelopeIntegrationTest.kt | 30 ++--- .../SystemEventsBreadcrumbsIntegrationTest.kt | 24 ++-- .../TempSensorBreadcrumbsIntegrationTest.kt | 32 +++--- .../SentryGestureListenerClickTest.kt | 22 ++-- .../SentryGestureListenerScrollTest.kt | 26 ++--- .../SentryGestureListenerTracingTest.kt | 58 +++++----- 40 files changed, 511 insertions(+), 504 deletions(-) diff --git a/sentry-android-core/api/sentry-android-core.api b/sentry-android-core/api/sentry-android-core.api index 8eb017346d..2afe788ef8 100644 --- a/sentry-android-core/api/sentry-android-core.api +++ b/sentry-android-core/api/sentry-android-core.api @@ -8,7 +8,7 @@ public final class io/sentry/android/core/ActivityBreadcrumbsIntegration : andro public fun onActivitySaveInstanceState (Landroid/app/Activity;Landroid/os/Bundle;)V public fun onActivityStarted (Landroid/app/Activity;)V public fun onActivityStopped (Landroid/app/Activity;)V - public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/android/core/ActivityFramesTracker { @@ -33,7 +33,7 @@ public final class io/sentry/android/core/ActivityLifecycleIntegration : android public fun onActivitySaveInstanceState (Landroid/app/Activity;Landroid/os/Bundle;)V public fun onActivityStarted (Landroid/app/Activity;)V public fun onActivityStopped (Landroid/app/Activity;)V - public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/android/core/AndroidCpuCollector : io/sentry/IPerformanceSnapshotCollector { @@ -87,7 +87,7 @@ public class io/sentry/android/core/AndroidProfiler$ProfileStartData { public final class io/sentry/android/core/AnrIntegration : io/sentry/Integration, java/io/Closeable { public fun (Landroid/content/Context;)V public fun close ()V - public final fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public final fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/android/core/AnrIntegrationFactory { @@ -104,7 +104,7 @@ public final class io/sentry/android/core/AnrV2EventProcessor : io/sentry/Backfi public class io/sentry/android/core/AnrV2Integration : io/sentry/Integration, java/io/Closeable { public fun (Landroid/content/Context;)V public fun close ()V - public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/android/core/AnrV2Integration$AnrV2Hint : io/sentry/hints/BlockingFlushHint, io/sentry/hints/AbnormalExit, io/sentry/hints/Backfillable { @@ -123,13 +123,13 @@ public final class io/sentry/android/core/AppComponentsBreadcrumbsIntegration : public fun onConfigurationChanged (Landroid/content/res/Configuration;)V public fun onLowMemory ()V public fun onTrimMemory (I)V - public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/android/core/AppLifecycleIntegration : io/sentry/Integration, java/io/Closeable { public fun ()V public fun close ()V - public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/android/core/AppState { @@ -177,7 +177,7 @@ public final class io/sentry/android/core/CurrentActivityIntegration : android/a public fun onActivitySaveInstanceState (Landroid/app/Activity;Landroid/os/Bundle;)V public fun onActivityStarted (Landroid/app/Activity;)V public fun onActivityStopped (Landroid/app/Activity;)V - public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/android/core/DeviceInfoUtil { @@ -193,7 +193,7 @@ public abstract class io/sentry/android/core/EnvelopeFileObserverIntegration : i public fun ()V public fun close ()V public static fun getOutboxFileObserver ()Lio/sentry/android/core/EnvelopeFileObserverIntegration; - public final fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public final fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public abstract interface class io/sentry/android/core/IDebugImagesLoader { @@ -219,19 +219,19 @@ public final class io/sentry/android/core/NdkIntegration : io/sentry/Integration public static final field SENTRY_NDK_CLASS_NAME Ljava/lang/String; public fun (Ljava/lang/Class;)V public fun close ()V - public final fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public final fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/android/core/NetworkBreadcrumbsIntegration : io/sentry/Integration, java/io/Closeable { public fun (Landroid/content/Context;Lio/sentry/android/core/BuildInfoProvider;Lio/sentry/ILogger;)V public fun close ()V - public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/android/core/PhoneStateBreadcrumbsIntegration : io/sentry/Integration, java/io/Closeable { public fun (Landroid/content/Context;)V public fun close ()V - public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/android/core/ScreenshotEventProcessor : io/sentry/EventProcessor { @@ -360,7 +360,7 @@ public final class io/sentry/android/core/SystemEventsBreadcrumbsIntegration : i public fun (Landroid/content/Context;)V public fun (Landroid/content/Context;Ljava/util/List;)V public fun close ()V - public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/android/core/TempSensorBreadcrumbsIntegration : android/hardware/SensorEventListener, io/sentry/Integration, java/io/Closeable { @@ -368,7 +368,7 @@ public final class io/sentry/android/core/TempSensorBreadcrumbsIntegration : and public fun close ()V public fun onAccuracyChanged (Landroid/hardware/Sensor;I)V public fun onSensorChanged (Landroid/hardware/SensorEvent;)V - public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/android/core/UserInteractionIntegration : android/app/Application$ActivityLifecycleCallbacks, io/sentry/Integration, java/io/Closeable { @@ -381,7 +381,7 @@ public final class io/sentry/android/core/UserInteractionIntegration : android/a public fun onActivitySaveInstanceState (Landroid/app/Activity;Landroid/os/Bundle;)V public fun onActivityStarted (Landroid/app/Activity;)V public fun onActivityStopped (Landroid/app/Activity;)V - public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/android/core/ViewHierarchyEventProcessor : io/sentry/EventProcessor { diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/ActivityBreadcrumbsIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/ActivityBreadcrumbsIntegration.java index dc03abe808..4a5ca63717 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/ActivityBreadcrumbsIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/ActivityBreadcrumbsIntegration.java @@ -8,7 +8,7 @@ import android.os.Bundle; import io.sentry.Breadcrumb; import io.sentry.Hint; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.Integration; import io.sentry.SentryLevel; import io.sentry.SentryOptions; @@ -23,7 +23,7 @@ public final class ActivityBreadcrumbsIntegration implements Integration, Closeable, Application.ActivityLifecycleCallbacks { private final @NotNull Application application; - private @Nullable IHub hub; + private @Nullable IScopes scopes; private boolean enabled; public ActivityBreadcrumbsIntegration(final @NotNull Application application) { @@ -31,13 +31,13 @@ public ActivityBreadcrumbsIntegration(final @NotNull Application application) { } @Override - public void register(final @NotNull IHub hub, final @NotNull SentryOptions options) { + public void register(final @NotNull IScopes scopes, final @NotNull SentryOptions options) { final SentryAndroidOptions androidOptions = Objects.requireNonNull( (options instanceof SentryAndroidOptions) ? (SentryAndroidOptions) options : null, "SentryAndroidOptions is required"); - this.hub = Objects.requireNonNull(hub, "Hub is required"); + this.scopes = Objects.requireNonNull(scopes, "Scopes are required"); this.enabled = androidOptions.isEnableActivityLifecycleBreadcrumbs(); options .getLogger() @@ -54,8 +54,9 @@ public void register(final @NotNull IHub hub, final @NotNull SentryOptions optio public void close() throws IOException { if (enabled) { application.unregisterActivityLifecycleCallbacks(this); - if (hub != null) { - hub.getOptions() + if (scopes != null) { + scopes + .getOptions() .getLogger() .log(SentryLevel.DEBUG, "ActivityBreadcrumbsIntegration removed."); } @@ -100,7 +101,7 @@ public synchronized void onActivityDestroyed(final @NotNull Activity activity) { } private void addBreadcrumb(final @NotNull Activity activity, final @NotNull String state) { - if (hub == null) { + if (scopes == null) { return; } @@ -114,7 +115,7 @@ private void addBreadcrumb(final @NotNull Activity activity, final @NotNull Stri final Hint hint = new Hint(); hint.set(ANDROID_ACTIVITY, activity); - hub.addBreadcrumb(breadcrumb, hint); + scopes.addBreadcrumb(breadcrumb, hint); } private @NotNull String getActivityName(final @NotNull Activity activity) { diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/ActivityLifecycleIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/ActivityLifecycleIntegration.java index 1121a6bfe7..76bedae5d0 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/ActivityLifecycleIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/ActivityLifecycleIntegration.java @@ -12,8 +12,8 @@ import android.view.View; import androidx.annotation.NonNull; import io.sentry.FullyDisplayedReporter; -import io.sentry.IHub; import io.sentry.IScope; +import io.sentry.IScopes; import io.sentry.ISpan; import io.sentry.ITransaction; import io.sentry.Instrumenter; @@ -60,7 +60,7 @@ public final class ActivityLifecycleIntegration private final @NotNull Application application; private final @NotNull BuildInfoProvider buildInfoProvider; - private @Nullable IHub hub; + private @Nullable IScopes scopes; private @Nullable SentryAndroidOptions options; private boolean performanceEnabled = false; @@ -102,13 +102,13 @@ public ActivityLifecycleIntegration( } @Override - public void register(final @NotNull IHub hub, final @NotNull SentryOptions options) { + public void register(final @NotNull IScopes scopes, final @NotNull SentryOptions options) { this.options = Objects.requireNonNull( (options instanceof SentryAndroidOptions) ? (SentryAndroidOptions) options : null, "SentryAndroidOptions is required"); - this.hub = Objects.requireNonNull(hub, "Hub is required"); + this.scopes = Objects.requireNonNull(scopes, "Scopes are required"); performanceEnabled = isPerformanceEnabled(this.options); fullyDisplayedReporter = this.options.getFullyDisplayedReporter(); @@ -150,10 +150,10 @@ private void stopPreviousTransactions() { private void startTracing(final @NotNull Activity activity) { WeakReference weakActivity = new WeakReference<>(activity); - if (hub != null && !isRunningTransactionOrTrace(activity)) { + if (scopes != null && !isRunningTransactionOrTrace(activity)) { if (!performanceEnabled) { activitiesWithOngoingTransactions.put(activity, NoOpTransaction.getInstance()); - TracingUtils.startNewTrace(hub); + TracingUtils.startNewTrace(scopes); } else { // as we allow a single transaction running on the bound Scope, we finish the previous ones stopPreviousTransactions(); @@ -225,7 +225,7 @@ private void startTracing(final @NotNull Activity activity) { // we can only bind to the scope if there's no running transaction ITransaction transaction = - hub.startTransaction( + scopes.startTransaction( new TransactionContext( activityName, TransactionNameSource.COMPONENT, @@ -278,7 +278,7 @@ private void startTracing(final @NotNull Activity activity) { } // lets bind to the scope so other integrations can pick it up - hub.configureScope( + scopes.configureScope( scope -> { applyScope(scope, transaction); }); @@ -356,10 +356,10 @@ private void finishTransaction( status = SpanStatus.OK; } transaction.finish(status); - if (hub != null) { + if (scopes != null) { // make sure to remove the transaction from scope, as it may contain running children, // therefore `finish` method will not remove it from scope - hub.configureScope( + scopes.configureScope( scope -> { clearScope(scope, transaction); }); @@ -371,9 +371,9 @@ private void finishTransaction( public synchronized void onActivityCreated( final @NotNull Activity activity, final @Nullable Bundle savedInstanceState) { setColdStart(savedInstanceState); - if (hub != null) { + if (scopes != null) { final @Nullable String activityClassName = ClassUtil.getClassName(activity); - hub.configureScope(scope -> scope.setScreen(activityClassName)); + scopes.configureScope(scope -> scope.setScreen(activityClassName)); } startTracing(activity); final @Nullable ISpan ttfdSpan = ttfdSpanMap.get(activity); @@ -429,10 +429,10 @@ public void onActivityPrePaused(@NonNull Activity activity) { // well // this ensures any newly launched activity will not use the app start timestamp as txn start firstActivityCreated = true; - if (hub == null) { + if (scopes == null) { lastPausedTime = AndroidDateUtils.getCurrentSentryDateTime(); } else { - lastPausedTime = hub.getOptions().getDateProvider().now(); + lastPausedTime = scopes.getOptions().getDateProvider().now(); } } } @@ -445,10 +445,10 @@ public synchronized void onActivityPaused(final @NotNull Activity activity) { // well // this ensures any newly launched activity will not use the app start timestamp as txn start firstActivityCreated = true; - if (hub == null) { + if (scopes == null) { lastPausedTime = AndroidDateUtils.getCurrentSentryDateTime(); } else { - lastPausedTime = hub.getOptions().getDateProvider().now(); + lastPausedTime = scopes.getOptions().getDateProvider().now(); } } } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidTransactionProfiler.java b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidTransactionProfiler.java index 3abfe1306a..0d232a6ada 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidTransactionProfiler.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidTransactionProfiler.java @@ -9,15 +9,15 @@ import android.os.Build; import android.os.Process; import android.os.SystemClock; -import io.sentry.HubAdapter; -import io.sentry.IHub; import io.sentry.ILogger; +import io.sentry.IScopes; import io.sentry.ISentryExecutorService; import io.sentry.ITransaction; import io.sentry.ITransactionProfiler; import io.sentry.PerformanceCollectionData; import io.sentry.ProfilingTraceData; import io.sentry.ProfilingTransactionData; +import io.sentry.ScopesAdapter; import io.sentry.SentryLevel; import io.sentry.SentryOptions; import io.sentry.android.core.internal.util.CpuInfoUtils; @@ -46,8 +46,8 @@ final class AndroidTransactionProfiler implements ITransactionProfiler { private long profileStartCpuMillis; /** - * @deprecated please use a constructor that doesn't takes a {@link IHub} instead, as it would be - * ignored anyway. + * @deprecated please use a constructor that doesn't takes a {@link IScopes} instead, as it would + * be ignored anyway. */ @Deprecated public AndroidTransactionProfiler( @@ -55,7 +55,7 @@ public AndroidTransactionProfiler( final @NotNull SentryAndroidOptions sentryAndroidOptions, final @NotNull BuildInfoProvider buildInfoProvider, final @NotNull SentryFrameMetricsCollector frameMetricsCollector, - final @NotNull IHub hub) { + final @NotNull IScopes scopes) { this(context, sentryAndroidOptions, buildInfoProvider, frameMetricsCollector); } @@ -311,7 +311,7 @@ public void close() { currentProfilingTransactionData.getTraceId(), true, null, - HubAdapter.getInstance().getOptions()); + ScopesAdapter.getInstance().getOptions()); } else if (transactionsCounter != 0) { // in case the app start profiling is running, and it's not bound to a transaction, we still // stop profiling, but we also have to manually update the counter. diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/AnrIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/AnrIntegration.java index 0ad2c242da..90d53a3c9b 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/AnrIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/AnrIntegration.java @@ -5,7 +5,7 @@ import android.annotation.SuppressLint; import android.content.Context; import io.sentry.Hint; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.Integration; import io.sentry.SentryEvent; import io.sentry.SentryLevel; @@ -48,12 +48,13 @@ public AnrIntegration(final @NotNull Context context) { private static final @NotNull Object watchDogLock = new Object(); @Override - public final void register(final @NotNull IHub hub, final @NotNull SentryOptions options) { + public final void register(final @NotNull IScopes scopes, final @NotNull SentryOptions options) { this.options = Objects.requireNonNull(options, "SentryOptions is required"); - register(hub, (SentryAndroidOptions) options); + register(scopes, (SentryAndroidOptions) options); } - private void register(final @NotNull IHub hub, final @NotNull SentryAndroidOptions options) { + private void register( + final @NotNull IScopes scopes, final @NotNull SentryAndroidOptions options) { options .getLogger() .log(SentryLevel.DEBUG, "AnrIntegration enabled: %s", options.isAnrEnabled()); @@ -67,7 +68,7 @@ private void register(final @NotNull IHub hub, final @NotNull SentryAndroidOptio () -> { synchronized (startLock) { if (!isClosed) { - startAnrWatchdog(hub, options); + startAnrWatchdog(scopes, options); } } }); @@ -80,7 +81,7 @@ private void register(final @NotNull IHub hub, final @NotNull SentryAndroidOptio } private void startAnrWatchdog( - final @NotNull IHub hub, final @NotNull SentryAndroidOptions options) { + final @NotNull IScopes scopes, final @NotNull SentryAndroidOptions options) { synchronized (watchDogLock) { if (anrWatchDog == null) { options @@ -94,7 +95,7 @@ private void startAnrWatchdog( new ANRWatchDog( options.getAnrTimeoutIntervalMillis(), options.isAnrReportInDebug(), - error -> reportANR(hub, options, error), + error -> reportANR(scopes, options, error), options.getLogger(), context); anrWatchDog.start(); @@ -106,7 +107,7 @@ private void startAnrWatchdog( @TestOnly void reportANR( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull SentryAndroidOptions options, final @NotNull ApplicationNotResponding error) { options.getLogger().log(SentryLevel.INFO, "ANR triggered with message: %s", error.getMessage()); @@ -122,7 +123,7 @@ void reportANR( final AnrHint anrHint = new AnrHint(isAppInBackground); final Hint hint = HintUtils.createWithTypeCheckHint(anrHint); - hub.captureEvent(event, hint); + scopes.captureEvent(event, hint); } private @NotNull Throwable buildAnrThrowable( diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/AnrV2Integration.java b/sentry-android-core/src/main/java/io/sentry/android/core/AnrV2Integration.java index 669233bb09..152ceed322 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/AnrV2Integration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/AnrV2Integration.java @@ -9,8 +9,8 @@ import io.sentry.Attachment; import io.sentry.DateUtils; import io.sentry.Hint; -import io.sentry.IHub; import io.sentry.ILogger; +import io.sentry.IScopes; import io.sentry.Integration; import io.sentry.SentryEvent; import io.sentry.SentryLevel; @@ -69,7 +69,7 @@ public AnrV2Integration(final @NotNull Context context) { @SuppressLint("NewApi") // we do the check in the AnrIntegrationFactory @Override - public void register(@NotNull IHub hub, @NotNull SentryOptions options) { + public void register(@NotNull IScopes scopes, @NotNull SentryOptions options) { this.options = Objects.requireNonNull( (options instanceof SentryAndroidOptions) ? (SentryAndroidOptions) options : null, @@ -90,7 +90,7 @@ public void register(@NotNull IHub hub, @NotNull SentryOptions options) { try { options .getExecutorService() - .submit(new AnrProcessor(context, hub, this.options, dateProvider)); + .submit(new AnrProcessor(context, scopes, this.options, dateProvider)); } catch (Throwable e) { options.getLogger().log(SentryLevel.DEBUG, "Failed to start AnrProcessor.", e); } @@ -109,17 +109,17 @@ public void close() throws IOException { static class AnrProcessor implements Runnable { private final @NotNull Context context; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @NotNull SentryAndroidOptions options; private final long threshold; AnrProcessor( final @NotNull Context context, - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull SentryAndroidOptions options, final @NotNull ICurrentDateProvider dateProvider) { this.context = context; - this.hub = hub; + this.scopes = scopes; this.options = options; this.threshold = dateProvider.getCurrentTimeMillis() - NINETY_DAYS_THRESHOLD; } @@ -277,7 +277,7 @@ private void reportAsSentryEvent( } } - final @NotNull SentryId sentryId = hub.captureEvent(event, hint); + final @NotNull SentryId sentryId = scopes.captureEvent(event, hint); final boolean isEventDropped = sentryId.equals(SentryId.EMPTY_ID); if (!isEventDropped) { // Block until the event is flushed to disk and the last_reported_anr marker is updated diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/AppComponentsBreadcrumbsIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/AppComponentsBreadcrumbsIntegration.java index eef4707683..0d20dc7a90 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/AppComponentsBreadcrumbsIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/AppComponentsBreadcrumbsIntegration.java @@ -8,7 +8,7 @@ import android.content.res.Configuration; import io.sentry.Breadcrumb; import io.sentry.Hint; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.Integration; import io.sentry.SentryLevel; import io.sentry.SentryOptions; @@ -25,7 +25,7 @@ public final class AppComponentsBreadcrumbsIntegration implements Integration, Closeable, ComponentCallbacks2 { private final @NotNull Context context; - private @Nullable IHub hub; + private @Nullable IScopes scopes; private @Nullable SentryAndroidOptions options; public AppComponentsBreadcrumbsIntegration(final @NotNull Context context) { @@ -33,8 +33,8 @@ public AppComponentsBreadcrumbsIntegration(final @NotNull Context context) { } @Override - public void register(final @NotNull IHub hub, final @NotNull SentryOptions options) { - this.hub = Objects.requireNonNull(hub, "Hub is required"); + public void register(final @NotNull IScopes scopes, final @NotNull SentryOptions options) { + this.scopes = Objects.requireNonNull(scopes, "Scopes are required"); this.options = Objects.requireNonNull( (options instanceof SentryAndroidOptions) ? (SentryAndroidOptions) options : null, @@ -84,7 +84,7 @@ public void close() throws IOException { @SuppressWarnings("deprecation") @Override public void onConfigurationChanged(@NotNull Configuration newConfig) { - if (hub != null) { + if (scopes != null) { final Device.DeviceOrientation deviceOrientation = DeviceOrientations.getOrientation(context.getResources().getConfiguration().orientation); @@ -104,7 +104,7 @@ public void onConfigurationChanged(@NotNull Configuration newConfig) { final Hint hint = new Hint(); hint.set(ANDROID_CONFIGURATION, newConfig); - hub.addBreadcrumb(breadcrumb, hint); + scopes.addBreadcrumb(breadcrumb, hint); } } @@ -119,7 +119,7 @@ public void onTrimMemory(final int level) { } private void createLowMemoryBreadcrumb(final @Nullable Integer level) { - if (hub != null) { + if (scopes != null) { final Breadcrumb breadcrumb = new Breadcrumb(); if (level != null) { // only add breadcrumb if TRIM_MEMORY_BACKGROUND, TRIM_MEMORY_MODERATE or @@ -143,7 +143,7 @@ private void createLowMemoryBreadcrumb(final @Nullable Integer level) { breadcrumb.setMessage("Low memory"); breadcrumb.setData("action", "LOW_MEMORY"); breadcrumb.setLevel(SentryLevel.WARNING); - hub.addBreadcrumb(breadcrumb); + scopes.addBreadcrumb(breadcrumb); } } } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/AppLifecycleIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/AppLifecycleIntegration.java index 3e8fe6383f..8614a60061 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/AppLifecycleIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/AppLifecycleIntegration.java @@ -3,7 +3,7 @@ import static io.sentry.util.IntegrationUtils.addIntegrationToSdkVersion; import androidx.lifecycle.ProcessLifecycleOwner; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.Integration; import io.sentry.SentryLevel; import io.sentry.SentryOptions; @@ -32,8 +32,8 @@ public AppLifecycleIntegration() { } @Override - public void register(final @NotNull IHub hub, final @NotNull SentryOptions options) { - Objects.requireNonNull(hub, "Hub is required"); + public void register(final @NotNull IScopes scopes, final @NotNull SentryOptions options) { + Objects.requireNonNull(scopes, "Scopes are required"); this.options = Objects.requireNonNull( (options instanceof SentryAndroidOptions) ? (SentryAndroidOptions) options : null, @@ -59,11 +59,11 @@ public void register(final @NotNull IHub hub, final @NotNull SentryOptions optio Class.forName("androidx.lifecycle.DefaultLifecycleObserver"); Class.forName("androidx.lifecycle.ProcessLifecycleOwner"); if (AndroidMainThreadChecker.getInstance().isMainThread()) { - addObserver(hub); + addObserver(scopes); } else { // some versions of the androidx lifecycle-process require this to be executed on the main // thread. - handler.post(() -> addObserver(hub)); + handler.post(() -> addObserver(scopes)); } } catch (ClassNotFoundException e) { options @@ -80,7 +80,7 @@ public void register(final @NotNull IHub hub, final @NotNull SentryOptions optio } } - private void addObserver(final @NotNull IHub hub) { + private void addObserver(final @NotNull IScopes scopes) { // this should never happen, check added to avoid warnings from NullAway if (this.options == null) { return; @@ -88,7 +88,7 @@ private void addObserver(final @NotNull IHub hub) { watcher = new LifecycleWatcher( - hub, + scopes, this.options.getSessionTrackingIntervalMillis(), this.options.isEnableAutoSessionTracking(), this.options.isEnableAppLifecycleBreadcrumbs()); diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/CurrentActivityIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/CurrentActivityIntegration.java index b4c5f1ed02..0b618636d3 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/CurrentActivityIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/CurrentActivityIntegration.java @@ -4,7 +4,7 @@ import android.app.Application; import android.os.Bundle; import androidx.annotation.NonNull; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.Integration; import io.sentry.SentryOptions; import io.sentry.util.Objects; @@ -25,7 +25,7 @@ public CurrentActivityIntegration(final @NotNull Application application) { } @Override - public void register(@NotNull IHub hub, @NotNull SentryOptions options) { + public void register(@NotNull IScopes scopes, @NotNull SentryOptions options) { application.registerActivityLifecycleCallbacks(this); } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/EnvelopeFileObserverIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/EnvelopeFileObserverIntegration.java index f99294584b..6e821e5be7 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/EnvelopeFileObserverIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/EnvelopeFileObserverIntegration.java @@ -1,7 +1,7 @@ package io.sentry.android.core; -import io.sentry.IHub; import io.sentry.ILogger; +import io.sentry.IScopes; import io.sentry.Integration; import io.sentry.OutboxSender; import io.sentry.SentryLevel; @@ -24,8 +24,8 @@ public abstract class EnvelopeFileObserverIntegration implements Integration, Cl } @Override - public final void register(final @NotNull IHub hub, final @NotNull SentryOptions options) { - Objects.requireNonNull(hub, "Hub is required"); + public final void register(final @NotNull IScopes scopes, final @NotNull SentryOptions options) { + Objects.requireNonNull(scopes, "Scopes are required"); Objects.requireNonNull(options, "SentryOptions is required"); logger = options.getLogger(); @@ -46,7 +46,7 @@ public final void register(final @NotNull IHub hub, final @NotNull SentryOptions () -> { synchronized (startLock) { if (!isClosed) { - startOutboxSender(hub, options, path); + startOutboxSender(scopes, options, path); } } }); @@ -60,10 +60,12 @@ public final void register(final @NotNull IHub hub, final @NotNull SentryOptions } private void startOutboxSender( - final @NotNull IHub hub, final @NotNull SentryOptions options, final @NotNull String path) { + final @NotNull IScopes scopes, + final @NotNull SentryOptions options, + final @NotNull String path) { final OutboxSender outboxSender = new OutboxSender( - hub, + scopes, options.getEnvelopeReader(), options.getSerializer(), options.getLogger(), diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/InternalSentrySdk.java b/sentry-android-core/src/main/java/io/sentry/android/core/InternalSentrySdk.java index 9bdbe86a77..692d8562f8 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/InternalSentrySdk.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/InternalSentrySdk.java @@ -4,12 +4,12 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import io.sentry.DateUtils; -import io.sentry.HubAdapter; -import io.sentry.IHub; import io.sentry.ILogger; import io.sentry.IScope; +import io.sentry.IScopes; import io.sentry.ISerializer; import io.sentry.ObjectWriter; +import io.sentry.ScopesAdapter; import io.sentry.SentryEnvelope; import io.sentry.SentryEnvelopeItem; import io.sentry.SentryEvent; @@ -39,12 +39,12 @@ public final class InternalSentrySdk { /** - * @return a copy of the current hub's topmost scope, or null in case the hub is disabled + * @return a copy of the current scopes's topmost scope, or null in case the scopes is disabled */ @Nullable public static IScope getCurrentScope() { final @NotNull AtomicReference scopeRef = new AtomicReference<>(); - HubAdapter.getInstance() + ScopesAdapter.getInstance() .configureScope( scope -> { scopeRef.set(scope.clone()); @@ -134,8 +134,8 @@ public static Map serializeScope( } /** - * Captures the provided envelope. Compared to {@link IHub#captureEvent(SentryEvent)} this method - *
+ * Captures the provided envelope. Compared to {@link IScopes#captureEvent(SentryEvent)} this + * method
* - will not enrich events with additional data (e.g. scope)
* - will not execute beforeSend: it's up to the caller to take care of this
* - will not perform any sampling: it's up to the caller to take care of this
@@ -147,8 +147,8 @@ public static Map serializeScope( */ @Nullable public static SentryId captureEnvelope(final @NotNull byte[] envelopeData) { - final @NotNull IHub hub = HubAdapter.getInstance(); - final @NotNull SentryOptions options = hub.getOptions(); + final @NotNull IScopes scopes = ScopesAdapter.getInstance(); + final @NotNull SentryOptions options = scopes.getOptions(); try (final InputStream envelopeInputStream = new ByteArrayInputStream(envelopeData)) { final @NotNull ISerializer serializer = options.getSerializer(); @@ -178,7 +178,7 @@ public static SentryId captureEnvelope(final @NotNull byte[] envelopeData) { } // update session and add it to envelope if necessary - final @Nullable Session session = updateSession(hub, options, status, crashedOrErrored); + final @Nullable Session session = updateSession(scopes, options, status, crashedOrErrored); if (session != null) { final SentryEnvelopeItem sessionItem = SentryEnvelopeItem.fromSession(serializer, session); envelopeItems.add(sessionItem); @@ -186,7 +186,7 @@ public static SentryId captureEnvelope(final @NotNull byte[] envelopeData) { final SentryEnvelope repackagedEnvelope = new SentryEnvelope(envelope.getHeader(), envelopeItems); - return hub.captureEnvelope(repackagedEnvelope); + return scopes.captureEnvelope(repackagedEnvelope); } catch (Throwable t) { options.getLogger().log(SentryLevel.ERROR, "Failed to capture envelope", t); } @@ -195,12 +195,12 @@ public static SentryId captureEnvelope(final @NotNull byte[] envelopeData) { @Nullable private static Session updateSession( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull SentryOptions options, final @Nullable Session.State status, final boolean crashedOrErrored) { final @NotNull AtomicReference sessionRef = new AtomicReference<>(); - hub.configureScope( + scopes.configureScope( scope -> { final @Nullable Session session = scope.getSession(); if (session != null) { diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/LifecycleWatcher.java b/sentry-android-core/src/main/java/io/sentry/android/core/LifecycleWatcher.java index 7b38bcd9c2..a32fa51d3f 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/LifecycleWatcher.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/LifecycleWatcher.java @@ -3,7 +3,7 @@ import androidx.lifecycle.DefaultLifecycleObserver; import androidx.lifecycle.LifecycleOwner; import io.sentry.Breadcrumb; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.SentryLevel; import io.sentry.Session; import io.sentry.android.core.internal.util.BreadcrumbFactory; @@ -25,19 +25,19 @@ final class LifecycleWatcher implements DefaultLifecycleObserver { private @Nullable TimerTask timerTask; private final @Nullable Timer timer; private final @NotNull Object timerLock = new Object(); - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final boolean enableSessionTracking; private final boolean enableAppLifecycleBreadcrumbs; private final @NotNull ICurrentDateProvider currentDateProvider; LifecycleWatcher( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final long sessionIntervalMillis, final boolean enableSessionTracking, final boolean enableAppLifecycleBreadcrumbs) { this( - hub, + scopes, sessionIntervalMillis, enableSessionTracking, enableAppLifecycleBreadcrumbs, @@ -45,7 +45,7 @@ final class LifecycleWatcher implements DefaultLifecycleObserver { } LifecycleWatcher( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final long sessionIntervalMillis, final boolean enableSessionTracking, final boolean enableAppLifecycleBreadcrumbs, @@ -53,7 +53,7 @@ final class LifecycleWatcher implements DefaultLifecycleObserver { this.sessionIntervalMillis = sessionIntervalMillis; this.enableSessionTracking = enableSessionTracking; this.enableAppLifecycleBreadcrumbs = enableAppLifecycleBreadcrumbs; - this.hub = hub; + this.scopes = scopes; this.currentDateProvider = currentDateProvider; if (enableSessionTracking) { timer = new Timer(true); @@ -79,7 +79,7 @@ private void startSession() { final long currentTimeMillis = currentDateProvider.getCurrentTimeMillis(); - hub.configureScope( + scopes.configureScope( scope -> { if (lastUpdatedSession.get() == 0L) { final @Nullable Session currentSession = scope.getSession(); @@ -93,7 +93,7 @@ private void startSession() { if (lastUpdatedSession == 0L || (lastUpdatedSession + sessionIntervalMillis) <= currentTimeMillis) { addSessionBreadcrumb("start"); - hub.startSession(); + scopes.startSession(); } this.lastUpdatedSession.set(currentTimeMillis); } @@ -123,7 +123,7 @@ private void scheduleEndSession() { @Override public void run() { addSessionBreadcrumb("end"); - hub.endSession(); + scopes.endSession(); } }; @@ -148,13 +148,13 @@ private void addAppBreadcrumb(final @NotNull String state) { breadcrumb.setData("state", state); breadcrumb.setCategory("app.lifecycle"); breadcrumb.setLevel(SentryLevel.INFO); - hub.addBreadcrumb(breadcrumb); + scopes.addBreadcrumb(breadcrumb); } } private void addSessionBreadcrumb(final @NotNull String state) { final Breadcrumb breadcrumb = BreadcrumbFactory.forSession(state); - hub.addBreadcrumb(breadcrumb); + scopes.addBreadcrumb(breadcrumb); } @TestOnly diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/NdkIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/NdkIntegration.java index 3a4a91498e..dc464303c6 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/NdkIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/NdkIntegration.java @@ -2,7 +2,7 @@ import static io.sentry.util.IntegrationUtils.addIntegrationToSdkVersion; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.Integration; import io.sentry.SentryLevel; import io.sentry.SentryOptions; @@ -28,8 +28,8 @@ public NdkIntegration(final @Nullable Class sentryNdkClass) { } @Override - public final void register(final @NotNull IHub hub, final @NotNull SentryOptions options) { - Objects.requireNonNull(hub, "Hub is required"); + public final void register(final @NotNull IScopes scopes, final @NotNull SentryOptions options) { + Objects.requireNonNull(scopes, "Scopes are required"); this.options = Objects.requireNonNull( (options instanceof SentryAndroidOptions) ? (SentryAndroidOptions) options : null, @@ -38,7 +38,8 @@ public final void register(final @NotNull IHub hub, final @NotNull SentryOptions final boolean enabled = this.options.isEnableNdk(); this.options.getLogger().log(SentryLevel.DEBUG, "NdkIntegration enabled: %s", enabled); - // Note: `hub` isn't used here because the NDK integration writes files to disk which are picked + // Note: `scopes` isn't used here because the NDK integration writes files to disk which are + // picked // up by another integration (EnvelopeFileObserverIntegration). if (enabled && sentryNdkClass != null) { final String cachedDir = this.options.getCacheDirPath(); diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/NetworkBreadcrumbsIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/NetworkBreadcrumbsIntegration.java index 1cd42e9dab..9f1dd3ecf6 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/NetworkBreadcrumbsIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/NetworkBreadcrumbsIntegration.java @@ -13,8 +13,8 @@ import io.sentry.Breadcrumb; import io.sentry.DateUtils; import io.sentry.Hint; -import io.sentry.IHub; import io.sentry.ILogger; +import io.sentry.IScopes; import io.sentry.Integration; import io.sentry.SentryDateProvider; import io.sentry.SentryLevel; @@ -50,8 +50,8 @@ public NetworkBreadcrumbsIntegration( @SuppressLint("NewApi") @Override - public void register(final @NotNull IHub hub, final @NotNull SentryOptions options) { - Objects.requireNonNull(hub, "Hub is required"); + public void register(final @NotNull IScopes scopes, final @NotNull SentryOptions options) { + Objects.requireNonNull(scopes, "Scopes are required"); SentryAndroidOptions androidOptions = Objects.requireNonNull( (options instanceof SentryAndroidOptions) ? (SentryAndroidOptions) options : null, @@ -72,7 +72,8 @@ public void register(final @NotNull IHub hub, final @NotNull SentryOptions optio } networkCallback = - new NetworkBreadcrumbsNetworkCallback(hub, buildInfoProvider, options.getDateProvider()); + new NetworkBreadcrumbsNetworkCallback( + scopes, buildInfoProvider, options.getDateProvider()); final boolean registered = AndroidConnectionStatusProvider.registerNetworkCallback( context, logger, buildInfoProvider, networkCallback); @@ -101,7 +102,7 @@ public void close() throws IOException { @SuppressLint("ObsoleteSdkInt") @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) static final class NetworkBreadcrumbsNetworkCallback extends ConnectivityManager.NetworkCallback { - final @NotNull IHub hub; + final @NotNull IScopes scopes; final @NotNull BuildInfoProvider buildInfoProvider; @Nullable Network currentNetwork = null; @@ -111,10 +112,10 @@ static final class NetworkBreadcrumbsNetworkCallback extends ConnectivityManager final @NotNull SentryDateProvider dateProvider; NetworkBreadcrumbsNetworkCallback( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull BuildInfoProvider buildInfoProvider, final @NotNull SentryDateProvider dateProvider) { - this.hub = Objects.requireNonNull(hub, "Hub is required"); + this.scopes = Objects.requireNonNull(scopes, "Scopes are required"); this.buildInfoProvider = Objects.requireNonNull(buildInfoProvider, "BuildInfoProvider is required"); this.dateProvider = Objects.requireNonNull(dateProvider, "SentryDateProvider is required"); @@ -126,7 +127,7 @@ public void onAvailable(final @NonNull Network network) { return; } final Breadcrumb breadcrumb = createBreadcrumb("NETWORK_AVAILABLE"); - hub.addBreadcrumb(breadcrumb); + scopes.addBreadcrumb(breadcrumb); currentNetwork = network; lastCapabilities = null; } @@ -156,7 +157,7 @@ public void onCapabilitiesChanged( } Hint hint = new Hint(); hint.set(TypeCheckHint.ANDROID_NETWORK_CAPABILITIES, connectionDetail); - hub.addBreadcrumb(breadcrumb, hint); + scopes.addBreadcrumb(breadcrumb, hint); } @Override @@ -165,7 +166,7 @@ public void onLost(final @NonNull Network network) { return; } final Breadcrumb breadcrumb = createBreadcrumb("NETWORK_LOST"); - hub.addBreadcrumb(breadcrumb); + scopes.addBreadcrumb(breadcrumb); currentNetwork = null; lastCapabilities = null; } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/PhoneStateBreadcrumbsIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/PhoneStateBreadcrumbsIntegration.java index c10d25b057..cae1492d3e 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/PhoneStateBreadcrumbsIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/PhoneStateBreadcrumbsIntegration.java @@ -6,7 +6,7 @@ import android.content.Context; import android.telephony.TelephonyManager; import io.sentry.Breadcrumb; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.Integration; import io.sentry.SentryLevel; import io.sentry.SentryOptions; @@ -32,8 +32,8 @@ public PhoneStateBreadcrumbsIntegration(final @NotNull Context context) { } @Override - public void register(final @NotNull IHub hub, final @NotNull SentryOptions options) { - Objects.requireNonNull(hub, "Hub is required"); + public void register(final @NotNull IScopes scopes, final @NotNull SentryOptions options) { + Objects.requireNonNull(scopes, "Scopes are required"); this.options = Objects.requireNonNull( (options instanceof SentryAndroidOptions) ? (SentryAndroidOptions) options : null, @@ -55,7 +55,7 @@ public void register(final @NotNull IHub hub, final @NotNull SentryOptions optio () -> { synchronized (startLock) { if (!isClosed) { - startTelephonyListener(hub, options); + startTelephonyListener(scopes, options); } } }); @@ -72,11 +72,11 @@ public void register(final @NotNull IHub hub, final @NotNull SentryOptions optio @SuppressWarnings("deprecation") private void startTelephonyListener( - final @NotNull IHub hub, final @NotNull SentryOptions options) { + final @NotNull IScopes scopes, final @NotNull SentryOptions options) { telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); if (telephonyManager != null) { try { - listener = new PhoneStateChangeListener(hub); + listener = new PhoneStateChangeListener(scopes); telephonyManager.listen(listener, android.telephony.PhoneStateListener.LISTEN_CALL_STATE); options.getLogger().log(SentryLevel.DEBUG, "PhoneStateBreadcrumbsIntegration installed."); @@ -110,10 +110,10 @@ public void close() throws IOException { @SuppressWarnings("deprecation") static final class PhoneStateChangeListener extends android.telephony.PhoneStateListener { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; - PhoneStateChangeListener(final @NotNull IHub hub) { - this.hub = hub; + PhoneStateChangeListener(final @NotNull IScopes scopes) { + this.scopes = scopes; } @SuppressWarnings("deprecation") @@ -128,7 +128,7 @@ public void onCallStateChanged(int state, String incomingNumber) { breadcrumb.setData("action", "CALL_STATE_RINGING"); breadcrumb.setMessage("Device ringing"); breadcrumb.setLevel(SentryLevel.INFO); - hub.addBreadcrumb(breadcrumb); + scopes.addBreadcrumb(breadcrumb); } } } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/SendCachedEnvelopeIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/SendCachedEnvelopeIntegration.java index 66e534bb7d..64f1cab362 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/SendCachedEnvelopeIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/SendCachedEnvelopeIntegration.java @@ -2,7 +2,7 @@ import io.sentry.DataCategory; import io.sentry.IConnectionStatusProvider; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.Integration; import io.sentry.SendCachedEnvelopeFireAndForgetIntegration; import io.sentry.SentryLevel; @@ -28,7 +28,7 @@ final class SendCachedEnvelopeIntegration private final @NotNull LazyEvaluator startupCrashMarkerEvaluator; private final AtomicBoolean startupCrashHandled = new AtomicBoolean(false); private @Nullable IConnectionStatusProvider connectionStatusProvider; - private @Nullable IHub hub; + private @Nullable IScopes scopes; private @Nullable SentryAndroidOptions options; private @Nullable SendCachedEnvelopeFireAndForgetIntegration.SendFireAndForget sender; private final AtomicBoolean isInitialized = new AtomicBoolean(false); @@ -42,8 +42,8 @@ public SendCachedEnvelopeIntegration( } @Override - public void register(@NotNull IHub hub, @NotNull SentryOptions options) { - this.hub = Objects.requireNonNull(hub, "Hub is required"); + public void register(@NotNull IScopes scopes, @NotNull SentryOptions options) { + this.scopes = Objects.requireNonNull(scopes, "Scopes are required"); this.options = Objects.requireNonNull( (options instanceof SentryAndroidOptions) ? (SentryAndroidOptions) options : null, @@ -55,7 +55,7 @@ public void register(@NotNull IHub hub, @NotNull SentryOptions options) { return; } - sendCachedEnvelopes(hub, this.options); + sendCachedEnvelopes(scopes, this.options); } @Override @@ -69,14 +69,14 @@ public void close() throws IOException { @Override public void onConnectionStatusChanged( final @NotNull IConnectionStatusProvider.ConnectionStatus status) { - if (hub != null && options != null) { - sendCachedEnvelopes(hub, options); + if (scopes != null && options != null) { + sendCachedEnvelopes(scopes, options); } } @SuppressWarnings({"NullAway"}) private synchronized void sendCachedEnvelopes( - final @NotNull IHub hub, final @NotNull SentryAndroidOptions options) { + final @NotNull IScopes scopes, final @NotNull SentryAndroidOptions options) { try { final Future future = options @@ -97,7 +97,7 @@ private synchronized void sendCachedEnvelopes( connectionStatusProvider = options.getConnectionStatusProvider(); connectionStatusProvider.addConnectionStatusObserver(this); - sender = factory.create(hub, options); + sender = factory.create(scopes, options); } if (connectionStatusProvider != null @@ -110,7 +110,7 @@ private synchronized void sendCachedEnvelopes( } // in case there's rate limiting active, skip processing - final @Nullable RateLimiter rateLimiter = hub.getRateLimiter(); + final @Nullable RateLimiter rateLimiter = scopes.getRateLimiter(); if (rateLimiter != null && rateLimiter.isActiveForCategory(DataCategory.All)) { options diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/SentryAndroid.java b/sentry-android-core/src/main/java/io/sentry/android/core/SentryAndroid.java index af68a026fb..424de4d82e 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/SentryAndroid.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/SentryAndroid.java @@ -4,8 +4,8 @@ import android.content.Context; import android.os.Process; import android.os.SystemClock; -import io.sentry.IHub; import io.sentry.ILogger; +import io.sentry.IScopes; import io.sentry.Integration; import io.sentry.OptionsContainer; import io.sentry.Sentry; @@ -144,10 +144,11 @@ public static synchronized void init( }, true); - final @NotNull IHub hub = Sentry.getCurrentHub(); - if (hub.getOptions().isEnableAutoSessionTracking() && ContextUtils.isForegroundImportance()) { - hub.addBreadcrumb(BreadcrumbFactory.forSession("session.start")); - hub.startSession(); + final @NotNull IScopes scopes = Sentry.getCurrentScopes(); + if (scopes.getOptions().isEnableAutoSessionTracking() + && ContextUtils.isForegroundImportance()) { + scopes.addBreadcrumb(BreadcrumbFactory.forSession("session.start")); + scopes.startSession(); } } catch (IllegalAccessException e) { logger.log(SentryLevel.FATAL, "Fatal error during SentryAndroid.init(...)", e); diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/SystemEventsBreadcrumbsIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/SystemEventsBreadcrumbsIntegration.java index 1c22a7dcc8..333ece2148 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/SystemEventsBreadcrumbsIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/SystemEventsBreadcrumbsIntegration.java @@ -40,8 +40,8 @@ import android.os.Bundle; import io.sentry.Breadcrumb; import io.sentry.Hint; -import io.sentry.IHub; import io.sentry.ILogger; +import io.sentry.IScopes; import io.sentry.Integration; import io.sentry.SentryLevel; import io.sentry.SentryOptions; @@ -80,8 +80,8 @@ public SystemEventsBreadcrumbsIntegration( } @Override - public void register(final @NotNull IHub hub, final @NotNull SentryOptions options) { - Objects.requireNonNull(hub, "Hub is required"); + public void register(final @NotNull IScopes scopes, final @NotNull SentryOptions options) { + Objects.requireNonNull(scopes, "Scopes are required"); this.options = Objects.requireNonNull( (options instanceof SentryAndroidOptions) ? (SentryAndroidOptions) options : null, @@ -103,7 +103,7 @@ public void register(final @NotNull IHub hub, final @NotNull SentryOptions optio () -> { synchronized (startLock) { if (!isClosed) { - startSystemEventsReceiver(hub, (SentryAndroidOptions) options); + startSystemEventsReceiver(scopes, (SentryAndroidOptions) options); } } }); @@ -119,8 +119,8 @@ public void register(final @NotNull IHub hub, final @NotNull SentryOptions optio } private void startSystemEventsReceiver( - final @NotNull IHub hub, final @NotNull SentryAndroidOptions options) { - receiver = new SystemEventsBroadcastReceiver(hub, options.getLogger()); + final @NotNull IScopes scopes, final @NotNull SentryAndroidOptions options) { + receiver = new SystemEventsBroadcastReceiver(scopes, options.getLogger()); final IntentFilter filter = new IntentFilter(); for (String item : actions) { filter.addAction(item); @@ -204,11 +204,11 @@ public void close() throws IOException { static final class SystemEventsBroadcastReceiver extends BroadcastReceiver { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @NotNull ILogger logger; - SystemEventsBroadcastReceiver(final @NotNull IHub hub, final @NotNull ILogger logger) { - this.hub = hub; + SystemEventsBroadcastReceiver(final @NotNull IScopes scopes, final @NotNull ILogger logger) { + this.scopes = scopes; this.logger = logger; } @@ -249,7 +249,7 @@ public void onReceive(Context context, Intent intent) { final Hint hint = new Hint(); hint.set(ANDROID_INTENT, intent); - hub.addBreadcrumb(breadcrumb, hint); + scopes.addBreadcrumb(breadcrumb, hint); } } } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/TempSensorBreadcrumbsIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/TempSensorBreadcrumbsIntegration.java index eaf5c64991..4d0e9c7e60 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/TempSensorBreadcrumbsIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/TempSensorBreadcrumbsIntegration.java @@ -11,7 +11,7 @@ import android.hardware.SensorManager; import io.sentry.Breadcrumb; import io.sentry.Hint; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.Integration; import io.sentry.SentryLevel; import io.sentry.SentryOptions; @@ -26,7 +26,7 @@ public final class TempSensorBreadcrumbsIntegration implements Integration, Closeable, SensorEventListener { private final @NotNull Context context; - private @Nullable IHub hub; + private @Nullable IScopes scopes; private @Nullable SentryAndroidOptions options; @TestOnly @Nullable SensorManager sensorManager; @@ -38,8 +38,8 @@ public TempSensorBreadcrumbsIntegration(final @NotNull Context context) { } @Override - public void register(final @NotNull IHub hub, final @NotNull SentryOptions options) { - this.hub = Objects.requireNonNull(hub, "Hub is required"); + public void register(final @NotNull IScopes scopes, final @NotNull SentryOptions options) { + this.scopes = Objects.requireNonNull(scopes, "Scopes are required"); this.options = Objects.requireNonNull( (options instanceof SentryAndroidOptions) ? (SentryAndroidOptions) options : null, @@ -121,7 +121,7 @@ public void onSensorChanged(final @NotNull SensorEvent event) { return; } - if (hub != null) { + if (scopes != null) { final Breadcrumb breadcrumb = new Breadcrumb(); breadcrumb.setType("system"); breadcrumb.setCategory("device.event"); @@ -134,7 +134,7 @@ public void onSensorChanged(final @NotNull SensorEvent event) { final Hint hint = new Hint(); hint.set(ANDROID_SENSOR_EVENT, event); - hub.addBreadcrumb(breadcrumb, hint); + scopes.addBreadcrumb(breadcrumb, hint); } } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/UserInteractionIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/UserInteractionIntegration.java index c361529671..712651b460 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/UserInteractionIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/UserInteractionIntegration.java @@ -6,7 +6,7 @@ import android.app.Application; import android.os.Bundle; import android.view.Window; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.Integration; import io.sentry.SentryLevel; import io.sentry.SentryOptions; @@ -23,7 +23,7 @@ public final class UserInteractionIntegration implements Integration, Closeable, Application.ActivityLifecycleCallbacks { private final @NotNull Application application; - private @Nullable IHub hub; + private @Nullable IScopes scopes; private @Nullable SentryAndroidOptions options; private final boolean isAndroidXAvailable; @@ -44,14 +44,14 @@ private void startTracking(final @NotNull Activity activity) { return; } - if (hub != null && options != null) { + if (scopes != null && options != null) { Window.Callback delegate = window.getCallback(); if (delegate == null) { delegate = new NoOpWindowCallback(); } final SentryGestureListener gestureListener = - new SentryGestureListener(activity, hub, options); + new SentryGestureListener(activity, scopes, options); window.setCallback(new SentryWindowCallback(delegate, activity, gestureListener, options)); } } @@ -102,13 +102,13 @@ public void onActivitySaveInstanceState(@NotNull Activity activity, @NotNull Bun public void onActivityDestroyed(@NotNull Activity activity) {} @Override - public void register(@NotNull IHub hub, @NotNull SentryOptions options) { + public void register(@NotNull IScopes scopes, @NotNull SentryOptions options) { this.options = Objects.requireNonNull( (options instanceof SentryAndroidOptions) ? (SentryAndroidOptions) options : null, "SentryAndroidOptions is required"); - this.hub = Objects.requireNonNull(hub, "Hub is required"); + this.scopes = Objects.requireNonNull(scopes, "Scopes are required"); final boolean integrationEnabled = this.options.isEnableUserInteractionBreadcrumbs() diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/internal/gestures/SentryGestureListener.java b/sentry-android-core/src/main/java/io/sentry/android/core/internal/gestures/SentryGestureListener.java index 0ec0d83258..9154f3e7c6 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/internal/gestures/SentryGestureListener.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/internal/gestures/SentryGestureListener.java @@ -10,8 +10,8 @@ import android.view.Window; import io.sentry.Breadcrumb; import io.sentry.Hint; -import io.sentry.IHub; import io.sentry.IScope; +import io.sentry.IScopes; import io.sentry.ITransaction; import io.sentry.SentryLevel; import io.sentry.SpanStatus; @@ -43,7 +43,7 @@ private enum GestureType { private static final String TRACE_ORIGIN = "auto.ui.gesture_listener"; private final @NotNull WeakReference activityRef; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @NotNull SentryAndroidOptions options; private @Nullable UiElement activeUiElement = null; @@ -54,10 +54,10 @@ private enum GestureType { public SentryGestureListener( final @NotNull Activity currentActivity, - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull SentryAndroidOptions options) { this.activityRef = new WeakReference<>(currentActivity); - this.hub = hub; + this.scopes = scopes; this.options = options; } @@ -185,7 +185,7 @@ private void addBreadcrumb( hint.set(ANDROID_MOTION_EVENT, motionEvent); hint.set(ANDROID_VIEW, target.getView()); - hub.addBreadcrumb( + scopes.addBreadcrumb( Breadcrumb.userInteraction( type, target.getResourceName(), target.getClassName(), target.getTag(), additionalData), hint); @@ -202,7 +202,7 @@ private void startTracing(final @NotNull UiElement target, final @NotNull Gestur if (!(options.isTracingEnabled() && options.isEnableUserInteractionTracing())) { if (isNewInteraction) { - TracingUtils.startNewTrace(hub); + TracingUtils.startNewTrace(scopes); activeUiElement = target; activeEventType = eventType; } @@ -253,12 +253,12 @@ private void startTracing(final @NotNull UiElement target, final @NotNull Gestur transactionOptions.setTrimEnd(true); final ITransaction transaction = - hub.startTransaction( + scopes.startTransaction( new TransactionContext(name, TransactionNameSource.COMPONENT, op), transactionOptions); transaction.getSpanContext().setOrigin(TRACE_ORIGIN + "." + target.getOrigin()); - hub.configureScope( + scopes.configureScope( scope -> { applyScope(scope, transaction); }); @@ -278,7 +278,7 @@ void stopTracing(final @NotNull SpanStatus status) { activeTransaction.finish(); } } - hub.configureScope( + scopes.configureScope( scope -> { // avoid method refs on Android due to some issues with older AGP setups // noinspection Convert2MethodRef diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/AndroidTransactionProfilerTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/AndroidTransactionProfilerTest.kt index 405aa6dc98..436c3ee6f9 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/AndroidTransactionProfilerTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/AndroidTransactionProfilerTest.kt @@ -5,8 +5,8 @@ import android.os.Build import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import io.sentry.CpuCollectionData -import io.sentry.IHub import io.sentry.ILogger +import io.sentry.IScopes import io.sentry.ISentryExecutorService import io.sentry.MemoryCollectionData import io.sentry.PerformanceCollectionData @@ -89,7 +89,7 @@ class AndroidTransactionProfilerTest { executorService = mockExecutorService } - val hub: IHub = mock() + val scopes: IScopes = mock() val frameMetricsCollector: SentryFrameMetricsCollector = mock() lateinit var transaction1: SentryTracer @@ -97,10 +97,10 @@ class AndroidTransactionProfilerTest { lateinit var transaction3: SentryTracer fun getSut(context: Context, buildInfoProvider: BuildInfoProvider = buildInfo): AndroidTransactionProfiler { - whenever(hub.options).thenReturn(options) - transaction1 = SentryTracer(TransactionContext("", ""), hub) - transaction2 = SentryTracer(TransactionContext("", ""), hub) - transaction3 = SentryTracer(TransactionContext("", ""), hub) + whenever(scopes.options).thenReturn(options) + transaction1 = SentryTracer(TransactionContext("", ""), scopes) + transaction2 = SentryTracer(TransactionContext("", ""), scopes) + transaction3 = SentryTracer(TransactionContext("", ""), scopes) return AndroidTransactionProfiler(context, options, buildInfoProvider, frameMetricsCollector) } } diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/AnrIntegrationTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/AnrIntegrationTest.kt index cceabc9774..1a74a47ae1 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/AnrIntegrationTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/AnrIntegrationTest.kt @@ -2,7 +2,7 @@ package io.sentry.android.core import android.content.Context import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryLevel import io.sentry.android.core.AnrIntegration.AnrHint import io.sentry.exception.ExceptionMechanismException @@ -24,7 +24,7 @@ class AnrIntegrationTest { private class Fixture { val context = mock() - val hub = mock() + val scopes = mock() var options: SentryAndroidOptions = SentryAndroidOptions().apply { setLogger(mock()) } @@ -49,7 +49,7 @@ class AnrIntegrationTest { fixture.options.executorService = ImmediateExecutorService() val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertNotNull(sut.anrWatchDog) assertTrue((sut.anrWatchDog as ANRWatchDog).isAlive) @@ -60,7 +60,7 @@ class AnrIntegrationTest { fixture.options.executorService = mock() val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertNull(sut.anrWatchDog) } @@ -70,7 +70,7 @@ class AnrIntegrationTest { val sut = fixture.getSut() fixture.options.isAnrEnabled = false - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertNull(sut.anrWatchDog) } @@ -79,9 +79,9 @@ class AnrIntegrationTest { fun `When ANR watch dog is triggered, it should capture an error event with AnrHint`() { val sut = fixture.getSut() - sut.reportANR(fixture.hub, fixture.options, getApplicationNotResponding()) + sut.reportANR(fixture.scopes, fixture.options, getApplicationNotResponding()) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { assertEquals(SentryLevel.ERROR, it.level) }, @@ -97,7 +97,7 @@ class AnrIntegrationTest { val sut = fixture.getSut() fixture.options.executorService = ImmediateExecutorService() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertNotNull(sut.anrWatchDog) @@ -107,11 +107,11 @@ class AnrIntegrationTest { } @Test - fun `when hub is closed right after start, integration is not registered`() { + fun `when scopes is closed right after start, integration is not registered`() { val deferredExecutorService = DeferredExecutorService() val sut = fixture.getSut() fixture.options.executorService = deferredExecutorService - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertNull(sut.anrWatchDog) sut.close() deferredExecutorService.runAll() @@ -122,9 +122,9 @@ class AnrIntegrationTest { fun `When ANR watch dog is triggered, constructs exception with proper mechanism and snapshot flag`() { val sut = fixture.getSut() - sut.reportANR(fixture.hub, fixture.options, getApplicationNotResponding()) + sut.reportANR(fixture.scopes, fixture.options, getApplicationNotResponding()) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { val ex = it.throwableMechanism as ExceptionMechanismException assertTrue(ex.isSnapshot) @@ -139,9 +139,9 @@ class AnrIntegrationTest { val sut = fixture.getSut() AppState.getInstance().setInBackground(true) - sut.reportANR(fixture.hub, fixture.options, getApplicationNotResponding()) + sut.reportANR(fixture.scopes, fixture.options, getApplicationNotResponding()) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { val message = it.throwable?.message assertTrue(message?.startsWith("Background") == true) diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/AnrV2IntegrationTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/AnrV2IntegrationTest.kt index 885ad22c8f..1abcd43719 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/AnrV2IntegrationTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/AnrV2IntegrationTest.kt @@ -6,8 +6,8 @@ import android.content.Context import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import io.sentry.Hint -import io.sentry.IHub import io.sentry.ILogger +import io.sentry.IScopes import io.sentry.SentryEnvelope import io.sentry.SentryLevel import io.sentry.android.core.AnrV2Integration.AnrV2Hint @@ -59,7 +59,7 @@ class AnrV2IntegrationTest { lateinit var lastReportedAnrFile: File val options = SentryAndroidOptions() - val hub = mock() + val scopes = mock() val logger = mock() fun getSut( @@ -93,7 +93,7 @@ class AnrV2IntegrationTest { lastReportedAnrFile = File(cacheDir, AndroidEnvelopeCache.LAST_ANR_REPORT) lastReportedAnrFile.writeText(lastReportedAnrTimestamp.toString()) } - whenever(hub.captureEvent(any(), anyOrNull())).thenReturn(lastEventId) + whenever(scopes.captureEvent(any(), anyOrNull())).thenReturn(lastEventId) return AnrV2Integration(context) } @@ -170,7 +170,7 @@ class AnrV2IntegrationTest { fun `when cacheDir is not set, does not process historical exits`() { val integration = fixture.getSut(null, useImmediateExecutorService = false) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) verify(fixture.options.executorService, never()).submit(any()) } @@ -180,7 +180,7 @@ class AnrV2IntegrationTest { val integration = fixture.getSut(tmpDir, isAnrEnabled = false, useImmediateExecutorService = false) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) verify(fixture.options.executorService, never()).submit(any()) } @@ -189,9 +189,9 @@ class AnrV2IntegrationTest { fun `when historical exit list is empty, does not process historical exits`() { val integration = fixture.getSut(tmpDir) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) - verify(fixture.hub, never()).captureEvent(any(), anyOrNull()) + verify(fixture.scopes, never()).captureEvent(any(), anyOrNull()) } @Test @@ -199,9 +199,9 @@ class AnrV2IntegrationTest { val integration = fixture.getSut(tmpDir) fixture.addAppExitInfo(reason = null) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) - verify(fixture.hub, never()).captureEvent(any(), anyOrNull()) + verify(fixture.scopes, never()).captureEvent(any(), anyOrNull()) } @Test @@ -212,9 +212,9 @@ class AnrV2IntegrationTest { val integration = fixture.getSut(tmpDir) fixture.addAppExitInfo(timestamp = oldTimestamp) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) - verify(fixture.hub, never()).captureEvent(any(), anyOrNull()) + verify(fixture.scopes, never()).captureEvent(any(), anyOrNull()) } @Test @@ -222,9 +222,9 @@ class AnrV2IntegrationTest { val integration = fixture.getSut(tmpDir, lastReportedAnrTimestamp = oldTimestamp) fixture.addAppExitInfo(timestamp = oldTimestamp) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) - verify(fixture.hub, never()).captureEvent(any(), anyOrNull()) + verify(fixture.scopes, never()).captureEvent(any(), anyOrNull()) } @Test @@ -232,9 +232,9 @@ class AnrV2IntegrationTest { val integration = fixture.getSut(tmpDir, lastReportedAnrTimestamp = null) fixture.addAppExitInfo(timestamp = oldTimestamp) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) - verify(fixture.hub).captureEvent(any(), anyOrNull()) + verify(fixture.scopes).captureEvent(any(), anyOrNull()) } @Test @@ -242,9 +242,9 @@ class AnrV2IntegrationTest { val integration = fixture.getSut(tmpDir, lastReportedAnrTimestamp = oldTimestamp) fixture.addAppExitInfo(timestamp = newTimestamp) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { assertEquals(newTimestamp, it.timestamp.time) assertEquals(SentryLevel.FATAL, it.level) @@ -291,9 +291,9 @@ class AnrV2IntegrationTest { importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND ) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( any(), argThat { val hint = HintUtils.getSentrySdkHint(this) @@ -311,7 +311,7 @@ class AnrV2IntegrationTest { ) fixture.addAppExitInfo(timestamp = newTimestamp) - whenever(fixture.hub.captureEvent(any(), any())).thenAnswer { invocation -> + whenever(fixture.scopes.captureEvent(any(), any())).thenAnswer { invocation -> val hint = HintUtils.getSentrySdkHint(invocation.getArgument(1)) as DiskFlushNotification thread { @@ -321,9 +321,9 @@ class AnrV2IntegrationTest { SentryId() } - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) - verify(fixture.hub).captureEvent(any(), anyOrNull()) + verify(fixture.scopes).captureEvent(any(), anyOrNull()) // shouldn't fall into timed out state, because we marked event as flushed on another thread verify(fixture.logger, never()).log( any(), @@ -341,9 +341,9 @@ class AnrV2IntegrationTest { ) fixture.addAppExitInfo(timestamp = newTimestamp) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) - verify(fixture.hub).captureEvent(any(), anyOrNull()) + verify(fixture.scopes).captureEvent(any(), anyOrNull()) // we do not call markFlushed, hence it should time out waiting for flush, but because // we drop the event, it should not even come to this if-check verify(fixture.logger, never()).log( @@ -360,9 +360,9 @@ class AnrV2IntegrationTest { fixture.addAppExitInfo(timestamp = newTimestamp - 1 * 60 * 1000) fixture.addAppExitInfo(timestamp = newTimestamp) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) - verify(fixture.hub, times(2)).captureEvent( + verify(fixture.scopes, times(2)).captureEvent( any(), argThat { val hint = HintUtils.getSentrySdkHint(this) @@ -382,10 +382,10 @@ class AnrV2IntegrationTest { fixture.addAppExitInfo(timestamp = newTimestamp - 1 * 60 * 1000) fixture.addAppExitInfo(timestamp = newTimestamp) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) // only the latest anr is reported which should be enrichable - verify(fixture.hub, atMost(1)).captureEvent( + verify(fixture.scopes, atMost(1)).captureEvent( any(), argThat { val hint = HintUtils.getSentrySdkHint(this) @@ -402,20 +402,20 @@ class AnrV2IntegrationTest { fixture.addAppExitInfo(timestamp = newTimestamp - TimeUnit.DAYS.toMillis(1)) fixture.addAppExitInfo(timestamp = newTimestamp) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) // the order is reverse here, so the oldest ANR will be reported first to keep track of // last reported ANR in a marker file - inOrder(fixture.hub) { - verify(fixture.hub).captureEvent( + inOrder(fixture.scopes) { + verify(fixture.scopes).captureEvent( argThat { timestamp.time == newTimestamp - TimeUnit.DAYS.toMillis(2) }, anyOrNull() ) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( argThat { timestamp.time == newTimestamp - TimeUnit.DAYS.toMillis(1) }, anyOrNull() ) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( argThat { timestamp.time == newTimestamp }, anyOrNull() ) @@ -427,9 +427,9 @@ class AnrV2IntegrationTest { val integration = fixture.getSut(tmpDir, lastReportedAnrTimestamp = oldTimestamp) fixture.addAppExitInfo(timestamp = newTimestamp) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( any(), argThat { val hint = HintUtils.getSentrySdkHint(this) @@ -443,9 +443,9 @@ class AnrV2IntegrationTest { val integration = fixture.getSut(tmpDir, lastReportedAnrTimestamp = oldTimestamp) fixture.addAppExitInfo(timestamp = newTimestamp) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( any(), argThat { val hint = HintUtils.getSentrySdkHint(this) @@ -472,7 +472,7 @@ class AnrV2IntegrationTest { ) } - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) // we store envelope with StartSessionHint on different thread after some delay, which // triggers the previous session flush, so no timeout @@ -493,14 +493,14 @@ class AnrV2IntegrationTest { ) fixture.addAppExitInfo(timestamp = newTimestamp) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) verify(fixture.logger, never()).log( any(), argThat { startsWith("Timed out waiting to flush previous session to its own file.") }, any() ) - verify(fixture.hub).captureEvent(any(), any()) + verify(fixture.scopes).captureEvent(any(), any()) } @Test @@ -512,7 +512,7 @@ class AnrV2IntegrationTest { ) fixture.addAppExitInfo(timestamp = newTimestamp) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) verify(fixture.logger).log( any(), @@ -532,9 +532,9 @@ class AnrV2IntegrationTest { ) fixture.addAppExitInfo(timestamp = newTimestamp) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( any(), check { assertNotNull(it.threadDump) @@ -547,8 +547,8 @@ class AnrV2IntegrationTest { val integration = fixture.getSut(tmpDir, lastReportedAnrTimestamp = oldTimestamp) fixture.addAppExitInfo(timestamp = newTimestamp, addTrace = false) - integration.register(fixture.hub, fixture.options) + integration.register(fixture.scopes, fixture.options) - verify(fixture.hub, never()).captureEvent(any(), anyOrNull()) + verify(fixture.scopes, never()).captureEvent(any(), anyOrNull()) } } diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/AppComponentsBreadcrumbsIntegrationTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/AppComponentsBreadcrumbsIntegrationTest.kt index 15a6d690e5..5f8792c850 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/AppComponentsBreadcrumbsIntegrationTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/AppComponentsBreadcrumbsIntegrationTest.kt @@ -5,7 +5,7 @@ import android.content.Context import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import io.sentry.Breadcrumb -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryLevel import org.junit.runner.RunWith import org.mockito.kotlin.any @@ -37,8 +37,8 @@ class AppComponentsBreadcrumbsIntegrationTest { fun `When app components breadcrumb is enabled, it registers callback`() { val sut = fixture.getSut() val options = SentryAndroidOptions() - val hub = mock() - sut.register(hub, options) + val scopes = mock() + sut.register(scopes, options) verify(fixture.context).registerComponentCallbacks(any()) } @@ -46,10 +46,10 @@ class AppComponentsBreadcrumbsIntegrationTest { fun `When app components breadcrumb is enabled, but ComponentCallbacks is not ready, do not throw`() { val sut = fixture.getSut() val options = SentryAndroidOptions() - val hub = mock() - sut.register(hub, options) + val scopes = mock() + sut.register(scopes, options) whenever(fixture.context.registerComponentCallbacks(any())).thenThrow(NullPointerException()) - sut.register(hub, options) + sut.register(scopes, options) assertFalse(options.isEnableAppComponentBreadcrumbs) } @@ -59,8 +59,8 @@ class AppComponentsBreadcrumbsIntegrationTest { val options = SentryAndroidOptions().apply { isEnableAppComponentBreadcrumbs = false } - val hub = mock() - sut.register(hub, options) + val scopes = mock() + sut.register(scopes, options) verify(fixture.context, never()).registerComponentCallbacks(any()) } @@ -68,8 +68,8 @@ class AppComponentsBreadcrumbsIntegrationTest { fun `When AppComponentsBreadcrumbsIntegrationTest is closed, it should unregister the callback`() { val sut = fixture.getSut() val options = SentryAndroidOptions() - val hub = mock() - sut.register(hub, options) + val scopes = mock() + sut.register(scopes, options) sut.close() verify(fixture.context).unregisterComponentCallbacks(any()) } @@ -78,10 +78,10 @@ class AppComponentsBreadcrumbsIntegrationTest { fun `When app components breadcrumb is closed, but ComponentCallbacks is not ready, do not throw`() { val sut = fixture.getSut() val options = SentryAndroidOptions() - val hub = mock() + val scopes = mock() whenever(fixture.context.registerComponentCallbacks(any())).thenThrow(NullPointerException()) whenever(fixture.context.unregisterComponentCallbacks(any())).thenThrow(NullPointerException()) - sut.register(hub, options) + sut.register(scopes, options) sut.close() } @@ -89,10 +89,10 @@ class AppComponentsBreadcrumbsIntegrationTest { fun `When low memory event, a breadcrumb with type, category and level should be set`() { val sut = fixture.getSut() val options = SentryAndroidOptions() - val hub = mock() - sut.register(hub, options) + val scopes = mock() + sut.register(scopes, options) sut.onLowMemory() - verify(hub).addBreadcrumb( + verify(scopes).addBreadcrumb( check { assertEquals("device.event", it.category) assertEquals("system", it.type) @@ -105,10 +105,10 @@ class AppComponentsBreadcrumbsIntegrationTest { fun `When trim memory event with level, a breadcrumb with type, category and level should be set`() { val sut = fixture.getSut() val options = SentryAndroidOptions() - val hub = mock() - sut.register(hub, options) + val scopes = mock() + sut.register(scopes, options) sut.onTrimMemory(ComponentCallbacks2.TRIM_MEMORY_BACKGROUND) - verify(hub).addBreadcrumb( + verify(scopes).addBreadcrumb( check { assertEquals("device.event", it.category) assertEquals("system", it.type) @@ -121,20 +121,20 @@ class AppComponentsBreadcrumbsIntegrationTest { fun `When trim memory event with level not so high, do not add a breadcrumb`() { val sut = fixture.getSut() val options = SentryAndroidOptions() - val hub = mock() - sut.register(hub, options) + val scopes = mock() + sut.register(scopes, options) sut.onTrimMemory(ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL) - verify(hub, never()).addBreadcrumb(any()) + verify(scopes, never()).addBreadcrumb(any()) } @Test fun `When device orientation event, a breadcrumb with type, category and level should be set`() { val sut = AppComponentsBreadcrumbsIntegration(ApplicationProvider.getApplicationContext()) val options = SentryAndroidOptions() - val hub = mock() - sut.register(hub, options) + val scopes = mock() + sut.register(scopes, options) sut.onConfigurationChanged(mock()) - verify(hub).addBreadcrumb( + verify(scopes).addBreadcrumb( check { assertEquals("device.orientation", it.category) assertEquals("navigation", it.type) diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/AppLifecycleIntegrationTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/AppLifecycleIntegrationTest.kt index ed8d53227c..733aefa8d6 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/AppLifecycleIntegrationTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/AppLifecycleIntegrationTest.kt @@ -2,7 +2,7 @@ package io.sentry.android.core import android.os.Looper import androidx.test.ext.junit.runners.AndroidJUnit4 -import io.sentry.IHub +import io.sentry.IScopes import org.junit.runner.RunWith import org.mockito.kotlin.any import org.mockito.kotlin.mock @@ -17,7 +17,7 @@ import kotlin.test.assertNull class AppLifecycleIntegrationTest { private class Fixture { - val hub = mock() + val scopes = mock() lateinit var handler: MainLooperHandler val options = SentryAndroidOptions() @@ -33,7 +33,7 @@ class AppLifecycleIntegrationTest { fun `When AppLifecycleIntegration is added, lifecycle watcher should be started`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertNotNull(sut.watcher) } @@ -46,7 +46,7 @@ class AppLifecycleIntegrationTest { isEnableAutoSessionTracking = false } - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertNull(sut.watcher) } @@ -55,7 +55,7 @@ class AppLifecycleIntegrationTest { fun `When AppLifecycleIntegration is closed, lifecycle watcher should be closed`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertNotNull(sut.watcher) @@ -70,7 +70,7 @@ class AppLifecycleIntegrationTest { val latch = CountDownLatch(1) Thread { - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) latch.countDown() }.start() @@ -84,7 +84,7 @@ class AppLifecycleIntegrationTest { val sut = fixture.getSut() val latch = CountDownLatch(1) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertNotNull(sut.watcher) @@ -103,7 +103,7 @@ class AppLifecycleIntegrationTest { val sut = fixture.getSut(mockHandler = false) val latch = CountDownLatch(1) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertNotNull(sut.watcher) diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/CurrentActivityIntegrationTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/CurrentActivityIntegrationTest.kt index 6330623121..ecdbff5104 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/CurrentActivityIntegrationTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/CurrentActivityIntegrationTest.kt @@ -3,7 +3,7 @@ package io.sentry.android.core import android.app.Activity import android.app.Application import androidx.test.ext.junit.runners.AndroidJUnit4 -import io.sentry.IHub +import io.sentry.IScopes import org.junit.runner.RunWith import org.mockito.kotlin.any import org.mockito.kotlin.mock @@ -19,7 +19,7 @@ class CurrentActivityIntegrationTest { private class Fixture { val application = mock() val activity = mock() - val hub = mock() + val scopes = mock() val options = SentryAndroidOptions().apply { dsn = "https://key@sentry.io/proj" @@ -27,7 +27,7 @@ class CurrentActivityIntegrationTest { fun getSut(): CurrentActivityIntegration { val integration = CurrentActivityIntegration(application) - integration.register(hub, options) + integration.register(scopes, options) return integration } } diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/DefaultAndroidEventProcessorTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/DefaultAndroidEventProcessorTest.kt index 80954f67a5..c4fef01cc2 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/DefaultAndroidEventProcessorTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/DefaultAndroidEventProcessorTest.kt @@ -7,7 +7,7 @@ import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import io.sentry.DiagnosticLogger import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryEvent import io.sentry.SentryLevel import io.sentry.SentryTracer @@ -62,13 +62,13 @@ class DefaultAndroidEventProcessorTest { sdkVersion = SdkVersion("test", "1.2.3") } - val hub: IHub = mock() + val scopes: IScopes = mock() lateinit var sentryTracer: SentryTracer fun getSut(context: Context): DefaultAndroidEventProcessor { - whenever(hub.options).thenReturn(options) - sentryTracer = SentryTracer(TransactionContext("", ""), hub) + whenever(scopes.options).thenReturn(options) + sentryTracer = SentryTracer(TransactionContext("", ""), scopes) return DefaultAndroidEventProcessor(context, buildInfo, options) } } diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/EnvelopeFileObserverIntegrationTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/EnvelopeFileObserverIntegrationTest.kt index 699fa2d2f2..192565f101 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/EnvelopeFileObserverIntegrationTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/EnvelopeFileObserverIntegrationTest.kt @@ -2,8 +2,8 @@ package io.sentry.android.core import androidx.test.ext.junit.runners.AndroidJUnit4 import io.sentry.Hub -import io.sentry.IHub import io.sentry.ILogger +import io.sentry.IScopes import io.sentry.SentryLevel import io.sentry.SentryOptions import io.sentry.test.DeferredExecutorService @@ -24,7 +24,7 @@ import kotlin.test.assertEquals @RunWith(AndroidJUnit4::class) class EnvelopeFileObserverIntegrationTest { inner class Fixture { - val hub: IHub = mock() + val scopes: IScopes = mock() private lateinit var options: SentryAndroidOptions val logger = mock() @@ -33,7 +33,7 @@ class EnvelopeFileObserverIntegrationTest { options.setLogger(logger) options.isDebug = true optionConfiguration(options) - whenever(hub.options).thenReturn(options) + whenever(scopes.options).thenReturn(options) return object : EnvelopeFileObserverIntegration() { override fun getPath(options: SentryOptions): String? = file.absolutePath @@ -65,7 +65,7 @@ class EnvelopeFileObserverIntegrationTest { } @Test - fun `when hub is closed, integrations should be closed`() { + fun `when scopes is closed, integrations should be closed`() { val integrationMock = mock() val options = SentryOptions() options.dsn = "https://key@sentry.io/proj" @@ -73,19 +73,19 @@ class EnvelopeFileObserverIntegrationTest { options.addIntegration(integrationMock) options.setSerializer(mock()) // val expected = HubAdapter.getInstance() - val hub = Hub(options) + val scopes = Hub(options) // verify(integrationMock).register(expected, options) - hub.close() + scopes.close() verify(integrationMock).close() } @Test - fun `when hub is closed right after start, integration is not registered`() { + fun `when scopes is closed right after start, integration is not registered`() { val deferredExecutorService = DeferredExecutorService() val integration = fixture.getSut { it.executorService = deferredExecutorService } - integration.register(fixture.hub, fixture.hub.options) + integration.register(fixture.scopes, fixture.scopes.options) integration.close() deferredExecutorService.runAll() verify(fixture.logger, never()).log(eq(SentryLevel.DEBUG), eq("EnvelopeFileObserverIntegration installed.")) @@ -96,7 +96,7 @@ class EnvelopeFileObserverIntegrationTest { val integration = fixture.getSut { it.executorService = mock() } - integration.register(fixture.hub, fixture.hub.options) + integration.register(fixture.scopes, fixture.scopes.options) verify(fixture.logger).log( eq(SentryLevel.DEBUG), eq("Registering EnvelopeFileObserverIntegration for path: %s"), @@ -110,7 +110,7 @@ class EnvelopeFileObserverIntegrationTest { val integration = fixture.getSut { it.executorService = ImmediateExecutorService() } - integration.register(fixture.hub, fixture.hub.options) + integration.register(fixture.scopes, fixture.scopes.options) verify(fixture.logger).log( eq(SentryLevel.DEBUG), eq("Registering EnvelopeFileObserverIntegration for path: %s"), diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/LifecycleWatcherTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/LifecycleWatcherTest.kt index be30993142..73571a5ad4 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/LifecycleWatcherTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/LifecycleWatcherTest.kt @@ -3,8 +3,8 @@ package io.sentry.android.core import androidx.lifecycle.LifecycleOwner import io.sentry.Breadcrumb import io.sentry.DateUtils -import io.sentry.IHub import io.sentry.IScope +import io.sentry.IScopes import io.sentry.ScopeCallback import io.sentry.SentryLevel import io.sentry.Session @@ -32,7 +32,7 @@ class LifecycleWatcherTest { private class Fixture { val ownerMock = mock() - val hub = mock() + val scopes = mock() val dateProvider = mock() fun getSUT( @@ -44,12 +44,12 @@ class LifecycleWatcherTest { val argumentCaptor: ArgumentCaptor = ArgumentCaptor.forClass(ScopeCallback::class.java) val scope = mock() whenever(scope.session).thenReturn(session) - whenever(hub.configureScope(argumentCaptor.capture())).thenAnswer { + whenever(scopes.configureScope(argumentCaptor.capture())).thenAnswer { argumentCaptor.value.run(scope) } return LifecycleWatcher( - hub, + scopes, sessionIntervalMillis, enableAutoSessionTracking, enableAppLifecycleBreadcrumbs, @@ -69,7 +69,7 @@ class LifecycleWatcherTest { fun `if last started session is 0, start new session`() { val watcher = fixture.getSUT(enableAppLifecycleBreadcrumbs = false) watcher.onStart(fixture.ownerMock) - verify(fixture.hub).startSession() + verify(fixture.scopes).startSession() } @Test @@ -78,7 +78,7 @@ class LifecycleWatcherTest { whenever(fixture.dateProvider.currentTimeMillis).thenReturn(1L, 2L) watcher.onStart(fixture.ownerMock) watcher.onStart(fixture.ownerMock) - verify(fixture.hub, times(2)).startSession() + verify(fixture.scopes, times(2)).startSession() } @Test @@ -87,7 +87,7 @@ class LifecycleWatcherTest { whenever(fixture.dateProvider.currentTimeMillis).thenReturn(2L, 1L) watcher.onStart(fixture.ownerMock) watcher.onStart(fixture.ownerMock) - verify(fixture.hub).startSession() + verify(fixture.scopes).startSession() } @Test @@ -95,7 +95,7 @@ class LifecycleWatcherTest { val watcher = fixture.getSUT(enableAppLifecycleBreadcrumbs = false) watcher.onStart(fixture.ownerMock) watcher.onStop(fixture.ownerMock) - verify(fixture.hub, timeout(10000)).endSession() + verify(fixture.scopes, timeout(10000)).endSession() } @Test @@ -109,14 +109,14 @@ class LifecycleWatcherTest { watcher.onStart(fixture.ownerMock) assertNull(watcher.timerTask) - verify(fixture.hub, never()).endSession() + verify(fixture.scopes, never()).endSession() } @Test fun `When session tracking is disabled, do not start session`() { val watcher = fixture.getSUT(enableAutoSessionTracking = false, enableAppLifecycleBreadcrumbs = false) watcher.onStart(fixture.ownerMock) - verify(fixture.hub, never()).startSession() + verify(fixture.scopes, never()).startSession() } @Test @@ -124,14 +124,14 @@ class LifecycleWatcherTest { val watcher = fixture.getSUT(enableAutoSessionTracking = false, enableAppLifecycleBreadcrumbs = false) watcher.onStop(fixture.ownerMock) assertNull(watcher.timerTask) - verify(fixture.hub, never()).endSession() + verify(fixture.scopes, never()).endSession() } @Test fun `When session tracking is enabled, add breadcrumb on start`() { val watcher = fixture.getSUT(enableAppLifecycleBreadcrumbs = false) watcher.onStart(fixture.ownerMock) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("app.lifecycle", it.category) assertEquals("session", it.type) @@ -145,8 +145,8 @@ class LifecycleWatcherTest { fun `When session tracking is enabled, add breadcrumb on stop`() { val watcher = fixture.getSUT(enableAppLifecycleBreadcrumbs = false) watcher.onStop(fixture.ownerMock) - verify(fixture.hub, timeout(10000)).endSession() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes, timeout(10000)).endSession() + verify(fixture.scopes).addBreadcrumb( check { assertEquals("app.lifecycle", it.category) assertEquals("session", it.type) @@ -160,7 +160,7 @@ class LifecycleWatcherTest { fun `When session tracking is disabled, do not add breadcrumb on start`() { val watcher = fixture.getSUT(enableAutoSessionTracking = false, enableAppLifecycleBreadcrumbs = false) watcher.onStart(fixture.ownerMock) - verify(fixture.hub, never()).addBreadcrumb(any()) + verify(fixture.scopes, never()).addBreadcrumb(any()) } @Test @@ -168,14 +168,14 @@ class LifecycleWatcherTest { val watcher = fixture.getSUT(enableAutoSessionTracking = false, enableAppLifecycleBreadcrumbs = false) watcher.onStop(fixture.ownerMock) assertNull(watcher.timerTask) - verify(fixture.hub, never()).addBreadcrumb(any()) + verify(fixture.scopes, never()).addBreadcrumb(any()) } @Test fun `When app lifecycle breadcrumbs is enabled, add breadcrumb on start`() { val watcher = fixture.getSUT(enableAutoSessionTracking = false) watcher.onStart(fixture.ownerMock) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("app.lifecycle", it.category) assertEquals("navigation", it.type) @@ -189,14 +189,14 @@ class LifecycleWatcherTest { fun `When app lifecycle breadcrumbs is disabled, do not add breadcrumb on start`() { val watcher = fixture.getSUT(enableAutoSessionTracking = false, enableAppLifecycleBreadcrumbs = false) watcher.onStart(fixture.ownerMock) - verify(fixture.hub, never()).addBreadcrumb(any()) + verify(fixture.scopes, never()).addBreadcrumb(any()) } @Test fun `When app lifecycle breadcrumbs is enabled, add breadcrumb on stop`() { val watcher = fixture.getSUT(enableAutoSessionTracking = false) watcher.onStop(fixture.ownerMock) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("app.lifecycle", it.category) assertEquals("navigation", it.type) @@ -210,7 +210,7 @@ class LifecycleWatcherTest { fun `When app lifecycle breadcrumbs is disabled, do not add breadcrumb on stop`() { val watcher = fixture.getSUT(enableAutoSessionTracking = false, enableAppLifecycleBreadcrumbs = false) watcher.onStop(fixture.ownerMock) - verify(fixture.hub, never()).addBreadcrumb(any()) + verify(fixture.scopes, never()).addBreadcrumb(any()) } @Test @@ -226,7 +226,7 @@ class LifecycleWatcherTest { } @Test - fun `if the hub has already a fresh session running, don't start new one`() { + fun `if the scopes has already a fresh session running, don't start new one`() { val watcher = fixture.getSUT( enableAppLifecycleBreadcrumbs = false, session = Session( @@ -248,11 +248,11 @@ class LifecycleWatcherTest { ) watcher.onStart(fixture.ownerMock) - verify(fixture.hub, never()).startSession() + verify(fixture.scopes, never()).startSession() } @Test - fun `if the hub has a long running session, start new one`() { + fun `if the scopes has a long running session, start new one`() { val watcher = fixture.getSUT( enableAppLifecycleBreadcrumbs = false, session = Session( @@ -274,7 +274,7 @@ class LifecycleWatcherTest { ) watcher.onStart(fixture.ownerMock) - verify(fixture.hub).startSession() + verify(fixture.scopes).startSession() } @Test diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/NdkIntegrationTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/NdkIntegrationTest.kt index e86de06814..e282ad7141 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/NdkIntegrationTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/NdkIntegrationTest.kt @@ -1,7 +1,7 @@ package io.sentry.android.core -import io.sentry.IHub import io.sentry.ILogger +import io.sentry.IScopes import io.sentry.SentryLevel import org.mockito.kotlin.any import org.mockito.kotlin.eq @@ -15,7 +15,7 @@ import kotlin.test.assertTrue class NdkIntegrationTest { private class Fixture { - val hub = mock() + val scopes = mock() val logger = mock() fun getSut(clazz: Class<*>? = SentryNdk::class.java): NdkIntegration { @@ -31,7 +31,7 @@ class NdkIntegrationTest { val options = getOptions() - integration.register(fixture.hub, options) + integration.register(fixture.scopes, options) verify(fixture.logger, never()).log(eq(SentryLevel.ERROR), any(), any()) assertTrue(options.isEnableNdk) @@ -44,7 +44,7 @@ class NdkIntegrationTest { val options = getOptions() - integration.register(fixture.hub, options) + integration.register(fixture.scopes, options) assertTrue(options.isEnableNdk) assertTrue(options.isEnableScopeSync) @@ -62,7 +62,7 @@ class NdkIntegrationTest { val options = getOptions(enableNdk = false) - integration.register(fixture.hub, options) + integration.register(fixture.scopes, options) verify(fixture.logger, never()).log(eq(SentryLevel.ERROR), any(), any()) @@ -76,7 +76,7 @@ class NdkIntegrationTest { val options = getOptions() - integration.register(fixture.hub, options) + integration.register(fixture.scopes, options) verify(fixture.logger, never()).log(eq(SentryLevel.ERROR), any(), any()) @@ -90,7 +90,7 @@ class NdkIntegrationTest { val options = getOptions() - integration.register(fixture.hub, options) + integration.register(fixture.scopes, options) verify(fixture.logger).log(eq(SentryLevel.ERROR), any(), any()) @@ -104,7 +104,7 @@ class NdkIntegrationTest { val options = getOptions() - integration.register(fixture.hub, options) + integration.register(fixture.scopes, options) assertTrue(options.isEnableNdk) assertTrue(options.isEnableScopeSync) @@ -122,7 +122,7 @@ class NdkIntegrationTest { val options = getOptions() - integration.register(fixture.hub, options) + integration.register(fixture.scopes, options) verify(fixture.logger).log(eq(SentryLevel.ERROR), any(), any()) @@ -136,7 +136,7 @@ class NdkIntegrationTest { val options = getOptions(cacheDir = null) - integration.register(fixture.hub, options) + integration.register(fixture.scopes, options) verify(fixture.logger).log(eq(SentryLevel.ERROR), any()) @@ -150,7 +150,7 @@ class NdkIntegrationTest { val options = getOptions(cacheDir = "") - integration.register(fixture.hub, options) + integration.register(fixture.scopes, options) verify(fixture.logger).log(eq(SentryLevel.ERROR), any()) diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/NetworkBreadcrumbsIntegrationTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/NetworkBreadcrumbsIntegrationTest.kt index 146f229fdf..c28cf64085 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/NetworkBreadcrumbsIntegrationTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/NetworkBreadcrumbsIntegrationTest.kt @@ -8,7 +8,7 @@ import android.net.NetworkCapabilities import android.os.Build import io.sentry.Breadcrumb import io.sentry.DateUtils -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryDateProvider import io.sentry.SentryLevel import io.sentry.SentryNanotimeDate @@ -39,7 +39,7 @@ class NetworkBreadcrumbsIntegrationTest { private class Fixture { val context = mock() var options = SentryAndroidOptions() - val hub = mock() + val scopes = mock() val mockBuildInfoProvider = mock() val connectivityManager = mock() var nowMs: Long = 0 @@ -68,7 +68,7 @@ class NetworkBreadcrumbsIntegrationTest { fun `When network events breadcrumb is enabled, it registers callback`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.connectivityManager).registerDefaultNetworkCallback(any()) assertNotNull(sut.networkCallback) @@ -78,7 +78,7 @@ class NetworkBreadcrumbsIntegrationTest { fun `When system events breadcrumb is disabled, it doesn't register callback`() { val sut = fixture.getSut(enableNetworkEventBreadcrumbs = false) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.connectivityManager, never()).registerDefaultNetworkCallback(any()) assertNull(sut.networkCallback) @@ -90,7 +90,7 @@ class NetworkBreadcrumbsIntegrationTest { whenever(buildInfo.sdkInfoVersion).thenReturn(Build.VERSION_CODES.M) val sut = fixture.getSut(buildInfo = buildInfo) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.connectivityManager, never()).registerDefaultNetworkCallback(any()) assertNull(sut.networkCallback) @@ -100,7 +100,7 @@ class NetworkBreadcrumbsIntegrationTest { fun `When NetworkBreadcrumbsIntegration is closed, it should unregister the callback`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) sut.close() verify(fixture.connectivityManager).unregisterNetworkCallback(any()) @@ -114,7 +114,7 @@ class NetworkBreadcrumbsIntegrationTest { val sut = fixture.getSut(buildInfo = buildInfo) assertNull(sut.networkCallback) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) sut.close() verify(fixture.connectivityManager, never()).unregisterNetworkCallback(any()) @@ -124,12 +124,12 @@ class NetworkBreadcrumbsIntegrationTest { @Test fun `When connected to a new network, a breadcrumb is captured`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) callback.onAvailable(mock()) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("system", it.type) assertEquals("network.event", it.category) @@ -142,27 +142,27 @@ class NetworkBreadcrumbsIntegrationTest { @Test fun `When connected to the same network without disconnecting from the previous one, only one breadcrumb is captured`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) callback.onAvailable(fixture.network) callback.onAvailable(fixture.network) - verify(fixture.hub, times(1)).addBreadcrumb(any()) + verify(fixture.scopes, times(1)).addBreadcrumb(any()) } @Test fun `When disconnected from a network, a breadcrumb is captured`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) callback.onAvailable(fixture.network) - verify(fixture.hub).addBreadcrumb(any()) + verify(fixture.scopes).addBreadcrumb(any()) callback.onLost(fixture.network) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("system", it.type) assertEquals("network.event", it.category) @@ -175,12 +175,12 @@ class NetworkBreadcrumbsIntegrationTest { @Test fun `When disconnected from a network, a breadcrumb is captured only if previously connected to that network`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) // callback.onAvailable(network) was not called, so no breadcrumb should be captured callback.onLost(mock()) - verify(fixture.hub, never()).addBreadcrumb(any()) + verify(fixture.scopes, never()).addBreadcrumb(any()) } @Test @@ -188,7 +188,7 @@ class NetworkBreadcrumbsIntegrationTest { val buildInfo = mock() whenever(buildInfo.sdkInfoVersion).thenReturn(Build.VERSION_CODES.Q) val sut = fixture.getSut(buildInfo = buildInfo) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) callback.onAvailable(fixture.network) @@ -204,7 +204,7 @@ class NetworkBreadcrumbsIntegrationTest { isCellular = false ) ) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("system", it.type) assertEquals("network.event", it.category) @@ -223,18 +223,18 @@ class NetworkBreadcrumbsIntegrationTest { @Test fun `When a network connection detail changes, a breadcrumb is captured only if previously connected to that network`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) // callback.onAvailable(network) was not called, so no breadcrumb should be captured onCapabilitiesChanged(callback, mock()) - verify(fixture.hub, never()).addBreadcrumb(any(), anyOrNull()) + verify(fixture.scopes, never()).addBreadcrumb(any(), anyOrNull()) } @Test fun `When a network connection detail changes, a new breadcrumb is captured if vpn flag changes`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) callback.onAvailable(fixture.network) @@ -245,17 +245,17 @@ class NetworkBreadcrumbsIntegrationTest { onCapabilitiesChanged(callback, details1) onCapabilitiesChanged(callback, details2) onCapabilitiesChanged(callback, details3) - inOrder(fixture.hub) { + inOrder(fixture.scopes) { verifyBreadcrumbInOrder { assertFalse(it.isVpn) } verifyBreadcrumbInOrder { assertTrue(it.isVpn) } - verify(fixture.hub, never()).addBreadcrumb(any(), any()) + verify(fixture.scopes, never()).addBreadcrumb(any(), any()) } } @Test fun `When a network connection detail changes, a new breadcrumb is captured if type changes`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) callback.onAvailable(fixture.network) @@ -266,10 +266,10 @@ class NetworkBreadcrumbsIntegrationTest { onCapabilitiesChanged(callback, details1) onCapabilitiesChanged(callback, details2) onCapabilitiesChanged(callback, details3) - inOrder(fixture.hub) { + inOrder(fixture.scopes) { verifyBreadcrumbInOrder { assertEquals("wifi", it.type) } verifyBreadcrumbInOrder { assertEquals("cellular", it.type) } - verify(fixture.hub, never()).addBreadcrumb(any(), any()) + verify(fixture.scopes, never()).addBreadcrumb(any(), any()) } } @@ -278,7 +278,7 @@ class NetworkBreadcrumbsIntegrationTest { val buildInfo = mock() whenever(buildInfo.sdkInfoVersion).thenReturn(Build.VERSION_CODES.Q) val sut = fixture.getSut(buildInfo = buildInfo) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) callback.onAvailable(fixture.network) @@ -289,10 +289,10 @@ class NetworkBreadcrumbsIntegrationTest { // A change of signal strength of 5 doesn't trigger a new breadcrumb onCapabilitiesChanged(callback, details2) onCapabilitiesChanged(callback, details3) - inOrder(fixture.hub) { + inOrder(fixture.scopes) { verifyBreadcrumbInOrder { assertEquals(50, it.signalStrength) } verifyBreadcrumbInOrder { assertEquals(56, it.signalStrength) } - verify(fixture.hub, never()).addBreadcrumb(any(), any()) + verify(fixture.scopes, never()).addBreadcrumb(any(), any()) } } @@ -301,7 +301,7 @@ class NetworkBreadcrumbsIntegrationTest { val buildInfo = mock() whenever(buildInfo.sdkInfoVersion).thenReturn(Build.VERSION_CODES.Q) val sut = fixture.getSut(buildInfo = buildInfo) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) callback.onAvailable(fixture.network) @@ -317,11 +317,11 @@ class NetworkBreadcrumbsIntegrationTest { // A change of download bandwidth of 10% (more than 1000) doesn't trigger a new breadcrumb onCapabilitiesChanged(callback, details4) onCapabilitiesChanged(callback, details5) - inOrder(fixture.hub) { + inOrder(fixture.scopes) { verifyBreadcrumbInOrder { assertEquals(1000, it.downBandwidth) } verifyBreadcrumbInOrder { assertEquals(20000, it.downBandwidth) } verifyBreadcrumbInOrder { assertEquals(22001, it.downBandwidth) } - verify(fixture.hub, never()).addBreadcrumb(any(), any()) + verify(fixture.scopes, never()).addBreadcrumb(any(), any()) } } @@ -330,7 +330,7 @@ class NetworkBreadcrumbsIntegrationTest { val buildInfo = mock() whenever(buildInfo.sdkInfoVersion).thenReturn(Build.VERSION_CODES.Q) val sut = fixture.getSut(buildInfo = buildInfo) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) callback.onAvailable(fixture.network) @@ -346,18 +346,18 @@ class NetworkBreadcrumbsIntegrationTest { // A change of upload bandwidth of 10% (more than 1000) doesn't trigger a new breadcrumb onCapabilitiesChanged(callback, details4) onCapabilitiesChanged(callback, details5) - inOrder(fixture.hub) { + inOrder(fixture.scopes) { verifyBreadcrumbInOrder { assertEquals(1000, it.upBandwidth) } verifyBreadcrumbInOrder { assertEquals(20000, it.upBandwidth) } verifyBreadcrumbInOrder { assertEquals(22001, it.upBandwidth) } - verify(fixture.hub, never()).addBreadcrumb(any(), any()) + verify(fixture.scopes, never()).addBreadcrumb(any(), any()) } } @Test fun `signal strength is 0 if not on Android Q+`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) callback.onAvailable(fixture.network) @@ -371,7 +371,7 @@ class NetworkBreadcrumbsIntegrationTest { val buildInfo = mock() whenever(buildInfo.sdkInfoVersion).thenReturn(Build.VERSION_CODES.Q) val sut = fixture.getSut(buildInfo = buildInfo) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) callback.onAvailable(fixture.network) @@ -384,7 +384,7 @@ class NetworkBreadcrumbsIntegrationTest { @Test fun `A breadcrumb is captured when vpn status changes, regardless of the timestamp`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) callback.onAvailable(fixture.network) @@ -392,17 +392,17 @@ class NetworkBreadcrumbsIntegrationTest { val details2 = createConnectionDetail(isVpn = true) onCapabilitiesChanged(callback, details1, 0) onCapabilitiesChanged(callback, details2, 0) - inOrder(fixture.hub) { + inOrder(fixture.scopes) { verifyBreadcrumbInOrder { assertFalse(it.isVpn) } verifyBreadcrumbInOrder { assertTrue(it.isVpn) } - verify(fixture.hub, never()).addBreadcrumb(any(), any()) + verify(fixture.scopes, never()).addBreadcrumb(any(), any()) } } @Test fun `A breadcrumb is captured when connection type changes, regardless of the timestamp`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) callback.onAvailable(fixture.network) @@ -412,11 +412,11 @@ class NetworkBreadcrumbsIntegrationTest { onCapabilitiesChanged(callback, details1, 0) onCapabilitiesChanged(callback, details2, 0) onCapabilitiesChanged(callback, details3, 0) - inOrder(fixture.hub) { + inOrder(fixture.scopes) { verifyBreadcrumbInOrder { assertEquals("wifi", it.type) } verifyBreadcrumbInOrder { assertEquals("cellular", it.type) } verifyBreadcrumbInOrder { assertEquals("ethernet", it.type) } - verify(fixture.hub, never()).addBreadcrumb(any(), any()) + verify(fixture.scopes, never()).addBreadcrumb(any(), any()) } } @@ -425,7 +425,7 @@ class NetworkBreadcrumbsIntegrationTest { val buildInfo = mock() whenever(buildInfo.sdkInfoVersion).thenReturn(Build.VERSION_CODES.Q) val sut = fixture.getSut(buildInfo = buildInfo) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) callback.onAvailable(fixture.network) @@ -435,17 +435,17 @@ class NetworkBreadcrumbsIntegrationTest { onCapabilitiesChanged(callback, details1, 0) onCapabilitiesChanged(callback, details2, 0) onCapabilitiesChanged(callback, details3, 5000) - inOrder(fixture.hub) { + inOrder(fixture.scopes) { verifyBreadcrumbInOrder { assertEquals(1, it.signalStrength) } verifyBreadcrumbInOrder { assertEquals(51, it.signalStrength) } - verify(fixture.hub, never()).addBreadcrumb(any(), any()) + verify(fixture.scopes, never()).addBreadcrumb(any(), any()) } } @Test fun `A breadcrumb is captured when downBandwidth changes at most once every 5 seconds`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) callback.onAvailable(fixture.network) @@ -455,17 +455,17 @@ class NetworkBreadcrumbsIntegrationTest { onCapabilitiesChanged(callback, details1, 0) onCapabilitiesChanged(callback, details2, 0) onCapabilitiesChanged(callback, details3, 5000) - inOrder(fixture.hub) { + inOrder(fixture.scopes) { verifyBreadcrumbInOrder { assertEquals(1, it.downBandwidth) } verifyBreadcrumbInOrder { assertEquals(2001, it.downBandwidth) } - verify(fixture.hub, never()).addBreadcrumb(any(), any()) + verify(fixture.scopes, never()).addBreadcrumb(any(), any()) } } @Test fun `A breadcrumb is captured when upBandwidth changes at most once every 5 seconds`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val callback = sut.networkCallback assertNotNull(callback) callback.onAvailable(fixture.network) @@ -475,15 +475,15 @@ class NetworkBreadcrumbsIntegrationTest { onCapabilitiesChanged(callback, details1, 0) onCapabilitiesChanged(callback, details2, 0) onCapabilitiesChanged(callback, details3, 5000) - inOrder(fixture.hub) { + inOrder(fixture.scopes) { verifyBreadcrumbInOrder { assertEquals(1, it.upBandwidth) } verifyBreadcrumbInOrder { assertEquals(2001, it.upBandwidth) } - verify(fixture.hub, never()).addBreadcrumb(any(), any()) + verify(fixture.scopes, never()).addBreadcrumb(any(), any()) } } private fun KInOrder.verifyBreadcrumbInOrder(check: (detail: NetworkBreadcrumbConnectionDetail) -> Unit) { - verify(fixture.hub, times(1)).addBreadcrumb( + verify(fixture.scopes, times(1)).addBreadcrumb( any(), check { val connectionDetail = it[TypeCheckHint.ANDROID_NETWORK_CAPABILITIES] as NetworkBreadcrumbConnectionDetail @@ -493,7 +493,7 @@ class NetworkBreadcrumbsIntegrationTest { } private fun verifyBreadcrumb(check: (detail: NetworkBreadcrumbConnectionDetail) -> Unit) { - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( any(), check { val connectionDetail = it[TypeCheckHint.ANDROID_NETWORK_CAPABILITIES] as NetworkBreadcrumbConnectionDetail diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/PerformanceAndroidEventProcessorTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/PerformanceAndroidEventProcessorTest.kt index 4c23691e63..e1593e600f 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/PerformanceAndroidEventProcessorTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/PerformanceAndroidEventProcessorTest.kt @@ -3,7 +3,7 @@ package io.sentry.android.core import android.content.ContentProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.MeasurementUnit import io.sentry.SentryTracer import io.sentry.SpanContext @@ -35,7 +35,7 @@ class PerformanceAndroidEventProcessorTest { private class Fixture { val options = SentryAndroidOptions() - val hub = mock() + val scopes = mock() val context = TransactionContext("name", "op", TracesSamplingDecision(true)) lateinit var tracer: SentryTracer val activityFramesTracker = mock() @@ -46,8 +46,8 @@ class PerformanceAndroidEventProcessorTest { ): PerformanceAndroidEventProcessor { options.tracesSampleRate = tracesSampleRate options.isEnablePerformanceV2 = enablePerformanceV2 - whenever(hub.options).thenReturn(options) - tracer = SentryTracer(context, hub) + whenever(scopes.options).thenReturn(options) + tracer = SentryTracer(context, scopes) return PerformanceAndroidEventProcessor(options, activityFramesTracker) } } @@ -181,7 +181,7 @@ class PerformanceAndroidEventProcessorTest { fun `add slow and frozen frames if auto transaction`() { val sut = fixture.getSut() val context = TransactionContext("Activity", UI_LOAD_OP) - val tracer = SentryTracer(context, fixture.hub) + val tracer = SentryTracer(context, fixture.scopes) var tr = SentryTransaction(tracer) val metrics = mapOf( @@ -227,7 +227,7 @@ class PerformanceAndroidEventProcessorTest { // when an activity transaction is created val sut = fixture.getSut(enablePerformanceV2 = true) val context = TransactionContext("Activity", UI_LOAD_OP) - val tracer = SentryTracer(context, fixture.hub) + val tracer = SentryTracer(context, fixture.scopes) var tr = SentryTransaction(tracer) // and it contains an app.start.cold span @@ -297,7 +297,7 @@ class PerformanceAndroidEventProcessorTest { // when an activity transaction is created val sut = fixture.getSut(enablePerformanceV2 = true) val context = TransactionContext("Activity", UI_LOAD_OP) - val tracer = SentryTracer(context, fixture.hub) + val tracer = SentryTracer(context, fixture.scopes) var tr = SentryTransaction(tracer) // then the app start metrics should not be attached @@ -326,7 +326,7 @@ class PerformanceAndroidEventProcessorTest { // when the first activity transaction is created val sut = fixture.getSut(enablePerformanceV2 = true) val context = TransactionContext("Activity", UI_LOAD_OP) - val tracer = SentryTracer(context, fixture.hub) + val tracer = SentryTracer(context, fixture.scopes) var tr = SentryTransaction(tracer) val appStartSpan = SentrySpan( 0.0, @@ -377,7 +377,7 @@ class PerformanceAndroidEventProcessorTest { val sut = fixture.getSut(enablePerformanceV2 = true) val context = TransactionContext("Activity", UI_LOAD_OP) - val tracer = SentryTracer(context, fixture.hub) + val tracer = SentryTracer(context, fixture.scopes) var tr = SentryTransaction(tracer) val appStartSpan = SentrySpan( 0.0, @@ -424,7 +424,7 @@ class PerformanceAndroidEventProcessorTest { val sut = fixture.getSut(enablePerformanceV2 = true) val context = TransactionContext("Activity", UI_LOAD_OP) - val tracer = SentryTracer(context, fixture.hub) + val tracer = SentryTracer(context, fixture.scopes) var tr = SentryTransaction(tracer) val appStartSpan = SentrySpan( 0.0, diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/PhoneStateBreadcrumbsIntegrationTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/PhoneStateBreadcrumbsIntegrationTest.kt index 2b6ca801da..c764d11c2d 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/PhoneStateBreadcrumbsIntegrationTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/PhoneStateBreadcrumbsIntegrationTest.kt @@ -4,7 +4,7 @@ import android.content.Context import android.telephony.PhoneStateListener import android.telephony.TelephonyManager import io.sentry.Breadcrumb -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ISentryExecutorService import io.sentry.SentryLevel import io.sentry.test.DeferredExecutorService @@ -41,8 +41,8 @@ class PhoneStateBreadcrumbsIntegrationTest { @Test fun `When system events breadcrumb is enabled, it registers callback`() { val sut = fixture.getSut() - val hub = mock() - sut.register(hub, fixture.options) + val scopes = mock() + sut.register(scopes, fixture.options) verify(fixture.manager).listen(any(), eq(PhoneStateListener.LISTEN_CALL_STATE)) assertNotNull(sut.listener) } @@ -50,8 +50,8 @@ class PhoneStateBreadcrumbsIntegrationTest { @Test fun `Phone state callback is registered in the executorService`() { val sut = fixture.getSut(mock()) - val hub = mock() - sut.register(hub, fixture.options) + val scopes = mock() + sut.register(scopes, fixture.options) assertNull(sut.listener) } @@ -59,9 +59,9 @@ class PhoneStateBreadcrumbsIntegrationTest { @Test fun `When system events breadcrumb is disabled, it doesn't register callback`() { val sut = fixture.getSut() - val hub = mock() + val scopes = mock() sut.register( - hub, + scopes, fixture.options.apply { isEnableSystemEventBreadcrumbs = false } @@ -73,15 +73,15 @@ class PhoneStateBreadcrumbsIntegrationTest { @Test fun `When ActivityBreadcrumbsIntegration is closed, it should unregister the callback`() { val sut = fixture.getSut() - val hub = mock() - sut.register(hub, fixture.options) + val scopes = mock() + sut.register(scopes, fixture.options) sut.close() verify(fixture.manager).listen(any(), eq(PhoneStateListener.LISTEN_NONE)) assertNull(sut.listener) } @Test - fun `when hub is closed right after start, integration is not registered`() { + fun `when scopes is closed right after start, integration is not registered`() { val deferredExecutorService = DeferredExecutorService() val sut = fixture.getSut(executorService = deferredExecutorService) sut.register(mock(), fixture.options) @@ -94,11 +94,11 @@ class PhoneStateBreadcrumbsIntegrationTest { @Test fun `When on call state received, added breadcrumb with type and category`() { val sut = fixture.getSut() - val hub = mock() - sut.register(hub, fixture.options) + val scopes = mock() + sut.register(scopes, fixture.options) sut.listener!!.onCallStateChanged(TelephonyManager.CALL_STATE_RINGING, null) - verify(hub).addBreadcrumb( + verify(scopes).addBreadcrumb( check { assertEquals("device.event", it.category) assertEquals("system", it.type) @@ -111,18 +111,18 @@ class PhoneStateBreadcrumbsIntegrationTest { @Test fun `When on idle state received, added breadcrumb with type and category`() { val sut = fixture.getSut() - val hub = mock() - sut.register(hub, fixture.options) + val scopes = mock() + sut.register(scopes, fixture.options) sut.listener!!.onCallStateChanged(TelephonyManager.CALL_STATE_IDLE, null) - verify(hub, never()).addBreadcrumb(any()) + verify(scopes, never()).addBreadcrumb(any()) } @Test fun `When on offhook state received, added breadcrumb with type and category`() { val sut = fixture.getSut() - val hub = mock() - sut.register(hub, fixture.options) + val scopes = mock() + sut.register(scopes, fixture.options) sut.listener!!.onCallStateChanged(TelephonyManager.CALL_STATE_OFFHOOK, null) - verify(hub, never()).addBreadcrumb(any()) + verify(scopes, never()).addBreadcrumb(any()) } } diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/SendCachedEnvelopeIntegrationTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/SendCachedEnvelopeIntegrationTest.kt index 403f40ee70..f1e345eefc 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/SendCachedEnvelopeIntegrationTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/SendCachedEnvelopeIntegrationTest.kt @@ -2,8 +2,8 @@ package io.sentry.android.core import io.sentry.IConnectionStatusProvider import io.sentry.IConnectionStatusProvider.ConnectionStatus -import io.sentry.IHub import io.sentry.ILogger +import io.sentry.IScopes import io.sentry.ISentryExecutorService import io.sentry.SendCachedEnvelopeFireAndForgetIntegration.SendFireAndForget import io.sentry.SendCachedEnvelopeFireAndForgetIntegration.SendFireAndForgetFactory @@ -28,7 +28,7 @@ import kotlin.test.Test class SendCachedEnvelopeIntegrationTest { private class Fixture { - val hub: IHub = mock() + val scopes: IScopes = mock() val options = SentryAndroidOptions() val logger = mock() val factory = mock() @@ -74,7 +74,7 @@ class SendCachedEnvelopeIntegrationTest { fun `when cacheDirPath is not set, does nothing`() { val sut = fixture.getSut(cacheDirPath = null) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.factory, never()).create(any(), any()) } @@ -83,7 +83,7 @@ class SendCachedEnvelopeIntegrationTest { fun `when factory returns null, does nothing`() { val sut = fixture.getSut(hasSender = false, mockExecutorService = ImmediateExecutorService()) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.factory).create(any(), any()) verify(fixture.sender, never()).send() @@ -93,7 +93,7 @@ class SendCachedEnvelopeIntegrationTest { fun `when has factory and cacheDirPath set, submits task into queue`() { val sut = fixture.getSut(mockExecutorService = ImmediateExecutorService()) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) await.untilFalse(fixture.flag) verify(fixture.sender).send() @@ -102,7 +102,7 @@ class SendCachedEnvelopeIntegrationTest { @Test fun `when executorService is fake, does nothing`() { val sut = fixture.getSut(mockExecutorService = mock()) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.factory, never()).create(any(), any()) verify(fixture.sender, never()).send() @@ -112,7 +112,7 @@ class SendCachedEnvelopeIntegrationTest { fun `when has startup crash marker, awaits the task on the calling thread`() { val sut = fixture.getSut(hasStartupCrashMarker = true) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) // we do not need to await here, because it's executed synchronously verify(fixture.sender).send() @@ -123,7 +123,7 @@ class SendCachedEnvelopeIntegrationTest { val sut = fixture.getSut(hasStartupCrashMarker = true, delaySend = 1000) fixture.options.startupCrashFlushTimeoutMillis = 100 - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) // first wait until synchronous send times out and check that the logger was hit in the catch block await.atLeast(500, MILLISECONDS) @@ -144,7 +144,7 @@ class SendCachedEnvelopeIntegrationTest { val connectionStatusProvider = mock() fixture.options.connectionStatusProvider = connectionStatusProvider - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(connectionStatusProvider).addConnectionStatusObserver(any()) } @@ -159,7 +159,7 @@ class SendCachedEnvelopeIntegrationTest { ConnectionStatus.DISCONNECTED ) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.sender, never()).send() } @@ -174,7 +174,7 @@ class SendCachedEnvelopeIntegrationTest { ConnectionStatus.UNKNOWN ) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.factory).create(any(), any()) } @@ -187,7 +187,7 @@ class SendCachedEnvelopeIntegrationTest { whenever(connectionStatusProvider.connectionStatus).thenReturn( ConnectionStatus.DISCONNECTED ) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) // when there's no connection no factory create call should be done verify(fixture.sender, never()).send() @@ -215,9 +215,9 @@ class SendCachedEnvelopeIntegrationTest { val rateLimiter = mock { whenever(mock.isActiveForCategory(any())).thenReturn(true) } - whenever(fixture.hub.rateLimiter).thenReturn(rateLimiter) + whenever(fixture.scopes.rateLimiter).thenReturn(rateLimiter) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) // no factory call should be done if there's rate limiting active verify(fixture.sender, never()).send() @@ -228,7 +228,7 @@ class SendCachedEnvelopeIntegrationTest { val deferredExecutorService = DeferredExecutorService() val sut = fixture.getSut(mockExecutorService = deferredExecutorService) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.sender, never()).send() sut.close() diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/SystemEventsBreadcrumbsIntegrationTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/SystemEventsBreadcrumbsIntegrationTest.kt index f8293f9b87..146abb617e 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/SystemEventsBreadcrumbsIntegrationTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/SystemEventsBreadcrumbsIntegrationTest.kt @@ -3,7 +3,7 @@ package io.sentry.android.core import android.content.Context import android.content.Intent import io.sentry.Breadcrumb -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ISentryExecutorService import io.sentry.SentryLevel import io.sentry.test.DeferredExecutorService @@ -26,7 +26,7 @@ class SystemEventsBreadcrumbsIntegrationTest { private class Fixture { val context = mock() var options = SentryAndroidOptions() - val hub = mock() + val scopes = mock() fun getSut(enableSystemEventBreadcrumbs: Boolean = true, executorService: ISentryExecutorService = ImmediateExecutorService()): SystemEventsBreadcrumbsIntegration { options = SentryAndroidOptions().apply { @@ -43,7 +43,7 @@ class SystemEventsBreadcrumbsIntegrationTest { fun `When system events breadcrumb is enabled, it registers callback`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.context).registerReceiver(any(), any()) assertNotNull(sut.receiver) @@ -52,8 +52,8 @@ class SystemEventsBreadcrumbsIntegrationTest { @Test fun `system events callback is registered in the executorService`() { val sut = fixture.getSut(executorService = mock()) - val hub = mock() - sut.register(hub, fixture.options) + val scopes = mock() + sut.register(scopes, fixture.options) assertNull(sut.receiver) } @@ -62,7 +62,7 @@ class SystemEventsBreadcrumbsIntegrationTest { fun `When system events breadcrumb is disabled, it doesn't register callback`() { val sut = fixture.getSut(enableSystemEventBreadcrumbs = false) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.context, never()).registerReceiver(any(), any()) assertNull(sut.receiver) @@ -72,7 +72,7 @@ class SystemEventsBreadcrumbsIntegrationTest { fun `When ActivityBreadcrumbsIntegration is closed, it should unregister the callback`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) sut.close() verify(fixture.context).unregisterReceiver(any()) @@ -80,10 +80,10 @@ class SystemEventsBreadcrumbsIntegrationTest { } @Test - fun `when hub is closed right after start, integration is not registered`() { + fun `when scopes is closed right after start, integration is not registered`() { val deferredExecutorService = DeferredExecutorService() val sut = fixture.getSut(executorService = deferredExecutorService) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertNull(sut.receiver) sut.close() deferredExecutorService.runAll() @@ -94,13 +94,13 @@ class SystemEventsBreadcrumbsIntegrationTest { fun `When broadcast received, added breadcrumb with type and category`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) val intent = Intent().apply { action = Intent.ACTION_TIME_CHANGED } sut.receiver!!.onReceive(fixture.context, intent) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("device.event", it.category) assertEquals("system", it.type) @@ -116,7 +116,7 @@ class SystemEventsBreadcrumbsIntegrationTest { val sut = fixture.getSut() whenever(fixture.context.registerReceiver(any(), any())).thenThrow(SecurityException()) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertFalse(fixture.options.isEnableSystemEventBreadcrumbs) } diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/TempSensorBreadcrumbsIntegrationTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/TempSensorBreadcrumbsIntegrationTest.kt index d443b1e345..5d049e3dad 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/TempSensorBreadcrumbsIntegrationTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/TempSensorBreadcrumbsIntegrationTest.kt @@ -7,7 +7,7 @@ import android.hardware.SensorEventListener import android.hardware.SensorManager import io.sentry.Breadcrumb import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ISentryExecutorService import io.sentry.SentryLevel import io.sentry.TypeCheckHint @@ -47,8 +47,8 @@ class TempSensorBreadcrumbsIntegrationTest { @Test fun `When system events breadcrumb is enabled, it registers callback`() { val sut = fixture.getSut() - val hub = mock() - sut.register(hub, fixture.options) + val scopes = mock() + sut.register(scopes, fixture.options) verify(fixture.manager).registerListener(any(), any(), eq(SensorManager.SENSOR_DELAY_NORMAL)) assertNotNull(sut.sensorManager) } @@ -56,8 +56,8 @@ class TempSensorBreadcrumbsIntegrationTest { @Test fun `temp sensor listener is registered in the executorService`() { val sut = fixture.getSut(executorService = mock()) - val hub = mock() - sut.register(hub, fixture.options) + val scopes = mock() + sut.register(scopes, fixture.options) assertNull(sut.sensorManager) } @@ -65,9 +65,9 @@ class TempSensorBreadcrumbsIntegrationTest { @Test fun `When system events breadcrumb is disabled, it should not register a callback`() { val sut = fixture.getSut() - val hub = mock() + val scopes = mock() sut.register( - hub, + scopes, fixture.options.apply { isEnableSystemEventBreadcrumbs = false } @@ -79,15 +79,15 @@ class TempSensorBreadcrumbsIntegrationTest { @Test fun `When TempSensorBreadcrumbsIntegration is closed, it should unregister the callback`() { val sut = fixture.getSut() - val hub = mock() - sut.register(hub, fixture.options) + val scopes = mock() + sut.register(scopes, fixture.options) sut.close() verify(fixture.manager).unregisterListener(any()) assertNull(sut.sensorManager) } @Test - fun `when hub is closed right after start, integration is not registered`() { + fun `when scopes is closed right after start, integration is not registered`() { val deferredExecutorService = DeferredExecutorService() val sut = fixture.getSut(executorService = deferredExecutorService) sut.register(mock(), fixture.options) @@ -100,14 +100,14 @@ class TempSensorBreadcrumbsIntegrationTest { @Test fun `When onSensorChanged received, add a breadcrumb with type and category`() { val sut = fixture.getSut() - val hub = mock() - sut.register(hub, fixture.options) + val scopes = mock() + sut.register(scopes, fixture.options) val sensorCtor = "android.hardware.SensorEvent".getDeclaredCtor(emptyArray()) val sensorEvent: SensorEvent = sensorCtor.newInstance() as SensorEvent sensorEvent.injectForField("values", FloatArray(2) { 1F }) sut.onSensorChanged(sensorEvent) - verify(hub).addBreadcrumb( + verify(scopes).addBreadcrumb( check { assertEquals("device.event", it.category) assertEquals("system", it.type) @@ -122,12 +122,12 @@ class TempSensorBreadcrumbsIntegrationTest { @Test fun `When onSensorChanged received and null values, do not add a breadcrumb`() { val sut = fixture.getSut() - val hub = mock() - sut.register(hub, fixture.options) + val scopes = mock() + sut.register(scopes, fixture.options) val event = mock() assertNull(event.values) sut.onSensorChanged(event) - verify(hub, never()).addBreadcrumb(any()) + verify(scopes, never()).addBreadcrumb(any()) } } diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/SentryGestureListenerClickTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/SentryGestureListenerClickTest.kt index 1e6652276a..74edfb4302 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/SentryGestureListenerClickTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/SentryGestureListenerClickTest.kt @@ -10,8 +10,8 @@ import android.view.Window import android.widget.CheckBox import android.widget.RadioButton import io.sentry.Breadcrumb -import io.sentry.IHub import io.sentry.IScope +import io.sentry.IScopes import io.sentry.PropagationContext import io.sentry.Scope.IWithPropagationContext import io.sentry.ScopeCallback @@ -40,7 +40,7 @@ class SentryGestureListenerClickTest { gestureTargetLocators = listOf(AndroidViewGestureTargetLocator(true)) dsn = "https://key@sentry.io/proj" } - val hub = mock() + val scopes = mock() val scope = mock() val propagationContext = PropagationContext() lateinit var target: View @@ -86,11 +86,11 @@ class SentryGestureListenerClickTest { whenever(context.resources).thenReturn(resources) whenever(this.target.context).thenReturn(context) whenever(activity.window).thenReturn(window) - doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(hub).configureScope(any()) + doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(scopes).configureScope(any()) doAnswer { (it.arguments[0] as IWithPropagationContext).accept(propagationContext); propagationContext; }.whenever(scope).withPropagationContext(any()) return SentryGestureListener( activity, - hub, + scopes, options ) } @@ -123,7 +123,7 @@ class SentryGestureListenerClickTest { sut.onSingleTapUp(event) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("ui.click", it.category) assertEquals("user", it.type) @@ -146,7 +146,7 @@ class SentryGestureListenerClickTest { sut.onSingleTapUp(event) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("radio_button", it.data["view.id"]) assertEquals("android.widget.RadioButton", it.data["view.class"]) @@ -166,7 +166,7 @@ class SentryGestureListenerClickTest { sut.onSingleTapUp(event) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("check_box", it.data["view.id"]) assertEquals("android.widget.CheckBox", it.data["view.class"]) @@ -185,7 +185,7 @@ class SentryGestureListenerClickTest { sut.onSingleTapUp(event) - verify(fixture.hub, never()).addBreadcrumb(any()) + verify(fixture.scopes, never()).addBreadcrumb(any()) } @Test @@ -198,7 +198,7 @@ class SentryGestureListenerClickTest { val sut = fixture.getSut(event, "decor_view", targetOverride = decorView) sut.onSingleTapUp(event) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals(decorView.javaClass.canonicalName, it.data["view.class"]) assertEquals("decor_view", it.data["view.id"]) @@ -214,7 +214,7 @@ class SentryGestureListenerClickTest { sut.onSingleTapUp(event) - verify(fixture.hub, never()).addBreadcrumb(any()) + verify(fixture.scopes, never()).addBreadcrumb(any()) } @Test @@ -230,7 +230,7 @@ class SentryGestureListenerClickTest { sut.onSingleTapUp(event) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals(fixture.target.javaClass.simpleName, it.data["view.class"]) }, diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/SentryGestureListenerScrollTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/SentryGestureListenerScrollTest.kt index 5d39b64753..e5a9623c4d 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/SentryGestureListenerScrollTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/SentryGestureListenerScrollTest.kt @@ -11,8 +11,8 @@ import android.widget.AbsListView import android.widget.ListAdapter import androidx.core.view.ScrollingView import io.sentry.Breadcrumb -import io.sentry.IHub import io.sentry.IScope +import io.sentry.IScopes import io.sentry.PropagationContext import io.sentry.Scope import io.sentry.ScopeCallback @@ -44,7 +44,7 @@ class SentryGestureListenerScrollTest { isEnableUserInteractionTracing = true gestureTargetLocators = listOf(AndroidViewGestureTargetLocator(true)) } - val hub = mock() + val scopes = mock() val scope = mock() val propagationContext = PropagationContext() @@ -77,11 +77,11 @@ class SentryGestureListenerScrollTest { endEvent.mockDirection(firstEvent, direction) } whenever(activity.window).thenReturn(window) - doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(hub).configureScope(any()) + doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(scopes).configureScope(any()) doAnswer { (it.arguments[0] as Scope.IWithPropagationContext).accept(propagationContext); propagationContext }.whenever(scope).withPropagationContext(any()) return SentryGestureListener( activity, - hub, + scopes, options ) } @@ -99,7 +99,7 @@ class SentryGestureListenerScrollTest { } sut.onUp(fixture.endEvent) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("ui.scroll", it.category) assertEquals("user", it.type) @@ -122,7 +122,7 @@ class SentryGestureListenerScrollTest { } sut.onUp(fixture.endEvent) - verify(fixture.hub, never()).addBreadcrumb(any()) + verify(fixture.scopes, never()).addBreadcrumb(any()) } @Test @@ -143,8 +143,8 @@ class SentryGestureListenerScrollTest { sut.onFling(fixture.firstEvent, fixture.endEvent, 1.0f, 1.0f) sut.onUp(fixture.endEvent) - inOrder(fixture.hub) { - verify(fixture.hub).addBreadcrumb( + inOrder(fixture.scopes) { + verify(fixture.scopes).addBreadcrumb( check { assertEquals("ui.swipe", it.category) assertEquals("user", it.type) @@ -155,8 +155,8 @@ class SentryGestureListenerScrollTest { }, anyOrNull() ) - verify(fixture.hub).configureScope(anyOrNull()) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).configureScope(anyOrNull()) + verify(fixture.scopes).addBreadcrumb( check { assertEquals("ui.swipe", it.category) assertEquals("user", it.type) @@ -168,7 +168,7 @@ class SentryGestureListenerScrollTest { anyOrNull() ) } - verifyNoMoreInteractions(fixture.hub) + verifyNoMoreInteractions(fixture.scopes) } @Test @@ -177,7 +177,7 @@ class SentryGestureListenerScrollTest { sut.onUp(fixture.firstEvent) sut.onDown(fixture.endEvent) - verify(fixture.hub, never()).addBreadcrumb(any()) + verify(fixture.scopes, never()).addBreadcrumb(any()) } @Test @@ -190,7 +190,7 @@ class SentryGestureListenerScrollTest { } sut.onUp(fixture.endEvent) - verify(fixture.hub, never()).addBreadcrumb(any()) + verify(fixture.scopes, never()).addBreadcrumb(any()) } @Test diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/SentryGestureListenerTracingTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/SentryGestureListenerTracingTest.kt index c7ada69c88..d3f6647c2a 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/SentryGestureListenerTracingTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/internal/gestures/SentryGestureListenerTracingTest.kt @@ -9,8 +9,8 @@ import android.view.ViewGroup import android.view.Window import android.widget.AbsListView import android.widget.ListAdapter -import io.sentry.IHub import io.sentry.IScope +import io.sentry.IScopes import io.sentry.Scope import io.sentry.ScopeCallback import io.sentry.SentryTracer @@ -46,7 +46,7 @@ class SentryGestureListenerTracingTest { val options = SentryAndroidOptions().apply { dsn = "https://key@sentry.io/proj" } - val hub = mock() + val scopes = mock() val event = mock() val scope = mock() lateinit var target: View @@ -64,9 +64,9 @@ class SentryGestureListenerTracingTest { options.isEnableUserInteractionBreadcrumbs = true options.gestureTargetLocators = listOf(AndroidViewGestureTargetLocator(true)) - whenever(hub.options).thenReturn(options) + whenever(scopes.options).thenReturn(options) - this.transaction = transaction ?: SentryTracer(TransactionContext("name", "op"), hub) + this.transaction = transaction ?: SentryTracer(TransactionContext("name", "op"), scopes) target = mockView(event = event, clickable = true, context = context) window.mockDecorView(event = event, context = context) { @@ -86,13 +86,13 @@ class SentryGestureListenerTracingTest { whenever(activity.window).thenReturn(window) - whenever(hub.startTransaction(any(), any())) + whenever(scopes.startTransaction(any(), any())) .thenReturn(this.transaction) - doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(hub).configureScope(any()) + doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(scopes).configureScope(any()) return SentryGestureListener( activity, - hub, + scopes, options ) } @@ -106,7 +106,7 @@ class SentryGestureListenerTracingTest { sut.onSingleTapUp(fixture.event) - verify(fixture.hub, never()).startTransaction( + verify(fixture.scopes, never()).startTransaction( any(), any() ) @@ -118,7 +118,7 @@ class SentryGestureListenerTracingTest { sut.onSingleTapUp(fixture.event) - verify(fixture.hub, never()).startTransaction( + verify(fixture.scopes, never()).startTransaction( any(), any() ) @@ -130,7 +130,7 @@ class SentryGestureListenerTracingTest { sut.onSingleTapUp(fixture.event) - verify(fixture.hub, never()).startTransaction( + verify(fixture.scopes, never()).startTransaction( any(), any() ) @@ -140,7 +140,7 @@ class SentryGestureListenerTracingTest { fun `when transaction is created, set transaction to the bound Scope`() { val sut = fixture.getSut() - whenever(fixture.hub.configureScope(any())).thenAnswer { + whenever(fixture.scopes.configureScope(any())).thenAnswer { val scope = Scope(fixture.options) sut.applyScope(scope, fixture.transaction) @@ -155,9 +155,9 @@ class SentryGestureListenerTracingTest { fun `when transaction is created, do not overwrite transaction already bound to the Scope`() { val sut = fixture.getSut() - whenever(fixture.hub.configureScope(any())).thenAnswer { + whenever(fixture.scopes.configureScope(any())).thenAnswer { val scope = Scope(fixture.options) - val previousTransaction = SentryTracer(TransactionContext("name", "op"), fixture.hub) + val previousTransaction = SentryTracer(TransactionContext("name", "op"), fixture.scopes) scope.transaction = previousTransaction sut.applyScope(scope, fixture.transaction) @@ -173,14 +173,14 @@ class SentryGestureListenerTracingTest { val sut = fixture.getSut() val expectedStatus = SpanStatus.CANCELLED - whenever(fixture.hub.configureScope(any())).thenAnswer { + whenever(fixture.scopes.configureScope(any())).thenAnswer { val scope = Scope(fixture.options) sut.applyScope(scope, fixture.transaction) } sut.onSingleTapUp(fixture.event) - whenever(fixture.hub.configureScope(any())).thenAnswer { + whenever(fixture.scopes.configureScope(any())).thenAnswer { val scope = Scope(fixture.options) scope.transaction = fixture.transaction @@ -199,7 +199,7 @@ class SentryGestureListenerTracingTest { sut.onSingleTapUp(fixture.event) - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( check { assertEquals("Activity.test_button", it.name) assertEquals(TransactionNameSource.COMPONENT, it.transactionNameSource) @@ -214,7 +214,7 @@ class SentryGestureListenerTracingTest { sut.onSingleTapUp(fixture.event) - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( any(), check { transactionOptions -> assertEquals(fixture.options.idleTimeout, transactionOptions.idleTimeout) @@ -232,7 +232,7 @@ class SentryGestureListenerTracingTest { sut.onSingleTapUp(fixture.event) - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( check { assertEquals("ui.action.click", it.operation) assertEquals(TransactionNameSource.COMPONENT, it.transactionNameSource) @@ -248,7 +248,7 @@ class SentryGestureListenerTracingTest { sut.onSingleTapUp(fixture.event) - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( check { assertEquals("Activity.test_button", it.name) assertEquals(TransactionNameSource.COMPONENT, it.transactionNameSource) @@ -256,7 +256,7 @@ class SentryGestureListenerTracingTest { any() ) - clearInvocations(fixture.hub) + clearInvocations(fixture.scopes) // second view interaction with another view val newTarget = mockView(event = fixture.event, clickable = true, context = fixture.context) val newContext = mock() @@ -269,16 +269,16 @@ class SentryGestureListenerTracingTest { whenever(it.getChildAt(0)).thenReturn(newTarget) } - whenever(fixture.hub.startTransaction(any(), any())) + whenever(fixture.scopes.startTransaction(any(), any())) .thenAnswer { // verify that the active transaction gets finished when a new one appears assertEquals(true, fixture.transaction.isFinished) - SentryTracer(TransactionContext("name", "op"), fixture.hub) + SentryTracer(TransactionContext("name", "op"), fixture.scopes) } sut.onSingleTapUp(fixture.event) - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( check { assertEquals("Activity.test_checkbox", it.name) assertEquals(TransactionNameSource.COMPONENT, it.transactionNameSource) @@ -293,7 +293,7 @@ class SentryGestureListenerTracingTest { sut.onSingleTapUp(fixture.event) - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( check { assertEquals("Activity.test_scroll_view", it.name) assertEquals("ui.action.click", it.operation) @@ -302,20 +302,20 @@ class SentryGestureListenerTracingTest { any() ) - clearInvocations(fixture.hub) + clearInvocations(fixture.scopes) // second view interaction with a different interaction type (scroll) - whenever(fixture.hub.startTransaction(any(), any())) + whenever(fixture.scopes.startTransaction(any(), any())) .thenAnswer { // verify that the active transaction gets finished when a new one appears assertEquals(true, fixture.transaction.isFinished) - SentryTracer(TransactionContext("name", "op"), fixture.hub) + SentryTracer(TransactionContext("name", "op"), fixture.scopes) } sut.onScroll(fixture.event, mock(), 10.0f, 0f) sut.onUp(mock()) - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( check { assertEquals("Activity.test_scroll_view", it.name) assertEquals("ui.action.scroll", it.operation) @@ -340,7 +340,7 @@ class SentryGestureListenerTracingTest { sut.onSingleTapUp(fixture.event) // then two transaction should be captured - verify(fixture.hub, times(2)).startTransaction( + verify(fixture.scopes, times(2)).startTransaction( check { assertEquals("Activity.test_button", it.name) assertEquals(TransactionNameSource.COMPONENT, it.transactionNameSource) From 22ddc005c07f64752b137e2babe96ac9dfbc9f50 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Tue, 2 Apr 2024 14:23:32 +0200 Subject: [PATCH 06/28] Replace `IHub` with `IScopes` in android integrations --- .../api/sentry-android-fragment.api | 8 +-- .../fragment/FragmentLifecycleIntegration.kt | 10 ++-- .../SentryFragmentLifecycleCallbacks.kt | 18 +++---- .../FragmentLifecycleIntegrationTest.kt | 16 +++--- .../SentryFragmentLifecycleCallbacksTest.kt | 14 ++--- .../android/mockservers/RelayAsserter.kt | 2 +- .../api/sentry-android-navigation.api | 10 ++-- .../navigation/SentryNavigationListener.kt | 24 ++++----- .../SentryNavigationListenerTest.kt | 46 ++++++++-------- .../api/sentry-android-okhttp.api | 18 +++---- .../okhttp/SentryOkHttpEventListener.kt | 22 ++++---- .../android/okhttp/SentryOkHttpInterceptor.kt | 16 +++--- .../android/sqlite/SQLiteSpanManager.kt | 12 ++--- .../android/sqlite/SQLiteSpanManagerTest.kt | 12 ++--- .../sqlite/SentrySupportSQLiteDatabaseTest.kt | 12 ++--- .../SentrySupportSQLiteStatementTest.kt | 12 ++--- .../api/sentry-android-timber.api | 4 +- .../android/timber/SentryTimberIntegration.kt | 6 +-- .../sentry/android/timber/SentryTimberTree.kt | 8 +-- .../timber/SentryTimberIntegrationTest.kt | 18 +++---- .../android/timber/SentryTimberTreeTest.kt | 52 +++++++++---------- 21 files changed, 170 insertions(+), 170 deletions(-) diff --git a/sentry-android-fragment/api/sentry-android-fragment.api b/sentry-android-fragment/api/sentry-android-fragment.api index 4b3487c36e..f2f3334280 100644 --- a/sentry-android-fragment/api/sentry-android-fragment.api +++ b/sentry-android-fragment/api/sentry-android-fragment.api @@ -18,7 +18,7 @@ public final class io/sentry/android/fragment/FragmentLifecycleIntegration : and public fun onActivitySaveInstanceState (Landroid/app/Activity;Landroid/os/Bundle;)V public fun onActivityStarted (Landroid/app/Activity;)V public fun onActivityStopped (Landroid/app/Activity;)V - public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/android/fragment/FragmentLifecycleState : java/lang/Enum { @@ -40,9 +40,9 @@ public final class io/sentry/android/fragment/FragmentLifecycleState : java/lang public final class io/sentry/android/fragment/SentryFragmentLifecycleCallbacks : androidx/fragment/app/FragmentManager$FragmentLifecycleCallbacks { public static final field Companion Lio/sentry/android/fragment/SentryFragmentLifecycleCallbacks$Companion; public static final field FRAGMENT_LOAD_OP Ljava/lang/String; - public fun (Lio/sentry/IHub;Ljava/util/Set;Z)V - public synthetic fun (Lio/sentry/IHub;Ljava/util/Set;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V - public fun (Lio/sentry/IHub;ZZ)V + public fun (Lio/sentry/IScopes;Ljava/util/Set;Z)V + public synthetic fun (Lio/sentry/IScopes;Ljava/util/Set;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lio/sentry/IScopes;ZZ)V public fun (ZZ)V public synthetic fun (ZZILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun getEnableAutoFragmentLifecycleTracing ()Z diff --git a/sentry-android-fragment/src/main/java/io/sentry/android/fragment/FragmentLifecycleIntegration.kt b/sentry-android-fragment/src/main/java/io/sentry/android/fragment/FragmentLifecycleIntegration.kt index 4129ea4356..d2fd393200 100644 --- a/sentry-android-fragment/src/main/java/io/sentry/android/fragment/FragmentLifecycleIntegration.kt +++ b/sentry-android-fragment/src/main/java/io/sentry/android/fragment/FragmentLifecycleIntegration.kt @@ -5,7 +5,7 @@ import android.app.Application import android.app.Application.ActivityLifecycleCallbacks import android.os.Bundle import androidx.fragment.app.FragmentActivity -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.Integration import io.sentry.SentryIntegrationPackageStorage import io.sentry.SentryLevel.DEBUG @@ -40,11 +40,11 @@ class FragmentLifecycleIntegration( enableAutoFragmentLifecycleTracing = enableAutoFragmentLifecycleTracing ) - private lateinit var hub: IHub + private lateinit var scopes: IScopes private lateinit var options: SentryOptions - override fun register(hub: IHub, options: SentryOptions) { - this.hub = hub + override fun register(scopes: IScopes, options: SentryOptions) { + this.scopes = scopes this.options = options application.registerActivityLifecycleCallbacks(this) @@ -66,7 +66,7 @@ class FragmentLifecycleIntegration( ?.supportFragmentManager ?.registerFragmentLifecycleCallbacks( SentryFragmentLifecycleCallbacks( - hub = hub, + scopes = scopes, filterFragmentLifecycleBreadcrumbs = filterFragmentLifecycleBreadcrumbs, enableAutoFragmentLifecycleTracing = enableAutoFragmentLifecycleTracing ), diff --git a/sentry-android-fragment/src/main/java/io/sentry/android/fragment/SentryFragmentLifecycleCallbacks.kt b/sentry-android-fragment/src/main/java/io/sentry/android/fragment/SentryFragmentLifecycleCallbacks.kt index 78f45474e2..64ecb21d41 100644 --- a/sentry-android-fragment/src/main/java/io/sentry/android/fragment/SentryFragmentLifecycleCallbacks.kt +++ b/sentry-android-fragment/src/main/java/io/sentry/android/fragment/SentryFragmentLifecycleCallbacks.kt @@ -8,9 +8,9 @@ import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager.FragmentLifecycleCallbacks import io.sentry.Breadcrumb import io.sentry.Hint -import io.sentry.HubAdapter -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ISpan +import io.sentry.ScopesAdapter import io.sentry.SentryLevel.INFO import io.sentry.SpanStatus import io.sentry.TypeCheckHint.ANDROID_FRAGMENT @@ -20,17 +20,17 @@ private const val TRACE_ORIGIN = "auto.ui.fragment" @Suppress("TooManyFunctions") class SentryFragmentLifecycleCallbacks( - private val hub: IHub = HubAdapter.getInstance(), + private val scopes: IScopes = ScopesAdapter.getInstance(), val filterFragmentLifecycleBreadcrumbs: Set, val enableAutoFragmentLifecycleTracing: Boolean ) : FragmentLifecycleCallbacks() { constructor( - hub: IHub, + scopes: IScopes, enableFragmentLifecycleBreadcrumbs: Boolean, enableAutoFragmentLifecycleTracing: Boolean ) : this( - hub = hub, + scopes = scopes, filterFragmentLifecycleBreadcrumbs = FragmentLifecycleState.values().toSet() .takeIf { enableFragmentLifecycleBreadcrumbs } .orEmpty(), @@ -41,14 +41,14 @@ class SentryFragmentLifecycleCallbacks( enableFragmentLifecycleBreadcrumbs: Boolean = true, enableAutoFragmentLifecycleTracing: Boolean = false ) : this( - hub = HubAdapter.getInstance(), + scopes = ScopesAdapter.getInstance(), filterFragmentLifecycleBreadcrumbs = FragmentLifecycleState.values().toSet() .takeIf { enableFragmentLifecycleBreadcrumbs } .orEmpty(), enableAutoFragmentLifecycleTracing = enableAutoFragmentLifecycleTracing ) - private val isPerformanceEnabled get() = hub.options.isTracingEnabled && enableAutoFragmentLifecycleTracing + private val isPerformanceEnabled get() = scopes.options.isTracingEnabled && enableAutoFragmentLifecycleTracing private val fragmentsWithOngoingTransactions = WeakHashMap() @@ -141,7 +141,7 @@ class SentryFragmentLifecycleCallbacks( val hint = Hint() .also { it.set(ANDROID_FRAGMENT, fragment) } - hub.addBreadcrumb(breadcrumb, hint) + scopes.addBreadcrumb(breadcrumb, hint) } private fun getFragmentName(fragment: Fragment): String { @@ -157,7 +157,7 @@ class SentryFragmentLifecycleCallbacks( } var transaction: ISpan? = null - hub.configureScope { + scopes.configureScope { transaction = it.transaction } diff --git a/sentry-android-fragment/src/test/java/io/sentry/android/fragment/FragmentLifecycleIntegrationTest.kt b/sentry-android-fragment/src/test/java/io/sentry/android/fragment/FragmentLifecycleIntegrationTest.kt index 032aef58e1..84286503b9 100644 --- a/sentry-android-fragment/src/test/java/io/sentry/android/fragment/FragmentLifecycleIntegrationTest.kt +++ b/sentry-android-fragment/src/test/java/io/sentry/android/fragment/FragmentLifecycleIntegrationTest.kt @@ -4,7 +4,7 @@ import android.app.Activity import android.app.Application import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentManager -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryOptions import org.mockito.kotlin.check import org.mockito.kotlin.doReturn @@ -24,14 +24,14 @@ class FragmentLifecycleIntegrationTest { val fragmentActivity = mock { on { supportFragmentManager } doReturn fragmentManager } - val hub = mock() + val scopes = mock() val options = SentryOptions() fun getSut( enableFragmentLifecycleBreadcrumbs: Boolean = true, enableAutoFragmentLifecycleTracing: Boolean = false ): FragmentLifecycleIntegration { - whenever(hub.options).thenReturn(options) + whenever(scopes.options).thenReturn(options) return FragmentLifecycleIntegration( application = application, enableFragmentLifecycleBreadcrumbs = enableFragmentLifecycleBreadcrumbs, @@ -46,7 +46,7 @@ class FragmentLifecycleIntegrationTest { fun `When register, it should register activity lifecycle callbacks`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) verify(fixture.application).registerActivityLifecycleCallbacks(sut) } @@ -55,7 +55,7 @@ class FragmentLifecycleIntegrationTest { fun `When close, it should unregister lifecycle callbacks`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) sut.close() verify(fixture.application).unregisterActivityLifecycleCallbacks(sut) @@ -69,7 +69,7 @@ class FragmentLifecycleIntegrationTest { on { supportFragmentManager } doReturn fragmentManager } - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) sut.onActivityCreated(fragmentActivity, savedInstanceState = null) verify(fragmentManager).registerFragmentLifecycleCallbacks( @@ -84,7 +84,7 @@ class FragmentLifecycleIntegrationTest { fun `When FragmentActivity is created, it should register fragment lifecycle callbacks with passed config`() { val sut = fixture.getSut(enableFragmentLifecycleBreadcrumbs = false, enableAutoFragmentLifecycleTracing = true) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) sut.onActivityCreated(fixture.fragmentActivity, savedInstanceState = null) verify(fixture.fragmentManager).registerFragmentLifecycleCallbacks( @@ -102,7 +102,7 @@ class FragmentLifecycleIntegrationTest { val sut = fixture.getSut() val activity = mock() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) sut.onActivityCreated(activity, savedInstanceState = null) } diff --git a/sentry-android-fragment/src/test/java/io/sentry/android/fragment/SentryFragmentLifecycleCallbacksTest.kt b/sentry-android-fragment/src/test/java/io/sentry/android/fragment/SentryFragmentLifecycleCallbacksTest.kt index 9b7fd5c5f2..26cb5b211a 100644 --- a/sentry-android-fragment/src/test/java/io/sentry/android/fragment/SentryFragmentLifecycleCallbacksTest.kt +++ b/sentry-android-fragment/src/test/java/io/sentry/android/fragment/SentryFragmentLifecycleCallbacksTest.kt @@ -5,8 +5,8 @@ import android.os.Bundle import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager import io.sentry.Breadcrumb -import io.sentry.Hub import io.sentry.IScope +import io.sentry.IScopes import io.sentry.ISpan import io.sentry.ITransaction import io.sentry.ScopeCallback @@ -32,7 +32,7 @@ class SentryFragmentLifecycleCallbacksTest { private class Fixture { val fragmentManager = mock() - val hub = mock() + val scopes = mock() val fragment = mock() val context = mock() val scope = mock() @@ -45,7 +45,7 @@ class SentryFragmentLifecycleCallbacksTest { tracesSampleRate: Double? = 1.0, isAdded: Boolean = true ): SentryFragmentLifecycleCallbacks { - whenever(hub.options).thenReturn( + whenever(scopes.options).thenReturn( SentryOptions().apply { setTracesSampleRate(tracesSampleRate) } @@ -55,12 +55,12 @@ class SentryFragmentLifecycleCallbacksTest { ) whenever(transaction.startChild(any(), any())).thenReturn(span) whenever(scope.transaction).thenReturn(transaction) - whenever(hub.configureScope(any())).thenAnswer { + whenever(scopes.configureScope(any())).thenAnswer { (it.arguments[0] as ScopeCallback).run(scope) } whenever(fragment.isAdded).thenReturn(isAdded) return SentryFragmentLifecycleCallbacks( - hub = hub, + scopes = scopes, filterFragmentLifecycleBreadcrumbs = loggedFragmentLifecycleStates, enableAutoFragmentLifecycleTracing = enableAutoFragmentLifecycleTracing ) @@ -272,7 +272,7 @@ class SentryFragmentLifecycleCallbacksTest { } private fun verifyBreadcrumbAdded(expectedState: String) { - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { breadcrumb: Breadcrumb -> assertEquals("ui.fragment.lifecycle", breadcrumb.category) assertEquals("navigation", breadcrumb.type) @@ -285,6 +285,6 @@ class SentryFragmentLifecycleCallbacksTest { } private fun verifyBreadcrumbAddedCount(count: Int) { - verify(fixture.hub, times(count)).addBreadcrumb(any(), anyOrNull()) + verify(fixture.scopes, times(count)).addBreadcrumb(any(), anyOrNull()) } } diff --git a/sentry-android-integration-tests/sentry-uitest-android/src/androidTest/java/io/sentry/uitest/android/mockservers/RelayAsserter.kt b/sentry-android-integration-tests/sentry-uitest-android/src/androidTest/java/io/sentry/uitest/android/mockservers/RelayAsserter.kt index e956978086..f685e84874 100644 --- a/sentry-android-integration-tests/sentry-uitest-android/src/androidTest/java/io/sentry/uitest/android/mockservers/RelayAsserter.kt +++ b/sentry-android-integration-tests/sentry-uitest-android/src/androidTest/java/io/sentry/uitest/android/mockservers/RelayAsserter.kt @@ -93,7 +93,7 @@ class RelayAsserter( /** Request parsed as envelope. */ val envelope: SentryEnvelope? by lazy { try { - EnvelopeReader(Sentry.getCurrentHub().options.serializer) + EnvelopeReader(Sentry.getCurrentScopes().options.serializer) .read(GZIPInputStream(request.body.inputStream())) } catch (e: IOException) { null diff --git a/sentry-android-navigation/api/sentry-android-navigation.api b/sentry-android-navigation/api/sentry-android-navigation.api index 79151bb3fb..03a46d8b87 100644 --- a/sentry-android-navigation/api/sentry-android-navigation.api +++ b/sentry-android-navigation/api/sentry-android-navigation.api @@ -10,11 +10,11 @@ public final class io/sentry/android/navigation/SentryNavigationListener : andro public static final field Companion Lio/sentry/android/navigation/SentryNavigationListener$Companion; public static final field NAVIGATION_OP Ljava/lang/String; public fun ()V - public fun (Lio/sentry/IHub;)V - public fun (Lio/sentry/IHub;Z)V - public fun (Lio/sentry/IHub;ZZ)V - public fun (Lio/sentry/IHub;ZZLjava/lang/String;)V - public synthetic fun (Lio/sentry/IHub;ZZLjava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lio/sentry/IScopes;)V + public fun (Lio/sentry/IScopes;Z)V + public fun (Lio/sentry/IScopes;ZZ)V + public fun (Lio/sentry/IScopes;ZZLjava/lang/String;)V + public synthetic fun (Lio/sentry/IScopes;ZZLjava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun onDestinationChanged (Landroidx/navigation/NavController;Landroidx/navigation/NavDestination;Landroid/os/Bundle;)V } diff --git a/sentry-android-navigation/src/main/java/io/sentry/android/navigation/SentryNavigationListener.kt b/sentry-android-navigation/src/main/java/io/sentry/android/navigation/SentryNavigationListener.kt index 8fdf8b0df8..bb06d66b3c 100644 --- a/sentry-android-navigation/src/main/java/io/sentry/android/navigation/SentryNavigationListener.kt +++ b/sentry-android-navigation/src/main/java/io/sentry/android/navigation/SentryNavigationListener.kt @@ -6,9 +6,9 @@ import androidx.navigation.NavController import androidx.navigation.NavDestination import io.sentry.Breadcrumb import io.sentry.Hint -import io.sentry.HubAdapter -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ITransaction +import io.sentry.ScopesAdapter import io.sentry.SentryIntegrationPackageStorage import io.sentry.SentryLevel.DEBUG import io.sentry.SentryLevel.INFO @@ -34,7 +34,7 @@ private const val TRACE_ORIGIN = "auto.navigation" * with [SentryOptions.idleTimeout] for navigation events. */ class SentryNavigationListener @JvmOverloads constructor( - private val hub: IHub = HubAdapter.getInstance(), + private val scopes: IScopes = ScopesAdapter.getInstance(), private val enableNavigationBreadcrumbs: Boolean = true, private val enableNavigationTracing: Boolean = true, private val traceOriginAppendix: String? = null @@ -43,7 +43,7 @@ class SentryNavigationListener @JvmOverloads constructor( private var previousDestinationRef: WeakReference? = null private var previousArgs: Bundle? = null - private val isPerformanceEnabled get() = hub.options.isTracingEnabled && enableNavigationTracing + private val isPerformanceEnabled get() = scopes.options.isTracingEnabled && enableNavigationTracing private var activeTransaction: ITransaction? = null @@ -91,7 +91,7 @@ class SentryNavigationListener @JvmOverloads constructor( } val hint = Hint() hint.set(TypeCheckHint.ANDROID_NAV_DESTINATION, destination) - hub.addBreadcrumb(breadcrumb, hint) + scopes.addBreadcrumb(breadcrumb, hint) } private fun startTracing( @@ -100,7 +100,7 @@ class SentryNavigationListener @JvmOverloads constructor( arguments: Map ) { if (!isPerformanceEnabled) { - TracingUtils.startNewTrace(hub) + TracingUtils.startNewTrace(scopes) return } @@ -111,7 +111,7 @@ class SentryNavigationListener @JvmOverloads constructor( if (destination.navigatorName == "activity") { // we do not trace navigation between activities to avoid clashing with activity lifecycle tracing - hub.options.logger.log( + scopes.options.logger.log( DEBUG, "Navigating to activity destination, no transaction captured." ) @@ -122,7 +122,7 @@ class SentryNavigationListener @JvmOverloads constructor( var name = destination.route ?: try { controller.context.resources.getResourceEntryName(destination.id) } catch (e: NotFoundException) { - hub.options.logger.log( + scopes.options.logger.log( DEBUG, "Destination id cannot be retrieved from Resources, no transaction captured." ) @@ -134,12 +134,12 @@ class SentryNavigationListener @JvmOverloads constructor( val transactionOptions = TransactionOptions().also { it.isWaitForChildren = true - it.idleTimeout = hub.options.idleTimeout + it.idleTimeout = scopes.options.idleTimeout it.deadlineTimeout = TransactionOptions.DEFAULT_DEADLINE_TIMEOUT_AUTO_TRANSACTION it.isTrimEnd = true } - val transaction = hub.startTransaction( + val transaction = scopes.startTransaction( TransactionContext(name, TransactionNameSource.ROUTE, NAVIGATION_OP), transactionOptions ) @@ -151,7 +151,7 @@ class SentryNavigationListener @JvmOverloads constructor( if (arguments.isNotEmpty()) { transaction.setData("arguments", arguments) } - hub.configureScope { scope -> + scopes.configureScope { scope -> scope.withTransaction { tx -> if (tx == null) { scope.transaction = transaction @@ -166,7 +166,7 @@ class SentryNavigationListener @JvmOverloads constructor( activeTransaction?.finish(status) // clear transaction from scope so others can bind to it - hub.configureScope { scope -> + scopes.configureScope { scope -> scope.withTransaction { tx -> if (tx == activeTransaction) { scope.clearTransaction() diff --git a/sentry-android-navigation/src/test/java/io/sentry/android/navigation/SentryNavigationListenerTest.kt b/sentry-android-navigation/src/test/java/io/sentry/android/navigation/SentryNavigationListenerTest.kt index 76c57159c3..b37133410f 100644 --- a/sentry-android-navigation/src/test/java/io/sentry/android/navigation/SentryNavigationListenerTest.kt +++ b/sentry-android-navigation/src/test/java/io/sentry/android/navigation/SentryNavigationListenerTest.kt @@ -7,8 +7,8 @@ import androidx.navigation.NavController import androidx.navigation.NavDestination import androidx.test.ext.junit.runners.AndroidJUnit4 import io.sentry.Breadcrumb -import io.sentry.IHub import io.sentry.IScope +import io.sentry.IScopes import io.sentry.Scope import io.sentry.Scope.IWithTransaction import io.sentry.ScopeCallback @@ -39,7 +39,7 @@ import kotlin.test.assertNull class SentryNavigationListenerTest { class Fixture { - val hub = mock() + val scopes = mock() val destination = mock() val navController = mock() @@ -67,20 +67,20 @@ class SentryNavigationListenerTest { tracesSampleRate ) } - whenever(hub.options).thenReturn(options) + whenever(scopes.options).thenReturn(options) this.transaction = transaction ?: SentryTracer( TransactionContext( "/$toRoute", SentryNavigationListener.NAVIGATION_OP ), - hub + scopes ) - whenever(hub.startTransaction(any(), any())) + whenever(scopes.startTransaction(any(), any())) .thenReturn(this.transaction) - whenever(hub.configureScope(any())).thenAnswer { + whenever(scopes.configureScope(any())).thenAnswer { (it.arguments[0] as ScopeCallback).run(scope) } @@ -96,7 +96,7 @@ class SentryNavigationListenerTest { whenever(navController.context).thenReturn(context) whenever(destination.route).thenReturn(toRoute) return SentryNavigationListener( - hub, + scopes, enableBreadcrumbs, enableTracing, traceOriginAppendix @@ -112,7 +112,7 @@ class SentryNavigationListenerTest { sut.onDestinationChanged(fixture.navController, fixture.destination, null) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("navigation", it.type) assertEquals("navigation", it.category) @@ -133,7 +133,7 @@ class SentryNavigationListenerTest { bundleOf("arg1" to "foo", "arg2" to "bar") ) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("/route", it.data["to"]) assertEquals(mapOf("arg1" to "foo", "arg2" to "bar"), it.data["to_arguments"]) @@ -152,7 +152,7 @@ class SentryNavigationListenerTest { bundleOf() ) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("/route", it.data["to"]) assertNull(it.data["to_arguments"]) @@ -180,7 +180,7 @@ class SentryNavigationListenerTest { bundleOf("to_arg1" to "to_foo") ) val captor = argumentCaptor() - verify(fixture.hub, times(2)).addBreadcrumb(captor.capture(), any()) + verify(fixture.scopes, times(2)).addBreadcrumb(captor.capture(), any()) captor.secondValue.let { assertEquals("/route_from", it.data["from"]) assertEquals(mapOf("from_arg1" to "from_foo"), it.data["from_arguments"]) @@ -196,7 +196,7 @@ class SentryNavigationListenerTest { sut.onDestinationChanged(fixture.navController, fixture.destination, null) - verify(fixture.hub, never()).addBreadcrumb(any()) + verify(fixture.scopes, never()).addBreadcrumb(any()) } @Test @@ -205,7 +205,7 @@ class SentryNavigationListenerTest { sut.onDestinationChanged(fixture.navController, fixture.destination, null) - verify(fixture.hub, never()).startTransaction( + verify(fixture.scopes, never()).startTransaction( any(), any() ) @@ -217,7 +217,7 @@ class SentryNavigationListenerTest { sut.onDestinationChanged(fixture.navController, fixture.destination, null) - verify(fixture.hub, never()).startTransaction( + verify(fixture.scopes, never()).startTransaction( any(), any() ) @@ -230,7 +230,7 @@ class SentryNavigationListenerTest { sut.onDestinationChanged(fixture.navController, fixture.destination, null) - verify(fixture.hub, never()).startTransaction( + verify(fixture.scopes, never()).startTransaction( any(), any() ) @@ -242,7 +242,7 @@ class SentryNavigationListenerTest { sut.onDestinationChanged(fixture.navController, fixture.destination, null) - verify(fixture.hub, never()).startTransaction( + verify(fixture.scopes, never()).startTransaction( any(), any() ) @@ -254,7 +254,7 @@ class SentryNavigationListenerTest { sut.onDestinationChanged(fixture.navController, fixture.destination, null) - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( check { assertEquals("/route", it.name) assertEquals(SentryNavigationListener.NAVIGATION_OP, it.operation) @@ -270,7 +270,7 @@ class SentryNavigationListenerTest { sut.onDestinationChanged(fixture.navController, fixture.destination, null) - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( check { assertEquals("/github", it.name) assertEquals(TransactionNameSource.ROUTE, it.transactionNameSource) @@ -285,7 +285,7 @@ class SentryNavigationListenerTest { sut.onDestinationChanged(fixture.navController, fixture.destination, null) - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( check { assertEquals("/destination-id-1", it.name) assertEquals(TransactionNameSource.ROUTE, it.transactionNameSource) @@ -304,7 +304,7 @@ class SentryNavigationListenerTest { bundleOf("user_id" to 123, "per_page" to 10) ) - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( check { assertEquals("/github", it.name) assertEquals(TransactionNameSource.ROUTE, it.transactionNameSource) @@ -365,13 +365,13 @@ class SentryNavigationListenerTest { ArgumentCaptor.forClass(ScopeCallback::class.java) val scope = Scope(fixture.options) val propagationContextAtStart = scope.propagationContext - whenever(fixture.hub.configureScope(argumentCaptor.capture())).thenAnswer { + whenever(fixture.scopes.configureScope(argumentCaptor.capture())).thenAnswer { argumentCaptor.value.run(scope) } sut.onDestinationChanged(fixture.navController, fixture.destination, null) - verify(fixture.hub).configureScope(any()) + verify(fixture.scopes).configureScope(any()) assertNotSame(propagationContextAtStart, scope.propagationContext) } @@ -399,7 +399,7 @@ class SentryNavigationListenerTest { sut.onDestinationChanged(fixture.navController, fixture.destination, null) - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( any(), check { options -> assertEquals(TransactionOptions.DEFAULT_DEADLINE_TIMEOUT_AUTO_TRANSACTION, options.deadlineTimeout) diff --git a/sentry-android-okhttp/api/sentry-android-okhttp.api b/sentry-android-okhttp/api/sentry-android-okhttp.api index a1ad9114a2..35f42842dd 100644 --- a/sentry-android-okhttp/api/sentry-android-okhttp.api +++ b/sentry-android-okhttp/api/sentry-android-okhttp.api @@ -8,12 +8,12 @@ public final class io/sentry/android/okhttp/BuildConfig { public final class io/sentry/android/okhttp/SentryOkHttpEventListener : okhttp3/EventListener { public fun ()V - public fun (Lio/sentry/IHub;Lkotlin/jvm/functions/Function1;)V - public synthetic fun (Lio/sentry/IHub;Lkotlin/jvm/functions/Function1;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public fun (Lio/sentry/IHub;Lokhttp3/EventListener$Factory;)V - public synthetic fun (Lio/sentry/IHub;Lokhttp3/EventListener$Factory;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public fun (Lio/sentry/IHub;Lokhttp3/EventListener;)V - public synthetic fun (Lio/sentry/IHub;Lokhttp3/EventListener;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lio/sentry/IScopes;Lkotlin/jvm/functions/Function1;)V + public synthetic fun (Lio/sentry/IScopes;Lkotlin/jvm/functions/Function1;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lio/sentry/IScopes;Lokhttp3/EventListener$Factory;)V + public synthetic fun (Lio/sentry/IScopes;Lokhttp3/EventListener$Factory;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lio/sentry/IScopes;Lokhttp3/EventListener;)V + public synthetic fun (Lio/sentry/IScopes;Lokhttp3/EventListener;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun (Lokhttp3/EventListener$Factory;)V public fun (Lokhttp3/EventListener;)V public fun cacheConditionalHit (Lokhttp3/Call;Lokhttp3/Response;)V @@ -49,9 +49,9 @@ public final class io/sentry/android/okhttp/SentryOkHttpEventListener : okhttp3/ public final class io/sentry/android/okhttp/SentryOkHttpInterceptor : okhttp3/Interceptor { public fun ()V - public fun (Lio/sentry/IHub;)V - public fun (Lio/sentry/IHub;Lio/sentry/android/okhttp/SentryOkHttpInterceptor$BeforeSpanCallback;ZLjava/util/List;Ljava/util/List;)V - public synthetic fun (Lio/sentry/IHub;Lio/sentry/android/okhttp/SentryOkHttpInterceptor$BeforeSpanCallback;ZLjava/util/List;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lio/sentry/IScopes;)V + public fun (Lio/sentry/IScopes;Lio/sentry/android/okhttp/SentryOkHttpInterceptor$BeforeSpanCallback;ZLjava/util/List;Ljava/util/List;)V + public synthetic fun (Lio/sentry/IScopes;Lio/sentry/android/okhttp/SentryOkHttpInterceptor$BeforeSpanCallback;ZLjava/util/List;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun (Lio/sentry/android/okhttp/SentryOkHttpInterceptor$BeforeSpanCallback;)V public fun intercept (Lokhttp3/Interceptor$Chain;)Lokhttp3/Response; } diff --git a/sentry-android-okhttp/src/main/java/io/sentry/android/okhttp/SentryOkHttpEventListener.kt b/sentry-android-okhttp/src/main/java/io/sentry/android/okhttp/SentryOkHttpEventListener.kt index 7ca5313d8f..f99106e8d9 100644 --- a/sentry-android-okhttp/src/main/java/io/sentry/android/okhttp/SentryOkHttpEventListener.kt +++ b/sentry-android-okhttp/src/main/java/io/sentry/android/okhttp/SentryOkHttpEventListener.kt @@ -1,7 +1,7 @@ package io.sentry.android.okhttp -import io.sentry.HubAdapter -import io.sentry.IHub +import io.sentry.IScopes +import io.sentry.ScopesAdapter import okhttp3.Call import okhttp3.Connection import okhttp3.EventListener @@ -42,35 +42,35 @@ import java.net.Proxy ) @Suppress("TooManyFunctions") class SentryOkHttpEventListener( - hub: IHub = HubAdapter.getInstance(), + scopes: IScopes = ScopesAdapter.getInstance(), originalEventListenerCreator: ((call: Call) -> EventListener)? = null ) : EventListener() { constructor() : this( - HubAdapter.getInstance(), + ScopesAdapter.getInstance(), originalEventListenerCreator = null ) constructor(originalEventListener: EventListener) : this( - HubAdapter.getInstance(), + ScopesAdapter.getInstance(), originalEventListenerCreator = { originalEventListener } ) constructor(originalEventListenerFactory: Factory) : this( - HubAdapter.getInstance(), + ScopesAdapter.getInstance(), originalEventListenerCreator = { originalEventListenerFactory.create(it) } ) - constructor(hub: IHub = HubAdapter.getInstance(), originalEventListener: EventListener) : this( - hub, + constructor(scopes: IScopes = ScopesAdapter.getInstance(), originalEventListener: EventListener) : this( + scopes, originalEventListenerCreator = { originalEventListener } ) - constructor(hub: IHub = HubAdapter.getInstance(), originalEventListenerFactory: Factory) : this( - hub, + constructor(scopes: IScopes = ScopesAdapter.getInstance(), originalEventListenerFactory: Factory) : this( + scopes, originalEventListenerCreator = { originalEventListenerFactory.create(it) } ) - private val delegate = io.sentry.okhttp.SentryOkHttpEventListener(hub, originalEventListenerCreator) + private val delegate = io.sentry.okhttp.SentryOkHttpEventListener(scopes, originalEventListenerCreator) override fun cacheConditionalHit(call: Call, cachedResponse: Response) { delegate.cacheConditionalHit(call, cachedResponse) diff --git a/sentry-android-okhttp/src/main/java/io/sentry/android/okhttp/SentryOkHttpInterceptor.kt b/sentry-android-okhttp/src/main/java/io/sentry/android/okhttp/SentryOkHttpInterceptor.kt index 971af925ff..3c7e590fe1 100644 --- a/sentry-android-okhttp/src/main/java/io/sentry/android/okhttp/SentryOkHttpInterceptor.kt +++ b/sentry-android-okhttp/src/main/java/io/sentry/android/okhttp/SentryOkHttpInterceptor.kt @@ -1,9 +1,9 @@ package io.sentry.android.okhttp import io.sentry.HttpStatusCodeRange -import io.sentry.HubAdapter -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ISpan +import io.sentry.ScopesAdapter import io.sentry.SentryIntegrationPackageStorage import io.sentry.SentryOptions.DEFAULT_PROPAGATION_TARGETS import io.sentry.android.okhttp.SentryOkHttpInterceptor.BeforeSpanCallback @@ -17,7 +17,7 @@ import okhttp3.Response * out of the active span bound to the scope for each HTTP Request. * If [captureFailedRequests] is enabled, the SDK will capture HTTP Client errors as well. * - * @param hub The [IHub], internal and only used for testing. + * @param scopes The [IScopes], internal and only used for testing. * @param beforeSpan The [ISpan] can be customized or dropped with the [BeforeSpanCallback]. * @param captureFailedRequests The SDK will only capture HTTP Client errors if it is enabled, * Defaults to false. @@ -31,7 +31,7 @@ import okhttp3.Response ReplaceWith("SentryOkHttpInterceptor", "io.sentry.okhttp.SentryOkHttpInterceptor") ) class SentryOkHttpInterceptor( - private val hub: IHub = HubAdapter.getInstance(), + private val scopes: IScopes = ScopesAdapter.getInstance(), private val beforeSpan: BeforeSpanCallback? = null, private val captureFailedRequests: Boolean = true, private val failedRequestStatusCodes: List = listOf( @@ -39,7 +39,7 @@ class SentryOkHttpInterceptor( ), private val failedRequestTargets: List = listOf(DEFAULT_PROPAGATION_TARGETS) ) : Interceptor by io.sentry.okhttp.SentryOkHttpInterceptor( - hub, + scopes, { span, request, response -> beforeSpan ?: return@SentryOkHttpInterceptor span beforeSpan.execute(span, request, response) @@ -49,9 +49,9 @@ class SentryOkHttpInterceptor( failedRequestTargets ) { - constructor() : this(HubAdapter.getInstance()) - constructor(hub: IHub) : this(hub, null) - constructor(beforeSpan: BeforeSpanCallback) : this(HubAdapter.getInstance(), beforeSpan) + constructor() : this(ScopesAdapter.getInstance()) + constructor(scopes: IScopes) : this(scopes, null) + constructor(beforeSpan: BeforeSpanCallback) : this(ScopesAdapter.getInstance(), beforeSpan) init { addIntegrationToSdkVersion(javaClass) diff --git a/sentry-android-sqlite/src/main/java/io/sentry/android/sqlite/SQLiteSpanManager.kt b/sentry-android-sqlite/src/main/java/io/sentry/android/sqlite/SQLiteSpanManager.kt index 3bfa855d53..2e39bf76ec 100644 --- a/sentry-android-sqlite/src/main/java/io/sentry/android/sqlite/SQLiteSpanManager.kt +++ b/sentry-android-sqlite/src/main/java/io/sentry/android/sqlite/SQLiteSpanManager.kt @@ -1,8 +1,8 @@ package io.sentry.android.sqlite import android.database.SQLException -import io.sentry.HubAdapter -import io.sentry.IHub +import io.sentry.IScopes +import io.sentry.ScopesAdapter import io.sentry.SentryIntegrationPackageStorage import io.sentry.SentryStackTraceFactory import io.sentry.SpanDataConvention @@ -11,10 +11,10 @@ import io.sentry.SpanStatus private const val TRACE_ORIGIN = "auto.db.sqlite" internal class SQLiteSpanManager( - private val hub: IHub = HubAdapter.getInstance(), + private val scopes: IScopes = ScopesAdapter.getInstance(), private val databaseName: String? = null ) { - private val stackTraceFactory = SentryStackTraceFactory(hub.options) + private val stackTraceFactory = SentryStackTraceFactory(scopes.options) init { SentryIntegrationPackageStorage.getInstance().addIntegration("SQLite") @@ -30,7 +30,7 @@ internal class SQLiteSpanManager( @Suppress("TooGenericExceptionCaught") @Throws(SQLException::class) fun performSql(sql: String, operation: () -> T): T { - val span = hub.span?.startChild("db.sql.query", sql) + val span = scopes.span?.startChild("db.sql.query", sql) span?.spanContext?.origin = TRACE_ORIGIN return try { val result = operation() @@ -42,7 +42,7 @@ internal class SQLiteSpanManager( throw e } finally { span?.apply { - val isMainThread: Boolean = hub.options.mainThreadChecker.isMainThread + val isMainThread: Boolean = scopes.options.mainThreadChecker.isMainThread setData(SpanDataConvention.BLOCKED_MAIN_THREAD_KEY, isMainThread) if (isMainThread) { setData(SpanDataConvention.CALL_STACK_KEY, stackTraceFactory.inAppCallStack) diff --git a/sentry-android-sqlite/src/test/java/io/sentry/android/sqlite/SQLiteSpanManagerTest.kt b/sentry-android-sqlite/src/test/java/io/sentry/android/sqlite/SQLiteSpanManagerTest.kt index e2fa0c2e4d..9265cd260a 100644 --- a/sentry-android-sqlite/src/test/java/io/sentry/android/sqlite/SQLiteSpanManagerTest.kt +++ b/sentry-android-sqlite/src/test/java/io/sentry/android/sqlite/SQLiteSpanManagerTest.kt @@ -1,7 +1,7 @@ package io.sentry.android.sqlite import android.database.SQLException -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryIntegrationPackageStorage import io.sentry.SentryOptions import io.sentry.SentryTracer @@ -22,7 +22,7 @@ import kotlin.test.assertTrue class SQLiteSpanManagerTest { private class Fixture { - private val hub = mock() + private val scopes = mock() lateinit var sentryTracer: SentryTracer lateinit var options: SentryOptions @@ -30,13 +30,13 @@ class SQLiteSpanManagerTest { options = SentryOptions().apply { dsn = "https://key@sentry.io/proj" } - whenever(hub.options).thenReturn(options) - sentryTracer = SentryTracer(TransactionContext("name", "op"), hub) + whenever(scopes.options).thenReturn(options) + sentryTracer = SentryTracer(TransactionContext("name", "op"), scopes) if (isSpanActive) { - whenever(hub.span).thenReturn(sentryTracer) + whenever(scopes.span).thenReturn(sentryTracer) } - return SQLiteSpanManager(hub, databaseName) + return SQLiteSpanManager(scopes, databaseName) } } diff --git a/sentry-android-sqlite/src/test/java/io/sentry/android/sqlite/SentrySupportSQLiteDatabaseTest.kt b/sentry-android-sqlite/src/test/java/io/sentry/android/sqlite/SentrySupportSQLiteDatabaseTest.kt index cf22c3b0ec..99e1d5f4a0 100644 --- a/sentry-android-sqlite/src/test/java/io/sentry/android/sqlite/SentrySupportSQLiteDatabaseTest.kt +++ b/sentry-android-sqlite/src/test/java/io/sentry/android/sqlite/SentrySupportSQLiteDatabaseTest.kt @@ -3,7 +3,7 @@ package io.sentry.android.sqlite import android.database.Cursor import androidx.sqlite.db.SupportSQLiteDatabase import androidx.sqlite.db.SupportSQLiteQuery -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ISpan import io.sentry.SentryOptions import io.sentry.SentryTracer @@ -23,8 +23,8 @@ import kotlin.test.assertTrue class SentrySupportSQLiteDatabaseTest { private class Fixture { - private val hub = mock() - private val spanManager = SQLiteSpanManager(hub) + private val scopes = mock() + private val spanManager = SQLiteSpanManager(scopes) val mockDatabase = mock() lateinit var sentryTracer: SentryTracer lateinit var options: SentryOptions @@ -37,11 +37,11 @@ class SentrySupportSQLiteDatabaseTest { options = SentryOptions().apply { dsn = "https://key@sentry.io/proj" } - whenever(hub.options).thenReturn(options) - sentryTracer = SentryTracer(TransactionContext("name", "op"), hub) + whenever(scopes.options).thenReturn(options) + sentryTracer = SentryTracer(TransactionContext("name", "op"), scopes) if (isSpanActive) { - whenever(hub.span).thenReturn(sentryTracer) + whenever(scopes.span).thenReturn(sentryTracer) } return SentrySupportSQLiteDatabase(mockDatabase, spanManager) diff --git a/sentry-android-sqlite/src/test/java/io/sentry/android/sqlite/SentrySupportSQLiteStatementTest.kt b/sentry-android-sqlite/src/test/java/io/sentry/android/sqlite/SentrySupportSQLiteStatementTest.kt index 9078ba8b08..4b6292bd27 100644 --- a/sentry-android-sqlite/src/test/java/io/sentry/android/sqlite/SentrySupportSQLiteStatementTest.kt +++ b/sentry-android-sqlite/src/test/java/io/sentry/android/sqlite/SentrySupportSQLiteStatementTest.kt @@ -1,7 +1,7 @@ package io.sentry.android.sqlite import androidx.sqlite.db.SupportSQLiteStatement -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ISpan import io.sentry.SentryOptions import io.sentry.SentryTracer @@ -18,8 +18,8 @@ import kotlin.test.assertTrue class SentrySupportSQLiteStatementTest { private class Fixture { - private val hub = mock() - private val spanManager = SQLiteSpanManager(hub) + private val scopes = mock() + private val spanManager = SQLiteSpanManager(scopes) val mockStatement = mock() lateinit var sentryTracer: SentryTracer lateinit var options: SentryOptions @@ -28,11 +28,11 @@ class SentrySupportSQLiteStatementTest { options = SentryOptions().apply { dsn = "https://key@sentry.io/proj" } - whenever(hub.options).thenReturn(options) - sentryTracer = SentryTracer(TransactionContext("name", "op"), hub) + whenever(scopes.options).thenReturn(options) + sentryTracer = SentryTracer(TransactionContext("name", "op"), scopes) if (isSpanActive) { - whenever(hub.span).thenReturn(sentryTracer) + whenever(scopes.span).thenReturn(sentryTracer) } return SentrySupportSQLiteStatement(mockStatement, spanManager, sql) } diff --git a/sentry-android-timber/api/sentry-android-timber.api b/sentry-android-timber/api/sentry-android-timber.api index 808e91bf10..2d71f67570 100644 --- a/sentry-android-timber/api/sentry-android-timber.api +++ b/sentry-android-timber/api/sentry-android-timber.api @@ -14,11 +14,11 @@ public final class io/sentry/android/timber/SentryTimberIntegration : io/sentry/ public fun close ()V public final fun getMinBreadcrumbLevel ()Lio/sentry/SentryLevel; public final fun getMinEventLevel ()Lio/sentry/SentryLevel; - public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V + public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V } public final class io/sentry/android/timber/SentryTimberTree : timber/log/Timber$Tree { - public fun (Lio/sentry/IHub;Lio/sentry/SentryLevel;Lio/sentry/SentryLevel;)V + public fun (Lio/sentry/IScopes;Lio/sentry/SentryLevel;Lio/sentry/SentryLevel;)V public fun d (Ljava/lang/String;[Ljava/lang/Object;)V public fun d (Ljava/lang/Throwable;)V public fun d (Ljava/lang/Throwable;Ljava/lang/String;[Ljava/lang/Object;)V diff --git a/sentry-android-timber/src/main/java/io/sentry/android/timber/SentryTimberIntegration.kt b/sentry-android-timber/src/main/java/io/sentry/android/timber/SentryTimberIntegration.kt index d043faa5f6..334146a218 100644 --- a/sentry-android-timber/src/main/java/io/sentry/android/timber/SentryTimberIntegration.kt +++ b/sentry-android-timber/src/main/java/io/sentry/android/timber/SentryTimberIntegration.kt @@ -1,7 +1,7 @@ package io.sentry.android.timber -import io.sentry.IHub import io.sentry.ILogger +import io.sentry.IScopes import io.sentry.Integration import io.sentry.SentryIntegrationPackageStorage import io.sentry.SentryLevel @@ -21,10 +21,10 @@ class SentryTimberIntegration( private lateinit var tree: SentryTimberTree private lateinit var logger: ILogger - override fun register(hub: IHub, options: SentryOptions) { + override fun register(scopes: IScopes, options: SentryOptions) { logger = options.logger - tree = SentryTimberTree(hub, minEventLevel, minBreadcrumbLevel) + tree = SentryTimberTree(scopes, minEventLevel, minBreadcrumbLevel) Timber.plant(tree) logger.log(SentryLevel.DEBUG, "SentryTimberIntegration installed.") diff --git a/sentry-android-timber/src/main/java/io/sentry/android/timber/SentryTimberTree.kt b/sentry-android-timber/src/main/java/io/sentry/android/timber/SentryTimberTree.kt index f3a0f599a9..dddab75133 100644 --- a/sentry-android-timber/src/main/java/io/sentry/android/timber/SentryTimberTree.kt +++ b/sentry-android-timber/src/main/java/io/sentry/android/timber/SentryTimberTree.kt @@ -2,7 +2,7 @@ package io.sentry.android.timber import android.util.Log import io.sentry.Breadcrumb -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryEvent import io.sentry.SentryLevel import io.sentry.protocol.Message @@ -13,7 +13,7 @@ import timber.log.Timber */ @Suppress("TooManyFunctions") // we have to override all methods to be able to tweak logging class SentryTimberTree( - private val hub: IHub, + private val scopes: IScopes, private val minEventLevel: SentryLevel, private val minBreadcrumbLevel: SentryLevel ) : Timber.Tree() { @@ -269,7 +269,7 @@ class SentryTimberTree( logger = "Timber" } - hub.captureEvent(sentryEvent) + scopes.captureEvent(sentryEvent) } } @@ -296,7 +296,7 @@ class SentryTimberTree( else -> null } - breadCrumb?.let { hub.addBreadcrumb(it) } + breadCrumb?.let { scopes.addBreadcrumb(it) } } } diff --git a/sentry-android-timber/src/test/java/io/sentry/android/timber/SentryTimberIntegrationTest.kt b/sentry-android-timber/src/test/java/io/sentry/android/timber/SentryTimberIntegrationTest.kt index a57853e059..8bb85aa085 100644 --- a/sentry-android-timber/src/test/java/io/sentry/android/timber/SentryTimberIntegrationTest.kt +++ b/sentry-android-timber/src/test/java/io/sentry/android/timber/SentryTimberIntegrationTest.kt @@ -1,6 +1,6 @@ package io.sentry.android.timber -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryLevel import io.sentry.SentryOptions import io.sentry.protocol.SdkVersion @@ -16,7 +16,7 @@ import kotlin.test.assertTrue class SentryTimberIntegrationTest { private class Fixture { - val hub = mock() + val scopes = mock() val options = SentryOptions().apply { sdkVersion = SdkVersion("test", "1.2.3") } @@ -41,7 +41,7 @@ class SentryTimberIntegrationTest { @Test fun `Integrations plants a tree into Timber on register`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertEquals(1, Timber.treeCount()) @@ -53,16 +53,16 @@ class SentryTimberIntegrationTest { @Test fun `Integrations plants the SentryTimberTree tree`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) Timber.e(Throwable()) - verify(fixture.hub).captureEvent(any()) + verify(fixture.scopes).captureEvent(any()) } @Test fun `Integrations removes a tree from Timber on close integration`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertEquals(1, Timber.treeCount()) @@ -84,7 +84,7 @@ class SentryTimberIntegrationTest { minEventLevel = SentryLevel.INFO, minBreadcrumbLevel = SentryLevel.DEBUG ) - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertEquals(sut.minEventLevel, SentryLevel.INFO) assertEquals(sut.minBreadcrumbLevel, SentryLevel.DEBUG) @@ -93,7 +93,7 @@ class SentryTimberIntegrationTest { @Test fun `Integration adds itself to the package list`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertTrue( fixture.options.sdkVersion!!.packageSet.any { @@ -106,7 +106,7 @@ class SentryTimberIntegrationTest { @Test fun `Integration adds itself to the integration list`() { val sut = fixture.getSut() - sut.register(fixture.hub, fixture.options) + sut.register(fixture.scopes, fixture.options) assertTrue( fixture.options.sdkVersion!!.integrationSet.contains("Timber") diff --git a/sentry-android-timber/src/test/java/io/sentry/android/timber/SentryTimberTreeTest.kt b/sentry-android-timber/src/test/java/io/sentry/android/timber/SentryTimberTreeTest.kt index 3d82b139ec..2ab7ff64db 100644 --- a/sentry-android-timber/src/test/java/io/sentry/android/timber/SentryTimberTreeTest.kt +++ b/sentry-android-timber/src/test/java/io/sentry/android/timber/SentryTimberTreeTest.kt @@ -1,7 +1,7 @@ package io.sentry.android.timber import io.sentry.Breadcrumb -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryLevel import io.sentry.getExc import org.mockito.kotlin.any @@ -19,13 +19,13 @@ import kotlin.test.assertNull class SentryTimberTreeTest { private class Fixture { - val hub = mock() + val scopes = mock() fun getSut( minEventLevel: SentryLevel = SentryLevel.ERROR, minBreadcrumbLevel: SentryLevel = SentryLevel.INFO ): SentryTimberTree { - return SentryTimberTree(hub, minEventLevel, minBreadcrumbLevel) + return SentryTimberTree(scopes, minEventLevel, minBreadcrumbLevel) } } @@ -40,28 +40,28 @@ class SentryTimberTreeTest { fun `Tree captures an event if min level is equal`() { val sut = fixture.getSut() sut.e(Throwable()) - verify(fixture.hub).captureEvent(any()) + verify(fixture.scopes).captureEvent(any()) } @Test fun `Tree captures an event if min level is higher`() { val sut = fixture.getSut() sut.wtf(Throwable()) - verify(fixture.hub).captureEvent(any()) + verify(fixture.scopes).captureEvent(any()) } @Test fun `Tree won't capture an event if min level is lower`() { val sut = fixture.getSut() sut.d(Throwable()) - verify(fixture.hub, never()).captureEvent(any()) + verify(fixture.scopes, never()).captureEvent(any()) } @Test fun `Tree captures debug level event`() { val sut = fixture.getSut(SentryLevel.DEBUG) sut.d(Throwable()) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { assertEquals(SentryLevel.DEBUG, it.level) } @@ -72,7 +72,7 @@ class SentryTimberTreeTest { fun `Tree captures info level event`() { val sut = fixture.getSut(SentryLevel.DEBUG) sut.i(Throwable()) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { assertEquals(SentryLevel.INFO, it.level) } @@ -83,7 +83,7 @@ class SentryTimberTreeTest { fun `Tree captures warning level event`() { val sut = fixture.getSut(SentryLevel.DEBUG) sut.w(Throwable()) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { assertEquals(SentryLevel.WARNING, it.level) } @@ -94,7 +94,7 @@ class SentryTimberTreeTest { fun `Tree captures error level event`() { val sut = fixture.getSut(SentryLevel.DEBUG) sut.e(Throwable()) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { assertEquals(SentryLevel.ERROR, it.level) } @@ -105,7 +105,7 @@ class SentryTimberTreeTest { fun `Tree captures fatal level event`() { val sut = fixture.getSut(SentryLevel.DEBUG) sut.wtf(Throwable()) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { assertEquals(SentryLevel.FATAL, it.level) } @@ -116,7 +116,7 @@ class SentryTimberTreeTest { fun `Tree captures unknown as debug level event`() { val sut = fixture.getSut(SentryLevel.DEBUG) sut.log(15, Throwable()) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { assertEquals(SentryLevel.DEBUG, it.level) } @@ -128,7 +128,7 @@ class SentryTimberTreeTest { val sut = fixture.getSut() val throwable = Throwable() sut.e(throwable) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { assertEquals(throwable, it.getExc()) } @@ -139,7 +139,7 @@ class SentryTimberTreeTest { fun `Tree captures an event without an exception`() { val sut = fixture.getSut() sut.e("message") - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { assertNull(it.getExc()) } @@ -150,7 +150,7 @@ class SentryTimberTreeTest { fun `Tree captures an event and sets Timber as a logger`() { val sut = fixture.getSut() sut.e("message") - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { assertEquals("Timber", it.logger) } @@ -164,7 +164,7 @@ class SentryTimberTreeTest { // only available thru static class Timber.tag("tag") Timber.e("message") - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { assertEquals("tag", it.getTag("TimberTag")) } @@ -176,7 +176,7 @@ class SentryTimberTreeTest { val sut = fixture.getSut() Timber.plant(sut) Timber.e("message") - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { assertNull(it.getTag("TimberTag")) } @@ -187,7 +187,7 @@ class SentryTimberTreeTest { fun `Tree captures an event with given message`() { val sut = fixture.getSut() sut.e("message") - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { assertNotNull(it.message) { message -> assertEquals("message", message.message) @@ -200,7 +200,7 @@ class SentryTimberTreeTest { fun `Tree captures an event with formatted message and arguments, when provided`() { val sut = fixture.getSut() sut.e("test count: %d", 32) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { assertNotNull(it.message) { message -> assertEquals("test count: %d", message.message) @@ -216,7 +216,7 @@ class SentryTimberTreeTest { val sut = fixture.getSut() sut.e("test count: %d", 32) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("test count: 32", it.message) } @@ -227,28 +227,28 @@ class SentryTimberTreeTest { fun `Tree adds a breadcrumb if min level is equal`() { val sut = fixture.getSut() sut.i(Throwable("test")) - verify(fixture.hub).addBreadcrumb(any()) + verify(fixture.scopes).addBreadcrumb(any()) } @Test fun `Tree adds a breadcrumb if min level is higher`() { val sut = fixture.getSut() sut.e(Throwable("test")) - verify(fixture.hub).addBreadcrumb(any()) + verify(fixture.scopes).addBreadcrumb(any()) } @Test fun `Tree won't add a breadcrumb if min level is lower`() { val sut = fixture.getSut(minBreadcrumbLevel = SentryLevel.ERROR) sut.i(Throwable("test")) - verify(fixture.hub, never()).addBreadcrumb(any()) + verify(fixture.scopes, never()).addBreadcrumb(any()) } @Test fun `Tree adds an info breadcrumb`() { val sut = fixture.getSut() sut.i("message") - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("Timber", it.category) assertEquals(SentryLevel.INFO, it.level) @@ -261,7 +261,7 @@ class SentryTimberTreeTest { fun `Tree adds an error breadcrumb`() { val sut = fixture.getSut() sut.e(Throwable("test")) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("exception", it.category) assertEquals(SentryLevel.ERROR, it.level) @@ -274,7 +274,7 @@ class SentryTimberTreeTest { fun `Tree does not add a breadcrumb, if no message provided`() { val sut = fixture.getSut() sut.e(Throwable()) - verify(fixture.hub, never()).addBreadcrumb(any()) + verify(fixture.scopes, never()).addBreadcrumb(any()) } @Test From 305c217401c21fb47ea48d9b20bef1a433c80120 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Tue, 2 Apr 2024 14:26:37 +0200 Subject: [PATCH 07/28] Replace `IHub` with `IScopes` in apollo integrations --- sentry-apollo-3/api/sentry-apollo-3.api | 20 +++++----- .../apollo3/SentryApollo3HttpInterceptor.kt | 34 ++++++++-------- .../apollo3/SentryApolloBuilderExtensions.kt | 10 ++--- .../SentryApollo3InterceptorClientErrors.kt | 40 +++++++++---------- .../apollo3/SentryApollo3InterceptorTest.kt | 40 +++++++++---------- ...ntryApollo3InterceptorWithVariablesTest.kt | 22 +++++----- sentry-apollo/api/sentry-apollo.api | 6 +-- .../sentry/apollo/SentryApolloInterceptor.kt | 20 +++++----- .../apollo/SentryApolloInterceptorTest.kt | 38 +++++++++--------- 9 files changed, 115 insertions(+), 115 deletions(-) diff --git a/sentry-apollo-3/api/sentry-apollo-3.api b/sentry-apollo-3/api/sentry-apollo-3.api index 1c80e1950b..e106585156 100644 --- a/sentry-apollo-3/api/sentry-apollo-3.api +++ b/sentry-apollo-3/api/sentry-apollo-3.api @@ -17,11 +17,11 @@ public final class io/sentry/apollo3/SentryApollo3HttpInterceptor : com/apollogr public static final field SENTRY_APOLLO_3_OPERATION_TYPE Ljava/lang/String; public static final field SENTRY_APOLLO_3_VARIABLES Ljava/lang/String; public fun ()V - public fun (Lio/sentry/IHub;)V - public fun (Lio/sentry/IHub;Lio/sentry/apollo3/SentryApollo3HttpInterceptor$BeforeSpanCallback;)V - public fun (Lio/sentry/IHub;Lio/sentry/apollo3/SentryApollo3HttpInterceptor$BeforeSpanCallback;Z)V - public fun (Lio/sentry/IHub;Lio/sentry/apollo3/SentryApollo3HttpInterceptor$BeforeSpanCallback;ZLjava/util/List;)V - public synthetic fun (Lio/sentry/IHub;Lio/sentry/apollo3/SentryApollo3HttpInterceptor$BeforeSpanCallback;ZLjava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lio/sentry/IScopes;)V + public fun (Lio/sentry/IScopes;Lio/sentry/apollo3/SentryApollo3HttpInterceptor$BeforeSpanCallback;)V + public fun (Lio/sentry/IScopes;Lio/sentry/apollo3/SentryApollo3HttpInterceptor$BeforeSpanCallback;Z)V + public fun (Lio/sentry/IScopes;Lio/sentry/apollo3/SentryApollo3HttpInterceptor$BeforeSpanCallback;ZLjava/util/List;)V + public synthetic fun (Lio/sentry/IScopes;Lio/sentry/apollo3/SentryApollo3HttpInterceptor$BeforeSpanCallback;ZLjava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun dispose ()V public fun intercept (Lcom/apollographql/apollo3/api/http/HttpRequest;Lcom/apollographql/apollo3/network/http/HttpInterceptorChain;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } @@ -40,12 +40,12 @@ public final class io/sentry/apollo3/SentryApollo3Interceptor : com/apollographq public final class io/sentry/apollo3/SentryApolloBuilderExtensionsKt { public static final fun sentryTracing (Lcom/apollographql/apollo3/ApolloClient$Builder;)Lcom/apollographql/apollo3/ApolloClient$Builder; - public static final fun sentryTracing (Lcom/apollographql/apollo3/ApolloClient$Builder;Lio/sentry/IHub;)Lcom/apollographql/apollo3/ApolloClient$Builder; - public static final fun sentryTracing (Lcom/apollographql/apollo3/ApolloClient$Builder;Lio/sentry/IHub;Z)Lcom/apollographql/apollo3/ApolloClient$Builder; - public static final fun sentryTracing (Lcom/apollographql/apollo3/ApolloClient$Builder;Lio/sentry/IHub;ZLjava/util/List;)Lcom/apollographql/apollo3/ApolloClient$Builder; - public static final fun sentryTracing (Lcom/apollographql/apollo3/ApolloClient$Builder;Lio/sentry/IHub;ZLjava/util/List;Lio/sentry/apollo3/SentryApollo3HttpInterceptor$BeforeSpanCallback;)Lcom/apollographql/apollo3/ApolloClient$Builder; + public static final fun sentryTracing (Lcom/apollographql/apollo3/ApolloClient$Builder;Lio/sentry/IScopes;)Lcom/apollographql/apollo3/ApolloClient$Builder; + public static final fun sentryTracing (Lcom/apollographql/apollo3/ApolloClient$Builder;Lio/sentry/IScopes;Z)Lcom/apollographql/apollo3/ApolloClient$Builder; + public static final fun sentryTracing (Lcom/apollographql/apollo3/ApolloClient$Builder;Lio/sentry/IScopes;ZLjava/util/List;)Lcom/apollographql/apollo3/ApolloClient$Builder; + public static final fun sentryTracing (Lcom/apollographql/apollo3/ApolloClient$Builder;Lio/sentry/IScopes;ZLjava/util/List;Lio/sentry/apollo3/SentryApollo3HttpInterceptor$BeforeSpanCallback;)Lcom/apollographql/apollo3/ApolloClient$Builder; public static final fun sentryTracing (Lcom/apollographql/apollo3/ApolloClient$Builder;ZLjava/util/List;Lio/sentry/apollo3/SentryApollo3HttpInterceptor$BeforeSpanCallback;)Lcom/apollographql/apollo3/ApolloClient$Builder; - public static synthetic fun sentryTracing$default (Lcom/apollographql/apollo3/ApolloClient$Builder;Lio/sentry/IHub;ZLjava/util/List;Lio/sentry/apollo3/SentryApollo3HttpInterceptor$BeforeSpanCallback;ILjava/lang/Object;)Lcom/apollographql/apollo3/ApolloClient$Builder; + public static synthetic fun sentryTracing$default (Lcom/apollographql/apollo3/ApolloClient$Builder;Lio/sentry/IScopes;ZLjava/util/List;Lio/sentry/apollo3/SentryApollo3HttpInterceptor$BeforeSpanCallback;ILjava/lang/Object;)Lcom/apollographql/apollo3/ApolloClient$Builder; public static synthetic fun sentryTracing$default (Lcom/apollographql/apollo3/ApolloClient$Builder;ZLjava/util/List;Lio/sentry/apollo3/SentryApollo3HttpInterceptor$BeforeSpanCallback;ILjava/lang/Object;)Lcom/apollographql/apollo3/ApolloClient$Builder; } diff --git a/sentry-apollo-3/src/main/java/io/sentry/apollo3/SentryApollo3HttpInterceptor.kt b/sentry-apollo-3/src/main/java/io/sentry/apollo3/SentryApollo3HttpInterceptor.kt index 08cab179a5..52219cb8e1 100644 --- a/sentry-apollo-3/src/main/java/io/sentry/apollo3/SentryApollo3HttpInterceptor.kt +++ b/sentry-apollo-3/src/main/java/io/sentry/apollo3/SentryApollo3HttpInterceptor.kt @@ -11,9 +11,9 @@ import com.apollographql.apollo3.network.http.HttpInterceptorChain import io.sentry.BaggageHeader import io.sentry.Breadcrumb import io.sentry.Hint -import io.sentry.HubAdapter -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ISpan +import io.sentry.ScopesAdapter import io.sentry.SentryEvent import io.sentry.SentryIntegrationPackageStorage import io.sentry.SentryLevel @@ -41,7 +41,7 @@ import java.util.Locale private const val TRACE_ORIGIN = "auto.graphql.apollo3" class SentryApollo3HttpInterceptor @JvmOverloads constructor( - @ApiStatus.Internal private val hub: IHub = HubAdapter.getInstance(), + @ApiStatus.Internal private val scopes: IScopes = ScopesAdapter.getInstance(), private val beforeSpan: BeforeSpanCallback? = null, private val captureFailedRequests: Boolean = DEFAULT_CAPTURE_FAILED_REQUESTS, private val failedRequestTargets: List = listOf(DEFAULT_PROPAGATION_TARGETS) @@ -65,7 +65,7 @@ class SentryApollo3HttpInterceptor @JvmOverloads constructor( request: HttpRequest, chain: HttpInterceptorChain ): HttpResponse { - val activeSpan = if (Platform.isAndroid()) hub.transaction else hub.span + val activeSpan = if (Platform.isAndroid()) scopes.transaction else scopes.span val operationName = getHeader(HEADER_APOLLO_OPERATION_NAME, request.headers) val operationType = decodeHeaderValue(request, SENTRY_APOLLO_3_OPERATION_TYPE) @@ -77,7 +77,7 @@ class SentryApollo3HttpInterceptor @JvmOverloads constructor( span = startChild(request, activeSpan, operationName, operationType, operationId) } - val modifiedRequest = maybeAddTracingHeaders(hub, request, span) + val modifiedRequest = maybeAddTracingHeaders(scopes, request, span) var httpResponse: HttpResponse? = null var statusCode: Int? = null @@ -117,10 +117,10 @@ class SentryApollo3HttpInterceptor @JvmOverloads constructor( } } - private fun maybeAddTracingHeaders(hub: IHub, request: HttpRequest, span: ISpan?): HttpRequest { + private fun maybeAddTracingHeaders(scopes: IScopes, request: HttpRequest, span: ISpan?): HttpRequest { var cleanedHeaders = removeSentryInternalHeaders(request.headers).toMutableList() - TracingUtils.traceIfAllowed(hub, request.url, request.headers.filter { it.name == BaggageHeader.BAGGAGE_HEADER }.map { it.value }, span)?.let { + TracingUtils.traceIfAllowed(scopes, request.url, request.headers.filter { it.name == BaggageHeader.BAGGAGE_HEADER }.map { it.value }, span)?.let { cleanedHeaders.add(HttpHeader(it.sentryTraceHeader.name, it.sentryTraceHeader.value)) it.baggageHeader?.let { baggageHeader -> cleanedHeaders = cleanedHeaders.filterNot { it.name == BaggageHeader.BAGGAGE_HEADER }.toMutableList().apply { @@ -179,7 +179,7 @@ class SentryApollo3HttpInterceptor @JvmOverloads constructor( try { String(Base64.decode(it, Base64.NO_WRAP)) } catch (e: Throwable) { - hub.options.logger.log( + scopes.options.logger.log( SentryLevel.ERROR, "Error decoding internal apolloHeader $headerName", e @@ -218,7 +218,7 @@ class SentryApollo3HttpInterceptor @JvmOverloads constructor( span.spanContext.sampled = false } } catch (e: Throwable) { - hub.options.logger.log( + scopes.options.logger.log( SentryLevel.ERROR, "An error occurred while executing beforeSpan on ApolloInterceptor", e @@ -256,7 +256,7 @@ class SentryApollo3HttpInterceptor @JvmOverloads constructor( hint.set(APOLLO_RESPONSE, httpResponse) } - hub.addBreadcrumb(breadcrumb, hint) + scopes.addBreadcrumb(breadcrumb, hint) } // Extensions @@ -273,7 +273,7 @@ class SentryApollo3HttpInterceptor @JvmOverloads constructor( private fun getHeaders(headers: List): MutableMap? { // Headers are only sent if isSendDefaultPii is enabled due to PII - if (!hub.options.isSendDefaultPii) { + if (!scopes.options.isSendDefaultPii) { return null } @@ -311,7 +311,7 @@ class SentryApollo3HttpInterceptor @JvmOverloads constructor( val body = try { response.body?.peek()?.readUtf8() ?: "" } catch (e: Throwable) { - hub.options.logger.log( + scopes.options.logger.log( SentryLevel.ERROR, "Error reading the response body.", e @@ -368,7 +368,7 @@ class SentryApollo3HttpInterceptor @JvmOverloads constructor( urlDetails.applyToRequest(this) // Cookie is only sent if isSendDefaultPii is enabled cookies = - if (hub.options.isSendDefaultPii) getHeader("Cookie", request.headers) else null + if (scopes.options.isSendDefaultPii) getHeader("Cookie", request.headers) else null method = request.method.name headers = getHeaders(request.headers) apiTarget = "graphql" @@ -382,7 +382,7 @@ class SentryApollo3HttpInterceptor @JvmOverloads constructor( it.writeTo(buffer) data = buffer.readUtf8() } catch (e: Throwable) { - hub.options.logger.log( + scopes.options.logger.log( SentryLevel.ERROR, "Error reading the request body.", e @@ -396,7 +396,7 @@ class SentryApollo3HttpInterceptor @JvmOverloads constructor( val sentryResponse = Response().apply { // Set-Cookie is only sent if isSendDefaultPii is enabled due to PII - cookies = if (hub.options.isSendDefaultPii) { + cookies = if (scopes.options.isSendDefaultPii) { getHeader( "Set-Cookie", response.headers @@ -419,9 +419,9 @@ class SentryApollo3HttpInterceptor @JvmOverloads constructor( event.contexts.setResponse(sentryResponse) event.fingerprints = fingerprints - hub.captureEvent(event, hint) + scopes.captureEvent(event, hint) } catch (e: Throwable) { - hub.options.logger.log( + scopes.options.logger.log( SentryLevel.ERROR, "Error capturing the GraphQL error.", e diff --git a/sentry-apollo-3/src/main/java/io/sentry/apollo3/SentryApolloBuilderExtensions.kt b/sentry-apollo-3/src/main/java/io/sentry/apollo3/SentryApolloBuilderExtensions.kt index 2cdbc148fb..b40b1c183d 100644 --- a/sentry-apollo-3/src/main/java/io/sentry/apollo3/SentryApolloBuilderExtensions.kt +++ b/sentry-apollo-3/src/main/java/io/sentry/apollo3/SentryApolloBuilderExtensions.kt @@ -1,14 +1,14 @@ package io.sentry.apollo3 import com.apollographql.apollo3.ApolloClient -import io.sentry.HubAdapter -import io.sentry.IHub +import io.sentry.IScopes +import io.sentry.ScopesAdapter import io.sentry.SentryOptions.DEFAULT_PROPAGATION_TARGETS import io.sentry.apollo3.SentryApollo3HttpInterceptor.Companion.DEFAULT_CAPTURE_FAILED_REQUESTS @JvmOverloads fun ApolloClient.Builder.sentryTracing( - hub: IHub = HubAdapter.getInstance(), + scopes: IScopes = ScopesAdapter.getInstance(), captureFailedRequests: Boolean = DEFAULT_CAPTURE_FAILED_REQUESTS, failedRequestTargets: List = listOf(DEFAULT_PROPAGATION_TARGETS), beforeSpan: SentryApollo3HttpInterceptor.BeforeSpanCallback? = null @@ -16,7 +16,7 @@ fun ApolloClient.Builder.sentryTracing( addInterceptor(SentryApollo3Interceptor()) addHttpInterceptor( SentryApollo3HttpInterceptor( - hub = hub, + scopes = scopes, captureFailedRequests = captureFailedRequests, failedRequestTargets = failedRequestTargets, beforeSpan = beforeSpan @@ -31,7 +31,7 @@ fun ApolloClient.Builder.sentryTracing( beforeSpan: SentryApollo3HttpInterceptor.BeforeSpanCallback? = null ): ApolloClient.Builder { return sentryTracing( - hub = HubAdapter.getInstance(), + scopes = ScopesAdapter.getInstance(), captureFailedRequests = captureFailedRequests, failedRequestTargets = failedRequestTargets, beforeSpan = beforeSpan diff --git a/sentry-apollo-3/src/test/java/io/sentry/apollo3/SentryApollo3InterceptorClientErrors.kt b/sentry-apollo-3/src/test/java/io/sentry/apollo3/SentryApollo3InterceptorClientErrors.kt index 40406b77b5..b3f8b6d57e 100644 --- a/sentry-apollo-3/src/test/java/io/sentry/apollo3/SentryApollo3InterceptorClientErrors.kt +++ b/sentry-apollo-3/src/test/java/io/sentry/apollo3/SentryApollo3InterceptorClientErrors.kt @@ -5,7 +5,7 @@ import com.apollographql.apollo3.api.http.HttpRequest import com.apollographql.apollo3.api.http.HttpResponse import com.apollographql.apollo3.exception.ApolloException import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryIntegrationPackageStorage import io.sentry.SentryOptions import io.sentry.SentryOptions.DEFAULT_PROPAGATION_TARGETS @@ -35,7 +35,7 @@ import kotlin.test.assertTrue class SentryApollo3InterceptorClientErrors { class Fixture { val server = MockWebServer() - lateinit var hub: IHub + lateinit var scopes: IScopes private val responseBodyOk = """{ @@ -75,7 +75,7 @@ class SentryApollo3InterceptorClientErrors { ): ApolloClient { SentryIntegrationPackageStorage.getInstance().clearStorage() - hub = mock().apply { + scopes = mock().apply { whenever(options).thenReturn( SentryOptions().apply { dsn = "https://key@sentry.io/proj" @@ -84,7 +84,7 @@ class SentryApollo3InterceptorClientErrors { } ) } - whenever(hub.captureEvent(any(), any())).thenReturn(SentryId.EMPTY_ID) + whenever(scopes.captureEvent(any(), any())).thenReturn(SentryId.EMPTY_ID) val response = MockResponse() .setBody(responseBody) @@ -102,7 +102,7 @@ class SentryApollo3InterceptorClientErrors { val builder = ApolloClient.Builder() .serverUrl(server.url("?myQuery=query#myFragment").toString()) .sentryTracing( - hub = hub, + scopes = scopes, captureFailedRequests = captureFailedRequests, failedRequestTargets = failedRequestTargets ) @@ -123,7 +123,7 @@ class SentryApollo3InterceptorClientErrors { val sut = fixture.getSut(captureFailedRequests = false, responseBody = fixture.responseBodyNotOk) executeQuery(sut) - verify(fixture.hub, never()).captureEvent(any(), any()) + verify(fixture.scopes, never()).captureEvent(any(), any()) } @Test @@ -132,7 +132,7 @@ class SentryApollo3InterceptorClientErrors { fixture.getSut(responseBody = fixture.responseBodyNotOk) executeQuery(sut) - verify(fixture.hub).captureEvent(any(), any()) + verify(fixture.scopes).captureEvent(any(), any()) } // endregion @@ -165,7 +165,7 @@ class SentryApollo3InterceptorClientErrors { ) executeQuery(sut) - verify(fixture.hub, never()).captureEvent(any(), any()) + verify(fixture.scopes, never()).captureEvent(any(), any()) } @Test @@ -174,7 +174,7 @@ class SentryApollo3InterceptorClientErrors { fixture.getSut(responseBody = fixture.responseBodyNotOk) executeQuery(sut) - verify(fixture.hub).captureEvent(any(), any()) + verify(fixture.scopes).captureEvent(any(), any()) } // endregion @@ -187,7 +187,7 @@ class SentryApollo3InterceptorClientErrors { fixture.getSut(responseBody = fixture.responseBodyNotOk) executeQuery(sut) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { val throwable = (it.throwableMechanism as ExceptionMechanismException) assertEquals("SentryApollo3Interceptor", throwable.exceptionMechanism.type) @@ -202,7 +202,7 @@ class SentryApollo3InterceptorClientErrors { fixture.getSut(responseBody = fixture.responseBodyNotOk) executeQuery(sut) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { val throwable = (it.throwableMechanism as ExceptionMechanismException) assertEquals("GraphQL Request failed, name: LaunchDetails, type: query", throwable.throwable.message) @@ -217,7 +217,7 @@ class SentryApollo3InterceptorClientErrors { fixture.getSut(responseBody = fixture.responseBodyNotOk) executeQuery(sut) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { val throwable = (it.throwableMechanism as ExceptionMechanismException) assertTrue(throwable.isSnapshot) @@ -238,7 +238,7 @@ class SentryApollo3InterceptorClientErrors { {"operationName":"LaunchDetails","variables":{"id":"83"},"query":"query LaunchDetails($escapeDolar: ID!) { launch(id: $escapeDolar) { id site mission { name missionPatch(size: LARGE) } rocket { name type } } }"} """.trimIndent() - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { val request = it.request!! @@ -262,7 +262,7 @@ class SentryApollo3InterceptorClientErrors { fixture.getSut(responseBody = fixture.responseBodyNotOk, sendDefaultPii = true) executeQuery(sut) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { val request = it.request!! @@ -280,7 +280,7 @@ class SentryApollo3InterceptorClientErrors { fixture.getSut(responseBody = fixture.responseBodyNotOk) executeQuery(sut) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { val response = it.contexts.response!! @@ -300,7 +300,7 @@ class SentryApollo3InterceptorClientErrors { fixture.getSut(responseBody = fixture.responseBodyNotOk, sendDefaultPii = true) executeQuery(sut) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { val response = it.contexts.response!! @@ -318,7 +318,7 @@ class SentryApollo3InterceptorClientErrors { fixture.getSut(responseBody = fixture.responseBodyNotOk) executeQuery(sut) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { assertEquals(listOf("LaunchDetails", "query", "200"), it.fingerprints) }, @@ -337,7 +337,7 @@ class SentryApollo3InterceptorClientErrors { executeQuery(sut) // HttpInterceptor does not throw for >= 400 - verify(fixture.hub).captureEvent(any(), any()) + verify(fixture.scopes).captureEvent(any(), any()) } @Test @@ -345,7 +345,7 @@ class SentryApollo3InterceptorClientErrors { val sut = fixture.getSut(responseBody = fixture.responseBodyNotOk) - whenever(fixture.hub.captureEvent(any(), any())).thenThrow(RuntimeException()) + whenever(fixture.scopes.captureEvent(any(), any())).thenThrow(RuntimeException()) executeQuery(sut) } @@ -360,7 +360,7 @@ class SentryApollo3InterceptorClientErrors { fixture.getSut(responseBody = fixture.responseBodyNotOk) executeQuery(sut) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( any(), check { val request = it.get(TypeCheckHint.APOLLO_REQUEST) diff --git a/sentry-apollo-3/src/test/java/io/sentry/apollo3/SentryApollo3InterceptorTest.kt b/sentry-apollo-3/src/test/java/io/sentry/apollo3/SentryApollo3InterceptorTest.kt index 44d8bfd624..3b836f45b9 100644 --- a/sentry-apollo-3/src/test/java/io/sentry/apollo3/SentryApollo3InterceptorTest.kt +++ b/sentry-apollo-3/src/test/java/io/sentry/apollo3/SentryApollo3InterceptorTest.kt @@ -9,7 +9,7 @@ import com.apollographql.apollo3.network.http.HttpInterceptor import com.apollographql.apollo3.network.http.HttpInterceptorChain import io.sentry.BaggageHeader import io.sentry.Breadcrumb -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ITransaction import io.sentry.Scope import io.sentry.ScopeCallback @@ -57,11 +57,11 @@ class SentryApollo3InterceptorTest { sdkVersion = SdkVersion("test", "1.2.3") } val scope = Scope(options) - val hub = mock().also { + val scopes = mock().also { whenever(it.options).thenReturn(options) doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(it).configureScope(any()) } - private var httpInterceptor = SentryApollo3HttpInterceptor(hub, captureFailedRequests = false) + private var httpInterceptor = SentryApollo3HttpInterceptor(scopes, captureFailedRequests = false) @SuppressWarnings("LongParameterList") fun getSut( @@ -93,7 +93,7 @@ class SentryApollo3InterceptorTest { ) if (beforeSpan != null) { - httpInterceptor = SentryApollo3HttpInterceptor(hub, beforeSpan, captureFailedRequests = false) + httpInterceptor = SentryApollo3HttpInterceptor(scopes, beforeSpan, captureFailedRequests = false) } val builder = ApolloClient.Builder() @@ -124,7 +124,7 @@ class SentryApollo3InterceptorTest { fun `creates a span around the successful request`() { executeQuery() - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertTransactionDetails(it, httpStatusCode = 200) assertEquals(SpanStatus.OK, it.spans.first().status) @@ -139,7 +139,7 @@ class SentryApollo3InterceptorTest { fun `creates a span around the failed request`() { executeQuery(fixture.getSut(httpStatusCode = 403)) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertTransactionDetails(it, httpStatusCode = 403) assertEquals(SpanStatus.PERMISSION_DENIED, it.spans.first().status) @@ -159,7 +159,7 @@ class SentryApollo3InterceptorTest { } executeQuery(fixture.getSut(interceptor = failingInterceptor)) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertTransactionDetails(it, httpStatusCode = 404, contentLength = null) assertEquals("POST", it.spans.first().data?.get(SpanDataConvention.HTTP_METHOD_KEY)) @@ -176,7 +176,7 @@ class SentryApollo3InterceptorTest { fun `creates a span around the request failing with network error`() { executeQuery(fixture.getSut(socketPolicy = SocketPolicy.DISCONNECT_DURING_REQUEST_BODY)) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertTransactionDetails(it, httpStatusCode = null, contentLength = null) assertEquals(SpanStatus.INTERNAL_ERROR, it.spans.first().status) @@ -241,7 +241,7 @@ class SentryApollo3InterceptorTest { ) ) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertEquals(1, it.spans.size) val httpClientSpan = it.spans.first() @@ -261,7 +261,7 @@ class SentryApollo3InterceptorTest { ) ) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertEquals(0, it.spans.size) }, @@ -281,7 +281,7 @@ class SentryApollo3InterceptorTest { ) ) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertEquals(1, it.spans.size) }, @@ -294,7 +294,7 @@ class SentryApollo3InterceptorTest { @Test fun `adds breadcrumb when http calls succeeds`() { executeQuery(fixture.getSut()) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) // response_body_size is added but mock webserver returns 0 always @@ -309,9 +309,9 @@ class SentryApollo3InterceptorTest { @Test fun `sets SDKVersion Info`() { - assertNotNull(fixture.hub.options.sdkVersion) - assert(fixture.hub.options.sdkVersion!!.integrationSet.contains("Apollo3")) - val packageInfo = fixture.hub.options.sdkVersion!!.packageSet.firstOrNull { pkg -> pkg.name == "maven:io.sentry:sentry-apollo-3" } + assertNotNull(fixture.scopes.options.sdkVersion) + assert(fixture.scopes.options.sdkVersion!!.integrationSet.contains("Apollo3")) + val packageInfo = fixture.scopes.options.sdkVersion!!.packageSet.firstOrNull { pkg -> pkg.name == "maven:io.sentry:sentry-apollo-3" } assertNotNull(packageInfo) assert(packageInfo.version == BuildConfig.VERSION_NAME) } @@ -320,14 +320,14 @@ class SentryApollo3InterceptorTest { fun `attaches to root transaction on Android`() { Apollo3PlatformTestManipulator.pretendIsAndroid(true) executeQuery(fixture.getSut()) - verify(fixture.hub).transaction + verify(fixture.scopes).transaction } @Test fun `attaches to child span on non-Android`() { Apollo3PlatformTestManipulator.pretendIsAndroid(false) executeQuery(fixture.getSut()) - verify(fixture.hub).span + verify(fixture.scopes).span } private fun assertTransactionDetails(it: SentryTransaction, httpStatusCode: Int? = 200, contentLength: Long? = 0L) { @@ -350,9 +350,9 @@ class SentryApollo3InterceptorTest { private fun executeQuery(sut: ApolloClient = fixture.getSut(), isSpanActive: Boolean = true, id: String = "83") = runBlocking { var tx: ITransaction? = null if (isSpanActive) { - tx = SentryTracer(TransactionContext("op", "desc", TracesSamplingDecision(true)), fixture.hub) - whenever(fixture.hub.transaction).thenReturn(tx) - whenever(fixture.hub.span).thenReturn(tx) + tx = SentryTracer(TransactionContext("op", "desc", TracesSamplingDecision(true)), fixture.scopes) + whenever(fixture.scopes.transaction).thenReturn(tx) + whenever(fixture.scopes.span).thenReturn(tx) } val coroutine = launch { diff --git a/sentry-apollo-3/src/test/java/io/sentry/apollo3/SentryApollo3InterceptorWithVariablesTest.kt b/sentry-apollo-3/src/test/java/io/sentry/apollo3/SentryApollo3InterceptorWithVariablesTest.kt index 81775efc18..3ac3d80d7d 100644 --- a/sentry-apollo-3/src/test/java/io/sentry/apollo3/SentryApollo3InterceptorWithVariablesTest.kt +++ b/sentry-apollo-3/src/test/java/io/sentry/apollo3/SentryApollo3InterceptorWithVariablesTest.kt @@ -3,7 +3,7 @@ package io.sentry.apollo3 import com.apollographql.apollo3.ApolloClient import com.apollographql.apollo3.exception.ApolloException import io.sentry.Breadcrumb -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ITransaction import io.sentry.SentryOptions import io.sentry.SentryTracer @@ -32,7 +32,7 @@ class SentryApollo3InterceptorWithVariablesTest { class Fixture { val server = MockWebServer() - val hub = mock() + val scopes = mock() @SuppressWarnings("LongParameterList") fun getSut( @@ -54,7 +54,7 @@ class SentryApollo3InterceptorWithVariablesTest { socketPolicy: SocketPolicy = SocketPolicy.KEEP_OPEN, beforeSpan: BeforeSpanCallback? = null ): ApolloClient { - whenever(hub.options).thenReturn( + whenever(scopes.options).thenReturn( SentryOptions().apply { dsn = "http://key@localhost/proj" } @@ -68,7 +68,7 @@ class SentryApollo3InterceptorWithVariablesTest { ) return ApolloClient.Builder().serverUrl(server.url("/").toString()) - .sentryTracing(hub = hub, beforeSpan = beforeSpan, captureFailedRequests = false) + .sentryTracing(scopes = scopes, beforeSpan = beforeSpan, captureFailedRequests = false) .build() } } @@ -79,7 +79,7 @@ class SentryApollo3InterceptorWithVariablesTest { fun `creates a span around the successful request`() { executeQuery() - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertTransactionDetails(it) assertEquals(SpanStatus.OK, it.spans.first().status) @@ -94,7 +94,7 @@ class SentryApollo3InterceptorWithVariablesTest { fun `creates a span around the failed request`() { executeQuery(fixture.getSut(httpStatusCode = 403)) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertTransactionDetails(it) assertEquals(SpanStatus.PERMISSION_DENIED, it.spans.first().status) @@ -109,7 +109,7 @@ class SentryApollo3InterceptorWithVariablesTest { fun `creates a span around the request failing with network error`() { executeQuery(fixture.getSut(socketPolicy = SocketPolicy.DISCONNECT_DURING_REQUEST_BODY)) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertTransactionDetails(it) assertEquals(SpanStatus.INTERNAL_ERROR, it.spans.first().status) @@ -124,7 +124,7 @@ class SentryApollo3InterceptorWithVariablesTest { fun `handles non-ascii header values correctly`() { executeQuery(id = "á") - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertTransactionDetails(it) assertEquals(SpanStatus.OK, it.spans.first().status) @@ -138,7 +138,7 @@ class SentryApollo3InterceptorWithVariablesTest { @Test fun `adds breadcrumb when http calls succeeds`() { executeQuery(fixture.getSut()) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) // response_body_size is added but mock webserver returns 0 always @@ -173,8 +173,8 @@ class SentryApollo3InterceptorWithVariablesTest { private fun executeQuery(sut: ApolloClient = fixture.getSut(), isSpanActive: Boolean = true, id: String = "83") = runBlocking { var tx: ITransaction? = null if (isSpanActive) { - tx = SentryTracer(TransactionContext("op", "desc", TracesSamplingDecision(true)), fixture.hub) - whenever(fixture.hub.span).thenReturn(tx) + tx = SentryTracer(TransactionContext("op", "desc", TracesSamplingDecision(true)), fixture.scopes) + whenever(fixture.scopes.span).thenReturn(tx) } val coroutine = launch { diff --git a/sentry-apollo/api/sentry-apollo.api b/sentry-apollo/api/sentry-apollo.api index 8c18bce06e..63eac6a193 100644 --- a/sentry-apollo/api/sentry-apollo.api +++ b/sentry-apollo/api/sentry-apollo.api @@ -5,9 +5,9 @@ public final class io/sentry/apollo/BuildConfig { public final class io/sentry/apollo/SentryApolloInterceptor : com/apollographql/apollo/interceptor/ApolloInterceptor { public fun ()V - public fun (Lio/sentry/IHub;)V - public fun (Lio/sentry/IHub;Lio/sentry/apollo/SentryApolloInterceptor$BeforeSpanCallback;)V - public synthetic fun (Lio/sentry/IHub;Lio/sentry/apollo/SentryApolloInterceptor$BeforeSpanCallback;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lio/sentry/IScopes;)V + public fun (Lio/sentry/IScopes;Lio/sentry/apollo/SentryApolloInterceptor$BeforeSpanCallback;)V + public synthetic fun (Lio/sentry/IScopes;Lio/sentry/apollo/SentryApolloInterceptor$BeforeSpanCallback;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun (Lio/sentry/apollo/SentryApolloInterceptor$BeforeSpanCallback;)V public fun dispose ()V public fun interceptAsync (Lcom/apollographql/apollo/interceptor/ApolloInterceptor$InterceptorRequest;Lcom/apollographql/apollo/interceptor/ApolloInterceptorChain;Ljava/util/concurrent/Executor;Lcom/apollographql/apollo/interceptor/ApolloInterceptor$CallBack;)V diff --git a/sentry-apollo/src/main/java/io/sentry/apollo/SentryApolloInterceptor.kt b/sentry-apollo/src/main/java/io/sentry/apollo/SentryApolloInterceptor.kt index faa8a549a9..fe5a6a4762 100644 --- a/sentry-apollo/src/main/java/io/sentry/apollo/SentryApolloInterceptor.kt +++ b/sentry-apollo/src/main/java/io/sentry/apollo/SentryApolloInterceptor.kt @@ -15,9 +15,9 @@ import com.apollographql.apollo.request.RequestHeaders import io.sentry.BaggageHeader import io.sentry.Breadcrumb import io.sentry.Hint -import io.sentry.HubAdapter -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ISpan +import io.sentry.ScopesAdapter import io.sentry.SentryIntegrationPackageStorage import io.sentry.SentryLevel import io.sentry.SpanDataConvention @@ -32,12 +32,12 @@ import java.util.concurrent.Executor private const val TRACE_ORIGIN = "auto.graphql.apollo" class SentryApolloInterceptor( - private val hub: IHub = HubAdapter.getInstance(), + private val scopes: IScopes = ScopesAdapter.getInstance(), private val beforeSpan: BeforeSpanCallback? = null ) : ApolloInterceptor { - constructor(hub: IHub) : this(hub, null) - constructor(beforeSpan: BeforeSpanCallback) : this(HubAdapter.getInstance(), beforeSpan) + constructor(scopes: IScopes) : this(scopes, null) + constructor(beforeSpan: BeforeSpanCallback) : this(ScopesAdapter.getInstance(), beforeSpan) init { addIntegrationToSdkVersion(javaClass) @@ -45,7 +45,7 @@ class SentryApolloInterceptor( } override fun interceptAsync(request: InterceptorRequest, chain: ApolloInterceptorChain, dispatcher: Executor, callBack: CallBack) { - val activeSpan = if (io.sentry.util.Platform.isAndroid()) hub.transaction else hub.span + val activeSpan = if (io.sentry.util.Platform.isAndroid()) scopes.transaction else scopes.span if (activeSpan == null) { val headers = addTracingHeaders(request, null) val modifiedRequest = request.toBuilder().requestHeaders(headers).build() @@ -115,10 +115,10 @@ class SentryApolloInterceptor( private fun addTracingHeaders(request: InterceptorRequest, span: ISpan?): RequestHeaders { val requestHeaderBuilder = request.requestHeaders.toBuilder() - if (hub.options.isTraceSampling) { + if (scopes.options.isTraceSampling) { // we have no access to URI, no way to verify tracing origins TracingUtils.trace( - hub, + scopes, listOf(request.requestHeaders.headerValue(BaggageHeader.BAGGAGE_HEADER)), span )?.let { tracingHeaders -> @@ -154,7 +154,7 @@ class SentryApolloInterceptor( try { newSpan = beforeSpan.execute(span, request, response) } catch (e: Exception) { - hub.options.logger.log(SentryLevel.ERROR, "An error occurred while executing beforeSpan on ApolloInterceptor", e) + scopes.options.logger.log(SentryLevel.ERROR, "An error occurred while executing beforeSpan on ApolloInterceptor", e) } } if (newSpan == null) { @@ -182,7 +182,7 @@ class SentryApolloInterceptor( set(APOLLO_REQUEST, httpRequest) set(APOLLO_RESPONSE, httpResponse) } - hub.addBreadcrumb(breadcrumb, hint) + scopes.addBreadcrumb(breadcrumb, hint) } } } diff --git a/sentry-apollo/src/test/java/io/sentry/apollo/SentryApolloInterceptorTest.kt b/sentry-apollo/src/test/java/io/sentry/apollo/SentryApolloInterceptorTest.kt index d22c2fd3e5..b1b118c334 100644 --- a/sentry-apollo/src/test/java/io/sentry/apollo/SentryApolloInterceptorTest.kt +++ b/sentry-apollo/src/test/java/io/sentry/apollo/SentryApolloInterceptorTest.kt @@ -5,7 +5,7 @@ import com.apollographql.apollo.coroutines.await import com.apollographql.apollo.exception.ApolloException import io.sentry.BaggageHeader import io.sentry.Breadcrumb -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ITransaction import io.sentry.Scope import io.sentry.ScopeCallback @@ -48,13 +48,13 @@ class SentryApolloInterceptorTest { sdkVersion = SdkVersion("test", "1.2.3") } val scope = Scope(options) - val hub = mock().also { + val scopes = mock().also { whenever(it.options).thenReturn(options) doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(it).configureScope( any() ) } - private var interceptor = SentryApolloInterceptor(hub) + private var interceptor = SentryApolloInterceptor(scopes) @SuppressWarnings("LongParameterList") fun getSut( @@ -84,7 +84,7 @@ class SentryApolloInterceptorTest { ) if (beforeSpan != null) { - interceptor = SentryApolloInterceptor(hub, beforeSpan) + interceptor = SentryApolloInterceptor(scopes, beforeSpan) } return ApolloClient.builder() .serverUrl(server.url("/")) @@ -104,7 +104,7 @@ class SentryApolloInterceptorTest { fun `creates a span around the successful request`() { executeQuery() - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertTransactionDetails(it) assertEquals(SpanStatus.OK, it.spans.first().status) @@ -120,7 +120,7 @@ class SentryApolloInterceptorTest { fun `creates a span around the failed request`() { executeQuery(fixture.getSut(httpStatusCode = 403)) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertTransactionDetails(it) assertEquals(SpanStatus.PERMISSION_DENIED, it.spans.first().status) @@ -138,7 +138,7 @@ class SentryApolloInterceptorTest { fun `creates a span around the request failing with network error`() { executeQuery(fixture.getSut(socketPolicy = SocketPolicy.DISCONNECT_DURING_REQUEST_BODY)) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertTransactionDetails(it) assertEquals(SpanStatus.INTERNAL_ERROR, it.spans.first().status) @@ -176,7 +176,7 @@ class SentryApolloInterceptorTest { } ) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertEquals(1, it.spans.size) val httpClientSpan = it.spans.first() @@ -196,7 +196,7 @@ class SentryApolloInterceptorTest { } ) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertTrue(it.spans.isEmpty()) }, @@ -212,7 +212,7 @@ class SentryApolloInterceptorTest { fixture.getSut { _, _, _ -> throw RuntimeException() } ) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertEquals(1, it.spans.size) }, @@ -225,7 +225,7 @@ class SentryApolloInterceptorTest { @Test fun `adds breadcrumb when http calls succeeds`() { executeQuery() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(280L, it.data["response_body_size"]) @@ -237,9 +237,9 @@ class SentryApolloInterceptorTest { @Test fun `sets SDKVersion Info`() { - assertNotNull(fixture.hub.options.sdkVersion) - assert(fixture.hub.options.sdkVersion!!.integrationSet.contains("Apollo")) - val packageInfo = fixture.hub.options.sdkVersion!!.packageSet.firstOrNull { pkg -> pkg.name == "maven:io.sentry:sentry-apollo" } + assertNotNull(fixture.scopes.options.sdkVersion) + assert(fixture.scopes.options.sdkVersion!!.integrationSet.contains("Apollo")) + val packageInfo = fixture.scopes.options.sdkVersion!!.packageSet.firstOrNull { pkg -> pkg.name == "maven:io.sentry:sentry-apollo" } assertNotNull(packageInfo) assert(packageInfo.version == BuildConfig.VERSION_NAME) } @@ -248,14 +248,14 @@ class SentryApolloInterceptorTest { fun `attaches to root transaction on Android`() { ApolloPlatformTestManipulator.pretendIsAndroid(true) executeQuery(fixture.getSut()) - verify(fixture.hub).transaction + verify(fixture.scopes).transaction } @Test fun `attaches to child span on non-Android`() { ApolloPlatformTestManipulator.pretendIsAndroid(false) executeQuery(fixture.getSut()) - verify(fixture.hub).span + verify(fixture.scopes).span } private fun assertTransactionDetails(it: SentryTransaction) { @@ -273,9 +273,9 @@ class SentryApolloInterceptorTest { private fun executeQuery(sut: ApolloClient = fixture.getSut(), isSpanActive: Boolean = true) = runBlocking { var tx: ITransaction? = null if (isSpanActive) { - tx = SentryTracer(TransactionContext("op", "desc", TracesSamplingDecision(true)), fixture.hub) - whenever(fixture.hub.transaction).thenReturn(tx) - whenever(fixture.hub.span).thenReturn(tx) + tx = SentryTracer(TransactionContext("op", "desc", TracesSamplingDecision(true)), fixture.scopes) + whenever(fixture.scopes.transaction).thenReturn(tx) + whenever(fixture.scopes.span).thenReturn(tx) } val coroutine = launch { From da927bcca927a31ed5b5a7d186790adb7b857d67 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Tue, 2 Apr 2024 14:30:11 +0200 Subject: [PATCH 08/28] Replace `IHub` with `IScopes` in okhttp integration --- sentry-okhttp/api/sentry-okhttp.api | 18 +++---- .../io/sentry/okhttp/SentryOkHttpEvent.kt | 16 +++--- .../okhttp/SentryOkHttpEventListener.kt | 24 ++++----- .../sentry/okhttp/SentryOkHttpInterceptor.kt | 22 ++++---- .../io/sentry/okhttp/SentryOkHttpUtils.kt | 18 +++---- .../okhttp/SentryOkHttpEventListenerTest.kt | 28 +++++----- .../io/sentry/okhttp/SentryOkHttpEventTest.kt | 52 +++++++++---------- .../okhttp/SentryOkHttpInterceptorTest.kt | 50 +++++++++--------- .../io/sentry/okhttp/SentryOkHttpUtilsTest.kt | 22 ++++---- 9 files changed, 125 insertions(+), 125 deletions(-) diff --git a/sentry-okhttp/api/sentry-okhttp.api b/sentry-okhttp/api/sentry-okhttp.api index 3095659c88..9cb875ff34 100644 --- a/sentry-okhttp/api/sentry-okhttp.api +++ b/sentry-okhttp/api/sentry-okhttp.api @@ -6,12 +6,12 @@ public final class io/sentry/okhttp/BuildConfig { public class io/sentry/okhttp/SentryOkHttpEventListener : okhttp3/EventListener { public static final field Companion Lio/sentry/okhttp/SentryOkHttpEventListener$Companion; public fun ()V - public fun (Lio/sentry/IHub;Lkotlin/jvm/functions/Function1;)V - public synthetic fun (Lio/sentry/IHub;Lkotlin/jvm/functions/Function1;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public fun (Lio/sentry/IHub;Lokhttp3/EventListener$Factory;)V - public synthetic fun (Lio/sentry/IHub;Lokhttp3/EventListener$Factory;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public fun (Lio/sentry/IHub;Lokhttp3/EventListener;)V - public synthetic fun (Lio/sentry/IHub;Lokhttp3/EventListener;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lio/sentry/IScopes;Lkotlin/jvm/functions/Function1;)V + public synthetic fun (Lio/sentry/IScopes;Lkotlin/jvm/functions/Function1;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lio/sentry/IScopes;Lokhttp3/EventListener$Factory;)V + public synthetic fun (Lio/sentry/IScopes;Lokhttp3/EventListener$Factory;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lio/sentry/IScopes;Lokhttp3/EventListener;)V + public synthetic fun (Lio/sentry/IScopes;Lokhttp3/EventListener;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun (Lokhttp3/EventListener$Factory;)V public fun (Lokhttp3/EventListener;)V public fun cacheConditionalHit (Lokhttp3/Call;Lokhttp3/Response;)V @@ -50,9 +50,9 @@ public final class io/sentry/okhttp/SentryOkHttpEventListener$Companion { public class io/sentry/okhttp/SentryOkHttpInterceptor : okhttp3/Interceptor { public fun ()V - public fun (Lio/sentry/IHub;)V - public fun (Lio/sentry/IHub;Lio/sentry/okhttp/SentryOkHttpInterceptor$BeforeSpanCallback;ZLjava/util/List;Ljava/util/List;)V - public synthetic fun (Lio/sentry/IHub;Lio/sentry/okhttp/SentryOkHttpInterceptor$BeforeSpanCallback;ZLjava/util/List;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lio/sentry/IScopes;)V + public fun (Lio/sentry/IScopes;Lio/sentry/okhttp/SentryOkHttpInterceptor$BeforeSpanCallback;ZLjava/util/List;Ljava/util/List;)V + public synthetic fun (Lio/sentry/IScopes;Lio/sentry/okhttp/SentryOkHttpInterceptor$BeforeSpanCallback;ZLjava/util/List;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun (Lio/sentry/okhttp/SentryOkHttpInterceptor$BeforeSpanCallback;)V public fun intercept (Lokhttp3/Interceptor$Chain;)Lokhttp3/Response; } diff --git a/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpEvent.kt b/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpEvent.kt index 00cc26e754..153499210c 100644 --- a/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpEvent.kt +++ b/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpEvent.kt @@ -2,7 +2,7 @@ package io.sentry.okhttp import io.sentry.Breadcrumb import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ISpan import io.sentry.SentryDate import io.sentry.SentryLevel @@ -30,7 +30,7 @@ private const val RESPONSE_BODY_TIMEOUT_MILLIS = 800L internal const val TRACE_ORIGIN = "auto.http.okhttp" @Suppress("TooManyFunctions") -internal class SentryOkHttpEvent(private val hub: IHub, private val request: Request) { +internal class SentryOkHttpEvent(private val scopes: IScopes, private val request: Request) { private val eventSpans: MutableMap = ConcurrentHashMap() private val breadcrumb: Breadcrumb internal val callRootSpan: ISpan? @@ -47,7 +47,7 @@ internal class SentryOkHttpEvent(private val hub: IHub, private val request: Req val method: String = request.method // We start the call span that will contain all the others - val parentSpan = if (Platform.isAndroid()) hub.transaction else hub.span + val parentSpan = if (Platform.isAndroid()) scopes.transaction else scopes.span callRootSpan = parentSpan?.startChild("http.client", "$method $url") callRootSpan?.spanContext?.origin = TRACE_ORIGIN urlDetails.applyToSpan(callRootSpan) @@ -149,13 +149,13 @@ internal class SentryOkHttpEvent(private val hub: IHub, private val request: Req response?.let { hint.set(TypeCheckHint.OKHTTP_RESPONSE, it) } // We send the breadcrumb even without spans. - hub.addBreadcrumb(breadcrumb, hint) + scopes.addBreadcrumb(breadcrumb, hint) // No span is created (e.g. no transaction is running) if (callRootSpan == null) { // We report the client error even without spans. clientErrorResponse?.let { - SentryOkHttpUtils.captureClientError(hub, it.request, it) + SentryOkHttpUtils.captureClientError(scopes, it.request, it) } return } @@ -173,7 +173,7 @@ internal class SentryOkHttpEvent(private val hub: IHub, private val request: Req // We report the client error here, after all sub-spans finished, so that it will be bound // to the root call span. clientErrorResponse?.let { - SentryOkHttpUtils.captureClientError(hub, it.request, it) + SentryOkHttpUtils.captureClientError(scopes, it.request, it) } if (finishDate != null) { callRootSpan.finish(callRootSpan.status, finishDate) @@ -204,7 +204,7 @@ internal class SentryOkHttpEvent(private val hub: IHub, private val request: Req fun scheduleFinish(timestamp: SentryDate) { try { - hub.options.executorService.schedule({ + scopes.options.executorService.schedule({ if (!isReadingResponseBody.get() && (eventSpans.values.all { it.isFinished } || callRootSpan?.isFinished != true) ) { @@ -212,7 +212,7 @@ internal class SentryOkHttpEvent(private val hub: IHub, private val request: Req } }, RESPONSE_BODY_TIMEOUT_MILLIS) } catch (e: RejectedExecutionException) { - hub.options + scopes.options .logger .log( SentryLevel.ERROR, diff --git a/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpEventListener.kt b/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpEventListener.kt index 67a8cd8b56..f20e2ef0cb 100644 --- a/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpEventListener.kt +++ b/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpEventListener.kt @@ -1,7 +1,7 @@ package io.sentry.okhttp -import io.sentry.HubAdapter -import io.sentry.IHub +import io.sentry.IScopes +import io.sentry.ScopesAdapter import io.sentry.SpanDataConvention import io.sentry.SpanStatus import okhttp3.Call @@ -41,7 +41,7 @@ import java.util.concurrent.ConcurrentHashMap */ @Suppress("TooManyFunctions") public open class SentryOkHttpEventListener( - private val hub: IHub = HubAdapter.getInstance(), + private val scopes: IScopes = ScopesAdapter.getInstance(), private val originalEventListenerCreator: ((call: Call) -> EventListener)? = null ) : EventListener() { @@ -62,27 +62,27 @@ public open class SentryOkHttpEventListener( } public constructor() : this( - HubAdapter.getInstance(), + ScopesAdapter.getInstance(), originalEventListenerCreator = null ) public constructor(originalEventListener: EventListener) : this( - HubAdapter.getInstance(), + ScopesAdapter.getInstance(), originalEventListenerCreator = { originalEventListener } ) public constructor(originalEventListenerFactory: Factory) : this( - HubAdapter.getInstance(), + ScopesAdapter.getInstance(), originalEventListenerCreator = { originalEventListenerFactory.create(it) } ) - public constructor(hub: IHub = HubAdapter.getInstance(), originalEventListener: EventListener) : this( - hub, + public constructor(scopes: IScopes = ScopesAdapter.getInstance(), originalEventListener: EventListener) : this( + scopes, originalEventListenerCreator = { originalEventListener } ) - public constructor(hub: IHub = HubAdapter.getInstance(), originalEventListenerFactory: Factory) : this( - hub, + public constructor(scopes: IScopes = ScopesAdapter.getInstance(), originalEventListenerFactory: Factory) : this( + scopes, originalEventListenerCreator = { originalEventListenerFactory.create(it) } ) @@ -92,7 +92,7 @@ public open class SentryOkHttpEventListener( // If the wrapped EventListener is ours, we can just delegate the calls, // without creating other events that would create duplicates if (canCreateEventSpan()) { - eventMap[call] = SentryOkHttpEvent(hub, call.request()) + eventMap[call] = SentryOkHttpEvent(scopes, call.request()) } } @@ -318,7 +318,7 @@ public open class SentryOkHttpEventListener( it.status = SpanStatus.fromHttpStatusCode(response.code) } } - okHttpEvent.scheduleFinish(responseHeadersSpan?.finishDate ?: hub.options.dateProvider.now()) + okHttpEvent.scheduleFinish(responseHeadersSpan?.finishDate ?: scopes.options.dateProvider.now()) } override fun responseBodyStart(call: Call) { diff --git a/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpInterceptor.kt b/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpInterceptor.kt index efa472963d..a079864612 100644 --- a/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpInterceptor.kt +++ b/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpInterceptor.kt @@ -4,9 +4,9 @@ import io.sentry.BaggageHeader import io.sentry.Breadcrumb import io.sentry.Hint import io.sentry.HttpStatusCodeRange -import io.sentry.HubAdapter -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ISpan +import io.sentry.ScopesAdapter import io.sentry.SentryIntegrationPackageStorage import io.sentry.SentryOptions.DEFAULT_PROPAGATION_TARGETS import io.sentry.SpanDataConvention @@ -29,7 +29,7 @@ import java.io.IOException * out of the active span bound to the scope for each HTTP Request. * If [captureFailedRequests] is enabled, the SDK will capture HTTP Client errors as well. * - * @param hub The [IHub], internal and only used for testing. + * @param scopes The [IScopes], internal and only used for testing. * @param beforeSpan The [ISpan] can be customized or dropped with the [BeforeSpanCallback]. * @param captureFailedRequests The SDK will only capture HTTP Client errors if it is enabled, * Defaults to false. @@ -39,7 +39,7 @@ import java.io.IOException * is a match for any of the defined targets. */ public open class SentryOkHttpInterceptor( - private val hub: IHub = HubAdapter.getInstance(), + private val scopes: IScopes = ScopesAdapter.getInstance(), private val beforeSpan: BeforeSpanCallback? = null, private val captureFailedRequests: Boolean = true, private val failedRequestStatusCodes: List = listOf( @@ -48,9 +48,9 @@ public open class SentryOkHttpInterceptor( private val failedRequestTargets: List = listOf(DEFAULT_PROPAGATION_TARGETS) ) : Interceptor { - public constructor() : this(HubAdapter.getInstance()) - public constructor(hub: IHub) : this(hub, null) - public constructor(beforeSpan: BeforeSpanCallback) : this(HubAdapter.getInstance(), beforeSpan) + public constructor() : this(ScopesAdapter.getInstance()) + public constructor(scopes: IScopes) : this(scopes, null) + public constructor(beforeSpan: BeforeSpanCallback) : this(ScopesAdapter.getInstance(), beforeSpan) init { addIntegrationToSdkVersion(javaClass) @@ -76,7 +76,7 @@ public open class SentryOkHttpInterceptor( } else { // read the span from the bound scope okHttpEvent = null - val parentSpan = if (Platform.isAndroid()) hub.transaction else hub.span + val parentSpan = if (Platform.isAndroid()) scopes.transaction else scopes.span span = parentSpan?.startChild("http.client", "$method $url") } @@ -92,7 +92,7 @@ public open class SentryOkHttpInterceptor( val requestBuilder = request.newBuilder() TracingUtils.traceIfAllowed( - hub, + scopes, request.url.toString(), request.headers(BaggageHeader.BAGGAGE_HEADER), span @@ -121,7 +121,7 @@ public open class SentryOkHttpInterceptor( if (isFromEventListener && okHttpEvent != null) { okHttpEvent.setClientErrorResponse(response) } else { - SentryOkHttpUtils.captureClientError(hub, request, response) + SentryOkHttpUtils.captureClientError(scopes, request, response) } } @@ -157,7 +157,7 @@ public open class SentryOkHttpInterceptor( hint[OKHTTP_RESPONSE] = it } - hub.addBreadcrumb(breadcrumb, hint) + scopes.addBreadcrumb(breadcrumb, hint) } private fun finishSpan(span: ISpan?, request: Request, response: Response?, isFromEventListener: Boolean) { diff --git a/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpUtils.kt b/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpUtils.kt index 0cfc1c5a75..eea35ca22e 100644 --- a/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpUtils.kt +++ b/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpUtils.kt @@ -1,7 +1,7 @@ package io.sentry.okhttp import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryEvent import io.sentry.TypeCheckHint import io.sentry.exception.ExceptionMechanismException @@ -15,7 +15,7 @@ import okhttp3.Response internal object SentryOkHttpUtils { - internal fun captureClientError(hub: IHub, request: Request, response: Response) { + internal fun captureClientError(scopes: IScopes, request: Request, response: Response) { // not possible to get a parameterized url, but we remove at least the // query string and the fragment. // url example: https://api.github.com/users/getsentry/repos/#fragment?query=query @@ -40,9 +40,9 @@ internal object SentryOkHttpUtils { val sentryRequest = io.sentry.protocol.Request().apply { urlDetails.applyToRequest(this) // Cookie is only sent if isSendDefaultPii is enabled - cookies = if (hub.options.isSendDefaultPii) request.headers["Cookie"] else null + cookies = if (scopes.options.isSendDefaultPii) request.headers["Cookie"] else null method = request.method - headers = getHeaders(hub, request.headers) + headers = getHeaders(scopes, request.headers) request.body?.contentLength().ifHasValidLength { bodySize = it @@ -51,8 +51,8 @@ internal object SentryOkHttpUtils { val sentryResponse = io.sentry.protocol.Response().apply { // Set-Cookie is only sent if isSendDefaultPii is enabled due to PII - cookies = if (hub.options.isSendDefaultPii) response.headers["Set-Cookie"] else null - headers = getHeaders(hub, response.headers) + cookies = if (scopes.options.isSendDefaultPii) response.headers["Set-Cookie"] else null + headers = getHeaders(scopes, response.headers) statusCode = response.code response.body?.contentLength().ifHasValidLength { @@ -63,7 +63,7 @@ internal object SentryOkHttpUtils { event.request = sentryRequest event.contexts.setResponse(sentryResponse) - hub.captureEvent(event, hint) + scopes.captureEvent(event, hint) } private fun Long?.ifHasValidLength(fn: (Long) -> Unit) { @@ -72,9 +72,9 @@ internal object SentryOkHttpUtils { } } - private fun getHeaders(hub: IHub, requestHeaders: Headers): MutableMap? { + private fun getHeaders(scopes: IScopes, requestHeaders: Headers): MutableMap? { // Headers are only sent if isSendDefaultPii is enabled due to PII - if (!hub.options.isSendDefaultPii) { + if (!scopes.options.isSendDefaultPii) { return null } diff --git a/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpEventListenerTest.kt b/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpEventListenerTest.kt index 1d90da70fe..3a90a4c05c 100644 --- a/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpEventListenerTest.kt +++ b/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpEventListenerTest.kt @@ -1,7 +1,7 @@ package io.sentry.okhttp import io.sentry.BaggageHeader -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryOptions import io.sentry.SentryTraceHeader import io.sentry.SentryTracer @@ -36,7 +36,7 @@ import kotlin.test.assertTrue class SentryOkHttpEventListenerTest { class Fixture { - val hub = mock() + val scopes = mock() val server = MockWebServer() val mockEventListener = mock() val mockEventListenerFactory = mock() @@ -63,12 +63,12 @@ class SentryOkHttpEventListenerTest { isSendDefaultPii = sendDefaultPii configureOptions(this) } - whenever(hub.options).thenReturn(options) + whenever(scopes.options).thenReturn(options) - sentryTracer = SentryTracer(TransactionContext("name", "op"), hub) + sentryTracer = SentryTracer(TransactionContext("name", "op"), scopes) if (isSpanActive) { - whenever(hub.span).thenReturn(sentryTracer) + whenever(scopes.span).thenReturn(sentryTracer) } server.enqueue( MockResponse() @@ -80,12 +80,12 @@ class SentryOkHttpEventListenerTest { val builder = OkHttpClient.Builder() if (useInterceptor) { - builder.addInterceptor(SentryOkHttpInterceptor(hub)) + builder.addInterceptor(SentryOkHttpInterceptor(scopes)) } sentryOkHttpEventListener = when { - eventListenerFactory != null -> SentryOkHttpEventListener(hub, eventListenerFactory) - eventListener != null -> SentryOkHttpEventListener(hub, eventListener) - else -> SentryOkHttpEventListener(hub) + eventListenerFactory != null -> SentryOkHttpEventListener(scopes, eventListenerFactory) + eventListener != null -> SentryOkHttpEventListener(scopes, eventListener) + else -> SentryOkHttpEventListener(scopes) } return builder.eventListener(sentryOkHttpEventListener).build() } @@ -276,7 +276,7 @@ class SentryOkHttpEventListenerTest { @Test fun `propagate all calls to the SentryOkHttpEventListener passed in the ctor`() { - val originalListener = spy(SentryOkHttpEventListener(fixture.hub, fixture.mockEventListener)) + val originalListener = spy(SentryOkHttpEventListener(fixture.scopes, fixture.mockEventListener)) val sut = fixture.getSut(eventListener = originalListener) val listener = fixture.sentryOkHttpEventListener val request = postRequest(body = "requestBody") @@ -288,7 +288,7 @@ class SentryOkHttpEventListenerTest { @Test fun `propagate all calls to the SentryOkHttpEventListener factory passed in the ctor`() { - val originalListener = spy(SentryOkHttpEventListener(fixture.hub, fixture.mockEventListener)) + val originalListener = spy(SentryOkHttpEventListener(fixture.scopes, fixture.mockEventListener)) val sut = fixture.getSut(eventListenerFactory = { originalListener }) val listener = fixture.sentryOkHttpEventListener val request = postRequest(body = "requestBody") @@ -300,7 +300,7 @@ class SentryOkHttpEventListenerTest { @Test fun `does not duplicated spans if an SentryOkHttpEventListener is passed in the ctor`() { - val originalListener = spy(SentryOkHttpEventListener(fixture.hub, fixture.mockEventListener)) + val originalListener = spy(SentryOkHttpEventListener(fixture.scopes, fixture.mockEventListener)) val sut = fixture.getSut(eventListener = originalListener) val request = postRequest(body = "requestBody") val call = sut.newCall(request) @@ -363,8 +363,8 @@ class SentryOkHttpEventListenerTest { @Test fun `responseHeadersEnd schedules event finish`() { - val listener = SentryOkHttpEventListener(fixture.hub, fixture.mockEventListener) - whenever(fixture.hub.options).thenReturn(SentryOptions()) + val listener = SentryOkHttpEventListener(fixture.scopes, fixture.mockEventListener) + whenever(fixture.scopes.options).thenReturn(SentryOptions()) val call = mock() whenever(call.request()).thenReturn(getRequest()) val okHttpEvent = mock() diff --git a/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpEventTest.kt b/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpEventTest.kt index 337f722848..4d9f005143 100644 --- a/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpEventTest.kt +++ b/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpEventTest.kt @@ -2,7 +2,7 @@ package io.sentry.okhttp import io.sentry.Breadcrumb import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ISentryExecutorService import io.sentry.ISpan import io.sentry.SentryDate @@ -50,14 +50,14 @@ import kotlin.test.assertTrue class SentryOkHttpEventTest { private class Fixture { - val hub = mock() + val scopes = mock() val server = MockWebServer() val span: ISpan val mockRequest: Request val response: Response init { - whenever(hub.options).thenReturn( + whenever(scopes.options).thenReturn( SentryOptions().apply { dsn = "https://key@sentry.io/proj" } @@ -65,8 +65,8 @@ class SentryOkHttpEventTest { span = Span( TransactionContext("name", "op", TracesSamplingDecision(true)), - SentryTracer(TransactionContext("name", "op", TracesSamplingDecision(true)), hub), - hub, + SentryTracer(TransactionContext("name", "op", TracesSamplingDecision(true)), scopes), + scopes, null, SpanOptions() ) @@ -86,7 +86,7 @@ class SentryOkHttpEventTest { } fun getSut(currentSpan: ISpan? = span, requestUrl: String ? = null): SentryOkHttpEvent { - whenever(hub.span).thenReturn(currentSpan) + whenever(scopes.span).thenReturn(currentSpan) val request = if (requestUrl == null) { mockRequest } else { @@ -96,7 +96,7 @@ class SentryOkHttpEventTest { .url(server.url(requestUrl)) .build() } - return SentryOkHttpEvent(hub, request) + return SentryOkHttpEvent(scopes, request) } } @@ -126,7 +126,7 @@ class SentryOkHttpEventTest { val sut = fixture.getSut(currentSpan = null) assertNull(sut.callRootSpan) sut.finishEvent() - verify(fixture.hub).addBreadcrumb(any(), anyOrNull()) + verify(fixture.scopes).addBreadcrumb(any(), anyOrNull()) } @Test @@ -240,7 +240,7 @@ class SentryOkHttpEventTest { fun `when finishEvent, a breadcrumb is captured with request in the hint`() { val sut = fixture.getSut() sut.finishEvent() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals(fixture.mockRequest.url.toString(), it.data["url"]) assertEquals(fixture.mockRequest.url.host, it.data["host"]) @@ -258,7 +258,7 @@ class SentryOkHttpEventTest { val sut = fixture.getSut() sut.finishEvent() sut.finishEvent() - verify(fixture.hub, times(1)).addBreadcrumb(any(), any()) + verify(fixture.scopes, times(1)).addBreadcrumb(any(), any()) } @Test @@ -283,7 +283,7 @@ class SentryOkHttpEventTest { assertEquals(fixture.response.code, sut.callRootSpan?.getData(SpanDataConvention.HTTP_STATUS_CODE_KEY)) sut.finishEvent() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals(fixture.response.protocol.name, it.data["protocol"]) assertEquals(fixture.response.code, it.data["status_code"]) @@ -300,7 +300,7 @@ class SentryOkHttpEventTest { sut.setProtocol("protocol") assertEquals("protocol", sut.callRootSpan?.getData("protocol")) sut.finishEvent() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("protocol", it.data["protocol"]) }, @@ -314,7 +314,7 @@ class SentryOkHttpEventTest { sut.setProtocol(null) assertNull(sut.callRootSpan?.getData("protocol")) sut.finishEvent() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertNull(it.data["protocol"]) }, @@ -328,7 +328,7 @@ class SentryOkHttpEventTest { sut.setRequestBodySize(10) assertEquals(10L, sut.callRootSpan?.getData("http.request_content_length")) sut.finishEvent() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals(10L, it.data["request_content_length"]) }, @@ -342,7 +342,7 @@ class SentryOkHttpEventTest { sut.setRequestBodySize(-1) assertNull(sut.callRootSpan?.getData("http.request_content_length")) sut.finishEvent() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertNull(it.data["request_content_length"]) }, @@ -356,7 +356,7 @@ class SentryOkHttpEventTest { sut.setResponseBodySize(10) assertEquals(10L, sut.callRootSpan?.getData(SpanDataConvention.HTTP_RESPONSE_CONTENT_LENGTH_KEY)) sut.finishEvent() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals(10L, it.data["response_content_length"]) }, @@ -370,7 +370,7 @@ class SentryOkHttpEventTest { sut.setResponseBodySize(-1) assertNull(sut.callRootSpan?.getData(SpanDataConvention.HTTP_RESPONSE_CONTENT_LENGTH_KEY)) sut.finishEvent() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertNull(it.data["response_content_length"]) }, @@ -384,7 +384,7 @@ class SentryOkHttpEventTest { sut.setError("errorMessage") assertEquals("errorMessage", sut.callRootSpan?.getData("error_message")) sut.finishEvent() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("errorMessage", it.data["error_message"]) }, @@ -399,7 +399,7 @@ class SentryOkHttpEventTest { assertNotNull(sut.callRootSpan) assertNull(sut.callRootSpan.getData("error_message")) sut.finishEvent() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertNull(it.data["error_message"]) }, @@ -532,7 +532,7 @@ class SentryOkHttpEventTest { @Test fun `scheduleFinish schedules finishEvent and finish running spans to specific timestamp`() { - fixture.hub.options.executorService = ImmediateExecutorService() + fixture.scopes.options.executorService = ImmediateExecutorService() val sut = spy(fixture.getSut()) val timestamp = mock() sut.startSpan(CONNECTION_EVENT) @@ -554,7 +554,7 @@ class SentryOkHttpEventTest { fun `scheduleFinish does not throw if executor is shut down`() { val executorService = mock() whenever(executorService.schedule(any(), any())).thenThrow(RejectedExecutionException()) - whenever(fixture.hub.options).thenReturn(SentryOptions().apply { this.executorService = executorService }) + whenever(fixture.scopes.options).thenReturn(SentryOptions().apply { this.executorService = executorService }) val sut = fixture.getSut() sut.scheduleFinish(mock()) } @@ -565,10 +565,10 @@ class SentryOkHttpEventTest { val clientErrorResponse = mock() whenever(clientErrorResponse.request).thenReturn(fixture.mockRequest) sut.setClientErrorResponse(clientErrorResponse) - verify(fixture.hub, never()).captureEvent(any(), any()) + verify(fixture.scopes, never()).captureEvent(any(), any()) sut.finishEvent() assertNotNull(sut.callRootSpan) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( argThat { throwable is SentryHttpClientException && throwable!!.message!!.startsWith("HTTP Client Error with status code: ") @@ -586,10 +586,10 @@ class SentryOkHttpEventTest { val clientErrorResponse = mock() whenever(clientErrorResponse.request).thenReturn(fixture.mockRequest) sut.setClientErrorResponse(clientErrorResponse) - verify(fixture.hub, never()).captureEvent(any(), any()) + verify(fixture.scopes, never()).captureEvent(any(), any()) sut.finishEvent() assertNull(sut.callRootSpan) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( argThat { throwable is SentryHttpClientException && throwable!!.message!!.startsWith("HTTP Client Error with status code: ") @@ -605,7 +605,7 @@ class SentryOkHttpEventTest { fun `when setClientErrorResponse is not called, no client error is captured`() { val sut = fixture.getSut() sut.finishEvent() - verify(fixture.hub, never()).captureEvent(any(), any()) + verify(fixture.scopes, never()).captureEvent(any(), any()) } /** Retrieve all the spans started in the event using reflection. */ diff --git a/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpInterceptorTest.kt b/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpInterceptorTest.kt index fce16d9220..f40b2c4cb5 100644 --- a/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpInterceptorTest.kt +++ b/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpInterceptorTest.kt @@ -6,8 +6,8 @@ import io.sentry.BaggageHeader import io.sentry.Breadcrumb import io.sentry.Hint import io.sentry.HttpStatusCodeRange -import io.sentry.IHub import io.sentry.IScope +import io.sentry.IScopes import io.sentry.Scope import io.sentry.ScopeCallback import io.sentry.SentryOptions @@ -47,7 +47,7 @@ import kotlin.test.fail class SentryOkHttpInterceptorTest { class Fixture { - val hub = mock() + val scopes = mock() val server = MockWebServer() lateinit var sentryTracer: SentryTracer lateinit var options: SentryOptions @@ -82,13 +82,13 @@ class SentryOkHttpInterceptorTest { isSendDefaultPii = sendDefaultPii } scope = Scope(options) - whenever(hub.options).thenReturn(options) - doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(hub).configureScope(any()) + whenever(scopes.options).thenReturn(options) + doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(scopes).configureScope(any()) - sentryTracer = SentryTracer(TransactionContext("name", "op"), hub) + sentryTracer = SentryTracer(TransactionContext("name", "op"), scopes) if (isSpanActive) { - whenever(hub.span).thenReturn(sentryTracer) + whenever(scopes.span).thenReturn(sentryTracer) } server.enqueue( MockResponse() @@ -100,14 +100,14 @@ class SentryOkHttpInterceptorTest { val interceptor = when (captureFailedRequests) { null -> SentryOkHttpInterceptor( - hub, + scopes, beforeSpan, failedRequestTargets = failedRequestTargets, failedRequestStatusCodes = failedRequestStatusCodes ) else -> SentryOkHttpInterceptor( - hub, + scopes, beforeSpan, captureFailedRequests = captureFailedRequests, failedRequestTargets = failedRequestTargets, @@ -281,7 +281,7 @@ class SentryOkHttpInterceptorTest { fun `adds breadcrumb when http calls succeeds`() { val sut = fixture.getSut(responseBody = "response body") sut.newCall(postRequest()).execute() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(13L, it.data[SpanDataConvention.HTTP_RESPONSE_CONTENT_LENGTH_KEY]) @@ -296,7 +296,7 @@ class SentryOkHttpInterceptorTest { fun `adds breadcrumb when http calls results in exception`() { // to setup mocks fixture.getSut() - val interceptor = SentryOkHttpInterceptor(fixture.hub) + val interceptor = SentryOkHttpInterceptor(fixture.scopes) val chain = mock() whenever(chain.call()).thenReturn(mock()) whenever(chain.proceed(any())).thenThrow(IOException()) @@ -308,7 +308,7 @@ class SentryOkHttpInterceptorTest { } catch (e: IOException) { // ignore me } - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) }, @@ -385,7 +385,7 @@ class SentryOkHttpInterceptorTest { ) sut.newCall(getRequest()).execute() - verify(fixture.hub).captureEvent(any(), any()) + verify(fixture.scopes).captureEvent(any(), any()) } @Test @@ -396,7 +396,7 @@ class SentryOkHttpInterceptorTest { ) sut.newCall(getRequest()).execute() - verify(fixture.hub).captureEvent(any(), any()) + verify(fixture.scopes).captureEvent(any(), any()) } @Test @@ -406,7 +406,7 @@ class SentryOkHttpInterceptorTest { ) sut.newCall(getRequest()).execute() - verify(fixture.hub, never()).captureEvent(any(), any()) + verify(fixture.scopes, never()).captureEvent(any(), any()) } @Test @@ -417,7 +417,7 @@ class SentryOkHttpInterceptorTest { ) sut.newCall(getRequest()).execute() - verify(fixture.hub, never()).captureEvent(any(), any()) + verify(fixture.scopes, never()).captureEvent(any(), any()) } @Test @@ -429,7 +429,7 @@ class SentryOkHttpInterceptorTest { ) sut.newCall(getRequest()).execute() - verify(fixture.hub, never()).captureEvent(any(), any()) + verify(fixture.scopes, never()).captureEvent(any(), any()) } @Test @@ -440,7 +440,7 @@ class SentryOkHttpInterceptorTest { ) sut.newCall(getRequest()).execute() - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( any(), check { assertNotNull(it.get(TypeCheckHint.OKHTTP_REQUEST)) @@ -462,7 +462,7 @@ class SentryOkHttpInterceptorTest { val request = getRequest(url = "/hello?myQuery=myValue#myFragment") val response = sut.newCall(request).execute() - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { val sentryRequest = it.request!! assertEquals("http://localhost:${fixture.server.port}/hello", sentryRequest.url) @@ -503,7 +503,7 @@ class SentryOkHttpInterceptorTest { sut.newCall(postRequest(body = body)).execute() - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { val sentryRequest = it.request!! assertEquals(body.contentLength(), sentryRequest.bodySize) @@ -522,7 +522,7 @@ class SentryOkHttpInterceptorTest { sut.newCall(getRequest()).execute() - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( check { val sentryRequest = it.request!! assertEquals("myValue", sentryRequest.headers!!["myHeader"]) @@ -540,7 +540,7 @@ class SentryOkHttpInterceptorTest { // to setup mocks fixture.getSut() val interceptor = SentryOkHttpInterceptor( - fixture.hub, + fixture.scopes, captureFailedRequests = true ) val chain = mock() @@ -554,7 +554,7 @@ class SentryOkHttpInterceptorTest { } catch (e: IOException) { // ignore me } - verify(fixture.hub, never()).captureEvent(any(), any()) + verify(fixture.scopes, never()).captureEvent(any(), any()) } @Test @@ -565,7 +565,7 @@ class SentryOkHttpInterceptorTest { call.execute() val httpClientSpan = fixture.sentryTracer.children.firstOrNull() assertNull(httpClientSpan) - verify(fixture.hub, never()).addBreadcrumb(any(), anyOrNull()) + verify(fixture.scopes, never()).addBreadcrumb(any(), anyOrNull()) } @Test @@ -573,7 +573,7 @@ class SentryOkHttpInterceptorTest { val sut = fixture.getSut(captureFailedRequests = true, httpStatusCode = 500) val call = sut.newCall(getRequest()) call.execute() - verify(fixture.hub).captureEvent(any(), any()) + verify(fixture.scopes).captureEvent(any(), any()) } @Test @@ -582,6 +582,6 @@ class SentryOkHttpInterceptorTest { val call = sut.newCall(getRequest()) SentryOkHttpEventListener.eventMap[call] = mock() call.execute() - verify(fixture.hub, never()).captureEvent(any(), any()) + verify(fixture.scopes, never()).captureEvent(any(), any()) } } diff --git a/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpUtilsTest.kt b/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpUtilsTest.kt index ec19454327..c7194e5994 100644 --- a/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpUtilsTest.kt +++ b/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpUtilsTest.kt @@ -1,7 +1,7 @@ package io.sentry.okhttp import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryOptions import io.sentry.SentryTracer import io.sentry.TransactionContext @@ -29,7 +29,7 @@ import kotlin.test.assertTrue class SentryOkHttpUtilsTest { class Fixture { - val hub = mock() + val scopes = mock() val server = MockWebServer() fun getSut( @@ -43,11 +43,11 @@ class SentryOkHttpUtilsTest { setTracePropagationTargets(listOf(server.hostName)) isSendDefaultPii = sendDefaultPii } - whenever(hub.options).thenReturn(options) + whenever(scopes.options).thenReturn(options) - val sentryTracer = SentryTracer(TransactionContext("name", "op"), hub) + val sentryTracer = SentryTracer(TransactionContext("name", "op"), scopes) - whenever(hub.span).thenReturn(sentryTracer) + whenever(scopes.span).thenReturn(sentryTracer) server.enqueue( MockResponse() @@ -78,8 +78,8 @@ class SentryOkHttpUtilsTest { val request = getRequest() val response = sut.newCall(request).execute() - SentryOkHttpUtils.captureClientError(fixture.hub, request, response) - verify(fixture.hub).captureEvent( + SentryOkHttpUtils.captureClientError(fixture.scopes, request, response) + verify(fixture.scopes).captureEvent( check { val req = it.request val resp = it.contexts.response @@ -103,8 +103,8 @@ class SentryOkHttpUtilsTest { val request = getRequest() val response = sut.newCall(request).execute() - SentryOkHttpUtils.captureClientError(fixture.hub, request, response) - verify(fixture.hub).captureEvent( + SentryOkHttpUtils.captureClientError(fixture.scopes, request, response) + verify(fixture.scopes).captureEvent( check { val req = it.request val resp = it.contexts.response @@ -127,8 +127,8 @@ class SentryOkHttpUtilsTest { val request = getRequest() val response = sut.newCall(request).execute() - SentryOkHttpUtils.captureClientError(fixture.hub, request, response) - verify(fixture.hub).captureEvent( + SentryOkHttpUtils.captureClientError(fixture.scopes, request, response) + verify(fixture.scopes).captureEvent( check { val req = it.request val resp = it.contexts.response From 82792768eaff84e41c66b238e654d482cdd071bb Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Tue, 2 Apr 2024 14:33:01 +0200 Subject: [PATCH 09/28] Replace `IHub` with `IScopes` in graphql integration --- sentry-graphql/api/sentry-graphql.api | 20 +++++---- .../io/sentry/graphql/ExceptionReporter.java | 43 +++++++++++-------- .../graphql/NoOpSubscriptionHandler.java | 4 +- .../SentryDataFetcherExceptionHandler.java | 14 +++--- ...tryGenericDataFetcherExceptionHandler.java | 4 +- .../sentry/graphql/SentryInstrumentation.java | 38 ++++++++-------- .../graphql/SentrySubscriptionHandler.java | 4 +- .../sentry/graphql/ExceptionReporterTest.kt | 32 +++++++------- .../SentryDataFetcherExceptionHandlerTest.kt | 8 ++-- ...yGenericDataFetcherExceptionHandlerTest.kt | 6 +-- .../SentryInstrumentationAnotherTest.kt | 40 +++++++++-------- .../graphql/SentryInstrumentationTest.kt | 36 ++++++++-------- 12 files changed, 132 insertions(+), 117 deletions(-) diff --git a/sentry-graphql/api/sentry-graphql.api b/sentry-graphql/api/sentry-graphql.api index 57c253e23c..d119256010 100644 --- a/sentry-graphql/api/sentry-graphql.api +++ b/sentry-graphql/api/sentry-graphql.api @@ -9,10 +9,11 @@ public final class io/sentry/graphql/ExceptionReporter { } public final class io/sentry/graphql/ExceptionReporter$ExceptionDetails { - public fun (Lio/sentry/IHub;Lgraphql/execution/instrumentation/parameters/InstrumentationExecutionParameters;Z)V - public fun (Lio/sentry/IHub;Lgraphql/schema/DataFetchingEnvironment;Z)V - public fun getHub ()Lio/sentry/IHub; + public fun (Lio/sentry/IScopes;Lgraphql/execution/instrumentation/parameters/InstrumentationExecutionParameters;Z)V + public fun (Lio/sentry/IScopes;Lgraphql/schema/DataFetchingEnvironment;Z)V + public fun getHub ()Lio/sentry/IScopes; public fun getQuery ()Ljava/lang/String; + public fun getScopes ()Lio/sentry/IScopes; public fun getVariables ()Ljava/util/Map; public fun isSubscription ()Z } @@ -26,19 +27,19 @@ public final class io/sentry/graphql/GraphqlStringUtils { public final class io/sentry/graphql/NoOpSubscriptionHandler : io/sentry/graphql/SentrySubscriptionHandler { public static fun getInstance ()Lio/sentry/graphql/NoOpSubscriptionHandler; - public fun onSubscriptionResult (Ljava/lang/Object;Lio/sentry/IHub;Lio/sentry/graphql/ExceptionReporter;Lgraphql/execution/instrumentation/parameters/InstrumentationFieldFetchParameters;)Ljava/lang/Object; + public fun onSubscriptionResult (Ljava/lang/Object;Lio/sentry/IScopes;Lio/sentry/graphql/ExceptionReporter;Lgraphql/execution/instrumentation/parameters/InstrumentationFieldFetchParameters;)Ljava/lang/Object; } public final class io/sentry/graphql/SentryDataFetcherExceptionHandler : graphql/execution/DataFetcherExceptionHandler { public fun (Lgraphql/execution/DataFetcherExceptionHandler;)V - public fun (Lio/sentry/IHub;Lgraphql/execution/DataFetcherExceptionHandler;)V + public fun (Lio/sentry/IScopes;Lgraphql/execution/DataFetcherExceptionHandler;)V public fun handleException (Lgraphql/execution/DataFetcherExceptionHandlerParameters;)Ljava/util/concurrent/CompletableFuture; public fun onException (Lgraphql/execution/DataFetcherExceptionHandlerParameters;)Lgraphql/execution/DataFetcherExceptionHandlerResult; } public final class io/sentry/graphql/SentryGenericDataFetcherExceptionHandler : graphql/execution/DataFetcherExceptionHandler { public fun (Lgraphql/execution/DataFetcherExceptionHandler;)V - public fun (Lio/sentry/IHub;Lgraphql/execution/DataFetcherExceptionHandler;)V + public fun (Lio/sentry/IScopes;Lgraphql/execution/DataFetcherExceptionHandler;)V public fun handleException (Lgraphql/execution/DataFetcherExceptionHandlerParameters;)Ljava/util/concurrent/CompletableFuture; public fun onException (Lgraphql/execution/DataFetcherExceptionHandlerParameters;)Lgraphql/execution/DataFetcherExceptionHandlerResult; } @@ -51,9 +52,10 @@ public final class io/sentry/graphql/SentryGraphqlExceptionHandler { public final class io/sentry/graphql/SentryInstrumentation : graphql/execution/instrumentation/SimpleInstrumentation { public static final field SENTRY_EXCEPTIONS_CONTEXT_KEY Ljava/lang/String; public static final field SENTRY_HUB_CONTEXT_KEY Ljava/lang/String; + public static final field SENTRY_SCOPES_CONTEXT_KEY Ljava/lang/String; public fun ()V - public fun (Lio/sentry/IHub;)V - public fun (Lio/sentry/IHub;Lio/sentry/graphql/SentryInstrumentation$BeforeSpanCallback;)V + public fun (Lio/sentry/IScopes;)V + public fun (Lio/sentry/IScopes;Lio/sentry/graphql/SentryInstrumentation$BeforeSpanCallback;)V public fun (Lio/sentry/graphql/SentryInstrumentation$BeforeSpanCallback;)V public fun (Lio/sentry/graphql/SentryInstrumentation$BeforeSpanCallback;Lio/sentry/graphql/SentrySubscriptionHandler;Lio/sentry/graphql/ExceptionReporter;Ljava/util/List;)V public fun (Lio/sentry/graphql/SentryInstrumentation$BeforeSpanCallback;Lio/sentry/graphql/SentrySubscriptionHandler;Z)V @@ -71,6 +73,6 @@ public abstract interface class io/sentry/graphql/SentryInstrumentation$BeforeSp } public abstract interface class io/sentry/graphql/SentrySubscriptionHandler { - public abstract fun onSubscriptionResult (Ljava/lang/Object;Lio/sentry/IHub;Lio/sentry/graphql/ExceptionReporter;Lgraphql/execution/instrumentation/parameters/InstrumentationFieldFetchParameters;)Ljava/lang/Object; + public abstract fun onSubscriptionResult (Ljava/lang/Object;Lio/sentry/IScopes;Lio/sentry/graphql/ExceptionReporter;Lgraphql/execution/instrumentation/parameters/InstrumentationFieldFetchParameters;)Ljava/lang/Object; } diff --git a/sentry-graphql/src/main/java/io/sentry/graphql/ExceptionReporter.java b/sentry-graphql/src/main/java/io/sentry/graphql/ExceptionReporter.java index 30ccb21425..843ca77494 100644 --- a/sentry-graphql/src/main/java/io/sentry/graphql/ExceptionReporter.java +++ b/sentry-graphql/src/main/java/io/sentry/graphql/ExceptionReporter.java @@ -5,7 +5,7 @@ import graphql.language.AstPrinter; import graphql.schema.DataFetchingEnvironment; import io.sentry.Hint; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.SentryEvent; import io.sentry.SentryLevel; import io.sentry.SentryOptions; @@ -33,7 +33,7 @@ public void captureThrowable( final @NotNull Throwable throwable, final @NotNull ExceptionDetails exceptionDetails, final @Nullable ExecutionResult result) { - final @NotNull IHub hub = exceptionDetails.getHub(); + final @NotNull IScopes scopes = exceptionDetails.getScopes(); final @NotNull Mechanism mechanism = new Mechanism(); mechanism.setType(MECHANISM_TYPE); mechanism.setHandled(false); @@ -43,44 +43,44 @@ public void captureThrowable( event.setLevel(SentryLevel.FATAL); final @NotNull Hint hint = new Hint(); - setRequestDetailsOnEvent(hub, exceptionDetails, event); + setRequestDetailsOnEvent(scopes, exceptionDetails, event); - if (result != null && isAllowedToAttachBody(hub)) { + if (result != null && isAllowedToAttachBody(scopes)) { final @NotNull Response response = new Response(); final @NotNull Map responseBody = result.toSpecification(); response.setData(responseBody); event.getContexts().setResponse(response); } - hub.captureEvent(event, hint); + scopes.captureEvent(event, hint); } - private boolean isAllowedToAttachBody(final @NotNull IHub hub) { - final @NotNull SentryOptions options = hub.getOptions(); + private boolean isAllowedToAttachBody(final @NotNull IScopes scopes) { + final @NotNull SentryOptions options = scopes.getOptions(); return options.isSendDefaultPii() && !SentryOptions.RequestSize.NONE.equals(options.getMaxRequestBodySize()); } private void setRequestDetailsOnEvent( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull ExceptionDetails exceptionDetails, final @NotNull SentryEvent event) { - hub.configureScope( + scopes.configureScope( (scope) -> { final @Nullable Request scopeRequest = scope.getRequest(); final @NotNull Request request = scopeRequest == null ? new Request() : scopeRequest; - setDetailsOnRequest(hub, exceptionDetails, request); + setDetailsOnRequest(scopes, exceptionDetails, request); event.setRequest(request); }); } private void setDetailsOnRequest( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull ExceptionDetails exceptionDetails, final @NotNull Request request) { request.setApiTarget("graphql"); - if (isAllowedToAttachBody(hub) + if (isAllowedToAttachBody(scopes) && (exceptionDetails.isSubscription() || captureRequestBodyForNonSubscriptions)) { final @NotNull Map data = new HashMap<>(); @@ -99,27 +99,27 @@ private void setDetailsOnRequest( public static final class ExceptionDetails { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @Nullable InstrumentationExecutionParameters instrumentationExecutionParameters; private final @Nullable DataFetchingEnvironment dataFetchingEnvironment; private final boolean isSubscription; public ExceptionDetails( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @Nullable InstrumentationExecutionParameters instrumentationExecutionParameters, final boolean isSubscription) { - this.hub = hub; + this.scopes = scopes; this.instrumentationExecutionParameters = instrumentationExecutionParameters; dataFetchingEnvironment = null; this.isSubscription = isSubscription; } public ExceptionDetails( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @Nullable DataFetchingEnvironment dataFetchingEnvironment, final boolean isSubscription) { - this.hub = hub; + this.scopes = scopes; this.dataFetchingEnvironment = dataFetchingEnvironment; instrumentationExecutionParameters = null; this.isSubscription = isSubscription; @@ -149,8 +149,13 @@ public boolean isSubscription() { return isSubscription; } - public @NotNull IHub getHub() { - return hub; + @Deprecated + public @NotNull IScopes getHub() { + return scopes; + } + + public @NotNull IScopes getScopes() { + return scopes; } } } diff --git a/sentry-graphql/src/main/java/io/sentry/graphql/NoOpSubscriptionHandler.java b/sentry-graphql/src/main/java/io/sentry/graphql/NoOpSubscriptionHandler.java index df241ce35b..839f413719 100644 --- a/sentry-graphql/src/main/java/io/sentry/graphql/NoOpSubscriptionHandler.java +++ b/sentry-graphql/src/main/java/io/sentry/graphql/NoOpSubscriptionHandler.java @@ -1,7 +1,7 @@ package io.sentry.graphql; import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; -import io.sentry.IHub; +import io.sentry.IScopes; import org.jetbrains.annotations.NotNull; public final class NoOpSubscriptionHandler implements SentrySubscriptionHandler { @@ -17,7 +17,7 @@ private NoOpSubscriptionHandler() {} @Override public @NotNull Object onSubscriptionResult( @NotNull Object result, - @NotNull IHub hub, + @NotNull IScopes scopes, @NotNull ExceptionReporter exceptionReporter, @NotNull InstrumentationFieldFetchParameters parameters) { return result; diff --git a/sentry-graphql/src/main/java/io/sentry/graphql/SentryDataFetcherExceptionHandler.java b/sentry-graphql/src/main/java/io/sentry/graphql/SentryDataFetcherExceptionHandler.java index c0467c0089..0813aab851 100644 --- a/sentry-graphql/src/main/java/io/sentry/graphql/SentryDataFetcherExceptionHandler.java +++ b/sentry-graphql/src/main/java/io/sentry/graphql/SentryDataFetcherExceptionHandler.java @@ -6,8 +6,8 @@ import graphql.execution.DataFetcherExceptionHandlerParameters; import graphql.execution.DataFetcherExceptionHandlerResult; import io.sentry.Hint; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; +import io.sentry.ScopesAdapter; import io.sentry.SentryIntegrationPackageStorage; import io.sentry.util.Objects; import java.util.concurrent.CompletableFuture; @@ -24,18 +24,18 @@ */ @Deprecated public final class SentryDataFetcherExceptionHandler implements DataFetcherExceptionHandler { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @NotNull DataFetcherExceptionHandler delegate; public SentryDataFetcherExceptionHandler( - final @NotNull IHub hub, final @NotNull DataFetcherExceptionHandler delegate) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + final @NotNull IScopes scopes, final @NotNull DataFetcherExceptionHandler delegate) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); this.delegate = Objects.requireNonNull(delegate, "delegate is required"); SentryIntegrationPackageStorage.getInstance().addIntegration("GrahQLLegacyExceptionHandler"); } public SentryDataFetcherExceptionHandler(final @NotNull DataFetcherExceptionHandler delegate) { - this(HubAdapter.getInstance(), delegate); + this(ScopesAdapter.getInstance(), delegate); } @Override @@ -44,7 +44,7 @@ public CompletableFuture handleException( final Hint hint = new Hint(); hint.set(GRAPHQL_HANDLER_PARAMETERS, handlerParameters); - hub.captureException(handlerParameters.getException(), hint); + scopes.captureException(handlerParameters.getException(), hint); return delegate.handleException(handlerParameters); } diff --git a/sentry-graphql/src/main/java/io/sentry/graphql/SentryGenericDataFetcherExceptionHandler.java b/sentry-graphql/src/main/java/io/sentry/graphql/SentryGenericDataFetcherExceptionHandler.java index 6251d00779..1287d38caa 100644 --- a/sentry-graphql/src/main/java/io/sentry/graphql/SentryGenericDataFetcherExceptionHandler.java +++ b/sentry-graphql/src/main/java/io/sentry/graphql/SentryGenericDataFetcherExceptionHandler.java @@ -3,7 +3,7 @@ import graphql.execution.DataFetcherExceptionHandler; import graphql.execution.DataFetcherExceptionHandlerParameters; import graphql.execution.DataFetcherExceptionHandlerResult; -import io.sentry.IHub; +import io.sentry.IScopes; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import org.jetbrains.annotations.NotNull; @@ -17,7 +17,7 @@ public final class SentryGenericDataFetcherExceptionHandler implements DataFetch private final @NotNull SentryGraphqlExceptionHandler handler; public SentryGenericDataFetcherExceptionHandler( - final @Nullable IHub hub, final @NotNull DataFetcherExceptionHandler delegate) { + final @Nullable IScopes scopes, final @NotNull DataFetcherExceptionHandler delegate) { this.handler = new SentryGraphqlExceptionHandler(delegate); } diff --git a/sentry-graphql/src/main/java/io/sentry/graphql/SentryInstrumentation.java b/sentry-graphql/src/main/java/io/sentry/graphql/SentryInstrumentation.java index d2d62c99d8..e4f85d12a2 100644 --- a/sentry-graphql/src/main/java/io/sentry/graphql/SentryInstrumentation.java +++ b/sentry-graphql/src/main/java/io/sentry/graphql/SentryInstrumentation.java @@ -18,9 +18,9 @@ import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLOutputType; import io.sentry.Breadcrumb; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ISpan; -import io.sentry.NoOpHub; +import io.sentry.NoOpScopes; import io.sentry.Sentry; import io.sentry.SentryIntegrationPackageStorage; import io.sentry.SpanStatus; @@ -46,7 +46,11 @@ public final class SentryInstrumentation "INTERNAL", // Netflix DGS "DataFetchingException" // raw graphql-java ); - public static final @NotNull String SENTRY_HUB_CONTEXT_KEY = "sentry.hub"; + public static final @NotNull String SENTRY_SCOPES_CONTEXT_KEY = "sentry.scopes"; + + @Deprecated + public static final @NotNull String SENTRY_HUB_CONTEXT_KEY = SENTRY_SCOPES_CONTEXT_KEY; + public static final @NotNull String SENTRY_EXCEPTIONS_CONTEXT_KEY = "sentry.exceptions"; private static final String TRACE_ORIGIN = "auto.graphql.graphql"; private final @Nullable BeforeSpanCallback beforeSpan; @@ -70,7 +74,7 @@ public SentryInstrumentation() { */ @Deprecated @SuppressWarnings("InlineMeSuggester") - public SentryInstrumentation(final @Nullable IHub hub) { + public SentryInstrumentation(final @Nullable IScopes scopes) { this(null, NoOpSubscriptionHandler.getInstance(), true); } @@ -89,7 +93,7 @@ public SentryInstrumentation(final @Nullable BeforeSpanCallback beforeSpan) { @Deprecated @SuppressWarnings("InlineMeSuggester") public SentryInstrumentation( - final @Nullable IHub hub, final @Nullable BeforeSpanCallback beforeSpan) { + final @Nullable IScopes scopes, final @Nullable BeforeSpanCallback beforeSpan) { this(beforeSpan, NoOpSubscriptionHandler.getInstance(), true); } @@ -172,9 +176,9 @@ public SentryInstrumentation( public @NotNull InstrumentationContext beginExecution( final @NotNull InstrumentationExecutionParameters parameters) { final TracingState tracingState = parameters.getInstrumentationState(); - final @NotNull IHub currentHub = Sentry.getCurrentHub(); - tracingState.setTransaction(currentHub.getSpan()); - parameters.getGraphQLContext().put(SENTRY_HUB_CONTEXT_KEY, currentHub); + final @NotNull IScopes currentScopes = Sentry.getCurrentScopes(); + tracingState.setTransaction(currentScopes.getSpan()); + parameters.getGraphQLContext().put(SENTRY_SCOPES_CONTEXT_KEY, currentScopes); return super.beginExecution(parameters); } @@ -195,7 +199,7 @@ public CompletableFuture instrumentExecutionResult( exceptionReporter.captureThrowable( throwable, new ExceptionReporter.ExceptionDetails( - hubFromContext(graphQLContext), parameters, false), + scopesFromContext(graphQLContext), parameters, false), result); } } @@ -207,7 +211,7 @@ public CompletableFuture instrumentExecutionResult( exceptionReporter.captureThrowable( new RuntimeException(error.getMessage()), new ExceptionReporter.ExceptionDetails( - hubFromContext(graphQLContext), parameters, false), + scopesFromContext(graphQLContext), parameters, false), result); } } @@ -217,7 +221,7 @@ public CompletableFuture instrumentExecutionResult( exceptionReporter.captureThrowable( exception, new ExceptionReporter.ExceptionDetails( - hubFromContext(parameters.getGraphQLContext()), parameters, false), + scopesFromContext(parameters.getGraphQLContext()), parameters, false), null); } }); @@ -262,7 +266,7 @@ private boolean isIgnored(final @Nullable String errorType) { operationDefinition.getOperation(); final @Nullable String operationType = operation == null ? null : operation.name().toLowerCase(Locale.ROOT); - hubFromContext(parameters.getExecutionContext().getGraphQLContext()) + scopesFromContext(parameters.getExecutionContext().getGraphQLContext()) .addBreadcrumb( Breadcrumb.graphqlOperation( operationDefinition.getName(), @@ -273,11 +277,11 @@ private boolean isIgnored(final @Nullable String errorType) { return super.beginExecuteOperation(parameters); } - private @NotNull IHub hubFromContext(final @Nullable GraphQLContext context) { + private @NotNull IScopes scopesFromContext(final @Nullable GraphQLContext context) { if (context == null) { - return NoOpHub.getInstance(); + return NoOpScopes.getInstance(); } - return context.getOrDefault(SENTRY_HUB_CONTEXT_KEY, NoOpHub.getInstance()); + return context.getOrDefault(SENTRY_SCOPES_CONTEXT_KEY, NoOpScopes.getInstance()); } @Override @@ -293,7 +297,7 @@ private boolean isIgnored(final @Nullable String errorType) { return environment -> { final @Nullable ExecutionStepInfo executionStepInfo = environment.getExecutionStepInfo(); if (executionStepInfo != null) { - hubFromContext(parameters.getExecutionContext().getGraphQLContext()) + scopesFromContext(parameters.getExecutionContext().getGraphQLContext()) .addBreadcrumb( Breadcrumb.graphqlDataFetcher( StringUtils.toString(executionStepInfo.getPath()), @@ -351,7 +355,7 @@ private boolean isIgnored(final @Nullable String errorType) { environment.getOperationDefinition().getOperation())) { return subscriptionHandler.onSubscriptionResult( tmpResult, - hubFromContext(environment.getGraphQlContext()), + scopesFromContext(environment.getGraphQlContext()), exceptionReporter, parameters); } diff --git a/sentry-graphql/src/main/java/io/sentry/graphql/SentrySubscriptionHandler.java b/sentry-graphql/src/main/java/io/sentry/graphql/SentrySubscriptionHandler.java index bfc962b501..0a5538ce22 100644 --- a/sentry-graphql/src/main/java/io/sentry/graphql/SentrySubscriptionHandler.java +++ b/sentry-graphql/src/main/java/io/sentry/graphql/SentrySubscriptionHandler.java @@ -1,14 +1,14 @@ package io.sentry.graphql; import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; -import io.sentry.IHub; +import io.sentry.IScopes; import org.jetbrains.annotations.NotNull; public interface SentrySubscriptionHandler { @NotNull Object onSubscriptionResult( @NotNull Object result, - @NotNull IHub hub, + @NotNull IScopes scopes, @NotNull ExceptionReporter exceptionReporter, @NotNull InstrumentationFieldFetchParameters parameters); } diff --git a/sentry-graphql/src/test/kotlin/io/sentry/graphql/ExceptionReporterTest.kt b/sentry-graphql/src/test/kotlin/io/sentry/graphql/ExceptionReporterTest.kt index a2b2b0f101..3a798a2f86 100644 --- a/sentry-graphql/src/test/kotlin/io/sentry/graphql/ExceptionReporterTest.kt +++ b/sentry-graphql/src/test/kotlin/io/sentry/graphql/ExceptionReporterTest.kt @@ -12,8 +12,8 @@ import graphql.schema.GraphQLObjectType import graphql.schema.GraphQLScalarType import graphql.schema.GraphQLSchema import io.sentry.Hint -import io.sentry.IHub import io.sentry.IScope +import io.sentry.IScopes import io.sentry.Scope import io.sentry.ScopeCallback import io.sentry.SentryOptions @@ -39,7 +39,7 @@ class ExceptionReporterTest { it.maxRequestBodySize = SentryOptions.RequestSize.ALWAYS } val exception = IllegalStateException("some exception") - val hub = mock() + val scopes = mock() lateinit var instrumentationExecutionParameters: InstrumentationExecutionParameters lateinit var executionResult: ExecutionResult lateinit var scope: IScope @@ -47,7 +47,7 @@ class ExceptionReporterTest { val variables = mapOf("variableA" to "value a") fun getSut(options: SentryOptions = defaultOptions, captureRequestBodyForNonSubscriptions: Boolean = true): ExceptionReporter { - whenever(hub.options).thenReturn(options) + whenever(scopes.options).thenReturn(options) scope = Scope(options) val exceptionReporter = ExceptionReporter(captureRequestBodyForNonSubscriptions) executionResult = ExecutionResultImpl.newExecutionResult() @@ -77,7 +77,7 @@ class ExceptionReporterTest { ).build() val instrumentationState = SentryInstrumentation.TracingState() instrumentationExecutionParameters = InstrumentationExecutionParameters(executionInput, schema, instrumentationState) - doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(hub).configureScope(any()) + doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(scopes).configureScope(any()) return exceptionReporter } @@ -88,9 +88,9 @@ class ExceptionReporterTest { @Test fun `captures throwable`() { val exceptionReporter = fixture.getSut() - exceptionReporter.captureThrowable(fixture.exception, ExceptionReporter.ExceptionDetails(fixture.hub, fixture.instrumentationExecutionParameters, false), fixture.executionResult) + exceptionReporter.captureThrowable(fixture.exception, ExceptionReporter.ExceptionDetails(fixture.scopes, fixture.instrumentationExecutionParameters, false), fixture.executionResult) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( org.mockito.kotlin.check { val ex = it.throwableMechanism as ExceptionMechanismException assertFalse(ex.exceptionMechanism.isHandled!!) @@ -112,9 +112,9 @@ class ExceptionReporterTest { val exceptionReporter = fixture.getSut() val headers = mapOf("some-header" to "some-header-value") fixture.scope.request = Request().also { it.headers = headers } - exceptionReporter.captureThrowable(fixture.exception, ExceptionReporter.ExceptionDetails(fixture.hub, fixture.instrumentationExecutionParameters, false), fixture.executionResult) + exceptionReporter.captureThrowable(fixture.exception, ExceptionReporter.ExceptionDetails(fixture.scopes, fixture.instrumentationExecutionParameters, false), fixture.executionResult) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( org.mockito.kotlin.check { val ex = it.throwableMechanism as ExceptionMechanismException assertFalse(ex.exceptionMechanism.isHandled!!) @@ -136,9 +136,9 @@ class ExceptionReporterTest { @Test fun `does not attach query or variables if spring`() { val exceptionReporter = fixture.getSut(captureRequestBodyForNonSubscriptions = false) - exceptionReporter.captureThrowable(fixture.exception, ExceptionReporter.ExceptionDetails(fixture.hub, fixture.instrumentationExecutionParameters, false), fixture.executionResult) + exceptionReporter.captureThrowable(fixture.exception, ExceptionReporter.ExceptionDetails(fixture.scopes, fixture.instrumentationExecutionParameters, false), fixture.executionResult) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( org.mockito.kotlin.check { val ex = it.throwableMechanism as ExceptionMechanismException assertFalse(ex.exceptionMechanism.isHandled!!) @@ -156,9 +156,9 @@ class ExceptionReporterTest { @Test fun `does not attach query or variables if no max body size is set`() { val exceptionReporter = fixture.getSut(SentryOptions().also { it.isSendDefaultPii = true }, false) - exceptionReporter.captureThrowable(fixture.exception, ExceptionReporter.ExceptionDetails(fixture.hub, fixture.instrumentationExecutionParameters, false), fixture.executionResult) + exceptionReporter.captureThrowable(fixture.exception, ExceptionReporter.ExceptionDetails(fixture.scopes, fixture.instrumentationExecutionParameters, false), fixture.executionResult) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( org.mockito.kotlin.check { val ex = it.throwableMechanism as ExceptionMechanismException assertFalse(ex.exceptionMechanism.isHandled!!) @@ -176,9 +176,9 @@ class ExceptionReporterTest { @Test fun `does not attach query or variables if sendDefaultPii is false`() { val exceptionReporter = fixture.getSut(SentryOptions().also { it.maxRequestBodySize = SentryOptions.RequestSize.ALWAYS }, false) - exceptionReporter.captureThrowable(fixture.exception, ExceptionReporter.ExceptionDetails(fixture.hub, fixture.instrumentationExecutionParameters, false), fixture.executionResult) + exceptionReporter.captureThrowable(fixture.exception, ExceptionReporter.ExceptionDetails(fixture.scopes, fixture.instrumentationExecutionParameters, false), fixture.executionResult) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( org.mockito.kotlin.check { val ex = it.throwableMechanism as ExceptionMechanismException assertFalse(ex.exceptionMechanism.isHandled!!) @@ -196,9 +196,9 @@ class ExceptionReporterTest { @Test fun `attaches query and variables if spring and subscription`() { val exceptionReporter = fixture.getSut(captureRequestBodyForNonSubscriptions = false) - exceptionReporter.captureThrowable(fixture.exception, ExceptionReporter.ExceptionDetails(fixture.hub, fixture.instrumentationExecutionParameters, true), fixture.executionResult) + exceptionReporter.captureThrowable(fixture.exception, ExceptionReporter.ExceptionDetails(fixture.scopes, fixture.instrumentationExecutionParameters, true), fixture.executionResult) - verify(fixture.hub).captureEvent( + verify(fixture.scopes).captureEvent( org.mockito.kotlin.check { val ex = it.throwableMechanism as ExceptionMechanismException assertFalse(ex.exceptionMechanism.isHandled!!) diff --git a/sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryDataFetcherExceptionHandlerTest.kt b/sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryDataFetcherExceptionHandlerTest.kt index b571fa8218..de51abac21 100644 --- a/sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryDataFetcherExceptionHandlerTest.kt +++ b/sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryDataFetcherExceptionHandlerTest.kt @@ -3,7 +3,7 @@ package io.sentry.graphql import graphql.execution.DataFetcherExceptionHandler import graphql.execution.DataFetcherExceptionHandlerParameters import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import org.mockito.kotlin.anyOrNull import org.mockito.kotlin.eq import org.mockito.kotlin.mock @@ -14,15 +14,15 @@ class SentryDataFetcherExceptionHandlerTest { @Test fun `passes exception to Sentry and invokes delegate`() { - val hub = mock() + val scopes = mock() val delegate = mock() - val handler = SentryDataFetcherExceptionHandler(hub, delegate) + val handler = SentryDataFetcherExceptionHandler(scopes, delegate) val exception = RuntimeException() val parameters = DataFetcherExceptionHandlerParameters.newExceptionParameters().exception(exception).build() handler.onException(parameters) - verify(hub).captureException(eq(exception), anyOrNull()) + verify(scopes).captureException(eq(exception), anyOrNull()) verify(delegate).handleException(parameters) } } diff --git a/sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryGenericDataFetcherExceptionHandlerTest.kt b/sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryGenericDataFetcherExceptionHandlerTest.kt index 6d643baf01..88e2f5df55 100644 --- a/sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryGenericDataFetcherExceptionHandlerTest.kt +++ b/sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryGenericDataFetcherExceptionHandlerTest.kt @@ -4,7 +4,7 @@ import graphql.GraphQLContext import graphql.execution.DataFetcherExceptionHandler import graphql.execution.DataFetcherExceptionHandlerParameters import graphql.schema.DataFetchingEnvironmentImpl -import io.sentry.IHub +import io.sentry.IScopes import org.mockito.kotlin.mock import org.mockito.kotlin.verify import kotlin.test.Test @@ -15,10 +15,10 @@ class SentryGenericDataFetcherExceptionHandlerTest { @Test fun `collects exception into GraphQLContext and invokes delegate`() { - val hub = mock() + val scopes = mock() val delegate = mock() val handler = SentryGenericDataFetcherExceptionHandler( - hub, + scopes, delegate ) diff --git a/sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryInstrumentationAnotherTest.kt b/sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryInstrumentationAnotherTest.kt index e30bbc9415..087a1dfa72 100644 --- a/sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryInstrumentationAnotherTest.kt +++ b/sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryInstrumentationAnotherTest.kt @@ -28,7 +28,8 @@ import graphql.schema.GraphQLObjectType import graphql.schema.GraphQLScalarType import graphql.schema.GraphQLSchema import io.sentry.Breadcrumb -import io.sentry.IHub +import io.sentry.HubScopesWrapper +import io.sentry.IScopes import io.sentry.Sentry import io.sentry.SentryOptions import io.sentry.SentryTracer @@ -52,7 +53,7 @@ import kotlin.test.assertSame class SentryInstrumentationAnotherTest { class Fixture { - val hub = mock() + val scopes = mock() lateinit var activeSpan: SentryTracer lateinit var dataFetcher: DataFetcher lateinit var fieldFetchParameters: InstrumentationFieldFetchParameters @@ -70,17 +71,17 @@ class SentryInstrumentationAnotherTest { val variables = mapOf("variableA" to "value a") fun getSut(isTransactionActive: Boolean = true, operation: OperationDefinition.Operation = OperationDefinition.Operation.QUERY, graphQLContextParam: Map? = null, addTransactionToTracingState: Boolean = true, ignoredErrors: List = emptyList()): SentryInstrumentation { - whenever(hub.options).thenReturn(SentryOptions()) - activeSpan = SentryTracer(TransactionContext("name", "op"), hub) + whenever(scopes.options).thenReturn(SentryOptions()) + activeSpan = SentryTracer(TransactionContext("name", "op"), scopes) if (isTransactionActive) { - whenever(hub.span).thenReturn(activeSpan) + whenever(scopes.span).thenReturn(activeSpan) } else { - whenever(hub.span).thenReturn(null) + whenever(scopes.span).thenReturn(null) } val defaultGraphQLContext = mapOf( - SentryInstrumentation.SENTRY_HUB_CONTEXT_KEY to hub + SentryInstrumentation.SENTRY_SCOPES_CONTEXT_KEY to scopes ) val mergedField = MergedField.newMergedField().addField(Field.newField("myFieldName").build()).build() @@ -165,7 +166,7 @@ class SentryInstrumentationAnotherTest { val result = instrumentedDataFetcher.get(fixture.environment) assertEquals("result modified by subscription handler", result) - verify(fixture.subscriptionHandler).onSubscriptionResult(eq("raw result"), same(fixture.hub), same(fixture.exceptionReporter), same(fixture.fieldFetchParameters)) + verify(fixture.subscriptionHandler).onSubscriptionResult(eq("raw result"), same(fixture.scopes), same(fixture.exceptionReporter), same(fixture.fieldFetchParameters)) } @Test @@ -175,7 +176,7 @@ class SentryInstrumentationAnotherTest { val result = instrumentedDataFetcher.get(fixture.environment) assertEquals("result modified by subscription handler", result) - verify(fixture.subscriptionHandler).onSubscriptionResult(eq("raw result"), same(fixture.hub), same(fixture.exceptionReporter), same(fixture.fieldFetchParameters)) + verify(fixture.subscriptionHandler).onSubscriptionResult(eq("raw result"), same(fixture.scopes), same(fixture.exceptionReporter), same(fixture.fieldFetchParameters)) } @Test @@ -222,7 +223,7 @@ class SentryInstrumentationAnotherTest { fun `adds a breadcrumb for operation`() { val instrumentation = fixture.getSut() instrumentation.beginExecuteOperation(fixture.instrumentationExecuteOperationParameters) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( org.mockito.kotlin.check { breadcrumb -> assertEquals("graphql", breadcrumb.type) assertEquals("query", breadcrumb.category) @@ -237,7 +238,7 @@ class SentryInstrumentationAnotherTest { fun `adds a breadcrumb for data fetcher`() { val instrumentation = fixture.getSut() instrumentation.instrumentDataFetcher(fixture.dataFetcher, fixture.fieldFetchParameters).get(fixture.environment) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( org.mockito.kotlin.check { breadcrumb -> assertEquals("graphql", breadcrumb.type) assertEquals("graphql.fetcher", breadcrumb.category) @@ -250,11 +251,11 @@ class SentryInstrumentationAnotherTest { } @Test - fun `stores hub in context and adds transaction to state`() { + fun `stores scopes in context and adds transaction to state`() { val instrumentation = fixture.getSut(isTransactionActive = true, operation = OperationDefinition.Operation.MUTATION, graphQLContextParam = emptyMap(), addTransactionToTracingState = false) - withMockHub { + withMockScopes { instrumentation.beginExecution(fixture.instrumentationExecutionParameters) - assertSame(fixture.hub, fixture.instrumentationExecutionParameters.graphQLContext.get(SentryInstrumentation.SENTRY_HUB_CONTEXT_KEY)) + assertSame(fixture.scopes, fixture.instrumentationExecutionParameters.graphQLContext.get(SentryInstrumentation.SENTRY_SCOPES_CONTEXT_KEY)) assertNotNull(fixture.instrumentationState.transaction) } } @@ -276,7 +277,7 @@ class SentryInstrumentationAnotherTest { assertEquals("exception message", it.message) }, org.mockito.kotlin.check { - assertSame(fixture.hub, it.hub) + assertSame(fixture.scopes, it.scopes) assertSame(fixture.query, it.query) assertEquals(false, it.isSubscription) assertEquals(fixture.variables, it.variables) @@ -293,7 +294,7 @@ class SentryInstrumentationAnotherTest { val instrumentation = fixture.getSut( graphQLContextParam = mapOf( SENTRY_EXCEPTIONS_CONTEXT_KEY to listOf(exception), - SentryInstrumentation.SENTRY_HUB_CONTEXT_KEY to fixture.hub + SentryInstrumentation.SENTRY_SCOPES_CONTEXT_KEY to fixture.scopes ) ) val executionResult = ExecutionResultImpl.newExecutionResult() @@ -305,7 +306,7 @@ class SentryInstrumentationAnotherTest { assertSame(exception, it) }, org.mockito.kotlin.check { - assertSame(fixture.hub, it.hub) + assertSame(fixture.scopes, it.scopes) assertSame(fixture.query, it.query) assertEquals(false, it.isSubscription) assertEquals(fixture.variables, it.variables) @@ -356,8 +357,9 @@ class SentryInstrumentationAnotherTest { assertSame(executionResult, result) } - fun withMockHub(closure: () -> Unit) = Mockito.mockStatic(Sentry::class.java).use { - it.`when` { Sentry.getCurrentHub() }.thenReturn(fixture.hub) + fun withMockScopes(closure: () -> Unit) = Mockito.mockStatic(Sentry::class.java).use { + it.`when` { Sentry.getCurrentHub() }.thenReturn(HubScopesWrapper(fixture.scopes)) + it.`when` { Sentry.getCurrentScopes() }.thenReturn(fixture.scopes) closure.invoke() } diff --git a/sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryInstrumentationTest.kt b/sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryInstrumentationTest.kt index 8a579e2687..2bb46f79fc 100644 --- a/sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryInstrumentationTest.kt +++ b/sentry-graphql/src/test/kotlin/io/sentry/graphql/SentryInstrumentationTest.kt @@ -18,7 +18,8 @@ import graphql.schema.GraphQLScalarType import graphql.schema.idl.RuntimeWiring import graphql.schema.idl.SchemaGenerator import graphql.schema.idl.SchemaParser -import io.sentry.IHub +import io.sentry.HubScopesWrapper +import io.sentry.IScopes import io.sentry.Sentry import io.sentry.SentryOptions import io.sentry.SentryTracer @@ -39,12 +40,12 @@ import kotlin.test.assertTrue class SentryInstrumentationTest { class Fixture { - val hub = mock() + val scopes = mock() lateinit var activeSpan: SentryTracer fun getSut(isTransactionActive: Boolean = true, dataFetcherThrows: Boolean = false, beforeSpan: SentryInstrumentation.BeforeSpanCallback? = null): GraphQL { - whenever(hub.options).thenReturn(SentryOptions()) - activeSpan = SentryTracer(TransactionContext("name", "op"), hub) + whenever(scopes.options).thenReturn(SentryOptions()) + activeSpan = SentryTracer(TransactionContext("name", "op"), scopes) val schema = """ type Query { shows: [Show] @@ -61,9 +62,9 @@ class SentryInstrumentationTest { .build() if (isTransactionActive) { - whenever(hub.span).thenReturn(activeSpan) + whenever(scopes.span).thenReturn(activeSpan) } else { - whenever(hub.span).thenReturn(null) + whenever(scopes.span).thenReturn(null) } return graphQL @@ -87,7 +88,7 @@ class SentryInstrumentationTest { fun `when transaction is active, creates inner spans`() { val sut = fixture.getSut() - withMockHub { + withMockScopes { val result = sut.execute("{ shows { id } }") assertTrue(result.errors.isEmpty()) @@ -105,7 +106,7 @@ class SentryInstrumentationTest { fun `when transaction is active, and data fetcher throws, creates inner spans`() { val sut = fixture.getSut(dataFetcherThrows = true) - withMockHub { + withMockScopes { val result = sut.execute("{ shows { id } }") assertTrue(result.errors.isNotEmpty()) @@ -122,7 +123,7 @@ class SentryInstrumentationTest { fun `when transaction is not active, does not create spans`() { val sut = fixture.getSut(isTransactionActive = false) - withMockHub { + withMockScopes { val result = sut.execute("{ shows { id } }") assertTrue(result.errors.isEmpty()) @@ -134,7 +135,7 @@ class SentryInstrumentationTest { fun `beforeSpan can drop spans`() { val sut = fixture.getSut(beforeSpan = SentryInstrumentation.BeforeSpanCallback { _, _, _ -> null }) - withMockHub { + withMockScopes { val result = sut.execute("{ shows { id } }") assertTrue(result.errors.isEmpty()) @@ -152,7 +153,7 @@ class SentryInstrumentationTest { fun `beforeSpan can modify spans`() { val sut = fixture.getSut(beforeSpan = SentryInstrumentation.BeforeSpanCallback { span, _, _ -> span.apply { description = "changed" } }) - withMockHub { + withMockScopes { val result = sut.execute("{ shows { id } }") assertTrue(result.errors.isEmpty()) @@ -208,19 +209,20 @@ class SentryInstrumentationTest { @Test fun `Integration adds itself to integration and package list`() { - withMockHub { + withMockScopes { val sut = fixture.getSut() - assertNotNull(fixture.hub.options.sdkVersion) - assert(fixture.hub.options.sdkVersion!!.integrationSet.contains("GraphQL")) + assertNotNull(fixture.scopes.options.sdkVersion) + assert(fixture.scopes.options.sdkVersion!!.integrationSet.contains("GraphQL")) val packageInfo = - fixture.hub.options.sdkVersion!!.packageSet.firstOrNull { pkg -> pkg.name == "maven:io.sentry:sentry-graphql" } + fixture.scopes.options.sdkVersion!!.packageSet.firstOrNull { pkg -> pkg.name == "maven:io.sentry:sentry-graphql" } assertNotNull(packageInfo) assert(packageInfo.version == BuildConfig.VERSION_NAME) } } - fun withMockHub(closure: () -> Unit) = Mockito.mockStatic(Sentry::class.java).use { - it.`when` { Sentry.getCurrentHub() }.thenReturn(fixture.hub) + fun withMockScopes(closure: () -> Unit) = Mockito.mockStatic(Sentry::class.java).use { + it.`when` { Sentry.getCurrentHub() }.thenReturn(HubScopesWrapper(fixture.scopes)) + it.`when` { Sentry.getCurrentScopes() }.thenReturn(fixture.scopes) closure.invoke() } From 9bfc0863bc61b6d4107b0ffa6801302fb92b6e26 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Tue, 2 Apr 2024 14:36:44 +0200 Subject: [PATCH 10/28] Replace `IHub` with `IScopes` in logging integrations --- .../java/io/sentry/jul/SentryHandler.java | 6 +++--- sentry-log4j2/api/sentry-log4j2.api | 2 +- .../java/io/sentry/log4j2/SentryAppender.java | 20 +++++++++---------- .../io/sentry/log4j2/SentryAppenderTest.kt | 6 +++--- .../io/sentry/logback/SentryAppender.java | 6 +++--- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/sentry-jul/src/main/java/io/sentry/jul/SentryHandler.java b/sentry-jul/src/main/java/io/sentry/jul/SentryHandler.java index 2ca775572b..c52b4706f2 100644 --- a/sentry-jul/src/main/java/io/sentry/jul/SentryHandler.java +++ b/sentry-jul/src/main/java/io/sentry/jul/SentryHandler.java @@ -6,7 +6,7 @@ import com.jakewharton.nopen.annotation.Open; import io.sentry.Breadcrumb; import io.sentry.Hint; -import io.sentry.HubAdapter; +import io.sentry.ScopesAdapter; import io.sentry.Sentry; import io.sentry.SentryEvent; import io.sentry.SentryIntegrationPackageStorage; @@ -210,9 +210,9 @@ SentryEvent createEvent(final @NotNull LogRecord record) { mdcProperties = CollectionUtils.filterMapEntries(mdcProperties, entry -> entry.getValue() != null); if (!mdcProperties.isEmpty()) { - // get tags from HubAdapter options to allow getting the correct tags if Sentry has been + // get tags from ScopesAdapter options to allow getting the correct tags if Sentry has been // initialized somewhere else - final List contextTags = HubAdapter.getInstance().getOptions().getContextTags(); + final List contextTags = ScopesAdapter.getInstance().getOptions().getContextTags(); if (!contextTags.isEmpty()) { for (final String contextTag : contextTags) { // if mdc tag is listed in SentryOptions, apply as event tag diff --git a/sentry-log4j2/api/sentry-log4j2.api b/sentry-log4j2/api/sentry-log4j2.api index 76aa3e823e..b7fe8b3273 100644 --- a/sentry-log4j2/api/sentry-log4j2.api +++ b/sentry-log4j2/api/sentry-log4j2.api @@ -5,7 +5,7 @@ public final class io/sentry/log4j2/BuildConfig { public class io/sentry/log4j2/SentryAppender : org/apache/logging/log4j/core/appender/AbstractAppender { public static final field MECHANISM_TYPE Ljava/lang/String; - public fun (Ljava/lang/String;Lorg/apache/logging/log4j/core/Filter;Ljava/lang/String;Lorg/apache/logging/log4j/Level;Lorg/apache/logging/log4j/Level;Ljava/lang/Boolean;Lio/sentry/ITransportFactory;Lio/sentry/IHub;[Ljava/lang/String;)V + public fun (Ljava/lang/String;Lorg/apache/logging/log4j/core/Filter;Ljava/lang/String;Lorg/apache/logging/log4j/Level;Lorg/apache/logging/log4j/Level;Ljava/lang/Boolean;Lio/sentry/ITransportFactory;Lio/sentry/IScopes;[Ljava/lang/String;)V public fun append (Lorg/apache/logging/log4j/core/LogEvent;)V public static fun createAppender (Ljava/lang/String;Lorg/apache/logging/log4j/Level;Lorg/apache/logging/log4j/Level;Ljava/lang/String;Ljava/lang/Boolean;Lorg/apache/logging/log4j/core/Filter;Ljava/lang/String;)Lio/sentry/log4j2/SentryAppender; protected fun createBreadcrumb (Lorg/apache/logging/log4j/core/LogEvent;)Lio/sentry/Breadcrumb; diff --git a/sentry-log4j2/src/main/java/io/sentry/log4j2/SentryAppender.java b/sentry-log4j2/src/main/java/io/sentry/log4j2/SentryAppender.java index 4cf4ad4a86..4ee07ab7b9 100644 --- a/sentry-log4j2/src/main/java/io/sentry/log4j2/SentryAppender.java +++ b/sentry-log4j2/src/main/java/io/sentry/log4j2/SentryAppender.java @@ -7,9 +7,9 @@ import io.sentry.Breadcrumb; import io.sentry.DateUtils; import io.sentry.Hint; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ITransportFactory; +import io.sentry.ScopesAdapter; import io.sentry.Sentry; import io.sentry.SentryEvent; import io.sentry.SentryIntegrationPackageStorage; @@ -50,7 +50,7 @@ public class SentryAppender extends AbstractAppender { private @NotNull Level minimumBreadcrumbLevel = Level.INFO; private @NotNull Level minimumEventLevel = Level.ERROR; private final @Nullable Boolean debug; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @Nullable List contextTags; public SentryAppender( @@ -61,7 +61,7 @@ public SentryAppender( final @Nullable Level minimumEventLevel, final @Nullable Boolean debug, final @Nullable ITransportFactory transportFactory, - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @Nullable String[] contextTags) { super(name, filter, null, true, null); this.dsn = dsn; @@ -73,7 +73,7 @@ public SentryAppender( } this.debug = debug; this.transportFactory = transportFactory; - this.hub = hub; + this.scopes = scopes; this.contextTags = contextTags != null ? Arrays.asList(contextTags) : null; } @@ -110,7 +110,7 @@ public SentryAppender( minimumEventLevel, debug, null, - HubAdapter.getInstance(), + ScopesAdapter.getInstance(), contextTags != null ? contextTags.split(",") : null); } @@ -149,13 +149,13 @@ public void append(final @NotNull LogEvent eventObject) { final Hint hint = new Hint(); hint.set(SENTRY_SYNTHETIC_EXCEPTION, eventObject); - hub.captureEvent(createEvent(eventObject), hint); + scopes.captureEvent(createEvent(eventObject), hint); } if (eventObject.getLevel().isMoreSpecificThan(minimumBreadcrumbLevel)) { final Hint hint = new Hint(); hint.set(LOG4J_LOG_EVENT, eventObject); - hub.addBreadcrumb(createBreadcrumb(eventObject), hint); + scopes.addBreadcrumb(createBreadcrumb(eventObject), hint); } } @@ -199,9 +199,9 @@ public void append(final @NotNull LogEvent eventObject) { CollectionUtils.filterMapEntries( loggingEvent.getContextData().toMap(), entry -> entry.getValue() != null); if (!contextData.isEmpty()) { - // get tags from HubAdapter options to allow getting the correct tags if Sentry has been + // get tags from ScopesAdapter options to allow getting the correct tags if Sentry has been // initialized somewhere else - final List contextTags = hub.getOptions().getContextTags(); + final List contextTags = scopes.getOptions().getContextTags(); if (contextTags != null && !contextTags.isEmpty()) { for (final String contextTag : contextTags) { // if mdc tag is listed in SentryOptions, apply as event tag diff --git a/sentry-log4j2/src/test/kotlin/io/sentry/log4j2/SentryAppenderTest.kt b/sentry-log4j2/src/test/kotlin/io/sentry/log4j2/SentryAppenderTest.kt index b6f004232c..3786555a61 100644 --- a/sentry-log4j2/src/test/kotlin/io/sentry/log4j2/SentryAppenderTest.kt +++ b/sentry-log4j2/src/test/kotlin/io/sentry/log4j2/SentryAppenderTest.kt @@ -1,7 +1,7 @@ package io.sentry.log4j2 -import io.sentry.HubAdapter import io.sentry.ITransportFactory +import io.sentry.ScopesAdapter import io.sentry.Sentry import io.sentry.SentryLevel import io.sentry.checkEvent @@ -49,7 +49,7 @@ class SentryAppenderTest { } loggerContext.start() val config: Configuration = loggerContext.configuration - val appender = SentryAppender("sentry", null, "http://key@localhost/proj", minimumBreadcrumbLevel, minimumEventLevel, debug, this.transportFactory, HubAdapter.getInstance(), contextTags?.toTypedArray()) + val appender = SentryAppender("sentry", null, "http://key@localhost/proj", minimumBreadcrumbLevel, minimumEventLevel, debug, this.transportFactory, ScopesAdapter.getInstance(), contextTags?.toTypedArray()) config.addAppender(appender) val ref = AppenderRef.createAppenderRef("sentry", null, null) @@ -445,6 +445,6 @@ class SentryAppenderTest { @Test fun `sets the debug mode`() { fixture.getSut(debug = true) - assertTrue(HubAdapter.getInstance().options.isDebug) + assertTrue(ScopesAdapter.getInstance().options.isDebug) } } diff --git a/sentry-logback/src/main/java/io/sentry/logback/SentryAppender.java b/sentry-logback/src/main/java/io/sentry/logback/SentryAppender.java index d0be108149..56db0b4dbc 100644 --- a/sentry-logback/src/main/java/io/sentry/logback/SentryAppender.java +++ b/sentry-logback/src/main/java/io/sentry/logback/SentryAppender.java @@ -12,8 +12,8 @@ import io.sentry.Breadcrumb; import io.sentry.DateUtils; import io.sentry.Hint; -import io.sentry.HubAdapter; import io.sentry.ITransportFactory; +import io.sentry.ScopesAdapter; import io.sentry.Sentry; import io.sentry.SentryEvent; import io.sentry.SentryIntegrationPackageStorage; @@ -134,9 +134,9 @@ protected void append(@NotNull ILoggingEvent eventObject) { CollectionUtils.filterMapEntries( loggingEvent.getMDCPropertyMap(), entry -> entry.getValue() != null); if (!mdcProperties.isEmpty()) { - // get tags from HubAdapter options to allow getting the correct tags if Sentry has been + // get tags from ScopesAdapter options to allow getting the correct tags if Sentry has been // initialized somewhere else - final List contextTags = HubAdapter.getInstance().getOptions().getContextTags(); + final List contextTags = ScopesAdapter.getInstance().getOptions().getContextTags(); if (!contextTags.isEmpty()) { for (final String contextTag : contextTags) { // if mdc tag is listed in SentryOptions, apply as event tag From b998e50993d6f012f4d8087382c9de6a77eacaa2 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Tue, 2 Apr 2024 14:40:25 +0200 Subject: [PATCH 11/28] Replace `IHub` with `IScopes` in more integrations --- sentry-jdbc/api/sentry-jdbc.api | 2 +- .../sentry/jdbc/SentryJdbcEventListener.java | 14 +++++----- .../jdbc/SentryJdbcEventListenerTest.kt | 16 +++++------ .../api/sentry-kotlin-extensions.api | 8 +++--- .../java/io/sentry/kotlin/SentryContext.kt | 28 +++++++++++-------- .../io/sentry/kotlin/SentryContextTest.kt | 6 ++-- sentry-openfeign/api/sentry-openfeign.api | 4 +-- .../io/sentry/openfeign/SentryCapability.java | 17 +++++------ .../sentry/openfeign/SentryFeignClient.java | 14 +++++----- .../sentry/openfeign/SentryFeignClientTest.kt | 22 +++++++-------- sentry-quartz/api/sentry-quartz.api | 2 +- .../io/sentry/quartz/SentryJobListener.java | 28 ++++++++++--------- .../api/sentry-servlet-jakarta.api | 2 +- .../jakarta/SentryServletRequestListener.java | 20 ++++++------- .../SentryServletRequestListenerTest.kt | 12 ++++---- sentry-servlet/api/sentry-servlet.api | 2 +- .../servlet/SentryServletRequestListener.java | 20 ++++++------- .../SentryServletRequestListenerTest.kt | 12 ++++---- .../api/sentry-test-support.api | 1 + .../main/kotlin/io/sentry/test/Reflection.kt | 11 ++++++-- 20 files changed, 129 insertions(+), 112 deletions(-) diff --git a/sentry-jdbc/api/sentry-jdbc.api b/sentry-jdbc/api/sentry-jdbc.api index cff0f37fd2..700cbb2d69 100644 --- a/sentry-jdbc/api/sentry-jdbc.api +++ b/sentry-jdbc/api/sentry-jdbc.api @@ -16,7 +16,7 @@ public final class io/sentry/jdbc/DatabaseUtils$DatabaseDetails { public class io/sentry/jdbc/SentryJdbcEventListener : com/p6spy/engine/event/SimpleJdbcEventListener { public fun ()V - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun onAfterAnyExecute (Lcom/p6spy/engine/common/StatementInformation;JLjava/sql/SQLException;)V public fun onBeforeAnyExecute (Lcom/p6spy/engine/common/StatementInformation;)V } diff --git a/sentry-jdbc/src/main/java/io/sentry/jdbc/SentryJdbcEventListener.java b/sentry-jdbc/src/main/java/io/sentry/jdbc/SentryJdbcEventListener.java index 0346d2d0b9..4cb21188e4 100644 --- a/sentry-jdbc/src/main/java/io/sentry/jdbc/SentryJdbcEventListener.java +++ b/sentry-jdbc/src/main/java/io/sentry/jdbc/SentryJdbcEventListener.java @@ -6,9 +6,9 @@ import com.jakewharton.nopen.annotation.Open; import com.p6spy.engine.common.StatementInformation; import com.p6spy.engine.event.SimpleJdbcEventListener; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ISpan; +import io.sentry.ScopesAdapter; import io.sentry.SentryIntegrationPackageStorage; import io.sentry.Span; import io.sentry.SpanStatus; @@ -21,24 +21,24 @@ @Open public class SentryJdbcEventListener extends SimpleJdbcEventListener { private static final String TRACE_ORIGIN = "auto.db.jdbc"; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private static final @NotNull ThreadLocal CURRENT_SPAN = new ThreadLocal<>(); private volatile @Nullable DatabaseUtils.DatabaseDetails cachedDatabaseDetails = null; private final @NotNull Object databaseDetailsLock = new Object(); - public SentryJdbcEventListener(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentryJdbcEventListener(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); addPackageAndIntegrationInfo(); } public SentryJdbcEventListener() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } @Override public void onBeforeAnyExecute(final @NotNull StatementInformation statementInformation) { - final ISpan parent = hub.getSpan(); + final ISpan parent = scopes.getSpan(); if (parent != null && !parent.isNoOp()) { final ISpan span = parent.startChild("db.query", statementInformation.getSql()); CURRENT_SPAN.set(span); diff --git a/sentry-jdbc/src/test/kotlin/io/sentry/jdbc/SentryJdbcEventListenerTest.kt b/sentry-jdbc/src/test/kotlin/io/sentry/jdbc/SentryJdbcEventListenerTest.kt index 78c5d4cf12..00ce03de41 100644 --- a/sentry-jdbc/src/test/kotlin/io/sentry/jdbc/SentryJdbcEventListenerTest.kt +++ b/sentry-jdbc/src/test/kotlin/io/sentry/jdbc/SentryJdbcEventListenerTest.kt @@ -2,7 +2,7 @@ package io.sentry.jdbc import com.p6spy.engine.common.StatementInformation import com.p6spy.engine.spy.P6DataSource -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryOptions import io.sentry.SentryTracer import io.sentry.SpanDataConvention.DB_NAME_KEY @@ -26,7 +26,7 @@ import kotlin.test.assertTrue class SentryJdbcEventListenerTest { class Fixture { - val hub = mock().apply { + val scopes = mock().apply { whenever(options).thenReturn( SentryOptions().apply { sdkVersion = SdkVersion("test", "1.2.3") @@ -37,9 +37,9 @@ class SentryJdbcEventListenerTest { val actualDataSource = JDBCDataSource() fun getSut(withRunningTransaction: Boolean = true, existingRow: Int? = null): DataSource { - tx = SentryTracer(TransactionContext("name", "op"), hub) + tx = SentryTracer(TransactionContext("name", "op"), scopes) if (withRunningTransaction) { - whenever(hub.span).thenReturn(tx) + whenever(scopes.span).thenReturn(tx) } actualDataSource.setURL("jdbc:hsqldb:mem:testdb") @@ -54,7 +54,7 @@ class SentryJdbcEventListenerTest { } } - val sentryQueryExecutionListener = SentryJdbcEventListener(hub) + val sentryQueryExecutionListener = SentryJdbcEventListener(scopes) val p6spyDataSource = P6DataSource(actualDataSource) p6spyDataSource.setJdbcEventListenerFactory { sentryQueryExecutionListener } return p6spyDataSource @@ -131,9 +131,9 @@ class SentryJdbcEventListenerTest { @Test fun `sets SDKVersion Info`() { val sut = fixture.getSut() - assertNotNull(fixture.hub.options.sdkVersion) - assert(fixture.hub.options.sdkVersion!!.integrationSet.contains("JDBC")) - val packageInfo = fixture.hub.options.sdkVersion!!.packageSet.firstOrNull { pkg -> pkg.name == "maven:io.sentry:sentry-jdbc" } + assertNotNull(fixture.scopes.options.sdkVersion) + assert(fixture.scopes.options.sdkVersion!!.integrationSet.contains("JDBC")) + val packageInfo = fixture.scopes.options.sdkVersion!!.packageSet.firstOrNull { pkg -> pkg.name == "maven:io.sentry:sentry-jdbc" } assertNotNull(packageInfo) assert(packageInfo.version == BuildConfig.VERSION_NAME) } diff --git a/sentry-kotlin-extensions/api/sentry-kotlin-extensions.api b/sentry-kotlin-extensions/api/sentry-kotlin-extensions.api index d501240a3a..7e3be67279 100644 --- a/sentry-kotlin-extensions/api/sentry-kotlin-extensions.api +++ b/sentry-kotlin-extensions/api/sentry-kotlin-extensions.api @@ -1,16 +1,16 @@ public final class io/sentry/kotlin/SentryContext : kotlin/coroutines/AbstractCoroutineContextElement, kotlinx/coroutines/CopyableThreadContextElement { public fun ()V - public fun (Lio/sentry/IHub;)V - public synthetic fun (Lio/sentry/IHub;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lio/sentry/IScopes;)V + public synthetic fun (Lio/sentry/IScopes;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun copyForChild ()Lkotlinx/coroutines/CopyableThreadContextElement; public fun fold (Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; public fun get (Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext$Element; public fun mergeForChild (Lkotlin/coroutines/CoroutineContext$Element;)Lkotlin/coroutines/CoroutineContext; public fun minusKey (Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext; public fun plus (Lkotlin/coroutines/CoroutineContext;)Lkotlin/coroutines/CoroutineContext; - public fun restoreThreadContext (Lkotlin/coroutines/CoroutineContext;Lio/sentry/IHub;)V + public fun restoreThreadContext (Lkotlin/coroutines/CoroutineContext;Lio/sentry/IScopes;)V public synthetic fun restoreThreadContext (Lkotlin/coroutines/CoroutineContext;Ljava/lang/Object;)V - public fun updateThreadContext (Lkotlin/coroutines/CoroutineContext;)Lio/sentry/IHub; + public fun updateThreadContext (Lkotlin/coroutines/CoroutineContext;)Lio/sentry/IScopes; public synthetic fun updateThreadContext (Lkotlin/coroutines/CoroutineContext;)Ljava/lang/Object; } diff --git a/sentry-kotlin-extensions/src/main/java/io/sentry/kotlin/SentryContext.kt b/sentry-kotlin-extensions/src/main/java/io/sentry/kotlin/SentryContext.kt index 3cf22a20da..4c814f2805 100644 --- a/sentry-kotlin-extensions/src/main/java/io/sentry/kotlin/SentryContext.kt +++ b/sentry-kotlin-extensions/src/main/java/io/sentry/kotlin/SentryContext.kt @@ -1,6 +1,6 @@ package io.sentry.kotlin -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.Sentry import kotlinx.coroutines.CopyableThreadContextElement import kotlin.coroutines.AbstractCoroutineContextElement @@ -9,26 +9,32 @@ import kotlin.coroutines.CoroutineContext /** * Sentry context element for [CoroutineContext]. */ -public class SentryContext(private val hub: IHub = Sentry.getCurrentHub().clone()) : - CopyableThreadContextElement, AbstractCoroutineContextElement(Key) { +@SuppressWarnings("deprecation") +// TODO fork instead +public class SentryContext(private val scopes: IScopes = Sentry.getCurrentScopes().clone()) : + CopyableThreadContextElement, AbstractCoroutineContextElement(Key) { private companion object Key : CoroutineContext.Key - override fun copyForChild(): CopyableThreadContextElement { - return SentryContext(hub.clone()) + @SuppressWarnings("deprecation") + override fun copyForChild(): CopyableThreadContextElement { + // TODO fork instead + return SentryContext(scopes.clone()) } + @SuppressWarnings("deprecation") override fun mergeForChild(overwritingElement: CoroutineContext.Element): CoroutineContext { - return overwritingElement[Key] ?: SentryContext(hub.clone()) + // TODO fork instead? + return overwritingElement[Key] ?: SentryContext(scopes.clone()) } - override fun updateThreadContext(context: CoroutineContext): IHub { - val oldState = Sentry.getCurrentHub() - Sentry.setCurrentHub(hub) + override fun updateThreadContext(context: CoroutineContext): IScopes { + val oldState = Sentry.getCurrentScopes() + Sentry.setCurrentScopes(scopes) return oldState } - override fun restoreThreadContext(context: CoroutineContext, oldState: IHub) { - Sentry.setCurrentHub(oldState) + override fun restoreThreadContext(context: CoroutineContext, oldState: IScopes) { + Sentry.setCurrentScopes(oldState) } } diff --git a/sentry-kotlin-extensions/src/test/java/io/sentry/kotlin/SentryContextTest.kt b/sentry-kotlin-extensions/src/test/java/io/sentry/kotlin/SentryContextTest.kt index b54ceabc51..578b610267 100644 --- a/sentry-kotlin-extensions/src/test/java/io/sentry/kotlin/SentryContextTest.kt +++ b/sentry-kotlin-extensions/src/test/java/io/sentry/kotlin/SentryContextTest.kt @@ -119,7 +119,7 @@ class SentryContextTest { val c2 = launch( SentryContext( - Sentry.getCurrentHub().clone().also { + Sentry.getCurrentScopes().clone().also { it.setTag("cloned", "clonedValue") } ) @@ -145,7 +145,7 @@ class SentryContextTest { @Test fun `mergeForChild returns copy of initial context if Key not present`() { val initialContextElement = SentryContext( - Sentry.getCurrentHub().clone().also { + Sentry.getCurrentScopes().clone().also { it.setTag("cloned", "clonedValue") } ) @@ -158,7 +158,7 @@ class SentryContextTest { @Test fun `mergeForChild returns passed context`() { val initialContextElement = SentryContext( - Sentry.getCurrentHub().clone().also { + Sentry.getCurrentScopes().clone().also { it.setTag("cloned", "clonedValue") } ) diff --git a/sentry-openfeign/api/sentry-openfeign.api b/sentry-openfeign/api/sentry-openfeign.api index beb15c9e02..4ab65a5ca4 100644 --- a/sentry-openfeign/api/sentry-openfeign.api +++ b/sentry-openfeign/api/sentry-openfeign.api @@ -1,12 +1,12 @@ public final class io/sentry/openfeign/SentryCapability : feign/Capability { public fun ()V - public fun (Lio/sentry/IHub;Lio/sentry/openfeign/SentryFeignClient$BeforeSpanCallback;)V + public fun (Lio/sentry/IScopes;Lio/sentry/openfeign/SentryFeignClient$BeforeSpanCallback;)V public fun (Lio/sentry/openfeign/SentryFeignClient$BeforeSpanCallback;)V public fun enrich (Lfeign/Client;)Lfeign/Client; } public final class io/sentry/openfeign/SentryFeignClient : feign/Client { - public fun (Lfeign/Client;Lio/sentry/IHub;Lio/sentry/openfeign/SentryFeignClient$BeforeSpanCallback;)V + public fun (Lfeign/Client;Lio/sentry/IScopes;Lio/sentry/openfeign/SentryFeignClient$BeforeSpanCallback;)V public fun execute (Lfeign/Request;Lfeign/Request$Options;)Lfeign/Response; } diff --git a/sentry-openfeign/src/main/java/io/sentry/openfeign/SentryCapability.java b/sentry-openfeign/src/main/java/io/sentry/openfeign/SentryCapability.java index b65685c3fd..1ad6b1f274 100644 --- a/sentry-openfeign/src/main/java/io/sentry/openfeign/SentryCapability.java +++ b/sentry-openfeign/src/main/java/io/sentry/openfeign/SentryCapability.java @@ -2,33 +2,34 @@ import feign.Capability; import feign.Client; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; +import io.sentry.ScopesAdapter; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** Adds Sentry tracing capability to Feign clients. */ public final class SentryCapability implements Capability { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @Nullable SentryFeignClient.BeforeSpanCallback beforeSpan; public SentryCapability( - final @NotNull IHub hub, final @Nullable SentryFeignClient.BeforeSpanCallback beforeSpan) { - this.hub = hub; + final @NotNull IScopes scopes, + final @Nullable SentryFeignClient.BeforeSpanCallback beforeSpan) { + this.scopes = scopes; this.beforeSpan = beforeSpan; } public SentryCapability(final @Nullable SentryFeignClient.BeforeSpanCallback beforeSpan) { - this(HubAdapter.getInstance(), beforeSpan); + this(ScopesAdapter.getInstance(), beforeSpan); } public SentryCapability() { - this(HubAdapter.getInstance(), null); + this(ScopesAdapter.getInstance(), null); } @Override public @NotNull Client enrich(final @NotNull Client client) { - return new SentryFeignClient(client, hub, beforeSpan); + return new SentryFeignClient(client, scopes, beforeSpan); } } diff --git a/sentry-openfeign/src/main/java/io/sentry/openfeign/SentryFeignClient.java b/sentry-openfeign/src/main/java/io/sentry/openfeign/SentryFeignClient.java index cb8aa3d9e0..037768c7ad 100644 --- a/sentry-openfeign/src/main/java/io/sentry/openfeign/SentryFeignClient.java +++ b/sentry-openfeign/src/main/java/io/sentry/openfeign/SentryFeignClient.java @@ -9,7 +9,7 @@ import io.sentry.BaggageHeader; import io.sentry.Breadcrumb; import io.sentry.Hint; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ISpan; import io.sentry.SpanDataConvention; import io.sentry.SpanStatus; @@ -30,15 +30,15 @@ public final class SentryFeignClient implements Client { private static final String TRACE_ORIGIN = "auto.http.openfeign"; private final @NotNull Client delegate; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @Nullable BeforeSpanCallback beforeSpan; public SentryFeignClient( final @NotNull Client delegate, - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @Nullable BeforeSpanCallback beforeSpan) { this.delegate = Objects.requireNonNull(delegate, "delegate is required"); - this.hub = Objects.requireNonNull(hub, "hub is required"); + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); this.beforeSpan = beforeSpan; } @@ -47,7 +47,7 @@ public Response execute(final @NotNull Request request, final @NotNull Request.O throws IOException { Response response = null; try { - final ISpan activeSpan = hub.getSpan(); + final ISpan activeSpan = scopes.getSpan(); if (activeSpan == null) { final @NotNull Request modifiedRequest = maybeAddTracingHeaders(request, null); @@ -102,7 +102,7 @@ public Response execute(final @NotNull Request request, final @NotNull Request.O final @Nullable TracingUtils.TracingHeaders tracingHeaders = TracingUtils.traceIfAllowed( - hub, + scopes, request.url(), (requestBaggageHeaders != null ? new ArrayList<>(requestBaggageHeaders) : null), span); @@ -139,7 +139,7 @@ private void addBreadcrumb(final @NotNull Request request, final @Nullable Respo hint.set(OPEN_FEIGN_RESPONSE, response); } - hub.addBreadcrumb(breadcrumb, hint); + scopes.addBreadcrumb(breadcrumb, hint); } static final class RequestWrapper { diff --git a/sentry-openfeign/src/test/kotlin/io/sentry/openfeign/SentryFeignClientTest.kt b/sentry-openfeign/src/test/kotlin/io/sentry/openfeign/SentryFeignClientTest.kt index 65e56ab02b..959b890d46 100644 --- a/sentry-openfeign/src/test/kotlin/io/sentry/openfeign/SentryFeignClientTest.kt +++ b/sentry-openfeign/src/test/kotlin/io/sentry/openfeign/SentryFeignClientTest.kt @@ -7,7 +7,7 @@ import feign.HeaderMap import feign.RequestLine import io.sentry.BaggageHeader import io.sentry.Breadcrumb -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.Scope import io.sentry.ScopeCallback import io.sentry.SentryOptions @@ -37,7 +37,7 @@ import kotlin.test.fail class SentryFeignClientTest { class Fixture { - val hub = mock() + val scopes = mock() val server = MockWebServer() val sentryTracer: SentryTracer val sentryOptions = SentryOptions().apply { @@ -46,9 +46,9 @@ class SentryFeignClientTest { val scope = Scope(sentryOptions) init { - whenever(hub.options).thenReturn(sentryOptions) - doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(hub).configureScope(any()) - sentryTracer = SentryTracer(TransactionContext("name", "op"), hub) + whenever(scopes.options).thenReturn(sentryOptions) + doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(scopes).configureScope(any()) + sentryTracer = SentryTracer(TransactionContext("name", "op"), scopes) } fun getSut( @@ -59,7 +59,7 @@ class SentryFeignClientTest { beforeSpan: SentryFeignClient.BeforeSpanCallback? = null ): MockApi { if (isSpanActive) { - whenever(hub.span).thenReturn(sentryTracer) + whenever(scopes.span).thenReturn(sentryTracer) } server.enqueue( MockResponse() @@ -70,12 +70,12 @@ class SentryFeignClientTest { return if (!networkError) { Feign.builder() - .addCapability(SentryCapability(hub, beforeSpan)) + .addCapability(SentryCapability(scopes, beforeSpan)) } else { val mockClient = mock() whenever(mockClient.execute(any(), any())).thenThrow(RuntimeException::class.java) Feign.builder() - .client(SentryFeignClient(mockClient, hub, beforeSpan)) + .client(SentryFeignClient(mockClient, scopes, beforeSpan)) }.target(MockApi::class.java, server.url("/").toUrl().toString()) } } @@ -201,7 +201,7 @@ class SentryFeignClientTest { fun `adds breadcrumb when http calls succeeds`() { val sut = fixture.getSut(responseBody = "response body") sut.postWithBody("request-body") - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(13, it.data["response_body_size"]) @@ -215,7 +215,7 @@ class SentryFeignClientTest { fun `adds breadcrumb when http calls succeeds even though response body is null`() { val sut = fixture.getSut(responseBody = "") sut.postWithBody("request-body") - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(0, it.data["response_body_size"]) @@ -236,7 +236,7 @@ class SentryFeignClientTest { } catch (e: Exception) { // ignore me } - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) }, diff --git a/sentry-quartz/api/sentry-quartz.api b/sentry-quartz/api/sentry-quartz.api index ff32280dc5..23fce49e7d 100644 --- a/sentry-quartz/api/sentry-quartz.api +++ b/sentry-quartz/api/sentry-quartz.api @@ -7,7 +7,7 @@ public final class io/sentry/quartz/SentryJobListener : org/quartz/JobListener { public static final field SENTRY_CHECK_IN_ID_KEY Ljava/lang/String; public static final field SENTRY_SLUG_KEY Ljava/lang/String; public fun ()V - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun getName ()Ljava/lang/String; public fun jobExecutionVetoed (Lorg/quartz/JobExecutionContext;)V public fun jobToBeExecuted (Lorg/quartz/JobExecutionContext;)V diff --git a/sentry-quartz/src/main/java/io/sentry/quartz/SentryJobListener.java b/sentry-quartz/src/main/java/io/sentry/quartz/SentryJobListener.java index 28a0e51200..f9c22022cc 100644 --- a/sentry-quartz/src/main/java/io/sentry/quartz/SentryJobListener.java +++ b/sentry-quartz/src/main/java/io/sentry/quartz/SentryJobListener.java @@ -3,8 +3,8 @@ import io.sentry.BuildConfig; import io.sentry.CheckIn; import io.sentry.CheckInStatus; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; +import io.sentry.ScopesAdapter; import io.sentry.SentryIntegrationPackageStorage; import io.sentry.SentryLevel; import io.sentry.protocol.SentryId; @@ -24,14 +24,14 @@ public final class SentryJobListener implements JobListener { public static final String SENTRY_CHECK_IN_ID_KEY = "sentry-checkin-id"; public static final String SENTRY_SLUG_KEY = "sentry-slug"; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; public SentryJobListener() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } - public SentryJobListener(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentryJobListener(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); SentryIntegrationPackageStorage.getInstance().addIntegration("Quartz"); SentryIntegrationPackageStorage.getInstance() .addPackage("maven:io.sentry:sentry-quartz", BuildConfig.VERSION_NAME); @@ -49,15 +49,16 @@ public void jobToBeExecuted(final @NotNull JobExecutionContext context) { if (maybeSlug == null) { return; } - hub.pushScope(); - TracingUtils.startNewTrace(hub); + scopes.pushScope(); + TracingUtils.startNewTrace(scopes); final @NotNull String slug = maybeSlug; final @NotNull CheckIn checkIn = new CheckIn(slug, CheckInStatus.IN_PROGRESS); - final @NotNull SentryId checkInId = hub.captureCheckIn(checkIn); + final @NotNull SentryId checkInId = scopes.captureCheckIn(checkIn); context.put(SENTRY_CHECK_IN_ID_KEY, checkInId); context.put(SENTRY_SLUG_KEY, slug); } catch (Throwable t) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log(SentryLevel.ERROR, "Unable to capture check-in in jobToBeExecuted.", t); } @@ -94,14 +95,15 @@ public void jobWasExecuted(JobExecutionContext context, JobExecutionException jo if (slug != null) { final boolean isFailed = jobException != null; final @NotNull CheckInStatus status = isFailed ? CheckInStatus.ERROR : CheckInStatus.OK; - hub.captureCheckIn(new CheckIn(checkInId, slug, status)); + scopes.captureCheckIn(new CheckIn(checkInId, slug, status)); } } catch (Throwable t) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log(SentryLevel.ERROR, "Unable to capture check-in in jobWasExecuted.", t); } finally { - hub.popScope(); + scopes.popScope(); } } } diff --git a/sentry-servlet-jakarta/api/sentry-servlet-jakarta.api b/sentry-servlet-jakarta/api/sentry-servlet-jakarta.api index d0367e5195..a5421e7453 100644 --- a/sentry-servlet-jakarta/api/sentry-servlet-jakarta.api +++ b/sentry-servlet-jakarta/api/sentry-servlet-jakarta.api @@ -10,7 +10,7 @@ public class io/sentry/servlet/jakarta/SentryServletContainerInitializer : jakar public class io/sentry/servlet/jakarta/SentryServletRequestListener : jakarta/servlet/ServletRequestListener { public fun ()V - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun requestDestroyed (Ljakarta/servlet/ServletRequestEvent;)V public fun requestInitialized (Ljakarta/servlet/ServletRequestEvent;)V } diff --git a/sentry-servlet-jakarta/src/main/java/io/sentry/servlet/jakarta/SentryServletRequestListener.java b/sentry-servlet-jakarta/src/main/java/io/sentry/servlet/jakarta/SentryServletRequestListener.java index e3811157f8..54775386fd 100644 --- a/sentry-servlet-jakarta/src/main/java/io/sentry/servlet/jakarta/SentryServletRequestListener.java +++ b/sentry-servlet-jakarta/src/main/java/io/sentry/servlet/jakarta/SentryServletRequestListener.java @@ -5,8 +5,8 @@ import com.jakewharton.nopen.annotation.Open; import io.sentry.Breadcrumb; import io.sentry.Hint; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; +import io.sentry.ScopesAdapter; import io.sentry.util.Objects; import jakarta.servlet.ServletRequest; import jakarta.servlet.ServletRequestEvent; @@ -21,24 +21,24 @@ @Open public class SentryServletRequestListener implements ServletRequestListener { - private final IHub hub; + private final IScopes scopes; - public SentryServletRequestListener(@NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentryServletRequestListener(@NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } public SentryServletRequestListener() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } @Override public void requestDestroyed(@NotNull ServletRequestEvent servletRequestEvent) { - hub.popScope(); + scopes.popScope(); } @Override public void requestInitialized(@NotNull ServletRequestEvent servletRequestEvent) { - hub.pushScope(); + scopes.pushScope(); final ServletRequest servletRequest = servletRequestEvent.getServletRequest(); if (servletRequest instanceof HttpServletRequest) { @@ -47,10 +47,10 @@ public void requestInitialized(@NotNull ServletRequestEvent servletRequestEvent) final Hint hint = new Hint(); hint.set(SERVLET_REQUEST, httpRequest); - hub.addBreadcrumb( + scopes.addBreadcrumb( Breadcrumb.http(httpRequest.getRequestURI(), httpRequest.getMethod()), hint); - hub.configureScope( + scopes.configureScope( scope -> { scope.addEventProcessor(new SentryRequestHttpServletRequestProcessor(httpRequest)); }); diff --git a/sentry-servlet-jakarta/src/test/kotlin/io/sentry/servlet/jakarta/SentryServletRequestListenerTest.kt b/sentry-servlet-jakarta/src/test/kotlin/io/sentry/servlet/jakarta/SentryServletRequestListenerTest.kt index b87ea218a2..3be76d1cd2 100644 --- a/sentry-servlet-jakarta/src/test/kotlin/io/sentry/servlet/jakarta/SentryServletRequestListenerTest.kt +++ b/sentry-servlet-jakarta/src/test/kotlin/io/sentry/servlet/jakarta/SentryServletRequestListenerTest.kt @@ -1,7 +1,7 @@ package io.sentry.servlet.jakarta import io.sentry.Breadcrumb -import io.sentry.IHub +import io.sentry.IScopes import jakarta.servlet.ServletRequestEvent import org.mockito.kotlin.anyOrNull import org.mockito.kotlin.check @@ -13,9 +13,9 @@ import kotlin.test.assertEquals class SentryServletRequestListenerTest { private class Fixture { - val hub = mock() + val scopes = mock() val listener = - SentryServletRequestListener(hub) + SentryServletRequestListener(scopes) val request = mockRequest( url = "http://localhost:8080/some-uri", method = "POST" @@ -33,14 +33,14 @@ class SentryServletRequestListenerTest { fun `pushes scope when request gets initialized`() { fixture.listener.requestInitialized(fixture.event) - verify(fixture.hub).pushScope() + verify(fixture.scopes).pushScope() } @Test fun `adds breadcrumb when request gets initialized`() { fixture.listener.requestInitialized(fixture.event) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { it: Breadcrumb -> assertEquals("/some-uri", it.getData("url")) assertEquals("POST", it.getData("method")) @@ -54,6 +54,6 @@ class SentryServletRequestListenerTest { fun `pops scope when request gets destroyed`() { fixture.listener.requestDestroyed(fixture.event) - verify(fixture.hub).popScope() + verify(fixture.scopes).popScope() } } diff --git a/sentry-servlet/api/sentry-servlet.api b/sentry-servlet/api/sentry-servlet.api index a0a2a1e0d2..fd7aee819b 100644 --- a/sentry-servlet/api/sentry-servlet.api +++ b/sentry-servlet/api/sentry-servlet.api @@ -10,7 +10,7 @@ public class io/sentry/servlet/SentryServletContainerInitializer : javax/servlet public class io/sentry/servlet/SentryServletRequestListener : javax/servlet/ServletRequestListener { public fun ()V - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun requestDestroyed (Ljavax/servlet/ServletRequestEvent;)V public fun requestInitialized (Ljavax/servlet/ServletRequestEvent;)V } diff --git a/sentry-servlet/src/main/java/io/sentry/servlet/SentryServletRequestListener.java b/sentry-servlet/src/main/java/io/sentry/servlet/SentryServletRequestListener.java index 9b981676c4..97c37e1133 100644 --- a/sentry-servlet/src/main/java/io/sentry/servlet/SentryServletRequestListener.java +++ b/sentry-servlet/src/main/java/io/sentry/servlet/SentryServletRequestListener.java @@ -5,8 +5,8 @@ import com.jakewharton.nopen.annotation.Open; import io.sentry.Breadcrumb; import io.sentry.Hint; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; +import io.sentry.ScopesAdapter; import io.sentry.util.Objects; import javax.servlet.ServletRequest; import javax.servlet.ServletRequestEvent; @@ -21,24 +21,24 @@ @Open public class SentryServletRequestListener implements ServletRequestListener { - private final IHub hub; + private final IScopes scopes; - public SentryServletRequestListener(@NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentryServletRequestListener(@NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } public SentryServletRequestListener() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } @Override public void requestDestroyed(@NotNull ServletRequestEvent servletRequestEvent) { - hub.popScope(); + scopes.popScope(); } @Override public void requestInitialized(@NotNull ServletRequestEvent servletRequestEvent) { - hub.pushScope(); + scopes.pushScope(); final ServletRequest servletRequest = servletRequestEvent.getServletRequest(); if (servletRequest instanceof HttpServletRequest) { @@ -47,10 +47,10 @@ public void requestInitialized(@NotNull ServletRequestEvent servletRequestEvent) final Hint hint = new Hint(); hint.set(SERVLET_REQUEST, httpRequest); - hub.addBreadcrumb( + scopes.addBreadcrumb( Breadcrumb.http(httpRequest.getRequestURI(), httpRequest.getMethod()), hint); - hub.configureScope( + scopes.configureScope( scope -> { scope.addEventProcessor(new SentryRequestHttpServletRequestProcessor(httpRequest)); }); diff --git a/sentry-servlet/src/test/kotlin/io/sentry/servlet/SentryServletRequestListenerTest.kt b/sentry-servlet/src/test/kotlin/io/sentry/servlet/SentryServletRequestListenerTest.kt index b94e73f2ef..bfa216f738 100644 --- a/sentry-servlet/src/test/kotlin/io/sentry/servlet/SentryServletRequestListenerTest.kt +++ b/sentry-servlet/src/test/kotlin/io/sentry/servlet/SentryServletRequestListenerTest.kt @@ -1,7 +1,7 @@ package io.sentry.servlet import io.sentry.Breadcrumb -import io.sentry.IHub +import io.sentry.IScopes import org.assertj.core.api.Assertions.assertThat import org.mockito.kotlin.anyOrNull import org.mockito.kotlin.check @@ -14,8 +14,8 @@ import kotlin.test.Test class SentryServletRequestListenerTest { private class Fixture { - val hub = mock() - val listener = SentryServletRequestListener(hub) + val scopes = mock() + val listener = SentryServletRequestListener(scopes) val request = MockHttpServletRequest() val event = mock() @@ -32,14 +32,14 @@ class SentryServletRequestListenerTest { fun `pushes scope when request gets initialized`() { fixture.listener.requestInitialized(fixture.event) - verify(fixture.hub).pushScope() + verify(fixture.scopes).pushScope() } @Test fun `adds breadcrumb when request gets initialized`() { fixture.listener.requestInitialized(fixture.event) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { it: Breadcrumb -> assertThat(it.getData("url")).isEqualTo("http://localhost:8080/some-uri") assertThat(it.getData("method")).isEqualTo("POST") @@ -53,6 +53,6 @@ class SentryServletRequestListenerTest { fun `pops scope when request gets destroyed`() { fixture.listener.requestDestroyed(fixture.event) - verify(fixture.hub).popScope() + verify(fixture.scopes).popScope() } } diff --git a/sentry-test-support/api/sentry-test-support.api b/sentry-test-support/api/sentry-test-support.api index ffce23a516..dd1a4b69d3 100644 --- a/sentry-test-support/api/sentry-test-support.api +++ b/sentry-test-support/api/sentry-test-support.api @@ -32,6 +32,7 @@ public final class io/sentry/test/ImmediateExecutorService : io/sentry/ISentryEx } public final class io/sentry/test/ReflectionKt { + public static final fun collectInterfaceHierarchy (Ljava/lang/Class;)Ljava/util/List; public static final fun containsMethod (Ljava/lang/Class;Ljava/lang/String;Ljava/lang/Class;)Z public static final fun containsMethod (Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/Class;)Z public static final fun getCtor (Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Constructor; diff --git a/sentry-test-support/src/main/kotlin/io/sentry/test/Reflection.kt b/sentry-test-support/src/main/kotlin/io/sentry/test/Reflection.kt index 690dcc8725..19d11676e1 100644 --- a/sentry-test-support/src/main/kotlin/io/sentry/test/Reflection.kt +++ b/sentry-test-support/src/main/kotlin/io/sentry/test/Reflection.kt @@ -12,16 +12,23 @@ inline fun T.callMethod(name: String, parameterTypes: Class<*> val declaredMethod = try { T::class.java.getDeclaredMethod(name, parameterTypes) } catch (e: NoSuchMethodException) { - T::class.java.interfaces.first { it.containsMethod(name, parameterTypes) }.getDeclaredMethod(name, parameterTypes) + collectInterfaceHierarchy(T::class.java).first { it.containsMethod(name, parameterTypes) }.getDeclaredMethod(name, parameterTypes) } return declaredMethod.invoke(this, value) } +fun collectInterfaceHierarchy(clazz: Class<*>): List> { + if (clazz.interfaces.isEmpty()) { + return listOf(clazz) + } + return clazz.interfaces.flatMap { iface -> collectInterfaceHierarchy(iface) }.also { it.toMutableList().add(clazz) } +} + inline fun T.callMethod(name: String, parameterTypes: Array>, vararg value: Any?): Any? { val declaredMethod = try { T::class.java.getDeclaredMethod(name, *parameterTypes) } catch (e: NoSuchMethodException) { - T::class.java.interfaces.first { it.containsMethod(name, parameterTypes) }.getDeclaredMethod(name, *parameterTypes) + collectInterfaceHierarchy(T::class.java).first { it.containsMethod(name, parameterTypes) }.getDeclaredMethod(name, *parameterTypes) } return declaredMethod.invoke(this, *value) } From 739827ab98f30b4b7b06567167e9e84aa2857092 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Tue, 2 Apr 2024 14:43:12 +0200 Subject: [PATCH 12/28] Replace `IHub` with `IScopes` in OTel integration --- .../OpenTelemetryLinkErrorEventProcessor.java | 26 ++++++---- .../opentelemetry/SentryPropagator.java | 24 +++++---- .../opentelemetry/SentrySpanProcessor.java | 50 +++++++++++-------- .../test/kotlin/SentrySpanProcessorTest.kt | 46 ++++++++--------- 4 files changed, 82 insertions(+), 64 deletions(-) diff --git a/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/OpenTelemetryLinkErrorEventProcessor.java b/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/OpenTelemetryLinkErrorEventProcessor.java index 1e373ece9c..bfc4cd05f1 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/OpenTelemetryLinkErrorEventProcessor.java +++ b/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/OpenTelemetryLinkErrorEventProcessor.java @@ -5,10 +5,10 @@ import io.opentelemetry.api.trace.TraceId; import io.sentry.EventProcessor; import io.sentry.Hint; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ISpan; import io.sentry.Instrumenter; +import io.sentry.ScopesAdapter; import io.sentry.SentryEvent; import io.sentry.SentryLevel; import io.sentry.SentrySpanStorage; @@ -20,21 +20,21 @@ public final class OpenTelemetryLinkErrorEventProcessor implements EventProcessor { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @NotNull SentrySpanStorage spanStorage = SentrySpanStorage.getInstance(); public OpenTelemetryLinkErrorEventProcessor() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } @TestOnly - OpenTelemetryLinkErrorEventProcessor(final @NotNull IHub hub) { - this.hub = hub; + OpenTelemetryLinkErrorEventProcessor(final @NotNull IScopes scopes) { + this.scopes = scopes; } @Override public @Nullable SentryEvent process(final @NotNull SentryEvent event, final @NotNull Hint hint) { - final @NotNull Instrumenter instrumenter = hub.getOptions().getInstrumenter(); + final @NotNull Instrumenter instrumenter = scopes.getOptions().getInstrumenter(); if (Instrumenter.OTEL.equals(instrumenter)) { @NotNull final Span otelSpan = Span.current(); @NotNull final String traceId = otelSpan.getSpanContext().getTraceId(); @@ -55,7 +55,8 @@ public OpenTelemetryLinkErrorEventProcessor() { null); event.getContexts().setTrace(spanContext); - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -64,7 +65,8 @@ public OpenTelemetryLinkErrorEventProcessor() { spanId, traceId); } else { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -74,7 +76,8 @@ public OpenTelemetryLinkErrorEventProcessor() { traceId); } } else { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -84,7 +87,8 @@ public OpenTelemetryLinkErrorEventProcessor() { spanId); } } else { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, diff --git a/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/SentryPropagator.java b/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/SentryPropagator.java index 14ac12323b..ed3e243f4d 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/SentryPropagator.java +++ b/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/SentryPropagator.java @@ -10,9 +10,9 @@ import io.opentelemetry.context.propagation.TextMapSetter; import io.sentry.Baggage; import io.sentry.BaggageHeader; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ISpan; +import io.sentry.ScopesAdapter; import io.sentry.SentryLevel; import io.sentry.SentrySpanStorage; import io.sentry.SentryTraceHeader; @@ -29,14 +29,14 @@ public final class SentryPropagator implements TextMapPropagator { private static final @NotNull List FIELDS = Arrays.asList(SentryTraceHeader.SENTRY_TRACE_HEADER, BaggageHeader.BAGGAGE_HEADER); private final @NotNull SentrySpanStorage spanStorage = SentrySpanStorage.getInstance(); - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; public SentryPropagator() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } - SentryPropagator(final @NotNull IHub hub) { - this.hub = hub; + SentryPropagator(final @NotNull IScopes scopes) { + this.scopes = scopes; } @Override @@ -49,7 +49,8 @@ public void inject(final Context context, final C carrier, final TextMapSett final @NotNull Span otelSpan = Span.fromContext(context); final @NotNull SpanContext otelSpanContext = otelSpan.getSpanContext(); if (!otelSpanContext.isValid()) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -58,7 +59,8 @@ public void inject(final Context context, final C carrier, final TextMapSett } final @Nullable ISpan sentrySpan = spanStorage.get(otelSpanContext.getSpanId()); if (sentrySpan == null || sentrySpan.isNoOp()) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -106,13 +108,15 @@ public Context extract( Span wrappedSpan = Span.wrap(otelSpanContext); modifiedContext = modifiedContext.with(wrappedSpan); - hub.getOptions() + scopes + .getOptions() .getLogger() .log(SentryLevel.DEBUG, "Continuing Sentry trace %s", sentryTraceHeader.getTraceId()); return modifiedContext; } catch (InvalidSentryTraceHeaderException e) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.ERROR, diff --git a/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/SentrySpanProcessor.java b/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/SentrySpanProcessor.java index a9e70f66a0..6b7797153b 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/SentrySpanProcessor.java +++ b/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/SentrySpanProcessor.java @@ -13,12 +13,12 @@ import io.opentelemetry.semconv.SemanticAttributes; import io.sentry.Baggage; import io.sentry.DsnUtil; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ISpan; import io.sentry.ITransaction; import io.sentry.Instrumenter; import io.sentry.PropagationContext; +import io.sentry.ScopesAdapter; import io.sentry.SentryDate; import io.sentry.SentryLevel; import io.sentry.SentryLongDate; @@ -46,14 +46,14 @@ public final class SentrySpanProcessor implements SpanProcessor { private final @NotNull SpanDescriptionExtractor spanDescriptionExtractor = new SpanDescriptionExtractor(); private final @NotNull SentrySpanStorage spanStorage = SentrySpanStorage.getInstance(); - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; public SentrySpanProcessor() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } - SentrySpanProcessor(final @NotNull IHub hub) { - this.hub = hub; + SentrySpanProcessor(final @NotNull IScopes scopes) { + this.scopes = scopes; } @Override @@ -65,7 +65,8 @@ public void onStart(final @NotNull Context parentContext, final @NotNull ReadWri final @NotNull TraceData traceData = getTraceData(otelSpan, parentContext); if (isSentryRequest(otelSpan)) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -78,7 +79,8 @@ public void onStart(final @NotNull Context parentContext, final @NotNull ReadWri traceData.getParentSpanId() == null ? null : spanStorage.get(traceData.getParentSpanId()); if (sentryParentSpan != null) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -94,7 +96,8 @@ public void onStart(final @NotNull Context parentContext, final @NotNull ReadWri sentryChildSpan.getSpanContext().setOrigin(TRACE_ORIGN); spanStorage.store(traceData.getSpanId(), sentryChildSpan); } else { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -123,7 +126,7 @@ public void onStart(final @NotNull Context parentContext, final @NotNull ReadWri transactionOptions.setStartTimestamp( new SentryLongDate(otelSpan.toSpanData().getStartEpochNanos())); - ISpan sentryTransaction = hub.startTransaction(transactionContext, transactionOptions); + ISpan sentryTransaction = scopes.startTransaction(transactionContext, transactionOptions); sentryTransaction.getSpanContext().setOrigin(TRACE_ORIGN); spanStorage.store(traceData.getSpanId(), sentryTransaction); } @@ -144,7 +147,8 @@ public void onEnd(final @NotNull ReadableSpan otelSpan) { final @Nullable ISpan sentrySpan = spanStorage.removeAndGet(traceData.getSpanId()); if (sentrySpan == null) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -155,7 +159,8 @@ public void onEnd(final @NotNull ReadableSpan otelSpan) { } if (isSentryRequest(otelSpan)) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -168,7 +173,8 @@ public void onEnd(final @NotNull ReadableSpan otelSpan) { if (sentrySpan instanceof ITransaction) { final @NotNull ITransaction sentryTransaction = (ITransaction) sentrySpan; updateTransactionWithOtelData(sentryTransaction, otelSpan); - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -178,7 +184,8 @@ public void onEnd(final @NotNull ReadableSpan otelSpan) { traceData.getTraceId()); } else { updateSpanWithOtelData(sentrySpan, otelSpan); - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -201,7 +208,8 @@ public boolean isEndRequired() { private boolean ensurePrerequisites(final @NotNull ReadableSpan otelSpan) { if (!hasSentryBeenInitialized()) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -209,9 +217,10 @@ private boolean ensurePrerequisites(final @NotNull ReadableSpan otelSpan) { return false; } - final @NotNull Instrumenter instrumenter = hub.getOptions().getInstrumenter(); + final @NotNull Instrumenter instrumenter = scopes.getOptions().getInstrumenter(); if (!Instrumenter.OTEL.equals(instrumenter)) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -222,7 +231,8 @@ private boolean ensurePrerequisites(final @NotNull ReadableSpan otelSpan) { final @NotNull SpanContext otelSpanContext = otelSpan.getSpanContext(); if (!otelSpanContext.isValid()) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.DEBUG, @@ -241,7 +251,7 @@ private boolean isSentryRequest(final @NotNull ReadableSpan otelSpan) { } final @Nullable String httpUrl = otelSpan.getAttribute(SemanticAttributes.HTTP_URL); - return DsnUtil.urlContainsDsnHost(hub.getOptions(), httpUrl); + return DsnUtil.urlContainsDsnHost(scopes.getOptions(), httpUrl); } private @NotNull TraceData getTraceData( @@ -334,7 +344,7 @@ private SpanStatus mapOtelStatus(final @NotNull ReadableSpan otelSpan) { } private boolean hasSentryBeenInitialized() { - return hub.isEnabled(); + return scopes.isEnabled(); } private @NotNull Map toMapWithStringKeys(final @Nullable Attributes attributes) { diff --git a/sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/SentrySpanProcessorTest.kt b/sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/SentrySpanProcessorTest.kt index 5ed757ba16..50d70f34f5 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/SentrySpanProcessorTest.kt +++ b/sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/SentrySpanProcessorTest.kt @@ -21,7 +21,7 @@ import io.opentelemetry.semconv.SemanticAttributes import io.sentry.Baggage import io.sentry.BaggageHeader import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ISpan import io.sentry.ITransaction import io.sentry.Instrumenter @@ -65,7 +65,7 @@ class SentrySpanProcessorTest { it.dsn = "https://key@sentry.io/proj" it.instrumenter = Instrumenter.OTEL } - val hub = mock() + val scopes = mock() val transaction = mock() val span = mock() val spanContext = mock() @@ -75,9 +75,9 @@ class SentrySpanProcessorTest { val baggage = Baggage.fromHeader(BAGGAGE_HEADER_STRING) fun setup() { - whenever(hub.isEnabled).thenReturn(true) - whenever(hub.options).thenReturn(options) - whenever(hub.startTransaction(any(), any())).thenReturn(transaction) + whenever(scopes.isEnabled).thenReturn(true) + whenever(scopes.options).thenReturn(options) + whenever(scopes.startTransaction(any(), any())).thenReturn(transaction) whenever(spanContext.operation).thenReturn("spanContextOp") whenever(spanContext.parentSpanId).thenReturn(io.sentry.SpanId("cedf5b7571cb4972")) @@ -94,7 +94,7 @@ class SentrySpanProcessorTest { whenever(transaction.startChild(any(), anyOrNull(), anyOrNull(), eq(Instrumenter.OTEL))).thenReturn(span) val sdkTracerProvider = SdkTracerProvider.builder() - .addSpanProcessor(SentrySpanProcessor(hub)) + .addSpanProcessor(SentrySpanProcessor(scopes)) .build() openTelemetry = OpenTelemetrySdk.builder() @@ -146,13 +146,13 @@ class SentrySpanProcessorTest { val context = mock() val span = mock() - whenever(fixture.hub.isEnabled).thenReturn(false) + whenever(fixture.scopes.isEnabled).thenReturn(false) - SentrySpanProcessor(fixture.hub).onStart(context, span) + SentrySpanProcessor(fixture.scopes).onStart(context, span) - verify(fixture.hub).isEnabled - verify(fixture.hub).options - verifyNoMoreInteractions(fixture.hub) + verify(fixture.scopes).isEnabled + verify(fixture.scopes).options + verifyNoMoreInteractions(fixture.scopes) verifyNoInteractions(context, span) } @@ -161,13 +161,13 @@ class SentrySpanProcessorTest { fixture.setup() val span = mock() - whenever(fixture.hub.isEnabled).thenReturn(false) + whenever(fixture.scopes.isEnabled).thenReturn(false) - SentrySpanProcessor(fixture.hub).onEnd(span) + SentrySpanProcessor(fixture.scopes).onEnd(span) - verify(fixture.hub).isEnabled - verify(fixture.hub).options - verifyNoMoreInteractions(fixture.hub) + verify(fixture.scopes).isEnabled + verify(fixture.scopes).options + verifyNoMoreInteractions(fixture.scopes) verifyNoInteractions(span) } @@ -178,7 +178,7 @@ class SentrySpanProcessorTest { val mockSpanContext = mock() whenever(mockSpanContext.spanId).thenReturn(SpanId.getInvalid()) whenever(mockSpan.spanContext).thenReturn(mockSpanContext) - SentrySpanProcessor(fixture.hub).onStart(Context.current(), mockSpan) + SentrySpanProcessor(fixture.scopes).onStart(Context.current(), mockSpan) thenNoTransactionIsStarted() } @@ -190,7 +190,7 @@ class SentrySpanProcessorTest { whenever(mockSpanContext.spanId).thenReturn(SpanId.fromBytes("seed".toByteArray())) whenever(mockSpanContext.traceId).thenReturn(TraceId.getInvalid()) whenever(mockSpan.spanContext).thenReturn(mockSpanContext) - SentrySpanProcessor(fixture.hub).onStart(Context.current(), mockSpan) + SentrySpanProcessor(fixture.scopes).onStart(Context.current(), mockSpan) thenNoTransactionIsStarted() } @@ -342,7 +342,7 @@ class SentrySpanProcessorTest { thenTransactionIsStarted(otelSpan, isContinued = true) otelSpan.makeCurrent().use { _ -> - val processedEvent = OpenTelemetryLinkErrorEventProcessor(fixture.hub).process(SentryEvent(), Hint()) + val processedEvent = OpenTelemetryLinkErrorEventProcessor(fixture.scopes).process(SentryEvent(), Hint()) val traceContext = processedEvent!!.contexts.trace!! assertEquals("2722d9f6ec019ade60c776169d9a8904", traceContext.traceId.toString()) @@ -361,7 +361,7 @@ class SentrySpanProcessorTest { fixture.options.instrumenter = Instrumenter.SENTRY fixture.setup() - val processedEvent = OpenTelemetryLinkErrorEventProcessor(fixture.hub).process(SentryEvent(), Hint()) + val processedEvent = OpenTelemetryLinkErrorEventProcessor(fixture.scopes).process(SentryEvent(), Hint()) thenNoTraceContextHasBeenAddedToEvent(processedEvent) } @@ -393,7 +393,7 @@ class SentrySpanProcessorTest { private fun thenTransactionIsStarted(otelSpan: Span, isContinued: Boolean = false, continuesWithFilledBaggage: Boolean = true) { if (isContinued) { - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( check { assertEquals("testspan", it.name) assertEquals(TransactionNameSource.CUSTOM, it.transactionNameSource) @@ -423,7 +423,7 @@ class SentrySpanProcessorTest { } ) } else { - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( check { assertEquals("testspan", it.name) assertEquals(TransactionNameSource.CUSTOM, it.transactionNameSource) @@ -451,7 +451,7 @@ class SentrySpanProcessorTest { } private fun thenNoTransactionIsStarted() { - verify(fixture.hub, never()).startTransaction( + verify(fixture.scopes, never()).startTransaction( any(), any() ) From 69f2d63dac76b396c44f09e6103685d5a45d59f5 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Tue, 2 Apr 2024 14:51:42 +0200 Subject: [PATCH 13/28] Replace `IHub` with `IScopes` in Spring 5 / Spring Boot 2 integrations --- sentry-spring-boot/api/sentry-spring-boot.api | 4 +- .../spring/boot/SentryAutoConfiguration.java | 39 ++++---- .../SentrySpanRestTemplateCustomizer.java | 6 +- .../boot/SentrySpanWebClientCustomizer.java | 6 +- .../boot/SentryWebfluxAutoConfiguration.java | 15 +-- .../boot/SentryAutoConfigurationTest.kt | 12 +-- .../SentrySpanRestTemplateCustomizerTest.kt | 22 ++--- .../boot/SentrySpanWebClientCustomizerTest.kt | 22 ++--- .../boot/it/SentrySpringIntegrationTest.kt | 6 +- sentry-spring/api/sentry-spring.api | 37 ++++---- .../spring/SentryExceptionResolver.java | 10 +- .../io/sentry/spring/SentryHubRegistrar.java | 4 +- .../spring/SentryInitBeanPostProcessor.java | 16 ++-- .../sentry/spring/SentryRequestResolver.java | 16 ++-- .../io/sentry/spring/SentrySpringFilter.java | 38 ++++---- .../io/sentry/spring/SentryTaskDecorator.java | 14 +-- .../io/sentry/spring/SentryUserFilter.java | 12 +-- .../spring/checkin/SentryCheckInAdvice.java | 28 +++--- ...SentryCaptureExceptionParameterAdvice.java | 14 +-- .../graphql/SentryBatchLoaderRegistry.java | 16 ++-- .../graphql/SentryDgsSubscriptionHandler.java | 6 +- .../SentrySpringSubscriptionHandler.java | 6 +- .../spring/tracing/SentrySpanAdvice.java | 14 +-- ...entrySpanClientHttpRequestInterceptor.java | 14 +-- .../SentrySpanClientWebRequestFilter.java | 14 +-- .../spring/tracing/SentryTracingFilter.java | 31 +++--- .../tracing/SentryTransactionAdvice.java | 20 ++-- .../spring/webflux/SentryRequestResolver.java | 13 +-- .../spring/webflux/SentryScheduleHook.java | 12 ++- .../webflux/SentryWebExceptionHandler.java | 10 +- .../spring/webflux/SentryWebFilter.java | 33 ++++--- .../io/sentry/spring/EnableSentryTest.kt | 6 +- .../sentry/spring/SentryCheckInAdviceTest.kt | 94 +++++++++---------- .../spring/SentryExceptionResolverTest.kt | 28 +++--- .../spring/SentryInitBeanPostProcessorTest.kt | 10 +- ...yRequestHttpServletRequestProcessorTest.kt | 6 +- .../sentry/spring/SentrySpringFilterTest.kt | 20 ++-- .../sentry/spring/SentryTaskDecoratorTest.kt | 16 ++-- .../io/sentry/spring/SentryUserFilterTest.kt | 20 ++-- ...ntryCaptureExceptionParameterAdviceTest.kt | 16 ++-- .../SentrySpringSubscriptionHandlerTest.kt | 14 +-- .../spring/mvc/SentrySpringIntegrationTest.kt | 24 ++--- .../spring/tracing/SentrySpanAdviceTest.kt | 40 ++++---- .../spring/tracing/SentryTracingFilterTest.kt | 52 +++++----- .../tracing/SentryTransactionAdviceTest.kt | 38 ++++---- .../spring/webflux/SentryScheduleHookTest.kt | 14 +-- .../webflux/SentryWebFluxTracingFilterTest.kt | 93 +++++++++--------- .../webflux/SentryWebfluxIntegrationTest.kt | 10 +- 48 files changed, 516 insertions(+), 495 deletions(-) diff --git a/sentry-spring-boot/api/sentry-spring-boot.api b/sentry-spring-boot/api/sentry-spring-boot.api index 32d7cc8c60..d97e2e1111 100644 --- a/sentry-spring-boot/api/sentry-spring-boot.api +++ b/sentry-spring-boot/api/sentry-spring-boot.api @@ -53,8 +53,8 @@ public class io/sentry/spring/boot/SentryProperties$Logging { public class io/sentry/spring/boot/SentryWebfluxAutoConfiguration { public fun ()V public fun sentryScheduleHookApplicationRunner ()Lorg/springframework/boot/ApplicationRunner; - public fun sentryWebExceptionHandler (Lio/sentry/IHub;)Lio/sentry/spring/webflux/SentryWebExceptionHandler; - public fun sentryWebFilter (Lio/sentry/IHub;)Lio/sentry/spring/webflux/SentryWebFilter; + public fun sentryWebExceptionHandler (Lio/sentry/IScopes;)Lio/sentry/spring/webflux/SentryWebExceptionHandler; + public fun sentryWebFilter (Lio/sentry/IScopes;)Lio/sentry/spring/webflux/SentryWebFilter; } public class io/sentry/spring/boot/graphql/SentryGraphqlAutoConfiguration { diff --git a/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentryAutoConfiguration.java b/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentryAutoConfiguration.java index edbfee271d..7d6a6a6fc4 100644 --- a/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentryAutoConfiguration.java +++ b/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentryAutoConfiguration.java @@ -3,10 +3,10 @@ import com.jakewharton.nopen.annotation.Open; import graphql.GraphQLError; import io.sentry.EventProcessor; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ITransportFactory; import io.sentry.Integration; +import io.sentry.ScopesAdapter; import io.sentry.Sentry; import io.sentry.SentryIntegrationPackageStorage; import io.sentry.SentryOptions; @@ -114,7 +114,7 @@ static class HubConfiguration { } @Bean - public @NotNull IHub sentryHub( + public @NotNull IScopes sentryHub( final @NotNull List> optionsConfigurations, final @NotNull SentryProperties options, final @NotNull ObjectProvider gitProperties) { @@ -137,7 +137,7 @@ static class HubConfiguration { // here we make sure that only classes that extend throwable are set on this field options.getIgnoredExceptionsForType().removeIf(it -> !Throwable.class.isAssignableFrom(it)); Sentry.init(options); - return HubAdapter.getInstance(); + return ScopesAdapter.getInstance(); } @Configuration(proxyBeanMethods = false) @@ -237,7 +237,7 @@ static class SentrySecurityConfiguration { * HttpServletRequest#getUserPrincipal()}. If Spring Security is auto-configured, its order is * set to run after Spring Security. * - * @param hub the Sentry hub + * @param scopes the Sentry scopes * @param sentryProperties the Sentry properties * @param sentryUserProvider the user provider * @return {@link SentryUserFilter} registration bean @@ -245,11 +245,11 @@ static class SentrySecurityConfiguration { @Bean @ConditionalOnBean(SentryUserProvider.class) public @NotNull FilterRegistrationBean sentryUserFilter( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull SentryProperties sentryProperties, final @NotNull List sentryUserProvider) { final FilterRegistrationBean filter = new FilterRegistrationBean<>(); - filter.setFilter(new SentryUserFilter(hub, sentryUserProvider)); + filter.setFilter(new SentryUserFilter(scopes, sentryUserProvider)); filter.setOrder(resolveUserFilterOrder(sentryProperties)); return filter; } @@ -261,8 +261,8 @@ static class SentrySecurityConfiguration { } @Bean - public @NotNull SentryRequestResolver sentryRequestResolver(final @NotNull IHub hub) { - return new SentryRequestResolver(hub); + public @NotNull SentryRequestResolver sentryRequestResolver(final @NotNull IScopes scopes) { + return new SentryRequestResolver(scopes); } @Bean @@ -274,12 +274,12 @@ static class SentrySecurityConfiguration { @Bean @ConditionalOnMissingBean(name = "sentrySpringFilter") public @NotNull FilterRegistrationBean sentrySpringFilter( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull SentryRequestResolver requestResolver, final @NotNull TransactionNameProvider transactionNameProvider) { FilterRegistrationBean filter = new FilterRegistrationBean<>( - new SentrySpringFilter(hub, requestResolver, transactionNameProvider)); + new SentrySpringFilter(scopes, requestResolver, transactionNameProvider)); filter.setOrder(SENTRY_SPRING_FILTER_PRECEDENCE); return filter; } @@ -287,9 +287,10 @@ static class SentrySecurityConfiguration { @Bean @ConditionalOnMissingBean(name = "sentryTracingFilter") public FilterRegistrationBean sentryTracingFilter( - final @NotNull IHub hub, final @NotNull TransactionNameProvider transactionNameProvider) { + final @NotNull IScopes scopes, + final @NotNull TransactionNameProvider transactionNameProvider) { FilterRegistrationBean filter = - new FilterRegistrationBean<>(new SentryTracingFilter(hub, transactionNameProvider)); + new FilterRegistrationBean<>(new SentryTracingFilter(scopes, transactionNameProvider)); filter.setOrder(SENTRY_SPRING_FILTER_PRECEDENCE + 1); // must run after SentrySpringFilter return filter; } @@ -298,11 +299,11 @@ public FilterRegistrationBean sentryTracingFilter( @ConditionalOnMissingBean @ConditionalOnClass(HandlerExceptionResolver.class) public @NotNull SentryExceptionResolver sentryExceptionResolver( - final @NotNull IHub sentryHub, + final @NotNull IScopes scopes, final @NotNull TransactionNameProvider transactionNameProvider, final @NotNull SentryProperties options) { return new SentryExceptionResolver( - sentryHub, transactionNameProvider, options.getExceptionResolverOrder()); + scopes, transactionNameProvider, options.getExceptionResolverOrder()); } } @@ -348,8 +349,8 @@ static class SentrySpanPointcutAutoConfiguration {} @Open static class SentryPerformanceRestTemplateConfiguration { @Bean - public SentrySpanRestTemplateCustomizer sentrySpanRestTemplateCustomizer(IHub hub) { - return new SentrySpanRestTemplateCustomizer(hub); + public SentrySpanRestTemplateCustomizer sentrySpanRestTemplateCustomizer(IScopes scopes) { + return new SentrySpanRestTemplateCustomizer(scopes); } } @@ -359,8 +360,8 @@ public SentrySpanRestTemplateCustomizer sentrySpanRestTemplateCustomizer(IHub hu @Open static class SentryPerformanceWebClientConfiguration { @Bean - public SentrySpanWebClientCustomizer sentrySpanWebClientCustomizer(IHub hub) { - return new SentrySpanWebClientCustomizer(hub); + public SentrySpanWebClientCustomizer sentrySpanWebClientCustomizer(IScopes scopes) { + return new SentrySpanWebClientCustomizer(scopes); } } diff --git a/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentrySpanRestTemplateCustomizer.java b/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentrySpanRestTemplateCustomizer.java index bd311c55f1..2a5e4f1be5 100644 --- a/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentrySpanRestTemplateCustomizer.java +++ b/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentrySpanRestTemplateCustomizer.java @@ -1,7 +1,7 @@ package io.sentry.spring.boot; import com.jakewharton.nopen.annotation.Open; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.spring.tracing.SentrySpanClientHttpRequestInterceptor; import java.util.ArrayList; import java.util.List; @@ -14,8 +14,8 @@ class SentrySpanRestTemplateCustomizer implements RestTemplateCustomizer { private final @NotNull SentrySpanClientHttpRequestInterceptor interceptor; - public SentrySpanRestTemplateCustomizer(final @NotNull IHub hub) { - this.interceptor = new SentrySpanClientHttpRequestInterceptor(hub); + public SentrySpanRestTemplateCustomizer(final @NotNull IScopes scopes) { + this.interceptor = new SentrySpanClientHttpRequestInterceptor(scopes); } @Override diff --git a/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentrySpanWebClientCustomizer.java b/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentrySpanWebClientCustomizer.java index 0b8aa4055c..79e59f1cf0 100644 --- a/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentrySpanWebClientCustomizer.java +++ b/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentrySpanWebClientCustomizer.java @@ -1,7 +1,7 @@ package io.sentry.spring.boot; import com.jakewharton.nopen.annotation.Open; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.spring.tracing.SentrySpanClientWebRequestFilter; import org.jetbrains.annotations.NotNull; import org.springframework.boot.web.reactive.function.client.WebClientCustomizer; @@ -11,8 +11,8 @@ class SentrySpanWebClientCustomizer implements WebClientCustomizer { private final @NotNull SentrySpanClientWebRequestFilter filter; - public SentrySpanWebClientCustomizer(final @NotNull IHub hub) { - this.filter = new SentrySpanClientWebRequestFilter(hub); + public SentrySpanWebClientCustomizer(final @NotNull IScopes scopes) { + this.filter = new SentrySpanClientWebRequestFilter(scopes); } @Override diff --git a/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentryWebfluxAutoConfiguration.java b/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentryWebfluxAutoConfiguration.java index 3d507f1b6b..e7f6a444b8 100644 --- a/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentryWebfluxAutoConfiguration.java +++ b/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentryWebfluxAutoConfiguration.java @@ -1,8 +1,8 @@ package io.sentry.spring.boot; import com.jakewharton.nopen.annotation.Open; -import io.sentry.IHub; import io.sentry.IScope; +import io.sentry.IScopes; import io.sentry.spring.webflux.SentryScheduleHook; import io.sentry.spring.webflux.SentryWebExceptionHandler; import io.sentry.spring.webflux.SentryWebFilter; @@ -21,14 +21,14 @@ /** Configures Sentry integration for Spring Webflux and Project Reactor. */ @Configuration(proxyBeanMethods = false) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) -@ConditionalOnBean(IHub.class) +@ConditionalOnBean(IScopes.class) @ConditionalOnClass(Schedulers.class) @Open @ApiStatus.Experimental public class SentryWebfluxAutoConfiguration { private static final int SENTRY_SPRING_FILTER_PRECEDENCE = Ordered.HIGHEST_PRECEDENCE; - /** Configures hook that sets correct hub on the executing thread. */ + /** Configures hook that sets correct scopes on the executing thread. */ @Bean public @NotNull ApplicationRunner sentryScheduleHookApplicationRunner() { return args -> { @@ -39,13 +39,14 @@ public class SentryWebfluxAutoConfiguration { /** Configures a filter that sets up Sentry {@link IScope} for each request. */ @Bean @Order(SENTRY_SPRING_FILTER_PRECEDENCE) - public @NotNull SentryWebFilter sentryWebFilter(final @NotNull IHub hub) { - return new SentryWebFilter(hub); + public @NotNull SentryWebFilter sentryWebFilter(final @NotNull IScopes scopes) { + return new SentryWebFilter(scopes); } /** Configures exception handler that handles unhandled exceptions and sends them to Sentry. */ @Bean - public @NotNull SentryWebExceptionHandler sentryWebExceptionHandler(final @NotNull IHub hub) { - return new SentryWebExceptionHandler(hub); + public @NotNull SentryWebExceptionHandler sentryWebExceptionHandler( + final @NotNull IScopes scopes) { + return new SentryWebExceptionHandler(scopes); } } diff --git a/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentryAutoConfigurationTest.kt b/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentryAutoConfigurationTest.kt index c7fd177ec0..e1fe220aea 100644 --- a/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentryAutoConfigurationTest.kt +++ b/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentryAutoConfigurationTest.kt @@ -5,7 +5,7 @@ import io.sentry.AsyncHttpTransportFactory import io.sentry.Breadcrumb import io.sentry.EventProcessor import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ITransportFactory import io.sentry.Integration import io.sentry.NoOpTransportFactory @@ -76,18 +76,18 @@ class SentryAutoConfigurationTest { .withConfiguration(AutoConfigurations.of(SentryAutoConfiguration::class.java, WebMvcAutoConfiguration::class.java)) @Test - fun `hub is not created when auto-configuration dsn is not set`() { + fun `scopes is not created when auto-configuration dsn is not set`() { contextRunner .run { - assertThat(it).doesNotHaveBean(IHub::class.java) + assertThat(it).doesNotHaveBean(IScopes::class.java) } } @Test - fun `hub is created when dsn is provided`() { + fun `scopes is created when dsn is provided`() { contextRunner.withPropertyValues("sentry.dsn=http://key@localhost/proj") .run { - assertThat(it).hasSingleBean(IHub::class.java) + assertThat(it).hasSingleBean(IScopes::class.java) } } @@ -943,7 +943,7 @@ class SentryAutoConfigurationTest { } class CustomIntegration : Integration { - override fun register(hub: IHub, options: SentryOptions) {} + override fun register(scopes: IScopes, options: SentryOptions) {} } @Configuration(proxyBeanMethods = false) diff --git a/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentrySpanRestTemplateCustomizerTest.kt b/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentrySpanRestTemplateCustomizerTest.kt index 0d675b6841..33d7974d8a 100644 --- a/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentrySpanRestTemplateCustomizerTest.kt +++ b/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentrySpanRestTemplateCustomizerTest.kt @@ -2,7 +2,7 @@ package io.sentry.spring.boot import io.sentry.BaggageHeader import io.sentry.Breadcrumb -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.Scope import io.sentry.ScopeCallback import io.sentry.SentryOptions @@ -37,23 +37,23 @@ import kotlin.test.assertTrue class SentrySpanRestTemplateCustomizerTest { class Fixture { val sentryOptions = SentryOptions() - val hub = mock() + val scopes = mock() val restTemplate = RestTemplateBuilder() .setConnectTimeout(Duration.ofSeconds(2)) .setReadTimeout(Duration.ofSeconds(2)) .build() var mockServer = MockWebServer() val transaction: SentryTracer - internal val customizer = SentrySpanRestTemplateCustomizer(hub) + internal val customizer = SentrySpanRestTemplateCustomizer(scopes) val url = mockServer.url("/test/123").toString() val scope = Scope(sentryOptions) init { - whenever(hub.options).thenReturn(sentryOptions) - doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(hub).configureScope( + whenever(scopes.options).thenReturn(sentryOptions) + doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(scopes).configureScope( any() ) - transaction = SentryTracer(TransactionContext("aTransaction", "op", TracesSamplingDecision(true)), hub) + transaction = SentryTracer(TransactionContext("aTransaction", "op", TracesSamplingDecision(true)), scopes) } fun getSut(isTransactionActive: Boolean, status: HttpStatus = HttpStatus.OK, socketPolicy: SocketPolicy = SocketPolicy.KEEP_OPEN, includeMockServerInTracingOrigins: Boolean = true): RestTemplate { @@ -76,7 +76,7 @@ class SentrySpanRestTemplateCustomizerTest { ) if (isTransactionActive) { - whenever(hub.span).thenReturn(transaction) + whenever(scopes.span).thenReturn(transaction) } return restTemplate @@ -211,7 +211,7 @@ class SentrySpanRestTemplateCustomizerTest { @Test fun `when transaction is active adds breadcrumb when http calls succeeds`() { fixture.getSut(isTransactionActive = true).postForObject(fixture.url, "content", String::class.java) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(fixture.url, it.data["url"]) @@ -229,7 +229,7 @@ class SentrySpanRestTemplateCustomizerTest { fixture.getSut(isTransactionActive = true, status = HttpStatus.INTERNAL_SERVER_ERROR).getForObject(fixture.url, String::class.java) } catch (e: Throwable) { } - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(fixture.url, it.data["url"]) @@ -242,7 +242,7 @@ class SentrySpanRestTemplateCustomizerTest { @Test fun `when transaction is not active adds breadcrumb when http calls succeeds`() { fixture.getSut(isTransactionActive = false).postForObject(fixture.url, "content", String::class.java) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(fixture.url, it.data["url"]) @@ -260,7 +260,7 @@ class SentrySpanRestTemplateCustomizerTest { fixture.getSut(isTransactionActive = false, status = HttpStatus.INTERNAL_SERVER_ERROR).getForObject(fixture.url, String::class.java) } catch (e: Throwable) { } - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(fixture.url, it.data["url"]) diff --git a/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentrySpanWebClientCustomizerTest.kt b/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentrySpanWebClientCustomizerTest.kt index f925435fd3..4f1f70d75e 100644 --- a/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentrySpanWebClientCustomizerTest.kt +++ b/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/SentrySpanWebClientCustomizerTest.kt @@ -2,8 +2,8 @@ package io.sentry.spring.boot import io.sentry.BaggageHeader import io.sentry.Breadcrumb -import io.sentry.IHub import io.sentry.IScope +import io.sentry.IScopes import io.sentry.Scope import io.sentry.ScopeCallback import io.sentry.SentryOptions @@ -39,10 +39,10 @@ class SentrySpanWebClientCustomizerTest { class Fixture { lateinit var sentryOptions: SentryOptions lateinit var scope: IScope - val hub = mock() + val scopes = mock() var mockServer = MockWebServer() lateinit var transaction: SentryTracer - private val customizer = SentrySpanWebClientCustomizer(hub) + private val customizer = SentrySpanWebClientCustomizer(scopes) fun getSut(isTransactionActive: Boolean, status: HttpStatus = HttpStatus.OK, throwIOException: Boolean = false, includeMockServerInTracingOrigins: Boolean = true): WebClient { sentryOptions = SentryOptions().apply { @@ -54,11 +54,11 @@ class SentrySpanWebClientCustomizerTest { dsn = "http://key@localhost/proj" } scope = Scope(sentryOptions) - whenever(hub.options).thenReturn(sentryOptions) - doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(hub).configureScope( + whenever(scopes.options).thenReturn(sentryOptions) + doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(scopes).configureScope( any() ) - transaction = SentryTracer(TransactionContext("aTransaction", "op", TracesSamplingDecision(true)), hub) + transaction = SentryTracer(TransactionContext("aTransaction", "op", TracesSamplingDecision(true)), scopes) val webClientBuilder = WebClient.builder() customizer.customize(webClientBuilder) val webClient = webClientBuilder.build() @@ -66,7 +66,7 @@ class SentrySpanWebClientCustomizerTest { if (isTransactionActive) { val scope = Scope(sentryOptions) scope.transaction = transaction - whenever(hub.span).thenReturn(transaction) + whenever(scopes.span).thenReturn(transaction) } val dispatcher: Dispatcher = object : Dispatcher() { @@ -238,7 +238,7 @@ class SentrySpanWebClientCustomizerTest { .retrieve() .bodyToMono(String::class.java) .block() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(uri.toString(), it.data["url"]) @@ -261,7 +261,7 @@ class SentrySpanWebClientCustomizerTest { .block() } catch (e: Throwable) { } - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(uri.toString(), it.data["url"]) @@ -281,7 +281,7 @@ class SentrySpanWebClientCustomizerTest { .retrieve() .bodyToMono(String::class.java) .block() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(uri.toString(), it.data["url"]) @@ -304,7 +304,7 @@ class SentrySpanWebClientCustomizerTest { .block() } catch (e: Throwable) { } - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(uri.toString(), it.data["url"]) diff --git a/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/it/SentrySpringIntegrationTest.kt b/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/it/SentrySpringIntegrationTest.kt index eb6d159a7c..3bbcb2c3e7 100644 --- a/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/it/SentrySpringIntegrationTest.kt +++ b/sentry-spring-boot/src/test/kotlin/io/sentry/spring/boot/it/SentrySpringIntegrationTest.kt @@ -1,6 +1,6 @@ package io.sentry.spring.boot.it -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ITransportFactory import io.sentry.Sentry import io.sentry.checkEvent @@ -60,7 +60,7 @@ class SentrySpringIntegrationTest { lateinit var transport: ITransport @SpyBean - lateinit var hub: IHub + lateinit var scopes: IScopes @LocalServerPort var port: Int? = null @@ -188,7 +188,7 @@ class SentrySpringIntegrationTest { restTemplate.getForEntity("http://localhost:$port/throws-handled", String::class.java) - verify(hub, never()).captureEvent(any()) + verify(scopes, never()).captureEvent(any()) } @Test diff --git a/sentry-spring/api/sentry-spring.api b/sentry-spring/api/sentry-spring.api index 9ef6b5bb3a..58de26098f 100644 --- a/sentry-spring/api/sentry-spring.api +++ b/sentry-spring/api/sentry-spring.api @@ -22,7 +22,7 @@ public final class io/sentry/spring/HttpServletRequestSentryUserProvider : io/se public class io/sentry/spring/SentryExceptionResolver : org/springframework/core/Ordered, org/springframework/web/servlet/HandlerExceptionResolver { public static final field MECHANISM_TYPE Ljava/lang/String; - public fun (Lio/sentry/IHub;Lio/sentry/spring/tracing/TransactionNameProvider;I)V + public fun (Lio/sentry/IScopes;Lio/sentry/spring/tracing/TransactionNameProvider;I)V protected fun createEvent (Ljavax/servlet/http/HttpServletRequest;Ljava/lang/Exception;)Lio/sentry/SentryEvent; protected fun createHint (Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)Lio/sentry/Hint; public fun getOrder ()I @@ -47,14 +47,14 @@ public class io/sentry/spring/SentryRequestHttpServletRequestProcessor : io/sent } public class io/sentry/spring/SentryRequestResolver { - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun resolveSentryRequest (Ljavax/servlet/http/HttpServletRequest;)Lio/sentry/protocol/Request; } public class io/sentry/spring/SentrySpringFilter : org/springframework/web/filter/OncePerRequestFilter { public fun ()V - public fun (Lio/sentry/IHub;)V - public fun (Lio/sentry/IHub;Lio/sentry/spring/SentryRequestResolver;Lio/sentry/spring/tracing/TransactionNameProvider;)V + public fun (Lio/sentry/IScopes;)V + public fun (Lio/sentry/IScopes;Lio/sentry/spring/SentryRequestResolver;Lio/sentry/spring/tracing/TransactionNameProvider;)V protected fun doFilterInternal (Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;Ljavax/servlet/FilterChain;)V } @@ -69,7 +69,7 @@ public final class io/sentry/spring/SentryTaskDecorator : org/springframework/co } public class io/sentry/spring/SentryUserFilter : org/springframework/web/filter/OncePerRequestFilter { - public fun (Lio/sentry/IHub;Ljava/util/List;)V + public fun (Lio/sentry/IScopes;Ljava/util/List;)V protected fun doFilterInternal (Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;Ljavax/servlet/FilterChain;)V public fun getSentryUserProviders ()Ljava/util/List; } @@ -96,7 +96,7 @@ public abstract interface annotation class io/sentry/spring/checkin/SentryCheckI public class io/sentry/spring/checkin/SentryCheckInAdvice : org/aopalliance/intercept/MethodInterceptor, org/springframework/context/EmbeddedValueResolverAware { public fun ()V - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun invoke (Lorg/aopalliance/intercept/MethodInvocation;)Ljava/lang/Object; public fun setEmbeddedValueResolver (Lorg/springframework/util/StringValueResolver;)V } @@ -127,7 +127,7 @@ public abstract interface annotation class io/sentry/spring/exception/SentryCapt public class io/sentry/spring/exception/SentryCaptureExceptionParameterAdvice : org/aopalliance/intercept/MethodInterceptor { public fun ()V - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun invoke (Lorg/aopalliance/intercept/MethodInvocation;)Ljava/lang/Object; } @@ -169,7 +169,7 @@ public final class io/sentry/spring/graphql/SentryDataFetcherExceptionResolverAd public final class io/sentry/spring/graphql/SentryDgsSubscriptionHandler : io/sentry/graphql/SentrySubscriptionHandler { public fun ()V - public fun onSubscriptionResult (Ljava/lang/Object;Lio/sentry/IHub;Lio/sentry/graphql/ExceptionReporter;Lgraphql/execution/instrumentation/parameters/InstrumentationFieldFetchParameters;)Ljava/lang/Object; + public fun onSubscriptionResult (Ljava/lang/Object;Lio/sentry/IScopes;Lio/sentry/graphql/ExceptionReporter;Lgraphql/execution/instrumentation/parameters/InstrumentationFieldFetchParameters;)Ljava/lang/Object; } public final class io/sentry/spring/graphql/SentryGraphqlBeanPostProcessor : org/springframework/beans/factory/config/BeanPostProcessor, org/springframework/core/PriorityOrdered { @@ -188,7 +188,7 @@ public class io/sentry/spring/graphql/SentryGraphqlConfiguration { public final class io/sentry/spring/graphql/SentrySpringSubscriptionHandler : io/sentry/graphql/SentrySubscriptionHandler { public fun ()V - public fun onSubscriptionResult (Ljava/lang/Object;Lio/sentry/IHub;Lio/sentry/graphql/ExceptionReporter;Lgraphql/execution/instrumentation/parameters/InstrumentationFieldFetchParameters;)Ljava/lang/Object; + public fun onSubscriptionResult (Ljava/lang/Object;Lio/sentry/IScopes;Lio/sentry/graphql/ExceptionReporter;Lgraphql/execution/instrumentation/parameters/InstrumentationFieldFetchParameters;)Ljava/lang/Object; } public class io/sentry/spring/tracing/SentryAdviceConfiguration { @@ -207,17 +207,17 @@ public abstract interface annotation class io/sentry/spring/tracing/SentrySpan : public class io/sentry/spring/tracing/SentrySpanAdvice : org/aopalliance/intercept/MethodInterceptor { public fun ()V - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun invoke (Lorg/aopalliance/intercept/MethodInvocation;)Ljava/lang/Object; } public class io/sentry/spring/tracing/SentrySpanClientHttpRequestInterceptor : org/springframework/http/client/ClientHttpRequestInterceptor { - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun intercept (Lorg/springframework/http/HttpRequest;[BLorg/springframework/http/client/ClientHttpRequestExecution;)Lorg/springframework/http/client/ClientHttpResponse; } public class io/sentry/spring/tracing/SentrySpanClientWebRequestFilter : org/springframework/web/reactive/function/client/ExchangeFilterFunction { - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun filter (Lorg/springframework/web/reactive/function/client/ClientRequest;Lorg/springframework/web/reactive/function/client/ExchangeFunction;)Lreactor/core/publisher/Mono; } @@ -232,8 +232,8 @@ public class io/sentry/spring/tracing/SentryTracingConfiguration { public class io/sentry/spring/tracing/SentryTracingFilter : org/springframework/web/filter/OncePerRequestFilter { public fun ()V - public fun (Lio/sentry/IHub;)V - public fun (Lio/sentry/IHub;Lio/sentry/spring/tracing/TransactionNameProvider;)V + public fun (Lio/sentry/IScopes;)V + public fun (Lio/sentry/IScopes;Lio/sentry/spring/tracing/TransactionNameProvider;)V protected fun doFilterInternal (Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;Ljavax/servlet/FilterChain;)V } @@ -245,7 +245,7 @@ public abstract interface annotation class io/sentry/spring/tracing/SentryTransa public class io/sentry/spring/tracing/SentryTransactionAdvice : org/aopalliance/intercept/MethodInterceptor { public fun ()V - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun invoke (Lorg/aopalliance/intercept/MethodInvocation;)Ljava/lang/Object; } @@ -266,7 +266,7 @@ public abstract interface class io/sentry/spring/tracing/TransactionNameProvider } public class io/sentry/spring/webflux/SentryRequestResolver { - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun resolveSentryRequest (Lorg/springframework/http/server/reactive/ServerHttpRequest;)Lio/sentry/protocol/Request; } @@ -278,13 +278,14 @@ public final class io/sentry/spring/webflux/SentryScheduleHook : java/util/funct public final class io/sentry/spring/webflux/SentryWebExceptionHandler : org/springframework/web/server/WebExceptionHandler { public static final field MECHANISM_TYPE Ljava/lang/String; - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun handle (Lorg/springframework/web/server/ServerWebExchange;Ljava/lang/Throwable;)Lreactor/core/publisher/Mono; } public final class io/sentry/spring/webflux/SentryWebFilter : org/springframework/web/server/WebFilter { public static final field SENTRY_HUB_KEY Ljava/lang/String; - public fun (Lio/sentry/IHub;)V + public static final field SENTRY_SCOPES_KEY Ljava/lang/String; + public fun (Lio/sentry/IScopes;)V public fun filter (Lorg/springframework/web/server/ServerWebExchange;Lorg/springframework/web/server/WebFilterChain;)Lreactor/core/publisher/Mono; } diff --git a/sentry-spring/src/main/java/io/sentry/spring/SentryExceptionResolver.java b/sentry-spring/src/main/java/io/sentry/spring/SentryExceptionResolver.java index fc9da87933..ba0586eade 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/SentryExceptionResolver.java +++ b/sentry-spring/src/main/java/io/sentry/spring/SentryExceptionResolver.java @@ -5,7 +5,7 @@ import com.jakewharton.nopen.annotation.Open; import io.sentry.Hint; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.SentryEvent; import io.sentry.SentryLevel; import io.sentry.exception.ExceptionMechanismException; @@ -29,15 +29,15 @@ public class SentryExceptionResolver implements HandlerExceptionResolver, Ordered { public static final String MECHANISM_TYPE = "Spring5ExceptionResolver"; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @NotNull TransactionNameProvider transactionNameProvider; private final int order; public SentryExceptionResolver( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull TransactionNameProvider transactionNameProvider, final int order) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); this.transactionNameProvider = Objects.requireNonNull(transactionNameProvider, "transactionNameProvider is required"); this.order = order; @@ -53,7 +53,7 @@ public SentryExceptionResolver( final SentryEvent event = createEvent(request, ex); final Hint hint = createHint(request, response); - hub.captureEvent(event, hint); + scopes.captureEvent(event, hint); // null = run other HandlerExceptionResolvers to actually handle the exception return null; diff --git a/sentry-spring/src/main/java/io/sentry/spring/SentryHubRegistrar.java b/sentry-spring/src/main/java/io/sentry/spring/SentryHubRegistrar.java index e597d175b6..195a88e277 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/SentryHubRegistrar.java +++ b/sentry-spring/src/main/java/io/sentry/spring/SentryHubRegistrar.java @@ -1,7 +1,7 @@ package io.sentry.spring; import com.jakewharton.nopen.annotation.Open; -import io.sentry.HubAdapter; +import io.sentry.ScopesAdapter; import io.sentry.SentryIntegrationPackageStorage; import io.sentry.SentryOptions; import io.sentry.protocol.SdkVersion; @@ -60,7 +60,7 @@ private void registerSentryOptions( private void registerSentryHubBean(final @NotNull BeanDefinitionRegistry registry) { final BeanDefinitionBuilder builder = - BeanDefinitionBuilder.genericBeanDefinition(HubAdapter.class); + BeanDefinitionBuilder.genericBeanDefinition(ScopesAdapter.class); builder.setInitMethodName("getInstance"); registry.registerBeanDefinition("sentryHub", builder.getBeanDefinition()); diff --git a/sentry-spring/src/main/java/io/sentry/spring/SentryInitBeanPostProcessor.java b/sentry-spring/src/main/java/io/sentry/spring/SentryInitBeanPostProcessor.java index 9e455dfb04..ca431aae14 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/SentryInitBeanPostProcessor.java +++ b/sentry-spring/src/main/java/io/sentry/spring/SentryInitBeanPostProcessor.java @@ -2,10 +2,10 @@ import com.jakewharton.nopen.annotation.Open; import io.sentry.EventProcessor; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ITransportFactory; import io.sentry.Integration; +import io.sentry.ScopesAdapter; import io.sentry.Sentry; import io.sentry.SentryOptions; import io.sentry.SentryOptions.TracesSamplerCallback; @@ -27,15 +27,15 @@ public class SentryInitBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware, DisposableBean { private @Nullable ApplicationContext applicationContext; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; public SentryInitBeanPostProcessor() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } - SentryInitBeanPostProcessor(final @NotNull IHub hub) { - Objects.requireNonNull(hub, "hub is required"); - this.hub = hub; + SentryInitBeanPostProcessor(final @NotNull IScopes scopes) { + Objects.requireNonNull(scopes, "scopes are required"); + this.scopes = scopes; } @Override @@ -86,6 +86,6 @@ public void setApplicationContext(final @NotNull ApplicationContext applicationC @Override public void destroy() { - hub.close(); + scopes.close(); } } diff --git a/sentry-spring/src/main/java/io/sentry/spring/SentryRequestResolver.java b/sentry-spring/src/main/java/io/sentry/spring/SentryRequestResolver.java index 442644fcac..2d9e2996f7 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/SentryRequestResolver.java +++ b/sentry-spring/src/main/java/io/sentry/spring/SentryRequestResolver.java @@ -1,7 +1,7 @@ package io.sentry.spring; import com.jakewharton.nopen.annotation.Open; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.SentryLevel; import io.sentry.protocol.Request; import io.sentry.util.HttpUtils; @@ -20,11 +20,11 @@ @Open public class SentryRequestResolver { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private volatile @Nullable List extraSecurityCookies; - public SentryRequestResolver(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "options is required"); + public SentryRequestResolver(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } // httpRequest.getRequestURL() returns StringBuffer which is considered an obsolete class. @@ -40,7 +40,7 @@ public SentryRequestResolver(final @NotNull IHub hub) { extractSecurityCookieNamesOrUseCached(httpRequest); sentryRequest.setHeaders(resolveHeadersMap(httpRequest, additionalSecurityCookieNames)); - if (hub.getOptions().isSendDefaultPii()) { + if (scopes.getOptions().isSendDefaultPii()) { String cookieName = HttpUtils.COOKIE_HEADER_NAME; final @Nullable List filteredHeaders = HttpUtils.filterOutSecurityCookiesFromHeader( @@ -57,7 +57,8 @@ Map resolveHeadersMap( final Map headersMap = new HashMap<>(); for (String headerName : Collections.list(request.getHeaderNames())) { // do not copy personal information identifiable headers - if (hub.getOptions().isSendDefaultPii() || !HttpUtils.containsSensitiveHeader(headerName)) { + if (scopes.getOptions().isSendDefaultPii() + || !HttpUtils.containsSensitiveHeader(headerName)) { final @Nullable List filteredHeaders = HttpUtils.filterOutSecurityCookiesFromHeader( request.getHeaders(headerName), headerName, additionalSecurityCookieNames); @@ -94,7 +95,8 @@ private List extractSecurityCookieNames(final @NotNull HttpServletReques } } } catch (Throwable t) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log(SentryLevel.WARNING, "Failed to extract session cookie name from request.", t); } diff --git a/sentry-spring/src/main/java/io/sentry/spring/SentrySpringFilter.java b/sentry-spring/src/main/java/io/sentry/spring/SentrySpringFilter.java index 8fd8180941..7695545f04 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/SentrySpringFilter.java +++ b/sentry-spring/src/main/java/io/sentry/spring/SentrySpringFilter.java @@ -8,8 +8,8 @@ import io.sentry.Breadcrumb; import io.sentry.EventProcessor; import io.sentry.Hint; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; +import io.sentry.ScopesAdapter; import io.sentry.SentryEvent; import io.sentry.SentryLevel; import io.sentry.SentryOptions; @@ -29,26 +29,26 @@ @Open public class SentrySpringFilter extends OncePerRequestFilter { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @NotNull SentryRequestResolver requestResolver; private final @NotNull TransactionNameProvider transactionNameProvider; public SentrySpringFilter( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull SentryRequestResolver requestResolver, final @NotNull TransactionNameProvider transactionNameProvider) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); this.requestResolver = Objects.requireNonNull(requestResolver, "requestResolver is required"); this.transactionNameProvider = Objects.requireNonNull(transactionNameProvider, "transactionNameProvider is required"); } - public SentrySpringFilter(final @NotNull IHub hub) { - this(hub, new SentryRequestResolver(hub), new SpringMvcTransactionNameProvider()); + public SentrySpringFilter(final @NotNull IScopes scopes) { + this(scopes, new SentryRequestResolver(scopes), new SpringMvcTransactionNameProvider()); } public SentrySpringFilter() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } @Override @@ -57,20 +57,20 @@ protected void doFilterInternal( final @NotNull HttpServletResponse response, final @NotNull FilterChain filterChain) throws ServletException, IOException { - if (hub.isEnabled()) { + if (scopes.isEnabled()) { // request may qualify for caching request body, if so resolve cached request final HttpServletRequest request = resolveHttpServletRequest(servletRequest); - hub.pushScope(); + scopes.pushScope(); try { final Hint hint = new Hint(); hint.set(SPRING_REQUEST_FILTER_REQUEST, servletRequest); hint.set(SPRING_REQUEST_FILTER_RESPONSE, response); - hub.addBreadcrumb(Breadcrumb.http(request.getRequestURI(), request.getMethod()), hint); + scopes.addBreadcrumb(Breadcrumb.http(request.getRequestURI(), request.getMethod()), hint); configureScope(request); filterChain.doFilter(request, response); } finally { - hub.popScope(); + scopes.popScope(); } } else { filterChain.doFilter(servletRequest, response); @@ -79,7 +79,7 @@ protected void doFilterInternal( private void configureScope(HttpServletRequest request) { try { - hub.configureScope( + scopes.configureScope( scope -> { // set basic request information on the scope scope.setRequest(requestResolver.resolveSentryRequest(request)); @@ -92,11 +92,12 @@ private void configureScope(HttpServletRequest request) { // request processing if (request instanceof CachedBodyHttpServletRequest) { scope.addEventProcessor( - new RequestBodyExtractingEventProcessor(request, hub.getOptions())); + new RequestBodyExtractingEventProcessor(request, scopes.getOptions())); } }); } catch (Throwable e) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log(SentryLevel.ERROR, "Failed to set scope for HTTP request", e); } @@ -104,12 +105,13 @@ private void configureScope(HttpServletRequest request) { private @NotNull HttpServletRequest resolveHttpServletRequest( final @NotNull HttpServletRequest request) { - if (hub.getOptions().isSendDefaultPii() - && qualifiesForCaching(request, hub.getOptions().getMaxRequestBodySize())) { + if (scopes.getOptions().isSendDefaultPii() + && qualifiesForCaching(request, scopes.getOptions().getMaxRequestBodySize())) { try { return new CachedBodyHttpServletRequest(request); } catch (IOException e) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.WARNING, diff --git a/sentry-spring/src/main/java/io/sentry/spring/SentryTaskDecorator.java b/sentry-spring/src/main/java/io/sentry/spring/SentryTaskDecorator.java index cb4a700696..88d205a57e 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/SentryTaskDecorator.java +++ b/sentry-spring/src/main/java/io/sentry/spring/SentryTaskDecorator.java @@ -1,6 +1,6 @@ package io.sentry.spring; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.Sentry; import java.util.concurrent.Callable; import org.jetbrains.annotations.NotNull; @@ -9,21 +9,23 @@ /** * Sets a current hub on a thread running a {@link Runnable} given by parameter. Used to propagate - * the current {@link IHub} on the thread executing async task - like MVC controller methods + * the current {@link IScopes} on the thread executing async task - like MVC controller methods * returning a {@link Callable} or Spring beans methods annotated with {@link Async}. */ public final class SentryTaskDecorator implements TaskDecorator { @Override + @SuppressWarnings("deprecation") public @NotNull Runnable decorate(final @NotNull Runnable runnable) { - final IHub newHub = Sentry.getCurrentHub().clone(); + // TODO fork instead + final IScopes newHub = Sentry.getCurrentScopes().clone(); return () -> { - final IHub oldState = Sentry.getCurrentHub(); - Sentry.setCurrentHub(newHub); + final IScopes oldState = Sentry.getCurrentScopes(); + Sentry.setCurrentScopes(newHub); try { runnable.run(); } finally { - Sentry.setCurrentHub(oldState); + Sentry.setCurrentScopes(oldState); } }; } diff --git a/sentry-spring/src/main/java/io/sentry/spring/SentryUserFilter.java b/sentry-spring/src/main/java/io/sentry/spring/SentryUserFilter.java index 55c5826d40..e0b4e9c1ba 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/SentryUserFilter.java +++ b/sentry-spring/src/main/java/io/sentry/spring/SentryUserFilter.java @@ -1,8 +1,8 @@ package io.sentry.spring; import com.jakewharton.nopen.annotation.Open; -import io.sentry.IHub; import io.sentry.IScope; +import io.sentry.IScopes; import io.sentry.IpAddressUtils; import io.sentry.protocol.User; import io.sentry.util.Objects; @@ -26,12 +26,12 @@ */ @Open public class SentryUserFilter extends OncePerRequestFilter { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @NotNull List sentryUserProviders; public SentryUserFilter( - final @NotNull IHub hub, final @NotNull List sentryUserProviders) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + final @NotNull IScopes scopes, final @NotNull List sentryUserProviders) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); this.sentryUserProviders = Objects.requireNonNull(sentryUserProviders, "sentryUserProviders list is required"); } @@ -46,13 +46,13 @@ protected void doFilterInternal( for (final SentryUserProvider provider : sentryUserProviders) { apply(user, provider.provideUser()); } - if (hub.getOptions().isSendDefaultPii()) { + if (scopes.getOptions().isSendDefaultPii()) { if (IpAddressUtils.isDefault(user.getIpAddress())) { // unset {{auto}} as it would set the server's ip address as a user ip address user.setIpAddress(null); } } - hub.setUser(user); + scopes.setUser(user); chain.doFilter(request, response); } diff --git a/sentry-spring/src/main/java/io/sentry/spring/checkin/SentryCheckInAdvice.java b/sentry-spring/src/main/java/io/sentry/spring/checkin/SentryCheckInAdvice.java index c29ad44900..edae74c2ac 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/checkin/SentryCheckInAdvice.java +++ b/sentry-spring/src/main/java/io/sentry/spring/checkin/SentryCheckInAdvice.java @@ -4,8 +4,8 @@ import io.sentry.CheckIn; import io.sentry.CheckInStatus; import io.sentry.DateUtils; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; +import io.sentry.ScopesAdapter; import io.sentry.SentryLevel; import io.sentry.protocol.SentryId; import io.sentry.util.Objects; @@ -30,16 +30,16 @@ @ApiStatus.Experimental @Open public class SentryCheckInAdvice implements MethodInterceptor, EmbeddedValueResolverAware { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private @Nullable StringValueResolver resolver; public SentryCheckInAdvice() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } - public SentryCheckInAdvice(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentryCheckInAdvice(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } @Override @@ -69,7 +69,8 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl // Sentry should alert the user about missed checkins in this case since the monitor slug // won't match // what is configured in Sentry. - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.WARNING, @@ -79,7 +80,8 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl } if (ObjectUtils.isEmpty(monitorSlug)) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.WARNING, @@ -87,8 +89,8 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl return invocation.proceed(); } - hub.pushScope(); - TracingUtils.startNewTrace(hub); + scopes.pushScope(); + TracingUtils.startNewTrace(scopes); @Nullable SentryId checkInId = null; final long startTime = System.currentTimeMillis(); @@ -96,7 +98,7 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl try { if (!isHeartbeatOnly) { - checkInId = hub.captureCheckIn(new CheckIn(monitorSlug, CheckInStatus.IN_PROGRESS)); + checkInId = scopes.captureCheckIn(new CheckIn(monitorSlug, CheckInStatus.IN_PROGRESS)); } return invocation.proceed(); } catch (Throwable e) { @@ -106,8 +108,8 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl final @NotNull CheckInStatus status = didError ? CheckInStatus.ERROR : CheckInStatus.OK; CheckIn checkIn = new CheckIn(checkInId, monitorSlug, status); checkIn.setDuration(DateUtils.millisToSeconds(System.currentTimeMillis() - startTime)); - hub.captureCheckIn(checkIn); - hub.popScope(); + scopes.captureCheckIn(checkIn); + scopes.popScope(); } } diff --git a/sentry-spring/src/main/java/io/sentry/spring/exception/SentryCaptureExceptionParameterAdvice.java b/sentry-spring/src/main/java/io/sentry/spring/exception/SentryCaptureExceptionParameterAdvice.java index bababbce77..119f39ba6c 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/exception/SentryCaptureExceptionParameterAdvice.java +++ b/sentry-spring/src/main/java/io/sentry/spring/exception/SentryCaptureExceptionParameterAdvice.java @@ -1,8 +1,8 @@ package io.sentry.spring.exception; import com.jakewharton.nopen.annotation.Open; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; +import io.sentry.ScopesAdapter; import io.sentry.exception.ExceptionMechanismException; import io.sentry.protocol.Mechanism; import io.sentry.util.Objects; @@ -22,14 +22,14 @@ @Open public class SentryCaptureExceptionParameterAdvice implements MethodInterceptor { private static final String MECHANISM_TYPE = "SentrySpring5CaptureExceptionParameterAdvice"; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; public SentryCaptureExceptionParameterAdvice() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } - public SentryCaptureExceptionParameterAdvice(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentryCaptureExceptionParameterAdvice(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } @Override @@ -58,6 +58,6 @@ private void captureException(final @NotNull Throwable throwable) { mechanism.setHandled(true); final Throwable mechanismException = new ExceptionMechanismException(mechanism, throwable, Thread.currentThread()); - hub.captureException(mechanismException); + scopes.captureException(mechanismException); } } diff --git a/sentry-spring/src/main/java/io/sentry/spring/graphql/SentryBatchLoaderRegistry.java b/sentry-spring/src/main/java/io/sentry/spring/graphql/SentryBatchLoaderRegistry.java index 62a8669f89..f1d8717598 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/graphql/SentryBatchLoaderRegistry.java +++ b/sentry-spring/src/main/java/io/sentry/spring/graphql/SentryBatchLoaderRegistry.java @@ -1,11 +1,11 @@ package io.sentry.spring.graphql; -import static io.sentry.graphql.SentryInstrumentation.SENTRY_HUB_CONTEXT_KEY; +import static io.sentry.graphql.SentryInstrumentation.SENTRY_SCOPES_CONTEXT_KEY; import graphql.GraphQLContext; import io.sentry.Breadcrumb; -import io.sentry.IHub; -import io.sentry.NoOpHub; +import io.sentry.IScopes; +import io.sentry.NoOpScopes; import java.util.List; import java.util.Map; import java.util.Set; @@ -89,7 +89,7 @@ public BatchLoaderRegistry.RegistrationSpec withOptions(DataLoaderOptions public void registerBatchLoader(BiFunction, BatchLoaderEnvironment, Flux> loader) { delegate.registerBatchLoader( (keys, batchLoaderEnvironment) -> { - hubFromContext(batchLoaderEnvironment) + scopesFromContext(batchLoaderEnvironment) .addBreadcrumb(Breadcrumb.graphqlDataLoader(keys, keyType, valueType, name)); return loader.apply(keys, batchLoaderEnvironment); }); @@ -100,20 +100,20 @@ public void registerMappedBatchLoader( BiFunction, BatchLoaderEnvironment, Mono>> loader) { delegate.registerMappedBatchLoader( (keys, batchLoaderEnvironment) -> { - hubFromContext(batchLoaderEnvironment) + scopesFromContext(batchLoaderEnvironment) .addBreadcrumb(Breadcrumb.graphqlDataLoader(keys, keyType, valueType, name)); return loader.apply(keys, batchLoaderEnvironment); }); } - private @NotNull IHub hubFromContext(final @NotNull BatchLoaderEnvironment environment) { + private @NotNull IScopes scopesFromContext(final @NotNull BatchLoaderEnvironment environment) { Object context = environment.getContext(); if (context instanceof GraphQLContext) { GraphQLContext graphqlContext = (GraphQLContext) context; - return graphqlContext.getOrDefault(SENTRY_HUB_CONTEXT_KEY, NoOpHub.getInstance()); + return graphqlContext.getOrDefault(SENTRY_SCOPES_CONTEXT_KEY, NoOpScopes.getInstance()); } - return NoOpHub.getInstance(); + return NoOpScopes.getInstance(); } } } diff --git a/sentry-spring/src/main/java/io/sentry/spring/graphql/SentryDgsSubscriptionHandler.java b/sentry-spring/src/main/java/io/sentry/spring/graphql/SentryDgsSubscriptionHandler.java index fb4e09e889..eef5fdae69 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/graphql/SentryDgsSubscriptionHandler.java +++ b/sentry-spring/src/main/java/io/sentry/spring/graphql/SentryDgsSubscriptionHandler.java @@ -1,7 +1,7 @@ package io.sentry.spring.graphql; import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.SentryIntegrationPackageStorage; import io.sentry.graphql.ExceptionReporter; import io.sentry.graphql.SentrySubscriptionHandler; @@ -17,7 +17,7 @@ public SentryDgsSubscriptionHandler() { @Override public @NotNull Object onSubscriptionResult( final @NotNull Object result, - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull ExceptionReporter exceptionReporter, final @NotNull InstrumentationFieldFetchParameters parameters) { if (result instanceof Flux) { @@ -25,7 +25,7 @@ public SentryDgsSubscriptionHandler() { return flux.doOnError( throwable -> { final @NotNull ExceptionReporter.ExceptionDetails exceptionDetails = - new ExceptionReporter.ExceptionDetails(hub, parameters.getEnvironment(), true); + new ExceptionReporter.ExceptionDetails(scopes, parameters.getEnvironment(), true); exceptionReporter.captureThrowable(throwable, exceptionDetails, null); }); } diff --git a/sentry-spring/src/main/java/io/sentry/spring/graphql/SentrySpringSubscriptionHandler.java b/sentry-spring/src/main/java/io/sentry/spring/graphql/SentrySpringSubscriptionHandler.java index a7809eb230..b3f0b9830e 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/graphql/SentrySpringSubscriptionHandler.java +++ b/sentry-spring/src/main/java/io/sentry/spring/graphql/SentrySpringSubscriptionHandler.java @@ -1,7 +1,7 @@ package io.sentry.spring.graphql; import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.graphql.ExceptionReporter; import io.sentry.graphql.SentrySubscriptionHandler; import org.jetbrains.annotations.NotNull; @@ -13,7 +13,7 @@ public final class SentrySpringSubscriptionHandler implements SentrySubscription @Override public @NotNull Object onSubscriptionResult( final @NotNull Object result, - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull ExceptionReporter exceptionReporter, final @NotNull InstrumentationFieldFetchParameters parameters) { if (result instanceof Flux) { @@ -21,7 +21,7 @@ public final class SentrySpringSubscriptionHandler implements SentrySubscription return flux.doOnError( throwable -> { final @NotNull ExceptionReporter.ExceptionDetails exceptionDetails = - new ExceptionReporter.ExceptionDetails(hub, parameters.getEnvironment(), true); + new ExceptionReporter.ExceptionDetails(scopes, parameters.getEnvironment(), true); if (throwable instanceof SubscriptionPublisherException && throwable.getCause() != null) { exceptionReporter.captureThrowable(throwable.getCause(), exceptionDetails, null); diff --git a/sentry-spring/src/main/java/io/sentry/spring/tracing/SentrySpanAdvice.java b/sentry-spring/src/main/java/io/sentry/spring/tracing/SentrySpanAdvice.java index 96c4275836..c1b7305d4f 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/tracing/SentrySpanAdvice.java +++ b/sentry-spring/src/main/java/io/sentry/spring/tracing/SentrySpanAdvice.java @@ -1,9 +1,9 @@ package io.sentry.spring.tracing; import com.jakewharton.nopen.annotation.Open; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ISpan; +import io.sentry.ScopesAdapter; import io.sentry.SpanStatus; import io.sentry.util.Objects; import java.lang.reflect.Method; @@ -22,20 +22,20 @@ @Open public class SentrySpanAdvice implements MethodInterceptor { private static final String TRACE_ORIGIN = "auto.function.spring.advice"; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; public SentrySpanAdvice() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } - public SentrySpanAdvice(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentrySpanAdvice(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } @SuppressWarnings("deprecation") @Override public Object invoke(final @NotNull MethodInvocation invocation) throws Throwable { - final ISpan activeSpan = hub.getSpan(); + final ISpan activeSpan = scopes.getSpan(); if (activeSpan == null || activeSpan.isNoOp()) { // there is no active transaction, we do not start new span diff --git a/sentry-spring/src/main/java/io/sentry/spring/tracing/SentrySpanClientHttpRequestInterceptor.java b/sentry-spring/src/main/java/io/sentry/spring/tracing/SentrySpanClientHttpRequestInterceptor.java index 4067c69c8c..bdf8417642 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/tracing/SentrySpanClientHttpRequestInterceptor.java +++ b/sentry-spring/src/main/java/io/sentry/spring/tracing/SentrySpanClientHttpRequestInterceptor.java @@ -8,7 +8,7 @@ import io.sentry.BaggageHeader; import io.sentry.Breadcrumb; import io.sentry.Hint; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ISpan; import io.sentry.SpanDataConvention; import io.sentry.SpanStatus; @@ -27,10 +27,10 @@ @Open public class SentrySpanClientHttpRequestInterceptor implements ClientHttpRequestInterceptor { private static final String TRACE_ORIGIN = "auto.http.spring.resttemplate"; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; - public SentrySpanClientHttpRequestInterceptor(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentrySpanClientHttpRequestInterceptor(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } @Override @@ -42,7 +42,7 @@ public SentrySpanClientHttpRequestInterceptor(final @NotNull IHub hub) { Integer responseStatusCode = null; ClientHttpResponse response = null; try { - final ISpan activeSpan = hub.getSpan(); + final ISpan activeSpan = scopes.getSpan(); if (activeSpan == null) { maybeAddTracingHeaders(request, null); return execution.execute(request, body); @@ -83,7 +83,7 @@ private void maybeAddTracingHeaders( final @NotNull HttpRequest request, final @Nullable ISpan span) { final @Nullable TracingUtils.TracingHeaders tracingHeaders = TracingUtils.traceIfAllowed( - hub, + scopes, request.getURI().toString(), request.getHeaders().get(BaggageHeader.BAGGAGE_HEADER), span); @@ -120,6 +120,6 @@ private void addBreadcrumb( hint.set(SPRING_REQUEST_INTERCEPTOR_RESPONSE, response); } - hub.addBreadcrumb(breadcrumb, hint); + scopes.addBreadcrumb(breadcrumb, hint); } } diff --git a/sentry-spring/src/main/java/io/sentry/spring/tracing/SentrySpanClientWebRequestFilter.java b/sentry-spring/src/main/java/io/sentry/spring/tracing/SentrySpanClientWebRequestFilter.java index 00ad91bbb0..c526cb64cc 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/tracing/SentrySpanClientWebRequestFilter.java +++ b/sentry-spring/src/main/java/io/sentry/spring/tracing/SentrySpanClientWebRequestFilter.java @@ -7,7 +7,7 @@ import io.sentry.BaggageHeader; import io.sentry.Breadcrumb; import io.sentry.Hint; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ISpan; import io.sentry.SpanDataConvention; import io.sentry.SpanStatus; @@ -26,16 +26,16 @@ @Open public class SentrySpanClientWebRequestFilter implements ExchangeFilterFunction { private static final String TRACE_ORIGIN = "auto.http.spring.webclient"; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; - public SentrySpanClientWebRequestFilter(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentrySpanClientWebRequestFilter(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } @Override public @NotNull Mono filter( final @NotNull ClientRequest request, final @NotNull ExchangeFunction next) { - final ISpan activeSpan = hub.getSpan(); + final ISpan activeSpan = scopes.getSpan(); if (activeSpan == null) { addBreadcrumb(request, null); return next.exchange(maybeAddHeaders(request, null)); @@ -76,7 +76,7 @@ private ClientRequest maybeAddHeaders( final @Nullable TracingUtils.TracingHeaders tracingHeaders = TracingUtils.traceIfAllowed( - hub, + scopes, request.url().toString(), request.headers().get(BaggageHeader.BAGGAGE_HEADER), span); @@ -113,6 +113,6 @@ private void addBreadcrumb( hint.set(SPRING_EXCHANGE_FILTER_RESPONSE, response); } - hub.addBreadcrumb(breadcrumb, hint); + scopes.addBreadcrumb(breadcrumb, hint); } } diff --git a/sentry-spring/src/main/java/io/sentry/spring/tracing/SentryTracingFilter.java b/sentry-spring/src/main/java/io/sentry/spring/tracing/SentryTracingFilter.java index 5af329f600..50cdb8dc3a 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/tracing/SentryTracingFilter.java +++ b/sentry-spring/src/main/java/io/sentry/spring/tracing/SentryTracingFilter.java @@ -3,9 +3,9 @@ import com.jakewharton.nopen.annotation.Open; import io.sentry.BaggageHeader; import io.sentry.CustomSamplingContext; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ITransaction; +import io.sentry.ScopesAdapter; import io.sentry.SentryTraceHeader; import io.sentry.SpanStatus; import io.sentry.TransactionContext; @@ -35,7 +35,7 @@ public class SentryTracingFilter extends OncePerRequestFilter { private static final String TRACE_ORIGIN = "auto.http.spring.webmvc"; private final @NotNull TransactionNameProvider transactionNameProvider; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; /** * Creates filter that resolves transaction name using {@link SpringMvcTransactionNameProvider}. @@ -46,25 +46,26 @@ public class SentryTracingFilter extends OncePerRequestFilter { * javax.servlet.Filter}. */ public SentryTracingFilter() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } /** * Creates filter that resolves transaction name using transaction name provider given by * parameter. * - * @param hub - the hub + * @param scopes - the scopes * @param transactionNameProvider - transaction name provider. */ public SentryTracingFilter( - final @NotNull IHub hub, final @NotNull TransactionNameProvider transactionNameProvider) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + final @NotNull IScopes scopes, + final @NotNull TransactionNameProvider transactionNameProvider) { + this.scopes = Objects.requireNonNull(scopes, "scopes is required"); this.transactionNameProvider = Objects.requireNonNull(transactionNameProvider, "transactionNameProvider is required"); } - public SentryTracingFilter(final @NotNull IHub hub) { - this(hub, new SpringMvcTransactionNameProvider()); + public SentryTracingFilter(final @NotNull IScopes scopes) { + this(scopes, new SpringMvcTransactionNameProvider()); } @Override @@ -74,15 +75,15 @@ protected void doFilterInternal( final @NotNull FilterChain filterChain) throws ServletException, IOException { - if (hub.isEnabled()) { + if (scopes.isEnabled()) { final @Nullable String sentryTraceHeader = httpRequest.getHeader(SentryTraceHeader.SENTRY_TRACE_HEADER); final @Nullable List baggageHeader = Collections.list(httpRequest.getHeaders(BaggageHeader.BAGGAGE_HEADER)); final @Nullable TransactionContext transactionContext = - hub.continueTrace(sentryTraceHeader, baggageHeader); + scopes.continueTrace(sentryTraceHeader, baggageHeader); - if (hub.getOptions().isTracingEnabled() && shouldTraceRequest(httpRequest)) { + if (scopes.getOptions().isTracingEnabled() && shouldTraceRequest(httpRequest)) { doFilterWithTransaction(httpRequest, httpResponse, filterChain, transactionContext); } else { filterChain.doFilter(httpRequest, httpResponse); @@ -129,7 +130,7 @@ private void doFilterWithTransaction( } private boolean shouldTraceRequest(final @NotNull HttpServletRequest request) { - return hub.getOptions().isTraceOptionsRequests() + return scopes.getOptions().isTraceOptionsRequests() || !HttpMethod.OPTIONS.name().equals(request.getMethod()); } @@ -151,14 +152,14 @@ private ITransaction startTransaction( transactionOptions.setCustomSamplingContext(customSamplingContext); transactionOptions.setBindToScope(true); - return hub.startTransaction(transactionContext, transactionOptions); + return scopes.startTransaction(transactionContext, transactionOptions); } final TransactionOptions transactionOptions = new TransactionOptions(); transactionOptions.setCustomSamplingContext(customSamplingContext); transactionOptions.setBindToScope(true); - return hub.startTransaction( + return scopes.startTransaction( new TransactionContext(name, TransactionNameSource.URL, "http.server"), transactionOptions); } } diff --git a/sentry-spring/src/main/java/io/sentry/spring/tracing/SentryTransactionAdvice.java b/sentry-spring/src/main/java/io/sentry/spring/tracing/SentryTransactionAdvice.java index c417f14a14..8f4f5bbdfc 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/tracing/SentryTransactionAdvice.java +++ b/sentry-spring/src/main/java/io/sentry/spring/tracing/SentryTransactionAdvice.java @@ -1,9 +1,9 @@ package io.sentry.spring.tracing; import com.jakewharton.nopen.annotation.Open; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ITransaction; +import io.sentry.ScopesAdapter; import io.sentry.SpanStatus; import io.sentry.TransactionContext; import io.sentry.TransactionOptions; @@ -27,14 +27,14 @@ @Open public class SentryTransactionAdvice implements MethodInterceptor { private static final String TRACE_ORIGIN = "auto.function.spring.advice"; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; public SentryTransactionAdvice() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } - public SentryTransactionAdvice(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentryTransactionAdvice(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } @SuppressWarnings("deprecation") @@ -67,11 +67,11 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl } else { operation = "bean"; } - hub.pushScope(); + scopes.pushScope(); final TransactionOptions transactionOptions = new TransactionOptions(); transactionOptions.setBindToScope(true); final ITransaction transaction = - hub.startTransaction( + scopes.startTransaction( new TransactionContext(nameAndSource.name, nameAndSource.source, operation), transactionOptions); transaction.getSpanContext().setOrigin(TRACE_ORIGIN); @@ -85,7 +85,7 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl throw e; } finally { transaction.finish(); - hub.popScope(); + scopes.popScope(); } } } @@ -105,7 +105,7 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl } private boolean isTransactionActive() { - return hub.getSpan() != null; + return scopes.getSpan() != null; } private static class TransactionNameAndSource { diff --git a/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryRequestResolver.java b/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryRequestResolver.java index a710438c46..76e50985e5 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryRequestResolver.java +++ b/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryRequestResolver.java @@ -1,7 +1,7 @@ package io.sentry.spring.webflux; import com.jakewharton.nopen.annotation.Open; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.protocol.Request; import io.sentry.util.HttpUtils; import io.sentry.util.Objects; @@ -20,10 +20,10 @@ @Open @ApiStatus.Experimental public class SentryRequestResolver { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; - public SentryRequestResolver(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "options is required"); + public SentryRequestResolver(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } public @NotNull Request resolveSentryRequest(final @NotNull ServerHttpRequest httpRequest) { @@ -36,7 +36,7 @@ public SentryRequestResolver(final @NotNull IHub hub) { urlDetails.applyToRequest(sentryRequest); sentryRequest.setHeaders(resolveHeadersMap(httpRequest.getHeaders())); - if (hub.getOptions().isSendDefaultPii()) { + if (scopes.getOptions().isSendDefaultPii()) { String headerName = HttpUtils.COOKIE_HEADER_NAME; sentryRequest.setCookies( toString( @@ -52,7 +52,8 @@ Map resolveHeadersMap(final HttpHeaders request) { for (Map.Entry> entry : request.entrySet()) { // do not copy personal information identifiable headers String headerName = entry.getKey(); - if (hub.getOptions().isSendDefaultPii() || !HttpUtils.containsSensitiveHeader(headerName)) { + if (scopes.getOptions().isSendDefaultPii() + || !HttpUtils.containsSensitiveHeader(headerName)) { headersMap.put( headerName, toString( diff --git a/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryScheduleHook.java b/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryScheduleHook.java index 7775d4e482..20f494168d 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryScheduleHook.java +++ b/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryScheduleHook.java @@ -1,6 +1,6 @@ package io.sentry.spring.webflux; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.Sentry; import java.util.function.Function; import org.jetbrains.annotations.ApiStatus; @@ -13,16 +13,18 @@ @ApiStatus.Experimental public final class SentryScheduleHook implements Function { @Override + @SuppressWarnings("deprecation") public Runnable apply(final @NotNull Runnable runnable) { - final IHub newHub = Sentry.getCurrentHub().clone(); + // TODO fork instead + final IScopes newHub = Sentry.getCurrentScopes().clone(); return () -> { - final IHub oldState = Sentry.getCurrentHub(); - Sentry.setCurrentHub(newHub); + final IScopes oldState = Sentry.getCurrentScopes(); + Sentry.setCurrentScopes(newHub); try { runnable.run(); } finally { - Sentry.setCurrentHub(oldState); + Sentry.setCurrentScopes(oldState); } }; } diff --git a/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryWebExceptionHandler.java b/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryWebExceptionHandler.java index 98d3855a04..042d1d48ec 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryWebExceptionHandler.java +++ b/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryWebExceptionHandler.java @@ -5,7 +5,7 @@ import static io.sentry.TypeCheckHint.WEBFLUX_EXCEPTION_HANDLER_RESPONSE; import io.sentry.Hint; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.SentryEvent; import io.sentry.SentryLevel; import io.sentry.exception.ExceptionMechanismException; @@ -26,10 +26,10 @@ @ApiStatus.Experimental public final class SentryWebExceptionHandler implements WebExceptionHandler { public static final String MECHANISM_TYPE = "Spring5WebFluxExceptionResolver"; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; - public SentryWebExceptionHandler(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentryWebExceptionHandler(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } @Override @@ -50,7 +50,7 @@ public SentryWebExceptionHandler(final @NotNull IHub hub) { hint.set(WEBFLUX_EXCEPTION_HANDLER_RESPONSE, serverWebExchange.getResponse()); hint.set(WEBFLUX_EXCEPTION_HANDLER_EXCHANGE, serverWebExchange); - hub.captureEvent(event, hint); + scopes.captureEvent(event, hint); } return Mono.error(ex); } diff --git a/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryWebFilter.java b/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryWebFilter.java index f68a87ae0f..3bb7de5ae4 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryWebFilter.java +++ b/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryWebFilter.java @@ -7,10 +7,10 @@ import io.sentry.Breadcrumb; import io.sentry.CustomSamplingContext; import io.sentry.Hint; -import io.sentry.IHub; import io.sentry.IScope; +import io.sentry.IScopes; import io.sentry.ITransaction; -import io.sentry.NoOpHub; +import io.sentry.NoOpScopes; import io.sentry.Sentry; import io.sentry.SentryTraceHeader; import io.sentry.SpanStatus; @@ -34,22 +34,24 @@ /** Manages {@link IScope} in Webflux request processing. */ @ApiStatus.Experimental public final class SentryWebFilter implements WebFilter { - public static final String SENTRY_HUB_KEY = "sentry-hub"; + public static final String SENTRY_SCOPES_KEY = "sentry-scopes"; + @Deprecated public static final String SENTRY_HUB_KEY = SENTRY_SCOPES_KEY; private static final String TRANSACTION_OP = "http.server"; private static final String TRACE_ORIGIN = "auto.spring.webflux"; private final @NotNull SentryRequestResolver sentryRequestResolver; - public SentryWebFilter(final @NotNull IHub hub) { - Objects.requireNonNull(hub, "hub is required"); - this.sentryRequestResolver = new SentryRequestResolver(hub); + public SentryWebFilter(final @NotNull IScopes scopes) { + Objects.requireNonNull(scopes, "scopes are required"); + this.sentryRequestResolver = new SentryRequestResolver(scopes); } @Override public Mono filter( final @NotNull ServerWebExchange serverWebExchange, final @NotNull WebFilterChain webFilterChain) { - @NotNull IHub requestHub = Sentry.cloneMainHub(); + @NotNull IScopes requestHub = Sentry.cloneMainHub(); + // TODO do not push / pop, use fork instead if (!requestHub.isEnabled()) { return webFilterChain.filter(serverWebExchange); } @@ -80,7 +82,8 @@ isTracingEnabled && shouldTraceRequest(requestHub, request) finishTransaction(serverWebExchange, transaction); } requestHub.popScope(); - Sentry.setCurrentHub(NoOpHub.getInstance()); + // TODO token based cleanup instead? + Sentry.setCurrentScopes(NoOpScopes.getInstance()); }) .doOnError( e -> { @@ -91,8 +94,8 @@ isTracingEnabled && shouldTraceRequest(requestHub, request) }) .doFirst( () -> { - serverWebExchange.getAttributes().put(SENTRY_HUB_KEY, requestHub); - Sentry.setCurrentHub(requestHub); + serverWebExchange.getAttributes().put(SENTRY_SCOPES_KEY, requestHub); + Sentry.setCurrentScopes(requestHub); requestHub.pushScope(); final ServerHttpResponse response = serverWebExchange.getResponse(); @@ -109,13 +112,13 @@ isTracingEnabled && shouldTraceRequest(requestHub, request) } private boolean shouldTraceRequest( - final @NotNull IHub hub, final @NotNull ServerHttpRequest request) { - return hub.getOptions().isTraceOptionsRequests() + final @NotNull IScopes scopes, final @NotNull ServerHttpRequest request) { + return scopes.getOptions().isTraceOptionsRequests() || !HttpMethod.OPTIONS.equals(request.getMethod()); } private @NotNull ITransaction startTransaction( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull ServerHttpRequest request, final @Nullable TransactionContext transactionContext) { final @NotNull String name = request.getMethod() + " " + request.getURI().getPath(); @@ -131,10 +134,10 @@ private boolean shouldTraceRequest( transactionContext.setTransactionNameSource(TransactionNameSource.URL); transactionContext.setOperation(TRANSACTION_OP); - return hub.startTransaction(transactionContext, transactionOptions); + return scopes.startTransaction(transactionContext, transactionOptions); } - return hub.startTransaction( + return scopes.startTransaction( new TransactionContext(name, TransactionNameSource.URL, TRANSACTION_OP), transactionOptions); } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/EnableSentryTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/EnableSentryTest.kt index 5a8fec3053..5182309416 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/EnableSentryTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/EnableSentryTest.kt @@ -1,7 +1,7 @@ package io.sentry.spring import io.sentry.EventProcessor -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ITransportFactory import io.sentry.Integration import io.sentry.Sentry @@ -65,9 +65,9 @@ class EnableSentryTest { } @Test - fun `creates Sentry Hub`() { + fun `creates Sentry Scopes`() { contextRunner.run { - assertThat(it).hasSingleBean(IHub::class.java) + assertThat(it).hasSingleBean(IScopes::class.java) } } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/SentryCheckInAdviceTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/SentryCheckInAdviceTest.kt index 4f94fd7ce0..23807e1fd9 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/SentryCheckInAdviceTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/SentryCheckInAdviceTest.kt @@ -2,7 +2,7 @@ package io.sentry.spring import io.sentry.CheckIn import io.sentry.CheckInStatus -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.Sentry import io.sentry.SentryOptions import io.sentry.protocol.SentryId @@ -55,19 +55,19 @@ class SentryCheckInAdviceTest { lateinit var sampleServiceSpringProperties: SampleServiceSpringProperties @Autowired - lateinit var hub: IHub + lateinit var scopes: IScopes @BeforeTest fun setup() { - reset(hub) - whenever(hub.options).thenReturn(SentryOptions()) + reset(scopes) + whenever(scopes.options).thenReturn(SentryOptions()) } @Test fun `when method is annotated with @SentryCheckIn, every method call creates two check-ins`() { val checkInId = SentryId() val checkInCaptor = argumentCaptor() - whenever(hub.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) + whenever(scopes.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) val result = sampleService.hello() assertEquals(1, result) assertEquals(2, checkInCaptor.allValues.size) @@ -80,17 +80,17 @@ class SentryCheckInAdviceTest { assertEquals("monitor_slug_1", doneCheckIn.monitorSlug) assertEquals(CheckInStatus.OK.apiName(), doneCheckIn.status) - val order = inOrder(hub) - order.verify(hub).pushScope() - order.verify(hub, times(2)).captureCheckIn(any()) - order.verify(hub).popScope() + val order = inOrder(scopes) + order.verify(scopes).pushScope() + order.verify(scopes, times(2)).captureCheckIn(any()) + order.verify(scopes).popScope() } @Test fun `when method is annotated with @SentryCheckIn, every method call creates two check-ins error`() { val checkInId = SentryId() val checkInCaptor = argumentCaptor() - whenever(hub.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) + whenever(scopes.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) assertThrows { sampleService.oops() } @@ -104,17 +104,17 @@ class SentryCheckInAdviceTest { assertEquals("monitor_slug_1e", doneCheckIn.monitorSlug) assertEquals(CheckInStatus.ERROR.apiName(), doneCheckIn.status) - val order = inOrder(hub) - order.verify(hub).pushScope() - order.verify(hub, times(2)).captureCheckIn(any()) - order.verify(hub).popScope() + val order = inOrder(scopes) + order.verify(scopes).pushScope() + order.verify(scopes, times(2)).captureCheckIn(any()) + order.verify(scopes).popScope() } @Test fun `when method is annotated with @SentryCheckIn and heartbeat only, every method call creates only one check-in at the end`() { val checkInId = SentryId() val checkInCaptor = argumentCaptor() - whenever(hub.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) + whenever(scopes.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) val result = sampleServiceHeartbeat.hello() assertEquals(1, result) assertEquals(1, checkInCaptor.allValues.size) @@ -124,17 +124,17 @@ class SentryCheckInAdviceTest { assertEquals(CheckInStatus.OK.apiName(), doneCheckIn.status) assertNotNull(doneCheckIn.duration) - val order = inOrder(hub) - order.verify(hub).pushScope() - order.verify(hub).captureCheckIn(any()) - order.verify(hub).popScope() + val order = inOrder(scopes) + order.verify(scopes).pushScope() + order.verify(scopes).captureCheckIn(any()) + order.verify(scopes).popScope() } @Test fun `when method is annotated with @SentryCheckIn and heartbeat only, every method call creates only one check-in at the end with error`() { val checkInId = SentryId() val checkInCaptor = argumentCaptor() - whenever(hub.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) + whenever(scopes.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) assertThrows { sampleServiceHeartbeat.oops() } @@ -145,31 +145,31 @@ class SentryCheckInAdviceTest { assertEquals(CheckInStatus.ERROR.apiName(), doneCheckIn.status) assertNotNull(doneCheckIn.duration) - val order = inOrder(hub) - order.verify(hub).pushScope() - order.verify(hub).captureCheckIn(any()) - order.verify(hub).popScope() + val order = inOrder(scopes) + order.verify(scopes).pushScope() + order.verify(scopes).captureCheckIn(any()) + order.verify(scopes).popScope() } @Test fun `when method is annotated with @SentryCheckIn but slug is missing, does not create check-in`() { val checkInId = SentryId() val checkInCaptor = argumentCaptor() - whenever(hub.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) + whenever(scopes.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) val result = sampleServiceNoSlug.hello() assertEquals(1, result) assertEquals(0, checkInCaptor.allValues.size) - verify(hub, never()).pushScope() - verify(hub, never()).captureCheckIn(any()) - verify(hub, never()).popScope() + verify(scopes, never()).pushScope() + verify(scopes, never()).captureCheckIn(any()) + verify(scopes, never()).popScope() } @Test fun `when @SentryCheckIn is passed a spring property it is resolved correctly`() { val checkInId = SentryId() val checkInCaptor = argumentCaptor() - whenever(hub.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) + whenever(scopes.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) val result = sampleServiceSpringProperties.hello() assertEquals(1, result) assertEquals(1, checkInCaptor.allValues.size) @@ -179,17 +179,17 @@ class SentryCheckInAdviceTest { assertEquals(CheckInStatus.OK.apiName(), doneCheckIn.status) assertNotNull(doneCheckIn.duration) - val order = inOrder(hub) - order.verify(hub).pushScope() - order.verify(hub).captureCheckIn(any()) - order.verify(hub).popScope() + val order = inOrder(scopes) + order.verify(scopes).pushScope() + order.verify(scopes).captureCheckIn(any()) + order.verify(scopes).popScope() } @Test fun `when @SentryCheckIn is passed a spring property that does not exist, raw value is used`() { val checkInId = SentryId() val checkInCaptor = argumentCaptor() - whenever(hub.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) + whenever(scopes.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) val result = sampleServiceSpringProperties.helloUnresolvedProperty() assertEquals(1, result) assertEquals(1, checkInCaptor.allValues.size) @@ -199,17 +199,17 @@ class SentryCheckInAdviceTest { assertEquals(CheckInStatus.OK.apiName(), doneCheckIn.status) assertNotNull(doneCheckIn.duration) - val order = inOrder(hub) - order.verify(hub).pushScope() - order.verify(hub).captureCheckIn(any()) - order.verify(hub).popScope() + val order = inOrder(scopes) + order.verify(scopes).pushScope() + order.verify(scopes).captureCheckIn(any()) + order.verify(scopes).popScope() } @Test fun `when @SentryCheckIn is passed a spring property that causes an exception, raw value is used`() { val checkInId = SentryId() val checkInCaptor = argumentCaptor() - whenever(hub.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) + whenever(scopes.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) val result = sampleServiceSpringProperties.helloExceptionProperty() assertEquals(1, result) assertEquals(1, checkInCaptor.allValues.size) @@ -219,10 +219,10 @@ class SentryCheckInAdviceTest { assertEquals(CheckInStatus.OK.apiName(), doneCheckIn.status) assertNotNull(doneCheckIn.duration) - val order = inOrder(hub) - order.verify(hub).pushScope() - order.verify(hub).captureCheckIn(any()) - order.verify(hub).popScope() + val order = inOrder(scopes) + order.verify(scopes).pushScope() + order.verify(scopes).captureCheckIn(any()) + order.verify(scopes).popScope() } @Configuration @@ -243,10 +243,10 @@ class SentryCheckInAdviceTest { open fun sampleServiceSpringProperties() = SampleServiceSpringProperties() @Bean - open fun hub(): IHub { - val hub = mock() - Sentry.setCurrentHub(hub) - return hub + open fun scopes(): IScopes { + val scopes = mock() + Sentry.setCurrentScopes(scopes) + return scopes } companion object { diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/SentryExceptionResolverTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/SentryExceptionResolverTest.kt index f3e4c32fb0..048166107b 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/SentryExceptionResolverTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/SentryExceptionResolverTest.kt @@ -1,7 +1,7 @@ package io.sentry.spring import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryEvent import io.sentry.SentryLevel import io.sentry.exception.ExceptionMechanismException @@ -17,7 +17,7 @@ import javax.servlet.http.HttpServletResponse import kotlin.test.Test class SentryExceptionResolverTest { - private val hub = mock() + private val scopes = mock() private val transactionNameProvider = mock() private val request = mock() @@ -26,10 +26,10 @@ class SentryExceptionResolverTest { @Test fun `when handles exception, sets wrapped exception for event`() { val eventCaptor = argumentCaptor() - whenever(hub.captureEvent(eventCaptor.capture(), any())).thenReturn(null) + whenever(scopes.captureEvent(eventCaptor.capture(), any())).thenReturn(null) val expectedCause = RuntimeException("test") - SentryExceptionResolver(hub, transactionNameProvider, 1) + SentryExceptionResolver(scopes, transactionNameProvider, 1) .resolveException(request, response, null, expectedCause) assertThat(eventCaptor.firstValue.throwable).isEqualTo(expectedCause) @@ -46,9 +46,9 @@ class SentryExceptionResolverTest { @Test fun `when handles exception, sets fatal level for event`() { val eventCaptor = argumentCaptor() - whenever(hub.captureEvent(eventCaptor.capture(), any())).thenReturn(null) + whenever(scopes.captureEvent(eventCaptor.capture(), any())).thenReturn(null) - SentryExceptionResolver(hub, transactionNameProvider, 1) + SentryExceptionResolver(scopes, transactionNameProvider, 1) .resolveException(request, response, null, RuntimeException("test")) assertThat(eventCaptor.firstValue.level).isEqualTo(SentryLevel.FATAL) @@ -59,9 +59,9 @@ class SentryExceptionResolverTest { val expectedTransactionName = "test-transaction" whenever(transactionNameProvider.provideTransactionName(any())).thenReturn(expectedTransactionName) val eventCaptor = argumentCaptor() - whenever(hub.captureEvent(eventCaptor.capture(), any())).thenReturn(null) + whenever(scopes.captureEvent(eventCaptor.capture(), any())).thenReturn(null) - SentryExceptionResolver(hub, transactionNameProvider, 1) + SentryExceptionResolver(scopes, transactionNameProvider, 1) .resolveException(request, response, null, RuntimeException("test")) assertThat(eventCaptor.firstValue.transaction).isEqualTo(expectedTransactionName) @@ -71,9 +71,9 @@ class SentryExceptionResolverTest { @Test fun `when handles exception, provides spring resolver hint`() { val hintCaptor = argumentCaptor() - whenever(hub.captureEvent(any(), hintCaptor.capture())).thenReturn(null) + whenever(scopes.captureEvent(any(), hintCaptor.capture())).thenReturn(null) - SentryExceptionResolver(hub, transactionNameProvider, 1) + SentryExceptionResolver(scopes, transactionNameProvider, 1) .resolveException(request, response, null, RuntimeException("test")) with(hintCaptor.firstValue) { @@ -86,8 +86,8 @@ class SentryExceptionResolverTest { fun `when custom create event method provided, uses it to capture event`() { val expectedEvent = SentryEvent() val eventCaptor = argumentCaptor() - whenever(hub.captureEvent(eventCaptor.capture(), any())).thenReturn(null) - val resolver = object : SentryExceptionResolver(hub, transactionNameProvider, 1) { + whenever(scopes.captureEvent(eventCaptor.capture(), any())).thenReturn(null) + val resolver = object : SentryExceptionResolver(scopes, transactionNameProvider, 1) { override fun createEvent(request: HttpServletRequest, ex: Exception) = expectedEvent } @@ -100,8 +100,8 @@ class SentryExceptionResolverTest { fun `when custom create hint method provided, uses it to capture event`() { val expectedHint = Hint() val hintCaptor = argumentCaptor() - whenever(hub.captureEvent(any(), hintCaptor.capture())).thenReturn(null) - val resolver = object : SentryExceptionResolver(hub, transactionNameProvider, 1) { + whenever(scopes.captureEvent(any(), hintCaptor.capture())).thenReturn(null) + val resolver = object : SentryExceptionResolver(scopes, transactionNameProvider, 1) { override fun createHint(request: HttpServletRequest, response: HttpServletResponse) = expectedHint } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/SentryInitBeanPostProcessorTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/SentryInitBeanPostProcessorTest.kt index 78ebf961c9..dc4a14e656 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/SentryInitBeanPostProcessorTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/SentryInitBeanPostProcessorTest.kt @@ -1,6 +1,6 @@ package io.sentry.spring -import io.sentry.IHub +import io.sentry.IScopes import org.mockito.kotlin.mock import org.mockito.kotlin.verify import org.springframework.context.annotation.AnnotationConfigApplicationContext @@ -13,18 +13,18 @@ class SentryInitBeanPostProcessorTest { @Test fun closesSentryOnApplicationContextDestroy() { val ctx = AnnotationConfigApplicationContext(TestConfig::class.java) - val hub = ctx.getBean(IHub::class.java) + val scopes = ctx.getBean(IScopes::class.java) ctx.close() - verify(hub).close() + verify(scopes).close() } @Configuration open class TestConfig { @Bean(destroyMethod = "") - open fun hub() = mock() + open fun scopes() = mock() @Bean - open fun sentryInitBeanPostProcessor() = SentryInitBeanPostProcessor(hub()) + open fun sentryInitBeanPostProcessor() = SentryInitBeanPostProcessor(scopes()) } } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/SentryRequestHttpServletRequestProcessorTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/SentryRequestHttpServletRequestProcessorTest.kt index 3fe9b60743..c7277a2240 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/SentryRequestHttpServletRequestProcessorTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/SentryRequestHttpServletRequestProcessorTest.kt @@ -1,7 +1,7 @@ package io.sentry.spring import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryEvent import io.sentry.SentryOptions import io.sentry.spring.tracing.SpringMvcTransactionNameProvider @@ -19,10 +19,10 @@ import kotlin.test.assertNotNull class SentryRequestHttpServletRequestProcessorTest { private class Fixture { - val hub = mock() + val scopes = mock() fun getSut(request: HttpServletRequest, options: SentryOptions = SentryOptions()): SentryRequestHttpServletRequestProcessor { - whenever(hub.options).thenReturn(options) + whenever(scopes.options).thenReturn(options) return SentryRequestHttpServletRequestProcessor(SpringMvcTransactionNameProvider(), request) } } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/SentrySpringFilterTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/SentrySpringFilterTest.kt index ce83c4b9b7..c6ac952531 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/SentrySpringFilterTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/SentrySpringFilterTest.kt @@ -1,8 +1,8 @@ package io.sentry.spring import io.sentry.Breadcrumb -import io.sentry.IHub import io.sentry.IScope +import io.sentry.IScopes import io.sentry.Scope import io.sentry.ScopeCallback import io.sentry.SentryOptions @@ -37,7 +37,7 @@ import kotlin.test.fail class SentrySpringFilterTest { private class Fixture { - val hub = mock() + val scopes = mock() val response = MockHttpServletResponse() val chain = mock() lateinit var scope: IScope @@ -45,15 +45,15 @@ class SentrySpringFilterTest { fun getSut(request: HttpServletRequest? = null, options: SentryOptions = SentryOptions()): SentrySpringFilter { scope = Scope(options) - whenever(hub.options).thenReturn(options) - whenever(hub.isEnabled).thenReturn(true) - doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(hub).configureScope(any()) + whenever(scopes.options).thenReturn(options) + whenever(scopes.isEnabled).thenReturn(true) + doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(scopes).configureScope(any()) this.request = request ?: MockHttpServletRequest().apply { this.requestURI = "http://localhost:8080/some-uri" this.method = "post" } - return SentrySpringFilter(hub) + return SentrySpringFilter(scopes) } } @@ -64,7 +64,7 @@ class SentrySpringFilterTest { val listener = fixture.getSut() listener.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).pushScope() + verify(fixture.scopes).pushScope() } @Test @@ -72,7 +72,7 @@ class SentrySpringFilterTest { val listener = fixture.getSut() listener.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { it: Breadcrumb -> Assertions.assertThat(it.getData("url")).isEqualTo("http://localhost:8080/some-uri") Assertions.assertThat(it.getData("method")).isEqualTo("POST") @@ -87,7 +87,7 @@ class SentrySpringFilterTest { val listener = fixture.getSut() listener.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).popScope() + verify(fixture.scopes).popScope() } @Test @@ -99,7 +99,7 @@ class SentrySpringFilterTest { listener.doFilter(fixture.request, fixture.response, fixture.chain) fail() } catch (e: Exception) { - verify(fixture.hub).popScope() + verify(fixture.scopes).popScope() } } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/SentryTaskDecoratorTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/SentryTaskDecoratorTest.kt index e202deca86..3f34ab9d9d 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/SentryTaskDecoratorTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/SentryTaskDecoratorTest.kt @@ -32,28 +32,28 @@ class SentryTaskDecoratorTest { val sut = SentryTaskDecorator() - val mainHub = Sentry.getCurrentHub() - val threadedHub = Sentry.getCurrentHub().clone() + val mainHub = Sentry.getCurrentScopes() + val threadedHub = Sentry.getCurrentScopes().clone() executor.submit { - Sentry.setCurrentHub(threadedHub) + Sentry.setCurrentScopes(threadedHub) }.get() - assertEquals(mainHub, Sentry.getCurrentHub()) + assertEquals(mainHub, Sentry.getCurrentScopes()) val callableFuture = executor.submit( sut.decorate { - assertNotEquals(mainHub, Sentry.getCurrentHub()) - assertNotEquals(threadedHub, Sentry.getCurrentHub()) + assertNotEquals(mainHub, Sentry.getCurrentScopes()) + assertNotEquals(threadedHub, Sentry.getCurrentScopes()) } ) callableFuture.get() executor.submit { - assertNotEquals(mainHub, Sentry.getCurrentHub()) - assertEquals(threadedHub, Sentry.getCurrentHub()) + assertNotEquals(mainHub, Sentry.getCurrentScopes()) + assertEquals(threadedHub, Sentry.getCurrentScopes()) }.get() } } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/SentryUserFilterTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/SentryUserFilterTest.kt index 2dac9a57ed..7f9be1ba8b 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/SentryUserFilterTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/SentryUserFilterTest.kt @@ -1,6 +1,6 @@ package io.sentry.spring -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryOptions import io.sentry.protocol.User import org.mockito.kotlin.check @@ -16,7 +16,7 @@ import kotlin.test.assertNull class SentryUserFilterTest { class Fixture { - val hub = mock() + val scopes = mock() val request = MockHttpServletRequest() val response = MockHttpServletResponse() val chain = mock() @@ -25,8 +25,8 @@ class SentryUserFilterTest { val options = SentryOptions().apply { this.isSendDefaultPii = isSendDefaultPii } - whenever(hub.options).thenReturn(options) - return SentryUserFilter(hub, userProviders) + whenever(scopes.options).thenReturn(options) + return SentryUserFilter(scopes, userProviders) } } @@ -52,7 +52,7 @@ class SentryUserFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).setUser( + verify(fixture.scopes).setUser( check { assertEquals(sampleUser, it) } @@ -72,7 +72,7 @@ class SentryUserFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).setUser( + verify(fixture.scopes).setUser( check { assertEquals(sampleUser, it) } @@ -92,7 +92,7 @@ class SentryUserFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).setUser( + verify(fixture.scopes).setUser( check { assertEquals(sampleUser, it) } @@ -118,7 +118,7 @@ class SentryUserFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).setUser( + verify(fixture.scopes).setUser( check { assertEquals(mapOf("key" to "value", "new-key" to "new-value"), it.others) } @@ -140,7 +140,7 @@ class SentryUserFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).setUser( + verify(fixture.scopes).setUser( check { assertEquals("192.168.0.1", it.ipAddress) } @@ -162,7 +162,7 @@ class SentryUserFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).setUser( + verify(fixture.scopes).setUser( check { assertNull(it.ipAddress) } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/exception/SentryCaptureExceptionParameterAdviceTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/exception/SentryCaptureExceptionParameterAdviceTest.kt index 39bc66fabb..dca1c4c592 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/exception/SentryCaptureExceptionParameterAdviceTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/exception/SentryCaptureExceptionParameterAdviceTest.kt @@ -1,7 +1,7 @@ package io.sentry.spring.exception import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.Sentry import io.sentry.exception.ExceptionMechanismException import org.junit.runner.RunWith @@ -30,18 +30,18 @@ class SentryCaptureExceptionParameterAdviceTest { lateinit var sampleService: SampleService @Autowired - lateinit var hub: IHub + lateinit var scopes: IScopes @BeforeTest fun setup() { - reset(hub) + reset(scopes) } @Test fun `captures exception passed to method annotated with @SentryCaptureException`() { val exception = RuntimeException("test exception") sampleService.methodTakingAnException(exception) - verify(hub).captureException( + verify(scopes).captureException( check { assertTrue(it is ExceptionMechanismException) assertEquals(exception, it.throwable) @@ -60,10 +60,10 @@ class SentryCaptureExceptionParameterAdviceTest { open fun sampleService() = SampleService() @Bean - open fun hub(): IHub { - val hub = mock() - Sentry.setCurrentHub(hub) - return hub + open fun scopes(): IScopes { + val scopes = mock() + Sentry.setCurrentScopes(scopes) + return scopes } } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/graphql/SentrySpringSubscriptionHandlerTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/graphql/SentrySpringSubscriptionHandlerTest.kt index df2df5b3ef..1aa97cd262 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/graphql/SentrySpringSubscriptionHandlerTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/graphql/SentrySpringSubscriptionHandlerTest.kt @@ -4,7 +4,7 @@ import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchPar import graphql.language.Document import graphql.language.OperationDefinition import graphql.schema.DataFetchingEnvironment -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.graphql.ExceptionReporter import org.junit.jupiter.api.assertThrows import org.mockito.kotlin.anyOrNull @@ -23,7 +23,7 @@ class SentrySpringSubscriptionHandlerTest { @Test fun `reports exception`() { val exception = IllegalStateException("some exception") - val hub = mock() + val scopes = mock() val exceptionReporter = mock() val parameters = mock() val dataFetchingEnvironment = mock() @@ -32,7 +32,7 @@ class SentrySpringSubscriptionHandlerTest { .build() whenever(dataFetchingEnvironment.document).thenReturn(document) whenever(parameters.environment).thenReturn(dataFetchingEnvironment) - val resultObject = SentrySpringSubscriptionHandler().onSubscriptionResult(Flux.error(exception), hub, exceptionReporter, parameters) + val resultObject = SentrySpringSubscriptionHandler().onSubscriptionResult(Flux.error(exception), scopes, exceptionReporter, parameters) assertThrows { (resultObject as Flux).blockFirst() } @@ -41,7 +41,7 @@ class SentrySpringSubscriptionHandlerTest { same(exception), org.mockito.kotlin.check { assertEquals(true, it.isSubscription) - assertSame(hub, it.hub) + assertSame(scopes, it.scopes) assertEquals("query testQuery\n", it.query) }, anyOrNull() @@ -52,7 +52,7 @@ class SentrySpringSubscriptionHandlerTest { fun `unwraps SubscriptionPublisherException and reports cause`() { val exception = IllegalStateException("some exception") val wrappedException = SubscriptionPublisherException(emptyList(), exception) - val hub = mock() + val scopes = mock() val exceptionReporter = mock() val parameters = mock() val dataFetchingEnvironment = mock() @@ -61,7 +61,7 @@ class SentrySpringSubscriptionHandlerTest { .build() whenever(dataFetchingEnvironment.document).thenReturn(document) whenever(parameters.environment).thenReturn(dataFetchingEnvironment) - val resultObject = SentrySpringSubscriptionHandler().onSubscriptionResult(Flux.error(wrappedException), hub, exceptionReporter, parameters) + val resultObject = SentrySpringSubscriptionHandler().onSubscriptionResult(Flux.error(wrappedException), scopes, exceptionReporter, parameters) assertThrows { (resultObject as Flux).blockFirst() } @@ -70,7 +70,7 @@ class SentrySpringSubscriptionHandlerTest { same(exception), org.mockito.kotlin.check { assertEquals(true, it.isSubscription) - assertSame(hub, it.hub) + assertSame(scopes, it.scopes) assertEquals("query testQuery\n", it.query) }, anyOrNull() diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/mvc/SentrySpringIntegrationTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/mvc/SentrySpringIntegrationTest.kt index 998b27c7e8..ad9734def6 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/mvc/SentrySpringIntegrationTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/mvc/SentrySpringIntegrationTest.kt @@ -1,6 +1,6 @@ package io.sentry.spring.mvc -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ITransportFactory import io.sentry.Sentry import io.sentry.SentryOptions @@ -104,7 +104,7 @@ class SentrySpringIntegrationTest { lateinit var anotherService: AnotherService @Autowired - lateinit var hub: IHub + lateinit var scopes: IScopes @LocalServerPort var port: Int? = null @@ -260,7 +260,7 @@ class SentrySpringIntegrationTest { try { someService.aMethodThrowing() } catch (e: Exception) { - hub.captureException(e) + scopes.captureException(e) } verify(transport).send( checkEvent { @@ -276,7 +276,7 @@ class SentrySpringIntegrationTest { try { someService.aMethodWithInnerSpanThrowing() } catch (e: Exception) { - hub.captureException(e) + scopes.captureException(e) } verify(transport).send( checkEvent { @@ -370,20 +370,20 @@ open class App { open fun springSecuritySentryUserProvider(sentryOptions: SentryOptions) = SpringSecuritySentryUserProvider(sentryOptions) @Bean - open fun sentryUserFilter(hub: IHub, @Lazy sentryUserProviders: List) = FilterRegistrationBean().apply { - this.filter = SentryUserFilter(hub, sentryUserProviders) + open fun sentryUserFilter(scopes: IScopes, @Lazy sentryUserProviders: List) = FilterRegistrationBean().apply { + this.filter = SentryUserFilter(scopes, sentryUserProviders) this.order = Ordered.LOWEST_PRECEDENCE } @Bean - open fun sentrySpringFilter(hub: IHub) = FilterRegistrationBean().apply { - this.filter = SentrySpringFilter(hub) + open fun sentrySpringFilter(scopes: IScopes) = FilterRegistrationBean().apply { + this.filter = SentrySpringFilter(scopes) this.order = Ordered.HIGHEST_PRECEDENCE } @Bean - open fun sentryTracingFilter(hub: IHub) = FilterRegistrationBean().apply { - this.filter = SentryTracingFilter(hub) + open fun sentryTracingFilter(scopes: IScopes) = FilterRegistrationBean().apply { + this.filter = SentryTracingFilter(scopes) this.order = Ordered.HIGHEST_PRECEDENCE + 1 // must run after SentrySpringFilter } @@ -391,13 +391,13 @@ open class App { open fun sentryTaskDecorator() = SentryTaskDecorator() @Bean - open fun webClient(hub: IHub): WebClient { + open fun webClient(scopes: IScopes): WebClient { return WebClient.builder() .filter( ExchangeFilterFunctions .basicAuthentication("user", "password") ) - .filter(SentrySpanClientWebRequestFilter(hub)).build() + .filter(SentrySpanClientWebRequestFilter(scopes)).build() } } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/tracing/SentrySpanAdviceTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/tracing/SentrySpanAdviceTest.kt index dc6f00eb46..a6f59971c9 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/tracing/SentrySpanAdviceTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/tracing/SentrySpanAdviceTest.kt @@ -1,6 +1,6 @@ package io.sentry.spring.tracing -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.Scope import io.sentry.Sentry import io.sentry.SentryOptions @@ -37,20 +37,20 @@ class SentrySpanAdviceTest { lateinit var classAnnotatedWithOperationSampleService: ClassAnnotatedWithOperationSampleService @Autowired - lateinit var hub: IHub + lateinit var scopes: IScopes @BeforeTest fun setup() { - whenever(hub.options).thenReturn(SentryOptions()) + whenever(scopes.options).thenReturn(SentryOptions()) } @Test fun `when class is annotated with @SentrySpan, every method call attaches span to existing transaction`() { val scope = Scope(SentryOptions()) - val tx = SentryTracer(TransactionContext("aTransaction", "op"), hub) + val tx = SentryTracer(TransactionContext("aTransaction", "op"), scopes) scope.setTransaction(tx) - whenever(hub.span).thenReturn(tx) + whenever(scopes.span).thenReturn(tx) val result = classAnnotatedSampleService.hello() assertEquals(1, result) assertEquals(1, tx.spans.size) @@ -62,10 +62,10 @@ class SentrySpanAdviceTest { @Test fun `when class is annotated with @SentrySpan with operation set, every method call attaches span to existing transaction`() { val scope = Scope(SentryOptions()) - val tx = SentryTracer(TransactionContext("aTransaction", "op"), hub) + val tx = SentryTracer(TransactionContext("aTransaction", "op"), scopes) scope.setTransaction(tx) - whenever(hub.span).thenReturn(tx) + whenever(scopes.span).thenReturn(tx) val result = classAnnotatedWithOperationSampleService.hello() assertEquals(1, result) assertEquals(1, tx.spans.size) @@ -76,10 +76,10 @@ class SentrySpanAdviceTest { @Test fun `when method is annotated with @SentrySpan with properties set, attaches span to existing transaction`() { val scope = Scope(SentryOptions()) - val tx = SentryTracer(TransactionContext("aTransaction", "op"), hub) + val tx = SentryTracer(TransactionContext("aTransaction", "op"), scopes) scope.setTransaction(tx) - whenever(hub.span).thenReturn(tx) + whenever(scopes.span).thenReturn(tx) val result = sampleService.methodWithSpanDescriptionSet() assertEquals(1, result) assertEquals(1, tx.spans.size) @@ -90,10 +90,10 @@ class SentrySpanAdviceTest { @Test fun `when method is annotated with @SentrySpan without properties set, attaches span to existing transaction and sets Span description as className dot methodName`() { val scope = Scope(SentryOptions()) - val tx = SentryTracer(TransactionContext("aTransaction", "op"), hub) + val tx = SentryTracer(TransactionContext("aTransaction", "op"), scopes) scope.setTransaction(tx) - whenever(hub.span).thenReturn(tx) + whenever(scopes.span).thenReturn(tx) val result = sampleService.methodWithoutSpanDescriptionSet() assertEquals(2, result) assertEquals(1, tx.spans.size) @@ -104,10 +104,10 @@ class SentrySpanAdviceTest { @Test fun `when method is annotated with @SentrySpan and returns, attached span has status OK`() { val scope = Scope(SentryOptions()) - val tx = SentryTracer(TransactionContext("aTransaction", "op"), hub) + val tx = SentryTracer(TransactionContext("aTransaction", "op"), scopes) scope.setTransaction(tx) - whenever(hub.span).thenReturn(tx) + whenever(scopes.span).thenReturn(tx) sampleService.methodWithSpanDescriptionSet() assertEquals(SpanStatus.OK, tx.spans.first().status) } @@ -115,10 +115,10 @@ class SentrySpanAdviceTest { @Test fun `when method is annotated with @SentrySpan and throws exception, attached span has throwable set and INTERNAL_ERROR status`() { val scope = Scope(SentryOptions()) - val tx = SentryTracer(TransactionContext("aTransaction", "op"), hub) + val tx = SentryTracer(TransactionContext("aTransaction", "op"), scopes) scope.setTransaction(tx) - whenever(hub.span).thenReturn(tx) + whenever(scopes.span).thenReturn(tx) var throwable: Throwable? = null try { sampleService.methodThrowingException() @@ -131,7 +131,7 @@ class SentrySpanAdviceTest { @Test fun `when method is annotated with @SentrySpan and there is no active transaction, span is not created and method is executed`() { - whenever(hub.span).thenReturn(null) + whenever(scopes.span).thenReturn(null) val result = sampleService.methodWithSpanDescriptionSet() assertEquals(1, result) } @@ -151,10 +151,10 @@ class SentrySpanAdviceTest { open fun classAnnotatedWithOperationSampleService() = ClassAnnotatedWithOperationSampleService() @Bean - open fun hub(): IHub { - val hub = mock() - Sentry.setCurrentHub(hub) - return hub + open fun scopes(): IScopes { + val scopes = mock() + Sentry.setCurrentScopes(scopes) + return scopes } } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/tracing/SentryTracingFilterTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/tracing/SentryTracingFilterTest.kt index 6c4c06ebff..aca54809cc 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/tracing/SentryTracingFilterTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/tracing/SentryTracingFilterTest.kt @@ -1,7 +1,7 @@ package io.sentry.spring.tracing -import io.sentry.IHub import io.sentry.ILogger +import io.sentry.IScopes import io.sentry.PropagationContext import io.sentry.SentryOptions import io.sentry.SentryTracer @@ -38,7 +38,7 @@ import kotlin.test.fail class SentryTracingFilterTest { private class Fixture { - val hub = mock() + val scopes = mock() val request = MockHttpServletRequest() val response = MockHttpServletResponse() val chain = mock() @@ -50,7 +50,7 @@ class SentryTracingFilterTest { val logger = mock() init { - whenever(hub.options).thenReturn(options) + whenever(scopes.options).thenReturn(options) } fun getSut(isEnabled: Boolean = true, status: Int = 200, sentryTraceHeader: String? = null, baggageHeaders: List? = null): SentryTracingFilter { @@ -61,16 +61,16 @@ class SentryTracingFilterTest { whenever(transactionNameProvider.provideTransactionSource()).thenReturn(TransactionNameSource.CUSTOM) if (sentryTraceHeader != null) { request.addHeader("sentry-trace", sentryTraceHeader) - whenever(hub.startTransaction(any(), check { it.isBindToScope })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, hub) } + whenever(scopes.startTransaction(any(), check { it.isBindToScope })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, scopes) } } if (baggageHeaders != null) { request.addHeader("baggage", baggageHeaders) } response.status = status - whenever(hub.startTransaction(any(), check { assertTrue(it.isBindToScope) })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, hub) } - whenever(hub.isEnabled).thenReturn(isEnabled) - whenever(hub.continueTrace(any(), any())).thenAnswer { TransactionContext.fromPropagationContext(PropagationContext.fromHeaders(logger, it.arguments[0] as String?, it.arguments[1] as List?)) } - return SentryTracingFilter(hub, transactionNameProvider) + whenever(scopes.startTransaction(any(), check { assertTrue(it.isBindToScope) })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, scopes) } + whenever(scopes.isEnabled).thenReturn(isEnabled) + whenever(scopes.continueTrace(any(), any())).thenAnswer { TransactionContext.fromPropagationContext(PropagationContext.fromHeaders(logger, it.arguments[0] as String?, it.arguments[1] as List?)) } + return SentryTracingFilter(scopes, transactionNameProvider) } } @@ -82,7 +82,7 @@ class SentryTracingFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( check { assertEquals("POST /product/12", it.name) assertEquals(TransactionNameSource.URL, it.transactionNameSource) @@ -95,7 +95,7 @@ class SentryTracingFilterTest { } ) verify(fixture.chain).doFilter(fixture.request, fixture.response) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.transaction).isEqualTo("POST /product/{id}") assertThat(it.contexts.trace!!.status).isEqualTo(SpanStatus.OK) @@ -114,7 +114,7 @@ class SentryTracingFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.status).isEqualTo(SpanStatus.INTERNAL_ERROR) }, @@ -130,7 +130,7 @@ class SentryTracingFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.status).isNull() }, @@ -146,7 +146,7 @@ class SentryTracingFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.parentSpanId).isNull() }, @@ -163,7 +163,7 @@ class SentryTracingFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.parentSpanId).isEqualTo(parentSpanId) }, @@ -174,15 +174,15 @@ class SentryTracingFilterTest { } @Test - fun `when hub is disabled, components are not invoked`() { + fun `when scopes is disabled, components are not invoked`() { val filter = fixture.getSut(isEnabled = false) filter.doFilter(fixture.request, fixture.response, fixture.chain) verify(fixture.chain).doFilter(fixture.request, fixture.response) - verify(fixture.hub).isEnabled - verifyNoMoreInteractions(fixture.hub) + verify(fixture.scopes).isEnabled + verifyNoMoreInteractions(fixture.scopes) verify(fixture.transactionNameProvider, never()).provideTransactionName(any()) } @@ -196,7 +196,7 @@ class SentryTracingFilterTest { fail("filter is expected to rethrow exception") } catch (_: Exception) { } - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.status).isEqualTo(SpanStatus.INTERNAL_ERROR) }, @@ -216,10 +216,10 @@ class SentryTracingFilterTest { verify(fixture.chain).doFilter(fixture.request, fixture.response) - verify(fixture.hub).isEnabled - verify(fixture.hub, times(2)).options - verify(fixture.hub).continueTrace(anyOrNull(), anyOrNull()) - verifyNoMoreInteractions(fixture.hub) + verify(fixture.scopes).isEnabled + verify(fixture.scopes, times(2)).options + verify(fixture.scopes).continueTrace(anyOrNull(), anyOrNull()) + verifyNoMoreInteractions(fixture.scopes) verify(fixture.transactionNameProvider, never()).provideTransactionName(any()) } @@ -233,7 +233,7 @@ class SentryTracingFilterTest { verify(fixture.chain).doFilter(fixture.request, fixture.response) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.parentSpanId).isNull() }, @@ -253,7 +253,7 @@ class SentryTracingFilterTest { verify(fixture.chain).doFilter(fixture.request, fixture.response) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.parentSpanId).isNull() }, @@ -275,9 +275,9 @@ class SentryTracingFilterTest { verify(fixture.chain).doFilter(fixture.request, fixture.response) - verify(fixture.hub).continueTrace(eq(sentryTraceHeaderString), eq(baggageHeaderStrings)) + verify(fixture.scopes).continueTrace(eq(sentryTraceHeaderString), eq(baggageHeaderStrings)) - verify(fixture.hub, never()).captureTransaction( + verify(fixture.scopes, never()).captureTransaction( anyOrNull(), anyOrNull(), anyOrNull(), diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/tracing/SentryTransactionAdviceTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/tracing/SentryTransactionAdviceTest.kt index 0fa9abbb29..f53acde8aa 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/tracing/SentryTransactionAdviceTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/tracing/SentryTransactionAdviceTest.kt @@ -1,6 +1,6 @@ package io.sentry.spring.tracing -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.Sentry import io.sentry.SentryOptions import io.sentry.SentryTracer @@ -44,13 +44,13 @@ class SentryTransactionAdviceTest { lateinit var classAnnotatedWithOperationSampleService: ClassAnnotatedWithOperationSampleService @Autowired - lateinit var hub: IHub + lateinit var scopes: IScopes @BeforeTest fun setup() { - reset(hub) - whenever(hub.startTransaction(any(), check { assertTrue(it.isBindToScope) })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, hub) } - whenever(hub.options).thenReturn( + reset(scopes) + whenever(scopes.startTransaction(any(), check { assertTrue(it.isBindToScope) })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, scopes) } + whenever(scopes.options).thenReturn( SentryOptions().apply { dsn = "https://key@sentry.io/proj" } @@ -60,7 +60,7 @@ class SentryTransactionAdviceTest { @Test fun `creates transaction around method annotated with @SentryTransaction`() { sampleService.methodWithTransactionNameSet() - verify(hub).captureTransaction( + verify(scopes).captureTransaction( check { assertThat(it.transaction).isEqualTo("customName") assertThat(it.contexts.trace!!.operation).isEqualTo("bean") @@ -76,7 +76,7 @@ class SentryTransactionAdviceTest { @Test fun `when method annotated with @SentryTransaction throws exception, sets error status on transaction`() { assertThrows { sampleService.methodThrowingException() } - verify(hub).captureTransaction( + verify(scopes).captureTransaction( check { assertThat(it.status).isEqualTo(SpanStatus.INTERNAL_ERROR) }, @@ -89,7 +89,7 @@ class SentryTransactionAdviceTest { @Test fun `when @SentryTransaction has no name set, sets transaction name as className dot methodName`() { sampleService.methodWithoutTransactionNameSet() - verify(hub).captureTransaction( + verify(scopes).captureTransaction( check { assertThat(it.transaction).isEqualTo("SampleService.methodWithoutTransactionNameSet") assertThat(it.contexts.trace!!.operation).isEqualTo("op") @@ -102,18 +102,18 @@ class SentryTransactionAdviceTest { @Test fun `when transaction is already active, does not start new transaction`() { - whenever(hub.options).thenReturn(SentryOptions()) - whenever(hub.span).then { SentryTracer(TransactionContext("aTransaction", "op"), hub) } + whenever(scopes.options).thenReturn(SentryOptions()) + whenever(scopes.span).then { SentryTracer(TransactionContext("aTransaction", "op"), scopes) } sampleService.methodWithTransactionNameSet() - verify(hub, times(0)).captureTransaction(any(), any()) + verify(scopes, times(0)).captureTransaction(any(), any()) } @Test fun `creates transaction around method in class annotated with @SentryTransaction`() { classAnnotatedSampleService.hello() - verify(hub).captureTransaction( + verify(scopes).captureTransaction( check { assertThat(it.transaction).isEqualTo("ClassAnnotatedSampleService.hello") assertThat(it.contexts.trace!!.operation).isEqualTo("op") @@ -127,7 +127,7 @@ class SentryTransactionAdviceTest { @Test fun `creates transaction with operation set around method in class annotated with @SentryTransaction`() { classAnnotatedWithOperationSampleService.hello() - verify(hub).captureTransaction( + verify(scopes).captureTransaction( check { assertThat(it.transaction).isEqualTo("ClassAnnotatedWithOperationSampleService.hello") assertThat(it.contexts.trace!!.operation).isEqualTo("my-op") @@ -141,13 +141,13 @@ class SentryTransactionAdviceTest { @Test fun `pushes the scope when advice starts`() { classAnnotatedSampleService.hello() - verify(hub).pushScope() + verify(scopes).pushScope() } @Test fun `pops the scope when advice finishes`() { classAnnotatedSampleService.hello() - verify(hub).popScope() + verify(scopes).popScope() } @Configuration @@ -165,10 +165,10 @@ class SentryTransactionAdviceTest { open fun classAnnotatedWithOperationSampleService() = ClassAnnotatedWithOperationSampleService() @Bean - open fun hub(): IHub { - val hub = mock() - Sentry.setCurrentHub(hub) - return hub + open fun scopes(): IScopes { + val scopes = mock() + Sentry.setCurrentScopes(scopes) + return scopes } } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryScheduleHookTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryScheduleHookTest.kt index b09011d544..7a8b2993f9 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryScheduleHookTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryScheduleHookTest.kt @@ -33,28 +33,28 @@ class SentryScheduleHookTest { val sut = SentryScheduleHook() - val mainHub = Sentry.getCurrentHub() - val threadedHub = Sentry.getCurrentHub().clone() + val mainHub = Sentry.getCurrentScopes() + val threadedHub = Sentry.getCurrentScopes().clone() executor.submit { Sentry.setCurrentHub(threadedHub) }.get() - assertEquals(mainHub, Sentry.getCurrentHub()) + assertEquals(mainHub, Sentry.getCurrentScopes()) val callableFuture = executor.submit( sut.apply { - assertNotEquals(mainHub, Sentry.getCurrentHub()) - assertNotEquals(threadedHub, Sentry.getCurrentHub()) + assertNotEquals(mainHub, Sentry.getCurrentScopes()) + assertNotEquals(threadedHub, Sentry.getCurrentScopes()) } ) callableFuture.get() executor.submit { - assertNotEquals(mainHub, Sentry.getCurrentHub()) - assertEquals(threadedHub, Sentry.getCurrentHub()) + assertNotEquals(mainHub, Sentry.getCurrentScopes()) + assertEquals(threadedHub, Sentry.getCurrentScopes()) }.get() } } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryWebFluxTracingFilterTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryWebFluxTracingFilterTest.kt index be56a8391d..2113c748ee 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryWebFluxTracingFilterTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryWebFluxTracingFilterTest.kt @@ -2,8 +2,9 @@ package io.sentry.spring.webflux import io.sentry.Breadcrumb import io.sentry.Hint -import io.sentry.IHub +import io.sentry.HubScopesWrapper import io.sentry.ILogger +import io.sentry.IScopes import io.sentry.PropagationContext import io.sentry.ScopeCallback import io.sentry.Sentry @@ -17,7 +18,7 @@ import io.sentry.TransactionOptions import io.sentry.protocol.SentryId import io.sentry.protocol.SentryTransaction import io.sentry.protocol.TransactionNameSource -import io.sentry.spring.webflux.SentryWebFilter.SENTRY_HUB_KEY +import io.sentry.spring.webflux.SentryWebFilter.SENTRY_SCOPES_KEY import org.assertj.core.api.Assertions.assertThat import org.mockito.Mockito import org.mockito.kotlin.any @@ -47,7 +48,7 @@ import kotlin.test.fail class SentryWebFluxTracingFilterTest { private class Fixture { - val hub = mock() + val scopes = mock() lateinit var request: MockServerHttpRequest lateinit var exchange: MockServerWebExchange val chain = mock() @@ -58,35 +59,37 @@ class SentryWebFluxTracingFilterTest { val logger = mock() init { - whenever(hub.options).thenReturn(options) + whenever(scopes.options).thenReturn(options) } fun getSut(isEnabled: Boolean = true, status: HttpStatus = HttpStatus.OK, sentryTraceHeader: String? = null, baggageHeaders: List? = null, method: HttpMethod = HttpMethod.POST): SentryWebFilter { var requestBuilder = MockServerHttpRequest.method(method, "/product/{id}", 12) if (sentryTraceHeader != null) { requestBuilder = requestBuilder.header("sentry-trace", sentryTraceHeader) - whenever(hub.startTransaction(any(), check { it.isBindToScope })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, hub) } + whenever(scopes.startTransaction(any(), check { it.isBindToScope })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, scopes) } } if (baggageHeaders != null) { requestBuilder = requestBuilder.header("baggage", *baggageHeaders.toTypedArray()) } request = requestBuilder.build() exchange = MockServerWebExchange.builder(request).build() - exchange.attributes.put(SENTRY_HUB_KEY, hub) + exchange.attributes.put(SENTRY_SCOPES_KEY, scopes) exchange.attributes.put(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE, PathPatternParser().parse("/product/{id}")) exchange.response.statusCode = status - whenever(hub.startTransaction(any(), check { assertTrue(it.isBindToScope) })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, hub) } - whenever(hub.isEnabled).thenReturn(isEnabled) + whenever(scopes.startTransaction(any(), check { assertTrue(it.isBindToScope) })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, scopes) } + whenever(scopes.isEnabled).thenReturn(isEnabled) whenever(chain.filter(any())).thenReturn(Mono.create { s -> s.success() }) - whenever(hub.continueTrace(anyOrNull(), anyOrNull())).thenAnswer { TransactionContext.fromPropagationContext(PropagationContext.fromHeaders(logger, it.arguments[0] as String?, it.arguments[1] as List?)) } - return SentryWebFilter(hub) + whenever(scopes.continueTrace(anyOrNull(), anyOrNull())).thenAnswer { TransactionContext.fromPropagationContext(PropagationContext.fromHeaders(logger, it.arguments[0] as String?, it.arguments[1] as List?)) } + return SentryWebFilter(scopes) } } private val fixture = Fixture() - fun withMockHub(closure: () -> Unit) = Mockito.mockStatic(Sentry::class.java).use { - it.`when` { Sentry.cloneMainHub() }.thenReturn(fixture.hub) + fun withMockScopes(closure: () -> Unit) = Mockito.mockStatic(Sentry::class.java).use { + it.`when` { Sentry.getCurrentHub() }.thenReturn(HubScopesWrapper(fixture.scopes)) + it.`when` { Sentry.getCurrentScopes() }.thenReturn(fixture.scopes) + it.`when` { Sentry.cloneMainHub() }.thenReturn(fixture.scopes) closure.invoke() } @@ -94,10 +97,10 @@ class SentryWebFluxTracingFilterTest { fun `creates transaction around the request`() { val filter = fixture.getSut() - withMockHub { + withMockScopes { filter.filter(fixture.exchange, fixture.chain).block() - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( check { assertEquals("POST /product/12", it.name) assertEquals(TransactionNameSource.URL, it.transactionNameSource) @@ -110,7 +113,7 @@ class SentryWebFluxTracingFilterTest { } ) verify(fixture.chain).filter(fixture.exchange) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.transaction).isEqualTo("POST /product/{id}") assertThat(it.contexts.trace!!.status).isEqualTo(SpanStatus.OK) @@ -129,10 +132,10 @@ class SentryWebFluxTracingFilterTest { fun `sets correct span status based on the response status`() { val filter = fixture.getSut(status = HttpStatus.INTERNAL_SERVER_ERROR) - withMockHub { + withMockScopes { filter.filter(fixture.exchange, fixture.chain).block() - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.status).isEqualTo(SpanStatus.INTERNAL_ERROR) assertThat(it.contexts.response!!.statusCode).isEqualTo(500) @@ -148,10 +151,10 @@ class SentryWebFluxTracingFilterTest { fun `does not set span status for response status that dont match predefined span statuses`() { val filter = fixture.getSut(status = HttpStatus.FOUND) - withMockHub { + withMockScopes { filter.filter(fixture.exchange, fixture.chain).block() - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.status).isNull() }, @@ -166,10 +169,10 @@ class SentryWebFluxTracingFilterTest { fun `when sentry trace is not present, transaction does not have parentSpanId set`() { val filter = fixture.getSut() - withMockHub { + withMockScopes { filter.filter(fixture.exchange, fixture.chain).block() - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.parentSpanId).isNull() }, @@ -185,10 +188,10 @@ class SentryWebFluxTracingFilterTest { val parentSpanId = SpanId() val filter = fixture.getSut(sentryTraceHeader = "${SentryId()}-$parentSpanId-1") - withMockHub { + withMockScopes { filter.filter(fixture.exchange, fixture.chain).block() - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.parentSpanId).isEqualTo(parentSpanId) }, @@ -200,16 +203,16 @@ class SentryWebFluxTracingFilterTest { } @Test - fun `when hub is disabled, components are not invoked`() { + fun `when scopes is disabled, components are not invoked`() { val filter = fixture.getSut(isEnabled = false) - withMockHub { + withMockScopes { filter.filter(fixture.exchange, fixture.chain).block() verify(fixture.chain).filter(fixture.exchange) - verify(fixture.hub).isEnabled - verifyNoMoreInteractions(fixture.hub) + verify(fixture.scopes).isEnabled + verifyNoMoreInteractions(fixture.scopes) } } @@ -217,7 +220,7 @@ class SentryWebFluxTracingFilterTest { fun `sets status to internal server error when chain throws exception`() { val filter = fixture.getSut() - withMockHub { + withMockScopes { whenever(fixture.chain.filter(any())).thenReturn(Mono.error(RuntimeException("error"))) try { @@ -225,7 +228,7 @@ class SentryWebFluxTracingFilterTest { fail("filter is expected to rethrow exception") } catch (_: Exception) { } - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.status).isEqualTo(SpanStatus.INTERNAL_ERROR) }, @@ -240,21 +243,21 @@ class SentryWebFluxTracingFilterTest { fun `does not track OPTIONS request with traceOptionsRequests=false`() { val filter = fixture.getSut(method = HttpMethod.OPTIONS) - withMockHub { + withMockScopes { fixture.options.isTraceOptionsRequests = false filter.filter(fixture.exchange, fixture.chain).block() verify(fixture.chain).filter(fixture.exchange) - verify(fixture.hub).isEnabled - verify(fixture.hub, times(2)).options - verify(fixture.hub).continueTrace(anyOrNull(), anyOrNull()) - verify(fixture.hub).pushScope() - verify(fixture.hub).addBreadcrumb(any(), any()) - verify(fixture.hub).configureScope(any()) - verify(fixture.hub).popScope() - verifyNoMoreInteractions(fixture.hub) + verify(fixture.scopes).isEnabled + verify(fixture.scopes, times(2)).options + verify(fixture.scopes).continueTrace(anyOrNull(), anyOrNull()) + verify(fixture.scopes).pushScope() + verify(fixture.scopes).addBreadcrumb(any(), any()) + verify(fixture.scopes).configureScope(any()) + verify(fixture.scopes).popScope() + verifyNoMoreInteractions(fixture.scopes) } } @@ -262,14 +265,14 @@ class SentryWebFluxTracingFilterTest { fun `tracks OPTIONS request with traceOptionsRequests=true`() { val filter = fixture.getSut(method = HttpMethod.OPTIONS) - withMockHub { + withMockScopes { fixture.options.isTraceOptionsRequests = true filter.filter(fixture.exchange, fixture.chain).block() verify(fixture.chain).filter(fixture.exchange) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.parentSpanId).isNull() }, @@ -284,14 +287,14 @@ class SentryWebFluxTracingFilterTest { fun `tracks POST request with traceOptionsRequests=false`() { val filter = fixture.getSut(method = HttpMethod.POST) - withMockHub { + withMockScopes { fixture.options.isTraceOptionsRequests = false filter.filter(fixture.exchange, fixture.chain).block() verify(fixture.chain).filter(fixture.exchange) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.parentSpanId).isNull() }, @@ -310,19 +313,19 @@ class SentryWebFluxTracingFilterTest { fixture.options.enableTracing = false val filter = fixture.getSut(sentryTraceHeader = sentryTraceHeaderString, baggageHeaders = baggageHeaderStrings) - withMockHub { + withMockScopes { filter.filter(fixture.exchange, fixture.chain).block() verify(fixture.chain).filter(fixture.exchange) - verify(fixture.hub, never()).captureTransaction( + verify(fixture.scopes, never()).captureTransaction( anyOrNull(), anyOrNull(), anyOrNull(), anyOrNull() ) - verify(fixture.hub).continueTrace(eq(sentryTraceHeaderString), eq(baggageHeaderStrings)) + verify(fixture.scopes).continueTrace(eq(sentryTraceHeaderString), eq(baggageHeaderStrings)) } } } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryWebfluxIntegrationTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryWebfluxIntegrationTest.kt index 0d4346c5ae..8c5aeb1c0a 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryWebfluxIntegrationTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryWebfluxIntegrationTest.kt @@ -1,8 +1,8 @@ package io.sentry.spring.webflux -import io.sentry.HubAdapter -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ITransportFactory +import io.sentry.ScopesAdapter import io.sentry.Sentry import io.sentry.checkEvent import io.sentry.checkTransaction @@ -160,13 +160,13 @@ open class App { open fun mockTransport() = transport @Bean - open fun hub() = HubAdapter.getInstance() + open fun scopes() = ScopesAdapter.getInstance() @Bean - open fun sentryFilter(hub: IHub) = SentryWebFilter(hub) + open fun sentryFilter(scopes: IScopes) = SentryWebFilter(scopes) @Bean - open fun sentryWebExceptionHandler(hub: IHub) = SentryWebExceptionHandler(hub) + open fun sentryWebExceptionHandler(scopes: IScopes) = SentryWebExceptionHandler(scopes) @Bean open fun sentryScheduleHookRegistrar() = ApplicationRunner { From 792d482570aca7ef1d321e0cf46dc543db431c96 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Tue, 2 Apr 2024 14:53:48 +0200 Subject: [PATCH 14/28] Replace `IHub` with `IScopes` in Spring 6 / Spring Boot 3 integrations --- .../api/sentry-spring-boot-jakarta.api | 2 +- .../boot/jakarta/SentryAutoConfiguration.java | 43 ++++----- .../SentrySpanRestClientCustomizer.java | 6 +- .../SentrySpanRestTemplateCustomizer.java | 6 +- .../SentrySpanWebClientCustomizer.java | 6 +- .../SentryWebfluxAutoConfiguration.java | 21 +++-- .../jakarta/SentryAutoConfigurationTest.kt | 12 +-- .../SentrySpanRestClientCustomizerTest.kt | 22 ++--- .../SentrySpanRestTemplateCustomizerTest.kt | 22 ++--- .../SentrySpanWebClientCustomizerTest.kt | 22 ++--- .../jakarta/it/SentrySpringIntegrationTest.kt | 6 +- .../api/sentry-spring-jakarta.api | 61 ++++++------ .../sentry/spring/jakarta/EnableSentry.java | 2 +- .../jakarta/SentryExceptionResolver.java | 10 +- .../spring/jakarta/SentryHubRegistrar.java | 4 +- .../jakarta/SentryInitBeanPostProcessor.java | 16 ++-- .../spring/jakarta/SentryRequestResolver.java | 16 ++-- .../spring/jakarta/SentrySpringFilter.java | 38 ++++---- .../spring/jakarta/SentryTaskDecorator.java | 18 ++-- .../spring/jakarta/SentryUserFilter.java | 12 +-- .../jakarta/checkin/SentryCheckInAdvice.java | 28 +++--- ...SentryCaptureExceptionParameterAdvice.java | 14 +-- .../graphql/SentryBatchLoaderRegistry.java | 16 ++-- .../graphql/SentryDgsSubscriptionHandler.java | 6 +- .../SentrySpringSubscriptionHandler.java | 6 +- .../jakarta/tracing/SentrySpanAdvice.java | 14 +-- ...entrySpanClientHttpRequestInterceptor.java | 18 ++-- .../SentrySpanClientWebRequestFilter.java | 14 +-- .../jakarta/tracing/SentryTracingFilter.java | 31 +++--- .../tracing/SentryTransactionAdvice.java | 20 ++-- .../webflux/AbstractSentryWebFilter.java | 35 +++---- .../spring/jakarta/webflux/ReactorUtils.java | 35 ++++--- .../SentryReactorThreadLocalAccessor.java | 18 ++-- .../webflux/SentryRequestResolver.java | 13 +-- .../jakarta/webflux/SentryScheduleHook.java | 12 ++- .../webflux/SentryWebExceptionHandler.java | 18 ++-- .../jakarta/webflux/SentryWebFilter.java | 16 ++-- ...entryWebFilterWithThreadLocalAccessor.java | 13 +-- .../sentry/spring/jakarta/EnableSentryTest.kt | 4 +- .../spring/jakarta/SentryCheckInAdviceTest.kt | 94 +++++++++---------- .../jakarta/SentryExceptionResolverTest.kt | 28 +++--- .../SentryInitBeanPostProcessorTest.kt | 10 +- ...yRequestHttpServletRequestProcessorTest.kt | 6 +- .../spring/jakarta/SentrySpringFilterTest.kt | 20 ++-- .../spring/jakarta/SentryTaskDecoratorTest.kt | 16 ++-- .../spring/jakarta/SentryUserFilterTest.kt | 20 ++-- ...ntryCaptureExceptionParameterAdviceTest.kt | 16 ++-- .../SentrySpringSubscriptionHandlerTest.kt | 14 +-- .../mvc/SentrySpringIntegrationTest.kt | 24 ++--- .../jakarta/tracing/SentrySpanAdviceTest.kt | 40 ++++---- .../tracing/SentryTracingFilterTest.kt | 52 +++++----- .../tracing/SentryTransactionAdviceTest.kt | 38 ++++---- .../jakarta/webflux/ReactorUtilsTest.kt | 45 ++++----- .../jakarta/webflux/SentryScheduleHookTest.kt | 16 ++-- .../webflux/SentryWebFluxTracingFilterTest.kt | 93 +++++++++--------- .../webflux/SentryWebfluxIntegrationTest.kt | 10 +- 56 files changed, 623 insertions(+), 595 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 a392ff75ee..009036082e 100644 --- a/sentry-spring-boot-jakarta/api/sentry-spring-boot-jakarta.api +++ b/sentry-spring-boot-jakarta/api/sentry-spring-boot-jakarta.api @@ -62,7 +62,7 @@ public class io/sentry/spring/boot/jakarta/SentryProperties$Reactive { public class io/sentry/spring/boot/jakarta/SentryWebfluxAutoConfiguration { public fun ()V - public fun sentryWebExceptionHandler (Lio/sentry/IHub;)Lio/sentry/spring/jakarta/webflux/SentryWebExceptionHandler; + public fun sentryWebExceptionHandler (Lio/sentry/IScopes;)Lio/sentry/spring/jakarta/webflux/SentryWebExceptionHandler; } public class io/sentry/spring/boot/jakarta/graphql/SentryGraphqlAutoConfiguration { diff --git a/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentryAutoConfiguration.java b/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentryAutoConfiguration.java index fbf3162280..b2c8df213c 100644 --- a/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentryAutoConfiguration.java +++ b/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentryAutoConfiguration.java @@ -3,10 +3,10 @@ import com.jakewharton.nopen.annotation.Open; import graphql.GraphQLError; import io.sentry.EventProcessor; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ITransportFactory; import io.sentry.Integration; +import io.sentry.ScopesAdapter; import io.sentry.Sentry; import io.sentry.SentryIntegrationPackageStorage; import io.sentry.SentryOptions; @@ -116,7 +116,7 @@ static class HubConfiguration { } @Bean - public @NotNull IHub sentryHub( + public @NotNull IScopes sentryHub( final @NotNull List> optionsConfigurations, final @NotNull SentryProperties options, final @NotNull ObjectProvider gitProperties) { @@ -139,7 +139,7 @@ static class HubConfiguration { // here we make sure that only classes that extend throwable are set on this field options.getIgnoredExceptionsForType().removeIf(it -> !Throwable.class.isAssignableFrom(it)); Sentry.init(options); - return HubAdapter.getInstance(); + return ScopesAdapter.getInstance(); } @Configuration(proxyBeanMethods = false) @@ -239,7 +239,7 @@ static class SentrySecurityConfiguration { * HttpServletRequest#getUserPrincipal()}. If Spring Security is auto-configured, its order is * set to run after Spring Security. * - * @param hub the Sentry hub + * @param scopes the Sentry scopes * @param sentryProperties the Sentry properties * @param sentryUserProvider the user provider * @return {@link SentryUserFilter} registration bean @@ -247,11 +247,11 @@ static class SentrySecurityConfiguration { @Bean @ConditionalOnBean(SentryUserProvider.class) public @NotNull FilterRegistrationBean sentryUserFilter( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull SentryProperties sentryProperties, final @NotNull List sentryUserProvider) { final FilterRegistrationBean filter = new FilterRegistrationBean<>(); - filter.setFilter(new SentryUserFilter(hub, sentryUserProvider)); + filter.setFilter(new SentryUserFilter(scopes, sentryUserProvider)); filter.setOrder(resolveUserFilterOrder(sentryProperties)); return filter; } @@ -263,8 +263,8 @@ static class SentrySecurityConfiguration { } @Bean - public @NotNull SentryRequestResolver sentryRequestResolver(final @NotNull IHub hub) { - return new SentryRequestResolver(hub); + public @NotNull SentryRequestResolver sentryRequestResolver(final @NotNull IScopes scopes) { + return new SentryRequestResolver(scopes); } @Bean @@ -276,12 +276,12 @@ static class SentrySecurityConfiguration { @Bean @ConditionalOnMissingBean(name = "sentrySpringFilter") public @NotNull FilterRegistrationBean sentrySpringFilter( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull SentryRequestResolver requestResolver, final @NotNull TransactionNameProvider transactionNameProvider) { FilterRegistrationBean filter = new FilterRegistrationBean<>( - new SentrySpringFilter(hub, requestResolver, transactionNameProvider)); + new SentrySpringFilter(scopes, requestResolver, transactionNameProvider)); filter.setOrder(SENTRY_SPRING_FILTER_PRECEDENCE); return filter; } @@ -289,9 +289,10 @@ static class SentrySecurityConfiguration { @Bean @ConditionalOnMissingBean(name = "sentryTracingFilter") public FilterRegistrationBean sentryTracingFilter( - final @NotNull IHub hub, final @NotNull TransactionNameProvider transactionNameProvider) { + final @NotNull IScopes scopes, + final @NotNull TransactionNameProvider transactionNameProvider) { FilterRegistrationBean filter = - new FilterRegistrationBean<>(new SentryTracingFilter(hub, transactionNameProvider)); + new FilterRegistrationBean<>(new SentryTracingFilter(scopes, transactionNameProvider)); filter.setOrder(SENTRY_SPRING_FILTER_PRECEDENCE + 1); // must run after SentrySpringFilter return filter; } @@ -300,11 +301,11 @@ public FilterRegistrationBean sentryTracingFilter( @ConditionalOnMissingBean @ConditionalOnClass(HandlerExceptionResolver.class) public @NotNull SentryExceptionResolver sentryExceptionResolver( - final @NotNull IHub sentryHub, + final @NotNull IScopes scopes, final @NotNull TransactionNameProvider transactionNameProvider, final @NotNull SentryProperties options) { return new SentryExceptionResolver( - sentryHub, transactionNameProvider, options.getExceptionResolverOrder()); + scopes, transactionNameProvider, options.getExceptionResolverOrder()); } } @@ -354,8 +355,8 @@ static class SentrySpanPointcutAutoConfiguration {} @Open static class SentryPerformanceRestTemplateConfiguration { @Bean - public SentrySpanRestTemplateCustomizer sentrySpanRestTemplateCustomizer(IHub hub) { - return new SentrySpanRestTemplateCustomizer(hub); + public SentrySpanRestTemplateCustomizer sentrySpanRestTemplateCustomizer(IScopes scopes) { + return new SentrySpanRestTemplateCustomizer(scopes); } } @@ -365,8 +366,8 @@ public SentrySpanRestTemplateCustomizer sentrySpanRestTemplateCustomizer(IHub hu @Open static class SentrySpanRestClientConfiguration { @Bean - public SentrySpanRestClientCustomizer sentrySpanRestClientCustomizer(IHub hub) { - return new SentrySpanRestClientCustomizer(hub); + public SentrySpanRestClientCustomizer sentrySpanRestClientCustomizer(IScopes scopes) { + return new SentrySpanRestClientCustomizer(scopes); } } @@ -376,8 +377,8 @@ public SentrySpanRestClientCustomizer sentrySpanRestClientCustomizer(IHub hub) { @Open static class SentryPerformanceWebClientConfiguration { @Bean - public SentrySpanWebClientCustomizer sentrySpanWebClientCustomizer(IHub hub) { - return new SentrySpanWebClientCustomizer(hub); + public SentrySpanWebClientCustomizer sentrySpanWebClientCustomizer(IScopes scopes) { + return new SentrySpanWebClientCustomizer(scopes); } } diff --git a/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentrySpanRestClientCustomizer.java b/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentrySpanRestClientCustomizer.java index 243a4d1f50..304fb6911e 100644 --- a/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentrySpanRestClientCustomizer.java +++ b/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentrySpanRestClientCustomizer.java @@ -1,7 +1,7 @@ package io.sentry.spring.boot.jakarta; import com.jakewharton.nopen.annotation.Open; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.spring.jakarta.tracing.SentrySpanClientHttpRequestInterceptor; import org.jetbrains.annotations.NotNull; import org.springframework.boot.web.client.RestClientCustomizer; @@ -11,8 +11,8 @@ class SentrySpanRestClientCustomizer implements RestClientCustomizer { private final @NotNull SentrySpanClientHttpRequestInterceptor interceptor; - public SentrySpanRestClientCustomizer(final @NotNull IHub hub) { - this.interceptor = new SentrySpanClientHttpRequestInterceptor(hub, false); + public SentrySpanRestClientCustomizer(final @NotNull IScopes scopes) { + this.interceptor = new SentrySpanClientHttpRequestInterceptor(scopes, false); } @Override diff --git a/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentrySpanRestTemplateCustomizer.java b/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentrySpanRestTemplateCustomizer.java index c1ded006e8..4a0faa9875 100644 --- a/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentrySpanRestTemplateCustomizer.java +++ b/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentrySpanRestTemplateCustomizer.java @@ -1,7 +1,7 @@ package io.sentry.spring.boot.jakarta; import com.jakewharton.nopen.annotation.Open; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.spring.jakarta.tracing.SentrySpanClientHttpRequestInterceptor; import java.util.ArrayList; import java.util.List; @@ -14,8 +14,8 @@ class SentrySpanRestTemplateCustomizer implements RestTemplateCustomizer { private final @NotNull SentrySpanClientHttpRequestInterceptor interceptor; - public SentrySpanRestTemplateCustomizer(final @NotNull IHub hub) { - this.interceptor = new SentrySpanClientHttpRequestInterceptor(hub); + public SentrySpanRestTemplateCustomizer(final @NotNull IScopes scopes) { + this.interceptor = new SentrySpanClientHttpRequestInterceptor(scopes); } @Override diff --git a/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentrySpanWebClientCustomizer.java b/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentrySpanWebClientCustomizer.java index afbe2eb6c4..d349ac4c6e 100644 --- a/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentrySpanWebClientCustomizer.java +++ b/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentrySpanWebClientCustomizer.java @@ -1,7 +1,7 @@ package io.sentry.spring.boot.jakarta; import com.jakewharton.nopen.annotation.Open; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.spring.jakarta.tracing.SentrySpanClientWebRequestFilter; import org.jetbrains.annotations.NotNull; import org.springframework.boot.web.reactive.function.client.WebClientCustomizer; @@ -11,8 +11,8 @@ class SentrySpanWebClientCustomizer implements WebClientCustomizer { private final @NotNull SentrySpanClientWebRequestFilter filter; - public SentrySpanWebClientCustomizer(final @NotNull IHub hub) { - this.filter = new SentrySpanClientWebRequestFilter(hub); + public SentrySpanWebClientCustomizer(final @NotNull IScopes scopes) { + this.filter = new SentrySpanClientWebRequestFilter(scopes); } @Override diff --git a/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentryWebfluxAutoConfiguration.java b/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentryWebfluxAutoConfiguration.java index d1cda8b4d2..2bc8bc87ed 100644 --- a/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentryWebfluxAutoConfiguration.java +++ b/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/SentryWebfluxAutoConfiguration.java @@ -1,8 +1,8 @@ package io.sentry.spring.boot.jakarta; import com.jakewharton.nopen.annotation.Open; -import io.sentry.IHub; import io.sentry.IScope; +import io.sentry.IScopes; import io.sentry.spring.jakarta.webflux.SentryScheduleHook; import io.sentry.spring.jakarta.webflux.SentryWebExceptionHandler; import io.sentry.spring.jakarta.webflux.SentryWebFilter; @@ -28,7 +28,7 @@ /** Configures Sentry integration for Spring Webflux and Project Reactor. */ @Configuration(proxyBeanMethods = false) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) -@ConditionalOnBean(IHub.class) +@ConditionalOnBean(IScopes.class) @ConditionalOnClass(Schedulers.class) @Open @ApiStatus.Experimental @@ -44,14 +44,14 @@ static class SentryWebfluxFilterThreadLocalAccessorConfiguration { * Configures a filter that sets up Sentry {@link IScope} for each request. * *

Makes use of newer reactor-core and context-propagation library feature - * ThreadLocalAccessor to propagate the Sentry hub. + * ThreadLocalAccessor to propagate the Sentry scopes. */ @Bean @Order(SENTRY_SPRING_FILTER_PRECEDENCE) public @NotNull SentryWebFilterWithThreadLocalAccessor sentryWebFilterWithContextPropagation( - final @NotNull IHub hub) { + final @NotNull IScopes scopes) { Hooks.enableAutomaticContextPropagation(); - return new SentryWebFilterWithThreadLocalAccessor(hub); + return new SentryWebFilterWithThreadLocalAccessor(scopes); } } @@ -60,7 +60,7 @@ static class SentryWebfluxFilterThreadLocalAccessorConfiguration { @Open static class SentryWebfluxFilterConfiguration { - /** Configures hook that sets correct hub on the executing thread. */ + /** Configures hook that sets correct scopes on the executing thread. */ @Bean public @NotNull ApplicationRunner sentryScheduleHookApplicationRunner() { return args -> { @@ -71,15 +71,16 @@ static class SentryWebfluxFilterConfiguration { /** Configures a filter that sets up Sentry {@link IScope} for each request. */ @Bean @Order(SENTRY_SPRING_FILTER_PRECEDENCE) - public @NotNull SentryWebFilter sentryWebFilter(final @NotNull IHub hub) { - return new SentryWebFilter(hub); + public @NotNull SentryWebFilter sentryWebFilter(final @NotNull IScopes scopes) { + return new SentryWebFilter(scopes); } } /** Configures exception handler that handles unhandled exceptions and sends them to Sentry. */ @Bean - public @NotNull SentryWebExceptionHandler sentryWebExceptionHandler(final @NotNull IHub hub) { - return new SentryWebExceptionHandler(hub); + public @NotNull SentryWebExceptionHandler sentryWebExceptionHandler( + final @NotNull IScopes scopes) { + return new SentryWebExceptionHandler(scopes); } static final class SentryLegacyFilterConfigurationCondition extends AnyNestedCondition { diff --git a/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentryAutoConfigurationTest.kt b/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentryAutoConfigurationTest.kt index aecb1b4712..df0fe96cf0 100644 --- a/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentryAutoConfigurationTest.kt +++ b/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentryAutoConfigurationTest.kt @@ -5,7 +5,7 @@ import io.sentry.AsyncHttpTransportFactory import io.sentry.Breadcrumb import io.sentry.EventProcessor import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ITransportFactory import io.sentry.Integration import io.sentry.NoOpTransportFactory @@ -77,18 +77,18 @@ class SentryAutoConfigurationTest { .withConfiguration(AutoConfigurations.of(SentryAutoConfiguration::class.java, WebMvcAutoConfiguration::class.java)) @Test - fun `hub is not created when auto-configuration dsn is not set`() { + fun `scopes is not created when auto-configuration dsn is not set`() { contextRunner .run { - assertThat(it).doesNotHaveBean(IHub::class.java) + assertThat(it).doesNotHaveBean(IScopes::class.java) } } @Test - fun `hub is created when dsn is provided`() { + fun `scopes is created when dsn is provided`() { contextRunner.withPropertyValues("sentry.dsn=http://key@localhost/proj") .run { - assertThat(it).hasSingleBean(IHub::class.java) + assertThat(it).hasSingleBean(IScopes::class.java) } } @@ -961,7 +961,7 @@ class SentryAutoConfigurationTest { } class CustomIntegration : Integration { - override fun register(hub: IHub, options: SentryOptions) {} + override fun register(scopes: IScopes, options: SentryOptions) {} } @Configuration(proxyBeanMethods = false) diff --git a/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanRestClientCustomizerTest.kt b/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanRestClientCustomizerTest.kt index f9f55ffede..9ba9bf57d2 100644 --- a/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanRestClientCustomizerTest.kt +++ b/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanRestClientCustomizerTest.kt @@ -2,7 +2,7 @@ package io.sentry.spring.boot.jakarta import io.sentry.BaggageHeader import io.sentry.Breadcrumb -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.Scope import io.sentry.ScopeCallback import io.sentry.SentryOptions @@ -36,18 +36,18 @@ import kotlin.test.assertTrue class SentrySpanRestClientCustomizerTest { class Fixture { val sentryOptions = SentryOptions() - val hub = mock() + val scopes = mock() val restClientBuilder = RestClient.builder() var mockServer = MockWebServer() val transaction: SentryTracer - internal val customizer = SentrySpanRestClientCustomizer(hub) + internal val customizer = SentrySpanRestClientCustomizer(scopes) val url = mockServer.url("/test/123").toString() val scope = Scope(sentryOptions) init { - whenever(hub.options).thenReturn(sentryOptions) - doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(hub).configureScope(any()) - transaction = SentryTracer(TransactionContext("aTransaction", "op", TracesSamplingDecision(true)), hub) + whenever(scopes.options).thenReturn(sentryOptions) + doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(scopes).configureScope(any()) + transaction = SentryTracer(TransactionContext("aTransaction", "op", TracesSamplingDecision(true)), scopes) } fun getSut( @@ -75,7 +75,7 @@ class SentrySpanRestClientCustomizerTest { ) if (isTransactionActive) { - whenever(hub.span).thenReturn(transaction) + whenever(scopes.span).thenReturn(transaction) } return restClientBuilder.apply { @@ -247,7 +247,7 @@ class SentrySpanRestClientCustomizerTest { .body("content") .retrieve() .toEntity(String::class.java) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(fixture.url, it.data["url"]) @@ -269,7 +269,7 @@ class SentrySpanRestClientCustomizerTest { .toEntity(String::class.java) } catch (e: Throwable) { } - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(fixture.url, it.data["url"]) @@ -287,7 +287,7 @@ class SentrySpanRestClientCustomizerTest { .body("content") .retrieve() .toEntity(String::class.java) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(fixture.url, it.data["url"]) @@ -309,7 +309,7 @@ class SentrySpanRestClientCustomizerTest { .toEntity(String::class.java) } catch (e: Throwable) { } - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(fixture.url, it.data["url"]) diff --git a/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanRestTemplateCustomizerTest.kt b/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanRestTemplateCustomizerTest.kt index db5b25de44..4ab3205b31 100644 --- a/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanRestTemplateCustomizerTest.kt +++ b/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanRestTemplateCustomizerTest.kt @@ -2,7 +2,7 @@ package io.sentry.spring.boot.jakarta import io.sentry.BaggageHeader import io.sentry.Breadcrumb -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.Scope import io.sentry.ScopeCallback import io.sentry.SentryOptions @@ -37,21 +37,21 @@ import kotlin.test.assertTrue class SentrySpanRestTemplateCustomizerTest { class Fixture { val sentryOptions = SentryOptions() - val hub = mock() + val scopes = mock() val restTemplate = RestTemplateBuilder() .setConnectTimeout(Duration.ofSeconds(2)) .setReadTimeout(Duration.ofSeconds(2)) .build() var mockServer = MockWebServer() val transaction: SentryTracer - internal val customizer = SentrySpanRestTemplateCustomizer(hub) + internal val customizer = SentrySpanRestTemplateCustomizer(scopes) val url = mockServer.url("/test/123").toString() val scope = Scope(sentryOptions) init { - whenever(hub.options).thenReturn(sentryOptions) - doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(hub).configureScope(any()) - transaction = SentryTracer(TransactionContext("aTransaction", "op", TracesSamplingDecision(true)), hub) + whenever(scopes.options).thenReturn(sentryOptions) + doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(scopes).configureScope(any()) + transaction = SentryTracer(TransactionContext("aTransaction", "op", TracesSamplingDecision(true)), scopes) } fun getSut(isTransactionActive: Boolean, status: HttpStatus = HttpStatus.OK, socketPolicy: SocketPolicy = SocketPolicy.KEEP_OPEN, includeMockServerInTracingOrigins: Boolean = true): RestTemplate { @@ -74,7 +74,7 @@ class SentrySpanRestTemplateCustomizerTest { ) if (isTransactionActive) { - whenever(hub.span).thenReturn(transaction) + whenever(scopes.span).thenReturn(transaction) } return restTemplate @@ -209,7 +209,7 @@ class SentrySpanRestTemplateCustomizerTest { @Test fun `when transaction is active adds breadcrumb when http calls succeeds`() { fixture.getSut(isTransactionActive = true).postForObject(fixture.url, "content", String::class.java) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(fixture.url, it.data["url"]) @@ -227,7 +227,7 @@ class SentrySpanRestTemplateCustomizerTest { fixture.getSut(isTransactionActive = true, status = HttpStatus.INTERNAL_SERVER_ERROR).getForObject(fixture.url, String::class.java) } catch (e: Throwable) { } - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(fixture.url, it.data["url"]) @@ -240,7 +240,7 @@ class SentrySpanRestTemplateCustomizerTest { @Test fun `when transaction is not active adds breadcrumb when http calls succeeds`() { fixture.getSut(isTransactionActive = false).postForObject(fixture.url, "content", String::class.java) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(fixture.url, it.data["url"]) @@ -258,7 +258,7 @@ class SentrySpanRestTemplateCustomizerTest { fixture.getSut(isTransactionActive = false, status = HttpStatus.INTERNAL_SERVER_ERROR).getForObject(fixture.url, String::class.java) } catch (e: Throwable) { } - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(fixture.url, it.data["url"]) diff --git a/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanWebClientCustomizerTest.kt b/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanWebClientCustomizerTest.kt index 51f0a6cb3d..d3fb5f7d31 100644 --- a/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanWebClientCustomizerTest.kt +++ b/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentrySpanWebClientCustomizerTest.kt @@ -2,8 +2,8 @@ package io.sentry.spring.boot.jakarta import io.sentry.BaggageHeader import io.sentry.Breadcrumb -import io.sentry.IHub import io.sentry.IScope +import io.sentry.IScopes import io.sentry.Scope import io.sentry.ScopeCallback import io.sentry.SentryOptions @@ -39,10 +39,10 @@ class SentrySpanWebClientCustomizerTest { class Fixture { lateinit var sentryOptions: SentryOptions lateinit var scope: IScope - val hub = mock() + val scopes = mock() var mockServer = MockWebServer() lateinit var transaction: SentryTracer - private val customizer = SentrySpanWebClientCustomizer(hub) + private val customizer = SentrySpanWebClientCustomizer(scopes) fun getSut(isTransactionActive: Boolean, status: HttpStatus = HttpStatus.OK, throwIOException: Boolean = false, includeMockServerInTracingOrigins: Boolean = true): WebClient { sentryOptions = SentryOptions().apply { @@ -54,9 +54,9 @@ class SentrySpanWebClientCustomizerTest { dsn = "http://key@localhost/proj" } scope = Scope(sentryOptions) - whenever(hub.options).thenReturn(sentryOptions) - doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(hub).configureScope(any()) - transaction = SentryTracer(TransactionContext("aTransaction", "op", TracesSamplingDecision(true)), hub) + whenever(scopes.options).thenReturn(sentryOptions) + doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(scopes).configureScope(any()) + transaction = SentryTracer(TransactionContext("aTransaction", "op", TracesSamplingDecision(true)), scopes) val webClientBuilder = WebClient.builder() customizer.customize(webClientBuilder) val webClient = webClientBuilder.build() @@ -64,7 +64,7 @@ class SentrySpanWebClientCustomizerTest { if (isTransactionActive) { val scope = Scope(sentryOptions) scope.transaction = transaction - whenever(hub.span).thenReturn(transaction) + whenever(scopes.span).thenReturn(transaction) } val dispatcher: Dispatcher = object : Dispatcher() { @@ -236,7 +236,7 @@ class SentrySpanWebClientCustomizerTest { .retrieve() .bodyToMono(String::class.java) .block() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(uri.toString(), it.data["url"]) @@ -259,7 +259,7 @@ class SentrySpanWebClientCustomizerTest { .block() } catch (e: Throwable) { } - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(uri.toString(), it.data["url"]) @@ -279,7 +279,7 @@ class SentrySpanWebClientCustomizerTest { .retrieve() .bodyToMono(String::class.java) .block() - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(uri.toString(), it.data["url"]) @@ -302,7 +302,7 @@ class SentrySpanWebClientCustomizerTest { .block() } catch (e: Throwable) { } - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { assertEquals("http", it.type) assertEquals(uri.toString(), it.data["url"]) diff --git a/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/it/SentrySpringIntegrationTest.kt b/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/it/SentrySpringIntegrationTest.kt index 4b8a0c26be..13a207d8eb 100644 --- a/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/it/SentrySpringIntegrationTest.kt +++ b/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/it/SentrySpringIntegrationTest.kt @@ -1,6 +1,6 @@ package io.sentry.spring.boot.jakarta.it -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ITransportFactory import io.sentry.Sentry import io.sentry.checkEvent @@ -60,7 +60,7 @@ class SentrySpringIntegrationTest { lateinit var transport: ITransport @SpyBean - lateinit var hub: IHub + lateinit var scopes: IScopes @LocalServerPort var port: Int? = null @@ -188,7 +188,7 @@ class SentrySpringIntegrationTest { restTemplate.getForEntity("http://localhost:$port/throws-handled", String::class.java) - verify(hub, never()).captureEvent(any()) + verify(scopes, never()).captureEvent(any()) } @Test diff --git a/sentry-spring-jakarta/api/sentry-spring-jakarta.api b/sentry-spring-jakarta/api/sentry-spring-jakarta.api index cebbd26b4f..13eb6033f9 100644 --- a/sentry-spring-jakarta/api/sentry-spring-jakarta.api +++ b/sentry-spring-jakarta/api/sentry-spring-jakarta.api @@ -22,7 +22,7 @@ public final class io/sentry/spring/jakarta/HttpServletRequestSentryUserProvider public class io/sentry/spring/jakarta/SentryExceptionResolver : org/springframework/core/Ordered, org/springframework/web/servlet/HandlerExceptionResolver { public static final field MECHANISM_TYPE Ljava/lang/String; - public fun (Lio/sentry/IHub;Lio/sentry/spring/jakarta/tracing/TransactionNameProvider;I)V + public fun (Lio/sentry/IScopes;Lio/sentry/spring/jakarta/tracing/TransactionNameProvider;I)V protected fun createEvent (Ljakarta/servlet/http/HttpServletRequest;Ljava/lang/Exception;)Lio/sentry/SentryEvent; protected fun createHint (Ljakarta/servlet/http/HttpServletRequest;Ljakarta/servlet/http/HttpServletResponse;)Lio/sentry/Hint; public fun getOrder ()I @@ -47,14 +47,14 @@ public class io/sentry/spring/jakarta/SentryRequestHttpServletRequestProcessor : } public class io/sentry/spring/jakarta/SentryRequestResolver { - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun resolveSentryRequest (Ljakarta/servlet/http/HttpServletRequest;)Lio/sentry/protocol/Request; } public class io/sentry/spring/jakarta/SentrySpringFilter : org/springframework/web/filter/OncePerRequestFilter { public fun ()V - public fun (Lio/sentry/IHub;)V - public fun (Lio/sentry/IHub;Lio/sentry/spring/jakarta/SentryRequestResolver;Lio/sentry/spring/jakarta/tracing/TransactionNameProvider;)V + public fun (Lio/sentry/IScopes;)V + public fun (Lio/sentry/IScopes;Lio/sentry/spring/jakarta/SentryRequestResolver;Lio/sentry/spring/jakarta/tracing/TransactionNameProvider;)V protected fun doFilterInternal (Ljakarta/servlet/http/HttpServletRequest;Ljakarta/servlet/http/HttpServletResponse;Ljakarta/servlet/FilterChain;)V } @@ -69,7 +69,7 @@ public final class io/sentry/spring/jakarta/SentryTaskDecorator : org/springfram } public class io/sentry/spring/jakarta/SentryUserFilter : org/springframework/web/filter/OncePerRequestFilter { - public fun (Lio/sentry/IHub;Ljava/util/List;)V + public fun (Lio/sentry/IScopes;Ljava/util/List;)V protected fun doFilterInternal (Ljakarta/servlet/http/HttpServletRequest;Ljakarta/servlet/http/HttpServletResponse;Ljakarta/servlet/FilterChain;)V public fun getSentryUserProviders ()Ljava/util/List; } @@ -96,7 +96,7 @@ public abstract interface annotation class io/sentry/spring/jakarta/checkin/Sent public class io/sentry/spring/jakarta/checkin/SentryCheckInAdvice : org/aopalliance/intercept/MethodInterceptor, org/springframework/context/EmbeddedValueResolverAware { public fun ()V - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun invoke (Lorg/aopalliance/intercept/MethodInvocation;)Ljava/lang/Object; public fun setEmbeddedValueResolver (Lorg/springframework/util/StringValueResolver;)V } @@ -127,7 +127,7 @@ public abstract interface annotation class io/sentry/spring/jakarta/exception/Se public class io/sentry/spring/jakarta/exception/SentryCaptureExceptionParameterAdvice : org/aopalliance/intercept/MethodInterceptor { public fun ()V - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun invoke (Lorg/aopalliance/intercept/MethodInvocation;)Ljava/lang/Object; } @@ -169,7 +169,7 @@ public final class io/sentry/spring/jakarta/graphql/SentryDataFetcherExceptionRe public final class io/sentry/spring/jakarta/graphql/SentryDgsSubscriptionHandler : io/sentry/graphql/SentrySubscriptionHandler { public fun ()V - public fun onSubscriptionResult (Ljava/lang/Object;Lio/sentry/IHub;Lio/sentry/graphql/ExceptionReporter;Lgraphql/execution/instrumentation/parameters/InstrumentationFieldFetchParameters;)Ljava/lang/Object; + public fun onSubscriptionResult (Ljava/lang/Object;Lio/sentry/IScopes;Lio/sentry/graphql/ExceptionReporter;Lgraphql/execution/instrumentation/parameters/InstrumentationFieldFetchParameters;)Ljava/lang/Object; } public final class io/sentry/spring/jakarta/graphql/SentryGraphqlBeanPostProcessor : org/springframework/beans/factory/config/BeanPostProcessor, org/springframework/core/PriorityOrdered { @@ -188,7 +188,7 @@ public class io/sentry/spring/jakarta/graphql/SentryGraphqlConfiguration { public final class io/sentry/spring/jakarta/graphql/SentrySpringSubscriptionHandler : io/sentry/graphql/SentrySubscriptionHandler { public fun ()V - public fun onSubscriptionResult (Ljava/lang/Object;Lio/sentry/IHub;Lio/sentry/graphql/ExceptionReporter;Lgraphql/execution/instrumentation/parameters/InstrumentationFieldFetchParameters;)Ljava/lang/Object; + public fun onSubscriptionResult (Ljava/lang/Object;Lio/sentry/IScopes;Lio/sentry/graphql/ExceptionReporter;Lgraphql/execution/instrumentation/parameters/InstrumentationFieldFetchParameters;)Ljava/lang/Object; } public class io/sentry/spring/jakarta/tracing/SentryAdviceConfiguration { @@ -207,18 +207,18 @@ public abstract interface annotation class io/sentry/spring/jakarta/tracing/Sent public class io/sentry/spring/jakarta/tracing/SentrySpanAdvice : org/aopalliance/intercept/MethodInterceptor { public fun ()V - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun invoke (Lorg/aopalliance/intercept/MethodInvocation;)Ljava/lang/Object; } public class io/sentry/spring/jakarta/tracing/SentrySpanClientHttpRequestInterceptor : org/springframework/http/client/ClientHttpRequestInterceptor { - public fun (Lio/sentry/IHub;)V - public fun (Lio/sentry/IHub;Z)V + public fun (Lio/sentry/IScopes;)V + public fun (Lio/sentry/IScopes;Z)V public fun intercept (Lorg/springframework/http/HttpRequest;[BLorg/springframework/http/client/ClientHttpRequestExecution;)Lorg/springframework/http/client/ClientHttpResponse; } public class io/sentry/spring/jakarta/tracing/SentrySpanClientWebRequestFilter : org/springframework/web/reactive/function/client/ExchangeFilterFunction { - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun filter (Lorg/springframework/web/reactive/function/client/ClientRequest;Lorg/springframework/web/reactive/function/client/ExchangeFunction;)Lreactor/core/publisher/Mono; } @@ -233,8 +233,8 @@ public class io/sentry/spring/jakarta/tracing/SentryTracingConfiguration { public class io/sentry/spring/jakarta/tracing/SentryTracingFilter : org/springframework/web/filter/OncePerRequestFilter { public fun ()V - public fun (Lio/sentry/IHub;)V - public fun (Lio/sentry/IHub;Lio/sentry/spring/jakarta/tracing/TransactionNameProvider;)V + public fun (Lio/sentry/IScopes;)V + public fun (Lio/sentry/IScopes;Lio/sentry/spring/jakarta/tracing/TransactionNameProvider;)V protected fun doFilterInternal (Ljakarta/servlet/http/HttpServletRequest;Ljakarta/servlet/http/HttpServletResponse;Ljakarta/servlet/FilterChain;)V } @@ -246,7 +246,7 @@ public abstract interface annotation class io/sentry/spring/jakarta/tracing/Sent public class io/sentry/spring/jakarta/tracing/SentryTransactionAdvice : org/aopalliance/intercept/MethodInterceptor { public fun ()V - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun invoke (Lorg/aopalliance/intercept/MethodInvocation;)Ljava/lang/Object; } @@ -268,21 +268,22 @@ public abstract interface class io/sentry/spring/jakarta/tracing/TransactionName public abstract class io/sentry/spring/jakarta/webflux/AbstractSentryWebFilter : org/springframework/web/server/WebFilter { public static final field SENTRY_HUB_KEY Ljava/lang/String; - public fun (Lio/sentry/IHub;)V - protected fun doFinally (Lorg/springframework/web/server/ServerWebExchange;Lio/sentry/IHub;Lio/sentry/ITransaction;)V - protected fun doFirst (Lorg/springframework/web/server/ServerWebExchange;Lio/sentry/IHub;)V + public static final field SENTRY_SCOPES_KEY Ljava/lang/String; + public fun (Lio/sentry/IScopes;)V + protected fun doFinally (Lorg/springframework/web/server/ServerWebExchange;Lio/sentry/IScopes;Lio/sentry/ITransaction;)V + protected fun doFirst (Lorg/springframework/web/server/ServerWebExchange;Lio/sentry/IScopes;)V protected fun doOnError (Lio/sentry/ITransaction;Ljava/lang/Throwable;)V - protected fun maybeStartTransaction (Lio/sentry/IHub;Lorg/springframework/http/server/reactive/ServerHttpRequest;)Lio/sentry/ITransaction; - protected fun shouldTraceRequest (Lio/sentry/IHub;Lorg/springframework/http/server/reactive/ServerHttpRequest;)Z - protected fun startTransaction (Lio/sentry/IHub;Lorg/springframework/http/server/reactive/ServerHttpRequest;Lio/sentry/TransactionContext;)Lio/sentry/ITransaction; + protected fun maybeStartTransaction (Lio/sentry/IScopes;Lorg/springframework/http/server/reactive/ServerHttpRequest;)Lio/sentry/ITransaction; + protected fun shouldTraceRequest (Lio/sentry/IScopes;Lorg/springframework/http/server/reactive/ServerHttpRequest;)Z + protected fun startTransaction (Lio/sentry/IScopes;Lorg/springframework/http/server/reactive/ServerHttpRequest;Lio/sentry/TransactionContext;)Lio/sentry/ITransaction; } public final class io/sentry/spring/jakarta/webflux/ReactorUtils { public fun ()V public static fun withSentry (Lreactor/core/publisher/Flux;)Lreactor/core/publisher/Flux; public static fun withSentry (Lreactor/core/publisher/Mono;)Lreactor/core/publisher/Mono; - public static fun withSentryHub (Lreactor/core/publisher/Flux;Lio/sentry/IHub;)Lreactor/core/publisher/Flux; - public static fun withSentryHub (Lreactor/core/publisher/Mono;Lio/sentry/IHub;)Lreactor/core/publisher/Mono; + public static fun withSentryHub (Lreactor/core/publisher/Flux;Lio/sentry/IScopes;)Lreactor/core/publisher/Flux; + public static fun withSentryHub (Lreactor/core/publisher/Mono;Lio/sentry/IScopes;)Lreactor/core/publisher/Mono; public static fun withSentryNewMainHubClone (Lreactor/core/publisher/Flux;)Lreactor/core/publisher/Flux; public static fun withSentryNewMainHubClone (Lreactor/core/publisher/Mono;)Lreactor/core/publisher/Mono; } @@ -290,16 +291,16 @@ public final class io/sentry/spring/jakarta/webflux/ReactorUtils { public final class io/sentry/spring/jakarta/webflux/SentryReactorThreadLocalAccessor : io/micrometer/context/ThreadLocalAccessor { public static final field KEY Ljava/lang/String; public fun ()V - public fun getValue ()Lio/sentry/IHub; + public fun getValue ()Lio/sentry/IScopes; public synthetic fun getValue ()Ljava/lang/Object; public fun key ()Ljava/lang/Object; public fun reset ()V - public fun setValue (Lio/sentry/IHub;)V + public fun setValue (Lio/sentry/IScopes;)V public synthetic fun setValue (Ljava/lang/Object;)V } public class io/sentry/spring/jakarta/webflux/SentryRequestResolver { - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun resolveSentryRequest (Lorg/springframework/http/server/reactive/ServerHttpRequest;)Lio/sentry/protocol/Request; } @@ -311,18 +312,18 @@ public final class io/sentry/spring/jakarta/webflux/SentryScheduleHook : java/ut public final class io/sentry/spring/jakarta/webflux/SentryWebExceptionHandler : org/springframework/web/server/WebExceptionHandler { public static final field MECHANISM_TYPE Ljava/lang/String; - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun handle (Lorg/springframework/web/server/ServerWebExchange;Ljava/lang/Throwable;)Lreactor/core/publisher/Mono; } public class io/sentry/spring/jakarta/webflux/SentryWebFilter : io/sentry/spring/jakarta/webflux/AbstractSentryWebFilter { - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun filter (Lorg/springframework/web/server/ServerWebExchange;Lorg/springframework/web/server/WebFilterChain;)Lreactor/core/publisher/Mono; } public final class io/sentry/spring/jakarta/webflux/SentryWebFilterWithThreadLocalAccessor : io/sentry/spring/jakarta/webflux/AbstractSentryWebFilter { public static final field TRACE_ORIGIN Ljava/lang/String; - public fun (Lio/sentry/IHub;)V + public fun (Lio/sentry/IScopes;)V public fun filter (Lorg/springframework/web/server/ServerWebExchange;Lorg/springframework/web/server/WebFilterChain;)Lreactor/core/publisher/Mono; } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/EnableSentry.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/EnableSentry.java index 1395e035a1..e8cd91f3f4 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/EnableSentry.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/EnableSentry.java @@ -12,7 +12,7 @@ * *

    *
  • creates bean of type {@link io.sentry.SentryOptions} - *
  • registers {@link io.sentry.IHub} for sending Sentry events + *
  • registers {@link io.sentry.IScopes} for sending Sentry events *
  • registers {@link SentryExceptionResolver} to send Sentry event for any uncaught exception * in Spring MVC flow. *
diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryExceptionResolver.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryExceptionResolver.java index 6d4098d624..efa98ef581 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryExceptionResolver.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryExceptionResolver.java @@ -5,7 +5,7 @@ import com.jakewharton.nopen.annotation.Open; import io.sentry.Hint; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.SentryEvent; import io.sentry.SentryLevel; import io.sentry.exception.ExceptionMechanismException; @@ -29,15 +29,15 @@ public class SentryExceptionResolver implements HandlerExceptionResolver, Ordered { public static final String MECHANISM_TYPE = "Spring6ExceptionResolver"; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @NotNull TransactionNameProvider transactionNameProvider; private final int order; public SentryExceptionResolver( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull TransactionNameProvider transactionNameProvider, final int order) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); this.transactionNameProvider = Objects.requireNonNull(transactionNameProvider, "transactionNameProvider is required"); this.order = order; @@ -53,7 +53,7 @@ public SentryExceptionResolver( final SentryEvent event = createEvent(request, ex); final Hint hint = createHint(request, response); - hub.captureEvent(event, hint); + scopes.captureEvent(event, hint); // null = run other HandlerExceptionResolvers to actually handle the exception return null; diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryHubRegistrar.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryHubRegistrar.java index 4a8789c812..9598f0c926 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryHubRegistrar.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryHubRegistrar.java @@ -1,7 +1,7 @@ package io.sentry.spring.jakarta; import com.jakewharton.nopen.annotation.Open; -import io.sentry.HubAdapter; +import io.sentry.ScopesAdapter; import io.sentry.SentryIntegrationPackageStorage; import io.sentry.SentryOptions; import io.sentry.protocol.SdkVersion; @@ -60,7 +60,7 @@ private void registerSentryOptions( private void registerSentryHubBean(final @NotNull BeanDefinitionRegistry registry) { final BeanDefinitionBuilder builder = - BeanDefinitionBuilder.genericBeanDefinition(HubAdapter.class); + BeanDefinitionBuilder.genericBeanDefinition(ScopesAdapter.class); builder.setInitMethodName("getInstance"); registry.registerBeanDefinition("sentryHub", builder.getBeanDefinition()); diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryInitBeanPostProcessor.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryInitBeanPostProcessor.java index 9937bfbf1a..d33dfca8d8 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryInitBeanPostProcessor.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryInitBeanPostProcessor.java @@ -2,10 +2,10 @@ import com.jakewharton.nopen.annotation.Open; import io.sentry.EventProcessor; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ITransportFactory; import io.sentry.Integration; +import io.sentry.ScopesAdapter; import io.sentry.Sentry; import io.sentry.SentryOptions; import io.sentry.SentryOptions.TracesSamplerCallback; @@ -27,15 +27,15 @@ public class SentryInitBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware, DisposableBean { private @Nullable ApplicationContext applicationContext; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; public SentryInitBeanPostProcessor() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } - SentryInitBeanPostProcessor(final @NotNull IHub hub) { - Objects.requireNonNull(hub, "hub is required"); - this.hub = hub; + SentryInitBeanPostProcessor(final @NotNull IScopes scopes) { + Objects.requireNonNull(scopes, "Scopes are required"); + this.scopes = scopes; } @Override @@ -86,6 +86,6 @@ public void setApplicationContext(final @NotNull ApplicationContext applicationC @Override public void destroy() { - hub.close(); + scopes.close(); } } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryRequestResolver.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryRequestResolver.java index e1bc45ac64..71f9079f9f 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryRequestResolver.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryRequestResolver.java @@ -1,7 +1,7 @@ package io.sentry.spring.jakarta; import com.jakewharton.nopen.annotation.Open; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.SentryLevel; import io.sentry.protocol.Request; import io.sentry.util.HttpUtils; @@ -20,11 +20,11 @@ @Open public class SentryRequestResolver { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private volatile @Nullable List extraSecurityCookies; - public SentryRequestResolver(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "options is required"); + public SentryRequestResolver(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "options is required"); } // httpRequest.getRequestURL() returns StringBuffer which is considered an obsolete class. @@ -40,7 +40,7 @@ public SentryRequestResolver(final @NotNull IHub hub) { extractSecurityCookieNamesOrUseCached(httpRequest); sentryRequest.setHeaders(resolveHeadersMap(httpRequest, additionalSecurityCookieNames)); - if (hub.getOptions().isSendDefaultPii()) { + if (scopes.getOptions().isSendDefaultPii()) { String cookieName = HttpUtils.COOKIE_HEADER_NAME; final @Nullable List filteredHeaders = HttpUtils.filterOutSecurityCookiesFromHeader( @@ -57,7 +57,8 @@ Map resolveHeadersMap( final Map headersMap = new HashMap<>(); for (String headerName : Collections.list(request.getHeaderNames())) { // do not copy personal information identifiable headers - if (hub.getOptions().isSendDefaultPii() || !HttpUtils.containsSensitiveHeader(headerName)) { + if (scopes.getOptions().isSendDefaultPii() + || !HttpUtils.containsSensitiveHeader(headerName)) { final @Nullable List filteredHeaders = HttpUtils.filterOutSecurityCookiesFromHeader( request.getHeaders(headerName), headerName, additionalSecurityCookieNames); @@ -94,7 +95,8 @@ private List extractSecurityCookieNames(final @NotNull HttpServletReques } } } catch (Throwable t) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log(SentryLevel.WARNING, "Failed to extract session cookie name from request.", t); } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentrySpringFilter.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentrySpringFilter.java index 129ea739d6..be06d3d253 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentrySpringFilter.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentrySpringFilter.java @@ -8,8 +8,8 @@ import io.sentry.Breadcrumb; import io.sentry.EventProcessor; import io.sentry.Hint; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; +import io.sentry.ScopesAdapter; import io.sentry.SentryEvent; import io.sentry.SentryLevel; import io.sentry.SentryOptions; @@ -29,26 +29,26 @@ @Open public class SentrySpringFilter extends OncePerRequestFilter { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @NotNull SentryRequestResolver requestResolver; private final @NotNull TransactionNameProvider transactionNameProvider; public SentrySpringFilter( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull SentryRequestResolver requestResolver, final @NotNull TransactionNameProvider transactionNameProvider) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); this.requestResolver = Objects.requireNonNull(requestResolver, "requestResolver is required"); this.transactionNameProvider = Objects.requireNonNull(transactionNameProvider, "transactionNameProvider is required"); } - public SentrySpringFilter(final @NotNull IHub hub) { - this(hub, new SentryRequestResolver(hub), new SpringMvcTransactionNameProvider()); + public SentrySpringFilter(final @NotNull IScopes scopes) { + this(scopes, new SentryRequestResolver(scopes), new SpringMvcTransactionNameProvider()); } public SentrySpringFilter() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } @Override @@ -57,20 +57,20 @@ protected void doFilterInternal( final @NotNull HttpServletResponse response, final @NotNull FilterChain filterChain) throws ServletException, IOException { - if (hub.isEnabled()) { + if (scopes.isEnabled()) { // request may qualify for caching request body, if so resolve cached request final HttpServletRequest request = resolveHttpServletRequest(servletRequest); - hub.pushScope(); + scopes.pushScope(); try { final Hint hint = new Hint(); hint.set(SPRING_REQUEST_FILTER_REQUEST, servletRequest); hint.set(SPRING_REQUEST_FILTER_RESPONSE, response); - hub.addBreadcrumb(Breadcrumb.http(request.getRequestURI(), request.getMethod()), hint); + scopes.addBreadcrumb(Breadcrumb.http(request.getRequestURI(), request.getMethod()), hint); configureScope(request); filterChain.doFilter(request, response); } finally { - hub.popScope(); + scopes.popScope(); } } else { filterChain.doFilter(servletRequest, response); @@ -79,7 +79,7 @@ protected void doFilterInternal( private void configureScope(HttpServletRequest request) { try { - hub.configureScope( + scopes.configureScope( scope -> { // set basic request information on the scope scope.setRequest(requestResolver.resolveSentryRequest(request)); @@ -92,11 +92,12 @@ private void configureScope(HttpServletRequest request) { // request processing if (request instanceof CachedBodyHttpServletRequest) { scope.addEventProcessor( - new RequestBodyExtractingEventProcessor(request, hub.getOptions())); + new RequestBodyExtractingEventProcessor(request, scopes.getOptions())); } }); } catch (Throwable e) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log(SentryLevel.ERROR, "Failed to set scope for HTTP request", e); } @@ -104,12 +105,13 @@ private void configureScope(HttpServletRequest request) { private @NotNull HttpServletRequest resolveHttpServletRequest( final @NotNull HttpServletRequest request) { - if (hub.getOptions().isSendDefaultPii() - && qualifiesForCaching(request, hub.getOptions().getMaxRequestBodySize())) { + if (scopes.getOptions().isSendDefaultPii() + && qualifiesForCaching(request, scopes.getOptions().getMaxRequestBodySize())) { try { return new CachedBodyHttpServletRequest(request); } catch (IOException e) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.WARNING, diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryTaskDecorator.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryTaskDecorator.java index 5c4f37e521..c99abf3e21 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryTaskDecorator.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryTaskDecorator.java @@ -1,6 +1,6 @@ package io.sentry.spring.jakarta; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.Sentry; import java.util.concurrent.Callable; import org.jetbrains.annotations.NotNull; @@ -8,22 +8,24 @@ import org.springframework.scheduling.annotation.Async; /** - * Sets a current hub on a thread running a {@link Runnable} given by parameter. Used to propagate - * the current {@link IHub} on the thread executing async task - like MVC controller methods - * returning a {@link Callable} or Spring beans methods annotated with {@link Async}. + * Sets a current scopes on a thread running a {@link Runnable} given by parameter. Used to + * propagate the current {@link IScopes} on the thread executing async task - like MVC controller + * methods returning a {@link Callable} or Spring beans methods annotated with {@link Async}. */ public final class SentryTaskDecorator implements TaskDecorator { @Override + @SuppressWarnings("deprecation") public @NotNull Runnable decorate(final @NotNull Runnable runnable) { - final IHub newHub = Sentry.getCurrentHub().clone(); + // TODO fork + final IScopes newHub = Sentry.getCurrentScopes().clone(); return () -> { - final IHub oldState = Sentry.getCurrentHub(); - Sentry.setCurrentHub(newHub); + final IScopes oldState = Sentry.getCurrentScopes(); + Sentry.setCurrentScopes(newHub); try { runnable.run(); } finally { - Sentry.setCurrentHub(oldState); + Sentry.setCurrentScopes(oldState); } }; } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryUserFilter.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryUserFilter.java index f7b8bc62d6..31cc73a346 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryUserFilter.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryUserFilter.java @@ -1,8 +1,8 @@ package io.sentry.spring.jakarta; import com.jakewharton.nopen.annotation.Open; -import io.sentry.IHub; import io.sentry.IScope; +import io.sentry.IScopes; import io.sentry.IpAddressUtils; import io.sentry.protocol.User; import io.sentry.util.Objects; @@ -26,12 +26,12 @@ */ @Open public class SentryUserFilter extends OncePerRequestFilter { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @NotNull List sentryUserProviders; public SentryUserFilter( - final @NotNull IHub hub, final @NotNull List sentryUserProviders) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + final @NotNull IScopes scopes, final @NotNull List sentryUserProviders) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); this.sentryUserProviders = Objects.requireNonNull(sentryUserProviders, "sentryUserProviders list is required"); } @@ -46,13 +46,13 @@ protected void doFilterInternal( for (final SentryUserProvider provider : sentryUserProviders) { apply(user, provider.provideUser()); } - if (hub.getOptions().isSendDefaultPii()) { + if (scopes.getOptions().isSendDefaultPii()) { if (IpAddressUtils.isDefault(user.getIpAddress())) { // unset {{auto}} as it would set the server's ip address as a user ip address user.setIpAddress(null); } } - hub.setUser(user); + scopes.setUser(user); chain.doFilter(request, response); } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/checkin/SentryCheckInAdvice.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/checkin/SentryCheckInAdvice.java index 5a4e329fa8..4a366a8b01 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/checkin/SentryCheckInAdvice.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/checkin/SentryCheckInAdvice.java @@ -4,8 +4,8 @@ import io.sentry.CheckIn; import io.sentry.CheckInStatus; import io.sentry.DateUtils; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; +import io.sentry.ScopesAdapter; import io.sentry.SentryLevel; import io.sentry.protocol.SentryId; import io.sentry.util.Objects; @@ -30,16 +30,16 @@ @ApiStatus.Experimental @Open public class SentryCheckInAdvice implements MethodInterceptor, EmbeddedValueResolverAware { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private @Nullable StringValueResolver resolver; public SentryCheckInAdvice() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } - public SentryCheckInAdvice(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentryCheckInAdvice(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } @Override @@ -66,7 +66,8 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl // expressions. Testing shows this can also happen if properties cannot be resolved (without // an exception being thrown). Sentry should alert the user about missed checkins in this // case since the monitor slug won't match what is configured in Sentry. - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.WARNING, @@ -76,7 +77,8 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl } if (ObjectUtils.isEmpty(monitorSlug)) { - hub.getOptions() + scopes + .getOptions() .getLogger() .log( SentryLevel.WARNING, @@ -84,8 +86,8 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl return invocation.proceed(); } - hub.pushScope(); - TracingUtils.startNewTrace(hub); + scopes.pushScope(); + TracingUtils.startNewTrace(scopes); @Nullable SentryId checkInId = null; final long startTime = System.currentTimeMillis(); @@ -93,7 +95,7 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl try { if (!isHeartbeatOnly) { - checkInId = hub.captureCheckIn(new CheckIn(monitorSlug, CheckInStatus.IN_PROGRESS)); + checkInId = scopes.captureCheckIn(new CheckIn(monitorSlug, CheckInStatus.IN_PROGRESS)); } return invocation.proceed(); } catch (Throwable e) { @@ -103,8 +105,8 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl final @NotNull CheckInStatus status = didError ? CheckInStatus.ERROR : CheckInStatus.OK; CheckIn checkIn = new CheckIn(checkInId, monitorSlug, status); checkIn.setDuration(DateUtils.millisToSeconds(System.currentTimeMillis() - startTime)); - hub.captureCheckIn(checkIn); - hub.popScope(); + scopes.captureCheckIn(checkIn); + scopes.popScope(); } } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/exception/SentryCaptureExceptionParameterAdvice.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/exception/SentryCaptureExceptionParameterAdvice.java index f989382045..c6537f853c 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/exception/SentryCaptureExceptionParameterAdvice.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/exception/SentryCaptureExceptionParameterAdvice.java @@ -1,8 +1,8 @@ package io.sentry.spring.jakarta.exception; import com.jakewharton.nopen.annotation.Open; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; +import io.sentry.ScopesAdapter; import io.sentry.exception.ExceptionMechanismException; import io.sentry.protocol.Mechanism; import io.sentry.util.Objects; @@ -22,14 +22,14 @@ @Open public class SentryCaptureExceptionParameterAdvice implements MethodInterceptor { private static final String MECHANISM_TYPE = "SentrySpring6CaptureExceptionParameterAdvice"; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; public SentryCaptureExceptionParameterAdvice() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } - public SentryCaptureExceptionParameterAdvice(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentryCaptureExceptionParameterAdvice(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } @Override @@ -58,6 +58,6 @@ private void captureException(final @NotNull Throwable throwable) { mechanism.setHandled(true); final Throwable mechanismException = new ExceptionMechanismException(mechanism, throwable, Thread.currentThread()); - hub.captureException(mechanismException); + scopes.captureException(mechanismException); } } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/graphql/SentryBatchLoaderRegistry.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/graphql/SentryBatchLoaderRegistry.java index 1d5576c596..3e2223b694 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/graphql/SentryBatchLoaderRegistry.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/graphql/SentryBatchLoaderRegistry.java @@ -1,11 +1,11 @@ package io.sentry.spring.jakarta.graphql; -import static io.sentry.graphql.SentryInstrumentation.SENTRY_HUB_CONTEXT_KEY; +import static io.sentry.graphql.SentryInstrumentation.SENTRY_SCOPES_CONTEXT_KEY; import graphql.GraphQLContext; import io.sentry.Breadcrumb; -import io.sentry.IHub; -import io.sentry.NoOpHub; +import io.sentry.IScopes; +import io.sentry.NoOpScopes; import java.util.List; import java.util.Map; import java.util.Set; @@ -89,7 +89,7 @@ public BatchLoaderRegistry.RegistrationSpec withOptions(DataLoaderOptions public void registerBatchLoader(BiFunction, BatchLoaderEnvironment, Flux> loader) { delegate.registerBatchLoader( (keys, batchLoaderEnvironment) -> { - hubFromContext(batchLoaderEnvironment) + scopesFromContext(batchLoaderEnvironment) .addBreadcrumb(Breadcrumb.graphqlDataLoader(keys, keyType, valueType, name)); return loader.apply(keys, batchLoaderEnvironment); }); @@ -100,20 +100,20 @@ public void registerMappedBatchLoader( BiFunction, BatchLoaderEnvironment, Mono>> loader) { delegate.registerMappedBatchLoader( (keys, batchLoaderEnvironment) -> { - hubFromContext(batchLoaderEnvironment) + scopesFromContext(batchLoaderEnvironment) .addBreadcrumb(Breadcrumb.graphqlDataLoader(keys, keyType, valueType, name)); return loader.apply(keys, batchLoaderEnvironment); }); } - private @NotNull IHub hubFromContext(final @NotNull BatchLoaderEnvironment environment) { + private @NotNull IScopes scopesFromContext(final @NotNull BatchLoaderEnvironment environment) { Object context = environment.getContext(); if (context instanceof GraphQLContext) { GraphQLContext graphqlContext = (GraphQLContext) context; - return graphqlContext.getOrDefault(SENTRY_HUB_CONTEXT_KEY, NoOpHub.getInstance()); + return graphqlContext.getOrDefault(SENTRY_SCOPES_CONTEXT_KEY, NoOpScopes.getInstance()); } - return NoOpHub.getInstance(); + return NoOpScopes.getInstance(); } } } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/graphql/SentryDgsSubscriptionHandler.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/graphql/SentryDgsSubscriptionHandler.java index 83a090954d..a7a6cccd3e 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/graphql/SentryDgsSubscriptionHandler.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/graphql/SentryDgsSubscriptionHandler.java @@ -1,7 +1,7 @@ package io.sentry.spring.jakarta.graphql; import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.SentryIntegrationPackageStorage; import io.sentry.graphql.ExceptionReporter; import io.sentry.graphql.SentrySubscriptionHandler; @@ -17,7 +17,7 @@ public SentryDgsSubscriptionHandler() { @Override public @NotNull Object onSubscriptionResult( final @NotNull Object result, - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull ExceptionReporter exceptionReporter, final @NotNull InstrumentationFieldFetchParameters parameters) { if (result instanceof Flux) { @@ -25,7 +25,7 @@ public SentryDgsSubscriptionHandler() { return flux.doOnError( throwable -> { final @NotNull ExceptionReporter.ExceptionDetails exceptionDetails = - new ExceptionReporter.ExceptionDetails(hub, parameters.getEnvironment(), true); + new ExceptionReporter.ExceptionDetails(scopes, parameters.getEnvironment(), true); exceptionReporter.captureThrowable(throwable, exceptionDetails, null); }); } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/graphql/SentrySpringSubscriptionHandler.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/graphql/SentrySpringSubscriptionHandler.java index 4c51981035..eec86f5e8b 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/graphql/SentrySpringSubscriptionHandler.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/graphql/SentrySpringSubscriptionHandler.java @@ -1,7 +1,7 @@ package io.sentry.spring.jakarta.graphql; import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.graphql.ExceptionReporter; import io.sentry.graphql.SentrySubscriptionHandler; import org.jetbrains.annotations.NotNull; @@ -13,7 +13,7 @@ public final class SentrySpringSubscriptionHandler implements SentrySubscription @Override public @NotNull Object onSubscriptionResult( final @NotNull Object result, - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull ExceptionReporter exceptionReporter, final @NotNull InstrumentationFieldFetchParameters parameters) { if (result instanceof Flux) { @@ -21,7 +21,7 @@ public final class SentrySpringSubscriptionHandler implements SentrySubscription return flux.doOnError( throwable -> { final @NotNull ExceptionReporter.ExceptionDetails exceptionDetails = - new ExceptionReporter.ExceptionDetails(hub, parameters.getEnvironment(), true); + new ExceptionReporter.ExceptionDetails(scopes, parameters.getEnvironment(), true); if (throwable instanceof SubscriptionPublisherException && throwable.getCause() != null) { exceptionReporter.captureThrowable(throwable.getCause(), exceptionDetails, null); diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentrySpanAdvice.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentrySpanAdvice.java index 5f345a4e02..e8de36487f 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentrySpanAdvice.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentrySpanAdvice.java @@ -1,9 +1,9 @@ package io.sentry.spring.jakarta.tracing; import com.jakewharton.nopen.annotation.Open; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ISpan; +import io.sentry.ScopesAdapter; import io.sentry.SpanStatus; import io.sentry.util.Objects; import java.lang.reflect.Method; @@ -22,20 +22,20 @@ @Open public class SentrySpanAdvice implements MethodInterceptor { private static final String TRACE_ORIGIN = "auto.function.spring_jakarta.advice"; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; public SentrySpanAdvice() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } - public SentrySpanAdvice(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentrySpanAdvice(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } @SuppressWarnings("deprecation") @Override public Object invoke(final @NotNull MethodInvocation invocation) throws Throwable { - final ISpan activeSpan = hub.getSpan(); + final ISpan activeSpan = scopes.getSpan(); if (activeSpan == null || activeSpan.isNoOp()) { // there is no active transaction, we do not start new span diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentrySpanClientHttpRequestInterceptor.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentrySpanClientHttpRequestInterceptor.java index 59c1926ff3..7a787fb29d 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentrySpanClientHttpRequestInterceptor.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentrySpanClientHttpRequestInterceptor.java @@ -8,7 +8,7 @@ import io.sentry.BaggageHeader; import io.sentry.Breadcrumb; import io.sentry.Hint; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ISpan; import io.sentry.SpanDataConvention; import io.sentry.SpanStatus; @@ -28,16 +28,16 @@ public class SentrySpanClientHttpRequestInterceptor implements ClientHttpRequestInterceptor { private static final String TRACE_ORIGIN_REST_TEMPLATE = "auto.http.spring_jakarta.resttemplate"; private static final String TRACE_ORIGIN_REST_CLIENT = "auto.http.spring_jakarta.restclient"; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; private final @NotNull String traceOrigin; - public SentrySpanClientHttpRequestInterceptor(final @NotNull IHub hub) { - this(hub, true); + public SentrySpanClientHttpRequestInterceptor(final @NotNull IScopes scopes) { + this(scopes, true); } public SentrySpanClientHttpRequestInterceptor( - final @NotNull IHub hub, final @NotNull boolean isRestTemplate) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + final @NotNull IScopes scopes, final @NotNull boolean isRestTemplate) { + this.scopes = Objects.requireNonNull(scopes, "Scopes are required"); this.traceOrigin = isRestTemplate ? TRACE_ORIGIN_REST_TEMPLATE : TRACE_ORIGIN_REST_CLIENT; } @@ -50,7 +50,7 @@ public SentrySpanClientHttpRequestInterceptor( Integer responseStatusCode = null; ClientHttpResponse response = null; try { - final ISpan activeSpan = hub.getSpan(); + final ISpan activeSpan = scopes.getSpan(); if (activeSpan == null) { maybeAddTracingHeaders(request, null); return execution.execute(request, body); @@ -91,7 +91,7 @@ private void maybeAddTracingHeaders( final @NotNull HttpRequest request, final @Nullable ISpan span) { final @Nullable TracingUtils.TracingHeaders tracingHeaders = TracingUtils.traceIfAllowed( - hub, + scopes, request.getURI().toString(), request.getHeaders().get(BaggageHeader.BAGGAGE_HEADER), span); @@ -128,6 +128,6 @@ private void addBreadcrumb( hint.set(SPRING_REQUEST_INTERCEPTOR_RESPONSE, response); } - hub.addBreadcrumb(breadcrumb, hint); + scopes.addBreadcrumb(breadcrumb, hint); } } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentrySpanClientWebRequestFilter.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentrySpanClientWebRequestFilter.java index 4ac511721e..bc5c0edfab 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentrySpanClientWebRequestFilter.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentrySpanClientWebRequestFilter.java @@ -7,7 +7,7 @@ import io.sentry.BaggageHeader; import io.sentry.Breadcrumb; import io.sentry.Hint; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ISpan; import io.sentry.SpanDataConvention; import io.sentry.SpanStatus; @@ -25,16 +25,16 @@ @Open public class SentrySpanClientWebRequestFilter implements ExchangeFilterFunction { private static final String TRACE_ORIGIN = "auto.http.spring_jakarta.webclient"; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; - public SentrySpanClientWebRequestFilter(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentrySpanClientWebRequestFilter(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "Scopes are required"); } @Override public @NotNull Mono filter( final @NotNull ClientRequest request, final @NotNull ExchangeFunction next) { - final ISpan activeSpan = hub.getSpan(); + final ISpan activeSpan = scopes.getSpan(); if (activeSpan == null) { final @NotNull ClientRequest modifiedRequest = maybeAddTracingHeaders(request, null); addBreadcrumb(modifiedRequest, null); @@ -74,7 +74,7 @@ public SentrySpanClientWebRequestFilter(final @NotNull IHub hub) { final @Nullable TracingUtils.TracingHeaders tracingHeaders = TracingUtils.traceIfAllowed( - hub, + scopes, request.url().toString(), request.headers().get(BaggageHeader.BAGGAGE_HEADER), span); @@ -111,6 +111,6 @@ private void addBreadcrumb( hint.set(SPRING_EXCHANGE_FILTER_RESPONSE, response); } - hub.addBreadcrumb(breadcrumb, hint); + scopes.addBreadcrumb(breadcrumb, hint); } } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentryTracingFilter.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentryTracingFilter.java index ed91f85a29..097528ac44 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentryTracingFilter.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentryTracingFilter.java @@ -3,9 +3,9 @@ import com.jakewharton.nopen.annotation.Open; import io.sentry.BaggageHeader; import io.sentry.CustomSamplingContext; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ITransaction; +import io.sentry.ScopesAdapter; import io.sentry.SentryTraceHeader; import io.sentry.SpanStatus; import io.sentry.TransactionContext; @@ -38,7 +38,7 @@ public class SentryTracingFilter extends OncePerRequestFilter { private static final String TRACE_ORIGIN = "auto.http.spring_jakarta.webmvc"; private final @NotNull TransactionNameProvider transactionNameProvider; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; /** * Creates filter that resolves transaction name using {@link SpringMvcTransactionNameProvider}. @@ -49,25 +49,26 @@ public class SentryTracingFilter extends OncePerRequestFilter { * jakarta.servlet.Filter}. */ public SentryTracingFilter() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } /** * Creates filter that resolves transaction name using transaction name provider given by * parameter. * - * @param hub - the hub + * @param scopes - the scopes * @param transactionNameProvider - transaction name provider. */ public SentryTracingFilter( - final @NotNull IHub hub, final @NotNull TransactionNameProvider transactionNameProvider) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + final @NotNull IScopes scopes, + final @NotNull TransactionNameProvider transactionNameProvider) { + this.scopes = Objects.requireNonNull(scopes, "Scopes are required"); this.transactionNameProvider = Objects.requireNonNull(transactionNameProvider, "transactionNameProvider is required"); } - public SentryTracingFilter(final @NotNull IHub hub) { - this(hub, new SpringMvcTransactionNameProvider()); + public SentryTracingFilter(final @NotNull IScopes scopes) { + this(scopes, new SpringMvcTransactionNameProvider()); } @Override @@ -76,14 +77,14 @@ protected void doFilterInternal( final @NotNull HttpServletResponse httpResponse, final @NotNull FilterChain filterChain) throws ServletException, IOException { - if (hub.isEnabled()) { + if (scopes.isEnabled()) { final @Nullable String sentryTraceHeader = httpRequest.getHeader(SentryTraceHeader.SENTRY_TRACE_HEADER); final @Nullable List baggageHeader = Collections.list(httpRequest.getHeaders(BaggageHeader.BAGGAGE_HEADER)); final @Nullable TransactionContext transactionContext = - hub.continueTrace(sentryTraceHeader, baggageHeader); - if (hub.getOptions().isTracingEnabled() && shouldTraceRequest(httpRequest)) { + scopes.continueTrace(sentryTraceHeader, baggageHeader); + if (scopes.getOptions().isTracingEnabled() && shouldTraceRequest(httpRequest)) { doFilterWithTransaction(httpRequest, httpResponse, filterChain, transactionContext); } else { filterChain.doFilter(httpRequest, httpResponse); @@ -130,7 +131,7 @@ private void doFilterWithTransaction( } private boolean shouldTraceRequest(final @NotNull HttpServletRequest request) { - return hub.getOptions().isTraceOptionsRequests() + return scopes.getOptions().isTraceOptionsRequests() || !HttpMethod.OPTIONS.name().equals(request.getMethod()); } @@ -152,14 +153,14 @@ private ITransaction startTransaction( transactionOptions.setCustomSamplingContext(customSamplingContext); transactionOptions.setBindToScope(true); - return hub.startTransaction(transactionContext, transactionOptions); + return scopes.startTransaction(transactionContext, transactionOptions); } final TransactionOptions transactionOptions = new TransactionOptions(); transactionOptions.setCustomSamplingContext(customSamplingContext); transactionOptions.setBindToScope(true); - return hub.startTransaction( + return scopes.startTransaction( new TransactionContext(name, TransactionNameSource.URL, "http.server"), transactionOptions); } } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentryTransactionAdvice.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentryTransactionAdvice.java index 5b264defa4..f04b3dd7a6 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentryTransactionAdvice.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentryTransactionAdvice.java @@ -1,9 +1,9 @@ package io.sentry.spring.jakarta.tracing; import com.jakewharton.nopen.annotation.Open; -import io.sentry.HubAdapter; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.ITransaction; +import io.sentry.ScopesAdapter; import io.sentry.SpanStatus; import io.sentry.TransactionContext; import io.sentry.TransactionOptions; @@ -28,14 +28,14 @@ public class SentryTransactionAdvice implements MethodInterceptor { private static final String TRACE_ORIGIN = "auto.function.spring_jakarta.advice"; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; public SentryTransactionAdvice() { - this(HubAdapter.getInstance()); + this(ScopesAdapter.getInstance()); } - public SentryTransactionAdvice(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentryTransactionAdvice(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } @SuppressWarnings("deprecation") @@ -68,11 +68,11 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl } else { operation = "bean"; } - hub.pushScope(); + scopes.pushScope(); final TransactionOptions transactionOptions = new TransactionOptions(); transactionOptions.setBindToScope(true); final ITransaction transaction = - hub.startTransaction( + scopes.startTransaction( new TransactionContext(nameAndSource.name, nameAndSource.source, operation), transactionOptions); transaction.getSpanContext().setOrigin(TRACE_ORIGIN); @@ -86,7 +86,7 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl throw e; } finally { transaction.finish(); - hub.popScope(); + scopes.popScope(); } } } @@ -106,7 +106,7 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl } private boolean isTransactionActive() { - return hub.getSpan() != null; + return scopes.getSpan() != null; } private static class TransactionNameAndSource { diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/AbstractSentryWebFilter.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/AbstractSentryWebFilter.java index bf25aa5f49..3321874dd8 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/AbstractSentryWebFilter.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/AbstractSentryWebFilter.java @@ -7,10 +7,10 @@ import io.sentry.Breadcrumb; import io.sentry.CustomSamplingContext; import io.sentry.Hint; -import io.sentry.IHub; import io.sentry.IScope; +import io.sentry.IScopes; import io.sentry.ITransaction; -import io.sentry.NoOpHub; +import io.sentry.NoOpScopes; import io.sentry.Sentry; import io.sentry.SentryTraceHeader; import io.sentry.SpanStatus; @@ -34,16 +34,17 @@ @ApiStatus.Experimental public abstract class AbstractSentryWebFilter implements WebFilter { private final @NotNull SentryRequestResolver sentryRequestResolver; - public static final String SENTRY_HUB_KEY = "sentry-hub"; + public static final String SENTRY_SCOPES_KEY = "sentry-scopes"; + @Deprecated public static final String SENTRY_HUB_KEY = SENTRY_SCOPES_KEY; private static final String TRANSACTION_OP = "http.server"; - public AbstractSentryWebFilter(final @NotNull IHub hub) { - Objects.requireNonNull(hub, "hub is required"); - this.sentryRequestResolver = new SentryRequestResolver(hub); + public AbstractSentryWebFilter(final @NotNull IScopes scopes) { + Objects.requireNonNull(scopes, "scopes are required"); + this.sentryRequestResolver = new SentryRequestResolver(scopes); } protected @Nullable ITransaction maybeStartTransaction( - final @NotNull IHub requestHub, final @NotNull ServerHttpRequest request) { + final @NotNull IScopes requestHub, final @NotNull ServerHttpRequest request) { if (requestHub.isEnabled()) { final @NotNull HttpHeaders headers = request.getHeaders(); final @Nullable String sentryTraceHeader = @@ -62,21 +63,23 @@ public AbstractSentryWebFilter(final @NotNull IHub hub) { protected void doFinally( final @NotNull ServerWebExchange serverWebExchange, - final @NotNull IHub requestHub, + final @NotNull IScopes requestHub, final @Nullable ITransaction transaction) { if (transaction != null) { finishTransaction(serverWebExchange, transaction); } if (requestHub.isEnabled()) { + // TODO close lifecycle token instead of popscope requestHub.popScope(); } - Sentry.setCurrentHub(NoOpHub.getInstance()); + Sentry.setCurrentScopes(NoOpScopes.getInstance()); } protected void doFirst( - final @NotNull ServerWebExchange serverWebExchange, final @NotNull IHub requestHub) { + final @NotNull ServerWebExchange serverWebExchange, final @NotNull IScopes requestHub) { if (requestHub.isEnabled()) { - serverWebExchange.getAttributes().put(SENTRY_HUB_KEY, requestHub); + serverWebExchange.getAttributes().put(SENTRY_SCOPES_KEY, requestHub); + // TODO fork instead requestHub.pushScope(); final ServerHttpRequest request = serverWebExchange.getRequest(); final ServerHttpResponse response = serverWebExchange.getResponse(); @@ -100,8 +103,8 @@ protected void doOnError(final @Nullable ITransaction transaction, final @NotNul } protected boolean shouldTraceRequest( - final @NotNull IHub hub, final @NotNull ServerHttpRequest request) { - return hub.getOptions().isTraceOptionsRequests() + final @NotNull IScopes scopes, final @NotNull ServerHttpRequest request) { + return scopes.getOptions().isTraceOptionsRequests() || !HttpMethod.OPTIONS.equals(request.getMethod()); } @@ -130,7 +133,7 @@ private void finishTransaction(ServerWebExchange exchange, ITransaction transact } protected @NotNull ITransaction startTransaction( - final @NotNull IHub hub, + final @NotNull IScopes scopes, final @NotNull ServerHttpRequest request, final @Nullable TransactionContext transactionContext) { final @NotNull String name = request.getMethod() + " " + request.getURI().getPath(); @@ -146,10 +149,10 @@ private void finishTransaction(ServerWebExchange exchange, ITransaction transact transactionContext.setTransactionNameSource(TransactionNameSource.URL); transactionContext.setOperation(TRANSACTION_OP); - return hub.startTransaction(transactionContext, transactionOptions); + return scopes.startTransaction(transactionContext, transactionOptions); } - return hub.startTransaction( + return scopes.startTransaction( new TransactionContext(name, TransactionNameSource.URL, TRANSACTION_OP), transactionOptions); } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/ReactorUtils.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/ReactorUtils.java index 4af641af29..41dd2e4bc0 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/ReactorUtils.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/ReactorUtils.java @@ -1,6 +1,6 @@ package io.sentry.spring.jakarta.webflux; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.Sentry; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; @@ -8,11 +8,12 @@ import reactor.core.publisher.Mono; import reactor.util.context.Context; +// TODO deprecate and replace with "withSentryScopes" etc. @ApiStatus.Experimental public final class ReactorUtils { /** - * Writes the current Sentry {@link IHub} to the {@link Context} and uses {@link + * Writes the current Sentry {@link IScopes} to the {@link Context} and uses {@link * io.micrometer.context.ThreadLocalAccessor} to propagate it. * *

This requires - reactor.core.publisher.Hooks#enableAutomaticContextPropagation() to be @@ -20,14 +21,16 @@ public final class ReactorUtils { * having `io.projectreactor:reactor-core:3.5.3+` (provided by Spring Boot 3.0.3+) */ @ApiStatus.Experimental + @SuppressWarnings("deprecation") public static Mono withSentry(final @NotNull Mono mono) { - final @NotNull IHub oldHub = Sentry.getCurrentHub(); - final @NotNull IHub clonedHub = oldHub.clone(); + final @NotNull IScopes oldHub = Sentry.getCurrentScopes(); + // TODO fork + final @NotNull IScopes clonedHub = oldHub.clone(); return withSentryHub(mono, clonedHub); } /** - * Writes a new Sentry {@link IHub} cloned from the main hub to the {@link Context} and uses + * Writes a new Sentry {@link IScopes} cloned from the main hub to the {@link Context} and uses * {@link io.micrometer.context.ThreadLocalAccessor} to propagate it. * *

This requires - reactor.core.publisher.Hooks#enableAutomaticContextPropagation() to be @@ -36,12 +39,12 @@ public static Mono withSentry(final @NotNull Mono mono) { */ @ApiStatus.Experimental public static Mono withSentryNewMainHubClone(final @NotNull Mono mono) { - final @NotNull IHub hub = Sentry.cloneMainHub(); + final @NotNull IScopes hub = Sentry.cloneMainHub(); return withSentryHub(mono, hub); } /** - * Writes the given Sentry {@link IHub} to the {@link Context} and uses {@link + * Writes the given Sentry {@link IScopes} to the {@link Context} and uses {@link * io.micrometer.context.ThreadLocalAccessor} to propagate it. * *

This requires - reactor.core.publisher.Hooks#enableAutomaticContextPropagation() to be @@ -49,7 +52,7 @@ public static Mono withSentryNewMainHubClone(final @NotNull Mono mono) * having `io.projectreactor:reactor-core:3.5.3+` (provided by Spring Boot 3.0.3+) */ @ApiStatus.Experimental - public static Mono withSentryHub(final @NotNull Mono mono, final @NotNull IHub hub) { + public static Mono withSentryHub(final @NotNull Mono mono, final @NotNull IScopes hub) { /** * WARNING: Cannot set the hub as current. It would be used by others to clone again causing * shared hubs and scopes and thus leading to issues like unrelated breadcrumbs showing up in @@ -62,7 +65,7 @@ public static Mono withSentryHub(final @NotNull Mono mono, final @NotN } /** - * Writes the current Sentry {@link IHub} to the {@link Context} and uses {@link + * Writes the current Sentry {@link IScopes} to the {@link Context} and uses {@link * io.micrometer.context.ThreadLocalAccessor} to propagate it. * *

This requires - reactor.core.publisher.Hooks#enableAutomaticContextPropagation() to be @@ -70,15 +73,17 @@ public static Mono withSentryHub(final @NotNull Mono mono, final @NotN * having `io.projectreactor:reactor-core:3.5.3+` (provided by Spring Boot 3.0.3+) */ @ApiStatus.Experimental + @SuppressWarnings("deprecation") public static Flux withSentry(final @NotNull Flux flux) { - final @NotNull IHub oldHub = Sentry.getCurrentHub(); - final @NotNull IHub clonedHub = oldHub.clone(); + final @NotNull IScopes oldHub = Sentry.getCurrentScopes(); + // TODO fork + final @NotNull IScopes clonedHub = oldHub.clone(); return withSentryHub(flux, clonedHub); } /** - * Writes a new Sentry {@link IHub} cloned from the main hub to the {@link Context} and uses + * Writes a new Sentry {@link IScopes} cloned from the main hub to the {@link Context} and uses * {@link io.micrometer.context.ThreadLocalAccessor} to propagate it. * *

This requires - reactor.core.publisher.Hooks#enableAutomaticContextPropagation() to be @@ -87,12 +92,12 @@ public static Flux withSentry(final @NotNull Flux flux) { */ @ApiStatus.Experimental public static Flux withSentryNewMainHubClone(final @NotNull Flux flux) { - final @NotNull IHub hub = Sentry.cloneMainHub(); + final @NotNull IScopes hub = Sentry.cloneMainHub(); return withSentryHub(flux, hub); } /** - * Writes the given Sentry {@link IHub} to the {@link Context} and uses {@link + * Writes the given Sentry {@link IScopes} to the {@link Context} and uses {@link * io.micrometer.context.ThreadLocalAccessor} to propagate it. * *

This requires - reactor.core.publisher.Hooks#enableAutomaticContextPropagation() to be @@ -100,7 +105,7 @@ public static Flux withSentryNewMainHubClone(final @NotNull Flux flux) * having `io.projectreactor:reactor-core:3.5.3+` (provided by Spring Boot 3.0.3+) */ @ApiStatus.Experimental - public static Flux withSentryHub(final @NotNull Flux flux, final @NotNull IHub hub) { + public static Flux withSentryHub(final @NotNull Flux flux, final @NotNull IScopes hub) { /** * WARNING: Cannot set the hub as current. It would be used by others to clone again causing * shared hubs and scopes and thus leading to issues like unrelated breadcrumbs showing up in diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryReactorThreadLocalAccessor.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryReactorThreadLocalAccessor.java index c64cf3d634..9b7e51db73 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryReactorThreadLocalAccessor.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryReactorThreadLocalAccessor.java @@ -1,15 +1,15 @@ package io.sentry.spring.jakarta.webflux; import io.micrometer.context.ThreadLocalAccessor; -import io.sentry.IHub; -import io.sentry.NoOpHub; +import io.sentry.IScopes; +import io.sentry.NoOpScopes; import io.sentry.Sentry; import org.jetbrains.annotations.ApiStatus; @ApiStatus.Experimental -public final class SentryReactorThreadLocalAccessor implements ThreadLocalAccessor { +public final class SentryReactorThreadLocalAccessor implements ThreadLocalAccessor { - public static final String KEY = "sentry-hub"; + public static final String KEY = "sentry-scopes"; @Override public Object key() { @@ -17,18 +17,18 @@ public Object key() { } @Override - public IHub getValue() { - return Sentry.getCurrentHub(); + public IScopes getValue() { + return Sentry.getCurrentScopes(); } @Override - public void setValue(IHub value) { - Sentry.setCurrentHub(value); + public void setValue(IScopes value) { + Sentry.setCurrentScopes(value); } @Override @SuppressWarnings("deprecation") public void reset() { - Sentry.setCurrentHub(NoOpHub.getInstance()); + Sentry.setCurrentScopes(NoOpScopes.getInstance()); } } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryRequestResolver.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryRequestResolver.java index 2f41ba93ca..d58291ade6 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryRequestResolver.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryRequestResolver.java @@ -1,7 +1,7 @@ package io.sentry.spring.jakarta.webflux; import com.jakewharton.nopen.annotation.Open; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.protocol.Request; import io.sentry.util.HttpUtils; import io.sentry.util.Objects; @@ -20,10 +20,10 @@ @Open @ApiStatus.Experimental public class SentryRequestResolver { - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; - public SentryRequestResolver(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "options is required"); + public SentryRequestResolver(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } public @NotNull Request resolveSentryRequest(final @NotNull ServerHttpRequest httpRequest) { @@ -36,7 +36,7 @@ public SentryRequestResolver(final @NotNull IHub hub) { urlDetails.applyToRequest(sentryRequest); sentryRequest.setHeaders(resolveHeadersMap(httpRequest.getHeaders())); - if (hub.getOptions().isSendDefaultPii()) { + if (scopes.getOptions().isSendDefaultPii()) { String headerName = HttpUtils.COOKIE_HEADER_NAME; sentryRequest.setCookies( toString( @@ -52,7 +52,8 @@ Map resolveHeadersMap(final HttpHeaders request) { for (Map.Entry> entry : request.entrySet()) { // do not copy personal information identifiable headers String headerName = entry.getKey(); - if (hub.getOptions().isSendDefaultPii() || !HttpUtils.containsSensitiveHeader(headerName)) { + if (scopes.getOptions().isSendDefaultPii() + || !HttpUtils.containsSensitiveHeader(headerName)) { headersMap.put( headerName, toString( diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryScheduleHook.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryScheduleHook.java index 2bf27f246d..882a0b268a 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryScheduleHook.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryScheduleHook.java @@ -1,6 +1,6 @@ package io.sentry.spring.jakarta.webflux; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.Sentry; import java.util.function.Function; import org.jetbrains.annotations.ApiStatus; @@ -13,16 +13,18 @@ @ApiStatus.Experimental public final class SentryScheduleHook implements Function { @Override + @SuppressWarnings("deprecation") public Runnable apply(final @NotNull Runnable runnable) { - final IHub newHub = Sentry.getCurrentHub().clone(); + // TODO fork instead + final IScopes newHub = Sentry.getCurrentScopes().clone(); return () -> { - final IHub oldState = Sentry.getCurrentHub(); - Sentry.setCurrentHub(newHub); + final IScopes oldState = Sentry.getCurrentScopes(); + Sentry.setCurrentScopes(newHub); try { runnable.run(); } finally { - Sentry.setCurrentHub(oldState); + Sentry.setCurrentScopes(oldState); } }; } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebExceptionHandler.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebExceptionHandler.java index 24439cd0e9..40b0ed4e87 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebExceptionHandler.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebExceptionHandler.java @@ -5,7 +5,7 @@ import static io.sentry.TypeCheckHint.WEBFLUX_EXCEPTION_HANDLER_RESPONSE; import io.sentry.Hint; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.SentryEvent; import io.sentry.SentryLevel; import io.sentry.exception.ExceptionMechanismException; @@ -27,18 +27,18 @@ @ApiStatus.Experimental public final class SentryWebExceptionHandler implements WebExceptionHandler { public static final String MECHANISM_TYPE = "Spring6WebFluxExceptionResolver"; - private final @NotNull IHub hub; + private final @NotNull IScopes scopes; - public SentryWebExceptionHandler(final @NotNull IHub hub) { - this.hub = Objects.requireNonNull(hub, "hub is required"); + public SentryWebExceptionHandler(final @NotNull IScopes scopes) { + this.scopes = Objects.requireNonNull(scopes, "scopes are required"); } @Override public @NotNull Mono handle( final @NotNull ServerWebExchange serverWebExchange, final @NotNull Throwable ex) { - final @Nullable IHub requestHub = - serverWebExchange.getAttributeOrDefault(SentryWebFilter.SENTRY_HUB_KEY, null); - final @NotNull IHub hubToUse = requestHub != null ? requestHub : hub; + final @Nullable IScopes requestScopes = + serverWebExchange.getAttributeOrDefault(SentryWebFilter.SENTRY_SCOPES_KEY, null); + final @NotNull IScopes scopesToUse = requestScopes != null ? requestScopes : scopes; return ReactorUtils.withSentryHub( Mono.just(ex) @@ -61,12 +61,12 @@ public SentryWebExceptionHandler(final @NotNull IHub hub) { WEBFLUX_EXCEPTION_HANDLER_RESPONSE, serverWebExchange.getResponse()); hint.set(WEBFLUX_EXCEPTION_HANDLER_EXCHANGE, serverWebExchange); - hub.captureEvent(event, hint); + scopes.captureEvent(event, hint); } return it; }), - hubToUse) + scopesToUse) .flatMap(it -> Mono.error(ex)); } } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebFilter.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebFilter.java index a57a389499..dab985eecf 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebFilter.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebFilter.java @@ -1,8 +1,8 @@ package io.sentry.spring.jakarta.webflux; import com.jakewharton.nopen.annotation.Open; -import io.sentry.IHub; import io.sentry.IScope; +import io.sentry.IScopes; import io.sentry.ITransaction; import io.sentry.Sentry; import org.jetbrains.annotations.ApiStatus; @@ -20,28 +20,28 @@ public class SentryWebFilter extends AbstractSentryWebFilter { private static final String TRACE_ORIGIN = "auto.spring_jakarta.webflux"; - public SentryWebFilter(final @NotNull IHub hub) { - super(hub); + public SentryWebFilter(final @NotNull IScopes scopes) { + super(scopes); } @Override public Mono filter( final @NotNull ServerWebExchange serverWebExchange, final @NotNull WebFilterChain webFilterChain) { - @NotNull IHub requestHub = Sentry.cloneMainHub(); + @NotNull IScopes requestScopes = Sentry.cloneMainHub(); final ServerHttpRequest request = serverWebExchange.getRequest(); - final @Nullable ITransaction transaction = maybeStartTransaction(requestHub, request); + final @Nullable ITransaction transaction = maybeStartTransaction(requestScopes, request); if (transaction != null) { transaction.getSpanContext().setOrigin(TRACE_ORIGIN); } return webFilterChain .filter(serverWebExchange) - .doFinally(__ -> doFinally(serverWebExchange, requestHub, transaction)) + .doFinally(__ -> doFinally(serverWebExchange, requestScopes, transaction)) .doOnError(e -> doOnError(transaction, e)) .doFirst( () -> { - Sentry.setCurrentHub(requestHub); - doFirst(serverWebExchange, requestHub); + Sentry.setCurrentScopes(requestScopes); + doFirst(serverWebExchange, requestScopes); }); } } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebFilterWithThreadLocalAccessor.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebFilterWithThreadLocalAccessor.java index 278c2b8e7e..e760ef8f3e 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebFilterWithThreadLocalAccessor.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebFilterWithThreadLocalAccessor.java @@ -1,7 +1,7 @@ package io.sentry.spring.jakarta.webflux; -import io.sentry.IHub; import io.sentry.IScope; +import io.sentry.IScopes; import io.sentry.ITransaction; import io.sentry.Sentry; import org.jetbrains.annotations.ApiStatus; @@ -17,8 +17,8 @@ public final class SentryWebFilterWithThreadLocalAccessor extends AbstractSentry public static final String TRACE_ORIGIN = "auto.spring_jakarta.webflux"; - public SentryWebFilterWithThreadLocalAccessor(final @NotNull IHub hub) { - super(hub); + public SentryWebFilterWithThreadLocalAccessor(final @NotNull IScopes scopes) { + super(scopes); } @Override @@ -33,14 +33,15 @@ public Mono filter( __ -> doFinally( serverWebExchange, - Sentry.getCurrentHub(), + Sentry.getCurrentScopes(), transactionContainer.transaction)) .doOnError(e -> doOnError(transactionContainer.transaction, e)) .doFirst( () -> { - doFirst(serverWebExchange, Sentry.getCurrentHub()); + doFirst(serverWebExchange, Sentry.getCurrentScopes()); final ITransaction transaction = - maybeStartTransaction(Sentry.getCurrentHub(), serverWebExchange.getRequest()); + maybeStartTransaction( + Sentry.getCurrentScopes(), serverWebExchange.getRequest()); transactionContainer.transaction = transaction; if (transaction != null) { transaction.getSpanContext().setOrigin(TRACE_ORIGIN); diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/EnableSentryTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/EnableSentryTest.kt index 7b51bbc1e7..37853c3101 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/EnableSentryTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/EnableSentryTest.kt @@ -1,7 +1,7 @@ package io.sentry.spring.jakarta import io.sentry.EventProcessor -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ITransportFactory import io.sentry.Integration import io.sentry.Sentry @@ -67,7 +67,7 @@ class EnableSentryTest { @Test fun `creates Sentry Hub`() { contextRunner.run { - assertThat(it).hasSingleBean(IHub::class.java) + assertThat(it).hasSingleBean(IScopes::class.java) } } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryCheckInAdviceTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryCheckInAdviceTest.kt index 05b97ba24c..5d093f50f1 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryCheckInAdviceTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryCheckInAdviceTest.kt @@ -2,7 +2,7 @@ package io.sentry.spring.jakarta import io.sentry.CheckIn import io.sentry.CheckInStatus -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.Sentry import io.sentry.SentryOptions import io.sentry.protocol.SentryId @@ -54,19 +54,19 @@ class SentryCheckInAdviceTest { lateinit var sampleServiceSpringProperties: SampleServiceSpringProperties @Autowired - lateinit var hub: IHub + lateinit var scopes: IScopes @BeforeTest fun setup() { - reset(hub) - whenever(hub.options).thenReturn(SentryOptions()) + reset(scopes) + whenever(scopes.options).thenReturn(SentryOptions()) } @Test fun `when method is annotated with @SentryCheckIn, every method call creates two check-ins`() { val checkInId = SentryId() val checkInCaptor = argumentCaptor() - whenever(hub.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) + whenever(scopes.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) val result = sampleService.hello() assertEquals(1, result) assertEquals(2, checkInCaptor.allValues.size) @@ -79,17 +79,17 @@ class SentryCheckInAdviceTest { assertEquals("monitor_slug_1", doneCheckIn.monitorSlug) assertEquals(CheckInStatus.OK.apiName(), doneCheckIn.status) - val order = inOrder(hub) - order.verify(hub).pushScope() - order.verify(hub, times(2)).captureCheckIn(any()) - order.verify(hub).popScope() + val order = inOrder(scopes) + order.verify(scopes).pushScope() + order.verify(scopes, times(2)).captureCheckIn(any()) + order.verify(scopes).popScope() } @Test fun `when method is annotated with @SentryCheckIn, every method call creates two check-ins error`() { val checkInId = SentryId() val checkInCaptor = argumentCaptor() - whenever(hub.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) + whenever(scopes.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) assertThrows { sampleService.oops() } @@ -103,17 +103,17 @@ class SentryCheckInAdviceTest { assertEquals("monitor_slug_1e", doneCheckIn.monitorSlug) assertEquals(CheckInStatus.ERROR.apiName(), doneCheckIn.status) - val order = inOrder(hub) - order.verify(hub).pushScope() - order.verify(hub, times(2)).captureCheckIn(any()) - order.verify(hub).popScope() + val order = inOrder(scopes) + order.verify(scopes).pushScope() + order.verify(scopes, times(2)).captureCheckIn(any()) + order.verify(scopes).popScope() } @Test fun `when method is annotated with @SentryCheckIn and heartbeat only, every method call creates only one check-in at the end`() { val checkInId = SentryId() val checkInCaptor = argumentCaptor() - whenever(hub.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) + whenever(scopes.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) val result = sampleServiceHeartbeat.hello() assertEquals(1, result) assertEquals(1, checkInCaptor.allValues.size) @@ -123,17 +123,17 @@ class SentryCheckInAdviceTest { assertEquals(CheckInStatus.OK.apiName(), doneCheckIn.status) assertNotNull(doneCheckIn.duration) - val order = inOrder(hub) - order.verify(hub).pushScope() - order.verify(hub).captureCheckIn(any()) - order.verify(hub).popScope() + val order = inOrder(scopes) + order.verify(scopes).pushScope() + order.verify(scopes).captureCheckIn(any()) + order.verify(scopes).popScope() } @Test fun `when method is annotated with @SentryCheckIn and heartbeat only, every method call creates only one check-in at the end with error`() { val checkInId = SentryId() val checkInCaptor = argumentCaptor() - whenever(hub.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) + whenever(scopes.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) assertThrows { sampleServiceHeartbeat.oops() } @@ -144,31 +144,31 @@ class SentryCheckInAdviceTest { assertEquals(CheckInStatus.ERROR.apiName(), doneCheckIn.status) assertNotNull(doneCheckIn.duration) - val order = inOrder(hub) - order.verify(hub).pushScope() - order.verify(hub).captureCheckIn(any()) - order.verify(hub).popScope() + val order = inOrder(scopes) + order.verify(scopes).pushScope() + order.verify(scopes).captureCheckIn(any()) + order.verify(scopes).popScope() } @Test fun `when method is annotated with @SentryCheckIn but slug is missing, does not create check-in`() { val checkInId = SentryId() val checkInCaptor = argumentCaptor() - whenever(hub.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) + whenever(scopes.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) val result = sampleServiceNoSlug.hello() assertEquals(1, result) assertEquals(0, checkInCaptor.allValues.size) - verify(hub, never()).pushScope() - verify(hub, never()).captureCheckIn(any()) - verify(hub, never()).popScope() + verify(scopes, never()).pushScope() + verify(scopes, never()).captureCheckIn(any()) + verify(scopes, never()).popScope() } @Test fun `when @SentryCheckIn is passed a spring property it is resolved correctly`() { val checkInId = SentryId() val checkInCaptor = argumentCaptor() - whenever(hub.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) + whenever(scopes.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) val result = sampleServiceSpringProperties.hello() assertEquals(1, result) assertEquals(1, checkInCaptor.allValues.size) @@ -178,17 +178,17 @@ class SentryCheckInAdviceTest { assertEquals(CheckInStatus.OK.apiName(), doneCheckIn.status) assertNotNull(doneCheckIn.duration) - val order = inOrder(hub) - order.verify(hub).pushScope() - order.verify(hub).captureCheckIn(any()) - order.verify(hub).popScope() + val order = inOrder(scopes) + order.verify(scopes).pushScope() + order.verify(scopes).captureCheckIn(any()) + order.verify(scopes).popScope() } @Test fun `when @SentryCheckIn is passed a spring property that does not exist, raw value is used`() { val checkInId = SentryId() val checkInCaptor = argumentCaptor() - whenever(hub.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) + whenever(scopes.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) val result = sampleServiceSpringProperties.helloUnresolvedProperty() assertEquals(1, result) assertEquals(1, checkInCaptor.allValues.size) @@ -198,17 +198,17 @@ class SentryCheckInAdviceTest { assertEquals(CheckInStatus.OK.apiName(), doneCheckIn.status) assertNotNull(doneCheckIn.duration) - val order = inOrder(hub) - order.verify(hub).pushScope() - order.verify(hub).captureCheckIn(any()) - order.verify(hub).popScope() + val order = inOrder(scopes) + order.verify(scopes).pushScope() + order.verify(scopes).captureCheckIn(any()) + order.verify(scopes).popScope() } @Test fun `when @SentryCheckIn is passed a spring property that causes an exception, raw value is used`() { val checkInId = SentryId() val checkInCaptor = argumentCaptor() - whenever(hub.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) + whenever(scopes.captureCheckIn(checkInCaptor.capture())).thenReturn(checkInId) val result = sampleServiceSpringProperties.helloExceptionProperty() assertEquals(1, result) assertEquals(1, checkInCaptor.allValues.size) @@ -218,10 +218,10 @@ class SentryCheckInAdviceTest { assertEquals(CheckInStatus.OK.apiName(), doneCheckIn.status) assertNotNull(doneCheckIn.duration) - val order = inOrder(hub) - order.verify(hub).pushScope() - order.verify(hub).captureCheckIn(any()) - order.verify(hub).popScope() + val order = inOrder(scopes) + order.verify(scopes).pushScope() + order.verify(scopes).captureCheckIn(any()) + order.verify(scopes).popScope() } @Configuration @@ -242,10 +242,10 @@ class SentryCheckInAdviceTest { open fun sampleServiceSpringProperties() = SampleServiceSpringProperties() @Bean - open fun hub(): IHub { - val hub = mock() - Sentry.setCurrentHub(hub) - return hub + open fun scopes(): IScopes { + val scopes = mock() + Sentry.setCurrentScopes(scopes) + return scopes } companion object { diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryExceptionResolverTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryExceptionResolverTest.kt index 797d5aa5ac..431137aabd 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryExceptionResolverTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryExceptionResolverTest.kt @@ -1,7 +1,7 @@ package io.sentry.spring.jakarta import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryEvent import io.sentry.SentryLevel import io.sentry.exception.ExceptionMechanismException @@ -17,7 +17,7 @@ import org.mockito.kotlin.whenever import kotlin.test.Test class SentryExceptionResolverTest { - private val hub = mock() + private val scopes = mock() private val transactionNameProvider = mock() private val request = mock() @@ -26,10 +26,10 @@ class SentryExceptionResolverTest { @Test fun `when handles exception, sets wrapped exception for event`() { val eventCaptor = argumentCaptor() - whenever(hub.captureEvent(eventCaptor.capture(), any())).thenReturn(null) + whenever(scopes.captureEvent(eventCaptor.capture(), any())).thenReturn(null) val expectedCause = RuntimeException("test") - SentryExceptionResolver(hub, transactionNameProvider, 1) + SentryExceptionResolver(scopes, transactionNameProvider, 1) .resolveException(request, response, null, expectedCause) assertThat(eventCaptor.firstValue.throwable).isEqualTo(expectedCause) @@ -46,9 +46,9 @@ class SentryExceptionResolverTest { @Test fun `when handles exception, sets fatal level for event`() { val eventCaptor = argumentCaptor() - whenever(hub.captureEvent(eventCaptor.capture(), any())).thenReturn(null) + whenever(scopes.captureEvent(eventCaptor.capture(), any())).thenReturn(null) - SentryExceptionResolver(hub, transactionNameProvider, 1) + SentryExceptionResolver(scopes, transactionNameProvider, 1) .resolveException(request, response, null, RuntimeException("test")) assertThat(eventCaptor.firstValue.level).isEqualTo(SentryLevel.FATAL) @@ -59,9 +59,9 @@ class SentryExceptionResolverTest { val expectedTransactionName = "test-transaction" whenever(transactionNameProvider.provideTransactionName(any())).thenReturn(expectedTransactionName) val eventCaptor = argumentCaptor() - whenever(hub.captureEvent(eventCaptor.capture(), any())).thenReturn(null) + whenever(scopes.captureEvent(eventCaptor.capture(), any())).thenReturn(null) - SentryExceptionResolver(hub, transactionNameProvider, 1) + SentryExceptionResolver(scopes, transactionNameProvider, 1) .resolveException(request, response, null, RuntimeException("test")) assertThat(eventCaptor.firstValue.transaction).isEqualTo(expectedTransactionName) @@ -71,9 +71,9 @@ class SentryExceptionResolverTest { @Test fun `when handles exception, provides spring resolver hint`() { val hintCaptor = argumentCaptor() - whenever(hub.captureEvent(any(), hintCaptor.capture())).thenReturn(null) + whenever(scopes.captureEvent(any(), hintCaptor.capture())).thenReturn(null) - SentryExceptionResolver(hub, transactionNameProvider, 1) + SentryExceptionResolver(scopes, transactionNameProvider, 1) .resolveException(request, response, null, RuntimeException("test")) with(hintCaptor.firstValue) { @@ -86,8 +86,8 @@ class SentryExceptionResolverTest { fun `when custom create event method provided, uses it to capture event`() { val expectedEvent = SentryEvent() val eventCaptor = argumentCaptor() - whenever(hub.captureEvent(eventCaptor.capture(), any())).thenReturn(null) - val resolver = object : SentryExceptionResolver(hub, transactionNameProvider, 1) { + whenever(scopes.captureEvent(eventCaptor.capture(), any())).thenReturn(null) + val resolver = object : SentryExceptionResolver(scopes, transactionNameProvider, 1) { override fun createEvent(request: HttpServletRequest, ex: Exception) = expectedEvent } @@ -100,8 +100,8 @@ class SentryExceptionResolverTest { fun `when custom create hint method provided, uses it to capture event`() { val expectedHint = Hint() val hintCaptor = argumentCaptor() - whenever(hub.captureEvent(any(), hintCaptor.capture())).thenReturn(null) - val resolver = object : SentryExceptionResolver(hub, transactionNameProvider, 1) { + whenever(scopes.captureEvent(any(), hintCaptor.capture())).thenReturn(null) + val resolver = object : SentryExceptionResolver(scopes, transactionNameProvider, 1) { override fun createHint(request: HttpServletRequest, response: HttpServletResponse) = expectedHint } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryInitBeanPostProcessorTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryInitBeanPostProcessorTest.kt index 4168605823..54b6acb0f3 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryInitBeanPostProcessorTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryInitBeanPostProcessorTest.kt @@ -1,6 +1,6 @@ package io.sentry.spring.jakarta -import io.sentry.IHub +import io.sentry.IScopes import org.mockito.kotlin.mock import org.mockito.kotlin.verify import org.springframework.context.annotation.AnnotationConfigApplicationContext @@ -13,18 +13,18 @@ class SentryInitBeanPostProcessorTest { @Test fun closesSentryOnApplicationContextDestroy() { val ctx = AnnotationConfigApplicationContext(TestConfig::class.java) - val hub = ctx.getBean(IHub::class.java) + val scopes = ctx.getBean(IScopes::class.java) ctx.close() - verify(hub).close() + verify(scopes).close() } @Configuration open class TestConfig { @Bean(destroyMethod = "") - open fun hub() = mock() + open fun scopes() = mock() @Bean - open fun sentryInitBeanPostProcessor() = SentryInitBeanPostProcessor(hub()) + open fun sentryInitBeanPostProcessor() = SentryInitBeanPostProcessor(scopes()) } } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryRequestHttpServletRequestProcessorTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryRequestHttpServletRequestProcessorTest.kt index 279abce417..8faa243f83 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryRequestHttpServletRequestProcessorTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryRequestHttpServletRequestProcessorTest.kt @@ -1,7 +1,7 @@ package io.sentry.spring.jakarta import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryEvent import io.sentry.SentryOptions import io.sentry.spring.jakarta.tracing.SpringMvcTransactionNameProvider @@ -19,10 +19,10 @@ import kotlin.test.assertNotNull class SentryRequestHttpServletRequestProcessorTest { private class Fixture { - val hub = mock() + val scopes = mock() fun getSut(request: HttpServletRequest, options: SentryOptions = SentryOptions()): SentryRequestHttpServletRequestProcessor { - whenever(hub.options).thenReturn(options) + whenever(scopes.options).thenReturn(options) return SentryRequestHttpServletRequestProcessor(SpringMvcTransactionNameProvider(), request) } } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentrySpringFilterTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentrySpringFilterTest.kt index 4e1bbb0ee5..b6bce77a0b 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentrySpringFilterTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentrySpringFilterTest.kt @@ -1,8 +1,8 @@ package io.sentry.spring.jakarta import io.sentry.Breadcrumb -import io.sentry.IHub import io.sentry.IScope +import io.sentry.IScopes import io.sentry.Scope import io.sentry.ScopeCallback import io.sentry.SentryOptions @@ -37,7 +37,7 @@ import kotlin.test.fail class SentrySpringFilterTest { private class Fixture { - val hub = mock() + val scopes = mock() val response = MockHttpServletResponse() val chain = mock() lateinit var scope: IScope @@ -45,15 +45,15 @@ class SentrySpringFilterTest { fun getSut(request: HttpServletRequest? = null, options: SentryOptions = SentryOptions()): SentrySpringFilter { scope = Scope(options) - whenever(hub.options).thenReturn(options) - whenever(hub.isEnabled).thenReturn(true) - doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(hub).configureScope(any()) + whenever(scopes.options).thenReturn(options) + whenever(scopes.isEnabled).thenReturn(true) + doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(scopes).configureScope(any()) this.request = request ?: MockHttpServletRequest().apply { this.requestURI = "http://localhost:8080/some-uri" this.method = "post" } - return SentrySpringFilter(hub) + return SentrySpringFilter(scopes) } } @@ -64,7 +64,7 @@ class SentrySpringFilterTest { val listener = fixture.getSut() listener.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).pushScope() + verify(fixture.scopes).pushScope() } @Test @@ -72,7 +72,7 @@ class SentrySpringFilterTest { val listener = fixture.getSut() listener.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).addBreadcrumb( + verify(fixture.scopes).addBreadcrumb( check { it: Breadcrumb -> Assertions.assertThat(it.getData("url")).isEqualTo("http://localhost:8080/some-uri") Assertions.assertThat(it.getData("method")).isEqualTo("POST") @@ -87,7 +87,7 @@ class SentrySpringFilterTest { val listener = fixture.getSut() listener.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).popScope() + verify(fixture.scopes).popScope() } @Test @@ -99,7 +99,7 @@ class SentrySpringFilterTest { listener.doFilter(fixture.request, fixture.response, fixture.chain) fail() } catch (e: Exception) { - verify(fixture.hub).popScope() + verify(fixture.scopes).popScope() } } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryTaskDecoratorTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryTaskDecoratorTest.kt index aa809259d1..e5f8704b49 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryTaskDecoratorTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryTaskDecoratorTest.kt @@ -32,28 +32,28 @@ class SentryTaskDecoratorTest { val sut = SentryTaskDecorator() - val mainHub = Sentry.getCurrentHub() - val threadedHub = Sentry.getCurrentHub().clone() + val mainHub = Sentry.getCurrentScopes() + val threadedHub = Sentry.getCurrentScopes().clone() executor.submit { - Sentry.setCurrentHub(threadedHub) + Sentry.setCurrentScopes(threadedHub) }.get() - assertEquals(mainHub, Sentry.getCurrentHub()) + assertEquals(mainHub, Sentry.getCurrentScopes()) val callableFuture = executor.submit( sut.decorate { - assertNotEquals(mainHub, Sentry.getCurrentHub()) - assertNotEquals(threadedHub, Sentry.getCurrentHub()) + assertNotEquals(mainHub, Sentry.getCurrentScopes()) + assertNotEquals(threadedHub, Sentry.getCurrentScopes()) } ) callableFuture.get() executor.submit { - assertNotEquals(mainHub, Sentry.getCurrentHub()) - assertEquals(threadedHub, Sentry.getCurrentHub()) + assertNotEquals(mainHub, Sentry.getCurrentScopes()) + assertEquals(threadedHub, Sentry.getCurrentScopes()) }.get() } } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryUserFilterTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryUserFilterTest.kt index 2f128cc4bb..b30dc937e5 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryUserFilterTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryUserFilterTest.kt @@ -1,6 +1,6 @@ package io.sentry.spring.jakarta -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.SentryOptions import io.sentry.protocol.User import jakarta.servlet.FilterChain @@ -16,7 +16,7 @@ import kotlin.test.assertNull class SentryUserFilterTest { class Fixture { - val hub = mock() + val scopes = mock() val request = MockHttpServletRequest() val response = MockHttpServletResponse() val chain = mock() @@ -25,8 +25,8 @@ class SentryUserFilterTest { val options = SentryOptions().apply { this.isSendDefaultPii = isSendDefaultPii } - whenever(hub.options).thenReturn(options) - return SentryUserFilter(hub, userProviders) + whenever(scopes.options).thenReturn(options) + return SentryUserFilter(scopes, userProviders) } } @@ -52,7 +52,7 @@ class SentryUserFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).setUser( + verify(fixture.scopes).setUser( check { assertEquals(sampleUser, it) } @@ -72,7 +72,7 @@ class SentryUserFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).setUser( + verify(fixture.scopes).setUser( check { assertEquals(sampleUser, it) } @@ -92,7 +92,7 @@ class SentryUserFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).setUser( + verify(fixture.scopes).setUser( check { assertEquals(sampleUser, it) } @@ -118,7 +118,7 @@ class SentryUserFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).setUser( + verify(fixture.scopes).setUser( check { assertEquals(mapOf("key" to "value", "new-key" to "new-value"), it.others) } @@ -140,7 +140,7 @@ class SentryUserFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).setUser( + verify(fixture.scopes).setUser( check { assertEquals("192.168.0.1", it.ipAddress) } @@ -162,7 +162,7 @@ class SentryUserFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).setUser( + verify(fixture.scopes).setUser( check { assertNull(it.ipAddress) } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/exception/SentryCaptureExceptionParameterAdviceTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/exception/SentryCaptureExceptionParameterAdviceTest.kt index 0da5047251..3f8371ca3d 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/exception/SentryCaptureExceptionParameterAdviceTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/exception/SentryCaptureExceptionParameterAdviceTest.kt @@ -1,7 +1,7 @@ package io.sentry.spring.jakarta.exception import io.sentry.Hint -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.Sentry import io.sentry.exception.ExceptionMechanismException import org.junit.runner.RunWith @@ -30,18 +30,18 @@ class SentryCaptureExceptionParameterAdviceTest { lateinit var sampleService: SampleService @Autowired - lateinit var hub: IHub + lateinit var scopes: IScopes @BeforeTest fun setup() { - reset(hub) + reset(scopes) } @Test fun `captures exception passed to method annotated with @SentryCaptureException`() { val exception = RuntimeException("test exception") sampleService.methodTakingAnException(exception) - verify(hub).captureException( + verify(scopes).captureException( check { assertTrue(it is ExceptionMechanismException) assertEquals(exception, it.throwable) @@ -60,10 +60,10 @@ class SentryCaptureExceptionParameterAdviceTest { open fun sampleService() = SampleService() @Bean - open fun hub(): IHub { - val hub = mock() - Sentry.setCurrentHub(hub) - return hub + open fun scopes(): IScopes { + val scopes = mock() + Sentry.setCurrentScopes(scopes) + return scopes } } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/graphql/SentrySpringSubscriptionHandlerTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/graphql/SentrySpringSubscriptionHandlerTest.kt index 3f71eaf23e..c2ebb95e48 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/graphql/SentrySpringSubscriptionHandlerTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/graphql/SentrySpringSubscriptionHandlerTest.kt @@ -4,7 +4,7 @@ import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchPar import graphql.language.Document import graphql.language.OperationDefinition import graphql.schema.DataFetchingEnvironment -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.graphql.ExceptionReporter import io.sentry.spring.jakarta.graphql.SentrySpringSubscriptionHandler import org.junit.jupiter.api.assertThrows @@ -24,7 +24,7 @@ class SentrySpringSubscriptionHandlerTest { @Test fun `reports exception`() { val exception = IllegalStateException("some exception") - val hub = mock() + val scopes = mock() val exceptionReporter = mock() val parameters = mock() val dataFetchingEnvironment = mock() @@ -33,7 +33,7 @@ class SentrySpringSubscriptionHandlerTest { .build() whenever(dataFetchingEnvironment.document).thenReturn(document) whenever(parameters.environment).thenReturn(dataFetchingEnvironment) - val resultObject = SentrySpringSubscriptionHandler().onSubscriptionResult(Flux.error(exception), hub, exceptionReporter, parameters) + val resultObject = SentrySpringSubscriptionHandler().onSubscriptionResult(Flux.error(exception), scopes, exceptionReporter, parameters) assertThrows { (resultObject as Flux).blockFirst() } @@ -42,7 +42,7 @@ class SentrySpringSubscriptionHandlerTest { same(exception), org.mockito.kotlin.check { assertEquals(true, it.isSubscription) - assertSame(hub, it.hub) + assertSame(scopes, it.scopes) assertEquals("query testQuery\n", it.query) }, anyOrNull() @@ -53,7 +53,7 @@ class SentrySpringSubscriptionHandlerTest { fun `unwraps SubscriptionPublisherException and reports cause`() { val exception = IllegalStateException("some exception") val wrappedException = SubscriptionPublisherException(emptyList(), exception) - val hub = mock() + val scopes = mock() val exceptionReporter = mock() val parameters = mock() val dataFetchingEnvironment = mock() @@ -62,7 +62,7 @@ class SentrySpringSubscriptionHandlerTest { .build() whenever(dataFetchingEnvironment.document).thenReturn(document) whenever(parameters.environment).thenReturn(dataFetchingEnvironment) - val resultObject = SentrySpringSubscriptionHandler().onSubscriptionResult(Flux.error(wrappedException), hub, exceptionReporter, parameters) + val resultObject = SentrySpringSubscriptionHandler().onSubscriptionResult(Flux.error(wrappedException), scopes, exceptionReporter, parameters) assertThrows { (resultObject as Flux).blockFirst() } @@ -71,7 +71,7 @@ class SentrySpringSubscriptionHandlerTest { same(exception), org.mockito.kotlin.check { assertEquals(true, it.isSubscription) - assertSame(hub, it.hub) + assertSame(scopes, it.scopes) assertEquals("query testQuery\n", it.query) }, anyOrNull() diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/mvc/SentrySpringIntegrationTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/mvc/SentrySpringIntegrationTest.kt index f472a75a65..0b4be869d0 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/mvc/SentrySpringIntegrationTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/mvc/SentrySpringIntegrationTest.kt @@ -1,6 +1,6 @@ package io.sentry.spring.jakarta.mvc -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ITransportFactory import io.sentry.Sentry import io.sentry.SentryOptions @@ -104,7 +104,7 @@ class SentrySpringIntegrationTest { lateinit var anotherService: AnotherService @Autowired - lateinit var hub: IHub + lateinit var scopes: IScopes @LocalServerPort var port: Int? = null @@ -260,7 +260,7 @@ class SentrySpringIntegrationTest { try { someService.aMethodThrowing() } catch (e: Exception) { - hub.captureException(e) + scopes.captureException(e) } verify(transport).send( checkEvent { @@ -276,7 +276,7 @@ class SentrySpringIntegrationTest { try { someService.aMethodWithInnerSpanThrowing() } catch (e: Exception) { - hub.captureException(e) + scopes.captureException(e) } verify(transport).send( checkEvent { @@ -370,20 +370,20 @@ open class App { open fun springSecuritySentryUserProvider(sentryOptions: SentryOptions) = SpringSecuritySentryUserProvider(sentryOptions) @Bean - open fun sentryUserFilter(hub: IHub, @Lazy sentryUserProviders: List) = FilterRegistrationBean().apply { - this.filter = SentryUserFilter(hub, sentryUserProviders) + open fun sentryUserFilter(scopes: IScopes, @Lazy sentryUserProviders: List) = FilterRegistrationBean().apply { + this.filter = SentryUserFilter(scopes, sentryUserProviders) this.order = Ordered.LOWEST_PRECEDENCE } @Bean - open fun sentrySpringFilter(hub: IHub) = FilterRegistrationBean().apply { - this.filter = SentrySpringFilter(hub) + open fun sentrySpringFilter(scopes: IScopes) = FilterRegistrationBean().apply { + this.filter = SentrySpringFilter(scopes) this.order = Ordered.HIGHEST_PRECEDENCE } @Bean - open fun sentryTracingFilter(hub: IHub) = FilterRegistrationBean().apply { - this.filter = SentryTracingFilter(hub) + open fun sentryTracingFilter(scopes: IScopes) = FilterRegistrationBean().apply { + this.filter = SentryTracingFilter(scopes) this.order = Ordered.HIGHEST_PRECEDENCE + 1 // must run after SentrySpringFilter } @@ -391,13 +391,13 @@ open class App { open fun sentryTaskDecorator() = SentryTaskDecorator() @Bean - open fun webClient(hub: IHub): WebClient { + open fun webClient(scopes: IScopes): WebClient { return WebClient.builder() .filter( ExchangeFilterFunctions .basicAuthentication("user", "password") ) - .filter(SentrySpanClientWebRequestFilter(hub)).build() + .filter(SentrySpanClientWebRequestFilter(scopes)).build() } } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/tracing/SentrySpanAdviceTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/tracing/SentrySpanAdviceTest.kt index 2910e7aac6..8b74b08fb1 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/tracing/SentrySpanAdviceTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/tracing/SentrySpanAdviceTest.kt @@ -1,6 +1,6 @@ package io.sentry.spring.jakarta.tracing -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.Scope import io.sentry.Sentry import io.sentry.SentryOptions @@ -37,20 +37,20 @@ class SentrySpanAdviceTest { lateinit var classAnnotatedWithOperationSampleService: ClassAnnotatedWithOperationSampleService @Autowired - lateinit var hub: IHub + lateinit var scopes: IScopes @BeforeTest fun setup() { - whenever(hub.options).thenReturn(SentryOptions()) + whenever(scopes.options).thenReturn(SentryOptions()) } @Test fun `when class is annotated with @SentrySpan, every method call attaches span to existing transaction`() { val scope = Scope(SentryOptions()) - val tx = SentryTracer(TransactionContext("aTransaction", "op"), hub) + val tx = SentryTracer(TransactionContext("aTransaction", "op"), scopes) scope.setTransaction(tx) - whenever(hub.span).thenReturn(tx) + whenever(scopes.span).thenReturn(tx) val result = classAnnotatedSampleService.hello() assertEquals(1, result) assertEquals(1, tx.spans.size) @@ -62,10 +62,10 @@ class SentrySpanAdviceTest { @Test fun `when class is annotated with @SentrySpan with operation set, every method call attaches span to existing transaction`() { val scope = Scope(SentryOptions()) - val tx = SentryTracer(TransactionContext("aTransaction", "op"), hub) + val tx = SentryTracer(TransactionContext("aTransaction", "op"), scopes) scope.setTransaction(tx) - whenever(hub.span).thenReturn(tx) + whenever(scopes.span).thenReturn(tx) val result = classAnnotatedWithOperationSampleService.hello() assertEquals(1, result) assertEquals(1, tx.spans.size) @@ -76,10 +76,10 @@ class SentrySpanAdviceTest { @Test fun `when method is annotated with @SentrySpan with properties set, attaches span to existing transaction`() { val scope = Scope(SentryOptions()) - val tx = SentryTracer(TransactionContext("aTransaction", "op"), hub) + val tx = SentryTracer(TransactionContext("aTransaction", "op"), scopes) scope.setTransaction(tx) - whenever(hub.span).thenReturn(tx) + whenever(scopes.span).thenReturn(tx) val result = sampleService.methodWithSpanDescriptionSet() assertEquals(1, result) assertEquals(1, tx.spans.size) @@ -90,10 +90,10 @@ class SentrySpanAdviceTest { @Test fun `when method is annotated with @SentrySpan without properties set, attaches span to existing transaction and sets Span description as className dot methodName`() { val scope = Scope(SentryOptions()) - val tx = SentryTracer(TransactionContext("aTransaction", "op"), hub) + val tx = SentryTracer(TransactionContext("aTransaction", "op"), scopes) scope.setTransaction(tx) - whenever(hub.span).thenReturn(tx) + whenever(scopes.span).thenReturn(tx) val result = sampleService.methodWithoutSpanDescriptionSet() assertEquals(2, result) assertEquals(1, tx.spans.size) @@ -104,10 +104,10 @@ class SentrySpanAdviceTest { @Test fun `when method is annotated with @SentrySpan and returns, attached span has status OK`() { val scope = Scope(SentryOptions()) - val tx = SentryTracer(TransactionContext("aTransaction", "op"), hub) + val tx = SentryTracer(TransactionContext("aTransaction", "op"), scopes) scope.setTransaction(tx) - whenever(hub.span).thenReturn(tx) + whenever(scopes.span).thenReturn(tx) sampleService.methodWithSpanDescriptionSet() assertEquals(SpanStatus.OK, tx.spans.first().status) } @@ -115,10 +115,10 @@ class SentrySpanAdviceTest { @Test fun `when method is annotated with @SentrySpan and throws exception, attached span has throwable set and INTERNAL_ERROR status`() { val scope = Scope(SentryOptions()) - val tx = SentryTracer(TransactionContext("aTransaction", "op"), hub) + val tx = SentryTracer(TransactionContext("aTransaction", "op"), scopes) scope.setTransaction(tx) - whenever(hub.span).thenReturn(tx) + whenever(scopes.span).thenReturn(tx) var throwable: Throwable? = null try { sampleService.methodThrowingException() @@ -131,7 +131,7 @@ class SentrySpanAdviceTest { @Test fun `when method is annotated with @SentrySpan and there is no active transaction, span is not created and method is executed`() { - whenever(hub.span).thenReturn(null) + whenever(scopes.span).thenReturn(null) val result = sampleService.methodWithSpanDescriptionSet() assertEquals(1, result) } @@ -151,10 +151,10 @@ class SentrySpanAdviceTest { open fun classAnnotatedWithOperationSampleService() = ClassAnnotatedWithOperationSampleService() @Bean - open fun hub(): IHub { - val hub = mock() - Sentry.setCurrentHub(hub) - return hub + open fun scopes(): IScopes { + val scopes = mock() + Sentry.setCurrentScopes(scopes) + return scopes } } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/tracing/SentryTracingFilterTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/tracing/SentryTracingFilterTest.kt index 0424696fad..265d607b70 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/tracing/SentryTracingFilterTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/tracing/SentryTracingFilterTest.kt @@ -1,7 +1,7 @@ package io.sentry.spring.jakarta.tracing -import io.sentry.IHub import io.sentry.ILogger +import io.sentry.IScopes import io.sentry.PropagationContext import io.sentry.SentryOptions import io.sentry.SentryTracer @@ -38,7 +38,7 @@ import kotlin.test.fail class SentryTracingFilterTest { private class Fixture { - val hub = mock() + val scopes = mock() val request = MockHttpServletRequest() val response = MockHttpServletResponse() val chain = mock() @@ -50,7 +50,7 @@ class SentryTracingFilterTest { val logger = mock() init { - whenever(hub.options).thenReturn(options) + whenever(scopes.options).thenReturn(options) } fun getSut(isEnabled: Boolean = true, status: Int = 200, sentryTraceHeader: String? = null, baggageHeaders: List? = null): SentryTracingFilter { @@ -61,16 +61,16 @@ class SentryTracingFilterTest { whenever(transactionNameProvider.provideTransactionSource()).thenReturn(TransactionNameSource.CUSTOM) if (sentryTraceHeader != null) { request.addHeader("sentry-trace", sentryTraceHeader) - whenever(hub.startTransaction(any(), check { it.isBindToScope })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, hub) } + whenever(scopes.startTransaction(any(), check { it.isBindToScope })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, scopes) } } if (baggageHeaders != null) { request.addHeader("baggage", baggageHeaders) } response.status = status - whenever(hub.startTransaction(any(), check { assertTrue(it.isBindToScope) })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, hub) } - whenever(hub.isEnabled).thenReturn(isEnabled) - whenever(hub.continueTrace(any(), any())).thenAnswer { TransactionContext.fromPropagationContext(PropagationContext.fromHeaders(logger, it.arguments[0] as String?, it.arguments[1] as List?)) } - return SentryTracingFilter(hub, transactionNameProvider) + whenever(scopes.startTransaction(any(), check { assertTrue(it.isBindToScope) })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, scopes) } + whenever(scopes.isEnabled).thenReturn(isEnabled) + whenever(scopes.continueTrace(any(), any())).thenAnswer { TransactionContext.fromPropagationContext(PropagationContext.fromHeaders(logger, it.arguments[0] as String?, it.arguments[1] as List?)) } + return SentryTracingFilter(scopes, transactionNameProvider) } } @@ -82,7 +82,7 @@ class SentryTracingFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( check { assertEquals("POST /product/12", it.name) assertEquals(TransactionNameSource.URL, it.transactionNameSource) @@ -95,7 +95,7 @@ class SentryTracingFilterTest { } ) verify(fixture.chain).doFilter(fixture.request, fixture.response) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.transaction).isEqualTo("POST /product/{id}") assertThat(it.contexts.trace!!.status).isEqualTo(SpanStatus.OK) @@ -114,7 +114,7 @@ class SentryTracingFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.status).isEqualTo(SpanStatus.INTERNAL_ERROR) }, @@ -130,7 +130,7 @@ class SentryTracingFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.status).isNull() }, @@ -146,7 +146,7 @@ class SentryTracingFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.parentSpanId).isNull() }, @@ -163,7 +163,7 @@ class SentryTracingFilterTest { filter.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.parentSpanId).isEqualTo(parentSpanId) }, @@ -174,15 +174,15 @@ class SentryTracingFilterTest { } @Test - fun `when hub is disabled, components are not invoked`() { + fun `when scopes is disabled, components are not invoked`() { val filter = fixture.getSut(isEnabled = false) filter.doFilter(fixture.request, fixture.response, fixture.chain) verify(fixture.chain).doFilter(fixture.request, fixture.response) - verify(fixture.hub).isEnabled - verifyNoMoreInteractions(fixture.hub) + verify(fixture.scopes).isEnabled + verifyNoMoreInteractions(fixture.scopes) verify(fixture.transactionNameProvider, never()).provideTransactionName(any()) } @@ -196,7 +196,7 @@ class SentryTracingFilterTest { fail("filter is expected to rethrow exception") } catch (_: Exception) { } - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.status).isEqualTo(SpanStatus.INTERNAL_ERROR) }, @@ -216,10 +216,10 @@ class SentryTracingFilterTest { verify(fixture.chain).doFilter(fixture.request, fixture.response) - verify(fixture.hub).isEnabled - verify(fixture.hub).continueTrace(anyOrNull(), anyOrNull()) - verify(fixture.hub, times(2)).options - verifyNoMoreInteractions(fixture.hub) + verify(fixture.scopes).isEnabled + verify(fixture.scopes).continueTrace(anyOrNull(), anyOrNull()) + verify(fixture.scopes, times(2)).options + verifyNoMoreInteractions(fixture.scopes) verify(fixture.transactionNameProvider, never()).provideTransactionName(any()) } @@ -233,7 +233,7 @@ class SentryTracingFilterTest { verify(fixture.chain).doFilter(fixture.request, fixture.response) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.parentSpanId).isNull() }, @@ -253,7 +253,7 @@ class SentryTracingFilterTest { verify(fixture.chain).doFilter(fixture.request, fixture.response) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.parentSpanId).isNull() }, @@ -275,9 +275,9 @@ class SentryTracingFilterTest { verify(fixture.chain).doFilter(fixture.request, fixture.response) - verify(fixture.hub).continueTrace(eq(sentryTraceHeaderString), eq(baggageHeaderStrings)) + verify(fixture.scopes).continueTrace(eq(sentryTraceHeaderString), eq(baggageHeaderStrings)) - verify(fixture.hub, never()).captureTransaction( + verify(fixture.scopes, never()).captureTransaction( anyOrNull(), anyOrNull(), anyOrNull(), diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/tracing/SentryTransactionAdviceTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/tracing/SentryTransactionAdviceTest.kt index 5d2863310f..390b4d8241 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/tracing/SentryTransactionAdviceTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/tracing/SentryTransactionAdviceTest.kt @@ -1,6 +1,6 @@ package io.sentry.spring.jakarta.tracing -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.Sentry import io.sentry.SentryOptions import io.sentry.SentryTracer @@ -44,13 +44,13 @@ class SentryTransactionAdviceTest { lateinit var classAnnotatedWithOperationSampleService: ClassAnnotatedWithOperationSampleService @Autowired - lateinit var hub: IHub + lateinit var scopes: IScopes @BeforeTest fun setup() { - reset(hub) - whenever(hub.startTransaction(any(), check { assertTrue(it.isBindToScope) })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, hub) } - whenever(hub.options).thenReturn( + reset(scopes) + whenever(scopes.startTransaction(any(), check { assertTrue(it.isBindToScope) })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, scopes) } + whenever(scopes.options).thenReturn( SentryOptions().apply { dsn = "https://key@sentry.io/proj" } @@ -60,7 +60,7 @@ class SentryTransactionAdviceTest { @Test fun `creates transaction around method annotated with @SentryTransaction`() { sampleService.methodWithTransactionNameSet() - verify(hub).captureTransaction( + verify(scopes).captureTransaction( check { assertThat(it.transaction).isEqualTo("customName") assertThat(it.contexts.trace!!.operation).isEqualTo("bean") @@ -76,7 +76,7 @@ class SentryTransactionAdviceTest { @Test fun `when method annotated with @SentryTransaction throws exception, sets error status on transaction`() { assertThrows { sampleService.methodThrowingException() } - verify(hub).captureTransaction( + verify(scopes).captureTransaction( check { assertThat(it.status).isEqualTo(SpanStatus.INTERNAL_ERROR) }, @@ -89,7 +89,7 @@ class SentryTransactionAdviceTest { @Test fun `when @SentryTransaction has no name set, sets transaction name as className dot methodName`() { sampleService.methodWithoutTransactionNameSet() - verify(hub).captureTransaction( + verify(scopes).captureTransaction( check { assertThat(it.transaction).isEqualTo("SampleService.methodWithoutTransactionNameSet") assertThat(it.contexts.trace!!.operation).isEqualTo("op") @@ -102,18 +102,18 @@ class SentryTransactionAdviceTest { @Test fun `when transaction is already active, does not start new transaction`() { - whenever(hub.options).thenReturn(SentryOptions()) - whenever(hub.span).then { SentryTracer(TransactionContext("aTransaction", "op"), hub) } + whenever(scopes.options).thenReturn(SentryOptions()) + whenever(scopes.span).then { SentryTracer(TransactionContext("aTransaction", "op"), scopes) } sampleService.methodWithTransactionNameSet() - verify(hub, times(0)).captureTransaction(any(), any()) + verify(scopes, times(0)).captureTransaction(any(), any()) } @Test fun `creates transaction around method in class annotated with @SentryTransaction`() { classAnnotatedSampleService.hello() - verify(hub).captureTransaction( + verify(scopes).captureTransaction( check { assertThat(it.transaction).isEqualTo("ClassAnnotatedSampleService.hello") assertThat(it.contexts.trace!!.operation).isEqualTo("op") @@ -127,7 +127,7 @@ class SentryTransactionAdviceTest { @Test fun `creates transaction with operation set around method in class annotated with @SentryTransaction`() { classAnnotatedWithOperationSampleService.hello() - verify(hub).captureTransaction( + verify(scopes).captureTransaction( check { assertThat(it.transaction).isEqualTo("ClassAnnotatedWithOperationSampleService.hello") assertThat(it.contexts.trace!!.operation).isEqualTo("my-op") @@ -141,13 +141,13 @@ class SentryTransactionAdviceTest { @Test fun `pushes the scope when advice starts`() { classAnnotatedSampleService.hello() - verify(hub).pushScope() + verify(scopes).pushScope() } @Test fun `pops the scope when advice finishes`() { classAnnotatedSampleService.hello() - verify(hub).popScope() + verify(scopes).popScope() } @Configuration @@ -165,10 +165,10 @@ class SentryTransactionAdviceTest { open fun classAnnotatedWithOperationSampleService() = ClassAnnotatedWithOperationSampleService() @Bean - open fun hub(): IHub { - val hub = mock() - Sentry.setCurrentHub(hub) - return hub + open fun scopes(): IScopes { + val scopes = mock() + Sentry.setCurrentScopes(scopes) + return scopes } } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/ReactorUtilsTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/ReactorUtilsTest.kt index ad335333ed..9c851cde11 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/ReactorUtilsTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/ReactorUtilsTest.kt @@ -1,7 +1,8 @@ package io.sentry.spring.jakarta.webflux import io.sentry.IHub -import io.sentry.NoOpHub +import io.sentry.IScopes +import io.sentry.NoOpScopes import io.sentry.Sentry import org.mockito.kotlin.mock import org.mockito.kotlin.verify @@ -26,18 +27,18 @@ class ReactorUtilsTest { @AfterTest fun teardown() { - Sentry.setCurrentHub(NoOpHub.getInstance()) + Sentry.setCurrentScopes(NoOpScopes.getInstance()) } @Test fun `propagates hub inside mono`() { - val hubToUse = mock() - var hubInside: IHub? = null + val hubToUse = mock() + var hubInside: IScopes? = null val mono = ReactorUtils.withSentryHub( Mono.just("hello") .publishOn(Schedulers.boundedElastic()) .map { it -> - hubInside = Sentry.getCurrentHub() + hubInside = Sentry.getCurrentScopes() it }, hubToUse @@ -49,13 +50,13 @@ class ReactorUtilsTest { @Test fun `propagates hub inside flux`() { - val hubToUse = mock() - var hubInside: IHub? = null + val hubToUse = mock() + var hubInside: IScopes? = null val flux = ReactorUtils.withSentryHub( Flux.just("hello") .publishOn(Schedulers.boundedElastic()) .map { it -> - hubInside = Sentry.getCurrentHub() + hubInside = Sentry.getCurrentScopes() it }, hubToUse @@ -67,12 +68,12 @@ class ReactorUtilsTest { @Test fun `without reactive utils hub is not propagated to mono`() { - val hubToUse = mock() - var hubInside: IHub? = null + val hubToUse = mock() + var hubInside: IScopes? = null val mono = Mono.just("hello") .publishOn(Schedulers.boundedElastic()) .map { it -> - hubInside = Sentry.getCurrentHub() + hubInside = Sentry.getCurrentScopes() it } @@ -82,12 +83,12 @@ class ReactorUtilsTest { @Test fun `without reactive utils hub is not propagated to flux`() { - val hubToUse = mock() - var hubInside: IHub? = null + val hubToUse = mock() + var hubInside: IScopes? = null val flux = Flux.just("hello") .publishOn(Schedulers.boundedElastic()) .map { it -> - hubInside = Sentry.getCurrentHub() + hubInside = Sentry.getCurrentScopes() it } @@ -97,21 +98,21 @@ class ReactorUtilsTest { @Test fun `clones hub for mono`() { - val mockHub = mock() - whenever(mockHub.clone()).thenReturn(mock()) - Sentry.setCurrentHub(mockHub) + val mockScopes = mock() + whenever(mockScopes.clone()).thenReturn(mock()) + Sentry.setCurrentScopes(mockScopes) ReactorUtils.withSentry(Mono.just("hello")).block() - verify(mockHub).clone() + verify(mockScopes).clone() } @Test fun `clones hub for flux`() { - val mockHub = mock() - whenever(mockHub.clone()).thenReturn(mock()) - Sentry.setCurrentHub(mockHub) + val mockScopes = mock() + whenever(mockScopes.clone()).thenReturn(mock()) + Sentry.setCurrentScopes(mockScopes) ReactorUtils.withSentry(Flux.just("hello")).blockFirst() - verify(mockHub).clone() + verify(mockScopes).clone() } } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryScheduleHookTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryScheduleHookTest.kt index 1eb06d0afe..5403caa7e0 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryScheduleHookTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryScheduleHookTest.kt @@ -33,28 +33,28 @@ class SentryScheduleHookTest { val sut = SentryScheduleHook() - val mainHub = Sentry.getCurrentHub() - val threadedHub = Sentry.getCurrentHub().clone() + val mainHub = Sentry.getCurrentScopes() + val threadedHub = Sentry.getCurrentScopes().clone() executor.submit { - Sentry.setCurrentHub(threadedHub) + Sentry.setCurrentScopes(threadedHub) }.get() - assertEquals(mainHub, Sentry.getCurrentHub()) + assertEquals(mainHub, Sentry.getCurrentScopes()) val callableFuture = executor.submit( sut.apply { - assertNotEquals(mainHub, Sentry.getCurrentHub()) - assertNotEquals(threadedHub, Sentry.getCurrentHub()) + assertNotEquals(mainHub, Sentry.getCurrentScopes()) + assertNotEquals(threadedHub, Sentry.getCurrentScopes()) } ) callableFuture.get() executor.submit { - assertNotEquals(mainHub, Sentry.getCurrentHub()) - assertEquals(threadedHub, Sentry.getCurrentHub()) + assertNotEquals(mainHub, Sentry.getCurrentScopes()) + assertEquals(threadedHub, Sentry.getCurrentScopes()) }.get() } } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryWebFluxTracingFilterTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryWebFluxTracingFilterTest.kt index eac0b9c60f..e936394039 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryWebFluxTracingFilterTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryWebFluxTracingFilterTest.kt @@ -2,8 +2,9 @@ package io.sentry.spring.jakarta.webflux import io.sentry.Breadcrumb import io.sentry.Hint -import io.sentry.IHub +import io.sentry.HubScopesWrapper import io.sentry.ILogger +import io.sentry.IScopes import io.sentry.PropagationContext import io.sentry.ScopeCallback import io.sentry.Sentry @@ -17,7 +18,7 @@ import io.sentry.TransactionOptions import io.sentry.protocol.SentryId import io.sentry.protocol.SentryTransaction import io.sentry.protocol.TransactionNameSource -import io.sentry.spring.jakarta.webflux.AbstractSentryWebFilter.SENTRY_HUB_KEY +import io.sentry.spring.jakarta.webflux.AbstractSentryWebFilter.SENTRY_SCOPES_KEY import org.assertj.core.api.Assertions.assertThat import org.mockito.Mockito import org.mockito.kotlin.any @@ -47,7 +48,7 @@ import kotlin.test.fail class SentryWebFluxTracingFilterTest { private class Fixture { - val hub = mock() + val scopes = mock() lateinit var request: MockServerHttpRequest lateinit var exchange: MockServerWebExchange val chain = mock() @@ -58,45 +59,47 @@ class SentryWebFluxTracingFilterTest { val logger = mock() init { - whenever(hub.options).thenReturn(options) + whenever(scopes.options).thenReturn(options) } fun getSut(isEnabled: Boolean = true, status: HttpStatus = HttpStatus.OK, sentryTraceHeader: String? = null, baggageHeaders: List? = null, method: HttpMethod = HttpMethod.POST): SentryWebFilter { var requestBuilder = MockServerHttpRequest.method(method, "/product/{id}", 12) if (sentryTraceHeader != null) { requestBuilder = requestBuilder.header("sentry-trace", sentryTraceHeader) - whenever(hub.startTransaction(any(), check { it.isBindToScope })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, hub) } + whenever(scopes.startTransaction(any(), check { it.isBindToScope })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, scopes) } } if (baggageHeaders != null) { requestBuilder = requestBuilder.header("baggage", *baggageHeaders.toTypedArray()) } request = requestBuilder.build() exchange = MockServerWebExchange.builder(request).build() - exchange.attributes.put(SENTRY_HUB_KEY, hub) + exchange.attributes.put(SENTRY_SCOPES_KEY, scopes) exchange.attributes.put(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE, PathPatternParser().parse("/product/{id}")) exchange.response.statusCode = status - whenever(hub.startTransaction(any(), check { assertTrue(it.isBindToScope) })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, hub) } - whenever(hub.isEnabled).thenReturn(isEnabled) + whenever(scopes.startTransaction(any(), check { assertTrue(it.isBindToScope) })).thenAnswer { SentryTracer(it.arguments[0] as TransactionContext, scopes) } + whenever(scopes.isEnabled).thenReturn(isEnabled) whenever(chain.filter(any())).thenReturn(Mono.create { s -> s.success() }) - whenever(hub.continueTrace(anyOrNull(), anyOrNull())).thenAnswer { TransactionContext.fromPropagationContext(PropagationContext.fromHeaders(logger, it.arguments[0] as String?, it.arguments[1] as List?)) } - return SentryWebFilter(hub) + whenever(scopes.continueTrace(anyOrNull(), anyOrNull())).thenAnswer { TransactionContext.fromPropagationContext(PropagationContext.fromHeaders(logger, it.arguments[0] as String?, it.arguments[1] as List?)) } + return SentryWebFilter(scopes) } } private val fixture = Fixture() - fun withMockHub(closure: () -> Unit) = Mockito.mockStatic(Sentry::class.java).use { - it.`when` { Sentry.cloneMainHub() }.thenReturn(fixture.hub) + fun withMockScopes(closure: () -> Unit) = Mockito.mockStatic(Sentry::class.java).use { + it.`when` { Sentry.getCurrentHub() }.thenReturn(HubScopesWrapper(fixture.scopes)) + it.`when` { Sentry.getCurrentScopes() }.thenReturn(fixture.scopes) + it.`when` { Sentry.cloneMainHub() }.thenReturn(fixture.scopes) closure.invoke() } @Test fun `creates transaction around the request`() { val filter = fixture.getSut() - withMockHub { + withMockScopes { filter.filter(fixture.exchange, fixture.chain).block() - verify(fixture.hub).startTransaction( + verify(fixture.scopes).startTransaction( check { assertEquals("POST /product/12", it.name) assertEquals(TransactionNameSource.URL, it.transactionNameSource) @@ -109,7 +112,7 @@ class SentryWebFluxTracingFilterTest { } ) verify(fixture.chain).filter(fixture.exchange) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.transaction).isEqualTo("POST /product/{id}") assertThat(it.contexts.trace!!.status).isEqualTo(SpanStatus.OK) @@ -128,10 +131,10 @@ class SentryWebFluxTracingFilterTest { fun `sets correct span status based on the response status`() { val filter = fixture.getSut(status = HttpStatus.INTERNAL_SERVER_ERROR) - withMockHub { + withMockScopes { filter.filter(fixture.exchange, fixture.chain).block() - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.status).isEqualTo(SpanStatus.INTERNAL_ERROR) assertThat(it.contexts.response!!.statusCode).isEqualTo(500) @@ -147,10 +150,10 @@ class SentryWebFluxTracingFilterTest { fun `does not set span status for response status that dont match predefined span statuses`() { val filter = fixture.getSut(status = HttpStatus.FOUND) - withMockHub { + withMockScopes { filter.filter(fixture.exchange, fixture.chain).block() - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.status).isNull() }, @@ -165,10 +168,10 @@ class SentryWebFluxTracingFilterTest { fun `when sentry trace is not present, transaction does not have parentSpanId set`() { val filter = fixture.getSut() - withMockHub { + withMockScopes { filter.filter(fixture.exchange, fixture.chain).block() - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.parentSpanId).isNull() }, @@ -184,10 +187,10 @@ class SentryWebFluxTracingFilterTest { val parentSpanId = SpanId() val filter = fixture.getSut(sentryTraceHeader = "${SentryId()}-$parentSpanId-1") - withMockHub { + withMockScopes { filter.filter(fixture.exchange, fixture.chain).block() - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.parentSpanId).isEqualTo(parentSpanId) }, @@ -199,16 +202,16 @@ class SentryWebFluxTracingFilterTest { } @Test - fun `when hub is disabled, components are not invoked`() { + fun `when scopes is disabled, components are not invoked`() { val filter = fixture.getSut(isEnabled = false) - withMockHub { + withMockScopes { filter.filter(fixture.exchange, fixture.chain).block() verify(fixture.chain).filter(fixture.exchange) - verify(fixture.hub, times(3)).isEnabled - verifyNoMoreInteractions(fixture.hub) + verify(fixture.scopes, times(3)).isEnabled + verifyNoMoreInteractions(fixture.scopes) } } @@ -216,7 +219,7 @@ class SentryWebFluxTracingFilterTest { fun `sets status to internal server error when chain throws exception`() { val filter = fixture.getSut() - withMockHub { + withMockScopes { whenever(fixture.chain.filter(any())).thenReturn(Mono.error(RuntimeException("error"))) try { @@ -224,7 +227,7 @@ class SentryWebFluxTracingFilterTest { fail("filter is expected to rethrow exception") } catch (_: Exception) { } - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.status).isEqualTo(SpanStatus.INTERNAL_ERROR) }, @@ -239,21 +242,21 @@ class SentryWebFluxTracingFilterTest { fun `does not track OPTIONS request with traceOptionsRequests=false`() { val filter = fixture.getSut(method = HttpMethod.OPTIONS) - withMockHub { + withMockScopes { fixture.options.isTraceOptionsRequests = false filter.filter(fixture.exchange, fixture.chain).block() verify(fixture.chain).filter(fixture.exchange) - verify(fixture.hub, times(3)).isEnabled - verify(fixture.hub, times(2)).options - verify(fixture.hub).continueTrace(anyOrNull(), anyOrNull()) - verify(fixture.hub).pushScope() - verify(fixture.hub).addBreadcrumb(any(), any()) - verify(fixture.hub).configureScope(any()) - verify(fixture.hub).popScope() - verifyNoMoreInteractions(fixture.hub) + verify(fixture.scopes, times(3)).isEnabled + verify(fixture.scopes, times(2)).options + verify(fixture.scopes).continueTrace(anyOrNull(), anyOrNull()) + verify(fixture.scopes).pushScope() + verify(fixture.scopes).addBreadcrumb(any(), any()) + verify(fixture.scopes).configureScope(any()) + verify(fixture.scopes).popScope() + verifyNoMoreInteractions(fixture.scopes) } } @@ -261,14 +264,14 @@ class SentryWebFluxTracingFilterTest { fun `tracks OPTIONS request with traceOptionsRequests=true`() { val filter = fixture.getSut(method = HttpMethod.OPTIONS) - withMockHub { + withMockScopes { fixture.options.isTraceOptionsRequests = true filter.filter(fixture.exchange, fixture.chain).block() verify(fixture.chain).filter(fixture.exchange) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.parentSpanId).isNull() }, @@ -283,14 +286,14 @@ class SentryWebFluxTracingFilterTest { fun `tracks POST request with traceOptionsRequests=false`() { val filter = fixture.getSut(method = HttpMethod.POST) - withMockHub { + withMockScopes { fixture.options.isTraceOptionsRequests = false filter.filter(fixture.exchange, fixture.chain).block() verify(fixture.chain).filter(fixture.exchange) - verify(fixture.hub).captureTransaction( + verify(fixture.scopes).captureTransaction( check { assertThat(it.contexts.trace!!.parentSpanId).isNull() }, @@ -309,19 +312,19 @@ class SentryWebFluxTracingFilterTest { fixture.options.enableTracing = false val filter = fixture.getSut(sentryTraceHeader = sentryTraceHeaderString, baggageHeaders = baggageHeaderStrings) - withMockHub { + withMockScopes { filter.filter(fixture.exchange, fixture.chain).block() verify(fixture.chain).filter(fixture.exchange) - verify(fixture.hub, never()).captureTransaction( + verify(fixture.scopes, never()).captureTransaction( anyOrNull(), anyOrNull(), anyOrNull(), anyOrNull() ) - verify(fixture.hub).continueTrace(eq(sentryTraceHeaderString), eq(baggageHeaderStrings)) + verify(fixture.scopes).continueTrace(eq(sentryTraceHeaderString), eq(baggageHeaderStrings)) } } } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryWebfluxIntegrationTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryWebfluxIntegrationTest.kt index 3f4628ea3c..59f9a700b6 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryWebfluxIntegrationTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryWebfluxIntegrationTest.kt @@ -1,8 +1,8 @@ package io.sentry.spring.jakarta.webflux -import io.sentry.HubAdapter -import io.sentry.IHub +import io.sentry.IScopes import io.sentry.ITransportFactory +import io.sentry.ScopesAdapter import io.sentry.Sentry import io.sentry.checkEvent import io.sentry.checkTransaction @@ -160,13 +160,13 @@ open class App { open fun mockTransport() = transport @Bean - open fun hub() = HubAdapter.getInstance() + open fun scopes() = ScopesAdapter.getInstance() @Bean - open fun sentryFilter(hub: IHub) = SentryWebFilter(hub) + open fun sentryFilter(scopes: IScopes) = SentryWebFilter(scopes) @Bean - open fun sentryWebExceptionHandler(hub: IHub) = SentryWebExceptionHandler(hub) + open fun sentryWebExceptionHandler(scopes: IScopes) = SentryWebExceptionHandler(scopes) @Bean open fun sentryScheduleHookRegistrar() = ApplicationRunner { From 9bcbce657d392795a7507daea9824d3f1a2e4bdc Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Tue, 2 Apr 2024 14:55:42 +0200 Subject: [PATCH 15/28] Replace `IHub` with `IScopes` in samples --- .../java/io/sentry/samples/android/ProfilingActivity.kt | 2 +- .../java/io/sentry/samples/spring/jakarta/AppConfig.java | 6 +++--- .../java/io/sentry/samples/spring/jakarta/WebConfig.java | 8 ++++---- .../src/main/java/io/sentry/samples/spring/AppConfig.java | 6 +++--- .../src/main/java/io/sentry/samples/spring/WebConfig.java | 8 ++++---- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/sentry-samples/sentry-samples-android/src/main/java/io/sentry/samples/android/ProfilingActivity.kt b/sentry-samples/sentry-samples-android/src/main/java/io/sentry/samples/android/ProfilingActivity.kt index 610fc1534d..a7004deb35 100644 --- a/sentry-samples/sentry-samples-android/src/main/java/io/sentry/samples/android/ProfilingActivity.kt +++ b/sentry-samples/sentry-samples-android/src/main/java/io/sentry/samples/android/ProfilingActivity.kt @@ -100,7 +100,7 @@ class ProfilingActivity : AppCompatActivity() { val traceData = ProfilingTraceData(profile, t) // Create envelope item from copied profile val item = - SentryEnvelopeItem.fromProfilingTrace(traceData, Long.MAX_VALUE, Sentry.getCurrentHub().options.serializer) + SentryEnvelopeItem.fromProfilingTrace(traceData, Long.MAX_VALUE, Sentry.getCurrentScopes().options.serializer) val itemData = item.data // Compress the envelope item using Gzip diff --git a/sentry-samples/sentry-samples-spring-jakarta/src/main/java/io/sentry/samples/spring/jakarta/AppConfig.java b/sentry-samples/sentry-samples-spring-jakarta/src/main/java/io/sentry/samples/spring/jakarta/AppConfig.java index f78c3f71d5..72ecb14e2f 100644 --- a/sentry-samples/sentry-samples-spring-jakarta/src/main/java/io/sentry/samples/spring/jakarta/AppConfig.java +++ b/sentry-samples/sentry-samples-spring-jakarta/src/main/java/io/sentry/samples/spring/jakarta/AppConfig.java @@ -1,6 +1,6 @@ package io.sentry.samples.spring.jakarta; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.spring.jakarta.SentryUserFilter; import io.sentry.spring.jakarta.SentryUserProvider; import java.util.List; @@ -14,7 +14,7 @@ public class AppConfig { @Bean SentryUserFilter sentryUserFilter( - final IHub hub, final List sentryUserProviders) { - return new SentryUserFilter(hub, sentryUserProviders); + final IScopes scopes, final List sentryUserProviders) { + return new SentryUserFilter(scopes, sentryUserProviders); } } diff --git a/sentry-samples/sentry-samples-spring-jakarta/src/main/java/io/sentry/samples/spring/jakarta/WebConfig.java b/sentry-samples/sentry-samples-spring-jakarta/src/main/java/io/sentry/samples/spring/jakarta/WebConfig.java index 92b48b138c..73d425b286 100644 --- a/sentry-samples/sentry-samples-spring-jakarta/src/main/java/io/sentry/samples/spring/jakarta/WebConfig.java +++ b/sentry-samples/sentry-samples-spring-jakarta/src/main/java/io/sentry/samples/spring/jakarta/WebConfig.java @@ -1,6 +1,6 @@ package io.sentry.samples.spring.jakarta; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.spring.jakarta.tracing.SentrySpanClientHttpRequestInterceptor; import java.util.Collections; import org.springframework.context.annotation.Bean; @@ -20,14 +20,14 @@ public class WebConfig { * Creates a {@link RestTemplate} which calls are intercepted with {@link * SentrySpanClientHttpRequestInterceptor} to create spans around HTTP calls. * - * @param hub - sentry hub + * @param scopes - sentry scopes * @return RestTemplate */ @Bean - RestTemplate restTemplate(IHub hub) { + RestTemplate restTemplate(IScopes scopes) { RestTemplate restTemplate = new RestTemplate(); SentrySpanClientHttpRequestInterceptor sentryRestTemplateInterceptor = - new SentrySpanClientHttpRequestInterceptor(hub); + new SentrySpanClientHttpRequestInterceptor(scopes); restTemplate.setInterceptors(Collections.singletonList(sentryRestTemplateInterceptor)); return restTemplate; } diff --git a/sentry-samples/sentry-samples-spring/src/main/java/io/sentry/samples/spring/AppConfig.java b/sentry-samples/sentry-samples-spring/src/main/java/io/sentry/samples/spring/AppConfig.java index 7d46f09fb9..89a968834a 100644 --- a/sentry-samples/sentry-samples-spring/src/main/java/io/sentry/samples/spring/AppConfig.java +++ b/sentry-samples/sentry-samples-spring/src/main/java/io/sentry/samples/spring/AppConfig.java @@ -1,6 +1,6 @@ package io.sentry.samples.spring; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.spring.SentryUserFilter; import io.sentry.spring.SentryUserProvider; import java.util.List; @@ -14,7 +14,7 @@ public class AppConfig { @Bean SentryUserFilter sentryUserFilter( - final IHub hub, final List sentryUserProviders) { - return new SentryUserFilter(hub, sentryUserProviders); + final IScopes scopes, final List sentryUserProviders) { + return new SentryUserFilter(scopes, sentryUserProviders); } } diff --git a/sentry-samples/sentry-samples-spring/src/main/java/io/sentry/samples/spring/WebConfig.java b/sentry-samples/sentry-samples-spring/src/main/java/io/sentry/samples/spring/WebConfig.java index e135cbe233..2990ba8a38 100644 --- a/sentry-samples/sentry-samples-spring/src/main/java/io/sentry/samples/spring/WebConfig.java +++ b/sentry-samples/sentry-samples-spring/src/main/java/io/sentry/samples/spring/WebConfig.java @@ -1,6 +1,6 @@ package io.sentry.samples.spring; -import io.sentry.IHub; +import io.sentry.IScopes; import io.sentry.spring.tracing.SentrySpanClientHttpRequestInterceptor; import java.util.Collections; import org.springframework.context.annotation.Bean; @@ -20,14 +20,14 @@ public class WebConfig { * Creates a {@link RestTemplate} which calls are intercepted with {@link * SentrySpanClientHttpRequestInterceptor} to create spans around HTTP calls. * - * @param hub - sentry hub + * @param scopes - sentry scopes * @return RestTemplate */ @Bean - RestTemplate restTemplate(IHub hub) { + RestTemplate restTemplate(IScopes scopes) { RestTemplate restTemplate = new RestTemplate(); SentrySpanClientHttpRequestInterceptor sentryRestTemplateInterceptor = - new SentrySpanClientHttpRequestInterceptor(hub); + new SentrySpanClientHttpRequestInterceptor(scopes); restTemplate.setInterceptors(Collections.singletonList(sentryRestTemplateInterceptor)); return restTemplate; } From d6fb40ad03da82ed6d416aa684a6b7a905b9c738 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Tue, 2 Apr 2024 15:49:05 +0200 Subject: [PATCH 16/28] gitscopes -> github --- .../android/navigation/SentryNavigationListenerTest.kt | 8 ++++---- .../io/sentry/apollo3/SentryApollo3HttpInterceptor.kt | 2 +- .../src/test/kotlin/SentrySpanProcessorTest.kt | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sentry-android-navigation/src/test/java/io/sentry/android/navigation/SentryNavigationListenerTest.kt b/sentry-android-navigation/src/test/java/io/sentry/android/navigation/SentryNavigationListenerTest.kt index 7308b6b659..b37133410f 100644 --- a/sentry-android-navigation/src/test/java/io/sentry/android/navigation/SentryNavigationListenerTest.kt +++ b/sentry-android-navigation/src/test/java/io/sentry/android/navigation/SentryNavigationListenerTest.kt @@ -266,13 +266,13 @@ class SentryNavigationListenerTest { @Test fun `onDestinationChanged strips out route parameters from transaction name`() { - val sut = fixture.getSut(toRoute = "gitscopes/{user_id}?per_page={per_page}") + val sut = fixture.getSut(toRoute = "github/{user_id}?per_page={per_page}") sut.onDestinationChanged(fixture.navController, fixture.destination, null) verify(fixture.scopes).startTransaction( check { - assertEquals("/gitscopes", it.name) + assertEquals("/github", it.name) assertEquals(TransactionNameSource.ROUTE, it.transactionNameSource) }, any() @@ -296,7 +296,7 @@ class SentryNavigationListenerTest { @Test fun `onDestinationChanged captures arguments as additional data for transaction`() { - val sut = fixture.getSut(toRoute = "gitscopes/{user_id}?per_page={per_page}") + val sut = fixture.getSut(toRoute = "github/{user_id}?per_page={per_page}") sut.onDestinationChanged( fixture.navController, @@ -306,7 +306,7 @@ class SentryNavigationListenerTest { verify(fixture.scopes).startTransaction( check { - assertEquals("/gitscopes", it.name) + assertEquals("/github", it.name) assertEquals(TransactionNameSource.ROUTE, it.transactionNameSource) }, any() diff --git a/sentry-apollo-3/src/main/java/io/sentry/apollo3/SentryApollo3HttpInterceptor.kt b/sentry-apollo-3/src/main/java/io/sentry/apollo3/SentryApollo3HttpInterceptor.kt index 10e56ce7be..52219cb8e1 100644 --- a/sentry-apollo-3/src/main/java/io/sentry/apollo3/SentryApollo3HttpInterceptor.kt +++ b/sentry-apollo-3/src/main/java/io/sentry/apollo3/SentryApollo3HttpInterceptor.kt @@ -91,7 +91,7 @@ class SentryApollo3HttpInterceptor @JvmOverloads constructor( return httpResponse } catch (e: Throwable) { - // https://gitscopes.com/apollographql/apollo-kotlin/issues/4711 will change error handling in v4 + // https://github.com/apollographql/apollo-kotlin/issues/4711 will change error handling in v4 when (e) { is ApolloHttpException -> { statusCode = e.statusCode diff --git a/sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/SentrySpanProcessorTest.kt b/sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/SentrySpanProcessorTest.kt index 625fd54004..50d70f34f5 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/SentrySpanProcessorTest.kt +++ b/sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/SentrySpanProcessorTest.kt @@ -303,7 +303,7 @@ class SentrySpanProcessorTest { thenChildSpanIsStarted() otelChildSpan.setStatus(StatusCode.ERROR) - otelChildSpan.setAttribute(SemanticAttributes.HTTP_URL, "http://gitscopes.com/getsentry/sentry-java") + otelChildSpan.setAttribute(SemanticAttributes.HTTP_URL, "http://github.com/getsentry/sentry-java") otelChildSpan.setAttribute(SemanticAttributes.HTTP_STATUS_CODE, 404L) otelChildSpan.end() From 7752bcc13869a208b2332c5127bbf613735f4212 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Thu, 4 Apr 2024 13:53:20 +0200 Subject: [PATCH 17/28] Replace ThreadLocal with ScopesStorage --- sentry/api/sentry.api | 24 +++++++++++ .../java/io/sentry/DefaultScopesStorage.java | 42 +++++++++++++++++++ .../main/java/io/sentry/IScopesStorage.java | 13 ++++++ .../java/io/sentry/ISentryLifecycleToken.java | 8 ++++ .../java/io/sentry/NoOpScopesStorage.java | 40 ++++++++++++++++++ sentry/src/main/java/io/sentry/Sentry.java | 42 +++++++++++-------- 6 files changed, 152 insertions(+), 17 deletions(-) create mode 100644 sentry/src/main/java/io/sentry/DefaultScopesStorage.java create mode 100644 sentry/src/main/java/io/sentry/IScopesStorage.java create mode 100644 sentry/src/main/java/io/sentry/ISentryLifecycleToken.java create mode 100644 sentry/src/main/java/io/sentry/NoOpScopesStorage.java diff --git a/sentry/api/sentry.api b/sentry/api/sentry.api index 24935be274..32ce777a3d 100644 --- a/sentry/api/sentry.api +++ b/sentry/api/sentry.api @@ -259,6 +259,13 @@ public final class io/sentry/DeduplicateMultithreadedEventProcessor : io/sentry/ public fun process (Lio/sentry/SentryEvent;Lio/sentry/Hint;)Lio/sentry/SentryEvent; } +public final class io/sentry/DefaultScopesStorage : io/sentry/IScopesStorage { + public fun ()V + public fun close ()V + public fun get ()Lio/sentry/IScopes; + public fun set (Lio/sentry/IScopes;)Lio/sentry/ISentryLifecycleToken; +} + public final class io/sentry/DefaultTransactionPerformanceCollector : io/sentry/TransactionPerformanceCollector { public fun (Lio/sentry/SentryOptions;)V public fun close ()V @@ -792,6 +799,12 @@ public abstract interface class io/sentry/IScopes { public abstract fun withScope (Lio/sentry/ScopeCallback;)V } +public abstract interface class io/sentry/IScopesStorage { + public abstract fun close ()V + public abstract fun get ()Lio/sentry/IScopes; + public abstract fun set (Lio/sentry/IScopes;)Lio/sentry/ISentryLifecycleToken; +} + public abstract interface class io/sentry/ISentryClient { public abstract fun captureCheckIn (Lio/sentry/CheckIn;Lio/sentry/IScope;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId; public fun captureEnvelope (Lio/sentry/SentryEnvelope;)Lio/sentry/protocol/SentryId; @@ -831,6 +844,10 @@ public abstract interface class io/sentry/ISentryExecutorService { public abstract fun submit (Ljava/util/concurrent/Callable;)Ljava/util/concurrent/Future; } +public abstract interface class io/sentry/ISentryLifecycleToken : java/lang/AutoCloseable { + public abstract fun close ()V +} + public abstract interface class io/sentry/ISerializer { public abstract fun deserialize (Ljava/io/Reader;Ljava/lang/Class;)Ljava/lang/Object; public abstract fun deserializeCollection (Ljava/io/Reader;Ljava/lang/Class;Lio/sentry/JsonDeserializer;)Ljava/lang/Object; @@ -1390,6 +1407,13 @@ public final class io/sentry/NoOpScopes : io/sentry/IScopes { public fun withScope (Lio/sentry/ScopeCallback;)V } +public final class io/sentry/NoOpScopesStorage : io/sentry/IScopesStorage { + public fun close ()V + public fun get ()Lio/sentry/IScopes; + public static fun getInstance ()Lio/sentry/NoOpScopesStorage; + public fun set (Lio/sentry/IScopes;)Lio/sentry/ISentryLifecycleToken; +} + public final class io/sentry/NoOpSpan : io/sentry/ISpan { public fun finish ()V public fun finish (Lio/sentry/SpanStatus;)V diff --git a/sentry/src/main/java/io/sentry/DefaultScopesStorage.java b/sentry/src/main/java/io/sentry/DefaultScopesStorage.java new file mode 100644 index 0000000000..12902a1dff --- /dev/null +++ b/sentry/src/main/java/io/sentry/DefaultScopesStorage.java @@ -0,0 +1,42 @@ +package io.sentry; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public final class DefaultScopesStorage implements IScopesStorage { + + private static final @NotNull ThreadLocal currentScopes = new ThreadLocal<>(); + + @Override + public ISentryLifecycleToken set(@Nullable IScopes scopes) { + final @Nullable IScopes oldScopes = get(); + currentScopes.set(scopes); + return new DefaultScopesLifecycleToken(oldScopes); + } + + @Override + public @Nullable IScopes get() { + return currentScopes.get(); + } + + @Override + public void close() { + // TODO prevent further storing? would this cause problems if singleton, closed and + // re-initialized? + currentScopes.remove(); + } + + static final class DefaultScopesLifecycleToken implements ISentryLifecycleToken { + + private final @Nullable IScopes oldValue; + + DefaultScopesLifecycleToken(final @Nullable IScopes scopes) { + this.oldValue = scopes; + } + + @Override + public void close() { + currentScopes.set(oldValue); + } + } +} diff --git a/sentry/src/main/java/io/sentry/IScopesStorage.java b/sentry/src/main/java/io/sentry/IScopesStorage.java new file mode 100644 index 0000000000..92f6b587c4 --- /dev/null +++ b/sentry/src/main/java/io/sentry/IScopesStorage.java @@ -0,0 +1,13 @@ +package io.sentry; + +import org.jetbrains.annotations.Nullable; + +public interface IScopesStorage { + + ISentryLifecycleToken set(final @Nullable IScopes scopes); + + @Nullable + IScopes get(); + + void close(); +} diff --git a/sentry/src/main/java/io/sentry/ISentryLifecycleToken.java b/sentry/src/main/java/io/sentry/ISentryLifecycleToken.java new file mode 100644 index 0000000000..2d0ad180f7 --- /dev/null +++ b/sentry/src/main/java/io/sentry/ISentryLifecycleToken.java @@ -0,0 +1,8 @@ +package io.sentry; + +public interface ISentryLifecycleToken extends AutoCloseable { + + // overridden to not have a checked exception on the method. + @Override + void close(); +} diff --git a/sentry/src/main/java/io/sentry/NoOpScopesStorage.java b/sentry/src/main/java/io/sentry/NoOpScopesStorage.java new file mode 100644 index 0000000000..fa507987ae --- /dev/null +++ b/sentry/src/main/java/io/sentry/NoOpScopesStorage.java @@ -0,0 +1,40 @@ +package io.sentry; + +import org.jetbrains.annotations.Nullable; + +public final class NoOpScopesStorage implements IScopesStorage { + private static final NoOpScopesStorage instance = new NoOpScopesStorage(); + + private NoOpScopesStorage() {} + + public static NoOpScopesStorage getInstance() { + return instance; + } + + @Override + public ISentryLifecycleToken set(@Nullable IScopes scopes) { + return NoOpScopesLifecycleToken.getInstance(); + } + + @Override + public @Nullable IScopes get() { + return NoOpScopes.getInstance(); + } + + @Override + public void close() {} + + static final class NoOpScopesLifecycleToken implements ISentryLifecycleToken { + + private static final NoOpScopesLifecycleToken instance = new NoOpScopesLifecycleToken(); + + private NoOpScopesLifecycleToken() {} + + public static NoOpScopesLifecycleToken getInstance() { + return instance; + } + + @Override + public void close() {} + } +} diff --git a/sentry/src/main/java/io/sentry/Sentry.java b/sentry/src/main/java/io/sentry/Sentry.java index f4996bb8ad..e01ca2f281 100644 --- a/sentry/src/main/java/io/sentry/Sentry.java +++ b/sentry/src/main/java/io/sentry/Sentry.java @@ -43,8 +43,7 @@ public final class Sentry { private Sentry() {} - /** Holds Hubs per thread or only mainScopes if globalHubMode is enabled. */ - private static final @NotNull ThreadLocal currentScopes = new ThreadLocal<>(); + private static volatile @NotNull IScopesStorage scopesStorage = new DefaultScopesStorage(); /** The Main Hub or NoOp if Sentry is disabled. */ private static volatile @NotNull IScopes mainScopes = NoOpScopes.getInstance(); @@ -83,13 +82,17 @@ private Sentry() {} if (globalHubMode) { return mainScopes; } - IScopes hub = currentScopes.get(); - if (hub == null || hub.isNoOp()) { + IScopes scopes = getScopesStorage().get(); + if (scopes == null || scopes.isNoOp()) { // TODO fork instead - hub = mainScopes.clone(); - currentScopes.set(hub); + scopes = mainScopes.clone(); + getScopesStorage().set(scopes); } - return hub; + return scopes; + } + + private static @NotNull IScopesStorage getScopesStorage() { + return scopesStorage; } /** @@ -110,14 +113,15 @@ private Sentry() {} @ApiStatus.Internal // exposed for the coroutines integration in SentryContext @Deprecated - @SuppressWarnings("deprecation") + @SuppressWarnings({"deprecation", "InlineMeSuggester"}) public static void setCurrentHub(final @NotNull IHub hub) { - currentScopes.set(hub); + setCurrentScopes(hub); } @ApiStatus.Internal // exposed for the coroutines integration in SentryContext - public static void setCurrentScopes(final @NotNull IScopes scopes) { - currentScopes.set(scopes); + public static @NotNull ISentryLifecycleToken setCurrentScopes(final @NotNull IScopes scopes) { + return getScopesStorage().set(scopes); + } } /** @@ -253,14 +257,18 @@ private static synchronized void init( options.getLogger().log(SentryLevel.INFO, "GlobalHubMode: '%s'", String.valueOf(globalHubMode)); Sentry.globalHubMode = globalHubMode; - final IScopes hub = getCurrentScopes(); + final IScopes scopes = getCurrentScopes(); final IScope rootScope = new Scope(options); - final IScope rootIsolationScope = new Scope(options); - mainScopes = new Scopes(rootScope, rootIsolationScope, options, "Sentry.init"); + // TODO should use separate isolation scope: + // final IScope rootIsolationScope = new Scope(options); + // TODO should be: + // getGlobalScope().bindClient(new SentryClient(options)); + rootScope.bindClient(new SentryClient(options)); + mainScopes = new Scopes(rootScope, rootScope, options, "Sentry.init"); - currentScopes.set(mainScopes); + getScopesStorage().set(mainScopes); - hub.close(true); + scopes.close(true); // If the executorService passed in the init is the same that was previously closed, we have to // set a new one @@ -508,7 +516,7 @@ public static synchronized void close() { final IScopes scopes = getCurrentScopes(); mainScopes = NoOpScopes.getInstance(); // remove thread local to avoid memory leak - currentScopes.remove(); + getScopesStorage().close(); scopes.close(false); } From 1e329c59b7a63638f67720077f838c8665d83470 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Thu, 4 Apr 2024 14:13:51 +0200 Subject: [PATCH 18/28] Move client and throwable to span map to scope --- sentry/api/sentry.api | 12 ++- sentry/src/main/java/io/sentry/IScope.java | 11 ++- sentry/src/main/java/io/sentry/NoOpScope.java | 9 +- sentry/src/main/java/io/sentry/Scope.java | 52 +++++++++++- sentry/src/main/java/io/sentry/Scopes.java | 83 ++++++------------- 5 files changed, 105 insertions(+), 62 deletions(-) diff --git a/sentry/api/sentry.api b/sentry/api/sentry.api index 32ce777a3d..81107f75a5 100644 --- a/sentry/api/sentry.api +++ b/sentry/api/sentry.api @@ -660,6 +660,8 @@ public abstract interface class io/sentry/IScope { public abstract fun addBreadcrumb (Lio/sentry/Breadcrumb;)V public abstract fun addBreadcrumb (Lio/sentry/Breadcrumb;Lio/sentry/Hint;)V public abstract fun addEventProcessor (Lio/sentry/EventProcessor;)V + public abstract fun assignTraceContext (Lio/sentry/SentryEvent;)V + public abstract fun bindClient (Lio/sentry/ISentryClient;)V public abstract fun clear ()V public abstract fun clearAttachments ()V public abstract fun clearBreadcrumbs ()V @@ -688,7 +690,6 @@ public abstract interface class io/sentry/IScope { public abstract fun removeContexts (Ljava/lang/String;)V public abstract fun removeExtra (Ljava/lang/String;)V public abstract fun removeTag (Ljava/lang/String;)V - public abstract fun setClient (Lio/sentry/ISentryClient;)V public abstract fun setContexts (Ljava/lang/String;Ljava/lang/Boolean;)V public abstract fun setContexts (Ljava/lang/String;Ljava/lang/Character;)V public abstract fun setContexts (Ljava/lang/String;Ljava/lang/Number;)V @@ -703,6 +704,7 @@ public abstract interface class io/sentry/IScope { public abstract fun setPropagationContext (Lio/sentry/PropagationContext;)V public abstract fun setRequest (Lio/sentry/protocol/Request;)V public abstract fun setScreen (Ljava/lang/String;)V + public abstract fun setSpanContext (Ljava/lang/Throwable;Lio/sentry/ISpan;Ljava/lang/String;)V public abstract fun setTag (Ljava/lang/String;Ljava/lang/String;)V public abstract fun setTransaction (Lio/sentry/ITransaction;)V public abstract fun setTransaction (Ljava/lang/String;)V @@ -1298,6 +1300,8 @@ public final class io/sentry/NoOpScope : io/sentry/IScope { public fun addBreadcrumb (Lio/sentry/Breadcrumb;)V public fun addBreadcrumb (Lio/sentry/Breadcrumb;Lio/sentry/Hint;)V public fun addEventProcessor (Lio/sentry/EventProcessor;)V + public fun assignTraceContext (Lio/sentry/SentryEvent;)V + public fun bindClient (Lio/sentry/ISentryClient;)V public fun clear ()V public fun clearAttachments ()V public fun clearBreadcrumbs ()V @@ -1328,7 +1332,6 @@ public final class io/sentry/NoOpScope : io/sentry/IScope { public fun removeContexts (Ljava/lang/String;)V public fun removeExtra (Ljava/lang/String;)V public fun removeTag (Ljava/lang/String;)V - public fun setClient (Lio/sentry/ISentryClient;)V public fun setContexts (Ljava/lang/String;Ljava/lang/Boolean;)V public fun setContexts (Ljava/lang/String;Ljava/lang/Character;)V public fun setContexts (Ljava/lang/String;Ljava/lang/Number;)V @@ -1343,6 +1346,7 @@ public final class io/sentry/NoOpScope : io/sentry/IScope { public fun setPropagationContext (Lio/sentry/PropagationContext;)V public fun setRequest (Lio/sentry/protocol/Request;)V public fun setScreen (Ljava/lang/String;)V + public fun setSpanContext (Ljava/lang/Throwable;Lio/sentry/ISpan;Ljava/lang/String;)V public fun setTag (Ljava/lang/String;Ljava/lang/String;)V public fun setTransaction (Lio/sentry/ITransaction;)V public fun setTransaction (Ljava/lang/String;)V @@ -1731,6 +1735,8 @@ public final class io/sentry/Scope : io/sentry/IScope { public fun addBreadcrumb (Lio/sentry/Breadcrumb;)V public fun addBreadcrumb (Lio/sentry/Breadcrumb;Lio/sentry/Hint;)V public fun addEventProcessor (Lio/sentry/EventProcessor;)V + public fun assignTraceContext (Lio/sentry/SentryEvent;)V + public fun bindClient (Lio/sentry/ISentryClient;)V public fun clear ()V public fun clearAttachments ()V public fun clearBreadcrumbs ()V @@ -1760,7 +1766,6 @@ public final class io/sentry/Scope : io/sentry/IScope { public fun removeContexts (Ljava/lang/String;)V public fun removeExtra (Ljava/lang/String;)V public fun removeTag (Ljava/lang/String;)V - public fun setClient (Lio/sentry/ISentryClient;)V public fun setContexts (Ljava/lang/String;Ljava/lang/Boolean;)V public fun setContexts (Ljava/lang/String;Ljava/lang/Character;)V public fun setContexts (Ljava/lang/String;Ljava/lang/Number;)V @@ -1775,6 +1780,7 @@ public final class io/sentry/Scope : io/sentry/IScope { public fun setPropagationContext (Lio/sentry/PropagationContext;)V public fun setRequest (Lio/sentry/protocol/Request;)V public fun setScreen (Ljava/lang/String;)V + public fun setSpanContext (Ljava/lang/Throwable;Lio/sentry/ISpan;Ljava/lang/String;)V public fun setTag (Ljava/lang/String;Ljava/lang/String;)V public fun setTransaction (Lio/sentry/ITransaction;)V public fun setTransaction (Ljava/lang/String;)V diff --git a/sentry/src/main/java/io/sentry/IScope.java b/sentry/src/main/java/io/sentry/IScope.java index 3bc25ce8e9..d761ccc192 100644 --- a/sentry/src/main/java/io/sentry/IScope.java +++ b/sentry/src/main/java/io/sentry/IScope.java @@ -377,8 +377,17 @@ public interface IScope { @NotNull SentryId getLastEventId(); - void setClient(final @NotNull ISentryClient client); + void bindClient(final @NotNull ISentryClient client); @NotNull ISentryClient getClient(); + + @ApiStatus.Internal + void assignTraceContext(final @NotNull SentryEvent event); + + @ApiStatus.Internal + void setSpanContext( + final @NotNull Throwable throwable, + final @NotNull ISpan span, + final @NotNull String transactionName); } diff --git a/sentry/src/main/java/io/sentry/NoOpScope.java b/sentry/src/main/java/io/sentry/NoOpScope.java index f7336d6edb..400a7e739f 100644 --- a/sentry/src/main/java/io/sentry/NoOpScope.java +++ b/sentry/src/main/java/io/sentry/NoOpScope.java @@ -256,10 +256,17 @@ public void setLastEventId(@NotNull SentryId lastEventId) {} } @Override - public void setClient(@NotNull ISentryClient client) {} + public void bindClient(@NotNull ISentryClient client) {} @Override public @NotNull ISentryClient getClient() { return NoOpSentryClient.getInstance(); } + + @Override + public void assignTraceContext(@NotNull SentryEvent event) {} + + @Override + public void setSpanContext( + @NotNull Throwable throwable, @NotNull ISpan span, @NotNull String transactionName) {} } diff --git a/sentry/src/main/java/io/sentry/Scope.java b/sentry/src/main/java/io/sentry/Scope.java index aa35ccfd7a..fcbcd74650 100644 --- a/sentry/src/main/java/io/sentry/Scope.java +++ b/sentry/src/main/java/io/sentry/Scope.java @@ -7,13 +7,18 @@ import io.sentry.protocol.TransactionNameSource; import io.sentry.protocol.User; import io.sentry.util.CollectionUtils; +import io.sentry.util.ExceptionUtils; import io.sentry.util.Objects; +import io.sentry.util.Pair; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Queue; +import java.util.WeakHashMap; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import org.jetbrains.annotations.ApiStatus; @@ -85,6 +90,11 @@ public final class Scope implements IScope { private @NotNull ISentryClient client = NoOpSentryClient.getInstance(); + // TODO intended only for global scope + // TODO test for memory leak + private final @NotNull Map, String>> throwableToSpan = + Collections.synchronizedMap(new WeakHashMap<>()); + /** * Scope's ctor * @@ -103,6 +113,7 @@ private Scope(final @NotNull Scope scope) { this.session = scope.session; this.options = scope.options; this.level = scope.level; + this.client = scope.client; // TODO should we do this? didn't do it for Hub this.lastEventId = scope.getLastEventId(); @@ -964,7 +975,7 @@ public void setLastEventId(@NotNull SentryId lastEventId) { } @Override - public void setClient(@NotNull ISentryClient client) { + public void bindClient(@NotNull ISentryClient client) { this.client = client; } @@ -973,6 +984,45 @@ public void setClient(@NotNull ISentryClient client) { return client; } + @Override + @ApiStatus.Internal + public void assignTraceContext(final @NotNull SentryEvent event) { + if (options.isTracingEnabled() && event.getThrowable() != null) { + final Pair, String> pair = + throwableToSpan.get(ExceptionUtils.findRootCause(event.getThrowable())); + if (pair != null) { + final WeakReference spanWeakRef = pair.getFirst(); + if (event.getContexts().getTrace() == null && spanWeakRef != null) { + final ISpan span = spanWeakRef.get(); + if (span != null) { + event.getContexts().setTrace(span.getSpanContext()); + } + } + final String transactionName = pair.getSecond(); + if (event.getTransaction() == null && transactionName != null) { + event.setTransaction(transactionName); + } + } + } + } + + @Override + @ApiStatus.Internal + public void setSpanContext( + final @NotNull Throwable throwable, + final @NotNull ISpan span, + final @NotNull String transactionName) { + Objects.requireNonNull(throwable, "throwable is required"); + Objects.requireNonNull(span, "span is required"); + Objects.requireNonNull(transactionName, "transactionName is required"); + // to match any cause, span context is always attached to the root cause of the exception + final Throwable rootCause = ExceptionUtils.findRootCause(throwable); + // the most inner span should be assigned to a throwable + if (!throwableToSpan.containsKey(rootCause)) { + throwableToSpan.put(rootCause, new Pair<>(new WeakReference<>(span), transactionName)); + } + } + /** The IWithTransaction callback */ @ApiStatus.Internal public interface IWithTransaction { diff --git a/sentry/src/main/java/io/sentry/Scopes.java b/sentry/src/main/java/io/sentry/Scopes.java index 618864b649..b384d39c05 100644 --- a/sentry/src/main/java/io/sentry/Scopes.java +++ b/sentry/src/main/java/io/sentry/Scopes.java @@ -9,19 +9,15 @@ import io.sentry.protocol.SentryTransaction; import io.sentry.protocol.User; import io.sentry.transport.RateLimiter; -import io.sentry.util.ExceptionUtils; import io.sentry.util.HintUtils; import io.sentry.util.Objects; -import io.sentry.util.Pair; import io.sentry.util.TracingUtils; import java.io.Closeable; import java.io.IOException; -import java.lang.ref.WeakReference; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.WeakHashMap; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -40,10 +36,6 @@ public final class Scopes implements IScopes, MetricsApi.IMetricsInterface { private final @NotNull SentryOptions options; private volatile boolean isEnabled; private final @NotNull TracesSampler tracesSampler; - - // TODO should this go on global scope? - private final @NotNull Map, String>> throwableToSpan = - Collections.synchronizedMap(new WeakHashMap<>()); private final @NotNull TransactionPerformanceCollector transactionPerformanceCollector; private final @NotNull MetricsApi metricsApi; @@ -120,7 +112,10 @@ public boolean isAncestorOf(final @Nullable Scopes otherScopes) { // TODO add to IScopes interface public @NotNull Scopes forkedCurrentScope(final @NotNull String creator) { - return new Scopes(scope.clone(), isolationScope, this, options, creator); + IScope clone = scope.clone(); + // TODO should use isolation scope + // return new Scopes(clone, isolationScope, this, options, creator); + return new Scopes(clone, clone, this, options, creator); } // // TODO in Sentry.init? @@ -180,23 +175,7 @@ public boolean isEnabled() { } private void assignTraceContext(final @NotNull SentryEvent event) { - if (options.isTracingEnabled() && event.getThrowable() != null) { - final Pair, String> pair = - throwableToSpan.get(ExceptionUtils.findRootCause(event.getThrowable())); - if (pair != null) { - final WeakReference spanWeakRef = pair.getFirst(); - if (event.getContexts().getTrace() == null && spanWeakRef != null) { - final ISpan span = spanWeakRef.get(); - if (span != null) { - event.getContexts().setTrace(span.getSpanContext()); - } - } - final String transactionName = pair.getSecond(); - if (event.getTransaction() == null && transactionName != null) { - event.setTransaction(transactionName); - } - } - } + Sentry.getGlobalScope().assignTraceContext(event); } private IScope buildLocalScope( @@ -691,10 +670,10 @@ public void bindClient(final @NotNull ISentryClient client) { } else { if (client != null) { options.getLogger().log(SentryLevel.DEBUG, "New client bound to scope."); - getDefaultWriteScope().setClient(client); + getDefaultWriteScope().bindClient(client); } else { options.getLogger().log(SentryLevel.DEBUG, "NoOp client bound to scope."); - getDefaultWriteScope().setClient(NoOpSentryClient.getInstance()); + getDefaultWriteScope().bindClient(NoOpSentryClient.getInstance()); } } } @@ -871,34 +850,26 @@ public void setSpanContext( final @NotNull Throwable throwable, final @NotNull ISpan span, final @NotNull String transactionName) { - Objects.requireNonNull(throwable, "throwable is required"); - Objects.requireNonNull(span, "span is required"); - Objects.requireNonNull(transactionName, "transactionName is required"); - // to match any cause, span context is always attached to the root cause of the exception - final Throwable rootCause = ExceptionUtils.findRootCause(throwable); - // the most inner span should be assigned to a throwable - if (!throwableToSpan.containsKey(rootCause)) { - throwableToSpan.put(rootCause, new Pair<>(new WeakReference<>(span), transactionName)); - } - } - - // TODO this seems unused - @Nullable - SpanContext getSpanContext(final @NotNull Throwable throwable) { - Objects.requireNonNull(throwable, "throwable is required"); - final Throwable rootCause = ExceptionUtils.findRootCause(throwable); - final Pair, String> pair = this.throwableToSpan.get(rootCause); - if (pair != null) { - final WeakReference spanWeakRef = pair.getFirst(); - if (spanWeakRef != null) { - final ISpan span = spanWeakRef.get(); - if (span != null) { - return span.getSpanContext(); - } - } - } - return null; - } + Sentry.getGlobalScope().setSpanContext(throwable, span, transactionName); + } + + // // TODO this seems unused + // @Nullable + // SpanContext getSpanContext(final @NotNull Throwable throwable) { + // Objects.requireNonNull(throwable, "throwable is required"); + // final Throwable rootCause = ExceptionUtils.findRootCause(throwable); + // final Pair, String> pair = this.throwableToSpan.get(rootCause); + // if (pair != null) { + // final WeakReference spanWeakRef = pair.getFirst(); + // if (spanWeakRef != null) { + // final ISpan span = spanWeakRef.get(); + // if (span != null) { + // return span.getSpanContext(); + // } + // } + // } + // return null; + // } @Override public @Nullable ISpan getSpan() { From b0d89ae630829c1c223bbb0e599af4554261c3dd Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Thu, 4 Apr 2024 14:22:16 +0200 Subject: [PATCH 19/28] Add global scope --- sentry/api/sentry.api | 1 + sentry/src/main/java/io/sentry/Scopes.java | 3 ++- sentry/src/main/java/io/sentry/Sentry.java | 7 +++++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/sentry/api/sentry.api b/sentry/api/sentry.api index 81107f75a5..0d33cccdc4 100644 --- a/sentry/api/sentry.api +++ b/sentry/api/sentry.api @@ -2001,6 +2001,7 @@ public final class io/sentry/Sentry { public static fun getBaggage ()Lio/sentry/BaggageHeader; public static fun getCurrentHub ()Lio/sentry/IHub; public static fun getCurrentScopes ()Lio/sentry/IScopes; + public static fun getGlobalScope ()Lio/sentry/IScope; public static fun getLastEventId ()Lio/sentry/protocol/SentryId; public static fun getSpan ()Lio/sentry/ISpan; public static fun getTraceparent ()Lio/sentry/SentryTraceHeader; diff --git a/sentry/src/main/java/io/sentry/Scopes.java b/sentry/src/main/java/io/sentry/Scopes.java index b384d39c05..d99e0d8bd7 100644 --- a/sentry/src/main/java/io/sentry/Scopes.java +++ b/sentry/src/main/java/io/sentry/Scopes.java @@ -579,7 +579,8 @@ private void updateLastEventId(final @NotNull SentryId lastEventId) { // TODO add to IScopes interface public @NotNull IScope getGlobalScope() { - // TODO return singleton global scope here + // TODO should be: + // return Sentry.getGlobalScope(); return scope; } diff --git a/sentry/src/main/java/io/sentry/Sentry.java b/sentry/src/main/java/io/sentry/Sentry.java index e01ca2f281..76ada357f2 100644 --- a/sentry/src/main/java/io/sentry/Sentry.java +++ b/sentry/src/main/java/io/sentry/Sentry.java @@ -47,6 +47,8 @@ private Sentry() {} /** The Main Hub or NoOp if Sentry is disabled. */ private static volatile @NotNull IScopes mainScopes = NoOpScopes.getInstance(); + // TODO cannot pass options here + private static volatile @NotNull IScope globalScope = new Scope(new SentryOptions()); /** Default value for globalHubMode is false */ private static final boolean GLOBAL_HUB_DEFAULT_MODE = false; @@ -122,6 +124,9 @@ public static void setCurrentHub(final @NotNull IHub hub) { public static @NotNull ISentryLifecycleToken setCurrentScopes(final @NotNull IScopes scopes) { return getScopesStorage().set(scopes); } + + public static @NotNull IScope getGlobalScope() { + return globalScope; } /** @@ -264,6 +269,8 @@ private static synchronized void init( // TODO should be: // getGlobalScope().bindClient(new SentryClient(options)); rootScope.bindClient(new SentryClient(options)); + // TODO shouldn't replace global scope + globalScope = rootScope; mainScopes = new Scopes(rootScope, rootScope, options, "Sentry.init"); getScopesStorage().set(mainScopes); From cdd414aaa9590c284561fd92f0325356f48d002c Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Thu, 4 Apr 2024 16:24:34 +0200 Subject: [PATCH 20/28] use global scope in Scopes --- sentry/src/main/java/io/sentry/Scopes.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sentry/src/main/java/io/sentry/Scopes.java b/sentry/src/main/java/io/sentry/Scopes.java index d99e0d8bd7..c440b995ec 100644 --- a/sentry/src/main/java/io/sentry/Scopes.java +++ b/sentry/src/main/java/io/sentry/Scopes.java @@ -580,8 +580,8 @@ private void updateLastEventId(final @NotNull SentryId lastEventId) { // TODO add to IScopes interface public @NotNull IScope getGlobalScope() { // TODO should be: - // return Sentry.getGlobalScope(); - return scope; + return Sentry.getGlobalScope(); + // return scope; } @Override From 98da9ff6e4a1be1d01cfdafdd850ed51e8f07ce1 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Thu, 4 Apr 2024 16:28:30 +0200 Subject: [PATCH 21/28] Implement pushScope popScope and withScope for Scopes --- .../webflux/SentryWebFluxTracingFilterTest.kt | 4 +-- .../spring/webflux/SentryWebFilter.java | 4 +-- .../webflux/SentryWebFluxTracingFilterTest.kt | 4 +-- sentry/api/sentry.api | 21 ++++++++-------- sentry/src/main/java/io/sentry/Hub.java | 3 ++- .../src/main/java/io/sentry/HubAdapter.java | 4 +-- .../main/java/io/sentry/HubScopesWrapper.java | 4 +-- sentry/src/main/java/io/sentry/IScopes.java | 3 ++- sentry/src/main/java/io/sentry/NoOpHub.java | 4 ++- .../src/main/java/io/sentry/NoOpScopes.java | 4 ++- sentry/src/main/java/io/sentry/Scopes.java | 25 +++++++++++-------- .../main/java/io/sentry/ScopesAdapter.java | 4 +-- sentry/src/main/java/io/sentry/Sentry.java | 5 ++-- sentry/src/test/java/io/sentry/NoOpHubTest.kt | 4 ++- 14 files changed, 54 insertions(+), 39 deletions(-) diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryWebFluxTracingFilterTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryWebFluxTracingFilterTest.kt index e936394039..ddbbe75817 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryWebFluxTracingFilterTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryWebFluxTracingFilterTest.kt @@ -252,10 +252,10 @@ class SentryWebFluxTracingFilterTest { verify(fixture.scopes, times(3)).isEnabled verify(fixture.scopes, times(2)).options verify(fixture.scopes).continueTrace(anyOrNull(), anyOrNull()) - verify(fixture.scopes).pushScope() + verify(fixture.scopes).pushScope() // TODO don't verify(fixture.scopes).addBreadcrumb(any(), any()) verify(fixture.scopes).configureScope(any()) - verify(fixture.scopes).popScope() + verify(fixture.scopes).popScope() // TODO don't verifyNoMoreInteractions(fixture.scopes) } } diff --git a/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryWebFilter.java b/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryWebFilter.java index 3bb7de5ae4..4d39e092bc 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryWebFilter.java +++ b/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryWebFilter.java @@ -81,7 +81,7 @@ isTracingEnabled && shouldTraceRequest(requestHub, request) if (transaction != null) { finishTransaction(serverWebExchange, transaction); } - requestHub.popScope(); + requestHub.popScope(); // TODO don't // TODO token based cleanup instead? Sentry.setCurrentScopes(NoOpScopes.getInstance()); }) @@ -96,7 +96,7 @@ isTracingEnabled && shouldTraceRequest(requestHub, request) () -> { serverWebExchange.getAttributes().put(SENTRY_SCOPES_KEY, requestHub); Sentry.setCurrentScopes(requestHub); - requestHub.pushScope(); + requestHub.pushScope(); // TODO don't final ServerHttpResponse response = serverWebExchange.getResponse(); final Hint hint = new Hint(); diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryWebFluxTracingFilterTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryWebFluxTracingFilterTest.kt index 2113c748ee..1a31dcaa10 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryWebFluxTracingFilterTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryWebFluxTracingFilterTest.kt @@ -253,10 +253,10 @@ class SentryWebFluxTracingFilterTest { verify(fixture.scopes).isEnabled verify(fixture.scopes, times(2)).options verify(fixture.scopes).continueTrace(anyOrNull(), anyOrNull()) - verify(fixture.scopes).pushScope() + verify(fixture.scopes).pushScope() // TODO don't verify(fixture.scopes).addBreadcrumb(any(), any()) verify(fixture.scopes).configureScope(any()) - verify(fixture.scopes).popScope() + verify(fixture.scopes).popScope() // TODO don't verifyNoMoreInteractions(fixture.scopes) } } diff --git a/sentry/api/sentry.api b/sentry/api/sentry.api index 0d33cccdc4..9063972579 100644 --- a/sentry/api/sentry.api +++ b/sentry/api/sentry.api @@ -456,7 +456,7 @@ public final class io/sentry/Hub : io/sentry/IHub, io/sentry/metrics/MetricsApi$ public fun isHealthy ()Z public fun metrics ()Lio/sentry/metrics/MetricsApi; public fun popScope ()V - public fun pushScope ()V + public fun pushScope ()Lio/sentry/ISentryLifecycleToken; public fun removeExtra (Ljava/lang/String;)V public fun removeTag (Ljava/lang/String;)V public fun reportFullyDisplayed ()V @@ -510,7 +510,7 @@ public final class io/sentry/HubAdapter : io/sentry/IHub { public fun isHealthy ()Z public fun metrics ()Lio/sentry/metrics/MetricsApi; public fun popScope ()V - public fun pushScope ()V + public fun pushScope ()Lio/sentry/ISentryLifecycleToken; public fun removeExtra (Ljava/lang/String;)V public fun removeTag (Ljava/lang/String;)V public fun reportFullyDisplayed ()V @@ -563,7 +563,7 @@ public final class io/sentry/HubScopesWrapper : io/sentry/IHub { public fun isHealthy ()Z public fun metrics ()Lio/sentry/metrics/MetricsApi; public fun popScope ()V - public fun pushScope ()V + public fun pushScope ()Lio/sentry/ISentryLifecycleToken; public fun removeExtra (Ljava/lang/String;)V public fun removeTag (Ljava/lang/String;)V public fun reportFullyDisplayed ()V @@ -780,7 +780,7 @@ public abstract interface class io/sentry/IScopes { public fun isNoOp ()Z public abstract fun metrics ()Lio/sentry/metrics/MetricsApi; public abstract fun popScope ()V - public abstract fun pushScope ()V + public abstract fun pushScope ()Lio/sentry/ISentryLifecycleToken; public abstract fun removeExtra (Ljava/lang/String;)V public abstract fun removeTag (Ljava/lang/String;)V public fun reportFullDisplayed ()V @@ -1270,7 +1270,7 @@ public final class io/sentry/NoOpHub : io/sentry/IHub { public fun isNoOp ()Z public fun metrics ()Lio/sentry/metrics/MetricsApi; public fun popScope ()V - public fun pushScope ()V + public fun pushScope ()Lio/sentry/ISentryLifecycleToken; public fun removeExtra (Ljava/lang/String;)V public fun removeTag (Ljava/lang/String;)V public fun reportFullyDisplayed ()V @@ -1394,7 +1394,7 @@ public final class io/sentry/NoOpScopes : io/sentry/IScopes { public fun isNoOp ()Z public fun metrics ()Lio/sentry/metrics/MetricsApi; public fun popScope ()V - public fun pushScope ()V + public fun pushScope ()Lio/sentry/ISentryLifecycleToken; public fun removeExtra (Ljava/lang/String;)V public fun removeTag (Ljava/lang/String;)V public fun reportFullyDisplayed ()V @@ -1866,9 +1866,10 @@ public final class io/sentry/Scopes : io/sentry/IScopes, io/sentry/metrics/Metri public fun isCrashedLastRun ()Ljava/lang/Boolean; public fun isEnabled ()Z public fun isHealthy ()Z + public fun makeCurrent ()Lio/sentry/ISentryLifecycleToken; public fun metrics ()Lio/sentry/metrics/MetricsApi; public fun popScope ()V - public fun pushScope ()V + public fun pushScope ()Lio/sentry/ISentryLifecycleToken; public fun removeExtra (Ljava/lang/String;)V public fun removeTag (Ljava/lang/String;)V public fun reportFullyDisplayed ()V @@ -1922,7 +1923,7 @@ public final class io/sentry/ScopesAdapter : io/sentry/IScopes { public fun isHealthy ()Z public fun metrics ()Lio/sentry/metrics/MetricsApi; public fun popScope ()V - public fun pushScope ()V + public fun pushScope ()Lio/sentry/ISentryLifecycleToken; public fun removeExtra (Ljava/lang/String;)V public fun removeTag (Ljava/lang/String;)V public fun reportFullyDisplayed ()V @@ -2017,13 +2018,13 @@ public final class io/sentry/Sentry { public static fun isHealthy ()Z public static fun metrics ()Lio/sentry/metrics/MetricsApi; public static fun popScope ()V - public static fun pushScope ()V + public static fun pushScope ()Lio/sentry/ISentryLifecycleToken; public static fun removeExtra (Ljava/lang/String;)V public static fun removeTag (Ljava/lang/String;)V public static fun reportFullDisplayed ()V public static fun reportFullyDisplayed ()V public static fun setCurrentHub (Lio/sentry/IHub;)V - public static fun setCurrentScopes (Lio/sentry/IScopes;)V + public static fun setCurrentScopes (Lio/sentry/IScopes;)Lio/sentry/ISentryLifecycleToken; public static fun setExtra (Ljava/lang/String;Ljava/lang/String;)V public static fun setFingerprint (Ljava/util/List;)V public static fun setLevel (Lio/sentry/SentryLevel;)V diff --git a/sentry/src/main/java/io/sentry/Hub.java b/sentry/src/main/java/io/sentry/Hub.java index 6a98bb2367..d56305be5d 100644 --- a/sentry/src/main/java/io/sentry/Hub.java +++ b/sentry/src/main/java/io/sentry/Hub.java @@ -526,7 +526,7 @@ public void removeExtra(final @NotNull String key) { } @Override - public void pushScope() { + public @NotNull ISentryLifecycleToken pushScope() { if (!isEnabled()) { options .getLogger() @@ -536,6 +536,7 @@ public void pushScope() { final StackItem newItem = new StackItem(options, item.getClient(), item.getScope().clone()); stack.push(newItem); } + return NoOpScopesStorage.NoOpScopesLifecycleToken.getInstance(); } @Override diff --git a/sentry/src/main/java/io/sentry/HubAdapter.java b/sentry/src/main/java/io/sentry/HubAdapter.java index 746d51f0cc..f7970200ce 100644 --- a/sentry/src/main/java/io/sentry/HubAdapter.java +++ b/sentry/src/main/java/io/sentry/HubAdapter.java @@ -154,8 +154,8 @@ public void removeExtra(@NotNull String key) { } @Override - public void pushScope() { - Sentry.pushScope(); + public @NotNull ISentryLifecycleToken pushScope() { + return Sentry.pushScope(); } @Override diff --git a/sentry/src/main/java/io/sentry/HubScopesWrapper.java b/sentry/src/main/java/io/sentry/HubScopesWrapper.java index 9b294d05b7..90c485d7f4 100644 --- a/sentry/src/main/java/io/sentry/HubScopesWrapper.java +++ b/sentry/src/main/java/io/sentry/HubScopesWrapper.java @@ -149,8 +149,8 @@ public void removeExtra(@NotNull String key) { } @Override - public void pushScope() { - scopes.pushScope(); + public @NotNull ISentryLifecycleToken pushScope() { + return scopes.pushScope(); } @Override diff --git a/sentry/src/main/java/io/sentry/IScopes.java b/sentry/src/main/java/io/sentry/IScopes.java index 03662457e4..29edb6627d 100644 --- a/sentry/src/main/java/io/sentry/IScopes.java +++ b/sentry/src/main/java/io/sentry/IScopes.java @@ -306,7 +306,8 @@ default void addBreadcrumb(@NotNull String message, @NotNull String category) { SentryId getLastEventId(); /** Pushes a new scope while inheriting the current scope's data. */ - void pushScope(); + @NotNull + ISentryLifecycleToken pushScope(); /** Removes the first scope */ void popScope(); diff --git a/sentry/src/main/java/io/sentry/NoOpHub.java b/sentry/src/main/java/io/sentry/NoOpHub.java index 704bd2b44a..1d5134d865 100644 --- a/sentry/src/main/java/io/sentry/NoOpHub.java +++ b/sentry/src/main/java/io/sentry/NoOpHub.java @@ -124,7 +124,9 @@ public void removeExtra(@NotNull String key) {} } @Override - public void pushScope() {} + public @NotNull ISentryLifecycleToken pushScope() { + return NoOpScopesStorage.NoOpScopesLifecycleToken.getInstance(); + } @Override public void popScope() {} diff --git a/sentry/src/main/java/io/sentry/NoOpScopes.java b/sentry/src/main/java/io/sentry/NoOpScopes.java index 6fef262944..edf7ce1ecb 100644 --- a/sentry/src/main/java/io/sentry/NoOpScopes.java +++ b/sentry/src/main/java/io/sentry/NoOpScopes.java @@ -122,7 +122,9 @@ public void removeExtra(@NotNull String key) {} } @Override - public void pushScope() {} + public @NotNull ISentryLifecycleToken pushScope() { + return NoOpScopesStorage.NoOpScopesLifecycleToken.getInstance(); + } @Override public void popScope() {} diff --git a/sentry/src/main/java/io/sentry/Scopes.java b/sentry/src/main/java/io/sentry/Scopes.java index c440b995ec..5e3de8a855 100644 --- a/sentry/src/main/java/io/sentry/Scopes.java +++ b/sentry/src/main/java/io/sentry/Scopes.java @@ -595,20 +595,21 @@ private void updateLastEventId(final @NotNull SentryId lastEventId) { // TODO needs to be deprecated because there's no more stack // TODO needs to return a lifecycle token @Override - public void pushScope() { + public ISentryLifecycleToken pushScope() { if (!isEnabled()) { options .getLogger() .log(SentryLevel.WARNING, "Instance is disabled and this 'pushScope' call is a no-op."); + return NoOpScopesStorage.NoOpScopesLifecycleToken.getInstance(); } else { - // Scopes scopes = this.forkedScopes("pushScope"); - // return scopes.makeCurrent(); + Scopes scopes = this.forkedCurrentScope("pushScope"); + return scopes.makeCurrent(); } } - // public SentryLifecycleToken makeCurrent() { - // // TODO store.set(this); - // } + public ISentryLifecycleToken makeCurrent() { + return Sentry.setCurrentScopes(this); + } // TODO needs to be deprecated because there's no more stack @Override @@ -618,8 +619,11 @@ public void popScope() { .getLogger() .log(SentryLevel.WARNING, "Instance is disabled and this 'popScope' call is a no-op."); } else { - // TODO how to remove fork? - // TODO getParentScopes().makeCurrent()? + final @Nullable Scopes parent = getParent(); + if (parent != null) { + // TODO this is never closed + parent.makeCurrent(); + } } } @@ -634,7 +638,7 @@ public void withScope(final @NotNull ScopeCallback callback) { } } else { - Scopes forkedScopes = forkedScopes("withScope"); + Scopes forkedScopes = forkedCurrentScope("withScope"); // TODO should forkedScopes be made current inside callback? // TODO forkedScopes.makeCurrent()? try { @@ -705,7 +709,8 @@ public void flush(long timeoutMillis) { if (!isEnabled()) { options.getLogger().log(SentryLevel.WARNING, "Disabled Hub cloned."); } - return new HubScopesWrapper(forkedScopes("scopes clone")); + // TODO should this fork isolation scope as well? + return new HubScopesWrapper(forkedCurrentScope("scopes clone")); } @ApiStatus.Internal diff --git a/sentry/src/main/java/io/sentry/ScopesAdapter.java b/sentry/src/main/java/io/sentry/ScopesAdapter.java index 1ecd31e248..3ffdc01186 100644 --- a/sentry/src/main/java/io/sentry/ScopesAdapter.java +++ b/sentry/src/main/java/io/sentry/ScopesAdapter.java @@ -150,8 +150,8 @@ public void removeExtra(@NotNull String key) { } @Override - public void pushScope() { - Sentry.pushScope(); + public @NotNull ISentryLifecycleToken pushScope() { + return Sentry.pushScope(); } @Override diff --git a/sentry/src/main/java/io/sentry/Sentry.java b/sentry/src/main/java/io/sentry/Sentry.java index 76ada357f2..d9ebaa78be 100644 --- a/sentry/src/main/java/io/sentry/Sentry.java +++ b/sentry/src/main/java/io/sentry/Sentry.java @@ -813,12 +813,13 @@ public static void removeExtra(final @NotNull String key) { } /** Pushes a new scope while inheriting the current scope's data. */ - public static void pushScope() { + public static @NotNull ISentryLifecycleToken pushScope() { // pushScope is no-op in global hub mode if (!globalHubMode) { // TODO this might have to behave differently from Scopes.pushScope - getCurrentScopes().pushScope(); + return getCurrentScopes().pushScope(); } + return NoOpScopesStorage.NoOpScopesLifecycleToken.getInstance(); } /** Removes the first scope */ diff --git a/sentry/src/test/java/io/sentry/NoOpHubTest.kt b/sentry/src/test/java/io/sentry/NoOpHubTest.kt index dbbfb4b4f1..94af1acc9f 100644 --- a/sentry/src/test/java/io/sentry/NoOpHubTest.kt +++ b/sentry/src/test/java/io/sentry/NoOpHubTest.kt @@ -71,7 +71,9 @@ class NoOpHubTest { } @Test - fun `pushScope is no op`() = sut.pushScope() + fun `pushScope is no op`() { + sut.pushScope() + } @Test fun `popScope is no op`() = sut.popScope() From 2d2603384ae80946b24dabaff6dd6d05c6f21a9b Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Fri, 12 Apr 2024 08:01:03 +0200 Subject: [PATCH 22/28] Add pushIsolationScope; add fork methods to ISCope --- sentry/src/main/java/io/sentry/Hub.java | 30 +++++++++++++ .../src/main/java/io/sentry/HubAdapter.java | 31 +++++++++++++ .../main/java/io/sentry/HubScopesWrapper.java | 30 +++++++++++++ sentry/src/main/java/io/sentry/IScopes.java | 45 +++++++++++++++++++ sentry/src/main/java/io/sentry/NoOpHub.java | 30 +++++++++++++ .../src/main/java/io/sentry/NoOpScopes.java | 30 +++++++++++++ sentry/src/main/java/io/sentry/Scopes.java | 45 +++++++++++-------- .../main/java/io/sentry/ScopesAdapter.java | 31 +++++++++++++ sentry/src/main/java/io/sentry/Sentry.java | 19 +++++++- 9 files changed, 270 insertions(+), 21 deletions(-) diff --git a/sentry/src/main/java/io/sentry/Hub.java b/sentry/src/main/java/io/sentry/Hub.java index d56305be5d..dd468d1eca 100644 --- a/sentry/src/main/java/io/sentry/Hub.java +++ b/sentry/src/main/java/io/sentry/Hub.java @@ -539,6 +539,11 @@ public void removeExtra(final @NotNull String key) { return NoOpScopesStorage.NoOpScopesLifecycleToken.getInstance(); } + @Override + public @NotNull ISentryLifecycleToken pushIsolationScope() { + return NoOpScopesStorage.NoOpScopesLifecycleToken.getInstance(); + } + @Override public @NotNull SentryOptions getOptions() { return this.stack.peek().getOptions(); @@ -652,6 +657,31 @@ public void flush(long timeoutMillis) { return new Hub(this.options, new Stack(this.stack)); } + @Override + public @NotNull IScopes forkedScopes(@NotNull String creator) { + return Sentry.forkedScopes(creator); + } + + @Override + public @NotNull IScopes forkedCurrentScope(@NotNull String creator) { + return Sentry.forkedCurrentScope(creator); + } + + @Override + public @NotNull ISentryLifecycleToken makeCurrent() { + return NoOpScopesStorage.NoOpScopesLifecycleToken.getInstance(); + } + + @Override + public @NotNull IScope getScope() { + return Sentry.getCurrentScopes().getScope(); + } + + @Override + public @NotNull IScope getIsolationScope() { + return Sentry.getCurrentScopes().getIsolationScope(); + } + @ApiStatus.Internal @Override public @NotNull SentryId captureTransaction( diff --git a/sentry/src/main/java/io/sentry/HubAdapter.java b/sentry/src/main/java/io/sentry/HubAdapter.java index f7970200ce..d813a11391 100644 --- a/sentry/src/main/java/io/sentry/HubAdapter.java +++ b/sentry/src/main/java/io/sentry/HubAdapter.java @@ -158,6 +158,11 @@ public void removeExtra(@NotNull String key) { return Sentry.pushScope(); } + @Override + public @NotNull ISentryLifecycleToken pushIsolationScope() { + return Sentry.pushIsolationScope(); + } + @Override public void popScope() { Sentry.popScope(); @@ -193,6 +198,32 @@ public void flush(long timeoutMillis) { return Sentry.getCurrentScopes().clone(); } + @Override + public @NotNull IScopes forkedScopes(@NotNull String creator) { + return Sentry.forkedScopes(creator); + } + + @Override + public @NotNull IScopes forkedCurrentScope(@NotNull String creator) { + return Sentry.forkedCurrentScope(creator); + } + + @Override + public @NotNull ISentryLifecycleToken makeCurrent() { + // TODO this wouldn't do anything since it replaced the current with the same Scopes + return NoOpScopesStorage.NoOpScopesLifecycleToken.getInstance(); + } + + @Override + public @NotNull IScope getScope() { + return Sentry.getCurrentScopes().getScope(); + } + + @Override + public @NotNull IScope getIsolationScope() { + return Sentry.getCurrentScopes().getIsolationScope(); + } + @Override public @NotNull SentryId captureTransaction( @NotNull SentryTransaction transaction, diff --git a/sentry/src/main/java/io/sentry/HubScopesWrapper.java b/sentry/src/main/java/io/sentry/HubScopesWrapper.java index 90c485d7f4..c3b2b19d80 100644 --- a/sentry/src/main/java/io/sentry/HubScopesWrapper.java +++ b/sentry/src/main/java/io/sentry/HubScopesWrapper.java @@ -153,6 +153,11 @@ public void removeExtra(@NotNull String key) { return scopes.pushScope(); } + @Override + public @NotNull ISentryLifecycleToken pushIsolationScope() { + return scopes.pushIsolationScope(); + } + @Override public void popScope() { scopes.popScope(); @@ -188,6 +193,31 @@ public void flush(long timeoutMillis) { return scopes.clone(); } + @Override + public @NotNull IScopes forkedScopes(@NotNull String creator) { + return scopes.forkedScopes(creator); + } + + @Override + public @NotNull IScopes forkedCurrentScope(@NotNull String creator) { + return scopes.forkedCurrentScope(creator); + } + + @Override + public @NotNull ISentryLifecycleToken makeCurrent() { + return scopes.makeCurrent(); + } + + @Override + public @NotNull IScope getScope() { + return scopes.getScope(); + } + + @Override + public @NotNull IScope getIsolationScope() { + return scopes.getIsolationScope(); + } + @ApiStatus.Internal @Override public @NotNull SentryId captureTransaction( diff --git a/sentry/src/main/java/io/sentry/IScopes.java b/sentry/src/main/java/io/sentry/IScopes.java index 29edb6627d..1ad2d62887 100644 --- a/sentry/src/main/java/io/sentry/IScopes.java +++ b/sentry/src/main/java/io/sentry/IScopes.java @@ -309,6 +309,9 @@ default void addBreadcrumb(@NotNull String message, @NotNull String category) { @NotNull ISentryLifecycleToken pushScope(); + @NotNull + ISentryLifecycleToken pushIsolationScope(); + /** Removes the first scope */ void popScope(); @@ -354,12 +357,54 @@ default void addBreadcrumb(@NotNull String message, @NotNull String category) { /** * Clones the Hub * + * @deprecated please use {@link IScopes#forkedScopes(String)} or {@link + * IScopes#forkedCurrentScope(String)} instead. * @return the cloned Hub */ @NotNull @Deprecated IHub clone(); + /** + * Creates a fork of both current and isolation scope. + * + * @param creator debug information to see why scopes where forked + * @return forked Scopes + */ + @NotNull + IScopes forkedScopes(final @NotNull String creator); + + /** + * Creates a fork of current scope without forking isolation scope. + * + * @param creator debug information to see why scopes where forked + * @return forked Scopes + */ + @NotNull + IScopes forkedCurrentScope(final @NotNull String creator); + + /** + * Stores this Scopes in store, making it the current one that is used by static API. + * + * @return a token you should call .close() on when you're done. + */ + @NotNull + ISentryLifecycleToken makeCurrent(); + + /** + * Returns the current scope of this Scopes. + * + * @return scope + */ + public @NotNull IScope getScope(); + + /** + * Returns the isolation scope of this Scopes. + * + * @return isolation scope + */ + public @NotNull IScope getIsolationScope(); + /** * Captures the transaction and enqueues it for sending to Sentry server. * diff --git a/sentry/src/main/java/io/sentry/NoOpHub.java b/sentry/src/main/java/io/sentry/NoOpHub.java index 1d5134d865..890c41d43e 100644 --- a/sentry/src/main/java/io/sentry/NoOpHub.java +++ b/sentry/src/main/java/io/sentry/NoOpHub.java @@ -128,6 +128,11 @@ public void removeExtra(@NotNull String key) {} return NoOpScopesStorage.NoOpScopesLifecycleToken.getInstance(); } + @Override + public @NotNull ISentryLifecycleToken pushIsolationScope() { + return NoOpScopesStorage.NoOpScopesLifecycleToken.getInstance(); + } + @Override public void popScope() {} @@ -155,6 +160,31 @@ public void flush(long timeoutMillis) {} return instance; } + @Override + public @NotNull IScopes forkedScopes(@NotNull String creator) { + return NoOpScopes.getInstance(); + } + + @Override + public @NotNull IScopes forkedCurrentScope(@NotNull String creator) { + return NoOpScopes.getInstance(); + } + + @Override + public @NotNull ISentryLifecycleToken makeCurrent() { + return NoOpScopesStorage.NoOpScopesLifecycleToken.getInstance(); + } + + @Override + public @NotNull IScope getScope() { + return NoOpScope.getInstance(); + } + + @Override + public @NotNull IScope getIsolationScope() { + return NoOpScope.getInstance(); + } + @Override public @NotNull SentryId captureTransaction( final @NotNull SentryTransaction transaction, diff --git a/sentry/src/main/java/io/sentry/NoOpScopes.java b/sentry/src/main/java/io/sentry/NoOpScopes.java index edf7ce1ecb..aa2b0fd2f3 100644 --- a/sentry/src/main/java/io/sentry/NoOpScopes.java +++ b/sentry/src/main/java/io/sentry/NoOpScopes.java @@ -126,6 +126,11 @@ public void removeExtra(@NotNull String key) {} return NoOpScopesStorage.NoOpScopesLifecycleToken.getInstance(); } + @Override + public @NotNull ISentryLifecycleToken pushIsolationScope() { + return NoOpScopesStorage.NoOpScopesLifecycleToken.getInstance(); + } + @Override public void popScope() {} @@ -154,6 +159,31 @@ public void flush(long timeoutMillis) {} return NoOpHub.getInstance(); } + @Override + public @NotNull IScopes forkedScopes(@NotNull String creator) { + return NoOpScopes.getInstance(); + } + + @Override + public @NotNull IScopes forkedCurrentScope(@NotNull String creator) { + return NoOpScopes.getInstance(); + } + + @Override + public @NotNull ISentryLifecycleToken makeCurrent() { + return NoOpScopesStorage.NoOpScopesLifecycleToken.getInstance(); + } + + @Override + public @NotNull IScope getScope() { + return NoOpScope.getInstance(); + } + + @Override + public @NotNull IScope getIsolationScope() { + return NoOpScope.getInstance(); + } + @Override public @NotNull SentryId captureTransaction( final @NotNull SentryTransaction transaction, diff --git a/sentry/src/main/java/io/sentry/Scopes.java b/sentry/src/main/java/io/sentry/Scopes.java index 5e3de8a855..f844119be3 100644 --- a/sentry/src/main/java/io/sentry/Scopes.java +++ b/sentry/src/main/java/io/sentry/Scopes.java @@ -72,12 +72,12 @@ private Scopes( return creator; } - // TODO add to IScopes interface + @Override public @NotNull IScope getScope() { return scope; } - // TODO add to IScopes interface + @Override public @NotNull IScope getIsolationScope() { return isolationScope; } @@ -105,25 +105,16 @@ public boolean isAncestorOf(final @Nullable Scopes otherScopes) { return false; } - // TODO add to IScopes interface - public @NotNull Scopes forkedScopes(final @NotNull String creator) { + @Override + public @NotNull IScopes forkedScopes(final @NotNull String creator) { return new Scopes(scope.clone(), isolationScope.clone(), this, options, creator); } - // TODO add to IScopes interface - public @NotNull Scopes forkedCurrentScope(final @NotNull String creator) { - IScope clone = scope.clone(); - // TODO should use isolation scope - // return new Scopes(clone, isolationScope, this, options, creator); - return new Scopes(clone, clone, this, options, creator); + @Override + public @NotNull IScopes forkedCurrentScope(final @NotNull String creator) { + return new Scopes(scope.clone(), isolationScope, this, options, creator); } - // // TODO in Sentry.init? - // public static Scopes forkedRoots(final @NotNull SentryOptions options, final @NotNull String - // creator) { - // return new Scopes(ROOT_SCOPE.clone(), ROOT_ISOLATION_SCOPE.clone(), options, creator); - // } - // TODO always read from root scope? @Override public boolean isEnabled() { @@ -602,12 +593,28 @@ public ISentryLifecycleToken pushScope() { .log(SentryLevel.WARNING, "Instance is disabled and this 'pushScope' call is a no-op."); return NoOpScopesStorage.NoOpScopesLifecycleToken.getInstance(); } else { - Scopes scopes = this.forkedCurrentScope("pushScope"); + final @NotNull IScopes scopes = this.forkedCurrentScope("pushScope"); return scopes.makeCurrent(); } } - public ISentryLifecycleToken makeCurrent() { + @Override + public ISentryLifecycleToken pushIsolationScope() { + if (!isEnabled()) { + options + .getLogger() + .log( + SentryLevel.WARNING, + "Instance is disabled and this 'pushIsolationScope' call is a no-op."); + return NoOpScopesStorage.NoOpScopesLifecycleToken.getInstance(); + } else { + final @NotNull IScopes scopes = this.forkedScopes("pushIsolationScope"); + return scopes.makeCurrent(); + } + } + + @Override + public @NotNull ISentryLifecycleToken makeCurrent() { return Sentry.setCurrentScopes(this); } @@ -638,7 +645,7 @@ public void withScope(final @NotNull ScopeCallback callback) { } } else { - Scopes forkedScopes = forkedCurrentScope("withScope"); + final @NotNull IScopes forkedScopes = forkedCurrentScope("withScope"); // TODO should forkedScopes be made current inside callback? // TODO forkedScopes.makeCurrent()? try { diff --git a/sentry/src/main/java/io/sentry/ScopesAdapter.java b/sentry/src/main/java/io/sentry/ScopesAdapter.java index 3ffdc01186..fe79a42731 100644 --- a/sentry/src/main/java/io/sentry/ScopesAdapter.java +++ b/sentry/src/main/java/io/sentry/ScopesAdapter.java @@ -154,6 +154,11 @@ public void removeExtra(@NotNull String key) { return Sentry.pushScope(); } + @Override + public @NotNull ISentryLifecycleToken pushIsolationScope() { + return Sentry.pushIsolationScope(); + } + @Override public void popScope() { Sentry.popScope(); @@ -190,6 +195,32 @@ public void flush(long timeoutMillis) { return Sentry.getCurrentScopes().clone(); } + @Override + public @NotNull IScopes forkedScopes(@NotNull String creator) { + return Sentry.forkedScopes(creator); + } + + @Override + public @NotNull IScopes forkedCurrentScope(@NotNull String creator) { + return Sentry.forkedCurrentScope(creator); + } + + @Override + public @NotNull ISentryLifecycleToken makeCurrent() { + // TODO this wouldn't do anything since it replaced the current with the same Scopes + return NoOpScopesStorage.NoOpScopesLifecycleToken.getInstance(); + } + + @Override + public @NotNull IScope getScope() { + return Sentry.getCurrentScopes().getScope(); + } + + @Override + public @NotNull IScope getIsolationScope() { + return Sentry.getCurrentScopes().getIsolationScope(); + } + @ApiStatus.Internal @Override public @NotNull SentryId captureTransaction( diff --git a/sentry/src/main/java/io/sentry/Sentry.java b/sentry/src/main/java/io/sentry/Sentry.java index d9ebaa78be..aac1b9d66d 100644 --- a/sentry/src/main/java/io/sentry/Sentry.java +++ b/sentry/src/main/java/io/sentry/Sentry.java @@ -113,6 +113,14 @@ private Sentry() {} return mainScopes.clone(); } + public static @NotNull IScopes forkedScopes(final @NotNull String creator) { + return getCurrentScopes().forkedScopes(creator); + } + + public static @NotNull IScopes forkedCurrentScope(final @NotNull String creator) { + return getCurrentScopes().forkedCurrentScope(creator); + } + @ApiStatus.Internal // exposed for the coroutines integration in SentryContext @Deprecated @SuppressWarnings({"deprecation", "InlineMeSuggester"}) @@ -822,11 +830,19 @@ public static void removeExtra(final @NotNull String key) { return NoOpScopesStorage.NoOpScopesLifecycleToken.getInstance(); } + /** Pushes a new isolation and current scope while inheriting the current scope's data. */ + public static @NotNull ISentryLifecycleToken pushIsolationScope() { + // pushScope is no-op in global hub mode + if (!globalHubMode) { + return getCurrentScopes().pushIsolationScope(); + } + return NoOpScopesStorage.NoOpScopesLifecycleToken.getInstance(); + } + /** Removes the first scope */ public static void popScope() { // popScope is no-op in global hub mode if (!globalHubMode) { - // TODO this might have to behave differently from Scopes.popScope getCurrentScopes().popScope(); } } @@ -837,7 +853,6 @@ public static void popScope() { * @param callback the callback */ public static void withScope(final @NotNull ScopeCallback callback) { - // TODO this might have to behave differently from Scopes.withScope getCurrentScopes().withScope(callback); } From bbb6700e0e704ef9340dd04fa3ce82704da6a043 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Fri, 12 Apr 2024 09:07:17 +0200 Subject: [PATCH 23/28] Use separate scopes for current, isolation and global scope; rename mainScopes to rootScopes --- sentry/src/main/java/io/sentry/Sentry.java | 41 +++++++++----------- sentry/src/test/java/io/sentry/SentryTest.kt | 10 ++--- 2 files changed, 23 insertions(+), 28 deletions(-) diff --git a/sentry/src/main/java/io/sentry/Sentry.java b/sentry/src/main/java/io/sentry/Sentry.java index aac1b9d66d..1a8c7db4b5 100644 --- a/sentry/src/main/java/io/sentry/Sentry.java +++ b/sentry/src/main/java/io/sentry/Sentry.java @@ -45,8 +45,8 @@ private Sentry() {} private static volatile @NotNull IScopesStorage scopesStorage = new DefaultScopesStorage(); - /** The Main Hub or NoOp if Sentry is disabled. */ - private static volatile @NotNull IScopes mainScopes = NoOpScopes.getInstance(); + /** The root Scopes or NoOp if Sentry is disabled. */ + private static volatile @NotNull IScopes rootScopes = NoOpScopes.getInstance(); // TODO cannot pass options here private static volatile @NotNull IScope globalScope = new Scope(new SentryOptions()); @@ -67,7 +67,7 @@ private Sentry() {} private static final long classCreationTimestamp = System.currentTimeMillis(); /** - * Returns the current (threads) hub, if none, clones the mainScopes and returns it. + * Returns the current (threads) hub, if none, clones the rootScopes and returns it. * * @return the hub */ @@ -82,12 +82,11 @@ private Sentry() {} @SuppressWarnings("deprecation") public static @NotNull IScopes getCurrentScopes() { if (globalHubMode) { - return mainScopes; + return rootScopes; } IScopes scopes = getScopesStorage().get(); if (scopes == null || scopes.isNoOp()) { - // TODO fork instead - scopes = mainScopes.clone(); + scopes = rootScopes.forkedScopes("getCurrentScopes"); getScopesStorage().set(scopes); } return scopes; @@ -98,19 +97,18 @@ private Sentry() {} } /** - * Returns a new hub which is cloned from the mainScopes. + * Returns a new Scopes which is cloned from the rootScopes. * * @return the hub */ @ApiStatus.Internal @ApiStatus.Experimental @SuppressWarnings("deprecation") - public static @NotNull IScopes cloneMainHub() { + public static @NotNull IScopes forkedRootScopes(final @NotNull String creator) { if (globalHubMode) { - return mainScopes; + return rootScopes; } - // TODO fork instead - return mainScopes.clone(); + return rootScopes.forkedScopes(creator); } public static @NotNull IScopes forkedScopes(final @NotNull String creator) { @@ -123,9 +121,9 @@ private Sentry() {} @ApiStatus.Internal // exposed for the coroutines integration in SentryContext @Deprecated - @SuppressWarnings({"deprecation", "InlineMeSuggester"}) - public static void setCurrentHub(final @NotNull IHub hub) { - setCurrentScopes(hub); + @SuppressWarnings({"deprecation"}) + public static @NotNull ISentryLifecycleToken setCurrentHub(final @NotNull IHub hub) { + return setCurrentScopes(hub); } @ApiStatus.Internal // exposed for the coroutines integration in SentryContext @@ -272,16 +270,13 @@ private static synchronized void init( final IScopes scopes = getCurrentScopes(); final IScope rootScope = new Scope(options); - // TODO should use separate isolation scope: - // final IScope rootIsolationScope = new Scope(options); - // TODO should be: - // getGlobalScope().bindClient(new SentryClient(options)); - rootScope.bindClient(new SentryClient(options)); + final IScope rootIsolationScope = new Scope(options); // TODO shouldn't replace global scope - globalScope = rootScope; - mainScopes = new Scopes(rootScope, rootScope, options, "Sentry.init"); + globalScope = new Scope(options); + globalScope.bindClient(new SentryClient(options)); + rootScopes = new Scopes(rootScope, rootIsolationScope, options, "Sentry.init"); - getScopesStorage().set(mainScopes); + getScopesStorage().set(rootScopes); scopes.close(true); @@ -529,7 +524,7 @@ private static boolean initConfigurations(final @NotNull SentryOptions options) /** Close the SDK */ public static synchronized void close() { final IScopes scopes = getCurrentScopes(); - mainScopes = NoOpScopes.getInstance(); + rootScopes = NoOpScopes.getInstance(); // remove thread local to avoid memory leak getScopesStorage().close(); scopes.close(false); diff --git a/sentry/src/test/java/io/sentry/SentryTest.kt b/sentry/src/test/java/io/sentry/SentryTest.kt index 70728d2900..77d443f909 100644 --- a/sentry/src/test/java/io/sentry/SentryTest.kt +++ b/sentry/src/test/java/io/sentry/SentryTest.kt @@ -422,7 +422,7 @@ class SentryTest { assertNotNull(scopes) assertFalse(Sentry.getCurrentScopes().isNoOp) - val newMainHubClone = Sentry.cloneMainHub() + val newMainHubClone = Sentry.forkedRootScopes("test") newMainHubClone.addBreadcrumb("breadcrumbMainClone") scopes.captureMessage("messageCurrent") @@ -473,7 +473,7 @@ class SentryTest { assertNotNull(scopes) assertFalse(scopes.isNoOp) - val newMainHubClone = Sentry.cloneMainHub() + val newMainHubClone = Sentry.forkedRootScopes("test") newMainHubClone.addBreadcrumb("breadcrumbMainClone") scopes.captureMessage("messageCurrent") @@ -921,7 +921,7 @@ class SentryTest { } @Test - fun `getSpan calls returns root span if globalscopes mode is enabled on Android`() { + fun `getSpan calls returns root span if globalHubMode is enabled on Android`() { PlatformTestManipulator.pretendIsAndroid(true) Sentry.init({ it.dsn = dsn @@ -938,7 +938,7 @@ class SentryTest { } @Test - fun `getSpan calls returns child span if globalscopes mode is enabled, but the platform is not Android`() { + fun `getSpan calls returns child span if globalHubMode is enabled, but the platform is not Android`() { PlatformTestManipulator.pretendIsAndroid(false) Sentry.init({ it.dsn = dsn @@ -954,7 +954,7 @@ class SentryTest { } @Test - fun `getSpan calls returns child span if globalscopes mode is disabled`() { + fun `getSpan calls returns child span if globalHubMode is disabled`() { Sentry.init({ it.dsn = dsn it.enableTracing = true From c714b214dcd17d946248e2898e7fff01105863f0 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Fri, 12 Apr 2024 09:22:08 +0200 Subject: [PATCH 24/28] Allow controlling which scope configureScope uses --- .../core/AndroidOptionsInitializer.java | 3 ++ sentry/src/main/java/io/sentry/Hub.java | 3 +- .../src/main/java/io/sentry/HubAdapter.java | 4 +- .../main/java/io/sentry/HubScopesWrapper.java | 4 +- sentry/src/main/java/io/sentry/IScopes.java | 11 +++++- sentry/src/main/java/io/sentry/NoOpHub.java | 2 +- .../src/main/java/io/sentry/NoOpScopes.java | 2 +- sentry/src/main/java/io/sentry/ScopeType.java | 7 ++++ sentry/src/main/java/io/sentry/Scopes.java | 38 +++++++++++++------ .../main/java/io/sentry/ScopesAdapter.java | 4 +- sentry/src/main/java/io/sentry/Sentry.java | 12 +++++- .../main/java/io/sentry/SentryOptions.java | 10 +++++ .../src/test/java/io/sentry/HubAdapterTest.kt | 3 +- .../test/java/io/sentry/ScopesAdapterTest.kt | 3 +- 14 files changed, 82 insertions(+), 24 deletions(-) create mode 100644 sentry/src/main/java/io/sentry/ScopeType.java diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidOptionsInitializer.java b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidOptionsInitializer.java index 372448b8e7..605de4c0a8 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidOptionsInitializer.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidOptionsInitializer.java @@ -10,6 +10,7 @@ import io.sentry.ILogger; import io.sentry.ITransactionProfiler; import io.sentry.NoOpConnectionStatusProvider; +import io.sentry.ScopeType; import io.sentry.SendFireAndForgetEnvelopeSender; import io.sentry.SendFireAndForgetOutboxSender; import io.sentry.SentryLevel; @@ -98,6 +99,8 @@ static void loadDefaultAndMetadataOptions( // Firstly set the logger, if `debug=true` configured, logging can start asap. options.setLogger(logger); + options.setDefaultScopeType(ScopeType.CURRENT); + options.setDateProvider(new SentryAndroidDateProvider()); // set a lower flush timeout on Android to avoid ANRs diff --git a/sentry/src/main/java/io/sentry/Hub.java b/sentry/src/main/java/io/sentry/Hub.java index dd468d1eca..35740f4c3e 100644 --- a/sentry/src/main/java/io/sentry/Hub.java +++ b/sentry/src/main/java/io/sentry/Hub.java @@ -594,7 +594,8 @@ public void withScope(final @NotNull ScopeCallback callback) { } @Override - public void configureScope(final @NotNull ScopeCallback callback) { + public void configureScope( + final @Nullable ScopeType scopeType, final @NotNull ScopeCallback callback) { if (!isEnabled()) { options .getLogger() diff --git a/sentry/src/main/java/io/sentry/HubAdapter.java b/sentry/src/main/java/io/sentry/HubAdapter.java index d813a11391..f0d7335a80 100644 --- a/sentry/src/main/java/io/sentry/HubAdapter.java +++ b/sentry/src/main/java/io/sentry/HubAdapter.java @@ -174,8 +174,8 @@ public void withScope(@NotNull ScopeCallback callback) { } @Override - public void configureScope(@NotNull ScopeCallback callback) { - Sentry.configureScope(callback); + public void configureScope(@Nullable ScopeType scopeType, @NotNull ScopeCallback callback) { + Sentry.configureScope(scopeType, callback); } @Override diff --git a/sentry/src/main/java/io/sentry/HubScopesWrapper.java b/sentry/src/main/java/io/sentry/HubScopesWrapper.java index c3b2b19d80..3309e59671 100644 --- a/sentry/src/main/java/io/sentry/HubScopesWrapper.java +++ b/sentry/src/main/java/io/sentry/HubScopesWrapper.java @@ -169,8 +169,8 @@ public void withScope(@NotNull ScopeCallback callback) { } @Override - public void configureScope(@NotNull ScopeCallback callback) { - scopes.configureScope(callback); + public void configureScope(@Nullable ScopeType scopeType, @NotNull ScopeCallback callback) { + scopes.configureScope(scopeType, callback); } @Override diff --git a/sentry/src/main/java/io/sentry/IScopes.java b/sentry/src/main/java/io/sentry/IScopes.java index 1ad2d62887..af6f41ae13 100644 --- a/sentry/src/main/java/io/sentry/IScopes.java +++ b/sentry/src/main/java/io/sentry/IScopes.java @@ -331,7 +331,16 @@ default void addBreadcrumb(@NotNull String message, @NotNull String category) { * * @param callback The configure scope callback. */ - void configureScope(@NotNull ScopeCallback callback); + default void configureScope(@NotNull ScopeCallback callback) { + configureScope(null, callback); + } + + /** + * Configures the scope through the callback. + * + * @param callback The configure scope callback. + */ + void configureScope(@Nullable ScopeType scopeType, @NotNull ScopeCallback callback); /** * Binds a different client to the hub diff --git a/sentry/src/main/java/io/sentry/NoOpHub.java b/sentry/src/main/java/io/sentry/NoOpHub.java index 890c41d43e..ac1c542a94 100644 --- a/sentry/src/main/java/io/sentry/NoOpHub.java +++ b/sentry/src/main/java/io/sentry/NoOpHub.java @@ -142,7 +142,7 @@ public void withScope(@NotNull ScopeCallback callback) { } @Override - public void configureScope(@NotNull ScopeCallback callback) {} + public void configureScope(@Nullable ScopeType scopeType, @NotNull ScopeCallback callback) {} @Override public void bindClient(@NotNull ISentryClient client) {} diff --git a/sentry/src/main/java/io/sentry/NoOpScopes.java b/sentry/src/main/java/io/sentry/NoOpScopes.java index aa2b0fd2f3..de75ff8178 100644 --- a/sentry/src/main/java/io/sentry/NoOpScopes.java +++ b/sentry/src/main/java/io/sentry/NoOpScopes.java @@ -140,7 +140,7 @@ public void withScope(@NotNull ScopeCallback callback) { } @Override - public void configureScope(@NotNull ScopeCallback callback) {} + public void configureScope(@Nullable ScopeType scopeType, @NotNull ScopeCallback callback) {} @Override public void bindClient(@NotNull ISentryClient client) {} diff --git a/sentry/src/main/java/io/sentry/ScopeType.java b/sentry/src/main/java/io/sentry/ScopeType.java new file mode 100644 index 0000000000..d54c2b635c --- /dev/null +++ b/sentry/src/main/java/io/sentry/ScopeType.java @@ -0,0 +1,7 @@ +package io.sentry; + +public enum ScopeType { + CURRENT, + ISOLATION, + GLOBAL; +} diff --git a/sentry/src/main/java/io/sentry/Scopes.java b/sentry/src/main/java/io/sentry/Scopes.java index f844119be3..c37dddfd31 100644 --- a/sentry/src/main/java/io/sentry/Scopes.java +++ b/sentry/src/main/java/io/sentry/Scopes.java @@ -428,16 +428,31 @@ public void addBreadcrumb(final @NotNull Breadcrumb breadcrumb, final @Nullable } } - private IScope getDefaultConfigureScope() { - // TODO configurable default scope via SentryOptions, Android = global or isolation, backend = - // isolation - return scope; - } + private IScope getSpecificScope(final @Nullable ScopeType scopeType) { + if (scopeType != null) { + switch (scopeType) { + case CURRENT: + return scope; + case ISOLATION: + return isolationScope; + case GLOBAL: + return getGlobalScope(); + default: + break; + } + } - private IScope getDefaultWriteScope() { - // TODO configurable default scope via SentryOptions, Android = global or isolation, backend = - // isolation - return getIsolationScope(); + switch (getOptions().getDefaultScopeType()) { + case CURRENT: + return scope; + case ISOLATION: + return isolationScope; + case GLOBAL: + return getGlobalScope(); + default: + // calm the compiler + return scope; + } } @Override @@ -657,7 +672,8 @@ public void withScope(final @NotNull ScopeCallback callback) { } @Override - public void configureScope(final @NotNull ScopeCallback callback) { + public void configureScope( + final @Nullable ScopeType scopeType, final @NotNull ScopeCallback callback) { if (!isEnabled()) { options .getLogger() @@ -666,7 +682,7 @@ public void configureScope(final @NotNull ScopeCallback callback) { "Instance is disabled and this 'configureScope' call is a no-op."); } else { try { - callback.run(getDefaultConfigureScope()); + callback.run(getSpecificScope(scopeType)); } catch (Throwable e) { options.getLogger().log(SentryLevel.ERROR, "Error in the 'configureScope' callback.", e); } diff --git a/sentry/src/main/java/io/sentry/ScopesAdapter.java b/sentry/src/main/java/io/sentry/ScopesAdapter.java index fe79a42731..d3b0f43bf2 100644 --- a/sentry/src/main/java/io/sentry/ScopesAdapter.java +++ b/sentry/src/main/java/io/sentry/ScopesAdapter.java @@ -170,8 +170,8 @@ public void withScope(@NotNull ScopeCallback callback) { } @Override - public void configureScope(@NotNull ScopeCallback callback) { - Sentry.configureScope(callback); + public void configureScope(@Nullable ScopeType scopeType, @NotNull ScopeCallback callback) { + Sentry.configureScope(scopeType, callback); } @Override diff --git a/sentry/src/main/java/io/sentry/Sentry.java b/sentry/src/main/java/io/sentry/Sentry.java index 1a8c7db4b5..090cba0d66 100644 --- a/sentry/src/main/java/io/sentry/Sentry.java +++ b/sentry/src/main/java/io/sentry/Sentry.java @@ -857,7 +857,17 @@ public static void withScope(final @NotNull ScopeCallback callback) { * @param callback The configure scope callback. */ public static void configureScope(final @NotNull ScopeCallback callback) { - getCurrentScopes().configureScope(callback); + configureScope(null, callback); + } + + /** + * Configures the scope through the callback. + * + * @param callback The configure scope callback. + */ + public static void configureScope( + final @Nullable ScopeType scopeType, final @NotNull ScopeCallback callback) { + getCurrentScopes().configureScope(scopeType, callback); } /** diff --git a/sentry/src/main/java/io/sentry/SentryOptions.java b/sentry/src/main/java/io/sentry/SentryOptions.java index b3bf66a1c2..c693907121 100644 --- a/sentry/src/main/java/io/sentry/SentryOptions.java +++ b/sentry/src/main/java/io/sentry/SentryOptions.java @@ -479,6 +479,8 @@ public class SentryOptions { @ApiStatus.Experimental private @Nullable Cron cron = null; + private @NotNull ScopeType defaultScopeType = ScopeType.ISOLATION; + /** * Adds an event processor * @@ -2385,6 +2387,14 @@ public void setCron(@Nullable Cron cron) { this.cron = cron; } + public void setDefaultScopeType(final @NotNull ScopeType scopeType) { + this.defaultScopeType = scopeType; + } + + public @NotNull ScopeType getDefaultScopeType() { + return defaultScopeType; + } + /** The BeforeSend callback */ public interface BeforeSendCallback { diff --git a/sentry/src/test/java/io/sentry/HubAdapterTest.kt b/sentry/src/test/java/io/sentry/HubAdapterTest.kt index 0e7e1d0f77..c8e17bfb2b 100644 --- a/sentry/src/test/java/io/sentry/HubAdapterTest.kt +++ b/sentry/src/test/java/io/sentry/HubAdapterTest.kt @@ -3,6 +3,7 @@ package io.sentry import io.sentry.protocol.SentryTransaction import io.sentry.protocol.User import org.mockito.kotlin.any +import org.mockito.kotlin.anyOrNull import org.mockito.kotlin.eq import org.mockito.kotlin.mock import org.mockito.kotlin.reset @@ -185,7 +186,7 @@ class HubAdapterTest { @Test fun `configureScope calls Hub`() { val scopeCallback = mock() HubAdapter.getInstance().configureScope(scopeCallback) - verify(scopes).configureScope(eq(scopeCallback)) + verify(scopes).configureScope(anyOrNull(), eq(scopeCallback)) } @Test fun `bindClient calls Hub`() { diff --git a/sentry/src/test/java/io/sentry/ScopesAdapterTest.kt b/sentry/src/test/java/io/sentry/ScopesAdapterTest.kt index 85a0b6ef75..7637e6c74e 100644 --- a/sentry/src/test/java/io/sentry/ScopesAdapterTest.kt +++ b/sentry/src/test/java/io/sentry/ScopesAdapterTest.kt @@ -3,6 +3,7 @@ package io.sentry import io.sentry.protocol.SentryTransaction import io.sentry.protocol.User import org.mockito.kotlin.any +import org.mockito.kotlin.anyOrNull import org.mockito.kotlin.eq import org.mockito.kotlin.mock import org.mockito.kotlin.reset @@ -185,7 +186,7 @@ class ScopesAdapterTest { @Test fun `configureScope calls Hub`() { val scopeCallback = mock() ScopesAdapter.getInstance().configureScope(scopeCallback) - verify(scopes).configureScope(eq(scopeCallback)) + verify(scopes).configureScope(anyOrNull(), eq(scopeCallback)) } @Test fun `bindClient calls Hub`() { From a4744028342b7b0abf7d93e4a1b387cd09a24404 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Fri, 12 Apr 2024 11:32:03 +0200 Subject: [PATCH 25/28] Combine scopes --- .../android/core/InternalSentrySdkTest.kt | 4 +- .../src/main/java/io/sentry/Breadcrumb.java | 8 +- .../java/io/sentry/CombinedContextsView.java | 214 ++++++++ .../java/io/sentry/CombinedScopeView.java | 456 ++++++++++++++++++ sentry/src/main/java/io/sentry/Scopes.java | 46 +- sentry/src/main/java/io/sentry/Sentry.java | 2 +- .../java/io/sentry/protocol/Contexts.java | 4 +- 7 files changed, 702 insertions(+), 32 deletions(-) create mode 100644 sentry/src/main/java/io/sentry/CombinedContextsView.java create mode 100644 sentry/src/main/java/io/sentry/CombinedScopeView.java diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/InternalSentrySdkTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/InternalSentrySdkTest.kt index a10d8add7b..b34e79991f 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/InternalSentrySdkTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/InternalSentrySdkTest.kt @@ -118,7 +118,7 @@ class InternalSentrySdkTest { @Test fun `current scope returns obj when hub is active`() { - Sentry.setCurrentHub( + Sentry.setCurrentScopes( Hub( SentryOptions().apply { dsn = "https://key@uri/1234567" @@ -131,7 +131,7 @@ class InternalSentrySdkTest { @Test fun `current scope returns a copy of the scope`() { - Sentry.setCurrentHub( + Sentry.setCurrentScopes( Hub( SentryOptions().apply { dsn = "https://key@uri/1234567" diff --git a/sentry/src/main/java/io/sentry/Breadcrumb.java b/sentry/src/main/java/io/sentry/Breadcrumb.java index fe2055c336..5f43ab6d29 100644 --- a/sentry/src/main/java/io/sentry/Breadcrumb.java +++ b/sentry/src/main/java/io/sentry/Breadcrumb.java @@ -17,7 +17,7 @@ import org.jetbrains.annotations.Nullable; /** Series of application events */ -public final class Breadcrumb implements JsonUnknown, JsonSerializable { +public final class Breadcrumb implements JsonUnknown, JsonSerializable, Comparable { /** A timestamp representing when the breadcrumb occurred. */ private final @NotNull Date timestamp; @@ -660,6 +660,12 @@ public void setUnknown(@Nullable Map unknown) { this.unknown = unknown; } + @Override + @SuppressWarnings("JavaUtilDate") + public int compareTo(@NotNull Breadcrumb o) { + return timestamp.compareTo(o.timestamp); + } + public static final class JsonKeys { public static final String TIMESTAMP = "timestamp"; public static final String MESSAGE = "message"; diff --git a/sentry/src/main/java/io/sentry/CombinedContextsView.java b/sentry/src/main/java/io/sentry/CombinedContextsView.java new file mode 100644 index 0000000000..3362a8ea1e --- /dev/null +++ b/sentry/src/main/java/io/sentry/CombinedContextsView.java @@ -0,0 +1,214 @@ +package io.sentry; + +import io.sentry.protocol.App; +import io.sentry.protocol.Browser; +import io.sentry.protocol.Contexts; +import io.sentry.protocol.Device; +import io.sentry.protocol.Gpu; +import io.sentry.protocol.OperatingSystem; +import io.sentry.protocol.Response; +import io.sentry.protocol.SentryRuntime; +import io.sentry.util.HintUtils; +import java.io.IOException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public final class CombinedContextsView extends Contexts { + + private static final long serialVersionUID = 3585992094653318439L; + private final @NotNull Contexts globalContexts; + private final @NotNull Contexts isolationContexts; + private final @NotNull Contexts currentContexts; + + private final @NotNull ScopeType defaultScopeType; + + public CombinedContextsView( + final @NotNull Contexts globalContexts, + final @NotNull Contexts isolationContexts, + final @NotNull Contexts currentContexts, + final @NotNull ScopeType defaultScopeType) { + this.globalContexts = globalContexts; + this.isolationContexts = isolationContexts; + this.currentContexts = currentContexts; + this.defaultScopeType = defaultScopeType; + } + + @Override + public @Nullable SpanContext getTrace() { + final @Nullable SpanContext current = currentContexts.getTrace(); + if (current != null) { + return current; + } + final @Nullable SpanContext isolation = isolationContexts.getTrace(); + if (isolation != null) { + return isolation; + } + return globalContexts.getTrace(); + } + + @Override + public void setTrace(@Nullable SpanContext traceContext) { + getDefaultContexts().setTrace(traceContext); + } + + private Contexts getDefaultContexts() { + switch (defaultScopeType) { + case CURRENT: + return currentContexts; + case ISOLATION: + return isolationContexts; + case GLOBAL: + return globalContexts; + default: + return currentContexts; + } + } + + @Override + public @Nullable App getApp() { + final @Nullable App current = currentContexts.getApp(); + if (current != null) { + return current; + } + final @Nullable App isolation = isolationContexts.getApp(); + if (isolation != null) { + return isolation; + } + return globalContexts.getApp(); + } + + @Override + public void setApp(@NotNull App app) { + getDefaultContexts().setApp(app); + } + + @Override + public @Nullable Browser getBrowser() { + final @Nullable Browser current = currentContexts.getBrowser(); + if (current != null) { + return current; + } + final @Nullable Browser isolation = isolationContexts.getBrowser(); + if (isolation != null) { + return isolation; + } + return globalContexts.getBrowser(); + } + + @Override + public void setBrowser(@NotNull Browser browser) { + getDefaultContexts().setBrowser(browser); + } + + @Override + public @Nullable Device getDevice() { + final @Nullable Device current = currentContexts.getDevice(); + if (current != null) { + return current; + } + final @Nullable Device isolation = isolationContexts.getDevice(); + if (isolation != null) { + return isolation; + } + return globalContexts.getDevice(); + } + + @Override + public void setDevice(@NotNull Device device) { + getDefaultContexts().setDevice(device); + } + + @Override + public @Nullable OperatingSystem getOperatingSystem() { + final @Nullable OperatingSystem current = currentContexts.getOperatingSystem(); + if (current != null) { + return current; + } + final @Nullable OperatingSystem isolation = isolationContexts.getOperatingSystem(); + if (isolation != null) { + return isolation; + } + return globalContexts.getOperatingSystem(); + } + + @Override + public void setOperatingSystem(@NotNull OperatingSystem operatingSystem) { + getDefaultContexts().setOperatingSystem(operatingSystem); + } + + @Override + public @Nullable SentryRuntime getRuntime() { + final @Nullable SentryRuntime current = currentContexts.getRuntime(); + if (current != null) { + return current; + } + final @Nullable SentryRuntime isolation = isolationContexts.getRuntime(); + if (isolation != null) { + return isolation; + } + return globalContexts.getRuntime(); + } + + @Override + public void setRuntime(@NotNull SentryRuntime runtime) { + getDefaultContexts().setRuntime(runtime); + } + + @Override + public @Nullable Gpu getGpu() { + final @Nullable Gpu current = currentContexts.getGpu(); + if (current != null) { + return current; + } + final @Nullable Gpu isolation = isolationContexts.getGpu(); + if (isolation != null) { + return isolation; + } + return globalContexts.getGpu(); + } + + @Override + public void setGpu(@NotNull Gpu gpu) { + getDefaultContexts().setGpu(gpu); + } + + @Override + public @Nullable Response getResponse() { + final @Nullable Response current = currentContexts.getResponse(); + if (current != null) { + return current; + } + final @Nullable Response isolation = isolationContexts.getResponse(); + if (isolation != null) { + return isolation; + } + return globalContexts.getResponse(); + } + + @Override + public void withResponse(HintUtils.SentryConsumer callback) { + if (currentContexts.getResponse() != null) { + currentContexts.withResponse(callback); + } else if (isolationContexts.getResponse() != null) { + isolationContexts.withResponse(callback); + } else if (globalContexts.getResponse() != null) { + globalContexts.withResponse(callback); + } else { + getDefaultContexts().withResponse(callback); + } + } + + @Override + public void setResponse(@NotNull Response response) { + getDefaultContexts().setResponse(response); + } + + @Override + public void serialize(@NotNull ObjectWriter writer, @NotNull ILogger logger) throws IOException { + final @NotNull Contexts allContexts = new Contexts(); + allContexts.putAll(globalContexts); + allContexts.putAll(isolationContexts); + allContexts.putAll(currentContexts); + allContexts.serialize(writer, logger); + } +} diff --git a/sentry/src/main/java/io/sentry/CombinedScopeView.java b/sentry/src/main/java/io/sentry/CombinedScopeView.java new file mode 100644 index 0000000000..b9f8ab2c70 --- /dev/null +++ b/sentry/src/main/java/io/sentry/CombinedScopeView.java @@ -0,0 +1,456 @@ +package io.sentry; + +import io.sentry.protocol.Contexts; +import io.sentry.protocol.Request; +import io.sentry.protocol.SentryId; +import io.sentry.protocol.User; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Queue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public final class CombinedScopeView implements IScope { + + private final IScope globalScope; + private final IScope isolationScope; + private final IScope scope; + + public CombinedScopeView( + final @NotNull IScope globalScope, + final @NotNull IScope isolationScope, + final @NotNull IScope scope) { + this.globalScope = globalScope; + this.isolationScope = isolationScope; + this.scope = scope; + } + + @Override + public @Nullable SentryLevel getLevel() { + final @Nullable SentryLevel current = scope.getLevel(); + if (current != null) { + return current; + } + final @Nullable SentryLevel isolation = isolationScope.getLevel(); + if (isolation != null) { + return isolation; + } + return globalScope.getLevel(); + } + + @Override + public void setLevel(@Nullable SentryLevel level) { + getDefaultWriteScope().setLevel(level); + } + + @Override + public @Nullable String getTransactionName() { + final @Nullable String current = scope.getTransactionName(); + if (current != null) { + return current; + } + final @Nullable String isolation = isolationScope.getTransactionName(); + if (isolation != null) { + return isolation; + } + return globalScope.getTransactionName(); + } + + @Override + public void setTransaction(@NotNull String transaction) { + getDefaultWriteScope().setTransaction(transaction); + } + + @Override + public @Nullable ISpan getSpan() { + final @Nullable ISpan current = scope.getSpan(); + if (current != null) { + return current; + } + final @Nullable ISpan isolation = isolationScope.getSpan(); + if (isolation != null) { + return isolation; + } + return globalScope.getSpan(); + } + + @Override + public void setTransaction(@Nullable ITransaction transaction) { + getDefaultWriteScope().setTransaction(transaction); + } + + @Override + public @Nullable User getUser() { + final @Nullable User current = scope.getUser(); + if (current != null) { + return current; + } + final @Nullable User isolation = isolationScope.getUser(); + if (isolation != null) { + return isolation; + } + return globalScope.getUser(); + } + + @Override + public void setUser(@Nullable User user) { + getDefaultWriteScope().setUser(user); + } + + @Override + public @Nullable String getScreen() { + final @Nullable String current = scope.getScreen(); + if (current != null) { + return current; + } + final @Nullable String isolation = isolationScope.getScreen(); + if (isolation != null) { + return isolation; + } + return globalScope.getScreen(); + } + + @Override + public void setScreen(@Nullable String screen) { + getDefaultWriteScope().setScreen(screen); + } + + @Override + public @Nullable Request getRequest() { + final @Nullable Request current = scope.getRequest(); + if (current != null) { + return current; + } + final @Nullable Request isolation = isolationScope.getRequest(); + if (isolation != null) { + return isolation; + } + return globalScope.getRequest(); + } + + @Override + public void setRequest(@Nullable Request request) { + getDefaultWriteScope().setRequest(request); + } + + @Override + public @NotNull List getFingerprint() { + final @Nullable List current = scope.getFingerprint(); + if (!current.isEmpty()) { + return current; + } + final @Nullable List isolation = isolationScope.getFingerprint(); + if (!isolation.isEmpty()) { + return isolation; + } + return globalScope.getFingerprint(); + } + + @Override + public void setFingerprint(@NotNull List fingerprint) { + getDefaultWriteScope().setFingerprint(fingerprint); + } + + @Override + public @NotNull Queue getBreadcrumbs() { + final @NotNull List allBreadcrumbs = new ArrayList<>(); + allBreadcrumbs.addAll(globalScope.getBreadcrumbs()); + allBreadcrumbs.addAll(isolationScope.getBreadcrumbs()); + allBreadcrumbs.addAll(scope.getBreadcrumbs()); + Collections.sort(allBreadcrumbs); + + // TODO test oldest are removed first + final @NotNull Queue breadcrumbs = + createBreadcrumbsList(scope.getOptions().getMaxBreadcrumbs()); + breadcrumbs.addAll(allBreadcrumbs); + + return breadcrumbs; + } + + /** + * Creates a breadcrumb list with the max number of breadcrumbs + * + * @param maxBreadcrumb the max number of breadcrumbs + * @return the breadcrumbs queue + */ + // TODO copied from Scope, should reuse instead + private @NotNull Queue createBreadcrumbsList(final int maxBreadcrumb) { + return SynchronizedQueue.synchronizedQueue(new CircularFifoQueue<>(maxBreadcrumb)); + } + + @Override + public void addBreadcrumb(@NotNull Breadcrumb breadcrumb, @Nullable Hint hint) { + getDefaultWriteScope().addBreadcrumb(breadcrumb, hint); + } + + @Override + public void addBreadcrumb(@NotNull Breadcrumb breadcrumb) { + getDefaultWriteScope().addBreadcrumb(breadcrumb); + } + + @Override + public void clearBreadcrumbs() { + getDefaultWriteScope().clearBreadcrumbs(); + } + + @Override + public void clearTransaction() { + getDefaultWriteScope().clearTransaction(); + } + + @Override + public @Nullable ITransaction getTransaction() { + final @Nullable ITransaction current = scope.getTransaction(); + if (current != null) { + return current; + } + final @Nullable ITransaction isolation = isolationScope.getTransaction(); + if (isolation != null) { + return isolation; + } + return globalScope.getTransaction(); + } + + @Override + public void clear() { + getDefaultWriteScope().clear(); + } + + @Override + public @NotNull Map getTags() { + final @NotNull Map allTags = new ConcurrentHashMap<>(); + allTags.putAll(globalScope.getTags()); + allTags.putAll(isolationScope.getTags()); + allTags.putAll(scope.getTags()); + return allTags; + } + + @Override + public void setTag(@NotNull String key, @NotNull String value) { + getDefaultWriteScope().setTag(key, value); + } + + @Override + public void removeTag(@NotNull String key) { + getDefaultWriteScope().removeTag(key); + } + + @Override + public @NotNull Map getExtras() { + final @NotNull Map allTags = new ConcurrentHashMap<>(); + allTags.putAll(globalScope.getExtras()); + allTags.putAll(isolationScope.getExtras()); + allTags.putAll(scope.getExtras()); + return allTags; + } + + @Override + public void setExtra(@NotNull String key, @NotNull String value) { + getDefaultWriteScope().setExtra(key, value); + } + + @Override + public void removeExtra(@NotNull String key) { + getDefaultWriteScope().removeExtra(key); + } + + @Override + public @NotNull Contexts getContexts() { + return new CombinedContextsView( + globalScope.getContexts(), + isolationScope.getContexts(), + scope.getContexts(), + getOptions().getDefaultScopeType()); + } + + @Override + public void setContexts(@NotNull String key, @NotNull Object value) { + getDefaultWriteScope().setContexts(key, value); + } + + @Override + public void setContexts(@NotNull String key, @NotNull Boolean value) { + getDefaultWriteScope().setContexts(key, value); + } + + @Override + public void setContexts(@NotNull String key, @NotNull String value) { + getDefaultWriteScope().setContexts(key, value); + } + + @Override + public void setContexts(@NotNull String key, @NotNull Number value) { + getDefaultWriteScope().setContexts(key, value); + } + + @Override + public void setContexts(@NotNull String key, @NotNull Collection value) { + getDefaultWriteScope().setContexts(key, value); + } + + @Override + public void setContexts(@NotNull String key, @NotNull Object[] value) { + getDefaultWriteScope().setContexts(key, value); + } + + @Override + public void setContexts(@NotNull String key, @NotNull Character value) { + getDefaultWriteScope().setContexts(key, value); + } + + @Override + public void removeContexts(@NotNull String key) { + getDefaultWriteScope().removeContexts(key); + } + + private @NotNull IScope getDefaultWriteScope() { + if (ScopeType.CURRENT.equals(getOptions().getDefaultScopeType())) { + return scope; + } + if (ScopeType.ISOLATION.equals(getOptions().getDefaultScopeType())) { + return isolationScope; + } + return globalScope; + } + + @Override + public @NotNull List getAttachments() { + final @NotNull List allAttachments = new CopyOnWriteArrayList<>(); + allAttachments.addAll(globalScope.getAttachments()); + allAttachments.addAll(isolationScope.getAttachments()); + allAttachments.addAll(scope.getAttachments()); + return allAttachments; + } + + @Override + public void addAttachment(@NotNull Attachment attachment) { + getDefaultWriteScope().addAttachment(attachment); + } + + @Override + public void clearAttachments() { + getDefaultWriteScope().clearAttachments(); + } + + @Override + public @NotNull List getEventProcessors() { + // TODO mechanism for ordering event processors + final @NotNull List allEventProcessors = new CopyOnWriteArrayList<>(); + allEventProcessors.addAll(globalScope.getEventProcessors()); + allEventProcessors.addAll(isolationScope.getEventProcessors()); + allEventProcessors.addAll(scope.getEventProcessors()); + return allEventProcessors; + } + + @Override + public void addEventProcessor(@NotNull EventProcessor eventProcessor) { + getDefaultWriteScope().addEventProcessor(eventProcessor); + } + + @Override + public @Nullable Session withSession(Scope.@NotNull IWithSession sessionCallback) { + return getDefaultWriteScope().withSession(sessionCallback); + } + + @Override + public @Nullable Scope.SessionPair startSession() { + return getDefaultWriteScope().startSession(); + } + + @Override + public @Nullable Session endSession() { + return getDefaultWriteScope().endSession(); + } + + @Override + public void withTransaction(Scope.@NotNull IWithTransaction callback) { + getDefaultWriteScope().withTransaction(callback); + } + + @Override + public @NotNull SentryOptions getOptions() { + return scope.getOptions(); + } + + @Override + public @Nullable Session getSession() { + final @Nullable Session current = scope.getSession(); + if (current != null) { + return current; + } + final @Nullable Session isolation = isolationScope.getSession(); + if (isolation != null) { + return isolation; + } + return globalScope.getSession(); + } + + @Override + public void setPropagationContext(@NotNull PropagationContext propagationContext) { + getDefaultWriteScope().setPropagationContext(propagationContext); + } + + @Override + public @NotNull PropagationContext getPropagationContext() { + return getDefaultWriteScope().getPropagationContext(); + } + + @Override + public @NotNull PropagationContext withPropagationContext( + Scope.@NotNull IWithPropagationContext callback) { + return getDefaultWriteScope().withPropagationContext(callback); + } + + @Override + public @NotNull IScope clone() { + // TODO just return a new CombinedScopeView with forked scope? + return getDefaultWriteScope().clone(); + } + + @Override + public void setLastEventId(@NotNull SentryId lastEventId) { + globalScope.setLastEventId(lastEventId); + isolationScope.setLastEventId(lastEventId); + scope.setLastEventId(lastEventId); + } + + @Override + public @NotNull SentryId getLastEventId() { + return globalScope.getLastEventId(); + } + + @Override + public void bindClient(@NotNull ISentryClient client) { + getDefaultWriteScope().bindClient(client); + } + + @Override + public @NotNull ISentryClient getClient() { + // TODO checking for noop here doesn't allow disabling via client, is that ok? + final @Nullable ISentryClient current = scope.getClient(); + if (!(current instanceof NoOpSentryClient)) { + return current; + } + final @Nullable ISentryClient isolation = isolationScope.getClient(); + if (!(isolation instanceof NoOpSentryClient)) { + return isolation; + } + return globalScope.getClient(); + } + + @Override + public void assignTraceContext(@NotNull SentryEvent event) { + globalScope.assignTraceContext(event); + } + + @Override + public void setSpanContext( + @NotNull Throwable throwable, @NotNull ISpan span, @NotNull String transactionName) { + globalScope.setSpanContext(throwable, span, transactionName); + } +} diff --git a/sentry/src/main/java/io/sentry/Scopes.java b/sentry/src/main/java/io/sentry/Scopes.java index c37dddfd31..daf143ba66 100644 --- a/sentry/src/main/java/io/sentry/Scopes.java +++ b/sentry/src/main/java/io/sentry/Scopes.java @@ -166,7 +166,7 @@ public boolean isEnabled() { } private void assignTraceContext(final @NotNull SentryEvent event) { - Sentry.getGlobalScope().assignTraceContext(event); + getCombinedScopeView().assignTraceContext(event); } private IScope buildLocalScope( @@ -363,8 +363,7 @@ public void endSession() { } private IScope getCombinedScopeView() { - // TODO combine global, isolation and current scope - return scope; + return new CombinedScopeView(getGlobalScope(), isolationScope, scope); } @Override @@ -424,7 +423,7 @@ public void addBreadcrumb(final @NotNull Breadcrumb breadcrumb, final @Nullable } else if (breadcrumb == null) { options.getLogger().log(SentryLevel.WARNING, "addBreadcrumb called with null parameter."); } else { - getDefaultWriteScope().addBreadcrumb(breadcrumb, hint); + getCombinedScopeView().addBreadcrumb(breadcrumb, hint); } } @@ -467,7 +466,7 @@ public void setLevel(final @Nullable SentryLevel level) { .getLogger() .log(SentryLevel.WARNING, "Instance is disabled and this 'setLevel' call is a no-op."); } else { - getDefaultWriteScope().setLevel(level); + getCombinedScopeView().setLevel(level); } } @@ -480,7 +479,7 @@ public void setTransaction(final @Nullable String transaction) { SentryLevel.WARNING, "Instance is disabled and this 'setTransaction' call is a no-op."); } else if (transaction != null) { - getDefaultWriteScope().setTransaction(transaction); + getCombinedScopeView().setTransaction(transaction); } else { options.getLogger().log(SentryLevel.WARNING, "Transaction cannot be null"); } @@ -493,7 +492,7 @@ public void setUser(final @Nullable User user) { .getLogger() .log(SentryLevel.WARNING, "Instance is disabled and this 'setUser' call is a no-op."); } else { - getDefaultWriteScope().setUser(user); + getCombinedScopeView().setUser(user); } } @@ -508,7 +507,7 @@ public void setFingerprint(final @NotNull List fingerprint) { } else if (fingerprint == null) { options.getLogger().log(SentryLevel.WARNING, "setFingerprint called with null parameter."); } else { - getDefaultWriteScope().setFingerprint(fingerprint); + getCombinedScopeView().setFingerprint(fingerprint); } } @@ -521,7 +520,7 @@ public void clearBreadcrumbs() { SentryLevel.WARNING, "Instance is disabled and this 'clearBreadcrumbs' call is a no-op."); } else { - getDefaultWriteScope().clearBreadcrumbs(); + getCombinedScopeView().clearBreadcrumbs(); } } @@ -534,7 +533,7 @@ public void setTag(final @NotNull String key, final @NotNull String value) { } else if (key == null || value == null) { options.getLogger().log(SentryLevel.WARNING, "setTag called with null parameter."); } else { - getDefaultWriteScope().setTag(key, value); + getCombinedScopeView().setTag(key, value); } } @@ -547,7 +546,7 @@ public void removeTag(final @NotNull String key) { } else if (key == null) { options.getLogger().log(SentryLevel.WARNING, "removeTag called with null parameter."); } else { - getDefaultWriteScope().removeTag(key); + getCombinedScopeView().removeTag(key); } } @@ -560,7 +559,7 @@ public void setExtra(final @NotNull String key, final @NotNull String value) { } else if (key == null || value == null) { options.getLogger().log(SentryLevel.WARNING, "setExtra called with null parameter."); } else { - getDefaultWriteScope().setExtra(key, value); + getCombinedScopeView().setExtra(key, value); } } @@ -573,14 +572,12 @@ public void removeExtra(final @NotNull String key) { } else if (key == null) { options.getLogger().log(SentryLevel.WARNING, "removeExtra called with null parameter."); } else { - getDefaultWriteScope().removeExtra(key); + getCombinedScopeView().removeExtra(key); } } private void updateLastEventId(final @NotNull SentryId lastEventId) { - scope.setLastEventId(lastEventId); - isolationScope.setLastEventId(lastEventId); - getGlobalScope().setLastEventId(lastEventId); + getCombinedScopeView().setLastEventId(lastEventId); } // TODO add to IScopes interface @@ -592,14 +589,9 @@ private void updateLastEventId(final @NotNull SentryId lastEventId) { @Override public @NotNull SentryId getLastEventId() { - // TODO read all scopes here / read default scope? - // returning scope.lastEventId isn't ideal because changed to child scope are not stored in - // there - return getGlobalScope().getLastEventId(); + return getCombinedScopeView().getLastEventId(); } - // TODO needs to be deprecated because there's no more stack - // TODO needs to return a lifecycle token @Override public ISentryLifecycleToken pushScope() { if (!isEnabled()) { @@ -698,10 +690,10 @@ public void bindClient(final @NotNull ISentryClient client) { } else { if (client != null) { options.getLogger().log(SentryLevel.DEBUG, "New client bound to scope."); - getDefaultWriteScope().bindClient(client); + getCombinedScopeView().bindClient(client); } else { options.getLogger().log(SentryLevel.DEBUG, "NoOp client bound to scope."); - getDefaultWriteScope().bindClient(NoOpSentryClient.getInstance()); + getCombinedScopeView().bindClient(NoOpSentryClient.getInstance()); } } } @@ -879,7 +871,7 @@ public void setSpanContext( final @NotNull Throwable throwable, final @NotNull ISpan span, final @NotNull String transactionName) { - Sentry.getGlobalScope().setSpanContext(throwable, span, transactionName); + getCombinedScopeView().setSpanContext(throwable, span, transactionName); } // // TODO this seems unused @@ -908,7 +900,7 @@ public void setSpanContext( .getLogger() .log(SentryLevel.WARNING, "Instance is disabled and this 'getSpan' call is a no-op."); } else { - span = getScope().getSpan(); + span = getCombinedScopeView().getSpan(); } return span; } @@ -924,7 +916,7 @@ public void setSpanContext( SentryLevel.WARNING, "Instance is disabled and this 'getTransaction' call is a no-op."); } else { - span = getScope().getTransaction(); + span = getCombinedScopeView().getTransaction(); } return span; } diff --git a/sentry/src/main/java/io/sentry/Sentry.java b/sentry/src/main/java/io/sentry/Sentry.java index 090cba0d66..42ccc3cf63 100644 --- a/sentry/src/main/java/io/sentry/Sentry.java +++ b/sentry/src/main/java/io/sentry/Sentry.java @@ -121,7 +121,7 @@ private Sentry() {} @ApiStatus.Internal // exposed for the coroutines integration in SentryContext @Deprecated - @SuppressWarnings({"deprecation"}) + @SuppressWarnings({"deprecation", "InlineMeSuggester"}) public static @NotNull ISentryLifecycleToken setCurrentHub(final @NotNull IHub hub) { return setCurrentScopes(hub); } diff --git a/sentry/src/main/java/io/sentry/protocol/Contexts.java b/sentry/src/main/java/io/sentry/protocol/Contexts.java index 21be9fd8a5..aa157e665e 100644 --- a/sentry/src/main/java/io/sentry/protocol/Contexts.java +++ b/sentry/src/main/java/io/sentry/protocol/Contexts.java @@ -1,5 +1,6 @@ package io.sentry.protocol; +import com.jakewharton.nopen.annotation.Open; import io.sentry.ILogger; import io.sentry.JsonDeserializer; import io.sentry.JsonObjectReader; @@ -17,7 +18,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public final class Contexts extends ConcurrentHashMap implements JsonSerializable { +@Open +public class Contexts extends ConcurrentHashMap implements JsonSerializable { private static final long serialVersionUID = 252445813254943011L; /** Response lock, Ops should be atomic */ From ae93e336ef1ed057a3f58f2f1c019d7d4a1de981 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Fri, 12 Apr 2024 13:01:25 +0200 Subject: [PATCH 26/28] Use new API for CRONS integrations --- .../io/sentry/log4j2/SentryAppenderTest.kt | 1 + sentry-quartz/api/sentry-quartz.api | 1 + .../io/sentry/quartz/SentryJobListener.java | 8 ++- .../jakarta/checkin/SentryCheckInAdvice.java | 5 +- .../spring/jakarta/SentryCheckInAdviceTest.kt | 46 +++++++++-------- .../spring/checkin/SentryCheckInAdvice.java | 5 +- .../sentry/spring/SentryCheckInAdviceTest.kt | 50 ++++++++++--------- .../java/io/sentry/util/CheckInUtils.java | 6 +-- .../java/io/sentry/util/CheckInUtilsTest.kt | 45 ++++++++++++----- 9 files changed, 102 insertions(+), 65 deletions(-) diff --git a/sentry-log4j2/src/test/kotlin/io/sentry/log4j2/SentryAppenderTest.kt b/sentry-log4j2/src/test/kotlin/io/sentry/log4j2/SentryAppenderTest.kt index 3786555a61..2713bb7f17 100644 --- a/sentry-log4j2/src/test/kotlin/io/sentry/log4j2/SentryAppenderTest.kt +++ b/sentry-log4j2/src/test/kotlin/io/sentry/log4j2/SentryAppenderTest.kt @@ -78,6 +78,7 @@ class SentryAppenderTest { @BeforeTest fun `clear MDC`() { ThreadContext.clearAll() + Sentry.close() } @Test diff --git a/sentry-quartz/api/sentry-quartz.api b/sentry-quartz/api/sentry-quartz.api index 23fce49e7d..21ca2abca6 100644 --- a/sentry-quartz/api/sentry-quartz.api +++ b/sentry-quartz/api/sentry-quartz.api @@ -5,6 +5,7 @@ public final class io/sentry/quartz/BuildConfig { public final class io/sentry/quartz/SentryJobListener : org/quartz/JobListener { public static final field SENTRY_CHECK_IN_ID_KEY Ljava/lang/String; + public static final field SENTRY_LIFECYCLE_TOKEN_KEY Ljava/lang/String; public static final field SENTRY_SLUG_KEY Ljava/lang/String; public fun ()V public fun (Lio/sentry/IScopes;)V diff --git a/sentry-quartz/src/main/java/io/sentry/quartz/SentryJobListener.java b/sentry-quartz/src/main/java/io/sentry/quartz/SentryJobListener.java index f9c22022cc..03f1acbbed 100644 --- a/sentry-quartz/src/main/java/io/sentry/quartz/SentryJobListener.java +++ b/sentry-quartz/src/main/java/io/sentry/quartz/SentryJobListener.java @@ -4,10 +4,12 @@ import io.sentry.CheckIn; import io.sentry.CheckInStatus; import io.sentry.IScopes; +import io.sentry.ISentryLifecycleToken; import io.sentry.ScopesAdapter; import io.sentry.SentryIntegrationPackageStorage; import io.sentry.SentryLevel; import io.sentry.protocol.SentryId; +import io.sentry.util.LifecycleHelper; import io.sentry.util.Objects; import io.sentry.util.TracingUtils; import org.jetbrains.annotations.ApiStatus; @@ -23,6 +25,7 @@ public final class SentryJobListener implements JobListener { public static final String SENTRY_CHECK_IN_ID_KEY = "sentry-checkin-id"; public static final String SENTRY_SLUG_KEY = "sentry-slug"; + public static final String SENTRY_LIFECYCLE_TOKEN_KEY = "sentry-lifecycle"; private final @NotNull IScopes scopes; @@ -49,13 +52,14 @@ public void jobToBeExecuted(final @NotNull JobExecutionContext context) { if (maybeSlug == null) { return; } - scopes.pushScope(); + final @NotNull ISentryLifecycleToken lifecycleToken = scopes.pushIsolationScope(); TracingUtils.startNewTrace(scopes); final @NotNull String slug = maybeSlug; final @NotNull CheckIn checkIn = new CheckIn(slug, CheckInStatus.IN_PROGRESS); final @NotNull SentryId checkInId = scopes.captureCheckIn(checkIn); context.put(SENTRY_CHECK_IN_ID_KEY, checkInId); context.put(SENTRY_SLUG_KEY, slug); + context.put(SENTRY_LIFECYCLE_TOKEN_KEY, lifecycleToken); } catch (Throwable t) { scopes .getOptions() @@ -103,7 +107,7 @@ public void jobWasExecuted(JobExecutionContext context, JobExecutionException jo .getLogger() .log(SentryLevel.ERROR, "Unable to capture check-in in jobWasExecuted.", t); } finally { - scopes.popScope(); + LifecycleHelper.close(context.get(SENTRY_LIFECYCLE_TOKEN_KEY)); } } } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/checkin/SentryCheckInAdvice.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/checkin/SentryCheckInAdvice.java index 4a366a8b01..e51647cba8 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/checkin/SentryCheckInAdvice.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/checkin/SentryCheckInAdvice.java @@ -5,6 +5,7 @@ import io.sentry.CheckInStatus; import io.sentry.DateUtils; import io.sentry.IScopes; +import io.sentry.ISentryLifecycleToken; import io.sentry.ScopesAdapter; import io.sentry.SentryLevel; import io.sentry.protocol.SentryId; @@ -86,7 +87,7 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl return invocation.proceed(); } - scopes.pushScope(); + final @NotNull ISentryLifecycleToken lifecycleToken = scopes.pushIsolationScope(); TracingUtils.startNewTrace(scopes); @Nullable SentryId checkInId = null; @@ -106,7 +107,7 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl CheckIn checkIn = new CheckIn(checkInId, monitorSlug, status); checkIn.setDuration(DateUtils.millisToSeconds(System.currentTimeMillis() - startTime)); scopes.captureCheckIn(checkIn); - scopes.popScope(); + lifecycleToken.close(); } } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryCheckInAdviceTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryCheckInAdviceTest.kt index 5d093f50f1..e87b5f5b26 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryCheckInAdviceTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryCheckInAdviceTest.kt @@ -3,6 +3,7 @@ package io.sentry.spring.jakarta import io.sentry.CheckIn import io.sentry.CheckInStatus import io.sentry.IScopes +import io.sentry.ISentryLifecycleToken import io.sentry.Sentry import io.sentry.SentryOptions import io.sentry.protocol.SentryId @@ -56,10 +57,13 @@ class SentryCheckInAdviceTest { @Autowired lateinit var scopes: IScopes + val lifecycleToken = mock() + @BeforeTest fun setup() { reset(scopes) whenever(scopes.options).thenReturn(SentryOptions()) + whenever(scopes.pushIsolationScope()).thenReturn(lifecycleToken) } @Test @@ -79,10 +83,10 @@ class SentryCheckInAdviceTest { assertEquals("monitor_slug_1", doneCheckIn.monitorSlug) assertEquals(CheckInStatus.OK.apiName(), doneCheckIn.status) - val order = inOrder(scopes) - order.verify(scopes).pushScope() + val order = inOrder(scopes, lifecycleToken) + order.verify(scopes).pushIsolationScope() order.verify(scopes, times(2)).captureCheckIn(any()) - order.verify(scopes).popScope() + order.verify(lifecycleToken).close() } @Test @@ -103,10 +107,10 @@ class SentryCheckInAdviceTest { assertEquals("monitor_slug_1e", doneCheckIn.monitorSlug) assertEquals(CheckInStatus.ERROR.apiName(), doneCheckIn.status) - val order = inOrder(scopes) - order.verify(scopes).pushScope() + val order = inOrder(scopes, lifecycleToken) + order.verify(scopes).pushIsolationScope() order.verify(scopes, times(2)).captureCheckIn(any()) - order.verify(scopes).popScope() + order.verify(lifecycleToken).close() } @Test @@ -123,10 +127,10 @@ class SentryCheckInAdviceTest { assertEquals(CheckInStatus.OK.apiName(), doneCheckIn.status) assertNotNull(doneCheckIn.duration) - val order = inOrder(scopes) - order.verify(scopes).pushScope() + val order = inOrder(scopes, lifecycleToken) + order.verify(scopes).pushIsolationScope() order.verify(scopes).captureCheckIn(any()) - order.verify(scopes).popScope() + order.verify(lifecycleToken).close() } @Test @@ -144,10 +148,10 @@ class SentryCheckInAdviceTest { assertEquals(CheckInStatus.ERROR.apiName(), doneCheckIn.status) assertNotNull(doneCheckIn.duration) - val order = inOrder(scopes) - order.verify(scopes).pushScope() + val order = inOrder(scopes, lifecycleToken) + order.verify(scopes).pushIsolationScope() order.verify(scopes).captureCheckIn(any()) - order.verify(scopes).popScope() + order.verify(lifecycleToken).close() } @Test @@ -178,10 +182,10 @@ class SentryCheckInAdviceTest { assertEquals(CheckInStatus.OK.apiName(), doneCheckIn.status) assertNotNull(doneCheckIn.duration) - val order = inOrder(scopes) - order.verify(scopes).pushScope() + val order = inOrder(scopes, lifecycleToken) + order.verify(scopes).pushIsolationScope() order.verify(scopes).captureCheckIn(any()) - order.verify(scopes).popScope() + order.verify(lifecycleToken).close() } @Test @@ -198,10 +202,10 @@ class SentryCheckInAdviceTest { assertEquals(CheckInStatus.OK.apiName(), doneCheckIn.status) assertNotNull(doneCheckIn.duration) - val order = inOrder(scopes) - order.verify(scopes).pushScope() + val order = inOrder(scopes, lifecycleToken) + order.verify(scopes).pushIsolationScope() order.verify(scopes).captureCheckIn(any()) - order.verify(scopes).popScope() + order.verify(lifecycleToken).close() } @Test @@ -218,10 +222,10 @@ class SentryCheckInAdviceTest { assertEquals(CheckInStatus.OK.apiName(), doneCheckIn.status) assertNotNull(doneCheckIn.duration) - val order = inOrder(scopes) - order.verify(scopes).pushScope() + val order = inOrder(scopes, lifecycleToken) + order.verify(scopes).pushIsolationScope() order.verify(scopes).captureCheckIn(any()) - order.verify(scopes).popScope() + order.verify(lifecycleToken).close() } @Configuration diff --git a/sentry-spring/src/main/java/io/sentry/spring/checkin/SentryCheckInAdvice.java b/sentry-spring/src/main/java/io/sentry/spring/checkin/SentryCheckInAdvice.java index edae74c2ac..9e59093b16 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/checkin/SentryCheckInAdvice.java +++ b/sentry-spring/src/main/java/io/sentry/spring/checkin/SentryCheckInAdvice.java @@ -5,6 +5,7 @@ import io.sentry.CheckInStatus; import io.sentry.DateUtils; import io.sentry.IScopes; +import io.sentry.ISentryLifecycleToken; import io.sentry.ScopesAdapter; import io.sentry.SentryLevel; import io.sentry.protocol.SentryId; @@ -89,7 +90,7 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl return invocation.proceed(); } - scopes.pushScope(); + final @NotNull ISentryLifecycleToken lifecycleToken = scopes.pushIsolationScope(); TracingUtils.startNewTrace(scopes); @Nullable SentryId checkInId = null; @@ -109,7 +110,7 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl CheckIn checkIn = new CheckIn(checkInId, monitorSlug, status); checkIn.setDuration(DateUtils.millisToSeconds(System.currentTimeMillis() - startTime)); scopes.captureCheckIn(checkIn); - scopes.popScope(); + lifecycleToken.close(); } } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/SentryCheckInAdviceTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/SentryCheckInAdviceTest.kt index 23807e1fd9..57bd293756 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/SentryCheckInAdviceTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/SentryCheckInAdviceTest.kt @@ -3,6 +3,7 @@ package io.sentry.spring import io.sentry.CheckIn import io.sentry.CheckInStatus import io.sentry.IScopes +import io.sentry.ISentryLifecycleToken import io.sentry.Sentry import io.sentry.SentryOptions import io.sentry.protocol.SentryId @@ -57,10 +58,13 @@ class SentryCheckInAdviceTest { @Autowired lateinit var scopes: IScopes + val lifecycleToken = mock() + @BeforeTest fun setup() { reset(scopes) whenever(scopes.options).thenReturn(SentryOptions()) + whenever(scopes.pushIsolationScope()).thenReturn(lifecycleToken) } @Test @@ -80,10 +84,10 @@ class SentryCheckInAdviceTest { assertEquals("monitor_slug_1", doneCheckIn.monitorSlug) assertEquals(CheckInStatus.OK.apiName(), doneCheckIn.status) - val order = inOrder(scopes) - order.verify(scopes).pushScope() + val order = inOrder(scopes, lifecycleToken) + order.verify(scopes).pushIsolationScope() order.verify(scopes, times(2)).captureCheckIn(any()) - order.verify(scopes).popScope() + order.verify(lifecycleToken).close() } @Test @@ -104,10 +108,10 @@ class SentryCheckInAdviceTest { assertEquals("monitor_slug_1e", doneCheckIn.monitorSlug) assertEquals(CheckInStatus.ERROR.apiName(), doneCheckIn.status) - val order = inOrder(scopes) - order.verify(scopes).pushScope() + val order = inOrder(scopes, lifecycleToken) + order.verify(scopes).pushIsolationScope() order.verify(scopes, times(2)).captureCheckIn(any()) - order.verify(scopes).popScope() + order.verify(lifecycleToken).close() } @Test @@ -124,10 +128,10 @@ class SentryCheckInAdviceTest { assertEquals(CheckInStatus.OK.apiName(), doneCheckIn.status) assertNotNull(doneCheckIn.duration) - val order = inOrder(scopes) - order.verify(scopes).pushScope() + val order = inOrder(scopes, lifecycleToken) + order.verify(scopes).pushIsolationScope() order.verify(scopes).captureCheckIn(any()) - order.verify(scopes).popScope() + order.verify(lifecycleToken).close() } @Test @@ -145,10 +149,10 @@ class SentryCheckInAdviceTest { assertEquals(CheckInStatus.ERROR.apiName(), doneCheckIn.status) assertNotNull(doneCheckIn.duration) - val order = inOrder(scopes) - order.verify(scopes).pushScope() + val order = inOrder(scopes, lifecycleToken) + order.verify(scopes).pushIsolationScope() order.verify(scopes).captureCheckIn(any()) - order.verify(scopes).popScope() + order.verify(lifecycleToken).close() } @Test @@ -160,9 +164,9 @@ class SentryCheckInAdviceTest { assertEquals(1, result) assertEquals(0, checkInCaptor.allValues.size) - verify(scopes, never()).pushScope() + verify(scopes, never()).pushIsolationScope() verify(scopes, never()).captureCheckIn(any()) - verify(scopes, never()).popScope() + verify(lifecycleToken, never()).close() } @Test @@ -179,10 +183,10 @@ class SentryCheckInAdviceTest { assertEquals(CheckInStatus.OK.apiName(), doneCheckIn.status) assertNotNull(doneCheckIn.duration) - val order = inOrder(scopes) - order.verify(scopes).pushScope() + val order = inOrder(scopes, lifecycleToken) + order.verify(scopes).pushIsolationScope() order.verify(scopes).captureCheckIn(any()) - order.verify(scopes).popScope() + order.verify(lifecycleToken).close() } @Test @@ -199,10 +203,10 @@ class SentryCheckInAdviceTest { assertEquals(CheckInStatus.OK.apiName(), doneCheckIn.status) assertNotNull(doneCheckIn.duration) - val order = inOrder(scopes) - order.verify(scopes).pushScope() + val order = inOrder(scopes, lifecycleToken) + order.verify(scopes).pushIsolationScope() order.verify(scopes).captureCheckIn(any()) - order.verify(scopes).popScope() + order.verify(lifecycleToken).close() } @Test @@ -219,10 +223,10 @@ class SentryCheckInAdviceTest { assertEquals(CheckInStatus.OK.apiName(), doneCheckIn.status) assertNotNull(doneCheckIn.duration) - val order = inOrder(scopes) - order.verify(scopes).pushScope() + val order = inOrder(scopes, lifecycleToken) + order.verify(scopes).pushIsolationScope() order.verify(scopes).captureCheckIn(any()) - order.verify(scopes).popScope() + order.verify(lifecycleToken).close() } @Configuration diff --git a/sentry/src/main/java/io/sentry/util/CheckInUtils.java b/sentry/src/main/java/io/sentry/util/CheckInUtils.java index 6719e24839..d42cf4edf4 100644 --- a/sentry/src/main/java/io/sentry/util/CheckInUtils.java +++ b/sentry/src/main/java/io/sentry/util/CheckInUtils.java @@ -4,6 +4,7 @@ import io.sentry.CheckInStatus; import io.sentry.DateUtils; import io.sentry.IScopes; +import io.sentry.ISentryLifecycleToken; import io.sentry.MonitorConfig; import io.sentry.Sentry; import io.sentry.protocol.SentryId; @@ -30,12 +31,11 @@ public static U withCheckIn( final @Nullable MonitorConfig monitorConfig, final @NotNull Callable callable) throws Exception { + final @NotNull ISentryLifecycleToken lifecycleToken = Sentry.pushIsolationScope(); final @NotNull IScopes scopes = Sentry.getCurrentScopes(); final long startTime = System.currentTimeMillis(); boolean didError = false; - // TODO fork instead - scopes.pushScope(); TracingUtils.startNewTrace(scopes); CheckIn inProgressCheckIn = new CheckIn(monitorSlug, CheckInStatus.IN_PROGRESS); @@ -53,7 +53,7 @@ public static U withCheckIn( CheckIn checkIn = new CheckIn(checkInId, monitorSlug, status); checkIn.setDuration(DateUtils.millisToSeconds(System.currentTimeMillis() - startTime)); scopes.captureCheckIn(checkIn); - scopes.popScope(); + lifecycleToken.close(); } } diff --git a/sentry/src/test/java/io/sentry/util/CheckInUtilsTest.kt b/sentry/src/test/java/io/sentry/util/CheckInUtilsTest.kt index 9f330348b0..7058083ac9 100644 --- a/sentry/src/test/java/io/sentry/util/CheckInUtilsTest.kt +++ b/sentry/src/test/java/io/sentry/util/CheckInUtilsTest.kt @@ -3,6 +3,7 @@ package io.sentry.util import io.sentry.CheckInStatus import io.sentry.HubScopesWrapper import io.sentry.IScopes +import io.sentry.ISentryLifecycleToken import io.sentry.MonitorConfig import io.sentry.MonitorSchedule import io.sentry.MonitorScheduleUnit @@ -58,16 +59,21 @@ class CheckInUtilsTest { fun `sends check-in for wrapped supplier`() { Mockito.mockStatic(Sentry::class.java).use { sentry -> val scopes = mock() + val lifecycleToken = mock() sentry.`when` { Sentry.getCurrentScopes() }.thenReturn(scopes) sentry.`when` { Sentry.getCurrentHub() }.thenReturn(HubScopesWrapper(scopes)) + sentry.`when` { Sentry.pushIsolationScope() }.then { + scopes.pushIsolationScope() + lifecycleToken + } whenever(scopes.options).thenReturn(SentryOptions()) val returnValue = CheckInUtils.withCheckIn("monitor-1") { return@withCheckIn "test1" } assertEquals("test1", returnValue) - inOrder(scopes) { - verify(scopes).pushScope() + inOrder(scopes, lifecycleToken) { + verify(scopes).pushIsolationScope() verify(scopes).configureScope(any()) verify(scopes).captureCheckIn( check { @@ -81,7 +87,7 @@ class CheckInUtilsTest { assertEquals(CheckInStatus.OK.apiName(), it.status) } ) - verify(scopes).popScope() + verify(lifecycleToken).close() } } } @@ -90,8 +96,13 @@ class CheckInUtilsTest { fun `sends check-in for wrapped supplier with exception`() { Mockito.mockStatic(Sentry::class.java).use { sentry -> val scopes = mock() + val lifecycleToken = mock() sentry.`when` { Sentry.getCurrentScopes() }.thenReturn(scopes) sentry.`when` { Sentry.getCurrentHub() }.thenReturn(HubScopesWrapper(scopes)) + sentry.`when` { Sentry.pushIsolationScope() }.then { + scopes.pushIsolationScope() + lifecycleToken + } try { CheckInUtils.withCheckIn("monitor-1") { @@ -102,8 +113,8 @@ class CheckInUtilsTest { assertEquals("thrown on purpose", e.message) } - inOrder(scopes) { - verify(scopes).pushScope() + inOrder(scopes, lifecycleToken) { + verify(scopes).pushIsolationScope() verify(scopes).configureScope(any()) verify(scopes).captureCheckIn( check { @@ -117,7 +128,7 @@ class CheckInUtilsTest { assertEquals(CheckInStatus.ERROR.apiName(), it.status) } ) - verify(scopes).popScope() + verify(lifecycleToken).close() } } } @@ -126,8 +137,13 @@ class CheckInUtilsTest { fun `sends check-in for wrapped supplier with upsert`() { Mockito.mockStatic(Sentry::class.java).use { sentry -> val scopes = mock() + val lifecycleToken = mock() sentry.`when` { Sentry.getCurrentScopes() }.thenReturn(scopes) sentry.`when` { Sentry.getCurrentHub() }.thenReturn(HubScopesWrapper(scopes)) + sentry.`when` { Sentry.pushIsolationScope() }.then { + scopes.pushIsolationScope() + lifecycleToken + } whenever(scopes.options).thenReturn(SentryOptions()) val monitorConfig = MonitorConfig(MonitorSchedule.interval(7, MonitorScheduleUnit.DAY)) val returnValue = CheckInUtils.withCheckIn("monitor-1", monitorConfig) { @@ -135,8 +151,8 @@ class CheckInUtilsTest { } assertEquals("test1", returnValue) - inOrder(scopes) { - verify(scopes).pushScope() + inOrder(scopes, lifecycleToken) { + verify(scopes).pushIsolationScope() verify(scopes).configureScope(any()) verify(scopes).captureCheckIn( check { @@ -151,7 +167,7 @@ class CheckInUtilsTest { assertEquals(CheckInStatus.OK.apiName(), it.status) } ) - verify(scopes).popScope() + verify(lifecycleToken).close() } } } @@ -160,8 +176,13 @@ class CheckInUtilsTest { fun `sends check-in for wrapped supplier with upsert and thresholds`() { Mockito.mockStatic(Sentry::class.java).use { sentry -> val scopes = mock() + val lifecycleToken = mock() sentry.`when` { Sentry.getCurrentScopes() }.thenReturn(scopes) sentry.`when` { Sentry.getCurrentHub() }.thenReturn(HubScopesWrapper(scopes)) + sentry.`when` { Sentry.pushIsolationScope() }.then { + scopes.pushIsolationScope() + lifecycleToken + } whenever(scopes.options).thenReturn(SentryOptions()) val monitorConfig = MonitorConfig(MonitorSchedule.interval(7, MonitorScheduleUnit.DAY)).apply { failureIssueThreshold = 10 @@ -172,8 +193,8 @@ class CheckInUtilsTest { } assertEquals("test1", returnValue) - inOrder(scopes) { - verify(scopes).pushScope() + inOrder(scopes, lifecycleToken) { + verify(scopes).pushIsolationScope() verify(scopes).configureScope(any()) verify(scopes).captureCheckIn( check { @@ -188,7 +209,7 @@ class CheckInUtilsTest { assertEquals(CheckInStatus.OK.apiName(), it.status) } ) - verify(scopes).popScope() + verify(lifecycleToken).close() } } } From b01298b7cb497afaa90a6460204753f90ea03d35 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Fri, 12 Apr 2024 14:03:52 +0200 Subject: [PATCH 27/28] Add lifecycle helper --- .../main/java/io/sentry/util/LifecycleHelper.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 sentry/src/main/java/io/sentry/util/LifecycleHelper.java diff --git a/sentry/src/main/java/io/sentry/util/LifecycleHelper.java b/sentry/src/main/java/io/sentry/util/LifecycleHelper.java new file mode 100644 index 0000000000..4a029f620c --- /dev/null +++ b/sentry/src/main/java/io/sentry/util/LifecycleHelper.java @@ -0,0 +1,15 @@ +package io.sentry.util; + +import io.sentry.ISentryLifecycleToken; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public final class LifecycleHelper { + + public static void close(final @Nullable Object tokenObject) { + if (tokenObject != null && tokenObject instanceof ISentryLifecycleToken) { + final @NotNull ISentryLifecycleToken token = (ISentryLifecycleToken) tokenObject; + token.close(); + } + } +} From b64e6884cf81762062d1b5447bacc5242928d2d8 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Fri, 12 Apr 2024 14:05:37 +0200 Subject: [PATCH 28/28] Change spring integrations to use new API --- .../api/sentry-spring-jakarta.api | 8 +-- .../spring/jakarta/SentrySpringFilter.java | 5 +- .../spring/jakarta/SentryTaskDecorator.java | 12 ++-- .../tracing/SentryTransactionAdvice.java | 5 +- .../webflux/AbstractSentryWebFilter.java | 6 -- .../spring/jakarta/webflux/ReactorUtils.java | 65 ++++++++----------- .../jakarta/webflux/SentryScheduleHook.java | 13 ++-- .../webflux/SentryWebExceptionHandler.java | 2 +- .../jakarta/webflux/SentryWebFilter.java | 2 +- ...entryWebFilterWithThreadLocalAccessor.java | 2 +- .../spring/jakarta/SentrySpringFilterTest.kt | 9 ++- .../spring/jakarta/SentryTaskDecoratorTest.kt | 18 ++--- .../tracing/SentryTransactionAdviceTest.kt | 8 ++- .../jakarta/webflux/ReactorUtilsTest.kt | 62 +++++++++--------- .../jakarta/webflux/SentryScheduleHookTest.kt | 18 ++--- .../webflux/SentryWebFluxTracingFilterTest.kt | 8 +-- .../io/sentry/spring/SentrySpringFilter.java | 5 +- .../io/sentry/spring/SentryTaskDecorator.java | 12 ++-- .../tracing/SentryTransactionAdvice.java | 5 +- .../spring/webflux/SentryScheduleHook.java | 13 ++-- .../spring/webflux/SentryWebFilter.java | 5 +- .../sentry/spring/SentrySpringFilterTest.kt | 9 ++- .../sentry/spring/SentryTaskDecoratorTest.kt | 18 ++--- .../tracing/SentryTransactionAdviceTest.kt | 8 ++- .../spring/webflux/SentryScheduleHookTest.kt | 18 ++--- .../webflux/SentryWebFluxTracingFilterTest.kt | 4 +- 26 files changed, 159 insertions(+), 181 deletions(-) diff --git a/sentry-spring-jakarta/api/sentry-spring-jakarta.api b/sentry-spring-jakarta/api/sentry-spring-jakarta.api index 13eb6033f9..156ab1aaee 100644 --- a/sentry-spring-jakarta/api/sentry-spring-jakarta.api +++ b/sentry-spring-jakarta/api/sentry-spring-jakarta.api @@ -282,10 +282,10 @@ public final class io/sentry/spring/jakarta/webflux/ReactorUtils { public fun ()V public static fun withSentry (Lreactor/core/publisher/Flux;)Lreactor/core/publisher/Flux; public static fun withSentry (Lreactor/core/publisher/Mono;)Lreactor/core/publisher/Mono; - public static fun withSentryHub (Lreactor/core/publisher/Flux;Lio/sentry/IScopes;)Lreactor/core/publisher/Flux; - public static fun withSentryHub (Lreactor/core/publisher/Mono;Lio/sentry/IScopes;)Lreactor/core/publisher/Mono; - public static fun withSentryNewMainHubClone (Lreactor/core/publisher/Flux;)Lreactor/core/publisher/Flux; - public static fun withSentryNewMainHubClone (Lreactor/core/publisher/Mono;)Lreactor/core/publisher/Mono; + public static fun withSentryForkedRoots (Lreactor/core/publisher/Flux;)Lreactor/core/publisher/Flux; + public static fun withSentryForkedRoots (Lreactor/core/publisher/Mono;)Lreactor/core/publisher/Mono; + public static fun withSentryScopes (Lreactor/core/publisher/Flux;Lio/sentry/IScopes;)Lreactor/core/publisher/Flux; + public static fun withSentryScopes (Lreactor/core/publisher/Mono;Lio/sentry/IScopes;)Lreactor/core/publisher/Mono; } public final class io/sentry/spring/jakarta/webflux/SentryReactorThreadLocalAccessor : io/micrometer/context/ThreadLocalAccessor { diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentrySpringFilter.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentrySpringFilter.java index be06d3d253..2e3561a982 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentrySpringFilter.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentrySpringFilter.java @@ -9,6 +9,7 @@ import io.sentry.EventProcessor; import io.sentry.Hint; import io.sentry.IScopes; +import io.sentry.ISentryLifecycleToken; import io.sentry.ScopesAdapter; import io.sentry.SentryEvent; import io.sentry.SentryLevel; @@ -60,7 +61,7 @@ protected void doFilterInternal( if (scopes.isEnabled()) { // request may qualify for caching request body, if so resolve cached request final HttpServletRequest request = resolveHttpServletRequest(servletRequest); - scopes.pushScope(); + final @NotNull ISentryLifecycleToken lifecycleToken = scopes.pushIsolationScope(); try { final Hint hint = new Hint(); hint.set(SPRING_REQUEST_FILTER_REQUEST, servletRequest); @@ -70,7 +71,7 @@ protected void doFilterInternal( configureScope(request); filterChain.doFilter(request, response); } finally { - scopes.popScope(); + lifecycleToken.close(); } } else { filterChain.doFilter(servletRequest, response); diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryTaskDecorator.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryTaskDecorator.java index c99abf3e21..943a7cc5ff 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryTaskDecorator.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/SentryTaskDecorator.java @@ -1,6 +1,7 @@ package io.sentry.spring.jakarta; import io.sentry.IScopes; +import io.sentry.ISentryLifecycleToken; import io.sentry.Sentry; import java.util.concurrent.Callable; import org.jetbrains.annotations.NotNull; @@ -14,18 +15,13 @@ */ public final class SentryTaskDecorator implements TaskDecorator { @Override - @SuppressWarnings("deprecation") + // TODO should there also be a SentryIsolatedTaskDecorator or similar that uses forkedScopes()? public @NotNull Runnable decorate(final @NotNull Runnable runnable) { - // TODO fork - final IScopes newHub = Sentry.getCurrentScopes().clone(); + final IScopes newScopes = Sentry.getCurrentScopes().forkedCurrentScope("spring.taskDecorator"); return () -> { - final IScopes oldState = Sentry.getCurrentScopes(); - Sentry.setCurrentScopes(newHub); - try { + try (final @NotNull ISentryLifecycleToken ignored = newScopes.makeCurrent()) { runnable.run(); - } finally { - Sentry.setCurrentScopes(oldState); } }; } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentryTransactionAdvice.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentryTransactionAdvice.java index f04b3dd7a6..da781afcd8 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentryTransactionAdvice.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentryTransactionAdvice.java @@ -2,6 +2,7 @@ import com.jakewharton.nopen.annotation.Open; import io.sentry.IScopes; +import io.sentry.ISentryLifecycleToken; import io.sentry.ITransaction; import io.sentry.ScopesAdapter; import io.sentry.SpanStatus; @@ -68,7 +69,7 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl } else { operation = "bean"; } - scopes.pushScope(); + final @NotNull ISentryLifecycleToken lifecycleToken = scopes.pushIsolationScope(); final TransactionOptions transactionOptions = new TransactionOptions(); transactionOptions.setBindToScope(true); final ITransaction transaction = @@ -86,7 +87,7 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl throw e; } finally { transaction.finish(); - scopes.popScope(); + lifecycleToken.close(); } } } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/AbstractSentryWebFilter.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/AbstractSentryWebFilter.java index 3321874dd8..5995728785 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/AbstractSentryWebFilter.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/AbstractSentryWebFilter.java @@ -68,10 +68,6 @@ protected void doFinally( if (transaction != null) { finishTransaction(serverWebExchange, transaction); } - if (requestHub.isEnabled()) { - // TODO close lifecycle token instead of popscope - requestHub.popScope(); - } Sentry.setCurrentScopes(NoOpScopes.getInstance()); } @@ -79,8 +75,6 @@ protected void doFirst( final @NotNull ServerWebExchange serverWebExchange, final @NotNull IScopes requestHub) { if (requestHub.isEnabled()) { serverWebExchange.getAttributes().put(SENTRY_SCOPES_KEY, requestHub); - // TODO fork instead - requestHub.pushScope(); final ServerHttpRequest request = serverWebExchange.getRequest(); final ServerHttpResponse response = serverWebExchange.getResponse(); diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/ReactorUtils.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/ReactorUtils.java index 41dd2e4bc0..cc7509129e 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/ReactorUtils.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/ReactorUtils.java @@ -8,8 +8,9 @@ import reactor.core.publisher.Mono; import reactor.util.context.Context; -// TODO deprecate and replace with "withSentryScopes" etc. @ApiStatus.Experimental +// TODO do we keep old methods around and deprecate them? +// TODO do we need to offer isolated variants? public final class ReactorUtils { /** @@ -20,27 +21,23 @@ public final class ReactorUtils { * enabled - having `io.micrometer:context-propagation:1.0.2+` (provided by Spring Boot 3.0.3+) - * having `io.projectreactor:reactor-core:3.5.3+` (provided by Spring Boot 3.0.3+) */ - @ApiStatus.Experimental - @SuppressWarnings("deprecation") public static Mono withSentry(final @NotNull Mono mono) { - final @NotNull IScopes oldHub = Sentry.getCurrentScopes(); - // TODO fork - final @NotNull IScopes clonedHub = oldHub.clone(); - return withSentryHub(mono, clonedHub); + final @NotNull IScopes oldScopes = Sentry.getCurrentScopes(); + final @NotNull IScopes forkedScopes = oldScopes.forkedCurrentScope("reactor.withSentry"); + return withSentryScopes(mono, forkedScopes); } /** - * Writes a new Sentry {@link IScopes} cloned from the main hub to the {@link Context} and uses + * Writes a new Sentry {@link IScopes} cloned from the main scopes to the {@link Context} and uses * {@link io.micrometer.context.ThreadLocalAccessor} to propagate it. * *

This requires - reactor.core.publisher.Hooks#enableAutomaticContextPropagation() to be * enabled - having `io.micrometer:context-propagation:1.0.2+` (provided by Spring Boot 3.0.3+) - * having `io.projectreactor:reactor-core:3.5.3+` (provided by Spring Boot 3.0.3+) */ - @ApiStatus.Experimental - public static Mono withSentryNewMainHubClone(final @NotNull Mono mono) { - final @NotNull IScopes hub = Sentry.cloneMainHub(); - return withSentryHub(mono, hub); + public static Mono withSentryForkedRoots(final @NotNull Mono mono) { + final @NotNull IScopes scopes = Sentry.forkedRootScopes("reactor"); + return withSentryScopes(mono, scopes); } /** @@ -51,17 +48,16 @@ public static Mono withSentryNewMainHubClone(final @NotNull Mono mono) * enabled - having `io.micrometer:context-propagation:1.0.2+` (provided by Spring Boot 3.0.3+) - * having `io.projectreactor:reactor-core:3.5.3+` (provided by Spring Boot 3.0.3+) */ - @ApiStatus.Experimental - public static Mono withSentryHub(final @NotNull Mono mono, final @NotNull IScopes hub) { + public static Mono withSentryScopes( + final @NotNull Mono mono, final @NotNull IScopes scopes) { /** - * WARNING: Cannot set the hub as current. It would be used by others to clone again causing - * shared hubs and scopes and thus leading to issues like unrelated breadcrumbs showing up in - * events. + * WARNING: Cannot set the scopes as current. It would be used by others to clone again causing + * shared scopes and thus leading to issues like unrelated breadcrumbs showing up in events. */ - // Sentry.setCurrentHub(clonedHub); + // Sentry.setCurrentScopes(forkedScopes); return Mono.deferContextual(ctx -> mono) - .contextWrite(Context.of(SentryReactorThreadLocalAccessor.KEY, hub)); + .contextWrite(Context.of(SentryReactorThreadLocalAccessor.KEY, scopes)); } /** @@ -72,28 +68,24 @@ public static Mono withSentryHub(final @NotNull Mono mono, final @NotN * enabled - having `io.micrometer:context-propagation:1.0.2+` (provided by Spring Boot 3.0.3+) - * having `io.projectreactor:reactor-core:3.5.3+` (provided by Spring Boot 3.0.3+) */ - @ApiStatus.Experimental - @SuppressWarnings("deprecation") public static Flux withSentry(final @NotNull Flux flux) { - final @NotNull IScopes oldHub = Sentry.getCurrentScopes(); - // TODO fork - final @NotNull IScopes clonedHub = oldHub.clone(); + final @NotNull IScopes oldScopes = Sentry.getCurrentScopes(); + final @NotNull IScopes forkedScopes = oldScopes.forkedCurrentScope("reactor.withSentry"); - return withSentryHub(flux, clonedHub); + return withSentryScopes(flux, forkedScopes); } /** - * Writes a new Sentry {@link IScopes} cloned from the main hub to the {@link Context} and uses + * Writes a new Sentry {@link IScopes} cloned from the main scopes to the {@link Context} and uses * {@link io.micrometer.context.ThreadLocalAccessor} to propagate it. * *

This requires - reactor.core.publisher.Hooks#enableAutomaticContextPropagation() to be * enabled - having `io.micrometer:context-propagation:1.0.2+` (provided by Spring Boot 3.0.3+) - * having `io.projectreactor:reactor-core:3.5.3+` (provided by Spring Boot 3.0.3+) */ - @ApiStatus.Experimental - public static Flux withSentryNewMainHubClone(final @NotNull Flux flux) { - final @NotNull IScopes hub = Sentry.cloneMainHub(); - return withSentryHub(flux, hub); + public static Flux withSentryForkedRoots(final @NotNull Flux flux) { + final @NotNull IScopes scopes = Sentry.forkedRootScopes("reactor"); + return withSentryScopes(flux, scopes); } /** @@ -104,16 +96,15 @@ public static Flux withSentryNewMainHubClone(final @NotNull Flux flux) * enabled - having `io.micrometer:context-propagation:1.0.2+` (provided by Spring Boot 3.0.3+) - * having `io.projectreactor:reactor-core:3.5.3+` (provided by Spring Boot 3.0.3+) */ - @ApiStatus.Experimental - public static Flux withSentryHub(final @NotNull Flux flux, final @NotNull IScopes hub) { + public static Flux withSentryScopes( + final @NotNull Flux flux, final @NotNull IScopes scopes) { /** - * WARNING: Cannot set the hub as current. It would be used by others to clone again causing - * shared hubs and scopes and thus leading to issues like unrelated breadcrumbs showing up in - * events. + * WARNING: Cannot set the scopes as current. It would be used by others to clone again causing + * shared scopes and thus leading to issues like unrelated breadcrumbs showing up in events. */ - // Sentry.setCurrentHub(clonedHub); + // Sentry.setCurrentScopes(forkedScopes); return Flux.deferContextual(ctx -> flux) - .contextWrite(Context.of(SentryReactorThreadLocalAccessor.KEY, hub)); + .contextWrite(Context.of(SentryReactorThreadLocalAccessor.KEY, scopes)); } } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryScheduleHook.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryScheduleHook.java index 882a0b268a..57a74732ea 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryScheduleHook.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryScheduleHook.java @@ -1,6 +1,7 @@ package io.sentry.spring.jakarta.webflux; import io.sentry.IScopes; +import io.sentry.ISentryLifecycleToken; import io.sentry.Sentry; import java.util.function.Function; import org.jetbrains.annotations.ApiStatus; @@ -8,23 +9,17 @@ /** * Hook meant to used with {@link reactor.core.scheduler.Schedulers#onScheduleHook(String, - * Function)} to configure Reactor to copy correct hub into the operating thread. + * Function)} to configure Reactor to copy correct scopes into the operating thread. */ @ApiStatus.Experimental public final class SentryScheduleHook implements Function { @Override - @SuppressWarnings("deprecation") public Runnable apply(final @NotNull Runnable runnable) { - // TODO fork instead - final IScopes newHub = Sentry.getCurrentScopes().clone(); + final IScopes newScopes = Sentry.getCurrentScopes().forkedCurrentScope("spring.scheduleHook"); return () -> { - final IScopes oldState = Sentry.getCurrentScopes(); - Sentry.setCurrentScopes(newHub); - try { + try (final @NotNull ISentryLifecycleToken ignored = newScopes.makeCurrent()) { runnable.run(); - } finally { - Sentry.setCurrentScopes(oldState); } }; } diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebExceptionHandler.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebExceptionHandler.java index 40b0ed4e87..15c73ab625 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebExceptionHandler.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebExceptionHandler.java @@ -40,7 +40,7 @@ public SentryWebExceptionHandler(final @NotNull IScopes scopes) { serverWebExchange.getAttributeOrDefault(SentryWebFilter.SENTRY_SCOPES_KEY, null); final @NotNull IScopes scopesToUse = requestScopes != null ? requestScopes : scopes; - return ReactorUtils.withSentryHub( + return ReactorUtils.withSentryScopes( Mono.just(ex) .map( it -> { diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebFilter.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebFilter.java index dab985eecf..0a6b767ec4 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebFilter.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebFilter.java @@ -28,7 +28,7 @@ public SentryWebFilter(final @NotNull IScopes scopes) { public Mono filter( final @NotNull ServerWebExchange serverWebExchange, final @NotNull WebFilterChain webFilterChain) { - @NotNull IScopes requestScopes = Sentry.cloneMainHub(); + @NotNull IScopes requestScopes = Sentry.forkedRootScopes("request.webflux"); final ServerHttpRequest request = serverWebExchange.getRequest(); final @Nullable ITransaction transaction = maybeStartTransaction(requestScopes, request); if (transaction != null) { diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebFilterWithThreadLocalAccessor.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebFilterWithThreadLocalAccessor.java index e760ef8f3e..c38e322731 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebFilterWithThreadLocalAccessor.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/webflux/SentryWebFilterWithThreadLocalAccessor.java @@ -26,7 +26,7 @@ public Mono filter( final @NotNull ServerWebExchange serverWebExchange, final @NotNull WebFilterChain webFilterChain) { final @NotNull TransactionContainer transactionContainer = new TransactionContainer(); - return ReactorUtils.withSentryNewMainHubClone( + return ReactorUtils.withSentryForkedRoots( webFilterChain .filter(serverWebExchange) .doFinally( diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentrySpringFilterTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentrySpringFilterTest.kt index b6bce77a0b..ac394deb31 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentrySpringFilterTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentrySpringFilterTest.kt @@ -3,6 +3,7 @@ package io.sentry.spring.jakarta import io.sentry.Breadcrumb import io.sentry.IScope import io.sentry.IScopes +import io.sentry.ISentryLifecycleToken import io.sentry.Scope import io.sentry.ScopeCallback import io.sentry.SentryOptions @@ -39,6 +40,7 @@ class SentrySpringFilterTest { private class Fixture { val scopes = mock() val response = MockHttpServletResponse() + val lifecycleToken = mock() val chain = mock() lateinit var scope: IScope lateinit var request: HttpServletRequest @@ -47,6 +49,7 @@ class SentrySpringFilterTest { scope = Scope(options) whenever(scopes.options).thenReturn(options) whenever(scopes.isEnabled).thenReturn(true) + whenever(scopes.pushIsolationScope()).thenReturn(lifecycleToken) doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(scopes).configureScope(any()) this.request = request ?: MockHttpServletRequest().apply { @@ -64,7 +67,7 @@ class SentrySpringFilterTest { val listener = fixture.getSut() listener.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.scopes).pushScope() + verify(fixture.scopes).pushIsolationScope() } @Test @@ -87,7 +90,7 @@ class SentrySpringFilterTest { val listener = fixture.getSut() listener.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.scopes).popScope() + verify(fixture.lifecycleToken).close() } @Test @@ -99,7 +102,7 @@ class SentrySpringFilterTest { listener.doFilter(fixture.request, fixture.response, fixture.chain) fail() } catch (e: Exception) { - verify(fixture.scopes).popScope() + verify(fixture.lifecycleToken).close() } } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryTaskDecoratorTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryTaskDecoratorTest.kt index e5f8704b49..d44e64f78d 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryTaskDecoratorTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/SentryTaskDecoratorTest.kt @@ -25,35 +25,35 @@ class SentryTaskDecoratorTest { } @Test - fun `hub is reset to its state within the thread after decoration is done`() { + fun `scopes is reset to its state within the thread after decoration is done`() { Sentry.init { it.dsn = dsn } val sut = SentryTaskDecorator() - val mainHub = Sentry.getCurrentScopes() - val threadedHub = Sentry.getCurrentScopes().clone() + val mainScopes = Sentry.getCurrentScopes() + val threadedScopes = Sentry.getCurrentScopes().forkedCurrentScope("test") executor.submit { - Sentry.setCurrentScopes(threadedHub) + Sentry.setCurrentScopes(threadedScopes) }.get() - assertEquals(mainHub, Sentry.getCurrentScopes()) + assertEquals(mainScopes, Sentry.getCurrentScopes()) val callableFuture = executor.submit( sut.decorate { - assertNotEquals(mainHub, Sentry.getCurrentScopes()) - assertNotEquals(threadedHub, Sentry.getCurrentScopes()) + assertNotEquals(mainScopes, Sentry.getCurrentScopes()) + assertNotEquals(threadedScopes, Sentry.getCurrentScopes()) } ) callableFuture.get() executor.submit { - assertNotEquals(mainHub, Sentry.getCurrentScopes()) - assertEquals(threadedHub, Sentry.getCurrentScopes()) + assertNotEquals(mainScopes, Sentry.getCurrentScopes()) + assertEquals(threadedScopes, Sentry.getCurrentScopes()) }.get() } } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/tracing/SentryTransactionAdviceTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/tracing/SentryTransactionAdviceTest.kt index 390b4d8241..b0f83782e0 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/tracing/SentryTransactionAdviceTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/tracing/SentryTransactionAdviceTest.kt @@ -1,6 +1,7 @@ package io.sentry.spring.jakarta.tracing import io.sentry.IScopes +import io.sentry.ISentryLifecycleToken import io.sentry.Sentry import io.sentry.SentryOptions import io.sentry.SentryTracer @@ -46,6 +47,8 @@ class SentryTransactionAdviceTest { @Autowired lateinit var scopes: IScopes + val lifecycleToken = mock() + @BeforeTest fun setup() { reset(scopes) @@ -55,6 +58,7 @@ class SentryTransactionAdviceTest { dsn = "https://key@sentry.io/proj" } ) + whenever(scopes.pushIsolationScope()).thenReturn(lifecycleToken) } @Test @@ -141,13 +145,13 @@ class SentryTransactionAdviceTest { @Test fun `pushes the scope when advice starts`() { classAnnotatedSampleService.hello() - verify(scopes).pushScope() + verify(scopes).pushIsolationScope() } @Test fun `pops the scope when advice finishes`() { classAnnotatedSampleService.hello() - verify(scopes).popScope() + verify(lifecycleToken).close() } @Configuration diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/ReactorUtilsTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/ReactorUtilsTest.kt index 9c851cde11..f3bd5d2653 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/ReactorUtilsTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/ReactorUtilsTest.kt @@ -1,9 +1,9 @@ package io.sentry.spring.jakarta.webflux -import io.sentry.IHub import io.sentry.IScopes import io.sentry.NoOpScopes import io.sentry.Sentry +import org.mockito.kotlin.any import org.mockito.kotlin.mock import org.mockito.kotlin.verify import org.mockito.kotlin.whenever @@ -31,88 +31,88 @@ class ReactorUtilsTest { } @Test - fun `propagates hub inside mono`() { - val hubToUse = mock() - var hubInside: IScopes? = null - val mono = ReactorUtils.withSentryHub( + fun `propagates scopes inside mono`() { + val scopesToUse = mock() + var scopesInside: IScopes? = null + val mono = ReactorUtils.withSentryScopes( Mono.just("hello") .publishOn(Schedulers.boundedElastic()) .map { it -> - hubInside = Sentry.getCurrentScopes() + scopesInside = Sentry.getCurrentScopes() it }, - hubToUse + scopesToUse ) assertEquals("hello", mono.block()) - assertSame(hubToUse, hubInside) + assertSame(scopesToUse, scopesInside) } @Test - fun `propagates hub inside flux`() { - val hubToUse = mock() - var hubInside: IScopes? = null - val flux = ReactorUtils.withSentryHub( + fun `propagates scopes inside flux`() { + val scopesToUse = mock() + var scopesInside: IScopes? = null + val flux = ReactorUtils.withSentryScopes( Flux.just("hello") .publishOn(Schedulers.boundedElastic()) .map { it -> - hubInside = Sentry.getCurrentScopes() + scopesInside = Sentry.getCurrentScopes() it }, - hubToUse + scopesToUse ) assertEquals("hello", flux.blockFirst()) - assertSame(hubToUse, hubInside) + assertSame(scopesToUse, scopesInside) } @Test - fun `without reactive utils hub is not propagated to mono`() { - val hubToUse = mock() - var hubInside: IScopes? = null + fun `without reactive utils scopes is not propagated to mono`() { + val scopesToUse = mock() + var scopesInside: IScopes? = null val mono = Mono.just("hello") .publishOn(Schedulers.boundedElastic()) .map { it -> - hubInside = Sentry.getCurrentScopes() + scopesInside = Sentry.getCurrentScopes() it } assertEquals("hello", mono.block()) - assertNotSame(hubToUse, hubInside) + assertNotSame(scopesToUse, scopesInside) } @Test - fun `without reactive utils hub is not propagated to flux`() { - val hubToUse = mock() - var hubInside: IScopes? = null + fun `without reactive utils scopes is not propagated to flux`() { + val scopesToUse = mock() + var scopesInside: IScopes? = null val flux = Flux.just("hello") .publishOn(Schedulers.boundedElastic()) .map { it -> - hubInside = Sentry.getCurrentScopes() + scopesInside = Sentry.getCurrentScopes() it } assertEquals("hello", flux.blockFirst()) - assertNotSame(hubToUse, hubInside) + assertNotSame(scopesToUse, scopesInside) } @Test - fun `clones hub for mono`() { + fun `clones scopes for mono`() { val mockScopes = mock() - whenever(mockScopes.clone()).thenReturn(mock()) + whenever(mockScopes.forkedCurrentScope(any())).thenReturn(mock()) Sentry.setCurrentScopes(mockScopes) ReactorUtils.withSentry(Mono.just("hello")).block() - verify(mockScopes).clone() + verify(mockScopes).forkedCurrentScope(any()) } @Test - fun `clones hub for flux`() { + fun `clones scopes for flux`() { val mockScopes = mock() - whenever(mockScopes.clone()).thenReturn(mock()) + whenever(mockScopes.forkedCurrentScope(any())).thenReturn(mock()) Sentry.setCurrentScopes(mockScopes) ReactorUtils.withSentry(Flux.just("hello")).blockFirst() - verify(mockScopes).clone() + verify(mockScopes).forkedCurrentScope(any()) } } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryScheduleHookTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryScheduleHookTest.kt index 5403caa7e0..4b540da1aa 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryScheduleHookTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryScheduleHookTest.kt @@ -26,35 +26,35 @@ class SentryScheduleHookTest { } @Test - fun `hub is reset to its state within the thread after hook is done`() { + fun `scopes is reset to its state within the thread after hook is done`() { Sentry.init { it.dsn = dsn } val sut = SentryScheduleHook() - val mainHub = Sentry.getCurrentScopes() - val threadedHub = Sentry.getCurrentScopes().clone() + val mainScopes = Sentry.getCurrentScopes() + val threadedScopes = Sentry.getCurrentScopes().forkedCurrentScope("test") executor.submit { - Sentry.setCurrentScopes(threadedHub) + Sentry.setCurrentScopes(threadedScopes) }.get() - assertEquals(mainHub, Sentry.getCurrentScopes()) + assertEquals(mainScopes, Sentry.getCurrentScopes()) val callableFuture = executor.submit( sut.apply { - assertNotEquals(mainHub, Sentry.getCurrentScopes()) - assertNotEquals(threadedHub, Sentry.getCurrentScopes()) + assertNotEquals(mainScopes, Sentry.getCurrentScopes()) + assertNotEquals(threadedScopes, Sentry.getCurrentScopes()) } ) callableFuture.get() executor.submit { - assertNotEquals(mainHub, Sentry.getCurrentScopes()) - assertEquals(threadedHub, Sentry.getCurrentScopes()) + assertNotEquals(mainScopes, Sentry.getCurrentScopes()) + assertEquals(threadedScopes, Sentry.getCurrentScopes()) }.get() } } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryWebFluxTracingFilterTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryWebFluxTracingFilterTest.kt index ddbbe75817..44f4925c2d 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryWebFluxTracingFilterTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/webflux/SentryWebFluxTracingFilterTest.kt @@ -89,7 +89,7 @@ class SentryWebFluxTracingFilterTest { fun withMockScopes(closure: () -> Unit) = Mockito.mockStatic(Sentry::class.java).use { it.`when` { Sentry.getCurrentHub() }.thenReturn(HubScopesWrapper(fixture.scopes)) it.`when` { Sentry.getCurrentScopes() }.thenReturn(fixture.scopes) - it.`when` { Sentry.cloneMainHub() }.thenReturn(fixture.scopes) + it.`when` { Sentry.forkedRootScopes(any()) }.thenReturn(fixture.scopes) closure.invoke() } @@ -210,7 +210,7 @@ class SentryWebFluxTracingFilterTest { verify(fixture.chain).filter(fixture.exchange) - verify(fixture.scopes, times(3)).isEnabled + verify(fixture.scopes, times(2)).isEnabled verifyNoMoreInteractions(fixture.scopes) } } @@ -249,13 +249,11 @@ class SentryWebFluxTracingFilterTest { verify(fixture.chain).filter(fixture.exchange) - verify(fixture.scopes, times(3)).isEnabled + verify(fixture.scopes, times(2)).isEnabled verify(fixture.scopes, times(2)).options verify(fixture.scopes).continueTrace(anyOrNull(), anyOrNull()) - verify(fixture.scopes).pushScope() // TODO don't verify(fixture.scopes).addBreadcrumb(any(), any()) verify(fixture.scopes).configureScope(any()) - verify(fixture.scopes).popScope() // TODO don't verifyNoMoreInteractions(fixture.scopes) } } diff --git a/sentry-spring/src/main/java/io/sentry/spring/SentrySpringFilter.java b/sentry-spring/src/main/java/io/sentry/spring/SentrySpringFilter.java index 7695545f04..252a07910c 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/SentrySpringFilter.java +++ b/sentry-spring/src/main/java/io/sentry/spring/SentrySpringFilter.java @@ -9,6 +9,7 @@ import io.sentry.EventProcessor; import io.sentry.Hint; import io.sentry.IScopes; +import io.sentry.ISentryLifecycleToken; import io.sentry.ScopesAdapter; import io.sentry.SentryEvent; import io.sentry.SentryLevel; @@ -60,7 +61,7 @@ protected void doFilterInternal( if (scopes.isEnabled()) { // request may qualify for caching request body, if so resolve cached request final HttpServletRequest request = resolveHttpServletRequest(servletRequest); - scopes.pushScope(); + final @NotNull ISentryLifecycleToken lifecycleToken = scopes.pushIsolationScope(); try { final Hint hint = new Hint(); hint.set(SPRING_REQUEST_FILTER_REQUEST, servletRequest); @@ -70,7 +71,7 @@ protected void doFilterInternal( configureScope(request); filterChain.doFilter(request, response); } finally { - scopes.popScope(); + lifecycleToken.close(); } } else { filterChain.doFilter(servletRequest, response); diff --git a/sentry-spring/src/main/java/io/sentry/spring/SentryTaskDecorator.java b/sentry-spring/src/main/java/io/sentry/spring/SentryTaskDecorator.java index 88d205a57e..761038ece0 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/SentryTaskDecorator.java +++ b/sentry-spring/src/main/java/io/sentry/spring/SentryTaskDecorator.java @@ -1,6 +1,7 @@ package io.sentry.spring; import io.sentry.IScopes; +import io.sentry.ISentryLifecycleToken; import io.sentry.Sentry; import java.util.concurrent.Callable; import org.jetbrains.annotations.NotNull; @@ -14,18 +15,13 @@ */ public final class SentryTaskDecorator implements TaskDecorator { @Override - @SuppressWarnings("deprecation") + // TODO should there also be a SentryIsolatedTaskDecorator or similar that uses forkedScopes()? public @NotNull Runnable decorate(final @NotNull Runnable runnable) { - // TODO fork instead - final IScopes newHub = Sentry.getCurrentScopes().clone(); + final IScopes newHub = Sentry.getCurrentScopes().forkedCurrentScope("spring.taskDecorator"); return () -> { - final IScopes oldState = Sentry.getCurrentScopes(); - Sentry.setCurrentScopes(newHub); - try { + try (final @NotNull ISentryLifecycleToken ignored = newHub.makeCurrent()) { runnable.run(); - } finally { - Sentry.setCurrentScopes(oldState); } }; } diff --git a/sentry-spring/src/main/java/io/sentry/spring/tracing/SentryTransactionAdvice.java b/sentry-spring/src/main/java/io/sentry/spring/tracing/SentryTransactionAdvice.java index 8f4f5bbdfc..a885510fcd 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/tracing/SentryTransactionAdvice.java +++ b/sentry-spring/src/main/java/io/sentry/spring/tracing/SentryTransactionAdvice.java @@ -2,6 +2,7 @@ import com.jakewharton.nopen.annotation.Open; import io.sentry.IScopes; +import io.sentry.ISentryLifecycleToken; import io.sentry.ITransaction; import io.sentry.ScopesAdapter; import io.sentry.SpanStatus; @@ -67,7 +68,7 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl } else { operation = "bean"; } - scopes.pushScope(); + final @NotNull ISentryLifecycleToken lifecycleToken = scopes.pushIsolationScope(); final TransactionOptions transactionOptions = new TransactionOptions(); transactionOptions.setBindToScope(true); final ITransaction transaction = @@ -85,7 +86,7 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl throw e; } finally { transaction.finish(); - scopes.popScope(); + lifecycleToken.close(); } } } diff --git a/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryScheduleHook.java b/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryScheduleHook.java index 20f494168d..50839e653e 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryScheduleHook.java +++ b/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryScheduleHook.java @@ -1,6 +1,7 @@ package io.sentry.spring.webflux; import io.sentry.IScopes; +import io.sentry.ISentryLifecycleToken; import io.sentry.Sentry; import java.util.function.Function; import org.jetbrains.annotations.ApiStatus; @@ -8,23 +9,17 @@ /** * Hook meant to used with {@link reactor.core.scheduler.Schedulers#onScheduleHook(String, - * Function)} to configure Reactor to copy correct hub into the operating thread. + * Function)} to configure Reactor to copy correct scopes into the operating thread. */ @ApiStatus.Experimental public final class SentryScheduleHook implements Function { @Override - @SuppressWarnings("deprecation") public Runnable apply(final @NotNull Runnable runnable) { - // TODO fork instead - final IScopes newHub = Sentry.getCurrentScopes().clone(); + final IScopes newScopes = Sentry.getCurrentScopes().forkedCurrentScope("spring.scheduleHook"); return () -> { - final IScopes oldState = Sentry.getCurrentScopes(); - Sentry.setCurrentScopes(newHub); - try { + try (final @NotNull ISentryLifecycleToken ignored = newScopes.makeCurrent()) { runnable.run(); - } finally { - Sentry.setCurrentScopes(oldState); } }; } diff --git a/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryWebFilter.java b/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryWebFilter.java index 4d39e092bc..10e80ebe8b 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryWebFilter.java +++ b/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryWebFilter.java @@ -50,7 +50,7 @@ public SentryWebFilter(final @NotNull IScopes scopes) { public Mono filter( final @NotNull ServerWebExchange serverWebExchange, final @NotNull WebFilterChain webFilterChain) { - @NotNull IScopes requestHub = Sentry.cloneMainHub(); + @NotNull IScopes requestHub = Sentry.forkedRootScopes("request.webflux"); // TODO do not push / pop, use fork instead if (!requestHub.isEnabled()) { return webFilterChain.filter(serverWebExchange); @@ -81,8 +81,6 @@ isTracingEnabled && shouldTraceRequest(requestHub, request) if (transaction != null) { finishTransaction(serverWebExchange, transaction); } - requestHub.popScope(); // TODO don't - // TODO token based cleanup instead? Sentry.setCurrentScopes(NoOpScopes.getInstance()); }) .doOnError( @@ -96,7 +94,6 @@ isTracingEnabled && shouldTraceRequest(requestHub, request) () -> { serverWebExchange.getAttributes().put(SENTRY_SCOPES_KEY, requestHub); Sentry.setCurrentScopes(requestHub); - requestHub.pushScope(); // TODO don't final ServerHttpResponse response = serverWebExchange.getResponse(); final Hint hint = new Hint(); diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/SentrySpringFilterTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/SentrySpringFilterTest.kt index c6ac952531..6037e253c8 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/SentrySpringFilterTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/SentrySpringFilterTest.kt @@ -3,6 +3,7 @@ package io.sentry.spring import io.sentry.Breadcrumb import io.sentry.IScope import io.sentry.IScopes +import io.sentry.ISentryLifecycleToken import io.sentry.Scope import io.sentry.ScopeCallback import io.sentry.SentryOptions @@ -39,6 +40,7 @@ class SentrySpringFilterTest { private class Fixture { val scopes = mock() val response = MockHttpServletResponse() + val lifecycleToken = mock() val chain = mock() lateinit var scope: IScope lateinit var request: HttpServletRequest @@ -47,6 +49,7 @@ class SentrySpringFilterTest { scope = Scope(options) whenever(scopes.options).thenReturn(options) whenever(scopes.isEnabled).thenReturn(true) + whenever(scopes.pushIsolationScope()).thenReturn(lifecycleToken) doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }.whenever(scopes).configureScope(any()) this.request = request ?: MockHttpServletRequest().apply { @@ -64,7 +67,7 @@ class SentrySpringFilterTest { val listener = fixture.getSut() listener.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.scopes).pushScope() + verify(fixture.scopes).pushIsolationScope() } @Test @@ -87,7 +90,7 @@ class SentrySpringFilterTest { val listener = fixture.getSut() listener.doFilter(fixture.request, fixture.response, fixture.chain) - verify(fixture.scopes).popScope() + verify(fixture.lifecycleToken).close() } @Test @@ -99,7 +102,7 @@ class SentrySpringFilterTest { listener.doFilter(fixture.request, fixture.response, fixture.chain) fail() } catch (e: Exception) { - verify(fixture.scopes).popScope() + verify(fixture.lifecycleToken).close() } } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/SentryTaskDecoratorTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/SentryTaskDecoratorTest.kt index 3f34ab9d9d..4bbce919eb 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/SentryTaskDecoratorTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/SentryTaskDecoratorTest.kt @@ -25,35 +25,35 @@ class SentryTaskDecoratorTest { } @Test - fun `hub is reset to its state within the thread after decoration is done`() { + fun `scopes is reset to its state within the thread after decoration is done`() { Sentry.init { it.dsn = dsn } val sut = SentryTaskDecorator() - val mainHub = Sentry.getCurrentScopes() - val threadedHub = Sentry.getCurrentScopes().clone() + val mainScopes = Sentry.getCurrentScopes() + val threadedScopes = Sentry.getCurrentScopes().forkedCurrentScope("test") executor.submit { - Sentry.setCurrentScopes(threadedHub) + Sentry.setCurrentScopes(threadedScopes) }.get() - assertEquals(mainHub, Sentry.getCurrentScopes()) + assertEquals(mainScopes, Sentry.getCurrentScopes()) val callableFuture = executor.submit( sut.decorate { - assertNotEquals(mainHub, Sentry.getCurrentScopes()) - assertNotEquals(threadedHub, Sentry.getCurrentScopes()) + assertNotEquals(mainScopes, Sentry.getCurrentScopes()) + assertNotEquals(threadedScopes, Sentry.getCurrentScopes()) } ) callableFuture.get() executor.submit { - assertNotEquals(mainHub, Sentry.getCurrentScopes()) - assertEquals(threadedHub, Sentry.getCurrentScopes()) + assertNotEquals(mainScopes, Sentry.getCurrentScopes()) + assertEquals(threadedScopes, Sentry.getCurrentScopes()) }.get() } } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/tracing/SentryTransactionAdviceTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/tracing/SentryTransactionAdviceTest.kt index f53acde8aa..8a3d8ee46c 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/tracing/SentryTransactionAdviceTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/tracing/SentryTransactionAdviceTest.kt @@ -1,6 +1,7 @@ package io.sentry.spring.tracing import io.sentry.IScopes +import io.sentry.ISentryLifecycleToken import io.sentry.Sentry import io.sentry.SentryOptions import io.sentry.SentryTracer @@ -46,6 +47,8 @@ class SentryTransactionAdviceTest { @Autowired lateinit var scopes: IScopes + val lifecycleToken = mock() + @BeforeTest fun setup() { reset(scopes) @@ -55,6 +58,7 @@ class SentryTransactionAdviceTest { dsn = "https://key@sentry.io/proj" } ) + whenever(scopes.pushIsolationScope()).thenReturn(lifecycleToken) } @Test @@ -141,13 +145,13 @@ class SentryTransactionAdviceTest { @Test fun `pushes the scope when advice starts`() { classAnnotatedSampleService.hello() - verify(scopes).pushScope() + verify(scopes).pushIsolationScope() } @Test fun `pops the scope when advice finishes`() { classAnnotatedSampleService.hello() - verify(scopes).popScope() + verify(lifecycleToken).close() } @Configuration diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryScheduleHookTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryScheduleHookTest.kt index 7a8b2993f9..88c33c3695 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryScheduleHookTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryScheduleHookTest.kt @@ -26,35 +26,35 @@ class SentryScheduleHookTest { } @Test - fun `hub is reset to its state within the thread after hook is done`() { + fun `scopes is reset to its state within the thread after hook is done`() { Sentry.init { it.dsn = dsn } val sut = SentryScheduleHook() - val mainHub = Sentry.getCurrentScopes() - val threadedHub = Sentry.getCurrentScopes().clone() + val mainScopes = Sentry.getCurrentScopes() + val threadedScopes = Sentry.getCurrentScopes().forkedCurrentScope("test") executor.submit { - Sentry.setCurrentHub(threadedHub) + Sentry.setCurrentScopes(threadedScopes) }.get() - assertEquals(mainHub, Sentry.getCurrentScopes()) + assertEquals(mainScopes, Sentry.getCurrentScopes()) val callableFuture = executor.submit( sut.apply { - assertNotEquals(mainHub, Sentry.getCurrentScopes()) - assertNotEquals(threadedHub, Sentry.getCurrentScopes()) + assertNotEquals(mainScopes, Sentry.getCurrentScopes()) + assertNotEquals(threadedScopes, Sentry.getCurrentScopes()) } ) callableFuture.get() executor.submit { - assertNotEquals(mainHub, Sentry.getCurrentScopes()) - assertEquals(threadedHub, Sentry.getCurrentScopes()) + assertNotEquals(mainScopes, Sentry.getCurrentScopes()) + assertEquals(threadedScopes, Sentry.getCurrentScopes()) }.get() } } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryWebFluxTracingFilterTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryWebFluxTracingFilterTest.kt index 1a31dcaa10..ff527abd7d 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryWebFluxTracingFilterTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/webflux/SentryWebFluxTracingFilterTest.kt @@ -89,7 +89,7 @@ class SentryWebFluxTracingFilterTest { fun withMockScopes(closure: () -> Unit) = Mockito.mockStatic(Sentry::class.java).use { it.`when` { Sentry.getCurrentHub() }.thenReturn(HubScopesWrapper(fixture.scopes)) it.`when` { Sentry.getCurrentScopes() }.thenReturn(fixture.scopes) - it.`when` { Sentry.cloneMainHub() }.thenReturn(fixture.scopes) + it.`when` { Sentry.forkedRootScopes(any()) }.thenReturn(fixture.scopes) closure.invoke() } @@ -253,10 +253,8 @@ class SentryWebFluxTracingFilterTest { verify(fixture.scopes).isEnabled verify(fixture.scopes, times(2)).options verify(fixture.scopes).continueTrace(anyOrNull(), anyOrNull()) - verify(fixture.scopes).pushScope() // TODO don't verify(fixture.scopes).addBreadcrumb(any(), any()) verify(fixture.scopes).configureScope(any()) - verify(fixture.scopes).popScope() // TODO don't verifyNoMoreInteractions(fixture.scopes) } }