Saving some CPU cycles, only serializing finTsModel if required

This commit is contained in:
dankito 2024-10-15 13:21:19 +02:00
parent ecf930fcad
commit 4802493886
7 changed files with 24 additions and 39 deletions

View File

@ -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)
}

View File

@ -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) }
}

View File

@ -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>(serializedFinTsData)
mapper.map(serializedData)

View File

@ -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<MessageLogEntry>,
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) } }
}

View File

@ -10,9 +10,8 @@ open class GetAccountDataResponse(
errorMessage: String?,
open val customerAccount: CustomerAccount?,
messageLog: List<MessageLogEntry>,
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

View File

@ -8,6 +8,5 @@ open class TransferMoneyResponse(
error: ErrorCode?,
errorMessage: String?,
messageLog: List<MessageLogEntry>,
finTsModel: BankData? = null,
serializedFinTsModel: String? = null
) : FinTsClientResponse(error, errorMessage, messageLog, finTsModel, serializedFinTsModel)
finTsModel: BankData? = null
) : FinTsClientResponse(error, errorMessage, messageLog, finTsModel)

View File

@ -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))
}
}