diff --git a/bin/configs/other/kotlin-spring-boot-modelMutable.yaml b/bin/configs/kotlin-spring-boot-modelMutable.yaml
similarity index 100%
rename from bin/configs/other/kotlin-spring-boot-modelMutable.yaml
rename to bin/configs/kotlin-spring-boot-modelMutable.yaml
diff --git a/bin/configs/other/kotlin-vertx-vertx.yaml b/bin/configs/kotlin-vertx-vertx.yaml
similarity index 100%
rename from bin/configs/other/kotlin-vertx-vertx.yaml
rename to bin/configs/kotlin-vertx-vertx.yaml
diff --git a/bin/configs/other/openapi3/kotlin-jvm-retrofit2-coroutines.yaml b/bin/configs/other/kotlin-jvm-retrofit2-coroutines.yaml
similarity index 100%
rename from bin/configs/other/openapi3/kotlin-jvm-retrofit2-coroutines.yaml
rename to bin/configs/other/kotlin-jvm-retrofit2-coroutines.yaml
diff --git a/bin/configs/other/openapi3/kotlin-jvm-retrofit2-rx.yaml b/bin/configs/other/kotlin-jvm-retrofit2-rx.yaml
similarity index 100%
rename from bin/configs/other/openapi3/kotlin-jvm-retrofit2-rx.yaml
rename to bin/configs/other/kotlin-jvm-retrofit2-rx.yaml
diff --git a/bin/configs/other/openapi3/kotlin-jvm-retrofit2-rx2-kotlinx_serialization.yaml b/bin/configs/other/kotlin-jvm-retrofit2-rx2-kotlinx_serialization.yaml
similarity index 100%
rename from bin/configs/other/openapi3/kotlin-jvm-retrofit2-rx2-kotlinx_serialization.yaml
rename to bin/configs/other/kotlin-jvm-retrofit2-rx2-kotlinx_serialization.yaml
diff --git a/bin/configs/other/openapi3/kotlin-jvm-retrofit2-rx2.yaml b/bin/configs/other/kotlin-jvm-retrofit2-rx2.yaml
similarity index 100%
rename from bin/configs/other/openapi3/kotlin-jvm-retrofit2-rx2.yaml
rename to bin/configs/other/kotlin-jvm-retrofit2-rx2.yaml
diff --git a/bin/configs/other/openapi3/kotlin-multiplatform.yaml b/bin/configs/other/kotlin-multiplatform.yaml
similarity index 100%
rename from bin/configs/other/openapi3/kotlin-multiplatform.yaml
rename to bin/configs/other/kotlin-multiplatform.yaml
diff --git a/bin/configs/other/openapi3/kotlin-spring-boot-reactive.yaml b/bin/configs/other/kotlin-spring-boot-reactive.yaml
similarity index 100%
rename from bin/configs/other/openapi3/kotlin-spring-boot-reactive.yaml
rename to bin/configs/other/kotlin-spring-boot-reactive.yaml
diff --git a/bin/configs/other/openapi3/kotlin-spring-boot.yaml b/bin/configs/other/kotlin-spring-boot.yaml
similarity index 100%
rename from bin/configs/other/openapi3/kotlin-spring-boot.yaml
rename to bin/configs/other/kotlin-spring-boot.yaml
diff --git a/bin/configs/other/openapi3/kotlin.yaml b/bin/configs/other/kotlin.yaml
similarity index 100%
rename from bin/configs/other/openapi3/kotlin.yaml
rename to bin/configs/other/kotlin.yaml
diff --git a/docs/generators/kotlin-server-deprecated.md b/docs/generators/kotlin-server-deprecated.md
index 2287e954abf..7e53620aa6e 100644
--- a/docs/generators/kotlin-server-deprecated.md
+++ b/docs/generators/kotlin-server-deprecated.md
@@ -74,6 +74,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
## RESERVED WORDS
+- ApiResponse
- abstract
- actual
- annotation
diff --git a/docs/generators/kotlin-server.md b/docs/generators/kotlin-server.md
index 81f75ca5785..0c0228d8a8c 100644
--- a/docs/generators/kotlin-server.md
+++ b/docs/generators/kotlin-server.md
@@ -76,6 +76,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
## RESERVED WORDS
+- ApiResponse
- abstract
- actual
- annotation
diff --git a/docs/generators/kotlin-vertx.md b/docs/generators/kotlin-vertx.md
index 90afde4de81..02d608e5274 100644
--- a/docs/generators/kotlin-vertx.md
+++ b/docs/generators/kotlin-vertx.md
@@ -68,6 +68,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
## RESERVED WORDS
+- ApiResponse
- abstract
- actual
- annotation
diff --git a/docs/generators/kotlin.md b/docs/generators/kotlin.md
index 49e02994b74..cbf43a3a1e9 100644
--- a/docs/generators/kotlin.md
+++ b/docs/generators/kotlin.md
@@ -79,6 +79,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
## RESERVED WORDS
+- ApiResponse
- abstract
- actual
- annotation
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenResponse.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenResponse.java
index b81bda5f583..7a23b3ab726 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenResponse.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenResponse.java
@@ -21,6 +21,7 @@ import java.util.*;
public class CodegenResponse implements IJsonSchemaValidationProperties {
public final List headers = new ArrayList();
+ private List responseHeaders = new ArrayList();
public String code;
public boolean is1xx;
public boolean is2xx;
@@ -87,6 +88,7 @@ public class CodegenResponse implements IJsonSchemaValidationProperties {
private boolean hasDiscriminatorWithNonEmptyMapping;
private CodegenComposedSchemas composedSchemas;
private boolean hasMultipleTypes = false;
+ private LinkedHashMap content;
@Override
public int hashCode() {
@@ -98,7 +100,7 @@ public class CodegenResponse implements IJsonSchemaValidationProperties {
getMaxProperties(), getMinProperties(), uniqueItems, getMaxItems(), getMinItems(), getMaxLength(),
getMinLength(), exclusiveMinimum, exclusiveMaximum, getMinimum(), getMaximum(), getPattern(),
is1xx, is2xx, is3xx, is4xx, is5xx, additionalPropertiesIsAnyType, hasVars, hasRequired,
- hasDiscriminatorWithNonEmptyMapping, composedSchemas, hasMultipleTypes);
+ hasDiscriminatorWithNonEmptyMapping, composedSchemas, hasMultipleTypes, responseHeaders, content);
}
@Override
@@ -147,6 +149,8 @@ public class CodegenResponse implements IJsonSchemaValidationProperties {
getAdditionalPropertiesIsAnyType() == that.getAdditionalPropertiesIsAnyType() &&
getHasVars() == that.getHasVars() &&
getHasRequired() == that.getHasRequired() &&
+ Objects.equals(content, that.getContent()) &&
+ Objects.equals(responseHeaders, that.getResponseHeaders()) &&
Objects.equals(composedSchemas, that.getComposedSchemas()) &&
Objects.equals(vars, that.vars) &&
Objects.equals(requiredVars, that.requiredVars) &&
@@ -176,6 +180,22 @@ public class CodegenResponse implements IJsonSchemaValidationProperties {
}
+ public LinkedHashMap getContent() {
+ return content;
+ }
+
+ public void setContent(LinkedHashMap content) {
+ this.content = content;
+ }
+
+ public List getResponseHeaders() {
+ return responseHeaders;
+ }
+
+ public void setResponseHeaders(List responseHeaders) {
+ this.responseHeaders = responseHeaders;
+ }
+
@Override
public String getPattern() {
return pattern;
@@ -488,6 +508,8 @@ public class CodegenResponse implements IJsonSchemaValidationProperties {
sb.append(", getHasDiscriminatorWithNonEmptyMapping=").append(hasDiscriminatorWithNonEmptyMapping);
sb.append(", composedSchemas=").append(composedSchemas);
sb.append(", hasMultipleTypes=").append(hasMultipleTypes);
+ sb.append(", responseHeaders=").append(responseHeaders);
+ sb.append(", content=").append(content);
sb.append('}');
return sb.toString();
}
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java
index e97a6caf557..a9780140f4c 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java
@@ -3170,10 +3170,16 @@ public class DefaultCodegen implements CodegenConfig {
List uniqueDescendants = new ArrayList();
if (sourceDiscriminator.getMapping() != null && !sourceDiscriminator.getMapping().isEmpty()) {
for (Entry e : sourceDiscriminator.getMapping().entrySet()) {
- String nameOrRef = e.getValue();
- String name = nameOrRef.indexOf('/') >= 0 ? ModelUtils.getSimpleRef(nameOrRef) : nameOrRef;
- String modelName = toModelName(name);
- uniqueDescendants.add(new MappedModel(e.getKey(), modelName));
+ String name;
+ if (e.getValue().indexOf('/') >= 0) {
+ name = ModelUtils.getSimpleRef(e.getValue());
+ if (ModelUtils.getSchema(openAPI, name) == null) {
+ LOGGER.error("Failed to lookup the schema '{}' when processing the discriminator mapping of oneOf/anyOf. Please check to ensure it's defined properly.", name);
+ }
+ } else {
+ name = e.getValue();
+ }
+ uniqueDescendants.add(new MappedModel(e.getKey(), toModelName(name)));
}
}
@@ -3959,6 +3965,20 @@ public class DefaultCodegen implements CodegenConfig {
ApiResponse response = operationGetResponsesEntry.getValue();
addProducesInfo(response, op);
CodegenResponse r = fromResponse(key, response);
+ Map headers = response.getHeaders();
+ if (headers != null) {
+ List responseHeaders = new ArrayList<>();
+ for (Entry entry: headers.entrySet()) {
+ String headerName = entry.getKey();
+ Header header = entry.getValue();
+ CodegenParameter responseHeader = heeaderToCodegenParameter(header, headerName, imports, String.format(Locale.ROOT, "%sResponseParameter", r.code));
+ responseHeaders.add(responseHeader);
+ }
+ r.setResponseHeaders(responseHeaders);
+ }
+ String mediaTypeSchemaSuffix = String.format(Locale.ROOT, "%sResponseBody", r.code);
+ r.setContent(getContent(response.getContent(), imports, mediaTypeSchemaSuffix));
+
if (r.baseType != null &&
!defaultIncludes.contains(r.baseType) &&
!languageSpecificPrimitives.contains(r.baseType)) {
@@ -4065,6 +4085,7 @@ public class DefaultCodegen implements CodegenConfig {
param = ModelUtils.getReferencedParameter(this.openAPI, param);
CodegenParameter p = fromParameter(param, imports);
+ p.setContent(getContent(param.getContent(), imports, "RequestParameter" + toModelName(param.getName())));
// ensure unique params
if (ensureUniqueParams) {
@@ -4502,7 +4523,6 @@ public class DefaultCodegen implements CodegenConfig {
codegenParameter.isDeprecated = parameter.getDeprecated();
}
codegenParameter.jsonSchema = Json.pretty(parameter);
- codegenParameter.setContent(getContent(parameter.getContent(), imports));
if (GlobalSettings.getProperty("debugParser") != null) {
LOGGER.info("working on Parameter {}", parameter.getName());
@@ -6586,11 +6606,36 @@ public class DefaultCodegen implements CodegenConfig {
codegenParameter.pattern = toRegularExpression(schema.getPattern());
}
- protected String toMediaTypeSchemaName(String contentType) {
- return toModelName(contentType + "Schema");
+ protected String toMediaTypeSchemaName(String contentType, String mediaTypeSchemaSuffix) {
+ return "SchemaFor" + mediaTypeSchemaSuffix + toModelName(contentType);
}
- protected LinkedHashMap getContent(Content content, Set imports) {
+ private CodegenParameter heeaderToCodegenParameter(Header header, String headerName, Set imports, String mediaTypeSchemaSuffix) {
+ if (header == null) {
+ return null;
+ }
+ Parameter headerParam = new Parameter();
+ headerParam.setName(headerName);
+ headerParam.setIn("header");
+ headerParam.setDescription(header.getDescription());
+ headerParam.setRequired(header.getRequired());
+ headerParam.setDeprecated(header.getDeprecated());
+ Header.StyleEnum style = header.getStyle();
+ if (style != null) {
+ headerParam.setStyle(Parameter.StyleEnum.valueOf(style.name()));
+ }
+ headerParam.setExplode(header.getExplode());
+ headerParam.setSchema(header.getSchema());
+ headerParam.setExamples(header.getExamples());
+ headerParam.setExample(header.getExample());
+ headerParam.setContent(header.getContent());
+ headerParam.setExtensions(header.getExtensions());
+ CodegenParameter param = fromParameter(headerParam, imports);
+ param.setContent(getContent(headerParam.getContent(), imports, mediaTypeSchemaSuffix));
+ return param;
+ }
+
+ protected LinkedHashMap getContent(Content content, Set imports, String mediaTypeSchemaSuffix) {
if (content == null) {
return null;
}
@@ -6609,20 +6654,7 @@ public class DefaultCodegen implements CodegenConfig {
for (Entry headerEntry: encHeaders.entrySet()) {
String headerName = headerEntry.getKey();
Header header = ModelUtils.getReferencedHeader(this.openAPI, headerEntry.getValue());
- Parameter headerParam = new Parameter();
- headerParam.setName(headerName);
- headerParam.setIn("header");
- headerParam.setDescription(header.getDescription());
- headerParam.setRequired(header.getRequired());
- headerParam.setDeprecated(header.getDeprecated());
- headerParam.setStyle(Parameter.StyleEnum.valueOf(header.getStyle().name()));
- headerParam.setExplode(header.getExplode());
- headerParam.setSchema(header.getSchema());
- headerParam.setExamples(header.getExamples());
- headerParam.setExample(header.getExample());
- headerParam.setContent(header.getContent());
- headerParam.setExtensions(header.getExtensions());
- CodegenParameter param = fromParameter(headerParam, imports);
+ CodegenParameter param = heeaderToCodegenParameter(header, headerName, imports, mediaTypeSchemaSuffix);
headers.add(param);
}
}
@@ -6638,7 +6670,7 @@ public class DefaultCodegen implements CodegenConfig {
}
}
String contentType = contentEntry.getKey();
- CodegenProperty schemaProp = fromProperty(toMediaTypeSchemaName(contentType), mt.getSchema());
+ CodegenProperty schemaProp = fromProperty(toMediaTypeSchemaName(contentType, mediaTypeSchemaSuffix), mt.getSchema());
CodegenMediaType codegenMt = new CodegenMediaType(schemaProp, ceMap);
cmtContent.put(contentType, codegenMt);
}
@@ -6666,7 +6698,7 @@ public class DefaultCodegen implements CodegenConfig {
if (schema == null) {
throw new RuntimeException("Request body cannot be null. Possible cause: missing schema in body parameter (OAS v2): " + body);
}
- codegenParameter.setContent(getContent(body.getContent(), imports));
+ codegenParameter.setContent(getContent(body.getContent(), imports, "RequestBody"));
if (StringUtils.isNotBlank(schema.get$ref())) {
name = ModelUtils.getSimpleRef(schema.get$ref());
@@ -6721,6 +6753,8 @@ public class DefaultCodegen implements CodegenConfig {
} else if (ModelUtils.isObjectSchema(schema)) {
// object type schema OR (AnyType schema with properties defined)
this.addBodyModelSchema(codegenParameter, name, schema, imports, bodyParameterName, false);
+ } else {
+ updateRequestBodyForPrimitiveType(codegenParameter, schema, bodyParameterName, imports);
}
addVarsRequiredVarsAdditionalProps(schema, codegenParameter);
} else {
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractKotlinCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractKotlinCodegen.java
index e0fb899e2f3..0cd24435d48 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractKotlinCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractKotlinCodegen.java
@@ -98,6 +98,7 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
// this includes hard reserved words defined by https://github.com/JetBrains/kotlin/blob/master/core/descriptors/src/org/jetbrains/kotlin/renderer/KeywordStringsGenerated.java
// as well as keywords from https://kotlinlang.org/docs/reference/keyword-reference.html
reservedWords = new HashSet<>(Arrays.asList(
+ "ApiResponse", // Used in the auto-generated api client
"abstract",
"actual",
"annotation",
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 28a3853332d..c8d7a87716d 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
@@ -18,8 +18,21 @@
package org.openapitools.codegen.languages;
import org.apache.commons.lang3.StringUtils;
-import org.openapitools.codegen.*;
-import org.openapitools.codegen.meta.features.*;
+import org.openapitools.codegen.CliOption;
+import org.openapitools.codegen.CodegenConstants;
+import org.openapitools.codegen.CodegenModel;
+import org.openapitools.codegen.CodegenOperation;
+import org.openapitools.codegen.CodegenParameter;
+import org.openapitools.codegen.CodegenProperty;
+import org.openapitools.codegen.CodegenType;
+import org.openapitools.codegen.SupportingFile;
+import org.openapitools.codegen.meta.features.ClientModificationFeature;
+import org.openapitools.codegen.meta.features.DocumentationFeature;
+import org.openapitools.codegen.meta.features.GlobalFeature;
+import org.openapitools.codegen.meta.features.ParameterFeature;
+import org.openapitools.codegen.meta.features.SchemaSupportFeature;
+import org.openapitools.codegen.meta.features.SecurityFeature;
+import org.openapitools.codegen.meta.features.WireFormatFeature;
import org.openapitools.codegen.utils.ProcessUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -28,6 +41,7 @@ import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -479,14 +493,12 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen {
break;
case gson:
- supportingFiles.add(new SupportingFile("jvm-common/infrastructure/DateAdapter.kt.mustache", infrastructureFolder, "DateAdapter.kt"));
supportingFiles.add(new SupportingFile("jvm-common/infrastructure/LocalDateAdapter.kt.mustache", infrastructureFolder, "LocalDateAdapter.kt"));
supportingFiles.add(new SupportingFile("jvm-common/infrastructure/LocalDateTimeAdapter.kt.mustache", infrastructureFolder, "LocalDateTimeAdapter.kt"));
supportingFiles.add(new SupportingFile("jvm-common/infrastructure/OffsetDateTimeAdapter.kt.mustache", infrastructureFolder, "OffsetDateTimeAdapter.kt"));
break;
case jackson:
- //supportingFiles.add(new SupportingFile("jvm-common/infrastructure/DateAdapter.kt.mustache", infrastructureFolder, "DateAdapter.kt"));
break;
case kotlinx_serialization:
@@ -497,7 +509,6 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen {
supportingFiles.add(new SupportingFile("jvm-common/infrastructure/URLAdapter.kt.mustache", infrastructureFolder, "URLAdapter.kt"));
supportingFiles.add(new SupportingFile("jvm-common/infrastructure/BigIntegerAdapter.kt.mustache", infrastructureFolder, "BigIntegerAdapter.kt"));
supportingFiles.add(new SupportingFile("jvm-common/infrastructure/BigDecimalAdapter.kt.mustache", infrastructureFolder, "BigDecimalAdapter.kt"));
- supportingFiles.add(new SupportingFile("jvm-common/infrastructure/DateAdapter.kt.mustache", infrastructureFolder, "DateAdapter.kt"));
supportingFiles.add(new SupportingFile("jvm-common/infrastructure/LocalDateAdapter.kt.mustache", infrastructureFolder, "LocalDateAdapter.kt"));
supportingFiles.add(new SupportingFile("jvm-common/infrastructure/LocalDateTimeAdapter.kt.mustache", infrastructureFolder, "LocalDateTimeAdapter.kt"));
supportingFiles.add(new SupportingFile("jvm-common/infrastructure/OffsetDateTimeAdapter.kt.mustache", infrastructureFolder, "OffsetDateTimeAdapter.kt"));
@@ -527,7 +538,7 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen {
// jvm specific supporting files
supportingFiles.add(new SupportingFile("infrastructure/Errors.kt.mustache", infrastructureFolder, "Errors.kt"));
supportingFiles.add(new SupportingFile("infrastructure/ResponseExtensions.kt.mustache", infrastructureFolder, "ResponseExtensions.kt"));
- supportingFiles.add(new SupportingFile("infrastructure/ApiInfrastructureResponse.kt.mustache", infrastructureFolder, "ApiInfrastructureResponse.kt"));
+ supportingFiles.add(new SupportingFile("infrastructure/ApiResponse.kt.mustache", infrastructureFolder, "ApiResponse.kt"));
}
private void processMultiplatformLibrary(final String infrastructureFolder) {
@@ -617,14 +628,14 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen {
// escape the variable base name for use as a string literal
List vars = Stream.of(
- cm.vars,
- cm.allVars,
- cm.optionalVars,
- cm.requiredVars,
- cm.readOnlyVars,
- cm.readWriteVars,
- cm.parentVars
- )
+ cm.vars,
+ cm.allVars,
+ cm.optionalVars,
+ cm.requiredVars,
+ cm.readOnlyVars,
+ cm.readWriteVars,
+ cm.parentVars
+ )
.flatMap(List::stream)
.collect(Collectors.toList());
@@ -653,6 +664,35 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen {
operation.path = operation.path.substring(1);
}
+ if (JVM_OKHTTP.equals(getLibrary()) || JVM_OKHTTP3.equals(getLibrary()) || JVM_OKHTTP4.equals(getLibrary())) {
+ // Ideally we would do content negotiation to choose the best mediatype, but that would be a next step.
+ // For now we take the first mediatype we can parse and send that.
+ Predicate