diff --git a/bin/configs/kotlin-server-jaxrs-spec.yaml b/bin/configs/kotlin-server-jaxrs-spec.yaml new file mode 100644 index 00000000000..11d4fcec7a8 --- /dev/null +++ b/bin/configs/kotlin-server-jaxrs-spec.yaml @@ -0,0 +1,7 @@ +generatorName: kotlin-server +outputDir: samples/server/petstore/kotlin-server/jaxrs-spec +library: jaxrs-spec +inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml +templateDir: modules/openapi-generator/src/main/resources/kotlin-server +additionalProperties: + useCoroutines: "true" diff --git a/docs/generators/kotlin-server.md b/docs/generators/kotlin-server.md index 4d79d17024f..9fa866983a4 100644 --- a/docs/generators/kotlin-server.md +++ b/docs/generators/kotlin-server.md @@ -30,15 +30,19 @@ These options may be applied as additional-properties (cli) or configOptions (pl |featureLocations|Generates routes in a typed way, for both: constructing URLs and reading the parameters.| |true| |featureMetrics|Enables metrics feature.| |true| |groupId|Generated artifact package's organization (i.e. maven groupId).| |org.openapitools| -|library|library template (sub-template)|
**ktor**
ktor framework
|ktor| +|interfaceOnly|Whether to generate only API interface stubs without the server files. This option is currently supported only when using jaxrs-spec library.| |false| +|library|library template (sub-template)|
**ktor**
ktor framework
**jaxrs-spec**
JAX-RS spec only
|ktor| |modelMutable|Create mutable models| |false| |packageName|Generated artifact package name.| |org.openapitools.server| |parcelizeModels|toggle "@Parcelize" for generated models| |null| +|returnResponse|Whether generate API interface should return javax.ws.rs.core.Response instead of a deserialized entity. Only useful if interfaceOnly is true. This option is currently supported only when using jaxrs-spec library.| |false| |serializableModel|boolean - toggle "implements Serializable" for generated models| |null| |serializationLibrary|What serialization library to use: 'moshi' (default), or 'gson' or 'jackson'| |moshi| |sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |null| |sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |null| |sourceFolder|source folder for generated code| |src/main/kotlin| +|useBeanValidation|Use BeanValidation API annotations. This option is currently supported only when using jaxrs-spec library.| |false| +|useCoroutines|Whether to use the Coroutines. This option is currently supported only when using jaxrs-spec library.| |false| ## IMPORT MAPPING 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 3caa91e404d..d1b1d1d57fb 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 @@ -23,6 +23,7 @@ import org.openapitools.codegen.CliOption; import org.openapitools.codegen.CodegenConstants; import org.openapitools.codegen.CodegenType; import org.openapitools.codegen.SupportingFile; +import org.openapitools.codegen.languages.features.BeanValidationFeatures; import org.openapitools.codegen.meta.features.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -33,9 +34,14 @@ import java.util.EnumSet; import java.util.List; import java.util.Map; -public class KotlinServerCodegen extends AbstractKotlinCodegen { +public class KotlinServerCodegen extends AbstractKotlinCodegen implements BeanValidationFeatures { + + public static final String INTERFACE_ONLY = "interfaceOnly"; + public static final String USE_COROUTINES = "useCoroutines"; + public static final String RETURN_RESPONSE = "returnResponse"; public static final String DEFAULT_LIBRARY = Constants.KTOR; private final Logger LOGGER = LoggerFactory.getLogger(KotlinServerCodegen.class); + private Boolean autoHeadFeatureEnabled = true; private Boolean conditionalHeadersFeatureEnabled = false; private Boolean hstsFeatureEnabled = true; @@ -43,6 +49,10 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen { private Boolean compressionFeatureEnabled = true; private Boolean locationsFeatureEnabled = true; private Boolean metricsFeatureEnabled = true; + private boolean interfaceOnly = false; + private boolean useBeanValidation = false; + private boolean useCoroutines = false; + private boolean returnResponse = false; // This is here to potentially warn the user when an option is not supported by the target framework. private Map> optionsSupportedPerFramework = new ImmutableMap.Builder>() @@ -102,6 +112,7 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen { modelPackage = packageName + ".models"; supportedLibraries.put(Constants.KTOR, "ktor framework"); + supportedLibraries.put(Constants.JAXRS_SPEC, "JAX-RS spec only"); // TODO: Configurable server engine. Defaults to netty in build.gradle. CliOption library = new CliOption(CodegenConstants.LIBRARY, CodegenConstants.LIBRARY_DESC); @@ -117,6 +128,11 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen { addSwitch(Constants.COMPRESSION, Constants.COMPRESSION_DESC, getCompressionFeatureEnabled()); addSwitch(Constants.LOCATIONS, Constants.LOCATIONS_DESC, getLocationsFeatureEnabled()); addSwitch(Constants.METRICS, Constants.METRICS_DESC, getMetricsFeatureEnabled()); + + cliOptions.add(CliOption.newBoolean(INTERFACE_ONLY, "Whether to generate only API interface stubs without the server files. This option is currently supported only when using jaxrs-spec library.").defaultValue(String.valueOf(interfaceOnly))); + cliOptions.add(CliOption.newBoolean(USE_BEANVALIDATION, "Use BeanValidation API annotations. This option is currently supported only when using jaxrs-spec library.", useBeanValidation)); + cliOptions.add(CliOption.newBoolean(USE_COROUTINES, "Whether to use the Coroutines. This option is currently supported only when using jaxrs-spec library.")); + cliOptions.add(CliOption.newBoolean(RETURN_RESPONSE, "Whether generate API interface should return javax.ws.rs.core.Response instead of a deserialized entity. Only useful if interfaceOnly is true. This option is currently supported only when using jaxrs-spec library.").defaultValue(String.valueOf(returnResponse))); } public Boolean getAutoHeadFeatureEnabled() { @@ -191,6 +207,37 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen { public void processOpts() { super.processOpts(); + if (additionalProperties.containsKey(CodegenConstants.LIBRARY)) { + this.setLibrary((String) additionalProperties.get(CodegenConstants.LIBRARY)); + } + + if (additionalProperties.containsKey(INTERFACE_ONLY)) { + interfaceOnly = Boolean.parseBoolean(additionalProperties.get(INTERFACE_ONLY).toString()); + if (!interfaceOnly) { + additionalProperties.remove(INTERFACE_ONLY); + } + } + + if (additionalProperties.containsKey(USE_COROUTINES)) { + useCoroutines = Boolean.parseBoolean(additionalProperties.get(USE_COROUTINES).toString()); + if (!useCoroutines) { + additionalProperties.remove(USE_COROUTINES); + } + } + + if (additionalProperties.containsKey(RETURN_RESPONSE)) { + returnResponse = Boolean.parseBoolean(additionalProperties.get(RETURN_RESPONSE).toString()); + if (!returnResponse) { + additionalProperties.remove(RETURN_RESPONSE); + } + } + + if (additionalProperties.containsKey(USE_BEANVALIDATION)) { + setUseBeanValidation(convertPropertyToBoolean(USE_BEANVALIDATION)); + } + + writePropertyBack(USE_BEANVALIDATION, useBeanValidation); + // set default library to "ktor" if (StringUtils.isEmpty(library)) { this.setLibrary(DEFAULT_LIBRARY); @@ -245,29 +292,40 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen { String resourcesFolder = "src/main/resources"; // not sure this can be user configurable. supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")); - supportingFiles.add(new SupportingFile("Dockerfile.mustache", "", "Dockerfile")); + + if (library.equals(Constants.KTOR)) { + supportingFiles.add(new SupportingFile("Dockerfile.mustache", "", "Dockerfile")); + } supportingFiles.add(new SupportingFile("build.gradle.mustache", "", "build.gradle")); supportingFiles.add(new SupportingFile("settings.gradle.mustache", "", "settings.gradle")); supportingFiles.add(new SupportingFile("gradle.properties", "", "gradle.properties")); - supportingFiles.add(new SupportingFile("AppMain.kt.mustache", packageFolder, "AppMain.kt")); - supportingFiles.add(new SupportingFile("Configuration.kt.mustache", packageFolder, "Configuration.kt")); + if (library.equals(Constants.KTOR)) { + supportingFiles.add(new SupportingFile("AppMain.kt.mustache", packageFolder, "AppMain.kt")); + supportingFiles.add(new SupportingFile("Configuration.kt.mustache", packageFolder, "Configuration.kt")); - if (generateApis && locationsFeatureEnabled) { - supportingFiles.add(new SupportingFile("Paths.kt.mustache", packageFolder, "Paths.kt")); + if (generateApis && locationsFeatureEnabled) { + supportingFiles.add(new SupportingFile("Paths.kt.mustache", packageFolder, "Paths.kt")); + } + + supportingFiles.add(new SupportingFile("application.conf.mustache", resourcesFolder, "application.conf")); + supportingFiles.add(new SupportingFile("logback.xml", resourcesFolder, "logback.xml")); + + final String infrastructureFolder = (sourceFolder + File.separator + packageName + File.separator + "infrastructure").replace(".", File.separator); + + supportingFiles.add(new SupportingFile("ApiKeyAuth.kt.mustache", infrastructureFolder, "ApiKeyAuth.kt")); } + } - supportingFiles.add(new SupportingFile("application.conf.mustache", resourcesFolder, "application.conf")); - supportingFiles.add(new SupportingFile("logback.xml", resourcesFolder, "logback.xml")); - - final String infrastructureFolder = (sourceFolder + File.separator + packageName + File.separator + "infrastructure").replace(".", File.separator); - - supportingFiles.add(new SupportingFile("ApiKeyAuth.kt.mustache", infrastructureFolder, "ApiKeyAuth.kt")); + @Override + public void setUseBeanValidation(boolean useBeanValidation) { + this.useBeanValidation = useBeanValidation; } public static class Constants { public final static String KTOR = "ktor"; + public final static String JAXRS_SPEC = "jaxrs-spec"; public final static String AUTOMATIC_HEAD_REQUESTS = "featureAutoHead"; public final static String AUTOMATIC_HEAD_REQUESTS_DESC = "Automatically provide responses to HEAD requests for existing routes that have the GET verb defined."; public final static String CONDITIONAL_HEADERS = "featureConditionalHeaders"; diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/additionalModelTypeAnnotations.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/additionalModelTypeAnnotations.mustache new file mode 100644 index 00000000000..f4871c02cc2 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/additionalModelTypeAnnotations.mustache @@ -0,0 +1,2 @@ +{{#additionalModelTypeAnnotations}}{{{.}}} +{{/additionalModelTypeAnnotations}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/api.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/api.mustache new file mode 100644 index 00000000000..2d716bd7fdf --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/api.mustache @@ -0,0 +1,31 @@ +package {{package}}; + +{{#imports}}import {{import}} +{{/imports}} + +import javax.ws.rs.* +import javax.ws.rs.core.Response + +{{#useSwaggerAnnotations}} +import io.swagger.annotations.* +{{/useSwaggerAnnotations}} + +import java.io.InputStream +import java.util.Map +import java.util.List +{{#useBeanValidation}}import javax.validation.constraints.* +import javax.validation.Valid{{/useBeanValidation}} + +{{#useSwaggerAnnotations}} +@Api(description = "the {{{baseName}}} API"){{/useSwaggerAnnotations}}{{#hasConsumes}} +@Consumes({ {{#consumes}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}} }){{/hasConsumes}}{{#hasProduces}} +@Produces({ {{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}} }){{/hasProduces}} +@Path("/") +{{>generatedAnnotation}}{{#interfaceOnly}}interface{{/interfaceOnly}}{{^interfaceOnly}}class{{/interfaceOnly}} {{classname}} { +{{#operations}} +{{#operation}} + +{{#interfaceOnly}}{{>apiInterface}}{{/interfaceOnly}}{{^interfaceOnly}}{{>apiMethod}}{{/interfaceOnly}} +{{/operation}} +} +{{/operations}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/apiInterface.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/apiInterface.mustache new file mode 100644 index 00000000000..d64ab757938 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/apiInterface.mustache @@ -0,0 +1,13 @@ + @{{httpMethod}} + @Path("{{{path}}}"){{#hasConsumes}} + @Consumes({{#consumes}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}}){{/hasConsumes}}{{#hasProduces}} + @Produces({{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}}){{/hasProduces}}{{#useSwaggerAnnotations}} + @ApiOperation(value = "{{{summary}}}", notes = "{{{notes}}}"{{#hasAuthMethods}}, authorizations = { + {{#authMethods}}{{#isOAuth}}@Authorization(value = "{{name}}", scopes = { + {{#scopes}}@AuthorizationScope(scope = "{{scope}}", description = "{{description}}"){{^-last}}, + {{/-last}}{{/scopes}} }){{^-last}},{{/-last}}{{/isOAuth}} + {{^isOAuth}}@Authorization(value = "{{name}}"){{^-last}},{{/-last}} + {{/isOAuth}}{{/authMethods}} }{{/hasAuthMethods}}, tags={ {{#vendorExtensions.x-tags}}"{{tag}}"{{^-last}}, {{/-last}}{{/vendorExtensions.x-tags}} }) + @ApiResponses(value = { {{#responses}} + @ApiResponse(code = {{{code}}}, message = "{{{message}}}", response = {{{baseType}}}.class{{#returnContainer}}, responseContainer = "{{{.}}}"{{/returnContainer}}){{^-last}},{{/-last}}{{/responses}} }){{/useSwaggerAnnotations}} + {{#useCoroutines}}suspend {{/useCoroutines}}fun {{nickname}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{^-last}},{{/-last}}{{/allParams}}){{#returnResponse}}: Response{{/returnResponse}}{{^returnResponse}}{{#returnType}}: {{{returnType}}}{{/returnType}}{{/returnResponse}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/apiMethod.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/apiMethod.mustache new file mode 100644 index 00000000000..bfe70607f17 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/apiMethod.mustache @@ -0,0 +1,16 @@ + @{{httpMethod}}{{#subresourceOperation}} + @Path("{{{path}}}"){{/subresourceOperation}}{{#hasConsumes}} + @Consumes({{#consumes}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}}){{/hasConsumes}}{{#hasProduces}} + @Produces({{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}}){{/hasProduces}}{{#useSwaggerAnnotations}} + @ApiOperation(value = "{{{summary}}}", notes = "{{{notes}}}", response = {{{returnBaseType}}}.class{{#returnContainer}}, responseContainer = "{{{.}}}"{{/returnContainer}}{{#hasAuthMethods}}, authorizations = { + {{#authMethods}}{{#isOAuth}}@Authorization(value = "{{name}}", scopes = { + {{#scopes}}@AuthorizationScope(scope = "{{scope}}", description = "{{description}}"){{^-last}}, + {{/-last}}{{/scopes}} }){{^-last}},{{/-last}}{{/isOAuth}} + {{^isOAuth}}@Authorization(value = "{{name}}"){{^-last}},{{/-last}} + {{/isOAuth}}{{/authMethods}} }{{/hasAuthMethods}}, tags={ {{#vendorExtensions.x-tags}}"{{tag}}"{{^-last}}, {{/-last}}{{/vendorExtensions.x-tags}} }) + @ApiResponses(value = { {{#responses}} + @ApiResponse(code = {{{code}}}, message = "{{{message}}}", response = {{{baseType}}}.class{{#containerType}}, responseContainer = "{{{.}}}"{{/containerType}}){{^-last}},{{/-last}}{{/responses}} + }){{/useSwaggerAnnotations}} + {{#useCoroutines}}suspend {{/useCoroutines}}fun {{nickname}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>cookieParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{^-last}},{{/-last}}{{/allParams}}): Response { + return Response.ok().entity("magic!").build(); + } \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/beanValidation.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/beanValidation.mustache new file mode 100644 index 00000000000..ef7ab3fb7a9 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/beanValidation.mustache @@ -0,0 +1,5 @@ + @Valid +{{#required}} + @NotNull +{{/required}} +{{>beanValidationCore}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/beanValidationCore.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/beanValidationCore.mustache new file mode 100644 index 00000000000..d6e2f13b457 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/beanValidationCore.mustache @@ -0,0 +1,20 @@ +{{#pattern}} @Pattern(regexp="{{{.}}}"){{/pattern}}{{! +minLength && maxLength set +}}{{#minLength}}{{#maxLength}} @Size(min={{minLength}},max={{maxLength}}){{/maxLength}}{{/minLength}}{{! +minLength set, maxLength not +}}{{#minLength}}{{^maxLength}} @Size(min={{minLength}}){{/maxLength}}{{/minLength}}{{! +minLength not set, maxLength set +}}{{^minLength}}{{#maxLength}} @Size(max={{.}}){{/maxLength}}{{/minLength}}{{! +@Size: minItems && maxItems set +}}{{#minItems}}{{#maxItems}} @Size(min={{minItems}},max={{maxItems}}){{/maxItems}}{{/minItems}}{{! +@Size: minItems set, maxItems not +}}{{#minItems}}{{^maxItems}} @Size(min={{minItems}}){{/maxItems}}{{/minItems}}{{! +@Size: minItems not set && maxItems set +}}{{^minItems}}{{#maxItems}} @Size(max={{.}}){{/maxItems}}{{/minItems}}{{! +check for integer or long / all others=decimal type with @Decimal* +isInteger set +}}{{#isInteger}}{{#minimum}} @Min({{.}}){{/minimum}}{{#maximum}} @Max({{.}}){{/maximum}}{{/isInteger}}{{! +isLong set +}}{{#isLong}}{{#minimum}} @Min({{.}}L){{/minimum}}{{#maximum}} @Max({{.}}L){{/maximum}}{{/isLong}}{{! +Not Integer, not Long => we have a decimal value! +}}{{^isInteger}}{{^isLong}}{{#minimum}} @DecimalMin({{#exclusiveMinimum}}value={{/exclusiveMinimum}}"{{minimum}}"{{#exclusiveMinimum}},inclusive=false{{/exclusiveMinimum}}){{/minimum}}{{#maximum}} @DecimalMax({{#exclusiveMaximum}}value={{/exclusiveMaximum}}"{{maximum}}"{{#exclusiveMaximum}},inclusive=false{{/exclusiveMaximum}}){{/maximum}}{{/isLong}}{{/isInteger}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/beanValidationHeaderParams.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/beanValidationHeaderParams.mustache new file mode 100644 index 00000000000..c4ff01d7e55 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/beanValidationHeaderParams.mustache @@ -0,0 +1 @@ +{{#required}} @NotNull{{/required}}{{>beanValidationCore}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/beanValidationPathParams.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/beanValidationPathParams.mustache new file mode 100644 index 00000000000..051bd53c0a5 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/beanValidationPathParams.mustache @@ -0,0 +1 @@ +{{! PathParam is always required, no @NotNull necessary }}{{>beanValidationCore}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/beanValidationQueryParams.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/beanValidationQueryParams.mustache new file mode 100644 index 00000000000..c4ff01d7e55 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/beanValidationQueryParams.mustache @@ -0,0 +1 @@ +{{#required}} @NotNull{{/required}}{{>beanValidationCore}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/bodyParams.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/bodyParams.mustache new file mode 100644 index 00000000000..ba9197f35a4 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/bodyParams.mustache @@ -0,0 +1 @@ +{{#isBodyParam}}{{#useBeanValidation}}@Valid {{#required}}{{^isNullable}}@NotNull {{/isNullable}}{{/required}}{{/useBeanValidation}} {{paramName}}: {{{dataType}}}{{^required}}?{{/required}}{{/isBodyParam}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/build.gradle.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/build.gradle.mustache new file mode 100644 index 00000000000..639084ec35b --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/build.gradle.mustache @@ -0,0 +1,57 @@ +group "{{groupId}}" +version "{{artifactVersion}}" + +wrapper { + gradleVersion = "6.9" + distributionUrl = "https://services.gradle.org/distributions/gradle-$gradleVersion-all.zip" +} + +buildscript { + ext.kotlin_version = "1.4.32" + ext.jakarta_ws_rs_version = "2.1.6" + ext.swagger_annotations_version = "1.5.3" + ext.jakarta_annotations_version = "1.3.5" + ext.jackson_version = "2.9.9" +{{#useBeanValidation}} + ext.beanvalidation_version = "2.0.2" +{{/useBeanValidation}} + 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") +{{#useBeanValidation}} + implementation("jakarta.validation:jakarta.validation-api:$beanvalidation_version") +{{/useBeanValidation}} + testImplementation("junit:junit:4.13.2") +} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/cookieParams.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/cookieParams.mustache new file mode 100644 index 00000000000..eda2d526ebd --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/cookieParams.mustache @@ -0,0 +1 @@ +{{#isCookieParam}}@CookieParam("{{baseName}}"){{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}}{{^isContainer}}{{#defaultValue}} @DefaultValue("{{{.}}}"){{/defaultValue}}{{/isContainer}} {{#useSwaggerAnnotations}}{{#description}} @ApiParam("{{.}}"){{/description}}{{/useSwaggerAnnotations}} {{paramName}}: {{{dataType}}}{{^required}}?{{/required}}{{/isCookieParam}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/data_class.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/data_class.mustache new file mode 100644 index 00000000000..c0fdd457ba7 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/data_class.mustache @@ -0,0 +1,73 @@ +import com.fasterxml.jackson.annotation.JsonProperty +{{#kotlinx_serialization}} +import {{#serializableModel}}kotlinx.serialization.Serializable as KSerializable{{/serializableModel}}{{^serializableModel}}kotlinx.serialization.Serializable{{/serializableModel}} +import kotlinx.serialization.SerialName +import kotlinx.serialization.Contextual +{{#hasEnums}} +{{/hasEnums}} +{{/kotlinx_serialization}} +{{#parcelizeModels}} +import android.os.Parcelable +import kotlinx.parcelize.Parcelize +{{/parcelizeModels}} +{{#serializableModel}} +import java.io.Serializable +{{/serializableModel}} +/** + * {{{description}}} + * +{{#allVars}} + * @param {{{name}}} {{{description}}} +{{/allVars}} + */ +{{#parcelizeModels}} +@Parcelize +{{/parcelizeModels}} +{{#multiplatform}}{{^discriminator}}@Serializable{{/discriminator}}{{/multiplatform}}{{#kotlinx_serialization}}{{#serializableModel}}@KSerializable{{/serializableModel}}{{^serializableModel}}@Serializable{{/serializableModel}}{{/kotlinx_serialization}}{{#moshi}}{{#moshiCodeGen}}@JsonClass(generateAdapter = true){{/moshiCodeGen}}{{/moshi}}{{#jackson}}{{#discriminator}}{{>typeInfoAnnotation}}{{/discriminator}}{{/jackson}} +{{#isDeprecated}} +@Deprecated(message = "This schema is deprecated.") +{{/isDeprecated}} +{{>additionalModelTypeAnnotations}} +{{#nonPublicApi}}internal {{/nonPublicApi}}{{#discriminator}}interface{{/discriminator}}{{^discriminator}}data class{{/discriminator}} {{classname}}{{^discriminator}} ( + +{{#allVars}} +{{#required}}{{>data_class_req_var}}{{/required}}{{^required}}{{>data_class_opt_var}}{{/required}}{{^-last}},{{/-last}} + +{{/allVars}} +){{/discriminator}}{{#parent}}{{^serializableModel}}{{^parcelizeModels}} : {{{parent}}}{{#isMap}}(){{/isMap}}{{#isArray}}(){{/isArray}}{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{#parent}}{{#serializableModel}}{{^parcelizeModels}} : {{{parent}}}{{#isMap}}(){{/isMap}}{{#isArray}}(){{/isArray}}, Serializable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{#parent}}{{^serializableModel}}{{#parcelizeModels}} : {{{parent}}}{{#isMap}}(){{/isMap}}{{#isArray}}(){{/isArray}}, Parcelable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{#parent}}{{#serializableModel}}{{#parcelizeModels}} : {{{parent}}}{{#isMap}}(){{/isMap}}{{#isArray}}(){{/isArray}}, Serializable, Parcelable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{^parent}}{{#serializableModel}}{{^parcelizeModels}} : Serializable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{^parent}}{{^serializableModel}}{{#parcelizeModels}} : Parcelable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{^parent}}{{#serializableModel}}{{#parcelizeModels}} : Serializable, Parcelable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{#vendorExtensions.x-has-data-class-body}} { +{{/vendorExtensions.x-has-data-class-body}} +{{#serializableModel}} + {{#nonPublicApi}}internal {{/nonPublicApi}}companion object { + private const val serialVersionUID: Long = 123 + } +{{/serializableModel}} +{{#discriminator}}{{#vars}}{{#required}} +{{>interface_req_var}}{{/required}}{{^required}} +{{>interface_opt_var}}{{/required}}{{/vars}}{{/discriminator}} +{{#hasEnums}} +{{#vars}} +{{#isEnum}} + /** + * {{{description}}} + * + * Values: {{#allowableValues}}{{#enumVars}}{{&name}}{{^-last}},{{/-last}}{{/enumVars}}{{/allowableValues}} + */ + {{#kotlinx_serialization}} + {{#serializableModel}}@KSerializable{{/serializableModel}}{{^serializableModel}}@Serializable{{/serializableModel}} + {{/kotlinx_serialization}} + {{#nonPublicApi}}internal {{/nonPublicApi}}enum class {{{nameInCamelCase}}}(val value: {{^isContainer}}{{dataType}}{{/isContainer}}{{#isContainer}}kotlin.String{{/isContainer}}) { + {{#allowableValues}} + {{#enumVars}} + @JsonProperty(value = {{^isString}}"{{/isString}}{{{value}}}{{^isString}}"{{/isString}}) {{&name}}({{{value}}}){{^-last}},{{/-last}}{{#-last}};{{/-last}} + {{#kotlinx_serialization}} + @SerialName(value = {{^isString}}"{{/isString}}{{{value}}}{{^isString}}"{{/isString}}) {{&name}}({{{value}}}){{^-last}},{{/-last}}{{#-last}};{{/-last}} + {{/kotlinx_serialization}} + {{/enumVars}} + {{/allowableValues}} + } +{{/isEnum}} +{{/vars}} +{{/hasEnums}} +{{#vendorExtensions.x-has-data-class-body}} +} +{{/vendorExtensions.x-has-data-class-body}} diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/data_class_opt_var.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/data_class_opt_var.mustache new file mode 100644 index 00000000000..d99ccd902fa --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/data_class_opt_var.mustache @@ -0,0 +1,6 @@ +{{#description}} + /* {{{.}}} */ +{{/description}} + + @JsonProperty("{{{baseName}}}") +{{#useBeanValidation}}{{>beanValidation}}{{/useBeanValidation}} {{>modelMutable}} {{{name}}}: {{#isEnum}}{{classname}}.{{nameInCamelCase}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}? = {{{defaultValue}}}{{^defaultValue}}null{{/defaultValue}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/data_class_req_var.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/data_class_req_var.mustache new file mode 100644 index 00000000000..5c69ae13e51 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/data_class_req_var.mustache @@ -0,0 +1,6 @@ +{{#description}} + /* {{{.}}} */ +{{/description}} + + @JsonProperty("{{{baseName}}}") +{{#useBeanValidation}}{{>beanValidation}}{{/useBeanValidation}} {{>modelMutable}} {{{name}}}: {{#isEnum}}{{classname}}.{{nameInCamelCase}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/enum_class.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/enum_class.mustache new file mode 100644 index 00000000000..005b9daa596 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/enum_class.mustache @@ -0,0 +1,58 @@ +import com.fasterxml.jackson.annotation.JsonProperty +{{#kotlinx_serialization}} +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +{{/kotlinx_serialization}} + +/** + * {{{description}}} + * + * Values: {{#allowableValues}}{{#enumVars}}{{&name}}{{^-last}},{{/-last}}{{/enumVars}}{{/allowableValues}} + */ +{{#kotlinx_serialization}}@Serializable{{/kotlinx_serialization}} +{{>additionalModelTypeAnnotations}} +{{#nonPublicApi}}internal {{/nonPublicApi}}enum class {{classname}}(val value: {{{dataType}}}) { +{{#allowableValues}}{{#enumVars}} + @JsonProperty(value = {{^isString}}"{{/isString}}{{{value}}}{{^isString}}"{{/isString}}) + {{#kotlinx_serialization}} + @SerialName(value = {{^isString}}"{{/isString}}{{{value}}}{{^isString}}"{{/isString}}) + {{/kotlinx_serialization}} + {{#isArray}} + {{#isList}} + {{&name}}(listOf({{{value}}})){{^-last}},{{/-last}}{{#-last}};{{/-last}} + {{/isList}} + {{^isList}} + {{&name}}(arrayOf({{{value}}})){{^-last}},{{/-last}}{{#-last}};{{/-last}} + {{/isList}} + {{/isArray}} + {{^isArray}} + {{&name}}({{{value}}}){{^-last}},{{/-last}}{{#-last}};{{/-last}} + {{/isArray}} +{{/enumVars}}{{/allowableValues}} + /** + * Override toString() to avoid using the enum variable name as the value, and instead use + * the actual value defined in the API spec file. + * + * This solves a problem when the variable name and its value are different, and ensures that + * the client sends the correct enum values to the server always. + */ + override fun toString(): String = value{{^isString}}.toString(){{/isString}} + + companion object { + /** + * Converts the provided [data] to a [String] on success, null otherwise. + */ + fun encode(data: Any?): kotlin.String? = if (data is {{classname}}) "$data" else null + + /** + * Returns a valid [{{classname}}] for [data], null otherwise. + */ + @OptIn(ExperimentalStdlibApi::class) + fun decode(data: Any?): {{classname}}? = data?.let { + val normalizedData = "$it".lowercase() + values().firstOrNull { value -> + it == value || normalizedData == "$value".lowercase() + } + } + } +} diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/enum_doc.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/enum_doc.mustache new file mode 100644 index 00000000000..fcb3d7e61aa --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/enum_doc.mustache @@ -0,0 +1,7 @@ +# {{classname}} + +## Enum + +{{#allowableValues}}{{#enumVars}} + * `{{name}}` (value: `{{{value}}}`) +{{/enumVars}}{{/allowableValues}} diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/formParams.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/formParams.mustache new file mode 100644 index 00000000000..5427f037ae0 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/formParams.mustache @@ -0,0 +1 @@ +{{#isFormParam}}{{^isFile}}@FormParam(value = "{{baseName}}") {{paramName}}: {{{dataType}}}{{^required}}?{{/required}}{{/isFile}}{{#isFile}} @FormParam(value = "{{baseName}}") {{paramName}}InputStream: InputStream{{^required}}?{{/required}}{{/isFile}}{{/isFormParam}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/generatedAnnotation.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/generatedAnnotation.mustache new file mode 100644 index 00000000000..624b44019ad --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/generatedAnnotation.mustache @@ -0,0 +1 @@ +@javax.annotation.Generated(value = arrayOf("{{generatorClass}}"){{^hideGenerationTimestamp}}, date = "{{generatedDate}}"{{/hideGenerationTimestamp}}) \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/gradle.properties b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/gradle.properties new file mode 100644 index 00000000000..5f1ed7bbe02 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/gradle.properties @@ -0,0 +1 @@ +org.gradle.caching=true \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/headerParams.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/headerParams.mustache new file mode 100644 index 00000000000..980d55c7e51 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/headerParams.mustache @@ -0,0 +1 @@ +{{#isHeaderParam}}@HeaderParam("{{baseName}}"){{#useBeanValidation}}{{>beanValidationHeaderParams}}{{/useBeanValidation}} {{#defaultValue}} @DefaultValue("{{{.}}}"){{/defaultValue}} {{#useSwaggerAnnotations}}{{#description}} @ApiParam("{{.}}"){{/description}}{{/useSwaggerAnnotations}} {{paramName}}: {{{dataType}}}{{^required}}?{{/required}}{{/isHeaderParam}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/model.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/model.mustache new file mode 100644 index 00000000000..03eecdc64ac --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/model.mustache @@ -0,0 +1,14 @@ +{{>licenseInfo}} +package {{modelPackage}} + +{{#imports}}import {{import}} +{{/imports}} +{{#useBeanValidation}} +import javax.validation.constraints.* +import javax.validation.Valid +{{/useBeanValidation}} +{{#models}} +{{#model}} +{{#isEnum}}{{>enum_class}}{{/isEnum}}{{^isEnum}}{{#oneOf}}{{>oneof_model}}{{/oneOf}}{{^oneOf}}{{#isAlias}}typealias {{classname}} = {{{dataType}}}{{/isAlias}}{{^isAlias}}{{>data_class}}{{/isAlias}}{{/oneOf}}{{/isEnum}} +{{/model}} +{{/models}} diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/model_doc.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/model_doc.mustache new file mode 100644 index 00000000000..e3b71842118 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/model_doc.mustache @@ -0,0 +1,3 @@ +{{#models}}{{#model}} +{{#isEnum}}{{>enum_doc}}{{/isEnum}}{{^isEnum}}{{>class_doc}}{{/isEnum}} +{{/model}}{{/models}} diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/oneof_model.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/oneof_model.mustache new file mode 100644 index 00000000000..83c841f5600 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/oneof_model.mustache @@ -0,0 +1,3 @@ +{{#-first}} +typealias {{classname}} = Any +{{/-first}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/pathParams.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/pathParams.mustache new file mode 100644 index 00000000000..7839f91302b --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/pathParams.mustache @@ -0,0 +1 @@ +{{#isPathParam}}@PathParam("{{baseName}}"){{#useBeanValidation}}{{>beanValidationPathParams}}{{/useBeanValidation}}{{#useSwaggerAnnotations}}{{#description}} @ApiParam("{{.}}"){{/description}}{{/useSwaggerAnnotations}} {{paramName}}: {{{dataType}}}{{/isPathParam}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/queryParams.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/queryParams.mustache new file mode 100644 index 00000000000..91a0dfdb664 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/queryParams.mustache @@ -0,0 +1 @@ +{{#isQueryParam}}@QueryParam("{{baseName}}"){{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}}{{^isContainer}}{{#defaultValue}} @DefaultValue("{{{.}}}"){{/defaultValue}}{{/isContainer}} {{#useSwaggerAnnotations}}{{#description}} @ApiParam("{{.}}"){{/description}}{{/useSwaggerAnnotations}} {{paramName}}: {{{dataType}}}{{^required}}?{{/required}}{{/isQueryParam}} \ No newline at end of file diff --git a/samples/server/petstore/kotlin-server/jaxrs-spec/.openapi-generator-ignore b/samples/server/petstore/kotlin-server/jaxrs-spec/.openapi-generator-ignore new file mode 100644 index 00000000000..7484ee590a3 --- /dev/null +++ b/samples/server/petstore/kotlin-server/jaxrs-spec/.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/petstore/kotlin-server/jaxrs-spec/.openapi-generator/FILES b/samples/server/petstore/kotlin-server/jaxrs-spec/.openapi-generator/FILES new file mode 100644 index 00000000000..8311b1e0d0a --- /dev/null +++ b/samples/server/petstore/kotlin-server/jaxrs-spec/.openapi-generator/FILES @@ -0,0 +1,13 @@ +README.md +build.gradle +gradle.properties +settings.gradle +src/main/kotlin/org/openapitools/server/apis/PetApi.kt +src/main/kotlin/org/openapitools/server/apis/StoreApi.kt +src/main/kotlin/org/openapitools/server/apis/UserApi.kt +src/main/kotlin/org/openapitools/server/models/Category.kt +src/main/kotlin/org/openapitools/server/models/ModelApiResponse.kt +src/main/kotlin/org/openapitools/server/models/Order.kt +src/main/kotlin/org/openapitools/server/models/Pet.kt +src/main/kotlin/org/openapitools/server/models/Tag.kt +src/main/kotlin/org/openapitools/server/models/User.kt diff --git a/samples/server/petstore/kotlin-server/jaxrs-spec/.openapi-generator/VERSION b/samples/server/petstore/kotlin-server/jaxrs-spec/.openapi-generator/VERSION new file mode 100644 index 00000000000..0984c4c1ad2 --- /dev/null +++ b/samples/server/petstore/kotlin-server/jaxrs-spec/.openapi-generator/VERSION @@ -0,0 +1 @@ +5.4.0-SNAPSHOT \ No newline at end of file diff --git a/samples/server/petstore/kotlin-server/jaxrs-spec/README.md b/samples/server/petstore/kotlin-server/jaxrs-spec/README.md new file mode 100644 index 00000000000..d5e7ab18e68 --- /dev/null +++ b/samples/server/petstore/kotlin-server/jaxrs-spec/README.md @@ -0,0 +1,89 @@ +# org.openapitools.server - Kotlin Server library for OpenAPI Petstore + +## 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 *http://petstore.swagger.io/v2* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +*PetApi* | [**addPet**](docs/PetApi.md#addpet) | **POST** /pet | Add a new pet to the store +*PetApi* | [**deletePet**](docs/PetApi.md#deletepet) | **DELETE** /pet/{petId} | Deletes a pet +*PetApi* | [**findPetsByStatus**](docs/PetApi.md#findpetsbystatus) | **GET** /pet/findByStatus | Finds Pets by status +*PetApi* | [**findPetsByTags**](docs/PetApi.md#findpetsbytags) | **GET** /pet/findByTags | Finds Pets by tags +*PetApi* | [**getPetById**](docs/PetApi.md#getpetbyid) | **GET** /pet/{petId} | Find pet by ID +*PetApi* | [**updatePet**](docs/PetApi.md#updatepet) | **PUT** /pet | Update an existing pet +*PetApi* | [**updatePetWithForm**](docs/PetApi.md#updatepetwithform) | **POST** /pet/{petId} | Updates a pet in the store with form data +*PetApi* | [**uploadFile**](docs/PetApi.md#uploadfile) | **POST** /pet/{petId}/uploadImage | uploads an image +*StoreApi* | [**deleteOrder**](docs/StoreApi.md#deleteorder) | **DELETE** /store/order/{orderId} | Delete purchase order by ID +*StoreApi* | [**getInventory**](docs/StoreApi.md#getinventory) | **GET** /store/inventory | Returns pet inventories by status +*StoreApi* | [**getOrderById**](docs/StoreApi.md#getorderbyid) | **GET** /store/order/{orderId} | Find purchase order by ID +*StoreApi* | [**placeOrder**](docs/StoreApi.md#placeorder) | **POST** /store/order | Place an order for a pet +*UserApi* | [**createUser**](docs/UserApi.md#createuser) | **POST** /user | Create user +*UserApi* | [**createUsersWithArrayInput**](docs/UserApi.md#createuserswitharrayinput) | **POST** /user/createWithArray | Creates list of users with given input array +*UserApi* | [**createUsersWithListInput**](docs/UserApi.md#createuserswithlistinput) | **POST** /user/createWithList | Creates list of users with given input array +*UserApi* | [**deleteUser**](docs/UserApi.md#deleteuser) | **DELETE** /user/{username} | Delete user +*UserApi* | [**getUserByName**](docs/UserApi.md#getuserbyname) | **GET** /user/{username} | Get user by user name +*UserApi* | [**loginUser**](docs/UserApi.md#loginuser) | **GET** /user/login | Logs user into the system +*UserApi* | [**logoutUser**](docs/UserApi.md#logoutuser) | **GET** /user/logout | Logs out current logged in user session +*UserApi* | [**updateUser**](docs/UserApi.md#updateuser) | **PUT** /user/{username} | Updated user + + + +## Documentation for Models + + - [org.openapitools.server.models.Category](docs/Category.md) + - [org.openapitools.server.models.ModelApiResponse](docs/ModelApiResponse.md) + - [org.openapitools.server.models.Order](docs/Order.md) + - [org.openapitools.server.models.Pet](docs/Pet.md) + - [org.openapitools.server.models.Tag](docs/Tag.md) + - [org.openapitools.server.models.User](docs/User.md) + + + +## Documentation for Authorization + + +### api_key + +- **Type**: API key +- **API key parameter name**: api_key +- **Location**: HTTP header + + +### petstore_auth + +- **Type**: OAuth +- **Flow**: implicit +- **Authorization URL**: http://petstore.swagger.io/api/oauth/dialog +- **Scopes**: + - write:pets: modify pets in your account + - read:pets: read your pets + diff --git a/samples/server/petstore/kotlin-server/jaxrs-spec/build.gradle b/samples/server/petstore/kotlin-server/jaxrs-spec/build.gradle new file mode 100644 index 00000000000..b85cf730367 --- /dev/null +++ b/samples/server/petstore/kotlin-server/jaxrs-spec/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.4.32" + ext.jakarta_ws_rs_version = "2.1.6" + ext.swagger_annotations_version = "1.5.3" + ext.jakarta_annotations_version = "1.3.5" + 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") +} \ No newline at end of file diff --git a/samples/server/petstore/kotlin-server/jaxrs-spec/gradle.properties b/samples/server/petstore/kotlin-server/jaxrs-spec/gradle.properties new file mode 100644 index 00000000000..5f1ed7bbe02 --- /dev/null +++ b/samples/server/petstore/kotlin-server/jaxrs-spec/gradle.properties @@ -0,0 +1 @@ +org.gradle.caching=true \ No newline at end of file diff --git a/samples/server/petstore/kotlin-server/jaxrs-spec/settings.gradle b/samples/server/petstore/kotlin-server/jaxrs-spec/settings.gradle new file mode 100644 index 00000000000..a09a58efab1 --- /dev/null +++ b/samples/server/petstore/kotlin-server/jaxrs-spec/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'kotlin-server' \ No newline at end of file diff --git a/samples/server/petstore/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/apis/PetApi.kt b/samples/server/petstore/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/apis/PetApi.kt new file mode 100644 index 00000000000..eb94d6065e6 --- /dev/null +++ b/samples/server/petstore/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/apis/PetApi.kt @@ -0,0 +1,66 @@ +package org.openapitools.server.apis; + +import org.openapitools.server.models.ModelApiResponse +import org.openapitools.server.models.Pet + +import javax.ws.rs.* +import javax.ws.rs.core.Response + + +import java.io.InputStream +import java.util.Map +import java.util.List + + + +@Path("/") +@javax.annotation.Generated(value = arrayOf("org.openapitools.codegen.languages.KotlinServerCodegen"))class PetApi { + + @POST + @Consumes("application/json", "application/xml") + suspend fun addPet( body: Pet): Response { + return Response.ok().entity("magic!").build(); + } + + @DELETE + suspend fun deletePet(@PathParam("petId") petId: kotlin.Long,@HeaderParam("api_key") apiKey: kotlin.String?): Response { + return Response.ok().entity("magic!").build(); + } + + @GET + @Produces("application/xml", "application/json") + suspend fun findPetsByStatus(@QueryParam("status") status: kotlin.collections.List): Response { + return Response.ok().entity("magic!").build(); + } + + @GET + @Produces("application/xml", "application/json") + suspend fun findPetsByTags(@QueryParam("tags") tags: kotlin.collections.List): Response { + return Response.ok().entity("magic!").build(); + } + + @GET + @Produces("application/xml", "application/json") + suspend fun getPetById(@PathParam("petId") petId: kotlin.Long): Response { + return Response.ok().entity("magic!").build(); + } + + @PUT + @Consumes("application/json", "application/xml") + suspend fun updatePet( body: Pet): Response { + return Response.ok().entity("magic!").build(); + } + + @POST + @Consumes("application/x-www-form-urlencoded") + suspend fun updatePetWithForm(@PathParam("petId") petId: kotlin.Long,@FormParam(value = "name") name: kotlin.String?,@FormParam(value = "status") status: kotlin.String?): Response { + return Response.ok().entity("magic!").build(); + } + + @POST + @Consumes("multipart/form-data") + @Produces("application/json") + suspend fun uploadFile(@PathParam("petId") petId: kotlin.Long,@FormParam(value = "additionalMetadata") additionalMetadata: kotlin.String?, @FormParam(value = "file") fileInputStream: InputStream?): Response { + return Response.ok().entity("magic!").build(); + } +} diff --git a/samples/server/petstore/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt b/samples/server/petstore/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt new file mode 100644 index 00000000000..f297a11661d --- /dev/null +++ b/samples/server/petstore/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt @@ -0,0 +1,40 @@ +package org.openapitools.server.apis; + +import org.openapitools.server.models.Order + +import javax.ws.rs.* +import javax.ws.rs.core.Response + + +import java.io.InputStream +import java.util.Map +import java.util.List + + + +@Path("/") +@javax.annotation.Generated(value = arrayOf("org.openapitools.codegen.languages.KotlinServerCodegen"))class StoreApi { + + @DELETE + suspend fun deleteOrder(@PathParam("orderId") orderId: kotlin.String): Response { + return Response.ok().entity("magic!").build(); + } + + @GET + @Produces("application/json") + suspend fun getInventory(): Response { + return Response.ok().entity("magic!").build(); + } + + @GET + @Produces("application/xml", "application/json") + suspend fun getOrderById(@PathParam("orderId") orderId: kotlin.Long): Response { + return Response.ok().entity("magic!").build(); + } + + @POST + @Produces("application/xml", "application/json") + suspend fun placeOrder( body: Order): Response { + return Response.ok().entity("magic!").build(); + } +} diff --git a/samples/server/petstore/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/apis/UserApi.kt b/samples/server/petstore/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/apis/UserApi.kt new file mode 100644 index 00000000000..f824ebc217a --- /dev/null +++ b/samples/server/petstore/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/apis/UserApi.kt @@ -0,0 +1,59 @@ +package org.openapitools.server.apis; + +import org.openapitools.server.models.User + +import javax.ws.rs.* +import javax.ws.rs.core.Response + + +import java.io.InputStream +import java.util.Map +import java.util.List + + + +@Path("/") +@javax.annotation.Generated(value = arrayOf("org.openapitools.codegen.languages.KotlinServerCodegen"))class UserApi { + + @POST + suspend fun createUser( body: User): Response { + return Response.ok().entity("magic!").build(); + } + + @POST + suspend fun createUsersWithArrayInput( body: kotlin.collections.List): Response { + return Response.ok().entity("magic!").build(); + } + + @POST + suspend fun createUsersWithListInput( body: kotlin.collections.List): Response { + return Response.ok().entity("magic!").build(); + } + + @DELETE + suspend fun deleteUser(@PathParam("username") username: kotlin.String): Response { + return Response.ok().entity("magic!").build(); + } + + @GET + @Produces("application/xml", "application/json") + suspend fun getUserByName(@PathParam("username") username: kotlin.String): Response { + return Response.ok().entity("magic!").build(); + } + + @GET + @Produces("application/xml", "application/json") + suspend fun loginUser(@QueryParam("username") username: kotlin.String,@QueryParam("password") password: kotlin.String): Response { + return Response.ok().entity("magic!").build(); + } + + @GET + suspend fun logoutUser(): Response { + return Response.ok().entity("magic!").build(); + } + + @PUT + suspend fun updateUser(@PathParam("username") username: kotlin.String, body: User): Response { + return Response.ok().entity("magic!").build(); + } +} diff --git a/samples/server/petstore/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/models/ApiResponse.kt b/samples/server/petstore/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/models/ApiResponse.kt new file mode 100644 index 00000000000..974c9589a7f --- /dev/null +++ b/samples/server/petstore/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/models/ApiResponse.kt @@ -0,0 +1,33 @@ +/** + * OpenAPI Petstore + * This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. + * + * The version of the OpenAPI document: 1.0.0 + * + * + * 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 +/** + * Describes the result of uploading an image resource + * + * @param code + * @param type + * @param message + */ + + +data class ApiResponse ( + + val code: kotlin.Int? = null, + + val type: kotlin.String? = null, + + val message: kotlin.String? = null + +) + diff --git a/samples/server/petstore/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/models/Category.kt b/samples/server/petstore/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/models/Category.kt new file mode 100644 index 00000000000..9a39acd8aea --- /dev/null +++ b/samples/server/petstore/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/models/Category.kt @@ -0,0 +1,34 @@ +/** + * OpenAPI Petstore + * This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. + * + * The version of the OpenAPI document: 1.0.0 + * + * + * 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 +/** + * A category for a pet + * + * @param id + * @param name + */ + + +data class Category ( + + + @JsonProperty("id") + val id: kotlin.Long? = null, + + + @JsonProperty("name") + val name: kotlin.String? = null + +) + diff --git a/samples/server/petstore/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/models/ModelApiResponse.kt b/samples/server/petstore/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/models/ModelApiResponse.kt new file mode 100644 index 00000000000..531f364e2f7 --- /dev/null +++ b/samples/server/petstore/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/models/ModelApiResponse.kt @@ -0,0 +1,39 @@ +/** + * OpenAPI Petstore + * This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. + * + * The version of the OpenAPI document: 1.0.0 + * + * + * 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 +/** + * Describes the result of uploading an image resource + * + * @param code + * @param type + * @param message + */ + + +data class ModelApiResponse ( + + + @JsonProperty("code") + val code: kotlin.Int? = null, + + + @JsonProperty("type") + val type: kotlin.String? = null, + + + @JsonProperty("message") + val message: kotlin.String? = null + +) + diff --git a/samples/server/petstore/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/models/Order.kt b/samples/server/petstore/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/models/Order.kt new file mode 100644 index 00000000000..d4a39a2c2bb --- /dev/null +++ b/samples/server/petstore/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/models/Order.kt @@ -0,0 +1,67 @@ +/** + * OpenAPI Petstore + * This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. + * + * The version of the OpenAPI document: 1.0.0 + * + * + * 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 +/** + * An order for a pets from the pet store + * + * @param id + * @param petId + * @param quantity + * @param shipDate + * @param status Order Status + * @param complete + */ + + +data class Order ( + + + @JsonProperty("id") + val id: kotlin.Long? = null, + + + @JsonProperty("petId") + val petId: kotlin.Long? = null, + + + @JsonProperty("quantity") + val quantity: kotlin.Int? = null, + + + @JsonProperty("shipDate") + val shipDate: java.time.OffsetDateTime? = null, + + /* Order Status */ + + @JsonProperty("status") + val status: Order.Status? = null, + + + @JsonProperty("complete") + val complete: kotlin.Boolean? = false + +) { + + /** + * Order Status + * + * Values: placed,approved,delivered + */ + enum class Status(val value: kotlin.String) { + @JsonProperty(value = "placed") placed("placed"), + @JsonProperty(value = "approved") approved("approved"), + @JsonProperty(value = "delivered") delivered("delivered"); + } +} + diff --git a/samples/server/petstore/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/models/Pet.kt b/samples/server/petstore/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/models/Pet.kt new file mode 100644 index 00000000000..826d87a7303 --- /dev/null +++ b/samples/server/petstore/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/models/Pet.kt @@ -0,0 +1,69 @@ +/** + * OpenAPI Petstore + * This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. + * + * The version of the OpenAPI document: 1.0.0 + * + * + * 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 org.openapitools.server.models.Category +import org.openapitools.server.models.Tag +import com.fasterxml.jackson.annotation.JsonProperty +/** + * A pet for sale in the pet store + * + * @param name + * @param photoUrls + * @param id + * @param category + * @param tags + * @param status pet status in the store + */ + + +data class Pet ( + + + @JsonProperty("name") + val name: kotlin.String, + + + @JsonProperty("photoUrls") + val photoUrls: kotlin.collections.List, + + + @JsonProperty("id") + val id: kotlin.Long? = null, + + + @JsonProperty("category") + val category: Category? = null, + + + @JsonProperty("tags") + val tags: kotlin.collections.List? = null, + + /* pet status in the store */ + + @JsonProperty("status") + val status: Pet.Status? = null + +) { + + /** + * pet status in the store + * + * Values: available,pending,sold + */ + enum class Status(val value: kotlin.String) { + @JsonProperty(value = "available") available("available"), + @JsonProperty(value = "pending") pending("pending"), + @JsonProperty(value = "sold") sold("sold"); + } +} + diff --git a/samples/server/petstore/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/models/Tag.kt b/samples/server/petstore/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/models/Tag.kt new file mode 100644 index 00000000000..ded0e6fab03 --- /dev/null +++ b/samples/server/petstore/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/models/Tag.kt @@ -0,0 +1,34 @@ +/** + * OpenAPI Petstore + * This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. + * + * The version of the OpenAPI document: 1.0.0 + * + * + * 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 +/** + * A tag for a pet + * + * @param id + * @param name + */ + + +data class Tag ( + + + @JsonProperty("id") + val id: kotlin.Long? = null, + + + @JsonProperty("name") + val name: kotlin.String? = null + +) + diff --git a/samples/server/petstore/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/models/User.kt b/samples/server/petstore/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/models/User.kt new file mode 100644 index 00000000000..4d0dcec6691 --- /dev/null +++ b/samples/server/petstore/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/models/User.kt @@ -0,0 +1,65 @@ +/** + * OpenAPI Petstore + * This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. + * + * The version of the OpenAPI document: 1.0.0 + * + * + * 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 +/** + * A User who is purchasing from the pet store + * + * @param id + * @param username + * @param firstName + * @param lastName + * @param email + * @param password + * @param phone + * @param userStatus User Status + */ + + +data class User ( + + + @JsonProperty("id") + val id: kotlin.Long? = null, + + + @JsonProperty("username") + val username: kotlin.String? = null, + + + @JsonProperty("firstName") + val firstName: kotlin.String? = null, + + + @JsonProperty("lastName") + val lastName: kotlin.String? = null, + + + @JsonProperty("email") + val email: kotlin.String? = null, + + + @JsonProperty("password") + val password: kotlin.String? = null, + + + @JsonProperty("phone") + val phone: kotlin.String? = null, + + /* User Status */ + + @JsonProperty("userStatus") + val userStatus: kotlin.Int? = null + +) +