[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libeufin] branch master updated: time ranged history (access API)
From: |
gnunet |
Subject: |
[libeufin] branch master updated: time ranged history (access API) |
Date: |
Wed, 22 Mar 2023 16:23:52 +0100 |
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 4887d87c time ranged history (access API)
4887d87c is described below
commit 4887d87c0be652b21fcf6f2c6d6dde2b05dd4a66
Author: ms <ms@taler.net>
AuthorDate: Wed Mar 22 16:23:29 2023 +0100
time ranged history (access API)
---
nexus/src/test/kotlin/SandboxAccessApiTest.kt | 73 ++++++++++++++++++++++
.../src/main/kotlin/tech/libeufin/sandbox/Main.kt | 29 +++++----
util/src/main/kotlin/HTTP.kt | 15 +++++
3 files changed, 105 insertions(+), 12 deletions(-)
diff --git a/nexus/src/test/kotlin/SandboxAccessApiTest.kt
b/nexus/src/test/kotlin/SandboxAccessApiTest.kt
index b5182bd1..4c0232c9 100644
--- a/nexus/src/test/kotlin/SandboxAccessApiTest.kt
+++ b/nexus/src/test/kotlin/SandboxAccessApiTest.kt
@@ -1,3 +1,4 @@
+import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.databind.ObjectMapper
import io.ktor.client.plugins.*
import io.ktor.client.request.*
@@ -63,6 +64,78 @@ class SandboxAccessApiTest {
}
}
+ // Tests the time range filter of Access API's GET /transactions
+ @Test
+ fun timeRangedTransactions() {
+ fun getTxs(respJson: String): JsonNode {
+ val mapper = ObjectMapper()
+ return mapper.readTree(respJson).get("transactions")
+ }
+ withTestDatabase {
+ prepSandboxDb()
+ testApplication {
+ application(sandboxApp)
+ var R =
client.get("/demobanks/default/access-api/accounts/foo/transactions") {
+ expectSuccess = true
+ basicAuth("foo", "foo")
+ }
+ assert(getTxs(R.bodyAsText()).size() == 0) // Checking that no
transactions exist.
+ wireTransfer(
+ "admin",
+ "foo",
+ "default",
+ "#0",
+ "TESTKUDOS:2"
+ )
+ R =
client.get("/demobanks/default/access-api/accounts/foo/transactions") {
+ expectSuccess = true
+ basicAuth("foo", "foo")
+ }
+ assert(getTxs(R.bodyAsText()).size() == 1) // Checking that #0
shows up.
+ // Asking up to a point in the past, where no txs should exist.
+ R =
client.get("/demobanks/default/access-api/accounts/foo/transactions?until_ms=3000")
{
+ expectSuccess = true
+ basicAuth("foo", "foo")
+ }
+ assert(getTxs(R.bodyAsText()).size() == 0) // Not expecting
any transaction.
+ // Moving the transaction back in the past
+ transaction {
+ val tx_0 = BankAccountTransactionEntity.find {
+ BankAccountTransactionsTable.subject eq "#0" and
+ (BankAccountTransactionsTable.direction eq
"CRDT")
+ }.first()
+ tx_0.date = 10000
+ }
+ // Picking the past transaction from one including time range,
+ // therefore expecting one entry in the result
+ R =
client.get("/demobanks/default/access-api/accounts/foo/transactions?from_ms=9000&until_ms=11000")
{
+ expectSuccess = true
+ basicAuth("foo", "foo")
+ }
+ assert(getTxs(R.bodyAsText()).size() == 1)
+ // Not enough txs to fill the second page, expecting no txs
therefore.
+ R =
client.get("/demobanks/default/access-api/accounts/foo/transactions?page=2&size=1")
{
+ expectSuccess = true
+ basicAuth("foo", "foo")
+ }
+ assert(getTxs(R.bodyAsText()).size() == 0)
+ // Creating one more tx and asking the second 1-sized page,
expecting therefore one result.
+ wireTransfer(
+ "admin",
+ "foo",
+ "default",
+ "#1",
+ "TESTKUDOS:2"
+ )
+ R =
client.get("/demobanks/default/access-api/accounts/foo/transactions?page=2&size=1")
{
+ expectSuccess = true
+ basicAuth("foo", "foo")
+ }
+ assert(getTxs(R.bodyAsText()).size() == 1)
+ }
+ }
+ }
+
// Tests for #7482
@Test
fun highAmountWithdraw() {
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
index 5bceaf6b..4d91257d 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
@@ -1482,34 +1482,39 @@ val sandboxApp: Application.() -> Unit = {
val authGranted: Boolean = bankAccount.isPublic ||
!WITH_AUTH || username == "admin"
if (!authGranted && bankAccount.owner != username)
throw forbidden("Cannot access bank account
${bankAccount.label}")
- val page: Int =
Integer.decode(call.request.queryParameters["page"] ?: "0")
- val size: Int =
Integer.decode(call.request.queryParameters["size"] ?: "5")
-
+ // Paging values.
+ val page: Int =
expectInt(call.request.queryParameters["page"] ?: "1")
+ val size: Int =
expectInt(call.request.queryParameters["size"] ?: "5")
+ // Time range filter values
+ val fromMs =
expectLong(call.request.queryParameters["from_ms"] ?: "0")
+ val untilMs =
expectLong(call.request.queryParameters["until_ms"] ?:
Long.MAX_VALUE.toString())
val ret = mutableListOf<RawPayment>()
/**
* Case where page number wasn't given,
- * therefore the results starts from the last transaction.
*/
+ * therefore the results starts from the last transaction.
+ */
transaction {
/**
* Get a history page - from the calling bank account
- having
* 'firstElementId' as the latest transaction in it.
*/
fun getPage(firstElementId: Long):
Iterable<BankAccountTransactionEntity> {
- logger.debug("History page from tx
$firstElementId, including $size txs in the past.")
+ logger.debug("Trying to build pageBuf from ID:
$firstElementId," +
+ " including $size txs in the past."
+ )
return BankAccountTransactionEntity.find {
(BankAccountTransactionsTable.id lessEq
firstElementId) and
- (BankAccountTransactionsTable.account
eq bankAccount.id)
+ (BankAccountTransactionsTable.account
eq bankAccount.id) and
+
(BankAccountTransactionsTable.date.between(fromMs, untilMs))
}.sortedByDescending { it.id.value }.take(size)
}
val lt: BankAccountTransactionEntity? =
bankAccount.lastTransaction
if (lt == null) return@transaction
var nextPageIdUpperLimit: Long = lt.id.value
- /**
- * This loop fetches (and discards) pages until the
- * desired one is found. */
- for (i in 0..(page)) {
+ // This loop fetches (and discards) pages until the
desired one is found.
+ for (i in 1..(page)) {
val pageBuf = getPage(nextPageIdUpperLimit)
- logger.debug("Processing page:")
- pageBuf.forEach { logger.debug("${it.id}
${it.subject} ${it.amount}") }
+ logger.debug("pageBuf #$i follows. Request wants
#$page:")
+ pageBuf.forEach { logger.debug("ID: ${it.id},
subject: ${it.subject}, amount: ${it.currency}:${it.amount}") }
if (pageBuf.none()) return@transaction
nextPageIdUpperLimit = pageBuf.last().id.value - 1
if (i == page) pageBuf.forEach {
diff --git a/util/src/main/kotlin/HTTP.kt b/util/src/main/kotlin/HTTP.kt
index 85e592ab..374bc857 100644
--- a/util/src/main/kotlin/HTTP.kt
+++ b/util/src/main/kotlin/HTTP.kt
@@ -186,3 +186,18 @@ fun extractUserAndPassword(authorizationHeader: String):
Pair<String, String> {
}
return Pair(username, password)
}
+
+fun expectInt(uriParam: String): Int {
+ return try { Integer.decode(uriParam) }
+ catch (e: Exception) {
+ logger.error(e.message)
+ throw badRequest("'$uriParam' is not Int")
+ }
+}
+fun expectLong(uriParam: String): Long {
+ return try { uriParam.toLong() }
+ catch (e: Exception) {
+ logger.error(e.message)
+ throw badRequest("'$uriParam' is not Long")
+ }
+}
\ No newline at end of file
--
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: time ranged history (access API),
gnunet <=