diff --git a/.gitignore b/.gitignore index 558b9460112..942cbf75688 100644 --- a/.gitignore +++ b/.gitignore @@ -175,12 +175,14 @@ samples/client/petstore/typescript-angular/tsd-debug.log # aspnetcore samples/server/petstore/aspnetcore/.vs/ effective.pom + # kotlin samples/client/petstore/kotlin/src/main/kotlin/test/ samples/client/petstore/kotlin-threetenbp/build samples/client/petstore/kotlin-string/build -samples/server/petstore/kotlin-server/ktor/build samples/openapi3/client/petstore/kotlin/build +samples/server/petstore/kotlin-server/ktor/build +samples/server/petstore/kotlin-springboot/build \? # haskell diff --git a/docs/generators/kotlin-server.md b/docs/generators/kotlin-server.md index e9f60d115b3..161ca6d0a96 100644 --- a/docs/generators/kotlin-server.md +++ b/docs/generators/kotlin-server.md @@ -8,14 +8,14 @@ sidebar_label: kotlin-server | Option | Description | Values | Default | | ------ | ----------- | ------ | ------- | |sourceFolder|source folder for generated code| |src/main/kotlin| -|packageName|Generated artifact package name.| |org.openapitools| +|packageName|Generated artifact package name.| |org.openapitools.server| |apiSuffix|suffix for api classes| |Api| |groupId|Generated artifact package's organization (i.e. maven groupId).| |org.openapitools| -|artifactId|Generated artifact id (name of jar).| |null| +|artifactId|Generated artifact id (name of jar).| |kotlin-server| |artifactVersion|Generated artifact's package version.| |1.0.0| |enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |camelCase| |parcelizeModels|toggle "@Parcelize" for generated models| |null| -|library|library template (sub-template) to use|
**ktor**
ktor framework
|ktor| +|library|library template (sub-template)|
**ktor**
ktor framework
|ktor| |featureAutoHead|Automatically provide responses to HEAD requests for existing routes that have the GET verb defined.| |true| |featureConditionalHeaders|Avoid sending content if client already has same content, by checking ETag or LastModified properties.| |false| |featureHSTS|Avoid sending content if client already has same content, by checking ETag or LastModified properties.| |true| diff --git a/docs/generators/kotlin-spring.md b/docs/generators/kotlin-spring.md index 1e7f3bede7f..29f53a6c1ed 100644 --- a/docs/generators/kotlin-spring.md +++ b/docs/generators/kotlin-spring.md @@ -11,7 +11,7 @@ sidebar_label: kotlin-spring |packageName|Generated artifact package name.| |org.openapitools| |apiSuffix|suffix for api classes| |Api| |groupId|Generated artifact package's organization (i.e. maven groupId).| |org.openapitools| -|artifactId|Generated artifact id (name of jar).| |null| +|artifactId|Generated artifact id (name of jar).| |openapi-spring| |artifactVersion|Generated artifact's package version.| |1.0.0| |enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |camelCase| |parcelizeModels|toggle "@Parcelize" for generated models| |null| @@ -26,4 +26,4 @@ sidebar_label: kotlin-spring |serviceInterface|generate service interfaces to go alongside controllers. In most cases this option would be used to update an existing project, so not to override implementations. Useful to help facilitate the generation gap pattern| |false| |serviceImplementation|generate stub service implementations that extends service interfaces. If this is set to true service interfaces will also be generated| |false| |useBeanValidation|Use BeanValidation API annotations to validate data types| |true| -|library|library template (sub-template) to use|
**spring-boot**
Spring-boot Server application.
|spring-boot| +|library|library template (sub-template)|
**spring-boot**
Spring-boot Server application.
|spring-boot| diff --git a/docs/generators/kotlin.md b/docs/generators/kotlin.md index d6cbf2f5a69..008cf3ccce9 100644 --- a/docs/generators/kotlin.md +++ b/docs/generators/kotlin.md @@ -8,12 +8,12 @@ sidebar_label: kotlin | Option | Description | Values | Default | | ------ | ----------- | ------ | ------- | |sourceFolder|source folder for generated code| |src/main/kotlin| -|packageName|Generated artifact package name.| |org.openapitools| +|packageName|Generated artifact package name.| |org.openapitools.client| |apiSuffix|suffix for api classes| |Api| |groupId|Generated artifact package's organization (i.e. maven groupId).| |org.openapitools| -|artifactId|Generated artifact id (name of jar).| |null| +|artifactId|Generated artifact id (name of jar).| |kotlin-client| |artifactVersion|Generated artifact's package version.| |1.0.0| |enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |camelCase| |parcelizeModels|toggle "@Parcelize" for generated models| |null| -|dateLibrary|Option. Date library to use|
**string**
String
**java8**
Java 8 native JSR310
**threetenbp**
Threetenbp
|null| -|collectionType|Option. Collection type to use|
**array**
kotlin.Array
**list**
kotlin.collections.List
|null| +|dateLibrary|Option. Date library to use|
**string**
String
**java8**
Java 8 native JSR310
**threetenbp**
Threetenbp
|java8| +|collectionType|Option. Collection type to use|
**array**
kotlin.Array
**list**
kotlin.collections.List
|array| diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java index 766f8c51840..35c8a83aaa2 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java @@ -102,7 +102,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen apiPackage = "org.openapitools.client.api"; modelPackage = "org.openapitools.client.model"; - // clioOptions default redifinition need to be updated + // cliOptions default redefinition need to be updated updateOption(CodegenConstants.INVOKER_PACKAGE, this.getInvokerPackage()); updateOption(CodegenConstants.ARTIFACT_ID, this.getArtifactId()); updateOption(CodegenConstants.API_PACKAGE, apiPackage); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinClientCodegen.java index 2795ad22bb3..7b18594f2e5 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinClientCodegen.java @@ -21,8 +21,6 @@ import org.openapitools.codegen.CliOption; import org.openapitools.codegen.CodegenConstants; import org.openapitools.codegen.CodegenType; import org.openapitools.codegen.SupportingFile; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.io.File; import java.util.HashMap; @@ -32,7 +30,6 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen { public static final String DATE_LIBRARY = "dateLibrary"; public static final String COLLECTION_TYPE = "collectionType"; - private static final Logger LOGGER = LoggerFactory.getLogger(KotlinClientCodegen.class); protected String dateLibrary = DateLibrary.JAVA8.value; protected String collectionType = CollectionType.ARRAY.value; @@ -69,6 +66,10 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen { artifactId = "kotlin-client"; packageName = "org.openapitools.client"; + // cliOptions default redefinition need to be updated + updateOption(CodegenConstants.ARTIFACT_ID, this.artifactId); + updateOption(CodegenConstants.PACKAGE_NAME, this.packageName); + outputFolder = "generated-code" + File.separator + "kotlin-client"; modelTemplateFiles.put("model.mustache", ".kt"); apiTemplateFiles.put("api.mustache", ".kt"); @@ -78,14 +79,13 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen { apiPackage = packageName + ".apis"; modelPackage = packageName + ".models"; - enumPropertyNaming = CodegenConstants.ENUM_PROPERTY_NAMING_TYPE.camelCase; - CliOption dateLibrary = new CliOption(DATE_LIBRARY, "Option. Date library to use"); Map dateOptions = new HashMap<>(); dateOptions.put(DateLibrary.THREETENBP.value, "Threetenbp"); dateOptions.put(DateLibrary.STRING.value, "String"); dateOptions.put(DateLibrary.JAVA8.value, "Java 8 native JSR310"); dateLibrary.setEnum(dateOptions); + dateLibrary.setDefault(this.dateLibrary); cliOptions.add(dateLibrary); CliOption collectionType = new CliOption(COLLECTION_TYPE, "Option. Collection type to use"); @@ -93,6 +93,7 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen { collectionOptions.put(CollectionType.ARRAY.value, "kotlin.Array"); collectionOptions.put(CollectionType.LIST.value, "kotlin.collections.List"); collectionType.setEnum(collectionOptions); + collectionType.setDefault(this.collectionType); cliOptions.add(collectionType); } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinServerCodegen.java index 8c31c1a8a5e..80e48bf0bc0 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinServerCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinServerCodegen.java @@ -62,6 +62,11 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen { artifactId = "kotlin-server"; packageName = "org.openapitools.server"; + + // cliOptions default redefinition need to be updated + updateOption(CodegenConstants.ARTIFACT_ID, this.artifactId); + updateOption(CodegenConstants.PACKAGE_NAME, this.packageName); + outputFolder = "generated-code" + File.separator + "kotlin-server"; modelTemplateFiles.put("model.mustache", ".kt"); apiTemplateFiles.put("api.mustache", ".kt"); @@ -69,10 +74,10 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen { apiPackage = packageName + ".apis"; modelPackage = packageName + ".models"; - supportedLibraries.put("ktor", "ktor framework"); + supportedLibraries.put(Constants.KTOR, "ktor framework"); // TODO: Configurable server engine. Defaults to netty in build.gradle. - CliOption library = new CliOption(CodegenConstants.LIBRARY, "library template (sub-template) to use"); + CliOption library = new CliOption(CodegenConstants.LIBRARY, CodegenConstants.LIBRARY_DESC); library.setDefault(DEFAULT_LIBRARY); library.setEnum(supportedLibraries); @@ -147,9 +152,9 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen { // set default library to "ktor" if (StringUtils.isEmpty(library)) { - this.setLibrary("ktor"); - additionalProperties.put(CodegenConstants.LIBRARY, "ktor"); - LOGGER.info("`library` option is empty. Default to 'ktor'."); + this.setLibrary(DEFAULT_LIBRARY); + additionalProperties.put(CodegenConstants.LIBRARY, DEFAULT_LIBRARY); + LOGGER.info("`library` option is empty. Default to " + DEFAULT_LIBRARY); } if (additionalProperties.containsKey(Constants.AUTOMATIC_HEAD_REQUESTS)) { @@ -182,7 +187,7 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen { additionalProperties.put(Constants.COMPRESSION, getCompressionFeatureEnabled()); } - Boolean generateApis = additionalProperties.containsKey(CodegenConstants.GENERATE_APIS) && (Boolean)additionalProperties.get(CodegenConstants.GENERATE_APIS); + boolean generateApis = additionalProperties.containsKey(CodegenConstants.GENERATE_APIS) && (Boolean)additionalProperties.get(CodegenConstants.GENERATE_APIS); String packageFolder = (sourceFolder + File.separator + packageName).replace(".", File.separator); String resourcesFolder = "src/main/resources"; // not sure this can be user configurable. @@ -226,7 +231,7 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen { if (objs.containsKey("lambda")) { LOGGER.warn("A property named 'lambda' already exists. Mustache lambdas renamed from 'lambda' to '_lambda'. " + "You'll likely need to use a custom template, " + - "see https://github.com/swagger-api/swagger-codegen#modifying-the-client-library-format. "); // TODO: update the URL + "see https://github.com/OpenAPITools/openapi-generator/blob/master/docs/templating.md. "); objs.put("_lambda", lambdas); } else { objs.put("lambda", lambdas); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinSpringServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinSpringServerCodegen.java index 8536e099ca4..36fbb492475 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinSpringServerCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinSpringServerCodegen.java @@ -87,6 +87,9 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen apiPackage = "org.openapitools.api"; modelPackage = "org.openapitools.model"; + // cliOptions default redefinition need to be updated + updateOption(CodegenConstants.ARTIFACT_ID, this.artifactId); + // Use lists instead of arrays typeMapping.put("array", "List"); typeMapping.put("string", "String"); @@ -149,7 +152,7 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen supportedLibraries.put(SPRING_BOOT, "Spring-boot Server application."); setLibrary(SPRING_BOOT); - CliOption cliOpt = new CliOption(CodegenConstants.LIBRARY, "library template (sub-template) to use"); + CliOption cliOpt = new CliOption(CodegenConstants.LIBRARY, CodegenConstants.LIBRARY_DESC); cliOpt.setDefault(SPRING_BOOT); cliOpt.setEnum(supportedLibraries); cliOptions.add(cliOpt); diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/README.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/README.mustache index 2760de821a8..b85f67281d0 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/README.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/README.mustache @@ -2,7 +2,7 @@ ## Requires -* Kotlin 1.3.20 +* Kotlin 1.3.31 * Gradle 4.9 ## Build diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/api.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/api.mustache index cea3724397f..012baf0fdca 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/api.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/api.mustache @@ -4,7 +4,17 @@ package {{apiPackage}} {{#imports}}import {{import}} {{/imports}} -import {{packageName}}.infrastructure.* +import {{packageName}}.infrastructure.ApiClient +import {{packageName}}.infrastructure.ClientException +import {{packageName}}.infrastructure.ClientError +import {{packageName}}.infrastructure.ServerException +import {{packageName}}.infrastructure.ServerError +import {{packageName}}.infrastructure.MultiValueMap +import {{packageName}}.infrastructure.RequestConfig +import {{packageName}}.infrastructure.RequestMethod +import {{packageName}}.infrastructure.ResponseType +import {{packageName}}.infrastructure.Success +import {{packageName}}.infrastructure.toMultiValue {{#threetenbp}} import org.threeten.bp.LocalDateTime {{/threetenbp}} @@ -23,7 +33,7 @@ class {{classname}}(basePath: kotlin.String = "{{{basePath}}}") : ApiClient(base fun {{operationId}}({{#allParams}}{{paramName}}: {{{dataType}}}{{^required}}?{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) : {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Unit{{/returnType}} { val localVariableBody: kotlin.Any? = {{#hasBodyParam}}{{#bodyParams}}{{paramName}}{{/bodyParams}}{{/hasBodyParam}}{{^hasBodyParam}}{{^hasFormParams}}null{{/hasFormParams}}{{#hasFormParams}}mapOf({{#formParams}}"{{{baseName}}}" to "${{paramName}}"{{#hasMore}}, {{/hasMore}}{{/formParams}}){{/hasFormParams}}{{/hasBodyParam}} val localVariableQuery: MultiValueMap = {{^hasQueryParams}}mapOf(){{/hasQueryParams}}{{#hasQueryParams}}mapOf({{#queryParams}}"{{paramName}}" to {{#isContainer}}toMultiValue({{paramName}}.toList(), "{{collectionFormat}}"){{/isContainer}}{{^isContainer}}listOf("${{paramName}}"){{/isContainer}}{{#hasMore}}, {{/hasMore}}{{/queryParams}}){{/hasQueryParams}} - val localVariableHeaders: kotlin.collections.Map = mapOf({{#hasFormParams}}"Content-Type" to "multipart/form-data"{{/hasFormParams}}{{^hasHeaderParams}}){{/hasHeaderParams}}{{#hasHeaderParams}}{{#hasFormParams}}, {{/hasFormParams}}{{#headerParams}}"{{baseName}}" to {{#isContainer}}{{paramName}}.joinToString(separator = collectionDelimiter("{{collectionFormat}}")){{/isContainer}}{{^isContainer}}{{paramName}}.toString(){{/isContainer}}{{#hasMore}}, {{/hasMore}}{{/headerParams}}){{/hasHeaderParams}} + val localVariableHeaders: MutableMap = mutableMapOf({{#hasFormParams}}"Content-Type" to {{^consumes}}"multipart/form-data"{{/consumes}}{{#consumes.0}}"{{MediaType}}"{{/consumes.0}}{{/hasFormParams}}{{^hasHeaderParams}}){{/hasHeaderParams}}{{#hasHeaderParams}}{{#hasFormParams}}, {{/hasFormParams}}{{#headerParams}}"{{baseName}}" to {{#isContainer}}{{paramName}}.joinToString(separator = collectionDelimiter("{{collectionFormat}}")){{/isContainer}}{{^isContainer}}{{paramName}}.toString(){{/isContainer}}{{#hasMore}}, {{/hasMore}}{{/headerParams}}){{/hasHeaderParams}} val localVariableConfig = RequestConfig( RequestMethod.{{httpMethod}}, "{{path}}"{{#pathParams}}.replace("{"+"{{baseName}}"+"}", "${{paramName}}"){{/pathParams}}, diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/build.gradle.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/build.gradle.mustache index a60661d1f97..0ab36cb7747 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/build.gradle.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/build.gradle.mustache @@ -7,7 +7,7 @@ wrapper { } buildscript { - ext.kotlin_version = '1.3.20' + ext.kotlin_version = '1.3.31' repositories { mavenCentral() @@ -32,7 +32,7 @@ dependencies { compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" compile "com.squareup.moshi:moshi-kotlin:1.5.0" compile "com.squareup.moshi:moshi-adapters:1.5.0" - compile "com.squareup.okhttp3:okhttp:3.8.0" - compile "org.threeten:threetenbp:1.3.6" + compile "com.squareup.okhttp3:okhttp:3.14.0" + compile "org.threeten:threetenbp:1.3.8" testImplementation "io.kotlintest:kotlintest-runner-junit5:3.1.0" } diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/infrastructure/ApiClient.kt.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/infrastructure/ApiClient.kt.mustache index 4b6a2adc4b2..c0d5371c007 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/infrastructure/ApiClient.kt.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/infrastructure/ApiClient.kt.mustache @@ -3,9 +3,15 @@ package {{packageName}}.infrastructure import com.squareup.moshi.FromJson import com.squareup.moshi.Moshi import com.squareup.moshi.ToJson -import okhttp3.* +import okhttp3.OkHttpClient +import okhttp3.RequestBody +import okhttp3.MediaType +import okhttp3.FormBody +import okhttp3.HttpUrl +import okhttp3.ResponseBody +import okhttp3.Request import java.io.File -import java.util.* +import java.util.UUID open class ApiClient(val baseUrl: String) { companion object { @@ -13,6 +19,7 @@ open class ApiClient(val baseUrl: String) { protected const val Accept = "Accept" protected const val JsonMediaType = "application/json" protected const val FormDataMediaType = "multipart/form-data" + protected const val FormUrlEncMediaType = "application/x-www-form-urlencoded" protected const val XmlMediaType = "application/xml" @JvmStatic @@ -22,38 +29,38 @@ open class ApiClient(val baseUrl: String) { @JvmStatic val builder: OkHttpClient.Builder = OkHttpClient.Builder() - - @JvmStatic - var defaultHeaders: Map by ApplicationDelegates.setOnce(mapOf(ContentType to JsonMediaType, Accept to JsonMediaType)) - - @JvmStatic - val jsonHeaders: Map = mapOf(ContentType to JsonMediaType, Accept to JsonMediaType) } protected inline fun requestBody(content: T, mediaType: String = JsonMediaType): RequestBody = - when { - content is File -> RequestBody.create( - MediaType.parse(mediaType), content - ) - mediaType == FormDataMediaType -> { - var builder = FormBody.Builder() - // content's type *must* be Map - @Suppress("UNCHECKED_CAST") - (content as Map).forEach { key, value -> - builder = builder.add(key, value) - } - builder.build() - } - mediaType == JsonMediaType -> RequestBody.create( - MediaType.parse(mediaType), Serializer.moshi.adapter(T::class.java).toJson(content) - ) - mediaType == XmlMediaType -> TODO("xml not currently supported.") - // TODO: this should be extended with other serializers - else -> TODO("requestBody currently only supports JSON body and File body.") - } + when { + content is File -> RequestBody.create( + MediaType.parse(mediaType), content + ) + mediaType == FormDataMediaType || mediaType == FormUrlEncMediaType -> { + var builder = FormBody.Builder() + // content's type *must* be Map + @Suppress("UNCHECKED_CAST") + (content as Map).forEach { key, value -> + builder = builder.add(key, value) + } + builder.build() + } + mediaType == JsonMediaType -> RequestBody.create( + MediaType.parse(mediaType), Serializer.moshi.adapter(T::class.java).toJson(content) + ) + mediaType == XmlMediaType -> TODO("xml not currently supported.") + // TODO: this should be extended with other serializers + else -> TODO("requestBody currently only supports JSON body and File body.") + } - protected inline fun responseBody(body: ResponseBody?, mediaType: String = JsonMediaType): T? { - if(body == null) return null + protected inline fun responseBody(body: ResponseBody?, mediaType: String? = JsonMediaType): T? { + if(body == null) { + return null + } + val bodyContent = body.string() + if (bodyContent.length == 0) { + return null + } return when(mediaType) { JsonMediaType -> Moshi.Builder().add(object { @ToJson @@ -62,8 +69,8 @@ open class ApiClient(val baseUrl: String) { fun fromJson(s: String) = UUID.fromString(s) }) .add(ByteArrayAdapter()) - .build().adapter(T::class.java).fromJson(body.source()) - else -> TODO() + .build().adapter(T::class.java).fromJson(bodyContent) + else -> TODO("responseBody currently only supports JSON body.") } } @@ -80,7 +87,15 @@ open class ApiClient(val baseUrl: String) { } val url = urlBuilder.build() - val headers = requestConfig.headers + defaultHeaders + + // take content-type/accept from spec or set to default (application/json) if not defined + if (requestConfig.headers[ContentType].isNullOrEmpty()) { + requestConfig.headers.put(ContentType, JsonMediaType) + } + if (requestConfig.headers[Accept].isNullOrEmpty()) { + requestConfig.headers.put(Accept, JsonMediaType) + } + val headers = requestConfig.headers if(headers[ContentType] ?: "" == "") { throw kotlin.IllegalStateException("Missing Content-Type header. This is required.") @@ -90,9 +105,8 @@ open class ApiClient(val baseUrl: String) { throw kotlin.IllegalStateException("Missing Accept header. This is required.") } - // TODO: support multiple contentType,accept options here. + // TODO: support multiple contentType options here. val contentType = (headers[ContentType] as String).substringBefore(";").toLowerCase() - val accept = (headers[Accept] as String).substringBefore(";").toLowerCase() var request : Request.Builder = when (requestConfig.method) { RequestMethod.DELETE -> Request.Builder().url(url).delete() @@ -108,6 +122,7 @@ open class ApiClient(val baseUrl: String) { val realRequest = request.build() val response = client.newCall(realRequest).execute() + val accept = response.header(ContentType)?.substringBefore(";")?.toLowerCase() // TODO: handle specific mapping types. e.g. Map> when { diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/infrastructure/RequestConfig.kt.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/infrastructure/RequestConfig.kt.mustache index 5fc06ceb612..7216feeb011 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/infrastructure/RequestConfig.kt.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/infrastructure/RequestConfig.kt.mustache @@ -11,6 +11,6 @@ package {{packageName}}.infrastructure data class RequestConfig( val method: RequestMethod, val path: String, - val headers: Map = mapOf(), + val headers: MutableMap = mutableMapOf(), val query: Map> = mapOf() ) \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor/ApiKeyAuth.kt.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor/ApiKeyAuth.kt.mustache index fb90b9fd826..e50c0793be4 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor/ApiKeyAuth.kt.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor/ApiKeyAuth.kt.mustache @@ -2,8 +2,15 @@ package {{packageName}}.infrastructure import io.ktor.application.ApplicationCall import io.ktor.application.call -import io.ktor.auth.* -import io.ktor.http.auth.* +import io.ktor.auth.Authentication +import io.ktor.auth.AuthenticationFailedCause +import io.ktor.auth.AuthenticationPipeline +import io.ktor.auth.AuthenticationProvider +import io.ktor.auth.Credential +import io.ktor.auth.Principal +import io.ktor.auth.UnauthorizedResponse +import io.ktor.http.auth.HeaderValueEncoding +import io.ktor.http.auth.HttpAuthHeader import io.ktor.request.ApplicationRequest import io.ktor.response.respond diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor/AppMain.kt.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor/AppMain.kt.mustache index dfe39b8975c..9c1b3084712 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor/AppMain.kt.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor/AppMain.kt.mustache @@ -1,29 +1,36 @@ package {{packageName}} -import com.codahale.metrics.* +import com.codahale.metrics.Slf4jReporter import com.typesafe.config.ConfigFactory -import io.ktor.application.* +import io.ktor.application.Application +import io.ktor.application.ApplicationStopping +import io.ktor.application.install +import io.ktor.application.log import io.ktor.client.HttpClient import io.ktor.client.engine.apache.Apache import io.ktor.config.HoconApplicationConfig -import io.ktor.features.* +import io.ktor.features.AutoHeadResponse +import io.ktor.features.Compression +import io.ktor.features.ContentNegotiation +import io.ktor.features.DefaultHeaders +import io.ktor.features.HSTS import io.ktor.gson.GsonConverter import io.ktor.http.ContentType -import io.ktor.locations.* -import io.ktor.metrics.* -import io.ktor.routing.* -import java.util.concurrent.* +import io.ktor.locations.KtorExperimentalLocationsAPI +import io.ktor.locations.Locations +import io.ktor.metrics.Metrics +import io.ktor.routing.Routing +import java.util.concurrent.TimeUnit {{#hasAuthMethods}} -import io.ktor.auth.* +import io.ktor.auth.Authentication +import io.ktor.auth.oauth import io.ktor.util.KtorExperimentalAPI -import org.openapitools.server.infrastructure.* +import org.openapitools.server.infrastructure.ApiKeyCredential +import org.openapitools.server.infrastructure.ApiPrincipal +import org.openapitools.server.infrastructure.apiKeyAuth {{/hasAuthMethods}} -{{#generateApis}} -import {{apiPackage}}.* -{{/generateApis}} - -{{#imports}}import {{import}} -{{/imports}} +{{#generateApis}}{{#apiInfo}}{{#apis}}import {{apiPackage}}.{{classname}} +{{/apis}}{{/apiInfo}}{{/generateApis}} @KtorExperimentalAPI internal val settings = HoconApplicationConfig(ConfigFactory.defaultApplication(HTTP::class.java.classLoader)) diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor/Configuration.kt.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor/Configuration.kt.mustache index 0282b89ebb7..71a147bb5eb 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor/Configuration.kt.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor/Configuration.kt.mustache @@ -2,8 +2,12 @@ package {{packageName}} // Use this file to hold package-level internal functions that return receiver object passed to the `install` method. import io.ktor.auth.OAuthServerSettings -import io.ktor.features.* -import io.ktor.http.* +import io.ktor.features.Compression +import io.ktor.features.HSTS +import io.ktor.features.deflate +import io.ktor.features.gzip +import io.ktor.features.minimumSize +import io.ktor.http.HttpMethod import io.ktor.util.KtorExperimentalAPI import java.time.Duration import java.util.concurrent.Executors diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor/Paths.kt.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor/Paths.kt.mustache index b2fd2817998..fbb0db506dc 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor/Paths.kt.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor/Paths.kt.mustache @@ -1,11 +1,9 @@ {{>licenseInfo}} package {{packageName}} -import io.ktor.locations.* -import {{modelPackage}}.* - -{{#imports}} -import {{import}} +import io.ktor.locations.KtorExperimentalLocationsAPI +import io.ktor.locations.Location +{{#imports}}import {{import}} {{/imports}} {{#apiInfo}} diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor/api.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor/api.mustache index c968bf8c0a6..881e3b108ec 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor/api.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor/api.mustache @@ -10,10 +10,15 @@ import io.ktor.auth.OAuthAccessTokenResponse import io.ktor.auth.OAuthServerSettings import io.ktor.http.ContentType import io.ktor.http.HttpStatusCode -import io.ktor.locations.* +import io.ktor.locations.KtorExperimentalLocationsAPI +import io.ktor.locations.delete +import io.ktor.locations.get import io.ktor.response.respond import io.ktor.response.respondText -import io.ktor.routing.* +import io.ktor.routing.Route +import io.ktor.routing.post +import io.ktor.routing.put +import io.ktor.routing.route import {{packageName}}.Paths import {{packageName}}.infrastructure.ApiPrincipal diff --git a/modules/openapi-generator/src/main/resources/kotlin-spring/api.mustache b/modules/openapi-generator/src/main/resources/kotlin-spring/api.mustache index 65f1f78b065..83c84799b30 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-spring/api.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-spring/api.mustache @@ -3,7 +3,13 @@ package {{package}} {{#imports}}import {{import}} {{/imports}} {{#swaggerAnnotations}} -import io.swagger.annotations.* +import io.swagger.annotations.Api +import io.swagger.annotations.ApiOperation +import io.swagger.annotations.ApiParam +import io.swagger.annotations.ApiResponse +import io.swagger.annotations.ApiResponses +import io.swagger.annotations.Authorization +import io.swagger.annotations.AuthorizationScope {{/swaggerAnnotations}} import org.springframework.http.HttpStatus import org.springframework.http.MediaType @@ -24,7 +30,13 @@ import org.springframework.beans.factory.annotation.Autowired {{#useBeanValidation}} import javax.validation.Valid -import javax.validation.constraints.* +import javax.validation.constraints.DecimalMax +import javax.validation.constraints.DecimalMin +import javax.validation.constraints.Max +import javax.validation.constraints.Min +import javax.validation.constraints.NotNull +import javax.validation.constraints.Pattern +import javax.validation.constraints.Size {{/useBeanValidation}} import kotlin.collections.List diff --git a/modules/openapi-generator/src/main/resources/kotlin-spring/model.mustache b/modules/openapi-generator/src/main/resources/kotlin-spring/model.mustache index 37e21201cff..52492271870 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-spring/model.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-spring/model.mustache @@ -4,8 +4,13 @@ import java.util.Objects {{#imports}}import {{import}} {{/imports}} {{#useBeanValidation}} -import javax.validation.Valid -import javax.validation.constraints.* +import javax.validation.constraints.DecimalMax +import javax.validation.constraints.DecimalMin +import javax.validation.constraints.Max +import javax.validation.constraints.Min +import javax.validation.constraints.NotNull +import javax.validation.constraints.Pattern +import javax.validation.constraints.Size {{/useBeanValidation}} {{#swaggerAnnotations}} import io.swagger.annotations.ApiModelProperty diff --git a/samples/client/petstore/kotlin-string/README.md b/samples/client/petstore/kotlin-string/README.md index 811f25ab974..c1202b74fa4 100644 --- a/samples/client/petstore/kotlin-string/README.md +++ b/samples/client/petstore/kotlin-string/README.md @@ -2,7 +2,7 @@ ## Requires -* Kotlin 1.3.20 +* Kotlin 1.3.31 * Gradle 4.9 ## Build diff --git a/samples/client/petstore/kotlin-string/build.gradle b/samples/client/petstore/kotlin-string/build.gradle index 669d940ce32..07bdfbe04d0 100644 --- a/samples/client/petstore/kotlin-string/build.gradle +++ b/samples/client/petstore/kotlin-string/build.gradle @@ -7,7 +7,7 @@ wrapper { } buildscript { - ext.kotlin_version = '1.3.20' + ext.kotlin_version = '1.3.31' repositories { mavenCentral() @@ -32,7 +32,7 @@ dependencies { compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" compile "com.squareup.moshi:moshi-kotlin:1.5.0" compile "com.squareup.moshi:moshi-adapters:1.5.0" - compile "com.squareup.okhttp3:okhttp:3.8.0" - compile "org.threeten:threetenbp:1.3.6" + compile "com.squareup.okhttp3:okhttp:3.14.0" + compile "org.threeten:threetenbp:1.3.8" testImplementation "io.kotlintest:kotlintest-runner-junit5:3.1.0" } diff --git a/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/apis/PetApi.kt b/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/apis/PetApi.kt index 1e92d62a4aa..676b3edfc56 100644 --- a/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/apis/PetApi.kt +++ b/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/apis/PetApi.kt @@ -14,7 +14,17 @@ package org.openapitools.client.apis import org.openapitools.client.models.ApiResponse import org.openapitools.client.models.Pet -import org.openapitools.client.infrastructure.* +import org.openapitools.client.infrastructure.ApiClient +import org.openapitools.client.infrastructure.ClientException +import org.openapitools.client.infrastructure.ClientError +import org.openapitools.client.infrastructure.ServerException +import org.openapitools.client.infrastructure.ServerError +import org.openapitools.client.infrastructure.MultiValueMap +import org.openapitools.client.infrastructure.RequestConfig +import org.openapitools.client.infrastructure.RequestMethod +import org.openapitools.client.infrastructure.ResponseType +import org.openapitools.client.infrastructure.Success +import org.openapitools.client.infrastructure.toMultiValue class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiClient(basePath) { @@ -27,7 +37,7 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli fun addPet(body: Pet) : Unit { val localVariableBody: kotlin.Any? = body val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.POST, "/pet", @@ -58,7 +68,7 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli fun deletePet(petId: kotlin.Long, apiKey: kotlin.String?) : Unit { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf("api_key" to apiKey.toString()) + val localVariableHeaders: MutableMap = mutableMapOf("api_key" to apiKey.toString()) val localVariableConfig = RequestConfig( RequestMethod.DELETE, "/pet/{petId}".replace("{"+"petId"+"}", "$petId"), @@ -89,7 +99,7 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli fun findPetsByStatus(status: kotlin.Array) : kotlin.Array { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf("status" to toMultiValue(status.toList(), "csv")) - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.GET, "/pet/findByStatus", @@ -120,7 +130,7 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli fun findPetsByTags(tags: kotlin.Array) : kotlin.Array { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf("tags" to toMultiValue(tags.toList(), "csv")) - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.GET, "/pet/findByTags", @@ -151,7 +161,7 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli fun getPetById(petId: kotlin.Long) : Pet { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.GET, "/pet/{petId}".replace("{"+"petId"+"}", "$petId"), @@ -181,7 +191,7 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli fun updatePet(body: Pet) : Unit { val localVariableBody: kotlin.Any? = body val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.PUT, "/pet", @@ -213,7 +223,7 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli fun updatePetWithForm(petId: kotlin.Long, name: kotlin.String?, status: kotlin.String?) : Unit { val localVariableBody: kotlin.Any? = mapOf("name" to "$name", "status" to "$status") val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf("Content-Type" to "multipart/form-data") + val localVariableHeaders: MutableMap = mutableMapOf("Content-Type" to "") val localVariableConfig = RequestConfig( RequestMethod.POST, "/pet/{petId}".replace("{"+"petId"+"}", "$petId"), @@ -246,7 +256,7 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: java.io.File?) : ApiResponse { val localVariableBody: kotlin.Any? = mapOf("additionalMetadata" to "$additionalMetadata", "file" to "$file") val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf("Content-Type" to "multipart/form-data") + val localVariableHeaders: MutableMap = mutableMapOf("Content-Type" to "") val localVariableConfig = RequestConfig( RequestMethod.POST, "/pet/{petId}/uploadImage".replace("{"+"petId"+"}", "$petId"), diff --git a/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/apis/StoreApi.kt b/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/apis/StoreApi.kt index f54c7c9fb64..3de627c840b 100644 --- a/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/apis/StoreApi.kt +++ b/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/apis/StoreApi.kt @@ -13,7 +13,17 @@ package org.openapitools.client.apis import org.openapitools.client.models.Order -import org.openapitools.client.infrastructure.* +import org.openapitools.client.infrastructure.ApiClient +import org.openapitools.client.infrastructure.ClientException +import org.openapitools.client.infrastructure.ClientError +import org.openapitools.client.infrastructure.ServerException +import org.openapitools.client.infrastructure.ServerError +import org.openapitools.client.infrastructure.MultiValueMap +import org.openapitools.client.infrastructure.RequestConfig +import org.openapitools.client.infrastructure.RequestMethod +import org.openapitools.client.infrastructure.ResponseType +import org.openapitools.client.infrastructure.Success +import org.openapitools.client.infrastructure.toMultiValue class StoreApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiClient(basePath) { @@ -26,7 +36,7 @@ class StoreApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiC fun deleteOrder(orderId: kotlin.String) : Unit { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.DELETE, "/store/order/{orderId}".replace("{"+"orderId"+"}", "$orderId"), @@ -56,7 +66,7 @@ class StoreApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiC fun getInventory() : kotlin.collections.Map { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.GET, "/store/inventory", @@ -87,7 +97,7 @@ class StoreApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiC fun getOrderById(orderId: kotlin.Long) : Order { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.GET, "/store/order/{orderId}".replace("{"+"orderId"+"}", "$orderId"), @@ -118,7 +128,7 @@ class StoreApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiC fun placeOrder(body: Order) : Order { val localVariableBody: kotlin.Any? = body val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.POST, "/store/order", diff --git a/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/apis/UserApi.kt b/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/apis/UserApi.kt index 408c47da34e..f4b64f98ebd 100644 --- a/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/apis/UserApi.kt +++ b/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/apis/UserApi.kt @@ -13,7 +13,17 @@ package org.openapitools.client.apis import org.openapitools.client.models.User -import org.openapitools.client.infrastructure.* +import org.openapitools.client.infrastructure.ApiClient +import org.openapitools.client.infrastructure.ClientException +import org.openapitools.client.infrastructure.ClientError +import org.openapitools.client.infrastructure.ServerException +import org.openapitools.client.infrastructure.ServerError +import org.openapitools.client.infrastructure.MultiValueMap +import org.openapitools.client.infrastructure.RequestConfig +import org.openapitools.client.infrastructure.RequestMethod +import org.openapitools.client.infrastructure.ResponseType +import org.openapitools.client.infrastructure.Success +import org.openapitools.client.infrastructure.toMultiValue class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiClient(basePath) { @@ -26,7 +36,7 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl fun createUser(body: User) : Unit { val localVariableBody: kotlin.Any? = body val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.POST, "/user", @@ -56,7 +66,7 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl fun createUsersWithArrayInput(body: kotlin.Array) : Unit { val localVariableBody: kotlin.Any? = body val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.POST, "/user/createWithArray", @@ -86,7 +96,7 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl fun createUsersWithListInput(body: kotlin.Array) : Unit { val localVariableBody: kotlin.Any? = body val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.POST, "/user/createWithList", @@ -116,7 +126,7 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl fun deleteUser(username: kotlin.String) : Unit { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.DELETE, "/user/{username}".replace("{"+"username"+"}", "$username"), @@ -147,7 +157,7 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl fun getUserByName(username: kotlin.String) : User { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.GET, "/user/{username}".replace("{"+"username"+"}", "$username"), @@ -179,7 +189,7 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl fun loginUser(username: kotlin.String, password: kotlin.String) : kotlin.String { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf("username" to listOf("$username"), "password" to listOf("$password")) - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.GET, "/user/login", @@ -208,7 +218,7 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl fun logoutUser() : Unit { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.GET, "/user/logout", @@ -239,7 +249,7 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl fun updateUser(username: kotlin.String, body: User) : Unit { val localVariableBody: kotlin.Any? = body val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.PUT, "/user/{username}".replace("{"+"username"+"}", "$username"), diff --git a/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt index 9e79028a90b..c075b4fbb76 100644 --- a/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt +++ b/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt @@ -3,9 +3,15 @@ package org.openapitools.client.infrastructure import com.squareup.moshi.FromJson import com.squareup.moshi.Moshi import com.squareup.moshi.ToJson -import okhttp3.* +import okhttp3.OkHttpClient +import okhttp3.RequestBody +import okhttp3.MediaType +import okhttp3.FormBody +import okhttp3.HttpUrl +import okhttp3.ResponseBody +import okhttp3.Request import java.io.File -import java.util.* +import java.util.UUID open class ApiClient(val baseUrl: String) { companion object { @@ -13,6 +19,7 @@ open class ApiClient(val baseUrl: String) { protected const val Accept = "Accept" protected const val JsonMediaType = "application/json" protected const val FormDataMediaType = "multipart/form-data" + protected const val FormUrlEncMediaType = "application/x-www-form-urlencoded" protected const val XmlMediaType = "application/xml" @JvmStatic @@ -22,38 +29,38 @@ open class ApiClient(val baseUrl: String) { @JvmStatic val builder: OkHttpClient.Builder = OkHttpClient.Builder() - - @JvmStatic - var defaultHeaders: Map by ApplicationDelegates.setOnce(mapOf(ContentType to JsonMediaType, Accept to JsonMediaType)) - - @JvmStatic - val jsonHeaders: Map = mapOf(ContentType to JsonMediaType, Accept to JsonMediaType) } protected inline fun requestBody(content: T, mediaType: String = JsonMediaType): RequestBody = - when { - content is File -> RequestBody.create( - MediaType.parse(mediaType), content - ) - mediaType == FormDataMediaType -> { - var builder = FormBody.Builder() - // content's type *must* be Map - @Suppress("UNCHECKED_CAST") - (content as Map).forEach { key, value -> - builder = builder.add(key, value) - } - builder.build() - } - mediaType == JsonMediaType -> RequestBody.create( - MediaType.parse(mediaType), Serializer.moshi.adapter(T::class.java).toJson(content) - ) - mediaType == XmlMediaType -> TODO("xml not currently supported.") - // TODO: this should be extended with other serializers - else -> TODO("requestBody currently only supports JSON body and File body.") - } + when { + content is File -> RequestBody.create( + MediaType.parse(mediaType), content + ) + mediaType == FormDataMediaType || mediaType == FormUrlEncMediaType -> { + var builder = FormBody.Builder() + // content's type *must* be Map + @Suppress("UNCHECKED_CAST") + (content as Map).forEach { key, value -> + builder = builder.add(key, value) + } + builder.build() + } + mediaType == JsonMediaType -> RequestBody.create( + MediaType.parse(mediaType), Serializer.moshi.adapter(T::class.java).toJson(content) + ) + mediaType == XmlMediaType -> TODO("xml not currently supported.") + // TODO: this should be extended with other serializers + else -> TODO("requestBody currently only supports JSON body and File body.") + } - protected inline fun responseBody(body: ResponseBody?, mediaType: String = JsonMediaType): T? { - if(body == null) return null + protected inline fun responseBody(body: ResponseBody?, mediaType: String? = JsonMediaType): T? { + if(body == null) { + return null + } + val bodyContent = body.string() + if (bodyContent.length == 0) { + return null + } return when(mediaType) { JsonMediaType -> Moshi.Builder().add(object { @ToJson @@ -62,8 +69,8 @@ open class ApiClient(val baseUrl: String) { fun fromJson(s: String) = UUID.fromString(s) }) .add(ByteArrayAdapter()) - .build().adapter(T::class.java).fromJson(body.source()) - else -> TODO() + .build().adapter(T::class.java).fromJson(bodyContent) + else -> TODO("responseBody currently only supports JSON body.") } } @@ -80,7 +87,15 @@ open class ApiClient(val baseUrl: String) { } val url = urlBuilder.build() - val headers = requestConfig.headers + defaultHeaders + + // take content-type/accept from spec or set to default (application/json) if not defined + if (requestConfig.headers[ContentType].isNullOrEmpty()) { + requestConfig.headers.put(ContentType, JsonMediaType) + } + if (requestConfig.headers[Accept].isNullOrEmpty()) { + requestConfig.headers.put(Accept, JsonMediaType) + } + val headers = requestConfig.headers if(headers[ContentType] ?: "" == "") { throw kotlin.IllegalStateException("Missing Content-Type header. This is required.") @@ -90,9 +105,8 @@ open class ApiClient(val baseUrl: String) { throw kotlin.IllegalStateException("Missing Accept header. This is required.") } - // TODO: support multiple contentType,accept options here. + // TODO: support multiple contentType options here. val contentType = (headers[ContentType] as String).substringBefore(";").toLowerCase() - val accept = (headers[Accept] as String).substringBefore(";").toLowerCase() var request : Request.Builder = when (requestConfig.method) { RequestMethod.DELETE -> Request.Builder().url(url).delete() @@ -108,6 +122,7 @@ open class ApiClient(val baseUrl: String) { val realRequest = request.build() val response = client.newCall(realRequest).execute() + val accept = response.header(ContentType)?.substringBefore(";")?.toLowerCase() // TODO: handle specific mapping types. e.g. Map> when { diff --git a/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/infrastructure/RequestConfig.kt b/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/infrastructure/RequestConfig.kt index 86e2dadf9a8..53e689237d7 100644 --- a/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/infrastructure/RequestConfig.kt +++ b/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/infrastructure/RequestConfig.kt @@ -11,6 +11,6 @@ package org.openapitools.client.infrastructure data class RequestConfig( val method: RequestMethod, val path: String, - val headers: Map = mapOf(), + val headers: MutableMap = mutableMapOf(), val query: Map> = mapOf() ) \ No newline at end of file diff --git a/samples/client/petstore/kotlin-threetenbp/README.md b/samples/client/petstore/kotlin-threetenbp/README.md index 811f25ab974..c1202b74fa4 100644 --- a/samples/client/petstore/kotlin-threetenbp/README.md +++ b/samples/client/petstore/kotlin-threetenbp/README.md @@ -2,7 +2,7 @@ ## Requires -* Kotlin 1.3.20 +* Kotlin 1.3.31 * Gradle 4.9 ## Build diff --git a/samples/client/petstore/kotlin-threetenbp/build.gradle b/samples/client/petstore/kotlin-threetenbp/build.gradle index 669d940ce32..07bdfbe04d0 100644 --- a/samples/client/petstore/kotlin-threetenbp/build.gradle +++ b/samples/client/petstore/kotlin-threetenbp/build.gradle @@ -7,7 +7,7 @@ wrapper { } buildscript { - ext.kotlin_version = '1.3.20' + ext.kotlin_version = '1.3.31' repositories { mavenCentral() @@ -32,7 +32,7 @@ dependencies { compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" compile "com.squareup.moshi:moshi-kotlin:1.5.0" compile "com.squareup.moshi:moshi-adapters:1.5.0" - compile "com.squareup.okhttp3:okhttp:3.8.0" - compile "org.threeten:threetenbp:1.3.6" + compile "com.squareup.okhttp3:okhttp:3.14.0" + compile "org.threeten:threetenbp:1.3.8" testImplementation "io.kotlintest:kotlintest-runner-junit5:3.1.0" } diff --git a/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/apis/PetApi.kt b/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/apis/PetApi.kt index 1f3c81bb8fd..7d087964492 100644 --- a/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/apis/PetApi.kt +++ b/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/apis/PetApi.kt @@ -14,7 +14,17 @@ package org.openapitools.client.apis import org.openapitools.client.models.ApiResponse import org.openapitools.client.models.Pet -import org.openapitools.client.infrastructure.* +import org.openapitools.client.infrastructure.ApiClient +import org.openapitools.client.infrastructure.ClientException +import org.openapitools.client.infrastructure.ClientError +import org.openapitools.client.infrastructure.ServerException +import org.openapitools.client.infrastructure.ServerError +import org.openapitools.client.infrastructure.MultiValueMap +import org.openapitools.client.infrastructure.RequestConfig +import org.openapitools.client.infrastructure.RequestMethod +import org.openapitools.client.infrastructure.ResponseType +import org.openapitools.client.infrastructure.Success +import org.openapitools.client.infrastructure.toMultiValue import org.threeten.bp.LocalDateTime class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiClient(basePath) { @@ -28,7 +38,7 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli fun addPet(body: Pet) : Unit { val localVariableBody: kotlin.Any? = body val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.POST, "/pet", @@ -59,7 +69,7 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli fun deletePet(petId: kotlin.Long, apiKey: kotlin.String?) : Unit { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf("api_key" to apiKey.toString()) + val localVariableHeaders: MutableMap = mutableMapOf("api_key" to apiKey.toString()) val localVariableConfig = RequestConfig( RequestMethod.DELETE, "/pet/{petId}".replace("{"+"petId"+"}", "$petId"), @@ -90,7 +100,7 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli fun findPetsByStatus(status: kotlin.Array) : kotlin.Array { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf("status" to toMultiValue(status.toList(), "csv")) - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.GET, "/pet/findByStatus", @@ -121,7 +131,7 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli fun findPetsByTags(tags: kotlin.Array) : kotlin.Array { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf("tags" to toMultiValue(tags.toList(), "csv")) - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.GET, "/pet/findByTags", @@ -152,7 +162,7 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli fun getPetById(petId: kotlin.Long) : Pet { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.GET, "/pet/{petId}".replace("{"+"petId"+"}", "$petId"), @@ -182,7 +192,7 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli fun updatePet(body: Pet) : Unit { val localVariableBody: kotlin.Any? = body val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.PUT, "/pet", @@ -214,7 +224,7 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli fun updatePetWithForm(petId: kotlin.Long, name: kotlin.String?, status: kotlin.String?) : Unit { val localVariableBody: kotlin.Any? = mapOf("name" to "$name", "status" to "$status") val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf("Content-Type" to "multipart/form-data") + val localVariableHeaders: MutableMap = mutableMapOf("Content-Type" to "") val localVariableConfig = RequestConfig( RequestMethod.POST, "/pet/{petId}".replace("{"+"petId"+"}", "$petId"), @@ -247,7 +257,7 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: java.io.File?) : ApiResponse { val localVariableBody: kotlin.Any? = mapOf("additionalMetadata" to "$additionalMetadata", "file" to "$file") val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf("Content-Type" to "multipart/form-data") + val localVariableHeaders: MutableMap = mutableMapOf("Content-Type" to "") val localVariableConfig = RequestConfig( RequestMethod.POST, "/pet/{petId}/uploadImage".replace("{"+"petId"+"}", "$petId"), diff --git a/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/apis/StoreApi.kt b/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/apis/StoreApi.kt index c281c967267..c799f96b85d 100644 --- a/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/apis/StoreApi.kt +++ b/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/apis/StoreApi.kt @@ -13,7 +13,17 @@ package org.openapitools.client.apis import org.openapitools.client.models.Order -import org.openapitools.client.infrastructure.* +import org.openapitools.client.infrastructure.ApiClient +import org.openapitools.client.infrastructure.ClientException +import org.openapitools.client.infrastructure.ClientError +import org.openapitools.client.infrastructure.ServerException +import org.openapitools.client.infrastructure.ServerError +import org.openapitools.client.infrastructure.MultiValueMap +import org.openapitools.client.infrastructure.RequestConfig +import org.openapitools.client.infrastructure.RequestMethod +import org.openapitools.client.infrastructure.ResponseType +import org.openapitools.client.infrastructure.Success +import org.openapitools.client.infrastructure.toMultiValue import org.threeten.bp.LocalDateTime class StoreApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiClient(basePath) { @@ -27,7 +37,7 @@ class StoreApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiC fun deleteOrder(orderId: kotlin.String) : Unit { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.DELETE, "/store/order/{orderId}".replace("{"+"orderId"+"}", "$orderId"), @@ -57,7 +67,7 @@ class StoreApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiC fun getInventory() : kotlin.collections.Map { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.GET, "/store/inventory", @@ -88,7 +98,7 @@ class StoreApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiC fun getOrderById(orderId: kotlin.Long) : Order { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.GET, "/store/order/{orderId}".replace("{"+"orderId"+"}", "$orderId"), @@ -119,7 +129,7 @@ class StoreApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiC fun placeOrder(body: Order) : Order { val localVariableBody: kotlin.Any? = body val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.POST, "/store/order", diff --git a/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/apis/UserApi.kt b/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/apis/UserApi.kt index 301d20d91ce..7c22eecf968 100644 --- a/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/apis/UserApi.kt +++ b/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/apis/UserApi.kt @@ -13,7 +13,17 @@ package org.openapitools.client.apis import org.openapitools.client.models.User -import org.openapitools.client.infrastructure.* +import org.openapitools.client.infrastructure.ApiClient +import org.openapitools.client.infrastructure.ClientException +import org.openapitools.client.infrastructure.ClientError +import org.openapitools.client.infrastructure.ServerException +import org.openapitools.client.infrastructure.ServerError +import org.openapitools.client.infrastructure.MultiValueMap +import org.openapitools.client.infrastructure.RequestConfig +import org.openapitools.client.infrastructure.RequestMethod +import org.openapitools.client.infrastructure.ResponseType +import org.openapitools.client.infrastructure.Success +import org.openapitools.client.infrastructure.toMultiValue import org.threeten.bp.LocalDateTime class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiClient(basePath) { @@ -27,7 +37,7 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl fun createUser(body: User) : Unit { val localVariableBody: kotlin.Any? = body val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.POST, "/user", @@ -57,7 +67,7 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl fun createUsersWithArrayInput(body: kotlin.Array) : Unit { val localVariableBody: kotlin.Any? = body val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.POST, "/user/createWithArray", @@ -87,7 +97,7 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl fun createUsersWithListInput(body: kotlin.Array) : Unit { val localVariableBody: kotlin.Any? = body val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.POST, "/user/createWithList", @@ -117,7 +127,7 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl fun deleteUser(username: kotlin.String) : Unit { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.DELETE, "/user/{username}".replace("{"+"username"+"}", "$username"), @@ -148,7 +158,7 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl fun getUserByName(username: kotlin.String) : User { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.GET, "/user/{username}".replace("{"+"username"+"}", "$username"), @@ -180,7 +190,7 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl fun loginUser(username: kotlin.String, password: kotlin.String) : kotlin.String { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf("username" to listOf("$username"), "password" to listOf("$password")) - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.GET, "/user/login", @@ -209,7 +219,7 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl fun logoutUser() : Unit { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.GET, "/user/logout", @@ -240,7 +250,7 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl fun updateUser(username: kotlin.String, body: User) : Unit { val localVariableBody: kotlin.Any? = body val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.PUT, "/user/{username}".replace("{"+"username"+"}", "$username"), diff --git a/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt index 9e79028a90b..c075b4fbb76 100644 --- a/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt +++ b/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt @@ -3,9 +3,15 @@ package org.openapitools.client.infrastructure import com.squareup.moshi.FromJson import com.squareup.moshi.Moshi import com.squareup.moshi.ToJson -import okhttp3.* +import okhttp3.OkHttpClient +import okhttp3.RequestBody +import okhttp3.MediaType +import okhttp3.FormBody +import okhttp3.HttpUrl +import okhttp3.ResponseBody +import okhttp3.Request import java.io.File -import java.util.* +import java.util.UUID open class ApiClient(val baseUrl: String) { companion object { @@ -13,6 +19,7 @@ open class ApiClient(val baseUrl: String) { protected const val Accept = "Accept" protected const val JsonMediaType = "application/json" protected const val FormDataMediaType = "multipart/form-data" + protected const val FormUrlEncMediaType = "application/x-www-form-urlencoded" protected const val XmlMediaType = "application/xml" @JvmStatic @@ -22,38 +29,38 @@ open class ApiClient(val baseUrl: String) { @JvmStatic val builder: OkHttpClient.Builder = OkHttpClient.Builder() - - @JvmStatic - var defaultHeaders: Map by ApplicationDelegates.setOnce(mapOf(ContentType to JsonMediaType, Accept to JsonMediaType)) - - @JvmStatic - val jsonHeaders: Map = mapOf(ContentType to JsonMediaType, Accept to JsonMediaType) } protected inline fun requestBody(content: T, mediaType: String = JsonMediaType): RequestBody = - when { - content is File -> RequestBody.create( - MediaType.parse(mediaType), content - ) - mediaType == FormDataMediaType -> { - var builder = FormBody.Builder() - // content's type *must* be Map - @Suppress("UNCHECKED_CAST") - (content as Map).forEach { key, value -> - builder = builder.add(key, value) - } - builder.build() - } - mediaType == JsonMediaType -> RequestBody.create( - MediaType.parse(mediaType), Serializer.moshi.adapter(T::class.java).toJson(content) - ) - mediaType == XmlMediaType -> TODO("xml not currently supported.") - // TODO: this should be extended with other serializers - else -> TODO("requestBody currently only supports JSON body and File body.") - } + when { + content is File -> RequestBody.create( + MediaType.parse(mediaType), content + ) + mediaType == FormDataMediaType || mediaType == FormUrlEncMediaType -> { + var builder = FormBody.Builder() + // content's type *must* be Map + @Suppress("UNCHECKED_CAST") + (content as Map).forEach { key, value -> + builder = builder.add(key, value) + } + builder.build() + } + mediaType == JsonMediaType -> RequestBody.create( + MediaType.parse(mediaType), Serializer.moshi.adapter(T::class.java).toJson(content) + ) + mediaType == XmlMediaType -> TODO("xml not currently supported.") + // TODO: this should be extended with other serializers + else -> TODO("requestBody currently only supports JSON body and File body.") + } - protected inline fun responseBody(body: ResponseBody?, mediaType: String = JsonMediaType): T? { - if(body == null) return null + protected inline fun responseBody(body: ResponseBody?, mediaType: String? = JsonMediaType): T? { + if(body == null) { + return null + } + val bodyContent = body.string() + if (bodyContent.length == 0) { + return null + } return when(mediaType) { JsonMediaType -> Moshi.Builder().add(object { @ToJson @@ -62,8 +69,8 @@ open class ApiClient(val baseUrl: String) { fun fromJson(s: String) = UUID.fromString(s) }) .add(ByteArrayAdapter()) - .build().adapter(T::class.java).fromJson(body.source()) - else -> TODO() + .build().adapter(T::class.java).fromJson(bodyContent) + else -> TODO("responseBody currently only supports JSON body.") } } @@ -80,7 +87,15 @@ open class ApiClient(val baseUrl: String) { } val url = urlBuilder.build() - val headers = requestConfig.headers + defaultHeaders + + // take content-type/accept from spec or set to default (application/json) if not defined + if (requestConfig.headers[ContentType].isNullOrEmpty()) { + requestConfig.headers.put(ContentType, JsonMediaType) + } + if (requestConfig.headers[Accept].isNullOrEmpty()) { + requestConfig.headers.put(Accept, JsonMediaType) + } + val headers = requestConfig.headers if(headers[ContentType] ?: "" == "") { throw kotlin.IllegalStateException("Missing Content-Type header. This is required.") @@ -90,9 +105,8 @@ open class ApiClient(val baseUrl: String) { throw kotlin.IllegalStateException("Missing Accept header. This is required.") } - // TODO: support multiple contentType,accept options here. + // TODO: support multiple contentType options here. val contentType = (headers[ContentType] as String).substringBefore(";").toLowerCase() - val accept = (headers[Accept] as String).substringBefore(";").toLowerCase() var request : Request.Builder = when (requestConfig.method) { RequestMethod.DELETE -> Request.Builder().url(url).delete() @@ -108,6 +122,7 @@ open class ApiClient(val baseUrl: String) { val realRequest = request.build() val response = client.newCall(realRequest).execute() + val accept = response.header(ContentType)?.substringBefore(";")?.toLowerCase() // TODO: handle specific mapping types. e.g. Map> when { diff --git a/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/infrastructure/RequestConfig.kt b/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/infrastructure/RequestConfig.kt index 86e2dadf9a8..53e689237d7 100644 --- a/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/infrastructure/RequestConfig.kt +++ b/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/infrastructure/RequestConfig.kt @@ -11,6 +11,6 @@ package org.openapitools.client.infrastructure data class RequestConfig( val method: RequestMethod, val path: String, - val headers: Map = mapOf(), + val headers: MutableMap = mutableMapOf(), val query: Map> = mapOf() ) \ No newline at end of file diff --git a/samples/client/petstore/kotlin/README.md b/samples/client/petstore/kotlin/README.md index 811f25ab974..c1202b74fa4 100644 --- a/samples/client/petstore/kotlin/README.md +++ b/samples/client/petstore/kotlin/README.md @@ -2,7 +2,7 @@ ## Requires -* Kotlin 1.3.20 +* Kotlin 1.3.31 * Gradle 4.9 ## Build diff --git a/samples/client/petstore/kotlin/build.gradle b/samples/client/petstore/kotlin/build.gradle index 669d940ce32..07bdfbe04d0 100644 --- a/samples/client/petstore/kotlin/build.gradle +++ b/samples/client/petstore/kotlin/build.gradle @@ -7,7 +7,7 @@ wrapper { } buildscript { - ext.kotlin_version = '1.3.20' + ext.kotlin_version = '1.3.31' repositories { mavenCentral() @@ -32,7 +32,7 @@ dependencies { compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" compile "com.squareup.moshi:moshi-kotlin:1.5.0" compile "com.squareup.moshi:moshi-adapters:1.5.0" - compile "com.squareup.okhttp3:okhttp:3.8.0" - compile "org.threeten:threetenbp:1.3.6" + compile "com.squareup.okhttp3:okhttp:3.14.0" + compile "org.threeten:threetenbp:1.3.8" testImplementation "io.kotlintest:kotlintest-runner-junit5:3.1.0" } diff --git a/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/apis/PetApi.kt b/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/apis/PetApi.kt index 1e92d62a4aa..676b3edfc56 100644 --- a/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/apis/PetApi.kt +++ b/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/apis/PetApi.kt @@ -14,7 +14,17 @@ package org.openapitools.client.apis import org.openapitools.client.models.ApiResponse import org.openapitools.client.models.Pet -import org.openapitools.client.infrastructure.* +import org.openapitools.client.infrastructure.ApiClient +import org.openapitools.client.infrastructure.ClientException +import org.openapitools.client.infrastructure.ClientError +import org.openapitools.client.infrastructure.ServerException +import org.openapitools.client.infrastructure.ServerError +import org.openapitools.client.infrastructure.MultiValueMap +import org.openapitools.client.infrastructure.RequestConfig +import org.openapitools.client.infrastructure.RequestMethod +import org.openapitools.client.infrastructure.ResponseType +import org.openapitools.client.infrastructure.Success +import org.openapitools.client.infrastructure.toMultiValue class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiClient(basePath) { @@ -27,7 +37,7 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli fun addPet(body: Pet) : Unit { val localVariableBody: kotlin.Any? = body val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.POST, "/pet", @@ -58,7 +68,7 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli fun deletePet(petId: kotlin.Long, apiKey: kotlin.String?) : Unit { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf("api_key" to apiKey.toString()) + val localVariableHeaders: MutableMap = mutableMapOf("api_key" to apiKey.toString()) val localVariableConfig = RequestConfig( RequestMethod.DELETE, "/pet/{petId}".replace("{"+"petId"+"}", "$petId"), @@ -89,7 +99,7 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli fun findPetsByStatus(status: kotlin.Array) : kotlin.Array { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf("status" to toMultiValue(status.toList(), "csv")) - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.GET, "/pet/findByStatus", @@ -120,7 +130,7 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli fun findPetsByTags(tags: kotlin.Array) : kotlin.Array { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf("tags" to toMultiValue(tags.toList(), "csv")) - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.GET, "/pet/findByTags", @@ -151,7 +161,7 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli fun getPetById(petId: kotlin.Long) : Pet { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.GET, "/pet/{petId}".replace("{"+"petId"+"}", "$petId"), @@ -181,7 +191,7 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli fun updatePet(body: Pet) : Unit { val localVariableBody: kotlin.Any? = body val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.PUT, "/pet", @@ -213,7 +223,7 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli fun updatePetWithForm(petId: kotlin.Long, name: kotlin.String?, status: kotlin.String?) : Unit { val localVariableBody: kotlin.Any? = mapOf("name" to "$name", "status" to "$status") val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf("Content-Type" to "multipart/form-data") + val localVariableHeaders: MutableMap = mutableMapOf("Content-Type" to "") val localVariableConfig = RequestConfig( RequestMethod.POST, "/pet/{petId}".replace("{"+"petId"+"}", "$petId"), @@ -246,7 +256,7 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: java.io.File?) : ApiResponse { val localVariableBody: kotlin.Any? = mapOf("additionalMetadata" to "$additionalMetadata", "file" to "$file") val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf("Content-Type" to "multipart/form-data") + val localVariableHeaders: MutableMap = mutableMapOf("Content-Type" to "") val localVariableConfig = RequestConfig( RequestMethod.POST, "/pet/{petId}/uploadImage".replace("{"+"petId"+"}", "$petId"), diff --git a/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/apis/StoreApi.kt b/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/apis/StoreApi.kt index f54c7c9fb64..3de627c840b 100644 --- a/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/apis/StoreApi.kt +++ b/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/apis/StoreApi.kt @@ -13,7 +13,17 @@ package org.openapitools.client.apis import org.openapitools.client.models.Order -import org.openapitools.client.infrastructure.* +import org.openapitools.client.infrastructure.ApiClient +import org.openapitools.client.infrastructure.ClientException +import org.openapitools.client.infrastructure.ClientError +import org.openapitools.client.infrastructure.ServerException +import org.openapitools.client.infrastructure.ServerError +import org.openapitools.client.infrastructure.MultiValueMap +import org.openapitools.client.infrastructure.RequestConfig +import org.openapitools.client.infrastructure.RequestMethod +import org.openapitools.client.infrastructure.ResponseType +import org.openapitools.client.infrastructure.Success +import org.openapitools.client.infrastructure.toMultiValue class StoreApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiClient(basePath) { @@ -26,7 +36,7 @@ class StoreApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiC fun deleteOrder(orderId: kotlin.String) : Unit { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.DELETE, "/store/order/{orderId}".replace("{"+"orderId"+"}", "$orderId"), @@ -56,7 +66,7 @@ class StoreApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiC fun getInventory() : kotlin.collections.Map { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.GET, "/store/inventory", @@ -87,7 +97,7 @@ class StoreApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiC fun getOrderById(orderId: kotlin.Long) : Order { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.GET, "/store/order/{orderId}".replace("{"+"orderId"+"}", "$orderId"), @@ -118,7 +128,7 @@ class StoreApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiC fun placeOrder(body: Order) : Order { val localVariableBody: kotlin.Any? = body val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.POST, "/store/order", diff --git a/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/apis/UserApi.kt b/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/apis/UserApi.kt index 408c47da34e..f4b64f98ebd 100644 --- a/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/apis/UserApi.kt +++ b/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/apis/UserApi.kt @@ -13,7 +13,17 @@ package org.openapitools.client.apis import org.openapitools.client.models.User -import org.openapitools.client.infrastructure.* +import org.openapitools.client.infrastructure.ApiClient +import org.openapitools.client.infrastructure.ClientException +import org.openapitools.client.infrastructure.ClientError +import org.openapitools.client.infrastructure.ServerException +import org.openapitools.client.infrastructure.ServerError +import org.openapitools.client.infrastructure.MultiValueMap +import org.openapitools.client.infrastructure.RequestConfig +import org.openapitools.client.infrastructure.RequestMethod +import org.openapitools.client.infrastructure.ResponseType +import org.openapitools.client.infrastructure.Success +import org.openapitools.client.infrastructure.toMultiValue class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiClient(basePath) { @@ -26,7 +36,7 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl fun createUser(body: User) : Unit { val localVariableBody: kotlin.Any? = body val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.POST, "/user", @@ -56,7 +66,7 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl fun createUsersWithArrayInput(body: kotlin.Array) : Unit { val localVariableBody: kotlin.Any? = body val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.POST, "/user/createWithArray", @@ -86,7 +96,7 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl fun createUsersWithListInput(body: kotlin.Array) : Unit { val localVariableBody: kotlin.Any? = body val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.POST, "/user/createWithList", @@ -116,7 +126,7 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl fun deleteUser(username: kotlin.String) : Unit { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.DELETE, "/user/{username}".replace("{"+"username"+"}", "$username"), @@ -147,7 +157,7 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl fun getUserByName(username: kotlin.String) : User { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.GET, "/user/{username}".replace("{"+"username"+"}", "$username"), @@ -179,7 +189,7 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl fun loginUser(username: kotlin.String, password: kotlin.String) : kotlin.String { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf("username" to listOf("$username"), "password" to listOf("$password")) - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.GET, "/user/login", @@ -208,7 +218,7 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl fun logoutUser() : Unit { val localVariableBody: kotlin.Any? = null val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.GET, "/user/logout", @@ -239,7 +249,7 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl fun updateUser(username: kotlin.String, body: User) : Unit { val localVariableBody: kotlin.Any? = body val localVariableQuery: MultiValueMap = mapOf() - val localVariableHeaders: kotlin.collections.Map = mapOf() + val localVariableHeaders: MutableMap = mutableMapOf() val localVariableConfig = RequestConfig( RequestMethod.PUT, "/user/{username}".replace("{"+"username"+"}", "$username"), diff --git a/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt index 9e79028a90b..c075b4fbb76 100644 --- a/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt +++ b/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt @@ -3,9 +3,15 @@ package org.openapitools.client.infrastructure import com.squareup.moshi.FromJson import com.squareup.moshi.Moshi import com.squareup.moshi.ToJson -import okhttp3.* +import okhttp3.OkHttpClient +import okhttp3.RequestBody +import okhttp3.MediaType +import okhttp3.FormBody +import okhttp3.HttpUrl +import okhttp3.ResponseBody +import okhttp3.Request import java.io.File -import java.util.* +import java.util.UUID open class ApiClient(val baseUrl: String) { companion object { @@ -13,6 +19,7 @@ open class ApiClient(val baseUrl: String) { protected const val Accept = "Accept" protected const val JsonMediaType = "application/json" protected const val FormDataMediaType = "multipart/form-data" + protected const val FormUrlEncMediaType = "application/x-www-form-urlencoded" protected const val XmlMediaType = "application/xml" @JvmStatic @@ -22,38 +29,38 @@ open class ApiClient(val baseUrl: String) { @JvmStatic val builder: OkHttpClient.Builder = OkHttpClient.Builder() - - @JvmStatic - var defaultHeaders: Map by ApplicationDelegates.setOnce(mapOf(ContentType to JsonMediaType, Accept to JsonMediaType)) - - @JvmStatic - val jsonHeaders: Map = mapOf(ContentType to JsonMediaType, Accept to JsonMediaType) } protected inline fun requestBody(content: T, mediaType: String = JsonMediaType): RequestBody = - when { - content is File -> RequestBody.create( - MediaType.parse(mediaType), content - ) - mediaType == FormDataMediaType -> { - var builder = FormBody.Builder() - // content's type *must* be Map - @Suppress("UNCHECKED_CAST") - (content as Map).forEach { key, value -> - builder = builder.add(key, value) - } - builder.build() - } - mediaType == JsonMediaType -> RequestBody.create( - MediaType.parse(mediaType), Serializer.moshi.adapter(T::class.java).toJson(content) - ) - mediaType == XmlMediaType -> TODO("xml not currently supported.") - // TODO: this should be extended with other serializers - else -> TODO("requestBody currently only supports JSON body and File body.") - } + when { + content is File -> RequestBody.create( + MediaType.parse(mediaType), content + ) + mediaType == FormDataMediaType || mediaType == FormUrlEncMediaType -> { + var builder = FormBody.Builder() + // content's type *must* be Map + @Suppress("UNCHECKED_CAST") + (content as Map).forEach { key, value -> + builder = builder.add(key, value) + } + builder.build() + } + mediaType == JsonMediaType -> RequestBody.create( + MediaType.parse(mediaType), Serializer.moshi.adapter(T::class.java).toJson(content) + ) + mediaType == XmlMediaType -> TODO("xml not currently supported.") + // TODO: this should be extended with other serializers + else -> TODO("requestBody currently only supports JSON body and File body.") + } - protected inline fun responseBody(body: ResponseBody?, mediaType: String = JsonMediaType): T? { - if(body == null) return null + protected inline fun responseBody(body: ResponseBody?, mediaType: String? = JsonMediaType): T? { + if(body == null) { + return null + } + val bodyContent = body.string() + if (bodyContent.length == 0) { + return null + } return when(mediaType) { JsonMediaType -> Moshi.Builder().add(object { @ToJson @@ -62,8 +69,8 @@ open class ApiClient(val baseUrl: String) { fun fromJson(s: String) = UUID.fromString(s) }) .add(ByteArrayAdapter()) - .build().adapter(T::class.java).fromJson(body.source()) - else -> TODO() + .build().adapter(T::class.java).fromJson(bodyContent) + else -> TODO("responseBody currently only supports JSON body.") } } @@ -80,7 +87,15 @@ open class ApiClient(val baseUrl: String) { } val url = urlBuilder.build() - val headers = requestConfig.headers + defaultHeaders + + // take content-type/accept from spec or set to default (application/json) if not defined + if (requestConfig.headers[ContentType].isNullOrEmpty()) { + requestConfig.headers.put(ContentType, JsonMediaType) + } + if (requestConfig.headers[Accept].isNullOrEmpty()) { + requestConfig.headers.put(Accept, JsonMediaType) + } + val headers = requestConfig.headers if(headers[ContentType] ?: "" == "") { throw kotlin.IllegalStateException("Missing Content-Type header. This is required.") @@ -90,9 +105,8 @@ open class ApiClient(val baseUrl: String) { throw kotlin.IllegalStateException("Missing Accept header. This is required.") } - // TODO: support multiple contentType,accept options here. + // TODO: support multiple contentType options here. val contentType = (headers[ContentType] as String).substringBefore(";").toLowerCase() - val accept = (headers[Accept] as String).substringBefore(";").toLowerCase() var request : Request.Builder = when (requestConfig.method) { RequestMethod.DELETE -> Request.Builder().url(url).delete() @@ -108,6 +122,7 @@ open class ApiClient(val baseUrl: String) { val realRequest = request.build() val response = client.newCall(realRequest).execute() + val accept = response.header(ContentType)?.substringBefore(";")?.toLowerCase() // TODO: handle specific mapping types. e.g. Map> when { diff --git a/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/infrastructure/RequestConfig.kt b/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/infrastructure/RequestConfig.kt index 86e2dadf9a8..53e689237d7 100644 --- a/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/infrastructure/RequestConfig.kt +++ b/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/infrastructure/RequestConfig.kt @@ -11,6 +11,6 @@ package org.openapitools.client.infrastructure data class RequestConfig( val method: RequestMethod, val path: String, - val headers: Map = mapOf(), + val headers: MutableMap = mutableMapOf(), val query: Map> = mapOf() ) \ No newline at end of file diff --git a/samples/client/petstore/kotlin/src/test/kotlin/org/openapitools/client/PetApiTest.kt b/samples/client/petstore/kotlin/src/test/kotlin/org/openapitools/client/PetApiTest.kt index ad28e4cf8ea..d1c20493bcc 100644 --- a/samples/client/petstore/kotlin/src/test/kotlin/org/openapitools/client/PetApiTest.kt +++ b/samples/client/petstore/kotlin/src/test/kotlin/org/openapitools/client/PetApiTest.kt @@ -2,8 +2,11 @@ package org.openapitools.client import io.kotlintest.shouldBe import io.kotlintest.matchers.numerics.shouldBeGreaterThan +import io.kotlintest.matchers.string.shouldContain +import io.kotlintest.shouldThrow import io.kotlintest.specs.ShouldSpec import org.openapitools.client.apis.PetApi +import org.openapitools.client.infrastructure.ClientException import org.openapitools.client.models.Category import org.openapitools.client.models.Pet import org.openapitools.client.models.Tag @@ -11,8 +14,11 @@ import org.openapitools.client.models.Tag class PetApiTest : ShouldSpec() { init { + val petId:Long = 10006 + val api = PetApi() + should("add a pet") { - val petId:Long = 10006 + val pet = Pet( id = petId, name = "kotlin client test", @@ -20,15 +26,11 @@ class PetApiTest : ShouldSpec() { category = Category(petId, "test kotlin category"), tags = arrayOf(Tag(petId, "test kotlin tag")) ) - - val api = PetApi() api.addPet(pet) } should("get pet by id") { - val petId: Long = 10006 - val api = PetApi() val result = api.getPetById(petId) result.id shouldBe (petId) @@ -42,7 +44,6 @@ class PetApiTest : ShouldSpec() { } should("find pet by status") { - val api = PetApi() val result = api.findPetsByStatus(arrayOf("available")) result.size.shouldBeGreaterThan(0) @@ -58,15 +59,12 @@ class PetApiTest : ShouldSpec() { } should("update a pet") { - val petId:Long = 10007 val pet = Pet( id = petId, name = "kotlin client updatePet", status = Pet.Status.pending, photoUrls = arrayOf("http://test_kotlin_unit_test.com") ) - - val api = PetApi() api.updatePet(pet) // verify updated Pet @@ -77,14 +75,10 @@ class PetApiTest : ShouldSpec() { } - //TODO the test fail cause client doesn't support other JSON contentType/Accept - /* should("update a pet with form") { - val petId:Long = 10007 val name = "kotlin client updatePet with Form" val status = "pending" - val api = PetApi() api.updatePetWithForm(petId, name, status) // verify updated Pet @@ -94,7 +88,16 @@ class PetApiTest : ShouldSpec() { result.status shouldBe (Pet.Status.pending) } - */ + + should("delete a pet") { + api.deletePet(petId, "apiKey") + + // verify updated Pet + val exception = shouldThrow { + api.getPetById(petId) + } + exception.message?.shouldContain("Pet not found") + } } diff --git a/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/AppMain.kt b/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/AppMain.kt index ed8d551b297..1ebd2ba22c3 100644 --- a/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/AppMain.kt +++ b/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/AppMain.kt @@ -1,22 +1,35 @@ package org.openapitools.server -import com.codahale.metrics.* +import com.codahale.metrics.Slf4jReporter import com.typesafe.config.ConfigFactory -import io.ktor.application.* +import io.ktor.application.Application +import io.ktor.application.ApplicationStopping +import io.ktor.application.install +import io.ktor.application.log import io.ktor.client.HttpClient import io.ktor.client.engine.apache.Apache import io.ktor.config.HoconApplicationConfig -import io.ktor.features.* +import io.ktor.features.AutoHeadResponse +import io.ktor.features.Compression +import io.ktor.features.ContentNegotiation +import io.ktor.features.DefaultHeaders +import io.ktor.features.HSTS import io.ktor.gson.GsonConverter import io.ktor.http.ContentType -import io.ktor.locations.* -import io.ktor.metrics.* -import io.ktor.routing.* -import java.util.concurrent.* -import io.ktor.auth.* +import io.ktor.locations.KtorExperimentalLocationsAPI +import io.ktor.locations.Locations +import io.ktor.metrics.Metrics +import io.ktor.routing.Routing +import java.util.concurrent.TimeUnit +import io.ktor.auth.Authentication +import io.ktor.auth.oauth import io.ktor.util.KtorExperimentalAPI -import org.openapitools.server.infrastructure.* -import org.openapitools.server.apis.* +import org.openapitools.server.infrastructure.ApiKeyCredential +import org.openapitools.server.infrastructure.ApiPrincipal +import org.openapitools.server.infrastructure.apiKeyAuth +import org.openapitools.server.apis.PetApi +import org.openapitools.server.apis.StoreApi +import org.openapitools.server.apis.UserApi @KtorExperimentalAPI diff --git a/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/Configuration.kt b/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/Configuration.kt index 4cc0c0c106d..c16a32ef70f 100644 --- a/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/Configuration.kt +++ b/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/Configuration.kt @@ -2,8 +2,12 @@ package org.openapitools.server // Use this file to hold package-level internal functions that return receiver object passed to the `install` method. import io.ktor.auth.OAuthServerSettings -import io.ktor.features.* -import io.ktor.http.* +import io.ktor.features.Compression +import io.ktor.features.HSTS +import io.ktor.features.deflate +import io.ktor.features.gzip +import io.ktor.features.minimumSize +import io.ktor.http.HttpMethod import io.ktor.util.KtorExperimentalAPI import java.time.Duration import java.util.concurrent.Executors diff --git a/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/Paths.kt b/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/Paths.kt index 1807528794b..b4e203e02cf 100644 --- a/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/Paths.kt +++ b/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/Paths.kt @@ -11,9 +11,8 @@ */ package org.openapitools.server -import io.ktor.locations.* -import org.openapitools.server.models.* - +import io.ktor.locations.KtorExperimentalLocationsAPI +import io.ktor.locations.Location object Paths { /** diff --git a/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/apis/PetApi.kt b/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/apis/PetApi.kt index 813f185fe37..6423159ff17 100644 --- a/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/apis/PetApi.kt +++ b/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/apis/PetApi.kt @@ -20,10 +20,15 @@ import io.ktor.auth.OAuthAccessTokenResponse import io.ktor.auth.OAuthServerSettings import io.ktor.http.ContentType import io.ktor.http.HttpStatusCode -import io.ktor.locations.* +import io.ktor.locations.KtorExperimentalLocationsAPI +import io.ktor.locations.delete +import io.ktor.locations.get import io.ktor.response.respond import io.ktor.response.respondText -import io.ktor.routing.* +import io.ktor.routing.Route +import io.ktor.routing.post +import io.ktor.routing.put +import io.ktor.routing.route import org.openapitools.server.Paths import org.openapitools.server.infrastructure.ApiPrincipal diff --git a/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt b/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt index 81d5ed6a7b9..d46acf23c42 100644 --- a/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt +++ b/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt @@ -20,10 +20,15 @@ import io.ktor.auth.OAuthAccessTokenResponse import io.ktor.auth.OAuthServerSettings import io.ktor.http.ContentType import io.ktor.http.HttpStatusCode -import io.ktor.locations.* +import io.ktor.locations.KtorExperimentalLocationsAPI +import io.ktor.locations.delete +import io.ktor.locations.get import io.ktor.response.respond import io.ktor.response.respondText -import io.ktor.routing.* +import io.ktor.routing.Route +import io.ktor.routing.post +import io.ktor.routing.put +import io.ktor.routing.route import org.openapitools.server.Paths import org.openapitools.server.infrastructure.ApiPrincipal diff --git a/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/apis/UserApi.kt b/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/apis/UserApi.kt index 8fc86fef778..b8d8c708f2f 100644 --- a/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/apis/UserApi.kt +++ b/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/apis/UserApi.kt @@ -20,10 +20,15 @@ import io.ktor.auth.OAuthAccessTokenResponse import io.ktor.auth.OAuthServerSettings import io.ktor.http.ContentType import io.ktor.http.HttpStatusCode -import io.ktor.locations.* +import io.ktor.locations.KtorExperimentalLocationsAPI +import io.ktor.locations.delete +import io.ktor.locations.get import io.ktor.response.respond import io.ktor.response.respondText -import io.ktor.routing.* +import io.ktor.routing.Route +import io.ktor.routing.post +import io.ktor.routing.put +import io.ktor.routing.route import org.openapitools.server.Paths import org.openapitools.server.infrastructure.ApiPrincipal diff --git a/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/infrastructure/ApiKeyAuth.kt b/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/infrastructure/ApiKeyAuth.kt index 76fa161cc36..8de972967ef 100644 --- a/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/infrastructure/ApiKeyAuth.kt +++ b/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/infrastructure/ApiKeyAuth.kt @@ -2,8 +2,15 @@ package org.openapitools.server.infrastructure import io.ktor.application.ApplicationCall import io.ktor.application.call -import io.ktor.auth.* -import io.ktor.http.auth.* +import io.ktor.auth.Authentication +import io.ktor.auth.AuthenticationFailedCause +import io.ktor.auth.AuthenticationPipeline +import io.ktor.auth.AuthenticationProvider +import io.ktor.auth.Credential +import io.ktor.auth.Principal +import io.ktor.auth.UnauthorizedResponse +import io.ktor.http.auth.HeaderValueEncoding +import io.ktor.http.auth.HttpAuthHeader import io.ktor.request.ApplicationRequest import io.ktor.response.respond diff --git a/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/api/PetApi.kt b/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/api/PetApi.kt index 8249b82a638..2f70853c857 100644 --- a/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/api/PetApi.kt +++ b/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/api/PetApi.kt @@ -2,7 +2,13 @@ package org.openapitools.api import org.openapitools.model.ModelApiResponse import org.openapitools.model.Pet -import io.swagger.annotations.* +import io.swagger.annotations.Api +import io.swagger.annotations.ApiOperation +import io.swagger.annotations.ApiParam +import io.swagger.annotations.ApiResponse +import io.swagger.annotations.ApiResponses +import io.swagger.annotations.Authorization +import io.swagger.annotations.AuthorizationScope import org.springframework.http.HttpStatus import org.springframework.http.MediaType import org.springframework.http.ResponseEntity @@ -19,7 +25,13 @@ import org.springframework.web.context.request.NativeWebRequest import org.springframework.beans.factory.annotation.Autowired import javax.validation.Valid -import javax.validation.constraints.* +import javax.validation.constraints.DecimalMax +import javax.validation.constraints.DecimalMin +import javax.validation.constraints.Max +import javax.validation.constraints.Min +import javax.validation.constraints.NotNull +import javax.validation.constraints.Pattern +import javax.validation.constraints.Size import kotlin.collections.List import kotlin.collections.Map diff --git a/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/api/StoreApi.kt b/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/api/StoreApi.kt index 30a3ab439d2..ed467c5700e 100644 --- a/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/api/StoreApi.kt +++ b/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/api/StoreApi.kt @@ -1,7 +1,13 @@ package org.openapitools.api import org.openapitools.model.Order -import io.swagger.annotations.* +import io.swagger.annotations.Api +import io.swagger.annotations.ApiOperation +import io.swagger.annotations.ApiParam +import io.swagger.annotations.ApiResponse +import io.swagger.annotations.ApiResponses +import io.swagger.annotations.Authorization +import io.swagger.annotations.AuthorizationScope import org.springframework.http.HttpStatus import org.springframework.http.MediaType import org.springframework.http.ResponseEntity @@ -18,7 +24,13 @@ import org.springframework.web.context.request.NativeWebRequest import org.springframework.beans.factory.annotation.Autowired import javax.validation.Valid -import javax.validation.constraints.* +import javax.validation.constraints.DecimalMax +import javax.validation.constraints.DecimalMin +import javax.validation.constraints.Max +import javax.validation.constraints.Min +import javax.validation.constraints.NotNull +import javax.validation.constraints.Pattern +import javax.validation.constraints.Size import kotlin.collections.List import kotlin.collections.Map diff --git a/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/api/UserApi.kt b/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/api/UserApi.kt index 6eb0626a89a..bab2a54b117 100644 --- a/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/api/UserApi.kt +++ b/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/api/UserApi.kt @@ -1,7 +1,13 @@ package org.openapitools.api import org.openapitools.model.User -import io.swagger.annotations.* +import io.swagger.annotations.Api +import io.swagger.annotations.ApiOperation +import io.swagger.annotations.ApiParam +import io.swagger.annotations.ApiResponse +import io.swagger.annotations.ApiResponses +import io.swagger.annotations.Authorization +import io.swagger.annotations.AuthorizationScope import org.springframework.http.HttpStatus import org.springframework.http.MediaType import org.springframework.http.ResponseEntity @@ -18,7 +24,13 @@ import org.springframework.web.context.request.NativeWebRequest import org.springframework.beans.factory.annotation.Autowired import javax.validation.Valid -import javax.validation.constraints.* +import javax.validation.constraints.DecimalMax +import javax.validation.constraints.DecimalMin +import javax.validation.constraints.Max +import javax.validation.constraints.Min +import javax.validation.constraints.NotNull +import javax.validation.constraints.Pattern +import javax.validation.constraints.Size import kotlin.collections.List import kotlin.collections.Map diff --git a/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/model/Category.kt b/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/model/Category.kt index c34cec48df1..1a1dbf7223c 100644 --- a/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/model/Category.kt +++ b/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/model/Category.kt @@ -2,8 +2,13 @@ package org.openapitools.model import java.util.Objects import com.fasterxml.jackson.annotation.JsonProperty -import javax.validation.Valid -import javax.validation.constraints.* +import javax.validation.constraints.DecimalMax +import javax.validation.constraints.DecimalMin +import javax.validation.constraints.Max +import javax.validation.constraints.Min +import javax.validation.constraints.NotNull +import javax.validation.constraints.Pattern +import javax.validation.constraints.Size import io.swagger.annotations.ApiModelProperty /** diff --git a/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/model/ModelApiResponse.kt b/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/model/ModelApiResponse.kt index 17697fdfe8d..2f844a9c356 100644 --- a/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/model/ModelApiResponse.kt +++ b/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/model/ModelApiResponse.kt @@ -2,8 +2,13 @@ package org.openapitools.model import java.util.Objects import com.fasterxml.jackson.annotation.JsonProperty -import javax.validation.Valid -import javax.validation.constraints.* +import javax.validation.constraints.DecimalMax +import javax.validation.constraints.DecimalMin +import javax.validation.constraints.Max +import javax.validation.constraints.Min +import javax.validation.constraints.NotNull +import javax.validation.constraints.Pattern +import javax.validation.constraints.Size import io.swagger.annotations.ApiModelProperty /** diff --git a/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/model/Order.kt b/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/model/Order.kt index be8e2f33fb3..e20d850491f 100644 --- a/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/model/Order.kt +++ b/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/model/Order.kt @@ -3,8 +3,13 @@ package org.openapitools.model import java.util.Objects import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.annotation.JsonValue -import javax.validation.Valid -import javax.validation.constraints.* +import javax.validation.constraints.DecimalMax +import javax.validation.constraints.DecimalMin +import javax.validation.constraints.Max +import javax.validation.constraints.Min +import javax.validation.constraints.NotNull +import javax.validation.constraints.Pattern +import javax.validation.constraints.Size import io.swagger.annotations.ApiModelProperty /** diff --git a/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/model/Pet.kt b/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/model/Pet.kt index 80af728b7e4..9e054ac22f7 100644 --- a/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/model/Pet.kt +++ b/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/model/Pet.kt @@ -5,8 +5,13 @@ import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.annotation.JsonValue import org.openapitools.model.Category import org.openapitools.model.Tag -import javax.validation.Valid -import javax.validation.constraints.* +import javax.validation.constraints.DecimalMax +import javax.validation.constraints.DecimalMin +import javax.validation.constraints.Max +import javax.validation.constraints.Min +import javax.validation.constraints.NotNull +import javax.validation.constraints.Pattern +import javax.validation.constraints.Size import io.swagger.annotations.ApiModelProperty /** diff --git a/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/model/Tag.kt b/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/model/Tag.kt index 70c706d00a6..40ef1b9a86b 100644 --- a/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/model/Tag.kt +++ b/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/model/Tag.kt @@ -2,8 +2,13 @@ package org.openapitools.model import java.util.Objects import com.fasterxml.jackson.annotation.JsonProperty -import javax.validation.Valid -import javax.validation.constraints.* +import javax.validation.constraints.DecimalMax +import javax.validation.constraints.DecimalMin +import javax.validation.constraints.Max +import javax.validation.constraints.Min +import javax.validation.constraints.NotNull +import javax.validation.constraints.Pattern +import javax.validation.constraints.Size import io.swagger.annotations.ApiModelProperty /** diff --git a/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/model/User.kt b/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/model/User.kt index 4cfaf098874..95fe12aa467 100644 --- a/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/model/User.kt +++ b/samples/server/petstore/kotlin-springboot/src/main/kotlin/org/openapitools/model/User.kt @@ -2,8 +2,13 @@ package org.openapitools.model import java.util.Objects import com.fasterxml.jackson.annotation.JsonProperty -import javax.validation.Valid -import javax.validation.constraints.* +import javax.validation.constraints.DecimalMax +import javax.validation.constraints.DecimalMin +import javax.validation.constraints.Max +import javax.validation.constraints.Min +import javax.validation.constraints.NotNull +import javax.validation.constraints.Pattern +import javax.validation.constraints.Size import io.swagger.annotations.ApiModelProperty /**