gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[libeufin] 03/03: addressing #6988


From: gnunet
Subject: [libeufin] 03/03: addressing #6988
Date: Wed, 15 Feb 2023 15:07:41 +0100

This is an automated email from the git hooks/post-receive script.

ms pushed a commit to branch master
in repository libeufin.

commit a1820a97aaef36e0da8b7873dfacfa5363342045
Author: MS <ms@taler.net>
AuthorDate: Wed Feb 15 15:04:03 2023 +0100

    addressing #6988
---
 .../tech/libeufin/nexus/BankConnectionProtocol.kt    | 14 +++++++++++---
 nexus/src/main/kotlin/tech/libeufin/nexus/Taler.kt   |  1 -
 .../tech/libeufin/nexus/bankaccount/BankAccount.kt   | 13 +++++++++++--
 .../kotlin/tech/libeufin/nexus/ebics/EbicsClient.kt  |  4 +---
 .../kotlin/tech/libeufin/nexus/ebics/EbicsNexus.kt   | 14 +++++++++++++-
 .../kotlin/tech/libeufin/nexus/server/NexusServer.kt | 20 +++++++++++++++++++-
 6 files changed, 55 insertions(+), 11 deletions(-)

diff --git 
a/nexus/src/main/kotlin/tech/libeufin/nexus/BankConnectionProtocol.kt 
b/nexus/src/main/kotlin/tech/libeufin/nexus/BankConnectionProtocol.kt
index c56524ff..deaa007a 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/BankConnectionProtocol.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/BankConnectionProtocol.kt
@@ -58,14 +58,22 @@ interface BankConnectionProtocol {
     // Send to the bank a previously prepared payment instruction.
     suspend fun submitPaymentInitiation(httpClient: HttpClient, 
paymentInitiationId: Long)
 
-    // Downloads transactions from the bank, according to the specification
-    // given in the arguments.
+    /**
+     * Downloads transactions from the bank, according to the specification
+     * given in the arguments.
+     *
+     * This function returns a possibly empty list of exceptions.
+     * That helps not to stop fetching if ONE operation fails.  Notably,
+     * C52 and C53 may be asked along one invocation of this function,
+     * therefore storing the exception on C52 allows the C53 to still
+     * take place.  The caller then decides how to handle the exceptions.
+     */
     suspend fun fetchTransactions(
         fetchSpec: FetchSpecJson,
         client: HttpClient,
         bankConnectionId: String,
         accountId: String
-    )
+    ): List<Exception>?
 }
 
 fun getConnectionPlugin(connId: String): BankConnectionProtocol {
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Taler.kt 
b/nexus/src/main/kotlin/tech/libeufin/nexus/Taler.kt
index 957373d8..52dca293 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/Taler.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/Taler.kt
@@ -502,7 +502,6 @@ private suspend fun historyIncoming(call: ApplicationCall) {
  * In the future, a dedicate "add-incoming" facade should
  * be provided, offering the mean to store the credentials
  * at configuration time.
- *
  */
 private suspend fun addIncoming(call: ApplicationCall) {
     val facadeId = ensureNonNull(call.parameters["fcid"])
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 7dab22ff..b32b814a 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/bankaccount/BankAccount.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/bankaccount/BankAccount.kt
@@ -153,7 +153,15 @@ data class CamtTransactionsCount(
      * Total number of transactions that were included in a report
      * or a statement.
      */
-    val downloadedTransactions: Int
+    val downloadedTransactions: Int,
+    /**
+     * Exceptions occurred while fetching transactions.  Fetching
+     * transactions can be done via multiple EBICS messages, therefore
+     * a failing one should not prevent other messages to be sent.
+     * This list collects all the exceptions that happened during the
+     * execution of a batch of messages.
+     */
+    var errors: List<Exception>? = null
 )
 
 /**
@@ -426,7 +434,7 @@ suspend fun fetchBankAccountTransactions(
      * document into the database.  This function tries to download
      * both reports AND statements even if the first one fails.
      */
-    getConnectionPlugin(res.connectionType).fetchTransactions(
+    val errors: List<Exception>? = 
getConnectionPlugin(res.connectionType).fetchTransactions(
         fetchSpec,
         client,
         res.connectionName,
@@ -437,6 +445,7 @@ suspend fun fetchBankAccountTransactions(
     ingestFacadeTransactions(accountId, "taler-wire-gateway", ::talerFilter, 
::maybeTalerRefunds)
     ingestFacadeTransactions(accountId, "anastasis", ::anastasisFilter, null)
 
+    ingestionResult.errors = errors
     return ingestionResult
 }
 
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsClient.kt 
b/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsClient.kt
index 71cced71..33f2f720 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsClient.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsClient.kt
@@ -239,9 +239,7 @@ suspend fun doEbicsDownloadTransaction(
     return EbicsDownloadSuccessResult(respPayload)
 }
 
-/**
- * Currently only 1-segment requests.
- */
+// Currently only 1-segment requests.
 suspend fun doEbicsUploadTransaction(
     client: HttpClient,
     subscriberDetails: EbicsClientSubscriberDetails,
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 b02e8193..209c9384 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsNexus.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsNexus.kt
@@ -402,13 +402,20 @@ fun formatHex(ba: ByteArray): String {
     return out
 }
 
+/**
+ * This function returns a possibly empty list of Exception.
+ * That helps not to stop fetching if ONE operation fails.  Notably,
+ * C52 and C53 may be asked along one invocation of this function,
+ * therefore storing the exception on C52 allows the C53 to still
+ * take place.  The caller then decides how to handle the exceptions.
+ */
 class EbicsBankConnectionProtocol: BankConnectionProtocol {
     override suspend fun fetchTransactions(
         fetchSpec: FetchSpecJson,
         client: HttpClient,
         bankConnectionId: String,
         accountId: String
-    ) {
+    ): List<Exception>? {
         val subscriberDetails = transaction { 
getEbicsSubscriberDetails(bankConnectionId) }
         val lastTimes = transaction {
             val acct = NexusBankAccountEntity.findByName(accountId)
@@ -507,6 +514,7 @@ class EbicsBankConnectionProtocol: BankConnectionProtocol {
             }
         }
         // Downloads and stores the bank message into the database.  No 
ingestion.
+        val errors = mutableListOf<Exception>()
         for (spec in specs) {
             try {
                 fetchEbicsC5x(
@@ -518,8 +526,12 @@ class EbicsBankConnectionProtocol: BankConnectionProtocol {
                 )
             } catch (e: Exception) {
                 logger.warn("Fetching transactions (${spec.orderType}) 
excepted: ${e.message}.")
+                errors.add(e)
             }
         }
+        if (errors.size > 0)
+            return errors
+        return null
     }
     /**
      * Submit one Pain.001 for one payment initiations.
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 b600fbcd..79ab9adf 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/server/NexusServer.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/server/NexusServer.kt
@@ -729,7 +729,25 @@ val nexusApp: Application.() -> Unit = {
                 )
             }
             val ingestionResult = fetchBankAccountTransactions(client, 
fetchSpec, accountid)
-            call.respond(ingestionResult)
+            var statusCode = HttpStatusCode.OK
+            /**
+             * Client errors are unlikely here, because authentication
+             * and JSON validity fail earlier.  Hence either Nexus or the
+             * bank had a problem.  NOTE: because this handler triggers 
multiple
+             * fetches, it is ALSO possible that although one error is 
reported,
+             * SOME transactions made it to the database!
+             */
+            if (ingestionResult.errors != null)
+            /**
+             * 500 is intentionally generic, because multiple errors
+             * may suggest different statuses.  The response body however
+             * informs the client about what failed.
+             */
+            statusCode = HttpStatusCode.InternalServerError
+            call.respond(
+                status = statusCode,
+                ingestionResult
+            )
             return@post
         }
 

-- 
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]