Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove requirement for supplying appId #874

Merged
merged 1 commit into from
May 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ internal class EmbraceMetadataService private constructor(

override fun getLightweightAppInfo(): AppInfo = getAppInfo(false)

override fun getAppId(): String {
override fun getAppId(): String? {
return configService.sdkModeBehavior.appId
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ internal interface MetadataService {
*
* @return the app ID.
*/
fun getAppId(): String
fun getAppId(): String?

/**
* Gets information and specifications of the current device. This is sent with the following
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package io.embrace.android.embracesdk.comms.delivery

import io.embrace.android.embracesdk.internal.payload.Envelope
import io.embrace.android.embracesdk.internal.payload.LogPayload
import io.embrace.android.embracesdk.internal.utils.Provider
import io.embrace.android.embracesdk.ndk.NativeCrashService
import io.embrace.android.embracesdk.payload.EventMessage
import io.embrace.android.embracesdk.payload.NetworkEvent
import io.embrace.android.embracesdk.payload.SessionMessage
import io.embrace.android.embracesdk.session.id.SessionIdTracker
import io.embrace.android.embracesdk.session.orchestrator.SessionSnapshotType

internal class NoopDeliveryService : DeliveryService {

Check warning on line 13 in embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/comms/delivery/NoopDeliveryService.kt

View check run for this annotation

Codecov / codecov/patch

embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/comms/delivery/NoopDeliveryService.kt#L13

Added line #L13 was not covered by tests

override fun sendSession(sessionMessage: SessionMessage, snapshotType: SessionSnapshotType) {
}

override fun sendCachedSessions(
nativeCrashServiceProvider: Provider<NativeCrashService?>,
sessionIdTracker: SessionIdTracker
) {
}

override fun sendLog(eventMessage: EventMessage) {
}

override fun sendLogs(logEnvelope: Envelope<LogPayload>) {
}

override fun saveLogs(logEnvelope: Envelope<LogPayload>) {
}

override fun sendNetworkCall(networkEvent: NetworkEvent) {
}

override fun sendCrash(crash: EventMessage, processTerminating: Boolean) {
}

override fun sendMoment(eventMessage: EventMessage) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import kotlin.math.min
*/
internal class EmbraceConfigService @JvmOverloads constructor(
private val localConfig: LocalConfig,
private val apiService: ApiService,
private val apiService: ApiService?,
private val preferencesService: PreferencesService,
private val clock: Clock,
private val logger: EmbLogger,
Expand Down Expand Up @@ -181,8 +181,8 @@ internal class EmbraceConfigService @JvmOverloads constructor(
*/

fun loadConfigFromCache() {
val cachedConfig = apiService.getCachedConfig()
val obj = cachedConfig.remoteConfig
val cachedConfig = apiService?.getCachedConfig()
val obj = cachedConfig?.remoteConfig

if (obj != null) {
val oldConfig = configProp
Expand Down Expand Up @@ -214,7 +214,7 @@ internal class EmbraceConfigService @JvmOverloads constructor(
if (configRequiresRefresh()) {
try {
lastRefreshConfigAttempt = clock.now()
val newConfig = apiService.getConfig()
val newConfig = apiService?.getConfig()
if (newConfig != null) {
updateConfig(previousConfig, newConfig)
lastUpdated = clock.now()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
package io.embrace.android.embracesdk.config

import android.content.res.Resources.NotFoundException
import android.util.Base64
import io.embrace.android.embracesdk.config.local.LocalConfig
import io.embrace.android.embracesdk.config.local.SdkLocalConfig
import io.embrace.android.embracesdk.internal.AndroidResourcesService
import io.embrace.android.embracesdk.internal.ApkToolsConfig
import io.embrace.android.embracesdk.internal.serialization.EmbraceSerializer
import io.embrace.android.embracesdk.logging.EmbLogger
import io.embrace.android.embracesdk.opentelemetry.OpenTelemetryConfiguration

internal object LocalConfigParser {

/**
* Build info app id name.
*/
public const val BUILD_INFO_APP_ID = "emb_app_id"
const val BUILD_INFO_APP_ID = "emb_app_id"

/**
* Build info sdk config id name.
Expand All @@ -23,12 +25,12 @@
/**
* Build info ndk enabled.
*/
public const val BUILD_INFO_NDK_ENABLED = "emb_ndk_enabled"
const val BUILD_INFO_NDK_ENABLED = "emb_ndk_enabled"

/**
* The default value for native crash capture enabling
*/
public const val NDK_ENABLED_DEFAULT = false
const val NDK_ENABLED_DEFAULT = false

/**
* Loads the build information from resources provided by the config file packaged within the application by Gradle at
Expand All @@ -42,16 +44,11 @@
packageName: String,
customAppId: String?,
serializer: EmbraceSerializer,
openTelemetryCfg: OpenTelemetryConfiguration,
logger: EmbLogger
): LocalConfig {
return try {
val appId: String = customAppId ?: resources.getString(
resources.getIdentifier(
BUILD_INFO_APP_ID,
"string",
packageName
)
)
val appId = resolveAppId(customAppId, resources, packageName)
val ndkEnabledJsonId =
resources.getIdentifier(BUILD_INFO_NDK_ENABLED, "string", packageName)
val ndkEnabled = when {
Expand All @@ -74,20 +71,43 @@

else -> null
}
buildConfig(appId, ndkEnabled, sdkConfigJson, serializer, logger)
buildConfig(appId, ndkEnabled, sdkConfigJson, serializer, openTelemetryCfg, logger)
} catch (ex: Exception) {
throw IllegalStateException("Failed to load local config from resources.", ex)
}
}

private fun resolveAppId(
customAppId: String?,
resources: AndroidResourcesService,
packageName: String
): String? {
return try {
customAppId ?: resources.getString(
resources.getIdentifier(
BUILD_INFO_APP_ID,
"string",
packageName
)
)
} catch (exc: NotFoundException) {
null

Check warning on line 94 in embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/config/LocalConfigParser.kt

View check run for this annotation

Codecov / codecov/patch

embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/config/LocalConfigParser.kt#L93-L94

Added lines #L93 - L94 were not covered by tests
}
}

fun buildConfig(
appId: String?,
ndkEnabled: Boolean,
sdkConfigs: String?,
serializer: EmbraceSerializer,
openTelemetryCfg: OpenTelemetryConfiguration,
logger: EmbLogger
): LocalConfig {
require(!appId.isNullOrEmpty()) { "Embrace AppId cannot be null or empty." }
require(!appId.isNullOrEmpty() || openTelemetryCfg.hasConfiguredOtelExporters()) {
"No appId supplied in embrace-config.json. This is required if you want to " +
"send data to Embrace, unless you configure an OTel exporter and add" +
" embrace.disableMappingFileUpload=true to gradle.properties."
}

val enabledStr = when {
ndkEnabled -> "enabled"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,20 @@
/**
* Data base URL.
*/
fun getData(appId: String): String = local?.data ?: "https://a-$appId.$DATA_DEFAULT"
fun getData(appId: String?): String {
if (appId == null) {
return ""

Check warning on line 28 in embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/config/behavior/SdkEndpointBehavior.kt

View check run for this annotation

Codecov / codecov/patch

embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/config/behavior/SdkEndpointBehavior.kt#L28

Added line #L28 was not covered by tests
}
return local?.data ?: "https://a-$appId.$DATA_DEFAULT"
}

/**
* Config base URL.
*/
fun getConfig(appId: String): String = local?.config ?: "https://a-$appId.$CONFIG_DEFAULT"
fun getConfig(appId: String?): String {
if (appId == null) {
return ""

Check warning on line 38 in embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/config/behavior/SdkEndpointBehavior.kt

View check run for this annotation

Codecov / codecov/patch

embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/config/behavior/SdkEndpointBehavior.kt#L38

Added line #L38 was not covered by tests
}
return local?.config ?: "https://a-$appId.$CONFIG_DEFAULT"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ internal class SdkModeBehavior(
/**
* The Embrace app ID. This is used to identify the app within the database.
*/
val appId: String by lazy { local?.appId ?: error("App ID not supplied.") }
val appId: String? by lazy { local?.appId }

/**
* The % of devices that should be enabled.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ internal class LocalConfig(
/**
* The Embrace app ID. This is used to identify the app within the database.
*/
val appId: String,
val appId: String?,

/**
* Control whether the Embrace SDK is able to capture native crashes.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import io.embrace.android.embracesdk.comms.delivery.DeliveryService
import io.embrace.android.embracesdk.comms.delivery.EmbraceDeliveryService
import io.embrace.android.embracesdk.comms.delivery.NoopDeliveryService
import io.embrace.android.embracesdk.worker.WorkerName
import io.embrace.android.embracesdk.worker.WorkerThreadModule

Expand All @@ -18,12 +19,17 @@
) : DeliveryModule {

override val deliveryService: DeliveryService by singleton {
EmbraceDeliveryService(
storageModule.deliveryCacheManager,
essentialServiceModule.apiService,
workerThreadModule.backgroundWorker(WorkerName.DELIVERY_CACHE),
coreModule.jsonSerializer,
initModule.logger
)
val apiService = essentialServiceModule.apiService
if (apiService == null) {
NoopDeliveryService()

Check warning on line 24 in embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/injection/DeliveryModule.kt

View check run for this annotation

Codecov / codecov/patch

embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/injection/DeliveryModule.kt#L24

Added line #L24 was not covered by tests
} else {
EmbraceDeliveryService(
storageModule.deliveryCacheManager,
apiService,
workerThreadModule.backgroundWorker(WorkerName.DELIVERY_CACHE),
coreModule.jsonSerializer,
initModule.logger
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
val userService: UserService
val urlBuilder: ApiUrlBuilder
val apiClient: ApiClient
val apiService: ApiService
val apiService: ApiService?
val sharedObjectLoader: SharedObjectLoader
val cpuInfoDelegate: CpuInfoDelegate
val deviceArchitecture: DeviceArchitecture
Expand Down Expand Up @@ -95,6 +95,7 @@
coreModule.context.packageName,
customAppId,
coreModule.jsonSerializer,
openTelemetryModule.openTelemetryConfiguration,
initModule.logger
)
}
Expand Down Expand Up @@ -226,7 +227,7 @@
thresholdCheck = thresholdCheck,
localSupplier = localConfig.sdkConfig::baseUrls,
)

checkNotNull(appId)
fractalwrench marked this conversation as resolved.
Show resolved Hide resolved
val coreBaseUrl = sdkEndpointBehavior.getData(appId)
val configBaseUrl = sdkEndpointBehavior.getConfig(appId)

Expand Down Expand Up @@ -278,7 +279,10 @@
}
}

override val apiService: ApiService by singleton {
override val apiService: ApiService? by singleton {
if (appId == null) {
return@singleton null

Check warning on line 284 in embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/injection/EssentialServiceModule.kt

View check run for this annotation

Codecov / codecov/patch

embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/injection/EssentialServiceModule.kt#L284

Added line #L284 was not covered by tests
}
Systrace.traceSynchronous("api-service-init") {
EmbraceApiService(
apiClient = apiClient,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,7 @@
ex
)
} catch (ex: Resources.NotFoundException) {
throw IllegalArgumentException(
"No resource found for $buildProperty property. Failed to create build info.",
ex
)
null

Check warning on line 69 in embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/BuildInfo.kt

View check run for this annotation

Codecov / codecov/patch

embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/BuildInfo.kt#L69

Added line #L69 was not covered by tests
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,6 @@ internal class OpenTelemetryConfiguration(
fun addLogExporter(logExporter: LogRecordExporter) {
externalLogExporters.add(logExporter)
}

fun hasConfiguredOtelExporters() = externalLogExporters.isNotEmpty() || externalSpanExporters.isNotEmpty()
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
internal data class NetworkEvent(
@Json(name = "app_id")
val appId: String,
val appId: String?,

@Json(name = "a")
val appInfo: AppInfo,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,14 @@ import io.embrace.android.embracesdk.gating.SessionGatingKeys.SESSION_PROPERTIES
import io.embrace.android.embracesdk.gating.SessionGatingKeys.SESSION_USER_TERMINATION
import io.embrace.android.embracesdk.gating.SessionGatingKeys.STARTUP_MOMENT
import io.embrace.android.embracesdk.gating.SessionGatingKeys.USER_PERSONAS
import io.embrace.android.embracesdk.internal.SystemInfo
import io.embrace.android.embracesdk.internal.logs.LogSinkImpl
import io.embrace.android.embracesdk.internal.serialization.EmbraceSerializer
import io.embrace.android.embracesdk.internal.spans.SpanSinkImpl
import io.embrace.android.embracesdk.internal.utils.Uuid
import io.embrace.android.embracesdk.logging.EmbLogger
import io.embrace.android.embracesdk.logging.EmbLoggerImpl
import io.embrace.android.embracesdk.opentelemetry.OpenTelemetryConfiguration
import io.embrace.android.embracesdk.payload.DiskUsage
import io.embrace.android.embracesdk.payload.Event
import io.embrace.android.embracesdk.payload.EventMessage
Expand Down Expand Up @@ -81,6 +85,13 @@ internal class EmbraceGatingServiceV1PayloadTest {
LOGS_WARN
)

private val otelCfg = OpenTelemetryConfiguration(
SpanSinkImpl(),
LogSinkImpl(),
SystemInfo(),
"my-id"
)

private lateinit var sessionBehavior: SessionBehavior
private var cfg: RemoteConfig? = RemoteConfig()

Expand Down Expand Up @@ -176,6 +187,7 @@ internal class EmbraceGatingServiceV1PayloadTest {
"]" +
"}}",
EmbraceSerializer(),
otelCfg,
EmbLoggerImpl()
)

Expand Down
Loading