diff options
-rwxr-xr-x | cli/bin/libeufin-cli | 1 | ||||
-rw-r--r-- | nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsNexus.kt | 10 | ||||
-rw-r--r-- | nexus/src/test/kotlin/EbicsTest.kt | 25 | ||||
-rw-r--r-- | nexus/src/test/kotlin/NexusApiTest.kt | 2 | ||||
-rw-r--r-- | nexus/src/test/kotlin/TalerTest.kt | 4 | ||||
-rw-r--r-- | sandbox/src/main/kotlin/tech/libeufin/sandbox/CircuitApi.kt | 5 | ||||
-rw-r--r-- | sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt | 53 | ||||
-rw-r--r-- | sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt | 12 | ||||
-rw-r--r-- | sandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt | 10 | ||||
-rw-r--r-- | util/src/main/kotlin/time.kt | 11 | ||||
-rw-r--r-- | util/src/test/kotlin/TimeTest.kt | 4 |
11 files changed, 59 insertions, 78 deletions
diff --git a/cli/bin/libeufin-cli b/cli/bin/libeufin-cli index 82dbe992..a1fe9b11 100755 --- a/cli/bin/libeufin-cli +++ b/cli/bin/libeufin-cli @@ -987,7 +987,6 @@ def fetch_transactions(obj, account_name, range_type, level, start, end): check_response_status(resp) tell_user(resp) - @accounts.command(help="Get transactions from the simplified nexus JSON API") @click.option( "--compact/--no-compact", 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 0f007d77..18e1bb08 100644 --- a/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsNexus.kt +++ b/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsNexus.kt @@ -697,11 +697,13 @@ class EbicsBankConnectionProtocol: BankConnectionProtocol { addForLevel(fetchSpec.level, p) } is FetchSpecAllJson -> { + val start = ZonedDateTime.ofInstant( + Instant.EPOCH, + ZoneOffset.UTC + ) + val end = ZonedDateTime.ofInstant(Instant.now(), ZoneOffset.systemDefault()) val p = EbicsStandardOrderParams( - EbicsDateRange( - ZonedDateTime.ofInstant(Instant.EPOCH, ZoneOffset.UTC), - ZonedDateTime.now(ZoneOffset.UTC) - ) + EbicsDateRange(start, end) ) addForLevel(fetchSpec.level, p) } diff --git a/nexus/src/test/kotlin/EbicsTest.kt b/nexus/src/test/kotlin/EbicsTest.kt index 19646d6a..e004070f 100644 --- a/nexus/src/test/kotlin/EbicsTest.kt +++ b/nexus/src/test/kotlin/EbicsTest.kt @@ -6,6 +6,7 @@ import io.ktor.server.response.* import io.ktor.server.routing.* import io.ktor.server.testing.* import kotlinx.coroutines.runBlocking +import org.jetbrains.exposed.sql.and import org.jetbrains.exposed.sql.transactions.transaction import org.junit.Test import org.w3c.dom.Document @@ -16,15 +17,15 @@ import tech.libeufin.nexus.bankaccount.submitAllPaymentInitiations import tech.libeufin.nexus.ebics.* import tech.libeufin.nexus.iso20022.NexusPaymentInitiationData import tech.libeufin.nexus.iso20022.createPain001document -import tech.libeufin.nexus.server.FetchLevel -import tech.libeufin.nexus.server.FetchSpecAllJson -import tech.libeufin.nexus.server.Pain001Data +import tech.libeufin.nexus.server.* import tech.libeufin.sandbox.* import tech.libeufin.util.* import tech.libeufin.util.ebics_h004.EbicsRequest import tech.libeufin.util.ebics_h004.EbicsResponse import tech.libeufin.util.ebics_h004.EbicsTypes import tech.libeufin.util.ebics_h005.Ebics3Request +import java.time.LocalDate +import java.time.ZonedDateTime /** * These test cases run EBICS CCT and C52, mixing ordinary operations @@ -104,13 +105,16 @@ class DownloadAndSubmit { "Exist in logging!", "TESTKUDOS:5" ) + testApplication { application(sandboxApp) runBlocking { fetchBankAccountTransactions( client, - fetchSpec = FetchSpecAllJson( + fetchSpec = FetchSpecTimeRangeJson( level = FetchLevel.REPORT, + start = "2020-10-10", + end = "3000-10-10", bankConnection = "foo" ), accountId = "foo" @@ -138,7 +142,7 @@ class DownloadAndSubmit { // Create Pain.001 to be submitted. addPaymentInitiation( Pain001Data( - creditorIban = getIban(), + creditorIban = BAR_USER_IBAN, creditorBic = "SANDBOXX", creditorName = "Tester", subject = "test payment", @@ -157,11 +161,12 @@ class DownloadAndSubmit { ) } transaction { - val payment = BankAccountTransactionEntity[1] - assert(payment.debtorIban == FOO_USER_IBAN && - payment.subject == "test payment" && - payment.direction == "DBIT" - ) + val howMany = BankAccountTransactionEntity.find { + BankAccountTransactionsTable.debtorIban eq FOO_USER_IBAN and ( + BankAccountTransactionsTable.subject eq "test payment" + ) and (BankAccountTransactionsTable.direction eq "DBIT") + }.count() + assert(howMany == 1L) } } } diff --git a/nexus/src/test/kotlin/NexusApiTest.kt b/nexus/src/test/kotlin/NexusApiTest.kt index 899f6dad..01ef9565 100644 --- a/nexus/src/test/kotlin/NexusApiTest.kt +++ b/nexus/src/test/kotlin/NexusApiTest.kt @@ -256,7 +256,7 @@ class NexusApiTest { fetchSpec = FetchSpecTimeRangeJson( FetchLevel.REPORT, start = "2019-10-31", - end = "2020-11-30", + end = "2019-11-30", bankConnection = null ), accountId = "foo", diff --git a/nexus/src/test/kotlin/TalerTest.kt b/nexus/src/test/kotlin/TalerTest.kt index cd8b1776..8c9a5edd 100644 --- a/nexus/src/test/kotlin/TalerTest.kt +++ b/nexus/src/test/kotlin/TalerTest.kt @@ -68,8 +68,10 @@ class TalerTest { */ fetchBankAccountTransactions( client, - fetchSpec = FetchSpecAllJson( + fetchSpec = FetchSpecTimeRangeJson( level = if (testedAccount == "bar") FetchLevel.STATEMENT else FetchLevel.REPORT, + start = "2020-01-01", + end = "3000-01-01", bankConnection = testedAccount ), accountId = testedAccount diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/CircuitApi.kt b/sandbox/src/main/kotlin/tech/libeufin/sandbox/CircuitApi.kt index ebd72d3c..4d8d36d9 100644 --- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/CircuitApi.kt +++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/CircuitApi.kt @@ -13,7 +13,6 @@ import tech.libeufin.util.* import java.io.File import java.io.InputStreamReader import java.math.BigDecimal -import java.math.RoundingMode import java.util.concurrent.TimeUnit import kotlin.text.toByteArray @@ -322,7 +321,7 @@ fun circuitApi(circuitRoute: Route) { amount = op.amountDebit ) op.status = CashoutOperationStatus.CONFIRMED - op.confirmationTime = getUTCnow().toInstant().toEpochMilli() + op.confirmationTime = getSystemTimeNow().toInstant().toEpochMilli() // TODO(signal this payment over LIBEUFIN_REGIO_INCOMING) } call.respond(HttpStatusCode.NoContent) @@ -538,7 +537,7 @@ fun circuitApi(circuitRoute: Route) { this.sellAtRatio = ratiosAndFees.sell_at_ratio.toString() this.sellOutFee = ratiosAndFees.sell_out_fee.toString() this.subject = cashoutSubject - this.creationTime = getUTCnow().toInstant().toEpochMilli() + this.creationTime = getSystemTimeNow().toInstant().toEpochMilli() this.tanChannel = SupportedTanChannels.valueOf(tanChannel) this.account = user this.tan = getRandomString(5) diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt b/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt index 48f5d8a4..1bd6aa5e 100644 --- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt +++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt @@ -30,7 +30,6 @@ import io.ktor.util.AttributeKey import io.ktor.util.date.* import org.apache.xml.security.binding.xmldsig.RSAKeyValueType import org.jetbrains.exposed.sql.* -import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.statements.api.ExposedBlob import org.jetbrains.exposed.sql.transactions.transaction import org.w3c.dom.Document @@ -297,7 +296,7 @@ fun buildCamtString( * - Proprietary code of the bank transaction * - Id of the servicer (Issuer and Code) */ - val camtCreationTime = getUTCnow() // FIXME: should this be the payment time? + val camtCreationTime = getSystemTimeNow() // FIXME: should this be the payment time? val dashedDate = camtCreationTime.toDashedDate() val zonedDateTime = camtCreationTime.toZonedString() val creationTimeMillis = camtCreationTime.toInstant().toEpochMilli() @@ -703,46 +702,15 @@ private fun handleCct( } if (maybeDebit(bankAccount.label, maybeAmount, bankAccount.demoBank.name)) throw EbicsAmountCheckError("The requested amount (${parseResult.amount}) would exceed the debit threshold") - - // Get the two parties. - BankAccountTransactionEntity.new { - account = bankAccount - demobank = bankAccount.demoBank - creditorIban = parseResult.creditorIban - creditorName = parseResult.creditorName - creditorBic = parseResult.creditorBic - debtorIban = parseResult.debtorIban - debtorName = parseResult.debtorName - debtorBic = parseResult.debtorBic - subject = parseResult.subject - amount = parseResult.amount - currency = parseResult.currency - date = getUTCnow().toInstant().toEpochMilli() - pmtInfId = parseResult.pmtInfId + logger.debug("Wire-transfer'ing endToEndId: ${parseResult.endToEndId}") + wireTransfer( + bankAccount.label, + getBankAccountFromIban(parseResult.creditorIban).label, + bankAccount.demoBank.name, + parseResult.subject, + "${parseResult.currency}:${parseResult.amount}", endToEndId = parseResult.endToEndId - accountServicerReference = "sandboxref-${getRandomString(16)}" - direction = "DBIT" - } - val maybeLocalCreditor = BankAccountEntity.find(BankAccountsTable.iban eq parseResult.creditorIban).firstOrNull() - if (maybeLocalCreditor != null) { - BankAccountTransactionEntity.new { - account = maybeLocalCreditor - demobank = maybeLocalCreditor.demoBank - creditorIban = parseResult.creditorIban - creditorName = parseResult.creditorName - creditorBic = parseResult.creditorBic - debtorIban = parseResult.debtorIban - debtorName = parseResult.debtorName - debtorBic = parseResult.debtorBic - subject = parseResult.subject - amount = parseResult.amount - currency = parseResult.currency - date = getUTCnow().toInstant().toEpochMilli() - pmtInfId = parseResult.pmtInfId - accountServicerReference = "sandboxref-${getRandomString(16)}" - direction = "CRDT" - } - } + ) } } @@ -755,8 +723,9 @@ private fun handleEbicsC52(requestContext: RequestContext): ByteArray { val dateRange: Pair<Long, Long>? = if (maybeDateRange is EbicsRequest.StandardOrderParams) { val start: Long? = maybeDateRange.dateRange?.start?.toGregorianCalendar()?.timeInMillis val end: Long? = maybeDateRange.dateRange?.end?.toGregorianCalendar()?.timeInMillis - Pair(start ?: 0L, end ?: getTimeMillis()) + Pair(start ?: 0L, end ?: Long.MAX_VALUE) } else null + logger.debug("Date range: $dateRange") val report = constructCamtResponse( 52, requestContext.subscriber, diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt index cd886e55..bcd11a49 100644 --- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt +++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt @@ -272,7 +272,7 @@ class Camt053Tick : CliktCommand( ) BankAccountStatementEntity.new { statementId = camtData.messageId - creationTime = getUTCnow().toInstant().epochSecond + creationTime = getSystemTimeNow().toInstant().epochSecond xmlMessage = camtData.camtMessage bankAccount = accountIter } @@ -843,7 +843,7 @@ val sandboxApp: Application.() -> Unit = { debtorName = body.debtorName subject = body.subject this.amount = amount.amount - date = getUTCnow().toInstant().toEpochMilli() + date = getSystemTimeNow().toInstant().toEpochMilli() accountServicerReference = "sandbox-$randId" this.account = account direction = "CRDT" @@ -966,7 +966,7 @@ val sandboxApp: Application.() -> Unit = { debtorName = "Max Mustermann" subject = "sample transaction $transactionReferenceCrdt" this.amount = amount.toString() - date = getUTCnow().toInstant().toEpochMilli() + date = getSystemTimeNow().toInstant().toEpochMilli() accountServicerReference = transactionReferenceCrdt this.account = account direction = "CRDT" @@ -987,7 +987,7 @@ val sandboxApp: Application.() -> Unit = { creditorName = "Max Mustermann" subject = "sample transaction $transactionReferenceDbit" this.amount = amount.toString() - date = getUTCnow().toInstant().toEpochMilli() + date = getSystemTimeNow().toInstant().toEpochMilli() accountServicerReference = transactionReferenceDbit this.account = account direction = "DBIT" @@ -1530,9 +1530,9 @@ val sandboxApp: Application.() -> Unit = { val size: Int = expectInt(call.request.queryParameters["size"] ?: "5") if (size < 1) throw badRequest("'size' param is less than 1") // Time range filter values - val fromMs = expectLong(call.request.queryParameters["from_ms"] ?: "0") + val fromMs: Long = expectLong(call.request.queryParameters["from_ms"] ?: "0") if (fromMs < 0) throw badRequest("'from_ms' param is less than 0") - val untilMs = expectLong(call.request.queryParameters["until_ms"] ?: Long.MAX_VALUE.toString()) + val untilMs: Long = expectLong(call.request.queryParameters["until_ms"] ?: Long.MAX_VALUE.toString()) if (untilMs < 0) throw badRequest("'until_ms' param is less than 0") val longPollMs: Long? = call.maybeLong("long_poll_ms") // LISTEN, if Postgres. diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt b/sandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt index 5adb1af0..d82a0eb4 100644 --- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt +++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt @@ -1,8 +1,6 @@ package tech.libeufin.sandbox import io.ktor.http.* -import org.jetbrains.exposed.sql.StdOutSqlLogger -import org.jetbrains.exposed.sql.addLogger import org.jetbrains.exposed.sql.and import org.jetbrains.exposed.sql.transactions.transaction import tech.libeufin.util.* @@ -140,9 +138,10 @@ fun wireTransfer( demobank: String = "default", subject: String, amount: String, // $currency:x.y - pmtInfId: String? = null + pmtInfId: String? = null, + endToEndId: String? = null ): String { - logger.debug("Maybe wire transfer: $debitAccount -> $creditAccount, $subject, $amount") + logger.debug("Maybe wire transfer (endToEndId: $endToEndId): $debitAccount -> $creditAccount, $subject, $amount") return transaction { val demobankDb = ensureDemobank(demobank) val debitAccountDb = getBankAccountFromLabel(debitAccount, demobankDb) @@ -167,7 +166,7 @@ fun wireTransfer( logger.error("Account ${debitAccountDb.label} would surpass debit threshold. Rollback wire transfer") throw SandboxError(HttpStatusCode.Conflict, "Insufficient funds") } - val timeStamp = getUTCnow().toInstant().toEpochMilli() + val timeStamp = getNowMillis() val transactionRef = getRandomString(8) BankAccountTransactionEntity.new { creditorIban = creditAccountDb.iban @@ -202,6 +201,7 @@ fun wireTransfer( direction = "DBIT" this.demobank = demobankDb this.pmtInfId = pmtInfId + this.endToEndId = endToEndId } // Adjusting the balances (acceptable debit conditions checked before). diff --git a/util/src/main/kotlin/time.kt b/util/src/main/kotlin/time.kt index 9507bbad..1dd37df9 100644 --- a/util/src/main/kotlin/time.kt +++ b/util/src/main/kotlin/time.kt @@ -22,16 +22,19 @@ package tech.libeufin.util import java.time.* import java.time.format.DateTimeFormatter -private var LIBEUFIN_CLOCK = Clock.system(ZoneOffset.UTC) +private var LIBEUFIN_CLOCK = Clock.system(ZoneId.systemDefault()) fun setClock(rel: Duration) { LIBEUFIN_CLOCK = Clock.offset(LIBEUFIN_CLOCK, rel) } fun getNow(): ZonedDateTime { - return ZonedDateTime.now(LIBEUFIN_CLOCK) + return ZonedDateTime.now(ZoneId.systemDefault()) } -fun getUTCnow(): ZonedDateTime { - return ZonedDateTime.now(ZoneOffset.UTC) +fun getNowMillis(): Long = getNow().toInstant().toEpochMilli() + +fun getSystemTimeNow(): ZonedDateTime { + // return ZonedDateTime.now(ZoneOffset.UTC) + return ZonedDateTime.now(ZoneId.systemDefault()) } fun ZonedDateTime.toZonedString(): String { diff --git a/util/src/test/kotlin/TimeTest.kt b/util/src/test/kotlin/TimeTest.kt index 057bc075..76243f33 100644 --- a/util/src/test/kotlin/TimeTest.kt +++ b/util/src/test/kotlin/TimeTest.kt @@ -1,6 +1,7 @@ import org.junit.Ignore import org.junit.Test import tech.libeufin.util.getNow +import tech.libeufin.util.millis import tech.libeufin.util.setClock import java.time.* import java.time.format.DateTimeFormatter @@ -58,7 +59,8 @@ class TimeTest { val dtf = DateTimeFormatter.ISO_LOCAL_DATE return LocalDate.parse(dashedDate, dtf) } - val ret = parse("1970-01-01") + val ret: LocalDate = parse("1970-01-01") println(ret.toString()) + ret.millis() // Just testing it doesn't raise Exception. } }
\ No newline at end of file |