[Kotlin][server] Add kotlin-vertx-server (#3031)

* add kotlin-vertx

* add kotlin-vertx

* update kotlin server

* update

* move Fsharp... in Config

* replace java model to kotlin model. delete useless code

* add kotlin-vertx readme.md

* add kotlin-vertx

* add model null safety

* change to vert.x offical web api

* fix date and datetime missing

* fix fileupload
This commit is contained in:
Wooyme 2019-09-14 20:57:53 +08:00 committed by William Cheng
parent 8f43373948
commit 87dce1bfe1
21 changed files with 826 additions and 1 deletions

View File

@ -0,0 +1,31 @@
#!/bin/sh
SCRIPT="$0"
while [ -h "$SCRIPT" ] ; do
ls=$(ls -ld "$SCRIPT")
link=$(expr "$ls" : '.*-> \(.*\)$')
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=$(dirname "$SCRIPT")/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=$(dirname "$SCRIPT")/..
APP_DIR=$(cd "${APP_DIR}"; pwd)
fi
executable="./modules/openapi-generator-cli/target/openapi-generator-cli.jar"
if [ ! -f "$executable" ]
then
mvn clean package
fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ generate -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g kotlin-vertx -o samples/server/petstore/kotlin/vertx"
java ${JAVA_OPTS} -jar ${executable} ${ags}

View File

@ -0,0 +1,10 @@
set executable=.\modules\openapi-generator-cli\target\openapi-generator-cli.jar
If Not Exist %executable% (
mvn clean package
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M -DloggerPath=conf/log4j.properties
set ags=generate --artifact-id "kotlin-vertx-petstore-server" -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -g kotlin-vertx -o samples\server\petstore\kotlin\vertx
java %JAVA_OPTS% -jar %executable% %ags%

View File

@ -95,6 +95,7 @@ The following generators are available:
* [jaxrs-spec](generators/jaxrs-spec)
* [kotlin-server](generators/kotlin-server)
* [kotlin-spring](generators/kotlin-spring)
* [korlin-vertx](generators/kotlin-vertx)
* [nodejs-express-server (beta)](generators/nodejs-express-server)
* [nodejs-server-deprecated (deprecated)](generators/nodejs-server-deprecated)
* [php-laravel](generators/php-laravel)

View File

@ -0,0 +1,18 @@
---
id: generator-opts-server-kotlin-vertx
title: Config Options for kotlin-vertx
sidebar_label: kotlin-vertx
---
| Option | Description | Values | Default |
| ------ | ----------- | ------ | ------- |
|sourceFolder|source folder for generated code| |src/main/kotlin|
|modelPackage|package for generated models| |org.openapitools.server.api.model|
|apiPackage|package for generated api classes| |org.openapitools.server.api.verticle|
|apiSuffix|suffix for api classes| |Api|
|groupId|Generated artifact package's organization (i.e. maven groupId).| |org.openapitools|
|artifactId|Generated artifact id (name of jar).| |kotlin-server|
|artifactVersion|Generated artifact's package version.| |1.0.0|
|enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |camelCase|
|parcelizeModels|toggle "@Parcelize" for generated models| |null|

View File

@ -0,0 +1,85 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* 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
*
* http://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 org.openapitools.codegen.CodegenConstants;
import org.openapitools.codegen.CodegenType;
import org.openapitools.codegen.SupportingFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.Locale;
public class KotlinVertxServerCodegen extends AbstractKotlinCodegen {
protected String rootPackage = "org.openapitools.server.api";
protected String apiVersion = "1.0.0-SNAPSHOT";
public static final String ROOT_PACKAGE = "rootPackage";
public static final String PROJECT_NAME = "projectName";
static Logger LOGGER = LoggerFactory.getLogger(KotlinVertxServerCodegen.class);
public CodegenType getTag() {
return CodegenType.SERVER;
}
public String getName() {
return "kotlin-vertx";
}
public String getHelp() {
return "Generates a kotlin-vertx server.";
}
public KotlinVertxServerCodegen() {
super();
outputFolder = "generated-code" + File.separator + "kotlin-vertx";
modelTemplateFiles.put("model.mustache", ".kt");
apiTestTemplateFiles.clear();
modelDocTemplateFiles.clear();
supportingFiles.clear();
apiTemplateFiles.clear();
apiTemplateFiles.put("api.mustache", ".kt");
apiTemplateFiles.put("apiProxy.mustache", "VertxProxyHandler.kt");
apiTemplateFiles.put("api_verticle.mustache","Verticle.kt");
embeddedTemplateDir = templateDir = "kotlin-vertx-server";
apiPackage = rootPackage + ".verticle";
modelPackage = rootPackage + ".model";
artifactId = "openapi-kotlin-vertx-server";
artifactVersion = apiVersion;
updateOption(CodegenConstants.API_PACKAGE, apiPackage);
updateOption(CodegenConstants.MODEL_PACKAGE, modelPackage);
additionalProperties.put(ROOT_PACKAGE, rootPackage);
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
}
@Override
public String escapeReservedWord(String name) {
return name;
}
}

View File

@ -28,6 +28,7 @@ org.openapitools.codegen.languages.ErlangClientCodegen
org.openapitools.codegen.languages.ErlangProperCodegen
org.openapitools.codegen.languages.ErlangServerCodegen
org.openapitools.codegen.languages.FlashClientCodegen
org.openapitools.codegen.languages.FsharpGiraffeServerCodegen
org.openapitools.codegen.languages.GoClientCodegen
org.openapitools.codegen.languages.GoClientExperimentalCodegen
org.openapitools.codegen.languages.GoServerCodegen
@ -38,6 +39,7 @@ org.openapitools.codegen.languages.GroovyClientCodegen
org.openapitools.codegen.languages.KotlinClientCodegen
org.openapitools.codegen.languages.KotlinServerCodegen
org.openapitools.codegen.languages.KotlinSpringServerCodegen
org.openapitools.codegen.languages.KotlinVertxServerCodegen
org.openapitools.codegen.languages.HaskellHttpClientCodegen
org.openapitools.codegen.languages.HaskellServantCodegen
org.openapitools.codegen.languages.JavaClientCodegen
@ -114,5 +116,4 @@ org.openapitools.codegen.languages.TypeScriptJqueryClientCodegen
org.openapitools.codegen.languages.TypeScriptNodeClientCodegen
org.openapitools.codegen.languages.TypeScriptRxjsClientCodegen
org.openapitools.codegen.languages.FsharpGiraffeServerCodegen
org.openapitools.codegen.languages.AsciidocDocumentationCodegen

View File

@ -0,0 +1,76 @@
# {{packageName}} - Kotlin Server library for {{appName}}
## Requires
* Kotlin 1.3.10
* Maven 3.3
## Build
```
mvn clean package
```
This runs all tests and packages the library.
## Features/Implementation Notes
* Supports JSON inputs/outputs 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 name="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}}{{{summary}}}{{/summary}}
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
{{/generateApiDocs}}
{{#generateModelDocs}}
<a name="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 name="documentation-for-authorization"></a>{{! 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}}
<a name="{{name}}"></a>
### {{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}}

View File

@ -0,0 +1,53 @@
package {{package}}
{{#imports}}import {{import}}
{{/imports}}
import io.vertx.core.Vertx
import io.vertx.core.json.JsonObject
import io.vertx.core.json.JsonArray
import com.github.wooyme.openapi.Response
import io.vertx.ext.web.api.OperationRequest
import io.vertx.kotlin.ext.web.api.contract.openapi3.OpenAPI3RouterFactory
import io.vertx.serviceproxy.ServiceBinder
import io.vertx.ext.web.handler.CookieHandler
import io.vertx.ext.web.handler.SessionHandler
import io.vertx.ext.web.sstore.LocalSessionStore
import java.util.List
import java.util.Map
interface {{classname}} {
fun init(vertx:Vertx,config:JsonObject)
{{#operations}}
{{#operation}}
/* {{operationId}}
* {{summary}} */
suspend fun {{operationId}}({{#allParams}}{{paramName}}:{{^isFile}}{{{dataType}}}{{/isFile}}{{#isFile}}kotlin.collections.List<java.io.File>{{/isFile}}{{^isRequired}}?{{/isRequired}},{{/allParams}}context:OperationRequest):Response<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}>
{{/operation}}
{{/operations}}
companion object {
const val address = "{{classname}}-service"
suspend fun createRouterFactory(vertx: Vertx,path:String): io.vertx.ext.web.api.contract.openapi3.OpenAPI3RouterFactory {
val routerFactory = OpenAPI3RouterFactory.createAwait(vertx,path)
routerFactory.addGlobalHandler(CookieHandler.create())
routerFactory.addGlobalHandler(SessionHandler.create(LocalSessionStore.create(vertx)))
routerFactory.setExtraOperationContextPayloadMapper{
JsonObject().put("files",JsonArray(it.fileUploads().map { it.uploadedFileName() }))
}
val opf = routerFactory::class.java.getDeclaredField("operations")
opf.isAccessible = true
val operations = opf.get(routerFactory) as Map<String, Any>
for (m in {{classname}}::class.java.methods) {
val methodName = m.name
val op = operations[methodName]
if (op != null) {
val method = op::class.java.getDeclaredMethod("mountRouteToService",String::class.java,String::class.java)
method.isAccessible = true
method.invoke(op,address,methodName)
}
}
routerFactory.mountServiceInterface({{classname}}::class.java, address)
return routerFactory
}
}
}

View File

@ -0,0 +1,179 @@
package {{package}}
import io.vertx.core.Vertx
import io.vertx.core.eventbus.Message
import io.vertx.core.json.JsonObject
import io.vertx.ext.web.api.OperationRequest
import io.vertx.ext.web.api.OperationResponse
import io.vertx.ext.web.api.generator.ApiHandlerUtils
import io.vertx.serviceproxy.ProxyHandler
import io.vertx.serviceproxy.ServiceException
import io.vertx.serviceproxy.ServiceExceptionMessageCodec
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import io.vertx.kotlin.coroutines.dispatcher
import io.vertx.core.json.Json
import io.vertx.core.json.JsonArray
import com.google.gson.reflect.TypeToken
import com.google.gson.Gson
{{#imports}}import {{import}}
{{/imports}}
class {{classname}}VertxProxyHandler(private val vertx: Vertx, private val service: {{classname}}, topLevel: Boolean, private val timeoutSeconds: Long) : ProxyHandler() {
private val timerID: Long
private var lastAccessed: Long = 0
init {
try {
this.vertx.eventBus().registerDefaultCodec(ServiceException::class.java,
ServiceExceptionMessageCodec())
} catch (ex: IllegalStateException) {}
if (timeoutSeconds != (-1).toLong() && !topLevel) {
var period = timeoutSeconds * 1000 / 2
if (period > 10000) {
period = 10000
}
this.timerID = vertx.setPeriodic(period) { this.checkTimedOut(it) }
} else {
this.timerID = -1
}
accessed()
}
private fun checkTimedOut(id: Long) {
val now = System.nanoTime()
if (now - lastAccessed > timeoutSeconds * 1000000000) {
close()
}
}
override fun close() {
if (timerID != (-1).toLong()) {
vertx.cancelTimer(timerID)
}
super.close()
}
private fun accessed() {
this.lastAccessed = System.nanoTime()
}
override fun handle(msg: Message<JsonObject>) {
try {
val json = msg.body()
val action = msg.headers().get("action") ?: throw IllegalStateException("action not specified")
accessed()
val contextSerialized = json.getJsonObject("context") ?: throw IllegalStateException("Received action $action without OperationRequest \"context\"")
val context = OperationRequest(contextSerialized)
when (action) {
{{#operations}}{{#operation}}
"{{#vendorExtensions}}{{operationId}}{{/vendorExtensions}}" -> {
{{#hasParams}}
val params = context.params
{{#allParams}}
{{#isListContainer}}
val {{paramName}}Param = ApiHandlerUtils.searchJsonArrayInJson(params,"{{#isBodyParam}}body{{/isBodyParam}}{{^isBodyParam}}{{baseName}}{{/isBodyParam}}")
{{#required}}
if({{paramName}}Param == null){
throw IllegalArgumentException("{{paramName}} is required")
}
val {{paramName}}:{{{dataType}}} = Gson().fromJson({{paramName}}Param.encode()
, object : TypeToken<kotlin.collections.List<{{{baseType}}}>>(){}.type)
{{/required}}
{{^required}}
val {{paramName}}:{{{dataType}}}? = if({{paramName}}Param == null) {{#defaultValue}}{{defaultValue}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}
else Gson().fromJson({{paramName}}Param.encode(),
, object : TypeToken<kotlin.collections.List<{{{baseType}}}>>(){}.type)
{{/required}}
{{/isListContainer}}
{{^isListContainer}}
{{#isFile}}
val {{paramName}}Param = context.extra.getJsonArray("files")
{{#required}}
if ({{paramName}}Param == null) {
throw IllegalArgumentException("{{paramName}} is required")
}
val {{paramName}} = {{paramName}}Param.map{ java.io.File(it as String) }
{{/required}}
{{^required}}
val {{paramName}} = {{paramName}}Param?.map{ java.io.File(it as String) }
{{/required}}
{{/isFile}}
{{#isPrimitiveType}}
{{#isString}}
val {{paramName}} = ApiHandlerUtils.searchStringInJson(params,"{{^isBodyParam}}{{baseName}}{{/isBodyParam}}{{#isBodyParam}}body{{/isBodyParam}}")
{{/isString}}
{{#isDate}}
val {{paramName}} = java.time.LocalDate.parse(ApiHandlerUtils.searchStringInJson(params,"{{^isBodyParam}}{{baseName}}{{/isBodyParam}}{{#isBodyParam}}body{{/isBodyParam}}"))
{{/isDate}}
{{#isDateTime}}
val {{paramName}} = java.time.LocalDateTime.parse(ApiHandlerUtils.searchStringInJson(params,"{{^isBodyParam}}{{baseName}}{{/isBodyParam}}{{#isBodyParam}}body{{/isBodyParam}}"))
{{/isDateTime}}
{{#isEmail}}
val {{paramName}} = ApiHandlerUtils.searchStringInJson(params,"{{^isBodyParam}}{{baseName}}{{/isBodyParam}}{{#isBodyParam}}body{{/isBodyParam}}")
{{/isEmail}}
{{#isUuid}}
val {{paramName}} = ApiHandlerUtils.searchStringInJson(params,"{{^isBodyParam}}{{baseName}}{{/isBodyParam}}{{#isBodyParam}}body{{/isBodyParam}}")
{{/isUuid}}
{{#isNumber}}
val {{paramName}} = ApiHandlerUtils.searchDoubleInJson(params,"{{^isBodyParam}}{{baseName}}{{/isBodyParam}}{{#isBodyParam}}body{{/isBodyParam}}")
{{/isNumber}}
{{#isLong}}
val {{paramName}} = ApiHandlerUtils.searchLongInJson(params,"{{^isBodyParam}}{{baseName}}{{/isBodyParam}}{{#isBodyParam}}body{{/isBodyParam}}")
{{/isLong}}
{{#isInteger}}
val {{paramName}} = ApiHandlerUtils.searchIntegerInJson(params,"{{^isBodyParam}}{{baseName}}{{/isBodyParam}}{{#isBodyParam}}body{{/isBodyParam}}")
{{/isInteger}}
{{#isFloat}}
val {{paramName}} = ApiHandlerUtils.searchDoubleInJson(params,"{{^isBodyParam}}{{baseName}}{{/isBodyParam}}{{#isBodyParam}}body{{/isBodyParam}}")?.toFloat()
{{/isFloat}}
{{#isDouble}}
val {{paramName}} = ApiHandlerUtils.searchDoubleInJson(params,"{{^isBodyParam}}{{baseName}}{{/isBodyParam}}{{#isBodyParam}}body{{/isBodyParam}}")
{{/isDouble}}
{{#isBoolean}}
val {{paramName}} = ApiHandlerUtils.searchStringInJson(params,"{{^isBodyParam}}{{baseName}}{{/isBodyParam}}{{#isBodyParam}}body{{/isBodyParam}}")?.toBoolean()
{{/isBoolean}}
{{#isFreeFormObject}}
val {{paramName}} = ApiHandlerUtils.searchJsonObjectInJson(params,"{{^isBodyParam}}{{baseName}}{{/isBodyParam}}{{#isBodyParam}}body{{/isBodyParam}}")
{{/isFreeFormObject}}
{{#required}}
if({{paramName}} == null){
throw IllegalArgumentException("{{paramName}} is required")
}
{{/required}}
{{/isPrimitiveType}}
{{^isPrimitiveType}}
val {{paramName}}Param = ApiHandlerUtils.searchJsonObjectInJson(params,"{{^isBodyParam}}{{baseName}}{{/isBodyParam}}{{#isBodyParam}}body{{/isBodyParam}}")
{{#required}}
if ({{paramName}}Param == null) {
throw IllegalArgumentException("{{paramName}} is required")
}
val {{paramName}} = Gson().fromJson({{paramName}}Param.encode(), {{{dataType}}}::class.java)
{{/required}}
{{^required}}
val {{paramName}} = if({{paramName}}Param ==null) null else Gson().fromJson({{paramName}}Param.encode(), {{{dataType}}}::class.java)
{{/required}}
{{/isPrimitiveType}}
{{/isListContainer}}
{{/allParams}}
GlobalScope.launch(vertx.dispatcher()){
val result = service.{{operationId}}({{#hasParams}}{{#allParams}}{{paramName}},{{/allParams}}{{/hasParams}}context)
{{#isListContainer}}
val payload = JsonArray(Json.encode(result.payload)).toBuffer()
{{/isListContainer}}
{{^isListContainer}}
val payload = JsonObject(Json.encode(result.payload)).toBuffer()
{{/isListContainer}}
val res = OperationResponse(result.statusCode,result.statusMessage,payload,result.headers)
msg.reply(res.toJson())
}.invokeOnCompletion{
it?.let{ throw it }
}
{{/hasParams}}
}
{{/operation}}{{/operations}}
}
}catch (t: Throwable) {
msg.reply(ServiceException(500, t.message))
throw t
}
}
}

View File

@ -0,0 +1,42 @@
# {{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}}
<a name="{{operationId}}"></a>
# **{{operationId}}**
> {{#returnType}}{{returnType}} {{/returnType}}{{operationId}}({{#allParams}}{{{paramName}}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
{{summary}}{{#notes}}
{{notes}}{{/notes}}
### 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}}}{{#hasMore}}, {{/hasMore}}{{/consumes}}{{^consumes}}Not defined{{/consumes}}
- **Accept**: {{#produces}}{{{mediaType}}}{{#hasMore}}, {{/hasMore}}{{/produces}}{{^produces}}Not defined{{/produces}}
{{/operation}}
{{/operations}}

View File

@ -0,0 +1,19 @@
package {{package}}
import io.vertx.core.Vertx
import io.vertx.core.AbstractVerticle
import io.vertx.serviceproxy.ServiceBinder
fun main(){
Vertx.vertx().deployVerticle({{classname}}Verticle())
}
class {{classname}}Verticle:AbstractVerticle() {
override fun start() {
val instance = (javaClass.classLoader.loadClass("{{package}}.{{classname}}Impl").newInstance() as {{classname}})
instance.init(vertx,config())
ServiceBinder(vertx)
.setAddress({{classname}}.address)
.register({{classname}}::class.java,instance)
}
}

View File

@ -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}}{{#readOnly}} [readonly]{{/readOnly}}
{{/vars}}
{{#vars}}{{#isEnum}}
<a name="{{{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

@ -0,0 +1,42 @@
{{#parcelizeModels}}
import android.os.Parcelable
import kotlinx.android.parcel.Parcelize
{{/parcelizeModels}}
import com.google.gson.annotations.SerializedName
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
import com.fasterxml.jackson.annotation.JsonInclude
/**
* {{{description}}}
{{#vars}}
* @param {{name}} {{{description}}}
{{/vars}}
*/
{{#parcelizeModels}}
@Parcelize
{{/parcelizeModels}}
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
data class {{classname}} (
{{#requiredVars}}
{{>data_class_req_var}}{{^-last}},
{{/-last}}{{/requiredVars}}{{#hasRequired}}{{#hasOptional}},
{{/hasOptional}}{{/hasRequired}}{{#optionalVars}}{{>data_class_opt_var}}{{^-last}},
{{/-last}}{{/optionalVars}}
){{#parcelizeModels}} : Parcelable{{/parcelizeModels}} {
{{#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}}
{{#requiredVars}}
var {{{name}}} get() = _{{{name}}} ?: throw IllegalArgumentException("{{{name}}} is required")
set(value){ _{{{name}}} = value }
{{/requiredVars}}
}

View File

@ -0,0 +1,4 @@
{{#description}}
/* {{{description}}} */
{{/description}}
var {{{name}}}: {{#isEnum}}{{classname}}.{{nameInCamelCase}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}? = {{#defaultvalue}}{{defaultvalue}}{{/defaultvalue}}{{^defaultvalue}}null{{/defaultvalue}}

View File

@ -0,0 +1,4 @@
{{#description}}
/* {{{description}}} */
{{/description}}
@SerializedName("{{{name}}}") private var _{{{name}}}: {{#isEnum}}{{classname}}.{{nameInCamelCase}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}?

View File

@ -0,0 +1,17 @@
public enum {{{datatypeWithEnum}}} {
{{#allowableValues}}{{#enumVars}}{{{name}}}({{{value}}}){{^-last}},
{{/-last}}{{#-last}};{{/-last}}{{/enumVars}}{{/allowableValues}}
private String value;
{{{datatypeWithEnum}}}(String value) {
this.value = value;
}
@Override
@JsonValue
public String toString() {
return value;
}
}

View File

@ -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}}
}

View File

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

View File

@ -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.
*/

View File

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

View File

@ -0,0 +1,190 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>{{groupId}}</groupId>
<artifactId>{{artifactId}}</artifactId>
<version>{{artifactVersion}}</version>
<packaging>jar</packaging>
<name>{{appName}}</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<kotlin.version>1.3.10</kotlin.version>
<kotlin.compiler.incremental>true</kotlin.compiler.incremental>
<junit.version>4.12</junit.version>
<vertx.version>3.4.1</vertx.version>
<maven-compiler-plugin.version>3.3</maven-compiler-plugin.version>
<vertx-openapi-router.version>1.0.2</vertx-openapi-router.version>
<maven-shade-plugin.version>2.3</maven-shade-plugin.version>
<jackson-datatype-jsr310.version>2.7.4</jackson-datatype-jsr310.version>
<vertx.version>3.6.0</vertx.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-unit</artifactId>
<version>${vertx.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.wooyme</groupId>
<artifactId>vertx-openapi-router</artifactId>
<version>${vertx-openapi-router.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-coroutines-core</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-core</artifactId>
<version>${vertx.version}</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web</artifactId>
<version>${vertx.version}</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-lang-kotlin</artifactId>
<version>${vertx.version}</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-lang-kotlin-coroutines</artifactId>
<version>${vertx.version}</version>
</dependency>
<dependency>
<groupId>io.swagger.parser.v3</groupId>
<artifactId>swagger-parser</artifactId>
<version>2.0.5</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web-api-contract</artifactId>
<version>${vertx.version}</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-service-proxy</artifactId>
<version>${vertx.version}</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web-api-service</artifactId>
<version>${vertx.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>kotlin-maven-plugin</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<sourceDirs>
<sourceDir>${project.basedir}/src/main/kotlin</sourceDir>
<sourceDir>${project.basedir}/src/main/java</sourceDir>
</sourceDirs>
<jvmTarget>1.8</jvmTarget>
</configuration>
</execution>
<execution>
<id>test-compile</id>
<goals>
<goal>test-compile</goal>
</goals>
<configuration>
<sourceDirs>
<sourceDir>${project.basedir}/src/test/kotlin</sourceDir>
<sourceDir>${project.basedir}/src/test/java</sourceDir>
</sourceDirs>
<jvmTarget>1.8</jvmTarget>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>${maven-shade-plugin.version}</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>{{apiPackage}}.DefaultApiVerticleKt</Main-Class>
</manifestEntries>
</transformer>
</transformers>
<artifactSet />
<outputFile>${project.build.directory}/${project.artifactId}-${project.version}-fat.jar</outputFile>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>