Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add cbr source + impl getConvertedAmount method + refactoring #12

Merged
merged 9 commits into from
Jun 5, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ on:

jobs:
build:
uses: valitydev/base-workflow/.github/workflows/maven-service-build.yml@v2
uses: valitydev/java-workflow/.github/workflows/maven-service-build.yml@v2
2 changes: 1 addition & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:

jobs:
build-and-deploy:
uses: valitydev/base-workflow/.github/workflows/maven-service-deploy.yml@v2
uses: valitydev/java-workflow/.github/workflows/maven-service-deploy.yml@v2
secrets:
github-token: ${{ secrets.GITHUB_TOKEN }}
mm-webhook-url: ${{ secrets.MATTERMOST_WEBHOOK_URL }}
22 changes: 21 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
<dependency>
<groupId>dev.vality</groupId>
<artifactId>exrates-proto</artifactId>
<version>1.7-ce9563e</version>
<version>1.8-9794d14</version>
</dependency>
<dependency>
<groupId>dev.vality</groupId>
Expand Down Expand Up @@ -124,6 +124,26 @@
<groupId>software.amazon.msk</groupId>
<artifactId>aws-msk-iam-auth</artifactId>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.3.0.1</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.6</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>3.6.1</version>
</dependency>

<!--Test/Dev-->
<dependency>
Expand Down
40 changes: 40 additions & 0 deletions src/main/kotlin/dev/vality/rateboss/client/cbr/CbrApiClient.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package dev.vality.rateboss.client.cbr

import dev.vality.rateboss.client.cbr.model.CbrExchangeRateData
import dev.vality.rateboss.config.properties.RatesProperties
import org.springframework.http.HttpEntity
import org.springframework.http.HttpMethod
import org.springframework.stereotype.Component
import org.springframework.web.client.RestTemplate
import org.springframework.web.client.exchange
import org.springframework.web.util.UriComponentsBuilder
import java.time.Instant
import java.time.LocalDate
import java.time.format.DateTimeFormatter

@Component
class CbrApiClient(
private val restTemplate: RestTemplate,
private val ratesProperties: RatesProperties
) {

fun getExchangeRates(time: Instant): CbrExchangeRateData {
val baseUrl = ratesProperties.source.cbr.rootUrl
val timezone = ratesProperties.source.cbr.timeZone
val date = time.atZone(timezone).toLocalDate()
val url = buildUrl(baseUrl, date)
return restTemplate.exchange<CbrExchangeRateData>(url, HttpMethod.GET, HttpEntity(null, null)).body!!
}

private fun buildUrl(endpoint: String, date: LocalDate): String {
return UriComponentsBuilder
.fromUriString(endpoint)
.queryParam("date_req", date.format(DATE_TIME_FORMATTER))
.build()
.toUriString()
}

companion object {
val DATE_TIME_FORMATTER: DateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package dev.vality.rateboss.client.cbr.adapter

import java.math.BigDecimal
import java.util.*
import javax.xml.bind.annotation.adapters.XmlAdapter

class CbrBigDecimalXmlAdapter : XmlAdapter<String, BigDecimal>() {

override fun unmarshal(stringValue: String): BigDecimal {
return Optional.ofNullable(stringValue)
ggmaleva marked this conversation as resolved.
Show resolved Hide resolved
.map { value: String ->
BigDecimal(
value.replace(',', '.')
)
}
.orElse(null)
}

override fun marshal(bigDecimalValue: BigDecimal): String {
return Optional.ofNullable(bigDecimalValue)
.map { value: BigDecimal ->
value.toString().replace('.', ',')
}
.orElse(null)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package dev.vality.rateboss.client.cbr.adapter

import java.time.LocalDate
import java.time.format.DateTimeFormatter
import java.util.*
import javax.xml.bind.annotation.adapters.XmlAdapter

class CbrLocalDateXmlAdapter : XmlAdapter<String, LocalDate>() {

override fun unmarshal(stringValue: String): LocalDate {
return Optional.ofNullable(stringValue)
.map { value: String? ->
LocalDate.from(
DATE_FORMATTER.parse(value)
)
}
.orElse(null)
}

override fun marshal(dateValue: LocalDate): String {
return Optional.ofNullable(dateValue)
.map { value: LocalDate? ->
DATE_FORMATTER.format(
value
)
}
.orElse(null)
}

companion object {
val DATE_FORMATTER: DateTimeFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package dev.vality.rateboss.client.cbr.model

import dev.vality.rateboss.client.cbr.adapter.CbrBigDecimalXmlAdapter
import java.math.BigDecimal
import javax.xml.bind.annotation.*
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter

@XmlRootElement(name = "Valute")
@XmlAccessorType(XmlAccessType.FIELD)
class CbrCurrencyData {

@XmlAttribute(name = "ID")
var id: String? = null

@XmlElement(name = "NumCode")
var numCode: Int? = null

@XmlElement(name = "CharCode")
var charCode: String? = null

@XmlElement(name = "Nominal")
var nominal: Int? = null

@XmlElement(name = "Name")
var name: String? = null

@XmlJavaTypeAdapter(CbrBigDecimalXmlAdapter::class)
@XmlElement(name = "Value")
var value: BigDecimal? = null
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package dev.vality.rateboss.client.cbr.model

import dev.vality.rateboss.client.cbr.adapter.CbrLocalDateXmlAdapter
import java.time.LocalDate
import javax.xml.bind.annotation.*
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter

@XmlRootElement(name = "ValCurs")
@XmlAccessorType(XmlAccessType.FIELD)
class CbrExchangeRateData {

@XmlAttribute
var name: String? = null

@XmlAttribute(name = "Date")
@XmlJavaTypeAdapter(CbrLocalDateXmlAdapter::class)
var date: LocalDate? = null

@XmlElement(name = "Valute")
var currencies: List<CbrCurrencyData>? = null
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package dev.vality.rateboss.client
package dev.vality.rateboss.client.fixer

import dev.vality.rateboss.client.model.FixerLatestResponse
import dev.vality.rateboss.client.fixer.model.FixerLatestResponse
import dev.vality.rateboss.config.properties.RatesProperties
import org.springframework.http.HttpEntity
import org.springframework.http.HttpHeaders
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package dev.vality.rateboss.client.model
package dev.vality.rateboss.client.fixer.model

import java.math.BigDecimal
import java.time.LocalDate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package dev.vality.rateboss.config.properties
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.context.properties.ConstructorBinding
import org.springframework.validation.annotation.Validated
import java.time.ZoneId

@Validated
@ConstructorBinding
Expand All @@ -21,10 +22,16 @@ data class CurrencyProperties(
)

data class RatesSourceProperties(
val fixer: FixerProperties
val fixer: FixerProperties,
val cbr: CbrProperties
)

data class FixerProperties(
val rootUrl: String,
val apiKey: String
)

data class CbrProperties(
val rootUrl: String,
val timeZone: ZoneId
)
14 changes: 9 additions & 5 deletions src/main/kotlin/dev/vality/rateboss/converter/ExRateConverter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import org.springframework.stereotype.Component
import java.math.BigDecimal
import java.time.LocalDateTime
import java.time.ZoneOffset
import java.util.*

@Component
class ExRateConverter {
Expand All @@ -14,17 +15,20 @@ class ExRateConverter {
baseCurrencySymbolCode: String,
baseCurrencyExponent: Short,
exchangeRateMap: Map.Entry<String, BigDecimal>,
ggmaleva marked this conversation as resolved.
Show resolved Hide resolved
exchangeRateTimestamp: Long
exchangeRateTimestamp: Long,
sourceId: String
): ExRate {
val sourceCurrency = Currency.getInstance(exchangeRateMap.key)
return ExRate().apply {
sourceCurrencySymbolicCode = baseCurrencySymbolCode
sourceCurrencyExponent = baseCurrencyExponent
destinationCurrencySymbolicCode = exchangeRateMap.key
destinationCurrencyExponent = exchangeRateMap.value.scale().toShort()
destinationCurrencySymbolicCode = baseCurrencySymbolCode
destinationCurrencyExponent = baseCurrencyExponent
sourceCurrencySymbolicCode = sourceCurrency.currencyCode
sourceCurrencyExponent = sourceCurrency.defaultFractionDigits.toShort()
val rational = exchangeRateMap.value.toRational()
rationalP = rational.numerator
rationalQ = rational.denominator
rateTimestamp = LocalDateTime.ofEpochSecond(exchangeRateTimestamp, 0, ZoneOffset.UTC)
source = sourceId
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import dev.vality.exrates.base.Rational
import dev.vality.exrates.service.CurrencyData
import dev.vality.exrates.service.GetCurrencyExchangeRateResult
import dev.vality.rateboss.converter.Constants.Companion.DATE_TIME_FORMAT
import dev.vality.rateboss.source.model.ExchangeRateData
import dev.vality.rateboss.service.model.ExchangeRateData
import org.springframework.stereotype.Component
import java.time.format.DateTimeFormatter

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package dev.vality.rateboss.converter

import dev.vality.exrates.service.ConversionRequest
import dev.vality.rateboss.converter.Constants.Companion.DATE_TIME_FORMAT
import dev.vality.rateboss.service.model.TimestampExchangeRateRequest
import org.springframework.stereotype.Component
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter

@Component
class TimestampExchangeRateRequestConverter {

fun convert(
conversionRequest: ConversionRequest,
sourceId: String
): TimestampExchangeRateRequest {
return TimestampExchangeRateRequest(
sourceCurrency = conversionRequest.source,
destinationCurrency = conversionRequest.destination,
source = sourceId,
rateTimestamp = LocalDateTime.parse(
conversionRequest.datetime,
DateTimeFormatter.ofPattern(DATE_TIME_FORMAT)
)
)
}
}
5 changes: 4 additions & 1 deletion src/main/kotlin/dev/vality/rateboss/dao/ExRateDao.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package dev.vality.rateboss.dao

import dev.vality.rateboss.dao.domain.tables.pojos.ExRate
import dev.vality.rateboss.service.model.TimestampExchangeRateRequest

interface ExRateDao {

fun saveBatch(entities: List<ExRate>)

fun getBySymbolicCodes(sourceCode: String, destinationCode: String): ExRate?
fun getRecentBySymbolicCodes(sourceCode: String, destinationCode: String): ExRate?

fun getByCodesAndTimestamp(request: TimestampExchangeRateRequest): ExRate?
}
Loading
Loading