Skip to content

Commit 81d809e

Browse files
committed
Samples & fixes to missing libraries in Ktor versions
Samples & fixes to missing libraries in Ktor versions
1 parent ebaf934 commit 81d809e

File tree

129 files changed

+1329
-739
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

129 files changed

+1329
-739
lines changed

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinClientCodegen.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,8 @@ private void processJVMKtorLibrary(final String infrastructureFolder) {
661661
supportingFiles.add(new SupportingFile("infrastructure/ApiAbstractions.kt.mustache", infrastructureFolder, "ApiAbstractions.kt"));
662662
supportingFiles.add(new SupportingFile("infrastructure/ApiClient.kt.mustache", infrastructureFolder, "ApiClient.kt"));
663663
supportingFiles.add(new SupportingFile("infrastructure/HttpResponse.kt.mustache", infrastructureFolder, "HttpResponse.kt"));
664+
supportingFiles.add(new SupportingFile("infrastructure/HttpResponseExtensions.kt.mustache", infrastructureFolder, "HttpResponseExtensions.kt"));
665+
supportingFiles.add(new SupportingFile("infrastructure/Errors.kt.mustache", infrastructureFolder, "Errors.kt"));
664666
supportingFiles.add(new SupportingFile("infrastructure/RequestConfig.kt.mustache", infrastructureFolder, "RequestConfig.kt"));
665667
supportingFiles.add(new SupportingFile("infrastructure/RequestMethod.kt.mustache", infrastructureFolder, "RequestMethod.kt"));
666668

@@ -669,6 +671,8 @@ private void processJVMKtorLibrary(final String infrastructureFolder) {
669671
supportingFiles.add(new SupportingFile("auth/HttpBasicAuth.kt.mustache", authFolder, "HttpBasicAuth.kt"));
670672
supportingFiles.add(new SupportingFile("auth/HttpBearerAuth.kt.mustache", authFolder, "HttpBearerAuth.kt"));
671673
supportingFiles.add(new SupportingFile("auth/OAuth.kt.mustache", authFolder, "OAuth.kt"));
674+
675+
addSupportingSerializerAdapters(infrastructureFolder);
672676
}
673677

674678
/**

modules/openapi-generator/src/main/resources/kotlin-client/build.gradle.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ apply plugin: 'kotlinx-serialization'
5353
{{#idea}}
5454
apply plugin: 'idea'
5555
{{/idea}}
56-
apply plugin: 'maven-publish'
5756

5857
repositories {
5958
maven { url "https://repo1.maven.org/maven2" }
@@ -113,6 +112,7 @@ dependencies {
113112
implementation "io.ktor:ktor-client-jackson:$ktor_version"
114113
implementation "io.ktor:ktor-serialization-jackson:$ktor_version"
115114
{{/jackson}}
115+
implementation "io.ktor:ktor-client-cio:$ktor_version"
116116
{{/jvm-ktor}}
117117
{{#jvm-okhttp3}}
118118
implementation "com.squareup.okhttp3:okhttp:3.12.13"

modules/openapi-generator/src/main/resources/kotlin-client/jvm-common/infrastructure/OffsetDateTimeAdapter.kt.mustache

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,22 @@ import org.threeten.bp.format.DateTimeFormatter
3838

3939
@FromJson
4040
fun fromJson(value: String): OffsetDateTime {
41-
return OffsetDateTime.parse(value, DateTimeFormatter.ISO_OFFSET_DATE_TIME)
41+
return OffsetDateTime.parse(tryFormatDateTime(value), DateTimeFormatter.ISO_OFFSET_DATE_TIME)
4242
}
4343

44+
private fun tryFormatDateTime(stringValue: String): String {
45+
val offset = stringValue.substringAfter("+")
46+
return when (offset.length) {
47+
4 -> fixOffsetValue(stringValue, offset)
48+
else -> stringValue
49+
}
50+
}
51+
52+
private fun fixOffsetValue(stringValue: String = "0000", offset: String): String {
53+
val offsetChars = offset.toCharArray().toMutableList()
54+
offsetChars.add(2, ':')
55+
return stringValue.replaceAfter("+", offsetChars.joinToString(""))
56+
}
4457
}
4558
{{/moshi}}
4659
{{#gson}}
@@ -58,16 +71,28 @@ import org.threeten.bp.format.DateTimeFormatter
5871
override fun read(out: JsonReader?): OffsetDateTime? {
5972
out ?: return null
6073
61-
when (out.peek()) {
74+
return when (out.peek()) {
6275
NULL -> {
6376
out.nextNull()
6477
return null
6578
}
66-
else -> {
67-
return OffsetDateTime.parse(out.nextString(), formatter)
68-
}
79+
else -> OffsetDateTime.parse(tryFormatDateTime(out.nextString()), formatter)
80+
}
81+
}
82+
83+
private fun tryFormatDateTime(stringValue: String): String {
84+
val offset = stringValue.substringAfter("+")
85+
return when (offset.length) {
86+
4 -> fixOffsetValue(stringValue, offset)
87+
else -> stringValue
6988
}
7089
}
90+
91+
private fun fixOffsetValue(stringValue: String = "0000", offset: String): String {
92+
val offsetChars = offset.toCharArray().toMutableList()
93+
offsetChars.add(2, ':')
94+
return stringValue.replaceAfter("+", offsetChars.joinToString(""))
95+
}
7196
}
7297
{{/gson}}
7398
{{#kotlinx_serialization}}
@@ -80,7 +105,21 @@ import org.threeten.bp.format.DateTimeFormatter
80105
}
81106

82107
override fun deserialize(decoder: Decoder): OffsetDateTime {
83-
return OffsetDateTime.parse(decoder.decodeString(), DateTimeFormatter.ISO_OFFSET_DATE_TIME)
108+
return OffsetDateTime.parse(tryFormatDateTime(decoder.decodeString()), DateTimeFormatter.ISO_OFFSET_DATE_TIME)
109+
}
110+
111+
private fun tryFormatDateTime(stringValue: String): String {
112+
val offset = stringValue.substringAfter("+")
113+
return when (offset.length) {
114+
4 -> fixOffsetValue(stringValue, offset)
115+
else -> stringValue
116+
}
117+
}
118+
119+
private fun fixOffsetValue(stringValue: String = "0000", offset: String): String {
120+
val offsetChars = offset.toCharArray().toMutableList()
121+
offsetChars.add(2, ':')
122+
return stringValue.replaceAfter("+", offsetChars.joinToString(""))
84123
}
85124
}
86125
{{/kotlinx_serialization}}

modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-ktor/infrastructure/ApiClient.kt.mustache

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,14 @@ import io.ktor.http.content.PartData
2121
import io.ktor.http.encodeURLQueryComponent
2222
import io.ktor.http.encodedPath
2323
import io.ktor.http.takeFrom
24+
import io.ktor.http.ContentType.Application
2425
{{#gson}}
2526
import io.ktor.serialization.gson.*
2627
import com.google.gson.GsonBuilder
2728
import java.text.DateFormat
29+
import java.time.LocalDate
30+
import java.time.LocalDateTime
31+
import java.time.OffsetDateTime
2832
{{/gson}}
2933
{{#jackson}}
3034
import io.ktor.serialization.jackson.*
@@ -85,6 +89,10 @@ import {{packageName}}.auth.*
8589
{{#gson}}
8690
val JSON_DEFAULT : GsonBuilder.() -> Unit = {
8791
setDateFormat(DateFormat.LONG)
92+
registerTypeAdapter(OffsetDateTime::class.java, OffsetDateTimeAdapter())
93+
registerTypeAdapter(LocalDateTime::class.java, LocalDateTimeAdapter())
94+
registerTypeAdapter(LocalDate::class.java, LocalDateAdapter())
95+
registerTypeAdapter(ByteArray::class.java, ByteArrayAdapter())
8896
setPrettyPrinting()
8997
}
9098
{{/gson}}
@@ -196,6 +204,7 @@ import {{packageName}}.auth.*
196204
this.method = requestConfig.method.httpMethod
197205
headers.filter { header -> !UNSAFE_HEADERS.contains(header.key) }.forEach { header -> this.header(header.key, header.value) }
198206
if (requestConfig.method in listOf(RequestMethod.PUT, RequestMethod.POST, RequestMethod.PATCH)) {
207+
this.contentType(Application.Json)
199208
setBody(body)
200209
}
201210
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
@file:Suppress("unused")
2+
package {{packageName}}.infrastructure
3+
4+
import java.lang.RuntimeException
5+
6+
{{#nonPublicApi}}internal {{/nonPublicApi}}open class ClientException(message: kotlin.String? = null, val statusCode: Int = -1, val response: io.ktor.client.statement.HttpResponse? = null) : RuntimeException(message) {
7+
8+
{{#nonPublicApi}}internal {{/nonPublicApi}}companion object {
9+
private const val serialVersionUID: Long = 123L
10+
}
11+
}
12+
13+
{{#nonPublicApi}}internal {{/nonPublicApi}}open class ServerException(message: kotlin.String? = null, val statusCode: Int = -1, val response: io.ktor.client.statement.HttpResponse? = null) : RuntimeException(message) {
14+
15+
{{#nonPublicApi}}internal {{/nonPublicApi}}companion object {
16+
private const val serialVersionUID: Long = 456L
17+
}
18+
}

modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-ktor/infrastructure/HttpResponse.kt.mustache

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@ package {{packageName}}.infrastructure
22

33
import io.ktor.http.Headers
44
import io.ktor.http.isSuccess
5+
import io.ktor.util.InternalAPI
56
import io.ktor.util.reflect.TypeInfo
67
import io.ktor.util.reflect.typeInfo
8+
import io.ktor.utils.io.readUTF8Line
9+
710

811
{{#nonPublicApi}}internal {{/nonPublicApi}}open class HttpResponse<T : Any>(val response: io.ktor.client.statement.HttpResponse, val provider: BodyProvider<T>) {
912
val status: Int = response.status.value
@@ -26,10 +29,15 @@ import io.ktor.util.reflect.typeInfo
2629
suspend fun <V : Any> typedBody(response: io.ktor.client.statement.HttpResponse, type: TypeInfo): V
2730
}
2831

32+
@OptIn(InternalAPI::class)
2933
{{#nonPublicApi}}internal {{/nonPublicApi}}class TypedBodyProvider<T : Any>(private val type: TypeInfo) : BodyProvider<T> {
3034
@Suppress("UNCHECKED_CAST")
31-
override suspend fun body(response: io.ktor.client.statement.HttpResponse): T =
32-
response.call.body(type) as T
35+
override suspend fun body(response: io.ktor.client.statement.HttpResponse): T = when {
36+
response.status.isSuccess() -> response.call.body(type) as T
37+
response.isClientError -> throw ClientException("Client error : ${response.status.value} ${response.content.readUTF8Line()}", response.status.value, response)
38+
response.isServerError -> throw ServerException("Server error : ${response.status.value} ${response.content.readUTF8Line()}", response.status.value, response)
39+
else -> throw RuntimeException()
40+
}
3341

3442
@Suppress("UNCHECKED_CAST")
3543
override suspend fun <V : Any> typedBody(response: io.ktor.client.statement.HttpResponse, type: TypeInfo): V =
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package {{packageName}}.infrastructure
2+
3+
import io.ktor.client.statement.HttpResponse
4+
5+
/**
6+
* Provides an extension to evaluation whether the response is a 1xx code
7+
*/
8+
{{#nonPublicApi}}internal {{/nonPublicApi}}val HttpResponse.isInformational : Boolean get() = this.status.value in 100..199
9+
10+
/**
11+
* Provides an extension to evaluation whether the response is a 3xx code
12+
*/
13+
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
14+
{{#nonPublicApi}}internal {{/nonPublicApi}}val HttpResponse.isRedirect : Boolean get() = this.status.value in 300..399
15+
16+
/**
17+
* Provides an extension to evaluation whether the response is a 4xx code
18+
*/
19+
{{#nonPublicApi}}internal {{/nonPublicApi}}val HttpResponse.isClientError : Boolean get() = this.status.value in 400..499
20+
21+
/**
22+
* Provides an extension to evaluation whether the response is a 5xx (Standard) through 9999 (non-standard) code
23+
*/
24+
{{#nonPublicApi}}internal {{/nonPublicApi}}val HttpResponse.isServerError : Boolean get() = this.status.value in 500..9999

modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-okhttp/api.mustache

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,11 @@ import {{packageName}}.infrastructure.toMultiValue
143143
ResponseType.Redirection -> throw UnsupportedOperationException("Client does not support Redirection responses.")
144144
ResponseType.ClientError -> {
145145
val localVarError = localVarResponse as ClientError<*>
146-
throw ClientException("Client error : ${localVarError.statusCode} ${localVarError.message.orEmpty()}", localVarError.statusCode, localVarResponse)
146+
throw ClientException("Client error : ${localVarError.statusCode} ${localVarError.body}", localVarError.statusCode, localVarResponse)
147147
}
148148
ResponseType.ServerError -> {
149149
val localVarError = localVarResponse as ServerError<*>
150-
throw ServerException("Server error : ${localVarError.statusCode} ${localVarError.message.orEmpty()}", localVarError.statusCode, localVarResponse)
150+
throw ServerException("Server error : ${localVarError.statusCode} ${localVarError.body}", localVarError.statusCode, localVarResponse)
151151
}
152152
}
153153
}

samples/client/petstore/kotlin-allOff-discriminator/build.gradle

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ buildscript {
1818
}
1919

2020
apply plugin: 'kotlin'
21-
apply plugin: 'maven-publish'
2221

2322
repositories {
2423
maven { url "https://repo1.maven.org/maven2" }

samples/client/petstore/kotlin-allOff-discriminator/gradlew

100644100755
File mode changed.

0 commit comments

Comments
 (0)