[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libeufin] branch master updated: Including more details into C52 and C5
From: |
gnunet |
Subject: |
[libeufin] branch master updated: Including more details into C52 and C53 responses. |
Date: |
Wed, 15 Jan 2020 11:05:52 +0100 |
This is an automated email from the git hooks/post-receive script.
marcello pushed a commit to branch master
in repository libeufin.
The following commit(s) were added to refs/heads/master by this push:
new cbb6871 Including more details into C52 and C53 responses.
cbb6871 is described below
commit cbb687136fbefc4871a996b6b14a8d4d0528b533
Author: Marcello Stanisci <address@hidden>
AuthorDate: Wed Jan 15 11:03:22 2020 +0100
Including more details into C52 and C53 responses.
---
.../tech/libeufin/sandbox/EbicsProtocolBackend.kt | 245 +++++++++++++++++++--
sandbox/src/test/kotlin/XmlCombinatorsTest.kt | 32 +++
util/src/main/kotlin/XmlCombinators.kt | 11 +-
3 files changed, 265 insertions(+), 23 deletions(-)
diff --git
a/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
index 6166d08..012cfbc 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
@@ -41,6 +41,8 @@ import tech.libeufin.util.CryptoUtil
import tech.libeufin.util.EbicsOrderUtil
import tech.libeufin.util.XMLUtil
import tech.libeufin.util.*
+import java.awt.List
+import java.math.BigDecimal
import java.security.interfaces.RSAPrivateCrtKey
import java.util.*
import java.util.zip.DeflaterInputStream
@@ -111,7 +113,153 @@ private suspend fun
ApplicationCall.respondEbicsKeyManagement(
respondText(text, ContentType.Application.Xml, HttpStatusCode.OK)
}
-/* intra-day account traffic */
+/**
+ * This function populates the "history" content of both a CAMT.052 and
CAMT.053.
+ * FIXME: There might be needed some filter to exclude non-booked entries from
a
+ * query-set (as CAMT.053 should do, see #6046)
+ *
+ * @param cusromerId unique identifier of a bank's customer: not
EBICS-relevant.
+ * @param request the EBICS request carrying a "history" message.
+ * @param base the sub-node where to start attaching history elements.
+ *
+ */
+private fun iterHistory(customerId: Int, request: EbicsRequest, base:
XmlElementBuilder) {
+
+ extractHistoryForEach(
+ customerId,
+ try {
+ (request.header.static.orderDetails?.orderParams as
EbicsRequest.StandardOrderParams).dateRange?.start.toString()
+ } catch (e: Exception) {
+ getGregorianDate().toString()
+ },
+ try {
+ (request.header.static.orderDetails?.orderParams as
EbicsRequest.StandardOrderParams).dateRange?.end.toString()
+ } catch (e: Exception) {
+ getGregorianDate().toString()
+ }
+ ) {
+
+ base.element("Ntry") {
+ /* FIXME: one entry in an account history.
+ * NOTE: this element can appear from 0 to unbounded number of
times.
+ * */
+ element("Amt") {
+ /* FIXME: amount of this entry */
+ }
+ element("CdtDbtInd") {
+ /* FIXME: as above, whether the entry witnesses debit or
credit */
+ }
+ element("Sts") {
+ /* FIXME: status of the entry (see 2.4.2.15.5 from the
ISO20022 reference document.)
+ *
+ * From the original text:
+ * "Status of an entry on the books of the account servicer"
+ */
+ }
+ element("BkTxCd") {
+ /* FIXME: Bank-transaction-code, see section 2.4.2.15.10.
+ * From the original text:
+ *
+ * "Set of elements used to fully identify the type of
underlying
+ * transaction resulting in an entry"
+ */
+ }
+ element("BookgDt") {
+ /**
+ * FIXME, Booking-date: when the entry was posted on the books
+ * of the account servicer; do not necessarily implies that
assets
+ * become available. NOTE: this element is optional.
+ */
+ }
+ element("ValDt") {
+ /**
+ * FIXME, Value-date: when the asset corresponding to one entry
+ * becomes available (or unavailable, in case of debit type
entry)
+ * to the account owner. NOTE: this element is optional.
+ */
+ }
+ }
+ }
+}
+
+/**
+ * This function populates the content under "Rpt" or "Stmt" nodes,
+ * therefore is valid for generating both C52 and C53 responses.
+ *
+ * @param base the sub-node where starting to append content.
+ */
+private fun balance(base: XmlElementBuilder) {
+
+ base.element("Id") {
+ // unique identificator for a report.
+ text("id under report")
+ }
+ base.element("Acct") {
+ // mandatory account identifier
+ text("account identifier")
+ }
+ base.element("Bal") {
+ element("Tp") {
+ // FIXME: type
+ element("CdOrPrTry") {
+ /**
+ * FIXME: code-or-proprietary
+ * This section specifies the 'balance type', either in a
+ * 'coded' format or in a proprietary one.
+ */
+ }
+ }
+ element("Amt") {
+ /**
+ * FIXME: Amount
+ */
+ attribute("Ccy", "EUR")
+ BigDecimal("1.00")
+ }
+ element("CdtDbtInd") {
+ /**
+ * FIXME: credit-debit-indicator
+ * Indicates whether the balance is a 'credit' ("CRDT") or a
'debit' ("DBIT") balance.
+ */
+ }
+ element("Dt") {
+ /**
+ * FIXME: date, in YYYY-MM-DD format
+ */
+ }
+ }
+}
+
+/**
+ * Builds CAMT response.
+ *
+ * @param history the list of all the history elements
+ * @param type 52 or 53.
+ */
+private fun constructCamtResponse(type: Int, customerId: Int, request:
EbicsRequest): String {
+
+ val camt = constructXml(indent = true) {
+
+ namespace("foo", "bar") // FIXME: set right namespace!
+ root("foo:BkToCstmrAcctRpt") {
+ element("GrpHdr") {
+ element("MsgId") {
+ // unique identifier for a message
+ text("id under group header")
+ }
+ }
+
+ element(if (type == 52) "Rpt" else "Stmt") {
+
+ balance(this)
+ iterHistory(customerId, request, this)
+ }
+ }
+ }
+
+ return camt
+}
+
private fun ApplicationCall.handleEbicsC52(header: EbicsRequest.Header):
ByteArray {
val userId = header.static.userID!!
@@ -124,39 +272,100 @@ private fun ApplicationCall.handleEbicsC52(header:
EbicsRequest.Header): ByteArr
}
}.firstOrNull() ?: throw Exception("Unknown subscriber")
- val history = extractHistoryForEach(
- subscriber.bankCustomer.id.value,
- try {
- (op as
EbicsRequest.StandardOrderParams).dateRange?.start.toString()
- } catch (e: Exception) {
- getGregorianDate().toString()
- },
- try {
- (op as EbicsRequest.StandardOrderParams).dateRange?.end.toString()
- } catch (e: Exception) {
- getGregorianDate().toString()
- }
- ) { println(it) }
+ // call history builder here
val ret = constructXml(indent = true) {
namespace("foo", "bar")
root("foo:BkToCstmrAcctRpt") {
element("GrpHdr") {
-
element("MsgId") {
+ // unique identifier for a message
text("id under group header")
}
- element("CreDtTm") {
- text("now")
- }
}
+ /*
+ * NOTE: Rpt elements can be 1 or more
+ */
element("Rpt") {
element("Id") {
+ // unique identificator for a report.
text("id under report")
}
element("Acct") {
+ // mandatory account identifier
text("account identifier")
}
+ element("Bal") {
+ element("Tp") {
+ // FIXME: type
+ element("CdOrPrTry") {
+ /**
+ * FIXME: code-or-proprietary
+ * This section specifies the 'balance type',
either in a
+ * 'coded' format or in a proprietary one.
+ */
+ }
+ }
+ element("Amt") {
+ /**
+ * FIXME: Amount
+ */
+ attribute("Ccy", "EUR")
+ BigDecimal("1.00")
+ }
+ element("CdtDbtInd") {
+ /**
+ * FIXME: credit-debit-indicator
+ * Indicates whether the balance is a 'credit'
("CRDT") or a 'debit' ("DBIT") balance.
+ */
+ }
+ element("Dt") {
+ /**
+ * FIXME: date, in YYYY-MM-DD format
+ */
+ }
+ }
+ element("Ntry") {
+ /* FIXME: one statement in an account history.
+ * NOTE: this element can appear from 0 to unbounded
number of times.
+ * */
+ element("Amt") {
+ /* FIXME: amount of this entry */
+ }
+ element("CdtDbtInd") {
+ /* FIXME: as above, whether the entry witnesses debit
or credit */
+ }
+ element("Sts") {
+ /* FIXME: status of the entry (see 2.4.2.15.5 from the
ISO20022 reference document.)
+ *
+ * From the original text:
+ * "Status of an entry on the books of the account
servicer"
+ */
+ }
+ element("BkTxCd") {
+ /* FIXME: Bank-transaction-code, see section
2.4.2.15.10.
+
+ * From the original text:
+ *
+ * "Set of elements used to fully identify the type of
underlying
+ * transaction resulting in an entry"
+ */
+ }
+ element("BookgDt") {
+ /**
+ * FIXME, Booking-date: when the entry was posted on
the books
+ * of the account servicer; do not necessarily implies
that assets
+ * become available. NOTE: this element is optional.
+ */
+ }
+ element("ValDt") {
+ /**
+ * FIXME, Value-date: when the asset corresponding to
one entry
+ * becomes available (or unavailable, in case of debit
type entry)
+ * to the account owner. NOTE: this element is
optional.
+ */
+ }
+ }
}
}
}
diff --git a/sandbox/src/test/kotlin/XmlCombinatorsTest.kt
b/sandbox/src/test/kotlin/XmlCombinatorsTest.kt
index f2b2148..f55dc70 100644
--- a/sandbox/src/test/kotlin/XmlCombinatorsTest.kt
+++ b/sandbox/src/test/kotlin/XmlCombinatorsTest.kt
@@ -20,10 +20,42 @@
package tech.libeufin.sandbox
import org.junit.Test
+import tech.libeufin.util.XmlElementBuilder
import tech.libeufin.util.constructXml
class XmlCombinatorsTest {
+ @Test
+ fun testWithModularity() {
+ fun module(base: XmlElementBuilder) {
+ base.element("module")
+ }
+ val s = constructXml {
+ root("root") {
+ module(this)
+ }
+ }
+ println(s)
+ }
+
+ @Test
+ fun testWithIterable() {
+ val s = constructXml(indent = true) {
+ namespace("iter", "able")
+ root("iterable") {
+ element("endOfDocument") {
+ for (i in 1..10)
+ element("$i") {
+ element("$i$i") {
+ text("$i$i$i")
+ }
+ }
+ }
+ }
+ }
+ println(s)
+ }
+
@Test
fun testBasicXmlBuilding() {
val s = constructXml(indent = true) {
diff --git a/util/src/main/kotlin/XmlCombinators.kt
b/util/src/main/kotlin/XmlCombinators.kt
index 1ef44e8..9a812d6 100644
--- a/util/src/main/kotlin/XmlCombinators.kt
+++ b/util/src/main/kotlin/XmlCombinators.kt
@@ -7,17 +7,18 @@ import javax.xml.stream.XMLStreamWriter
class XmlElementBuilder(val w: XMLStreamWriter) {
+ /**
+ * First consumes all the path's components, and _then_ starts applying f.
+ */
fun element(path: MutableList<String>, f: XmlElementBuilder.() -> Unit =
{}) {
-
+ /* the wanted path got constructed, go on with f's logic now. */
if (path.isEmpty()) {
- f(this)
+ f()
return
}
-
w.writeStartElement(path.removeAt(0))
this.element(path, f)
w.writeEndElement()
-
}
fun element(path: String, f: XmlElementBuilder.() -> Unit = {}) {
@@ -59,7 +60,7 @@ class XmlDocumentBuilder {
fun root(name: String, f: XmlElementBuilder.() -> Unit) {
val elementBuilder = XmlElementBuilder(writer)
writer.writeStartElement(name)
- f(elementBuilder)
+ elementBuilder.f()
writer.writeEndElement()
}
}
--
To stop receiving notification emails like this one, please contact
address@hidden.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [libeufin] branch master updated: Including more details into C52 and C53 responses.,
gnunet <=