commit c47bf440794343d46edeec979817dbbf975a07fd
parent fdb0dd338087815af47f84278c4f5bebcf8fa415
Author: Antoine A <>
Date: Fri, 1 Aug 2025 16:40:02 +0200
nexus: improve ack logic
Diffstat:
6 files changed, 78 insertions(+), 27 deletions(-)
diff --git a/database-versioning/libeufin-nexus-0012.sql b/database-versioning/libeufin-nexus-0012.sql
@@ -20,6 +20,6 @@ SELECT _v.register_patch('libeufin-nexus-0012', NULL, NULL);
SET search_path TO libeufin_nexus;
ALTER TABLE initiated_outgoing_transactions
- ADD COLUMN awaiting_ack BOOLEAN NOT NULL DEFAULT FALSE;
+ ADD COLUMN awaiting_ack BOOLEAN NOT NULL DEFAULT TRUE;
COMMIT;
diff --git a/database-versioning/libeufin-nexus-procedures.sql b/database-versioning/libeufin-nexus-procedures.sql
@@ -488,7 +488,7 @@ local_sum taler_amount DEFAULT (0, 0)::taler_amount;
tx record;
BEGIN
IF require_ack THEN
- pending = EXISTS(SELECT FROM initiated_outgoing_transactions WHERE initiated_outgoing_batch_id IS NULL AND awaiting_ack);
+ pending = EXISTS(SELECT FROM initiated_outgoing_transactions WHERE initiated_outgoing_batch_id IS NULL AND NOT awaiting_ack);
ELSE
pending = EXISTS(SELECT FROM initiated_outgoing_transactions WHERE initiated_outgoing_batch_id IS NULL);
END IF;
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/cli/List.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/cli/List.kt
@@ -115,26 +115,39 @@ class ListInitiated: TalerCmd("initiated") {
override fun run() = cliCmd(logger) {
nexusConfig(config).withDb { db, cfg ->
- val txs = db.list.initiated(awaitingAck)
- for (tx in txs) {
- println(buildString{
- append("${tx.date} ${tx.id} ${tx.amount}\n")
- append(" creditor: ${fmtPayto(tx.creditor)}\n")
- append(" subject: ${tx.subject}\n")
- if (tx.batch != null) {
- append(" batch: ${tx.batch}")
- if (tx.batchOrder != null)
- append(" ${tx.batchOrder}")
+ if (awaitingAck) {
+ val txs = db.list.initiatedAck()
+ for (tx in txs) {
+ println(buildString{
+ append("${tx.date} ${tx.id} ${tx.amount}\n")
+ append(" creditor: ${fmtPayto(tx.creditor)}\n")
+ append(" subject: ${tx.subject}\n")
+ append(" ack: ${tx.dbId}")
append('\n')
- }
- append(" submission: ${tx.submissionTime} ${tx.submissionCounter}\n")
- append(" status: ${tx.status}")
- if (tx.msg != null) {
- append(" ${tx.msg}")
- }
- append('\n')
- })
- }
+ })
+ }
+ } else {
+ val txs = db.list.initiated()
+ for (tx in txs) {
+ println(buildString{
+ append("${tx.date} ${tx.id} ${tx.amount}\n")
+ append(" creditor: ${fmtPayto(tx.creditor)}\n")
+ append(" subject: ${tx.subject}\n")
+ if (tx.batch != null) {
+ append(" batch: ${tx.batch}")
+ if (tx.batchOrder != null)
+ append(" ${tx.batchOrder}")
+ append('\n')
+ }
+ append(" submission: ${tx.submissionTime} ${tx.submissionCounter}\n")
+ append(" status: ${tx.status}")
+ if (tx.msg != null) {
+ append(" ${tx.msg}")
+ }
+ append('\n')
+ })
+ }
+ }
}
}
}
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/db/InitiatedDAO.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/db/InitiatedDAO.kt
@@ -305,7 +305,7 @@ class InitiatedDAO(private val db: Database) {
}
suspend fun ack(id: Long): Boolean {
- return db.serializable("UPDATE initiated_outgoing_transactions SET awaiting_ack=true") {
+ return db.serializable("UPDATE initiated_outgoing_transactions SET awaiting_ack=false") {
executeUpdateCheck()
}
}
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/db/ListDAO.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/db/ListDAO.kt
@@ -112,7 +112,7 @@ class ListDAO(private val db: Database) {
}
/** List initiated transaction metadata for debugging */
- suspend fun initiated(awaitingAck: Boolean): List<InitiatedTxMetadata> = db.serializable(
+ suspend fun initiated(): List<InitiatedTxMetadata> = db.serializable(
"""
SELECT
(amount).val AS amount_val
@@ -129,7 +129,6 @@ class ListDAO(private val db: Database) {
,initiated_outgoing_transactions.status_msg
FROM initiated_outgoing_transactions
LEFT JOIN initiated_outgoing_batches USING (initiated_outgoing_batch_id)
- ${if (awaitingAck) "WHERE initiated_outgoing_transactions.initiated_outgoing_batch_id IS NULL AND awaiting_ack = true" else ""}
ORDER BY initiation_time
"""
) {
@@ -149,6 +148,34 @@ class ListDAO(private val db: Database) {
)
}
}
+
+ /** List initiated transaction metadata pending acknowledgment for debugging */
+ suspend fun initiatedAck(): List<InitiatedTxMetadataAck> = db.serializable(
+ """
+ SELECT
+ (amount).val AS amount_val
+ ,(amount).frac AS amount_frac
+ ,subject
+ ,initiation_time
+ ,credit_payto
+ ,end_to_end_id
+ ,initiated_outgoing_transaction_id
+ FROM initiated_outgoing_transactions
+ WHERE initiated_outgoing_batch_id IS NULL AND NOT awaiting_ack
+ ORDER BY initiation_time
+ """
+ ) {
+ all {
+ InitiatedTxMetadataAck(
+ date = it.getLong("initiation_time").asInstant(),
+ amount = it.getAmount("amount", db.currency),
+ subject = it.getString("subject"),
+ creditor = it.getString("credit_payto"),
+ id = it.getString("end_to_end_id"),
+ dbId = it.getLong("initiated_outgoing_transaction_id"),
+ )
+ }
+ }
}
/** Incoming transaction metadata for debugging */
@@ -187,4 +214,14 @@ data class InitiatedTxMetadata(
val msg: String?,
val submissionTime: Instant,
val submissionCounter: Int
+)
+
+/** Initiated metadata for debugging */
+data class InitiatedTxMetadataAck(
+ val date: Instant,
+ val amount: TalerAmount,
+ val subject: String,
+ val creditor: String,
+ val dbId: Long,
+ val id: String
)
\ No newline at end of file
diff --git a/testbench/src/main/kotlin/Main.kt b/testbench/src/main/kotlin/Main.kt
@@ -208,9 +208,10 @@ class Cli : CliktCommand() {
put("report", "Fetch BankToCustomerAccountReport", "ebics-fetch $ebicsFlags report")
put("notification", "Fetch BankToCustomerDebitCreditNotification", "ebics-fetch $ebicsFlags notification")
put("statement", "Fetch BankToCustomerStatement", "ebics-fetch $ebicsFlags statement")
- put("list-incoming", "List incoming transaction", "testing list $flags incoming")
- put("list-outgoing", "List outgoing transaction", "testing list $flags outgoing")
- put("list-initiated", "List initiated payments", "testing list $flags initiated")
+ put("list-incoming", "List incoming transaction", "list incoming $flags")
+ put("list-outgoing", "List outgoing transaction", "list outgoing $flags")
+ put("list-initiated", "List initiated payments", "list initiated $flags")
+ put("list-ack", "List initiated payments pending manual submission acknowledgement", "list initiated $flags --awaiting-ack")
put("wss", "Listen to notification over websocket", "testing wss $debugFlags")
put("submit", "Submit pending transactions", "ebics-submit $ebicsFlags")
put("export", "Export pending batches as pain001 messages", "manual export $flags payments.zip")