From 6093e335856e472c22313b2365317d4ef4a68ee8 Mon Sep 17 00:00:00 2001 From: Jeff Ward Date: Fri, 11 Nov 2022 10:55:56 -0500 Subject: [PATCH] Add telemetry configuration mapper This will allow cross platform SDKs to modify the configuration before sending it to telemetry. --- dd-sdk-android/apiSurface | 2 ++ .../com/datadog/android/_InternalProxy.kt | 13 ++++++++++ .../core/configuration/Configuration.kt | 11 ++++++++ .../internal/domain/event/RumEventMapper.kt | 7 ++--- .../configuration/ConfigurationBuilderTest.kt | 26 +++++++++++++++++++ .../domain/event/RumEventMapperTest.kt | 13 ++++++++-- .../utils/forge/RumEventMapperFactory.kt | 3 ++- 7 files changed, 69 insertions(+), 6 deletions(-) diff --git a/dd-sdk-android/apiSurface b/dd-sdk-android/apiSurface index 077649f55b..99859f3e38 100644 --- a/dd-sdk-android/apiSurface +++ b/dd-sdk-android/apiSurface @@ -67,6 +67,8 @@ class com.datadog.android._InternalProxy fun error(String, String?, String?) val _telemetry: _TelemetryProxy fun setCustomAppVersion(String) + companion object + fun setTelemetryConfigurationEventMapper(com.datadog.android.core.configuration.Configuration.Builder, com.datadog.android.event.EventMapper): com.datadog.android.core.configuration.Configuration.Builder enum com.datadog.android.core.configuration.BatchSize constructor(Long) - SMALL diff --git a/dd-sdk-android/src/main/kotlin/com/datadog/android/_InternalProxy.kt b/dd-sdk-android/src/main/kotlin/com/datadog/android/_InternalProxy.kt index 8255cee6e8..54a510e3ca 100644 --- a/dd-sdk-android/src/main/kotlin/com/datadog/android/_InternalProxy.kt +++ b/dd-sdk-android/src/main/kotlin/com/datadog/android/_InternalProxy.kt @@ -6,8 +6,11 @@ package com.datadog.android +import com.datadog.android.core.configuration.Configuration import com.datadog.android.core.internal.CoreFeature +import com.datadog.android.event.EventMapper import com.datadog.android.telemetry.internal.Telemetry +import com.datadog.android.telemetry.model.TelemetryConfigurationEvent /** * This class exposes internal methods that are used by other Datadog modules and cross platform @@ -48,4 +51,14 @@ class _InternalProxy internal constructor(telemetry: Telemetry) { fun setCustomAppVersion(version: String) { CoreFeature.packageVersionProvider.version = version } + + companion object { + @Suppress("FunctionMaxLength") + fun setTelemetryConfigurationEventMapper( + builder: Configuration.Builder, + eventMapper: EventMapper + ): Configuration.Builder { + return builder.setTelemetryConfigurationEventMapper(eventMapper) + } + } } diff --git a/dd-sdk-android/src/main/kotlin/com/datadog/android/core/configuration/Configuration.kt b/dd-sdk-android/src/main/kotlin/com/datadog/android/core/configuration/Configuration.kt index 8eee1c916d..ddd6d61ea2 100644 --- a/dd-sdk-android/src/main/kotlin/com/datadog/android/core/configuration/Configuration.kt +++ b/dd-sdk-android/src/main/kotlin/com/datadog/android/core/configuration/Configuration.kt @@ -44,6 +44,7 @@ import com.datadog.android.rum.tracking.NoOpInteractionPredicate import com.datadog.android.rum.tracking.TrackingStrategy import com.datadog.android.rum.tracking.ViewAttributesProvider import com.datadog.android.rum.tracking.ViewTrackingStrategy +import com.datadog.android.telemetry.model.TelemetryConfigurationEvent import okhttp3.Authenticator import java.net.Proxy import java.util.Locale @@ -581,6 +582,16 @@ internal constructor( return this } + @Suppress("FunctionMaxLength") + internal fun setTelemetryConfigurationEventMapper(eventMapper: EventMapper): Builder { + applyIfFeatureEnabled(PluginFeature.RUM, "setTelemetryConfigurationEventMapper") { + rumConfig = rumConfig.copy( + rumEventMapper = getRumEventMapper().copy(telemetryConfigurationMapper = eventMapper) + ) + } + return this + } + /** * Allows to set the necessary security configuration (used to control local * data storage encryption, for example). diff --git a/dd-sdk-android/src/main/kotlin/com/datadog/android/rum/internal/domain/event/RumEventMapper.kt b/dd-sdk-android/src/main/kotlin/com/datadog/android/rum/internal/domain/event/RumEventMapper.kt index 6f269ab18e..f4bbc1fe95 100644 --- a/dd-sdk-android/src/main/kotlin/com/datadog/android/rum/internal/domain/event/RumEventMapper.kt +++ b/dd-sdk-android/src/main/kotlin/com/datadog/android/rum/internal/domain/event/RumEventMapper.kt @@ -29,7 +29,8 @@ internal data class RumEventMapper( val errorEventMapper: EventMapper = NoOpEventMapper(), val resourceEventMapper: EventMapper = NoOpEventMapper(), val actionEventMapper: EventMapper = NoOpEventMapper(), - val longTaskEventMapper: EventMapper = NoOpEventMapper() + val longTaskEventMapper: EventMapper = NoOpEventMapper(), + val telemetryConfigurationMapper: EventMapper = NoOpEventMapper() ) : EventMapper { override fun map(event: Any): Any? { @@ -55,9 +56,9 @@ internal data class RumEventMapper( } is ResourceEvent -> resourceEventMapper.map(event) is LongTaskEvent -> longTaskEventMapper.map(event) + is TelemetryConfigurationEvent -> telemetryConfigurationMapper.map(event) is TelemetryDebugEvent, - is TelemetryErrorEvent, - is TelemetryConfigurationEvent -> event + is TelemetryErrorEvent -> event else -> { sdkLogger.warningWithTelemetry( NO_EVENT_MAPPER_ASSIGNED_WARNING_MESSAGE diff --git a/dd-sdk-android/src/test/kotlin/com/datadog/android/core/configuration/ConfigurationBuilderTest.kt b/dd-sdk-android/src/test/kotlin/com/datadog/android/core/configuration/ConfigurationBuilderTest.kt index 18e93aabc9..bafe579939 100644 --- a/dd-sdk-android/src/test/kotlin/com/datadog/android/core/configuration/ConfigurationBuilderTest.kt +++ b/dd-sdk-android/src/test/kotlin/com/datadog/android/core/configuration/ConfigurationBuilderTest.kt @@ -12,6 +12,7 @@ import android.os.Build import android.util.Log import com.datadog.android.DatadogEndpoint import com.datadog.android.DatadogSite +import com.datadog.android._InternalProxy import com.datadog.android.core.internal.event.NoOpEventMapper import com.datadog.android.event.EventMapper import com.datadog.android.event.NoOpSpanEventMapper @@ -35,6 +36,7 @@ import com.datadog.android.rum.tracking.InteractionPredicate import com.datadog.android.rum.tracking.NoOpInteractionPredicate import com.datadog.android.rum.tracking.ViewAttributesProvider import com.datadog.android.rum.tracking.ViewTrackingStrategy +import com.datadog.android.telemetry.model.TelemetryConfigurationEvent import com.datadog.android.utils.config.LoggerTestConfiguration import com.datadog.android.utils.forge.Configurator import com.datadog.tools.unit.annotations.TestConfigurationsProvider @@ -765,6 +767,30 @@ internal class ConfigurationBuilderTest { assertThat(config.additionalConfig).isEmpty() } + @Test + fun `𝕄 build config with RUM Telemetry eventMapper 𝕎 _InternalProxy setTelemetryConfigurationEventMapper() & build()`() { + // Given + val eventMapper: EventMapper = mock() + + // When + val builder = testedBuilder + _InternalProxy.setTelemetryConfigurationEventMapper(builder, eventMapper) + val config = builder.build() + + // Then + assertThat(config.coreConfig).isEqualTo(Configuration.DEFAULT_CORE_CONFIG) + assertThat(config.logsConfig).isEqualTo(Configuration.DEFAULT_LOGS_CONFIG) + assertThat(config.tracesConfig).isEqualTo(Configuration.DEFAULT_TRACING_CONFIG) + assertThat(config.crashReportConfig).isEqualTo(Configuration.DEFAULT_CRASH_CONFIG) + val expectedRumEventMapper = RumEventMapper(telemetryConfigurationMapper = eventMapper) + assertThat(config.rumConfig).isEqualTo( + Configuration.DEFAULT_RUM_CONFIG.copy( + rumEventMapper = expectedRumEventMapper + ) + ) + assertThat(config.additionalConfig).isEmpty() + } + @Test fun `𝕄 build config with plugin 𝕎 addPlugin() and build()`() { // Given diff --git a/dd-sdk-android/src/test/kotlin/com/datadog/android/rum/internal/domain/event/RumEventMapperTest.kt b/dd-sdk-android/src/test/kotlin/com/datadog/android/rum/internal/domain/event/RumEventMapperTest.kt index 41a07a461e..126b5ab536 100644 --- a/dd-sdk-android/src/test/kotlin/com/datadog/android/rum/internal/domain/event/RumEventMapperTest.kt +++ b/dd-sdk-android/src/test/kotlin/com/datadog/android/rum/internal/domain/event/RumEventMapperTest.kt @@ -71,6 +71,9 @@ internal class RumEventMapperTest { @Mock lateinit var mockLongTaskEventMapper: EventMapper + @Mock + lateinit var mockTelemetryConfigurationMapper: EventMapper + @BeforeEach fun `set up`() { whenever(mockViewEventMapper.map(any())).thenAnswer { it.arguments[0] } @@ -80,7 +83,8 @@ internal class RumEventMapperTest { viewEventMapper = mockViewEventMapper, resourceEventMapper = mockResourceEventMapper, errorEventMapper = mockErrorEventMapper, - longTaskEventMapper = mockLongTaskEventMapper + longTaskEventMapper = mockLongTaskEventMapper, + telemetryConfigurationMapper = mockTelemetryConfigurationMapper ) } @@ -211,14 +215,19 @@ internal class RumEventMapperTest { } @Test - fun `M return the original event W map { TelemetryConfigurationEvent }`( + fun `M return the bundled event W map { TelemetryConfigurationEvent }`( @Forgery telemetryConfigurationEvent: TelemetryConfigurationEvent ) { + // GIVEN + whenever(mockTelemetryConfigurationMapper.map(telemetryConfigurationEvent)) + .thenReturn(telemetryConfigurationEvent) + // WHEN val mappedRumEvent = testedRumEventMapper.map(telemetryConfigurationEvent) // THEN verifyZeroInteractions(logger.mockSdkLogHandler) + verify(mockTelemetryConfigurationMapper).map(telemetryConfigurationEvent) assertThat(mappedRumEvent).isSameAs(telemetryConfigurationEvent) } diff --git a/dd-sdk-android/src/test/kotlin/com/datadog/android/utils/forge/RumEventMapperFactory.kt b/dd-sdk-android/src/test/kotlin/com/datadog/android/utils/forge/RumEventMapperFactory.kt index 261d2a462d..e5ee90bb37 100644 --- a/dd-sdk-android/src/test/kotlin/com/datadog/android/utils/forge/RumEventMapperFactory.kt +++ b/dd-sdk-android/src/test/kotlin/com/datadog/android/utils/forge/RumEventMapperFactory.kt @@ -18,7 +18,8 @@ internal class RumEventMapperFactory : ForgeryFactory { viewEventMapper = mock(), actionEventMapper = mock(), resourceEventMapper = mock(), - errorEventMapper = mock() + errorEventMapper = mock(), + telemetryConfigurationMapper = mock() ) } }