libeufin

Integration and sandbox testing for FinTech APIs and data formats
Log | Files | Refs | Submodules | README | LICENSE

commit 75771006882617149ef31152462e90b412ca9acb
parent 6da14dee5b8ab8dc283c13cec352fb8e9b5b419b
Author: Florian Dold <florian.dold@gmail.com>
Date:   Fri, 19 Jun 2020 13:59:32 +0530

scheduling WIP

Diffstat:
M.idea/dictionaries/dold.xml | 1+
Mnexus/src/main/kotlin/tech/libeufin/nexus/DB.kt | 23++++++++++++++++++++++-
Mnexus/src/main/kotlin/tech/libeufin/nexus/server/JSON.kt | 12+++++++-----
Mnexus/src/main/kotlin/tech/libeufin/nexus/server/NexusServer.kt | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
4 files changed, 97 insertions(+), 10 deletions(-)

diff --git a/.idea/dictionaries/dold.xml b/.idea/dictionaries/dold.xml @@ -3,6 +3,7 @@ <words> <w>affero</w> <w>combinators</w> + <w>cronspec</w> <w>ebics</w> <w>libeufin</w> <w>payto</w> diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/DB.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/DB.kt @@ -336,6 +336,26 @@ class TalerFacadeStateEntity(id: EntityID<Int>) : IntEntity(id) { var highestSeenMsgID by TalerFacadeStateTable.highestSeenMsgID } +object NexusScheduledTasksTable : IntIdTable() { + val resourceType = text("resourceType") + val resourceId = text("resourceId") + val taskName = text("taskName") + val taskType = text("taskType") + val taskCronspec = text("taskCronspec") + val taskParams = text("taskParams") +} + +class NexusScheduledTaskEntity(id: EntityID<Int>) : IntEntity(id) { + companion object : IntEntityClass<NexusScheduledTaskEntity>(NexusScheduledTasksTable) + + var resourceType by NexusScheduledTasksTable.resourceType + var resourceId by NexusScheduledTasksTable.resourceId + var taskName by NexusScheduledTasksTable.taskName + var taskType by NexusScheduledTasksTable.taskType + var taskCronspec by NexusScheduledTasksTable.taskCronspec + var taskParams by NexusScheduledTasksTable.taskParams +} + fun dbCreateTables(dbName: String) { Database.connect("jdbc:sqlite:${dbName}", "org.sqlite.JDBC") TransactionManager.manager.defaultIsolationLevel = Connection.TRANSACTION_SERIALIZABLE @@ -352,7 +372,8 @@ fun dbCreateTables(dbName: String) { NexusBankConnectionsTable, NexusBankMessagesTable, FacadesTable, - TalerFacadeStateTable + TalerFacadeStateTable, + NexusScheduledTasksTable ) } } diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/server/JSON.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/server/JSON.kt @@ -288,10 +288,6 @@ data class TalerWireGatewayFacadeConfig( val intervalIncremental: String ) -/********************************************************************** - * Convenience types (ONLY used to gather data together in one place) * - **********************************************************************/ - data class Pain001Data( val creditorIban: String, val creditorBic: String?, @@ -301,4 +297,9 @@ data class Pain001Data( val subject: String ) - +data class CreateAccountTaskRequest( + val name: String, + val cronspec: String, + val type: String, + val params: JsonNode +) +\ No newline at end of file diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/server/NexusServer.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/server/NexusServer.kt @@ -42,15 +42,13 @@ import io.ktor.request.* import io.ktor.response.respond import io.ktor.response.respondBytes import io.ktor.response.respondText -import io.ktor.routing.get -import io.ktor.routing.post -import io.ktor.routing.route -import io.ktor.routing.routing +import io.ktor.routing.* import io.ktor.server.engine.embeddedServer import io.ktor.server.netty.Netty import io.ktor.utils.io.ByteReadChannel import io.ktor.utils.io.jvm.javaio.toByteReadChannel import io.ktor.utils.io.jvm.javaio.toInputStream +import org.jetbrains.exposed.sql.and import org.jetbrains.exposed.sql.transactions.transaction import org.slf4j.event.Level import tech.libeufin.nexus.* @@ -346,6 +344,71 @@ fun serverMain(dbName: String) { return@get } + get("/bank-accounts/{accountid}/schedule") { + val resp = jacksonObjectMapper().createObjectNode() + val ops = jacksonObjectMapper().createObjectNode() + val accountId = ensureNonNull(call.parameters["accountid"]) + resp.set<JsonNode>("schedule", ops) + transaction { + val bankAccount = NexusBankAccountEntity.findById(accountId) + if (bankAccount == null) { + throw NexusError(HttpStatusCode.NotFound, "unknown bank account") + } + NexusScheduledTaskEntity.find { + (NexusScheduledTasksTable.resourceType eq "bank-account") and + (NexusScheduledTasksTable.resourceId eq accountId) + + }.forEach { + val t = jacksonObjectMapper().createObjectNode() + ops.set<JsonNode>(it.taskName, t) + t.put("cronspec", it.taskCronspec) + t.put("type", it.taskType) + t.set<JsonNode>("params", jacksonObjectMapper().readTree(it.taskParams)) + } + Unit + } + call.respond(resp) + } + + post("/bank-accounts/{accountid}/schedule") { + val schedSpec = call.receive<CreateAccountTaskRequest>() + val accountId = ensureNonNull(call.parameters["accountid"]) + transaction { + authenticateRequest(call.request) + val bankAccount = NexusBankAccountEntity.findById(accountId) + if (bankAccount == null) { + throw NexusError(HttpStatusCode.NotFound, "unknown bank account") + } + when (schedSpec.type) { + "fetch" -> { + val fetchSpec = jacksonObjectMapper().treeToValue(schedSpec.params, FetchSpecJson::class.java) + if (fetchSpec == null) { + throw NexusError(HttpStatusCode.BadRequest, "bad fetch spec") + } + } + else -> throw NexusError(HttpStatusCode.BadRequest, "unsupported task type") + } + NexusScheduledTaskEntity.new { + resourceType = "bank-account" + resourceId = accountId + this.taskCronspec = schedSpec.cronspec + this.taskName = schedSpec.name + this.taskType = schedSpec.type + this.taskParams = + jacksonObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(schedSpec.params) + } + } + call.respond(object { }) + } + + get("/bank-accounts/{accountid}/schedule/{taskid}") { + + } + + delete("/bank-accounts/{accountid}/schedule/{taskid}") { + + } + get("/bank-accounts/{accountid}") { val accountId = ensureNonNull(call.parameters["accountid"]) val res = transaction {