Skip to content

Feature/update kotlin dependecies template #12966

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

Merged
Show file tree
Hide file tree
Changes from 13 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
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ version '{{artifactVersion}}'
{{^omitGradleWrapper}}

wrapper {
gradleVersion = '6.8.3'
gradleVersion = '7.5'
distributionUrl = "https://services.gradle.org/distributions/gradle-$gradleVersion-all.zip"
}
{{/omitGradleWrapper}}

buildscript {
ext.kotlin_version = '1.5.10'
ext.kotlin_version = '1.6.10'
{{#jvm-ktor}}
ext.ktor_version = '1.6.7'
ext.ktor_version = '2.0.3'
{{/jvm-ktor}}
{{#jvm-retrofit2}}
ext.retrofitVersion = '2.9.0'
Expand Down Expand Up @@ -72,46 +72,49 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
{{^doNotUseRxAndCoroutines}}
{{#useCoroutines}}
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.1"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.3"
{{/useCoroutines}}
{{/doNotUseRxAndCoroutines}}
{{#moshi}}
{{^moshiCodeGen}}
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
implementation "com.squareup.moshi:moshi-kotlin:1.12.0"
implementation "com.squareup.moshi:moshi-adapters:1.12.0"
implementation "com.squareup.moshi:moshi-kotlin:1.13.0"
implementation "com.squareup.moshi:moshi-adapters:1.13.0"
{{/moshiCodeGen}}
{{#moshiCodeGen}}
implementation "com.squareup.moshi:moshi:1.12.0"
implementation "com.squareup.moshi:moshi-adapters:1.12.0"
kapt "com.squareup.moshi:moshi-kotlin-codegen:1.12.0"
implementation "com.squareup.moshi:moshi:1.13.0"
implementation "com.squareup.moshi:moshi-adapters:1.13.0"
kapt "com.squareup.moshi:moshi-kotlin-codegen:1.13.0"
{{/moshiCodeGen}}
{{/moshi}}
{{#gson}}
implementation "com.google.code.gson:gson:2.8.7"
implementation "com.google.code.gson:gson:2.9.0"
{{/gson}}
{{#jackson}}
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.12.3"
implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.12.3"
implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.13.3"
implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.3"
{{/jackson}}
{{#kotlinx_serialization}}
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.1"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.3"
{{/kotlinx_serialization}}
{{#jvm-ktor}}
implementation "io.ktor:ktor-client-core:$ktor_version"
implementation "io.ktor:ktor-client-content-negotiation:$ktor_version"
{{#gson}}
implementation "io.ktor:ktor-serialization-gson:$ktor_version"
implementation "io.ktor:ktor-client-gson:$ktor_version"
{{/gson}}
{{#jackson}}
implementation "io.ktor:ktor-client-jackson:$ktor_version"
implementation "io.ktor:ktor-serialization-jackson:$ktor_version"
{{/jackson}}
{{/jvm-ktor}}
{{#jvm-okhttp3}}
implementation "com.squareup.okhttp3:okhttp:3.12.13"
{{/jvm-okhttp3}}
{{#jvm-okhttp4}}
implementation "com.squareup.okhttp3:okhttp:4.9.1"
implementation "com.squareup.okhttp3:okhttp:4.10.0"
{{/jvm-okhttp4}}
{{#threetenbp}}
implementation "org.threeten:threetenbp:1.5.1"
Expand All @@ -120,7 +123,7 @@ dependencies {
{{#hasOAuthMethods}}
implementation "org.apache.oltu.oauth2:org.apache.oltu.oauth2.client:1.0.2"
{{/hasOAuthMethods}}
implementation "com.squareup.okhttp3:logging-interceptor:4.9.1"
implementation "com.squareup.okhttp3:logging-interceptor:4.10.0"
{{#useRxJava}}
implementation "io.reactivex:rxjava:$rxJavaVersion"
implementation "com.squareup.retrofit2:adapter-rxjava:$retrofitVersion"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import io.ktor.http.ParametersBuilder

{{#gson}}
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import java.text.DateFormat
{{/gson}}
{{#jackson}}
import com.fasterxml.jackson.databind.ObjectMapper
Expand All @@ -22,8 +24,13 @@ import com.fasterxml.jackson.databind.ObjectMapper
baseUrl: String = ApiClient.BASE_URL,
httpClientEngine: HttpClientEngine? = null,
httpClientConfig: ((HttpClientConfig<*>) -> Unit)? = null,
json: {{#gson}}Gson{{/gson}}{{#jackson}}ObjectMapper{{/jackson}} = ApiClient.JSON_DEFAULT,
) : ApiClient(baseUrl, httpClientEngine, httpClientConfig, json) {
{{#gson}}
jsonBlock: GsonBuilder.() -> Unit = ApiClient.JSON_DEFAULT,
{{/gson}}
{{#jackson}}
jsonBlock: ObjectMapper.() -> Unit = ApiClient.JSON_DEFAULT,
{{/jackson}}
) : ApiClient(baseUrl, httpClientEngine, httpClientConfig, jsonBlock) {

{{#operation}}
/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,50 +1,69 @@
package {{packageName}}.infrastructure


import io.ktor.client.HttpClient
import io.ktor.client.HttpClientConfig
import io.ktor.client.engine.HttpClientEngine
import io.ktor.client.features.json.JsonFeature
import io.ktor.client.features.json.JsonSerializer
import io.ktor.client.request.*
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
import io.ktor.client.request.forms.FormDataContent
import io.ktor.client.request.forms.MultiPartFormDataContent
import io.ktor.client.request.header
import io.ktor.client.request.parameter
import io.ktor.client.request.request
import io.ktor.client.request.setBody
import io.ktor.client.statement.HttpResponse
import io.ktor.client.utils.EmptyContent
import io.ktor.http.*
import io.ktor.http.content.ByteArrayContent
import io.ktor.http.content.OutgoingContent
import io.ktor.http.HttpHeaders
import io.ktor.http.HttpMethod
import io.ktor.http.Parameters
import io.ktor.http.URLBuilder
import io.ktor.http.content.PartData
import kotlin.Unit

import io.ktor.http.encodeURLQueryComponent
import io.ktor.http.encodedPath
import io.ktor.http.takeFrom
{{#gson}}
import io.ktor.serialization.gson.*
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import java.nio.charset.StandardCharsets
{{/gson}}
{{#jackson}}
import io.ktor.serialization.jackson.*
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.SerializationFeature
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
import com.fasterxml.jackson.core.util.DefaultIndenter
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter
{{/jackson}}

import org.openapitools.client.auth.ApiKeyAuth
import org.openapitools.client.auth.Authentication
import org.openapitools.client.auth.HttpBasicAuth
import org.openapitools.client.auth.HttpBearerAuth
import org.openapitools.client.auth.OAuth
import {{packageName}}.auth.*

{{#nonPublicApi}}internal {{/nonPublicApi}}open class ApiClient(
private val baseUrl: String,
httpClientEngine: HttpClientEngine?,
httpClientConfig: ((HttpClientConfig<*>) -> Unit)? = null,
json: {{#gson}}Gson{{/gson}}{{#jackson}}ObjectMapper{{/jackson}},
{{#gson}}
jsonBlock: GsonBuilder.() -> Unit = JSON_DEFAULT,
{{/gson}}
{{#jackson}}
jsonBlock: ObjectMapper.() -> Unit = JSON_DEFAULT,
{{/jackson}}
) {

private val serializer: JsonSerializer by lazy {
JsonSerializerImpl(json)
}

private val clientConfig: (HttpClientConfig<*>) -> Unit by lazy {
{
// Hold a reference to the serializer to avoid freezing the entire ApiClient instance
// when the JsonFeature is configured.
val serializerReference = serializer
it.install(JsonFeature) { serializer = serializerReference }
it.install(ContentNegotiation) {
{{#gson}}
gson { jsonBlock() }
{{/gson}}
{{#jackson}}
jackson { jsonBlock() }
{{/jackson}}
}
httpClientConfig?.invoke(it)
}
}
Expand All @@ -67,9 +86,24 @@ import {{packageName}}.auth.*
{{/hasAuthMethods}}

{{#nonPublicApi}}internal {{/nonPublicApi}}companion object {
const val BASE_URL = "{{{basePath}}}"
val JSON_DEFAULT = {{#gson}}Gson(){{/gson}}{{#jackson}}ObjectMapper(){{/jackson}}
protected val UNSAFE_HEADERS = listOf(HttpHeaders.ContentType)
const val BASE_URL = "{{{basePath}}}"
{{#gson}}
val JSON_DEFAULT : GsonBuilder.() -> Unit = {
setDateFormat(DateFormat.LONG)
setPrettyPrinting()
}
{{/gson}}
{{#jackson}}
val JSON_DEFAULT: ObjectMapper.() -> Unit = {
configure(SerializationFeature.INDENT_OUTPUT, true)
setDefaultPrettyPrinter(DefaultPrettyPrinter().apply {
indentArraysWith(DefaultPrettyPrinter.FixedSpaceIndenter.instance)
indentObjectsWith(DefaultIndenter(" ", "\n"))
})
registerModule(JavaTimeModule())
}
{{/jackson}}
protected val UNSAFE_HEADERS = listOf(HttpHeaders.ContentType)
}

/**
Expand All @@ -78,7 +112,7 @@ import {{packageName}}.auth.*
* @param username Username
*/
fun setUsername(username: String) {
val auth = authentications?.values?.firstOrNull { it is HttpBasicAuth } as HttpBasicAuth?
val auth = authentications.values.firstOrNull { it is HttpBasicAuth } as HttpBasicAuth?
?: throw Exception("No HTTP basic authentication configured")
auth.username = username
}
Expand All @@ -89,7 +123,7 @@ import {{packageName}}.auth.*
* @param password Password
*/
fun setPassword(password: String) {
val auth = authentications?.values?.firstOrNull { it is HttpBasicAuth } as HttpBasicAuth?
val auth = authentications.values.firstOrNull { it is HttpBasicAuth } as HttpBasicAuth?
?: throw Exception("No HTTP basic authentication configured")
auth.password = password
}
Expand All @@ -101,7 +135,7 @@ import {{packageName}}.auth.*
* @param paramName The name of the API key parameter, or null or set the first key.
*/
fun setApiKey(apiKey: String, paramName: String? = null) {
val auth = authentications?.values?.firstOrNull { it is ApiKeyAuth && (paramName == null || paramName == it.paramName)} as ApiKeyAuth?
val auth = authentications.values.firstOrNull { it is ApiKeyAuth && (paramName == null || paramName == it.paramName)} as ApiKeyAuth?
?: throw Exception("No API key authentication configured")
auth.apiKey = apiKey
}
Expand All @@ -113,7 +147,7 @@ import {{packageName}}.auth.*
* @param paramName The name of the API key parameter, or null or set the first key.
*/
fun setApiKeyPrefix(apiKeyPrefix: String, paramName: String? = null) {
val auth = authentications?.values?.firstOrNull { it is ApiKeyAuth && (paramName == null || paramName == it.paramName) } as ApiKeyAuth?
val auth = authentications.values.firstOrNull { it is ApiKeyAuth && (paramName == null || paramName == it.paramName) } as ApiKeyAuth?
?: throw Exception("No API key authentication configured")
auth.apiKeyPrefix = apiKeyPrefix
}
Expand All @@ -124,7 +158,7 @@ import {{packageName}}.auth.*
* @param accessToken Access token
*/
fun setAccessToken(accessToken: String) {
val auth = authentications?.values?.firstOrNull { it is OAuth } as OAuth?
val auth = authentications.values.firstOrNull { it is OAuth } as OAuth?
?: throw Exception("No OAuth2 authentication configured")
auth.accessToken = accessToken
}
Expand All @@ -135,7 +169,7 @@ import {{packageName}}.auth.*
* @param bearerToken The bearer token.
*/
fun setBearerToken(bearerToken: String) {
val auth = authentications?.values?.firstOrNull { it is HttpBearerAuth } as HttpBearerAuth?
val auth = authentications.values.firstOrNull { it is HttpBearerAuth } as HttpBearerAuth?
?: throw Exception("No Bearer authentication configured")
auth.bearerToken = bearerToken
}
Expand All @@ -148,18 +182,13 @@ import {{packageName}}.auth.*
return request(requestConfig, FormDataContent(body ?: Parameters.Empty), authNames)
}

protected suspend fun <T: Any?> jsonRequest(requestConfig: RequestConfig<T>, body: Any? = null, authNames: kotlin.collections.List<String>): HttpResponse {
val contentType = (requestConfig.headers[HttpHeaders.ContentType]?.let { ContentType.parse(it) }
?: ContentType.Application.Json)
return if (body != null) request(requestConfig, serializer.write(body, contentType), authNames)
else request(requestConfig, authNames = authNames)
}
protected suspend fun <T: Any?> jsonRequest(requestConfig: RequestConfig<T>, body: Any? = null, authNames: kotlin.collections.List<String>): HttpResponse = request(requestConfig, body, authNames)

protected suspend fun <T: Any?> request(requestConfig: RequestConfig<T>, body: OutgoingContent = EmptyContent, authNames: kotlin.collections.List<String>): HttpResponse {
protected suspend fun <T: Any?> request(requestConfig: RequestConfig<T>, body: Any? = null, authNames: kotlin.collections.List<String>): HttpResponse {
requestConfig.updateForAuth<T>(authNames)
val headers = requestConfig.headers

return client.request<HttpResponse> {
return client.request {
this.url {
this.takeFrom(URLBuilder(baseUrl))
appendPath(requestConfig.path.trimStart('/').split('/'))
Expand All @@ -172,8 +201,7 @@ import {{packageName}}.auth.*
this.method = requestConfig.method.httpMethod
headers.filter { header -> !UNSAFE_HEADERS.contains(header.key) }.forEach { header -> this.header(header.key, header.value) }
if (requestConfig.method in listOf(RequestMethod.PUT, RequestMethod.POST, RequestMethod.PATCH))
this.body = body

setBody(body)
}
}

Expand All @@ -199,13 +227,3 @@ import {{packageName}}.auth.*
RequestMethod.OPTIONS -> HttpMethod.Options
}
}

{{#gson}}private class JsonSerializerImpl(private val gson: Gson) : JsonSerializer {
override fun write(data: Any, contentType: ContentType): OutgoingContent =
ByteArrayContent(gson.toJson(data).toByteArray(StandardCharsets.UTF_8), contentType)
}{{/gson}}

{{#jackson}}private class JsonSerializerImpl(private val objectMapper: ObjectMapper) : JsonSerializer {
override fun write(data: Any, contentType: ContentType): OutgoingContent =
ByteArrayContent(objectMapper.writeValueAsBytes(data), contentType)
}{{/jackson}}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package {{packageName}}.infrastructure

import io.ktor.client.call.TypeInfo
import io.ktor.client.call.typeInfo
import io.ktor.http.Headers
import io.ktor.http.isSuccess
import io.ktor.util.reflect.TypeInfo
import io.ktor.util.reflect.typeInfo

{{#nonPublicApi}}internal {{/nonPublicApi}}open class HttpResponse<T : Any>(val response: io.ktor.client.statement.HttpResponse, val provider: BodyProvider<T>) {
val status: Int = response.status.value
Expand All @@ -29,11 +29,11 @@ import io.ktor.http.isSuccess
{{#nonPublicApi}}internal {{/nonPublicApi}}class TypedBodyProvider<T : Any>(private val type: TypeInfo) : BodyProvider<T> {
@Suppress("UNCHECKED_CAST")
override suspend fun body(response: io.ktor.client.statement.HttpResponse): T =
response.call.receive(type) as T
response.call.body(type) as T

@Suppress("UNCHECKED_CAST")
override suspend fun <V : Any> typedBody(response: io.ktor.client.statement.HttpResponse, type: TypeInfo): V =
response.call.receive(type) as V
response.call.body(type) as V
}

{{#nonPublicApi}}internal {{/nonPublicApi}}class MappedBodyProvider<S : Any, T : Any>(private val provider: BodyProvider<S>, private val block: S.() -> T) : BodyProvider<T> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {{packageName}}.infrastructure.*
import io.ktor.client.HttpClientConfig
import io.ktor.client.request.forms.formData
import io.ktor.client.engine.HttpClientEngine
import io.ktor.client.features.json.serializer.KotlinxSerializer
import kotlinx.serialization.json.Json
import io.ktor.http.ParametersBuilder
import kotlinx.serialization.*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ plugins {
group = "{{groupId}}"
version = "{{artifactVersion}}"

val kotlin_version = "1.6.0"
val coroutines_version = "1.5.2"
val serialization_version = "1.3.0"
val ktor_version = "1.6.4"
val kotlin_version = "1.6.10"
val coroutines_version = "1.6.3"
val serialization_version = "1.3.3"
val ktor_version = "2.0.3"

repositories {
mavenCentral()
Expand All @@ -30,9 +30,11 @@ kotlin {
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:$serialization_version")

api("io.ktor:ktor-client-core:$ktor_version")
api("io.ktor:ktor-client-json:$ktor_version")
api("io.ktor:ktor-client-serialization:$ktor_version")
api("io.ktor:ktor-client-content-negotiation:$ktor_version")
api("io.ktor:ktor-serialization-kotlinx-json:$ktor_version")
}
}

Expand Down
Loading