commit b59efeeb55c6fe7af0d1adf77e01bae0d933c32e
parent d1d70485cb8f84f6b32f9a6894c494e11c4b99ca
Author: Antoine A <>
Date: Tue, 1 Oct 2024 17:01:04 +0200
nexus: lazier config parsing
Diffstat:
11 files changed, 70 insertions(+), 78 deletions(-)
diff --git a/common/src/main/kotlin/TalerConfig.kt b/common/src/main/kotlin/TalerConfig.kt
@@ -191,6 +191,7 @@ private class ConfigLoader(
if (recursionDepth > 128) {
throw genericError(file, lineNum, "Recursion limit in config inlining")
}
+ logger.trace("load file at $file")
return try {
file.useLines {
loadFromMem(it, file, recursionDepth+1)
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Config.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/Config.kt
@@ -53,11 +53,8 @@ class NexusSubmitConfig(config: TalerConfig) {
val frequencyRaw = section.string("frequency").require()
}
-class NexusEbicsConfig(
- config: TalerConfig,
+class NexusEbicsConfig(
sect: TalerConfigSection,
- val currency: String,
- val accountType: AccountType
) {
/** The bank base URL */
val hostBaseUrl = sect.string("host_base_url").require()
@@ -85,14 +82,6 @@ class NexusEbicsConfig(
val bankPublicKeysPath = sect.path("bank_public_keys_file").require()
/** Path where we store our private keys */
val clientPrivateKeysPath = sect.path("client_private_keys_file").require()
-
- val fetch = NexusFetchConfig(config)
- val submit = NexusSubmitConfig(config)
- val ingest get() = NexusIngestConfig(
- accountType,
- fetch.ignoreTransactionsBefore,
- fetch.ignoreBouncesBefore
- )
}
class ApiConfig(section: TalerConfigSection) {
@@ -116,7 +105,15 @@ class NexusConfig internal constructor (private val cfg: TalerConfig) {
"exchange" to AccountType.exchange
)).require()
- val ebics by lazy { NexusEbicsConfig(cfg, sect, currency, accountType) }
+ val fetch by lazy { NexusFetchConfig(cfg) }
+ val submit by lazy { NexusSubmitConfig(cfg) }
+ val ebics by lazy { NexusEbicsConfig(sect) }
+
+ val ingest get() = NexusIngestConfig(
+ accountType,
+ fetch.ignoreTransactionsBefore,
+ fetch.ignoreBouncesBefore
+ )
val wireGatewayApiCfg = cfg.section("nexus-httpd-wire-gateway-api").apiConf()
val revenueApiCfg = cfg.section("nexus-httpd-revenue-api").apiConf()
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/cli/EbicsFetch.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/cli/EbicsFetch.kt
@@ -158,14 +158,14 @@ suspend fun registerTransaction(
/** Register a single EBICS [xml] [document] into [db] */
suspend fun registerFile(
db: Database,
- cfg: NexusEbicsConfig,
+ cfg: NexusConfig,
xml: InputStream,
doc: OrderDoc
) {
when (doc) {
OrderDoc.report, OrderDoc.statement, OrderDoc.notification -> {
try {
- parseTx(xml, cfg.currency, cfg.dialect).forEach { tx ->
+ parseTx(xml, cfg.currency, cfg.ebics.dialect).forEach { tx ->
registerTransaction(db, cfg.ingest, tx)
}
} catch (e: Exception) {
@@ -247,7 +247,7 @@ suspend fun registerFile(
/** Register an EBICS [payload] of [doc] into [db] */
private suspend fun registerPayload(
db: Database,
- cfg: NexusEbicsConfig,
+ cfg: NexusConfig,
payload: InputStream,
doc: OrderDoc
) {
@@ -326,9 +326,8 @@ class EbicsFetch: CliktCommand() {
private val ebicsLog by ebicsLogOption()
override fun run() = cliCmd(logger, common.log) {
- nexusConfig(common.config).withDb { db, nexusCgf ->
- val cfg = nexusCgf.ebics
- val (clientKeys, bankKeys) = expectFullKeys(cfg)
+ nexusConfig(common.config).withDb { db, cfg ->
+ val (clientKeys, bankKeys) = expectFullKeys(cfg.ebics)
val client = EbicsClient(
cfg,
httpClient(),
@@ -338,7 +337,7 @@ class EbicsFetch: CliktCommand() {
bankKeys
)
val docs = if (documents.isEmpty()) OrderDoc.entries else documents.toList()
- val requestedOrders = docs.map { cfg.dialect.downloadDoc(it, false) }.toSet()
+ val requestedOrders = docs.map { cfg.ebics.dialect.downloadDoc(it, false) }.toSet()
/** Fetch requested documents only if they have new content */
suspend fun fetchAvailableDocuments(pinnedStartArg: Instant?): Boolean {
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/cli/EbicsSetup.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/cli/EbicsSetup.kt
@@ -163,17 +163,16 @@ class EbicsSetup: CliktCommand() {
* This function collects the main steps of setting up an EBICS access.
*/
override fun run() = cliCmd(logger, common.log) {
- val nexusCfg = nexusConfig(common.config)
- val cfg = nexusCfg.ebics
+ val cfg = nexusConfig(common.config)
val client = httpClient()
val ebicsLogger = EbicsLogger(ebicsLog)
- val clientKeys = loadOrGenerateClientKeys(cfg.clientPrivateKeysPath)
- var bankKeys = loadBankKeys(cfg.bankPublicKeysPath)
+ val clientKeys = loadOrGenerateClientKeys(cfg.ebics.clientPrivateKeysPath)
+ var bankKeys = loadBankKeys(cfg.ebics.bankPublicKeysPath)
// Check EBICS 3 support
- val versions = HEV(client, cfg, ebicsLogger)
+ val versions = HEV(client, cfg.ebics, ebicsLogger)
logger.debug("HEV: {}", versions)
if (!versions.contains(VersionNumber(3.0f, "H005")) && !versions.contains(VersionNumber(3.02f, "H005"))) {
throw Exception("EBICS 3 is not supported by your bank")
@@ -182,17 +181,17 @@ class EbicsSetup: CliktCommand() {
// Privs exist. Upload their pubs
val keysNotSub = !clientKeys.submitted_ini
if ((!clientKeys.submitted_ini) || forceKeysResubmission)
- doKeysRequestAndUpdateState(cfg, clientKeys, client, ebicsLogger, INI)
+ doKeysRequestAndUpdateState(cfg.ebics, clientKeys, client, ebicsLogger, INI)
// Eject PDF if the keys were submitted for the first time, or the user asked.
- if (keysNotSub || generateRegistrationPdf) makePdf(clientKeys, cfg)
+ if (keysNotSub || generateRegistrationPdf) makePdf(clientKeys, cfg.ebics)
if ((!clientKeys.submitted_hia) || forceKeysResubmission)
- doKeysRequestAndUpdateState(cfg, clientKeys, client, ebicsLogger, HIA)
+ doKeysRequestAndUpdateState(cfg.ebics, clientKeys, client, ebicsLogger, HIA)
// Checking if the bank keys exist on disk
if (bankKeys == null) {
- doKeysRequestAndUpdateState(cfg, clientKeys, client, ebicsLogger, HPB)
- logger.info("Bank keys stored at ${cfg.bankPublicKeysPath}")
- bankKeys = loadBankKeys(cfg.bankPublicKeysPath)!!
+ doKeysRequestAndUpdateState(cfg.ebics, clientKeys, client, ebicsLogger, HPB)
+ logger.info("Bank keys stored at ${cfg.ebics.bankPublicKeysPath}")
+ bankKeys = loadBankKeys(cfg.ebics.bankPublicKeysPath)!!
}
if (!bankKeys.accepted) {
@@ -204,7 +203,7 @@ class EbicsSetup: CliktCommand() {
throw Exception("Cannot successfully finish the setup without accepting the bank keys")
}
try {
- persistBankKeys(bankKeys, cfg.bankPublicKeysPath)
+ persistBankKeys(bankKeys, cfg.ebics.bankPublicKeysPath)
} catch (e: Exception) {
throw Exception("Could not set bank keys as accepted on disk", e)
}
@@ -213,7 +212,7 @@ class EbicsSetup: CliktCommand() {
// Check account information
logger.info("Doing administrative request HKD")
try {
- nexusCfg.withDb { db, _ ->
+ cfg.withDb { db, _ ->
EbicsClient(
cfg,
client,
@@ -223,7 +222,7 @@ class EbicsSetup: CliktCommand() {
bankKeys
).download(EbicsOrder.V3.HKD, null, null) { stream ->
val (partner, users) = EbicsAdministrative.parseHKD(stream)
- val user = users.find { it -> it.id == cfg.ebicsUserId }
+ val user = users.find { it -> it.id == cfg.ebics.ebicsUserId }
// Debug logging
logger.debug {
buildString {
@@ -261,18 +260,18 @@ class EbicsSetup: CliktCommand() {
}
// Check partner info match config
- if (partner.name != null && partner.name != cfg.account.name)
- logger.warn("Expected NAME '${cfg.account.name}' from config got '${partner.name}' from bank")
- val account = partner.accounts.find { it.iban == cfg.account.iban }
+ if (partner.name != null && partner.name != cfg.ebics.account.name)
+ logger.warn("Expected NAME '${cfg.ebics.account.name}' from config got '${partner.name}' from bank")
+ val account = partner.accounts.find { it.iban == cfg.ebics.account.iban }
if (account != null) {
if (account.currency != null && account.currency != cfg.currency)
logger.error("Expected CURRENCY '${cfg.currency}' from config got '${account.currency}' from bank")
} else if (partner.accounts.isNotEmpty()) {
val ibans = partner.accounts.map { it.iban }.joinToString(", ")
- logger.error("Expected IBAN ${cfg.account.iban} from config got $ibans from bank")
+ logger.error("Expected IBAN ${cfg.ebics.account.iban} from config got $ibans from bank")
}
- val requireOrders = cfg.dialect.orders()
+ val requireOrders = cfg.ebics.dialect.orders()
// Check partner support required orders
val unsupportedOrder = requireOrders subtract partner.orders.map { it.order }
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/cli/EbicsSubmit.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/cli/EbicsSubmit.kt
@@ -64,13 +64,14 @@ private suspend fun submitBatch(
client: EbicsClient,
batch: PaymentBatch
): String {
- val msg = batchToPain001Msg(client.cfg.account, batch)
+ val ebicsCfg = client.cfg.ebics
+ val msg = batchToPain001Msg(ebicsCfg.account, batch)
val xml = createPain001(
msg = msg,
- dialect = client.cfg.dialect
+ dialect = ebicsCfg.dialect
)
return client.upload(
- client.cfg.dialect.directDebit(),
+ ebicsCfg.dialect.directDebit(),
xml
)
}
@@ -105,9 +106,8 @@ class EbicsSubmit : CliktCommand() {
private val ebicsLog by ebicsLogOption()
override fun run() = cliCmd(logger, common.log) {
- nexusConfig(common.config).withDb { db, nexusCfg ->
- val cfg = nexusCfg.ebics
- val (clientKeys, bankKeys) = expectFullKeys(cfg)
+ nexusConfig(common.config).withDb { db, cfg ->
+ val (clientKeys, bankKeys) = expectFullKeys(cfg.ebics)
val client = EbicsClient(
cfg,
httpClient(),
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/cli/Testing.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/cli/Testing.kt
@@ -43,9 +43,8 @@ class Wss: CliktCommand() {
private val ebicsLog by ebicsLogOption()
override fun run() = cliCmd(logger, common.log) {
- nexusConfig(common.config).withDb { db, nexusCgf ->
- val cfg = nexusCgf.ebics
- val (clientKeys, bankKeys) = expectFullKeys(cfg)
+ nexusConfig(common.config).withDb { db, cfg ->
+ val (clientKeys, bankKeys) = expectFullKeys(cfg.ebics)
val httpClient = httpClient()
val client = EbicsClient(
cfg,
@@ -91,7 +90,7 @@ class FakeIncoming: CliktCommand() {
"Wrong currency: expected ${cfg.currency} got ${amount.currency}"
}
- registerIncomingPayment(db, cfg.ebics.ingest,
+ registerIncomingPayment(db, cfg.ingest,
IncomingPayment(
amount = amount,
debtorPayto = payto,
@@ -154,9 +153,8 @@ class EbicsDownload: CliktCommand("ebics-btd") {
class DryRun: Exception()
override fun run() = cliCmd(logger, common.log) {
- nexusConfig(common.config).withDb { db, nexusCgf ->
- val cfg = nexusCgf.ebics
- val (clientKeys, bankKeys) = expectFullKeys(cfg)
+ nexusConfig(common.config).withDb { db, cfg ->
+ val (clientKeys, bankKeys) = expectFullKeys(cfg.ebics)
val pinnedStartVal = pinnedStart
val pinnedStartArg = if (pinnedStartVal != null) {
logger.debug("Pinning start date to: $pinnedStartVal")
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsCommon.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsCommon.kt
@@ -127,7 +127,7 @@ suspend fun EbicsBTS.postBTS(
/** High level EBICS client */
class EbicsClient(
- val cfg: NexusEbicsConfig,
+ val cfg: NexusConfig,
val client: HttpClient,
val db: Database,
val ebicsLogger: EbicsLogger,
@@ -151,7 +151,7 @@ class EbicsClient(
val description = order.description()
logger.debug { "Download order $description" }
val txLog = ebicsLogger.tx(order)
- val impl = EbicsBTS(cfg, bankKeys, clientKeys, order)
+ val impl = EbicsBTS(cfg.ebics, bankKeys, clientKeys, order)
// Close pending
while (true) {
@@ -248,8 +248,8 @@ class EbicsClient(
val description = order.description();
logger.debug { "Upload order $description" }
val txLog = ebicsLogger.tx(order)
- val impl = EbicsBTS(cfg, bankKeys, clientKeys, order)
- val preparedPayload = prepareUploadPayload(cfg, clientKeys, bankKeys, payload)
+ val impl = EbicsBTS(cfg.ebics, bankKeys, clientKeys, order)
+ val preparedPayload = prepareUploadPayload(cfg.ebics, clientKeys, bankKeys, payload)
// Init phase
val initXml = impl.uploadInitialization(preparedPayload)
diff --git a/nexus/src/test/kotlin/DatabaseTest.kt b/nexus/src/test/kotlin/DatabaseTest.kt
@@ -319,29 +319,29 @@ class PaymentInitiationsTest {
genInPay("test at $executionTime", executionTime = executionTime),
genOutPay("test at $executionTime", executionTime = executionTime)
)) {
- registerTransaction(db, cfg.ebics.ingest, tx)
+ registerTransaction(db, cfg.ingest, tx)
}
}
- assertEquals(cfg.ebics.fetch.ignoreTransactionsBefore, dateToInstant("2024-04-04"))
- assertEquals(cfg.ebics.fetch.ignoreBouncesBefore, dateToInstant("2024-06-12"))
+ assertEquals(cfg.fetch.ignoreTransactionsBefore, dateToInstant("2024-04-04"))
+ assertEquals(cfg.fetch.ignoreBouncesBefore, dateToInstant("2024-06-12"))
// No transaction at the beginning
checkCount(0, 0)
// Skipped transactions
- ingest(cfg.ebics.fetch.ignoreTransactionsBefore.minusMillis(10))
+ ingest(cfg.fetch.ignoreTransactionsBefore.minusMillis(10))
checkCount(0, 0)
// Skipped bounces
- ingest(cfg.ebics.fetch.ignoreTransactionsBefore)
- ingest(cfg.ebics.fetch.ignoreTransactionsBefore.plusMillis(10))
- ingest(cfg.ebics.fetch.ignoreBouncesBefore.minusMillis(10))
+ ingest(cfg.fetch.ignoreTransactionsBefore)
+ ingest(cfg.fetch.ignoreTransactionsBefore.plusMillis(10))
+ ingest(cfg.fetch.ignoreBouncesBefore.minusMillis(10))
checkCount(6, 0)
// Bounces
- ingest(cfg.ebics.fetch.ignoreBouncesBefore)
- ingest(cfg.ebics.fetch.ignoreBouncesBefore.plusMillis(10))
+ ingest(cfg.fetch.ignoreBouncesBefore)
+ ingest(cfg.fetch.ignoreBouncesBefore.plusMillis(10))
checkCount(10, 2)
}
diff --git a/nexus/src/test/kotlin/RegistrationTest.kt b/nexus/src/test/kotlin/RegistrationTest.kt
@@ -50,7 +50,7 @@ class RegistrationTest {
/** Register an XML sample into the database */
suspend fun Database.register(
- cfg: NexusEbicsConfig,
+ cfg: NexusConfig,
path: String,
doc: OrderDoc
) {
@@ -196,7 +196,7 @@ class RegistrationTest {
))
// Register HAC files
- db.register(cfg.ebics, "sample/platform/hac.xml", OrderDoc.acknowledgement)
+ db.register(cfg, "sample/platform/hac.xml", OrderDoc.acknowledgement)
// Check state
db.check(
@@ -228,7 +228,7 @@ class RegistrationTest {
))
// Register pain files
- db.register(cfg.ebics, "sample/platform/pain002.xml", OrderDoc.status)
+ db.register(cfg, "sample/platform/pain002.xml", OrderDoc.status)
// Check state
db.check(
@@ -284,8 +284,8 @@ class RegistrationTest {
))
// Register camt files
- db.register(cfg.ebics, "sample/platform/gls_camt052.xml", OrderDoc.report)
- db.register(cfg.ebics, "sample/platform/gls_camt053.xml", OrderDoc.statement)
+ db.register(cfg, "sample/platform/gls_camt052.xml", OrderDoc.report)
+ db.register(cfg, "sample/platform/gls_camt053.xml", OrderDoc.statement)
// TODO camt054 with missing id before and after
// Check state
diff --git a/testbench/src/main/kotlin/Main.kt b/testbench/src/main/kotlin/Main.kt
@@ -103,11 +103,10 @@ class Cli : CliktCommand() {
[libeufin-nexusdb-postgres]
CONFIG = postgres:///libeufintestbench
""")
- val nexusCfg = nexusConfig(conf)
- val cfg = nexusCfg.ebics
+ val cfg = nexusConfig(conf)
// Check if platform is known
- val kind = when (cfg.hostBaseUrl) {
+ val kind = when (cfg.ebics.hostBaseUrl) {
"https://isotest.postfinance.ch/ebicsweb/ebicsweb" ->
Kind("PostFinance IsoTest", "https://isotest.postfinance.ch/corporates/user/settings/ebics")
"https://iso20022test.credit-suisse.com/ebicsweb/ebicsweb" ->
@@ -126,8 +125,8 @@ class Cli : CliktCommand() {
val flags = " -c $conf -L $log"
val debugFlags = "$flags --debug-ebics test/$platform"
val ebicsFlags = "$debugFlags --transient"
- val clientKeysPath = cfg.clientPrivateKeysPath
- val bankKeysPath = cfg.bankPublicKeysPath
+ val clientKeysPath = cfg.ebics.clientPrivateKeysPath
+ val bankKeysPath = cfg.ebics.bankPublicKeysPath
val currency = cfg.currency
val dummyPaytos = mapOf(
diff --git a/testbench/src/test/kotlin/Iso20022Test.kt b/testbench/src/test/kotlin/Iso20022Test.kt
@@ -100,10 +100,9 @@ class Iso20022Test {
}
// Load config
- val nexusCfg = nexusConfig(platform.resolve("ebics.conf"))
- val cfg = nexusCfg.ebics
+ val cfg = nexusConfig(platform.resolve("ebics.conf"))
val currency = cfg.currency
- val dialect = cfg.dialect
+ val dialect = cfg.ebics.dialect
// Parse logs
for (log in logs) {
val content = Files.newInputStream(log)