Skip to content

Commit

Permalink
refactor: remove unnecessary serialization functions
Browse files Browse the repository at this point in the history
  • Loading branch information
fractalwrench committed Dec 6, 2023
1 parent c666da0 commit 84c56dd
Show file tree
Hide file tree
Showing 17 changed files with 75 additions and 158 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,12 @@ internal class LogMessageTest : BaseTest() {
assertTrue(file.exists() && !file.isDirectory)
readFile(file, "/v1/log/logging")
val serializer = EmbraceSerializer()
file.bufferedReader().use { bufferedReader ->
val obj = serializer.fromJson(bufferedReader, PendingApiCalls::class.java)
val pendingApiCall = obj.pollNextPendingApiCall()
checkNotNull(pendingApiCall)
val pendingApiCallFileName = pendingApiCall.cachedPayloadFilename
assert(pendingApiCallFileName.isNotBlank())
readFileContent("Test log info fail", pendingApiCallFileName)
}
val obj = serializer.fromJson(file.inputStream(), PendingApiCalls::class.java)
val pendingApiCall = obj.pollNextPendingApiCall()
checkNotNull(pendingApiCall)
val pendingApiCallFileName = pendingApiCall.cachedPayloadFilename
assert(pendingApiCallFileName.isNotBlank())
readFileContent("Test log info fail", pendingApiCallFileName)
} catch (e: IOException) {
fail("IOException error: ${e.message}")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,11 @@ internal class MomentMessageTest : BaseTest() {
assertTrue(file.exists() && !file.isDirectory)
readFile(file, EmbraceEndpoint.EVENTS.url)
val serializer = EmbraceSerializer()
file.bufferedReader().use { bufferedReader ->
val obj = serializer.fromJson(bufferedReader, PendingApiCalls::class.java)
val pendingApiCall = obj.pollNextPendingApiCall()
checkNotNull(pendingApiCall)
val pendingApiCallFileName = pendingApiCall.cachedPayloadFilename
assert(pendingApiCallFileName.isNotBlank())
readFileContent("\"t\":\"start\"", pendingApiCallFileName)
}
val obj = serializer.fromJson(file.inputStream(), PendingApiCalls::class.java)
val pendingApiCall = checkNotNull(obj.pollNextPendingApiCall())
val pendingApiCallFileName = pendingApiCall.cachedPayloadFilename
assert(pendingApiCallFileName.isNotBlank())
readFileContent("\"t\":\"start\"", pendingApiCallFileName)
} catch (e: IOException) {
fail("IOException error: ${e.message}")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import io.embrace.android.embracesdk.logging.InternalStaticEmbraceLogger
import java.io.Closeable
import java.io.File
import java.io.IOException
import java.io.InputStreamReader
import java.net.CacheResponse
import java.net.URI

Expand Down Expand Up @@ -59,9 +58,7 @@ internal class ApiResponseCache @JvmOverloads constructor(
fun retrieveCachedConfig(url: String, request: ApiRequest): CachedConfig {
val cachedResponse = retrieveCacheResponse(url, request)
val obj = cachedResponse?.runCatching {
InputStreamReader(body).buffered().use {
serializer.fromJson(it, RemoteConfig::class.java)
}
serializer.fromJson(body, RemoteConfig::class.java)

Check warning on line 61 in embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/comms/api/ApiResponseCache.kt

View check run for this annotation

Codecov / codecov/patch

embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/comms/api/ApiResponseCache.kt#L61

Added line #L61 was not covered by tests
}?.getOrNull()
val eTag = cachedResponse?.let { retrieveETag(cachedResponse) }
return CachedConfig(obj, eTag)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import io.embrace.android.embracesdk.payload.BlobMessage
import io.embrace.android.embracesdk.payload.EventMessage
import io.embrace.android.embracesdk.payload.NetworkEvent
import java.io.ByteArrayInputStream
import java.io.StringReader
import java.util.concurrent.Future
import java.util.concurrent.ScheduledExecutorService
import java.util.concurrent.TimeUnit
Expand Down Expand Up @@ -63,7 +62,9 @@ internal class EmbraceApiService(
return when (val response = apiClient.executeGet(request)) {
is ApiResponse.Success -> {
logger.logInfo("Fetched new config successfully.")
serializer.fromJson(StringReader(response.body), RemoteConfig::class.java)
response.body?.let {
serializer.fromJson(it, RemoteConfig::class.java)
}
}
is ApiResponse.NotModified -> {
logger.logInfo("Confirmed config has not been modified.")
Expand Down Expand Up @@ -150,7 +151,7 @@ internal class EmbraceApiService(
* @param eventMessage the event message containing the event
*/
override fun sendEventAndWait(eventMessage: EventMessage) {
post(eventMessage, mapper::eventMessageRequest)?.get()
post(eventMessage, mapper::eventMessageRequest).get()

Check warning on line 154 in embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/comms/api/EmbraceApiService.kt

View check run for this annotation

Codecov / codecov/patch

embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/comms/api/EmbraceApiService.kt#L154

Added line #L154 was not covered by tests
}

/**
Expand All @@ -160,7 +161,7 @@ internal class EmbraceApiService(
*/
override fun sendCrash(crash: EventMessage) {
try {
post(crash, mapper::eventMessageRequest) { cacheManager.deleteCrash() }?.get(
post(crash, mapper::eventMessageRequest) { cacheManager.deleteCrash() }.get(
CRASH_TIMEOUT,
TimeUnit.SECONDS
)
Expand All @@ -178,16 +179,11 @@ internal class EmbraceApiService(
payload: T,
mapper: (T) -> ApiRequest,
noinline onComplete: (() -> Unit)? = null
): Future<*>? {
val bytes = serializer.bytesFromPayload(payload, T::class.java)
): Future<*> {
val bytes = serializer.toJson(payload).toByteArray()
val request: ApiRequest = mapper(payload)

bytes?.let {
logger.logDeveloper(TAG, "Post event")
return postOnExecutor(it, request, onComplete)
}
logger.logError("Failed to post event")
return null
logger.logDeveloper(TAG, "Post event")
return postOnExecutor(bytes, request, onComplete)
}

private fun postOnExecutor(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,7 @@ internal class EmbraceCacheService(
logger.logDeveloper(TAG, "Attempting to cache object: $name")
val file = File(storageDir, EMBRACE_PREFIX + name)
try {
file.bufferedWriter().use {
serializer.toJson(objectToCache, clazz, it)
}
serializer.toJson(objectToCache, clazz, file.outputStream())
} catch (ex: Exception) {
logger.logDebug("Failed to store cache object " + file.path, ex)
}
Expand All @@ -78,14 +76,7 @@ internal class EmbraceCacheService(
override fun <T> loadObject(name: String, clazz: Class<T>): T? {
val file = File(storageDir, EMBRACE_PREFIX + name)
try {
file.bufferedReader().use { bufferedReader ->
val obj = serializer.fromJson(bufferedReader, clazz)
if (obj != null) {
return obj
} else {
logger.logDeveloper("EmbraceCacheService", "Object $name not found")
}
}
return serializer.fromJson(file.inputStream(), clazz)
} catch (ex: FileNotFoundException) {
logger.logDebug("Cache file cannot be found " + file.path)
} catch (ex: Exception) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,18 +152,13 @@ internal class EmbraceDeliveryCacheManager(
return cachedSessions.keys.toList()
}

override fun saveBackgroundActivity(backgroundActivityMessage: BackgroundActivityMessage): ByteArray? {
override fun saveBackgroundActivity(backgroundActivityMessage: BackgroundActivityMessage): ByteArray {
val baId = backgroundActivityMessage.backgroundActivity.sessionId
val baBytes = serializer.bytesFromPayload(
backgroundActivityMessage,
BackgroundActivityMessage::class.java
)
val baBytes = serializer.toJson(backgroundActivityMessage).toByteArray()

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

View check run for this annotation

Codecov / codecov/patch

embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/comms/delivery/EmbraceDeliveryCacheManager.kt#L157

Added line #L157 was not covered by tests
// Do not add background activities to disk if we are over the limit
if (cachedSessions.size < MAX_SESSIONS_CACHED || cachedSessions.containsKey(baId)) {
baBytes?.let { bytes ->
saveBytes(baId) { filename ->
cacheService.cacheBytes(filename, bytes)
}
saveBytes(baId) { filename ->
cacheService.cacheBytes(filename, baBytes)

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

View check run for this annotation

Codecov / codecov/patch

embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/comms/delivery/EmbraceDeliveryCacheManager.kt#L160-L161

Added lines #L160 - L161 were not covered by tests
}
}
return baBytes
Expand Down Expand Up @@ -212,13 +207,9 @@ internal class EmbraceDeliveryCacheManager(
*/
override fun savePendingApiCalls(pendingApiCalls: PendingApiCalls) {
logger.logDeveloper(TAG, "Saving pending api calls")
serializer.bytesFromPayload(
pendingApiCalls,
PendingApiCalls::class.java
)?.let {
executorService.submit {
cacheService.cacheBytes(PENDING_API_CALLS_FILE_NAME, it)
}
val bytes = serializer.toJson(pendingApiCalls).toByteArray()
executorService.submit {
cacheService.cacheBytes(PENDING_API_CALLS_FILE_NAME, bytes)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,66 +1,47 @@
package io.embrace.android.embracesdk.internal

import com.google.gson.GsonBuilder
import com.google.gson.JsonIOException
import com.google.gson.reflect.TypeToken
import com.google.gson.stream.JsonReader
import com.google.gson.stream.JsonWriter
import io.embrace.android.embracesdk.comms.api.EmbraceUrl
import io.embrace.android.embracesdk.comms.api.EmbraceUrlAdapter
import io.embrace.android.embracesdk.internal.utils.threadLocal
import io.embrace.android.embracesdk.logging.InternalStaticEmbraceLogger
import java.io.BufferedWriter
import java.io.Reader
import java.lang.reflect.Type
import java.nio.charset.Charset
import java.io.InputStream
import java.io.OutputStream

/**
* A wrapper around Gson to allow for thread-safe serialization.
*/
internal class EmbraceSerializer {

private val gson by threadLocal {
private val impl by threadLocal {
GsonBuilder()
.registerTypeAdapter(EmbraceUrl::class.java, EmbraceUrlAdapter())
.create()
}

fun <T> toJson(src: T): String {
return gson.toJson(src) ?: throw JsonIOException("Failed converting object to JSON.")
return impl.toJson(src)
}

fun <T> toJson(src: T, type: Type): String {
return gson.toJson(src, type)
?: throw JsonIOException("Failed converting object to JSON.")
}

fun <T> toJson(any: T, clazz: Class<T>, writer: BufferedWriter): Boolean {
return try {
gson.toJson(any, clazz, JsonWriter(writer))
true
} catch (e: Exception) {
InternalStaticEmbraceLogger.logDebug("cannot write to bufferedWriter", e)
false
fun <T> toJson(any: T, clazz: Class<T>, outputStream: OutputStream) {
outputStream.writer().buffered().use {
impl.toJson(any, clazz, JsonWriter(it))
}
}

fun <T> fromJson(json: String, type: Type): T {
return gson.fromJson(json, type)
}

fun <T> fromJson(json: String, clz: Class<T>): T {
return gson.fromJson(json, clz)
return impl.fromJson(json, clz)
}

fun <T> fromJson(reader: Reader, clz: Class<T>): T {
return gson.fromJson(reader, clz)
}

fun <T> fromJson(json: String): T {
return gson.fromJson(json, object : TypeToken<T>() {}.type)
fun <T> fromJson(inputStream: InputStream, clz: Class<T>): T {
inputStream.bufferedReader().use {
return impl.fromJson(JsonReader(it), clz)
}
}

fun <T> bytesFromPayload(payload: T, clazz: Class<T>): ByteArray? {
val json = toJson(payload, clazz)
return json.toByteArray(Charset.forName("UTF-8"))
fun <T> fromJsonWithTypeToken(json: String): T {
return impl.fromJson(json, object : TypeToken<T>() {}.type)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ protected List<NativeCrashDataError> getNativeCrashErrors(NativeCrashData native
String errorsRaw = delegate._getErrors(absolutePath);
if (errorsRaw != null) {
try {
return serializer.<ArrayList<NativeCrashDataError>>fromJson(errorsRaw);
return serializer.<ArrayList<NativeCrashDataError>>fromJsonWithTypeToken(errorsRaw);
} catch (Exception e) {
logger.logError("Failed to parse native crash error file {crashId=" + nativeCrash.getNativeCrashId() +
", errorFilePath=" + absolutePath + "}");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ internal data class Crash(
var jsExceptions: List<String>? = null
if (jsException != null) {
try {
val jsonException = serializer.toJson(jsException, jsException.javaClass).toByteArray()
val jsonException = serializer.toJson(jsException).toByteArray()
val encodedString = Base64.encodeToString(jsonException, Base64.NO_WRAP)
jsExceptions = listOf(encodedString)
} catch (ex: Exception) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ internal class EmbracePreferencesService(
key: String
): Map<String, String>? {
val mapString = getString(key, null) ?: return null
return serializer.fromJson<HashMap<String, String>>(mapString)
return serializer.fromJsonWithTypeToken<HashMap<String, String>>(mapString)
}

override var appVersion: String?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,7 @@ package io.embrace.android.embracesdk.session

import io.embrace.android.embracesdk.comms.api.ApiClient
import io.embrace.android.embracesdk.internal.EmbraceSerializer
import io.embrace.android.embracesdk.payload.AppInfo
import io.embrace.android.embracesdk.payload.Breadcrumbs
import io.embrace.android.embracesdk.payload.DeviceInfo
import io.embrace.android.embracesdk.payload.PerformanceInfo
import io.embrace.android.embracesdk.payload.Session
import io.embrace.android.embracesdk.payload.SessionMessage
import io.embrace.android.embracesdk.payload.UserInfo
import java.io.BufferedWriter
import java.io.StringWriter
import java.io.Writer
Expand Down Expand Up @@ -42,26 +36,26 @@ internal class SessionMessageSerializer(
private fun BufferedWriter.serializeImpl(msg: SessionMessage) {
append("{")

val session = jsonValue(msg, "s", Session::class.java, SessionMessage::session)
val session = jsonValue(msg, "s", SessionMessage::session)
addJsonProperty("\"s\":", session)

val userInfo = jsonValue(msg, "u", UserInfo::class.java, SessionMessage::userInfo)
val userInfo = jsonValue(msg, "u", SessionMessage::userInfo)
addJsonProperty("\"u\":", userInfo)

val appInfo = jsonValue(msg, "a", AppInfo::class.java, SessionMessage::appInfo)
val appInfo = jsonValue(msg, "a", SessionMessage::appInfo)
addJsonProperty("\"a\":", appInfo)

val deviceInfo = jsonValue(msg, "d", DeviceInfo::class.java, SessionMessage::deviceInfo)
val deviceInfo = jsonValue(msg, "d", SessionMessage::deviceInfo)
addJsonProperty("\"d\":", deviceInfo)

val performanceInfo =
jsonValue(msg, "p", PerformanceInfo::class.java, SessionMessage::performanceInfo)
jsonValue(msg, "p", SessionMessage::performanceInfo)
addJsonProperty("\"p\":", performanceInfo)

val breadcrumbs = jsonValue(msg, "br", Breadcrumbs::class.java, SessionMessage::breadcrumbs)
val breadcrumbs = jsonValue(msg, "br", SessionMessage::breadcrumbs)
addJsonProperty("\"br\":", breadcrumbs)

val spans = jsonValue(msg, "spans", List::class.java, SessionMessage::spans)
val spans = jsonValue(msg, "spans", SessionMessage::spans)
addJsonProperty("\"spans\":", spans)

append("\"v\":")
Expand All @@ -80,7 +74,6 @@ internal class SessionMessageSerializer(
private fun <T> jsonValue(
msg: SessionMessage,
key: String,
clz: Class<T>,
fieldProvider: (sessionMessage: SessionMessage) -> T?
): String {
return runCatching {
Expand All @@ -90,7 +83,7 @@ internal class SessionMessageSerializer(
val isCacheValid = newValue == oldValue
return when {
cache != null && isCacheValid -> cache
else -> return serializer.toJson(newValue, clz).apply {
else -> return serializer.toJson(newValue).apply {
jsonCache[key] = this
}
}
Expand Down
Loading

0 comments on commit 84c56dd

Please sign in to comment.