gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[libeufin] branch master updated (a43fd507 -> 4f013599)


From: gnunet
Subject: [libeufin] branch master updated (a43fd507 -> 4f013599)
Date: Mon, 23 Oct 2023 12:17:44 +0200

This is an automated email from the git hooks/post-receive script.

antoine pushed a change to branch master
in repository libeufin.

    from a43fd507 Add /monitor endpoint and start testing stats
     new 4dc22917 Fix /monitor
     new 4f013599 cleanup

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../main/kotlin/tech/libeufin/bank/CoreBankApi.kt  |  2 +-
 .../src/main/kotlin/tech/libeufin/bank/Database.kt | 60 ++++++++++++----------
 bank/src/main/kotlin/tech/libeufin/bank/Main.kt    |  4 +-
 .../main/kotlin/tech/libeufin/bank/TalerMessage.kt |  8 +--
 .../kotlin/tech/libeufin/bank/WireGatewayApi.kt    |  2 +-
 bank/src/main/kotlin/tech/libeufin/bank/helpers.kt | 58 +++++++--------------
 bank/src/test/kotlin/CoreBankApiTest.kt            |  4 +-
 bank/src/test/kotlin/StatsTest.kt                  | 10 ++--
 bank/src/test/kotlin/WireGatewayApiTest.kt         |  6 +--
 bank/src/test/kotlin/helpers.kt                    |  2 +-
 database-versioning/procedures.sql                 | 12 +++--
 11 files changed, 79 insertions(+), 89 deletions(-)

diff --git a/bank/src/main/kotlin/tech/libeufin/bank/CoreBankApi.kt 
b/bank/src/main/kotlin/tech/libeufin/bank/CoreBankApi.kt
index 848c525d..5804a951 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/CoreBankApi.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/CoreBankApi.kt
@@ -343,7 +343,7 @@ private fun Routing.coreBankAccountsMgmtApi(db: Database, 
ctx: BankApplicationCo
 private fun Routing.coreBankTransactionsApi(db: Database, ctx: 
BankApplicationContext) {
     get("/accounts/{USERNAME}/transactions") {
         call.authCheck(db, TokenScope.readonly)
-        val params = getHistoryParams(call.request.queryParameters)
+        val params = HistoryParams.extract(call.request.queryParameters)
         val bankAccount = call.bankAccount(db)
 
         val history: List<BankAccountTransactionInfo> = 
db.bankPoolHistory(params, bankAccount.bankAccountId!!)
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Database.kt 
b/bank/src/main/kotlin/tech/libeufin/bank/Database.kt
index e9b92079..c64d1a74 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/Database.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/Database.kt
@@ -96,7 +96,7 @@ private fun PreparedStatement.executeUpdateViolation(): 
Boolean {
     }
 }
 
-class Database(dbConfig: String, private val bankCurrency: String, private val 
fiatCurrency: String): java.io.Closeable {
+class Database(dbConfig: String, private val bankCurrency: String, private val 
fiatCurrency: String?): java.io.Closeable {
     val dbPool: HikariDataSource
     private val notifWatcher: NotificationWatcher
 
@@ -1486,7 +1486,7 @@ class Database(dbConfig: String, private val 
bankCurrency: String, private val f
                 ,internal_taler_payments_count
                 ,(internal_taler_payments_volume).val as 
internal_taler_payments_volume_val
                 ,(internal_taler_payments_volume).frac as 
internal_taler_payments_volume_frac
-            FROM stats_get_frame(?::stat_timeframe_enum, ?)
+            FROM stats_get_frame(now()::timestamp, ?::stat_timeframe_enum, ?)
         """)
         stmt.setString(1, params.timeframe.name)
         if (params.which != null) {
@@ -1496,18 +1496,22 @@ class Database(dbConfig: String, private val 
bankCurrency: String, private val f
         }
         stmt.oneOrNull {
             MonitorResponse(
-                cashinCount = it.getLong("cashin_count"),
-                cashinExternalVolume = TalerAmount(
-                    value = it.getLong("cashin_volume_in_fiat_val"),
-                    frac = it.getInt("cashin_volume_in_fiat_frac"),
-                    currency = fiatCurrency
-                ),
-                cashoutCount = it.getLong("cashout_count"),
-                cashoutExternalVolume = TalerAmount(
-                    value = it.getLong("cashout_volume_in_fiat_val"),
-                    frac = it.getInt("cashout_volume_in_fiat_frac"),
-                    currency = fiatCurrency
-                ),
+                cashinCount = fiatCurrency?.run { it.getLong("cashin_count") },
+                cashinExternalVolume = fiatCurrency?.run { 
+                    TalerAmount(
+                        value = it.getLong("cashin_volume_in_fiat_val"),
+                        frac = it.getInt("cashin_volume_in_fiat_frac"),
+                        currency = this
+                    )
+                },
+                cashoutCount = fiatCurrency?.run { it.getLong("cashout_count") 
},
+                cashoutExternalVolume = fiatCurrency?.run {
+                    TalerAmount(
+                        value = it.getLong("cashout_volume_in_fiat_val"),
+                        frac = it.getInt("cashout_volume_in_fiat_frac"),
+                        currency = this
+                    )
+                },
                 talerPayoutCount = it.getLong("internal_taler_payments_count"),
                 talerPayoutInternalVolume = TalerAmount(
                     value = it.getLong("internal_taler_payments_volume_val"),
@@ -1516,18 +1520,22 @@ class Database(dbConfig: String, private val 
bankCurrency: String, private val f
                 )
             )
         } ?: MonitorResponse(
-            cashinCount = 0,
-            cashinExternalVolume = TalerAmount(
-                value = 0,
-                frac = 0,
-                currency = fiatCurrency
-            ),
-            cashoutCount = 0,
-            cashoutExternalVolume = TalerAmount(
-                value = 0,
-                frac = 0,
-                currency = fiatCurrency
-            ),
+            cashinCount = fiatCurrency?.run { 0 },
+            cashinExternalVolume = fiatCurrency?.run {
+                TalerAmount(
+                    value = 0,
+                    frac = 0,
+                    currency = this
+                )
+            },
+            cashoutCount = fiatCurrency?.run { 0 },
+            cashoutExternalVolume = fiatCurrency?.run {
+                TalerAmount(
+                    value = 0,
+                    frac = 0,
+                    currency = this
+                )
+            },
             talerPayoutCount = 0,
             talerPayoutInternalVolume = TalerAmount(
                 value = 0,
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Main.kt 
b/bank/src/main/kotlin/tech/libeufin/bank/Main.kt
index 674ab6b2..7f8aa237 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/Main.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/Main.kt
@@ -344,7 +344,7 @@ class ServeBank : CliktCommand("Run libeufin-bank HTTP 
server", name = "serve")
             logger.info("Can only serve libeufin-bank via TCP")
             exitProcess(1)
         }
-        val db = Database(dbCfg.dbConnStr, ctx.currency, "TODO")
+        val db = Database(dbCfg.dbConnStr, ctx.currency, null)
         runBlocking {
             if (!maybeCreateAdminAccount(db, ctx)) // logs provided by the 
helper
                 exitProcess(1)
@@ -367,7 +367,7 @@ class ChangePw : CliktCommand("Change account password", 
name = "passwd") {
         val cfg = talerConfig(configFile)
         val ctx = cfg.loadBankApplicationContext() 
         val dbCfg = cfg.loadDbConfig()
-        val db = Database(dbCfg.dbConnStr, ctx.currency, "TODO")
+        val db = Database(dbCfg.dbConnStr, ctx.currency, null)
         runBlocking {
             if (!maybeCreateAdminAccount(db, ctx)) // logs provided by the 
helper
             exitProcess(1)
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/TalerMessage.kt 
b/bank/src/main/kotlin/tech/libeufin/bank/TalerMessage.kt
index 91157dbf..79c67915 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/TalerMessage.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/TalerMessage.kt
@@ -108,10 +108,10 @@ data class TokenRequest(
 
 @Serializable
 data class MonitorResponse(
-    val cashinCount: Long,
-    val cashinExternalVolume: TalerAmount,
-    val cashoutCount: Long,
-    val cashoutExternalVolume: TalerAmount,
+    val cashinCount: Long? = null,
+    val cashinExternalVolume: TalerAmount? = null,
+    val cashoutCount: Long? = null,
+    val cashoutExternalVolume: TalerAmount? = null,
     val talerPayoutCount: Long,
     val talerPayoutInternalVolume: TalerAmount
 )
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/WireGatewayApi.kt 
b/bank/src/main/kotlin/tech/libeufin/bank/WireGatewayApi.kt
index dcf1f785..68b9c9f4 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/WireGatewayApi.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/WireGatewayApi.kt
@@ -95,7 +95,7 @@ fun Routing.wireGatewayApi(db: Database, ctx: 
BankApplicationContext) {
         dbLambda: suspend Database.(HistoryParams, Long) -> List<T>
     ) {
         val (login, _) = call.authCheck(db, TokenScope.readonly)
-        val params = getHistoryParams(call.request.queryParameters)
+        val params = HistoryParams.extract(call.request.queryParameters)
         val bankAccount = call.bankAccount(db)
         
         if (!bankAccount.isTalerExchange)
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/helpers.kt 
b/bank/src/main/kotlin/tech/libeufin/bank/helpers.kt
index 6a6cec64..e5f2335f 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/helpers.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/helpers.kt
@@ -196,12 +196,8 @@ data class MonitorParams(
 ) {
     companion object {
         fun extract(params: Parameters): MonitorParams {
-            val timeframe = Timeframe.valueOf(params["timeframe"] ?: throw 
MissingRequestParameterException(parameterName = "timeframe"))
-            val which = try {
-                params["which"]?.toInt()
-            } catch (e: Exception) {
-                throw badRequest("Param 'which' not a number")
-            }
+            val timeframe = Timeframe.valueOf(params["timeframe"] ?: "hour")
+            val which = params["which"]?.run { toIntOrNull() ?: throw 
badRequest("Param 'which' not a number") }
             if (which != null) {
                 val lastDayOfMonth = 
OffsetDateTime.now(ZoneOffset.UTC).with(TemporalAdjusters.lastDayOfMonth()).dayOfMonth
                 when {
@@ -223,41 +219,25 @@ data class MonitorParams(
 
 data class HistoryParams(
     val delta: Int, val start: Long, val poll_ms: Long
-)
-
-/**
- * Extracts the query parameters from "history-like" endpoints,
- * providing the defaults according to the API specification.
- */
-fun getHistoryParams(params: Parameters): HistoryParams {
-    val deltaParam: String =
-        params["delta"] ?: throw 
MissingRequestParameterException(parameterName = "delta")
-    val delta: Int = try {
-        deltaParam.toInt()
-    } 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 = params["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")
-        }
-    }
-    val poll_ms: Long = when (val param = params["long_poll_ms"]) {
-        null -> 0
-        else -> try {
-            param.toLong()
-        } catch (e: Exception) {
-            logger.error(e.message)
-            throw badRequest("Param 'long_poll_ms' not a number")
+) {
+    companion object {
+        fun extract(params: Parameters): HistoryParams {
+            val deltaParam: String =
+                params["delta"] ?: throw 
MissingRequestParameterException(parameterName = "delta")
+            val delta: Int = deltaParam.toIntOrNull() ?: throw 
badRequest("Param 'delta' not a number")
+            // Note: minimum 'start' is zero, as database IDs start from 1.
+            val start: Long = when (val param = params["start"]) {
+                null -> if (delta >= 0) 0L else Long.MAX_VALUE
+                else -> param.toLongOrNull() ?: throw badRequest("Param 
'start' not a number")
+            }
+            val poll_ms: Long = when (val param = params["long_poll_ms"]) {
+                null -> 0
+                else -> param.toLongOrNull() ?: throw badRequest("Param 
'long_poll_ms' not a number")
+            }
+            // TODO check params range
+            return HistoryParams(delta = delta, start = start, poll_ms = 
poll_ms)
         }
     }
-    return HistoryParams(delta = delta, start = start, poll_ms = poll_ms)
 }
 
 /**
diff --git a/bank/src/test/kotlin/CoreBankApiTest.kt 
b/bank/src/test/kotlin/CoreBankApiTest.kt
index be984cf5..56fbb002 100644
--- a/bank/src/test/kotlin/CoreBankApiTest.kt
+++ b/bank/src/test/kotlin/CoreBankApiTest.kt
@@ -456,9 +456,9 @@ class CoreBankTransactionsApiTest {
     fun testHistory() = bankSetup { _ -> 
         suspend fun HttpResponse.assertHistory(size: Int) {
             assertOk()
-            val txt = this.bodyAsText()
+            val txt = bodyAsText()
             val history = 
Json.decodeFromString<BankAccountTransactionsResponse>(txt)
-            val params = getHistoryParams(this.call.request.url.parameters)
+            val params = HistoryParams.extract(call.request.url.parameters)
        
             // testing the size is like expected.
             assert(history.transactions.size == size) {
diff --git a/bank/src/test/kotlin/StatsTest.kt 
b/bank/src/test/kotlin/StatsTest.kt
index ac4a6b13..28ecbd57 100644
--- a/bank/src/test/kotlin/StatsTest.kt
+++ b/bank/src/test/kotlin/StatsTest.kt
@@ -34,7 +34,7 @@ class StatsTest {
     @Test
     fun internalTalerPayment() = bankSetup { db ->  
         db.conn { conn ->
-            val stmt = conn.prepareStatement("CALL 
stats_register_internal_taler_payment((?, ?)::taler_amount)")
+            val stmt = conn.prepareStatement("CALL 
stats_register_internal_taler_payment(now()::timestamp, (?, ?)::taler_amount)")
         
             suspend fun register(amount: TalerAmount) {
                 stmt.setLong(1, amount.value)
@@ -42,7 +42,7 @@ class StatsTest {
                 stmt.executeUpdate()
             }
 
-            client.get("/monitor?timeframe=hour") {
+            client.get("/monitor") {
                 basicAuth("admin", "admin-password")
             }.assertOk().run {
                 val resp = Json.decodeFromString<MonitorResponse>(bodyAsText())
@@ -51,7 +51,7 @@ class StatsTest {
             }
 
             register(TalerAmount("KUDOS:10.0"))
-            client.get("/monitor?timeframe=hour") {
+            client.get("/monitor") {
                 basicAuth("admin", "admin-password")
             }.assertOk().run {
                 val resp = Json.decodeFromString<MonitorResponse>(bodyAsText())
@@ -60,7 +60,7 @@ class StatsTest {
             }
 
             register(TalerAmount("KUDOS:30.5"))
-            client.get("/monitor?timeframe=hour") {
+            client.get("/monitor") {
                 basicAuth("admin", "admin-password")
             }.assertOk().run {
                 val resp = Json.decodeFromString<MonitorResponse>(bodyAsText())
@@ -68,7 +68,7 @@ class StatsTest {
                 assertEquals(TalerAmount("KUDOS:40.5"), 
resp.talerPayoutInternalVolume)
             }
 
-            // TODO Test timeframe logic using now() mocking
+            // TODO Test timeframe logic with different timestamps
         }
     }
 }
\ No newline at end of file
diff --git a/bank/src/test/kotlin/WireGatewayApiTest.kt 
b/bank/src/test/kotlin/WireGatewayApiTest.kt
index e98043ba..1fa33dba 100644
--- a/bank/src/test/kotlin/WireGatewayApiTest.kt
+++ b/bank/src/test/kotlin/WireGatewayApiTest.kt
@@ -213,9 +213,9 @@ class WireGatewayApiTest {
 
         suspend fun HttpResponse.assertHistory(size: Int) {
             assertOk()
-            val txt = this.bodyAsText()
+            val txt = bodyAsText()
             val history = Json.decodeFromString<IncomingHistory>(txt)
-            val params = getHistoryParams(this.call.request.url.parameters)
+            val params = HistoryParams.extract(call.request.url.parameters)
        
             // testing the size is like expected.
             assert(history.incoming_transactions.size == size) {
@@ -394,7 +394,7 @@ class WireGatewayApiTest {
             assertOk()
             val txt = this.bodyAsText()
             val history = Json.decodeFromString<OutgoingHistory>(txt)
-            val params = getHistoryParams(this.call.request.url.parameters)
+            val params = 
HistoryParams.extract(this.call.request.url.parameters)
        
             // testing the size is like expected.
             assert(history.outgoing_transactions.size == size) {
diff --git a/bank/src/test/kotlin/helpers.kt b/bank/src/test/kotlin/helpers.kt
index 09a71459..cf3f40e0 100644
--- a/bank/src/test/kotlin/helpers.kt
+++ b/bank/src/test/kotlin/helpers.kt
@@ -58,7 +58,7 @@ fun setup(
     resetDatabaseTables(dbCfg, "libeufin-bank")
     initializeDatabaseTables(dbCfg, "libeufin-bank")
     val ctx = config.loadBankApplicationContext()
-    Database(dbCfg.dbConnStr, ctx.currency, "TODO").use {
+    Database(dbCfg.dbConnStr, ctx.currency, null).use {
         runBlocking {
             lambda(it, ctx)
         }
diff --git a/database-versioning/procedures.sql 
b/database-versioning/procedures.sql
index f0ae6fbb..b6b098c6 100644
--- a/database-versioning/procedures.sql
+++ b/database-versioning/procedures.sql
@@ -1020,6 +1020,7 @@ BEGIN
 END $$;
 
 CREATE OR REPLACE FUNCTION stats_get_frame(
+  IN now TIMESTAMP,
   IN timeframe stat_timeframe_enum,
   IN which INTEGER,
   OUT cashin_count BIGINT,
@@ -1040,15 +1041,16 @@ LANGUAGE sql AS $$
     FROM regional_stats AS s
   WHERE s.timeframe = timeframe 
     AND start_time = CASE 
-      WHEN which IS NULL        THEN date_trunc(timeframe::text, now())
-      WHEN timeframe = 'hour'   THEN date_trunc('day', now()) + '1 
hour'::interval * which
-      WHEN timeframe = 'day'    THEN date_trunc('month', now()) + '1 
day'::interval * which
-      WHEN timeframe = 'month'  THEN date_trunc('year', now()) + '1 
month'::interval * which
+      WHEN which IS NULL        THEN date_trunc(timeframe::text, now)
+      WHEN timeframe = 'hour'   THEN date_trunc('day', now) + '1 
hour'::interval * which
+      WHEN timeframe = 'day'    THEN date_trunc('month', now) + '1 
day'::interval * which
+      WHEN timeframe = 'month'  THEN date_trunc('year', now) + '1 
month'::interval * which
       WHEN timeframe = 'year'   THEN make_date(which, 1, 1)::TIMESTAMP
     END
 $$;
 
 CREATE OR REPLACE PROCEDURE stats_register_internal_taler_payment(
+  IN now TIMESTAMP,
   IN amount taler_amount
 )
 LANGUAGE plpgsql AS $$
@@ -1068,7 +1070,7 @@ BEGIN
       ) 
     VALUES (
         frame
-        ,date_trunc(frame::text, now())
+        ,date_trunc(frame::text, now)
         ,0
         ,(0, 0)::taler_amount
         ,0

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]