[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libeufin] branch master updated: Implementing GET /transactions.
From: |
gnunet |
Subject: |
[libeufin] branch master updated: Implementing GET /transactions. |
Date: |
Mon, 18 Sep 2023 15:25:00 +0200 |
This is an automated email from the git hooks/post-receive script.
ms pushed a commit to branch master
in repository libeufin.
The following commit(s) were added to refs/heads/master by this push:
new f632635b Implementing GET /transactions.
f632635b is described below
commit f632635b3292df19b5c204861eab7f74be07731b
Author: MS <ms@taler.net>
AuthorDate: Mon Sep 18 15:24:14 2023 +0200
Implementing GET /transactions.
---
.../src/main/kotlin/tech/libeufin/bank/Database.kt | 34 ++++++++-------
.../tech/libeufin/bank/transactionsHandlers.kt | 48 ++++++++++++++++++++++
bank/src/main/kotlin/tech/libeufin/bank/types.kt | 7 ++++
bank/src/test/kotlin/DatabaseTest.kt | 5 +--
4 files changed, 77 insertions(+), 17 deletions(-)
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Database.kt
b/bank/src/main/kotlin/tech/libeufin/bank/Database.kt
index be196676..34689a47 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/Database.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/Database.kt
@@ -25,6 +25,7 @@ import java.sql.DriverManager
import java.sql.PreparedStatement
import java.sql.SQLException
import java.util.*
+import kotlin.math.abs
private const val DB_CTR_LIMIT = 1000000
@@ -485,14 +486,19 @@ class Database(private val dbConfig: String) {
)
}
}
-
- fun bankTransactionGetForHistoryPage(
- upperBound: Long,
+ private data class HistoryParams(
+ val cmpOp: String, // < or >
+ val orderBy: String // ASC or DESC
+ )
+ fun bankTransactionGetHistory(
+ start: Long,
+ delta: Long,
bankAccountId: Long,
- fromMs: Long,
- toMs: Long
): List<BankAccountTransaction> {
reconnect()
+ val ops = if (delta < 0)
+ HistoryParams("<", "DESC") else
+ HistoryParams(">", "ASC")
val stmt = prepare("""
SELECT
creditor_payto_uri
@@ -508,15 +514,15 @@ class Database(private val dbConfig: String) {
,end_to_end_id
,direction
,bank_account_id
+ ,bank_transaction_id
FROM bank_account_transactions
- WHERE bank_transaction_id < ?
- AND bank_account_id=?
- AND transaction_date BETWEEN ? AND ?
+ WHERE bank_transaction_id ${ops.cmpOp} ? AND bank_account_id=?
+ ORDER BY bank_transaction_id ${ops.orderBy}
+ LIMIT ?
""")
- stmt.setLong(1, upperBound)
+ stmt.setLong(1, start)
stmt.setLong(2, bankAccountId)
- stmt.setLong(3, fromMs)
- stmt.setLong(4, toMs)
+ stmt.setLong(3, abs(delta))
val rs = stmt.executeQuery()
rs.use {
val ret = mutableListOf<BankAccountTransaction>()
@@ -544,9 +550,9 @@ class Database(private val dbConfig: String) {
bankAccountId = it.getLong("bank_account_id"),
paymentInformationId =
it.getString("payment_information_id"),
subject = it.getString("subject"),
- transactionDate = it.getLong("transaction_date")
- )
- )
+ transactionDate = it.getLong("transaction_date"),
+ dbRowId = it.getLong("bank_transaction_id")
+ ))
} while (it.next())
return ret
}
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/transactionsHandlers.kt
b/bank/src/main/kotlin/tech/libeufin/bank/transactionsHandlers.kt
index 0fe3ad69..2e315bdd 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/transactionsHandlers.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/transactionsHandlers.kt
@@ -2,14 +2,62 @@ package tech.libeufin.bank
import io.ktor.http.*
import io.ktor.server.application.*
+import io.ktor.server.plugins.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import net.taler.common.errorcodes.TalerErrorCode
import tech.libeufin.util.getNowUs
import tech.libeufin.util.parsePayto
+import kotlin.math.abs
fun Routing.transactionsHandlers() {
+ get("/accounts/{USERNAME}/transactions") {
+ val c = call.myAuth(TokenScope.readonly) ?: throw unauthorized()
+ val resourceName = call.expectUriComponent("USERNAME")
+ if (c.login != resourceName && c.login != "admin") throw forbidden()
+ // Collecting params.
+ val deltaParam: String = call.request.queryParameters["delta"] ?:
throw MissingRequestParameterException("Parameter 'delta' not found")
+ val delta: Long = try {
+ deltaParam.toLong()
+ } catch (e: Exception) {
+ logger.error(e.message)
+ throw badRequest("Param 'delta' not a number")
+ }
+ // Note: minimum 'start' is zero, as database IDs start from 1.
+ val start: Long = when (val param =
call.request.queryParameters["start"]) {
+ null -> if (delta >= 0) 0L else Long.MAX_VALUE
+ else -> try {
+ param.toLong()
+ } catch (e: Exception) {
+ logger.error(e.message)
+ throw badRequest("Param 'start' not a number")
+ }
+ }
+ logger.info("Param long_poll_ms not supported")
+ // Making the query.
+ val bankAccount = db.bankAccountGetFromOwnerId(c.expectRowId())
+ ?: throw internalServerError("Customer '${c.login}' lacks bank
account.")
+ val bankAccountId = bankAccount.bankAccountId
+ ?: throw internalServerError("Bank account lacks row ID.")
+ val history: List<BankAccountTransaction> =
db.bankTransactionGetHistory(bankAccountId, start, delta)
+ val res = BankAccountTransactionsResponse(transactions =
mutableListOf())
+ history.forEach {
+ res.transactions.add(BankAccountTransactionInfo(
+ debtor_payto_uri = it.debtorPaytoUri,
+ creditor_payto_uri = it.creditorPaytoUri,
+ subject = it.subject,
+ amount = it.amount.toString(),
+ direction = it.direction,
+ date = it.transactionDate,
+ row_id = it.dbRowId ?: throw internalServerError(
+ "Transaction timestamped with '${it.transactionDate}' did
not have row ID"
+ )
+ ))
+ }
+ call.respond(res)
+ return@get
+ }
// Creates a bank transaction.
post("/accounts/{USERNAME}/transactions") {
val c = call.myAuth(TokenScope.readwrite) ?: throw unauthorized()
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/types.kt
b/bank/src/main/kotlin/tech/libeufin/bank/types.kt
index d0d7d2c6..fd65d244 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/types.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/types.kt
@@ -289,6 +289,8 @@ data class BankAccountTransaction(
* bank account of the payer.
*/
val bankAccountId: Long,
+ // Null if this type is used to _create_ one transaction.
+ val dbRowId: Long? = null,
// Following are ISO20022 specific.
val accountServicerReference: String,
val paymentInformationId: String,
@@ -372,4 +374,9 @@ data class BankAccountTransactionInfo(
val subject: String,
val row_id: Long, // is T_ID
val date: Long
+)
+
+@Serializable
+data class BankAccountTransactionsResponse(
+ val transactions: MutableList<BankAccountTransactionInfo>
)
\ No newline at end of file
diff --git a/bank/src/test/kotlin/DatabaseTest.kt
b/bank/src/test/kotlin/DatabaseTest.kt
index 290d0d19..fc2a4f54 100644
--- a/bank/src/test/kotlin/DatabaseTest.kt
+++ b/bank/src/test/kotlin/DatabaseTest.kt
@@ -223,11 +223,10 @@ class DatabaseTest {
@Test
fun historyTest() {
val db = initDb()
- val res = db.bankTransactionGetForHistoryPage(
+ val res = db.bankTransactionGetHistory(
10L,
1L,
- fromMs = 0,
- toMs = Long.MAX_VALUE
+ 1L
)
assert(res.isEmpty())
}
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [libeufin] branch master updated: Implementing GET /transactions.,
gnunet <=