diff options
author | Antoine A <> | 2024-04-30 12:35:43 +0900 |
---|---|---|
committer | Antoine A <> | 2024-04-30 12:52:13 +0900 |
commit | 602a3b6e8afa3462a4f34cd6bb92005fec84c90b (patch) | |
tree | 47d3b873f20d438b025ea9ba443269d1e9b11b11 /nexus | |
parent | eeba7b9890a3fae2aebac4d7ca9423af8acd7e7d (diff) | |
download | libeufin-602a3b6e8afa3462a4f34cd6bb92005fec84c90b.tar.gz libeufin-602a3b6e8afa3462a4f34cd6bb92005fec84c90b.tar.bz2 libeufin-602a3b6e8afa3462a4f34cd6bb92005fec84c90b.zip |
nexus: revenue API
Diffstat (limited to 'nexus')
-rw-r--r-- | nexus/conf/test.conf | 5 | ||||
-rw-r--r-- | nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt | 1 | ||||
-rw-r--r-- | nexus/src/main/kotlin/tech/libeufin/nexus/api/RevenueApi.kt | 45 | ||||
-rw-r--r-- | nexus/src/main/kotlin/tech/libeufin/nexus/db/Database.kt | 12 | ||||
-rw-r--r-- | nexus/src/main/kotlin/tech/libeufin/nexus/db/ExchangeDAO.kt | 4 | ||||
-rw-r--r-- | nexus/src/main/kotlin/tech/libeufin/nexus/db/PaymentDAO.kt | 25 | ||||
-rw-r--r-- | nexus/src/test/kotlin/RevenueApiTest.kt | 65 | ||||
-rw-r--r-- | nexus/src/test/kotlin/WireGatewayApiTest.kt | 14 |
8 files changed, 156 insertions, 15 deletions
diff --git a/nexus/conf/test.conf b/nexus/conf/test.conf index f4edd11a..fc4b0946 100644 --- a/nexus/conf/test.conf +++ b/nexus/conf/test.conf @@ -20,4 +20,9 @@ IGNORE_TRANSACTIONS_BEFORE = 2024-04-04 [nexus-httpd-wire-gateway-api] ENABLED = YES AUTH_METHOD = bearer-token +AUTH_BEARER_TOKEN = secret-token + +[nexus-httpd-revenue-api] +ENABLED = YES +AUTH_METHOD = bearer-token AUTH_BEARER_TOKEN = secret-token
\ No newline at end of file diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt index 387bf68b..d4f133bd 100644 --- a/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt +++ b/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt @@ -73,6 +73,7 @@ fun Instant.fmtDateTime(): String = fun Application.nexusApi(db: Database, cfg: NexusConfig) = talerApi(logger) { wireGatewayApi(db, cfg) + revenueApi(db, cfg) } /** diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/api/RevenueApi.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/api/RevenueApi.kt new file mode 100644 index 00000000..e1435a44 --- /dev/null +++ b/nexus/src/main/kotlin/tech/libeufin/nexus/api/RevenueApi.kt @@ -0,0 +1,45 @@ +/* + * This file is part of LibEuFin. + * Copyright (C) 2024 Taler Systems S.A. + + * LibEuFin is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3, or + * (at your option) any later version. + + * LibEuFin is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + + * You should have received a copy of the GNU Affero General Public + * License along with LibEuFin; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/> + */ +package tech.libeufin.nexus.api + +import io.ktor.http.* +import io.ktor.server.application.* +import io.ktor.server.response.* +import io.ktor.server.routing.* +import tech.libeufin.nexus.* +import tech.libeufin.nexus.db.* +import tech.libeufin.common.* + +fun Routing.revenueApi(db: Database, cfg: NexusConfig) = authApi(cfg.revenueApiCfg) { + get("/taler-revenue/config") { + call.respond(RevenueConfig( + currency = cfg.currency + )) + } + get("/taler-revenue/history") { + val params = HistoryParams.extract(context.request.queryParameters) + val items = db.payment.revenueHistory(params) + + if (items.isEmpty()) { + call.respond(HttpStatusCode.NoContent) + } else { + call.respond(RevenueIncomingHistory(items, cfg.payto)) + } + } +}
\ No newline at end of file diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/db/Database.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/db/Database.kt index 01c512ef..25cfaa59 100644 --- a/nexus/src/main/kotlin/tech/libeufin/nexus/db/Database.kt +++ b/nexus/src/main/kotlin/tech/libeufin/nexus/db/Database.kt @@ -49,9 +49,14 @@ class Database(dbConfig: DatabaseConfig, val bankCurrency: String): DbPool(dbCon private val outgoingTxFlows: MutableSharedFlow<Long> = MutableSharedFlow() private val incomingTxFlows: MutableSharedFlow<Long> = MutableSharedFlow() + private val revenueTxFlows: MutableSharedFlow<Long> = MutableSharedFlow() init { watchNotifications(pgSource, "libeufin_nexus", LoggerFactory.getLogger("libeufin-nexus-db-watcher"), mapOf( + "revenue_tx" to { + val id = it.toLong() + revenueTxFlows.emit(id) + }, "outgoing_tx" to { val id = it.toLong() outgoingTxFlows.emit(id) @@ -65,8 +70,11 @@ class Database(dbConfig: DatabaseConfig, val bankCurrency: String): DbPool(dbCon /** Listen for new taler outgoing transactions */ suspend fun <R> listenOutgoing(lambda: suspend (Flow<Long>) -> R): R - = lambda(outgoingTxFlows as Flow<Long>) + = lambda(outgoingTxFlows) /** Listen for new taler incoming transactions */ suspend fun <R> listenIncoming(lambda: suspend (Flow<Long>) -> R): R - = lambda(incomingTxFlows as Flow<Long>) + = lambda(incomingTxFlows) + /** Listen for new incoming transactions */ + suspend fun <R> listenRevenue(lambda: suspend (Flow<Long>) -> R): R + = lambda(revenueTxFlows) }
\ No newline at end of file diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/db/ExchangeDAO.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/db/ExchangeDAO.kt index 13da1f2a..6f3a3a3a 100644 --- a/nexus/src/main/kotlin/tech/libeufin/nexus/db/ExchangeDAO.kt +++ b/nexus/src/main/kotlin/tech/libeufin/nexus/db/ExchangeDAO.kt @@ -54,9 +54,7 @@ class ExchangeDAO(private val db: Database) { /** Query [exchangeId] history of taler outgoing transactions */ suspend fun outgoingHistory( params: HistoryParams - ): List<OutgoingTransaction> - // Outgoing transactions can be initiated or recovered. We take the first data to - // reach database : the initiation first else the recovered transaction. + ): List<OutgoingTransaction> = db.poolHistoryGlobal(params, db::listenOutgoing, """ SELECT outgoing_transaction_id diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/db/PaymentDAO.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/db/PaymentDAO.kt index 4609def8..d9bdee00 100644 --- a/nexus/src/main/kotlin/tech/libeufin/nexus/db/PaymentDAO.kt +++ b/nexus/src/main/kotlin/tech/libeufin/nexus/db/PaymentDAO.kt @@ -20,7 +20,7 @@ package tech.libeufin.nexus.db import tech.libeufin.common.* -import tech.libeufin.common.db.one +import tech.libeufin.common.db.* import tech.libeufin.nexus.IncomingPayment import tech.libeufin.nexus.OutgoingPayment import java.time.Instant @@ -141,4 +141,27 @@ class PaymentDAO(private val db: Database) { } } } + + /** Query history of incoming transactions */ + suspend fun revenueHistory( + params: HistoryParams + ): List<RevenueIncomingBankTransaction> + = db.poolHistoryGlobal(params, db::listenRevenue, """ + SELECT + incoming_transaction_id + ,execution_time + ,(amount).val AS amount_val + ,(amount).frac AS amount_frac + ,debit_payto_uri + ,wire_transfer_subject + FROM incoming_transactions WHERE + """, "incoming_transaction_id") { + RevenueIncomingBankTransaction( + row_id = it.getLong("incoming_transaction_id"), + date = it.getTalerTimestamp("execution_time"), + amount = it.getAmount("amount", db.bankCurrency), + debit_account = it.getString("debit_payto_uri"), + subject = it.getString("wire_transfer_subject") + ) + } }
\ No newline at end of file diff --git a/nexus/src/test/kotlin/RevenueApiTest.kt b/nexus/src/test/kotlin/RevenueApiTest.kt new file mode 100644 index 00000000..5440998d --- /dev/null +++ b/nexus/src/test/kotlin/RevenueApiTest.kt @@ -0,0 +1,65 @@ +/* + * This file is part of LibEuFin. + * Copyright (C) 2024 Taler Systems S.A. + + * LibEuFin is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3, or + * (at your option) any later version. + + * LibEuFin is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + + * You should have received a copy of the GNU Affero General Public + * License along with LibEuFin; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/> + */ + +import io.ktor.http.* +import org.junit.Test +import tech.libeufin.common.* +import tech.libeufin.nexus.* + +class RevenueApiTest { + // GET /taler-revenue/config + @Test + fun config() = serverSetup { + authRoutine(HttpMethod.Get, "/taler-revenue/config") + + client.getA("/taler-revenue/config").assertOk() + } + + // GET /taler-revenue/history + @Test + fun history() = serverSetup { db -> + authRoutine(HttpMethod.Get, "/taler-revenue/history") + + historyRoutine<RevenueIncomingHistory>( + url = "/taler-revenue/history", + ids = { it.incoming_transactions.map { it.row_id } }, + registered = listOf( + { + // Transactions using clean transfer logic + talerableIn(db) + }, + { + // Common credit transactions + ingestIncomingPayment(db, genInPay("ignored")) + } + ), + ignored = listOf( + { + // Ignore debit transactions + talerableOut(db) + } + ) + ) + } + + @Test + fun noApi() = serverSetup("mini.conf") { + client.getA("/taler-revenue/config").assertNotImplemented() + } +}
\ No newline at end of file diff --git a/nexus/src/test/kotlin/WireGatewayApiTest.kt b/nexus/src/test/kotlin/WireGatewayApiTest.kt index 4bc22f06..55e5666e 100644 --- a/nexus/src/test/kotlin/WireGatewayApiTest.kt +++ b/nexus/src/test/kotlin/WireGatewayApiTest.kt @@ -27,7 +27,7 @@ import tech.libeufin.common.* import tech.libeufin.nexus.* class WireGatewayApiTest { - // GET /accounts/{USERNAME}/taler-wire-gateway/config + // GET /taler-wire-gateway/config @Test fun config() = serverSetup { _ -> authRoutine(HttpMethod.Get, "/taler-wire-gateway/config") @@ -35,7 +35,7 @@ class WireGatewayApiTest { client.getA("/taler-wire-gateway/config").assertOk() } - // Testing the POST /transfer call from the TWG API. + // POST /taler-wire-gateway/transfer @Test fun transfer() = serverSetup { _ -> val valid_req = obj { @@ -102,9 +102,7 @@ class WireGatewayApiTest { }.assertBadRequest() } - /** - * Testing the /history/incoming call from the TWG API. - */ + // GET /taler-wire-gateway/history/incoming @Test fun historyIncoming() = serverSetup { db -> authRoutine(HttpMethod.Get, "/taler-wire-gateway/history/incoming") @@ -139,9 +137,7 @@ class WireGatewayApiTest { ) } - /** - * Testing the /history/outgoing call from the TWG API. - */ + // GET /taler-wire-gateway/history/outgoing @Test fun historyOutgoing() = serverSetup { db -> authRoutine(HttpMethod.Get, "/taler-wire-gateway/history/outgoing") @@ -174,7 +170,7 @@ class WireGatewayApiTest { ) } - // Testing the /admin/add-incoming call from the TWG API. + // POST /taler-wire-gateway/admin/add-incoming @Test fun addIncoming() = serverSetup { _ -> val valid_req = obj { |