[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libeufin] branch master updated: allow timezones, use ISO time stamp fo
From: |
gnunet |
Subject: |
[libeufin] branch master updated: allow timezones, use ISO time stamp for last fetch date |
Date: |
Fri, 19 Jun 2020 14:25:43 +0200 |
This is an automated email from the git hooks/post-receive script.
dold pushed a commit to branch master
in repository libeufin.
The following commit(s) were added to refs/heads/master by this push:
new be4ffcb allow timezones, use ISO time stamp for last fetch date
be4ffcb is described below
commit be4ffcbcc55d656fbbf983de10d4e483949b127d
Author: Florian Dold <florian.dold@gmail.com>
AuthorDate: Fri Jun 19 17:55:35 2020 +0530
allow timezones, use ISO time stamp for last fetch date
---
nexus/src/main/kotlin/tech/libeufin/nexus/DB.kt | 14 +++-
.../tech/libeufin/nexus/bankaccount/BankAccount.kt | 9 ++-
.../kotlin/tech/libeufin/nexus/ebics/EbicsNexus.kt | 91 +++++++++++++++++-----
.../main/kotlin/tech/libeufin/nexus/server/JSON.kt | 22 +++++-
nexus/src/test/kotlin/authentication.kt | 1 +
util/src/main/kotlin/Ebics.kt | 14 +++-
util/src/main/kotlin/time.kt | 4 +-
7 files changed, 120 insertions(+), 35 deletions(-)
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/DB.kt
b/nexus/src/main/kotlin/tech/libeufin/nexus/DB.kt
index abc7375..361186e 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/DB.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/DB.kt
@@ -220,9 +220,14 @@ object NexusBankAccountsTable : IdTable<String>() {
val bankCode = text("bankCode")
val defaultBankConnection = reference("defaultBankConnection",
NexusBankConnectionsTable).nullable()
- val lastStatementCreationTimestamp =
long("lastStatementCreationTimestamp").nullable()
- val lastReportCreationTimestamp =
long("lastReportCreationTimestamp").nullable()
- val lastNotificationCreationTimestamp =
long("lastNotificationCreationTimestamp").nullable()
+ // ISO-8601 zoned date time
+ val lastStatementCreationTimestamp =
text("lastStatementCreationTimestamp").nullable()
+
+ // ISO-8601 zoned date time
+ val lastReportCreationTimestamp =
text("lastReportCreationTimestamp").nullable()
+
+ // ISO-8601 zoned date time
+ val lastNotificationCreationTimestamp =
text("lastNotificationCreationTimestamp").nullable()
// Highest bank message ID that this bank account is aware of.
val highestSeenBankMessageId = integer("highestSeenBankMessageId")
@@ -239,6 +244,9 @@ class NexusBankAccountEntity(id: EntityID<String>) :
Entity<String>(id) {
var defaultBankConnection by NexusBankConnectionEntity
optionalReferencedOn NexusBankAccountsTable.defaultBankConnection
var highestSeenBankMessageId by
NexusBankAccountsTable.highestSeenBankMessageId
var pain001Counter by NexusBankAccountsTable.pain001Counter
+ var lastStatementCreationTimestamp by
NexusBankAccountsTable.lastStatementCreationTimestamp
+ var lastReportCreationTimestamp by
NexusBankAccountsTable.lastReportCreationTimestamp
+ var lastNotificationCreationTimestamp by
NexusBankAccountsTable.lastNotificationCreationTimestamp
}
object EbicsSubscribersTable : IntIdTable() {
diff --git
a/nexus/src/main/kotlin/tech/libeufin/nexus/bankaccount/BankAccount.kt
b/nexus/src/main/kotlin/tech/libeufin/nexus/bankaccount/BankAccount.kt
index 396a45f..76d2524 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/bankaccount/BankAccount.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/bankaccount/BankAccount.kt
@@ -236,10 +236,10 @@ fun addPaymentInitiation(paymentData: Pain001Data,
debitorAccount: NexusBankAcco
suspend fun fetchBankAccountTransactions(
client: HttpClient,
fetchSpec: FetchSpecJson,
- accountid: String
+ accountId: String
) {
val res = transaction {
- val acct = NexusBankAccountEntity.findById(accountid)
+ val acct = NexusBankAccountEntity.findById(accountId)
if (acct == null) {
throw NexusError(
HttpStatusCode.NotFound,
@@ -263,7 +263,8 @@ suspend fun fetchBankAccountTransactions(
fetchEbicsBySpec(
fetchSpec,
client,
- res.connectionName
+ res.connectionName,
+ accountId
)
}
else -> throw NexusError(
@@ -271,6 +272,6 @@ suspend fun fetchBankAccountTransactions(
"Connection type '${res.connectionType}' not implemented"
)
}
- ingestBankMessagesIntoAccount(res.connectionName, accountid)
+ ingestBankMessagesIntoAccount(res.connectionName, accountId)
ingestTalerTransactions()
}
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsNexus.kt
b/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsNexus.kt
index 022aa64..9aa161f 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsNexus.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsNexus.kt
@@ -51,8 +51,10 @@ import tech.libeufin.util.ebics_h004.HTDResponseOrderData
import java.io.ByteArrayOutputStream
import java.security.interfaces.RSAPrivateCrtKey
import java.security.interfaces.RSAPublicKey
-import java.time.LocalDate
+import java.time.Instant
import java.time.LocalDateTime
+import java.time.ZoneOffset
+import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter
import java.util.*
import javax.crypto.EncryptedPrivateKeyInfo
@@ -63,37 +65,88 @@ private data class EbicsFetchSpec(
val orderParams: EbicsOrderParams
)
-suspend fun fetchEbicsBySpec(fetchSpec: FetchSpecJson, client: HttpClient,
bankConnectionId: String) {
+suspend fun fetchEbicsBySpec(
+ fetchSpec: FetchSpecJson,
+ client: HttpClient,
+ bankConnectionId: String,
+ accountId: String
+) {
val subscriberDetails = transaction {
getEbicsSubscriberDetails(bankConnectionId) }
+ val lastTimes = transaction {
+ val acct = NexusBankAccountEntity.findById(accountId)
+ if (acct == null) {
+ throw NexusError(
+ HttpStatusCode.NotFound,
+ "Account not found"
+ )
+ }
+ object {
+ val lastStatement = acct.lastStatementCreationTimestamp?.let {
+ ZonedDateTime.parse(it, DateTimeFormatter.ISO_DATE_TIME)
+ }
+ val lastReport = acct.lastReportCreationTimestamp?.let {
+ ZonedDateTime.parse(it, DateTimeFormatter.ISO_DATE_TIME)
+ }
+ }
+ }
val specs = mutableListOf<EbicsFetchSpec>()
+
+ fun addForLevel(l: FetchLevel, p: EbicsOrderParams) {
+ when (fetchSpec.level) {
+ FetchLevel.ALL -> {
+ specs.add(EbicsFetchSpec("C52", p))
+ specs.add(EbicsFetchSpec("C53", p))
+ }
+ FetchLevel.REPORT -> {
+ specs.add(EbicsFetchSpec("C52", p))
+ }
+ FetchLevel.STATEMENT -> {
+ specs.add(EbicsFetchSpec("C53", p))
+ }
+ }
+ }
+
when (fetchSpec) {
is FetchSpecLatestJson -> {
val p = EbicsStandardOrderParams()
- when (fetchSpec.level) {
- FetchLevel.ALL -> {
- specs.add(EbicsFetchSpec("C52", p))
- specs.add(EbicsFetchSpec("C53", p))
- }
- FetchLevel.REPORT -> {
- specs.add(EbicsFetchSpec("C52", p))
- }
- FetchLevel.STATEMENT -> {
- specs.add(EbicsFetchSpec("C53", p))
- }
- }
+ addForLevel(fetchSpec.level, p)
}
is FetchSpecAllJson -> {
- val p = EbicsStandardOrderParams(EbicsDateRange(LocalDate.EPOCH,
LocalDate.now()))
+ val p = EbicsStandardOrderParams(
+ EbicsDateRange(
+ ZonedDateTime.ofInstant(Instant.EPOCH, ZoneOffset.UTC),
+ ZonedDateTime.now(ZoneOffset.UTC)
+ )
+ )
+ addForLevel(fetchSpec.level, p)
+ }
+ is FetchSpecSinceLastJson -> {
+ val pRep = EbicsStandardOrderParams(
+ EbicsDateRange(
+ lastTimes.lastReport ?: ZonedDateTime.ofInstant(
+ Instant.EPOCH,
+ ZoneOffset.UTC
+ ), ZonedDateTime.now(ZoneOffset.UTC)
+ )
+ )
+ val pStmt = EbicsStandardOrderParams(
+ EbicsDateRange(
+ lastTimes.lastStatement ?: ZonedDateTime.ofInstant(
+ Instant.EPOCH,
+ ZoneOffset.UTC
+ ), ZonedDateTime.now(ZoneOffset.UTC)
+ )
+ )
when (fetchSpec.level) {
FetchLevel.ALL -> {
- specs.add(EbicsFetchSpec("C52", p))
- specs.add(EbicsFetchSpec("C53", p))
+ specs.add(EbicsFetchSpec("C52", pRep))
+ specs.add(EbicsFetchSpec("C53", pStmt))
}
FetchLevel.REPORT -> {
- specs.add(EbicsFetchSpec("C52", p))
+ specs.add(EbicsFetchSpec("C52", pRep))
}
FetchLevel.STATEMENT -> {
- specs.add(EbicsFetchSpec("C53", p))
+ specs.add(EbicsFetchSpec("C53", pStmt))
}
}
}
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/server/JSON.kt
b/nexus/src/main/kotlin/tech/libeufin/nexus/server/JSON.kt
index 6a8dd8a..d7318ba 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/server/JSON.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/server/JSON.kt
@@ -26,7 +26,14 @@ import com.fasterxml.jackson.annotation.JsonValue
import com.fasterxml.jackson.databind.JsonNode
import tech.libeufin.nexus.BankTransaction
import tech.libeufin.util.*
-import java.time.LocalDate
+import java.time.Instant
+import java.time.ZoneId
+import java.time.ZoneOffset
+import java.time.ZonedDateTime
+import java.time.format.DateTimeFormatter
+import java.time.format.DateTimeFormatterBuilder
+import java.time.temporal.ChronoField
+
data class BackupRequestJson(
val passphrase: String
@@ -62,6 +69,15 @@ class EbicsStandardOrderParamsEmptyJson :
EbicsOrderParamsJson() {
}
}
+object EbicsDateFormat {
+ var fmt = DateTimeFormatterBuilder()
+ .append(DateTimeFormatter.ISO_DATE)
+ .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
+ .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
+ .parseDefaulting(ChronoField.OFFSET_SECONDS,
ZoneId.systemDefault().rules.getOffset(Instant.now()).totalSeconds.toLong())
+ .toFormatter()
+}
+
@JsonTypeName("standard-date-range")
class EbicsStandardOrderParamsDateJson(
val start: String,
@@ -70,8 +86,8 @@ class EbicsStandardOrderParamsDateJson(
override fun toOrderParams(): EbicsOrderParams {
val dateRange: EbicsDateRange? =
EbicsDateRange(
- LocalDate.parse(this.start),
- LocalDate.parse(this.end)
+ ZonedDateTime.parse(this.start, EbicsDateFormat.fmt),
+ ZonedDateTime.parse(this.end, EbicsDateFormat.fmt)
)
return EbicsStandardOrderParams(dateRange)
}
diff --git a/nexus/src/test/kotlin/authentication.kt
b/nexus/src/test/kotlin/authentication.kt
index bcf3499..e0a0d75 100644
--- a/nexus/src/test/kotlin/authentication.kt
+++ b/nexus/src/test/kotlin/authentication.kt
@@ -2,6 +2,7 @@ package tech.libeufin.nexus
import org.junit.Test
import junit.framework.TestCase.assertEquals
+import tech.libeufin.nexus.server.extractUserAndPassword
class AuthenticationTest {
@Test
diff --git a/util/src/main/kotlin/Ebics.kt b/util/src/main/kotlin/Ebics.kt
index 077a47d..1c7e167 100644
--- a/util/src/main/kotlin/Ebics.kt
+++ b/util/src/main/kotlin/Ebics.kt
@@ -33,14 +33,15 @@ import java.math.BigInteger
import java.security.SecureRandom
import java.security.interfaces.RSAPrivateCrtKey
import java.security.interfaces.RSAPublicKey
-import java.time.LocalDate
+import java.time.ZonedDateTime
import java.util.*
import java.util.zip.DeflaterInputStream
import javax.xml.datatype.DatatypeFactory
+import javax.xml.datatype.XMLGregorianCalendar
data class EbicsProtocolError(val statusCode: HttpStatusCode, val reason:
String) : Exception(reason)
-data class EbicsDateRange(val start: LocalDate, val end: LocalDate)
+data class EbicsDateRange(val start: ZonedDateTime, val end: ZonedDateTime)
sealed class EbicsOrderParams
@@ -86,6 +87,11 @@ private fun getNonce(size: Int): ByteArray {
return ret
}
+private fun getXmlDate(d: ZonedDateTime): XMLGregorianCalendar {
+ return DatatypeFactory.newInstance()
+ .newXMLGregorianCalendar(d.year, d.monthValue, d.dayOfMonth, 0, 0, 0,
0, d.offset.totalSeconds / 60)
+}
+
private fun makeOrderParams(orderParams: EbicsOrderParams):
EbicsRequest.OrderParams {
return when (orderParams) {
is EbicsStandardOrderParams -> {
@@ -93,8 +99,8 @@ private fun makeOrderParams(orderParams: EbicsOrderParams):
EbicsRequest.OrderPa
val r = orderParams.dateRange
if (r != null) {
this.dateRange = EbicsRequest.DateRange().apply {
- this.start =
DatatypeFactory.newInstance().newXMLGregorianCalendar(r.start.toString())
- this.end =
DatatypeFactory.newInstance().newXMLGregorianCalendar(r.end.toString())
+ this.start = getXmlDate(r.start)
+ this.end = getXmlDate(r.end)
}
}
}
diff --git a/util/src/main/kotlin/time.kt b/util/src/main/kotlin/time.kt
index 6d6e378..4bd2f55 100644
--- a/util/src/main/kotlin/time.kt
+++ b/util/src/main/kotlin/time.kt
@@ -27,11 +27,11 @@ fun LocalDateTime.toZonedString(): String {
}
fun LocalDateTime.toDashedDate(): String {
- return DateTimeFormatter.ISO_DATE.format(this)
+ return DateTimeFormatter.ISO_OFFSET_DATE.format(this)
}
fun parseDashedDate(date: String): LocalDateTime {
- val dtf = DateTimeFormatter.ISO_DATE
+ val dtf = DateTimeFormatter.ISO_OFFSET_DATE
val asDate = LocalDate.parse(date, dtf)
return asDate.atStartOfDay()
}
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [libeufin] branch master updated: allow timezones, use ISO time stamp for last fetch date,
gnunet <=