libeufin

Integration and sandbox testing for FinTech APIs and data formats
Log | Files | Refs | Submodules | README | LICENSE

commit eb459c842f6d9b8516974b6c0940ab07f7156a5e
parent d368476a11b1e3cb905961ab429c3801c29c942e
Author: Antoine A <>
Date:   Tue,  8 Oct 2024 02:16:26 +0200

nexus: improve listing cmd

Diffstat:
Mnexus/src/main/kotlin/tech/libeufin/nexus/cli/Testing.kt | 13++++++-------
Mnexus/src/main/kotlin/tech/libeufin/nexus/db/Database.kt | 1+
Anexus/src/main/kotlin/tech/libeufin/nexus/db/ListDAO.kt | 167+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mnexus/src/main/kotlin/tech/libeufin/nexus/db/PaymentDAO.kt | 138++-----------------------------------------------------------------------------
Mnexus/src/test/kotlin/helpers.kt | 2+-
5 files changed, 177 insertions(+), 144 deletions(-)

diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/cli/Testing.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/cli/Testing.kt @@ -212,12 +212,12 @@ class ListCmd: CliktCommand("list") { if (parsed.receiverName != null) append(" ${parsed.receiverName}") } } catch (e: Exception) { - return payto + return payto.removePrefix("payto://") } } val (columnNames, rows) = when (kind) { ListKind.incoming -> { - val txs = db.payment.metadataIncoming() + val txs = db.list.incoming() Pair( listOf( "transaction", "id", "talerable", "debtor", "subject" @@ -234,25 +234,24 @@ class ListCmd: CliktCommand("list") { ) } ListKind.outgoing -> { - val txs = db.payment.metadataOutgoing() + val txs = db.list.outgoing() Pair( listOf( - "transaction", "id", "creditor", "wtid", "exchange URL", "subject" + "transaction", "id", "creditor", "talerable", "subject" ), txs.map { listOf( "${it.date} ${it.amount}", it.id, fmtPayto(it.creditor), - it.wtid?.toString() ?: "", - it.exchangeBaseUrl ?: "", + "${it.wtid?.toString() ?: ""} ${it.exchangeBaseUrl ?: ""}", it.subject ?: "", ) } ) } ListKind.initiated -> { - val txs = db.payment.metadataInitiated() + val txs = db.list.initiated() Pair( listOf( "transaction", "id", "submission", "creditor", "status", "subject" diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/db/Database.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/db/Database.kt @@ -91,6 +91,7 @@ class Database(dbConfig: DatabaseConfig, val bankCurrency: String): DbPool(dbCon val initiated = InitiatedDAO(this) val exchange = ExchangeDAO(this) val ebics = EbicsDAO(this) + val list = ListDAO(this) private val outgoingTxFlows: MutableSharedFlow<Long> = MutableSharedFlow() private val incomingTxFlows: MutableSharedFlow<Long> = MutableSharedFlow() diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/db/ListDAO.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/db/ListDAO.kt @@ -0,0 +1,166 @@ +/* + * This file is part of LibEuFin. + * Copyright (C) 2024 Taler Systems S.A. + + * LibEuFin is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3, or + * (at your option) any later version. + + * LibEuFin is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + + * You should have received a copy of the GNU Affero General Public + * License along with LibEuFin; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/> + */ + +package tech.libeufin.nexus.db + +import tech.libeufin.common.* +import tech.libeufin.common.db.* +import tech.libeufin.nexus.iso20022.IncomingPayment +import tech.libeufin.nexus.iso20022.OutgoingPayment +import java.sql.Types +import java.time.Instant + +/** Data access logic for metadata listing */ +class ListDAO(private val db: Database) { + /** List incoming transaction metadata for debugging */ + suspend fun incoming(): List<IncomingTxMetadata> = db.serializable( + """ + SELECT + (amount).val AS amount_val + ,(amount).frac AS amount_frac + ,subject + ,(bounced_transactions.initiated_outgoing_transaction_id IS NOT NULL) AS bounced + ,execution_time + ,debit_payto + ,bank_id + ,type + ,reserve_public_key + ,account_pub + FROM incoming_transactions AS incoming + LEFT JOIN talerable_incoming_transactions USING (incoming_transaction_id) + LEFT JOIN bounced_transactions USING (incoming_transaction_id) + ORDER BY execution_time + """ + ) { + all { + val type = it.getOptEnum<TalerIncomingType>("type") + IncomingTxMetadata( + date = it.getLong("execution_time").asInstant(), + amount = it.getDecimal("amount"), + subject = it.getString("subject"), + debtor = it.getString("debit_payto"), + id = it.getString("bank_id"), + talerable = when (type) { + null -> if (it.getBoolean("bounced")) "bounced" else "" + TalerIncomingType.reserve -> "reserve ${EddsaPublicKey(it.getBytes("reserve_public_key"))}" + TalerIncomingType.kyc -> "kyc ${EddsaPublicKey(it.getBytes("account_pub"))}" + TalerIncomingType.wad -> throw UnsupportedOperationException() + } + ) + } + } + + /** List outgoing transaction metadata for debugging */ + suspend fun outgoing(): List<OutgoingTxMetadata> = db.serializable( + """ + SELECT + (amount).val AS amount_val + ,(amount).frac AS amount_frac + ,subject + ,execution_time + ,credit_payto + ,end_to_end_id + ,wtid + ,exchange_base_url + FROM outgoing_transactions + LEFT JOIN talerable_outgoing_transactions using (outgoing_transaction_id) + ORDER BY execution_time + """ + ) { + all { + OutgoingTxMetadata( + date = it.getLong("execution_time").asInstant(), + amount = it.getDecimal("amount"), + subject = it.getString("subject"), + creditor = it.getString("credit_payto"), + id = it.getString("end_to_end_id"), + wtid = it.getBytes("wtid")?.run { ShortHashCode(this) }, + exchangeBaseUrl = it.getString("exchange_base_url") + ) + } + } + + /** List initiated transaction metadata for debugging */ + suspend fun initiated(): List<InitiatedTxMetadata> = db.serializable( + """ + SELECT + (amount).val AS amount_val + ,(amount).frac AS amount_frac + ,subject + ,initiation_time + ,submission_date + ,submission_counter + ,credit_payto + ,end_to_end_id + ,initiated_outgoing_transactions.status + ,initiated_outgoing_transactions.status_msg + FROM initiated_outgoing_transactions + LEFT JOIN initiated_outgoing_batches USING (initiated_outgoing_batch_id) + ORDER BY initiation_time + """ + ) { + all { + InitiatedTxMetadata( + date = it.getLong("initiation_time").asInstant(), + amount = it.getDecimal("amount"), + subject = it.getString("subject"), + creditor = it.getString("credit_payto"), + id = it.getString("end_to_end_id"), + status = it.getString("status"), + msg = it.getString("status_msg"), + submissionTime = it.getLong("submission_date").asInstant(), + submissionCounter = it.getInt("submission_counter") + ) + } + } +} + +/** Incoming transaction metadata for debugging */ +data class IncomingTxMetadata( + val date: Instant, + val amount: DecimalNumber, + val subject: String, + val debtor: String, + val id: String?, + val talerable: String? +) + +/** Outgoing transaction metadata for debugging */ +data class OutgoingTxMetadata( + val date: Instant, + val amount: DecimalNumber, + val subject: String?, + val creditor: String?, + val id: String, + val wtid: ShortHashCode?, + val exchangeBaseUrl: String? +) + +/** Initiated metadata for debugging */ +data class InitiatedTxMetadata( + val date: Instant, + val amount: DecimalNumber, + val subject: String, + val creditor: String, + val id: String, + val status: String, + val msg: String?, + val submissionTime: Instant, + val submissionCounter: Int +) +\ No newline at end of file diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/db/PaymentDAO.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/db/PaymentDAO.kt @@ -197,138 +197,4 @@ class PaymentDAO(private val db: Database) { subject = it.getString("subject") ) } - - /** List incoming transaction metadata for debugging */ - suspend fun metadataIncoming(): List<IncomingTxMetadata> = db.serializable( - """ - SELECT - (amount).val as amount_val - ,(amount).frac AS amount_frac - ,subject - ,execution_time - ,debit_payto - ,bank_id - ,type - ,reserve_public_key - ,account_pub - FROM incoming_transactions - LEFT OUTER JOIN talerable_incoming_transactions using (incoming_transaction_id) - ORDER BY execution_time - """ - ) { - all { - val type = it.getOptEnum<TalerIncomingType>("type") - IncomingTxMetadata( - date = it.getLong("execution_time").asInstant(), - amount = it.getDecimal("amount"), - subject = it.getString("subject"), - debtor = it.getString("debit_payto"), - id = it.getString("bank_id"), - talerable = when (type) { - null -> null - TalerIncomingType.reserve -> "reserve ${EddsaPublicKey(it.getBytes("reserve_public_key"))}" - TalerIncomingType.kyc -> "kyc ${EddsaPublicKey(it.getBytes("account_pub"))}" - TalerIncomingType.wad -> throw UnsupportedOperationException() - } - ) - } - } - - /** List outgoing transaction metadata for debugging */ - suspend fun metadataOutgoing(): List<OutgoingTxMetadata> = db.serializable( - """ - SELECT - (amount).val as amount_val - ,(amount).frac AS amount_frac - ,subject - ,execution_time - ,credit_payto - ,end_to_end_id - ,wtid - ,exchange_base_url - FROM outgoing_transactions - LEFT OUTER JOIN talerable_outgoing_transactions using (outgoing_transaction_id) - ORDER BY execution_time - """ - ) { - all { - OutgoingTxMetadata( - date = it.getLong("execution_time").asInstant(), - amount = it.getDecimal("amount"), - subject = it.getString("subject"), - creditor = it.getString("credit_payto"), - id = it.getString("end_to_end_id"), - wtid = it.getBytes("wtid")?.run { ShortHashCode(this) }, - exchangeBaseUrl = it.getString("exchange_base_url") - ) - } - } - - /** List initiated transaction metadata for debugging */ - suspend fun metadataInitiated(): List<InitiatedTxMetadata> = db.serializable( - """ - SELECT - (amount).val as amount_val - ,(amount).frac AS amount_frac - ,subject - ,initiation_time - ,submission_date - ,submission_counter - ,credit_payto - ,end_to_end_id - ,initiated_outgoing_transactions.status - ,initiated_outgoing_transactions.status_msg - FROM initiated_outgoing_transactions - LEFT JOIN initiated_outgoing_batches USING (initiated_outgoing_batch_id) - ORDER BY initiation_time - """ - ) { - all { - InitiatedTxMetadata( - date = it.getLong("initiation_time").asInstant(), - amount = it.getDecimal("amount"), - subject = it.getString("subject"), - creditor = it.getString("credit_payto"), - id = it.getString("end_to_end_id"), - status = it.getString("status"), - msg = it.getString("status_msg"), - submissionTime = it.getLong("submission_date").asInstant(), - submissionCounter = it.getInt("submission_counter") - ) - } - } -} - -/** Incoming transaction metadata for debugging */ -data class IncomingTxMetadata( - val date: Instant, - val amount: DecimalNumber, - val subject: String, - val debtor: String, - val id: String?, - val talerable: String? -) - -/** Outgoing transaction metadata for debugging */ -data class OutgoingTxMetadata( - val date: Instant, - val amount: DecimalNumber, - val subject: String?, - val creditor: String?, - val id: String, - val wtid: ShortHashCode?, - val exchangeBaseUrl: String? -) - -/** Initiated metadata for debugging */ -data class InitiatedTxMetadata( - val date: Instant, - val amount: DecimalNumber, - val subject: String, - val creditor: String, - val id: String, - val status: String, - val msg: String?, - val submissionTime: Instant, - val submissionCounter: Int -) -\ No newline at end of file +} +\ No newline at end of file diff --git a/nexus/src/test/kotlin/helpers.kt b/nexus/src/test/kotlin/helpers.kt @@ -195,7 +195,7 @@ suspend fun talerableKycIn(db: Database, nullId: Boolean = false, amount: String /** Register an incoming transaction */ suspend fun registerIn(db: Database) { - registerIncomingPayment(db, NexusIngestConfig.default(AccountType.normal), genInPay("ignored")) + registerIncomingPayment(db, NexusIngestConfig.default(AccountType.exchange), genInPay("ignored")) } /** Register an outgoing transaction */