commit e904129310ec75ed98bf1bfefbec73c1e5f29fc6
parent 785140724e8305d1e962d6140d10b2684bc464d3
Author: MS <ms@taler.net>
Date: Mon, 7 Dec 2020 17:07:03 +0100
Camt ingestion.
Flag messages that could not be understood by the parser.
Diffstat:
2 files changed, 13 insertions(+), 16 deletions(-)
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/DB.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/DB.kt
@@ -88,6 +88,7 @@ object NexusBankMessagesTable : IntIdTable() {
val messageId = text("messageId")
val code = text("code")
val message = blob("message")
+ val errors = bool("errors").default(false) // true when the parser could not ingest one message.
}
class NexusBankMessageEntity(id: EntityID<Int>) : IntEntity(id) {
@@ -97,6 +98,7 @@ class NexusBankMessageEntity(id: EntityID<Int>) : IntEntity(id) {
var messageId by NexusBankMessagesTable.messageId
var code by NexusBankMessagesTable.code
var message by NexusBankMessagesTable.message
+ var errors by NexusBankMessagesTable.errors
}
/**
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/bankaccount/BankAccount.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/bankaccount/BankAccount.kt
@@ -120,13 +120,9 @@ private fun findDuplicate(bankAccountId: String, acctSvcrRef: String): NexusBank
}
}
-fun processCamtMessage(
- bankAccountId: String,
- camtDoc: Document,
- code: String
-) {
+fun processCamtMessage(bankAccountId: String, camtDoc: Document, code: String): Boolean {
logger.info("processing CAMT message")
- transaction {
+ val success = transaction {
val acct = NexusBankAccountEntity.findById(bankAccountId)
if (acct == null) {
throw NexusError(HttpStatusCode.NotFound, "user not found")
@@ -134,10 +130,8 @@ fun processCamtMessage(
val res = try {
parseCamtMessage(camtDoc)
} catch (e: CamtParsingError) {
- throw NexusError(
- HttpStatusCode.BadGateway,
- "Invalid CAMT received from bank"
- )
+ logger.warn("Invalid CAMT received from bank")
+ return@transaction false
}
val stamp = ZonedDateTime.parse(res.creationDateTime, DateTimeFormatter.ISO_DATE_TIME).toInstant().toEpochMilli()
when (code) {
@@ -199,17 +193,16 @@ fun processCamtMessage(
// FIXME: find matching PaymentInitiation by PaymentInformationID, message ID or whatever is present
}
}
+ return@transaction true
}
+ return success
}
/**
* Create new transactions for an account based on bank messages it
* did not see before.
*/
-fun ingestBankMessagesIntoAccount(
- bankConnectionId: String,
- bankAccountId: String
-) {
+fun ingestBankMessagesIntoAccount(bankConnectionId: String, bankAccountId: String) {
transaction {
val conn = NexusBankConnectionEntity.findById(bankConnectionId)
if (conn == null) {
@@ -224,9 +217,11 @@ fun ingestBankMessagesIntoAccount(
(NexusBankMessagesTable.bankConnection eq conn.id) and
(NexusBankMessagesTable.id greater acct.highestSeenBankMessageId)
}.orderBy(Pair(NexusBankMessagesTable.id, SortOrder.ASC)).forEach {
- // FIXME: check if it's CAMT first!
val doc = XMLUtil.parseStringIntoDom(it.message.bytes.toString(Charsets.UTF_8))
- processCamtMessage(bankAccountId, doc, it.code)
+ if (!processCamtMessage(bankAccountId, doc, it.code)) {
+ it.errors = true
+ return@forEach
+ }
lastId = it.id.value
}
acct.highestSeenBankMessageId = lastId