[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libeufin] branch master updated: Advancing for the exchange-nexus test.
From: |
gnunet |
Subject: |
[libeufin] branch master updated: Advancing for the exchange-nexus test. |
Date: |
Wed, 03 Jun 2020 19:10:20 +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 1c89426 Advancing for the exchange-nexus test.
1c89426 is described below
commit 1c89426792953a838491b4592a14cc38849e43ed
Author: MS <ms@taler.net>
AuthorDate: Wed Jun 3 18:59:58 2020 +0200
Advancing for the exchange-nexus test.
Sandbox: fill CAMT values according to actual data received in payments.
Nexus: fix the launching of HTTP requests (namely to obtain C53) in the
background.
---
nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt | 40 +++++++++-----
nexus/src/main/kotlin/tech/libeufin/nexus/taler.kt | 63 +++++++++++++---------
.../src/main/kotlin/tech/libeufin/sandbox/DB.kt | 8 +++
.../tech/libeufin/sandbox/EbicsProtocolBackend.kt | 37 ++++++++-----
.../src/main/kotlin/tech/libeufin/sandbox/Main.kt | 10 +++-
util/src/main/kotlin/JSON.kt | 4 ++
6 files changed, 110 insertions(+), 52 deletions(-)
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt
b/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt
index fb4d0ba..0ed44db 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt
@@ -56,8 +56,7 @@ import io.ktor.server.netty.Netty
import io.ktor.utils.io.ByteReadChannel
import io.ktor.utils.io.jvm.javaio.toByteReadChannel
import io.ktor.utils.io.jvm.javaio.toInputStream
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.launch
+import kotlinx.coroutines.*
import kotlinx.coroutines.time.delay
import org.jetbrains.exposed.sql.and
import org.jetbrains.exposed.sql.statements.api.ExposedBlob
@@ -75,6 +74,7 @@ import java.util.*
import java.util.zip.InflaterInputStream
import javax.crypto.EncryptedPrivateKeyInfo
import java.time.LocalDateTime
+import kotlin.coroutines.CoroutineContext
data class NexusError(val statusCode: HttpStatusCode, val reason: String) :
Exception("${reason} (HTTP status $statusCode)")
@@ -258,21 +258,37 @@ fun ApplicationRequest.hasBody(): Boolean {
}
return false
}
-suspend fun schedulePeriodicWork(coroutineScope: CoroutineScope) {
- while (true) {
- delay(Duration.ofMillis(100))
- downloadFacadesTransactions(coroutineScope)
- ingestTalerTransactions()
+
+fun schedulePeriodicWork() {
+ GlobalScope.launch {
+ while (true) {
+ logger.debug("Outer background job")
+ try {
+ delay(Duration.ofSeconds(1))
+ downloadFacadesTransactions(this)
+ ingestTalerTransactions()
+ } catch (e: Exception) {
+ logger.info("==== Background job exception
====\n${e.message}======")
+ }
+ }
}
}
/** Crawls all the facades, and requests history for each of its creators. */
-suspend fun downloadFacadesTransactions(coroutineScope: CoroutineScope) {
+suspend fun downloadFacadesTransactions(myScope: CoroutineScope) {
val httpClient = HttpClient()
transaction {
FacadeEntity.all().forEach {
- coroutineScope.launch {
- fetchTransactionsInternal(httpClient, it.creator,
it.config.bankAccount, CollectedTransaction())
+ logger.debug(
+ "Fetching history for facade: ${it.id.value}, bank account:
${it.config.bankAccount}"
+ )
+ runBlocking {
+ fetchTransactionsInternal(
+ httpClient,
+ it.creator,
+ it.config.bankAccount,
+ CollectedTransaction(null, null, null)
+ )
}
}
}
@@ -344,9 +360,6 @@ fun serverMain(dbName: String) {
expectSuccess = false // this way, it does not throw exceptions on !=
200 responses.
}
val server = embeddedServer(Netty, port = 5001) {
- launch {
- schedulePeriodicWork(this)
- }
install(CallLogging) {
this.level = Level.DEBUG
this.logger = tech.libeufin.nexus.logger
@@ -413,6 +426,7 @@ fun serverMain(dbName: String) {
return@intercept
}
+ schedulePeriodicWork()
routing {
/**
* Shows information about the requesting user.
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/taler.kt
b/nexus/src/main/kotlin/tech/libeufin/nexus/taler.kt
index de7ea14..499743e 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/taler.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/taler.kt
@@ -3,9 +3,12 @@ package tech.libeufin.nexus
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import io.ktor.application.ApplicationCall
import io.ktor.application.call
+import io.ktor.client.HttpClient
+import io.ktor.client.request.post
import io.ktor.content.TextContent
import io.ktor.http.ContentType
import io.ktor.http.HttpStatusCode
+import io.ktor.http.contentType
import io.ktor.request.receive
import io.ktor.response.respond
import io.ktor.response.respondText
@@ -226,7 +229,7 @@ fun getFacadeBankAccount(nexusUser: NexusUserEntity):
NexusBankAccountEntity {
}
// /taler/transfer
-suspend fun talerTransfer(call: ApplicationCall): Unit {
+suspend fun talerTransfer(call: ApplicationCall) {
val transferRequest = call.receive<TalerTransferRequest>()
val amountObj = parseAmount(transferRequest.amount)
val creditorObj = parsePayto(transferRequest.credit_account)
@@ -260,20 +263,6 @@ suspend fun talerTransfer(call: ApplicationCall): Unit {
),
exchangeBankAccount
)
- val rawEbics = if (!isProduction()) {
- RawBankTransactionEntity.new {
- unstructuredRemittanceInformation = transferRequest.wtid
- transactionType = "DBIT"
- currency = amountObj.currency
- this.amount = amountObj.amount.toPlainString()
- counterpartBic = creditorObj.bic
- counterpartIban = creditorObj.iban
- counterpartName = creditorObj.name
- bankAccount = exchangeBankAccount
- bookingDate = System.currentTimeMillis()
- status = "BOOK"
- }
- } else null
val row = TalerRequestedPaymentEntity.new {
preparedPayment = pain001 // not really used/needed, just here to
silence warnings
exchangeBaseUrl = transferRequest.exchange_base_url
@@ -281,7 +270,6 @@ suspend fun talerTransfer(call: ApplicationCall): Unit {
amount = transferRequest.amount
wtid = transferRequest.wtid
creditAccount = transferRequest.credit_account
- rawConfirmed = rawEbics
}
row.id.value
}
@@ -307,25 +295,49 @@ suspend fun talerTransfer(call: ApplicationCall): Unit {
suspend fun talerAddIncoming(call: ApplicationCall): Unit {
val addIncomingData = call.receive<TalerAdminAddIncoming>()
val debtor = parsePayto(addIncomingData.debit_account)
- val amount = parseAmount(addIncomingData.amount)
-
- val myLastSeenRawPayment = transaction {
+ val res = transaction {
val facadeID = expectNonNull(call.parameters["fcid"])
val facade = FacadeEntity.findById(facadeID) ?: throw NexusError(
- HttpStatusCode.NotFound, "Could not find facade"
+ HttpStatusCode.NotFound, "Could not find facade '$facadeID'"
+ )
+ val facadeBankAccount =
NexusBankAccountEntity.findById(facade.config.bankAccount) ?: throw NexusError(
+ HttpStatusCode.NotFound,
+ "Such bank account '${facade.config.bankAccount}' wasn't found for
facade '$facadeID'"
)
- facade.highestSeenMsgID
+ return@transaction object {
+ val facadeLastSeen = facade.highestSeenMsgID
+ val facadeIban = facadeBankAccount.iban
+ val facadeBic = facadeBankAccount.bankCode
+ val facadeHolderName = facadeBankAccount.accountHolder
+ }
}
+ val httpClient = HttpClient()
+ /** forward the payment information to the sandbox. */
+ httpClient.post<String>(
+ urlString = "http://localhost:5000/admin/payments",
+ block = {
+ /** FIXME: ideally Jackson should define such request body. */
+ this.body = """{
+ "creditorIban": "${res.facadeIban}",
+ "creditorBic": "${res.facadeBic}",
+ "creditorName": "${res.facadeHolderName}",
+ "debitorIban": "${debtor.iban}",
+ "debitorBic": "${debtor.bic}",
+ "debitorName": "${debtor.name}",
+ "amount": "${addIncomingData.amount}",
+ "subject": "${addIncomingData.reserve_pub}"
+ }""".trimIndent()
+ contentType(ContentType.Application.Json)
+ }
+ )
return call.respond(
TextContent(
customConverter(
TalerAddIncomingResponse(
timestamp = GnunetTimestamp(
- // warning: this value might need to come from a real
last-seen payment.
- // FIXME(dold): I don't understand the comment above
^^.
System.currentTimeMillis()
),
- row_id = myLastSeenRawPayment
+ row_id = res.facadeLastSeen
)
),
ContentType.Application.Json
@@ -343,6 +355,7 @@ suspend fun talerAddIncoming(call: ApplicationCall): Unit {
*/
fun ingestTalerTransactions() {
fun ingest(subscriberAccount: NexusBankAccountEntity, facade:
FacadeEntity) {
+ logger.debug("Ingesting transactions for Taler facade:
${facade.id.value}")
var lastId = facade.highestSeenMsgID
RawBankTransactionEntity.find {
/** Those with exchange bank account involved */
@@ -510,4 +523,4 @@ fun talerFacadeRoutes(route: Route) {
call.respondText("Hello, this is Taler Facade")
return@get
}
-}
\ No newline at end of file
+}
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt
index de11908..baf1a94 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt
@@ -251,7 +251,11 @@ class EbicsUploadTransactionChunkEntity(id:
EntityID<String>) : Entity<String>(i
*/
object PaymentsTable : IntIdTable() {
val creditorIban = text("creditorIban")
+ val creditorBic = text("creditorBic")
+ val creditorName = text("creditorName")
val debitorIban = text("debitorIban")
+ val debitorBic = text("debitorBic")
+ val debitorName = text("debitorName")
val subject = text("subject")
val amount = text("amount")
val date = long("date")
@@ -261,7 +265,11 @@ class PaymentEntity(id: EntityID<Int>) : IntEntity(id) {
companion object : IntEntityClass<PaymentEntity>(PaymentsTable)
var creditorIban by PaymentsTable.creditorIban
+ var creditorBic by PaymentsTable.creditorBic
+ var creditorName by PaymentsTable.creditorName
var debitorIban by PaymentsTable.debitorIban
+ var debitorBic by PaymentsTable.debitorBic
+ var debitorName by PaymentsTable.debitorName
var subject by PaymentsTable.subject
var amount by PaymentsTable.amount
diff --git
a/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
index 2134fee..e610f5c 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
@@ -140,7 +140,7 @@ fun <T>expectNonNull(x: T?): T {
* words, the camt constructor does creates always only one "Ntry"
* node.
*/
-fun buildCamtString(type: Int, history: MutableList<RawPayment>):
MutableList<String> {
+fun buildCamtString(type: Int, subscriberIban: String, history:
MutableList<RawPayment>): MutableList<String> {
/**
* ID types required:
*
@@ -158,7 +158,7 @@ fun buildCamtString(type: Int, history:
MutableList<RawPayment>): MutableList<St
val dashedDate = expectNonNull(it.date)
val now = LocalDateTime.now()
val zonedDateTime = now.toZonedString()
-
+ val amount = parseAmount(it.amount)
ret.add(
constructXml(indent = true) {
root("Document") {
@@ -201,7 +201,7 @@ fun buildCamtString(type: Int, history:
MutableList<RawPayment>): MutableList<St
element("Acct") {
// mandatory account identifier
element("Id/IBAN") {
- text(it.debitorIban)
+ text(subscriberIban)
}
element("Ccy") {
text("EUR")
@@ -240,7 +240,7 @@ fun buildCamtString(type: Int, history:
MutableList<RawPayment>): MutableList<St
text(Amount(0).toPlainString())
}
element("CdtDbtInd") {
- text("DBIT")
+ text("UNUSED")
}
element("Dt/Dt") {
// date of this balance
@@ -260,20 +260,22 @@ fun buildCamtString(type: Int, history:
MutableList<RawPayment>): MutableList<St
}
element("CdtDbtInd") {
// CRDT or DBIT here
- text("DBIT")
+ text("UNUSED")
}
element("Dt/Dt") {
text(dashedDate)
}
}
-
element("Ntry") {
element("Amt") {
- attribute("Ccy", "EUR")
- text(it.amount)
+ attribute("Ccy", amount.currency)
+ text(amount.amount.toString())
}
element("CdtDbtInd") {
- text("DBIT")
+ text(
+ if
(subscriberIban.equals(it.creditorIban))
+ "CRDT" else "DBIT"
+ )
}
element("Sts") {
/* Status of the entry (see 2.4.2.15.5
from the ISO20022 reference document.)
@@ -355,13 +357,13 @@ fun buildCamtString(type: Int, history:
MutableList<RawPayment>): MutableList<St
}
element("RltdPties") {
element("Dbtr/Nm") {
- text("Debitor Name")
+ text(it.debitorName)
}
element("DbtrAcct/Id/IBAN") {
text(it.debitorIban)
}
element("Cdtr/Nm") {
- text("Creditor Name")
+ text(it.creditorName)
}
element("CdtrAcct/Id/IBAN") {
text(it.creditorIban)
@@ -369,7 +371,10 @@ fun buildCamtString(type: Int, history:
MutableList<RawPayment>): MutableList<St
}
element("RltdAgts") {
element("CdtrAgt/FinInstnId/BIC") {
- text("Creditor Bic")
+ text(
+ if
(subscriberIban.equals(it.creditorIban))
+ it.debitorBic else
it.creditorBic
+ )
}
}
element("RmtInf/Ustrd") {
@@ -411,6 +416,7 @@ private fun constructCamtResponse(
val history = mutableListOf<RawPayment>()
val bankAccount = getBankAccountFromSubscriber(subscriber)
transaction {
+ logger.debug("Querying transactions involving: ${bankAccount.iban}")
PaymentEntity.find {
PaymentsTable.creditorIban eq bankAccount.iban or
(PaymentsTable.debitorIban eq bankAccount.iban)
@@ -423,7 +429,11 @@ private fun constructCamtResponse(
RawPayment(
subject = it.subject,
creditorIban = it.creditorIban,
+ creditorBic = it.creditorBic,
+ creditorName = it.creditorName,
debitorIban = it.debitorIban,
+ debitorBic = it.debitorBic,
+ debitorName = it.debitorName,
date = importDateFromMillis(it.date).toDashedDate(),
amount = it.amount
)
@@ -431,7 +441,7 @@ private fun constructCamtResponse(
}
history
}
- return buildCamtString(type, history)
+ return buildCamtString(type, bankAccount.iban, history)
}
private fun handleEbicsTSD(requestContext: RequestContext): ByteArray {
@@ -471,6 +481,7 @@ private fun handleCct(paymentRequest: String) {
}
private fun handleEbicsC53(requestContext: RequestContext): ByteArray {
+ logger.debug("Handling C53 request")
val camt = constructCamtResponse(
53,
requestContext.requestObject.header,
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
index b525aed..d2f3a3e 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
@@ -171,7 +171,11 @@ fun main() {
debitorIban = it.debitorIban,
subject = it.subject,
date = it.date.toHttpDateString(),
- amount = it.amount
+ amount = it.amount,
+ creditorBic = it.creditorBic,
+ creditorName = it.creditorName,
+ debitorBic = it.debitorBic,
+ debitorName = it.debitorName
)
)
}
@@ -188,7 +192,11 @@ fun main() {
transaction {
PaymentEntity.new {
creditorIban = body.creditorIban
+ creditorBic = body.creditorBic
+ creditorName = body.creditorName
debitorIban = body.debitorIban
+ debitorBic = body.debitorBic
+ debitorName = body.debitorName
subject = body.subject
amount = body.amount
date = Instant.now().toEpochMilli()
diff --git a/util/src/main/kotlin/JSON.kt b/util/src/main/kotlin/JSON.kt
index 62fb992..ecd6950 100644
--- a/util/src/main/kotlin/JSON.kt
+++ b/util/src/main/kotlin/JSON.kt
@@ -7,7 +7,11 @@ package tech.libeufin.util
*/
data class RawPayment(
val creditorIban: String,
+ val creditorBic: String,
+ val creditorName: String,
val debitorIban: String,
+ val debitorBic: String,
+ val debitorName: String,
val amount: String,
val subject: String,
val date: String?
--
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: Advancing for the exchange-nexus test.,
gnunet <=