diff --git a/.github/workflows/samples-kotlin-server.yaml b/.github/workflows/samples-kotlin-server.yaml index 868cd3e4936..5f76d2fb9bc 100644 --- a/.github/workflows/samples-kotlin-server.yaml +++ b/.github/workflows/samples-kotlin-server.yaml @@ -5,12 +5,14 @@ on: branches: - samples/server/others/kotlin-server/jaxrs-spec/** - 'samples/server/petstore/kotlin*/**' + - 'samples/server/others/kotlin-server/jaxrs-spec-array-response/**' # comment out due to gradle build failure #- samples/server/petstore/kotlin-spring-default/** pull_request: paths: - samples/server/others/kotlin-server/jaxrs-spec/** - 'samples/server/petstore/kotlin*/**' + - 'samples/server/others/kotlin-server/jaxrs-spec-array-response/**' # comment out due to gradle build failure # - samples/server/petstore/kotlin-spring-default/** @@ -40,6 +42,7 @@ jobs: - samples/server/petstore/kotlin-server-modelMutable - samples/server/petstore/kotlin-server/javalin - samples/server/others/kotlin-server/jaxrs-spec + - samples/server/others/kotlin-server/jaxrs-spec-array-response # comment out due to gradle build failure #- samples/server/petstore/kotlin-spring-default # no build.gradle file diff --git a/bin/configs/kotlin-server-jaxrs-spec-array-response.yaml b/bin/configs/kotlin-server-jaxrs-spec-array-response.yaml new file mode 100644 index 00000000000..ce6fe3f06c8 --- /dev/null +++ b/bin/configs/kotlin-server-jaxrs-spec-array-response.yaml @@ -0,0 +1,8 @@ +generatorName: kotlin-server +outputDir: samples/server/others/kotlin-server/jaxrs-spec-array-response +library: jaxrs-spec +inputSpec: modules/openapi-generator/src/test/resources/3_0/kotlin/issue18177-array.yaml +templateDir: modules/openapi-generator/src/main/resources/kotlin-server +additionalProperties: + interfaceOnly: "true" + useJakartaEe: true 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 b3fb66cf704..b5b5bd36352 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 @@ -30,10 +30,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; -import java.util.Arrays; -import java.util.EnumSet; -import java.util.List; -import java.util.Map; +import java.util.*; public class KotlinServerCodegen extends AbstractKotlinCodegen implements BeanValidationFeatures { @@ -412,7 +409,8 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen implements BeanVa @Override public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List allModels) { OperationMap operations = objs.getOperations(); - if (operations != null) { + // The following processing breaks the JAX-RS spec, so we only do this for the other libs. + if (operations != null && !Objects.equals(library, Constants.JAXRS_SPEC)) { List ops = operations.getOperation(); ops.forEach(operation -> { List responses = operation.responses; diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinServerCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinServerCodegenTest.java index 795301dae72..42f4777d7dc 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinServerCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinServerCodegenTest.java @@ -15,6 +15,7 @@ import java.nio.file.Paths; import static org.openapitools.codegen.CodegenConstants.LIBRARY; import static org.openapitools.codegen.languages.AbstractKotlinCodegen.USE_JAKARTA_EE; +import static org.openapitools.codegen.languages.KotlinServerCodegen.Constants.INTERFACE_ONLY; import static org.openapitools.codegen.languages.KotlinServerCodegen.Constants.JAXRS_SPEC; import static org.openapitools.codegen.TestUtils.assertFileContains; import static org.openapitools.codegen.TestUtils.assertFileNotContains; @@ -166,6 +167,38 @@ public class KotlinServerCodegenTest { ); } + @Test + public void issue18177Arrays() throws IOException { + File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); + output.deleteOnExit(); + + KotlinServerCodegen codegen = new KotlinServerCodegen(); + codegen.setOutputDir(output.getAbsolutePath()); + codegen.setUseBeanValidation(true); + codegen.additionalProperties().put(INTERFACE_ONLY, true); + codegen.additionalProperties().put(USE_JAKARTA_EE, true); + codegen.additionalProperties().put(LIBRARY, JAXRS_SPEC); + new DefaultGenerator().opts(new ClientOptInput() + .openAPI(TestUtils.parseSpec("src/test/resources/3_0/kotlin/issue18177-array.yaml")) + .config(codegen)) + .generate(); + + String outputPath = output.getAbsolutePath() + "/src/main/kotlin/org/openapitools/server"; + Path stuffApi = Paths.get(outputPath + "/apis/StuffApi.kt"); + assertFileContains( + stuffApi, + "fun findStuff(): kotlin.collections.List" + ); + assertFileNotContains( + stuffApi, + "fun findStuff(): Stuff" + ); + assertFileContains( + stuffApi, + "fun findUniqueStuff(): kotlin.collections.Set" + ); + } + // to test attributes in the $ref (OpenAPI 3.1 spec) @Test public void attributesInRef() throws IOException { diff --git a/modules/openapi-generator/src/test/resources/3_0/kotlin/issue18177-array.yaml b/modules/openapi-generator/src/test/resources/3_0/kotlin/issue18177-array.yaml new file mode 100644 index 00000000000..3a9c4a7094a --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/kotlin/issue18177-array.yaml @@ -0,0 +1,77 @@ +openapi: 3.0.0 +servers: + - url: 'https://example.org/v1' +info: + description: >- + Example created + version: 1.0.0 + title: OpenAPI Stuff API created to reproduce issue + license: + name: Apache-2.0 + url: 'https://www.apache.org/licenses/LICENSE-2.0.html' +tags: + - name: stuff + description: All about the stuff +security: + - bearerAuth: [] +paths: + /stuff: + get: + tags: + - stuff + summary: Finds stuff + description: Finds stuff + operationId: findStuff + responses: + '200': + description: successful operation + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Stuff' + '400': + description: Invalid status value + /uniquestuff: + get: + tags: + - stuff + summary: Finds unique stuff + description: Finds unique stuff + operationId: find unique Stuff + responses: + '200': + description: successful operation + content: + application/json: + schema: + type: array + uniqueItems: true + items: + $ref: '#/components/schemas/Stuff' + '400': + description: Invalid status value +externalDocs: + description: Find out more about Swagger + url: 'http://swagger.io' +components: + securitySchemes: + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT + schemas: + Stuff: + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + tag: + type: string + required: + - name + diff --git a/samples/server/others/kotlin-server/jaxrs-spec-array-response/.openapi-generator-ignore b/samples/server/others/kotlin-server/jaxrs-spec-array-response/.openapi-generator-ignore new file mode 100644 index 00000000000..7484ee590a3 --- /dev/null +++ b/samples/server/others/kotlin-server/jaxrs-spec-array-response/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/server/others/kotlin-server/jaxrs-spec-array-response/.openapi-generator/FILES b/samples/server/others/kotlin-server/jaxrs-spec-array-response/.openapi-generator/FILES new file mode 100644 index 00000000000..2bb928a5e7e --- /dev/null +++ b/samples/server/others/kotlin-server/jaxrs-spec-array-response/.openapi-generator/FILES @@ -0,0 +1,6 @@ +README.md +build.gradle +gradle.properties +settings.gradle +src/main/kotlin/org/openapitools/server/apis/StuffApi.kt +src/main/kotlin/org/openapitools/server/models/Stuff.kt diff --git a/samples/server/others/kotlin-server/jaxrs-spec-array-response/.openapi-generator/VERSION b/samples/server/others/kotlin-server/jaxrs-spec-array-response/.openapi-generator/VERSION new file mode 100644 index 00000000000..08bfd0643b8 --- /dev/null +++ b/samples/server/others/kotlin-server/jaxrs-spec-array-response/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.5.0-SNAPSHOT diff --git a/samples/server/others/kotlin-server/jaxrs-spec-array-response/README.md b/samples/server/others/kotlin-server/jaxrs-spec-array-response/README.md new file mode 100644 index 00000000000..c299cbd2952 --- /dev/null +++ b/samples/server/others/kotlin-server/jaxrs-spec-array-response/README.md @@ -0,0 +1,56 @@ +# org.openapitools.server - Kotlin Server library for OpenAPI Stuff API created to reproduce issue + +## Requires + +* Kotlin 1.4.31 +* Gradle 6.8.2 + +## Build + +First, create the gradle wrapper script: + +``` +gradle wrapper +``` + +Then, run: + +``` +./gradlew check assemble +``` + +This runs all tests and packages the library. + +## Features/Implementation Notes + +* Supports JSON inputs/outputs, File inputs, and Form inputs. +* Supports collection formats for query parameters: csv, tsv, ssv, pipes. +* Some Kotlin and Java types are fully qualified to avoid conflicts with types defined in OpenAPI definitions. + + +## Documentation for API Endpoints + +All URIs are relative to *https://example.org/v1* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +*StuffApi* | [**findStuff**](docs/StuffApi.md#findstuff) | **GET** /stuff | Finds stuff +*StuffApi* | [**findUniqueStuff**](docs/StuffApi.md#finduniquestuff) | **GET** /uniquestuff | Finds unique stuff + + + +## Documentation for Models + + - [org.openapitools.server.models.Stuff](docs/Stuff.md) + + + +## Documentation for Authorization + + +Authentication schemes defined for the API: + +### bearerAuth + +- **Type**: HTTP Bearer Token authentication (JWT) + diff --git a/samples/server/others/kotlin-server/jaxrs-spec-array-response/build.gradle b/samples/server/others/kotlin-server/jaxrs-spec-array-response/build.gradle new file mode 100644 index 00000000000..1eb159881c5 --- /dev/null +++ b/samples/server/others/kotlin-server/jaxrs-spec-array-response/build.gradle @@ -0,0 +1,51 @@ +group "org.openapitools" +version "1.0.0" + +wrapper { + gradleVersion = '6.9' + distributionUrl = "https://services.gradle.org/distributions/gradle-$gradleVersion-all.zip" +} + +buildscript { + ext.kotlin_version = "1.7.20" + ext.swagger_annotations_version = "1.5.3" + ext.jakarta_annotations_version = "2.1.1" + ext.jakarta_ws_rs_version = "3.1.0" + ext.jackson_version = "2.9.9" + repositories { + maven { url "https://repo1.maven.org/maven2" } + maven { url "https://plugins.gradle.org/m2/" } + } + dependencies { + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version") + } +} + +apply plugin: "java" +apply plugin: "kotlin" +apply plugin: "application" + +sourceCompatibility = 1.8 + +compileKotlin { + kotlinOptions.jvmTarget = "1.8" +} + +compileTestKotlin { + kotlinOptions.jvmTarget = "1.8" +} + +repositories { + maven { setUrl("https://repo1.maven.org/maven2") } +} + +dependencies { + implementation("org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version") + implementation("ch.qos.logback:logback-classic:1.2.1") + implementation("jakarta.ws.rs:jakarta.ws.rs-api:$jakarta_ws_rs_version") + implementation("jakarta.annotation:jakarta.annotation-api:$jakarta_annotations_version") + implementation("io.swagger:swagger-annotations:$swagger_annotations_version") + implementation("com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:$jackson_version") + implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_version") + testImplementation("junit:junit:4.13.2") +} diff --git a/samples/server/others/kotlin-server/jaxrs-spec-array-response/gradle.properties b/samples/server/others/kotlin-server/jaxrs-spec-array-response/gradle.properties new file mode 100644 index 00000000000..5f1ed7bbe02 --- /dev/null +++ b/samples/server/others/kotlin-server/jaxrs-spec-array-response/gradle.properties @@ -0,0 +1 @@ +org.gradle.caching=true \ No newline at end of file diff --git a/samples/server/others/kotlin-server/jaxrs-spec-array-response/settings.gradle b/samples/server/others/kotlin-server/jaxrs-spec-array-response/settings.gradle new file mode 100644 index 00000000000..a09a58efab1 --- /dev/null +++ b/samples/server/others/kotlin-server/jaxrs-spec-array-response/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'kotlin-server' \ No newline at end of file diff --git a/samples/server/others/kotlin-server/jaxrs-spec-array-response/src/main/kotlin/org/openapitools/server/apis/StuffApi.kt b/samples/server/others/kotlin-server/jaxrs-spec-array-response/src/main/kotlin/org/openapitools/server/apis/StuffApi.kt new file mode 100644 index 00000000000..2cada764532 --- /dev/null +++ b/samples/server/others/kotlin-server/jaxrs-spec-array-response/src/main/kotlin/org/openapitools/server/apis/StuffApi.kt @@ -0,0 +1,26 @@ +package org.openapitools.server.apis; + +import org.openapitools.server.models.Stuff + +import jakarta.ws.rs.* +import jakarta.ws.rs.core.Response + + +import java.io.InputStream + + + +@Path("/") +@jakarta.annotation.Generated(value = arrayOf("org.openapitools.codegen.languages.KotlinServerCodegen"), comments = "Generator version: 7.5.0-SNAPSHOT") +interface StuffApi { + + @GET + @Path("/stuff") + @Produces("application/json") + fun findStuff(): kotlin.collections.List + + @GET + @Path("/uniquestuff") + @Produces("application/json") + fun findUniqueStuff(): kotlin.collections.Set +} diff --git a/samples/server/others/kotlin-server/jaxrs-spec-array-response/src/main/kotlin/org/openapitools/server/models/Stuff.kt b/samples/server/others/kotlin-server/jaxrs-spec-array-response/src/main/kotlin/org/openapitools/server/models/Stuff.kt new file mode 100644 index 00000000000..85c2c68adbf --- /dev/null +++ b/samples/server/others/kotlin-server/jaxrs-spec-array-response/src/main/kotlin/org/openapitools/server/models/Stuff.kt @@ -0,0 +1,39 @@ +/** + * OpenAPI Stuff API created to reproduce issue + * Example created + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. +*/ +package org.openapitools.server.models + +import com.fasterxml.jackson.annotation.JsonProperty +/** + * + * + * @param name + * @param id + * @param tag + */ + + +data class Stuff ( + + + @JsonProperty("name") + val name: kotlin.String, + + + @JsonProperty("id") + val id: kotlin.Long? = null, + + + @JsonProperty("tag") + val tag: kotlin.String? = null + +) +