[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libeufin] 01/02: Taler facade.
From: |
gnunet |
Subject: |
[libeufin] 01/02: Taler facade. |
Date: |
Mon, 14 Dec 2020 06:42:48 +0100 |
This is an automated email from the git hooks/post-receive script.
ms pushed a commit to branch master
in repository libeufin.
commit 236b6d7e0948121efe52fdbed4c108c9e5903fb5
Author: MS <ms@taler.net>
AuthorDate: Fri Dec 11 23:20:58 2020 +0100
Taler facade.
Getting to the point where one payment issued via
the Taler Wire Gateway shows up in a Camt53 report,
and is subsequently returned along the /outgoing
endpoint offered by the Taler facade.
---
integration-tests/tests.py | 25 +++++++++++-----
nexus/src/main/kotlin/tech/libeufin/nexus/Taler.kt | 20 +++++++------
.../tech/libeufin/nexus/bankaccount/BankAccount.kt | 33 +++++++++++++---------
.../kotlin/tech/libeufin/nexus/ebics/EbicsNexus.kt | 1 +
.../tech/libeufin/nexus/iso20022/Iso20022.kt | 11 +++-----
.../tech/libeufin/nexus/server/NexusServer.kt | 4 +--
.../src/main/kotlin/tech/libeufin/sandbox/DB.kt | 1 -
.../tech/libeufin/sandbox/EbicsProtocolBackend.kt | 15 ++++------
.../src/main/kotlin/tech/libeufin/sandbox/Main.kt | 1 -
.../kotlin/tech/libeufin/sandbox/bankAccount.kt | 4 ++-
util/src/main/kotlin/JSON.kt | 10 +++++--
11 files changed, 72 insertions(+), 53 deletions(-)
diff --git a/integration-tests/tests.py b/integration-tests/tests.py
index 3a14f7d..d7574ce 100755
--- a/integration-tests/tests.py
+++ b/integration-tests/tests.py
@@ -282,11 +282,7 @@ def test_taler_facade_config(make_taler_facade):
)
-# This test makes one payment via the Taler facade,
-# and expects too see it in the outgoing history.
-@pytest.mark.skip("Needs more attention")
-def test_taler_facade(make_taler_facade):
-
+def test_taler_facade_history(make_taler_facade):
assertResponse(
post(
f"{N}/facades/{TALER_FACADE}/taler/transfer",
@@ -295,13 +291,28 @@ def test_taler_facade(make_taler_facade):
amount="EUR:1",
exchange_base_url="http//url",
wtid="nice",
-
credit_account="payto://iban/THEBIC/THEIBAN?receiver-name=theName"
+
credit_account="payto://iban/AGRIFRPP/FR7630006000011234567890189?receiver-name=theName"
),
auth=NEXUS_AUTH
)
)
- sleep(5) # Let automatic tasks ingest the history.
+ # normally done by background tasks:
+ assertResponse(
+ post(
+
f"{N}/bank-accounts/{NEXUS_BANK_LABEL}/payment-initiations/1/submit",
+ json=dict(),
+ auth=NEXUS_AUTH
+ )
+ )
+ # normally done by background tasks:
+ assertResponse(
+ post(
+ f"{N}/bank-accounts/{NEXUS_BANK_LABEL}/fetch-transactions", #
_with_ ingestion
+ auth=NEXUS_AUTH
+ )
+ )
+
resp = assertResponse(
get(
f"{N}/facades/{TALER_FACADE}/taler/history/outgoing?delta=5",
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Taler.kt
b/nexus/src/main/kotlin/tech/libeufin/nexus/Taler.kt
index e63d8e3..f39a424 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/Taler.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/Taler.kt
@@ -419,15 +419,17 @@ fun ingestTalerTransactions() {
(NexusBankTransactionsTable.id.greater(lastId))
}.orderBy(Pair(NexusBankTransactionsTable.id, SortOrder.ASC)).forEach {
// Incoming payment.
- val tx = jacksonObjectMapper().readValue(it.transactionJson,
CamtBankAccountEntry::class.java)
- val txDetails = tx.details
- if (txDetails == null) {
- // We don't support batch transactions at the moment!
- logger.warn("batch transactions not supported")
- } else {
- when (tx.creditDebitIndicator) {
- CreditDebitIndicator.CRDT -> ingestIncoming(it, txDtls =
txDetails)
- }
+ logger.debug("Taler checks payment: ${it.transactionJson}")
+ val tx = jacksonObjectMapper().readValue(
+ it.transactionJson, CamtBankAccountEntry::class.java
+ )
+ val details =
tx.batches?.get(0)?.batchTransactions?.get(0)?.details
+ if (details == null) {
+ logger.warn("Met a void money movement: VERY strange")
+ return@forEach
+ }
+ when (tx.creditDebitIndicator) {
+ CreditDebitIndicator.CRDT -> ingestIncoming(it, txDtls =
details)
}
lastId = it.id.value
}
diff --git
a/nexus/src/main/kotlin/tech/libeufin/nexus/bankaccount/BankAccount.kt
b/nexus/src/main/kotlin/tech/libeufin/nexus/bankaccount/BankAccount.kt
index f75d9ac..6e7588d 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/bankaccount/BankAccount.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/bankaccount/BankAccount.kt
@@ -148,9 +148,14 @@ fun processCamtMessage(bankAccountId: String, camtDoc:
Document, code: String):
}
}
val entries = res.reports.map { it.entries }.flatten()
- logger.info("found ${entries.size} transactions")
- txloop@ for (tx in entries) {
- val acctSvcrRef = tx.accountServicerRef
+ logger.info("found ${entries.size} money movements")
+ txloop@ for (entry in entries) {
+ val singletonBatchedTransaction =
entry.batches?.get(0)?.batchTransactions?.get(0)
+ ?: throw NexusError(
+ HttpStatusCode.InternalServerError,
+ "Singleton money movements policy wasn't respected"
+ )
+ val acctSvcrRef = entry.accountServicerRef
if (acctSvcrRef == null) {
// FIXME(dold): Report this!
logger.error("missing account servicer reference in
transaction")
@@ -165,18 +170,18 @@ fun processCamtMessage(bankAccountId: String, camtDoc:
Document, code: String):
val rawEntity = NexusBankTransactionEntity.new {
bankAccount = acct
accountTransactionId = "AcctSvcrRef:$acctSvcrRef"
- amount = tx.amount.value.toPlainString()
- currency = tx.amount.currency
- transactionJson =
jacksonObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(tx)
- creditDebitIndicator = tx.creditDebitIndicator.name
- status = tx.status
+ amount =
singletonBatchedTransaction.amount.value.toPlainString()
+ currency = singletonBatchedTransaction.amount.currency
+ transactionJson =
jacksonObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(entry)
+ creditDebitIndicator =
singletonBatchedTransaction.creditDebitIndicator.name
+ status = entry.status
}
rawEntity.flush()
- if (tx.creditDebitIndicator == CreditDebitIndicator.DBIT) {
- val t0 = tx.details
- val msgId = t0?.messageId
- val pmtInfId = t0?.paymentInformationId
- if (t0 != null && msgId != null && pmtInfId != null) {
+ if (singletonBatchedTransaction.creditDebitIndicator ==
CreditDebitIndicator.DBIT) {
+ val t0 = singletonBatchedTransaction.details
+ val msgId = t0.messageId
+ val pmtInfId = t0.paymentInformationId
+ if (msgId != null && pmtInfId != null) {
val paymentInitiation = PaymentInitiationEntity.find {
(PaymentInitiationsTable.messageId eq msgId) and
(PaymentInitiationsTable.bankAccount eq
acct.id) and
@@ -184,6 +189,7 @@ fun processCamtMessage(bankAccountId: String, camtDoc:
Document, code: String):
}.firstOrNull()
if (paymentInitiation != null) {
+ logger.info("Could confirm one initiated payment:
$msgId")
paymentInitiation.confirmationTransaction = rawEntity
}
}
@@ -314,7 +320,6 @@ suspend fun fetchBankAccountTransactions(
fun importBankAccount(call: ApplicationCall, offeredBankAccountId: String,
nexusBankAccountId: String) {
transaction {
- addLogger(StdOutSqlLogger)
val conn = requireBankConnection(call, "connid")
// first get handle of the offered bank account
val offeredAccount = OfferedBankAccountsTable.select {
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsNexus.kt
b/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsNexus.kt
index fffc4f8..902d9ef 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsNexus.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsNexus.kt
@@ -195,6 +195,7 @@ private suspend fun fetchEbicsC5x(
orderParams: EbicsOrderParams,
subscriberDetails: EbicsClientSubscriberDetails
) {
+ logger.debug("Requesting $historyType")
val response = doEbicsDownloadTransaction(
client,
subscriberDetails,
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/iso20022/Iso20022.kt
b/nexus/src/main/kotlin/tech/libeufin/nexus/iso20022/Iso20022.kt
index d5c64be..6e9e977 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/iso20022/Iso20022.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/iso20022/Iso20022.kt
@@ -264,9 +264,9 @@ data class ReturnInfo(
)
data class BatchTransaction(
- val amount: CurrencyAmount?,
- val creditDebitIndicator: CreditDebitIndicator?,
- val details: TransactionDetails?
+ val amount: CurrencyAmount,
+ val creditDebitIndicator: CreditDebitIndicator,
+ val details: TransactionDetails
)
@JsonInclude(JsonInclude.Include.NON_NULL)
@@ -323,9 +323,6 @@ data class CamtBankAccountEntry(
*/
val instructedAmount: CurrencyAmount?,
- // This field got recently obsoleted.
- val details: TransactionDetails? = null,
-
// list of sub-transactions participating in this money movement.
val batches: List<Batch>?
)
@@ -656,7 +653,7 @@ private fun
XmlElementDestructor.extractMaybeCurrencyExchange(): CurrencyExchang
}
private fun XmlElementDestructor.extractBatches(
- inheritableAmount: CurrencyAmount?,
+ inheritableAmount: CurrencyAmount,
outerCreditDebitIndicator: CreditDebitIndicator
): List<Batch> {
if (mapEachChildNamed("NtryDtls") {}.size != 1) throw
CamtParsingError("This money movement is not a singleton #0")
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/server/NexusServer.kt
b/nexus/src/main/kotlin/tech/libeufin/nexus/server/NexusServer.kt
index 76e7760..14fc102 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/server/NexusServer.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/server/NexusServer.kt
@@ -669,7 +669,7 @@ fun serverMain(dbName: String, host: String) {
call.receive<FetchSpecJson>()
} else {
FetchSpecLatestJson(
- FetchLevel.ALL,
+ FetchLevel.STATEMENT,
null
)
}
@@ -678,7 +678,7 @@ fun serverMain(dbName: String, host: String) {
fetchSpec,
accountid
)
- call.respondText("Collection performed")
+ call.respond(object {})
return@post
}
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt
index aaa09fe..82124f9 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt
@@ -323,7 +323,6 @@ fun dbCreateTables(dbConnectionString: String) {
Database.connect("${dbConnectionString}")
TransactionManager.manager.defaultIsolationLevel =
Connection.TRANSACTION_SERIALIZABLE
transaction {
- addLogger(StdOutSqlLogger)
SchemaUtils.create(
EbicsSubscribersTable,
EbicsHostsTable,
diff --git
a/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
index fc369a1..5c31ba2 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
@@ -200,11 +200,7 @@ private fun getRelatedParty(branch: XmlElementBuilder,
payment: RawPayment) {
}
}
-fun buildCamtString(
- type: Int,
- subscriberIban: String,
- history: List<RawPayment>
-): String {
+fun buildCamtString(type: Int, subscriberIban: String, history:
List<RawPayment>): String {
/**
* ID types required:
*
@@ -387,10 +383,10 @@ fun buildCamtString(
element("NtryDtls/TxDtls") {
element("Refs") {
element("MsgId") {
- text("0")
+ text(it.msgId ?: "NOTPROVIDED")
}
element("PmtInfId") {
- text("0")
+ text(it.pmtInfId ?: "NOTPROVIDED")
}
element("EndToEndId") {
text("NOTPROVIDED")
@@ -556,6 +552,8 @@ private fun parsePain001(paymentRequest: String,
initiatorName: String): PainPar
* Process a payment request in the pain.001 format.
*/
private fun handleCct(paymentRequest: String, initiatorName: String, ctx:
RequestContext) {
+ LOGGER.debug("Handling CCT")
+ LOGGER.debug("Pain.001: $paymentRequest")
val parseResult = parsePain001(paymentRequest, initiatorName)
transaction {
try {
@@ -586,7 +584,7 @@ private fun handleCct(paymentRequest: String,
initiatorName: String, ctx: Reques
}
private fun handleEbicsC53(requestContext: RequestContext): ByteArray {
- logger.debug("Handling C53 request")
+ LOGGER.debug("Handling C53 request")
val camt = constructCamtResponse(
53,
requestContext.requestObject.header,
@@ -757,7 +755,6 @@ private suspend fun ApplicationCall.handleEbicsHpb(
*/
private fun ApplicationCall.ensureEbicsHost(requestHostID: String):
EbicsHostPublicInfo {
return transaction {
- addLogger(StdOutSqlLogger)
val ebicsHost =
EbicsHostEntity.find { EbicsHostsTable.hostID.upperCase() eq
requestHostID.toUpperCase() }.firstOrNull()
if (ebicsHost == null) {
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
index 907f77e..99f196b 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
@@ -392,7 +392,6 @@ fun serverMain(dbName: String) {
val pairB = CryptoUtil.generateRsaKeyPair(2048)
val pairC = CryptoUtil.generateRsaKeyPair(2048)
transaction {
- addLogger(StdOutSqlLogger)
EbicsHostEntity.new {
this.ebicsVersion = req.ebicsVersion
this.hostId = req.hostID
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt
index 50ff366..eb0e658 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt
@@ -41,7 +41,9 @@ fun historyForAccount(iban: String): List<RawPayment> {
// and it makes the document invalid!
// uid = "${it[pmtInfId]}-${it[msgId]}"
uid = "${it[BankAccountTransactionsTable.pmtInfId]}",
- direction = it[BankAccountTransactionsTable.direction]
+ direction = it[BankAccountTransactionsTable.direction],
+ pmtInfId = it[BankAccountTransactionsTable.pmtInfId],
+ msgId = it[BankAccountTransactionsTable.msgId]
)
)
}
diff --git a/util/src/main/kotlin/JSON.kt b/util/src/main/kotlin/JSON.kt
index 834f4b0..26b8f53 100644
--- a/util/src/main/kotlin/JSON.kt
+++ b/util/src/main/kotlin/JSON.kt
@@ -35,6 +35,12 @@ data class RawPayment(
val currency: String,
val subject: String,
val date: String? = null,
- val uid: String? = null,
- val direction: String
+ val uid: String? = null, // FIXME: explain this value.
+ val direction: String,
+ // the following two values are rather CAMT/PAIN
+ // specific, therefore do not need to be returned
+ // along every API call using this object.
+ val pmtInfId: String? = null,
+ val msgId: String? = null
+
)
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.