gnunet-svn
[Top][All Lists]
Advanced

[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.



reply via email to

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