gnunet-svn
[Top][All Lists]
Advanced

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

[libeufin] branch master updated: nexus submit: reading STDIN as input (


From: gnunet
Subject: [libeufin] branch master updated: nexus submit: reading STDIN as input (debug)
Date: Sat, 11 Nov 2023 23:57:37 +0100

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 9795bf25 nexus submit: reading STDIN as input (debug)
9795bf25 is described below

commit 9795bf25f5638573881b871340f3e4ed9c31e106
Author: MS <ms@taler.net>
AuthorDate: Sat Nov 11 23:55:15 2023 +0100

    nexus submit: reading STDIN as input (debug)
---
 .../main/kotlin/tech/libeufin/nexus/EbicsSubmit.kt | 155 +++++++++------------
 nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt  |  60 ++++++++
 2 files changed, 126 insertions(+), 89 deletions(-)

diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsSubmit.kt 
b/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsSubmit.kt
index 707fc8f9..ab92cc09 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsSubmit.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsSubmit.kt
@@ -55,6 +55,28 @@ enum class NexusSubmissionStage {
     reachability
 }
 
+/**
+ * Groups useful parameters to submit pain.001 via EBICS.
+ */
+data class SubmissionContext(
+    /**
+     * HTTP connection handle.
+     */
+    val httpClient: HttpClient,
+    /**
+     * Configuration handle.
+     */
+    val cfg: EbicsSetupConfig,
+    /**
+     * Subscriber EBICS private keys.
+     */
+    val clientPrivateKeysFile: ClientPrivateKeysFile,
+    /**
+     * Bank EBICS public keys.
+     */
+    val bankPublicKeysFile: BankPublicKeysFile
+)
+
 /**
  * Expresses one error that occurred while submitting one pain.001
  * document via EBICS.
@@ -70,20 +92,11 @@ class NexusSubmitException(
  * database, sanity-checks it, makes the pain.001 document and finally
  * submits it via EBICS to the bank.
  *
- * @param httpClient HTTP client to connect to the bank.
- * @param cfg configuration handle.  Contains the bank URL and EBICS IDs.
- * @param clientPrivateKeysFile client's private EBICS keys.
- * @param bankPublicKeysFile bank's public EBICS keys.
- * @param initiatedPayment payment initiation from the database.
- * @param debtor bank account information of the debited party.
- *               This values needs the BIC and the name.
+ * @param ctx [SubmissionContext]
  * @return true on success, false otherwise.
  */
 private suspend fun submitInitiatedPayment(
-    httpClient: HttpClient,
-    cfg: EbicsSetupConfig,
-    clientPrivateKeysFile: ClientPrivateKeysFile,
-    bankPublicKeysFile: BankPublicKeysFile,
+    ctx: SubmissionContext,
     initiatedPayment: InitiatedPayment
 ) {
     val creditor = parsePayto(initiatedPayment.creditPaytoUri)
@@ -97,16 +110,16 @@ private suspend fun submitInitiatedPayment(
         initiationTimestamp = initiatedPayment.initiationTime,
         amount = initiatedPayment.amount,
         creditAccount = creditor,
-        debitAccount = cfg.myIbanAccount,
+        debitAccount = ctx.cfg.myIbanAccount,
         wireTransferSubject = initiatedPayment.wireTransferSubject
     )
     try {
         submitPain001(
             xml,
-            cfg,
-            clientPrivateKeysFile,
-            bankPublicKeysFile,
-            httpClient
+            ctx.cfg,
+            ctx.clientPrivateKeysFile,
+            ctx.bankPublicKeysFile,
+            ctx.httpClient
         )
     } catch (early: EbicsSideException) {
         val errorStage = when (early.sideEc) {
@@ -133,7 +146,7 @@ private suspend fun submitInitiatedPayment(
         )
     }
     // Submission succeeded, storing the pain.001 to file.
-    val logDir: String? = cfg.config.lookupString(
+    val logDir: String? = ctx.cfg.config.lookupString(
         "neuxs-submit",
         "SUBMISSIONS_LOG_DIRECTORY"
     )
@@ -157,83 +170,25 @@ private suspend fun submitInitiatedPayment(
 }
 
 /**
- * Converts human-readable duration in how many seconds.  Supports
- * the suffixes 's' (seconds), 'm' (minute), 'h' (hours).  A valid
- * duration is therefore, for example, Nm, where N is the number of
- * minutes.
+ * Searches the database for payments to submit and calls
+ * the submitter helper.
  *
- * @param trimmed duration
- * @return how many seconds is the duration input, or null if the input
- *         is not valid.
+ * @param cfg configuration handle.
+ * @param db database connection.
+ * @param httpClient HTTP connection handle.
+ * @param clientKeys subscriber private keys.
+ * @param bankKeys bank public keys.
  */
-fun getFrequencyInSeconds(humanFormat: String): Int? {
-    val trimmed = humanFormat.trim()
-    if (trimmed.isEmpty()) {
-        logger.error("Input was empty")
-        return null
-    }
-    val lastChar = trimmed.last()
-    val howManySeconds: Int = when (lastChar) {
-        's' -> {1}
-        'm' -> {60}
-        'h' -> {60 * 60}
-        else -> {
-            logger.error("Duration symbol not one of s, m, h.  '$lastChar' was 
found instead")
-            return null
-        }
-    }
-    val maybeNumber = trimmed.dropLast(1)
-    val howMany = try {
-        maybeNumber.trimEnd().toInt()
-    } catch (e: Exception) {
-        logger.error("Prefix was not a valid input: '$maybeNumber'")
-        return null
-    }
-    if (howMany == 0) return 0
-    val ret = howMany * howManySeconds
-    if (howMany != ret / howManySeconds) {
-        logger.error("Result overflew")
-        return null
-    }
-    return ret
-}
-
-/**
- * Sanity-checks the frequency found in the configuration and
- * either returns it or fails the process.  Note: the returned
- * value is also guaranteed to be non-negative.
- *
- * @param foundInConfig frequency value as found in the configuration.
- * @return the duration in seconds of the value found in the configuration.
- */
-fun checkFrequency(foundInConfig: String): Int {
-    val frequencySeconds = getFrequencyInSeconds(foundInConfig)
-        ?: throw Exception("Invalid frequency value in config section 
nexus-submit: $foundInConfig")
-    if (frequencySeconds < 0) {
-        throw Exception("Configuration error: cannot operate with a negative 
submit frequency ($foundInConfig)")
-    }
-    return frequencySeconds
-}
-
 private fun submitBatch(
-    cfg: EbicsSetupConfig,
+    ctx: SubmissionContext,
     db: Database,
-    httpClient: HttpClient,
-    clientKeys: ClientPrivateKeysFile,
-    bankKeys: BankPublicKeysFile
 ) {
     logger.debug("Running submit at: ${Instant.now()}")
     runBlocking {
-        db.initiatedPaymentsUnsubmittedGet(cfg.currency).forEach {
+        db.initiatedPaymentsUnsubmittedGet(ctx.cfg.currency).forEach {
             logger.debug("Submitting payment initiation with row ID: 
${it.key}")
             val submissionState = try {
-                submitInitiatedPayment(
-                    httpClient,
-                    cfg,
-                    clientKeys,
-                    bankKeys,
-                    initiatedPayment = it.value
-                )
+                submitInitiatedPayment(ctx, initiatedPayment = it.value)
                 DatabaseSubmissionState.success
             } catch (e: NexusSubmitException) {
                 logger.error(e.message)
@@ -298,10 +253,32 @@ class EbicsSubmit : CliktCommand("Submits any initiated 
payment found in the dat
             logger.error("Client private keys not found at: 
${cfg.clientPrivateKeysFilename}")
             exitProcess(1)
         }
-        val httpClient = HttpClient()
+        val ctx = SubmissionContext(
+            cfg = cfg,
+            bankPublicKeysFile = bankKeys,
+            clientPrivateKeysFile = clientKeys,
+            httpClient = HttpClient()
+        )
+        // If STDIN has data, we run in debug mode: submit and return.
+        val maybeStdin = generateSequence(::readLine).joinToString("\n")
+        if (maybeStdin.isNotEmpty()) {
+            logger.info("Submitting STDIN to the bank")
+            doOrFail {
+                runBlocking {
+                    submitPain001(
+                        maybeStdin,
+                        ctx.cfg,
+                        ctx.clientPrivateKeysFile,
+                        ctx.bankPublicKeysFile,
+                        ctx.httpClient
+                    )
+                }
+            }
+            return
+        }
         if (transient) {
             logger.info("Transient mode: submitting what found and returning.")
-            submitBatch(cfg, db, httpClient, clientKeys, bankKeys)
+            submitBatch(ctx, db)
             return
         }
         val frequency: NexusFrequency = doOrFail {
@@ -312,14 +289,14 @@ class EbicsSubmit : CliktCommand("Submits any initiated 
payment found in the dat
         logger.debug("Running with a frequency of ${frequency.fromConfig}")
         if (frequency.inSeconds == 0) {
             logger.warn("Long-polling not implemented, running therefore in 
transient mode")
-            submitBatch(cfg, db, httpClient, clientKeys, bankKeys)
+            submitBatch(ctx, db)
             return
         }
         fixedRateTimer(
             name = "ebics submit period",
             period = (frequency.inSeconds * 1000).toLong(),
             action = {
-                submitBatch(cfg, db, httpClient, clientKeys, bankKeys)
+                submitBatch(ctx, db)
             }
         )
     }
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt 
b/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt
index c0ea4b98..64f94902 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt
@@ -84,6 +84,66 @@ data class NexusFrequency(
     val fromConfig: String
 )
 
+/**
+ * Converts human-readable duration in how many seconds.  Supports
+ * the suffixes 's' (seconds), 'm' (minute), 'h' (hours).  A valid
+ * duration is therefore, for example, Nm, where N is the number of
+ * minutes.
+ *
+ * @param trimmed duration
+ * @return how many seconds is the duration input, or null if the input
+ *         is not valid.
+ */
+fun getFrequencyInSeconds(humanFormat: String): Int? {
+    val trimmed = humanFormat.trim()
+    if (trimmed.isEmpty()) {
+        logger.error("Input was empty")
+        return null
+    }
+    val lastChar = trimmed.last()
+    val howManySeconds: Int = when (lastChar) {
+        's' -> {1}
+        'm' -> {60}
+        'h' -> {60 * 60}
+        else -> {
+            logger.error("Duration symbol not one of s, m, h.  '$lastChar' was 
found instead")
+            return null
+        }
+    }
+    val maybeNumber = trimmed.dropLast(1)
+    val howMany = try {
+        maybeNumber.trimEnd().toInt()
+    } catch (e: Exception) {
+        logger.error("Prefix was not a valid input: '$maybeNumber'")
+        return null
+    }
+    if (howMany == 0) return 0
+    val ret = howMany * howManySeconds
+    if (howMany != ret / howManySeconds) {
+        logger.error("Result overflew")
+        return null
+    }
+    return ret
+}
+
+/**
+ * Sanity-checks the frequency found in the configuration and
+ * either returns it or fails the process.  Note: the returned
+ * value is also guaranteed to be non-negative.
+ *
+ * @param foundInConfig frequency value as found in the configuration.
+ * @return the duration in seconds of the value found in the configuration.
+ */
+fun checkFrequency(foundInConfig: String): Int {
+    val frequencySeconds = getFrequencyInSeconds(foundInConfig)
+        ?: throw Exception("Invalid frequency value in config section 
nexus-submit: $foundInConfig")
+    if (frequencySeconds < 0) {
+        throw Exception("Configuration error: cannot operate with a negative 
submit frequency ($foundInConfig)")
+    }
+    return frequencySeconds
+}
+
+
 /**
  * Keeps all the options of the ebics-setup subcommand.  The
  * caller has to handle TalerConfigError if values are missing.

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