diff options
author | Antoine A <> | 2024-04-30 13:19:45 +0900 |
---|---|---|
committer | Antoine A <> | 2024-04-30 13:19:45 +0900 |
commit | 15ab519ed54c0d5ca5840c175f9aa0642a6ccf87 (patch) | |
tree | 91ca961f29f1510cf9b04146fd378e8683d7c5ed | |
parent | 602a3b6e8afa3462a4f34cd6bb92005fec84c90b (diff) | |
download | libeufin-15ab519ed54c0d5ca5840c175f9aa0642a6ccf87.tar.gz libeufin-15ab519ed54c0d5ca5840c175f9aa0642a6ccf87.tar.bz2 libeufin-15ab519ed54c0d5ca5840c175f9aa0642a6ccf87.zip |
nexus: add libeufin-nexus serve
-rw-r--r-- | bank/src/main/kotlin/tech/libeufin/bank/Config.kt | 13 | ||||
-rw-r--r-- | bank/src/main/kotlin/tech/libeufin/bank/Main.kt | 25 | ||||
-rw-r--r-- | common/src/main/kotlin/Config.kt | 13 | ||||
-rw-r--r-- | common/src/main/kotlin/TalerCommon.kt | 1 | ||||
-rw-r--r-- | common/src/main/kotlin/api/server.kt | 24 | ||||
-rw-r--r-- | contrib/nexus.conf | 14 | ||||
-rw-r--r-- | nexus/src/main/kotlin/tech/libeufin/nexus/EbicsFetch.kt | 2 | ||||
-rw-r--r-- | nexus/src/main/kotlin/tech/libeufin/nexus/EbicsSetup.kt | 6 | ||||
-rw-r--r-- | nexus/src/main/kotlin/tech/libeufin/nexus/EbicsSubmit.kt | 2 | ||||
-rw-r--r-- | nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt | 17 | ||||
-rw-r--r-- | testbench/src/test/kotlin/IntegrationTest.kt | 6 |
11 files changed, 81 insertions, 42 deletions
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Config.kt b/bank/src/main/kotlin/tech/libeufin/bank/Config.kt index 9cdfcf0f..17fef641 100644 --- a/bank/src/main/kotlin/tech/libeufin/bank/Config.kt +++ b/bank/src/main/kotlin/tech/libeufin/bank/Config.kt @@ -68,11 +68,6 @@ data class ConversionRate ( val cashout_min_amount: TalerAmount, ) -sealed interface ServerConfig { - data class Unix(val path: String, val mode: Int): ServerConfig - data class Tcp(val addr: String, val port: Int): ServerConfig -} - fun talerConfig(configPath: Path?): TalerConfig = BANK_CONFIG_SOURCE.fromFile(configPath) fun TalerConfig.loadDbConfig(): DatabaseConfig { @@ -82,14 +77,6 @@ fun TalerConfig.loadDbConfig(): DatabaseConfig { ) } -fun TalerConfig.loadServerConfig(): ServerConfig { - return when (val method = requireString("libeufin-bank", "serve")) { - "tcp" -> ServerConfig.Tcp(lookupString("libeufin-bank", "address") ?: requireString("libeufin-bank", "bind_to"), requireNumber("libeufin-bank", "port")) - "unix" -> ServerConfig.Unix(requireString("libeufin-bank", "unixpath"), requireNumber("libeufin-bank", "unixpath_mode")) - else -> throw TalerConfigError.invalid("server method", "libeufin-bank", "serve", "expected 'tcp' or 'unix' got '$method'") - } -} - fun TalerConfig.loadBankConfig(): BankConfig { val regionalCurrency = requireString("libeufin-bank", "currency") var fiatCurrency: String? = null diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Main.kt b/bank/src/main/kotlin/tech/libeufin/bank/Main.kt index 8733b907..9f581048 100644 --- a/bank/src/main/kotlin/tech/libeufin/bank/Main.kt +++ b/bank/src/main/kotlin/tech/libeufin/bank/Main.kt @@ -62,8 +62,7 @@ import kotlin.io.path.exists import kotlin.io.path.readText private val logger: Logger = LoggerFactory.getLogger("libeufin-bank") -// Dirty local variable to stop the server in test TODO remove this ugly hack -var engine: ApplicationEngine? = null + /** @@ -117,7 +116,7 @@ class ServeBank : CliktCommand("Run libeufin-bank HTTP server", name = "serve") val cfg = talerConfig(common.config) val ctx = cfg.loadBankConfig() val dbCfg = cfg.loadDbConfig() - val serverCfg = cfg.loadServerConfig() + val serverCfg = cfg.loadServerConfig("libeufin-bank") Database(dbCfg, ctx.regionalCurrency, ctx.fiatCurrency).use { db -> if (ctx.allowConversion) { logger.info("Ensure exchange account exists") @@ -142,25 +141,9 @@ class ServeBank : CliktCommand("Run libeufin-bank HTTP server", name = "serve") db.conn { it.execSQLUpdate(sqlProcedures.readText()) } // Remove conversion info from the database ? } - - val env = applicationEngineEnvironment { - when (serverCfg) { - is ServerConfig.Tcp -> { - for (addr in InetAddress.getAllByName(serverCfg.addr)) { - connector { - port = serverCfg.port - host = addr.hostAddress - } - } - } - is ServerConfig.Unix -> - throw Exception("Can only serve libeufin-bank via TCP") - } - module { corebankWebApp(db, ctx) } + serve(serverCfg) { + corebankWebApp(db, ctx) } - val local = embeddedServer(Netty, env) - engine = local - local.start(wait = true) } } } diff --git a/common/src/main/kotlin/Config.kt b/common/src/main/kotlin/Config.kt index 95496839..536e88ff 100644 --- a/common/src/main/kotlin/Config.kt +++ b/common/src/main/kotlin/Config.kt @@ -33,4 +33,17 @@ fun getVersion(): String { return Loader.getResource( "version.txt", ClassLoader.getSystemClassLoader() ).readText() +} + +sealed interface ServerConfig { + data class Unix(val path: String, val mode: Int): ServerConfig + data class Tcp(val addr: String, val port: Int): ServerConfig +} + +fun TalerConfig.loadServerConfig(section: String): ServerConfig { + return when (val method = requireString(section, "serve")) { + "tcp" -> ServerConfig.Tcp(lookupString(section, "address") ?: requireString(section, "bind_to"), requireNumber(section, "port")) + "unix" -> ServerConfig.Unix(requireString(section, "unixpath"), requireNumber(section, "unixpath_mode")) + else -> throw TalerConfigError.invalid("server method", section, "serve", "expected 'tcp' or 'unix' got '$method'") + } }
\ No newline at end of file diff --git a/common/src/main/kotlin/TalerCommon.kt b/common/src/main/kotlin/TalerCommon.kt index 7dc72650..5596fb95 100644 --- a/common/src/main/kotlin/TalerCommon.kt +++ b/common/src/main/kotlin/TalerCommon.kt @@ -67,7 +67,6 @@ data class TalerProtocolTimestamp( } else { encoder.encodeLong(value.epochSecond) } - } override fun deserialize(decoder: Decoder): Instant { diff --git a/common/src/main/kotlin/api/server.kt b/common/src/main/kotlin/api/server.kt index ba6f2f61..43e37186 100644 --- a/common/src/main/kotlin/api/server.kt +++ b/common/src/main/kotlin/api/server.kt @@ -222,4 +222,28 @@ fun Application.talerApi(logger: Logger, routes: Routing.() -> Unit) { } } routing { routes() } +} + +// Dirty local variable to stop the server in test TODO remove this ugly hack +var engine: ApplicationEngine? = null + +fun serve(cfg: ServerConfig, api: Application.() -> Unit) { + val env = applicationEngineEnvironment { + when (cfg) { + is ServerConfig.Tcp -> { + for (addr in InetAddress.getAllByName(cfg.addr)) { + connector { + port = cfg.port + host = addr.hostAddress + } + } + } + is ServerConfig.Unix -> + throw Exception("Can only serve via TCP") + } + module { api() } + } + val local = embeddedServer(Netty, env) + engine = local + local.start(wait = true) }
\ No newline at end of file diff --git a/contrib/nexus.conf b/contrib/nexus.conf index b5703208..94d203c7 100644 --- a/contrib/nexus.conf +++ b/contrib/nexus.conf @@ -56,9 +56,21 @@ FREQUENCY = 30m FREQUENCY = 30m [nexus-httpd] -PORT = 8080 +# How "libeufin-nexus serve" serves its API, this can either be tcp or unix SERVE = tcp +# Port on which the HTTP server listens, e.g. 9967. Only used if SERVE is tcp. +PORT = 8080 + +# Which IP address should we bind to? E.g. ``127.0.0.1`` or ``::1``for loopback. Can also be given as a hostname. Only used if SERVE is tcp. +BIND_TO = 0.0.0.0 + +# Which unix domain path should we bind to? Only used if SERVE is unix. +# UNIXPATH = libeufin-nexus.sock + +# What should be the file access permissions for UNIXPATH? Only used if SERVE is unix. +# UNIXPATH_MODE = 660 + [nexus-httpd-wire-gateway-api] ENABLED = NO AUTH_METHOD = bearer-token diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsFetch.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsFetch.kt index 8e876f20..43cef8ca 100644 --- a/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsFetch.kt +++ b/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsFetch.kt @@ -364,7 +364,7 @@ class EbicsFetch: CliktCommand("Fetches EBICS files") { * mode when no flags are passed to the invocation. */ override fun run() = cliCmd(logger, common.log) { - val cfg = extractEbicsConfig(common.config) + val cfg = loadNexusConfig(common.config) val dbCfg = cfg.config.dbConfig() Database(dbCfg, cfg.currency).use { db -> diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsSetup.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsSetup.kt index 1c9ea902..7da7da07 100644 --- a/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsSetup.kt +++ b/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsSetup.kt @@ -155,7 +155,7 @@ suspend fun doKeysRequestAndUpdateState( * @param configFile location of the configuration entry point. * @return internal representation of the configuration. */ -fun extractEbicsConfig(configFile: Path?): NexusConfig { +fun loadNexusConfig(configFile: Path?): NexusConfig { val config = loadConfig(configFile) return NexusConfig(config) } @@ -197,8 +197,8 @@ class EbicsSetup: CliktCommand("Set up the EBICS subscriber") { * This function collects the main steps of setting up an EBICS access. */ override fun run() = cliCmd(logger, common.log) { - val cfg = extractEbicsConfig(common.config) - val client = HttpClient { + val cfg = loadNexusConfig(common.config) + val client = HttpClient { install(HttpTimeout) { // It can take a lot of time for the bank to generate documents socketTimeoutMillis = 5 * 60 * 1000 diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsSubmit.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsSubmit.kt index 947ecab6..c6a6ceef 100644 --- a/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsSubmit.kt +++ b/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsSubmit.kt @@ -147,7 +147,7 @@ class EbicsSubmit : CliktCommand("Submits any initiated payment found in the dat * FIXME: reduce code duplication with the fetch subcommand. */ override fun run() = cliCmd(logger, common.log) { - val cfg = extractEbicsConfig(common.config) + val cfg = loadNexusConfig(common.config) val dbCfg = cfg.config.dbConfig() val (clientKeys, bankKeys) = expectFullKeys(cfg) val ctx = SubmissionContext( diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt index d4f133bd..c8b46008 100644 --- a/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt +++ b/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt @@ -146,6 +146,21 @@ class InitiatePayment: CliktCommand("Initiate an outgoing payment") { } } +class Serve : CliktCommand("Run libeufin-nexus HTTP server", name = "serve") { + private val common by CommonOption() + + override fun run() = cliCmd(logger, common.log) { + val cfg = loadNexusConfig(common.config) + val dbCfg = cfg.config.dbConfig() + val serverCfg = cfg.config.loadServerConfig("nexus-httpd") + Database(dbCfg, cfg.currency).use { db -> + serve(serverCfg) { + nexusApi(db, cfg) + } + } + } +} + class ConvertBackup: CliktCommand("Convert an old backup to the new config format") { private val backupPath by argument( "backup", @@ -302,7 +317,7 @@ class TestingCmd : CliktCommand("Testing helper commands", name = "testing") { class LibeufinNexusCommand : CliktCommand() { init { versionOption(getVersion()) - subcommands(EbicsSetup(), DbInit(), EbicsSubmit(), EbicsFetch(), InitiatePayment(), CliConfigCmd(NEXUS_CONFIG_SOURCE), TestingCmd()) + subcommands(EbicsSetup(), DbInit(), Serve(), EbicsSubmit(), EbicsFetch(), InitiatePayment(), CliConfigCmd(NEXUS_CONFIG_SOURCE), TestingCmd()) } override fun run() = Unit } diff --git a/testbench/src/test/kotlin/IntegrationTest.kt b/testbench/src/test/kotlin/IntegrationTest.kt index 8adc9782..ad425d38 100644 --- a/testbench/src/test/kotlin/IntegrationTest.kt +++ b/testbench/src/test/kotlin/IntegrationTest.kt @@ -29,6 +29,7 @@ import kotlinx.coroutines.runBlocking import org.junit.Test import tech.libeufin.bank.* import tech.libeufin.common.* +import tech.libeufin.common.api.engine import tech.libeufin.common.db.one import tech.libeufin.nexus.* import java.time.Instant @@ -111,6 +112,11 @@ class IntegrationTest { } bankCmd.run("gc $flags") + + server { + nexusCmd.run("serve $flags") + } + engine?.stop(0, 0) } @Test |