libeufin

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

commit cfd356517fe45c455281277e82acafed2765d9b7
parent 9677d8671fd8fcc07f64721223ba22627350ad7c
Author: Marcello Stanisci <stanisci.m@gmail.com>
Date:   Thu, 26 Sep 2019 18:57:26 +0200

inserting new "user" into DB

Diffstat:
Msrc/main/kotlin/Main.kt | 57++++++++++++++++++++++++++++++++++++++-------------------
Msrc/main/kotlin/tech/libeufin/DB.kt | 90+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
2 files changed, 99 insertions(+), 48 deletions(-)

diff --git a/src/main/kotlin/Main.kt b/src/main/kotlin/Main.kt @@ -34,26 +34,28 @@ import tech.libeufin.messages.HEVResponseDataType import javax.xml.bind.JAXBElement import io.ktor.features.* import io.netty.handler.codec.http.HttpContent +import org.jetbrains.exposed.sql.insert +import org.jetbrains.exposed.sql.transactions.transaction +import tech.libeufin.tech.libeufin.BankCustomers +import tech.libeufin.tech.libeufin.createSubscriber +import tech.libeufin.tech.libeufin.dbCreateTables import java.text.* -enum class Foo {BAR, BAZ} - fun main() { var xmlProcess = XMLTransform() var logger = getLogger() + dbCreateTables() val server = embeddedServer(Netty, port = 5000) { install(CallLogging) - install(ContentNegotiation){ + install(ContentNegotiation) { gson { setDateFormat(DateFormat.LONG) setPrettyPrinting() } - } - routing { get("/") { logger.debug("GET: not implemented") @@ -67,10 +69,21 @@ fun main() { try { val body = call.receive<Customer>() logger.info(body.toString()) + logger.info("name:: ->> " + body.name) + + transaction { + createSubscriber() + } + + transaction { + BankCustomers.insert { + it[name] = body.name + // it[ebicsSubscrber] = createSubscriber().id + } + } } catch (e: Exception) { e.printStackTrace() - // return error, FIXME: distinguish between server and client error! call.respond( HttpStatusCode.BadRequest, SandboxError(e.message.toString()) @@ -78,11 +91,9 @@ fun main() { return@post } + call.respondText { "Your stuff got created" } - - // create table entries: customer + user + partner + system. - - // return response + return@post } get("/admin/customers/:id") { @@ -98,8 +109,10 @@ fun main() { if (!isValid) { logger.error("Invalid request received") - call.respondText(contentType = ContentType.Application.Xml, - status = HttpStatusCode.BadRequest) {"Bad request"} + call.respondText( + contentType = ContentType.Application.Xml, + status = HttpStatusCode.BadRequest + ) { "Bad request" } return@post } @@ -107,8 +120,10 @@ fun main() { if (null == bodyDocument) { /* Should never happen. */ logger.error("A valid document failed to parse into DOM!") - call.respondText(contentType = ContentType.Application.Xml, - status = HttpStatusCode.InternalServerError) {"Internal server error"} + call.respondText( + contentType = ContentType.Application.Xml, + status = HttpStatusCode.InternalServerError + ) { "Internal server error" } return@post } logger.info(bodyDocument.documentElement.localName) @@ -123,19 +138,23 @@ fun main() { ProtocolAndVersion("H004", "02.50") ) ) - + val jaxbHEV: JAXBElement<HEVResponseDataType> = hevResponse.makeHEVResponse() val responseText: String? = xmlProcess.getStringFromJaxb(jaxbHEV) // FIXME: check if String is actually non-NULL! - call.respondText(contentType = ContentType.Application.Xml, - status = HttpStatusCode.OK) {responseText.toString()} + call.respondText( + contentType = ContentType.Application.Xml, + status = HttpStatusCode.OK + ) { responseText.toString() } return@post } else -> { /* Log to console and return "unknown type" */ logger.info("Unknown message, just logging it!") - call.respondText(contentType = ContentType.Application.Xml, - status = HttpStatusCode.NotFound) {"Not found"} + call.respondText( + contentType = ContentType.Application.Xml, + status = HttpStatusCode.NotFound + ) { "Not found" } return@post } } diff --git a/src/main/kotlin/tech/libeufin/DB.kt b/src/main/kotlin/tech/libeufin/DB.kt @@ -1,6 +1,7 @@ package tech.libeufin.tech.libeufin -import org.jetbrains.exposed.dao.IntIdTable +import com.sun.org.apache.bcel.internal.generic.NEW +import org.jetbrains.exposed.dao.* import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.transactions.transaction @@ -8,6 +9,7 @@ const val CUSTOMER_NAME_MAX_LENGTH = 20 const val SUBSCRIBER_ID_MAX_LENGTH = 10 const val PUBLIC_KEY_MAX_LENGTH = 256 // FIXME review this value! const val PRIV_KEY_MAX_LENGTH = 512 // FIXME review this value! +const val SQL_ENUM_SUBSCRIBER_STATES = "ENUM('NEW', 'PARTIALLI_INITIALIZED_INI', 'PARTIALLY_INITIALIZED_HIA', 'INITIALIZED', 'READY')" /** * All the states to give a subscriber. @@ -66,10 +68,10 @@ enum class KeyStates { * This table information *not* related to EBICS, for all * its customers. */ -object Customer: IntIdTable() { +object BankCustomers: IntIdTable() { // Customer ID is the default 'id' field provided by the constructor. val name = varchar("name", CUSTOMER_NAME_MAX_LENGTH) - val ebicsUserId = reference("ebicsUserId", EbicsUsers) + // val ebicsSubscrber = reference("ebicsSubscriber", EbicsUsers) } /** @@ -89,6 +91,10 @@ object EbicsUsers: IntIdTable() { // 'id' field provided by the table constructor by default. } +class EbicsUser(id: EntityID<Int>) : IntEntity(id) { + companion object : IntEntityClass<EbicsUser>(EbicsUsers) +} + /** * Table for UserID. */ @@ -97,6 +103,12 @@ object EbicsPartners: IntIdTable() { // 'id' field provided by the table constructor by default. } + +class EbicsPartner(id: EntityID<Int>) : IntEntity(id) { + companion object : IntEntityClass<EbicsPartner>(EbicsPartners) +} + + /** * Table for UserID. */ @@ -105,6 +117,10 @@ object EbicsSystems: IntIdTable() { // 'id' field provided by the table constructor by default. } +class EbicsSystem(id: EntityID<Int>) : IntEntity(id) { + companion object : IntEntityClass<EbicsSystem>(EbicsSystems) +} + /** * Subscribers table. This table associates users with partners * and systems. Each value can appear multiple times in the same column. @@ -113,42 +129,50 @@ object EbicsSubscribers: IntIdTable() { val userId = reference("UserId", EbicsUsers) val partnerId = reference("PartnerId", EbicsPartners) val systemId = reference("SystemId", EbicsSystems) + + val signatureKey = reference("signatureKey", EbicsPublicKey).nullable() + val encryptionKey = reference("encryptionKey", EbicsPublicKey).nullable() + val authorizationKey = reference("authorizationKey", EbicsPublicKey).nullable() + + val state = customEnumeration( + "state", + SQL_ENUM_SUBSCRIBER_STATES, + {SubscriberStates.values()[it as Int]}, + {it.name}) } +class EbicsSubscriber(id: EntityID<Int>) : IntEntity(id) { + companion object : IntEntityClass<EbicsSubscriber>(EbicsSubscribers) -/** - * This table maps customers with EBICS subscribers. - */ -object CustomerSubscriberMap: IntIdTable(){ - val customerId = reference("customerId", Customer) - val subscriberId = reference("subscriberId", Subscriber) + var userId by EbicsUser referencedOn EbicsSubscribers.userId + var partnerId by EbicsPartner referencedOn EbicsSubscribers.partnerId + var systemId by EbicsSystem referencedOn EbicsSubscribers.systemId + + var signatureKey by EbicsPublicKey.id + var encryptionKey by EbicsPublicKey.id + var authorizationKey by EbicsPublicKey.id + var state by EbicsSubscribers.state } /** - * This table defines a EBICS subscriber. + * Helper function that makes a new subscriber + * @return new object */ -object Subscriber: IntIdTable(){ - // is EBICS 'subscriber' ID? - val subscriberId: Column<String> = varchar( - "subscriberId", - SUBSCRIBER_ID_MAX_LENGTH).primaryKey() - - val state = customEnumeration( - "state", - "ENUM('NEW', 'PARTIALLI_INITIALIZED_INI', 'PARTIALLY_INITIALIZED_HIA', 'INITIALIZED', 'READY')", - {SubscriberStates.values()[it as Int]}, - {it.name} - ) +fun createSubscriber() : EbicsSubscriber { - val signatureKey = reference("signatureKey", EBICSPublicKEy) - val encryptionKey = reference("encryptionKey", EBICSPublicKEy) - val authorizationKey = reference("authorizationKey", EBICSPublicKEy) + return EbicsSubscriber.new { + userId = EbicsUser.new { } + partnerId = EbicsPartner.new { } + systemId = EbicsSystem.new { } + state = SubscriberStates.NEW + } } + /** * This table stores RSA public keys. */ -object EBICSPublicKEy: IntIdTable(){ +object EbicsPublicKey: IntIdTable() { val pub = binary("pub", PUBLIC_KEY_MAX_LENGTH) val state = customEnumeration( "state", @@ -160,14 +184,22 @@ object EBICSPublicKEy: IntIdTable(){ /** * This table stores RSA private keys. */ -object EBICSPrivateKEy: IntIdTable(){ +object EbicsPrivateKEy: IntIdTable() { val pub = binary("priv", PRIV_KEY_MAX_LENGTH) } -fun db() { - Database.connect("jdbc:h2:mem:test", driver = "org.h2.Driver") +fun dbCreateTables() { + Database.connect("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1", driver = "org.h2.Driver") transaction { addLogger(StdOutSqlLogger) + + SchemaUtils.create( + BankCustomers, + EbicsUsers, + EbicsPartners, + EbicsSystems, + EbicsSubscribers + ) } } \ No newline at end of file