remove kotlin-server-deprecated resource folder (#20328)

This commit is contained in:
William Cheng 2024-12-14 17:02:49 +08:00 committed by GitHub
parent b16144094d
commit cc40f40ead
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 0 additions and 971 deletions

View File

@ -1,82 +0,0 @@
# {{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}}
<a id="documentation-for-api-endpoints"></a>
## Documentation for API Endpoints
All URIs are relative to *{{{basePath}}}*
Class | Method | HTTP request | Description
------------ | ------------- | ------------- | -------------
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}*{{classname}}* | [**{{operationId}}**]({{apiDocPath}}{{classname}}.md#{{operationIdLowerCase}}) | **{{httpMethod}}** {{path}} | {{{summary}}}
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
{{/generateApiDocs}}
{{#generateModelDocs}}
<a id="documentation-for-models"></a>
## Documentation for Models
{{#modelPackage}}
{{#models}}{{#model}} - [{{{modelPackage}}}.{{{classname}}}]({{modelDocPath}}{{{classname}}}.md)
{{/model}}{{/models}}
{{/modelPackage}}
{{^modelPackage}}
No model defined in this package
{{/modelPackage}}
{{/generateModelDocs}}
<a id="documentation-for-authorization"></a>
## Documentation for Authorization
{{^authMethods}}Endpoints do not require authorization.{{/authMethods}}
{{#hasAuthMethods}}Authentication schemes defined for the API:{{/hasAuthMethods}}
{{#authMethods}}
<a id="{{name}}"></a>
### {{name}}
{{#isApiKey}}- **Type**: API key
- **API key parameter name**: {{keyParamName}}
- **Location**: {{#isKeyInQuery}}URL query string{{/isKeyInQuery}}{{#isKeyInHeader}}HTTP header{{/isKeyInHeader}}
{{/isApiKey}}
{{#isBasicBasic}}- **Type**: HTTP basic authentication
{{/isBasicBasic}}
{{#isBasicBearer}}- **Type**: HTTP Bearer Token authentication{{#bearerFormat}} ({{{.}}}){{/bearerFormat}}
{{/isBasicBearer}}
{{#isHttpSignature}}- **Type**: HTTP signature authentication
{{/isHttpSignature}}
{{#isOAuth}}- **Type**: OAuth
- **Flow**: {{flow}}
- **Authorization URL**: {{authorizationUrl}}
- **Scopes**: {{^scopes}}N/A{{/scopes}}
{{#scopes}} - {{scope}}: {{description}}
{{/scopes}}
{{/isOAuth}}
{{/authMethods}}

View File

@ -1,65 +0,0 @@
# {{classname}}{{#description}}
{{.}}{{/description}}
All URIs are relative to *{{basePath}}*
Method | HTTP request | Description
------------- | ------------- | -------------
{{#operations}}{{#operation}}[**{{operationId}}**]({{classname}}.md#{{operationId}}) | **{{httpMethod}}** {{path}} | {{summary}}
{{/operation}}{{/operations}}
{{#operations}}
{{#operation}}
<a id="{{operationId}}"></a>
# **{{operationId}}**
> {{#returnType}}{{.}} {{/returnType}}{{operationId}}({{#allParams}}{{{paramName}}}{{^-last}}, {{/-last}}{{/allParams}})
{{summary}}{{#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}}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}}{{#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}}

View File

@ -1,15 +0,0 @@
# {{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}}
<a id="{{{datatypeWithEnum}}}"></a>{{!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}}

View File

@ -1,52 +0,0 @@
{{#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 {{nameInPascalCase}}(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}}

View File

@ -1,4 +0,0 @@
{{#description}}
/* {{{.}}} */
{{/description}}
{{>modelMutable}} {{{name}}}: {{#isEnum}}{{classname}}.{{nameInPascalCase}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}? = {{{defaultValue}}}{{^defaultValue}}null{{/defaultValue}}

View File

@ -1,4 +0,0 @@
{{#description}}
/* {{{.}}} */
{{/description}}
{{>modelMutable}} {{{name}}}: {{#isEnum}}{{classname}}.{{nameInPascalCase}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}

View File

@ -1,9 +0,0 @@
/**
* {{{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}}
}

View File

@ -1,7 +0,0 @@
# {{classname}}
## Enum
{{#allowableValues}}{{#enumVars}}
* `{{name}}` (value: `{{{value}}}`)
{{/enumVars}}{{/allowableValues}}

View File

@ -1,85 +0,0 @@
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)
}
}

View File

@ -1,145 +0,0 @@
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}}
{{#isBasicBasic}}
basic("{{{name}}}") {
validate { credentials ->
// TODO: "Apply your basic authentication functionality."
// Accessible in-method via call.principal<UserIdPrincipal>()
if (credentials.name == "Swagger" && "Codegen" == credentials.password) {
UserIdPrincipal(credentials.name)
} else {
null
}
}
{{/isBasicBasic}}
{{#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()
}
}

View File

@ -1,114 +0,0 @@
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<String, OAuthServerSettings> = listOf<OAuthServerSettings>(
{{#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)

View File

@ -1,7 +0,0 @@
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"]

View File

@ -1,28 +0,0 @@
{{>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}}
{{#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}}

View File

@ -1,99 +0,0 @@
# {{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}}
<a id="documentation-for-api-endpoints"></a>
## Documentation for API Endpoints
All URIs are relative to *{{{basePath}}}*
Class | Method | HTTP request | Description
------------ | ------------- | ------------- | -------------
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}*{{classname}}* | [**{{operationId}}**]({{apiDocPath}}{{classname}}.md#{{operationIdLowerCase}}) | **{{httpMethod}}** {{path}} | {{{summary}}}
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
{{/generateApiDocs}}
{{#generateModelDocs}}
<a id="documentation-for-models"></a>
## Documentation for Models
{{#modelPackage}}
{{#models}}{{#model}} - [{{{modelPackage}}}.{{{classname}}}]({{modelDocPath}}{{{classname}}}.md)
{{/model}}{{/models}}
{{/modelPackage}}
{{^modelPackage}}
No model defined in this package
{{/modelPackage}}
{{/generateModelDocs}}
<a id="documentation-for-authorization"></a>
## Documentation for Authorization
{{^authMethods}}Endpoints do not require authorization.{{/authMethods}}
{{#hasAuthMethods}}Authentication schemes defined for the API:{{/hasAuthMethods}}
{{#authMethods}}
<a id="{{name}}"></a>
### {{name}}
{{#isApiKey}}- **Type**: API key
- **API key parameter name**: {{keyParamName}}
- **Location**: {{#isKeyInQuery}}URL query string{{/isKeyInQuery}}{{#isKeyInHeader}}HTTP header{{/isKeyInHeader}}
{{/isApiKey}}
{{#isBasicBasic}}- **Type**: HTTP basic authentication
{{/isBasicBasic}}
{{#isBasicBearer}}- **Type**: HTTP Bearer Token authentication{{#bearerFormat}} ({{{.}}}){{/bearerFormat}}
{{/isBasicBearer}}
{{#isHttpSignature}}- **Type**: HTTP signature authentication
{{/isHttpSignature}}
{{#isOAuth}}- **Type**: OAuth
- **Flow**: {{flow}}
- **Authorization URL**: {{authorizationUrl}}
- **Scopes**: {{^scopes}}N/A{{/scopes}}
{{#scopes}} - {{scope}}: {{description}}
{{/scopes}}
{{/isOAuth}}
{{/authMethods}}

View File

@ -1,25 +0,0 @@
{{#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}}

View File

@ -1,11 +0,0 @@
{{#authMethods}}
{{#isBasicBasic}}
val principal = call.authentication.principal<UserIdPrincipal>()
{{/isBasicBasic}}
{{#isApiKey}}
val principal = call.authentication.principal<ApiPrincipal>()
{{/isApiKey}}
{{#isOAuth}}
val principal = call.authentication.principal<OAuthAccessTokenResponse>()
{{/isOAuth}}
{{/authMethods}}

View File

@ -1,8 +0,0 @@
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)
}

View File

@ -1,62 +0,0 @@
{{>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<String, Any?>()
{{#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}}> { _: Paths.{{operationId}} ->
{{#lambda.indented_8}}{{>libraries/ktor/_api_body}}{{/lambda.indented_8}}
}
{{/bodyAllowed}}
{{/operation}}
}
{{/operations}}

View File

@ -1,27 +0,0 @@
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}}
}
}

View File

@ -1,68 +0,0 @@
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'
}

View File

@ -1,11 +0,0 @@
/**
* {{{appName}}}
* {{{appDescription}}}
*
* {{#version}}The version of the OpenAPI document: {{{.}}}{{/version}}
* {{#infoEmail}}Contact: {{{.}}}{{/infoEmail}}
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/

View File

@ -1,15 +0,0 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="trace">
<appender-ref ref="STDOUT"/>
</root>
<logger name="org.eclipse.jetty" level="INFO"/>
<logger name="io.netty" level="INFO"/>
</configuration>

View File

@ -1,11 +0,0 @@
/**
* {{{appName}}}
* {{{appDescription}}}
*
* {{#version}}The version of the OpenAPI document: {{{.}}}{{/version}}
* {{#infoEmail}}Contact: {{{.}}}{{/infoEmail}}
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/

View File

@ -1,11 +0,0 @@
{{>licenseInfo}}
package {{modelPackage}}
{{#imports}}import {{import}}
{{/imports}}
{{#models}}
{{#model}}
{{#isEnum}}{{>enum_class}}{{/isEnum}}{{^isEnum}}{{>data_class}}{{/isEnum}}
{{/model}}
{{/models}}

View File

@ -1 +0,0 @@
{{#modelMutable}}var{{/modelMutable}}{{^modelMutable}}val{{/modelMutable}}

View File

@ -1,3 +0,0 @@
{{#models}}{{#model}}
{{#isEnum}}{{>enum_doc}}{{/isEnum}}{{^isEnum}}{{>class_doc}}{{/isEnum}}
{{/model}}{{/models}}

View File

@ -1 +0,0 @@
rootProject.name = '{{artifactId}}'