diff --git a/.github/workflows/samples-kotlin-server-jdk17.yaml b/.github/workflows/samples-kotlin-server-jdk17.yaml index f79503de54f..f36a3fa4838 100644 --- a/.github/workflows/samples-kotlin-server-jdk17.yaml +++ b/.github/workflows/samples-kotlin-server-jdk17.yaml @@ -4,11 +4,13 @@ on: push: branches: - 'samples/server/petstore/kotlin-springboot-3*/**' + - 'samples/server/petstore/kotlin-server/javalin/**' # comment out due to gradle build failure # - samples/server/petstore/kotlin-spring-default/** pull_request: paths: - 'samples/server/petstore/kotlin-springboot-3*/**' + - 'samples/server/petstore/kotlin-server/javalin/**' # comment out due to gradle build failure # - samples/server/petstore/kotlin-spring-default/** @@ -26,6 +28,7 @@ jobs: # server - samples/server/petstore/kotlin-springboot-3 - samples/server/petstore/kotlin-springboot-request + - samples/server/petstore/kotlin-server/javalin # comment out due to gradle build failure # - samples/server/petstore/kotlin-spring-default/ steps: diff --git a/.github/workflows/samples-kotlin-server.yaml b/.github/workflows/samples-kotlin-server.yaml index f5ee278792f..cce5b85a54d 100644 --- a/.github/workflows/samples-kotlin-server.yaml +++ b/.github/workflows/samples-kotlin-server.yaml @@ -37,6 +37,7 @@ jobs: - samples/server/petstore/kotlin-server/jaxrs-spec - samples/server/petstore/kotlin-server/jaxrs-spec-mutiny - samples/server/petstore/kotlin-server-modelMutable + - samples/server/petstore/kotlin-server/javalin - samples/server/others/kotlin-server/jaxrs-spec # comment out due to gradle build failure #- samples/server/petstore/kotlin-spring-default diff --git a/bin/configs/kotlin-server-javalin.yaml b/bin/configs/kotlin-server-javalin.yaml new file mode 100644 index 00000000000..80392993a8f --- /dev/null +++ b/bin/configs/kotlin-server-javalin.yaml @@ -0,0 +1,7 @@ +generatorName: kotlin-server +outputDir: samples/server/petstore/kotlin-server/javalin +library: javalin5 +inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml +templateDir: modules/openapi-generator/src/main/resources/kotlin-server +additionalProperties: + hideGenerationTimestamp: "true" diff --git a/docs/generators/kotlin-server.md b/docs/generators/kotlin-server.md index b97a3267f88..54f8cb9f1c9 100644 --- a/docs/generators/kotlin-server.md +++ b/docs/generators/kotlin-server.md @@ -32,7 +32,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |featureResources|Generates routes in a typed way, for both: constructing URLs and reading the parameters.| |true| |groupId|Generated artifact package's organization (i.e. maven groupId).| |org.openapitools| |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| +|library|library template (sub-template)|
**ktor**
ktor framework
**jaxrs-spec**
JAX-RS spec only
**javalin5**
Javalin 5
|ktor| |modelMutable|Create mutable models| |false| |omitGradleWrapper|Whether to omit Gradle wrapper for creating a sub project.| |false| |packageName|Generated artifact package name.| |org.openapitools.server| 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 35e5e4a245a..3dee7ae6cc6 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 @@ -1143,4 +1143,44 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co return super.addMustacheLambdas() .put("escapeDollar", new EscapeChar("(?"); + if (end > 0) { + dataTypeAssigner.setReturnType(returnType.substring("kotlin.collections.List<".length(), end).trim()); + dataTypeAssigner.setReturnContainer("List"); + } + } else if (returnType.startsWith("kotlin.collections.MutableList")) { + int end = returnType.lastIndexOf(">"); + if (end > 0) { + dataTypeAssigner.setReturnType(returnType.substring("kotlin.collections.MutableList<".length(), end).trim()); + dataTypeAssigner.setReturnContainer("List"); + } + } else if (returnType.startsWith("kotlin.collections.Map")) { + int end = returnType.lastIndexOf(">"); + if (end > 0) { + dataTypeAssigner.setReturnType(returnType.substring("kotlin.collections.Map<".length(), end).split(",")[1].trim()); + dataTypeAssigner.setReturnContainer("Map"); + } + } else if (returnType.startsWith("kotlin.collections.MutableMap")) { + int end = returnType.lastIndexOf(">"); + if (end > 0) { + dataTypeAssigner.setReturnType(returnType.substring("kotlin.collections.MutableMap<".length(), end).split(",")[1].trim()); + dataTypeAssigner.setReturnContainer("Map"); + } + } + } } 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 9dcd71a06ea..b3fb66cf704 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 @@ -19,11 +19,13 @@ package org.openapitools.codegen.languages; import com.google.common.collect.ImmutableMap; import org.apache.commons.lang3.StringUtils; -import org.openapitools.codegen.CodegenConstants; -import org.openapitools.codegen.CodegenType; -import org.openapitools.codegen.SupportingFile; +import org.openapitools.codegen.*; import org.openapitools.codegen.languages.features.BeanValidationFeatures; import org.openapitools.codegen.meta.features.*; +import org.openapitools.codegen.model.ModelMap; +import org.openapitools.codegen.model.OperationMap; +import org.openapitools.codegen.model.OperationsMap; +import org.openapitools.codegen.templating.mustache.LowercaseLambda; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -119,6 +121,7 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen implements BeanVa supportedLibraries.put(Constants.KTOR, "ktor framework"); supportedLibraries.put(Constants.JAXRS_SPEC, "JAX-RS spec only"); + supportedLibraries.put(Constants.JAVALIN5, "Javalin 5"); // TODO: Configurable server engine. Defaults to netty in build.gradle. addOption(CodegenConstants.LIBRARY, CodegenConstants.LIBRARY_DESC, DEFAULT_LIBRARY, supportedLibraries); @@ -322,7 +325,13 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen implements BeanVa supportingFiles.add(new SupportingFile("Dockerfile.mustache", "", "Dockerfile")); } - supportingFiles.add(new SupportingFile("build.gradle.mustache", "", "build.gradle")); + String gradleBuildFile = "build.gradle"; + + if (library.equals(Constants.JAVALIN5)) { + gradleBuildFile = "build.gradle.kts"; + } + + supportingFiles.add(new SupportingFile(gradleBuildFile + ".mustache", "", gradleBuildFile)); supportingFiles.add(new SupportingFile("settings.gradle.mustache", "", "settings.gradle")); supportingFiles.add(new SupportingFile("gradle.properties", "", "gradle.properties")); @@ -340,6 +349,13 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen implements BeanVa final String infrastructureFolder = (sourceFolder + File.separator + packageName + File.separator + "infrastructure").replace(".", File.separator); supportingFiles.add(new SupportingFile("ApiKeyAuth.kt.mustache", infrastructureFolder, "ApiKeyAuth.kt")); + } else if (library.equals(Constants.JAVALIN5)) { + supportingFiles.add(new SupportingFile("Main.kt.mustache", packageFolder, "Main.kt")); + apiTemplateFiles.put("service.mustache", "Service.kt"); + apiTemplateFiles.put("serviceImpl.mustache", "ServiceImpl.kt"); + additionalProperties.put("lowercase", new LowercaseLambda()); + typeMapping.put("file", "io.javalin.http.UploadedFile"); + importMapping.put("io.javalin.http.UploadedFile", "io.javalin.http.UploadedFile"); } } @@ -351,6 +367,8 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen implements BeanVa public static class Constants { public final static String KTOR = "ktor"; public final static String JAXRS_SPEC = "jaxrs-spec"; + + public final static String JAVALIN5 = "javalin5"; 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"; @@ -390,4 +408,50 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen implements BeanVa System.out.println("# Please support his work directly via https://patreon.com/jimschubert \uD83D\uDE4F #"); System.out.println("################################################################################"); } + + @Override + public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List allModels) { + OperationMap operations = objs.getOperations(); + if (operations != null) { + List ops = operations.getOperation(); + ops.forEach(operation -> { + List responses = operation.responses; + if (responses != null) { + responses.forEach(resp -> { + + if ("0".equals(resp.code)) { + resp.code = "200"; + } + + doDataTypeAssignment(resp.dataType, new DataTypeAssigner() { + @Override + public void setReturnType(final String returnType) { + resp.dataType = returnType; + } + + @Override + public void setReturnContainer(final String returnContainer) { + resp.containerType = returnContainer; + } + }); + }); + } + + doDataTypeAssignment(operation.returnType, new DataTypeAssigner() { + + @Override + public void setReturnType(final String returnType) { + operation.returnType = returnType; + } + + @Override + public void setReturnContainer(final String returnContainer) { + operation.returnContainer = returnContainer; + } + }); + }); + } + + return objs; + } } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinSpringServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinSpringServerCodegen.java index ce14fe19a63..950d103f5bc 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinSpringServerCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinSpringServerCodegen.java @@ -949,46 +949,6 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen return type; } - private interface DataTypeAssigner { - void setReturnType(String returnType); - - void setReturnContainer(String returnContainer); - } - - /** - * @param returnType The return type that needs to be converted - * @param dataTypeAssigner An object that will assign the data to the respective fields in the model. - */ - private void doDataTypeAssignment(final String returnType, DataTypeAssigner dataTypeAssigner) { - if (returnType == null) { - dataTypeAssigner.setReturnType("Unit"); - } else if (returnType.startsWith("kotlin.collections.List")) { - int end = returnType.lastIndexOf(">"); - if (end > 0) { - dataTypeAssigner.setReturnType(returnType.substring("kotlin.collections.List<".length(), end).trim()); - dataTypeAssigner.setReturnContainer("List"); - } - } else if (returnType.startsWith("kotlin.collections.MutableList")) { - int end = returnType.lastIndexOf(">"); - if (end > 0) { - dataTypeAssigner.setReturnType(returnType.substring("kotlin.collections.MutableList<".length(), end).trim()); - dataTypeAssigner.setReturnContainer("List"); - } - } else if (returnType.startsWith("kotlin.collections.Map")) { - int end = returnType.lastIndexOf(">"); - if (end > 0) { - dataTypeAssigner.setReturnType(returnType.substring("kotlin.collections.Map<".length(), end).split(",")[1].trim()); - dataTypeAssigner.setReturnContainer("Map"); - } - } else if (returnType.startsWith("kotlin.collections.MutableMap")) { - int end = returnType.lastIndexOf(">"); - if (end > 0) { - dataTypeAssigner.setReturnType(returnType.substring("kotlin.collections.MutableMap<".length(), end).split(",")[1].trim()); - dataTypeAssigner.setReturnContainer("Map"); - } - } - } - private static String sanitizeDirectory(String in) { return in.replace(".", File.separator); } diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/Main.kt.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/Main.kt.mustache new file mode 100644 index 00000000000..1628b2fb2b9 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/Main.kt.mustache @@ -0,0 +1,36 @@ +package {{packageName}} + +import io.javalin.Javalin +import io.javalin.community.routing.dsl.routing + +{{#apiInfo}} +{{#apis}} +{{#operations}}import {{apiPackage}}.{{classname}} +import {{apiPackage}}.{{classname}}ServiceImpl +{{/operations}} +{{/apis}} + +fun main() { + {{#apis}} + {{#operations}} + val {{classname}} = {{classname}}({{classname}}ServiceImpl()) + {{/operations}} + {{/apis}} + + val app = Javalin + .create { config -> + config.routing { + {{#apis}} + {{#operations}} + {{#operation}} + {{#lowercase}}{{httpMethod}}{{/lowercase}}("{{path}}", {{classname}}::{{operationId}}) + {{/operation}} + {{/operations}} + + {{/apis}} + } + } + + app.start({{serverPort}}) +} +{{/apiInfo}} diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/README.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/README.mustache new file mode 100644 index 00000000000..2c5d5f19518 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/README.mustache @@ -0,0 +1,94 @@ +# {{packageName}} - Kotlin Server library for {{appName}} + +{{#unescapedAppDescription}} +{{.}} +{{/unescapedAppDescription}} + +Generated by OpenAPI Generator {{generatorVersion}}{{^hideGenerationTimestamp}} ({{generatedDate}}){{/hideGenerationTimestamp}}. + +## Build + +First, create the gradle wrapper script: + +``` +gradle wrapper +``` + +Then, run: + +``` +./gradlew check assemble +``` + +This runs all tests and packages the library. + +## Running + +The server builds as a fat jar with a main entrypoint. To start the service, run `java -jar ./build/libs/{{artifactId}}.jar`. + +You may also run in docker: + +``` +docker build -t {{artifactId}} . +docker run -p 8080:8080 {{artifactId}} +``` + +## Features/Implementation Notes + +* Supports JSON inputs/outputs, File inputs, and Form inputs (see ktor documentation for more info). +* ~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. + +{{#generateApiDocs}} + +## Documentation for API Endpoints + +All URIs are relative to *{{{basePath}}}* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}*{{classname}}* | [**{{operationId}}**]({{apiDocPath}}{{classname}}.md#{{operationIdLowerCase}}) | **{{httpMethod}}** {{path}} | {{{summary}}} +{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} +{{/generateApiDocs}} + +{{#generateModelDocs}} + +## Documentation for Models + +{{#modelPackage}} +{{#models}}{{#model}} - [{{{modelPackage}}}.{{{classname}}}]({{modelDocPath}}{{{classname}}}.md) +{{/model}}{{/models}} +{{/modelPackage}} +{{^modelPackage}} +No model defined in this package +{{/modelPackage}} +{{/generateModelDocs}} + + +## Documentation for Authorization + +{{^authMethods}}Endpoints do not require authorization.{{/authMethods}} +{{#hasAuthMethods}}Authentication schemes defined for the API:{{/hasAuthMethods}} +{{#authMethods}} + +### {{name}} + +{{#isApiKey}}- **Type**: API key +- **API key parameter name**: {{keyParamName}} +- **Location**: {{#isKeyInQuery}}URL query string{{/isKeyInQuery}}{{#isKeyInHeader}}HTTP header{{/isKeyInHeader}} +{{/isApiKey}} +{{#isBasicBasic}}- **Type**: HTTP basic authentication +{{/isBasicBasic}} +{{#isBasicBearer}}- **Type**: HTTP Bearer Token authentication{{#bearerFormat}} ({{{.}}}){{/bearerFormat}} +{{/isBasicBearer}} +{{#isHttpSignature}}- **Type**: HTTP signature authentication +{{/isHttpSignature}} +{{#isOAuth}}- **Type**: OAuth +- **Flow**: {{flow}} +- **Authorization URL**: {{authorizationUrl}} +- **Scopes**: {{^scopes}}N/A{{/scopes}} +{{#scopes}} - {{scope}}: {{description}} +{{/scopes}} +{{/isOAuth}} + +{{/authMethods}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/api.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/api.mustache new file mode 100644 index 00000000000..c1b331f8384 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/api.mustache @@ -0,0 +1,25 @@ +package {{apiPackage}} + +import io.javalin.http.Context +import io.javalin.http.bodyAsClass +import io.javalin.http.pathParamAsClass +import io.javalin.http.queryParamAsClass + +{{#imports}}import {{import}} +{{/imports}} + +{{#operations}} +class {{classname}}(private val service: {{classname}}Service) { + {{#operation}} + /**{{#summary}} + * {{.}}{{/summary}} + * {{unescapedNotes}} + {{#allParams}}* @param {{paramName}} {{description}} {{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}} + {{/allParams}}*/ + fun {{operationId}}(ctx: Context) { + ctx.status(200).json(service.{{operationId}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{^-last}}, {{/-last}}{{/allParams}})) + } + + {{/operation}} +} +{{/operations}} diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/bodyParams.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/bodyParams.mustache new file mode 100644 index 00000000000..63063e10d76 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/bodyParams.mustache @@ -0,0 +1 @@ +{{#isBodyParam}}{{#isArray}}ctx.bodyAsClass>(){{/isArray}}{{^isArray}}ctx.bodyAsClass<{{{baseType}}}>(){{/isArray}}{{/isBodyParam}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/build.gradle.kts.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/build.gradle.kts.mustache new file mode 100644 index 00000000000..7ca2fab59f8 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/build.gradle.kts.mustache @@ -0,0 +1,35 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + kotlin("jvm") version "1.9.21" +} + +group = "{{groupId}}" +version = "{{artifactVersion}}" +java.sourceCompatibility = JavaVersion.VERSION_17 + +repositories { + mavenCentral() +} + +tasks.withType { + kotlinOptions.jvmTarget = "17" +} + +dependencies { + implementation("io.javalin:javalin:5.6.3") + implementation("io.javalin.community.routing:routing-core:5.6.2-RC.1") + implementation("io.javalin.community.routing:routing-dsl:5.6.2-RC.1") + implementation("com.fasterxml.jackson.core:jackson-databind:2.16.1") + implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.16.1") + implementation("org.slf4j:slf4j-simple:2.0.7") + + testImplementation("org.jetbrains.kotlin:kotlin-test") +} + +tasks.test { + useJUnitPlatform() +} +kotlin { + jvmToolchain(17) +} diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/formParams.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/formParams.mustache new file mode 100644 index 00000000000..8dc63bc3ca6 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/formParams.mustache @@ -0,0 +1 @@ +{{#isFormParam}}{{^isFile}}ctx.formParam("{{baseName}}"){{/isFile}}{{#isFile}}ctx.uploadedFile("{{baseName}}"){{/isFile}}{{/isFormParam}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/gradle.properties b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/gradle.properties new file mode 100644 index 00000000000..5f1ed7bbe02 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/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/javalin5/headerParams.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/headerParams.mustache new file mode 100644 index 00000000000..a5b25b1a993 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/headerParams.mustache @@ -0,0 +1 @@ +{{#isHeaderParam}}ctx.header("{{baseName}}"){{/isHeaderParam}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/optionalDataType.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/optionalDataType.mustache new file mode 100644 index 00000000000..7c026fa826f --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/optionalDataType.mustache @@ -0,0 +1 @@ +{{#required}}{{{dataType}}}{{/required}}{{^required}}{{#defaultValue}}{{{dataType}}}{{/defaultValue}}{{^defaultValue}}{{{dataType}}}?{{/defaultValue}}{{/required}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/pathParams.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/pathParams.mustache new file mode 100644 index 00000000000..4f1cfe9bfc7 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/pathParams.mustache @@ -0,0 +1 @@ +{{#isPathParam}}ctx.pathParamAsClass<{{{dataType}}}>("{{baseName}}").get(){{/isPathParam}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/queryParams.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/queryParams.mustache new file mode 100644 index 00000000000..5fa2906d654 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/queryParams.mustache @@ -0,0 +1 @@ +{{#isQueryParam}}{{#isArray}}ctx.queryParams("{{baseName}}"){{/isArray}}{{^isArray}}ctx.queryParamAsClass("{{baseName}}").get(){{/isArray}}{{/isQueryParam}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/returnTypes.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/returnTypes.mustache new file mode 100644 index 00000000000..12a74e5ad7a --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/returnTypes.mustache @@ -0,0 +1 @@ +{{#isMap}}Map{{/isMap}}{{#isArray}}{{#reactive}}Flow{{/reactive}}{{^reactive}}{{{returnContainer}}}{{/reactive}}<{{{returnType}}}>{{/isArray}}{{^returnContainer}}{{{returnType}}}{{/returnContainer}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/service.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/service.mustache new file mode 100644 index 00000000000..73fb1332fda --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/service.mustache @@ -0,0 +1,33 @@ +package {{package}} + +{{#imports}}import {{import}} +{{/imports}} + +{{#operations}} +interface {{classname}}Service { +{{#operation}} + + /** + * {{httpMethod}} {{{path}}}{{#summary}} : {{.}}{{/summary}} + {{#notes}} + * {{.}} + {{/notes}} + * + {{#allParams}} + * @param {{{paramName}}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}} + {{/allParams}} + * @return {{#responses}}{{message}} (status code {{code}}){{^-last}} + * or {{/-last}}{{/responses}} + {{#isDeprecated}} + * @deprecated + {{/isDeprecated}} + {{#externalDocs}} + * {{description}} + * @see {{summary}} Documentation + {{/externalDocs}} + * @see {{classname}}#{{operationId}} + */ + {{#reactive}}{{^isArray}}suspend {{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{{paramName}}}: {{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}{{>optionalDataType}}{{/isArray}}{{#isArray}}Flow<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{^-last}}, {{/-last}}{{/allParams}}): {{>returnTypes}} +{{/operation}} +} +{{/operations}} diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/serviceImpl.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/serviceImpl.mustache new file mode 100644 index 00000000000..0d11f745b29 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/serviceImpl.mustache @@ -0,0 +1,18 @@ +package {{package}} + +{{#imports}}import {{import}} +{{/imports}} +{{#reactive}} +import kotlinx.coroutines.flow.Flow +{{/reactive}} +{{#operations}} + +class {{classname}}ServiceImpl : {{classname}}Service { +{{#operation}} + + override {{#reactive}}{{^isArray}}suspend {{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{paramName}}: {{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}{{>optionalDataType}}{{/isArray}}{{#isArray}}Flow<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{^-last}}, {{/-last}}{{/allParams}}): {{>returnTypes}} { + TODO("Implement me") + } +{{/operation}} +} +{{/operations}} diff --git a/samples/server/petstore/kotlin-server/javalin/.openapi-generator-ignore b/samples/server/petstore/kotlin-server/javalin/.openapi-generator-ignore new file mode 100644 index 00000000000..7484ee590a3 --- /dev/null +++ b/samples/server/petstore/kotlin-server/javalin/.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/javalin/.openapi-generator/FILES b/samples/server/petstore/kotlin-server/javalin/.openapi-generator/FILES new file mode 100644 index 00000000000..171ae436439 --- /dev/null +++ b/samples/server/petstore/kotlin-server/javalin/.openapi-generator/FILES @@ -0,0 +1,20 @@ +README.md +build.gradle.kts +gradle.properties +settings.gradle +src/main/kotlin/org/openapitools/server/Main.kt +src/main/kotlin/org/openapitools/server/apis/PetApi.kt +src/main/kotlin/org/openapitools/server/apis/PetApiService.kt +src/main/kotlin/org/openapitools/server/apis/PetApiServiceImpl.kt +src/main/kotlin/org/openapitools/server/apis/StoreApi.kt +src/main/kotlin/org/openapitools/server/apis/StoreApiService.kt +src/main/kotlin/org/openapitools/server/apis/StoreApiServiceImpl.kt +src/main/kotlin/org/openapitools/server/apis/UserApi.kt +src/main/kotlin/org/openapitools/server/apis/UserApiService.kt +src/main/kotlin/org/openapitools/server/apis/UserApiServiceImpl.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/javalin/.openapi-generator/VERSION b/samples/server/petstore/kotlin-server/javalin/.openapi-generator/VERSION new file mode 100644 index 00000000000..fff4bdd7ab5 --- /dev/null +++ b/samples/server/petstore/kotlin-server/javalin/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.3.0-SNAPSHOT \ No newline at end of file diff --git a/samples/server/petstore/kotlin-server/javalin/README.md b/samples/server/petstore/kotlin-server/javalin/README.md new file mode 100644 index 00000000000..408da8d35a9 --- /dev/null +++ b/samples/server/petstore/kotlin-server/javalin/README.md @@ -0,0 +1,101 @@ +# org.openapitools.server - Kotlin Server library for 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. + +Generated by OpenAPI Generator 7.3.0-SNAPSHOT. + +## Build + +First, create the gradle wrapper script: + +``` +gradle wrapper +``` + +Then, run: + +``` +./gradlew check assemble +``` + +This runs all tests and packages the library. + +## Running + +The server builds as a fat jar with a main entrypoint. To start the service, run `java -jar ./build/libs/kotlin-server.jar`. + +You may also run in docker: + +``` +docker build -t kotlin-server . +docker run -p 8080:8080 kotlin-server +``` + +## Features/Implementation Notes + +* Supports JSON inputs/outputs, File inputs, and Form inputs (see ktor documentation for more info). +* ~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 + + +Authentication schemes defined for the API: + +### 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 + + +### api_key + +- **Type**: API key +- **API key parameter name**: api_key +- **Location**: HTTP header + diff --git a/samples/server/petstore/kotlin-server/javalin/build.gradle.kts b/samples/server/petstore/kotlin-server/javalin/build.gradle.kts new file mode 100644 index 00000000000..1b34f07ad15 --- /dev/null +++ b/samples/server/petstore/kotlin-server/javalin/build.gradle.kts @@ -0,0 +1,35 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + kotlin("jvm") version "1.9.21" +} + +group = "org.openapitools" +version = "1.0.0" +java.sourceCompatibility = JavaVersion.VERSION_17 + +repositories { + mavenCentral() +} + +tasks.withType { + kotlinOptions.jvmTarget = "17" +} + +dependencies { + implementation("io.javalin:javalin:5.6.3") + implementation("io.javalin.community.routing:routing-core:5.6.2-RC.1") + implementation("io.javalin.community.routing:routing-dsl:5.6.2-RC.1") + implementation("com.fasterxml.jackson.core:jackson-databind:2.16.1") + implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.16.1") + implementation("org.slf4j:slf4j-simple:2.0.7") + + testImplementation("org.jetbrains.kotlin:kotlin-test") +} + +tasks.test { + useJUnitPlatform() +} +kotlin { + jvmToolchain(17) +} diff --git a/samples/server/petstore/kotlin-server/javalin/gradle.properties b/samples/server/petstore/kotlin-server/javalin/gradle.properties new file mode 100644 index 00000000000..5f1ed7bbe02 --- /dev/null +++ b/samples/server/petstore/kotlin-server/javalin/gradle.properties @@ -0,0 +1 @@ +org.gradle.caching=true \ No newline at end of file diff --git a/samples/server/petstore/kotlin-server/javalin/settings.gradle b/samples/server/petstore/kotlin-server/javalin/settings.gradle new file mode 100644 index 00000000000..a09a58efab1 --- /dev/null +++ b/samples/server/petstore/kotlin-server/javalin/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'kotlin-server' \ No newline at end of file diff --git a/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/Main.kt b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/Main.kt new file mode 100644 index 00000000000..67524428fb8 --- /dev/null +++ b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/Main.kt @@ -0,0 +1,48 @@ +package org.openapitools.server + +import io.javalin.Javalin +import io.javalin.community.routing.dsl.routing + +import org.openapitools.server.apis.PetApi +import org.openapitools.server.apis.PetApiServiceImpl +import org.openapitools.server.apis.StoreApi +import org.openapitools.server.apis.StoreApiServiceImpl +import org.openapitools.server.apis.UserApi +import org.openapitools.server.apis.UserApiServiceImpl + +fun main() { + val PetApi = PetApi(PetApiServiceImpl()) + val StoreApi = StoreApi(StoreApiServiceImpl()) + val UserApi = UserApi(UserApiServiceImpl()) + + val app = Javalin + .create { config -> + config.routing { + post("/pet", PetApi::addPet) + delete("/pet/{petId}", PetApi::deletePet) + get("/pet/findByStatus", PetApi::findPetsByStatus) + get("/pet/findByTags", PetApi::findPetsByTags) + get("/pet/{petId}", PetApi::getPetById) + put("/pet", PetApi::updatePet) + post("/pet/{petId}", PetApi::updatePetWithForm) + post("/pet/{petId}/uploadImage", PetApi::uploadFile) + + delete("/store/order/{orderId}", StoreApi::deleteOrder) + get("/store/inventory", StoreApi::getInventory) + get("/store/order/{orderId}", StoreApi::getOrderById) + post("/store/order", StoreApi::placeOrder) + + post("/user", UserApi::createUser) + post("/user/createWithArray", UserApi::createUsersWithArrayInput) + post("/user/createWithList", UserApi::createUsersWithListInput) + delete("/user/{username}", UserApi::deleteUser) + get("/user/{username}", UserApi::getUserByName) + get("/user/login", UserApi::loginUser) + get("/user/logout", UserApi::logoutUser) + put("/user/{username}", UserApi::updateUser) + + } + } + + app.start() +} diff --git a/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/apis/PetApi.kt b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/apis/PetApi.kt new file mode 100644 index 00000000000..9ab4ffa663f --- /dev/null +++ b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/apis/PetApi.kt @@ -0,0 +1,89 @@ +package org.openapitools.server.apis + +import io.javalin.http.Context +import io.javalin.http.bodyAsClass +import io.javalin.http.pathParamAsClass +import io.javalin.http.queryParamAsClass + +import org.openapitools.server.models.ModelApiResponse +import org.openapitools.server.models.Pet + +class PetApi(private val service: PetApiService) { + /** + * Add a new pet to the store + * + * @param pet Pet object that needs to be added to the store + */ + fun addPet(ctx: Context) { + ctx.status(200).json(service.addPet(ctx.bodyAsClass())) + } + + /** + * Deletes a pet + * + * @param petId Pet id to delete + * @param apiKey (optional) + */ + fun deletePet(ctx: Context) { + ctx.status(200).json(service.deletePet(ctx.pathParamAsClass("petId").get(), ctx.header("api_key"))) + } + + /** + * Finds Pets by status + * Multiple status values can be provided with comma separated strings + * @param status Status values that need to be considered for filter + */ + fun findPetsByStatus(ctx: Context) { + ctx.status(200).json(service.findPetsByStatus(ctx.queryParams("status"))) + } + + /** + * Finds Pets by tags + * Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. + * @param tags Tags to filter by + */ + fun findPetsByTags(ctx: Context) { + ctx.status(200).json(service.findPetsByTags(ctx.queryParams("tags"))) + } + + /** + * Find pet by ID + * Returns a single pet + * @param petId ID of pet to return + */ + fun getPetById(ctx: Context) { + ctx.status(200).json(service.getPetById(ctx.pathParamAsClass("petId").get())) + } + + /** + * Update an existing pet + * + * @param pet Pet object that needs to be added to the store + */ + fun updatePet(ctx: Context) { + ctx.status(200).json(service.updatePet(ctx.bodyAsClass())) + } + + /** + * Updates a pet in the store with form data + * + * @param petId ID of pet that needs to be updated + * @param name Updated name of the pet (optional) + * @param status Updated status of the pet (optional) + */ + fun updatePetWithForm(ctx: Context) { + ctx.status(200).json(service.updatePetWithForm(ctx.pathParamAsClass("petId").get(), ctx.formParam("name"), ctx.formParam("status"))) + } + + /** + * uploads an image + * + * @param petId ID of pet to update + * @param additionalMetadata Additional data to pass to server (optional) + * @param file file to upload (optional) + */ + fun uploadFile(ctx: Context) { + ctx.status(200).json(service.uploadFile(ctx.pathParamAsClass("petId").get(), ctx.formParam("additionalMetadata"), ctx.uploadedFile("file"))) + } + +} diff --git a/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/apis/PetApiService.kt b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/apis/PetApiService.kt new file mode 100644 index 00000000000..1783de4bca8 --- /dev/null +++ b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/apis/PetApiService.kt @@ -0,0 +1,103 @@ +package org.openapitools.server.apis + +import org.openapitools.server.models.ModelApiResponse +import org.openapitools.server.models.Pet + +interface PetApiService { + + /** + * POST /pet : Add a new pet to the store + * + * + * @param pet Pet object that needs to be added to the store (required) + * @return successful operation (status code 200) + * or Invalid input (status code 405) + * @see PetApi#addPet + */ + fun addPet(pet: Pet): Pet + + /** + * DELETE /pet/{petId} : Deletes a pet + * + * + * @param petId Pet id to delete (required) + * @param apiKey (optional) + * @return Invalid pet value (status code 400) + * @see PetApi#deletePet + */ + fun deletePet(petId: kotlin.Long, apiKey: kotlin.String?): Unit + + /** + * GET /pet/findByStatus : Finds Pets by status + * Multiple status values can be provided with comma separated strings + * + * @param status Status values that need to be considered for filter (required) + * @return successful operation (status code 200) + * or Invalid status value (status code 400) + * @see PetApi#findPetsByStatus + */ + fun findPetsByStatus(status: kotlin.collections.List): List + + /** + * GET /pet/findByTags : Finds Pets by tags + * Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. + * + * @param tags Tags to filter by (required) + * @return successful operation (status code 200) + * or Invalid tag value (status code 400) + * @deprecated + * @see PetApi#findPetsByTags + */ + fun findPetsByTags(tags: kotlin.collections.List): List + + /** + * GET /pet/{petId} : Find pet by ID + * Returns a single pet + * + * @param petId ID of pet to return (required) + * @return successful operation (status code 200) + * or Invalid ID supplied (status code 400) + * or Pet not found (status code 404) + * @see PetApi#getPetById + */ + fun getPetById(petId: kotlin.Long): Pet + + /** + * PUT /pet : Update an existing pet + * + * + * @param pet Pet object that needs to be added to the store (required) + * @return successful operation (status code 200) + * or Invalid ID supplied (status code 400) + * or Pet not found (status code 404) + * or Validation exception (status code 405) + * API documentation for the updatePet operation + * @see Update an existing pet Documentation + * @see PetApi#updatePet + */ + fun updatePet(pet: Pet): Pet + + /** + * POST /pet/{petId} : Updates a pet in the store with form data + * + * + * @param petId ID of pet that needs to be updated (required) + * @param name Updated name of the pet (optional) + * @param status Updated status of the pet (optional) + * @return Invalid input (status code 405) + * @see PetApi#updatePetWithForm + */ + fun updatePetWithForm(petId: kotlin.Long, name: kotlin.String?, status: kotlin.String?): Unit + + /** + * POST /pet/{petId}/uploadImage : uploads an image + * + * + * @param petId ID of pet to update (required) + * @param additionalMetadata Additional data to pass to server (optional) + * @param file file to upload (optional) + * @return successful operation (status code 200) + * @see PetApi#uploadFile + */ + fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: io.javalin.http.UploadedFile?): ModelApiResponse +} diff --git a/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/apis/PetApiServiceImpl.kt b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/apis/PetApiServiceImpl.kt new file mode 100644 index 00000000000..96760ed2675 --- /dev/null +++ b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/apis/PetApiServiceImpl.kt @@ -0,0 +1,39 @@ +package org.openapitools.server.apis + +import org.openapitools.server.models.ModelApiResponse +import org.openapitools.server.models.Pet + +class PetApiServiceImpl : PetApiService { + + override fun addPet(pet: Pet): Pet { + TODO("Implement me") + } + + override fun deletePet(petId: kotlin.Long, apiKey: kotlin.String?): Unit { + TODO("Implement me") + } + + override fun findPetsByStatus(status: kotlin.collections.List): List { + TODO("Implement me") + } + + override fun findPetsByTags(tags: kotlin.collections.List): List { + TODO("Implement me") + } + + override fun getPetById(petId: kotlin.Long): Pet { + TODO("Implement me") + } + + override fun updatePet(pet: Pet): Pet { + TODO("Implement me") + } + + override fun updatePetWithForm(petId: kotlin.Long, name: kotlin.String?, status: kotlin.String?): Unit { + TODO("Implement me") + } + + override fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: io.javalin.http.UploadedFile?): ModelApiResponse { + TODO("Implement me") + } +} diff --git a/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt new file mode 100644 index 00000000000..2ba373661b8 --- /dev/null +++ b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt @@ -0,0 +1,46 @@ +package org.openapitools.server.apis + +import io.javalin.http.Context +import io.javalin.http.bodyAsClass +import io.javalin.http.pathParamAsClass +import io.javalin.http.queryParamAsClass + +import org.openapitools.server.models.Order + +class StoreApi(private val service: StoreApiService) { + /** + * Delete purchase order by ID + * For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors + * @param orderId ID of the order that needs to be deleted + */ + fun deleteOrder(ctx: Context) { + ctx.status(200).json(service.deleteOrder(ctx.pathParamAsClass("orderId").get())) + } + + /** + * Returns pet inventories by status + * Returns a map of status codes to quantities + */ + fun getInventory(ctx: Context) { + ctx.status(200).json(service.getInventory()) + } + + /** + * Find purchase order by ID + * For valid response try integer IDs with value <= 5 or > 10. Other values will generate exceptions + * @param orderId ID of pet that needs to be fetched + */ + fun getOrderById(ctx: Context) { + ctx.status(200).json(service.getOrderById(ctx.pathParamAsClass("orderId").get())) + } + + /** + * Place an order for a pet + * + * @param order order placed for purchasing the pet + */ + fun placeOrder(ctx: Context) { + ctx.status(200).json(service.placeOrder(ctx.bodyAsClass())) + } + +} diff --git a/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/apis/StoreApiService.kt b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/apis/StoreApiService.kt new file mode 100644 index 00000000000..8ce5275ddd4 --- /dev/null +++ b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/apis/StoreApiService.kt @@ -0,0 +1,49 @@ +package org.openapitools.server.apis + +import org.openapitools.server.models.Order + +interface StoreApiService { + + /** + * DELETE /store/order/{orderId} : Delete purchase order by ID + * For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors + * + * @param orderId ID of the order that needs to be deleted (required) + * @return Invalid ID supplied (status code 400) + * or Order not found (status code 404) + * @see StoreApi#deleteOrder + */ + fun deleteOrder(orderId: kotlin.String): Unit + + /** + * GET /store/inventory : Returns pet inventories by status + * Returns a map of status codes to quantities + * + * @return successful operation (status code 200) + * @see StoreApi#getInventory + */ + fun getInventory(): Map + + /** + * GET /store/order/{orderId} : Find purchase order by ID + * For valid response try integer IDs with value <= 5 or > 10. Other values will generate exceptions + * + * @param orderId ID of pet that needs to be fetched (required) + * @return successful operation (status code 200) + * or Invalid ID supplied (status code 400) + * or Order not found (status code 404) + * @see StoreApi#getOrderById + */ + fun getOrderById(orderId: kotlin.Long): Order + + /** + * POST /store/order : Place an order for a pet + * + * + * @param order order placed for purchasing the pet (required) + * @return successful operation (status code 200) + * or Invalid Order (status code 400) + * @see StoreApi#placeOrder + */ + fun placeOrder(order: Order): Order +} diff --git a/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/apis/StoreApiServiceImpl.kt b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/apis/StoreApiServiceImpl.kt new file mode 100644 index 00000000000..b9a008ae2b2 --- /dev/null +++ b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/apis/StoreApiServiceImpl.kt @@ -0,0 +1,22 @@ +package org.openapitools.server.apis + +import org.openapitools.server.models.Order + +class StoreApiServiceImpl : StoreApiService { + + override fun deleteOrder(orderId: kotlin.String): Unit { + TODO("Implement me") + } + + override fun getInventory(): Map { + TODO("Implement me") + } + + override fun getOrderById(orderId: kotlin.Long): Order { + TODO("Implement me") + } + + override fun placeOrder(order: Order): Order { + TODO("Implement me") + } +} diff --git a/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/apis/UserApi.kt b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/apis/UserApi.kt new file mode 100644 index 00000000000..c5435f744c3 --- /dev/null +++ b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/apis/UserApi.kt @@ -0,0 +1,84 @@ +package org.openapitools.server.apis + +import io.javalin.http.Context +import io.javalin.http.bodyAsClass +import io.javalin.http.pathParamAsClass +import io.javalin.http.queryParamAsClass + +import org.openapitools.server.models.User + +class UserApi(private val service: UserApiService) { + /** + * Create user + * This can only be done by the logged in user. + * @param user Created user object + */ + fun createUser(ctx: Context) { + ctx.status(200).json(service.createUser(ctx.bodyAsClass())) + } + + /** + * Creates list of users with given input array + * + * @param user List of user object + */ + fun createUsersWithArrayInput(ctx: Context) { + ctx.status(200).json(service.createUsersWithArrayInput(ctx.bodyAsClass>())) + } + + /** + * Creates list of users with given input array + * + * @param user List of user object + */ + fun createUsersWithListInput(ctx: Context) { + ctx.status(200).json(service.createUsersWithListInput(ctx.bodyAsClass>())) + } + + /** + * Delete user + * This can only be done by the logged in user. + * @param username The name that needs to be deleted + */ + fun deleteUser(ctx: Context) { + ctx.status(200).json(service.deleteUser(ctx.pathParamAsClass("username").get())) + } + + /** + * Get user by user name + * + * @param username The name that needs to be fetched. Use user1 for testing. + */ + fun getUserByName(ctx: Context) { + ctx.status(200).json(service.getUserByName(ctx.pathParamAsClass("username").get())) + } + + /** + * Logs user into the system + * + * @param username The user name for login + * @param password The password for login in clear text + */ + fun loginUser(ctx: Context) { + ctx.status(200).json(service.loginUser(ctx.queryParamAsClass("username").get(), ctx.queryParamAsClass("password").get())) + } + + /** + * Logs out current logged in user session + * + */ + fun logoutUser(ctx: Context) { + ctx.status(200).json(service.logoutUser()) + } + + /** + * Updated user + * This can only be done by the logged in user. + * @param username name that need to be deleted + * @param user Updated user object + */ + fun updateUser(ctx: Context) { + ctx.status(200).json(service.updateUser(ctx.pathParamAsClass("username").get(), ctx.bodyAsClass())) + } + +} diff --git a/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/apis/UserApiService.kt b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/apis/UserApiService.kt new file mode 100644 index 00000000000..9215242d545 --- /dev/null +++ b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/apis/UserApiService.kt @@ -0,0 +1,92 @@ +package org.openapitools.server.apis + +import org.openapitools.server.models.User + +interface UserApiService { + + /** + * POST /user : Create user + * This can only be done by the logged in user. + * + * @param user Created user object (required) + * @return successful operation (status code 200) + * @see UserApi#createUser + */ + fun createUser(user: User): Unit + + /** + * POST /user/createWithArray : Creates list of users with given input array + * + * + * @param user List of user object (required) + * @return successful operation (status code 200) + * @see UserApi#createUsersWithArrayInput + */ + fun createUsersWithArrayInput(user: kotlin.collections.List): Unit + + /** + * POST /user/createWithList : Creates list of users with given input array + * + * + * @param user List of user object (required) + * @return successful operation (status code 200) + * @see UserApi#createUsersWithListInput + */ + fun createUsersWithListInput(user: kotlin.collections.List): Unit + + /** + * DELETE /user/{username} : Delete user + * This can only be done by the logged in user. + * + * @param username The name that needs to be deleted (required) + * @return Invalid username supplied (status code 400) + * or User not found (status code 404) + * @see UserApi#deleteUser + */ + fun deleteUser(username: kotlin.String): Unit + + /** + * GET /user/{username} : Get user by user name + * + * + * @param username The name that needs to be fetched. Use user1 for testing. (required) + * @return successful operation (status code 200) + * or Invalid username supplied (status code 400) + * or User not found (status code 404) + * @see UserApi#getUserByName + */ + fun getUserByName(username: kotlin.String): User + + /** + * GET /user/login : Logs user into the system + * + * + * @param username The user name for login (required) + * @param password The password for login in clear text (required) + * @return successful operation (status code 200) + * or Invalid username/password supplied (status code 400) + * @see UserApi#loginUser + */ + fun loginUser(username: kotlin.String, password: kotlin.String): kotlin.String + + /** + * GET /user/logout : Logs out current logged in user session + * + * + * @return successful operation (status code 200) + * @see UserApi#logoutUser + */ + fun logoutUser(): Unit + + /** + * PUT /user/{username} : Updated user + * This can only be done by the logged in user. + * + * @param username name that need to be deleted (required) + * @param user Updated user object (required) + * @return Invalid user supplied (status code 400) + * or User not found (status code 404) + * @see UserApi#updateUser + */ + fun updateUser(username: kotlin.String, user: User): Unit +} diff --git a/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/apis/UserApiServiceImpl.kt b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/apis/UserApiServiceImpl.kt new file mode 100644 index 00000000000..b889b79aabe --- /dev/null +++ b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/apis/UserApiServiceImpl.kt @@ -0,0 +1,38 @@ +package org.openapitools.server.apis + +import org.openapitools.server.models.User + +class UserApiServiceImpl : UserApiService { + + override fun createUser(user: User): Unit { + TODO("Implement me") + } + + override fun createUsersWithArrayInput(user: kotlin.collections.List): Unit { + TODO("Implement me") + } + + override fun createUsersWithListInput(user: kotlin.collections.List): Unit { + TODO("Implement me") + } + + override fun deleteUser(username: kotlin.String): Unit { + TODO("Implement me") + } + + override fun getUserByName(username: kotlin.String): User { + TODO("Implement me") + } + + override fun loginUser(username: kotlin.String, password: kotlin.String): kotlin.String { + TODO("Implement me") + } + + override fun logoutUser(): Unit { + TODO("Implement me") + } + + override fun updateUser(username: kotlin.String, user: User): Unit { + TODO("Implement me") + } +} diff --git a/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/models/Category.kt b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/models/Category.kt new file mode 100644 index 00000000000..71098339bc8 --- /dev/null +++ b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/models/Category.kt @@ -0,0 +1,24 @@ +/** + * 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 + + +/** + * A category for a pet + * @param id + * @param name + */ +data class Category( + val id: kotlin.Long? = null, + val name: kotlin.String? = null +) + diff --git a/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/models/ModelApiResponse.kt b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/models/ModelApiResponse.kt new file mode 100644 index 00000000000..9e80c50c660 --- /dev/null +++ b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/models/ModelApiResponse.kt @@ -0,0 +1,26 @@ +/** + * 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 + + +/** + * Describes the result of uploading an image resource + * @param code + * @param type + * @param message + */ +data class ModelApiResponse( + val code: kotlin.Int? = null, + val type: kotlin.String? = null, + val message: kotlin.String? = null +) + diff --git a/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/models/Order.kt b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/models/Order.kt new file mode 100644 index 00000000000..be802beb8d8 --- /dev/null +++ b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/models/Order.kt @@ -0,0 +1,44 @@ +/** + * 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 + + +/** + * 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( + val id: kotlin.Long? = null, + val petId: kotlin.Long? = null, + val quantity: kotlin.Int? = null, + val shipDate: java.time.OffsetDateTime? = null, + /* Order Status */ + val status: Order.Status? = null, + val complete: kotlin.Boolean? = false +) +{ + /** + * Order Status + * Values: placed,approved,delivered + */ + enum class Status(val value: kotlin.String){ + placed("placed"), + approved("approved"), + delivered("delivered"); + } +} + diff --git a/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/models/Pet.kt b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/models/Pet.kt new file mode 100644 index 00000000000..e5723fedd63 --- /dev/null +++ b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/models/Pet.kt @@ -0,0 +1,46 @@ +/** + * OpenAPI Petstore + * This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. + * + * The version of the OpenAPI document: 1.0.0 + * + * + * 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 + +/** + * 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( + val name: kotlin.String, + val photoUrls: kotlin.collections.List, + val id: kotlin.Long? = null, + val category: Category? = null, + val tags: kotlin.collections.List? = null, + /* pet status in the store */ + val status: Pet.Status? = null +) +{ + /** + * pet status in the store + * Values: available,pending,sold + */ + enum class Status(val value: kotlin.String){ + available("available"), + pending("pending"), + sold("sold"); + } +} + diff --git a/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/models/Tag.kt b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/models/Tag.kt new file mode 100644 index 00000000000..0a975290485 --- /dev/null +++ b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/models/Tag.kt @@ -0,0 +1,24 @@ +/** + * 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 + + +/** + * A tag for a pet + * @param id + * @param name + */ +data class Tag( + val id: kotlin.Long? = null, + val name: kotlin.String? = null +) + diff --git a/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/models/User.kt b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/models/User.kt new file mode 100644 index 00000000000..a4742582f46 --- /dev/null +++ b/samples/server/petstore/kotlin-server/javalin/src/main/kotlin/org/openapitools/server/models/User.kt @@ -0,0 +1,37 @@ +/** + * 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 + + +/** + * 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( + val id: kotlin.Long? = null, + val username: kotlin.String? = null, + val firstName: kotlin.String? = null, + val lastName: kotlin.String? = null, + val email: kotlin.String? = null, + val password: kotlin.String? = null, + val phone: kotlin.String? = null, + /* User Status */ + val userStatus: kotlin.Int? = null +) +