Skip to content

Commit a74e0ec

Browse files
authored
Merge pull request #45 from saltanovas/feature/update-ktor
Update Ktor to 2.2.4
2 parents ab9b136 + 6b72dfd commit a74e0ec

File tree

11 files changed

+99
-125
lines changed

11 files changed

+99
-125
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ JVM client implementing [kevin. platform API v0.3](https://api-reference.kevin.e
1010
## Prerequisites
1111

1212
- Java 8+
13+
- Ktor 2.x
1314

1415
## Installation
1516

@@ -20,13 +21,13 @@ Package and installation instructions are available at the [Maven Central Reposi
2021
<dependency>
2122
<groupId>eu.kevin</groupId>
2223
<artifactId>kevin-jvm</artifactId>
23-
<version>0.3.0</version>
24+
<version>1.0.0</version>
2425
</dependency>
2526
```
2627

2728
### Gradle
2829
```
29-
implementation 'eu.kevin:kevin-jvm:0.3.0'
30+
implementation 'eu.kevin:kevin-jvm:1.0.0'
3031
```
3132

3233
## Usage Examples

build.gradle.kts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ plugins {
1111
}
1212

1313
group = "eu.kevin"
14-
version = "0.3.0"
14+
version = "1.0.0"
1515

1616
repositories {
1717
mavenCentral()
@@ -22,6 +22,8 @@ dependencies {
2222
implementation("io.ktor:ktor-client-core:${Versions.KTOR}")
2323
implementation("io.ktor:ktor-client-cio:${Versions.KTOR}")
2424
implementation("io.ktor:ktor-client-serialization:${Versions.KTOR}")
25+
implementation("io.ktor:ktor-client-content-negotiation:${Versions.KTOR}")
26+
implementation("io.ktor:ktor-serialization-kotlinx-json:${Versions.KTOR}")
2527
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.6.4")
2628

2729
testImplementation(kotlin("test"))
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
object Versions {
22
const val KOTLIN = "1.6.10"
3-
const val KTOR = "1.6.5"
3+
const val KTOR = "2.2.4"
44
const val KTLINT = "10.2.0"
55
const val NEXUS_PUBLISH = "1.1.0"
6-
}
6+
}

src/main/kotlin/eu/kevin/api/Dependencies.kt

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ import eu.kevin.api.serializers.LocalDateSerializer
66
import eu.kevin.api.serializers.LocalDateTimeSerializer
77
import io.ktor.client.*
88
import io.ktor.client.engine.cio.*
9-
import io.ktor.client.features.*
10-
import io.ktor.client.features.json.*
11-
import io.ktor.client.features.json.serializer.*
9+
import io.ktor.client.plugins.*
10+
import io.ktor.client.plugins.contentnegotiation.*
1211
import io.ktor.client.request.*
1312
import io.ktor.client.statement.*
1413
import io.ktor.http.*
14+
import io.ktor.serialization.kotlinx.json.*
1515
import kotlinx.serialization.decodeFromString
1616
import kotlinx.serialization.json.Json
1717
import kotlinx.serialization.modules.SerializersModule
@@ -22,21 +22,22 @@ import java.time.LocalDateTime
2222
object Dependencies {
2323
val httpClient by lazy {
2424
HttpClient(CIO) {
25-
install(JsonFeature) {
26-
serializer = KotlinxSerializer(Dependencies.serializer)
25+
install(ContentNegotiation) {
26+
json(serializer)
27+
expectSuccess = true
2728
}
2829
defaultRequest {
2930
header(HttpHeaders.ContentType, ContentType.Application.Json)
3031
}
3132
HttpResponseValidator {
32-
handleResponseException { exception ->
33+
handleResponseExceptionWithRequest { exception, _ ->
3334
when (exception) {
3435
is ResponseException -> {
3536
val status = exception.response.status
3637
throw KevinApiErrorException(
3738
responseStatusCode = status.value,
3839
responseBody = if (status == HttpStatusCode.BadRequest)
39-
serializer.decodeFromString(exception.response.readText())
40+
serializer.decodeFromString(exception.response.bodyAsText())
4041
else null,
4142
externalMessage = exception.message
4243
)

src/main/kotlin/eu/kevin/api/extensions/UrlExtensions.kt

Lines changed: 0 additions & 9 deletions
This file was deleted.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
package eu.kevin.api.models.payment.paymentStatus
22

3-
data class GetPaymentStatusRequest @JvmOverloads constructor(
3+
data class GetPaymentStatusRequest(
44
val paymentId: String
55
)

src/main/kotlin/eu/kevin/api/services/Client.kt

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,21 @@ import eu.kevin.api.services.auth.AuthClient
88
import eu.kevin.api.services.general.GeneralClient
99
import eu.kevin.api.services.payment.PaymentClient
1010
import io.ktor.client.*
11-
import io.ktor.client.features.*
11+
import io.ktor.client.plugins.*
1212
import io.ktor.client.request.*
1313
import io.ktor.http.*
14-
import kotlinx.serialization.json.Json
1514
import java.net.URI
1615

1716
class Client internal constructor(
1817
private val authorization: Authorization,
1918
private val apiUrl: String,
2019
private val httpClient: HttpClient,
21-
private val serializer: Json,
2220
private val customHeaders: Map<String, String>
2321
) {
2422
val paymentClient by lazy { PaymentClient(httpClient = httpClient.withAuthorization()) }
2523
val authClient by lazy { AuthClient(httpClient = httpClient.withAuthorization()) }
2624
val generalClient by lazy { GeneralClient(httpClient = httpClient.withAuthorization()) }
27-
val accountClient by lazy { AccountClient(httpClient = httpClient.withAuthorization(), serializer = serializer) }
25+
val accountClient by lazy { AccountClient(httpClient = httpClient.withAuthorization()) }
2826

2927
constructor(
3028
authorization: Authorization,
@@ -34,7 +32,6 @@ class Client internal constructor(
3432
authorization = authorization,
3533
apiUrl = apiUrl,
3634
httpClient = Dependencies.httpClient,
37-
serializer = Dependencies.serializer,
3835
customHeaders = customHeaders
3936
)
4037

src/main/kotlin/eu/kevin/api/services/account/AccountClient.kt

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,28 +14,26 @@ import eu.kevin.api.models.account.list.AccountResponse
1414
import eu.kevin.api.models.account.transaction.request.GetAccountTransactionsRequest
1515
import eu.kevin.api.models.account.transaction.response.AccountTransactionResponse
1616
import io.ktor.client.*
17+
import io.ktor.client.call.*
1718
import io.ktor.client.request.*
18-
import kotlinx.serialization.json.Json
1919
import java.util.concurrent.CompletableFuture
2020

2121
/**
2222
* Implements API Methods of the [Account information service](https://api-reference.kevin.eu/public/platform/v0.3#tag/Account-Information-Service)
2323
*/
2424
class AccountClient internal constructor(
25-
private val httpClient: HttpClient,
26-
private val serializer: Json
25+
private val httpClient: HttpClient
2726
) {
2827

2928
/**
3029
* API Method: [Get accounts list](https://api-reference.kevin.eu/public/platform/v0.3#tag/Account-Information-Service/operation/getAccounts)
3130
*/
3231
@Throws(KevinApiErrorException::class)
3332
suspend fun getAccountsList(request: AccountRequestHeaders): List<AccountResponse> =
34-
httpClient.get<ResponseArray<AccountResponse>>(
35-
path = Endpoint.Paths.Account.getAccountsList()
36-
) {
33+
httpClient.get {
34+
url(path = Endpoint.Paths.Account.getAccountsList())
3735
appendAccountRequestHeaders(headers = request)
38-
}.data
36+
}.body<ResponseArray<AccountResponse>>().data
3937

4038
/**
4139
* Equivalent of suspending `getAccountsList(request: AccountRequestHeaders)` for Java interoperability
@@ -50,11 +48,10 @@ class AccountClient internal constructor(
5048
*/
5149
@Throws(KevinApiErrorException::class)
5250
suspend fun getAccountDetails(request: GetAccountDetailsRequest): AccountDetailsResponse =
53-
httpClient.get(
54-
path = Endpoint.Paths.Account.getAccountDetails(accountId = request.accountId)
55-
) {
51+
httpClient.get {
52+
url(path = Endpoint.Paths.Account.getAccountDetails(accountId = request.accountId))
5653
appendAccountRequestHeaders(headers = request.headers)
57-
}
54+
}.body()
5855

5956
/**
6057
* Equivalent of suspending `getAccountDetails(request: GetAccountDetailsRequest)` for Java interoperability
@@ -69,13 +66,12 @@ class AccountClient internal constructor(
6966
*/
7067
@Throws(KevinApiErrorException::class)
7168
suspend fun getAccountTransactions(request: GetAccountTransactionsRequest): List<AccountTransactionResponse> =
72-
httpClient.get<ResponseArray<AccountTransactionResponse>>(
73-
path = Endpoint.Paths.Account.getAccountTransactions(accountId = request.accountId)
74-
) {
69+
httpClient.get {
70+
url(path = Endpoint.Paths.Account.getAccountTransactions(accountId = request.accountId))
7571
appendAccountRequestHeaders(headers = request.headers)
7672
parameter("dateFrom", request.dateFrom)
7773
parameter("dateTo", request.dateTo)
78-
}.data
74+
}.body<ResponseArray<AccountTransactionResponse>>().data
7975

8076
/**
8177
* Equivalent of suspending `getAccountTransactions(request: GetAccountTransactionsRequest)` for Java interoperability
@@ -90,11 +86,10 @@ class AccountClient internal constructor(
9086
*/
9187
@Throws(KevinApiErrorException::class)
9288
suspend fun getAccountBalances(request: GetAccountBalanceRequest): List<AccountBalanceResponse> =
93-
httpClient.get<ResponseArray<AccountBalanceResponse>>(
94-
path = Endpoint.Paths.Account.getAccountBalance(accountId = request.accountId)
95-
) {
89+
httpClient.get {
90+
url(path = Endpoint.Paths.Account.getAccountBalance(accountId = request.accountId))
9691
appendAccountRequestHeaders(headers = request.headers)
97-
}.data
92+
}.body<ResponseArray<AccountBalanceResponse>>().data
9893

9994
/**
10095
* Equivalent of suspending `getAccountBalances(request: GetAccountBalanceRequest)` for Java interoperability
@@ -116,4 +111,4 @@ class AccountClient internal constructor(
116111
}
117112
}
118113
}
119-
}
114+
}

src/main/kotlin/eu/kevin/api/services/auth/AuthClient.kt

Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package eu.kevin.api.services.auth
33
import eu.kevin.api.Endpoint
44
import eu.kevin.api.exceptions.KevinApiErrorException
55
import eu.kevin.api.extensions.appendAtStartIfNotExist
6-
import eu.kevin.api.extensions.appendQueryParameter
76
import eu.kevin.api.extensions.suspendingToCompletableFuture
87
import eu.kevin.api.models.auth.authentication.request.StartAuthenticationRequest
98
import eu.kevin.api.models.auth.authentication.request.StartAuthenticationRequestBody
@@ -14,6 +13,7 @@ import eu.kevin.api.models.auth.token.response.ReceiveTokenResponse
1413
import eu.kevin.api.models.auth.tokenContent.ReceiveTokenContentRequest
1514
import eu.kevin.api.models.auth.tokenContent.ReceiveTokenContentResponse
1615
import io.ktor.client.*
16+
import io.ktor.client.call.*
1717
import io.ktor.client.request.*
1818
import io.ktor.http.*
1919
import java.util.concurrent.CompletableFuture
@@ -29,33 +29,27 @@ class AuthClient internal constructor(
2929
*/
3030
@Throws(KevinApiErrorException::class)
3131
suspend fun startAuthentication(request: StartAuthenticationRequest): StartAuthenticationResponse =
32-
httpClient.post<StartAuthenticationResponse>(
33-
path = Endpoint.Paths.Auth.startAuthentication(),
34-
body = StartAuthenticationRequestBody(
35-
email = request.email,
36-
cardMethod = request.cardMethod
32+
httpClient.post {
33+
url(path = Endpoint.Paths.Auth.startAuthentication())
34+
setBody(
35+
StartAuthenticationRequestBody(
36+
email = request.email,
37+
cardMethod = request.cardMethod
38+
)
3739
)
38-
) {
3940
request.run {
4041
parameter("bankId", bankId)
4142
parameter("redirectPreferred", redirectPreferred)
42-
scopes?.forEach {
43-
parameter("scopes", it)
44-
}
43+
scopes?.forEach { parameter("scopes", it) }
44+
parameter("lang", request.lang)
4545

4646
headers {
4747
append("Request-Id", requestId)
4848
append("Redirect-URL", redirectUrl)
4949
webhookUrl?.let { append("Webhook-URL", it) }
5050
}
5151
}
52-
}.run {
53-
copy(
54-
authorizationLink = Url(authorizationLink)
55-
.appendQueryParameter("lang", request.lang)
56-
.toString()
57-
)
58-
}
52+
}.body()
5953

6054
/**
6155
* Equivalent of suspending `startAuthentication(request: StartAuthenticationRequest)` for Java interoperability
@@ -70,10 +64,10 @@ class AuthClient internal constructor(
7064
*/
7165
@Throws(KevinApiErrorException::class)
7266
suspend fun receiveToken(request: ReceiveTokenRequest): ReceiveTokenResponse =
73-
httpClient.post(
74-
path = Endpoint.Paths.Auth.receiveToken(),
75-
body = request
76-
)
67+
httpClient.post {
68+
url(path = Endpoint.Paths.Auth.receiveToken())
69+
setBody(request)
70+
}.body()
7771

7872
/**
7973
* Equivalent of suspending `receiveToken(request: ReceiveTokenRequest)` for Java interoperability
@@ -88,10 +82,10 @@ class AuthClient internal constructor(
8882
*/
8983
@Throws(KevinApiErrorException::class)
9084
suspend fun refreshToken(request: RefreshTokenRequest): ReceiveTokenResponse =
91-
httpClient.post(
92-
path = Endpoint.Paths.Auth.receiveToken(),
93-
body = request
94-
)
85+
httpClient.post {
86+
url(path = Endpoint.Paths.Auth.receiveToken())
87+
setBody(request)
88+
}.body()
9589

9690
/**
9791
* Equivalent of suspending `refreshToken(request: RefreshTokenRequest)` for Java interoperability
@@ -106,13 +100,12 @@ class AuthClient internal constructor(
106100
*/
107101
@Throws(KevinApiErrorException::class)
108102
suspend fun receiveTokenContent(request: ReceiveTokenContentRequest): ReceiveTokenContentResponse =
109-
httpClient.get(
110-
path = Endpoint.Paths.Auth.receiveTokenContent()
111-
) {
103+
httpClient.get {
104+
url(path = Endpoint.Paths.Auth.receiveTokenContent())
112105
headers {
113106
append(HttpHeaders.Authorization, request.accessToken.appendAtStartIfNotExist("Bearer "))
114107
}
115-
}
108+
}.body()
116109

117110
/**
118111
* Equivalent of suspending `receiveTokenContent(request: ReceiveTokenContentRequest)` for Java interoperability

0 commit comments

Comments
 (0)