From ccbb78e1b2ff46f569df7b49c99231a9ff1ca050 Mon Sep 17 00:00:00 2001 From: Rustam Date: Thu, 29 Apr 2021 02:26:57 +0200 Subject: [PATCH] Keep old Ktor server generator for backward compatibility (#9365) --- .../kotlin-server-ktor-deprecated.yaml | 8 + docs/generators.md | 1 + docs/generators/README.md | 1 + docs/generators/kotlin-server-deprecated.md | 214 ++++++++++++++ .../KotlinServerDeprecatedCodegen.java | 263 ++++++++++++++++++ .../org.openapitools.codegen.CodegenConfig | 1 + .../kotlin-server-deprecated/README.mustache | 84 ++++++ .../kotlin-server-deprecated/api_doc.mustache | 65 +++++ .../class_doc.mustache | 15 + .../data_class.mustache | 52 ++++ .../data_class_opt_var.mustache | 4 + .../data_class_req_var.mustache | 4 + .../enum_class.mustache | 9 + .../enum_doc.mustache | 7 + .../libraries/ktor/ApiKeyAuth.kt.mustache | 85 ++++++ .../libraries/ktor/AppMain.kt.mustache | 145 ++++++++++ .../libraries/ktor/Configuration.kt.mustache | 114 ++++++++ .../libraries/ktor/Dockerfile.mustache | 7 + .../libraries/ktor/Paths.kt.mustache | 28 ++ .../libraries/ktor/README.mustache | 101 +++++++ .../libraries/ktor/_api_body.mustache | 25 ++ .../libraries/ktor/_principal.mustache | 11 + .../libraries/ktor/_response.mustache | 8 + .../libraries/ktor/api.mustache | 62 +++++ .../libraries/ktor/application.conf.mustache | 27 ++ .../libraries/ktor/build.gradle.mustache | 68 +++++ .../libraries/ktor/gradle.properties | 1 + .../libraries/ktor/licenseInfo.mustache | 11 + .../libraries/ktor/logback.xml | 15 + .../licenseInfo.mustache | 11 + .../kotlin-server-deprecated/model.mustache | 11 + .../modelMutable.mustache | 1 + .../model_doc.mustache | 3 + .../settings.gradle.mustache | 1 + .../kotlin/KotlinModelCodegenTest.java | 2 + .../ktor/.openapi-generator-ignore | 23 ++ .../ktor/.openapi-generator/FILES | 20 ++ .../ktor/.openapi-generator/VERSION | 1 + .../kotlin-server-deprecated/ktor/Dockerfile | 7 + .../kotlin-server-deprecated/ktor/README.md | 104 +++++++ .../ktor/build.gradle | 68 +++++ .../ktor/gradle.properties | 1 + .../ktor/settings.gradle | 1 + .../kotlin/org/openapitools/server/AppMain.kt | 91 ++++++ .../org/openapitools/server/Configuration.kt | 82 ++++++ .../kotlin/org/openapitools/server/Paths.kt | 106 +++++++ .../org/openapitools/server/apis/PetApi.kt | 228 +++++++++++++++ .../org/openapitools/server/apis/StoreApi.kt | 99 +++++++ .../org/openapitools/server/apis/UserApi.kt | 107 +++++++ .../server/infrastructure/ApiKeyAuth.kt | 85 ++++++ .../openapitools/server/models/ApiResponse.kt | 32 +++ .../openapitools/server/models/Category.kt | 30 ++ .../org/openapitools/server/models/Order.kt | 48 ++++ .../org/openapitools/server/models/Pet.kt | 50 ++++ .../org/openapitools/server/models/Tag.kt | 30 ++ .../org/openapitools/server/models/User.kt | 43 +++ .../ktor/src/main/resources/application.conf | 23 ++ .../ktor/src/main/resources/logback.xml | 15 + 58 files changed, 2759 insertions(+) create mode 100644 bin/configs/kotlin-server-ktor-deprecated.yaml create mode 100644 docs/generators/kotlin-server-deprecated.md create mode 100644 modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinServerDeprecatedCodegen.java create mode 100644 modules/openapi-generator/src/main/resources/kotlin-server-deprecated/README.mustache create mode 100644 modules/openapi-generator/src/main/resources/kotlin-server-deprecated/api_doc.mustache create mode 100644 modules/openapi-generator/src/main/resources/kotlin-server-deprecated/class_doc.mustache create mode 100644 modules/openapi-generator/src/main/resources/kotlin-server-deprecated/data_class.mustache create mode 100644 modules/openapi-generator/src/main/resources/kotlin-server-deprecated/data_class_opt_var.mustache create mode 100644 modules/openapi-generator/src/main/resources/kotlin-server-deprecated/data_class_req_var.mustache create mode 100644 modules/openapi-generator/src/main/resources/kotlin-server-deprecated/enum_class.mustache create mode 100644 modules/openapi-generator/src/main/resources/kotlin-server-deprecated/enum_doc.mustache create mode 100644 modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/ApiKeyAuth.kt.mustache create mode 100644 modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/AppMain.kt.mustache create mode 100644 modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/Configuration.kt.mustache create mode 100644 modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/Dockerfile.mustache create mode 100644 modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/Paths.kt.mustache create mode 100644 modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/README.mustache create mode 100644 modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/_api_body.mustache create mode 100644 modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/_principal.mustache create mode 100644 modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/_response.mustache create mode 100644 modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/api.mustache create mode 100644 modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/application.conf.mustache create mode 100644 modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/build.gradle.mustache create mode 100644 modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/gradle.properties create mode 100644 modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/licenseInfo.mustache create mode 100644 modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/logback.xml create mode 100644 modules/openapi-generator/src/main/resources/kotlin-server-deprecated/licenseInfo.mustache create mode 100644 modules/openapi-generator/src/main/resources/kotlin-server-deprecated/model.mustache create mode 100644 modules/openapi-generator/src/main/resources/kotlin-server-deprecated/modelMutable.mustache create mode 100644 modules/openapi-generator/src/main/resources/kotlin-server-deprecated/model_doc.mustache create mode 100644 modules/openapi-generator/src/main/resources/kotlin-server-deprecated/settings.gradle.mustache create mode 100644 samples/server/petstore/kotlin-server-deprecated/ktor/.openapi-generator-ignore create mode 100644 samples/server/petstore/kotlin-server-deprecated/ktor/.openapi-generator/FILES create mode 100644 samples/server/petstore/kotlin-server-deprecated/ktor/.openapi-generator/VERSION create mode 100644 samples/server/petstore/kotlin-server-deprecated/ktor/Dockerfile create mode 100644 samples/server/petstore/kotlin-server-deprecated/ktor/README.md create mode 100644 samples/server/petstore/kotlin-server-deprecated/ktor/build.gradle create mode 100644 samples/server/petstore/kotlin-server-deprecated/ktor/gradle.properties create mode 100644 samples/server/petstore/kotlin-server-deprecated/ktor/settings.gradle create mode 100644 samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/AppMain.kt create mode 100644 samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/Configuration.kt create mode 100644 samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/Paths.kt create mode 100644 samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/apis/PetApi.kt create mode 100644 samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt create mode 100644 samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/apis/UserApi.kt create mode 100644 samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/infrastructure/ApiKeyAuth.kt create mode 100644 samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/models/ApiResponse.kt create mode 100644 samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/models/Category.kt create mode 100644 samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/models/Order.kt create mode 100644 samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/models/Pet.kt create mode 100644 samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/models/Tag.kt create mode 100644 samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/models/User.kt create mode 100644 samples/server/petstore/kotlin-server-deprecated/ktor/src/main/resources/application.conf create mode 100644 samples/server/petstore/kotlin-server-deprecated/ktor/src/main/resources/logback.xml diff --git a/bin/configs/kotlin-server-ktor-deprecated.yaml b/bin/configs/kotlin-server-ktor-deprecated.yaml new file mode 100644 index 00000000000..818b279073a --- /dev/null +++ b/bin/configs/kotlin-server-ktor-deprecated.yaml @@ -0,0 +1,8 @@ +generatorName: kotlin-server-deprecated +outputDir: samples/server/petstore/kotlin-server-deprecated/ktor +library: ktor +inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml +templateDir: modules/openapi-generator/src/main/resources/kotlin-server-deprecated +additionalProperties: + hideGenerationTimestamp: "true" + serializableModel: "true" diff --git a/docs/generators.md b/docs/generators.md index 521bdc3dbf0..5dace860f9e 100644 --- a/docs/generators.md +++ b/docs/generators.md @@ -106,6 +106,7 @@ The following generators are available: * [jaxrs-resteasy-eap](generators/jaxrs-resteasy-eap.md) * [jaxrs-spec](generators/jaxrs-spec.md) * [kotlin-server](generators/kotlin-server.md) +* [kotlin-server-deprecated](generators/kotlin-server-deprecated.md) * [kotlin-spring](generators/kotlin-spring.md) * [kotlin-vertx (beta)](generators/kotlin-vertx.md) * [nodejs-express-server (beta)](generators/nodejs-express-server.md) diff --git a/docs/generators/README.md b/docs/generators/README.md index 6510770e47a..a8ac9c9310c 100644 --- a/docs/generators/README.md +++ b/docs/generators/README.md @@ -91,6 +91,7 @@ The following generators are available: * [jaxrs-resteasy-eap](jaxrs-resteasy-eap.md) * [jaxrs-spec](jaxrs-spec.md) * [kotlin-server](kotlin-server.md) +* [kotlin-server-deprecated](kotlin-server-deprecated.md) * [kotlin-spring](kotlin-spring.md) * [kotlin-vertx (beta)](kotlin-vertx.md) * [nodejs-express-server (beta)](nodejs-express-server.md) diff --git a/docs/generators/kotlin-server-deprecated.md b/docs/generators/kotlin-server-deprecated.md new file mode 100644 index 00000000000..5499354747c --- /dev/null +++ b/docs/generators/kotlin-server-deprecated.md @@ -0,0 +1,214 @@ +--- +title: Config Options for kotlin-server-deprecated +sidebar_label: kotlin-server-deprecated +--- + +These options may be applied as additional-properties (cli) or configOptions (plugins). Refer to [configuration docs](https://openapi-generator.tech/docs/configuration) for more details. + +| Option | Description | Values | Default | +| ------ | ----------- | ------ | ------- | +|apiSuffix|suffix for api classes| |Api| +|artifactId|Generated artifact id (name of jar).| |kotlin-server-deprecated| +|artifactVersion|Generated artifact's package version.| |1.0.0| +|enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |camelCase| +|featureAutoHead|Automatically provide responses to HEAD requests for existing routes that have the GET verb defined.| |true| +|featureCORS|Ktor by default provides an interceptor for implementing proper support for Cross-Origin Resource Sharing (CORS). See enable-cors.org.| |false| +|featureCompression|Adds ability to compress outgoing content using gzip, deflate or custom encoder and thus reduce size of the response.| |true| +|featureConditionalHeaders|Avoid sending content if client already has same content, by checking ETag or LastModified properties.| |false| +|featureHSTS|Avoid sending content if client already has same content, by checking ETag or LastModified properties.| |true| +|groupId|Generated artifact package's organization (i.e. maven groupId).| |org.openapitools| +|library|library template (sub-template)|
**ktor**
ktor framework
|ktor| +|modelMutable|Create mutable models| |false| +|packageName|Generated artifact package name.| |org.openapitools.server| +|parcelizeModels|toggle "@Parcelize" for generated models| |null| +|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| + +## IMPORT MAPPING + +| Type/Alias | Imports | +| ---------- | ------- | +|BigDecimal|java.math.BigDecimal| +|Date|java.time.LocalDate| +|DateTime|java.time.OffsetDateTime| +|File|java.io.File| +|LocalDate|java.time.LocalDate| +|LocalDateTime|java.time.LocalDateTime| +|LocalTime|java.time.LocalTime| +|Timestamp|java.sql.Timestamp| +|URI|java.net.URI| +|UUID|java.util.UUID| + + +## INSTANTIATION TYPES + +| Type/Alias | Instantiated By | +| ---------- | --------------- | +|array|kotlin.collections.ArrayList| +|list|kotlin.collections.ArrayList| +|map|kotlin.collections.HashMap| + + +## LANGUAGE PRIMITIVES + + + +## RESERVED WORDS + + + +## FEATURE SET + + +### Client Modification Feature +| Name | Supported | Defined By | +| ---- | --------- | ---------- | +|BasePath|✗|ToolingExtension +|Authorizations|✗|ToolingExtension +|UserAgent|✗|ToolingExtension +|MockServer|✗|ToolingExtension + +### Data Type Feature +| Name | Supported | Defined By | +| ---- | --------- | ---------- | +|Custom|✗|OAS2,OAS3 +|Int32|✓|OAS2,OAS3 +|Int64|✓|OAS2,OAS3 +|Float|✓|OAS2,OAS3 +|Double|✓|OAS2,OAS3 +|Decimal|✓|ToolingExtension +|String|✓|OAS2,OAS3 +|Byte|✓|OAS2,OAS3 +|Binary|✓|OAS2,OAS3 +|Boolean|✓|OAS2,OAS3 +|Date|✓|OAS2,OAS3 +|DateTime|✓|OAS2,OAS3 +|Password|✓|OAS2,OAS3 +|File|✓|OAS2 +|Array|✓|OAS2,OAS3 +|Maps|✓|ToolingExtension +|CollectionFormat|✓|OAS2 +|CollectionFormatMulti|✓|OAS2 +|Enum|✓|OAS2,OAS3 +|ArrayOfEnum|✓|ToolingExtension +|ArrayOfModel|✓|ToolingExtension +|ArrayOfCollectionOfPrimitives|✓|ToolingExtension +|ArrayOfCollectionOfModel|✓|ToolingExtension +|ArrayOfCollectionOfEnum|✓|ToolingExtension +|MapOfEnum|✓|ToolingExtension +|MapOfModel|✓|ToolingExtension +|MapOfCollectionOfPrimitives|✓|ToolingExtension +|MapOfCollectionOfModel|✓|ToolingExtension +|MapOfCollectionOfEnum|✓|ToolingExtension + +### Documentation Feature +| Name | Supported | Defined By | +| ---- | --------- | ---------- | +|Readme|✓|ToolingExtension +|Model|✓|ToolingExtension +|Api|✓|ToolingExtension + +### Global Feature +| Name | Supported | Defined By | +| ---- | --------- | ---------- | +|Host|✓|OAS2,OAS3 +|BasePath|✓|OAS2,OAS3 +|Info|✓|OAS2,OAS3 +|Schemes|✗|OAS2,OAS3 +|PartialSchemes|✓|OAS2,OAS3 +|Consumes|✓|OAS2 +|Produces|✓|OAS2 +|ExternalDocumentation|✓|OAS2,OAS3 +|Examples|✓|OAS2,OAS3 +|XMLStructureDefinitions|✗|OAS2,OAS3 +|MultiServer|✗|OAS3 +|ParameterizedServer|✗|OAS3 +|ParameterStyling|✗|OAS3 +|Callbacks|✗|OAS3 +|LinkObjects|✗|OAS3 + +### Parameter Feature +| Name | Supported | Defined By | +| ---- | --------- | ---------- | +|Path|✓|OAS2,OAS3 +|Query|✓|OAS2,OAS3 +|Header|✓|OAS2,OAS3 +|Body|✓|OAS2 +|FormUnencoded|✓|OAS2 +|FormMultipart|✓|OAS2 +|Cookie|✗|OAS3 + +### Schema Support Feature +| Name | Supported | Defined By | +| ---- | --------- | ---------- | +|Simple|✓|OAS2,OAS3 +|Composite|✓|OAS2,OAS3 +|Polymorphism|✗|OAS2,OAS3 +|Union|✗|OAS3 + +### Security Feature +| Name | Supported | Defined By | +| ---- | --------- | ---------- | +|BasicAuth|✓|OAS2,OAS3 +|ApiKey|✓|OAS2,OAS3 +|OpenIDConnect|✗|OAS3 +|BearerToken|✗|OAS3 +|OAuth2_Implicit|✓|OAS2,OAS3 +|OAuth2_Password|✗|OAS2,OAS3 +|OAuth2_ClientCredentials|✗|OAS2,OAS3 +|OAuth2_AuthorizationCode|✗|OAS2,OAS3 + +### Wire Format Feature +| Name | Supported | Defined By | +| ---- | --------- | ---------- | +|JSON|✓|OAS2,OAS3 +|XML|✓|OAS2,OAS3 +|PROTOBUF|✗|ToolingExtension +|Custom|✗|OAS2,OAS3 diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinServerDeprecatedCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinServerDeprecatedCodegen.java new file mode 100644 index 00000000000..46579134a21 --- /dev/null +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinServerDeprecatedCodegen.java @@ -0,0 +1,263 @@ +/* + * Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech) + * Copyright 2018 SmartBear Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openapitools.codegen.languages; + +import com.google.common.collect.ImmutableMap; +import org.apache.commons.lang3.StringUtils; +import org.openapitools.codegen.CliOption; +import org.openapitools.codegen.CodegenConstants; +import org.openapitools.codegen.CodegenType; +import org.openapitools.codegen.SupportingFile; +import org.openapitools.codegen.meta.features.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.List; +import java.util.Map; + +public class KotlinServerDeprecatedCodegen extends AbstractKotlinCodegen { + + public static final String DEFAULT_LIBRARY = Constants.KTOR; + private final Logger LOGGER = LoggerFactory.getLogger(KotlinServerDeprecatedCodegen.class); + private Boolean autoHeadFeatureEnabled = true; + private Boolean conditionalHeadersFeatureEnabled = false; + private Boolean hstsFeatureEnabled = true; + private Boolean corsFeatureEnabled = false; + private Boolean compressionFeatureEnabled = true; + + // This is here to potentially warn the user when an option is not supported by the target framework. + private Map> optionsSupportedPerFramework = new ImmutableMap.Builder>() + .put(Constants.KTOR, Arrays.asList( + Constants.AUTOMATIC_HEAD_REQUESTS, + Constants.CONDITIONAL_HEADERS, + Constants.HSTS, + Constants.CORS, + Constants.COMPRESSION + )) + .build(); + + /** + * Constructs an instance of `KotlinServerCodegen`. + */ + public KotlinServerDeprecatedCodegen() { + super(); + + modifyFeatureSet(features -> features + .includeDocumentationFeatures(DocumentationFeature.Readme) + .wireFormatFeatures(EnumSet.of(WireFormatFeature.JSON, WireFormatFeature.XML)) + .securityFeatures(EnumSet.of( + SecurityFeature.BasicAuth, + SecurityFeature.ApiKey, + SecurityFeature.OAuth2_Implicit + )) + .excludeGlobalFeatures( + GlobalFeature.XMLStructureDefinitions, + GlobalFeature.Callbacks, + GlobalFeature.LinkObjects, + GlobalFeature.ParameterStyling + ) + .excludeSchemaSupportFeatures( + SchemaSupportFeature.Polymorphism + ) + .excludeParameterFeatures( + ParameterFeature.Cookie + ) + ); + + artifactId = "kotlin-server-deprecated"; + packageName = "org.openapitools.server"; + + // cliOptions default redefinition need to be updated + updateOption(CodegenConstants.ARTIFACT_ID, this.artifactId); + updateOption(CodegenConstants.PACKAGE_NAME, this.packageName); + + outputFolder = "generated-code" + File.separator + "kotlin-server-deprecated"; + modelTemplateFiles.put("model.mustache", ".kt"); + apiTemplateFiles.put("api.mustache", ".kt"); + embeddedTemplateDir = templateDir = "kotlin-server-deprecated"; + apiPackage = packageName + ".apis"; + modelPackage = packageName + ".models"; + + supportedLibraries.put(Constants.KTOR, "ktor framework"); + + // TODO: Configurable server engine. Defaults to netty in build.gradle. + CliOption library = new CliOption(CodegenConstants.LIBRARY, CodegenConstants.LIBRARY_DESC); + library.setDefault(DEFAULT_LIBRARY); + library.setEnum(supportedLibraries); + + cliOptions.add(library); + + addSwitch(Constants.AUTOMATIC_HEAD_REQUESTS, Constants.AUTOMATIC_HEAD_REQUESTS_DESC, getAutoHeadFeatureEnabled()); + addSwitch(Constants.CONDITIONAL_HEADERS, Constants.CONDITIONAL_HEADERS_DESC, getConditionalHeadersFeatureEnabled()); + addSwitch(Constants.HSTS, Constants.HSTS_DESC, getHstsFeatureEnabled()); + addSwitch(Constants.CORS, Constants.CORS_DESC, getCorsFeatureEnabled()); + addSwitch(Constants.COMPRESSION, Constants.COMPRESSION_DESC, getCompressionFeatureEnabled()); + } + + public Boolean getAutoHeadFeatureEnabled() { + return autoHeadFeatureEnabled; + } + + public void setAutoHeadFeatureEnabled(Boolean autoHeadFeatureEnabled) { + this.autoHeadFeatureEnabled = autoHeadFeatureEnabled; + } + + public Boolean getCompressionFeatureEnabled() { + return compressionFeatureEnabled; + } + + public void setCompressionFeatureEnabled(Boolean compressionFeatureEnabled) { + this.compressionFeatureEnabled = compressionFeatureEnabled; + } + + public Boolean getConditionalHeadersFeatureEnabled() { + return conditionalHeadersFeatureEnabled; + } + + public void setConditionalHeadersFeatureEnabled(Boolean conditionalHeadersFeatureEnabled) { + this.conditionalHeadersFeatureEnabled = conditionalHeadersFeatureEnabled; + } + + public Boolean getCorsFeatureEnabled() { + return corsFeatureEnabled; + } + + public void setCorsFeatureEnabled(Boolean corsFeatureEnabled) { + this.corsFeatureEnabled = corsFeatureEnabled; + } + + public String getHelp() { + return "Generates a Kotlin server."; + } + + public Boolean getHstsFeatureEnabled() { + return hstsFeatureEnabled; + } + + public void setHstsFeatureEnabled(Boolean hstsFeatureEnabled) { + this.hstsFeatureEnabled = hstsFeatureEnabled; + } + + public String getName() { + return "kotlin-server-deprecated"; + } + + public CodegenType getTag() { + return CodegenType.SERVER; + } + + @Override + public void processOpts() { + super.processOpts(); + + if (additionalProperties.containsKey(CodegenConstants.LIBRARY)) { + this.setLibrary((String) additionalProperties.get(CodegenConstants.LIBRARY)); + } + + // set default library to "ktor" + if (StringUtils.isEmpty(library)) { + this.setLibrary(DEFAULT_LIBRARY); + additionalProperties.put(CodegenConstants.LIBRARY, DEFAULT_LIBRARY); + LOGGER.info("`library` option is empty. Default to " + DEFAULT_LIBRARY); + } + + if (additionalProperties.containsKey(Constants.AUTOMATIC_HEAD_REQUESTS)) { + setAutoHeadFeatureEnabled(convertPropertyToBooleanAndWriteBack(Constants.AUTOMATIC_HEAD_REQUESTS)); + } else { + additionalProperties.put(Constants.AUTOMATIC_HEAD_REQUESTS, getAutoHeadFeatureEnabled()); + } + + if (additionalProperties.containsKey(Constants.CONDITIONAL_HEADERS)) { + setConditionalHeadersFeatureEnabled(convertPropertyToBooleanAndWriteBack(Constants.CONDITIONAL_HEADERS)); + } else { + additionalProperties.put(Constants.CONDITIONAL_HEADERS, getConditionalHeadersFeatureEnabled()); + } + + if (additionalProperties.containsKey(Constants.HSTS)) { + setHstsFeatureEnabled(convertPropertyToBooleanAndWriteBack(Constants.HSTS)); + } else { + additionalProperties.put(Constants.HSTS, getHstsFeatureEnabled()); + } + + if (additionalProperties.containsKey(Constants.CORS)) { + setCorsFeatureEnabled(convertPropertyToBooleanAndWriteBack(Constants.CORS)); + } else { + additionalProperties.put(Constants.CORS, getCorsFeatureEnabled()); + } + + if (additionalProperties.containsKey(Constants.COMPRESSION)) { + setCompressionFeatureEnabled(convertPropertyToBooleanAndWriteBack(Constants.COMPRESSION)); + } else { + additionalProperties.put(Constants.COMPRESSION, getCompressionFeatureEnabled()); + } + + boolean generateApis = additionalProperties.containsKey(CodegenConstants.GENERATE_APIS) && (Boolean) additionalProperties.get(CodegenConstants.GENERATE_APIS); + String packageFolder = (sourceFolder + File.separator + packageName).replace(".", File.separator); + String resourcesFolder = "src/main/resources"; // not sure this can be user configurable. + + supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")); + 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 (generateApis) { + 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")); + } + + public static class Constants { + public final static String KTOR = "ktor"; + 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"; + public final static String CONDITIONAL_HEADERS_DESC = "Avoid sending content if client already has same content, by checking ETag or LastModified properties."; + public final static String HSTS = "featureHSTS"; + public final static String HSTS_DESC = "Avoid sending content if client already has same content, by checking ETag or LastModified properties."; + public final static String CORS = "featureCORS"; + public final static String CORS_DESC = "Ktor by default provides an interceptor for implementing proper support for Cross-Origin Resource Sharing (CORS). See enable-cors.org."; + public final static String COMPRESSION = "featureCompression"; + public final static String COMPRESSION_DESC = "Adds ability to compress outgoing content using gzip, deflate or custom encoder and thus reduce size of the response."; + } + + @Override + public void postProcess() { + System.out.println("################################################################################"); + System.out.println("# Thanks for using OpenAPI Generator. #"); + System.out.println("# Please consider donation to help us maintain this project \uD83D\uDE4F #"); + System.out.println("# https://opencollective.com/openapi_generator/donate #"); + System.out.println("# #"); + System.out.println("# This generator's contributed by Jim Schubert (https://github.com/jimschubert)#"); + System.out.println("# Please support his work directly via https://patreon.com/jimschubert \uD83D\uDE4F #"); + System.out.println("################################################################################"); + } +} diff --git a/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig b/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig index 87ab2b5e352..4226cade162 100644 --- a/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig +++ b/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig @@ -44,6 +44,7 @@ org.openapitools.codegen.languages.GraphQLNodeJSExpressServerCodegen org.openapitools.codegen.languages.GroovyClientCodegen org.openapitools.codegen.languages.KotlinClientCodegen org.openapitools.codegen.languages.KotlinServerCodegen +org.openapitools.codegen.languages.KotlinServerDeprecatedCodegen org.openapitools.codegen.languages.KotlinSpringServerCodegen org.openapitools.codegen.languages.KotlinVertxServerCodegen org.openapitools.codegen.languages.KtormSchemaCodegen diff --git a/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/README.mustache b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/README.mustache new file mode 100644 index 00000000000..24c4728fdd3 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/README.mustache @@ -0,0 +1,84 @@ +# {{packageName}} - Kotlin Server library for {{appName}} + +## Requires + +* Kotlin 1.1.2 +* Gradle 3.3 + +## 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. + +{{#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}}{{{summary}}}{{/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}} + +{{! TODO: optional documentation for authorization? }} +## Documentation for Authorization + +{{^authMethods}} +All endpoints do not require authorization. +{{/authMethods}} +{{#authMethods}} +{{#last}} +Authentication schemes defined for the API: +{{/last}} +{{/authMethods}} +{{#authMethods}} + +### {{name}} + +{{#isApiKey}}- **Type**: API key +- **API key parameter name**: {{keyParamName}} +- **Location**: {{#isKeyInQuery}}URL query string{{/isKeyInQuery}}{{#isKeyInHeader}}HTTP header{{/isKeyInHeader}} +{{/isApiKey}} +{{#isBasic}}- **Type**: HTTP basic authentication +{{/isBasic}} +{{#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-deprecated/api_doc.mustache b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/api_doc.mustache new file mode 100644 index 00000000000..08d90eef4a2 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/api_doc.mustache @@ -0,0 +1,65 @@ +# {{classname}}{{#description}} +{{description}}{{/description}} + +All URIs are relative to *{{basePath}}* + +Method | HTTP request | Description +------------- | ------------- | ------------- +{{#operations}}{{#operation}}[**{{operationId}}**]({{classname}}.md#{{operationId}}) | **{{httpMethod}}** {{path}} | {{#summary}}{{summary}}{{/summary}} +{{/operation}}{{/operations}} + +{{#operations}} +{{#operation}} + +# **{{operationId}}** +> {{#returnType}}{{returnType}} {{/returnType}}{{operationId}}({{#allParams}}{{{paramName}}}{{^-last}}, {{/-last}}{{/allParams}}) + +{{summary}}{{#notes}} + +{{notes}}{{/notes}} + +### Example +```kotlin +// Import classes: +//import {{{packageName}}}.infrastructure.* +//import {{{modelPackage}}}.* + +{{! TODO: Auth method documentation examples}} +val apiInstance = {{{classname}}}() +{{#allParams}} +val {{{paramName}}} : {{{dataType}}} = {{{example}}} // {{{dataType}}} | {{{description}}} +{{/allParams}} +try { + {{#returnType}}val result : {{{returnType}}} = {{/returnType}}apiInstance.{{{operationId}}}({{#allParams}}{{{paramName}}}{{^-last}}, {{/-last}}{{/allParams}}){{#returnType}} + println(result){{/returnType}} +} catch (e: ClientException) { + println("4xx response calling {{{classname}}}#{{{operationId}}}") + e.printStackTrace() +} catch (e: ServerException) { + println("5xx response calling {{{classname}}}#{{{operationId}}}") + e.printStackTrace() +} +``` + +### Parameters +{{^allParams}}This endpoint does not need any parameter.{{/allParams}}{{#allParams}}{{#-last}} +Name | Type | Description | Notes +------------- | ------------- | ------------- | -------------{{/-last}}{{/allParams}} +{{#allParams}} **{{paramName}}** | {{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}{{#isFile}}**{{dataType}}**{{/isFile}}{{^isFile}}{{#generateModelDocs}}[**{{dataType}}**]({{baseType}}.md){{/generateModelDocs}}{{^generateModelDocs}}**{{dataType}}**{{/generateModelDocs}}{{/isFile}}{{/isPrimitiveType}}| {{description}} |{{^required}} [optional]{{/required}}{{#defaultValue}} [default to {{defaultValue}}]{{/defaultValue}}{{#allowableValues}} [enum: {{#values}}{{{.}}}{{^-last}}, {{/-last}}{{/values}}]{{/allowableValues}} +{{/allParams}} + +### Return type + +{{#returnType}}{{#returnTypeIsPrimitive}}**{{returnType}}**{{/returnTypeIsPrimitive}}{{^returnTypeIsPrimitive}}{{#generateModelDocs}}[**{{returnType}}**]({{returnBaseType}}.md){{/generateModelDocs}}{{^generateModelDocs}}**{{returnType}}**{{/generateModelDocs}}{{/returnTypeIsPrimitive}}{{/returnType}}{{^returnType}}null (empty response body){{/returnType}} + +### Authorization + +{{^authMethods}}No authorization required{{/authMethods}}{{#authMethods}}[{{name}}](../README.md#{{name}}){{^-last}}, {{/-last}}{{/authMethods}} + +### HTTP request headers + + - **Content-Type**: {{#consumes}}{{{mediaType}}}{{^-last}}, {{/-last}}{{/consumes}}{{^consumes}}Not defined{{/consumes}} + - **Accept**: {{#produces}}{{{mediaType}}}{{^-last}}, {{/-last}}{{/produces}}{{^produces}}Not defined{{/produces}} + +{{/operation}} +{{/operations}} diff --git a/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/class_doc.mustache b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/class_doc.mustache new file mode 100644 index 00000000000..a3405b25c84 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/class_doc.mustache @@ -0,0 +1,15 @@ +# {{classname}} + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +{{#vars}}**{{name}}** | {{#isEnum}}[**inline**](#{{datatypeWithEnum}}){{/isEnum}}{{^isEnum}}{{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{dataType}}**]({{complexType}}.md){{/isPrimitiveType}}{{/isEnum}} | {{description}} | {{^required}} [optional]{{/required}}{{#isReadOnly}} [readonly]{{/isReadOnly}} +{{/vars}} +{{#vars}}{{#isEnum}} + +{{!NOTE: see java's resources "pojo_doc.mustache" once enums are fully implemented}} +## Enum: {{baseName}} +Name | Value +---- | -----{{#allowableValues}} +{{name}} | {{#values}}{{.}}{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}} +{{/isEnum}}{{/vars}} diff --git a/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/data_class.mustache b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/data_class.mustache new file mode 100644 index 00000000000..e22559b5cc9 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/data_class.mustache @@ -0,0 +1,52 @@ +{{#parcelizeModels}} +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + +{{/parcelizeModels}} +{{#serializableModel}} +import java.io.Serializable +{{/serializableModel}} +/** + * {{{description}}} +{{#vars}} + * @param {{name}} {{{description}}} +{{/vars}} + */ +{{#parcelizeModels}} +@Parcelize +{{/parcelizeModels}} +data class {{classname}} ( +{{#requiredVars}} +{{>data_class_req_var}}{{^-last}}, +{{/-last}}{{/requiredVars}}{{#hasRequired}}{{#hasOptional}}, +{{/hasOptional}}{{/hasRequired}}{{#optionalVars}}{{>data_class_opt_var}}{{^-last}}, +{{/-last}}{{/optionalVars}} +) {{^serializableModel}}{{#parcelizeModels}} : Parcelable{{/parcelizeModels}}{{/serializableModel}}{{^parcelizeModels}}{{#serializableModel}}: Serializable {{/serializableModel}}{{/parcelizeModels}}{{#parcelizeModels}}{{#serializableModel}} : Parcelable, Serializable {{/serializableModel}}{{/parcelizeModels}} +{{#vendorExtensions.x-has-data-class-body}} +{ +{{/vendorExtensions.x-has-data-class-body}} +{{#serializableModel}} + companion object { + private const val serialVersionUID: Long = 123 + } +{{/serializableModel}} +{{#hasEnums}} + {{#vars}} + {{#isEnum}} + /** + * {{{description}}} + * Values: {{#allowableValues}}{{#enumVars}}{{&name}}{{^-last}},{{/-last}}{{/enumVars}}{{/allowableValues}} + */ + enum class {{nameInCamelCase}}(val value: {{dataType}}){ + {{#allowableValues}} + {{#enumVars}} + {{&name}}({{{value}}}){{^-last}},{{/-last}}{{#-last}};{{/-last}} + {{/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-deprecated/data_class_opt_var.mustache b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/data_class_opt_var.mustache new file mode 100644 index 00000000000..b1060118732 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/data_class_opt_var.mustache @@ -0,0 +1,4 @@ +{{#description}} + /* {{{description}}} */ +{{/description}} + {{>modelMutable}} {{{name}}}: {{#isEnum}}{{classname}}.{{nameInCamelCase}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}? = {{#defaultvalue}}{{defaultvalue}}{{/defaultvalue}}{{^defaultvalue}}null{{/defaultvalue}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/data_class_req_var.mustache b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/data_class_req_var.mustache new file mode 100644 index 00000000000..c79bfec01bd --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/data_class_req_var.mustache @@ -0,0 +1,4 @@ +{{#description}} + /* {{{description}}} */ +{{/description}} + {{>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-deprecated/enum_class.mustache b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/enum_class.mustache new file mode 100644 index 00000000000..791398b9789 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/enum_class.mustache @@ -0,0 +1,9 @@ +/** +* {{{description}}} +* Values: {{#allowableValues}}{{#enumVars}}{{&name}}{{^-last}},{{/-last}}{{/enumVars}}{{/allowableValues}} +*/ +enum class {{classname}}(val value: {{dataType}}){ +{{#allowableValues}}{{#enumVars}} + {{&name}}({{{value}}}){{^-last}},{{/-last}}{{#-last}};{{/-last}} +{{/enumVars}}{{/allowableValues}} +} diff --git a/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/enum_doc.mustache b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/enum_doc.mustache new file mode 100644 index 00000000000..fcb3d7e61aa --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/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-deprecated/libraries/ktor/ApiKeyAuth.kt.mustache b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/ApiKeyAuth.kt.mustache new file mode 100644 index 00000000000..e50c0793be4 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/ApiKeyAuth.kt.mustache @@ -0,0 +1,85 @@ +package {{packageName}}.infrastructure + +import io.ktor.application.ApplicationCall +import io.ktor.application.call +import io.ktor.auth.Authentication +import io.ktor.auth.AuthenticationFailedCause +import io.ktor.auth.AuthenticationPipeline +import io.ktor.auth.AuthenticationProvider +import io.ktor.auth.Credential +import io.ktor.auth.Principal +import io.ktor.auth.UnauthorizedResponse +import io.ktor.http.auth.HeaderValueEncoding +import io.ktor.http.auth.HttpAuthHeader +import io.ktor.request.ApplicationRequest +import io.ktor.response.respond + +enum class ApiKeyLocation(val location: String) { + QUERY("query"), + HEADER("header") +} +data class ApiKeyCredential(val value: String): Credential +data class ApiPrincipal(val apiKeyCredential: ApiKeyCredential?) : Principal + + + +/** +* Represents a Api Key authentication provider +* @param name is the name of the provider, or `null` for a default provider +*/ +class ApiKeyAuthenticationProvider(name: String?) : AuthenticationProvider(name) { + internal var authenticationFunction: suspend ApplicationCall.(ApiKeyCredential) -> Principal? = { null } + + var apiKeyName: String = ""; + + var apiKeyLocation: ApiKeyLocation = ApiKeyLocation.QUERY; + + /** + * Sets a validation function that will check given [ApiKeyCredential] instance and return [Principal], + * or null if credential does not correspond to an authenticated principal + */ + fun validate(body: suspend ApplicationCall.(ApiKeyCredential) -> Principal?) { + authenticationFunction = body + } +} + +fun Authentication.Configuration.apiKeyAuth(name: String? = null, configure: ApiKeyAuthenticationProvider.() -> Unit) { + val provider = ApiKeyAuthenticationProvider(name).apply(configure) + val apiKeyName = provider.apiKeyName + val apiKeyLocation = provider.apiKeyLocation + val authenticate = provider.authenticationFunction + + provider.pipeline.intercept(AuthenticationPipeline.RequestAuthentication) { context -> + val credentials = call.request.apiKeyAuthenticationCredentials(apiKeyName, apiKeyLocation) + val principal = credentials?.let { authenticate(call, it) } + + val cause = when { + credentials == null -> AuthenticationFailedCause.NoCredentials + principal == null -> AuthenticationFailedCause.InvalidCredentials + else -> null + } + + if (cause != null) { + context.challenge(apiKeyName, cause) { + // TODO: Verify correct response structure here. + call.respond(UnauthorizedResponse(HttpAuthHeader.Parameterized("API_KEY", mapOf("key" to apiKeyName), HeaderValueEncoding.QUOTED_ALWAYS))) + it.complete() + } + } + + if (principal != null) { + context.principal(principal) + } + } +} + +fun ApplicationRequest.apiKeyAuthenticationCredentials(apiKeyName: String, apiKeyLocation: ApiKeyLocation): ApiKeyCredential? { + val value: String? = when(apiKeyLocation) { + ApiKeyLocation.QUERY -> this.queryParameters[apiKeyName] + ApiKeyLocation.HEADER -> this.headers[apiKeyName] + } + when (value) { + null -> return null + else -> return ApiKeyCredential(value) + } +} diff --git a/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/AppMain.kt.mustache b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/AppMain.kt.mustache new file mode 100644 index 00000000000..bef736de059 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/AppMain.kt.mustache @@ -0,0 +1,145 @@ +package {{packageName}} + +import com.codahale.metrics.Slf4jReporter +import com.typesafe.config.ConfigFactory +import io.ktor.application.Application +import io.ktor.application.ApplicationStopping +import io.ktor.application.install +import io.ktor.application.log +import io.ktor.client.HttpClient +import io.ktor.client.engine.apache.Apache +import io.ktor.config.HoconApplicationConfig +{{#featureAutoHead}} +import io.ktor.features.AutoHeadResponse +{{/featureAutoHead}} +{{#featureCompression}} +import io.ktor.features.Compression +{{/featureCompression}} +{{#featureCORS}} +import io.ktor.features.CORS +{{/featureCORS}} +{{#featureConditionalHeaders}} +import io.ktor.features.ConditionalHeaders +{{/featureConditionalHeaders}} +import io.ktor.features.ContentNegotiation +import io.ktor.features.DefaultHeaders +{{#featureHSTS}} +import io.ktor.features.HSTS +{{/featureHSTS}} +import io.ktor.gson.GsonConverter +import io.ktor.http.ContentType +import io.ktor.locations.KtorExperimentalLocationsAPI +import io.ktor.locations.Locations +import io.ktor.metrics.Metrics +import io.ktor.routing.Routing +import java.util.concurrent.TimeUnit +import io.ktor.util.KtorExperimentalAPI +{{#hasAuthMethods}} +import io.ktor.auth.Authentication +import io.ktor.auth.oauth +import org.openapitools.server.infrastructure.ApiKeyCredential +import org.openapitools.server.infrastructure.ApiPrincipal +import org.openapitools.server.infrastructure.apiKeyAuth +{{/hasAuthMethods}} +{{#generateApis}}{{#apiInfo}}{{#apis}}import {{apiPackage}}.{{classname}} +{{/apis}}{{/apiInfo}}{{/generateApis}} + +@KtorExperimentalAPI +internal val settings = HoconApplicationConfig(ConfigFactory.defaultApplication(HTTP::class.java.classLoader)) + +object HTTP { + val client = HttpClient(Apache) +} + +@KtorExperimentalAPI +@KtorExperimentalLocationsAPI +fun Application.main() { + install(DefaultHeaders) + install(Metrics) { + val reporter = Slf4jReporter.forRegistry(registry) + .outputTo(log) + .convertRatesTo(TimeUnit.SECONDS) + .convertDurationsTo(TimeUnit.MILLISECONDS) + .build() + reporter.start(10, TimeUnit.SECONDS) + } +{{#generateApis}} + install(ContentNegotiation) { + register(ContentType.Application.Json, GsonConverter()) + } + {{#featureAutoHead}} + install(AutoHeadResponse) // see http://ktor.io/features/autoheadresponse.html + {{/featureAutoHead}} + {{#featureConditionalHeaders}} + install(ConditionalHeaders) // see http://ktor.io/features/conditional-headers.html + {{/featureConditionalHeaders}} + {{#featureHSTS}} + install(HSTS, ApplicationHstsConfiguration()) // see http://ktor.io/features/hsts.html + {{/featureHSTS}} + {{#featureCORS}} + install(CORS, ApplicationCORSConfiguration()) // see http://ktor.io/features/cors.html + {{/featureCORS}} + {{#featureCompression}} + install(Compression, ApplicationCompressionConfiguration()) // see http://ktor.io/features/compression.html + {{/featureCompression}} + install(Locations) // see http://ktor.io/features/locations.html + {{#hasAuthMethods}} + install(Authentication) { + {{#authMethods}} + {{#isBasic}} + basic("{{{name}}}") { + validate { credentials -> + // TODO: "Apply your basic authentication functionality." + // Accessible in-method via call.principal() + if (credentials.name == "Swagger" && "Codegen" == credentials.password) { + UserIdPrincipal(credentials.name) + } else { + null + } + } + {{/isBasic}} + {{#isApiKey}} + // "Implement API key auth ({{{name}}}) for parameter name '{{{keyParamName}}}'." + apiKeyAuth("{{{name}}}") { + validate { apikeyCredential: ApiKeyCredential -> + when { + apikeyCredential.value == "keyboardcat" -> ApiPrincipal(apikeyCredential) + else -> null + } + } + } + {{/isApiKey}} + {{#isOAuth}} + {{#bodyAllowed}} + {{/bodyAllowed}} + {{^bodyAllowed}} + oauth("{{name}}") { + client = HttpClient(Apache) + providerLookup = { ApplicationAuthProviders["{{{name}}}"] } + urlProvider = { _ -> + // TODO: define a callback url here. + "/" + } + } + {{/bodyAllowed}} + {{/isOAuth}} + {{/authMethods}} + } + {{/hasAuthMethods}} + install(Routing) { + {{#apiInfo}} + {{#apis}} + {{#operations}} + {{classname}}() + {{/operations}} + {{/apis}} + {{/apiInfo}} + } + +{{/generateApis}} + + environment.monitor.subscribe(ApplicationStopping) + { + HTTP.client.close() + } +} diff --git a/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/Configuration.kt.mustache b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/Configuration.kt.mustache new file mode 100644 index 00000000000..3b568d21eba --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/Configuration.kt.mustache @@ -0,0 +1,114 @@ +package {{packageName}} + +// Use this file to hold package-level internal functions that return receiver object passed to the `install` method. +import io.ktor.auth.OAuthServerSettings +import io.ktor.features.Compression +import io.ktor.features.HSTS +import io.ktor.features.deflate +import io.ktor.features.gzip +import io.ktor.features.minimumSize +import io.ktor.http.HttpMethod +import io.ktor.util.KtorExperimentalAPI +import java.time.Duration +import java.util.concurrent.Executors + +import {{packageName}}.settings + +{{#featureCORS}} +/** + * Application block for [CORS] configuration. + * + * This file may be excluded in .openapi-generator-ignore, + * and application specific configuration can be applied in this function. + * + * See http://ktor.io/features/cors.html + */ +internal fun ApplicationCORSConfiguration(): CORS.Configuration.() -> Unit { + return { + // method(HttpMethod.Options) + // header(HttpHeaders.XForwardedProto) + // anyHost() + // host("my-host") + // host("my-host:80") + // host("my-host", subDomains = listOf("www")) + // host("my-host", schemes = listOf("http", "https")) + // allowCredentials = true + // maxAge = Duration.ofDays(1) + } +} +{{/featureCORS}} + +{{#featureHSTS}} +/** + * Application block for [HSTS] configuration. + * + * This file may be excluded in .openapi-generator-ignore, + * and application specific configuration can be applied in this function. + * + * See http://ktor.io/features/hsts.html + */ +internal fun ApplicationHstsConfiguration(): HSTS.Configuration.() -> Unit { + return { + maxAge = Duration.ofDays(365) + includeSubDomains = true + preload = false + + // You may also apply any custom directives supported by specific user-agent. For example: + // customDirectives.put("redirectHttpToHttps", "false") + } +} +{{/featureHSTS}} + +{{#featureCompression}} +/** + * Application block for [Compression] configuration. + * + * This file may be excluded in .openapi-generator-ignore, + * and application specific configuration can be applied in this function. + * + * See http://ktor.io/features/compression.html + */ +internal fun ApplicationCompressionConfiguration(): Compression.Configuration.() -> Unit { + return { + gzip { + priority = 1.0 + } + deflate { + priority = 10.0 + minimumSize(1024) // condition + } + } +} +{{/featureCompression}} + +// Defines authentication mechanisms used throughout the application. +@KtorExperimentalAPI +val ApplicationAuthProviders: Map = listOf( +{{#authMethods}} + {{#isOAuth}} + OAuthServerSettings.OAuth2ServerSettings( + name = "{{name}}", + authorizeUrl = "{{authorizationUrl}}", + accessTokenUrl = "{{tokenUrl}}", + requestMethod = HttpMethod.Get, + {{! TODO: flow, doesn't seem to be supported yet by ktor }} + clientId = settings.property("auth.oauth.{{name}}.clientId").getString(), + clientSecret = settings.property("auth.oauth.{{name}}.clientSecret").getString(), + defaultScopes = listOf({{#scopes}}"{{scope}}"{{^-last}}, {{/-last}}{{/scopes}}) + ){{^-last}},{{/-last}} + {{/isOAuth}} +{{/authMethods}} +// OAuthServerSettings.OAuth2ServerSettings( +// name = "facebook", +// authorizeUrl = "https://graph.facebook.com/oauth/authorize", +// accessTokenUrl = "https://graph.facebook.com/oauth/access_token", +// requestMethod = HttpMethod.Post, +// +// clientId = "settings.property("auth.oauth.facebook.clientId").getString()", +// clientSecret = "settings.property("auth.oauth.facebook.clientSecret").getString()", +// defaultScopes = listOf("public_profile") +// ) +).associateBy { it.name } + +// Provides an application-level fixed thread pool on which to execute coroutines (mainly) +internal val ApplicationExecutors = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 4) diff --git a/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/Dockerfile.mustache b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/Dockerfile.mustache new file mode 100644 index 00000000000..b9158ac26e3 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/Dockerfile.mustache @@ -0,0 +1,7 @@ +FROM openjdk:8-jre-alpine + +COPY ./build/libs/{{artifactId}}.jar /root/{{artifactId}}.jar + +WORKDIR /root + +CMD ["java", "-server", "-Xms4g", "-Xmx4g", "-XX:+UseG1GC", "-XX:MaxGCPauseMillis=100", "-XX:+UseStringDeduplication", "-jar", "{{artifactId}}.jar"] \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/Paths.kt.mustache b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/Paths.kt.mustache new file mode 100644 index 00000000000..610f48203aa --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/Paths.kt.mustache @@ -0,0 +1,28 @@ +{{>licenseInfo}} +package {{packageName}} + +import io.ktor.locations.KtorExperimentalLocationsAPI +import io.ktor.locations.Location +{{#imports}}import {{import}} +{{/imports}} + +{{#apiInfo}} +object Paths { +{{#apis}} +{{#operations}} + {{#operation}} + {{^bodyAllowed}} + /** + * {{summary}} + * {{#unescapedNotes}}{{.}}{{/unescapedNotes}} + {{#allParams}}* @param {{paramName}} {{description}} {{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}} + {{/allParams}}*/ + @KtorExperimentalLocationsAPI + @Location("{{path}}") class {{operationId}}({{#allParams}}val {{paramName}}: {{{dataType}}}{{^required}}? = null{{/required}}{{#required}}{{#isNullable}}?{{/isNullable}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}) + + {{/bodyAllowed}} + {{/operation}} +{{/operations}} +{{/apis}} +} +{{/apiInfo}} diff --git a/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/README.mustache b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/README.mustache new file mode 100644 index 00000000000..4c34e8f6bf2 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/README.mustache @@ -0,0 +1,101 @@ +# {{packageName}} - Kotlin Server library for {{appName}} + +{{#unescapedAppDescription}} +{{.}} +{{/unescapedAppDescription}} + +Generated by OpenAPI Generator {{generatorVersion}}{{^hideGenerationTimestamp}} ({{generatedDate}}){{/hideGenerationTimestamp}}. + +## Requires + +* Kotlin 1.3.21 +* Gradle 4.9 + +## 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}}{{{summary}}}{{/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}} + +{{! TODO: optional documentation for authorization? }} +## Documentation for Authorization + +{{^authMethods}} +All endpoints do not require authorization. +{{/authMethods}} +{{#authMethods}} +{{#last}} +Authentication schemes defined for the API: +{{/last}} +{{/authMethods}} +{{#authMethods}} + +### {{name}} + +{{#isApiKey}}- **Type**: API key +- **API key parameter name**: {{keyParamName}} +- **Location**: {{#isKeyInQuery}}URL query string{{/isKeyInQuery}}{{#isKeyInHeader}}HTTP header{{/isKeyInHeader}} +{{/isApiKey}} +{{#isBasic}}- **Type**: HTTP basic authentication +{{/isBasic}} +{{#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-deprecated/libraries/ktor/_api_body.mustache b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/_api_body.mustache new file mode 100644 index 00000000000..9dcf500f49b --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/_api_body.mustache @@ -0,0 +1,25 @@ +{{#hasAuthMethods}} +{{>libraries/ktor/_principal}} +if (principal == null) { + call.respond(HttpStatusCode.Unauthorized) +} else { + {{#examples}} + {{#-first}} + {{#lambda.indented}}{{>_response}}{{/lambda.indented}} + {{/-first}} + {{/examples}} + {{^examples}} + call.respond(HttpStatusCode.NotImplemented) + {{/examples}} +} +{{/hasAuthMethods}} +{{^hasAuthMethods}} +{{#examples}} +{{#-first}} +{{>libraries/ktor/_response}} +{{/-first}} +{{/examples}} +{{^examples}} +call.respond(HttpStatusCode.NotImplemented) +{{/examples}} +{{/hasAuthMethods}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/_principal.mustache b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/_principal.mustache new file mode 100644 index 00000000000..d49c5d537f0 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/_principal.mustache @@ -0,0 +1,11 @@ +{{#authMethods}} +{{#isBasic}} +val principal = call.authentication.principal() +{{/isBasic}} +{{#isApiKey}} +val principal = call.authentication.principal() +{{/isApiKey}} +{{#isOAuth}} +val principal = call.authentication.principal() +{{/isOAuth}} +{{/authMethods}} diff --git a/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/_response.mustache b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/_response.mustache new file mode 100644 index 00000000000..fb26fb4a7f1 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/_response.mustache @@ -0,0 +1,8 @@ +val exampleContentType = "{{{contentType}}}" +val exampleContentString = """{{&example}}""" + +when(exampleContentType) { + "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) + else -> call.respondText(exampleContentString) +} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/api.mustache b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/api.mustache new file mode 100644 index 00000000000..881e3b108ec --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/api.mustache @@ -0,0 +1,62 @@ +{{>licenseInfo}} +package {{apiPackage}} + +import com.google.gson.Gson +import io.ktor.application.call +import io.ktor.auth.UserIdPrincipal +import io.ktor.auth.authentication +import io.ktor.auth.authenticate +import io.ktor.auth.OAuthAccessTokenResponse +import io.ktor.auth.OAuthServerSettings +import io.ktor.http.ContentType +import io.ktor.http.HttpStatusCode +import io.ktor.locations.KtorExperimentalLocationsAPI +import io.ktor.locations.delete +import io.ktor.locations.get +import io.ktor.response.respond +import io.ktor.response.respondText +import io.ktor.routing.Route +import io.ktor.routing.post +import io.ktor.routing.put +import io.ktor.routing.route + +import {{packageName}}.Paths +import {{packageName}}.infrastructure.ApiPrincipal + + +{{#imports}}import {{import}} +{{/imports}} + +{{#operations}} +@KtorExperimentalLocationsAPI +fun Route.{{classname}}() { + val gson = Gson() + val empty = mutableMapOf() +{{#operation}} + {{#bodyAllowed}} + + route("{{path}}") { + {{#hasAuthMethods}} + {{#authMethods}} + authenticate("{{{name}}}") { + {{/authMethods}} + {{/hasAuthMethods}} + {{#lambda.lowercase}}{{httpMethod}}{{/lambda.lowercase}} { + {{#lambda.indented_12}}{{>libraries/ktor/_api_body}}{{/lambda.indented_12}} + } + {{#hasAuthMethods}} + } + {{/hasAuthMethods}} + } + {{/bodyAllowed}} + {{^bodyAllowed}} + + {{! NOTE: Locations can be used on routes without body parameters.}} + {{#lambda.lowercase}}{{httpMethod}}{{/lambda.lowercase}} { _: Paths.{{operationId}} -> + {{#lambda.indented_8}}{{>libraries/ktor/_api_body}}{{/lambda.indented_8}} + } + {{/bodyAllowed}} + +{{/operation}} +} +{{/operations}} diff --git a/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/application.conf.mustache b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/application.conf.mustache new file mode 100644 index 00000000000..032be42fa11 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/application.conf.mustache @@ -0,0 +1,27 @@ +ktor { + deployment { + environment = development + port = 8080 + autoreload = true + watch = [ {{packageName}} ] + } + + application { + modules = [ {{packageName}}.AppMainKt.main ] + } +} + +# Typesafe config allows multiple ways to provide configuration values without hard-coding them here. +# Please see https://github.com/lightbend/config for details. +auth { + oauth { +{{#authMethods}} +{{#isOAuth}} + {{name}} { + clientId = "" + clientSecret = "" + } +{{/isOAuth}} +{{/authMethods}} + } +} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/build.gradle.mustache b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/build.gradle.mustache new file mode 100644 index 00000000000..08c317ea666 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/build.gradle.mustache @@ -0,0 +1,68 @@ +group '{{groupId}}' +version '{{artifactVersion}}' + +wrapper { + gradleVersion = '4.9' + distributionUrl = "https://services.gradle.org/distributions/gradle-$gradleVersion-all.zip" +} + +buildscript { + ext.kotlin_version = '1.3.21' + ext.ktor_version = '1.1.3' + ext.shadow_version = '2.0.3' + + 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" + classpath "com.github.jengelman.gradle.plugins:shadow:$shadow_version" + } +} + +apply plugin: 'java' +apply plugin: 'kotlin' +apply plugin: 'application' + +mainClassName = "io.ktor.server.netty.DevelopmentEngine" + +// Initialization order with shadow 2.0.1 and Gradle 4.3 is weird. +// See https://github.com/johnrengelman/shadow/issues/336#issuecomment-355402508 +apply plugin: 'com.github.johnrengelman.shadow' + +sourceCompatibility = 1.8 + +compileKotlin { + kotlinOptions.jvmTarget = "1.8" +} + +compileTestKotlin { + kotlinOptions.jvmTarget = "1.8" +} + +shadowJar { + baseName = '{{artifactId}}' + classifier = null + version = null +} + +repositories { + maven { url "https://repo1.maven.org/maven2" } + maven { url "https://dl.bintray.com/kotlin/ktor" } + maven { url "https://dl.bintray.com/kotlin/kotlinx" } +} + +dependencies { + compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + compile "io.ktor:ktor-server-netty:$ktor_version" + compile "io.ktor:ktor-metrics:$ktor_version" + compile "io.ktor:ktor-locations:$ktor_version" + compile "io.ktor:ktor-gson:$ktor_version" + compile "io.ktor:ktor-client-core:$ktor_version" + compile "io.ktor:ktor-client-apache:$ktor_version" + compile "ch.qos.logback:logback-classic:1.2.1" + testCompile group: 'junit', name: 'junit', version: '4.13' +} diff --git a/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/gradle.properties b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/gradle.properties new file mode 100644 index 00000000000..5f1ed7bbe02 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/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-deprecated/libraries/ktor/licenseInfo.mustache b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/licenseInfo.mustache new file mode 100644 index 00000000000..3a547de74bb --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/licenseInfo.mustache @@ -0,0 +1,11 @@ +/** +* {{{appName}}} +* {{{appDescription}}} +* +* {{#version}}The version of the OpenAPI document: {{{version}}}{{/version}} +* {{#infoEmail}}Contact: {{{infoEmail}}}{{/infoEmail}} +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/logback.xml b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/logback.xml new file mode 100644 index 00000000000..d0eaba8debd --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/libraries/ktor/logback.xml @@ -0,0 +1,15 @@ + + + + %d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + diff --git a/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/licenseInfo.mustache b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/licenseInfo.mustache new file mode 100644 index 00000000000..3a547de74bb --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/licenseInfo.mustache @@ -0,0 +1,11 @@ +/** +* {{{appName}}} +* {{{appDescription}}} +* +* {{#version}}The version of the OpenAPI document: {{{version}}}{{/version}} +* {{#infoEmail}}Contact: {{{infoEmail}}}{{/infoEmail}} +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/model.mustache b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/model.mustache new file mode 100644 index 00000000000..780dd84b97e --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/model.mustache @@ -0,0 +1,11 @@ +{{>licenseInfo}} +package {{modelPackage}} + +{{#imports}}import {{import}} +{{/imports}} + +{{#models}} +{{#model}} +{{#isEnum}}{{>enum_class}}{{/isEnum}}{{^isEnum}}{{>data_class}}{{/isEnum}} +{{/model}} +{{/models}} diff --git a/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/modelMutable.mustache b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/modelMutable.mustache new file mode 100644 index 00000000000..4c7f3900717 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/modelMutable.mustache @@ -0,0 +1 @@ +{{#modelMutable}}var{{/modelMutable}}{{^modelMutable}}val{{/modelMutable}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/model_doc.mustache b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/model_doc.mustache new file mode 100644 index 00000000000..e3b71842118 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/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-deprecated/settings.gradle.mustache b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/settings.gradle.mustache new file mode 100644 index 00000000000..448dc07602e --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server-deprecated/settings.gradle.mustache @@ -0,0 +1 @@ +rootProject.name = '{{artifactId}}' \ No newline at end of file diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinModelCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinModelCodegenTest.java index 6885057c1c0..19829496e23 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinModelCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinModelCodegenTest.java @@ -9,6 +9,7 @@ import org.openapitools.codegen.DefaultGenerator; import org.openapitools.codegen.languages.AbstractKotlinCodegen; import org.openapitools.codegen.languages.KotlinClientCodegen; import org.openapitools.codegen.languages.KotlinServerCodegen; +import org.openapitools.codegen.languages.KotlinServerDeprecatedCodegen; import org.openapitools.codegen.languages.KotlinSpringServerCodegen; import org.openapitools.codegen.languages.KotlinVertxServerCodegen; import org.testng.annotations.DataProvider; @@ -28,6 +29,7 @@ public class KotlinModelCodegenTest { return new Object[][]{ {new KotlinClientCodegen()}, {new KotlinServerCodegen()}, + {new KotlinServerDeprecatedCodegen()}, {new KotlinSpringServerCodegen()}, {new KotlinVertxServerCodegen()}, }; diff --git a/samples/server/petstore/kotlin-server-deprecated/ktor/.openapi-generator-ignore b/samples/server/petstore/kotlin-server-deprecated/ktor/.openapi-generator-ignore new file mode 100644 index 00000000000..7484ee590a3 --- /dev/null +++ b/samples/server/petstore/kotlin-server-deprecated/ktor/.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-deprecated/ktor/.openapi-generator/FILES b/samples/server/petstore/kotlin-server-deprecated/ktor/.openapi-generator/FILES new file mode 100644 index 00000000000..10c026f11ff --- /dev/null +++ b/samples/server/petstore/kotlin-server-deprecated/ktor/.openapi-generator/FILES @@ -0,0 +1,20 @@ +Dockerfile +README.md +build.gradle +gradle.properties +settings.gradle +src/main/kotlin/org/openapitools/server/AppMain.kt +src/main/kotlin/org/openapitools/server/Configuration.kt +src/main/kotlin/org/openapitools/server/Paths.kt +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/infrastructure/ApiKeyAuth.kt +src/main/kotlin/org/openapitools/server/models/ApiResponse.kt +src/main/kotlin/org/openapitools/server/models/Category.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 +src/main/resources/application.conf +src/main/resources/logback.xml diff --git a/samples/server/petstore/kotlin-server-deprecated/ktor/.openapi-generator/VERSION b/samples/server/petstore/kotlin-server-deprecated/ktor/.openapi-generator/VERSION new file mode 100644 index 00000000000..6555596f931 --- /dev/null +++ b/samples/server/petstore/kotlin-server-deprecated/ktor/.openapi-generator/VERSION @@ -0,0 +1 @@ +5.2.0-SNAPSHOT \ No newline at end of file diff --git a/samples/server/petstore/kotlin-server-deprecated/ktor/Dockerfile b/samples/server/petstore/kotlin-server-deprecated/ktor/Dockerfile new file mode 100644 index 00000000000..5085d63db10 --- /dev/null +++ b/samples/server/petstore/kotlin-server-deprecated/ktor/Dockerfile @@ -0,0 +1,7 @@ +FROM openjdk:8-jre-alpine + +COPY ./build/libs/kotlin-server-deprecated.jar /root/kotlin-server-deprecated.jar + +WORKDIR /root + +CMD ["java", "-server", "-Xms4g", "-Xmx4g", "-XX:+UseG1GC", "-XX:MaxGCPauseMillis=100", "-XX:+UseStringDeduplication", "-jar", "kotlin-server-deprecated.jar"] \ No newline at end of file diff --git a/samples/server/petstore/kotlin-server-deprecated/ktor/README.md b/samples/server/petstore/kotlin-server-deprecated/ktor/README.md new file mode 100644 index 00000000000..12ea4fc5843 --- /dev/null +++ b/samples/server/petstore/kotlin-server-deprecated/ktor/README.md @@ -0,0 +1,104 @@ +# 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 5.2.0-SNAPSHOT. + +## Requires + +* Kotlin 1.3.21 +* Gradle 4.9 + +## 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-deprecated.jar`. + +You may also run in docker: + +``` +docker build -t kotlin-server-deprecated . +docker run -p 8080:8080 kotlin-server-deprecated +``` + +## 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.ApiResponse](docs/ApiResponse.md) + - [org.openapitools.server.models.Category](docs/Category.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-deprecated/ktor/build.gradle b/samples/server/petstore/kotlin-server-deprecated/ktor/build.gradle new file mode 100644 index 00000000000..466d2ca7c39 --- /dev/null +++ b/samples/server/petstore/kotlin-server-deprecated/ktor/build.gradle @@ -0,0 +1,68 @@ +group 'org.openapitools' +version '1.0.0' + +wrapper { + gradleVersion = '4.9' + distributionUrl = "https://services.gradle.org/distributions/gradle-$gradleVersion-all.zip" +} + +buildscript { + ext.kotlin_version = '1.3.21' + ext.ktor_version = '1.1.3' + ext.shadow_version = '2.0.3' + + 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" + classpath "com.github.jengelman.gradle.plugins:shadow:$shadow_version" + } +} + +apply plugin: 'java' +apply plugin: 'kotlin' +apply plugin: 'application' + +mainClassName = "io.ktor.server.netty.DevelopmentEngine" + +// Initialization order with shadow 2.0.1 and Gradle 4.3 is weird. +// See https://github.com/johnrengelman/shadow/issues/336#issuecomment-355402508 +apply plugin: 'com.github.johnrengelman.shadow' + +sourceCompatibility = 1.8 + +compileKotlin { + kotlinOptions.jvmTarget = "1.8" +} + +compileTestKotlin { + kotlinOptions.jvmTarget = "1.8" +} + +shadowJar { + baseName = 'kotlin-server-deprecated' + classifier = null + version = null +} + +repositories { + maven { url "https://repo1.maven.org/maven2" } + maven { url "https://dl.bintray.com/kotlin/ktor" } + maven { url "https://dl.bintray.com/kotlin/kotlinx" } +} + +dependencies { + compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + compile "io.ktor:ktor-server-netty:$ktor_version" + compile "io.ktor:ktor-metrics:$ktor_version" + compile "io.ktor:ktor-locations:$ktor_version" + compile "io.ktor:ktor-gson:$ktor_version" + compile "io.ktor:ktor-client-core:$ktor_version" + compile "io.ktor:ktor-client-apache:$ktor_version" + compile "ch.qos.logback:logback-classic:1.2.1" + testCompile group: 'junit', name: 'junit', version: '4.13' +} diff --git a/samples/server/petstore/kotlin-server-deprecated/ktor/gradle.properties b/samples/server/petstore/kotlin-server-deprecated/ktor/gradle.properties new file mode 100644 index 00000000000..5f1ed7bbe02 --- /dev/null +++ b/samples/server/petstore/kotlin-server-deprecated/ktor/gradle.properties @@ -0,0 +1 @@ +org.gradle.caching=true \ No newline at end of file diff --git a/samples/server/petstore/kotlin-server-deprecated/ktor/settings.gradle b/samples/server/petstore/kotlin-server-deprecated/ktor/settings.gradle new file mode 100644 index 00000000000..84d57dfbffb --- /dev/null +++ b/samples/server/petstore/kotlin-server-deprecated/ktor/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'kotlin-server-deprecated' \ No newline at end of file diff --git a/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/AppMain.kt b/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/AppMain.kt new file mode 100644 index 00000000000..2b0cd5cdb5f --- /dev/null +++ b/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/AppMain.kt @@ -0,0 +1,91 @@ +package org.openapitools.server + +import com.codahale.metrics.Slf4jReporter +import com.typesafe.config.ConfigFactory +import io.ktor.application.Application +import io.ktor.application.ApplicationStopping +import io.ktor.application.install +import io.ktor.application.log +import io.ktor.client.HttpClient +import io.ktor.client.engine.apache.Apache +import io.ktor.config.HoconApplicationConfig +import io.ktor.features.AutoHeadResponse +import io.ktor.features.Compression +import io.ktor.features.ContentNegotiation +import io.ktor.features.DefaultHeaders +import io.ktor.features.HSTS +import io.ktor.gson.GsonConverter +import io.ktor.http.ContentType +import io.ktor.locations.KtorExperimentalLocationsAPI +import io.ktor.locations.Locations +import io.ktor.metrics.Metrics +import io.ktor.routing.Routing +import java.util.concurrent.TimeUnit +import io.ktor.util.KtorExperimentalAPI +import io.ktor.auth.Authentication +import io.ktor.auth.oauth +import org.openapitools.server.infrastructure.ApiKeyCredential +import org.openapitools.server.infrastructure.ApiPrincipal +import org.openapitools.server.infrastructure.apiKeyAuth +import org.openapitools.server.apis.PetApi +import org.openapitools.server.apis.StoreApi +import org.openapitools.server.apis.UserApi + + +@KtorExperimentalAPI +internal val settings = HoconApplicationConfig(ConfigFactory.defaultApplication(HTTP::class.java.classLoader)) + +object HTTP { + val client = HttpClient(Apache) +} + +@KtorExperimentalAPI +@KtorExperimentalLocationsAPI +fun Application.main() { + install(DefaultHeaders) + install(Metrics) { + val reporter = Slf4jReporter.forRegistry(registry) + .outputTo(log) + .convertRatesTo(TimeUnit.SECONDS) + .convertDurationsTo(TimeUnit.MILLISECONDS) + .build() + reporter.start(10, TimeUnit.SECONDS) + } + install(ContentNegotiation) { + register(ContentType.Application.Json, GsonConverter()) + } + install(AutoHeadResponse) // see http://ktor.io/features/autoheadresponse.html + install(HSTS, ApplicationHstsConfiguration()) // see http://ktor.io/features/hsts.html + install(Compression, ApplicationCompressionConfiguration()) // see http://ktor.io/features/compression.html + install(Locations) // see http://ktor.io/features/locations.html + install(Authentication) { + // "Implement API key auth (api_key) for parameter name 'api_key'." + apiKeyAuth("api_key") { + validate { apikeyCredential: ApiKeyCredential -> + when { + apikeyCredential.value == "keyboardcat" -> ApiPrincipal(apikeyCredential) + else -> null + } + } + } + oauth("petstore_auth") { + client = HttpClient(Apache) + providerLookup = { ApplicationAuthProviders["petstore_auth"] } + urlProvider = { _ -> + // TODO: define a callback url here. + "/" + } + } + } + install(Routing) { + PetApi() + StoreApi() + UserApi() + } + + + environment.monitor.subscribe(ApplicationStopping) + { + HTTP.client.close() + } +} diff --git a/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/Configuration.kt b/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/Configuration.kt new file mode 100644 index 00000000000..c16a32ef70f --- /dev/null +++ b/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/Configuration.kt @@ -0,0 +1,82 @@ +package org.openapitools.server + +// Use this file to hold package-level internal functions that return receiver object passed to the `install` method. +import io.ktor.auth.OAuthServerSettings +import io.ktor.features.Compression +import io.ktor.features.HSTS +import io.ktor.features.deflate +import io.ktor.features.gzip +import io.ktor.features.minimumSize +import io.ktor.http.HttpMethod +import io.ktor.util.KtorExperimentalAPI +import java.time.Duration +import java.util.concurrent.Executors + +import org.openapitools.server.settings + + +/** + * Application block for [HSTS] configuration. + * + * This file may be excluded in .openapi-generator-ignore, + * and application specific configuration can be applied in this function. + * + * See http://ktor.io/features/hsts.html + */ +internal fun ApplicationHstsConfiguration(): HSTS.Configuration.() -> Unit { + return { + maxAge = Duration.ofDays(365) + includeSubDomains = true + preload = false + + // You may also apply any custom directives supported by specific user-agent. For example: + // customDirectives.put("redirectHttpToHttps", "false") + } +} + +/** + * Application block for [Compression] configuration. + * + * This file may be excluded in .openapi-generator-ignore, + * and application specific configuration can be applied in this function. + * + * See http://ktor.io/features/compression.html + */ +internal fun ApplicationCompressionConfiguration(): Compression.Configuration.() -> Unit { + return { + gzip { + priority = 1.0 + } + deflate { + priority = 10.0 + minimumSize(1024) // condition + } + } +} + +// Defines authentication mechanisms used throughout the application. +@KtorExperimentalAPI +val ApplicationAuthProviders: Map = listOf( + OAuthServerSettings.OAuth2ServerSettings( + name = "petstore_auth", + authorizeUrl = "http://petstore.swagger.io/api/oauth/dialog", + accessTokenUrl = "", + requestMethod = HttpMethod.Get, + clientId = settings.property("auth.oauth.petstore_auth.clientId").getString(), + clientSecret = settings.property("auth.oauth.petstore_auth.clientSecret").getString(), + defaultScopes = listOf("write:pets", "read:pets") + ) +// OAuthServerSettings.OAuth2ServerSettings( +// name = "facebook", +// authorizeUrl = "https://graph.facebook.com/oauth/authorize", +// accessTokenUrl = "https://graph.facebook.com/oauth/access_token", +// requestMethod = HttpMethod.Post, +// +// clientId = "settings.property("auth.oauth.facebook.clientId").getString()", +// clientSecret = "settings.property("auth.oauth.facebook.clientSecret").getString()", +// defaultScopes = listOf("public_profile") +// ) +).associateBy { it.name } + +// Provides an application-level fixed thread pool on which to execute coroutines (mainly) +internal val ApplicationExecutors = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 4) diff --git a/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/Paths.kt b/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/Paths.kt new file mode 100644 index 00000000000..1983ab78a49 --- /dev/null +++ b/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/Paths.kt @@ -0,0 +1,106 @@ +/** +* 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 + +import io.ktor.locations.KtorExperimentalLocationsAPI +import io.ktor.locations.Location + +object Paths { + /** + * Deletes a pet + * + * @param petId Pet id to delete + * @param apiKey (optional) + */ + @KtorExperimentalLocationsAPI + @Location("/pet/{petId}") class deletePet(val petId: kotlin.Long, val apiKey: kotlin.String? = null) + + /** + * 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 + */ + @KtorExperimentalLocationsAPI + @Location("/pet/findByStatus") class findPetsByStatus(val status: kotlin.Array) + + /** + * 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 + */ + @KtorExperimentalLocationsAPI + @Location("/pet/findByTags") class findPetsByTags(val tags: kotlin.Array) + + /** + * Find pet by ID + * Returns a single pet + * @param petId ID of pet to return + */ + @KtorExperimentalLocationsAPI + @Location("/pet/{petId}") class getPetById(val petId: kotlin.Long) + + /** + * 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 + */ + @KtorExperimentalLocationsAPI + @Location("/store/order/{orderId}") class deleteOrder(val orderId: kotlin.String) + + /** + * Returns pet inventories by status + * Returns a map of status codes to quantities + */ + @KtorExperimentalLocationsAPI + @Location("/store/inventory") class getInventory() + + /** + * Find purchase order by ID + * For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions + * @param orderId ID of pet that needs to be fetched + */ + @KtorExperimentalLocationsAPI + @Location("/store/order/{orderId}") class getOrderById(val orderId: kotlin.Long) + + /** + * Delete user + * This can only be done by the logged in user. + * @param username The name that needs to be deleted + */ + @KtorExperimentalLocationsAPI + @Location("/user/{username}") class deleteUser(val username: kotlin.String) + + /** + * Get user by user name + * + * @param username The name that needs to be fetched. Use user1 for testing. + */ + @KtorExperimentalLocationsAPI + @Location("/user/{username}") class getUserByName(val username: kotlin.String) + + /** + * Logs user into the system + * + * @param username The user name for login + * @param password The password for login in clear text + */ + @KtorExperimentalLocationsAPI + @Location("/user/login") class loginUser(val username: kotlin.String, val password: kotlin.String) + + /** + * Logs out current logged in user session + * + */ + @KtorExperimentalLocationsAPI + @Location("/user/logout") class logoutUser() + +} diff --git a/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/apis/PetApi.kt b/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/apis/PetApi.kt new file mode 100644 index 00000000000..3ac3578638d --- /dev/null +++ b/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/apis/PetApi.kt @@ -0,0 +1,228 @@ +/** +* 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.apis + +import com.google.gson.Gson +import io.ktor.application.call +import io.ktor.auth.UserIdPrincipal +import io.ktor.auth.authentication +import io.ktor.auth.authenticate +import io.ktor.auth.OAuthAccessTokenResponse +import io.ktor.auth.OAuthServerSettings +import io.ktor.http.ContentType +import io.ktor.http.HttpStatusCode +import io.ktor.locations.KtorExperimentalLocationsAPI +import io.ktor.locations.delete +import io.ktor.locations.get +import io.ktor.response.respond +import io.ktor.response.respondText +import io.ktor.routing.Route +import io.ktor.routing.post +import io.ktor.routing.put +import io.ktor.routing.route + +import org.openapitools.server.Paths +import org.openapitools.server.infrastructure.ApiPrincipal + + +import org.openapitools.server.models.ApiResponse +import org.openapitools.server.models.Pet + +@KtorExperimentalLocationsAPI +fun Route.PetApi() { + val gson = Gson() + val empty = mutableMapOf() + + route("/pet") { + authenticate("petstore_auth") { + post { + val principal = call.authentication.principal() + + if (principal == null) { + call.respond(HttpStatusCode.Unauthorized) + } else { + call.respond(HttpStatusCode.NotImplemented) + } + } + } + } + + + delete { _: Paths.deletePet -> + val principal = call.authentication.principal() + + if (principal == null) { + call.respond(HttpStatusCode.Unauthorized) + } else { + call.respond(HttpStatusCode.NotImplemented) + } + } + + + get { _: Paths.findPetsByStatus -> + val principal = call.authentication.principal() + + if (principal == null) { + call.respond(HttpStatusCode.Unauthorized) + } else { + val exampleContentType = "application/json" + val exampleContentString = """{ + "photoUrls" : [ "photoUrls", "photoUrls" ], + "name" : "doggie", + "id" : 0, + "category" : { + "name" : "name", + "id" : 6 + }, + "tags" : [ { + "name" : "name", + "id" : 1 + }, { + "name" : "name", + "id" : 1 + } ], + "status" : "available" + }""" + + when(exampleContentType) { + "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) + else -> call.respondText(exampleContentString) + } + } + } + + + get { _: Paths.findPetsByTags -> + val principal = call.authentication.principal() + + if (principal == null) { + call.respond(HttpStatusCode.Unauthorized) + } else { + val exampleContentType = "application/json" + val exampleContentString = """{ + "photoUrls" : [ "photoUrls", "photoUrls" ], + "name" : "doggie", + "id" : 0, + "category" : { + "name" : "name", + "id" : 6 + }, + "tags" : [ { + "name" : "name", + "id" : 1 + }, { + "name" : "name", + "id" : 1 + } ], + "status" : "available" + }""" + + when(exampleContentType) { + "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) + else -> call.respondText(exampleContentString) + } + } + } + + + get { _: Paths.getPetById -> + val principal = call.authentication.principal() + + if (principal == null) { + call.respond(HttpStatusCode.Unauthorized) + } else { + val exampleContentType = "application/json" + val exampleContentString = """{ + "photoUrls" : [ "photoUrls", "photoUrls" ], + "name" : "doggie", + "id" : 0, + "category" : { + "name" : "name", + "id" : 6 + }, + "tags" : [ { + "name" : "name", + "id" : 1 + }, { + "name" : "name", + "id" : 1 + } ], + "status" : "available" + }""" + + when(exampleContentType) { + "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) + else -> call.respondText(exampleContentString) + } + } + } + + + route("/pet") { + authenticate("petstore_auth") { + put { + val principal = call.authentication.principal() + + if (principal == null) { + call.respond(HttpStatusCode.Unauthorized) + } else { + call.respond(HttpStatusCode.NotImplemented) + } + } + } + } + + + route("/pet/{petId}") { + authenticate("petstore_auth") { + post { + val principal = call.authentication.principal() + + if (principal == null) { + call.respond(HttpStatusCode.Unauthorized) + } else { + call.respond(HttpStatusCode.NotImplemented) + } + } + } + } + + + route("/pet/{petId}/uploadImage") { + authenticate("petstore_auth") { + post { + val principal = call.authentication.principal() + + if (principal == null) { + call.respond(HttpStatusCode.Unauthorized) + } else { + val exampleContentType = "application/json" + val exampleContentString = """{ + "code" : 0, + "type" : "type", + "message" : "message" + }""" + + when(exampleContentType) { + "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) + else -> call.respondText(exampleContentString) + } + } + } + } + } + +} diff --git a/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt b/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt new file mode 100644 index 00000000000..17b2c526bd9 --- /dev/null +++ b/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt @@ -0,0 +1,99 @@ +/** +* 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.apis + +import com.google.gson.Gson +import io.ktor.application.call +import io.ktor.auth.UserIdPrincipal +import io.ktor.auth.authentication +import io.ktor.auth.authenticate +import io.ktor.auth.OAuthAccessTokenResponse +import io.ktor.auth.OAuthServerSettings +import io.ktor.http.ContentType +import io.ktor.http.HttpStatusCode +import io.ktor.locations.KtorExperimentalLocationsAPI +import io.ktor.locations.delete +import io.ktor.locations.get +import io.ktor.response.respond +import io.ktor.response.respondText +import io.ktor.routing.Route +import io.ktor.routing.post +import io.ktor.routing.put +import io.ktor.routing.route + +import org.openapitools.server.Paths +import org.openapitools.server.infrastructure.ApiPrincipal + + +import org.openapitools.server.models.Order + +@KtorExperimentalLocationsAPI +fun Route.StoreApi() { + val gson = Gson() + val empty = mutableMapOf() + + delete { _: Paths.deleteOrder -> + call.respond(HttpStatusCode.NotImplemented) + } + + + get { _: Paths.getInventory -> + val principal = call.authentication.principal() + + if (principal == null) { + call.respond(HttpStatusCode.Unauthorized) + } else { + call.respond(HttpStatusCode.NotImplemented) + } + } + + + get { _: Paths.getOrderById -> + val exampleContentType = "application/json" + val exampleContentString = """{ + "petId" : 6, + "quantity" : 1, + "id" : 0, + "shipDate" : "2000-01-23T04:56:07.000+00:00", + "complete" : false, + "status" : "placed" + }""" + + when(exampleContentType) { + "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) + else -> call.respondText(exampleContentString) + } + } + + + route("/store/order") { + post { + val exampleContentType = "application/json" + val exampleContentString = """{ + "petId" : 6, + "quantity" : 1, + "id" : 0, + "shipDate" : "2000-01-23T04:56:07.000+00:00", + "complete" : false, + "status" : "placed" + }""" + + when(exampleContentType) { + "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) + else -> call.respondText(exampleContentString) + } + } + } + +} diff --git a/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/apis/UserApi.kt b/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/apis/UserApi.kt new file mode 100644 index 00000000000..7fc0b78fa99 --- /dev/null +++ b/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/apis/UserApi.kt @@ -0,0 +1,107 @@ +/** +* 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.apis + +import com.google.gson.Gson +import io.ktor.application.call +import io.ktor.auth.UserIdPrincipal +import io.ktor.auth.authentication +import io.ktor.auth.authenticate +import io.ktor.auth.OAuthAccessTokenResponse +import io.ktor.auth.OAuthServerSettings +import io.ktor.http.ContentType +import io.ktor.http.HttpStatusCode +import io.ktor.locations.KtorExperimentalLocationsAPI +import io.ktor.locations.delete +import io.ktor.locations.get +import io.ktor.response.respond +import io.ktor.response.respondText +import io.ktor.routing.Route +import io.ktor.routing.post +import io.ktor.routing.put +import io.ktor.routing.route + +import org.openapitools.server.Paths +import org.openapitools.server.infrastructure.ApiPrincipal + + +import org.openapitools.server.models.User + +@KtorExperimentalLocationsAPI +fun Route.UserApi() { + val gson = Gson() + val empty = mutableMapOf() + + route("/user") { + post { + call.respond(HttpStatusCode.NotImplemented) + } + } + + + route("/user/createWithArray") { + post { + call.respond(HttpStatusCode.NotImplemented) + } + } + + + route("/user/createWithList") { + post { + call.respond(HttpStatusCode.NotImplemented) + } + } + + + delete { _: Paths.deleteUser -> + call.respond(HttpStatusCode.NotImplemented) + } + + + get { _: Paths.getUserByName -> + val exampleContentType = "application/json" + val exampleContentString = """{ + "firstName" : "firstName", + "lastName" : "lastName", + "password" : "password", + "userStatus" : 6, + "phone" : "phone", + "id" : 0, + "email" : "email", + "username" : "username" + }""" + + when(exampleContentType) { + "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) + else -> call.respondText(exampleContentString) + } + } + + + get { _: Paths.loginUser -> + call.respond(HttpStatusCode.NotImplemented) + } + + + get { _: Paths.logoutUser -> + call.respond(HttpStatusCode.NotImplemented) + } + + + route("/user/{username}") { + put { + call.respond(HttpStatusCode.NotImplemented) + } + } + +} diff --git a/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/infrastructure/ApiKeyAuth.kt b/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/infrastructure/ApiKeyAuth.kt new file mode 100644 index 00000000000..8de972967ef --- /dev/null +++ b/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/infrastructure/ApiKeyAuth.kt @@ -0,0 +1,85 @@ +package org.openapitools.server.infrastructure + +import io.ktor.application.ApplicationCall +import io.ktor.application.call +import io.ktor.auth.Authentication +import io.ktor.auth.AuthenticationFailedCause +import io.ktor.auth.AuthenticationPipeline +import io.ktor.auth.AuthenticationProvider +import io.ktor.auth.Credential +import io.ktor.auth.Principal +import io.ktor.auth.UnauthorizedResponse +import io.ktor.http.auth.HeaderValueEncoding +import io.ktor.http.auth.HttpAuthHeader +import io.ktor.request.ApplicationRequest +import io.ktor.response.respond + +enum class ApiKeyLocation(val location: String) { + QUERY("query"), + HEADER("header") +} +data class ApiKeyCredential(val value: String): Credential +data class ApiPrincipal(val apiKeyCredential: ApiKeyCredential?) : Principal + + + +/** +* Represents a Api Key authentication provider +* @param name is the name of the provider, or `null` for a default provider +*/ +class ApiKeyAuthenticationProvider(name: String?) : AuthenticationProvider(name) { + internal var authenticationFunction: suspend ApplicationCall.(ApiKeyCredential) -> Principal? = { null } + + var apiKeyName: String = ""; + + var apiKeyLocation: ApiKeyLocation = ApiKeyLocation.QUERY; + + /** + * Sets a validation function that will check given [ApiKeyCredential] instance and return [Principal], + * or null if credential does not correspond to an authenticated principal + */ + fun validate(body: suspend ApplicationCall.(ApiKeyCredential) -> Principal?) { + authenticationFunction = body + } +} + +fun Authentication.Configuration.apiKeyAuth(name: String? = null, configure: ApiKeyAuthenticationProvider.() -> Unit) { + val provider = ApiKeyAuthenticationProvider(name).apply(configure) + val apiKeyName = provider.apiKeyName + val apiKeyLocation = provider.apiKeyLocation + val authenticate = provider.authenticationFunction + + provider.pipeline.intercept(AuthenticationPipeline.RequestAuthentication) { context -> + val credentials = call.request.apiKeyAuthenticationCredentials(apiKeyName, apiKeyLocation) + val principal = credentials?.let { authenticate(call, it) } + + val cause = when { + credentials == null -> AuthenticationFailedCause.NoCredentials + principal == null -> AuthenticationFailedCause.InvalidCredentials + else -> null + } + + if (cause != null) { + context.challenge(apiKeyName, cause) { + // TODO: Verify correct response structure here. + call.respond(UnauthorizedResponse(HttpAuthHeader.Parameterized("API_KEY", mapOf("key" to apiKeyName), HeaderValueEncoding.QUOTED_ALWAYS))) + it.complete() + } + } + + if (principal != null) { + context.principal(principal) + } + } +} + +fun ApplicationRequest.apiKeyAuthenticationCredentials(apiKeyName: String, apiKeyLocation: ApiKeyLocation): ApiKeyCredential? { + val value: String? = when(apiKeyLocation) { + ApiKeyLocation.QUERY -> this.queryParameters[apiKeyName] + ApiKeyLocation.HEADER -> this.headers[apiKeyName] + } + when (value) { + null -> return null + else -> return ApiKeyCredential(value) + } +} diff --git a/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/models/ApiResponse.kt b/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/models/ApiResponse.kt new file mode 100644 index 00000000000..45760790990 --- /dev/null +++ b/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/models/ApiResponse.kt @@ -0,0 +1,32 @@ +/** +* 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 java.io.Serializable +/** + * 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 +) : Serializable +{ + companion object { + private const val serialVersionUID: Long = 123 + } +} + diff --git a/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/models/Category.kt b/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/models/Category.kt new file mode 100644 index 00000000000..ee26d4c76e5 --- /dev/null +++ b/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/models/Category.kt @@ -0,0 +1,30 @@ +/** +* 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 java.io.Serializable +/** + * A category for a pet + * @param id + * @param name + */ +data class Category ( + val id: kotlin.Long? = null, + val name: kotlin.String? = null +) : Serializable +{ + companion object { + private const val serialVersionUID: Long = 123 + } +} + diff --git a/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/models/Order.kt b/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/models/Order.kt new file mode 100644 index 00000000000..7889abe12ee --- /dev/null +++ b/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/models/Order.kt @@ -0,0 +1,48 @@ +/** +* 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 java.io.Serializable +/** + * 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? = null +) : Serializable +{ + companion object { + private const val serialVersionUID: Long = 123 + } + /** + * 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-deprecated/ktor/src/main/kotlin/org/openapitools/server/models/Pet.kt b/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/models/Pet.kt new file mode 100644 index 00000000000..8dc13b7ea6e --- /dev/null +++ b/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/models/Pet.kt @@ -0,0 +1,50 @@ +/** +* 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 java.io.Serializable +/** + * 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.Array, + val id: kotlin.Long? = null, + val category: Category? = null, + val tags: kotlin.Array? = null, + /* pet status in the store */ + val status: Pet.Status? = null +) : Serializable +{ + companion object { + private const val serialVersionUID: Long = 123 + } + /** + * 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-deprecated/ktor/src/main/kotlin/org/openapitools/server/models/Tag.kt b/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/models/Tag.kt new file mode 100644 index 00000000000..49c2887a503 --- /dev/null +++ b/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/models/Tag.kt @@ -0,0 +1,30 @@ +/** +* 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 java.io.Serializable +/** + * A tag for a pet + * @param id + * @param name + */ +data class Tag ( + val id: kotlin.Long? = null, + val name: kotlin.String? = null +) : Serializable +{ + companion object { + private const val serialVersionUID: Long = 123 + } +} + diff --git a/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/models/User.kt b/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/models/User.kt new file mode 100644 index 00000000000..dee8de740bd --- /dev/null +++ b/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/kotlin/org/openapitools/server/models/User.kt @@ -0,0 +1,43 @@ +/** +* 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 java.io.Serializable +/** + * 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 +) : Serializable +{ + companion object { + private const val serialVersionUID: Long = 123 + } +} + diff --git a/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/resources/application.conf b/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/resources/application.conf new file mode 100644 index 00000000000..d33fe93f993 --- /dev/null +++ b/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/resources/application.conf @@ -0,0 +1,23 @@ +ktor { + deployment { + environment = development + port = 8080 + autoreload = true + watch = [ org.openapitools.server ] + } + + application { + modules = [ org.openapitools.server.AppMainKt.main ] + } +} + +# Typesafe config allows multiple ways to provide configuration values without hard-coding them here. +# Please see https://github.com/lightbend/config for details. +auth { + oauth { + petstore_auth { + clientId = "" + clientSecret = "" + } + } +} \ No newline at end of file diff --git a/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/resources/logback.xml b/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/resources/logback.xml new file mode 100644 index 00000000000..d0eaba8debd --- /dev/null +++ b/samples/server/petstore/kotlin-server-deprecated/ktor/src/main/resources/logback.xml @@ -0,0 +1,15 @@ + + + + %d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + +