commit 4dc2291775e2eaca3c82ca943338962285051b68
parent a43fd507072d18eb559420e271587db5690b3d8d
Author: Antoine A <>
Date: Mon, 23 Oct 2023 10:04:10 +0000
Fix /monitor
Diffstat:
7 files changed, 54 insertions(+), 44 deletions(-)
diff --git 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
@@ -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
@@ -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/helpers.kt b/bank/src/main/kotlin/tech/libeufin/bank/helpers.kt
@@ -196,7 +196,7 @@ data class MonitorParams(
) {
companion object {
fun extract(params: Parameters): MonitorParams {
- val timeframe = Timeframe.valueOf(params["timeframe"] ?: throw MissingRequestParameterException(parameterName = "timeframe"))
+ val timeframe = Timeframe.valueOf(params["timeframe"] ?: "hour")
val which = try {
params["which"]?.toInt()
} catch (e: Exception) {
diff --git 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/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
@@ -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