From 4802493886f27a2ade153336ee24e9cfc474b902 Mon Sep 17 00:00:00 2001 From: dankito Date: Tue, 15 Oct 2024 13:21:19 +0200 Subject: [PATCH] Saving some CPU cycles, only serializing finTsModel if required --- .../net/codinux/banking/fints/FinTsClient.kt | 24 +++++++------------ .../banking/fints/mapper/FinTsModelMapper.kt | 8 +------ .../serialization/FinTsModelSerializer.kt | 6 ++--- .../model/response/FinTsClientResponse.kt | 7 ++++-- .../model/response/GetAccountDataResponse.kt | 5 ++-- .../model/response/TransferMoneyResponse.kt | 5 ++-- .../serialization/FinTsModelSerializerTest.kt | 8 +++---- 7 files changed, 24 insertions(+), 39 deletions(-) diff --git a/fints4k/src/commonMain/kotlin/net/codinux/banking/fints/FinTsClient.kt b/fints4k/src/commonMain/kotlin/net/codinux/banking/fints/FinTsClient.kt index 901e347d..9ce9cd61 100644 --- a/fints4k/src/commonMain/kotlin/net/codinux/banking/fints/FinTsClient.kt +++ b/fints4k/src/commonMain/kotlin/net/codinux/banking/fints/FinTsClient.kt @@ -73,7 +73,7 @@ open class FinTsClient( if (accountsSupportingRetrievingTransactions.isEmpty()) { val errorMessage = "None of the accounts ${accounts.map { it.productName }} supports retrieving balance or transactions" // TODO: translate - return GetAccountDataResponse(ErrorCode.NoneOfTheAccountsSupportsRetrievingData, errorMessage, mapper.map(bank), previousJobMessageLog ?: listOf(), bank, serialize(bank)) + return GetAccountDataResponse(ErrorCode.NoneOfTheAccountsSupportsRetrievingData, errorMessage, mapper.map(bank), previousJobMessageLog ?: listOf(), bank) } for (account in accountsSupportingRetrievingTransactions) { @@ -89,7 +89,7 @@ open class FinTsClient( val errorCode = unsuccessfulJob?.let { mapper.mapErrorCode(it) } ?: if (retrievedTransactionsResponses.size < accountsSupportingRetrievingTransactions.size) ErrorCode.DidNotRetrieveAllAccountData else null return GetAccountDataResponse(errorCode, mapper.mapErrorMessages(unsuccessfulJob), mapper.map(bank, retrievedTransactionsResponses, param.retrieveTransactionsTo), - mapper.mergeMessageLog(previousJobMessageLog, *retrievedTransactionsResponses.map { it.messageLog }.toTypedArray()), bank, serialize(bank)) + mapper.mergeMessageLog(previousJobMessageLog, *retrievedTransactionsResponses.map { it.messageLog }.toTypedArray()), bank) } protected open suspend fun getAccountTransactions(param: GetAccountDataParameter, bank: BankData, account: AccountData): GetAccountTransactionsResponse { @@ -124,7 +124,7 @@ open class FinTsClient( if (getAccountInfoResponse.successful == false) { return TransferMoneyResponse(mapper.mapErrorCode(getAccountInfoResponse), mapper.mapErrorMessages(getAccountInfoResponse), - getAccountInfoResponse.messageLog, bank, serialize(bank)) + getAccountInfoResponse.messageLog, bank) } else { return transferMoneyAsync(param, recipientBankIdentifier, getAccountInfoResponse.bank, getAccountInfoResponse.bank.accounts, getAccountInfoResponse) } @@ -138,14 +138,14 @@ open class FinTsClient( val accountToUse: AccountData if (accountsSupportingTransfer.isEmpty()) { - return TransferMoneyResponse(ErrorCode.NoAccountSupportsMoneyTransfer, "None of the accounts $accounts supports money transfer", previousJobResponse?.messageLog ?: listOf(), bank, serialize(bank)) + return TransferMoneyResponse(ErrorCode.NoAccountSupportsMoneyTransfer, "None of the accounts $accounts supports money transfer", previousJobResponse?.messageLog ?: listOf(), bank) } else if (accountsSupportingTransfer.size == 1) { accountToUse = accountsSupportingTransfer.first() } else { val selectedAccount = param.selectAccountToUseForTransfer?.invoke(accountsSupportingTransfer) if (selectedAccount == null) { - return TransferMoneyResponse(ErrorCode.MoreThanOneAccountSupportsMoneyTransfer, "More than one of the accounts $accountsSupportingTransfer supports money transfer, so we cannot clearly determine which one to use for this transfer", previousJobResponse?.messageLog ?: listOf(), bank, serialize(bank)) + return TransferMoneyResponse(ErrorCode.MoreThanOneAccountSupportsMoneyTransfer, "More than one of the accounts $accountsSupportingTransfer supports money transfer, so we cannot clearly determine which one to use for this transfer", previousJobResponse?.messageLog ?: listOf(), bank) } accountToUse = selectedAccount @@ -156,7 +156,7 @@ open class FinTsClient( val response = config.jobExecutor.transferMoneyAsync(context, BankTransferData(param.recipientName, param.recipientAccountIdentifier, recipientBankIdentifier, param.amount, param.reference, param.instantPayment)) - return TransferMoneyResponse(mapper.mapErrorCode(response), mapper.mapErrorMessages(response), mapper.mergeMessageLog(previousJobResponse, response), bank, serialize(bank)) + return TransferMoneyResponse(mapper.mapErrorCode(response), mapper.mapErrorMessages(response), mapper.mergeMessageLog(previousJobResponse, response), bank) } private fun getRecipientBankCode(param: TransferMoneyParameter): String? { @@ -194,7 +194,7 @@ open class FinTsClient( */ open suspend fun getRequiredDataToSendUserJobs(param: FinTsClientParameter): net.dankito.banking.client.model.response.FinTsClientResponse { if (param.finTsModel != null) { - return net.dankito.banking.client.model.response.FinTsClientResponse(null, null, emptyList(), param.finTsModel, serialize(param.finTsModel)) + return net.dankito.banking.client.model.response.FinTsClientResponse(null, null, emptyList(), param.finTsModel) } val defaultValues = (param as? GetAccountDataParameter)?.defaultBankValues @@ -209,7 +209,7 @@ open class FinTsClient( val getAccountInfoResponse = getAccountInfo(param, bank) return net.dankito.banking.client.model.response.FinTsClientResponse(mapper.mapErrorCode(getAccountInfoResponse), mapper.mapErrorMessages(getAccountInfoResponse), - getAccountInfoResponse.messageLog, bank, serialize(bank)) + getAccountInfoResponse.messageLog, bank) } protected open suspend fun getAccountInfo(param: FinTsClientParameter, bank: BankData): GetAccountInfoResponse { @@ -236,12 +236,4 @@ open class FinTsClient( return GetAccountInfoResponse(context, getAccountsResponse) } - - @JvmName("serializeNullable") - @JsName("serializeNullable") - private fun serialize(bank: BankData?) = - bank?.let { serialize(bank) } - - private fun serialize(bank: BankData): String? = mapper.serialize(bank) - } \ No newline at end of file diff --git a/fints4k/src/commonMain/kotlin/net/codinux/banking/fints/mapper/FinTsModelMapper.kt b/fints4k/src/commonMain/kotlin/net/codinux/banking/fints/mapper/FinTsModelMapper.kt index 1e138eb0..c84df1d8 100644 --- a/fints4k/src/commonMain/kotlin/net/codinux/banking/fints/mapper/FinTsModelMapper.kt +++ b/fints4k/src/commonMain/kotlin/net/codinux/banking/fints/mapper/FinTsModelMapper.kt @@ -15,12 +15,9 @@ import net.codinux.banking.fints.response.segments.AccountType import net.codinux.banking.fints.util.BicFinder import net.codinux.banking.fints.extensions.minusDays import net.codinux.banking.fints.extensions.todayAtEuropeBerlin -import net.codinux.banking.fints.serialization.FinTsModelSerializer -open class FinTsModelMapper( - private val serializer: FinTsModelSerializer = FinTsModelSerializer() -) { +open class FinTsModelMapper { protected open val bicFinder = BicFinder() @@ -203,7 +200,4 @@ open class FinTsModelMapper( return responses.filterNotNull().flatMap { it.messageLog } } - open fun serialize(finTsModel: BankData?): String? = - finTsModel?.let { serializer.serializeToJson(finTsModel) } - } \ No newline at end of file diff --git a/fints4k/src/commonMain/kotlin/net/codinux/banking/fints/serialization/FinTsModelSerializer.kt b/fints4k/src/commonMain/kotlin/net/codinux/banking/fints/serialization/FinTsModelSerializer.kt index 3c6765a7..ba5c1193 100644 --- a/fints4k/src/commonMain/kotlin/net/codinux/banking/fints/serialization/FinTsModelSerializer.kt +++ b/fints4k/src/commonMain/kotlin/net/codinux/banking/fints/serialization/FinTsModelSerializer.kt @@ -5,7 +5,7 @@ import kotlinx.serialization.json.Json import net.codinux.banking.fints.model.BankData import net.codinux.log.logger -open class FinTsModelSerializer { +object FinTsModelSerializer { private val json: Json by lazy { Json { this.ignoreUnknownKeys = true } @@ -23,7 +23,7 @@ open class FinTsModelSerializer { private val log by logger() - open fun serializeToJson(bank: BankData, prettyPrint: Boolean = false): String? { + fun serializeToJson(bank: BankData, prettyPrint: Boolean = false): String? { return try { val serializableData = mapper.map(bank) @@ -36,7 +36,7 @@ open class FinTsModelSerializer { } } - open fun deserializeFromJson(serializedFinTsData: String): BankData? = try { + fun deserializeFromJson(serializedFinTsData: String): BankData? = try { val serializedData = json.decodeFromString(serializedFinTsData) mapper.map(serializedData) diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/client/model/response/FinTsClientResponse.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/client/model/response/FinTsClientResponse.kt index 7fa706cc..26f36329 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/client/model/response/FinTsClientResponse.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/client/model/response/FinTsClientResponse.kt @@ -2,6 +2,7 @@ package net.dankito.banking.client.model.response import net.codinux.banking.fints.model.BankData import net.codinux.banking.fints.model.MessageLogEntry +import net.codinux.banking.fints.serialization.FinTsModelSerializer // TODO: rename to BankingClientResponse? @@ -9,8 +10,7 @@ open class FinTsClientResponse( open val error: ErrorCode?, open val errorMessage: String?, open val messageLog: List, - open val finTsModel: BankData? = null, - open val serializedFinTsModel: String? = null + open val finTsModel: BankData? = null ) { internal constructor() : this(null, null, listOf()) // for object deserializers @@ -22,4 +22,7 @@ open class FinTsClientResponse( open val errorCodeAndMessage: String get() = "$error${errorMessage?.let { " $it" }}" + // save some CPU cycles, only serialize finTsModel if required + open val serializedFinTsModel: String? by lazy { finTsModel?.let { FinTsModelSerializer.serializeToJson(it) } } + } \ No newline at end of file diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/client/model/response/GetAccountDataResponse.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/client/model/response/GetAccountDataResponse.kt index 491c2746..cfb87303 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/client/model/response/GetAccountDataResponse.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/client/model/response/GetAccountDataResponse.kt @@ -10,9 +10,8 @@ open class GetAccountDataResponse( errorMessage: String?, open val customerAccount: CustomerAccount?, messageLog: List, - finTsModel: BankData? = null, - serializedFinTsModel: String? = null -) : FinTsClientResponse(error, errorMessage, messageLog, finTsModel, serializedFinTsModel) { + finTsModel: BankData? = null +) : FinTsClientResponse(error, errorMessage, messageLog, finTsModel) { internal constructor() : this(null, null, null, listOf()) // for object deserializers diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/client/model/response/TransferMoneyResponse.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/client/model/response/TransferMoneyResponse.kt index 4923befe..d84dc1f9 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/client/model/response/TransferMoneyResponse.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/client/model/response/TransferMoneyResponse.kt @@ -8,6 +8,5 @@ open class TransferMoneyResponse( error: ErrorCode?, errorMessage: String?, messageLog: List, - finTsModel: BankData? = null, - serializedFinTsModel: String? = null -) : FinTsClientResponse(error, errorMessage, messageLog, finTsModel, serializedFinTsModel) \ No newline at end of file + finTsModel: BankData? = null +) : FinTsClientResponse(error, errorMessage, messageLog, finTsModel) \ No newline at end of file diff --git a/fints4k/src/commonTest/kotlin/net/codinux/banking/fints/serialization/FinTsModelSerializerTest.kt b/fints4k/src/commonTest/kotlin/net/codinux/banking/fints/serialization/FinTsModelSerializerTest.kt index fbaeb1fa..a464ba78 100644 --- a/fints4k/src/commonTest/kotlin/net/codinux/banking/fints/serialization/FinTsModelSerializerTest.kt +++ b/fints4k/src/commonTest/kotlin/net/codinux/banking/fints/serialization/FinTsModelSerializerTest.kt @@ -12,21 +12,19 @@ class FinTsModelSerializerTest { private val serializedBankData = TestDataGenerator.serializedBankData - private val underTest = FinTsModelSerializer() - @Test fun serializeToJson() { val bank = TestDataGenerator.generateBankDataForSerialization() - val result = underTest.serializeToJson(bank, true) + val result = FinTsModelSerializer.serializeToJson(bank, true) assertEquals(serializedBankData, result) } @Test fun deserializeFromJson() { - val result = underTest.deserializeFromJson(serializedBankData) + val result = FinTsModelSerializer.deserializeFromJson(serializedBankData) assertNotNull(result) @@ -48,7 +46,7 @@ class FinTsModelSerializerTest { assertContains(result.supportedJobs, account.allowedJobs) // check that it contains exactly the same object instances } - assertEquals(serializedBankData, underTest.serializeToJson(result, true)) + assertEquals(serializedBankData, FinTsModelSerializer.serializeToJson(result, true)) } } \ No newline at end of file