mirror of
https://github.com/OpenAPITools/openapi-generator.git
synced 2025-12-09 08:46:10 +00:00
[KOTLIN] Spring Boot Server Generator (#820)
* Kotlin Spring initial bootstrap * Basic configuration construction for Kotlin Spring * Wired up with comand line client * Initial kotlin spring boot application generated using gradle kotlin-dsl * Added basic support for generating models * Basic controllers generated without endpoints generated * Basic spring boot app generated with models and controllers * Added fix for type mapping in AbstractKotlinCodegen. Originally it was mapping list o kotlin.Array instead of kotlin.collections.List * Fixed return type mapping * Sorted bash springboot petstore generator script * Implemented toVarName in AbstractKotlinCodegen to better handle some edgecases * Checking for reserved words or numerical starting class names in AbstractKotlinCodegen * Implemented toOperationId in AbstractKotlinCodegen * Fixed types that were not correctly being mapped to primitives (byte / arrayOf / mapOf) * Escaping dollar symbols in function names * Added support for outter enum classes * Added basic support for generating services * Removed option for generated config package. Added option to enable/disable generated global exception handler * Added configuration option to generate gradle. Generated maven pom.xml file as default * Fixed up bash scripts for generating test sample code * Added configurable option for Swagger Annotations * Added configurable option for generating service interfaces and service implementations * Added README generation * Enable optional bean validation * Added kotlin spring sample to CircleCI pom.xml * Removed kotlin spring boot from .gitignore * Minor fixes from PR comments for user submission (#1) * Minor fixes from PR comments for user submission * Puts braces around conditional block bodies with one-liner bodies. * Modifies README.mustache to use artifact id and version supplied by user (or default configuration) * Targets templates under resource directory explicitly to prevent the need to rebuild for evaluation of template-only changes. * [kotlin-spring] Remove comments referencing sbt in bash scripts * List of changes based upon code review: * Additional comments around how we set the title based off the open api spec * Fixed missing `beanValidationCore` template * Put the lambdas into the lambda object as other generators do (Ktor, C#, cpp) * Bump swagger-annotations version to latest pre-2.0 version (1.5.21) * Set kotlin version to 1.2.60 * Updated README to set port based on template * Added more additional properties to build bash scripts * Removed `defaultBasePath.mustache` in place of using {{contextPath}} directly * Log warning for when `serviceImplementation` is set t o true * Updated samples * Generating ConstraintViolation Exception Handler, as Springboot doesnt correctly catch the error and return bad request. Handling other exceptions a litle better * Small fix for date time mappings (plus sample re-gen) * Minor fix in README template, where port was using wrong variable * Fix missing jackson-dataformat-xml dependency * Fix build - needed to re-run kotlin-server-petstore.sh * Fixes after merge with master * Revert "Small fix for date time mappings (plus sample re-gen)" This reverts commit 4152dc78b4813da71c675272ca90fb31a333aea1. * Moved type mappings to Kotlin Spring generator * Regenerated samples * Regenerated samples
This commit is contained in:
committed by
William Cheng
parent
5cd5143b80
commit
8689227b3e
4
.gitignore
vendored
4
.gitignore
vendored
@@ -115,14 +115,14 @@ samples/client/petstore/swift/**/SwaggerClientTests/SwaggerClient.xcworkspace/xc
|
|||||||
samples/client/petstore/swift/**/SwaggerClientTests/Pods/
|
samples/client/petstore/swift/**/SwaggerClientTests/Pods/
|
||||||
#samples/client/petstore/swift/**/SwaggerClientTests/Pods/Pods.xcodeproj/xcuserdata
|
#samples/client/petstore/swift/**/SwaggerClientTests/Pods/Pods.xcodeproj/xcuserdata
|
||||||
#samples/client/petstore/swift/**/SwaggerClientTests/Pods/Pods.xcodeproj/xcshareddata/xcschemes
|
#samples/client/petstore/swift/**/SwaggerClientTests/Pods/Pods.xcodeproj/xcshareddata/xcschemes
|
||||||
samples/client/petstore/swift/**/SwaggerClientTests/Podfile.lock
|
samples/client/petstore/swift/**/SwaggerClientTests/Podfile.lock
|
||||||
# Swift3
|
# Swift3
|
||||||
samples/client/petstore/swift3/**/SwaggerClientTests/SwaggerClient.xcodeproj/xcuserdata
|
samples/client/petstore/swift3/**/SwaggerClientTests/SwaggerClient.xcodeproj/xcuserdata
|
||||||
samples/client/petstore/swift3/**/SwaggerClientTests/SwaggerClient.xcworkspace/xcuserdata
|
samples/client/petstore/swift3/**/SwaggerClientTests/SwaggerClient.xcworkspace/xcuserdata
|
||||||
#samples/client/petstore/swift3/**/SwaggerClientTests/Pods/
|
#samples/client/petstore/swift3/**/SwaggerClientTests/Pods/
|
||||||
#samples/client/petstore/swift3/**/SwaggerClientTests/Pods/Pods.xcodeproj/xcuserdata
|
#samples/client/petstore/swift3/**/SwaggerClientTests/Pods/Pods.xcodeproj/xcuserdata
|
||||||
#samples/client/petstore/swift3/**/SwaggerClientTests/Pods/Pods.xcodeproj/xcshareddata/xcschemes
|
#samples/client/petstore/swift3/**/SwaggerClientTests/Pods/Pods.xcodeproj/xcshareddata/xcschemes
|
||||||
samples/client/petstore/swift3/**/SwaggerClientTests/Podfile.lock
|
samples/client/petstore/swift3/**/SwaggerClientTests/Podfile.lock
|
||||||
|
|
||||||
# C#
|
# C#
|
||||||
*.csproj.user
|
*.csproj.user
|
||||||
|
|||||||
@@ -957,6 +957,7 @@
|
|||||||
<module>samples/server/petstore/scala-lagom-server</module>
|
<module>samples/server/petstore/scala-lagom-server</module>
|
||||||
<module>samples/server/petstore/scalatra</module>
|
<module>samples/server/petstore/scalatra</module>
|
||||||
<module>samples/server/petstore/finch</module>
|
<module>samples/server/petstore/finch</module>
|
||||||
|
<module>samples/server/petstore/kotlin-springboot</module>
|
||||||
</modules>
|
</modules>
|
||||||
</profile>
|
</profile>
|
||||||
</profiles>
|
</profiles>
|
||||||
|
|||||||
35
bin/kotlin-springboot-petstore-server.sh
Executable file
35
bin/kotlin-springboot-petstore-server.sh
Executable file
@@ -0,0 +1,35 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
SCRIPT="$0"
|
||||||
|
echo "# START SCRIPT: $SCRIPT"
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
|
||||||
|
ags="$@ generate -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -t modules/openapi-generator/src/main/resources/kotlin-spring -g kotlin-spring -o samples/server/petstore/kotlin-springboot --additional-properties=library=spring-boot,beanValidations=true,swaggerAnnotations=true,serviceImplementation=true"
|
||||||
|
|
||||||
|
echo "Cleaning previously generated files if any from samples/server/petstore/kotlin-springboot"
|
||||||
|
rm -rf samples/server/petstore/kotlin-springboot
|
||||||
|
|
||||||
|
echo "Generating Kotling Spring Boot server..."
|
||||||
|
java $JAVA_OPTS -jar $executable $ags
|
||||||
35
bin/openapi3/kotlin-springboot-petstore-server.sh
Executable file
35
bin/openapi3/kotlin-springboot-petstore-server.sh
Executable file
@@ -0,0 +1,35 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
SCRIPT="$0"
|
||||||
|
echo "# START SCRIPT: $SCRIPT"
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
|
||||||
|
ags="$@ generate -i modules/openapi-generator/src/test/resources/3_0/petstore.yaml -t modules/openapi-generator/src/main/resources/kotlin-spring -g kotlin-spring -o samples/server/openapi3/petstore/kotlin-springboot --additional-properties=library=spring-boot,beanValidations=true,swaggerAnnotations=true,serviceImplementation=true"
|
||||||
|
|
||||||
|
echo "Cleaning previously generated files if any from samples/server/openapi3/petstore/kotlin-springboot"
|
||||||
|
rm -rf samples/server/openapi3/petstore/kotlin-springboot
|
||||||
|
|
||||||
|
echo "Generating Kotling Spring Boot server..."
|
||||||
|
java $JAVA_OPTS -jar $executable $ags
|
||||||
10
bin/windows/kotlin-springboot-petstore-server.bat
Normal file
10
bin/windows/kotlin-springboot-petstore-server.bat
Normal 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
|
||||||
|
set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -g kotlin-spring -o samples\server\petstore\kotlin-springboot --additional-properties=library=spring-boot
|
||||||
|
|
||||||
|
java %JAVA_OPTS% -jar %executable% %ags%
|
||||||
10
bin/windows/openapi3/kotlin-springboot-petstore-server.bat
Normal file
10
bin/windows/openapi3/kotlin-springboot-petstore-server.bat
Normal 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
|
||||||
|
set ags=generate -i modules\openapi-generator\src\test\resources\3_0\petstore.yaml -g kotlin-spring -o samples\server\openapi3\petstore\kotlin-springboot --additional-properties=library=spring-boot
|
||||||
|
|
||||||
|
java %JAVA_OPTS% -jar %executable% %ags%
|
||||||
@@ -19,6 +19,7 @@ package org.openapitools.codegen.languages;
|
|||||||
|
|
||||||
import io.swagger.v3.oas.models.media.ArraySchema;
|
import io.swagger.v3.oas.models.media.ArraySchema;
|
||||||
import io.swagger.v3.oas.models.media.Schema;
|
import io.swagger.v3.oas.models.media.Schema;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.openapitools.codegen.CliOption;
|
import org.openapitools.codegen.CliOption;
|
||||||
import org.openapitools.codegen.CodegenConfig;
|
import org.openapitools.codegen.CodegenConfig;
|
||||||
import org.openapitools.codegen.CodegenConstants;
|
import org.openapitools.codegen.CodegenConstants;
|
||||||
@@ -28,11 +29,7 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Arrays;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public abstract class AbstractKotlinCodegen extends DefaultCodegen implements CodegenConfig {
|
public abstract class AbstractKotlinCodegen extends DefaultCodegen implements CodegenConfig {
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractKotlinCodegen.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractKotlinCodegen.class);
|
||||||
@@ -55,6 +52,7 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
|
|||||||
|
|
||||||
languageSpecificPrimitives = new HashSet<String>(Arrays.asList(
|
languageSpecificPrimitives = new HashSet<String>(Arrays.asList(
|
||||||
"kotlin.Byte",
|
"kotlin.Byte",
|
||||||
|
"kotlin.ByteArray",
|
||||||
"kotlin.Short",
|
"kotlin.Short",
|
||||||
"kotlin.Int",
|
"kotlin.Int",
|
||||||
"kotlin.Long",
|
"kotlin.Long",
|
||||||
@@ -139,6 +137,7 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
|
|||||||
|
|
||||||
defaultIncludes = new HashSet<String>(Arrays.asList(
|
defaultIncludes = new HashSet<String>(Arrays.asList(
|
||||||
"kotlin.Byte",
|
"kotlin.Byte",
|
||||||
|
"kotlin.ByteArray",
|
||||||
"kotlin.Short",
|
"kotlin.Short",
|
||||||
"kotlin.Int",
|
"kotlin.Int",
|
||||||
"kotlin.Long",
|
"kotlin.Long",
|
||||||
@@ -159,21 +158,22 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
|
|||||||
typeMapping.put("float", "kotlin.Float");
|
typeMapping.put("float", "kotlin.Float");
|
||||||
typeMapping.put("long", "kotlin.Long");
|
typeMapping.put("long", "kotlin.Long");
|
||||||
typeMapping.put("double", "kotlin.Double");
|
typeMapping.put("double", "kotlin.Double");
|
||||||
|
typeMapping.put("ByteArray", "kotlin.ByteArray");
|
||||||
typeMapping.put("number", "java.math.BigDecimal");
|
typeMapping.put("number", "java.math.BigDecimal");
|
||||||
typeMapping.put("date-time", "java.time.LocalDateTime");
|
typeMapping.put("date-time", "java.time.LocalDateTime");
|
||||||
typeMapping.put("date", "java.time.LocalDateTime");
|
typeMapping.put("date", "java.time.LocalDateTime");
|
||||||
typeMapping.put("file", "java.io.File");
|
typeMapping.put("file", "java.io.File");
|
||||||
typeMapping.put("array", "kotlin.Array");
|
typeMapping.put("array", "kotlin.Array");
|
||||||
typeMapping.put("list", "kotlin.Array");
|
typeMapping.put("list", "kotlin.collections.List");
|
||||||
typeMapping.put("map", "kotlin.collections.Map");
|
typeMapping.put("map", "kotlin.collections.Map");
|
||||||
typeMapping.put("object", "kotlin.Any");
|
typeMapping.put("object", "kotlin.Any");
|
||||||
typeMapping.put("binary", "kotlin.Array<kotlin.Byte>");
|
typeMapping.put("binary", "kotlin.Array<kotlin.Byte>");
|
||||||
typeMapping.put("Date", "java.time.LocalDateTime");
|
typeMapping.put("Date", "java.time.LocalDateTime");
|
||||||
typeMapping.put("DateTime", "java.time.LocalDateTime");
|
typeMapping.put("DateTime", "java.time.LocalDateTime");
|
||||||
|
|
||||||
instantiationTypes.put("array", "arrayOf");
|
instantiationTypes.put("array", "kotlin.arrayOf");
|
||||||
instantiationTypes.put("list", "arrayOf");
|
instantiationTypes.put("list", "kotlin.arrayOf");
|
||||||
instantiationTypes.put("map", "mapOf");
|
instantiationTypes.put("map", "kotlin.mapOf");
|
||||||
|
|
||||||
importMapping = new HashMap<String, String>();
|
importMapping = new HashMap<String, String>();
|
||||||
importMapping.put("BigDecimal", "java.math.BigDecimal");
|
importMapping.put("BigDecimal", "java.math.BigDecimal");
|
||||||
@@ -473,13 +473,53 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
|
|||||||
// Camelize name of nested properties
|
// Camelize name of nested properties
|
||||||
modifiedName = camelize(modifiedName);
|
modifiedName = camelize(modifiedName);
|
||||||
|
|
||||||
if (reservedWords.contains(modifiedName)) {
|
// model name cannot use reserved keyword, e.g. return
|
||||||
modifiedName = escapeReservedWord(modifiedName);
|
if (isReservedWord(modifiedName)) {
|
||||||
|
final String modelName = "Model" + modifiedName;
|
||||||
|
LOGGER.warn(modifiedName + " (reserved word) cannot be used as model name. Renamed to " + modelName);
|
||||||
|
return modelName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// model name starts with number
|
||||||
|
if (modifiedName.matches("^\\d.*")) {
|
||||||
|
final String modelName = "Model" + modifiedName; // e.g. 200Response => Model200Response (after camelize)
|
||||||
|
LOGGER.warn(name + " (model name starts with number) cannot be used as model name. Renamed to " + modelName);
|
||||||
|
return modelName;
|
||||||
}
|
}
|
||||||
|
|
||||||
return titleCase(modifiedName);
|
return titleCase(modifiedName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the operation ID (method name)
|
||||||
|
*
|
||||||
|
* @param operationId operation ID
|
||||||
|
* @return the sanitized method name
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toOperationId(String operationId) {
|
||||||
|
// throw exception if method name is empty
|
||||||
|
if (StringUtils.isEmpty(operationId))
|
||||||
|
throw new RuntimeException("Empty method/operation name (operationId) not allowed");
|
||||||
|
|
||||||
|
operationId = camelize(sanitizeName(operationId), true);
|
||||||
|
|
||||||
|
// method name cannot use reserved keyword, e.g. return
|
||||||
|
if (isReservedWord(operationId)) {
|
||||||
|
String newOperationId = camelize("call_" + operationId, true);
|
||||||
|
LOGGER.warn(operationId + " (reserved word) cannot be used as method name. Renamed to " + newOperationId);
|
||||||
|
return newOperationId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// operationId starts with a number
|
||||||
|
if (operationId.matches("^\\d.*")) {
|
||||||
|
LOGGER.warn(operationId + " (starting with a number) cannot be used as method sname. Renamed to " + camelize("call_" + operationId), true);
|
||||||
|
operationId = camelize("call_" + operationId, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return operationId;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toModelFilename(String name) {
|
public String toModelFilename(String name) {
|
||||||
// Should be the same as the model name
|
// Should be the same as the model name
|
||||||
@@ -577,4 +617,70 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
|
|||||||
public boolean isDataTypeString(final String dataType) {
|
public boolean isDataTypeString(final String dataType) {
|
||||||
return "String".equals(dataType) || "kotlin.String".equals(dataType);
|
return "String".equals(dataType) || "kotlin.String".equals(dataType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toParamName(String name) {
|
||||||
|
// to avoid conflicts with 'callback' parameter for async call
|
||||||
|
if ("callback".equals(name)) {
|
||||||
|
return "paramCallback";
|
||||||
|
}
|
||||||
|
|
||||||
|
// should be the same as variable name
|
||||||
|
return toVarName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toVarName(String name) {
|
||||||
|
// sanitize name
|
||||||
|
name = sanitizeName(name, "\\W-[\\$]");
|
||||||
|
|
||||||
|
if (name.toLowerCase(Locale.ROOT).matches("^_*class$")) {
|
||||||
|
return "propertyClass";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("_".equals(name)) {
|
||||||
|
name = "_u";
|
||||||
|
}
|
||||||
|
|
||||||
|
// if it's all uppper case, do nothing
|
||||||
|
if (name.matches("^[A-Z_]*$")) {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startsWithTwoUppercaseLetters(name)) {
|
||||||
|
name = name.substring(0, 2).toLowerCase(Locale.ROOT) + name.substring(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If name contains special chars -> replace them.
|
||||||
|
if ((name.chars().anyMatch(character -> specialCharReplacements.keySet().contains("" + ((char) character))))) {
|
||||||
|
List<String> allowedCharacters = new ArrayList<>();
|
||||||
|
allowedCharacters.add("_");
|
||||||
|
allowedCharacters.add("$");
|
||||||
|
name = escapeSpecialCharacters(name, allowedCharacters, "_");
|
||||||
|
}
|
||||||
|
|
||||||
|
// camelize (lower first character) the variable name
|
||||||
|
// pet_id => petId
|
||||||
|
name = camelize(name, true);
|
||||||
|
|
||||||
|
// for reserved word or word starting with number or containing dollar symbol, escape it
|
||||||
|
if (isReservedWord(name) || name.matches("(^\\d.*)|(.*[$].*)")) {
|
||||||
|
name = escapeReservedWord(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toRegularExpression(String pattern) {
|
||||||
|
return escapeText(pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean startsWithTwoUppercaseLetters(String name) {
|
||||||
|
boolean startsWithTwoUppercaseLetters = false;
|
||||||
|
if (name.length() > 1) {
|
||||||
|
startsWithTwoUppercaseLetters = name.substring(0, 2).equals(name.substring(0, 2).toUpperCase(Locale.ROOT));
|
||||||
|
}
|
||||||
|
return startsWithTwoUppercaseLetters;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,485 @@
|
|||||||
|
package org.openapitools.codegen.languages;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.samskivert.mustache.Mustache;
|
||||||
|
import com.samskivert.mustache.Template;
|
||||||
|
import io.swagger.v3.oas.models.OpenAPI;
|
||||||
|
import org.openapitools.codegen.*;
|
||||||
|
import org.openapitools.codegen.languages.features.BeanValidationFeatures;
|
||||||
|
import org.openapitools.codegen.utils.URLPathUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
|
||||||
|
public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
|
||||||
|
implements BeanValidationFeatures {
|
||||||
|
|
||||||
|
private static Logger LOGGER =
|
||||||
|
LoggerFactory.getLogger(KotlinSpringServerCodegen.class);
|
||||||
|
|
||||||
|
private static final HashSet<String> VARIABLE_RESERVED_WORDS =
|
||||||
|
new HashSet<String>(Arrays.asList(
|
||||||
|
"ApiClient",
|
||||||
|
"ApiException",
|
||||||
|
"ApiResponse"
|
||||||
|
));
|
||||||
|
|
||||||
|
public static final String TITLE = "title";
|
||||||
|
public static final String LAMBDA = "lambda";
|
||||||
|
public static final String SERVER_PORT = "serverPort";
|
||||||
|
public static final String BASE_PACKAGE = "basePackage";
|
||||||
|
public static final String SPRING_BOOT = "spring-boot";
|
||||||
|
public static final String EXCEPTION_HANDLER = "exceptionHandler";
|
||||||
|
public static final String GRADLE_BUILD_FILE = "gradleBuildFile";
|
||||||
|
public static final String SWAGGER_ANNOTATIONS = "swaggerAnnotations";
|
||||||
|
public static final String SERVICE_INTERFACE = "serviceInterface";
|
||||||
|
public static final String SERVICE_IMPLEMENTATION = "serviceImplementation";
|
||||||
|
|
||||||
|
private String basePackage;
|
||||||
|
private String serverPort = "8080";
|
||||||
|
private String title = "OpenAPI Kotlin Spring";
|
||||||
|
private String resourceFolder = "src/main/resources";
|
||||||
|
private boolean useBeanValidation = true;
|
||||||
|
private boolean exceptionHandler = true;
|
||||||
|
private boolean gradleBuildFile = true;
|
||||||
|
private boolean swaggerAnnotations = false;
|
||||||
|
private boolean serviceInterface = false;
|
||||||
|
private boolean serviceImplementation = false;
|
||||||
|
|
||||||
|
public KotlinSpringServerCodegen() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
reservedWords.addAll(VARIABLE_RESERVED_WORDS);
|
||||||
|
|
||||||
|
outputFolder = "generated-code/kotlin-spring";
|
||||||
|
apiTestTemplateFiles.clear(); // TODO: add test template
|
||||||
|
embeddedTemplateDir = templateDir = "kotlin-spring";
|
||||||
|
|
||||||
|
artifactId = "openapi-spring";
|
||||||
|
basePackage = "org.openapitools";
|
||||||
|
apiPackage = "org.openapitools.api";
|
||||||
|
modelPackage = "org.openapitools.model";
|
||||||
|
|
||||||
|
addOption(TITLE, "server title name or client service name", title);
|
||||||
|
addOption(BASE_PACKAGE, "base package for generated code", basePackage);
|
||||||
|
addOption(SERVER_PORT, "configuration the port in which the sever is to run on", serverPort);
|
||||||
|
addOption(CodegenConstants.MODEL_PACKAGE, "model package for generated code", modelPackage);
|
||||||
|
addOption(CodegenConstants.API_PACKAGE, "api package for generated code", apiPackage);
|
||||||
|
addSwitch(EXCEPTION_HANDLER, "generate default global exception handlers", exceptionHandler);
|
||||||
|
addSwitch(GRADLE_BUILD_FILE, "generate a gradle build file using the Kotlin DSL", gradleBuildFile);
|
||||||
|
addSwitch(SWAGGER_ANNOTATIONS, "generate swagger annotations to go alongside controllers and models", swaggerAnnotations);
|
||||||
|
addSwitch(SERVICE_INTERFACE, "generate service interfaces to go alongside controllers. In most " +
|
||||||
|
"cases this option would be used to update an existing project, so not to override implementations. " +
|
||||||
|
"Useful to help facilitate the generation gap pattern", serviceInterface);
|
||||||
|
addSwitch(SERVICE_IMPLEMENTATION, "generate stub service implementations that extends service " +
|
||||||
|
"interfaces. If this is set to true service interfaces will also be generated", serviceImplementation);
|
||||||
|
addSwitch(USE_BEANVALIDATION, "Use BeanValidation API annotations to validate data types", useBeanValidation);
|
||||||
|
|
||||||
|
supportedLibraries.put(SPRING_BOOT, "Spring-boot Server application.");
|
||||||
|
setLibrary(SPRING_BOOT);
|
||||||
|
|
||||||
|
CliOption cliOpt = new CliOption(CodegenConstants.LIBRARY, "library template (sub-template) to use");
|
||||||
|
cliOpt.setDefault(SPRING_BOOT);
|
||||||
|
cliOpt.setEnum(supportedLibraries);
|
||||||
|
cliOptions.add(cliOpt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getResourceFolder() {
|
||||||
|
return this.resourceFolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResourceFolder(String resourceFolder) {
|
||||||
|
this.resourceFolder = resourceFolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBasePackage() {
|
||||||
|
return this.basePackage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBasePackage(String basePackage) {
|
||||||
|
this.basePackage = basePackage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServerPort() {
|
||||||
|
return this.serverPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServerPort(String serverPort) {
|
||||||
|
this.serverPort = serverPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getExceptionHandler() {
|
||||||
|
return this.exceptionHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExceptionHandler(boolean exceptionHandler) {
|
||||||
|
this.exceptionHandler = exceptionHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getGradleBuildFile() {
|
||||||
|
return this.gradleBuildFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGradleBuildFile(boolean gradleBuildFile) {
|
||||||
|
this.gradleBuildFile = gradleBuildFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getSwaggerAnnotations() {
|
||||||
|
return this.swaggerAnnotations;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSwaggerAnnotations(boolean swaggerAnnotations) {
|
||||||
|
this.swaggerAnnotations = swaggerAnnotations;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getServiceInterface() {
|
||||||
|
return this.serviceInterface;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServiceInterface(boolean serviceInterface) {
|
||||||
|
this.serviceInterface = serviceInterface;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getServiceImplementation() {
|
||||||
|
return this.serviceImplementation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServiceImplementation(boolean serviceImplementation) {
|
||||||
|
this.serviceImplementation = serviceImplementation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getUseBeanValidation() {
|
||||||
|
return this.useBeanValidation;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setUseBeanValidation(boolean useBeanValidation) {
|
||||||
|
this.useBeanValidation = useBeanValidation;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CodegenType getTag() {
|
||||||
|
return CodegenType.SERVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "kotlin-spring";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getHelp() {
|
||||||
|
return "Generates a Kotlin Spring application.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processOpts() {
|
||||||
|
super.processOpts();
|
||||||
|
|
||||||
|
typeMapping.put("date", "java.time.LocalDate");
|
||||||
|
typeMapping.put("date-time", "java.time.OffsetDateTime");
|
||||||
|
typeMapping.put("Date", "java.time.LocalDate");
|
||||||
|
typeMapping.put("DateTime", "java.time.OffsetDateTime");
|
||||||
|
|
||||||
|
importMapping.put("Date", "java.time.LocalDate");
|
||||||
|
importMapping.put("DateTime", "java.time.OffsetDateTime");
|
||||||
|
|
||||||
|
// optional jackson mappings for BigDecimal support
|
||||||
|
importMapping.put("ToStringSerializer", "com.fasterxml.jackson.databind.ser.std.ToStringSerializer");
|
||||||
|
importMapping.put("JsonSerialize", "com.fasterxml.jackson.databind.annotation.JsonSerialize");
|
||||||
|
|
||||||
|
// Swagger import mappings
|
||||||
|
importMapping.put("ApiModel", "io.swagger.annotations.ApiModel");
|
||||||
|
importMapping.put("ApiModelProperty", "io.swagger.annotations.ApiModelProperty");
|
||||||
|
|
||||||
|
// Jackson import mappings
|
||||||
|
importMapping.put("JsonValue", "com.fasterxml.jackson.annotation.JsonValue");
|
||||||
|
importMapping.put("JsonCreator", "com.fasterxml.jackson.annotation.JsonCreator");
|
||||||
|
importMapping.put("JsonProperty", "com.fasterxml.jackson.annotation.JsonProperty");
|
||||||
|
importMapping.put("JsonSubTypes", "com.fasterxml.jackson.annotation.JsonSubTypes");
|
||||||
|
importMapping.put("JsonTypeInfo", "com.fasterxml.jackson.annotation.JsonTypeInfo");
|
||||||
|
// import JsonCreator if JsonProperty is imported
|
||||||
|
// used later in recursive import in postProcessingModels
|
||||||
|
importMapping.put("com.fasterxml.jackson.annotation.JsonProperty", "com.fasterxml.jackson.annotation.JsonCreator");
|
||||||
|
|
||||||
|
// TODO when adding invokerPackage
|
||||||
|
//importMapping.put("StringUtil", invokerPackage + ".StringUtil");
|
||||||
|
|
||||||
|
if (!additionalProperties.containsKey(CodegenConstants.LIBRARY)) {
|
||||||
|
additionalProperties.put(CodegenConstants.LIBRARY, library);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(BASE_PACKAGE)) {
|
||||||
|
this.setBasePackage((String) additionalProperties.get(BASE_PACKAGE));
|
||||||
|
} else {
|
||||||
|
additionalProperties.put(BASE_PACKAGE, basePackage);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(SERVER_PORT)) {
|
||||||
|
this.setServerPort((String) additionalProperties.get(SERVER_PORT));
|
||||||
|
} else {
|
||||||
|
additionalProperties.put(SERVER_PORT, serverPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(EXCEPTION_HANDLER)) {
|
||||||
|
this.setExceptionHandler(Boolean.valueOf(additionalProperties.get(EXCEPTION_HANDLER).toString()));
|
||||||
|
}
|
||||||
|
writePropertyBack(EXCEPTION_HANDLER, exceptionHandler);
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(GRADLE_BUILD_FILE)) {
|
||||||
|
this.setGradleBuildFile(Boolean.valueOf(additionalProperties.get(GRADLE_BUILD_FILE).toString()));
|
||||||
|
}
|
||||||
|
writePropertyBack(GRADLE_BUILD_FILE, gradleBuildFile);
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(SWAGGER_ANNOTATIONS)) {
|
||||||
|
this.setSwaggerAnnotations(Boolean.valueOf(additionalProperties.get(SWAGGER_ANNOTATIONS).toString()));
|
||||||
|
}
|
||||||
|
writePropertyBack(SWAGGER_ANNOTATIONS, swaggerAnnotations);
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(SERVICE_INTERFACE)) {
|
||||||
|
this.setServiceInterface(Boolean.valueOf(additionalProperties.get(SERVICE_INTERFACE).toString()));
|
||||||
|
}
|
||||||
|
writePropertyBack(SERVICE_INTERFACE, serviceInterface);
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(SERVICE_IMPLEMENTATION)) {
|
||||||
|
this.setServiceImplementation(Boolean.valueOf(additionalProperties.get(SERVICE_IMPLEMENTATION).toString()));
|
||||||
|
}
|
||||||
|
writePropertyBack(SERVICE_IMPLEMENTATION, serviceImplementation);
|
||||||
|
|
||||||
|
if (additionalProperties.containsKey(USE_BEANVALIDATION)) {
|
||||||
|
this.setUseBeanValidation(convertPropertyToBoolean(USE_BEANVALIDATION));
|
||||||
|
}
|
||||||
|
writePropertyBack(USE_BEANVALIDATION, useBeanValidation);
|
||||||
|
|
||||||
|
modelTemplateFiles.put("model.mustache", ".kt");
|
||||||
|
apiTemplateFiles.put("api.mustache", ".kt");
|
||||||
|
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
|
||||||
|
|
||||||
|
if (this.serviceInterface) {
|
||||||
|
apiTemplateFiles.put("service.mustache", "Service.kt");
|
||||||
|
} else if (this.serviceImplementation) {
|
||||||
|
LOGGER.warn("If you set `serviceImplementation` to true, `serviceInterface` will also be set to true");
|
||||||
|
additionalProperties.put(SERVICE_INTERFACE, true);
|
||||||
|
apiTemplateFiles.put("service.mustache", "Service.kt");
|
||||||
|
apiTemplateFiles.put("serviceImpl.mustache", "ServiceImpl.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.exceptionHandler) {
|
||||||
|
supportingFiles.add(new SupportingFile("exceptions.mustache",
|
||||||
|
sanitizeDirectory(sourceFolder + File.separator + apiPackage), "Exceptions.kt"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (library.equals(SPRING_BOOT)) {
|
||||||
|
LOGGER.info("Setup code generator for Kotlin Spring Boot");
|
||||||
|
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
|
||||||
|
|
||||||
|
if (this.gradleBuildFile) {
|
||||||
|
supportingFiles.add(new SupportingFile("buildGradleKts.mustache", "", "build.gradle.kts"));
|
||||||
|
supportingFiles.add(new SupportingFile("settingsGradle.mustache", "", "settings.gradle"));
|
||||||
|
}
|
||||||
|
|
||||||
|
supportingFiles.add(new SupportingFile("application.mustache", resourceFolder, "application.yaml"));
|
||||||
|
supportingFiles.add(new SupportingFile("springBootApplication.mustache",
|
||||||
|
sanitizeDirectory(sourceFolder + File.separator + basePackage), "Application.kt"));
|
||||||
|
}
|
||||||
|
|
||||||
|
addMustacheLambdas(additionalProperties);
|
||||||
|
|
||||||
|
// spring uses the jackson lib, and we disallow configuration.
|
||||||
|
additionalProperties.put("jackson", "true");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addMustacheLambdas(final Map<String, Object> objs) {
|
||||||
|
Map<String, Mustache.Lambda> lambdas =
|
||||||
|
new ImmutableMap.Builder<String, Mustache.Lambda>()
|
||||||
|
.put("escapeDoubleQuote", new EscapeLambda("\"", "\\\""))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
if (objs.containsKey(LAMBDA)) {
|
||||||
|
LOGGER.warn("The lambda property is a reserved word, and will be overwritten!");
|
||||||
|
}
|
||||||
|
objs.put(LAMBDA, lambdas);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preprocessOpenAPI(OpenAPI openAPI) {
|
||||||
|
super.preprocessOpenAPI(openAPI);
|
||||||
|
|
||||||
|
if (!additionalProperties.containsKey(TITLE)) {
|
||||||
|
// The purpose of the title is for:
|
||||||
|
// - README documentation
|
||||||
|
// - The spring.application.name
|
||||||
|
// - And linking the @RequestMapping
|
||||||
|
// This is an additional step we add when pre-processing the API spec, if
|
||||||
|
// there is no user configuration set for the `title` of the project,
|
||||||
|
// we try build and normalise a title from the API spec itself.
|
||||||
|
String title = openAPI.getInfo().getTitle();
|
||||||
|
|
||||||
|
// Drop any API suffix
|
||||||
|
if (title != null) {
|
||||||
|
title = title.trim().replace(" ", "-");
|
||||||
|
if (title.toUpperCase(Locale.ROOT).endsWith("API"))
|
||||||
|
title = title.substring(0, title.length() - 3);
|
||||||
|
|
||||||
|
this.title = camelize(sanitizeName(title), true);
|
||||||
|
}
|
||||||
|
additionalProperties.put(TITLE, this.title);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!additionalProperties.containsKey(SERVER_PORT)) {
|
||||||
|
URL url = URLPathUtils.getServerURL(openAPI);
|
||||||
|
this.additionalProperties.put(SERVER_PORT, URLPathUtils.getPort(url, 8080));
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Handle tags
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postProcessModelProperty(CodegenModel model, CodegenProperty property) {
|
||||||
|
super.postProcessModelProperty(model, property);
|
||||||
|
|
||||||
|
if ("null".equals(property.example)) {
|
||||||
|
property.example = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Add imports for Jackson
|
||||||
|
if (!Boolean.TRUE.equals(model.isEnum)) {
|
||||||
|
model.imports.add("JsonProperty");
|
||||||
|
if (Boolean.TRUE.equals(model.hasEnums)) {
|
||||||
|
model.imports.add("JsonValue");
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
//Needed imports for Jackson's JsonCreator
|
||||||
|
if (additionalProperties.containsKey("jackson")) {
|
||||||
|
model.imports.add("JsonCreator");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> postProcessModelsEnum(Map<String, Object> objs) {
|
||||||
|
objs = super.postProcessModelsEnum(objs);
|
||||||
|
|
||||||
|
//Add imports for Jackson
|
||||||
|
List<Map<String, String>> imports = (List<Map<String, String>>) objs.get("imports");
|
||||||
|
List<Object> models = (List<Object>) objs.get("models");
|
||||||
|
|
||||||
|
models.stream()
|
||||||
|
.map(mo -> (Map<String, Object>) mo)
|
||||||
|
.map(mo -> (CodegenModel) mo.get("model"))
|
||||||
|
.filter(cm -> Boolean.TRUE.equals(cm.isEnum) && cm.allowableValues != null)
|
||||||
|
.forEach(cm -> {
|
||||||
|
cm.imports.add(importMapping.get("JsonValue"));
|
||||||
|
Map<String, String> item = new HashMap<>();
|
||||||
|
item.put("import", importMapping.get("JsonValue"));
|
||||||
|
imports.add(item);
|
||||||
|
});
|
||||||
|
|
||||||
|
return objs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) {
|
||||||
|
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
|
||||||
|
if (operations != null) {
|
||||||
|
List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
|
||||||
|
ops.forEach(operation -> {
|
||||||
|
List<CodegenResponse> responses = operation.responses;
|
||||||
|
if (responses != null) {
|
||||||
|
responses.forEach(resp -> {
|
||||||
|
|
||||||
|
if ("0".equals(resp.code)) {
|
||||||
|
resp.code = "200";
|
||||||
|
}
|
||||||
|
|
||||||
|
doDataTypeAssignment(resp.dataType, new DataTypeAssigner() {
|
||||||
|
@Override
|
||||||
|
public void setReturnType(final String returnType) {
|
||||||
|
resp.dataType = returnType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setReturnContainer(final String returnContainer) {
|
||||||
|
resp.containerType = returnContainer;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
doDataTypeAssignment(operation.returnType, new DataTypeAssigner() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setReturnType(final String returnType) {
|
||||||
|
operation.returnType = returnType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setReturnContainer(final String returnContainer) {
|
||||||
|
operation.returnContainer = returnContainer;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// if(implicitHeaders){
|
||||||
|
// removeHeadersFromAllParams(operation.allParams);
|
||||||
|
// }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return objs;
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface DataTypeAssigner {
|
||||||
|
void setReturnType(String returnType);
|
||||||
|
|
||||||
|
void setReturnContainer(String returnContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param returnType The return type that needs to be converted
|
||||||
|
* @param dataTypeAssigner An object that will assign the data to the respective fields in the model.
|
||||||
|
*/
|
||||||
|
private void doDataTypeAssignment(final String returnType, DataTypeAssigner dataTypeAssigner) {
|
||||||
|
if (returnType == null) {
|
||||||
|
dataTypeAssigner.setReturnType("Unit");
|
||||||
|
} else if (returnType.startsWith("kotlin.Array")) {
|
||||||
|
int end = returnType.lastIndexOf(">");
|
||||||
|
if (end > 0) {
|
||||||
|
dataTypeAssigner.setReturnType(returnType.substring("kotlin.Array<".length(), end).trim());
|
||||||
|
dataTypeAssigner.setReturnContainer("List");
|
||||||
|
}
|
||||||
|
} else if (returnType.startsWith("kotlin.collections.Map")) {
|
||||||
|
int end = returnType.lastIndexOf(">");
|
||||||
|
if (end > 0) {
|
||||||
|
dataTypeAssigner.setReturnType(returnType.substring("kotlin.collections.Map<".length(), end).split(",")[1].trim());
|
||||||
|
dataTypeAssigner.setReturnContainer("Map");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String sanitizeDirectory(String in) {
|
||||||
|
return in.replace(".", File.separator);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO could probably be made more generic, and moved to the `mustache` package if required by other components.
|
||||||
|
private static class EscapeLambda implements Mustache.Lambda {
|
||||||
|
private String from;
|
||||||
|
private String to;
|
||||||
|
|
||||||
|
EscapeLambda(final String from, final String to) {
|
||||||
|
this.from = from;
|
||||||
|
this.to = Matcher.quoteReplacement(to);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(Template.Fragment fragment, Writer writer) throws IOException {
|
||||||
|
writer.write(fragment.execute().replaceAll(from, to));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -91,3 +91,4 @@ org.openapitools.codegen.languages.TypeScriptFetchClientCodegen
|
|||||||
org.openapitools.codegen.languages.TypeScriptInversifyClientCodegen
|
org.openapitools.codegen.languages.TypeScriptInversifyClientCodegen
|
||||||
org.openapitools.codegen.languages.TypeScriptJqueryClientCodegen
|
org.openapitools.codegen.languages.TypeScriptJqueryClientCodegen
|
||||||
org.openapitools.codegen.languages.TypeScriptNodeClientCodegen
|
org.openapitools.codegen.languages.TypeScriptNodeClientCodegen
|
||||||
|
org.openapitools.codegen.languages.KotlinSpringServerCodegen
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
package {{package}}
|
||||||
|
|
||||||
|
{{#imports}}import {{import}}
|
||||||
|
{{/imports}}
|
||||||
|
{{#swaggerAnnotations}}
|
||||||
|
import io.swagger.annotations.*
|
||||||
|
{{/swaggerAnnotations}}
|
||||||
|
import org.springframework.http.HttpStatus
|
||||||
|
import org.springframework.http.MediaType
|
||||||
|
import org.springframework.http.ResponseEntity
|
||||||
|
import org.springframework.stereotype.Controller
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody
|
||||||
|
import org.springframework.web.bind.annotation.RequestPart
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable
|
||||||
|
import org.springframework.web.bind.annotation.RequestHeader
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping
|
||||||
|
{{#useBeanValidation}}
|
||||||
|
import org.springframework.validation.annotation.Validated
|
||||||
|
{{/useBeanValidation}}
|
||||||
|
import org.springframework.web.context.request.NativeWebRequest
|
||||||
|
import org.springframework.web.multipart.MultipartFile
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
|
||||||
|
{{#useBeanValidation}}
|
||||||
|
import javax.validation.Valid
|
||||||
|
import javax.validation.constraints.*
|
||||||
|
{{/useBeanValidation}}
|
||||||
|
|
||||||
|
import kotlin.collections.List
|
||||||
|
import kotlin.collections.Map
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
{{#useBeanValidation}}
|
||||||
|
@Validated
|
||||||
|
{{/useBeanValidation}}
|
||||||
|
{{#swaggerAnnotations}}
|
||||||
|
@Api(value = "{{{baseName}}}", description = "The {{{baseName}}} API")
|
||||||
|
{{/swaggerAnnotations}}
|
||||||
|
{{=<% %>=}}
|
||||||
|
@RequestMapping("\${openapi.<%title%>.base-path:<%contextPath%>}")
|
||||||
|
<%={{ }}=%>
|
||||||
|
{{#operations}}
|
||||||
|
class {{classname}}Controller({{#serviceInterface}}@Autowired(required = true) val service: {{classname}}Service{{/serviceInterface}}) {
|
||||||
|
{{#operation}}
|
||||||
|
|
||||||
|
{{#swaggerAnnotations}}
|
||||||
|
@ApiOperation(
|
||||||
|
value = "{{{summary}}}",
|
||||||
|
nickname = "{{{operationId}}}",
|
||||||
|
notes = "{{{notes}}}"{{#returnBaseType}},
|
||||||
|
response = {{{returnBaseType}}}::class{{/returnBaseType}}{{#returnContainer}},
|
||||||
|
responseContainer = "{{{returnContainer}}}"{{/returnContainer}}{{#hasAuthMethods}},
|
||||||
|
authorizations = [{{#authMethods}}Authorization(value = "{{name}}"{{#isOAuth}}, scopes = [{{#scopes}}AuthorizationScope(scope = "{{scope}}", description = "{{description}}"){{#hasMore}}, {{/hasMore}}{{/scopes}}]{{/isOAuth}}){{#hasMore}}, {{/hasMore}}{{/authMethods}}]{{/hasAuthMethods}})
|
||||||
|
@ApiResponses(
|
||||||
|
value = [{{#responses}}ApiResponse(code = {{{code}}}, message = "{{{message}}}"{{#baseType}}, response = {{{baseType}}}::class{{/baseType}}{{#containerType}}, responseContainer = "{{{containerType}}}"{{/containerType}}){{#hasMore}},{{/hasMore}}{{/responses}}]){{/swaggerAnnotations}}
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["{{#lambda.escapeDoubleQuote}}{{path}}{{/lambda.escapeDoubleQuote}}"],{{#singleContentTypes}}{{#hasProduces}}
|
||||||
|
produces = "{{{vendorExtensions.x-accepts}}}", {{/hasProduces}}{{#hasConsumes}}
|
||||||
|
consumes = "{{{vendorExtensions.x-contentType}}}",{{/hasConsumes}}{{/singleContentTypes}}{{^singleContentTypes}}{{#hasProduces}}
|
||||||
|
produces = [{{#produces}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/produces}}], {{/hasProduces}}{{#hasConsumes}}
|
||||||
|
consumes = [{{#consumes}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/consumes}}],{{/hasConsumes}}{{/singleContentTypes}}
|
||||||
|
method = [RequestMethod.{{httpMethod}}])
|
||||||
|
fun {{operationId}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}},{{/hasMore}}{{/allParams}}): ResponseEntity<{{>returnTypes}}> {
|
||||||
|
return {{>returnValue}}
|
||||||
|
}
|
||||||
|
{{/operation}}
|
||||||
|
}
|
||||||
|
{{/operations}}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
{{#pattern}}@get:Pattern(regexp="{{{pattern}}}") {{/pattern}}{{!
|
||||||
|
minLength && maxLength set
|
||||||
|
}}{{#minLength}}{{#maxLength}}@get:Size(min={{minLength}},max={{maxLength}}) {{/maxLength}}{{/minLength}}{{!
|
||||||
|
minLength set, maxLength not
|
||||||
|
}}{{#minLength}}{{^maxLength}}@get:Size(min={{minLength}}) {{/maxLength}}{{/minLength}}{{!
|
||||||
|
minLength not set, maxLength set
|
||||||
|
}}{{^minLength}}{{#maxLength}}@get:Size(max={{maxLength}}) {{/maxLength}}{{/minLength}}{{!
|
||||||
|
@Size: minItems && maxItems set
|
||||||
|
}}{{#minItems}}{{#maxItems}}@get:Size(min={{minItems}},max={{maxItems}}) {{/maxItems}}{{/minItems}}{{!
|
||||||
|
@Size: minItems set, maxItems not
|
||||||
|
}}{{#minItems}}{{^maxItems}}@get:Size(min={{minItems}}) {{/maxItems}}{{/minItems}}{{!
|
||||||
|
@Size: minItems not set && maxItems set
|
||||||
|
}}{{^minItems}}{{#maxItems}}@get:Size(max={{maxItems}}) {{/maxItems}}{{/minItems}}{{!
|
||||||
|
check for integer or long / all others=decimal type with @Decimal*
|
||||||
|
isInteger set
|
||||||
|
}}{{#isInteger}}{{#minimum}}@get:Min({{minimum}}){{/minimum}}{{#maximum}} @get:Max({{maximum}}) {{/maximum}}{{/isInteger}}{{!
|
||||||
|
isLong set
|
||||||
|
}}{{#isLong}}{{#minimum}}@get:Min({{minimum}}L){{/minimum}}{{#maximum}} @get:Max({{maximum}}L) {{/maximum}}{{/isLong}}{{!
|
||||||
|
Not Integer, not Long => we have a decimal value!
|
||||||
|
}}{{^isInteger}}{{^isLong}}{{#minimum}}@get:DecimalMin("{{minimum}}"){{/minimum}}{{#maximum}} @get:DecimalMax("{{maximum}}") {{/maximum}}{{/isLong}}{{/isInteger}}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
{{#pattern}}@Pattern(regexp="{{{pattern}}}") {{/pattern}}{{!
|
||||||
|
minLength && maxLength set
|
||||||
|
}}{{#minLength}}{{#maxLength}}@Size(min={{minLength}},max={{maxLength}}) {{/maxLength}}{{/minLength}}{{!
|
||||||
|
minLength set, maxLength not
|
||||||
|
}}{{#minLength}}{{^maxLength}}@Size(min={{minLength}}) {{/maxLength}}{{/minLength}}{{!
|
||||||
|
minLength not set, maxLength set
|
||||||
|
}}{{^minLength}}{{#maxLength}}@Size(max={{maxLength}}) {{/maxLength}}{{/minLength}}{{!
|
||||||
|
@Size: minItems && maxItems set
|
||||||
|
}}{{#minItems}}{{#maxItems}}@Size(min={{minItems}},max={{maxItems}}) {{/maxItems}}{{/minItems}}{{!
|
||||||
|
@Size: minItems set, maxItems not
|
||||||
|
}}{{#minItems}}{{^maxItems}}@Size(min={{minItems}}) {{/maxItems}}{{/minItems}}{{!
|
||||||
|
@Size: minItems not set && maxItems set
|
||||||
|
}}{{^minItems}}{{#maxItems}}@Size(max={{maxItems}}) {{/maxItems}}{{/minItems}}{{!
|
||||||
|
check for integer or long / all others=decimal type with @Decimal*
|
||||||
|
isInteger set
|
||||||
|
}}{{#isInteger}}{{#minimum}}@Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}) {{/maximum}}{{/isInteger}}{{!
|
||||||
|
isLong set
|
||||||
|
}}{{#isLong}}{{#minimum}}@Min({{minimum}}L){{/minimum}}{{#maximum}} @Max({{maximum}}L) {{/maximum}}{{/isLong}}{{!
|
||||||
|
Not Integer, not Long => we have a decimal value!
|
||||||
|
}}{{^isInteger}}{{^isLong}}{{#minimum}}@DecimalMin("{{minimum}}"){{/minimum}}{{#maximum}} @DecimalMax("{{maximum}}") {{/maximum}}{{/isLong}}{{/isInteger}}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{{! PathParam is always required, no @NotNull necessary }}{{>beanValidationPath}}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{{#required}}@NotNull {{/required}}{{>beanValidationPath}}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{{#isBodyParam}}{{#swaggerAnnotations}}@ApiParam(value = "{{{description}}}" {{#required}},required=true{{/required}} {{^isContainer}}{{#allowableValues}}, allowableValues="{{{allowableValues}}}"{{/allowableValues}}{{/isContainer}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}){{/swaggerAnnotations}} {{#useBeanValidation}}@Valid{{/useBeanValidation}} @RequestBody {{paramName}}: {{^reactive}}{{{dataType}}}{{/reactive}}{{#reactive}}{{^isListContainer}}Mono{{/isListContainer}}{{#isListContainer}}Flux{{/isListContainer}}<{{{baseType}}}>{{/reactive}}{{/isBodyParam}}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* {{{description}}}
|
||||||
|
{{#vars}}
|
||||||
|
* @param {{name}} {{{description}}}
|
||||||
|
{{/vars}}
|
||||||
|
*/
|
||||||
|
data class {{classname}} (
|
||||||
|
{{#requiredVars}}
|
||||||
|
{{>dataClassReqVar}}{{^-last}},
|
||||||
|
{{/-last}}{{/requiredVars}}{{#hasRequired}}{{#hasOptional}},
|
||||||
|
{{/hasOptional}}{{/hasRequired}}{{#optionalVars}}{{>dataClassOptVar}}{{^-last}},
|
||||||
|
{{/-last}}{{/optionalVars}}
|
||||||
|
) {
|
||||||
|
{{#hasEnums}}{{#vars}}{{#isEnum}}
|
||||||
|
/**
|
||||||
|
* {{{description}}}
|
||||||
|
* Values: {{#allowableValues}}{{#enumVars}}{{&name}}{{^-last}},{{/-last}}{{/enumVars}}{{/allowableValues}}
|
||||||
|
*/
|
||||||
|
enum class {{nameInCamelCase}}(val value: {{{dataType}}}) {
|
||||||
|
{{#allowableValues}}{{#enumVars}}
|
||||||
|
@JsonProperty({{{value}}}) {{{name}}}({{{value}}}){{^-last}},{{/-last}}{{#-last}};{{/-last}}
|
||||||
|
{{/enumVars}}{{/allowableValues}}
|
||||||
|
}
|
||||||
|
{{/isEnum}}{{/vars}}{{/hasEnums}}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{{#useBeanValidation}}{{#required}}
|
||||||
|
@get:NotNull {{/required}}{{>beanValidationModel}}{{/useBeanValidation}}{{#swaggerAnnotations}}
|
||||||
|
@ApiModelProperty({{#example}}example = "{{{example}}}", {{/example}}{{#required}}required = {{required}}, {{/required}}{{#isReadOnly}}readOnly = {{{isReadOnly}}}, {{/isReadOnly}}value = "{{{description}}}"){{/swaggerAnnotations}}
|
||||||
|
@JsonProperty("{{{baseName}}}") val {{{name}}}: {{#isEnum}}{{classname}}.{{nameInCamelCase}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}? = {{#defaultvalue}}{{defaultvalue}}{{/defaultvalue}}{{^defaultvalue}}null{{/defaultvalue}}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{{#useBeanValidation}}{{#required}}
|
||||||
|
@get:NotNull {{/required}}{{>beanValidationModel}}{{/useBeanValidation}}{{#swaggerAnnotations}}
|
||||||
|
@ApiModelProperty({{#example}}example = "{{{example}}}", {{/example}}{{#required}}required = {{required}}, {{/required}}{{#isReadOnly}}readOnly = {{{isReadOnly}}}, {{/isReadOnly}}value = "{{{description}}}"){{/swaggerAnnotations}}
|
||||||
|
@JsonProperty("{{{baseName}}}") val {{{name}}}: {{#isEnum}}{{classname}}.{{nameInCamelCase}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}
|
||||||
@@ -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}}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package {{apiPackage}}
|
||||||
|
|
||||||
|
import org.springframework.http.HttpStatus
|
||||||
|
import org.springframework.web.bind.annotation.ControllerAdvice
|
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler
|
||||||
|
import javax.servlet.http.HttpServletResponse
|
||||||
|
import javax.validation.ConstraintViolationException
|
||||||
|
|
||||||
|
// TODO Extend ApiException for custom exception handling, e.g. the below NotFound exception
|
||||||
|
sealed class ApiException(msg: String, val code: Int) : Exception(msg)
|
||||||
|
|
||||||
|
class NotFoundException(msg: String, code: Int = HttpStatus.NOT_FOUND.value()) : ApiException(msg, code)
|
||||||
|
|
||||||
|
|
||||||
|
@ControllerAdvice
|
||||||
|
class DefaultExceptionHandler {
|
||||||
|
|
||||||
|
@ExceptionHandler(value = [ApiException::class])
|
||||||
|
fun onApiException(ex: ApiException, response: HttpServletResponse): Unit =
|
||||||
|
response.sendError(ex.code, ex.message)
|
||||||
|
|
||||||
|
@ExceptionHandler(value = [NotImplementedError::class])
|
||||||
|
fun onNotImplemented(ex: NotImplementedError, response: HttpServletResponse): Unit =
|
||||||
|
response.sendError(HttpStatus.NOT_IMPLEMENTED.value())
|
||||||
|
|
||||||
|
@ExceptionHandler(value = [ConstraintViolationException::class])
|
||||||
|
fun onConstraintViolation(ex: ConstraintViolationException, response: HttpServletResponse): Unit =
|
||||||
|
response.sendError(HttpStatus.BAD_REQUEST.value(), ex.constraintViolations.joinToString(", ") { it.message })
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{{#isFormParam}}{{^isFile}}{{#swaggerAnnotations}}@ApiParam(value = "{{{description}}}"{{#required}}, required=true{{/required}}{{#allowableValues}}, allowableValues="{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{#-last}}{{/-last}}{{/values}}"{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}){{/swaggerAnnotations}} @RequestParam(value="{{baseName}}"{{#required}}, required=true{{/required}}{{^required}}, required=false{{/required}}) {{paramName}}: {{{dataType}}} {{/isFile}}{{#isFile}}{{#swaggerAnnotations}}@ApiParam(value = "file detail"){{/swaggerAnnotations}} {{#useBeanValidation}}@Valid{{/useBeanValidation}} @RequestPart("file") {{baseName}}: MultipartFile{{/isFile}}{{/isFormParam}}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{{#isHeaderParam}}{{#swaggerAnnotations}}@ApiParam(value = "{{{description}}}" {{#required}},required=true{{/required}}{{#allowableValues}}, allowableValues="{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{#-last}}{{/-last}}{{/values}}"{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}){{/swaggerAnnotations}} @RequestHeader(value="{{baseName}}", required={{#required}}true{{/required}}{{^required}}false{{/required}}) {{paramName}}: {{>optionalDataType}}{{/isHeaderParam}}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
# {{#title}}{{title}}{{/title}}{{^title}}Generated Kotlin Spring Boot App{{/title}}
|
||||||
|
|
||||||
|
This Kotlin based [Spring Boot](https://spring.io/projects/spring-boot) application has been generated using the [OpenAPI Generator](https://github.com/OpenAPITools/openapi-generator).
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
This document assumes you have either maven or gradle available, either via the wrapper or otherwise. This does not come with a gradle / maven wrapper checked in.
|
||||||
|
|
||||||
|
By default a [`pom.xml`](pom.xml) file will be generated. If you specified `gradleBuildFile=true` when generating this project, a `build.gradle.kts` will also be generated. Note this uses [Gradle Kotlin DSL](https://github.com/gradle/kotlin-dsl).
|
||||||
|
|
||||||
|
To build the project using maven, run:
|
||||||
|
```bash
|
||||||
|
mvn package && java -jar target/{{artifactId}}-{{artifactVersion}}.jar
|
||||||
|
```
|
||||||
|
|
||||||
|
To build the project using gradle, run:
|
||||||
|
```bash
|
||||||
|
gradle build && java -jar build/libs/{{artifactId}}-{{artifactVersion}}.jar
|
||||||
|
```
|
||||||
|
|
||||||
|
If all builds successfully, the server should run on [http://localhost:8080/](http://localhost:{{serverPort}}/)
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
spring.application.name={{title}}
|
||||||
|
server.port={{serverPort}}
|
||||||
|
spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
|
|
||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.0.3.RELEASE")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
group = "{{groupId}}"
|
||||||
|
version = "{{artifactVersion}}"
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType<KotlinCompile> {
|
||||||
|
kotlinOptions.jvmTarget = "1.8"
|
||||||
|
}
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
val kotlinVersion = "1.2.60"
|
||||||
|
id("org.jetbrains.kotlin.jvm") version kotlinVersion
|
||||||
|
id("org.jetbrains.kotlin.plugin.jpa") version kotlinVersion
|
||||||
|
id("org.jetbrains.kotlin.plugin.spring") version kotlinVersion
|
||||||
|
id("org.springframework.boot") version "2.0.3.RELEASE"
|
||||||
|
id("io.spring.dependency-management") version "1.0.5.RELEASE"
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
|
||||||
|
compile("org.jetbrains.kotlin:kotlin-reflect")
|
||||||
|
compile("org.springframework.boot:spring-boot-starter-web")
|
||||||
|
{{#swaggerAnnotations}}
|
||||||
|
compile("io.swagger:swagger-annotations:1.5.21")
|
||||||
|
{{/swaggerAnnotations}}
|
||||||
|
compile("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml")
|
||||||
|
compile("com.fasterxml.jackson.dataformat:jackson-dataformat-xml")
|
||||||
|
|
||||||
|
testCompile("org.springframework.boot:spring-boot-starter-test") {
|
||||||
|
exclude(module = "junit")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
<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>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<name>{{artifactId}}</name>
|
||||||
|
<version>{{artifactVersion}}</version>
|
||||||
|
<properties>
|
||||||
|
<kotlin.version>1.2.60</kotlin.version>
|
||||||
|
</properties>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>2.0.3.RELEASE</version>
|
||||||
|
</parent>
|
||||||
|
<build>
|
||||||
|
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
|
||||||
|
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>repackage</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>kotlin-maven-plugin</artifactId>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<compilerPlugins>
|
||||||
|
<plugin>spring</plugin>
|
||||||
|
</compilerPlugins>
|
||||||
|
<jvmTarget>1.8</jvmTarget>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>compile</id>
|
||||||
|
<phase>compile</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>compile</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>test-compile</id>
|
||||||
|
<phase>test-compile</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>test-compile</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-maven-allopen</artifactId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-reflect</artifactId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
{{#swaggerAnnotations}}
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.swagger</groupId>
|
||||||
|
<artifactId>swagger-annotations</artifactId>
|
||||||
|
<version>1.5.21</version>
|
||||||
|
</dependency>
|
||||||
|
{{/swaggerAnnotations}}
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||||
|
<artifactId>jackson-dataformat-yaml</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||||
|
<artifactId>jackson-dataformat-xml</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||||
|
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||||
|
</dependency>
|
||||||
|
{{#useBeanValidation}}
|
||||||
|
<!-- Bean Validation API support -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.validation</groupId>
|
||||||
|
<artifactId>validation-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
{{/useBeanValidation}}
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
rootProject.name = "{{artifactId}}"
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package {{basePackage}}
|
||||||
|
|
||||||
|
import org.springframework.boot.runApplication
|
||||||
|
import org.springframework.context.annotation.ComponentScan
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication
|
||||||
|
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
@ComponentScan(basePackages = ["{{basePackage}}", "{{apiPackage}}", "{{modelPackage}}"])
|
||||||
|
class Application
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
runApplication<Application>(*args)
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package {{package}}
|
||||||
|
|
||||||
|
import java.util.Objects
|
||||||
|
{{#imports}}import {{import}}
|
||||||
|
{{/imports}}
|
||||||
|
{{#useBeanValidation}}
|
||||||
|
import javax.validation.Valid
|
||||||
|
import javax.validation.constraints.*
|
||||||
|
{{/useBeanValidation}}
|
||||||
|
{{#swaggerAnnotations}}
|
||||||
|
import io.swagger.annotations.ApiModelProperty
|
||||||
|
{{/swaggerAnnotations}}
|
||||||
|
|
||||||
|
{{#models}}
|
||||||
|
{{#model}}
|
||||||
|
{{#isEnum}}{{>enumClass}}{{/isEnum}}{{^isEnum}}{{>dataClass}}{{/isEnum}}
|
||||||
|
{{/model}}
|
||||||
|
{{/models}}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{{#useOptional}}{{#required}}{{{dataType}}}{{/required}}{{^required}}Optional<{{{dataType}}}>{{/required}}{{/useOptional}}{{^useOptional}}{{{dataType}}}{{/useOptional}}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{{#isPathParam}}{{#useBeanValidation}}{{>beanValidationPathParams}}{{/useBeanValidation}}{{#swaggerAnnotations}}@ApiParam(value = "{{{description}}}"{{#required}}, required=true{{/required}}{{#allowableValues}}, allowableValues = "{{#enumVars}}{{#lambda.escapeDoubleQuote}}{{{value}}}{{/lambda.escapeDoubleQuote}}{{^-last}}, {{/-last}}{{#-last}}{{/-last}}{{/enumVars}}"{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}){{/swaggerAnnotations}} @PathVariable("{{baseName}}") {{paramName}}: {{>optionalDataType}}{{/isPathParam}}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{{#isQueryParam}}{{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}}{{#swaggerAnnotations}}@ApiParam(value = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}, allowableValues = "{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{#-last}}{{/-last}}{{/values}}"{{/allowableValues}}{{#defaultValue}}, defaultValue = "{{{defaultValue}}}"{{/defaultValue}}) {{#useBeanValidation}}@Valid{{/useBeanValidation}}{{/swaggerAnnotations}} @RequestParam(value = "{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) {{paramName}}: {{>optionalDataType}}{{/isQueryParam}}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{{#isMapContainer}}{{#reactive}}Mono<{{/reactive}}Map<String, {{{returnType}}}{{#reactive}}>{{/reactive}}>{{/isMapContainer}}{{#isListContainer}}{{#reactive}}Flux{{/reactive}}{{^reactive}}List{{/reactive}}<{{{returnType}}}>{{/isListContainer}}{{^returnContainer}}{{#reactive}}Mono<{{{returnType}}}>{{/reactive}}{{^reactive}}{{{returnType}}}{{/reactive}}{{/returnContainer}}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{{#serviceInterface}}ResponseEntity(service.{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}), HttpStatus.OK){{/serviceInterface}}{{^serviceInterface}}ResponseEntity(HttpStatus.NOT_IMPLEMENTED){{/serviceInterface}}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package {{package}}
|
||||||
|
|
||||||
|
{{#imports}}import {{import}}
|
||||||
|
{{/imports}}
|
||||||
|
|
||||||
|
{{#operations}}
|
||||||
|
interface {{classname}}Service {
|
||||||
|
{{#operation}}
|
||||||
|
|
||||||
|
fun {{operationId}}({{#allParams}}{{paramName}}: {{^isFile}}{{>optionalDataType}}{{/isFile}}{{#isFile}}org.springframework.web.multipart.MultipartFile{{/isFile}}{{#hasMore}},{{/hasMore}}{{/allParams}}): {{>returnTypes}}
|
||||||
|
{{/operation}}
|
||||||
|
}
|
||||||
|
{{/operations}}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package {{package}}
|
||||||
|
|
||||||
|
{{#imports}}import {{import}}
|
||||||
|
{{/imports}}
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
|
||||||
|
@Service
|
||||||
|
{{#operations}}
|
||||||
|
class {{classname}}ServiceImpl : {{classname}}Service {
|
||||||
|
{{#operation}}
|
||||||
|
|
||||||
|
override fun {{operationId}}({{#allParams}}{{paramName}}: {{^isFile}}{{>optionalDataType}}{{/isFile}}{{#isFile}}org.springframework.web.multipart.MultipartFile{{/isFile}}{{#hasMore}},{{/hasMore}}{{/allParams}}): {{>returnTypes}} {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
{{/operation}}
|
||||||
|
}
|
||||||
|
{{/operations}}
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
package org.openapitools.codegen.kotlin.spring;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.models.OpenAPI;
|
||||||
|
import io.swagger.v3.oas.models.info.Info;
|
||||||
|
import io.swagger.v3.oas.models.servers.Server;
|
||||||
|
import org.openapitools.codegen.CodegenConstants;
|
||||||
|
import org.openapitools.codegen.languages.KotlinSpringServerCodegen;
|
||||||
|
import org.testng.Assert;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
public class KotlinSpringServerCodegenTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInitialConfigValues() throws Exception {
|
||||||
|
final KotlinSpringServerCodegen codegen = new KotlinSpringServerCodegen();
|
||||||
|
codegen.processOpts();
|
||||||
|
|
||||||
|
final OpenAPI openAPI = new OpenAPI();
|
||||||
|
openAPI.addServersItem(new Server().url("https://api.abcde.xy:8082/v2"));
|
||||||
|
openAPI.setInfo(new Info());
|
||||||
|
codegen.preprocessOpenAPI(openAPI);
|
||||||
|
|
||||||
|
Assert.assertEquals(codegen.getLibrary(), KotlinSpringServerCodegen.SPRING_BOOT);
|
||||||
|
Assert.assertTrue(codegen.supportedLibraries().containsKey(KotlinSpringServerCodegen.SPRING_BOOT));
|
||||||
|
|
||||||
|
Assert.assertEquals(codegen.modelPackage(), "org.openapitools.model");
|
||||||
|
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.MODEL_PACKAGE), "org.openapitools.model");
|
||||||
|
Assert.assertEquals(codegen.apiPackage(), "org.openapitools.api");
|
||||||
|
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.API_PACKAGE), "org.openapitools.api");
|
||||||
|
Assert.assertEquals(codegen.getBasePackage(), "org.openapitools");
|
||||||
|
Assert.assertEquals(codegen.additionalProperties().get(KotlinSpringServerCodegen.BASE_PACKAGE), "org.openapitools");
|
||||||
|
Assert.assertEquals(codegen.getServerPort(), "8080");
|
||||||
|
Assert.assertEquals(codegen.additionalProperties().get(KotlinSpringServerCodegen.SERVER_PORT), "8080");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSettersForConfigValues() throws Exception {
|
||||||
|
final KotlinSpringServerCodegen codegen = new KotlinSpringServerCodegen();
|
||||||
|
codegen.setModelPackage("xx.yyyyyyyy.model");
|
||||||
|
codegen.setApiPackage("xx.yyyyyyyy.api");
|
||||||
|
codegen.setBasePackage("xx.yyyyyyyy.base");
|
||||||
|
codegen.setServerPort("8181");
|
||||||
|
codegen.setExceptionHandler(false);
|
||||||
|
codegen.setGradleBuildFile(false);
|
||||||
|
codegen.setSwaggerAnnotations(true);
|
||||||
|
codegen.setServiceInterface(true);
|
||||||
|
codegen.setServiceImplementation(true);
|
||||||
|
codegen.setUseBeanValidation(false);
|
||||||
|
codegen.processOpts();
|
||||||
|
|
||||||
|
Assert.assertEquals(codegen.modelPackage(), "xx.yyyyyyyy.model");
|
||||||
|
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.MODEL_PACKAGE), "xx.yyyyyyyy.model");
|
||||||
|
Assert.assertEquals(codegen.apiPackage(), "xx.yyyyyyyy.api");
|
||||||
|
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.API_PACKAGE), "xx.yyyyyyyy.api");
|
||||||
|
Assert.assertEquals(codegen.getBasePackage(), "xx.yyyyyyyy.base");
|
||||||
|
Assert.assertEquals(codegen.additionalProperties().get(KotlinSpringServerCodegen.BASE_PACKAGE), "xx.yyyyyyyy.base");
|
||||||
|
Assert.assertEquals(codegen.getServerPort(), "8181");
|
||||||
|
Assert.assertEquals(codegen.additionalProperties().get(KotlinSpringServerCodegen.SERVER_PORT), "8181");
|
||||||
|
Assert.assertFalse(codegen.getExceptionHandler());
|
||||||
|
Assert.assertEquals(codegen.additionalProperties().get(KotlinSpringServerCodegen.EXCEPTION_HANDLER), false);
|
||||||
|
Assert.assertFalse(codegen.getGradleBuildFile());
|
||||||
|
Assert.assertEquals(codegen.additionalProperties().get(KotlinSpringServerCodegen.GRADLE_BUILD_FILE), false);
|
||||||
|
Assert.assertTrue(codegen.getSwaggerAnnotations());
|
||||||
|
Assert.assertEquals(codegen.additionalProperties().get(KotlinSpringServerCodegen.SWAGGER_ANNOTATIONS), true);
|
||||||
|
Assert.assertTrue(codegen.getServiceInterface());
|
||||||
|
Assert.assertEquals(codegen.additionalProperties().get(KotlinSpringServerCodegen.SERVICE_INTERFACE), true);
|
||||||
|
Assert.assertTrue(codegen.getServiceImplementation());
|
||||||
|
Assert.assertEquals(codegen.additionalProperties().get(KotlinSpringServerCodegen.SERVICE_IMPLEMENTATION), true);
|
||||||
|
Assert.assertFalse(codegen.getUseBeanValidation());
|
||||||
|
Assert.assertEquals(codegen.additionalProperties().get(KotlinSpringServerCodegen.USE_BEANVALIDATION), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAdditionalPropertiesPutForConfigValues() throws Exception {
|
||||||
|
final KotlinSpringServerCodegen codegen = new KotlinSpringServerCodegen();
|
||||||
|
codegen.additionalProperties().put(CodegenConstants.MODEL_PACKAGE, "xyz.yyyyy.mmmmm.model");
|
||||||
|
codegen.additionalProperties().put(CodegenConstants.API_PACKAGE, "xyz.yyyyy.aaaaa.api");
|
||||||
|
codegen.additionalProperties().put(KotlinSpringServerCodegen.BASE_PACKAGE, "xyz.yyyyy.bbbb.base");
|
||||||
|
codegen.additionalProperties().put(KotlinSpringServerCodegen.SERVER_PORT, "8088");
|
||||||
|
codegen.additionalProperties().put(KotlinSpringServerCodegen.EXCEPTION_HANDLER, false);
|
||||||
|
codegen.additionalProperties().put(KotlinSpringServerCodegen.GRADLE_BUILD_FILE, false);
|
||||||
|
codegen.additionalProperties().put(KotlinSpringServerCodegen.SWAGGER_ANNOTATIONS, true);
|
||||||
|
codegen.additionalProperties().put(KotlinSpringServerCodegen.SERVICE_INTERFACE, true);
|
||||||
|
codegen.additionalProperties().put(KotlinSpringServerCodegen.SERVICE_IMPLEMENTATION, true);
|
||||||
|
codegen.additionalProperties().put(KotlinSpringServerCodegen.USE_BEANVALIDATION, false);
|
||||||
|
codegen.processOpts();
|
||||||
|
|
||||||
|
final OpenAPI openAPI = new OpenAPI();
|
||||||
|
openAPI.addServersItem(new Server().url("https://api.abcde.xy:8082/v2"));
|
||||||
|
openAPI.setInfo(new Info());
|
||||||
|
openAPI.getInfo().setTitle("Some test API");
|
||||||
|
codegen.preprocessOpenAPI(openAPI);
|
||||||
|
|
||||||
|
Assert.assertEquals(codegen.modelPackage(), "xyz.yyyyy.mmmmm.model");
|
||||||
|
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.MODEL_PACKAGE), "xyz.yyyyy.mmmmm.model");
|
||||||
|
Assert.assertEquals(codegen.apiPackage(), "xyz.yyyyy.aaaaa.api");
|
||||||
|
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.API_PACKAGE), "xyz.yyyyy.aaaaa.api");
|
||||||
|
Assert.assertEquals(codegen.getBasePackage(), "xyz.yyyyy.bbbb.base");
|
||||||
|
Assert.assertEquals(codegen.additionalProperties().get(KotlinSpringServerCodegen.BASE_PACKAGE), "xyz.yyyyy.bbbb.base");
|
||||||
|
Assert.assertEquals(codegen.additionalProperties().get(KotlinSpringServerCodegen.TITLE), "someTest");
|
||||||
|
Assert.assertEquals(codegen.additionalProperties().get(KotlinSpringServerCodegen.SERVER_PORT), "8088");
|
||||||
|
Assert.assertFalse(codegen.getExceptionHandler());
|
||||||
|
Assert.assertEquals(codegen.additionalProperties().get(KotlinSpringServerCodegen.EXCEPTION_HANDLER), false);
|
||||||
|
Assert.assertFalse(codegen.getGradleBuildFile());
|
||||||
|
Assert.assertEquals(codegen.additionalProperties().get(KotlinSpringServerCodegen.GRADLE_BUILD_FILE), false);
|
||||||
|
Assert.assertTrue(codegen.getSwaggerAnnotations());
|
||||||
|
Assert.assertEquals(codegen.additionalProperties().get(KotlinSpringServerCodegen.SWAGGER_ANNOTATIONS), true);
|
||||||
|
Assert.assertTrue(codegen.getServiceInterface());
|
||||||
|
Assert.assertEquals(codegen.additionalProperties().get(KotlinSpringServerCodegen.SERVICE_INTERFACE), true);
|
||||||
|
Assert.assertTrue(codegen.getServiceImplementation());
|
||||||
|
Assert.assertEquals(codegen.additionalProperties().get(KotlinSpringServerCodegen.SERVICE_IMPLEMENTATION), true);
|
||||||
|
Assert.assertFalse(codegen.getUseBeanValidation());
|
||||||
|
Assert.assertEquals(codegen.additionalProperties().get(KotlinSpringServerCodegen.USE_BEANVALIDATION), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
3.2.3-SNAPSHOT
|
||||||
21
samples/server/openapi3/petstore/kotlin-springboot/README.md
Normal file
21
samples/server/openapi3/petstore/kotlin-springboot/README.md
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# openAPIPetstore
|
||||||
|
|
||||||
|
This Kotlin based [Spring Boot](https://spring.io/projects/spring-boot) application has been generated using the [OpenAPI Generator](https://github.com/OpenAPITools/openapi-generator).
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
This document assumes you have either maven or gradle available, either via the wrapper or otherwise. This does not come with a gradle / maven wrapper checked in.
|
||||||
|
|
||||||
|
By default a [`pom.xml`](pom.xml) file will be generated. If you specified `gradleBuildFile=true` when generating this project, a `build.gradle.kts` will also be generated. Note this uses [Gradle Kotlin DSL](https://github.com/gradle/kotlin-dsl).
|
||||||
|
|
||||||
|
To build the project using maven, run:
|
||||||
|
```bash
|
||||||
|
mvn package && java -jar target/openapi-spring-1.0.0.jar
|
||||||
|
```
|
||||||
|
|
||||||
|
To build the project using gradle, run:
|
||||||
|
```bash
|
||||||
|
gradle build && java -jar build/libs/openapi-spring-1.0.0.jar
|
||||||
|
```
|
||||||
|
|
||||||
|
If all builds successfully, the server should run on [http://localhost:8080/](http://localhost:8080/)
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
|
|
||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.0.3.RELEASE")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
group = "org.openapitools"
|
||||||
|
version = "1.0.0"
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType<KotlinCompile> {
|
||||||
|
kotlinOptions.jvmTarget = "1.8"
|
||||||
|
}
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
val kotlinVersion = "1.2.60"
|
||||||
|
id("org.jetbrains.kotlin.jvm") version kotlinVersion
|
||||||
|
id("org.jetbrains.kotlin.plugin.jpa") version kotlinVersion
|
||||||
|
id("org.jetbrains.kotlin.plugin.spring") version kotlinVersion
|
||||||
|
id("org.springframework.boot") version "2.0.3.RELEASE"
|
||||||
|
id("io.spring.dependency-management") version "1.0.5.RELEASE"
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
|
||||||
|
compile("org.jetbrains.kotlin:kotlin-reflect")
|
||||||
|
compile("org.springframework.boot:spring-boot-starter-web")
|
||||||
|
compile("io.swagger:swagger-annotations:1.5.21")
|
||||||
|
compile("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml")
|
||||||
|
compile("com.fasterxml.jackson.dataformat:jackson-dataformat-xml")
|
||||||
|
|
||||||
|
testCompile("org.springframework.boot:spring-boot-starter-test") {
|
||||||
|
exclude(module = "junit")
|
||||||
|
}
|
||||||
|
}
|
||||||
105
samples/server/openapi3/petstore/kotlin-springboot/pom.xml
Normal file
105
samples/server/openapi3/petstore/kotlin-springboot/pom.xml
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
<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>org.openapitools</groupId>
|
||||||
|
<artifactId>openapi-spring</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<name>openapi-spring</name>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<properties>
|
||||||
|
<kotlin.version>1.2.60</kotlin.version>
|
||||||
|
</properties>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>2.0.3.RELEASE</version>
|
||||||
|
</parent>
|
||||||
|
<build>
|
||||||
|
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
|
||||||
|
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>repackage</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>kotlin-maven-plugin</artifactId>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<compilerPlugins>
|
||||||
|
<plugin>spring</plugin>
|
||||||
|
</compilerPlugins>
|
||||||
|
<jvmTarget>1.8</jvmTarget>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>compile</id>
|
||||||
|
<phase>compile</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>compile</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>test-compile</id>
|
||||||
|
<phase>test-compile</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>test-compile</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-maven-allopen</artifactId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-reflect</artifactId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.swagger</groupId>
|
||||||
|
<artifactId>swagger-annotations</artifactId>
|
||||||
|
<version>1.5.21</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||||
|
<artifactId>jackson-dataformat-yaml</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||||
|
<artifactId>jackson-dataformat-xml</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||||
|
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- Bean Validation API support -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.validation</groupId>
|
||||||
|
<artifactId>validation-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
rootProject.name = "openapi-spring"
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package org.openapitools
|
||||||
|
|
||||||
|
import org.springframework.boot.runApplication
|
||||||
|
import org.springframework.context.annotation.ComponentScan
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication
|
||||||
|
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
@ComponentScan(basePackages = ["org.openapitools", "org.openapitools.api", "org.openapitools.model"])
|
||||||
|
class Application
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
runApplication<Application>(*args)
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package org.openapitools.api
|
||||||
|
|
||||||
|
import org.springframework.http.HttpStatus
|
||||||
|
import org.springframework.web.bind.annotation.ControllerAdvice
|
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler
|
||||||
|
import javax.servlet.http.HttpServletResponse
|
||||||
|
import javax.validation.ConstraintViolationException
|
||||||
|
|
||||||
|
// TODO Extend ApiException for custom exception handling, e.g. the below NotFound exception
|
||||||
|
sealed class ApiException(msg: String, val code: Int) : Exception(msg)
|
||||||
|
|
||||||
|
class NotFoundException(msg: String, code: Int = HttpStatus.NOT_FOUND.value()) : ApiException(msg, code)
|
||||||
|
|
||||||
|
|
||||||
|
@ControllerAdvice
|
||||||
|
class DefaultExceptionHandler {
|
||||||
|
|
||||||
|
@ExceptionHandler(value = [ApiException::class])
|
||||||
|
fun onApiException(ex: ApiException, response: HttpServletResponse): Unit =
|
||||||
|
response.sendError(ex.code, ex.message)
|
||||||
|
|
||||||
|
@ExceptionHandler(value = [NotImplementedError::class])
|
||||||
|
fun onNotImplemented(ex: NotImplementedError, response: HttpServletResponse): Unit =
|
||||||
|
response.sendError(HttpStatus.NOT_IMPLEMENTED.value())
|
||||||
|
|
||||||
|
@ExceptionHandler(value = [ConstraintViolationException::class])
|
||||||
|
fun onConstraintViolation(ex: ConstraintViolationException, response: HttpServletResponse): Unit =
|
||||||
|
response.sendError(HttpStatus.BAD_REQUEST.value(), ex.constraintViolations.joinToString(", ") { it.message })
|
||||||
|
}
|
||||||
@@ -0,0 +1,159 @@
|
|||||||
|
package org.openapitools.api
|
||||||
|
|
||||||
|
import org.openapitools.model.ModelApiResponse
|
||||||
|
import org.openapitools.model.Pet
|
||||||
|
import io.swagger.annotations.*
|
||||||
|
import org.springframework.http.HttpStatus
|
||||||
|
import org.springframework.http.MediaType
|
||||||
|
import org.springframework.http.ResponseEntity
|
||||||
|
import org.springframework.stereotype.Controller
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody
|
||||||
|
import org.springframework.web.bind.annotation.RequestPart
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable
|
||||||
|
import org.springframework.web.bind.annotation.RequestHeader
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping
|
||||||
|
import org.springframework.validation.annotation.Validated
|
||||||
|
import org.springframework.web.context.request.NativeWebRequest
|
||||||
|
import org.springframework.web.multipart.MultipartFile
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
|
||||||
|
import javax.validation.Valid
|
||||||
|
import javax.validation.constraints.*
|
||||||
|
|
||||||
|
import kotlin.collections.List
|
||||||
|
import kotlin.collections.Map
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@Validated
|
||||||
|
@Api(value = "Pet", description = "The Pet API")
|
||||||
|
@RequestMapping("\${openapi.openAPIPetstore.base-path:/v2}")
|
||||||
|
class PetApiController(@Autowired(required = true) val service: PetApiService) {
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Add a new pet to the store",
|
||||||
|
nickname = "addPet",
|
||||||
|
notes = "",
|
||||||
|
authorizations = [Authorization(value = "petstore_auth", scopes = [AuthorizationScope(scope = "write:pets", description = "modify pets in your account"), AuthorizationScope(scope = "read:pets", description = "read your pets")])])
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 405, message = "Invalid input")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/pet"],
|
||||||
|
consumes = ["application/json", "application/xml"],
|
||||||
|
method = [RequestMethod.POST])
|
||||||
|
fun addPet(@ApiParam(value = "Pet object that needs to be added to the store" ,required=true ) @Valid @RequestBody pet: Pet): ResponseEntity<Unit> {
|
||||||
|
return ResponseEntity(service.addPet(pet), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Deletes a pet",
|
||||||
|
nickname = "deletePet",
|
||||||
|
notes = "",
|
||||||
|
authorizations = [Authorization(value = "petstore_auth", scopes = [AuthorizationScope(scope = "write:pets", description = "modify pets in your account"), AuthorizationScope(scope = "read:pets", description = "read your pets")])])
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 400, message = "Invalid pet value")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/pet/{petId}"],
|
||||||
|
method = [RequestMethod.DELETE])
|
||||||
|
fun deletePet(@ApiParam(value = "Pet id to delete", required=true) @PathVariable("petId") petId: kotlin.Long,@ApiParam(value = "" ) @RequestHeader(value="api_key", required=false) apiKey: kotlin.String): ResponseEntity<Unit> {
|
||||||
|
return ResponseEntity(service.deletePet(petId, apiKey), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Finds Pets by status",
|
||||||
|
nickname = "findPetsByStatus",
|
||||||
|
notes = "Multiple status values can be provided with comma separated strings",
|
||||||
|
response = Pet::class,
|
||||||
|
responseContainer = "List",
|
||||||
|
authorizations = [Authorization(value = "petstore_auth", scopes = [AuthorizationScope(scope = "write:pets", description = "modify pets in your account"), AuthorizationScope(scope = "read:pets", description = "read your pets")])])
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 200, message = "successful operation", response = Pet::class, responseContainer = "List"),ApiResponse(code = 400, message = "Invalid status value")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/pet/findByStatus"],
|
||||||
|
produces = ["application/xml", "application/json"],
|
||||||
|
method = [RequestMethod.GET])
|
||||||
|
fun findPetsByStatus(@NotNull @ApiParam(value = "Status values that need to be considered for filter", required = true, allowableValues = "available, pending, sold") @Valid @RequestParam(value = "status", required = true) status: kotlin.Array<kotlin.String>): ResponseEntity<List<Pet>> {
|
||||||
|
return ResponseEntity(service.findPetsByStatus(status), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Finds Pets by tags",
|
||||||
|
nickname = "findPetsByTags",
|
||||||
|
notes = "Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.",
|
||||||
|
response = Pet::class,
|
||||||
|
responseContainer = "List",
|
||||||
|
authorizations = [Authorization(value = "petstore_auth", scopes = [AuthorizationScope(scope = "write:pets", description = "modify pets in your account"), AuthorizationScope(scope = "read:pets", description = "read your pets")])])
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 200, message = "successful operation", response = Pet::class, responseContainer = "List"),ApiResponse(code = 400, message = "Invalid tag value")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/pet/findByTags"],
|
||||||
|
produces = ["application/xml", "application/json"],
|
||||||
|
method = [RequestMethod.GET])
|
||||||
|
fun findPetsByTags(@NotNull @ApiParam(value = "Tags to filter by", required = true) @Valid @RequestParam(value = "tags", required = true) tags: kotlin.Array<kotlin.String>): ResponseEntity<List<Pet>> {
|
||||||
|
return ResponseEntity(service.findPetsByTags(tags), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Find pet by ID",
|
||||||
|
nickname = "getPetById",
|
||||||
|
notes = "Returns a single pet",
|
||||||
|
response = Pet::class,
|
||||||
|
authorizations = [Authorization(value = "api_key")])
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 200, message = "successful operation", response = Pet::class),ApiResponse(code = 400, message = "Invalid ID supplied"),ApiResponse(code = 404, message = "Pet not found")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/pet/{petId}"],
|
||||||
|
produces = ["application/xml", "application/json"],
|
||||||
|
method = [RequestMethod.GET])
|
||||||
|
fun getPetById(@ApiParam(value = "ID of pet to return", required=true) @PathVariable("petId") petId: kotlin.Long): ResponseEntity<Pet> {
|
||||||
|
return ResponseEntity(service.getPetById(petId), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Update an existing pet",
|
||||||
|
nickname = "updatePet",
|
||||||
|
notes = "",
|
||||||
|
authorizations = [Authorization(value = "petstore_auth", scopes = [AuthorizationScope(scope = "write:pets", description = "modify pets in your account"), AuthorizationScope(scope = "read:pets", description = "read your pets")])])
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 400, message = "Invalid ID supplied"),ApiResponse(code = 404, message = "Pet not found"),ApiResponse(code = 405, message = "Validation exception")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/pet"],
|
||||||
|
consumes = ["application/json", "application/xml"],
|
||||||
|
method = [RequestMethod.PUT])
|
||||||
|
fun updatePet(@ApiParam(value = "Pet object that needs to be added to the store" ,required=true ) @Valid @RequestBody pet: Pet): ResponseEntity<Unit> {
|
||||||
|
return ResponseEntity(service.updatePet(pet), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Updates a pet in the store with form data",
|
||||||
|
nickname = "updatePetWithForm",
|
||||||
|
notes = "",
|
||||||
|
authorizations = [Authorization(value = "petstore_auth", scopes = [AuthorizationScope(scope = "write:pets", description = "modify pets in your account"), AuthorizationScope(scope = "read:pets", description = "read your pets")])])
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 405, message = "Invalid input")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/pet/{petId}"],
|
||||||
|
consumes = ["application/x-www-form-urlencoded"],
|
||||||
|
method = [RequestMethod.POST])
|
||||||
|
fun updatePetWithForm(@ApiParam(value = "ID of pet that needs to be updated", required=true) @PathVariable("petId") petId: kotlin.Long,@ApiParam(value = "Updated name of the pet", defaultValue="null") @RequestParam(value="name", required=false) name: kotlin.String ,@ApiParam(value = "Updated status of the pet", defaultValue="null") @RequestParam(value="status", required=false) status: kotlin.String ): ResponseEntity<Unit> {
|
||||||
|
return ResponseEntity(service.updatePetWithForm(petId, name, status), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "uploads an image",
|
||||||
|
nickname = "uploadFile",
|
||||||
|
notes = "",
|
||||||
|
response = ModelApiResponse::class,
|
||||||
|
authorizations = [Authorization(value = "petstore_auth", scopes = [AuthorizationScope(scope = "write:pets", description = "modify pets in your account"), AuthorizationScope(scope = "read:pets", description = "read your pets")])])
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 200, message = "successful operation", response = ModelApiResponse::class)])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/pet/{petId}/uploadImage"],
|
||||||
|
produces = ["application/json"],
|
||||||
|
consumes = ["multipart/form-data"],
|
||||||
|
method = [RequestMethod.POST])
|
||||||
|
fun uploadFile(@ApiParam(value = "ID of pet to update", required=true) @PathVariable("petId") petId: kotlin.Long,@ApiParam(value = "Additional data to pass to server", defaultValue="null") @RequestParam(value="additionalMetadata", required=false) additionalMetadata: kotlin.String ,@ApiParam(value = "file detail") @Valid @RequestPart("file") file: MultipartFile): ResponseEntity<ModelApiResponse> {
|
||||||
|
return ResponseEntity(service.uploadFile(petId, additionalMetadata, file), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package org.openapitools.api
|
||||||
|
|
||||||
|
import org.openapitools.model.ModelApiResponse
|
||||||
|
import org.openapitools.model.Pet
|
||||||
|
|
||||||
|
interface PetApiService {
|
||||||
|
|
||||||
|
fun addPet(pet: Pet): Unit
|
||||||
|
|
||||||
|
fun deletePet(petId: kotlin.Long,apiKey: kotlin.String): Unit
|
||||||
|
|
||||||
|
fun findPetsByStatus(status: kotlin.Array<kotlin.String>): List<Pet>
|
||||||
|
|
||||||
|
fun findPetsByTags(tags: kotlin.Array<kotlin.String>): List<Pet>
|
||||||
|
|
||||||
|
fun getPetById(petId: kotlin.Long): Pet
|
||||||
|
|
||||||
|
fun updatePet(pet: Pet): Unit
|
||||||
|
|
||||||
|
fun updatePetWithForm(petId: kotlin.Long,name: kotlin.String,status: kotlin.String): Unit
|
||||||
|
|
||||||
|
fun uploadFile(petId: kotlin.Long,additionalMetadata: kotlin.String,file: org.springframework.web.multipart.MultipartFile): ModelApiResponse
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package org.openapitools.api
|
||||||
|
|
||||||
|
import org.openapitools.model.ModelApiResponse
|
||||||
|
import org.openapitools.model.Pet
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
|
||||||
|
@Service
|
||||||
|
class PetApiServiceImpl : PetApiService {
|
||||||
|
|
||||||
|
override fun addPet(pet: Pet): Unit {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun deletePet(petId: kotlin.Long,apiKey: kotlin.String): Unit {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun findPetsByStatus(status: kotlin.Array<kotlin.String>): List<Pet> {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun findPetsByTags(tags: kotlin.Array<kotlin.String>): List<Pet> {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getPetById(petId: kotlin.Long): Pet {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updatePet(pet: Pet): Unit {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updatePetWithForm(petId: kotlin.Long,name: kotlin.String,status: kotlin.String): Unit {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun uploadFile(petId: kotlin.Long,additionalMetadata: kotlin.String,file: org.springframework.web.multipart.MultipartFile): ModelApiResponse {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
package org.openapitools.api
|
||||||
|
|
||||||
|
import org.openapitools.model.Order
|
||||||
|
import io.swagger.annotations.*
|
||||||
|
import org.springframework.http.HttpStatus
|
||||||
|
import org.springframework.http.MediaType
|
||||||
|
import org.springframework.http.ResponseEntity
|
||||||
|
import org.springframework.stereotype.Controller
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody
|
||||||
|
import org.springframework.web.bind.annotation.RequestPart
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable
|
||||||
|
import org.springframework.web.bind.annotation.RequestHeader
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping
|
||||||
|
import org.springframework.validation.annotation.Validated
|
||||||
|
import org.springframework.web.context.request.NativeWebRequest
|
||||||
|
import org.springframework.web.multipart.MultipartFile
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
|
||||||
|
import javax.validation.Valid
|
||||||
|
import javax.validation.constraints.*
|
||||||
|
|
||||||
|
import kotlin.collections.List
|
||||||
|
import kotlin.collections.Map
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@Validated
|
||||||
|
@Api(value = "Store", description = "The Store API")
|
||||||
|
@RequestMapping("\${openapi.openAPIPetstore.base-path:/v2}")
|
||||||
|
class StoreApiController(@Autowired(required = true) val service: StoreApiService) {
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Delete purchase order by ID",
|
||||||
|
nickname = "deleteOrder",
|
||||||
|
notes = "For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors")
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 400, message = "Invalid ID supplied"),ApiResponse(code = 404, message = "Order not found")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/store/order/{orderId}"],
|
||||||
|
method = [RequestMethod.DELETE])
|
||||||
|
fun deleteOrder(@ApiParam(value = "ID of the order that needs to be deleted", required=true) @PathVariable("orderId") orderId: kotlin.String): ResponseEntity<Unit> {
|
||||||
|
return ResponseEntity(service.deleteOrder(orderId), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Returns pet inventories by status",
|
||||||
|
nickname = "getInventory",
|
||||||
|
notes = "Returns a map of status codes to quantities",
|
||||||
|
response = kotlin.Int::class,
|
||||||
|
responseContainer = "Map",
|
||||||
|
authorizations = [Authorization(value = "api_key")])
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 200, message = "successful operation", response = kotlin.collections.Map::class, responseContainer = "Map")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/store/inventory"],
|
||||||
|
produces = ["application/json"],
|
||||||
|
method = [RequestMethod.GET])
|
||||||
|
fun getInventory(): ResponseEntity<Map<String, kotlin.Int>> {
|
||||||
|
return ResponseEntity(service.getInventory(), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Find purchase order by ID",
|
||||||
|
nickname = "getOrderById",
|
||||||
|
notes = "For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions",
|
||||||
|
response = Order::class)
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 200, message = "successful operation", response = Order::class),ApiResponse(code = 400, message = "Invalid ID supplied"),ApiResponse(code = 404, message = "Order not found")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/store/order/{orderId}"],
|
||||||
|
produces = ["application/xml", "application/json"],
|
||||||
|
method = [RequestMethod.GET])
|
||||||
|
fun getOrderById(@Min(1L) @Max(5L) @ApiParam(value = "ID of pet that needs to be fetched", required=true) @PathVariable("orderId") orderId: kotlin.Long): ResponseEntity<Order> {
|
||||||
|
return ResponseEntity(service.getOrderById(orderId), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Place an order for a pet",
|
||||||
|
nickname = "placeOrder",
|
||||||
|
notes = "",
|
||||||
|
response = Order::class)
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 200, message = "successful operation", response = Order::class),ApiResponse(code = 400, message = "Invalid Order")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/store/order"],
|
||||||
|
produces = ["application/xml", "application/json"],
|
||||||
|
consumes = ["application/json"],
|
||||||
|
method = [RequestMethod.POST])
|
||||||
|
fun placeOrder(@ApiParam(value = "order placed for purchasing the pet" ,required=true ) @Valid @RequestBody order: Order): ResponseEntity<Order> {
|
||||||
|
return ResponseEntity(service.placeOrder(order), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package org.openapitools.api
|
||||||
|
|
||||||
|
import org.openapitools.model.Order
|
||||||
|
|
||||||
|
interface StoreApiService {
|
||||||
|
|
||||||
|
fun deleteOrder(orderId: kotlin.String): Unit
|
||||||
|
|
||||||
|
fun getInventory(): Map<String, kotlin.Int>
|
||||||
|
|
||||||
|
fun getOrderById(orderId: kotlin.Long): Order
|
||||||
|
|
||||||
|
fun placeOrder(order: Order): Order
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package org.openapitools.api
|
||||||
|
|
||||||
|
import org.openapitools.model.Order
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
|
||||||
|
@Service
|
||||||
|
class StoreApiServiceImpl : StoreApiService {
|
||||||
|
|
||||||
|
override fun deleteOrder(orderId: kotlin.String): Unit {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getInventory(): Map<String, kotlin.Int> {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getOrderById(orderId: kotlin.Long): Order {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun placeOrder(order: Order): Order {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,144 @@
|
|||||||
|
package org.openapitools.api
|
||||||
|
|
||||||
|
import org.openapitools.model.User
|
||||||
|
import io.swagger.annotations.*
|
||||||
|
import org.springframework.http.HttpStatus
|
||||||
|
import org.springframework.http.MediaType
|
||||||
|
import org.springframework.http.ResponseEntity
|
||||||
|
import org.springframework.stereotype.Controller
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody
|
||||||
|
import org.springframework.web.bind.annotation.RequestPart
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable
|
||||||
|
import org.springframework.web.bind.annotation.RequestHeader
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping
|
||||||
|
import org.springframework.validation.annotation.Validated
|
||||||
|
import org.springframework.web.context.request.NativeWebRequest
|
||||||
|
import org.springframework.web.multipart.MultipartFile
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
|
||||||
|
import javax.validation.Valid
|
||||||
|
import javax.validation.constraints.*
|
||||||
|
|
||||||
|
import kotlin.collections.List
|
||||||
|
import kotlin.collections.Map
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@Validated
|
||||||
|
@Api(value = "User", description = "The User API")
|
||||||
|
@RequestMapping("\${openapi.openAPIPetstore.base-path:/v2}")
|
||||||
|
class UserApiController(@Autowired(required = true) val service: UserApiService) {
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Create user",
|
||||||
|
nickname = "createUser",
|
||||||
|
notes = "This can only be done by the logged in user.")
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 200, message = "successful operation")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/user"],
|
||||||
|
consumes = ["application/json"],
|
||||||
|
method = [RequestMethod.POST])
|
||||||
|
fun createUser(@ApiParam(value = "Created user object" ,required=true ) @Valid @RequestBody user: User): ResponseEntity<Unit> {
|
||||||
|
return ResponseEntity(service.createUser(user), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Creates list of users with given input array",
|
||||||
|
nickname = "createUsersWithArrayInput",
|
||||||
|
notes = "")
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 200, message = "successful operation")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/user/createWithArray"],
|
||||||
|
consumes = ["application/json"],
|
||||||
|
method = [RequestMethod.POST])
|
||||||
|
fun createUsersWithArrayInput(@ApiParam(value = "List of user object" ,required=true ) @Valid @RequestBody user: kotlin.Array<User>): ResponseEntity<Unit> {
|
||||||
|
return ResponseEntity(service.createUsersWithArrayInput(user), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Creates list of users with given input array",
|
||||||
|
nickname = "createUsersWithListInput",
|
||||||
|
notes = "")
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 200, message = "successful operation")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/user/createWithList"],
|
||||||
|
consumes = ["application/json"],
|
||||||
|
method = [RequestMethod.POST])
|
||||||
|
fun createUsersWithListInput(@ApiParam(value = "List of user object" ,required=true ) @Valid @RequestBody user: kotlin.Array<User>): ResponseEntity<Unit> {
|
||||||
|
return ResponseEntity(service.createUsersWithListInput(user), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Delete user",
|
||||||
|
nickname = "deleteUser",
|
||||||
|
notes = "This can only be done by the logged in user.")
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 400, message = "Invalid username supplied"),ApiResponse(code = 404, message = "User not found")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/user/{username}"],
|
||||||
|
method = [RequestMethod.DELETE])
|
||||||
|
fun deleteUser(@ApiParam(value = "The name that needs to be deleted", required=true) @PathVariable("username") username: kotlin.String): ResponseEntity<Unit> {
|
||||||
|
return ResponseEntity(service.deleteUser(username), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Get user by user name",
|
||||||
|
nickname = "getUserByName",
|
||||||
|
notes = "",
|
||||||
|
response = User::class)
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 200, message = "successful operation", response = User::class),ApiResponse(code = 400, message = "Invalid username supplied"),ApiResponse(code = 404, message = "User not found")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/user/{username}"],
|
||||||
|
produces = ["application/xml", "application/json"],
|
||||||
|
method = [RequestMethod.GET])
|
||||||
|
fun getUserByName(@ApiParam(value = "The name that needs to be fetched. Use user1 for testing.", required=true) @PathVariable("username") username: kotlin.String): ResponseEntity<User> {
|
||||||
|
return ResponseEntity(service.getUserByName(username), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Logs user into the system",
|
||||||
|
nickname = "loginUser",
|
||||||
|
notes = "",
|
||||||
|
response = kotlin.String::class)
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 200, message = "successful operation", response = kotlin.String::class),ApiResponse(code = 400, message = "Invalid username/password supplied")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/user/login"],
|
||||||
|
produces = ["application/xml", "application/json"],
|
||||||
|
method = [RequestMethod.GET])
|
||||||
|
fun loginUser(@NotNull @ApiParam(value = "The user name for login", required = true) @Valid @RequestParam(value = "username", required = true) username: kotlin.String,@NotNull @ApiParam(value = "The password for login in clear text", required = true) @Valid @RequestParam(value = "password", required = true) password: kotlin.String): ResponseEntity<kotlin.String> {
|
||||||
|
return ResponseEntity(service.loginUser(username, password), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Logs out current logged in user session",
|
||||||
|
nickname = "logoutUser",
|
||||||
|
notes = "")
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 200, message = "successful operation")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/user/logout"],
|
||||||
|
method = [RequestMethod.GET])
|
||||||
|
fun logoutUser(): ResponseEntity<Unit> {
|
||||||
|
return ResponseEntity(service.logoutUser(), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Updated user",
|
||||||
|
nickname = "updateUser",
|
||||||
|
notes = "This can only be done by the logged in user.")
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 400, message = "Invalid user supplied"),ApiResponse(code = 404, message = "User not found")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/user/{username}"],
|
||||||
|
consumes = ["application/json"],
|
||||||
|
method = [RequestMethod.PUT])
|
||||||
|
fun updateUser(@ApiParam(value = "name that need to be deleted", required=true) @PathVariable("username") username: kotlin.String,@ApiParam(value = "Updated user object" ,required=true ) @Valid @RequestBody user: User): ResponseEntity<Unit> {
|
||||||
|
return ResponseEntity(service.updateUser(username, user), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package org.openapitools.api
|
||||||
|
|
||||||
|
import org.openapitools.model.User
|
||||||
|
|
||||||
|
interface UserApiService {
|
||||||
|
|
||||||
|
fun createUser(user: User): Unit
|
||||||
|
|
||||||
|
fun createUsersWithArrayInput(user: kotlin.Array<User>): Unit
|
||||||
|
|
||||||
|
fun createUsersWithListInput(user: kotlin.Array<User>): Unit
|
||||||
|
|
||||||
|
fun deleteUser(username: kotlin.String): Unit
|
||||||
|
|
||||||
|
fun getUserByName(username: kotlin.String): User
|
||||||
|
|
||||||
|
fun loginUser(username: kotlin.String,password: kotlin.String): kotlin.String
|
||||||
|
|
||||||
|
fun logoutUser(): Unit
|
||||||
|
|
||||||
|
fun updateUser(username: kotlin.String,user: User): Unit
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package org.openapitools.api
|
||||||
|
|
||||||
|
import org.openapitools.model.User
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
|
||||||
|
@Service
|
||||||
|
class UserApiServiceImpl : UserApiService {
|
||||||
|
|
||||||
|
override fun createUser(user: User): Unit {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createUsersWithArrayInput(user: kotlin.Array<User>): Unit {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createUsersWithListInput(user: kotlin.Array<User>): Unit {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun deleteUser(username: kotlin.String): Unit {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getUserByName(username: kotlin.String): User {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun loginUser(username: kotlin.String,password: kotlin.String): kotlin.String {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun logoutUser(): Unit {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateUser(username: kotlin.String,user: User): Unit {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package org.openapitools.model
|
||||||
|
|
||||||
|
import java.util.Objects
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
|
import javax.validation.Valid
|
||||||
|
import javax.validation.constraints.*
|
||||||
|
import io.swagger.annotations.ApiModelProperty
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param name Updated name of the pet
|
||||||
|
* @param status Updated status of the pet
|
||||||
|
*/
|
||||||
|
data class Body (
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "Updated name of the pet")
|
||||||
|
@JsonProperty("name") val name: kotlin.String? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "Updated status of the pet")
|
||||||
|
@JsonProperty("status") val status: kotlin.String? = null
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package org.openapitools.model
|
||||||
|
|
||||||
|
import java.util.Objects
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
|
import javax.validation.Valid
|
||||||
|
import javax.validation.constraints.*
|
||||||
|
import io.swagger.annotations.ApiModelProperty
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param additionalMetadata Additional data to pass to server
|
||||||
|
* @param file file to upload
|
||||||
|
*/
|
||||||
|
data class Body1 (
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "Additional data to pass to server")
|
||||||
|
@JsonProperty("additionalMetadata") val additionalMetadata: kotlin.String? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "file to upload")
|
||||||
|
@JsonProperty("file") val file: java.io.File? = null
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package org.openapitools.model
|
||||||
|
|
||||||
|
import java.util.Objects
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
|
import javax.validation.Valid
|
||||||
|
import javax.validation.constraints.*
|
||||||
|
import io.swagger.annotations.ApiModelProperty
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A category for a pet
|
||||||
|
* @param id
|
||||||
|
* @param name
|
||||||
|
*/
|
||||||
|
data class Category (
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("id") val id: kotlin.Long? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("name") val name: kotlin.String? = null
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package org.openapitools.model
|
||||||
|
|
||||||
|
import java.util.Objects
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
|
import javax.validation.Valid
|
||||||
|
import javax.validation.constraints.*
|
||||||
|
import io.swagger.annotations.ApiModelProperty
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes the result of uploading an image resource
|
||||||
|
* @param code
|
||||||
|
* @param type
|
||||||
|
* @param message
|
||||||
|
*/
|
||||||
|
data class ModelApiResponse (
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("code") val code: kotlin.Int? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("type") val type: kotlin.String? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("message") val message: kotlin.String? = null
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package org.openapitools.model
|
||||||
|
|
||||||
|
import java.util.Objects
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
|
import com.fasterxml.jackson.annotation.JsonValue
|
||||||
|
import javax.validation.Valid
|
||||||
|
import javax.validation.constraints.*
|
||||||
|
import io.swagger.annotations.ApiModelProperty
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 (
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("id") val id: kotlin.Long? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("petId") val petId: kotlin.Long? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("quantity") val quantity: kotlin.Int? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("shipDate") val shipDate: java.time.OffsetDateTime? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "Order Status")
|
||||||
|
@JsonProperty("status") val status: Order.Status? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("complete") val complete: kotlin.Boolean? = null
|
||||||
|
) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Order Status
|
||||||
|
* Values: placed,approved,delivered
|
||||||
|
*/
|
||||||
|
enum class Status(val value: kotlin.String) {
|
||||||
|
|
||||||
|
@JsonProperty("placed") placed("placed"),
|
||||||
|
|
||||||
|
@JsonProperty("approved") approved("approved"),
|
||||||
|
|
||||||
|
@JsonProperty("delivered") delivered("delivered");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package org.openapitools.model
|
||||||
|
|
||||||
|
import java.util.Objects
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
|
import com.fasterxml.jackson.annotation.JsonValue
|
||||||
|
import org.openapitools.model.Category
|
||||||
|
import org.openapitools.model.Tag
|
||||||
|
import javax.validation.Valid
|
||||||
|
import javax.validation.constraints.*
|
||||||
|
import io.swagger.annotations.ApiModelProperty
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A pet for sale in the pet store
|
||||||
|
* @param id
|
||||||
|
* @param category
|
||||||
|
* @param name
|
||||||
|
* @param photoUrls
|
||||||
|
* @param tags
|
||||||
|
* @param status pet status in the store
|
||||||
|
*/
|
||||||
|
data class Pet (
|
||||||
|
|
||||||
|
@get:NotNull
|
||||||
|
@ApiModelProperty(example = "doggie", required = true, value = "")
|
||||||
|
@JsonProperty("name") val name: kotlin.String,
|
||||||
|
|
||||||
|
@get:NotNull
|
||||||
|
@ApiModelProperty(required = true, value = "")
|
||||||
|
@JsonProperty("photoUrls") val photoUrls: kotlin.Array<kotlin.String>,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("id") val id: kotlin.Long? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("category") val category: Category? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("tags") val tags: kotlin.Array<Tag>? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "pet status in the store")
|
||||||
|
@JsonProperty("status") val status: Pet.Status? = null
|
||||||
|
) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pet status in the store
|
||||||
|
* Values: available,pending,sold
|
||||||
|
*/
|
||||||
|
enum class Status(val value: kotlin.String) {
|
||||||
|
|
||||||
|
@JsonProperty("available") available("available"),
|
||||||
|
|
||||||
|
@JsonProperty("pending") pending("pending"),
|
||||||
|
|
||||||
|
@JsonProperty("sold") sold("sold");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package org.openapitools.model
|
||||||
|
|
||||||
|
import java.util.Objects
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
|
import javax.validation.Valid
|
||||||
|
import javax.validation.constraints.*
|
||||||
|
import io.swagger.annotations.ApiModelProperty
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A tag for a pet
|
||||||
|
* @param id
|
||||||
|
* @param name
|
||||||
|
*/
|
||||||
|
data class Tag (
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("id") val id: kotlin.Long? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("name") val name: kotlin.String? = null
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package org.openapitools.model
|
||||||
|
|
||||||
|
import java.util.Objects
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
|
import javax.validation.Valid
|
||||||
|
import javax.validation.constraints.*
|
||||||
|
import io.swagger.annotations.ApiModelProperty
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 (
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("id") val id: kotlin.Long? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("username") val username: kotlin.String? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("firstName") val firstName: kotlin.String? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("lastName") val lastName: kotlin.String? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("email") val email: kotlin.String? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("password") val password: kotlin.String? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("phone") val phone: kotlin.String? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "User Status")
|
||||||
|
@JsonProperty("userStatus") val userStatus: kotlin.Int? = null
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
spring.application.name=openAPIPetstore
|
||||||
|
server.port=8080
|
||||||
|
spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false
|
||||||
@@ -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
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
3.2.3-SNAPSHOT
|
||||||
21
samples/server/petstore/kotlin-springboot/README.md
Normal file
21
samples/server/petstore/kotlin-springboot/README.md
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# openAPIPetstore
|
||||||
|
|
||||||
|
This Kotlin based [Spring Boot](https://spring.io/projects/spring-boot) application has been generated using the [OpenAPI Generator](https://github.com/OpenAPITools/openapi-generator).
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
This document assumes you have either maven or gradle available, either via the wrapper or otherwise. This does not come with a gradle / maven wrapper checked in.
|
||||||
|
|
||||||
|
By default a [`pom.xml`](pom.xml) file will be generated. If you specified `gradleBuildFile=true` when generating this project, a `build.gradle.kts` will also be generated. Note this uses [Gradle Kotlin DSL](https://github.com/gradle/kotlin-dsl).
|
||||||
|
|
||||||
|
To build the project using maven, run:
|
||||||
|
```bash
|
||||||
|
mvn package && java -jar target/openapi-spring-1.0.0.jar
|
||||||
|
```
|
||||||
|
|
||||||
|
To build the project using gradle, run:
|
||||||
|
```bash
|
||||||
|
gradle build && java -jar build/libs/openapi-spring-1.0.0.jar
|
||||||
|
```
|
||||||
|
|
||||||
|
If all builds successfully, the server should run on [http://localhost:8080/](http://localhost:8080/)
|
||||||
45
samples/server/petstore/kotlin-springboot/build.gradle.kts
Normal file
45
samples/server/petstore/kotlin-springboot/build.gradle.kts
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
|
|
||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.0.3.RELEASE")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
group = "org.openapitools"
|
||||||
|
version = "1.0.0"
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType<KotlinCompile> {
|
||||||
|
kotlinOptions.jvmTarget = "1.8"
|
||||||
|
}
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
val kotlinVersion = "1.2.60"
|
||||||
|
id("org.jetbrains.kotlin.jvm") version kotlinVersion
|
||||||
|
id("org.jetbrains.kotlin.plugin.jpa") version kotlinVersion
|
||||||
|
id("org.jetbrains.kotlin.plugin.spring") version kotlinVersion
|
||||||
|
id("org.springframework.boot") version "2.0.3.RELEASE"
|
||||||
|
id("io.spring.dependency-management") version "1.0.5.RELEASE"
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
|
||||||
|
compile("org.jetbrains.kotlin:kotlin-reflect")
|
||||||
|
compile("org.springframework.boot:spring-boot-starter-web")
|
||||||
|
compile("io.swagger:swagger-annotations:1.5.21")
|
||||||
|
compile("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml")
|
||||||
|
compile("com.fasterxml.jackson.dataformat:jackson-dataformat-xml")
|
||||||
|
|
||||||
|
testCompile("org.springframework.boot:spring-boot-starter-test") {
|
||||||
|
exclude(module = "junit")
|
||||||
|
}
|
||||||
|
}
|
||||||
105
samples/server/petstore/kotlin-springboot/pom.xml
Normal file
105
samples/server/petstore/kotlin-springboot/pom.xml
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
<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>org.openapitools</groupId>
|
||||||
|
<artifactId>openapi-spring</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<name>openapi-spring</name>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<properties>
|
||||||
|
<kotlin.version>1.2.60</kotlin.version>
|
||||||
|
</properties>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>2.0.3.RELEASE</version>
|
||||||
|
</parent>
|
||||||
|
<build>
|
||||||
|
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
|
||||||
|
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>repackage</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>kotlin-maven-plugin</artifactId>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<compilerPlugins>
|
||||||
|
<plugin>spring</plugin>
|
||||||
|
</compilerPlugins>
|
||||||
|
<jvmTarget>1.8</jvmTarget>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>compile</id>
|
||||||
|
<phase>compile</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>compile</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>test-compile</id>
|
||||||
|
<phase>test-compile</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>test-compile</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-maven-allopen</artifactId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-reflect</artifactId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.swagger</groupId>
|
||||||
|
<artifactId>swagger-annotations</artifactId>
|
||||||
|
<version>1.5.21</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||||
|
<artifactId>jackson-dataformat-yaml</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||||
|
<artifactId>jackson-dataformat-xml</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||||
|
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- Bean Validation API support -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.validation</groupId>
|
||||||
|
<artifactId>validation-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
rootProject.name = "openapi-spring"
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package org.openapitools
|
||||||
|
|
||||||
|
import org.springframework.boot.runApplication
|
||||||
|
import org.springframework.context.annotation.ComponentScan
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication
|
||||||
|
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
@ComponentScan(basePackages = ["org.openapitools", "org.openapitools.api", "org.openapitools.model"])
|
||||||
|
class Application
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
runApplication<Application>(*args)
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package org.openapitools.api
|
||||||
|
|
||||||
|
import org.springframework.http.HttpStatus
|
||||||
|
import org.springframework.web.bind.annotation.ControllerAdvice
|
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler
|
||||||
|
import javax.servlet.http.HttpServletResponse
|
||||||
|
import javax.validation.ConstraintViolationException
|
||||||
|
|
||||||
|
// TODO Extend ApiException for custom exception handling, e.g. the below NotFound exception
|
||||||
|
sealed class ApiException(msg: String, val code: Int) : Exception(msg)
|
||||||
|
|
||||||
|
class NotFoundException(msg: String, code: Int = HttpStatus.NOT_FOUND.value()) : ApiException(msg, code)
|
||||||
|
|
||||||
|
|
||||||
|
@ControllerAdvice
|
||||||
|
class DefaultExceptionHandler {
|
||||||
|
|
||||||
|
@ExceptionHandler(value = [ApiException::class])
|
||||||
|
fun onApiException(ex: ApiException, response: HttpServletResponse): Unit =
|
||||||
|
response.sendError(ex.code, ex.message)
|
||||||
|
|
||||||
|
@ExceptionHandler(value = [NotImplementedError::class])
|
||||||
|
fun onNotImplemented(ex: NotImplementedError, response: HttpServletResponse): Unit =
|
||||||
|
response.sendError(HttpStatus.NOT_IMPLEMENTED.value())
|
||||||
|
|
||||||
|
@ExceptionHandler(value = [ConstraintViolationException::class])
|
||||||
|
fun onConstraintViolation(ex: ConstraintViolationException, response: HttpServletResponse): Unit =
|
||||||
|
response.sendError(HttpStatus.BAD_REQUEST.value(), ex.constraintViolations.joinToString(", ") { it.message })
|
||||||
|
}
|
||||||
@@ -0,0 +1,159 @@
|
|||||||
|
package org.openapitools.api
|
||||||
|
|
||||||
|
import org.openapitools.model.ModelApiResponse
|
||||||
|
import org.openapitools.model.Pet
|
||||||
|
import io.swagger.annotations.*
|
||||||
|
import org.springframework.http.HttpStatus
|
||||||
|
import org.springframework.http.MediaType
|
||||||
|
import org.springframework.http.ResponseEntity
|
||||||
|
import org.springframework.stereotype.Controller
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody
|
||||||
|
import org.springframework.web.bind.annotation.RequestPart
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable
|
||||||
|
import org.springframework.web.bind.annotation.RequestHeader
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping
|
||||||
|
import org.springframework.validation.annotation.Validated
|
||||||
|
import org.springframework.web.context.request.NativeWebRequest
|
||||||
|
import org.springframework.web.multipart.MultipartFile
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
|
||||||
|
import javax.validation.Valid
|
||||||
|
import javax.validation.constraints.*
|
||||||
|
|
||||||
|
import kotlin.collections.List
|
||||||
|
import kotlin.collections.Map
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@Validated
|
||||||
|
@Api(value = "Pet", description = "The Pet API")
|
||||||
|
@RequestMapping("\${openapi.openAPIPetstore.base-path:/v2}")
|
||||||
|
class PetApiController(@Autowired(required = true) val service: PetApiService) {
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Add a new pet to the store",
|
||||||
|
nickname = "addPet",
|
||||||
|
notes = "",
|
||||||
|
authorizations = [Authorization(value = "petstore_auth", scopes = [AuthorizationScope(scope = "write:pets", description = "modify pets in your account"), AuthorizationScope(scope = "read:pets", description = "read your pets")])])
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 405, message = "Invalid input")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/pet"],
|
||||||
|
consumes = ["application/json", "application/xml"],
|
||||||
|
method = [RequestMethod.POST])
|
||||||
|
fun addPet(@ApiParam(value = "Pet object that needs to be added to the store" ,required=true ) @Valid @RequestBody pet: Pet): ResponseEntity<Unit> {
|
||||||
|
return ResponseEntity(service.addPet(pet), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Deletes a pet",
|
||||||
|
nickname = "deletePet",
|
||||||
|
notes = "",
|
||||||
|
authorizations = [Authorization(value = "petstore_auth", scopes = [AuthorizationScope(scope = "write:pets", description = "modify pets in your account"), AuthorizationScope(scope = "read:pets", description = "read your pets")])])
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 400, message = "Invalid pet value")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/pet/{petId}"],
|
||||||
|
method = [RequestMethod.DELETE])
|
||||||
|
fun deletePet(@ApiParam(value = "Pet id to delete", required=true) @PathVariable("petId") petId: kotlin.Long,@ApiParam(value = "" ) @RequestHeader(value="api_key", required=false) apiKey: kotlin.String): ResponseEntity<Unit> {
|
||||||
|
return ResponseEntity(service.deletePet(petId, apiKey), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Finds Pets by status",
|
||||||
|
nickname = "findPetsByStatus",
|
||||||
|
notes = "Multiple status values can be provided with comma separated strings",
|
||||||
|
response = Pet::class,
|
||||||
|
responseContainer = "List",
|
||||||
|
authorizations = [Authorization(value = "petstore_auth", scopes = [AuthorizationScope(scope = "write:pets", description = "modify pets in your account"), AuthorizationScope(scope = "read:pets", description = "read your pets")])])
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 200, message = "successful operation", response = Pet::class, responseContainer = "List"),ApiResponse(code = 400, message = "Invalid status value")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/pet/findByStatus"],
|
||||||
|
produces = ["application/xml", "application/json"],
|
||||||
|
method = [RequestMethod.GET])
|
||||||
|
fun findPetsByStatus(@NotNull @ApiParam(value = "Status values that need to be considered for filter", required = true, allowableValues = "available, pending, sold") @Valid @RequestParam(value = "status", required = true) status: kotlin.Array<kotlin.String>): ResponseEntity<List<Pet>> {
|
||||||
|
return ResponseEntity(service.findPetsByStatus(status), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Finds Pets by tags",
|
||||||
|
nickname = "findPetsByTags",
|
||||||
|
notes = "Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.",
|
||||||
|
response = Pet::class,
|
||||||
|
responseContainer = "List",
|
||||||
|
authorizations = [Authorization(value = "petstore_auth", scopes = [AuthorizationScope(scope = "write:pets", description = "modify pets in your account"), AuthorizationScope(scope = "read:pets", description = "read your pets")])])
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 200, message = "successful operation", response = Pet::class, responseContainer = "List"),ApiResponse(code = 400, message = "Invalid tag value")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/pet/findByTags"],
|
||||||
|
produces = ["application/xml", "application/json"],
|
||||||
|
method = [RequestMethod.GET])
|
||||||
|
fun findPetsByTags(@NotNull @ApiParam(value = "Tags to filter by", required = true) @Valid @RequestParam(value = "tags", required = true) tags: kotlin.Array<kotlin.String>): ResponseEntity<List<Pet>> {
|
||||||
|
return ResponseEntity(service.findPetsByTags(tags), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Find pet by ID",
|
||||||
|
nickname = "getPetById",
|
||||||
|
notes = "Returns a single pet",
|
||||||
|
response = Pet::class,
|
||||||
|
authorizations = [Authorization(value = "api_key")])
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 200, message = "successful operation", response = Pet::class),ApiResponse(code = 400, message = "Invalid ID supplied"),ApiResponse(code = 404, message = "Pet not found")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/pet/{petId}"],
|
||||||
|
produces = ["application/xml", "application/json"],
|
||||||
|
method = [RequestMethod.GET])
|
||||||
|
fun getPetById(@ApiParam(value = "ID of pet to return", required=true) @PathVariable("petId") petId: kotlin.Long): ResponseEntity<Pet> {
|
||||||
|
return ResponseEntity(service.getPetById(petId), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Update an existing pet",
|
||||||
|
nickname = "updatePet",
|
||||||
|
notes = "",
|
||||||
|
authorizations = [Authorization(value = "petstore_auth", scopes = [AuthorizationScope(scope = "write:pets", description = "modify pets in your account"), AuthorizationScope(scope = "read:pets", description = "read your pets")])])
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 400, message = "Invalid ID supplied"),ApiResponse(code = 404, message = "Pet not found"),ApiResponse(code = 405, message = "Validation exception")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/pet"],
|
||||||
|
consumes = ["application/json", "application/xml"],
|
||||||
|
method = [RequestMethod.PUT])
|
||||||
|
fun updatePet(@ApiParam(value = "Pet object that needs to be added to the store" ,required=true ) @Valid @RequestBody pet: Pet): ResponseEntity<Unit> {
|
||||||
|
return ResponseEntity(service.updatePet(pet), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Updates a pet in the store with form data",
|
||||||
|
nickname = "updatePetWithForm",
|
||||||
|
notes = "",
|
||||||
|
authorizations = [Authorization(value = "petstore_auth", scopes = [AuthorizationScope(scope = "write:pets", description = "modify pets in your account"), AuthorizationScope(scope = "read:pets", description = "read your pets")])])
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 405, message = "Invalid input")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/pet/{petId}"],
|
||||||
|
consumes = ["application/x-www-form-urlencoded"],
|
||||||
|
method = [RequestMethod.POST])
|
||||||
|
fun updatePetWithForm(@ApiParam(value = "ID of pet that needs to be updated", required=true) @PathVariable("petId") petId: kotlin.Long,@ApiParam(value = "Updated name of the pet", defaultValue="null") @RequestParam(value="name", required=false) name: kotlin.String ,@ApiParam(value = "Updated status of the pet", defaultValue="null") @RequestParam(value="status", required=false) status: kotlin.String ): ResponseEntity<Unit> {
|
||||||
|
return ResponseEntity(service.updatePetWithForm(petId, name, status), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "uploads an image",
|
||||||
|
nickname = "uploadFile",
|
||||||
|
notes = "",
|
||||||
|
response = ModelApiResponse::class,
|
||||||
|
authorizations = [Authorization(value = "petstore_auth", scopes = [AuthorizationScope(scope = "write:pets", description = "modify pets in your account"), AuthorizationScope(scope = "read:pets", description = "read your pets")])])
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 200, message = "successful operation", response = ModelApiResponse::class)])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/pet/{petId}/uploadImage"],
|
||||||
|
produces = ["application/json"],
|
||||||
|
consumes = ["multipart/form-data"],
|
||||||
|
method = [RequestMethod.POST])
|
||||||
|
fun uploadFile(@ApiParam(value = "ID of pet to update", required=true) @PathVariable("petId") petId: kotlin.Long,@ApiParam(value = "Additional data to pass to server", defaultValue="null") @RequestParam(value="additionalMetadata", required=false) additionalMetadata: kotlin.String ,@ApiParam(value = "file detail") @Valid @RequestPart("file") file: MultipartFile): ResponseEntity<ModelApiResponse> {
|
||||||
|
return ResponseEntity(service.uploadFile(petId, additionalMetadata, file), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package org.openapitools.api
|
||||||
|
|
||||||
|
import org.openapitools.model.ModelApiResponse
|
||||||
|
import org.openapitools.model.Pet
|
||||||
|
|
||||||
|
interface PetApiService {
|
||||||
|
|
||||||
|
fun addPet(pet: Pet): Unit
|
||||||
|
|
||||||
|
fun deletePet(petId: kotlin.Long,apiKey: kotlin.String): Unit
|
||||||
|
|
||||||
|
fun findPetsByStatus(status: kotlin.Array<kotlin.String>): List<Pet>
|
||||||
|
|
||||||
|
fun findPetsByTags(tags: kotlin.Array<kotlin.String>): List<Pet>
|
||||||
|
|
||||||
|
fun getPetById(petId: kotlin.Long): Pet
|
||||||
|
|
||||||
|
fun updatePet(pet: Pet): Unit
|
||||||
|
|
||||||
|
fun updatePetWithForm(petId: kotlin.Long,name: kotlin.String,status: kotlin.String): Unit
|
||||||
|
|
||||||
|
fun uploadFile(petId: kotlin.Long,additionalMetadata: kotlin.String,file: org.springframework.web.multipart.MultipartFile): ModelApiResponse
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package org.openapitools.api
|
||||||
|
|
||||||
|
import org.openapitools.model.ModelApiResponse
|
||||||
|
import org.openapitools.model.Pet
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
|
||||||
|
@Service
|
||||||
|
class PetApiServiceImpl : PetApiService {
|
||||||
|
|
||||||
|
override fun addPet(pet: Pet): Unit {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun deletePet(petId: kotlin.Long,apiKey: kotlin.String): Unit {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun findPetsByStatus(status: kotlin.Array<kotlin.String>): List<Pet> {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun findPetsByTags(tags: kotlin.Array<kotlin.String>): List<Pet> {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getPetById(petId: kotlin.Long): Pet {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updatePet(pet: Pet): Unit {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updatePetWithForm(petId: kotlin.Long,name: kotlin.String,status: kotlin.String): Unit {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun uploadFile(petId: kotlin.Long,additionalMetadata: kotlin.String,file: org.springframework.web.multipart.MultipartFile): ModelApiResponse {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
package org.openapitools.api
|
||||||
|
|
||||||
|
import org.openapitools.model.Order
|
||||||
|
import io.swagger.annotations.*
|
||||||
|
import org.springframework.http.HttpStatus
|
||||||
|
import org.springframework.http.MediaType
|
||||||
|
import org.springframework.http.ResponseEntity
|
||||||
|
import org.springframework.stereotype.Controller
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody
|
||||||
|
import org.springframework.web.bind.annotation.RequestPart
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable
|
||||||
|
import org.springframework.web.bind.annotation.RequestHeader
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping
|
||||||
|
import org.springframework.validation.annotation.Validated
|
||||||
|
import org.springframework.web.context.request.NativeWebRequest
|
||||||
|
import org.springframework.web.multipart.MultipartFile
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
|
||||||
|
import javax.validation.Valid
|
||||||
|
import javax.validation.constraints.*
|
||||||
|
|
||||||
|
import kotlin.collections.List
|
||||||
|
import kotlin.collections.Map
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@Validated
|
||||||
|
@Api(value = "Store", description = "The Store API")
|
||||||
|
@RequestMapping("\${openapi.openAPIPetstore.base-path:/v2}")
|
||||||
|
class StoreApiController(@Autowired(required = true) val service: StoreApiService) {
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Delete purchase order by ID",
|
||||||
|
nickname = "deleteOrder",
|
||||||
|
notes = "For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors")
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 400, message = "Invalid ID supplied"),ApiResponse(code = 404, message = "Order not found")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/store/order/{orderId}"],
|
||||||
|
method = [RequestMethod.DELETE])
|
||||||
|
fun deleteOrder(@ApiParam(value = "ID of the order that needs to be deleted", required=true) @PathVariable("orderId") orderId: kotlin.String): ResponseEntity<Unit> {
|
||||||
|
return ResponseEntity(service.deleteOrder(orderId), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Returns pet inventories by status",
|
||||||
|
nickname = "getInventory",
|
||||||
|
notes = "Returns a map of status codes to quantities",
|
||||||
|
response = kotlin.Int::class,
|
||||||
|
responseContainer = "Map",
|
||||||
|
authorizations = [Authorization(value = "api_key")])
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 200, message = "successful operation", response = kotlin.collections.Map::class, responseContainer = "Map")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/store/inventory"],
|
||||||
|
produces = ["application/json"],
|
||||||
|
method = [RequestMethod.GET])
|
||||||
|
fun getInventory(): ResponseEntity<Map<String, kotlin.Int>> {
|
||||||
|
return ResponseEntity(service.getInventory(), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Find purchase order by ID",
|
||||||
|
nickname = "getOrderById",
|
||||||
|
notes = "For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions",
|
||||||
|
response = Order::class)
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 200, message = "successful operation", response = Order::class),ApiResponse(code = 400, message = "Invalid ID supplied"),ApiResponse(code = 404, message = "Order not found")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/store/order/{orderId}"],
|
||||||
|
produces = ["application/xml", "application/json"],
|
||||||
|
method = [RequestMethod.GET])
|
||||||
|
fun getOrderById(@Min(1L) @Max(5L) @ApiParam(value = "ID of pet that needs to be fetched", required=true) @PathVariable("orderId") orderId: kotlin.Long): ResponseEntity<Order> {
|
||||||
|
return ResponseEntity(service.getOrderById(orderId), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Place an order for a pet",
|
||||||
|
nickname = "placeOrder",
|
||||||
|
notes = "",
|
||||||
|
response = Order::class)
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 200, message = "successful operation", response = Order::class),ApiResponse(code = 400, message = "Invalid Order")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/store/order"],
|
||||||
|
produces = ["application/xml", "application/json"],
|
||||||
|
method = [RequestMethod.POST])
|
||||||
|
fun placeOrder(@ApiParam(value = "order placed for purchasing the pet" ,required=true ) @Valid @RequestBody order: Order): ResponseEntity<Order> {
|
||||||
|
return ResponseEntity(service.placeOrder(order), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package org.openapitools.api
|
||||||
|
|
||||||
|
import org.openapitools.model.Order
|
||||||
|
|
||||||
|
interface StoreApiService {
|
||||||
|
|
||||||
|
fun deleteOrder(orderId: kotlin.String): Unit
|
||||||
|
|
||||||
|
fun getInventory(): Map<String, kotlin.Int>
|
||||||
|
|
||||||
|
fun getOrderById(orderId: kotlin.Long): Order
|
||||||
|
|
||||||
|
fun placeOrder(order: Order): Order
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package org.openapitools.api
|
||||||
|
|
||||||
|
import org.openapitools.model.Order
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
|
||||||
|
@Service
|
||||||
|
class StoreApiServiceImpl : StoreApiService {
|
||||||
|
|
||||||
|
override fun deleteOrder(orderId: kotlin.String): Unit {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getInventory(): Map<String, kotlin.Int> {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getOrderById(orderId: kotlin.Long): Order {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun placeOrder(order: Order): Order {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
package org.openapitools.api
|
||||||
|
|
||||||
|
import org.openapitools.model.User
|
||||||
|
import io.swagger.annotations.*
|
||||||
|
import org.springframework.http.HttpStatus
|
||||||
|
import org.springframework.http.MediaType
|
||||||
|
import org.springframework.http.ResponseEntity
|
||||||
|
import org.springframework.stereotype.Controller
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody
|
||||||
|
import org.springframework.web.bind.annotation.RequestPart
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable
|
||||||
|
import org.springframework.web.bind.annotation.RequestHeader
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping
|
||||||
|
import org.springframework.validation.annotation.Validated
|
||||||
|
import org.springframework.web.context.request.NativeWebRequest
|
||||||
|
import org.springframework.web.multipart.MultipartFile
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
|
||||||
|
import javax.validation.Valid
|
||||||
|
import javax.validation.constraints.*
|
||||||
|
|
||||||
|
import kotlin.collections.List
|
||||||
|
import kotlin.collections.Map
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@Validated
|
||||||
|
@Api(value = "User", description = "The User API")
|
||||||
|
@RequestMapping("\${openapi.openAPIPetstore.base-path:/v2}")
|
||||||
|
class UserApiController(@Autowired(required = true) val service: UserApiService) {
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Create user",
|
||||||
|
nickname = "createUser",
|
||||||
|
notes = "This can only be done by the logged in user.")
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 200, message = "successful operation")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/user"],
|
||||||
|
method = [RequestMethod.POST])
|
||||||
|
fun createUser(@ApiParam(value = "Created user object" ,required=true ) @Valid @RequestBody user: User): ResponseEntity<Unit> {
|
||||||
|
return ResponseEntity(service.createUser(user), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Creates list of users with given input array",
|
||||||
|
nickname = "createUsersWithArrayInput",
|
||||||
|
notes = "")
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 200, message = "successful operation")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/user/createWithArray"],
|
||||||
|
method = [RequestMethod.POST])
|
||||||
|
fun createUsersWithArrayInput(@ApiParam(value = "List of user object" ,required=true ) @Valid @RequestBody user: kotlin.Array<User>): ResponseEntity<Unit> {
|
||||||
|
return ResponseEntity(service.createUsersWithArrayInput(user), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Creates list of users with given input array",
|
||||||
|
nickname = "createUsersWithListInput",
|
||||||
|
notes = "")
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 200, message = "successful operation")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/user/createWithList"],
|
||||||
|
method = [RequestMethod.POST])
|
||||||
|
fun createUsersWithListInput(@ApiParam(value = "List of user object" ,required=true ) @Valid @RequestBody user: kotlin.Array<User>): ResponseEntity<Unit> {
|
||||||
|
return ResponseEntity(service.createUsersWithListInput(user), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Delete user",
|
||||||
|
nickname = "deleteUser",
|
||||||
|
notes = "This can only be done by the logged in user.")
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 400, message = "Invalid username supplied"),ApiResponse(code = 404, message = "User not found")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/user/{username}"],
|
||||||
|
method = [RequestMethod.DELETE])
|
||||||
|
fun deleteUser(@ApiParam(value = "The name that needs to be deleted", required=true) @PathVariable("username") username: kotlin.String): ResponseEntity<Unit> {
|
||||||
|
return ResponseEntity(service.deleteUser(username), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Get user by user name",
|
||||||
|
nickname = "getUserByName",
|
||||||
|
notes = "",
|
||||||
|
response = User::class)
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 200, message = "successful operation", response = User::class),ApiResponse(code = 400, message = "Invalid username supplied"),ApiResponse(code = 404, message = "User not found")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/user/{username}"],
|
||||||
|
produces = ["application/xml", "application/json"],
|
||||||
|
method = [RequestMethod.GET])
|
||||||
|
fun getUserByName(@ApiParam(value = "The name that needs to be fetched. Use user1 for testing.", required=true) @PathVariable("username") username: kotlin.String): ResponseEntity<User> {
|
||||||
|
return ResponseEntity(service.getUserByName(username), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Logs user into the system",
|
||||||
|
nickname = "loginUser",
|
||||||
|
notes = "",
|
||||||
|
response = kotlin.String::class)
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 200, message = "successful operation", response = kotlin.String::class),ApiResponse(code = 400, message = "Invalid username/password supplied")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/user/login"],
|
||||||
|
produces = ["application/xml", "application/json"],
|
||||||
|
method = [RequestMethod.GET])
|
||||||
|
fun loginUser(@NotNull @ApiParam(value = "The user name for login", required = true) @Valid @RequestParam(value = "username", required = true) username: kotlin.String,@NotNull @ApiParam(value = "The password for login in clear text", required = true) @Valid @RequestParam(value = "password", required = true) password: kotlin.String): ResponseEntity<kotlin.String> {
|
||||||
|
return ResponseEntity(service.loginUser(username, password), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Logs out current logged in user session",
|
||||||
|
nickname = "logoutUser",
|
||||||
|
notes = "")
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 200, message = "successful operation")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/user/logout"],
|
||||||
|
method = [RequestMethod.GET])
|
||||||
|
fun logoutUser(): ResponseEntity<Unit> {
|
||||||
|
return ResponseEntity(service.logoutUser(), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(
|
||||||
|
value = "Updated user",
|
||||||
|
nickname = "updateUser",
|
||||||
|
notes = "This can only be done by the logged in user.")
|
||||||
|
@ApiResponses(
|
||||||
|
value = [ApiResponse(code = 400, message = "Invalid user supplied"),ApiResponse(code = 404, message = "User not found")])
|
||||||
|
@RequestMapping(
|
||||||
|
value = ["/user/{username}"],
|
||||||
|
method = [RequestMethod.PUT])
|
||||||
|
fun updateUser(@ApiParam(value = "name that need to be deleted", required=true) @PathVariable("username") username: kotlin.String,@ApiParam(value = "Updated user object" ,required=true ) @Valid @RequestBody user: User): ResponseEntity<Unit> {
|
||||||
|
return ResponseEntity(service.updateUser(username, user), HttpStatus.OK)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package org.openapitools.api
|
||||||
|
|
||||||
|
import org.openapitools.model.User
|
||||||
|
|
||||||
|
interface UserApiService {
|
||||||
|
|
||||||
|
fun createUser(user: User): Unit
|
||||||
|
|
||||||
|
fun createUsersWithArrayInput(user: kotlin.Array<User>): Unit
|
||||||
|
|
||||||
|
fun createUsersWithListInput(user: kotlin.Array<User>): Unit
|
||||||
|
|
||||||
|
fun deleteUser(username: kotlin.String): Unit
|
||||||
|
|
||||||
|
fun getUserByName(username: kotlin.String): User
|
||||||
|
|
||||||
|
fun loginUser(username: kotlin.String,password: kotlin.String): kotlin.String
|
||||||
|
|
||||||
|
fun logoutUser(): Unit
|
||||||
|
|
||||||
|
fun updateUser(username: kotlin.String,user: User): Unit
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package org.openapitools.api
|
||||||
|
|
||||||
|
import org.openapitools.model.User
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
|
||||||
|
@Service
|
||||||
|
class UserApiServiceImpl : UserApiService {
|
||||||
|
|
||||||
|
override fun createUser(user: User): Unit {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createUsersWithArrayInput(user: kotlin.Array<User>): Unit {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createUsersWithListInput(user: kotlin.Array<User>): Unit {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun deleteUser(username: kotlin.String): Unit {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getUserByName(username: kotlin.String): User {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun loginUser(username: kotlin.String,password: kotlin.String): kotlin.String {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun logoutUser(): Unit {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateUser(username: kotlin.String,user: User): Unit {
|
||||||
|
TODO("Implement me")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package org.openapitools.model
|
||||||
|
|
||||||
|
import java.util.Objects
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
|
import javax.validation.Valid
|
||||||
|
import javax.validation.constraints.*
|
||||||
|
import io.swagger.annotations.ApiModelProperty
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A category for a pet
|
||||||
|
* @param id
|
||||||
|
* @param name
|
||||||
|
*/
|
||||||
|
data class Category (
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("id") val id: kotlin.Long? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("name") val name: kotlin.String? = null
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package org.openapitools.model
|
||||||
|
|
||||||
|
import java.util.Objects
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
|
import javax.validation.Valid
|
||||||
|
import javax.validation.constraints.*
|
||||||
|
import io.swagger.annotations.ApiModelProperty
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes the result of uploading an image resource
|
||||||
|
* @param code
|
||||||
|
* @param type
|
||||||
|
* @param message
|
||||||
|
*/
|
||||||
|
data class ModelApiResponse (
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("code") val code: kotlin.Int? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("type") val type: kotlin.String? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("message") val message: kotlin.String? = null
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package org.openapitools.model
|
||||||
|
|
||||||
|
import java.util.Objects
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
|
import com.fasterxml.jackson.annotation.JsonValue
|
||||||
|
import javax.validation.Valid
|
||||||
|
import javax.validation.constraints.*
|
||||||
|
import io.swagger.annotations.ApiModelProperty
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 (
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("id") val id: kotlin.Long? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("petId") val petId: kotlin.Long? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("quantity") val quantity: kotlin.Int? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("shipDate") val shipDate: java.time.OffsetDateTime? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "Order Status")
|
||||||
|
@JsonProperty("status") val status: Order.Status? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("complete") val complete: kotlin.Boolean? = null
|
||||||
|
) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Order Status
|
||||||
|
* Values: placed,approved,delivered
|
||||||
|
*/
|
||||||
|
enum class Status(val value: kotlin.String) {
|
||||||
|
|
||||||
|
@JsonProperty("placed") placed("placed"),
|
||||||
|
|
||||||
|
@JsonProperty("approved") approved("approved"),
|
||||||
|
|
||||||
|
@JsonProperty("delivered") delivered("delivered");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package org.openapitools.model
|
||||||
|
|
||||||
|
import java.util.Objects
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
|
import com.fasterxml.jackson.annotation.JsonValue
|
||||||
|
import org.openapitools.model.Category
|
||||||
|
import org.openapitools.model.Tag
|
||||||
|
import javax.validation.Valid
|
||||||
|
import javax.validation.constraints.*
|
||||||
|
import io.swagger.annotations.ApiModelProperty
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A pet for sale in the pet store
|
||||||
|
* @param id
|
||||||
|
* @param category
|
||||||
|
* @param name
|
||||||
|
* @param photoUrls
|
||||||
|
* @param tags
|
||||||
|
* @param status pet status in the store
|
||||||
|
*/
|
||||||
|
data class Pet (
|
||||||
|
|
||||||
|
@get:NotNull
|
||||||
|
@ApiModelProperty(example = "doggie", required = true, value = "")
|
||||||
|
@JsonProperty("name") val name: kotlin.String,
|
||||||
|
|
||||||
|
@get:NotNull
|
||||||
|
@ApiModelProperty(required = true, value = "")
|
||||||
|
@JsonProperty("photoUrls") val photoUrls: kotlin.Array<kotlin.String>,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("id") val id: kotlin.Long? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("category") val category: Category? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("tags") val tags: kotlin.Array<Tag>? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "pet status in the store")
|
||||||
|
@JsonProperty("status") val status: Pet.Status? = null
|
||||||
|
) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pet status in the store
|
||||||
|
* Values: available,pending,sold
|
||||||
|
*/
|
||||||
|
enum class Status(val value: kotlin.String) {
|
||||||
|
|
||||||
|
@JsonProperty("available") available("available"),
|
||||||
|
|
||||||
|
@JsonProperty("pending") pending("pending"),
|
||||||
|
|
||||||
|
@JsonProperty("sold") sold("sold");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package org.openapitools.model
|
||||||
|
|
||||||
|
import java.util.Objects
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
|
import javax.validation.Valid
|
||||||
|
import javax.validation.constraints.*
|
||||||
|
import io.swagger.annotations.ApiModelProperty
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A tag for a pet
|
||||||
|
* @param id
|
||||||
|
* @param name
|
||||||
|
*/
|
||||||
|
data class Tag (
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("id") val id: kotlin.Long? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("name") val name: kotlin.String? = null
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package org.openapitools.model
|
||||||
|
|
||||||
|
import java.util.Objects
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
|
import javax.validation.Valid
|
||||||
|
import javax.validation.constraints.*
|
||||||
|
import io.swagger.annotations.ApiModelProperty
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 (
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("id") val id: kotlin.Long? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("username") val username: kotlin.String? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("firstName") val firstName: kotlin.String? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("lastName") val lastName: kotlin.String? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("email") val email: kotlin.String? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("password") val password: kotlin.String? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "")
|
||||||
|
@JsonProperty("phone") val phone: kotlin.String? = null,
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "User Status")
|
||||||
|
@JsonProperty("userStatus") val userStatus: kotlin.Int? = null
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
spring.application.name=openAPIPetstore
|
||||||
|
server.port=8080
|
||||||
|
spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false
|
||||||
Reference in New Issue
Block a user