mirror of
https://github.com/openflocon/Flocon.git
synced 2026-05-20 00:29:35 +00:00
Refact network model (#123)
* refact: [NETWORK] model with error * refact: [NETWORK] model with error * refact: [NETWORK] model with error * refact: [NETWORK] model with error * refact: [NETWORK] model with error * refact * merged with main --------- Co-authored-by: Florent Champigny <florent@bere.al>
This commit is contained in:
parent
db3c8a118c
commit
35d896af23
31 changed files with 571 additions and 504 deletions
|
|
@ -2,11 +2,8 @@ package io.github.openflocon.flocon.plugins.network
|
|||
|
||||
import io.github.openflocon.flocon.core.FloconPlugin
|
||||
import io.github.openflocon.flocon.plugins.network.model.BadQualityConfig
|
||||
import io.github.openflocon.flocon.plugins.network.model.FloconNetworkCall
|
||||
import io.github.openflocon.flocon.plugins.network.model.FloconNetworkCallRequest
|
||||
import io.github.openflocon.flocon.plugins.network.model.FloconNetworkCallResponse
|
||||
import io.github.openflocon.flocon.plugins.network.model.FloconNetworkRequest
|
||||
import io.github.openflocon.flocon.plugins.network.model.FloconNetworkResponse
|
||||
import io.github.openflocon.flocon.plugins.network.model.MockNetworkResponse
|
||||
|
||||
interface FloconNetworkPlugin : FloconPlugin {
|
||||
|
|
|
|||
|
|
@ -25,4 +25,5 @@ data class FloconNetworkResponse(
|
|||
val body: String?,
|
||||
val size: Long?,
|
||||
val headers: Map<String, String>,
|
||||
val error: String?,
|
||||
)
|
||||
|
|
@ -39,6 +39,7 @@ fun floconNetworkCallResponseToJson(network: FloconNetworkCallResponse): JSONObj
|
|||
response.body?.let { json.put("responseBody", it) }
|
||||
json.put("responseHeaders", JSONObject(response.headers))
|
||||
json.put("responseSize", response.size)
|
||||
response.error?.let { json.put("responseError", it) }
|
||||
}
|
||||
|
||||
return json
|
||||
|
|
|
|||
|
|
@ -148,6 +148,7 @@ private class LoggingClientCallListener<RespT>(
|
|||
contentType = "grpc",
|
||||
size = 0L,
|
||||
grpcStatus = status.code.toString(),
|
||||
error = null,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,7 +110,8 @@ val FloconKtorPlugin = createClientPlugin("FloconKtorPlugin") {
|
|||
body = bodyString.takeUnless { isImage },
|
||||
headers = responseHeadersMap,
|
||||
size = responseSize,
|
||||
grpcStatus = null
|
||||
grpcStatus = null,
|
||||
error = null,
|
||||
)
|
||||
|
||||
floconNetworkPlugin.logResponse(
|
||||
|
|
|
|||
|
|
@ -149,6 +149,7 @@ class FloconOkhttpInterceptor() : Interceptor {
|
|||
headers = responseHeadersMap,
|
||||
size = responseSize,
|
||||
grpcStatus = null,
|
||||
error = null,
|
||||
)
|
||||
|
||||
floconNetworkPlugin.logResponse(
|
||||
|
|
@ -171,12 +172,13 @@ class FloconOkhttpInterceptor() : Interceptor {
|
|||
val durationMs: Double = (endTime - startTime) / 1e6
|
||||
|
||||
val floconCallResponse = FloconNetworkResponse(
|
||||
httpCode = 0,
|
||||
contentType = "error",
|
||||
body = e.message, // TODO better handle of errors
|
||||
httpCode = null,
|
||||
contentType = null,
|
||||
body = null,
|
||||
headers = emptyMap(),
|
||||
size = null,
|
||||
grpcStatus = null,
|
||||
error = e.message ?: e.javaClass.simpleName,
|
||||
)
|
||||
|
||||
floconNetworkPlugin.logResponse(
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@
|
|||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 41,
|
||||
"identityHash": "d699dfc54e3dbaa0e3ae992b29140a1e",
|
||||
"identityHash": "f1dea53a3a26fcc273eacc8cb3f47879",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "FloconNetworkCallEntity",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`callId` TEXT NOT NULL, `deviceId` TEXT NOT NULL, `packageName` TEXT NOT NULL, `type` TEXT NOT NULL, `request_url` TEXT NOT NULL, `request_method` TEXT NOT NULL, `request_startTime` INTEGER NOT NULL, `request_requestHeaders` TEXT NOT NULL, `request_requestBody` TEXT, `request_requestByteSize` INTEGER NOT NULL, `request_isMocked` INTEGER NOT NULL, `request_graphql_query` TEXT, `request_graphql_operationType` TEXT, `response_durationMs` REAL, `response_responseContentType` TEXT, `response_responseBody` TEXT, `response_responseHeaders` TEXT, `response_responseByteSize` INTEGER, `response_graphql_isSuccess` INTEGER, `response_graphql_responseHttpCode` INTEGER, `response_http_responseHttpCode` INTEGER, `response_grpc_responseStatus` TEXT, PRIMARY KEY(`callId`))",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`callId` TEXT NOT NULL, `deviceId` TEXT NOT NULL, `packageName` TEXT NOT NULL, `type` TEXT NOT NULL, `request_url` TEXT NOT NULL, `request_method` TEXT NOT NULL, `request_startTime` INTEGER NOT NULL, `request_requestHeaders` TEXT NOT NULL, `request_requestBody` TEXT, `request_requestByteSize` INTEGER NOT NULL, `request_isMocked` INTEGER NOT NULL, `request_graphql_query` TEXT, `request_graphql_operationType` TEXT, `response_durationMs` INTEGER, `response_responseContentType` TEXT, `response_responseBody` TEXT, `response_responseHeaders` TEXT, `response_responseByteSize` INTEGER, `response_responseError` TEXT, `response_graphql_isSuccess` INTEGER, `response_graphql_responseHttpCode` INTEGER, `response_http_responseHttpCode` INTEGER, `response_grpc_responseStatus` TEXT, PRIMARY KEY(`callId`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "callId",
|
||||
|
|
@ -86,7 +86,7 @@
|
|||
{
|
||||
"fieldPath": "response.durationMs",
|
||||
"columnName": "response_durationMs",
|
||||
"affinity": "REAL"
|
||||
"affinity": "INTEGER"
|
||||
},
|
||||
{
|
||||
"fieldPath": "response.responseContentType",
|
||||
|
|
@ -108,6 +108,11 @@
|
|||
"columnName": "response_responseByteSize",
|
||||
"affinity": "INTEGER"
|
||||
},
|
||||
{
|
||||
"fieldPath": "response.responseError",
|
||||
"columnName": "response_responseError",
|
||||
"affinity": "TEXT"
|
||||
},
|
||||
{
|
||||
"fieldPath": "response.graphql.isSuccess",
|
||||
"columnName": "response_graphql_isSuccess",
|
||||
|
|
@ -1089,7 +1094,7 @@
|
|||
],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'd699dfc54e3dbaa0e3ae992b29140a1e')"
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f1dea53a3a26fcc273eacc8cb3f47879')"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -36,7 +36,7 @@ import io.github.openflocon.flocondesktop.common.db.converters.MapStringsConvert
|
|||
import kotlinx.coroutines.Dispatchers
|
||||
|
||||
@Database(
|
||||
version = 41,
|
||||
version = 43,
|
||||
entities = [
|
||||
FloconNetworkCallEntity::class,
|
||||
FileEntity::class,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package io.github.openflocon.flocondesktop.features.network.detail.mapper
|
||||
|
||||
import io.github.openflocon.domain.network.models.FloconNetworkCallDomainModel
|
||||
import io.github.openflocon.domain.network.models.httpCode
|
||||
import io.github.openflocon.flocondesktop.common.ui.ByteFormatter
|
||||
import io.github.openflocon.flocondesktop.common.ui.JsonPrettyPrinter
|
||||
import io.github.openflocon.flocondesktop.features.network.detail.model.NetworkDetailHeaderUi
|
||||
|
|
@ -17,43 +18,70 @@ import io.github.openflocon.flocondesktop.features.network.list.model.NetworkSta
|
|||
|
||||
fun toDetailUi(request: FloconNetworkCallDomainModel): NetworkDetailViewState = NetworkDetailViewState(
|
||||
callId = request.callId,
|
||||
fullUrl = request.networkRequest.url,
|
||||
fullUrl = request.request.url,
|
||||
method = toDetailMethodUi(request),
|
||||
status = toDetailHttpStatusUi(request),
|
||||
requestTimeFormatted = request.networkRequest.startTime.let { formatTimestamp(it) },
|
||||
durationFormatted = request.networkResponse?.durationMs?.let { formatDuration(it) },
|
||||
requestTimeFormatted = request.request.startTime.let { formatTimestamp(it) },
|
||||
durationFormatted = request.response?.durationMs?.let { formatDuration(it) },
|
||||
// request
|
||||
requestBody = httpBodyToUi(request.networkRequest.body),
|
||||
requestHeaders = toNetworkHeadersUi(request.networkRequest.headers),
|
||||
requestSize = ByteFormatter.formatBytes(request.networkRequest.byteSize),
|
||||
requestBody = httpBodyToUi(request.request.body),
|
||||
requestHeaders = toNetworkHeadersUi(request.request.headers),
|
||||
requestSize = ByteFormatter.formatBytes(request.request.byteSize),
|
||||
// response
|
||||
response = request.networkResponse?.let {
|
||||
NetworkDetailViewState.Response(
|
||||
body = httpBodyToUi(it.body),
|
||||
size = ByteFormatter.formatBytes(it.byteSize),
|
||||
headers = toNetworkHeadersUi(it.headers),
|
||||
)
|
||||
response = request.response?.let {
|
||||
when(it) {
|
||||
is FloconNetworkCallDomainModel.Response.Failure -> NetworkDetailViewState.Response.Error(
|
||||
issue = it.issue,
|
||||
)
|
||||
is FloconNetworkCallDomainModel.Response.Success -> NetworkDetailViewState.Response.Success(
|
||||
body = httpBodyToUi(it.body),
|
||||
size = ByteFormatter.formatBytes(it.byteSize),
|
||||
headers = toNetworkHeadersUi(it.headers),
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
graphQlSection = graphQlSection(request),
|
||||
)
|
||||
|
||||
private fun toDetailHttpStatusUi(networkCall: FloconNetworkCallDomainModel): NetworkStatusUi = networkCall.networkResponse?.let { response ->
|
||||
when (networkCall) {
|
||||
is FloconNetworkCallDomainModel.Grpc -> toGrpcNetworkStatusUi(networkCall)
|
||||
// here for grphql we want the http code, the graphql status will be displayed on the specific graphql section
|
||||
is FloconNetworkCallDomainModel.GraphQl -> toNetworkStatusUi(code = networkCall.response!!.httpCode)
|
||||
is FloconNetworkCallDomainModel.Http -> toNetworkStatusUi(code = networkCall.response!!.httpCode)
|
||||
private fun toDetailHttpStatusUi(networkCall: FloconNetworkCallDomainModel): NetworkStatusUi = networkCall.response?.let { response ->
|
||||
when (response) {
|
||||
is FloconNetworkCallDomainModel.Response.Failure -> NetworkStatusUi(
|
||||
text = response.issue,
|
||||
status = NetworkStatusUi.Status.ERROR,
|
||||
)
|
||||
is FloconNetworkCallDomainModel.Response.Success -> when(val s = response.specificInfos) {
|
||||
is FloconNetworkCallDomainModel.Response.Success.SpecificInfos.Grpc -> toGrpcNetworkStatusUi(networkCall)
|
||||
// here for grphql we want the http code, the graphql status will be displayed on the specific graphql section
|
||||
is FloconNetworkCallDomainModel.Response.Success.SpecificInfos.GraphQl -> toNetworkStatusUi(code = s.httpCode)
|
||||
is FloconNetworkCallDomainModel.Response.Success.SpecificInfos.Http -> toNetworkStatusUi(code = s.httpCode)
|
||||
}
|
||||
}
|
||||
} ?: loadingStatus()
|
||||
|
||||
fun graphQlSection(networkCall: FloconNetworkCallDomainModel): NetworkDetailViewState.GraphQlSection? = (networkCall as? FloconNetworkCallDomainModel.GraphQl)?.let {
|
||||
NetworkDetailViewState.GraphQlSection(
|
||||
queryName = it.request.query,
|
||||
method = getMethodUi(networkCall),
|
||||
status = it.response?.isSuccess?.let {
|
||||
toGraphQlNetworkStatusUi(isSuccess = it)
|
||||
} ?: loadingStatus(),
|
||||
)
|
||||
fun graphQlSection(networkCall: FloconNetworkCallDomainModel): NetworkDetailViewState.GraphQlSection? {
|
||||
return (networkCall.request.specificInfos as? FloconNetworkCallDomainModel.Request.SpecificInfos.GraphQl)?.let {
|
||||
NetworkDetailViewState.GraphQlSection(
|
||||
queryName = it.query,
|
||||
method = getMethodUi(networkCall),
|
||||
status = graphQlStatus(networkCall) ?: return null
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun graphQlStatus(networkCall: FloconNetworkCallDomainModel) : NetworkStatusUi? {
|
||||
return when(val r = networkCall.response) {
|
||||
is FloconNetworkCallDomainModel.Response.Failure -> NetworkStatusUi(
|
||||
text = r.issue,
|
||||
status = NetworkStatusUi.Status.ERROR,
|
||||
)
|
||||
is FloconNetworkCallDomainModel.Response.Success -> when(val s = r.specificInfos) {
|
||||
is FloconNetworkCallDomainModel.Response.Success.SpecificInfos.GraphQl -> toGraphQlNetworkStatusUi(isSuccess = s.isSuccess)
|
||||
else -> null
|
||||
}
|
||||
null -> loadingStatus()
|
||||
}
|
||||
}
|
||||
|
||||
fun httpBodyToUi(body: String?): String = body?.let { JsonPrettyPrinter.prettyPrint(body) } ?: ""
|
||||
|
|
@ -68,12 +96,12 @@ fun toNetworkHeadersUi(headers: Map<String, String>?): List<NetworkDetailHeaderU
|
|||
}.sortedBy { it.name }
|
||||
} ?: emptyList()
|
||||
|
||||
fun toDetailMethodUi(request: FloconNetworkCallDomainModel): NetworkDetailViewState.Method = when (request) {
|
||||
is FloconNetworkCallDomainModel.Grpc -> NetworkDetailViewState.Method.MethodName(
|
||||
name = request.networkRequest.method,
|
||||
fun toDetailMethodUi(request: FloconNetworkCallDomainModel): NetworkDetailViewState.Method = when (request.request.specificInfos) {
|
||||
is FloconNetworkCallDomainModel.Request.SpecificInfos.Grpc -> NetworkDetailViewState.Method.MethodName(
|
||||
name = request.request.method,
|
||||
)
|
||||
|
||||
is FloconNetworkCallDomainModel.GraphQl,
|
||||
is FloconNetworkCallDomainModel.Http,
|
||||
-> NetworkDetailViewState.Method.Http(toHttpMethodUi(request.networkRequest.method))
|
||||
is FloconNetworkCallDomainModel.Request.SpecificInfos.GraphQl,
|
||||
is FloconNetworkCallDomainModel.Request.SpecificInfos.Http,
|
||||
-> NetworkDetailViewState.Method.Http(toHttpMethodUi(request.request.method))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,11 +24,18 @@ data class NetworkDetailViewState(
|
|||
val response: Response?,
|
||||
) {
|
||||
@Immutable
|
||||
data class Response(
|
||||
val body: String,
|
||||
val size: String,
|
||||
val headers: List<NetworkDetailHeaderUi>,
|
||||
)
|
||||
sealed interface Response {
|
||||
@Immutable
|
||||
data class Success(
|
||||
val body: String,
|
||||
val size: String,
|
||||
val headers: List<NetworkDetailHeaderUi>,
|
||||
) : Response
|
||||
@Immutable
|
||||
data class Error(
|
||||
val issue: String,
|
||||
) : Response
|
||||
}
|
||||
|
||||
@Immutable
|
||||
data class GraphQlSection(
|
||||
|
|
|
|||
|
|
@ -122,11 +122,11 @@ private fun Request(
|
|||
Column {
|
||||
Column(
|
||||
modifier =
|
||||
Modifier
|
||||
.background(
|
||||
color = FloconTheme.colorPalette.surfaceVariant,
|
||||
shape = RoundedCornerShape(12.dp),
|
||||
).padding(horizontal = 8.dp, vertical = 4.dp),
|
||||
Modifier
|
||||
.background(
|
||||
color = FloconTheme.colorPalette.surfaceVariant,
|
||||
shape = RoundedCornerShape(12.dp),
|
||||
).padding(horizontal = 8.dp, vertical = 4.dp),
|
||||
) {
|
||||
DetailLineTextView(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
|
|
@ -198,11 +198,11 @@ private fun Request(
|
|||
) {
|
||||
Column(
|
||||
modifier =
|
||||
Modifier
|
||||
.background(
|
||||
color = FloconTheme.colorPalette.surfaceVariant,
|
||||
shape = RoundedCornerShape(12.dp),
|
||||
).padding(horizontal = 8.dp, vertical = 4.dp),
|
||||
Modifier
|
||||
.background(
|
||||
color = FloconTheme.colorPalette.surfaceVariant,
|
||||
shape = RoundedCornerShape(12.dp),
|
||||
).padding(horizontal = 8.dp, vertical = 4.dp),
|
||||
) {
|
||||
DetailLineTextView(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
|
|
@ -304,53 +304,72 @@ private fun Response(
|
|||
expanded = isResponseExpanded,
|
||||
) {
|
||||
// headers
|
||||
Column {
|
||||
DetailSectionTitleView(
|
||||
isExpanded = isResponseHeadersExpanded,
|
||||
title = "Response Headers",
|
||||
onCopy = null,
|
||||
onToggle = {
|
||||
isResponseHeadersExpanded = it
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
FloconSectionExpandable(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
expanded = isResponseHeadersExpanded,
|
||||
) {
|
||||
DetailHeadersView(
|
||||
headers = response.headers,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
labelWidth = headersLabelWidth,
|
||||
)
|
||||
}
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
when (response) {
|
||||
is NetworkDetailViewState.Response.Error -> {
|
||||
FloconSectionExpandable(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
expanded = isResponseBodyExpanded,
|
||||
) {
|
||||
CodeBlockView(
|
||||
code = response.issue,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// body
|
||||
DetailSectionTitleView(
|
||||
isExpanded = isResponseBodyExpanded,
|
||||
title = "Response Body",
|
||||
onCopy = { onAction(NetworkAction.CopyText(response.body)) },
|
||||
onToggle = {
|
||||
isResponseBodyExpanded = it
|
||||
},
|
||||
onDetail = {
|
||||
onAction(
|
||||
NetworkAction.JsonDetail(
|
||||
state.callId + "response",
|
||||
response.body,
|
||||
),
|
||||
is NetworkDetailViewState.Response.Success -> {
|
||||
DetailSectionTitleView(
|
||||
isExpanded = isResponseHeadersExpanded,
|
||||
title = "Response Headers",
|
||||
onCopy = null,
|
||||
onToggle = {
|
||||
isResponseHeadersExpanded = it
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
FloconSectionExpandable(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
expanded = isResponseBodyExpanded,
|
||||
) {
|
||||
CodeBlockView(
|
||||
code = response.body,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
FloconSectionExpandable(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
expanded = isResponseHeadersExpanded,
|
||||
) {
|
||||
DetailHeadersView(
|
||||
headers = response.headers,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
labelWidth = headersLabelWidth,
|
||||
)
|
||||
}
|
||||
|
||||
// body
|
||||
DetailSectionTitleView(
|
||||
isExpanded = isResponseBodyExpanded,
|
||||
title = "Response Body",
|
||||
onCopy = { onAction(NetworkAction.CopyText(response.body)) },
|
||||
onToggle = {
|
||||
isResponseBodyExpanded = it
|
||||
},
|
||||
onDetail = {
|
||||
onAction(
|
||||
NetworkAction.JsonDetail(
|
||||
state.callId + "response",
|
||||
response.body,
|
||||
),
|
||||
)
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
FloconSectionExpandable(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
expanded = isResponseBodyExpanded,
|
||||
) {
|
||||
CodeBlockView(
|
||||
code = response.body,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -367,18 +386,18 @@ private fun NetworkDetailViewPreview() {
|
|||
fullUrl = "http://www.google.com",
|
||||
method = NetworkDetailViewState.Method.Http(NetworkMethodUi.Http.GET),
|
||||
status =
|
||||
NetworkStatusUi(
|
||||
text = "200",
|
||||
status = NetworkStatusUi.Status.SUCCESS,
|
||||
),
|
||||
NetworkStatusUi(
|
||||
text = "200",
|
||||
status = NetworkStatusUi.Status.SUCCESS,
|
||||
),
|
||||
requestHeaders =
|
||||
listOf(
|
||||
previewNetworkDetailHeaderUi(),
|
||||
previewNetworkDetailHeaderUi(),
|
||||
previewNetworkDetailHeaderUi(),
|
||||
),
|
||||
listOf(
|
||||
previewNetworkDetailHeaderUi(),
|
||||
previewNetworkDetailHeaderUi(),
|
||||
previewNetworkDetailHeaderUi(),
|
||||
),
|
||||
requestBody =
|
||||
"""
|
||||
"""
|
||||
{
|
||||
"id": "123",
|
||||
"name": "Flocon App",
|
||||
|
|
@ -394,9 +413,9 @@ private fun NetworkDetailViewPreview() {
|
|||
requestTimeFormatted = "00:00:00.000",
|
||||
durationFormatted = "300ms",
|
||||
requestSize = "0kb",
|
||||
response = NetworkDetailViewState.Response(
|
||||
response = NetworkDetailViewState.Response.Success(
|
||||
body =
|
||||
"""
|
||||
"""
|
||||
{
|
||||
"networkStatusUi": "success",
|
||||
"message": "Data received and processed.",
|
||||
|
|
@ -408,13 +427,13 @@ private fun NetworkDetailViewPreview() {
|
|||
""".trimIndent(),
|
||||
size = "0kb",
|
||||
headers =
|
||||
listOf(
|
||||
previewNetworkDetailHeaderUi(),
|
||||
previewNetworkDetailHeaderUi(),
|
||||
previewNetworkDetailHeaderUi(),
|
||||
previewNetworkDetailHeaderUi(),
|
||||
previewNetworkDetailHeaderUi(),
|
||||
),
|
||||
listOf(
|
||||
previewNetworkDetailHeaderUi(),
|
||||
previewNetworkDetailHeaderUi(),
|
||||
previewNetworkDetailHeaderUi(),
|
||||
previewNetworkDetailHeaderUi(),
|
||||
previewNetworkDetailHeaderUi(),
|
||||
),
|
||||
),
|
||||
graphQlSection = null,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ class NetworkViewModel(
|
|||
viewModelScope.launch(dispatcherProvider.viewModel) {
|
||||
val domainModel = observeHttpRequestsByIdUseCase(action.item.uuid).firstOrNull()
|
||||
?: return@launch
|
||||
copyToClipboard(domainModel.networkRequest.url)
|
||||
copyToClipboard(domainModel.request.url)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,14 +3,14 @@ package io.github.openflocon.flocondesktop.features.network.list.mapper
|
|||
import io.github.openflocon.domain.network.models.FloconNetworkCallDomainModel
|
||||
import io.github.openflocon.flocondesktop.features.network.list.model.NetworkMethodUi
|
||||
|
||||
fun getMethodUi(networkRequest: FloconNetworkCallDomainModel): NetworkMethodUi = when (networkRequest) {
|
||||
is FloconNetworkCallDomainModel.GraphQl -> when (val t = networkRequest.request.operationType.lowercase()) {
|
||||
fun getMethodUi(networkCall: FloconNetworkCallDomainModel): NetworkMethodUi = when (val s = networkCall.request.specificInfos) {
|
||||
is FloconNetworkCallDomainModel.Request.SpecificInfos.GraphQl -> when (val t = s.operationType.lowercase()) {
|
||||
"query" -> NetworkMethodUi.GraphQl.QUERY
|
||||
"mutation" -> NetworkMethodUi.GraphQl.MUTATION
|
||||
else -> NetworkMethodUi.OTHER(networkRequest.request.operationType, icon = null)
|
||||
else -> NetworkMethodUi.OTHER(s.operationType, icon = null)
|
||||
}
|
||||
is FloconNetworkCallDomainModel.Http -> toHttpMethodUi(networkRequest.networkRequest.method)
|
||||
is FloconNetworkCallDomainModel.Grpc -> NetworkMethodUi.Grpc
|
||||
is FloconNetworkCallDomainModel.Request.SpecificInfos.Http -> toHttpMethodUi(networkCall.request.method)
|
||||
is FloconNetworkCallDomainModel.Request.SpecificInfos.Grpc -> NetworkMethodUi.Grpc
|
||||
}
|
||||
|
||||
fun toHttpMethodUi(httpMethod: String): NetworkMethodUi = when (httpMethod.lowercase()) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package io.github.openflocon.flocondesktop.features.network.list.mapper
|
||||
|
||||
import io.github.openflocon.domain.network.models.FloconNetworkCallDomainModel
|
||||
import io.github.openflocon.domain.network.models.byteSize
|
||||
import io.github.openflocon.flocondesktop.common.ui.ByteFormatter
|
||||
import io.github.openflocon.flocondesktop.features.network.list.model.NetworkItemViewState
|
||||
import io.ktor.http.Url
|
||||
|
|
@ -43,21 +44,21 @@ fun extractPath(url: String): String {
|
|||
|
||||
fun toUi(networkCall: FloconNetworkCallDomainModel): NetworkItemViewState = NetworkItemViewState(
|
||||
uuid = networkCall.callId,
|
||||
dateFormatted = formatTimestamp(networkCall.networkRequest.startTime),
|
||||
timeFormatted = networkCall.networkResponse?.durationMs?.let { formatDuration(it) },
|
||||
requestSize = ByteFormatter.formatBytes(networkCall.networkRequest.byteSize),
|
||||
responseSize = networkCall.networkResponse?.byteSize?.let { ByteFormatter.formatBytes(it) },
|
||||
dateFormatted = formatTimestamp(networkCall.request.startTime),
|
||||
timeFormatted = networkCall.response?.durationMs?.let { formatDuration(it) },
|
||||
requestSize = ByteFormatter.formatBytes(networkCall.request.byteSize),
|
||||
responseSize = networkCall.byteSize()?.let { ByteFormatter.formatBytes(it) },
|
||||
domain = getDomainUi(networkCall),
|
||||
type = toTypeUi(networkCall),
|
||||
method = getMethodUi(networkCall),
|
||||
status = getStatusUi(networkCall),
|
||||
isMocked = networkCall.networkRequest.isMocked,
|
||||
isMocked = networkCall.request.isMocked,
|
||||
)
|
||||
|
||||
fun getDomainUi(networkRequest: FloconNetworkCallDomainModel): String = when (networkRequest) {
|
||||
is FloconNetworkCallDomainModel.GraphQl -> extractDomainAndPath(networkRequest.networkRequest.url)
|
||||
is FloconNetworkCallDomainModel.Http -> extractDomain(networkRequest.networkRequest.url)
|
||||
is FloconNetworkCallDomainModel.Grpc -> networkRequest.networkRequest.url
|
||||
fun getDomainUi(networkRequest: FloconNetworkCallDomainModel): String = when (networkRequest.request.specificInfos) {
|
||||
is FloconNetworkCallDomainModel.Request.SpecificInfos.GraphQl -> extractDomainAndPath(networkRequest.request.url)
|
||||
is FloconNetworkCallDomainModel.Request.SpecificInfos.Http -> extractDomain(networkRequest.request.url)
|
||||
is FloconNetworkCallDomainModel.Request.SpecificInfos.Grpc -> networkRequest.request.url
|
||||
}
|
||||
|
||||
fun formatDuration(duration: Double): String = duration.milliseconds.toString(unit = DurationUnit.MILLISECONDS)
|
||||
|
|
|
|||
|
|
@ -8,11 +8,17 @@ fun loadingStatus() = NetworkStatusUi(
|
|||
status = NetworkStatusUi.Status.LOADING,
|
||||
)
|
||||
|
||||
fun getStatusUi(networkCall: FloconNetworkCallDomainModel): NetworkStatusUi = networkCall.networkResponse?.let { response ->
|
||||
when (val t = networkCall) {
|
||||
is FloconNetworkCallDomainModel.GraphQl -> toGraphQlNetworkStatusUi(isSuccess = t.response!!.isSuccess)
|
||||
is FloconNetworkCallDomainModel.Http -> toNetworkStatusUi(networkCall.response!!.httpCode)
|
||||
is FloconNetworkCallDomainModel.Grpc -> toGrpcNetworkStatusUi(t)
|
||||
fun getStatusUi(networkCall: FloconNetworkCallDomainModel): NetworkStatusUi = networkCall.response?.let { response ->
|
||||
when(response) {
|
||||
is FloconNetworkCallDomainModel.Response.Failure -> NetworkStatusUi(
|
||||
text = response.issue,
|
||||
status = NetworkStatusUi.Status.ERROR,
|
||||
)
|
||||
is FloconNetworkCallDomainModel.Response.Success -> when (val s = response.specificInfos) {
|
||||
is FloconNetworkCallDomainModel.Response.Success.SpecificInfos.GraphQl -> toGraphQlNetworkStatusUi(isSuccess = s.isSuccess)
|
||||
is FloconNetworkCallDomainModel.Response.Success.SpecificInfos.Http -> toNetworkStatusUi(s.httpCode)
|
||||
is FloconNetworkCallDomainModel.Response.Success.SpecificInfos.Grpc -> toGrpcNetworkStatusUi(networkCall)
|
||||
}
|
||||
}
|
||||
} ?: loadingStatus()
|
||||
|
||||
|
|
@ -26,11 +32,27 @@ fun toGraphQlNetworkStatusUi(isSuccess: Boolean): NetworkStatusUi = NetworkStatu
|
|||
status = if (isSuccess) NetworkStatusUi.Status.SUCCESS else NetworkStatusUi.Status.ERROR,
|
||||
)
|
||||
|
||||
fun toGrpcNetworkStatusUi(call: FloconNetworkCallDomainModel.Grpc): NetworkStatusUi {
|
||||
fun toGrpcNetworkStatusUi(call: FloconNetworkCallDomainModel): NetworkStatusUi {
|
||||
val response = call.response ?: return loadingStatus()
|
||||
val isSuccess = response.responseStatus == "OK"
|
||||
return NetworkStatusUi(
|
||||
text = response.responseStatus,
|
||||
status = if (isSuccess) NetworkStatusUi.Status.SUCCESS else NetworkStatusUi.Status.ERROR,
|
||||
)
|
||||
return when(response) {
|
||||
is FloconNetworkCallDomainModel.Response.Failure -> NetworkStatusUi(
|
||||
text = response.issue,
|
||||
status = NetworkStatusUi.Status.ERROR,
|
||||
)
|
||||
is FloconNetworkCallDomainModel.Response.Success -> {
|
||||
when(val s = response.specificInfos) {
|
||||
is FloconNetworkCallDomainModel.Response.Success.SpecificInfos.Grpc -> {
|
||||
val isSuccess = s.grpcStatus == "OK"
|
||||
NetworkStatusUi(
|
||||
text = s.grpcStatus,
|
||||
status = if (isSuccess) NetworkStatusUi.Status.SUCCESS else NetworkStatusUi.Status.ERROR,
|
||||
)
|
||||
}
|
||||
else -> NetworkStatusUi(
|
||||
text = "not a grpc response",
|
||||
status = NetworkStatusUi.Status.ERROR,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,22 +3,22 @@ package io.github.openflocon.flocondesktop.features.network.list.mapper
|
|||
import io.github.openflocon.domain.network.models.FloconNetworkCallDomainModel
|
||||
import io.github.openflocon.flocondesktop.features.network.list.model.NetworkItemViewState
|
||||
|
||||
fun toTypeUi(call: FloconNetworkCallDomainModel): NetworkItemViewState.NetworkTypeUi = when (call) {
|
||||
is FloconNetworkCallDomainModel.GraphQl -> NetworkItemViewState.NetworkTypeUi.GraphQl(
|
||||
queryName = call.request.query,
|
||||
fun toTypeUi(call: FloconNetworkCallDomainModel): NetworkItemViewState.NetworkTypeUi = when (val s = call.request.specificInfos) {
|
||||
is FloconNetworkCallDomainModel.Request.SpecificInfos.GraphQl -> NetworkItemViewState.NetworkTypeUi.GraphQl(
|
||||
queryName = s.query,
|
||||
)
|
||||
|
||||
is FloconNetworkCallDomainModel.Http -> {
|
||||
val query = extractPath(call.networkRequest.url)
|
||||
is FloconNetworkCallDomainModel.Request.SpecificInfos.Http -> {
|
||||
val query = extractPath(call.request.url)
|
||||
NetworkItemViewState.NetworkTypeUi.Url(
|
||||
query = query,
|
||||
method = call.networkRequest.method,
|
||||
method = call.request.method,
|
||||
)
|
||||
}
|
||||
|
||||
is FloconNetworkCallDomainModel.Grpc -> {
|
||||
is FloconNetworkCallDomainModel.Request.SpecificInfos.Grpc -> {
|
||||
NetworkItemViewState.NetworkTypeUi.Grpc(
|
||||
method = call.networkRequest.method,
|
||||
method = call.request.method,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,12 +45,12 @@ private fun sort(
|
|||
}
|
||||
|
||||
val comparator = when (sorted.column) {
|
||||
NetworkColumnsTypeUiModel.RequestTime -> compareBy<Pair<FloconNetworkCallDomainModel, NetworkItemViewState>> { it.first.networkRequest.startTime }
|
||||
NetworkColumnsTypeUiModel.RequestTime -> compareBy<Pair<FloconNetworkCallDomainModel, NetworkItemViewState>> { it.first.request.startTime }
|
||||
NetworkColumnsTypeUiModel.Method -> compareBy { it.second.method.text }
|
||||
NetworkColumnsTypeUiModel.Domain -> compareBy { it.second.domain }
|
||||
NetworkColumnsTypeUiModel.Query -> compareBy { it.second.type.text }
|
||||
NetworkColumnsTypeUiModel.Status -> compareBy { it.second.status.text }
|
||||
NetworkColumnsTypeUiModel.Time -> compareBy { it.first.networkResponse?.durationMs }
|
||||
NetworkColumnsTypeUiModel.Time -> compareBy { it.first.response?.durationMs }
|
||||
}
|
||||
|
||||
val sortedComparator = when (sorted.sort) {
|
||||
|
|
|
|||
|
|
@ -38,12 +38,12 @@ class ImagesRepositoryImpl(
|
|||
deviceId: String,
|
||||
call: FloconNetworkCallDomainModel,
|
||||
) {
|
||||
val duration = call.networkResponse?.durationMs ?: return
|
||||
val duration = call.response?.durationMs ?: return
|
||||
imagesLocalDataSource.addImage(
|
||||
deviceId = deviceId,
|
||||
image = DeviceImageDomainModel(
|
||||
url = call.networkRequest.url,
|
||||
time = (call.networkRequest.startTime + duration).toLong(),
|
||||
url = call.request.url,
|
||||
time = (call.request.startTime + duration).toLong(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import io.github.openflocon.domain.messages.models.FloconIncomingMessageDomainMo
|
|||
import io.github.openflocon.domain.network.models.BadQualityConfigDomainModel
|
||||
import io.github.openflocon.domain.network.models.FloconNetworkCallDomainModel
|
||||
import io.github.openflocon.domain.network.models.FloconNetworkCallIdDomainModel
|
||||
import io.github.openflocon.domain.network.models.FloconNetworkResponseDomainModel
|
||||
import io.github.openflocon.domain.network.models.FloconNetworkResponseOnlyDomainModel
|
||||
import io.github.openflocon.domain.network.models.MockNetworkDomainModel
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import io.github.openflocon.domain.network.models.BadQualityConfigId
|
|||
import io.github.openflocon.domain.network.models.FloconNetworkCallDomainModel
|
||||
import io.github.openflocon.domain.network.models.FloconNetworkResponseOnlyDomainModel
|
||||
import io.github.openflocon.domain.network.models.MockNetworkDomainModel
|
||||
import io.github.openflocon.domain.network.models.getContentType
|
||||
import io.github.openflocon.domain.network.repository.NetworkBadQualityRepository
|
||||
import io.github.openflocon.domain.network.repository.NetworkImageRepository
|
||||
import io.github.openflocon.domain.network.repository.NetworkMocksRepository
|
||||
|
|
@ -100,7 +101,7 @@ class NetworkRepositoryImpl(
|
|||
}
|
||||
toDomainForResponse(response = response, request = request)
|
||||
}?.let { call ->
|
||||
if (call.networkResponse?.contentType?.startsWith("image/") == true) {
|
||||
if (call.response?.getContentType()?.startsWith("image/") == true) {
|
||||
networkImageRepository.onImageReceived(deviceId = deviceId, call = call)
|
||||
}
|
||||
networkLocalDataSource.save(
|
||||
|
|
@ -159,48 +160,31 @@ class NetworkRepositoryImpl(
|
|||
response: FloconNetworkResponseOnlyDomainModel,
|
||||
request: FloconNetworkCallDomainModel,
|
||||
): FloconNetworkCallDomainModel? {
|
||||
try {
|
||||
val networkResponse = response.networkResponse
|
||||
|
||||
return when (request) {
|
||||
is FloconNetworkCallDomainModel.GraphQl -> {
|
||||
// throw an exception if not http
|
||||
val responseHttp = response as FloconNetworkResponseOnlyDomainModel.Http
|
||||
val response = FloconNetworkCallDomainModel.GraphQl.Response(
|
||||
networkResponse = networkResponse,
|
||||
httpCode = responseHttp.httpCode,
|
||||
isSuccess = responseHttp.httpCode in 200..299,
|
||||
)
|
||||
request.copy(
|
||||
response = response,
|
||||
)
|
||||
return try {
|
||||
val response = when (val r = response.response) {
|
||||
is FloconNetworkCallDomainModel.Response.Success -> {
|
||||
// specific case : map to graphQl if needed
|
||||
when (val s = r.specificInfos) {
|
||||
is FloconNetworkCallDomainModel.Response.Success.SpecificInfos.Http -> {
|
||||
r.copy(
|
||||
specificInfos = FloconNetworkCallDomainModel.Response.Success.SpecificInfos.GraphQl(
|
||||
httpCode = s.httpCode,
|
||||
isSuccess = s.httpCode in 200..299
|
||||
)
|
||||
)
|
||||
}
|
||||
else -> r
|
||||
}
|
||||
}
|
||||
|
||||
is FloconNetworkCallDomainModel.Grpc -> {
|
||||
val responseHttp = response as FloconNetworkResponseOnlyDomainModel.Grpc
|
||||
val response = FloconNetworkCallDomainModel.Grpc.Response(
|
||||
networkResponse = networkResponse,
|
||||
responseStatus = responseHttp.grpcStatus,
|
||||
)
|
||||
request.copy(
|
||||
response = response,
|
||||
)
|
||||
}
|
||||
|
||||
is FloconNetworkCallDomainModel.Http -> {
|
||||
val responseHttp = response as FloconNetworkResponseOnlyDomainModel.Http
|
||||
val response = FloconNetworkCallDomainModel.Http.Response(
|
||||
networkResponse = networkResponse,
|
||||
httpCode = responseHttp.httpCode,
|
||||
)
|
||||
request.copy(
|
||||
response = response,
|
||||
)
|
||||
}
|
||||
is FloconNetworkCallDomainModel.Response.Failure -> response.response
|
||||
}
|
||||
request.copy(
|
||||
response = response,
|
||||
)
|
||||
} catch (t: Throwable) {
|
||||
t.printStackTrace()
|
||||
return null
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,81 +2,68 @@ package io.github.openflocon.data.local.network.mapper
|
|||
|
||||
import io.github.openflocon.data.local.network.models.FloconNetwockCallEntityLite
|
||||
import io.github.openflocon.data.local.network.models.FloconNetworkCallType
|
||||
import io.github.openflocon.data.local.network.models.FloconNetworkRequestLiteEmbedded
|
||||
import io.github.openflocon.data.local.network.models.FloconNetworkResponseLiteEmbedded
|
||||
import io.github.openflocon.domain.network.models.FloconNetworkCallDomainModel
|
||||
import io.github.openflocon.domain.network.models.FloconNetworkRequestDomainModel
|
||||
import io.github.openflocon.domain.network.models.FloconNetworkResponseDomainModel
|
||||
import kotlin.Boolean
|
||||
|
||||
fun toDomainModel(request: FloconNetworkRequestLiteEmbedded): FloconNetworkRequestDomainModel {
|
||||
return with(request) {
|
||||
FloconNetworkRequestDomainModel(
|
||||
url = this.url,
|
||||
method = this.method,
|
||||
startTime = this.startTime,
|
||||
headers = this.requestHeaders,
|
||||
body = null, // null on lite
|
||||
byteSize = this.requestByteSize,
|
||||
isMocked = this.isMocked,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun FloconNetwockCallEntityLite.toDomainModel(): FloconNetworkCallDomainModel? {
|
||||
return try {
|
||||
val networkRequest = toDomainModel(request)
|
||||
when (type) {
|
||||
FloconNetworkCallType.HTTP -> FloconNetworkCallDomainModel.Http(
|
||||
callId = callId,
|
||||
networkRequest = networkRequest,
|
||||
response = response?.let {
|
||||
FloconNetworkCallDomainModel.Http.Response(
|
||||
httpCode = response.http!!.responseHttpCode,
|
||||
networkResponse = toDomainModel(response),
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
FloconNetworkCallType.GRAPHQL -> FloconNetworkCallDomainModel.GraphQl(
|
||||
callId = callId,
|
||||
request = FloconNetworkCallDomainModel.GraphQl.Request(
|
||||
networkRequest = networkRequest,
|
||||
query = request.graphql!!.query,
|
||||
operationType = request.graphql.operationType,
|
||||
),
|
||||
response = response?.let {
|
||||
FloconNetworkCallDomainModel.GraphQl.Response(
|
||||
httpCode = response.graphql!!.responseHttpCode,
|
||||
isSuccess = response.graphql.isSuccess,
|
||||
networkResponse = toDomainModel(response),
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
FloconNetworkCallType.GRPC -> FloconNetworkCallDomainModel.Grpc(
|
||||
callId = callId,
|
||||
networkRequest = networkRequest,
|
||||
response = response?.let {
|
||||
FloconNetworkCallDomainModel.Grpc.Response(
|
||||
networkResponse = toDomainModel(response),
|
||||
responseStatus = response.grpc!!.responseStatus,
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
FloconNetworkCallDomainModel(
|
||||
callId = callId,
|
||||
request = toRequestDomainModel(),
|
||||
response = response?.toDomainModel(),
|
||||
)
|
||||
} catch (t: Throwable) {
|
||||
t.printStackTrace()
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
private fun toDomainModel(response: FloconNetworkResponseLiteEmbedded): FloconNetworkResponseDomainModel = with(response) {
|
||||
FloconNetworkResponseDomainModel(
|
||||
contentType = responseContentType,
|
||||
private fun FloconNetwockCallEntityLite.toRequestDomainModel(): FloconNetworkCallDomainModel.Request =
|
||||
FloconNetworkCallDomainModel.Request(
|
||||
url = request.url,
|
||||
method = request.method,
|
||||
startTime = request.startTime,
|
||||
headers = request.requestHeaders,
|
||||
body = null, // null on lite
|
||||
headers = responseHeaders,
|
||||
byteSize = responseByteSize,
|
||||
durationMs = durationMs,
|
||||
byteSize = request.requestByteSize,
|
||||
isMocked = request.isMocked,
|
||||
specificInfos = when (type) {
|
||||
FloconNetworkCallType.HTTP -> FloconNetworkCallDomainModel.Request.SpecificInfos.Http
|
||||
FloconNetworkCallType.GRAPHQL -> FloconNetworkCallDomainModel.Request.SpecificInfos.GraphQl(
|
||||
query = request.graphql!!.query,
|
||||
operationType = request.graphql.operationType,
|
||||
)
|
||||
|
||||
FloconNetworkCallType.GRPC -> FloconNetworkCallDomainModel.Request.SpecificInfos.Grpc
|
||||
},
|
||||
)
|
||||
|
||||
private fun FloconNetworkResponseLiteEmbedded.toDomainModel(): FloconNetworkCallDomainModel.Response? {
|
||||
return if(responseError != null) {
|
||||
FloconNetworkCallDomainModel.Response.Failure(
|
||||
durationMs = durationMs,
|
||||
responseError
|
||||
)
|
||||
} else {
|
||||
FloconNetworkCallDomainModel.Response.Success(
|
||||
contentType = responseContentType,
|
||||
body = null, // null on lite
|
||||
headers = responseHeaders,
|
||||
byteSize = responseByteSize,
|
||||
durationMs = durationMs,
|
||||
specificInfos = when {
|
||||
graphql != null -> FloconNetworkCallDomainModel.Response.Success.SpecificInfos.GraphQl(
|
||||
httpCode = graphql.responseHttpCode,
|
||||
isSuccess = graphql.isSuccess,
|
||||
)
|
||||
grpc != null -> FloconNetworkCallDomainModel.Response.Success.SpecificInfos.Grpc(
|
||||
grpcStatus = grpc.responseStatus,
|
||||
)
|
||||
http != null -> FloconNetworkCallDomainModel.Response.Success.SpecificInfos.Http(
|
||||
httpCode = http.responseHttpCode,
|
||||
)
|
||||
else -> return null
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,82 +2,70 @@ package io.github.openflocon.data.local.network.mapper
|
|||
|
||||
import io.github.openflocon.data.local.network.models.FloconNetworkCallEntity
|
||||
import io.github.openflocon.data.local.network.models.FloconNetworkCallType
|
||||
import io.github.openflocon.data.local.network.models.FloconNetworkRequestEmbedded
|
||||
import io.github.openflocon.data.local.network.models.FloconNetworkResponseEmbedded
|
||||
import io.github.openflocon.domain.network.models.FloconNetworkCallDomainModel
|
||||
import io.github.openflocon.domain.network.models.FloconNetworkRequestDomainModel
|
||||
import io.github.openflocon.domain.network.models.FloconNetworkResponseDomainModel
|
||||
|
||||
private fun toDomainModel(request: FloconNetworkRequestEmbedded): FloconNetworkRequestDomainModel {
|
||||
return with(request) {
|
||||
FloconNetworkRequestDomainModel(
|
||||
url = this.url,
|
||||
method = this.method,
|
||||
startTime = this.startTime,
|
||||
headers = this.requestHeaders,
|
||||
body = this.requestBody,
|
||||
byteSize = this.requestByteSize,
|
||||
isMocked = this.isMocked,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun FloconNetworkCallEntity.toDomainModel(): FloconNetworkCallDomainModel? {
|
||||
return try {
|
||||
val networkRequest = toDomainModel(request)
|
||||
when (type) {
|
||||
FloconNetworkCallType.HTTP -> FloconNetworkCallDomainModel.Http(
|
||||
callId = callId,
|
||||
networkRequest = networkRequest,
|
||||
response = response?.let {
|
||||
FloconNetworkCallDomainModel.Http.Response(
|
||||
httpCode = response.http!!.responseHttpCode,
|
||||
networkResponse = toDomainModel(response),
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
FloconNetworkCallType.GRAPHQL -> FloconNetworkCallDomainModel.GraphQl(
|
||||
callId = callId,
|
||||
request = FloconNetworkCallDomainModel.GraphQl.Request(
|
||||
networkRequest = networkRequest,
|
||||
query = request.graphql!!.query,
|
||||
operationType = request.graphql.operationType,
|
||||
),
|
||||
response = response?.let {
|
||||
FloconNetworkCallDomainModel.GraphQl.Response(
|
||||
httpCode = response.graphql!!.responseHttpCode,
|
||||
isSuccess = response.graphql.isSuccess,
|
||||
networkResponse = toDomainModel(response),
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
FloconNetworkCallType.GRPC -> FloconNetworkCallDomainModel.Grpc(
|
||||
callId = callId,
|
||||
networkRequest = networkRequest,
|
||||
response = response?.let {
|
||||
FloconNetworkCallDomainModel.Grpc.Response(
|
||||
networkResponse = toDomainModel(response),
|
||||
responseStatus = response.grpc!!.responseStatus,
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
FloconNetworkCallDomainModel(
|
||||
callId = callId,
|
||||
request = toRequestDomainModel(),
|
||||
response = response?.toDomainModel(),
|
||||
)
|
||||
} catch (t: Throwable) {
|
||||
t.printStackTrace()
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
private fun toDomainModel(response: FloconNetworkResponseEmbedded): FloconNetworkResponseDomainModel =
|
||||
with(response) {
|
||||
FloconNetworkResponseDomainModel(
|
||||
private fun FloconNetworkCallEntity.toRequestDomainModel(): FloconNetworkCallDomainModel.Request =
|
||||
FloconNetworkCallDomainModel.Request(
|
||||
url = request.url,
|
||||
method = request.method,
|
||||
startTime = request.startTime,
|
||||
headers = request.requestHeaders,
|
||||
body = request.requestBody,
|
||||
byteSize = request.requestByteSize,
|
||||
isMocked = request.isMocked,
|
||||
specificInfos = when (type) {
|
||||
FloconNetworkCallType.HTTP -> FloconNetworkCallDomainModel.Request.SpecificInfos.Http
|
||||
FloconNetworkCallType.GRAPHQL -> FloconNetworkCallDomainModel.Request.SpecificInfos.GraphQl(
|
||||
query = request.graphql!!.query,
|
||||
operationType = request.graphql.operationType,
|
||||
)
|
||||
|
||||
FloconNetworkCallType.GRPC -> FloconNetworkCallDomainModel.Request.SpecificInfos.Grpc
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
private fun FloconNetworkResponseEmbedded.toDomainModel(): FloconNetworkCallDomainModel.Response? {
|
||||
return if(responseError != null) {
|
||||
FloconNetworkCallDomainModel.Response.Failure(
|
||||
durationMs = durationMs,
|
||||
issue = responseError
|
||||
)
|
||||
} else {
|
||||
FloconNetworkCallDomainModel.Response.Success(
|
||||
contentType = responseContentType,
|
||||
body = responseBody,
|
||||
headers = responseHeaders,
|
||||
byteSize = responseByteSize,
|
||||
durationMs = durationMs,
|
||||
specificInfos = when {
|
||||
graphql != null -> FloconNetworkCallDomainModel.Response.Success.SpecificInfos.GraphQl(
|
||||
httpCode = graphql.responseHttpCode,
|
||||
isSuccess = graphql.isSuccess,
|
||||
)
|
||||
grpc != null -> FloconNetworkCallDomainModel.Response.Success.SpecificInfos.Grpc(
|
||||
grpcStatus = grpc.responseStatus,
|
||||
)
|
||||
http != null -> FloconNetworkCallDomainModel.Response.Success.SpecificInfos.Http(
|
||||
httpCode = http.responseHttpCode,
|
||||
)
|
||||
else -> return null
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,61 +19,75 @@ fun FloconNetworkCallDomainModel.toEntity(
|
|||
callId = callId,
|
||||
deviceId = deviceId,
|
||||
packageName = packageName,
|
||||
type = when (this) {
|
||||
is FloconNetworkCallDomainModel.Http -> FloconNetworkCallType.HTTP
|
||||
is FloconNetworkCallDomainModel.GraphQl -> FloconNetworkCallType.GRAPHQL
|
||||
is FloconNetworkCallDomainModel.Grpc -> FloconNetworkCallType.GRPC
|
||||
type = when (this.request.specificInfos) {
|
||||
is FloconNetworkCallDomainModel.Request.SpecificInfos.Http -> FloconNetworkCallType.HTTP
|
||||
is FloconNetworkCallDomainModel.Request.SpecificInfos.GraphQl -> FloconNetworkCallType.GRAPHQL
|
||||
is FloconNetworkCallDomainModel.Request.SpecificInfos.Grpc -> FloconNetworkCallType.GRPC
|
||||
},
|
||||
request = FloconNetworkRequestEmbedded(
|
||||
url = networkRequest.url,
|
||||
method = networkRequest.method,
|
||||
startTime = networkRequest.startTime,
|
||||
requestHeaders = networkRequest.headers,
|
||||
requestBody = networkRequest.body,
|
||||
requestByteSize = networkRequest.byteSize,
|
||||
isMocked = networkRequest.isMocked,
|
||||
graphql = when (this) {
|
||||
is FloconNetworkCallDomainModel.GraphQl -> NetworkCallGraphQlRequestEmbedded(
|
||||
query = this.request.query,
|
||||
operationType = this.request.operationType,
|
||||
url = request.url,
|
||||
method = request.method,
|
||||
startTime = request.startTime,
|
||||
requestHeaders = request.headers,
|
||||
requestBody = request.body,
|
||||
requestByteSize = request.byteSize,
|
||||
isMocked = request.isMocked,
|
||||
graphql = when (val s = this.request.specificInfos) {
|
||||
is FloconNetworkCallDomainModel.Request.SpecificInfos.GraphQl -> NetworkCallGraphQlRequestEmbedded(
|
||||
query = s.query,
|
||||
operationType = s.operationType,
|
||||
)
|
||||
|
||||
else -> null
|
||||
}
|
||||
),
|
||||
response = networkResponse?.let { networkResponse ->
|
||||
FloconNetworkResponseEmbedded(
|
||||
durationMs = networkResponse.durationMs,
|
||||
responseContentType = networkResponse.contentType,
|
||||
responseBody = networkResponse.body,
|
||||
responseHeaders = networkResponse.headers,
|
||||
responseByteSize = networkResponse.byteSize,
|
||||
graphql = when (this) {
|
||||
is FloconNetworkCallDomainModel.GraphQl -> NetworkCallGraphQlResponseEmbedded(
|
||||
responseHttpCode = (this.response as FloconNetworkCallDomainModel.GraphQl.Response).httpCode,
|
||||
isSuccess = (this.response as FloconNetworkCallDomainModel.GraphQl.Response).isSuccess,
|
||||
response = response?.let { networkResponse ->
|
||||
when(networkResponse) {
|
||||
is FloconNetworkCallDomainModel.Response.Failure -> {
|
||||
FloconNetworkResponseEmbedded(
|
||||
durationMs = networkResponse.durationMs,
|
||||
responseError = networkResponse.issue,
|
||||
graphql = null,
|
||||
http = null,
|
||||
grpc = null,
|
||||
responseContentType = null,
|
||||
responseBody = null,
|
||||
responseHeaders = emptyMap(),
|
||||
responseByteSize = 0,
|
||||
)
|
||||
|
||||
is FloconNetworkCallDomainModel.Grpc,
|
||||
is FloconNetworkCallDomainModel.Http -> null
|
||||
},
|
||||
http = when (this) {
|
||||
is FloconNetworkCallDomainModel.Http -> NetworkCallHttpResponseEmbedded(
|
||||
responseHttpCode = (this.response as FloconNetworkCallDomainModel.Http.Response).httpCode,
|
||||
)
|
||||
|
||||
is FloconNetworkCallDomainModel.Grpc,
|
||||
is FloconNetworkCallDomainModel.GraphQl -> null
|
||||
},
|
||||
grpc = when (this) {
|
||||
is FloconNetworkCallDomainModel.Grpc -> NetworkCallGrpcResponseEmbedded(
|
||||
responseStatus = (this.response as FloconNetworkCallDomainModel.Grpc.Response).responseStatus,
|
||||
)
|
||||
|
||||
is FloconNetworkCallDomainModel.Http,
|
||||
is FloconNetworkCallDomainModel.GraphQl -> null
|
||||
}
|
||||
)
|
||||
is FloconNetworkCallDomainModel.Response.Success -> {
|
||||
FloconNetworkResponseEmbedded(
|
||||
durationMs = networkResponse.durationMs,
|
||||
responseContentType = networkResponse.contentType,
|
||||
responseBody = networkResponse.body,
|
||||
responseHeaders = networkResponse.headers,
|
||||
responseByteSize = networkResponse.byteSize,
|
||||
responseError = null,
|
||||
graphql = when (val s = networkResponse.specificInfos) {
|
||||
is FloconNetworkCallDomainModel.Response.Success.SpecificInfos.GraphQl -> NetworkCallGraphQlResponseEmbedded(
|
||||
responseHttpCode = s.httpCode,
|
||||
isSuccess = s.isSuccess,
|
||||
)
|
||||
|
||||
else -> null
|
||||
},
|
||||
http = when (val s = networkResponse.specificInfos) {
|
||||
is FloconNetworkCallDomainModel.Response.Success.SpecificInfos.Http -> NetworkCallHttpResponseEmbedded(
|
||||
responseHttpCode = s.httpCode,
|
||||
)
|
||||
|
||||
else -> null
|
||||
},
|
||||
grpc = when (val s = networkResponse.specificInfos) {
|
||||
is FloconNetworkCallDomainModel.Response.Success.SpecificInfos.Grpc -> NetworkCallGrpcResponseEmbedded(
|
||||
responseStatus = s.grpcStatus,
|
||||
)
|
||||
else -> null
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ data class FloconNetworkRequestLiteEmbedded(
|
|||
|
||||
data class FloconNetworkResponseLiteEmbedded(
|
||||
val durationMs: Double,
|
||||
val responseError: String?,
|
||||
val responseContentType: String?,
|
||||
//val responseBody: String?,
|
||||
val responseHeaders: Map<String, String>,
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ data class FloconNetworkResponseEmbedded(
|
|||
val responseBody: String?,
|
||||
val responseHeaders: Map<String, String>,
|
||||
val responseByteSize: Long,
|
||||
val responseError: String?,
|
||||
|
||||
@Embedded(prefix = "graphql_")
|
||||
val graphql: NetworkCallGraphQlResponseEmbedded?,
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import kotlinx.serialization.json.Json
|
|||
|
||||
internal inline fun <reified T> Json.safeDecodeFromString(data: String): T? = try {
|
||||
decodeFromString(data)
|
||||
} catch (e: Throwable) {
|
||||
} catch (t: Throwable) {
|
||||
t.printStackTrace()
|
||||
null
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import io.github.openflocon.data.core.network.graphql.model.GraphQlRequestBody
|
|||
import io.github.openflocon.data.core.network.graphql.model.GraphQlResponseBody
|
||||
import io.github.openflocon.domain.network.models.BadQualityConfigDomainModel
|
||||
import io.github.openflocon.domain.network.models.FloconNetworkCallDomainModel
|
||||
import io.github.openflocon.domain.network.models.FloconNetworkRequestDomainModel
|
||||
import io.github.openflocon.domain.network.models.MockNetworkDomainModel
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlin.uuid.ExperimentalUuidApi
|
||||
|
|
@ -34,7 +33,8 @@ fun toDomain(decoded: FloconNetworkRequestDataModel): FloconNetworkCallDomainMod
|
|||
val graphQl = extractGraphQl(decoded)
|
||||
|
||||
val callId = decoded.floconCallId!!
|
||||
val networkRequest = FloconNetworkRequestDomainModel(
|
||||
|
||||
val request = FloconNetworkCallDomainModel.Request(
|
||||
url = decoded.url!!,
|
||||
startTime = decoded.startTime!!,
|
||||
method = decoded.method!!,
|
||||
|
|
@ -42,33 +42,21 @@ fun toDomain(decoded: FloconNetworkRequestDataModel): FloconNetworkCallDomainMod
|
|||
body = decoded.requestBody,
|
||||
byteSize = decoded.requestSize ?: 0L,
|
||||
isMocked = decoded.isMocked ?: false,
|
||||
specificInfos = when {
|
||||
graphQl != null -> FloconNetworkCallDomainModel.Request.SpecificInfos.GraphQl(
|
||||
query = graphQl.request.requestBody.query,
|
||||
operationType = graphQl.request.operationType,
|
||||
)
|
||||
decoded.floconNetworkType == "grpc" -> FloconNetworkCallDomainModel.Request.SpecificInfos.Grpc
|
||||
else -> FloconNetworkCallDomainModel.Request.SpecificInfos.Http
|
||||
}
|
||||
)
|
||||
|
||||
when {
|
||||
graphQl != null -> FloconNetworkCallDomainModel.GraphQl(
|
||||
callId = callId,
|
||||
request = FloconNetworkCallDomainModel.GraphQl.Request(
|
||||
query = graphQl.request.queryName ?: "anonymous",
|
||||
operationType = graphQl.request.operationType,
|
||||
networkRequest = networkRequest,
|
||||
),
|
||||
response = null,
|
||||
)
|
||||
|
||||
decoded.floconNetworkType == "grpc" -> FloconNetworkCallDomainModel.Grpc(
|
||||
callId = callId,
|
||||
networkRequest = networkRequest,
|
||||
response = null,
|
||||
)
|
||||
// decoded.floconNetworkType == "http"
|
||||
else -> {
|
||||
FloconNetworkCallDomainModel.Http(
|
||||
callId = callId,
|
||||
networkRequest = networkRequest,
|
||||
response = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
FloconNetworkCallDomainModel(
|
||||
callId = callId,
|
||||
request = request,
|
||||
response = null, // for now it's null
|
||||
)
|
||||
} catch (t: Throwable) {
|
||||
t.printStackTrace()
|
||||
null
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package com.flocon.data.remote.network.models
|
||||
|
||||
import io.github.openflocon.domain.network.models.FloconNetworkCallDomainModel
|
||||
import io.github.openflocon.domain.network.models.FloconNetworkCallIdDomainModel
|
||||
import io.github.openflocon.domain.network.models.FloconNetworkResponseDomainModel
|
||||
import io.github.openflocon.domain.network.models.FloconNetworkResponseOnlyDomainModel
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
|
|
@ -37,31 +37,41 @@ data class FloconNetworkResponseDataModel(
|
|||
val responseHeaders: Map<String, String>? = null,
|
||||
val responseSize: Long? = null,
|
||||
val responseGrpcStatus: String? = null,
|
||||
val responseError: String? = null,
|
||||
)
|
||||
|
||||
internal fun FloconNetworkResponseDataModel.toDomain(): FloconNetworkResponseOnlyDomainModel? {
|
||||
return try {
|
||||
val callId = floconCallId!!
|
||||
val networkResponse = FloconNetworkResponseDomainModel(
|
||||
durationMs = durationMs ?: 0.0,
|
||||
body = responseBody,
|
||||
byteSize = responseSize ?: 0L,
|
||||
headers = responseHeaders.orEmpty(),
|
||||
contentType = responseContentType,
|
||||
)
|
||||
when (floconNetworkType) {
|
||||
"grpc" -> FloconNetworkResponseOnlyDomainModel.Grpc(
|
||||
floconCallId = callId,
|
||||
networkResponse = networkResponse,
|
||||
grpcStatus = responseGrpcStatus!!,
|
||||
val durationMs = durationMs ?: 0.0
|
||||
|
||||
val response = if (responseError != null) {
|
||||
FloconNetworkCallDomainModel.Response.Failure(
|
||||
durationMs = durationMs,
|
||||
issue = responseError,
|
||||
)
|
||||
// otherwise tread like http
|
||||
else -> FloconNetworkResponseOnlyDomainModel.Http(
|
||||
floconCallId = callId,
|
||||
networkResponse = networkResponse,
|
||||
httpCode = responseHttpCode!!,
|
||||
} else {
|
||||
FloconNetworkCallDomainModel.Response.Success(
|
||||
durationMs = durationMs,
|
||||
contentType = responseContentType,
|
||||
body = responseBody,
|
||||
headers = responseHeaders.orEmpty(),
|
||||
byteSize = responseSize ?: 0L,
|
||||
specificInfos = when (floconNetworkType) {
|
||||
"grpc" -> FloconNetworkCallDomainModel.Response.Success.SpecificInfos.Grpc(
|
||||
grpcStatus = responseGrpcStatus!!,
|
||||
)
|
||||
// otherwise tread like http
|
||||
else -> FloconNetworkCallDomainModel.Response.Success.SpecificInfos.Http(
|
||||
httpCode = responseHttpCode!!,
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
FloconNetworkResponseOnlyDomainModel(
|
||||
floconCallId = callId,
|
||||
response = response,
|
||||
)
|
||||
} catch (t: Throwable) {
|
||||
t.printStackTrace()
|
||||
return null
|
||||
|
|
|
|||
|
|
@ -1,65 +1,89 @@
|
|||
package io.github.openflocon.domain.network.models
|
||||
|
||||
sealed interface FloconNetworkCallDomainModel {
|
||||
val callId: String
|
||||
val networkRequest: FloconNetworkRequestDomainModel
|
||||
val networkResponse: FloconNetworkResponseDomainModel?
|
||||
data class FloconNetworkCallDomainModel(
|
||||
val callId: String,
|
||||
val request: Request,
|
||||
val response: Response?,
|
||||
) {
|
||||
|
||||
data class Http(
|
||||
override val callId: String,
|
||||
override val networkRequest: FloconNetworkRequestDomainModel,
|
||||
val response: Response?,
|
||||
) : FloconNetworkCallDomainModel {
|
||||
data class Response(
|
||||
val networkResponse: FloconNetworkResponseDomainModel,
|
||||
val httpCode: Int, // ex: 200
|
||||
)
|
||||
|
||||
override val networkResponse = response?.networkResponse
|
||||
data class Request(
|
||||
val url: String,
|
||||
val startTime: Long,
|
||||
val method: String,
|
||||
val headers: Map<String, String>,
|
||||
val body: String?,
|
||||
val byteSize: Long,
|
||||
val isMocked: Boolean,
|
||||
val specificInfos: SpecificInfos,
|
||||
) {
|
||||
sealed interface SpecificInfos {
|
||||
data object Http: SpecificInfos
|
||||
data class GraphQl(
|
||||
val query: String,
|
||||
val operationType: String,
|
||||
) : SpecificInfos
|
||||
data object Grpc : SpecificInfos
|
||||
}
|
||||
}
|
||||
|
||||
data class GraphQl(
|
||||
override val callId: String,
|
||||
val request: Request,
|
||||
val response: Response?,
|
||||
) : FloconNetworkCallDomainModel {
|
||||
sealed interface Response {
|
||||
|
||||
data class Request(
|
||||
val networkRequest: FloconNetworkRequestDomainModel,
|
||||
val query: String,
|
||||
val operationType: String,
|
||||
)
|
||||
val durationMs: Double
|
||||
|
||||
data class Response(
|
||||
val httpCode: Int, // ex: 200
|
||||
val isSuccess: Boolean,
|
||||
val networkResponse: FloconNetworkResponseDomainModel,
|
||||
)
|
||||
|
||||
override val networkRequest = request.networkRequest
|
||||
override val networkResponse = response?.networkResponse
|
||||
}
|
||||
|
||||
data class Grpc(
|
||||
override val callId: String,
|
||||
override val networkRequest: FloconNetworkRequestDomainModel,
|
||||
val response: Response?,
|
||||
) : FloconNetworkCallDomainModel {
|
||||
data class Response(
|
||||
val networkResponse: FloconNetworkResponseDomainModel,
|
||||
val responseStatus: String,
|
||||
)
|
||||
|
||||
override val networkResponse = response?.networkResponse
|
||||
data class Success(
|
||||
override val durationMs: Double,
|
||||
val contentType: String? = null,
|
||||
val body: String? = null,
|
||||
val headers: Map<String, String>,
|
||||
val byteSize: Long,
|
||||
val specificInfos: SpecificInfos,
|
||||
) : Response {
|
||||
sealed interface SpecificInfos {
|
||||
data class Http(
|
||||
val httpCode: Int, // ex: 200
|
||||
) : SpecificInfos
|
||||
data class GraphQl(
|
||||
val httpCode: Int, // ex: 200
|
||||
val isSuccess: Boolean,
|
||||
) : SpecificInfos
|
||||
data class Grpc(
|
||||
val grpcStatus: String,
|
||||
) : SpecificInfos
|
||||
}
|
||||
}
|
||||
data class Failure(
|
||||
override val durationMs: Double,
|
||||
val issue: String,
|
||||
) : Response
|
||||
}
|
||||
}
|
||||
|
||||
fun FloconNetworkCallDomainModel.Response.Success.SpecificInfos.httpCode() : Int? = when(this) {
|
||||
is FloconNetworkCallDomainModel.Response.Success.SpecificInfos.GraphQl -> httpCode
|
||||
is FloconNetworkCallDomainModel.Response.Success.SpecificInfos.Http -> httpCode
|
||||
is FloconNetworkCallDomainModel.Response.Success.SpecificInfos.Grpc -> null
|
||||
}
|
||||
|
||||
fun FloconNetworkCallDomainModel.httpCode(): Int? {
|
||||
return when (this) {
|
||||
is FloconNetworkCallDomainModel.Http -> this.response?.httpCode
|
||||
is FloconNetworkCallDomainModel.GraphQl -> this.response?.httpCode
|
||||
else -> null
|
||||
return when(this.response) {
|
||||
is FloconNetworkCallDomainModel.Response.Failure -> null
|
||||
is FloconNetworkCallDomainModel.Response.Success -> this.response.specificInfos.httpCode()
|
||||
null -> null
|
||||
}
|
||||
}
|
||||
|
||||
fun FloconNetworkCallDomainModel.byteSize(): Long? {
|
||||
return when(this.response) {
|
||||
is FloconNetworkCallDomainModel.Response.Failure -> null
|
||||
is FloconNetworkCallDomainModel.Response.Success -> this.response.byteSize
|
||||
null -> null
|
||||
}
|
||||
}
|
||||
|
||||
fun FloconNetworkCallDomainModel.Response.getContentType(): String? {
|
||||
return when(this) {
|
||||
is FloconNetworkCallDomainModel.Response.Failure -> null
|
||||
is FloconNetworkCallDomainModel.Response.Success -> this.contentType
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -67,6 +91,7 @@ data class FloconNetworkCallIdDomainModel(
|
|||
val floconCallId: String,
|
||||
)
|
||||
|
||||
/*
|
||||
data class FloconNetworkRequestDomainModel(
|
||||
val url: String,
|
||||
val startTime: Long,
|
||||
|
|
@ -76,28 +101,9 @@ data class FloconNetworkRequestDomainModel(
|
|||
val byteSize: Long,
|
||||
val isMocked: Boolean,
|
||||
)
|
||||
*/
|
||||
|
||||
sealed interface FloconNetworkResponseOnlyDomainModel {
|
||||
val floconCallId: String
|
||||
val networkResponse: FloconNetworkResponseDomainModel
|
||||
|
||||
data class Http(
|
||||
override val floconCallId: String,
|
||||
override val networkResponse: FloconNetworkResponseDomainModel,
|
||||
val httpCode: Int, // ex: 200
|
||||
) : FloconNetworkResponseOnlyDomainModel
|
||||
|
||||
data class Grpc(
|
||||
override val floconCallId: String,
|
||||
override val networkResponse: FloconNetworkResponseDomainModel,
|
||||
val grpcStatus: String,
|
||||
) : FloconNetworkResponseOnlyDomainModel
|
||||
}
|
||||
|
||||
data class FloconNetworkResponseDomainModel(
|
||||
val contentType: String? = null,
|
||||
val body: String? = null,
|
||||
val headers: Map<String, String>,
|
||||
val byteSize: Long,
|
||||
val durationMs: Double
|
||||
data class FloconNetworkResponseOnlyDomainModel(
|
||||
val floconCallId: String,
|
||||
val response: FloconNetworkCallDomainModel.Response,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -4,21 +4,21 @@ import io.github.openflocon.domain.network.models.FloconNetworkCallDomainModel
|
|||
|
||||
class GenerateCurlCommandUseCase {
|
||||
operator fun invoke(infos: FloconNetworkCallDomainModel): String {
|
||||
val url = infos.networkRequest.url
|
||||
val url = infos.request.url
|
||||
val commandBuilder = StringBuilder("curl")
|
||||
|
||||
// 1. Add HTTP Method
|
||||
commandBuilder.append(" -X ${infos.networkRequest.method}")
|
||||
commandBuilder.append(" -X ${infos.request.method}")
|
||||
|
||||
// 2. Add Request Headers
|
||||
infos.networkRequest.headers.forEach { (key, value) ->
|
||||
infos.request.headers.forEach { (key, value) ->
|
||||
// Escape double quotes within header values if they exist
|
||||
val escapedValue = value.replace("\"", "\\\"")
|
||||
commandBuilder.append(" -H \"$key: $escapedValue\"")
|
||||
}
|
||||
|
||||
// 3. Add Request Body (if present)
|
||||
infos.networkRequest.body?.let { body ->
|
||||
infos.request.body?.let { body ->
|
||||
if (body.isNotEmpty()) {
|
||||
// Escape single quotes within the body for shell compatibility
|
||||
// ' -> '\'' (closes current single quote, adds escaped single quote, reopens single quote)
|
||||
|
|
|
|||
|
|
@ -23,18 +23,21 @@ class GenerateNetworkMockFromNetworkCallUseCase(
|
|||
MockNetworkDomainModel(
|
||||
id = Uuid.random().toString(), // generate
|
||||
expectation = MockNetworkDomainModel.Expectation(
|
||||
urlPattern = request.networkRequest.url,
|
||||
method = request.networkRequest.method,
|
||||
urlPattern = request.request.url,
|
||||
method = request.request.method,
|
||||
),
|
||||
isEnabled = true, // enabled by default
|
||||
response = request.networkResponse?.let {
|
||||
MockNetworkDomainModel.Response(
|
||||
httpCode = request.httpCode() ?: 200,
|
||||
body = it.body ?: "",
|
||||
mediaType = it.headers["Content-Type"] ?: "",
|
||||
delay = 0,
|
||||
headers = it.headers,
|
||||
)
|
||||
response = request.response?.let {
|
||||
when(it) {
|
||||
is FloconNetworkCallDomainModel.Response.Failure -> null // maybe generate error response in this case
|
||||
is FloconNetworkCallDomainModel.Response.Success -> MockNetworkDomainModel.Response(
|
||||
httpCode = request.httpCode() ?: 200,
|
||||
body = it.body ?: "",
|
||||
mediaType = it.headers["Content-Type"] ?: "",
|
||||
delay = 0,
|
||||
headers = it.headers,
|
||||
)
|
||||
}
|
||||
} ?: MockNetworkDomainModel.Response(
|
||||
httpCode = 200,
|
||||
body = "",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue