Skip to content

Commit

Permalink
Merge pull request #2022 from Adyen/chore/improve-network-logging
Browse files Browse the repository at this point in the history
Improve network logging
  • Loading branch information
OscarSpruit authored Feb 26, 2025
2 parents cc86587 + 07514c3 commit b0bcc86
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright (c) 2025 Adyen N.V.
*
* This file is open source and available under the MIT license. See the LICENSE file for more info.
*
* Created by oscars on 21/2/2025.
*/

package com.adyen.checkout.core.internal.data.api

import androidx.annotation.RestrictTo

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
data class AdyenApiResponse(
val path: String,
val statusCode: Int,
val headers: Map<String, String>,
val body: String,
)
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ interface HttpClient {
path: String,
queryParameters: Map<String, String> = emptyMap(),
headers: Map<String, String> = emptyMap()
): ByteArray
): AdyenApiResponse

suspend fun post(
path: String,
jsonBody: String,
queryParameters: Map<String, String> = emptyMap(),
headers: Map<String, String> = emptyMap()
): ByteArray
): AdyenApiResponse
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,11 @@ suspend fun <T : ModelObject> HttpClient.get(
): T {
adyenLog(AdyenLogLevel.DEBUG) { "GET - $path" }

val result = runAndLogHttpException { get(path, queryParameters) }
val resultJson = result.toJSONObject()
val response = runAndLogHttpException { get(path, queryParameters) }

adyenLog(AdyenLogLevel.VERBOSE) { "response - ${resultJson.toStringPretty()}" }
logResponse(response)

return responseSerializer.deserialize(resultJson)
return responseSerializer.deserialize(response.body.toJSONObject())
}

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
Expand All @@ -43,12 +42,11 @@ suspend fun <T : ModelObject> HttpClient.getList(
): List<T> {
adyenLog(AdyenLogLevel.DEBUG) { "GET - $path" }

val result = runAndLogHttpException { get(path, queryParameters) }
val resultJson = JSONArray(String(result, Charsets.UTF_8))
val response = runAndLogHttpException { get(path, queryParameters) }

adyenLog(AdyenLogLevel.VERBOSE) { "response - ${resultJson.toStringPretty()}" }
logResponse(response)

return ModelUtils.deserializeOptList(resultJson, responseSerializer).orEmpty()
return ModelUtils.deserializeOptList(JSONArray(response.body), responseSerializer).orEmpty()
}

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
Expand All @@ -65,12 +63,11 @@ suspend fun <T : ModelObject, R : ModelObject> HttpClient.post(

adyenLog(AdyenLogLevel.VERBOSE) { "request - ${requestJson.toStringPretty()}" }

val result = runAndLogHttpException { post(path, requestJson.toString(), queryParameters) }
val resultJson = result.toJSONObject()
val response = runAndLogHttpException { post(path, requestJson.toString(), queryParameters) }

adyenLog(AdyenLogLevel.VERBOSE) { "response - ${resultJson.toStringPretty()}" }
logResponse(response)

return responseSerializer.deserialize(resultJson)
return responseSerializer.deserialize(response.body.toJSONObject())
}

private inline fun <T : Any, R> T.runAndLogHttpException(block: T.() -> R): R {
Expand All @@ -90,10 +87,19 @@ private fun HttpException.getLogMessage(): String {
}
}

private fun ByteArray.toJSONObject(): JSONObject {
private fun String.toJSONObject(): JSONObject {
return if (isEmpty()) {
JSONObject()
} else {
JSONObject(String(this, Charsets.UTF_8))
JSONObject(this)
}
}

private fun Any.logResponse(response: AdyenApiResponse) {
adyenLog(AdyenLogLevel.VERBOSE) { "response - ${response.statusCode} .../${response.path}" }
response.headers.forEach { (key, value) ->
adyenLog(AdyenLogLevel.VERBOSE) { "$key: $value" }
}
adyenLog(AdyenLogLevel.VERBOSE) { response.body.toJSONObject().toStringPretty() }
adyenLog(AdyenLogLevel.VERBOSE) { "response - END" }
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,29 +34,29 @@ internal class OkHttpClient(
path: String,
queryParameters: Map<String, String>,
headers: Map<String, String>
): ByteArray {
): AdyenApiResponse {
val request = Request.Builder()
.headers(headers.combineToHeaders())
.url(buildURL(path, queryParameters))
.get()
.build()

return executeRequest(request)
return executeRequest(request, path)
}

override suspend fun post(
path: String,
jsonBody: String,
queryParameters: Map<String, String>,
headers: Map<String, String>
): ByteArray {
): AdyenApiResponse {
val request = Request.Builder()
.headers(headers.combineToHeaders())
.url(buildURL(path, queryParameters))
.post(jsonBody.toRequestBody(MEDIA_TYPE_JSON))
.build()

return executeRequest(request)
return executeRequest(request, path)
}

private fun buildURL(path: String, queryParameters: Map<String, String>): String {
Expand All @@ -70,7 +70,7 @@ internal class OkHttpClient(
return builder.toString()
}

private fun executeRequest(request: Request): ByteArray {
private fun executeRequest(request: Request, path: String): AdyenApiResponse {
val call = client.newCall(request)

try {
Expand All @@ -81,7 +81,12 @@ internal class OkHttpClient(
?.bytes()
?: ByteArray(0)
response.body?.close()
return bytes
return AdyenApiResponse(
path = path,
statusCode = response.code,
headers = response.headers.toMap(),
body = String(bytes, Charsets.UTF_8),
)
} else {
val exception = response.getHttpException()
response.body?.close()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.adyen.checkout.components.core.internal.data.api

import com.adyen.checkout.components.core.internal.data.model.AnalyticsTrackRequest
import com.adyen.checkout.core.internal.data.api.AdyenApiResponse
import com.adyen.checkout.core.internal.data.api.HttpClient
import com.adyen.checkout.core.internal.data.model.EmptyResponse
import com.adyen.checkout.test.LoggingExtension
Expand Down Expand Up @@ -37,11 +38,11 @@ internal class AnalyticsServiceTest(
platform = "android",
info = emptyList(),
logs = emptyList(),
errors = emptyList()
errors = emptyList(),
)
val checkoutAttemptId = "testtest"
whenever(httpClient.post(eq("v3/analytics/$checkoutAttemptId"), any(), any(), any()))
.doReturn(ByteArray(0))
.doReturn(AdyenApiResponse("", 0, emptyMap(), ""))

val response = analyticsService.sendEvents(request, checkoutAttemptId, TEST_CLIENT_KEY)

Expand Down

0 comments on commit b0bcc86

Please sign in to comment.