[kotlin-client] Add ktor library with Jackson and GSON processing support (#11838)

This commit is contained in:
Sergey Vladimirov
2022-05-04 19:50:45 +03:00
committed by GitHub
parent bee9c79e5a
commit 6bd7036ff8
89 changed files with 6509 additions and 12 deletions

View File

@@ -0,0 +1,305 @@
/**
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* The version of the OpenAPI document: 1.0.0
*
*
* Please note:
* This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* Do not edit this file manually.
*/
@file:Suppress(
"ArrayInDataClass",
"EnumEntryName",
"RemoveRedundantQualifierName",
"UnusedImport"
)
package org.openapitools.client.apis
import org.openapitools.client.models.ModelApiResponse
import org.openapitools.client.models.Pet
import org.openapitools.client.infrastructure.*
import io.ktor.client.HttpClientConfig
import io.ktor.client.request.forms.formData
import io.ktor.client.engine.HttpClientEngine
import io.ktor.http.ParametersBuilder
import com.fasterxml.jackson.databind.ObjectMapper
open class PetApi(
baseUrl: String = ApiClient.BASE_URL,
httpClientEngine: HttpClientEngine? = null,
httpClientConfig: ((HttpClientConfig<*>) -> Unit)? = null,
json: ObjectMapper = ApiClient.JSON_DEFAULT,
) : ApiClient(baseUrl, httpClientEngine, httpClientConfig, json) {
/**
* Add a new pet to the store
*
* @param body Pet object that needs to be added to the store
* @return void
*/
open suspend fun addPet(body: Pet): HttpResponse<Unit> {
val localVariableAuthNames = listOf<String>("petstore_auth")
val localVariableBody = body
val localVariableQuery = mutableMapOf<String, List<String>>()
val localVariableHeaders = mutableMapOf<String, String>()
val localVariableConfig = RequestConfig<kotlin.Any?>(
RequestMethod.POST,
"/pet",
query = localVariableQuery,
headers = localVariableHeaders
)
return jsonRequest(
localVariableConfig,
localVariableBody,
localVariableAuthNames
).wrap()
}
/**
* Deletes a pet
*
* @param petId Pet id to delete
* @param apiKey (optional)
* @return void
*/
open suspend fun deletePet(petId: kotlin.Long, apiKey: kotlin.String?): HttpResponse<Unit> {
val localVariableAuthNames = listOf<String>("petstore_auth")
val localVariableBody =
io.ktor.client.utils.EmptyContent
val localVariableQuery = mutableMapOf<String, List<String>>()
val localVariableHeaders = mutableMapOf<String, String>()
apiKey?.apply { localVariableHeaders["api_key"] = this.toString() }
val localVariableConfig = RequestConfig<kotlin.Any?>(
RequestMethod.DELETE,
"/pet/{petId}".replace("{" + "petId" + "}", "$petId"),
query = localVariableQuery,
headers = localVariableHeaders
)
return request(
localVariableConfig,
localVariableBody,
localVariableAuthNames
).wrap()
}
/**
* Finds Pets by status
* Multiple status values can be provided with comma separated strings
* @param status Status values that need to be considered for filter
* @return kotlin.collections.List<Pet>
*/
@Suppress("UNCHECKED_CAST")
open suspend fun findPetsByStatus(status: kotlin.collections.List<kotlin.String>): HttpResponse<kotlin.collections.List<Pet>> {
val localVariableAuthNames = listOf<String>("petstore_auth")
val localVariableBody =
io.ktor.client.utils.EmptyContent
val localVariableQuery = mutableMapOf<String, List<String>>()
status?.apply { localVariableQuery["status"] = toMultiValue(this, "csv") }
val localVariableHeaders = mutableMapOf<String, String>()
val localVariableConfig = RequestConfig<kotlin.Any?>(
RequestMethod.GET,
"/pet/findByStatus",
query = localVariableQuery,
headers = localVariableHeaders
)
return request(
localVariableConfig,
localVariableBody,
localVariableAuthNames
).wrap()
}
/**
* Finds Pets by tags
* Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
* @param tags Tags to filter by
* @return kotlin.collections.List<Pet>
*/
@Suppress("UNCHECKED_CAST")
open suspend fun findPetsByTags(tags: kotlin.collections.List<kotlin.String>): HttpResponse<kotlin.collections.List<Pet>> {
val localVariableAuthNames = listOf<String>("petstore_auth")
val localVariableBody =
io.ktor.client.utils.EmptyContent
val localVariableQuery = mutableMapOf<String, List<String>>()
tags?.apply { localVariableQuery["tags"] = toMultiValue(this, "csv") }
val localVariableHeaders = mutableMapOf<String, String>()
val localVariableConfig = RequestConfig<kotlin.Any?>(
RequestMethod.GET,
"/pet/findByTags",
query = localVariableQuery,
headers = localVariableHeaders
)
return request(
localVariableConfig,
localVariableBody,
localVariableAuthNames
).wrap()
}
/**
* Find pet by ID
* Returns a single pet
* @param petId ID of pet to return
* @return Pet
*/
@Suppress("UNCHECKED_CAST")
open suspend fun getPetById(petId: kotlin.Long): HttpResponse<Pet> {
val localVariableAuthNames = listOf<String>("api_key")
val localVariableBody =
io.ktor.client.utils.EmptyContent
val localVariableQuery = mutableMapOf<String, List<String>>()
val localVariableHeaders = mutableMapOf<String, String>()
val localVariableConfig = RequestConfig<kotlin.Any?>(
RequestMethod.GET,
"/pet/{petId}".replace("{" + "petId" + "}", "$petId"),
query = localVariableQuery,
headers = localVariableHeaders
)
return request(
localVariableConfig,
localVariableBody,
localVariableAuthNames
).wrap()
}
/**
* Update an existing pet
*
* @param body Pet object that needs to be added to the store
* @return void
*/
open suspend fun updatePet(body: Pet): HttpResponse<Unit> {
val localVariableAuthNames = listOf<String>("petstore_auth")
val localVariableBody = body
val localVariableQuery = mutableMapOf<String, List<String>>()
val localVariableHeaders = mutableMapOf<String, String>()
val localVariableConfig = RequestConfig<kotlin.Any?>(
RequestMethod.PUT,
"/pet",
query = localVariableQuery,
headers = localVariableHeaders
)
return jsonRequest(
localVariableConfig,
localVariableBody,
localVariableAuthNames
).wrap()
}
/**
* Updates a pet in the store with form data
*
* @param petId ID of pet that needs to be updated
* @param name Updated name of the pet (optional)
* @param status Updated status of the pet (optional)
* @return void
*/
open suspend fun updatePetWithForm(petId: kotlin.Long, name: kotlin.String?, status: kotlin.String?): HttpResponse<Unit> {
val localVariableAuthNames = listOf<String>("petstore_auth")
val localVariableBody =
ParametersBuilder().also {
name?.apply { it.append("name", name.toString()) }
status?.apply { it.append("status", status.toString()) }
}.build()
val localVariableQuery = mutableMapOf<String, List<String>>()
val localVariableHeaders = mutableMapOf<String, String>()
val localVariableConfig = RequestConfig<kotlin.Any?>(
RequestMethod.POST,
"/pet/{petId}".replace("{" + "petId" + "}", "$petId"),
query = localVariableQuery,
headers = localVariableHeaders
)
return urlEncodedFormRequest(
localVariableConfig,
localVariableBody,
localVariableAuthNames
).wrap()
}
/**
* uploads an image
*
* @param petId ID of pet to update
* @param additionalMetadata Additional data to pass to server (optional)
* @param file file to upload (optional)
* @return ModelApiResponse
*/
@Suppress("UNCHECKED_CAST")
open suspend fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: io.ktor.client.request.forms.InputProvider?): HttpResponse<ModelApiResponse> {
val localVariableAuthNames = listOf<String>("petstore_auth")
val localVariableBody =
formData {
additionalMetadata?.apply { append("additionalMetadata", additionalMetadata) }
file?.apply { append("file", file) }
}
val localVariableQuery = mutableMapOf<String, List<String>>()
val localVariableHeaders = mutableMapOf<String, String>()
val localVariableConfig = RequestConfig<kotlin.Any?>(
RequestMethod.POST,
"/pet/{petId}/uploadImage".replace("{" + "petId" + "}", "$petId"),
query = localVariableQuery,
headers = localVariableHeaders
)
return multipartFormRequest(
localVariableConfig,
localVariableBody,
localVariableAuthNames
).wrap()
}
}

View File

@@ -0,0 +1,165 @@
/**
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* The version of the OpenAPI document: 1.0.0
*
*
* Please note:
* This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* Do not edit this file manually.
*/
@file:Suppress(
"ArrayInDataClass",
"EnumEntryName",
"RemoveRedundantQualifierName",
"UnusedImport"
)
package org.openapitools.client.apis
import org.openapitools.client.models.Order
import org.openapitools.client.infrastructure.*
import io.ktor.client.HttpClientConfig
import io.ktor.client.request.forms.formData
import io.ktor.client.engine.HttpClientEngine
import io.ktor.http.ParametersBuilder
import com.fasterxml.jackson.databind.ObjectMapper
open class StoreApi(
baseUrl: String = ApiClient.BASE_URL,
httpClientEngine: HttpClientEngine? = null,
httpClientConfig: ((HttpClientConfig<*>) -> Unit)? = null,
json: ObjectMapper = ApiClient.JSON_DEFAULT,
) : ApiClient(baseUrl, httpClientEngine, httpClientConfig, json) {
/**
* Delete purchase order by ID
* For valid response try integer IDs with value &lt; 1000. Anything above 1000 or nonintegers will generate API errors
* @param orderId ID of the order that needs to be deleted
* @return void
*/
open suspend fun deleteOrder(orderId: kotlin.String): HttpResponse<Unit> {
val localVariableAuthNames = listOf<String>()
val localVariableBody =
io.ktor.client.utils.EmptyContent
val localVariableQuery = mutableMapOf<String, List<String>>()
val localVariableHeaders = mutableMapOf<String, String>()
val localVariableConfig = RequestConfig<kotlin.Any?>(
RequestMethod.DELETE,
"/store/order/{orderId}".replace("{" + "orderId" + "}", "$orderId"),
query = localVariableQuery,
headers = localVariableHeaders
)
return request(
localVariableConfig,
localVariableBody,
localVariableAuthNames
).wrap()
}
/**
* Returns pet inventories by status
* Returns a map of status codes to quantities
* @return kotlin.collections.Map<kotlin.String, kotlin.Int>
*/
@Suppress("UNCHECKED_CAST")
open suspend fun getInventory(): HttpResponse<kotlin.collections.Map<kotlin.String, kotlin.Int>> {
val localVariableAuthNames = listOf<String>("api_key")
val localVariableBody =
io.ktor.client.utils.EmptyContent
val localVariableQuery = mutableMapOf<String, List<String>>()
val localVariableHeaders = mutableMapOf<String, String>()
val localVariableConfig = RequestConfig<kotlin.Any?>(
RequestMethod.GET,
"/store/inventory",
query = localVariableQuery,
headers = localVariableHeaders
)
return request(
localVariableConfig,
localVariableBody,
localVariableAuthNames
).wrap()
}
/**
* Find purchase order by ID
* For valid response try integer IDs with value &lt;&#x3D; 5 or &gt; 10. Other values will generated exceptions
* @param orderId ID of pet that needs to be fetched
* @return Order
*/
@Suppress("UNCHECKED_CAST")
open suspend fun getOrderById(orderId: kotlin.Long): HttpResponse<Order> {
val localVariableAuthNames = listOf<String>()
val localVariableBody =
io.ktor.client.utils.EmptyContent
val localVariableQuery = mutableMapOf<String, List<String>>()
val localVariableHeaders = mutableMapOf<String, String>()
val localVariableConfig = RequestConfig<kotlin.Any?>(
RequestMethod.GET,
"/store/order/{orderId}".replace("{" + "orderId" + "}", "$orderId"),
query = localVariableQuery,
headers = localVariableHeaders
)
return request(
localVariableConfig,
localVariableBody,
localVariableAuthNames
).wrap()
}
/**
* Place an order for a pet
*
* @param body order placed for purchasing the pet
* @return Order
*/
@Suppress("UNCHECKED_CAST")
open suspend fun placeOrder(body: Order): HttpResponse<Order> {
val localVariableAuthNames = listOf<String>()
val localVariableBody = body
val localVariableQuery = mutableMapOf<String, List<String>>()
val localVariableHeaders = mutableMapOf<String, String>()
val localVariableConfig = RequestConfig<kotlin.Any?>(
RequestMethod.POST,
"/store/order",
query = localVariableQuery,
headers = localVariableHeaders
)
return jsonRequest(
localVariableConfig,
localVariableBody,
localVariableAuthNames
).wrap()
}
}

View File

@@ -0,0 +1,289 @@
/**
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* The version of the OpenAPI document: 1.0.0
*
*
* Please note:
* This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* Do not edit this file manually.
*/
@file:Suppress(
"ArrayInDataClass",
"EnumEntryName",
"RemoveRedundantQualifierName",
"UnusedImport"
)
package org.openapitools.client.apis
import org.openapitools.client.models.User
import org.openapitools.client.infrastructure.*
import io.ktor.client.HttpClientConfig
import io.ktor.client.request.forms.formData
import io.ktor.client.engine.HttpClientEngine
import io.ktor.http.ParametersBuilder
import com.fasterxml.jackson.databind.ObjectMapper
open class UserApi(
baseUrl: String = ApiClient.BASE_URL,
httpClientEngine: HttpClientEngine? = null,
httpClientConfig: ((HttpClientConfig<*>) -> Unit)? = null,
json: ObjectMapper = ApiClient.JSON_DEFAULT,
) : ApiClient(baseUrl, httpClientEngine, httpClientConfig, json) {
/**
* Create user
* This can only be done by the logged in user.
* @param body Created user object
* @return void
*/
open suspend fun createUser(body: User): HttpResponse<Unit> {
val localVariableAuthNames = listOf<String>()
val localVariableBody = body
val localVariableQuery = mutableMapOf<String, List<String>>()
val localVariableHeaders = mutableMapOf<String, String>()
val localVariableConfig = RequestConfig<kotlin.Any?>(
RequestMethod.POST,
"/user",
query = localVariableQuery,
headers = localVariableHeaders
)
return jsonRequest(
localVariableConfig,
localVariableBody,
localVariableAuthNames
).wrap()
}
/**
* Creates list of users with given input array
*
* @param body List of user object
* @return void
*/
open suspend fun createUsersWithArrayInput(body: kotlin.collections.List<User>): HttpResponse<Unit> {
val localVariableAuthNames = listOf<String>()
val localVariableBody = body
val localVariableQuery = mutableMapOf<String, List<String>>()
val localVariableHeaders = mutableMapOf<String, String>()
val localVariableConfig = RequestConfig<kotlin.Any?>(
RequestMethod.POST,
"/user/createWithArray",
query = localVariableQuery,
headers = localVariableHeaders
)
return jsonRequest(
localVariableConfig,
localVariableBody,
localVariableAuthNames
).wrap()
}
/**
* Creates list of users with given input array
*
* @param body List of user object
* @return void
*/
open suspend fun createUsersWithListInput(body: kotlin.collections.List<User>): HttpResponse<Unit> {
val localVariableAuthNames = listOf<String>()
val localVariableBody = body
val localVariableQuery = mutableMapOf<String, List<String>>()
val localVariableHeaders = mutableMapOf<String, String>()
val localVariableConfig = RequestConfig<kotlin.Any?>(
RequestMethod.POST,
"/user/createWithList",
query = localVariableQuery,
headers = localVariableHeaders
)
return jsonRequest(
localVariableConfig,
localVariableBody,
localVariableAuthNames
).wrap()
}
/**
* Delete user
* This can only be done by the logged in user.
* @param username The name that needs to be deleted
* @return void
*/
open suspend fun deleteUser(username: kotlin.String): HttpResponse<Unit> {
val localVariableAuthNames = listOf<String>()
val localVariableBody =
io.ktor.client.utils.EmptyContent
val localVariableQuery = mutableMapOf<String, List<String>>()
val localVariableHeaders = mutableMapOf<String, String>()
val localVariableConfig = RequestConfig<kotlin.Any?>(
RequestMethod.DELETE,
"/user/{username}".replace("{" + "username" + "}", "$username"),
query = localVariableQuery,
headers = localVariableHeaders
)
return request(
localVariableConfig,
localVariableBody,
localVariableAuthNames
).wrap()
}
/**
* Get user by user name
*
* @param username The name that needs to be fetched. Use user1 for testing.
* @return User
*/
@Suppress("UNCHECKED_CAST")
open suspend fun getUserByName(username: kotlin.String): HttpResponse<User> {
val localVariableAuthNames = listOf<String>()
val localVariableBody =
io.ktor.client.utils.EmptyContent
val localVariableQuery = mutableMapOf<String, List<String>>()
val localVariableHeaders = mutableMapOf<String, String>()
val localVariableConfig = RequestConfig<kotlin.Any?>(
RequestMethod.GET,
"/user/{username}".replace("{" + "username" + "}", "$username"),
query = localVariableQuery,
headers = localVariableHeaders
)
return request(
localVariableConfig,
localVariableBody,
localVariableAuthNames
).wrap()
}
/**
* Logs user into the system
*
* @param username The user name for login
* @param password The password for login in clear text
* @return kotlin.String
*/
@Suppress("UNCHECKED_CAST")
open suspend fun loginUser(username: kotlin.String, password: kotlin.String): HttpResponse<kotlin.String> {
val localVariableAuthNames = listOf<String>()
val localVariableBody =
io.ktor.client.utils.EmptyContent
val localVariableQuery = mutableMapOf<String, List<String>>()
username?.apply { localVariableQuery["username"] = listOf("$username") }
password?.apply { localVariableQuery["password"] = listOf("$password") }
val localVariableHeaders = mutableMapOf<String, String>()
val localVariableConfig = RequestConfig<kotlin.Any?>(
RequestMethod.GET,
"/user/login",
query = localVariableQuery,
headers = localVariableHeaders
)
return request(
localVariableConfig,
localVariableBody,
localVariableAuthNames
).wrap()
}
/**
* Logs out current logged in user session
*
* @return void
*/
open suspend fun logoutUser(): HttpResponse<Unit> {
val localVariableAuthNames = listOf<String>()
val localVariableBody =
io.ktor.client.utils.EmptyContent
val localVariableQuery = mutableMapOf<String, List<String>>()
val localVariableHeaders = mutableMapOf<String, String>()
val localVariableConfig = RequestConfig<kotlin.Any?>(
RequestMethod.GET,
"/user/logout",
query = localVariableQuery,
headers = localVariableHeaders
)
return request(
localVariableConfig,
localVariableBody,
localVariableAuthNames
).wrap()
}
/**
* Updated user
* This can only be done by the logged in user.
* @param username name that need to be deleted
* @param body Updated user object
* @return void
*/
open suspend fun updateUser(username: kotlin.String, body: User): HttpResponse<Unit> {
val localVariableAuthNames = listOf<String>()
val localVariableBody = body
val localVariableQuery = mutableMapOf<String, List<String>>()
val localVariableHeaders = mutableMapOf<String, String>()
val localVariableConfig = RequestConfig<kotlin.Any?>(
RequestMethod.PUT,
"/user/{username}".replace("{" + "username" + "}", "$username"),
query = localVariableQuery,
headers = localVariableHeaders
)
return jsonRequest(
localVariableConfig,
localVariableBody,
localVariableAuthNames
).wrap()
}
}

View File

@@ -0,0 +1,16 @@
package org.openapitools.client.auth
class ApiKeyAuth(private val location: String, val paramName: String) : Authentication {
var apiKey: String? = null
var apiKeyPrefix: String? = null
override fun apply(query: MutableMap<String, List<String>>, headers: MutableMap<String, String>) {
val key: String = apiKey ?: return
val prefix: String? = apiKeyPrefix
val value: String = if (prefix != null) "$prefix $key" else key
when (location) {
"query" -> query[paramName] = listOf(value)
"header" -> headers[paramName] = value
}
}
}

View File

@@ -0,0 +1,13 @@
package org.openapitools.client.auth
interface Authentication {
/**
* Apply authentication settings to header and query params.
*
* @param query Query parameters.
* @param headers Header parameters.
*/
fun apply(query: MutableMap<String, List<String>>, headers: MutableMap<String, String>)
}

View File

@@ -0,0 +1,17 @@
package org.openapitools.client.auth
import io.ktor.util.InternalAPI
import io.ktor.util.encodeBase64
class HttpBasicAuth : Authentication {
var username: String? = null
var password: String? = null
@OptIn(InternalAPI::class)
override fun apply(query: MutableMap<String, List<String>>, headers: MutableMap<String, String>) {
if (username == null && password == null) return
val str = (username ?: "") + ":" + (password ?: "")
val auth = str.encodeBase64()
headers["Authorization"] = "Basic $auth"
}
}

View File

@@ -0,0 +1,14 @@
package org.openapitools.client.auth
class HttpBearerAuth(private val scheme: String?) : Authentication {
var bearerToken: String? = null
override fun apply(query: MutableMap<String, List<String>>, headers: MutableMap<String, String>) {
val token: String = bearerToken ?: return
headers["Authorization"] = (if (scheme != null) upperCaseBearer(scheme)!! + " " else "") + token
}
private fun upperCaseBearer(scheme: String): String? {
return if ("bearer".equals(scheme, ignoreCase = true)) "Bearer" else scheme
}
}

View File

@@ -0,0 +1,10 @@
package org.openapitools.client.auth
class OAuth : Authentication {
var accessToken: String? = null
override fun apply(query: MutableMap<String, List<String>>, headers: MutableMap<String, String>) {
val token: String = accessToken ?: return
headers["Authorization"] = "Bearer $token"
}
}

View File

@@ -0,0 +1,23 @@
package org.openapitools.client.infrastructure
typealias MultiValueMap = MutableMap<String,List<String>>
fun collectionDelimiter(collectionFormat: String) = when(collectionFormat) {
"csv" -> ","
"tsv" -> "\t"
"pipe" -> "|"
"space" -> " "
else -> ""
}
val defaultMultiValueConverter: (item: Any?) -> String = { item -> "$item" }
fun <T : Any?> toMultiValue(items: Array<T>, collectionFormat: String, map: (item: T) -> String = defaultMultiValueConverter)
= toMultiValue(items.asIterable(), collectionFormat, map)
fun <T : Any?> toMultiValue(items: Iterable<T>, collectionFormat: String, map: (item: T) -> String = defaultMultiValueConverter): List<String> {
return when(collectionFormat) {
"multi" -> items.map(map)
else -> listOf(items.joinToString(separator = collectionDelimiter(collectionFormat), transform = map))
}
}

View File

@@ -0,0 +1,195 @@
package org.openapitools.client.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.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.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.content.PartData
import kotlin.Unit
import com.fasterxml.jackson.databind.ObjectMapper
import org.openapitools.client.auth.*
open class ApiClient(
private val baseUrl: String,
httpClientEngine: HttpClientEngine?,
httpClientConfig: ((HttpClientConfig<*>) -> Unit)? = null,
json: ObjectMapper,
) {
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 }
httpClientConfig?.invoke(it)
}
}
private val client: HttpClient by lazy {
httpClientEngine?.let { HttpClient(it, clientConfig) } ?: HttpClient(clientConfig)
}
private val authentications: kotlin.collections.Map<String, Authentication> by lazy {
mapOf(
"api_key" to ApiKeyAuth("header", "api_key"),
"petstore_auth" to OAuth())
}
companion object {
const val BASE_URL = "http://petstore.swagger.io/v2"
val JSON_DEFAULT = ObjectMapper()
protected val UNSAFE_HEADERS = listOf(HttpHeaders.ContentType)
}
/**
* Set the username for the first HTTP basic authentication.
*
* @param username Username
*/
fun setUsername(username: String) {
val auth = authentications?.values?.firstOrNull { it is HttpBasicAuth } as HttpBasicAuth?
?: throw Exception("No HTTP basic authentication configured")
auth.username = username
}
/**
* Set the password for the first HTTP basic authentication.
*
* @param password Password
*/
fun setPassword(password: String) {
val auth = authentications?.values?.firstOrNull { it is HttpBasicAuth } as HttpBasicAuth?
?: throw Exception("No HTTP basic authentication configured")
auth.password = password
}
/**
* Set the API key value for the first API key authentication.
*
* @param apiKey API key
* @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?
?: throw Exception("No API key authentication configured")
auth.apiKey = apiKey
}
/**
* Set the API key prefix for the first API key authentication.
*
* @param apiKeyPrefix API key prefix
* @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?
?: throw Exception("No API key authentication configured")
auth.apiKeyPrefix = apiKeyPrefix
}
/**
* Set the access token for the first OAuth2 authentication.
*
* @param accessToken Access token
*/
fun setAccessToken(accessToken: String) {
val auth = authentications?.values?.firstOrNull { it is OAuth } as OAuth?
?: throw Exception("No OAuth2 authentication configured")
auth.accessToken = accessToken
}
/**
* Set the access token for the first Bearer authentication.
*
* @param bearerToken The bearer token.
*/
fun setBearerToken(bearerToken: String) {
val auth = authentications?.values?.firstOrNull { it is HttpBearerAuth } as HttpBearerAuth?
?: throw Exception("No Bearer authentication configured")
auth.bearerToken = bearerToken
}
protected suspend fun <T: Any?> multipartFormRequest(requestConfig: RequestConfig<T>, body: kotlin.collections.List<PartData>?, authNames: kotlin.collections.List<String>): HttpResponse {
return request(requestConfig, MultiPartFormDataContent(body ?: listOf()), authNames)
}
protected suspend fun <T: Any?> urlEncodedFormRequest(requestConfig: RequestConfig<T>, body: Parameters?, authNames: kotlin.collections.List<String>): HttpResponse {
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?> request(requestConfig: RequestConfig<T>, body: OutgoingContent = EmptyContent, authNames: kotlin.collections.List<String>): HttpResponse {
requestConfig.updateForAuth<T>(authNames)
val headers = requestConfig.headers
return client.request<HttpResponse> {
this.url {
this.takeFrom(URLBuilder(baseUrl))
appendPath(requestConfig.path.trimStart('/').split('/'))
requestConfig.query.forEach { query ->
query.value.forEach { value ->
parameter(query.key, value)
}
}
}
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
}
}
private fun <T: Any?> RequestConfig<T>.updateForAuth(authNames: kotlin.collections.List<String>) {
for (authName in authNames) {
val auth = authentications?.get(authName) ?: throw Exception("Authentication undefined: $authName")
auth.apply(query, headers)
}
}
private fun URLBuilder.appendPath(components: kotlin.collections.List<String>): URLBuilder = apply {
encodedPath = encodedPath.trimEnd('/') + components.joinToString("/", prefix = "/") { it.encodeURLQueryComponent() }
}
private val RequestMethod.httpMethod: HttpMethod
get() = when (this) {
RequestMethod.DELETE -> HttpMethod.Delete
RequestMethod.GET -> HttpMethod.Get
RequestMethod.HEAD -> HttpMethod.Head
RequestMethod.PATCH -> HttpMethod.Patch
RequestMethod.PUT -> HttpMethod.Put
RequestMethod.POST -> HttpMethod.Post
RequestMethod.OPTIONS -> HttpMethod.Options
}
}
private class JsonSerializerImpl(private val objectMapper: ObjectMapper) : JsonSerializer {
override fun write(data: Any, contentType: ContentType): OutgoingContent =
ByteArrayContent(objectMapper.writeValueAsBytes(data), contentType)
}

View File

@@ -0,0 +1,51 @@
package org.openapitools.client.infrastructure
import io.ktor.client.call.TypeInfo
import io.ktor.client.call.typeInfo
import io.ktor.http.Headers
import io.ktor.http.isSuccess
open class HttpResponse<T : Any>(val response: io.ktor.client.statement.HttpResponse, val provider: BodyProvider<T>) {
val status: Int = response.status.value
val success: Boolean = response.status.isSuccess()
val headers: Map<String, List<String>> = response.headers.mapEntries()
suspend fun body(): T = provider.body(response)
suspend fun <V : Any> typedBody(type: TypeInfo): V = provider.typedBody(response, type)
companion object {
private fun Headers.mapEntries(): Map<String, List<String>> {
val result = mutableMapOf<String, List<String>>()
entries().forEach { result[it.key] = it.value }
return result
}
}
}
interface BodyProvider<T : Any> {
suspend fun body(response: io.ktor.client.statement.HttpResponse): T
suspend fun <V : Any> typedBody(response: io.ktor.client.statement.HttpResponse, type: TypeInfo): V
}
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
@Suppress("UNCHECKED_CAST")
override suspend fun <V : Any> typedBody(response: io.ktor.client.statement.HttpResponse, type: TypeInfo): V =
response.call.receive(type) as V
}
class MappedBodyProvider<S : Any, T : Any>(private val provider: BodyProvider<S>, private val block: S.() -> T) : BodyProvider<T> {
override suspend fun body(response: io.ktor.client.statement.HttpResponse): T =
block(provider.body(response))
override suspend fun <V : Any> typedBody(response: io.ktor.client.statement.HttpResponse, type: TypeInfo): V =
provider.typedBody(response, type)
}
inline fun <reified T : Any> io.ktor.client.statement.HttpResponse.wrap(): HttpResponse<T> =
HttpResponse(this, TypedBodyProvider(typeInfo<T>()))
fun <T : Any, V : Any> HttpResponse<T>.map(block: T.() -> V): HttpResponse<V> =
HttpResponse(response, MappedBodyProvider(provider, block))

View File

@@ -0,0 +1,17 @@
package org.openapitools.client.infrastructure
/**
* Defines a config object for a given request.
* NOTE: This object doesn't include 'body' because it
* allows for caching of the constructed object
* for many request definitions.
* NOTE: Headers is a Map<String,String> because rfc2616 defines
* multi-valued headers as csv-only.
*/
data class RequestConfig<T>(
val method: RequestMethod,
val path: String,
val headers: MutableMap<String, String> = mutableMapOf(),
val query: MutableMap<String, List<String>> = mutableMapOf(),
val body: T? = null
)

View File

@@ -0,0 +1,8 @@
package org.openapitools.client.infrastructure
/**
* Provides enumerated HTTP verbs
*/
enum class RequestMethod {
GET, DELETE, HEAD, OPTIONS, PATCH, POST, PUT
}

View File

@@ -0,0 +1,42 @@
/**
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* The version of the OpenAPI document: 1.0.0
*
*
* Please note:
* This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* Do not edit this file manually.
*/
@file:Suppress(
"ArrayInDataClass",
"EnumEntryName",
"RemoveRedundantQualifierName",
"UnusedImport"
)
package org.openapitools.client.models
import com.fasterxml.jackson.annotation.JsonProperty
/**
* A category for a pet
*
* @param id
* @param name
*/
data class Category (
@field:JsonProperty("id")
val id: kotlin.Long? = null,
@field:JsonProperty("name")
val name: kotlin.String? = null
)

View File

@@ -0,0 +1,46 @@
/**
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* The version of the OpenAPI document: 1.0.0
*
*
* Please note:
* This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* Do not edit this file manually.
*/
@file:Suppress(
"ArrayInDataClass",
"EnumEntryName",
"RemoveRedundantQualifierName",
"UnusedImport"
)
package org.openapitools.client.models
import com.fasterxml.jackson.annotation.JsonProperty
/**
* Describes the result of uploading an image resource
*
* @param code
* @param type
* @param message
*/
data class ModelApiResponse (
@field:JsonProperty("code")
val code: kotlin.Int? = null,
@field:JsonProperty("type")
val type: kotlin.String? = null,
@field:JsonProperty("message")
val message: kotlin.String? = null
)

View File

@@ -0,0 +1,72 @@
/**
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* The version of the OpenAPI document: 1.0.0
*
*
* Please note:
* This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* Do not edit this file manually.
*/
@file:Suppress(
"ArrayInDataClass",
"EnumEntryName",
"RemoveRedundantQualifierName",
"UnusedImport"
)
package org.openapitools.client.models
import com.fasterxml.jackson.annotation.JsonProperty
/**
* An order for a pets from the pet store
*
* @param id
* @param petId
* @param quantity
* @param shipDate
* @param status Order Status
* @param complete
*/
data class Order (
@field:JsonProperty("id")
val id: kotlin.Long? = null,
@field:JsonProperty("petId")
val petId: kotlin.Long? = null,
@field:JsonProperty("quantity")
val quantity: kotlin.Int? = null,
@field:JsonProperty("shipDate")
val shipDate: java.time.OffsetDateTime? = null,
/* Order Status */
@field:JsonProperty("status")
val status: Order.Status? = null,
@field:JsonProperty("complete")
val complete: kotlin.Boolean? = false
) {
/**
* Order Status
*
* Values: placed,approved,delivered,unknownDefaultOpenApi
*/
enum class Status(val value: kotlin.String) {
@JsonProperty(value = "placed") placed("placed"),
@JsonProperty(value = "approved") approved("approved"),
@JsonProperty(value = "delivered") delivered("delivered"),
@JsonProperty(value = "unknown_default_open_api") unknownDefaultOpenApi("unknown_default_open_api");
}
}

View File

@@ -0,0 +1,74 @@
/**
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* The version of the OpenAPI document: 1.0.0
*
*
* Please note:
* This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* Do not edit this file manually.
*/
@file:Suppress(
"ArrayInDataClass",
"EnumEntryName",
"RemoveRedundantQualifierName",
"UnusedImport"
)
package org.openapitools.client.models
import org.openapitools.client.models.Category
import org.openapitools.client.models.Tag
import com.fasterxml.jackson.annotation.JsonProperty
/**
* A pet for sale in the pet store
*
* @param name
* @param photoUrls
* @param id
* @param category
* @param tags
* @param status pet status in the store
*/
data class Pet (
@field:JsonProperty("name")
val name: kotlin.String,
@field:JsonProperty("photoUrls")
val photoUrls: kotlin.collections.List<kotlin.String>,
@field:JsonProperty("id")
val id: kotlin.Long? = null,
@field:JsonProperty("category")
val category: Category? = null,
@field:JsonProperty("tags")
val tags: kotlin.collections.List<Tag>? = null,
/* pet status in the store */
@field:JsonProperty("status")
val status: Pet.Status? = null
) {
/**
* pet status in the store
*
* Values: available,pending,sold,unknownDefaultOpenApi
*/
enum class Status(val value: kotlin.String) {
@JsonProperty(value = "available") available("available"),
@JsonProperty(value = "pending") pending("pending"),
@JsonProperty(value = "sold") sold("sold"),
@JsonProperty(value = "unknown_default_open_api") unknownDefaultOpenApi("unknown_default_open_api");
}
}

View File

@@ -0,0 +1,42 @@
/**
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* The version of the OpenAPI document: 1.0.0
*
*
* Please note:
* This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* Do not edit this file manually.
*/
@file:Suppress(
"ArrayInDataClass",
"EnumEntryName",
"RemoveRedundantQualifierName",
"UnusedImport"
)
package org.openapitools.client.models
import com.fasterxml.jackson.annotation.JsonProperty
/**
* A tag for a pet
*
* @param id
* @param name
*/
data class Tag (
@field:JsonProperty("id")
val id: kotlin.Long? = null,
@field:JsonProperty("name")
val name: kotlin.String? = null
)

View File

@@ -0,0 +1,67 @@
/**
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* The version of the OpenAPI document: 1.0.0
*
*
* Please note:
* This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* Do not edit this file manually.
*/
@file:Suppress(
"ArrayInDataClass",
"EnumEntryName",
"RemoveRedundantQualifierName",
"UnusedImport"
)
package org.openapitools.client.models
import com.fasterxml.jackson.annotation.JsonProperty
/**
* A User who is purchasing from the pet store
*
* @param id
* @param username
* @param firstName
* @param lastName
* @param email
* @param password
* @param phone
* @param userStatus User Status
*/
data class User (
@field:JsonProperty("id")
val id: kotlin.Long? = null,
@field:JsonProperty("username")
val username: kotlin.String? = null,
@field:JsonProperty("firstName")
val firstName: kotlin.String? = null,
@field:JsonProperty("lastName")
val lastName: kotlin.String? = null,
@field:JsonProperty("email")
val email: kotlin.String? = null,
@field:JsonProperty("password")
val password: kotlin.String? = null,
@field:JsonProperty("phone")
val phone: kotlin.String? = null,
/* User Status */
@field:JsonProperty("userStatus")
val userStatus: kotlin.Int? = null
)