libeufin

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

commit 43325087dc1b85f584d903c70bad1979781d3ac3
parent 15ae0483272dfcdb6245443631c37b91223bb795
Author: Marcello Stanisci <stanisci.m@gmail.com>
Date:   Fri,  4 Oct 2019 17:30:21 +0200

override new{}

Diffstat:
Msrc/main/kotlin/tech/libeufin/DB.kt | 18++++++------------
Msrc/main/kotlin/tech/libeufin/Main.kt | 19++++++++++++++-----
Asrc/main/kotlin/tech/libeufin/XML.kt | 237+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dsrc/main/kotlin/tech/libeufin/XMLTransform.kt | 229-------------------------------------------------------------------------------
4 files changed, 257 insertions(+), 246 deletions(-)

diff --git a/src/main/kotlin/tech/libeufin/DB.kt b/src/main/kotlin/tech/libeufin/DB.kt @@ -99,14 +99,12 @@ object EbicsUsers: IntIdTable() { class EbicsUser(id: EntityID<Int>) : IntEntity(id){ companion object : IntEntityClass<EbicsUser>(EbicsUsers) { - fun newUser() : EbicsUser { - var row = Companion.new { - } + override fun new(init: EbicsUser.() -> Unit): EbicsUser { + var row = super.new(init) row.userId = "u${row.id}" return row } } - var userId by EbicsUsers.userId } @@ -114,16 +112,14 @@ class EbicsUser(id: EntityID<Int>) : IntEntity(id){ * Table for UserID. */ object EbicsPartners: IntIdTable() { - // For simplicity, this entity is implemented by the - // 'id' field provided by the table constructor by default. val partnerId = varchar("partnerId", EBICS_PARTNER_ID_MAX_LENGTH).nullable() } class EbicsPartner(id: EntityID<Int>) : IntEntity(id) { companion object : IntEntityClass<EbicsPartner>(EbicsPartners) { - fun newUser(): EbicsPartner { - var row = EbicsPartner.new { } + override fun new(init: EbicsPartner.() -> Unit): EbicsPartner { + var row = super.new(init) row.partnerId = "p${row.id}" return row } @@ -136,15 +132,13 @@ class EbicsPartner(id: EntityID<Int>) : IntEntity(id) { * Table for UserID. */ object EbicsSystems: IntIdTable() { - // For simplicity, this entity is implemented by the - // 'id' field provided by the table constructor by default. val systemId = EbicsPartners.varchar("systemId", EBICS_SYSTEM_ID_MAX_LENGTH).nullable() } class EbicsSystem(id: EntityID<Int>) : IntEntity(id) { companion object : IntEntityClass<EbicsSystem>(EbicsSystems) { - fun newUser(): EbicsSystem { - var row = EbicsSystem.new { } + override fun new(init: EbicsSystem.() -> Unit): EbicsSystem { + var row = super.new(init) row.systemId = "s${row.id}" return row } diff --git a/src/main/kotlin/tech/libeufin/Main.kt b/src/main/kotlin/tech/libeufin/Main.kt @@ -43,7 +43,7 @@ import javax.xml.bind.JAXBElement fun main() { - val xmlProcess = XMLTransform() + val xmlProcess = XML() val logger = getLogger() dbCreateTables() @@ -77,7 +77,7 @@ fun main() { logger.info(body.toString()) val returnId = transaction { - var myUserId = EbicsUser.newUser() + var myUserId = EbicsUser.new { } val myPartnerId = EbicsPartner.new { } val mySystemId = EbicsSystem.new { } val subscriber = EbicsSubscriber.new { @@ -160,9 +160,7 @@ fun main() { post("/ebicsweb") { val body: String = call.receiveText() - logger.debug("Body: $body") val bodyDocument: Document? = xmlProcess.parseStringIntoDom(body) - if (bodyDocument == null) { call.respondText( contentType = ContentType.Application.Xml, @@ -181,9 +179,20 @@ fun main() { return@post } - logger.info("Processing", bodyDocument.documentElement.localName) + logger.info("Processing ${bodyDocument.documentElement.localName}") when (bodyDocument.documentElement.localName) { + "ebicsUnsecuredRequest" -> { + + /* Manage request. */ + + call.respond( + HttpStatusCode.NotImplemented, + SandboxError("Not implemented") + ) + return@post + } + "ebicsHEVRequest" -> { val hevResponse = HEVResponse( "000000", diff --git a/src/main/kotlin/tech/libeufin/XML.kt b/src/main/kotlin/tech/libeufin/XML.kt @@ -0,0 +1,236 @@ +/* + * This file is part of LibEuFin. + * Copyright (C) 2019 Stanisci and Dold. + + * LibEuFin is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3, or + * (at your option) any later version. + + * LibEuFin is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + + * You should have received a copy of the GNU Affero General Public + * License along with LibEuFin; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/> + */ + +package tech.libeufin; + +import org.w3c.dom.Document +import org.xml.sax.InputSource +import org.xml.sax.SAXException +import java.io.ByteArrayInputStream +import java.io.IOException +import java.io.InputStream +import java.io.StringWriter +import javax.xml.XMLConstants +import javax.xml.bind.JAXBContext +import javax.xml.bind.JAXBElement +import javax.xml.bind.JAXBException +import javax.xml.bind.Marshaller +import javax.xml.parsers.DocumentBuilderFactory +import javax.xml.parsers.ParserConfigurationException +import javax.xml.transform.OutputKeys +import javax.xml.transform.TransformerConfigurationException +import javax.xml.transform.TransformerException +import javax.xml.transform.TransformerFactory +import javax.xml.transform.dom.DOMSource +import javax.xml.transform.stream.StreamResult +import javax.xml.transform.stream.StreamSource +import javax.xml.validation.SchemaFactory + +/** + * This class takes care of importing XSDs and validate + * XMLs against those. + */ +class XML { + + /** + * Bundle of all the XSDs loaded in memory, from disk. + */ + private val bundle = { + val classLoader = ClassLoader.getSystemClassLoader() + val schemas = arrayOf( + // StreamSource(classLoader.getResourceAsStream("ebics_hev.xsd")), + // StreamSource(classLoader.getResourceAsStream("ebics_H004.xsd")), + // StreamSource(classLoader.getResourceAsStream("ebics_orders_H004.xsd")), + StreamSource(classLoader.getResourceAsStream("xmldsig-core-schema.xsd")), + StreamSource(classLoader.getResourceAsStream("ebics_types_H004.xsd")), + // StreamSource(classLoader.getResourceAsStream("ebics_signature.xsd")), + // StreamSource(classLoader.getResourceAsStream("ebics_response_H004.xsd")), + // StreamSource(classLoader.getResourceAsStream("ebics_keymgmt_response_H004.xsd")), + StreamSource(classLoader.getResourceAsStream("ebics_keymgmt_request_H004.xsd")) + + ) + + try { + val sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI) + sf.newSchema(schemas) + } catch (e: SAXException) { + e.printStackTrace() + // FIXME: must stop everything if schemas fail to load. + null + } + }() + private val validator = bundle?.newValidator() + + /** + * Parse string into XML DOM. + * @param xmlString the string to parse. + * @return the DOM representing @a xmlString + */ + fun parseStringIntoDom(xmlString: String): Document? { + + val factory = DocumentBuilderFactory.newInstance() + factory.isNamespaceAware = true + + try { + val xmlInputStream = ByteArrayInputStream(xmlString.toByteArray()) + val builder = factory.newDocumentBuilder() + val document = builder.parse(InputSource(xmlInputStream)); + + return document; + + } catch (e: ParserConfigurationException) { + e.printStackTrace() + } catch (e: SAXException) { + e.printStackTrace() + } catch (e: IOException) { + e.printStackTrace() + } + return null; + } + + /** + * + * @param xmlDoc the XML document to validate + * @return true when validation passes, false otherwise + */ + private fun validate(xmlDoc: StreamSource): Boolean { + try { + validator?.validate(xmlDoc) + } catch (e: SAXException) { + println(e.message) + return false; + } catch (e: IOException) { + e.printStackTrace() + return false; + } + + return true + } + + /** + * Validates the DOM against the Schema(s) of this object. + * @param domDocument DOM to validate + * @return true/false if the document is valid/invalid + */ + fun validateFromDom(domDocument: Document): Boolean { + try { + validator?.validate(DOMSource(domDocument)) + } catch (e: SAXException) { + e.printStackTrace() + return false + } + return true + } + + /** + * Craft object to be passed to the XML validator. + * @param xmlString XML body, as read from the POST body. + * @return InputStream object, as wanted by the validator. + */ + fun validateFromString(xmlString: String): Boolean { + val xmlInputStream: InputStream = ByteArrayInputStream(xmlString.toByteArray()) + val xmlSource = StreamSource(xmlInputStream) + return this.validate(xmlSource) + } + + /** + * Return the DOM representation of the Java object, using the JAXB + * interface. FIXME: narrow input type to JAXB type! + * + * @param object to be transformed into DOM. Typically, the object + * has already got its setters called. + * @return the DOM Document, or null (if errors occur). + */ + fun convertJaxbToDom(obj: JAXBElement<Unit>): Document? { + + try { + val jc = JAXBContext.newInstance("tech.libeufin.messages") + + /* Make the target document. */ + val dbf = DocumentBuilderFactory.newInstance() + val db = dbf.newDocumentBuilder() + val document = db.newDocument() + + /* Marshalling the object into the document. */ + val m = jc.createMarshaller() + m.marshal(obj, document) // document absorbed the XML! + return document + + } catch (e: JAXBException) { + e.printStackTrace() + } catch (e: ParserConfigurationException) { + e.printStackTrace() + } + return null; + } + + /** + * Extract String from DOM. + * + * @param document the DOM to extract the string from. + * @return the final String, or null if errors occur. + */ + fun getStringFromDocument(document: Document): String? { + + try { + /* Make Transformer. */ + val tf = TransformerFactory.newInstance(); + val t = tf.newTransformer() + + t.setOutputProperty(OutputKeys.INDENT, "no") + + /* Make string writer. */ + val sw = StringWriter() + + /* Extract string. */ + t.transform(DOMSource(document), StreamResult(sw)) + return sw.toString() + + } catch (e: TransformerConfigurationException) { + e.printStackTrace() + } catch (e: TransformerException) { + e.printStackTrace() + } + return null; + } + + /** + * Extract String from JAXB. + * + * @param obj the JAXB instance + * @return String representation of @a object, or null if errors occur + */ + fun <T> getStringFromJaxb(obj: JAXBElement<T>): String? { + val sw = StringWriter() + + try { + val jc = JAXBContext.newInstance("tech.libeufin.messages") + /* Getting the string. */ + val m = jc.createMarshaller() + m.marshal(obj, sw) + m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true) + + } catch (e: JAXBException) { + e.printStackTrace() + return "Bank fatal error." + } + + return sw.toString() + } +} +\ No newline at end of file diff --git a/src/main/kotlin/tech/libeufin/XMLTransform.kt b/src/main/kotlin/tech/libeufin/XMLTransform.kt @@ -1,228 +0,0 @@ -/* - * This file is part of LibEuFin. - * Copyright (C) 2019 Stanisci and Dold. - - * LibEuFin is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3, or - * (at your option) any later version. - - * LibEuFin is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General - * Public License for more details. - - * You should have received a copy of the GNU Affero General Public - * License along with LibEuFin; see the file COPYING. If not, see - * <http://www.gnu.org/licenses/> - */ - -package tech.libeufin; - -import org.w3c.dom.Document -import org.xml.sax.InputSource -import org.xml.sax.SAXException -import java.io.ByteArrayInputStream -import java.io.IOException -import java.io.InputStream -import java.io.StringWriter -import javax.xml.XMLConstants -import javax.xml.bind.JAXBContext -import javax.xml.bind.JAXBElement -import javax.xml.bind.JAXBException -import javax.xml.bind.Marshaller -import javax.xml.parsers.DocumentBuilderFactory -import javax.xml.parsers.ParserConfigurationException -import javax.xml.transform.OutputKeys -import javax.xml.transform.TransformerConfigurationException -import javax.xml.transform.TransformerException -import javax.xml.transform.TransformerFactory -import javax.xml.transform.dom.DOMSource -import javax.xml.transform.stream.StreamResult -import javax.xml.transform.stream.StreamSource -import javax.xml.validation.SchemaFactory - -/** - * This class takes care of importing XSDs and validate - * XMLs against those. - */ -class XMLTransform { - - /** - * Bundle of all the XSDs loaded in memory, from disk. - */ - private val bundle = { - val classLoader = ClassLoader.getSystemClassLoader() - val ebicsHevPath = classLoader.getResourceAsStream("ebics_hev.xsd") - val schemas = arrayOf( - StreamSource(ebicsHevPath) - // other StreamSources for other schemas here .. - ) - - try { - val sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI) - sf.newSchema(schemas) - } catch (e: SAXException) { - e.printStackTrace() - null - } - }() - private val validator = bundle?.newValidator() - - /** - * Parse string into XML DOM. - * @param xmlString the string to parse. - * @return the DOM representing @a xmlString - */ - fun parseStringIntoDom(xmlString: String): Document? { - - val factory = DocumentBuilderFactory.newInstance() - factory.isNamespaceAware = true - - try { - val xmlInputStream = ByteArrayInputStream(xmlString.toByteArray()) - val builder = factory.newDocumentBuilder() - val document = builder.parse(InputSource(xmlInputStream)); - - return document; - - } catch (e: ParserConfigurationException) { - e.printStackTrace() - } catch (e: SAXException) { - e.printStackTrace() - } catch (e: IOException) { - e.printStackTrace() - } - return null; - } - - /** - * - * @param xmlDoc the XML document to validate - * @return true when validation passes, false otherwise - */ - private fun validate(xmlDoc: StreamSource): Boolean { - try { - validator?.validate(xmlDoc) - } catch (e: SAXException) { - e.printStackTrace() - return false; - } catch (e: IOException) { - e.printStackTrace() - return false; - } - - return true - } - - /** - * Validates the DOM against the Schema(s) of this object. - * @param domDocument DOM to validate - * @return true/false if the document is valid/invalid - */ - fun validateFromDom(domDocument: Document): Boolean { - try { - validator?.validate(DOMSource(domDocument)) - } catch (e: SAXException) { - e.printStackTrace() - return false - } - return true - } - - /** - * Craft object to be passed to the XML validator. - * @param xmlString XML body, as read from the POST body. - * @return InputStream object, as wanted by the validator. - */ - fun validateFromString(xmlString: String): Boolean { - val xmlInputStream: InputStream = ByteArrayInputStream(xmlString.toByteArray()) - val xmlSource = StreamSource(xmlInputStream) - return this.validate(xmlSource) - } - - /** - * Return the DOM representation of the Java object, using the JAXB - * interface. FIXME: narrow input type to JAXB type! - * - * @param object to be transformed into DOM. Typically, the object - * has already got its setters called. - * @return the DOM Document, or null (if errors occur). - */ - fun convertJaxbToDom(obj: JAXBElement<Unit>): Document? { - - try { - val jc = JAXBContext.newInstance("tech.libeufin.messages") - - /* Make the target document. */ - val dbf = DocumentBuilderFactory.newInstance() - val db = dbf.newDocumentBuilder() - val document = db.newDocument() - - /* Marshalling the object into the document. */ - val m = jc.createMarshaller() - m.marshal(obj, document) // document absorbed the XML! - return document - - } catch (e: JAXBException) { - e.printStackTrace() - } catch (e: ParserConfigurationException) { - e.printStackTrace() - } - return null; - } - - /** - * Extract String from DOM. - * - * @param document the DOM to extract the string from. - * @return the final String, or null if errors occur. - */ - fun getStringFromDocument(document: Document): String? { - - try { - /* Make Transformer. */ - val tf = TransformerFactory.newInstance(); - val t = tf.newTransformer() - - t.setOutputProperty(OutputKeys.INDENT, "no") - - /* Make string writer. */ - val sw = StringWriter() - - /* Extract string. */ - t.transform(DOMSource(document), StreamResult(sw)) - return sw.toString() - - } catch (e: TransformerConfigurationException) { - e.printStackTrace() - } catch (e: TransformerException) { - e.printStackTrace() - } - return null; - } - - /** - * Extract String from JAXB. - * - * @param obj the JAXB instance - * @return String representation of @a object, or null if errors occur - */ - fun <T> getStringFromJaxb(obj: JAXBElement<T>): String? { - val sw = StringWriter() - - try { - val jc = JAXBContext.newInstance("tech.libeufin.messages") - /* Getting the string. */ - val m = jc.createMarshaller() - m.marshal(obj, sw) - m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true) - - } catch (e: JAXBException) { - e.printStackTrace() - return "Bank fatal error." - } - - return sw.toString() - } -} -\ No newline at end of file