From 0923fef5f743f689fec4a4d879fe627c176e5c48 Mon Sep 17 00:00:00 2001 From: Patrick Tiu Date: Wed, 28 Aug 2019 13:45:41 -0400 Subject: [PATCH] Microprofile REST Client-compliant Java code gernerator (#1) * Create JavaMicroprofile generator * Add ApiException and ApiExeptionMapper * Add documentation for running the generator * Update README * Capitalize P in MicroProfile * Clean up generated model for microprofile rest client * Revert change in AbstractJavaCodegen and move the action into JavaMicroprofile * Remove non-cxf templates in JavaMicroprofile and rename cxf to mp" * Remove mp/server files * Update pom.xml to have MpRestClient dependencies * Generate tests using smallrye implementation * Change JavaMicroprofile.java to JavaMicroprofileCodegen.java * Add test for JavaMicroprofileCodegen * Add scripts to generate petstore sample * Add README * Revert "Add scripts to generate petstore sample" This reverts commit 25ee4960f5e3e62c28331a8edd7e56bb77383181. * Revert "Add README" This reverts commit 067b2a87447883a62ee8153525f07dd8aef57560. * Revert "Revert "Add scripts to generate petstore sample"" This reverts commit 5a3639048eb54a0b8ec1bb1dda04245f1b56f71f. * Add README * Move templates out of mp/ directory * Remove CXF references * Remove unnecessary templates * Fix compilation errors * Add missing jsonb dependency * Add license header to code templates * Increase copyright year to 2019 * Remove TODO comments and commented out code * Add more javadocs to the model templates * Fix issues with generated code * Revert README back to master's README * Add documentation for java microprofile client generator * Add MicroProfile Rest Client to list of clients in README * Remove smartbear copyright from java files * Add disableMultipart option * Fix licenseInfo * Rename JavaMicroprofileCodegen to JavaMicroprofileRestClientCodegen * Rename sample scripts to java-microprofile-rest-client * Adjust test comments * Better spacing between members for generated models * Update getHelp() method * Update javadoc for tests --- README.md | 2 +- bin/java-microprofile-rest-client.sh | 32 +++ bin/windows/java-microprofile-rest-client.bat | 10 + docs/generators/java-microprofile.md | 46 +++++ .../JavaMicroprofileRestClientCodegen.java | 192 ++++++++++++++++++ .../JavaMicroprofile/README.mustache | 10 + .../resources/JavaMicroprofile/api.mustache | 61 ++++++ .../JavaMicroprofile/api_exception.mustache | 23 +++ .../api_exception_mapper.mustache | 22 ++ .../JavaMicroprofile/api_test.mustache | 75 +++++++ .../JavaMicroprofile/beanValidation.mustache | 4 + .../beanValidationCore.mustache | 20 ++ .../beanValidationHeaderParams.mustache | 1 + .../beanValidationPathParams.mustache | 1 + .../beanValidationQueryParams.mustache | 1 + .../JavaMicroprofile/bodyParams.mustache | 1 + .../JavaMicroprofile/bodyParamsImpl.mustache | 1 + .../JavaMicroprofile/enumClass.mustache | 33 +++ .../JavaMicroprofile/enumOuterClass.mustache | 48 +++++ .../JavaMicroprofile/formParams.mustache | 1 + .../JavaMicroprofile/formParamsImpl.mustache | 1 + .../generatedAnnotation.mustache | 1 + .../JavaMicroprofile/headerParams.mustache | 1 + .../headerParamsImpl.mustache | 1 + .../JavaMicroprofile/licenseInfo.mustache | 23 +++ .../resources/JavaMicroprofile/model.mustache | 23 +++ .../JavaMicroprofile/pathParams.mustache | 1 + .../JavaMicroprofile/pathParamsImpl.mustache | 1 + .../resources/JavaMicroprofile/pojo.mustache | 129 ++++++++++++ .../resources/JavaMicroprofile/pom.mustache | 173 ++++++++++++++++ .../JavaMicroprofile/queryParams.mustache | 1 + .../JavaMicroprofile/queryParamsImpl.mustache | 1 + .../JavaMicroprofile/returnTypes.mustache | 4 + .../org.openapitools.codegen.CodegenConfig | 1 + ...JavaMicroprofileRestClientCodegenTest.java | 125 ++++++++++++ 35 files changed, 1069 insertions(+), 1 deletion(-) create mode 100755 bin/java-microprofile-rest-client.sh create mode 100755 bin/windows/java-microprofile-rest-client.bat create mode 100644 docs/generators/java-microprofile.md create mode 100644 modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaMicroprofileRestClientCodegen.java create mode 100644 modules/openapi-generator/src/main/resources/JavaMicroprofile/README.mustache create mode 100644 modules/openapi-generator/src/main/resources/JavaMicroprofile/api.mustache create mode 100644 modules/openapi-generator/src/main/resources/JavaMicroprofile/api_exception.mustache create mode 100644 modules/openapi-generator/src/main/resources/JavaMicroprofile/api_exception_mapper.mustache create mode 100644 modules/openapi-generator/src/main/resources/JavaMicroprofile/api_test.mustache create mode 100644 modules/openapi-generator/src/main/resources/JavaMicroprofile/beanValidation.mustache create mode 100644 modules/openapi-generator/src/main/resources/JavaMicroprofile/beanValidationCore.mustache create mode 100644 modules/openapi-generator/src/main/resources/JavaMicroprofile/beanValidationHeaderParams.mustache create mode 100644 modules/openapi-generator/src/main/resources/JavaMicroprofile/beanValidationPathParams.mustache create mode 100644 modules/openapi-generator/src/main/resources/JavaMicroprofile/beanValidationQueryParams.mustache create mode 100644 modules/openapi-generator/src/main/resources/JavaMicroprofile/bodyParams.mustache create mode 100644 modules/openapi-generator/src/main/resources/JavaMicroprofile/bodyParamsImpl.mustache create mode 100644 modules/openapi-generator/src/main/resources/JavaMicroprofile/enumClass.mustache create mode 100644 modules/openapi-generator/src/main/resources/JavaMicroprofile/enumOuterClass.mustache create mode 100644 modules/openapi-generator/src/main/resources/JavaMicroprofile/formParams.mustache create mode 100644 modules/openapi-generator/src/main/resources/JavaMicroprofile/formParamsImpl.mustache create mode 100644 modules/openapi-generator/src/main/resources/JavaMicroprofile/generatedAnnotation.mustache create mode 100644 modules/openapi-generator/src/main/resources/JavaMicroprofile/headerParams.mustache create mode 100644 modules/openapi-generator/src/main/resources/JavaMicroprofile/headerParamsImpl.mustache create mode 100644 modules/openapi-generator/src/main/resources/JavaMicroprofile/licenseInfo.mustache create mode 100644 modules/openapi-generator/src/main/resources/JavaMicroprofile/model.mustache create mode 100644 modules/openapi-generator/src/main/resources/JavaMicroprofile/pathParams.mustache create mode 100644 modules/openapi-generator/src/main/resources/JavaMicroprofile/pathParamsImpl.mustache create mode 100644 modules/openapi-generator/src/main/resources/JavaMicroprofile/pojo.mustache create mode 100644 modules/openapi-generator/src/main/resources/JavaMicroprofile/pom.mustache create mode 100644 modules/openapi-generator/src/main/resources/JavaMicroprofile/queryParams.mustache create mode 100644 modules/openapi-generator/src/main/resources/JavaMicroprofile/queryParamsImpl.mustache create mode 100644 modules/openapi-generator/src/main/resources/JavaMicroprofile/returnTypes.mustache create mode 100644 modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaMicroprofileRestClientCodegenTest.java diff --git a/README.md b/README.md index ac8bc5356090..8d4550e8c76d 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ OpenAPI Generator allows generation of API client libraries (SDK generation), se | | Languages/Frameworks | |-|-| -**API clients** | **ActionScript**, **Ada**, **Apex**, **Bash**, **C**, **C#** (.net 2.0, 3.5 or later, .NET Standard 1.3 - 2.0, .NET Core 2.0), **C++** (cpp-restsdk, Qt5, Tizen), **Clojure**, **Dart (1.x, 2.x)**, **Elixir**, **Elm**, **Eiffel**, **Erlang**, **Go**, **Groovy**, **Haskell** (http-client, Servant), **Java** (Jersey1.x, Jersey2.x, OkHttp, Retrofit1.x, Retrofit2.x, Feign, RestTemplate, RESTEasy, Vertx, Google API Client Library for Java, Rest-assured, Spring 5 Web Client), **Kotlin**, **Lua**, **Node.js/JavaScript** (ES5, ES6, AngularJS with Google Closure Compiler annotations, Flow types), **Objective-C**, **OCaml**, **Perl**, **PHP**, **PowerShell**, **Python**, **R**, **Ruby**, **Rust** (rust, rust-server), **Scala** (akka, http4s, scalaz, swagger-async-httpclient), **Swift** (2.x, 3.x, 4.x), **Typescript** (AngularJS, Angular (2.x - 8.x), Aurelia, Axios, Fetch, Inversify, jQuery, Node, Rxjs) +**API clients** | **ActionScript**, **Ada**, **Apex**, **Bash**, **C**, **C#** (.net 2.0, 3.5 or later, .NET Standard 1.3 - 2.0, .NET Core 2.0), **C++** (cpp-restsdk, Qt5, Tizen), **Clojure**, **Dart (1.x, 2.x)**, **Elixir**, **Elm**, **Eiffel**, **Erlang**, **Go**, **Groovy**, **Haskell** (http-client, Servant), **Java** (Jersey1.x, Jersey2.x, OkHttp, Retrofit1.x, Retrofit2.x, Feign, RestTemplate, RESTEasy, Vertx, Google API Client Library for Java, Rest-assured, Spring 5 Web Client), MicroProfile Rest Client), **Kotlin**, **Lua**, **Node.js/JavaScript** (ES5, ES6, AngularJS with Google Closure Compiler annotations, Flow types), **Objective-C**, **OCaml**, **Perl**, **PHP**, **PowerShell**, **Python**, **R**, **Ruby**, **Rust** (rust, rust-server), **Scala** (akka, http4s, scalaz, swagger-async-httpclient), **Swift** (2.x, 3.x, 4.x), **Typescript** (AngularJS, Angular (2.x - 8.x), Aurelia, Axios, Fetch, Inversify, jQuery, Node, Rxjs) **Server stubs** | **Ada**, **C#** (ASP.NET Core, NancyFx), **C++** (Pistache, Restbed, Qt5 QHTTPEngine), **Erlang**, **F#** (Giraffe), **Go** (net/http, Gin), **Haskell** (Servant), **Java** (MSF4J, Spring, Undertow, JAX-RS: CDI, CXF, Inflector, Jersey, RestEasy, Play Framework, [PKMST](https://github.com/ProKarma-Inc/pkmst-getting-started-examples)), **Kotlin** (Spring Boot, Ktor), **PHP** (Laravel, Lumen, Slim, Silex, [Symfony](https://symfony.com/), [Zend Expressive](https://github.com/zendframework/zend-expressive)), **Python** (Flask), **NodeJS**, **Ruby** (Sinatra, Rails5), **Rust** (rust-server), **Scala** ([Finch](https://github.com/finagle/finch), [Lagom](https://github.com/lagom/lagom), [Play](https://www.playframework.com/), Scalatra) **API documentation generators** | **HTML**, **Confluence Wiki** **Configuration files** | [**Apache2**](https://httpd.apache.org/) diff --git a/bin/java-microprofile-rest-client.sh b/bin/java-microprofile-rest-client.sh new file mode 100755 index 000000000000..61f93a515bba --- /dev/null +++ b/bin/java-microprofile-rest-client.sh @@ -0,0 +1,32 @@ +#!/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 -B clean package +fi + +# if you've executed sbt assembly previously it will use that instead. +export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties" +ags="generate --artifact-id "microprofile-rest-client" -t modules/openapi-generator/src/main/resources/JavaMicroprofile -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g microprofile-rest-client -o samples/client/petstore/microprofile-rest-client $@" + +java $JAVA_OPTS -jar $executable $ags diff --git a/bin/windows/java-microprofile-rest-client.bat b/bin/windows/java-microprofile-rest-client.bat new file mode 100755 index 000000000000..1dd0019857b9 --- /dev/null +++ b/bin/windows/java-microprofile-rest-client.bat @@ -0,0 +1,10 @@ +set executable=.\modules\openapi-generator-cli\target\openapi-generator-cli.jar + +If Not Exist %executable% ( + mvn clean package +) + +REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M -DloggerPath=conf/log4j.properties +set ags=generate --artifact-id "microprofile-rest-client" -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -g microprofile-rest-client -o samples\client\petstore\microprofile-rest-client + +java %JAVA_OPTS% -jar %executable% %ags% diff --git a/docs/generators/java-microprofile.md b/docs/generators/java-microprofile.md new file mode 100644 index 000000000000..5bb5633c6693 --- /dev/null +++ b/docs/generators/java-microprofile.md @@ -0,0 +1,46 @@ + +--- +id: generator-opts-client-java-microprofile +title: Config Options for java-microprofile +sidebar_label: java-microprofile +--- + +| Option | Description | Values | Default | +| ------ | ----------- | ------ | ------- | +|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true| +|ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true| +|allowUnicodeIdentifiers|boolean, toggles whether unicode identifiers are allowed in names or not, default is false| |false| +|prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false| +|modelPackage|package for generated models| |org.openapitools.model| +|apiPackage|package for generated api classes| |org.openapitools.api| +|invokerPackage|root package for generated code| |org.openapitools.api| +|groupId|groupId in generated pom.xml| |org.openapitools| +|artifactId|artifactId in generated pom.xml. This also becomes part of the generated library's filename| |openapi-jaxrs-client| +|artifactVersion|artifact version in generated pom.xml. This also becomes part of the generated library's filename| |1.0.0| +|artifactUrl|artifact URL in generated pom.xml| |https://github.com/openapitools/openapi-generator| +|artifactDescription|artifact description in generated pom.xml| |OpenAPI Java| +|scmConnection|SCM connection in generated pom.xml| |scm:git:git@github.com:openapitools/openapi-generator.git| +|scmDeveloperConnection|SCM developer connection in generated pom.xml| |scm:git:git@github.com:openapitools/openapi-generator.git| +|scmUrl|SCM URL in generated pom.xml| |https://github.com/openapitools/openapi-generator| +|developerName|developer name in generated pom.xml| |OpenAPI-Generator Contributors| +|developerEmail|developer email in generated pom.xml| |team@openapitools.org| +|developerOrganization|developer organization in generated pom.xml| |OpenAPITools.org| +|developerOrganizationUrl|developer organization URL in generated pom.xml| |http://openapitools.org| +|licenseName|The name of the license| |Unlicense| +|licenseUrl|The URL of the license| |http://unlicense.org| +|sourceFolder|source folder for generated code| |src/gen/java| +|serializableModel|boolean - toggle "implements Serializable" for generated models| |false| +|bigDecimalAsString|Treat BigDecimal values as Strings to avoid precision loss.| |false| +|fullJavaUtil|whether to use fully qualified name for classes under java.util. This option only works for Java API client| |false| +|hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |false| +|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false| +|dateLibrary|Option. Date library to use|
**joda**
Joda (for legacy app only)
**legacy**
Legacy java.util.Date (if you really have a good reason not to use threetenbp
**java8-localdatetime**
Java 8 using LocalDateTime (for legacy app only)
**java8**
Java 8 native JSR310 (preferred for jdk 1.8+) - note: this also sets "java8" to true
**threetenbp**
Backport of JSR310 (preferred for jdk < 1.8)
|legacy| +|java8|Option. Use Java8 classes instead of third party equivalents|
**true**
Use Java 8 classes such as Base64
**false**
Various third party libraries as needed
|false| +|disableHtmlEscaping|Disable HTML escaping of JSON strings when using gson (needed to avoid problems with byte[] fields)| |false| +|booleanGetterPrefix|Set booleanGetterPrefix| |get| +|parentGroupId|parent groupId in generated pom N.B. parentGroupId, parentArtifactId and parentVersion must all be specified for any of them to take effect| |null| +|parentArtifactId|parent artifactId in generated pom N.B. parentGroupId, parentArtifactId and parentVersion must all be specified for any of them to take effect| |null| +|parentVersion|parent version in generated pom N.B. parentGroupId, parentArtifactId and parentVersion must all be specified for any of them to take effect| |null| +|snapshotVersion|Uses a SNAPSHOT version.|
**true**
Use a SnapShot Version
**false**
Use a Release Version
|null| +|useGenericResponse|Use generic response| |false| +|disableMultipart|Disable multipart annotations| |false| diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaMicroprofileRestClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaMicroprofileRestClientCodegen.java new file mode 100644 index 000000000000..c3328a5d7f30 --- /dev/null +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaMicroprofileRestClientCodegen.java @@ -0,0 +1,192 @@ +/* + * Copyright 2019 OpenAPI-Generator Contributors (https://openapi-generator.tech) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openapitools.codegen.languages; + +import io.swagger.v3.oas.models.Operation; +import io.swagger.v3.oas.models.media.Schema; + +import org.openapitools.codegen.CliOption; +import org.openapitools.codegen.CodegenModel; +import org.openapitools.codegen.CodegenOperation; +import org.openapitools.codegen.CodegenProperty; +import org.openapitools.codegen.CodegenType; +import org.openapitools.codegen.SupportingFile; +import org.openapitools.codegen.languages.features.BeanValidationFeatures; +import org.openapitools.codegen.languages.features.GzipTestFeatures; +import org.openapitools.codegen.languages.features.LoggingTestFeatures; +import org.openapitools.codegen.languages.features.UseGenericResponseFeatures; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.util.List; +import java.util.Map; + +public class JavaMicroprofileRestClientCodegen extends AbstractJavaCodegen + implements BeanValidationFeatures, UseGenericResponseFeatures, GzipTestFeatures, LoggingTestFeatures { + + private static final Logger LOGGER = LoggerFactory.getLogger(JavaMicroprofileRestClientCodegen.class); + + /** + * Name of the sub-directory in "src/main/resource" where to find the + * Mustache template for the JAX-RS Codegen. + */ + protected static final String JAXRS_TEMPLATE_DIRECTORY_NAME = "JavaMicroprofile"; + + protected static final String DISABLE_MULTIPART = "disableMultipart"; + + protected boolean useBeanValidation = false; + + protected boolean useGenericResponse = false; + + protected boolean useGzipFeatureForTests = false; + + protected boolean useLoggingFeatureForTests = false; + + public JavaMicroprofileRestClientCodegen() { + super(); + + supportsInheritance = true; + + sourceFolder = "src/gen/java"; + invokerPackage = "org.openapitools.api"; + artifactId = "gen-microprofile-rest-client"; + dateLibrary = "legacy"; + + apiPackage = "org.openapitools.api"; + modelPackage = "org.openapitools.model"; + + outputFolder = "generated-code/JavaJaxRS-CXF"; + + // clear model and api doc template as this codegen + // does not support auto-generated markdown doc at the moment + modelDocTemplateFiles.remove("model_doc.mustache"); + apiDocTemplateFiles.remove("api_doc.mustache"); + + + typeMapping.put("date", "LocalDate"); + + importMapping.put("LocalDate", "org.joda.time.LocalDate"); + + embeddedTemplateDir = templateDir = JAXRS_TEMPLATE_DIRECTORY_NAME; + + cliOptions.add(CliOption.newBoolean(USE_BEANVALIDATION, "Use BeanValidation API annotations")); + + cliOptions.add(CliOption.newBoolean(USE_GZIP_FEATURE_FOR_TESTS, "Use Gzip Feature for tests")); + cliOptions.add(CliOption.newBoolean(USE_LOGGING_FEATURE_FOR_TESTS, "Use Logging Feature for tests")); + + cliOptions.add(CliOption.newBoolean(USE_GENERIC_RESPONSE, "Use generic response")); + cliOptions.add(CliOption.newBoolean(DISABLE_MULTIPART, "Disable multipart import")); + } + + + @Override + public void processOpts() { + super.processOpts(); + + if (additionalProperties.containsKey(USE_BEANVALIDATION)) { + boolean useBeanValidationProp = convertPropertyToBooleanAndWriteBack(USE_BEANVALIDATION); + this.setUseBeanValidation(useBeanValidationProp); + } + + if (additionalProperties.containsKey(USE_GENERIC_RESPONSE)) { + this.setUseGenericResponse(convertPropertyToBoolean(USE_GENERIC_RESPONSE)); + } + + if (useGenericResponse) { + writePropertyBack(USE_GENERIC_RESPONSE, useGenericResponse); + } + + this.setUseGzipFeatureForTests(convertPropertyToBooleanAndWriteBack(USE_GZIP_FEATURE_FOR_TESTS)); + this.setUseLoggingFeatureForTests(convertPropertyToBooleanAndWriteBack(USE_LOGGING_FEATURE_FOR_TESTS)); + + + supportingFiles.clear(); // Don't need extra files provided by AbstractJAX-RS & Java Codegen + String apiFolder = (sourceFolder + File.separator + apiPackage().replace('.', File.separatorChar)).replace('/', File.separatorChar); + supportingFiles.add(new SupportingFile("api_exception.mustache", apiFolder, "ApiException.java")); + supportingFiles.add(new SupportingFile("api_exception_mapper.mustache", apiFolder, "ApiExceptionMapper.java")); + supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")); + + writeOptional(outputFolder, new SupportingFile("pom.mustache", "", "pom.xml")); + + } + + @Override + public String getName() { + return "microprofile-rest-client"; + } + + + @Override + public CodegenType getTag() { + return CodegenType.CLIENT; + } + + @Override + public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map> operations) { + super.addOperationToGroup(tag, resourcePath, operation, co, operations); + co.subresourceOperation = !co.path.isEmpty(); + } + + @Override + public void postProcessModelProperty(CodegenModel model, CodegenProperty property) { + super.postProcessModelProperty(model, property); + model.imports.remove("ApiModelProperty"); + model.imports.remove("ApiModel"); + model.imports.remove("JsonSerialize"); + model.imports.remove("ToStringSerializer"); + } + + @Override + public CodegenModel fromModel(String name, Schema model) { + CodegenModel codegenModel = super.fromModel(name, model); + if (codegenModel.imports.contains("ApiModel")) { + // Remove io.swagger.annotations.ApiModel import + codegenModel.imports.remove("ApiModel"); + } + + return codegenModel; + } + + @Override + public Map postProcessOperationsWithModels(Map objs, List allModels) { + objs = super.postProcessOperationsWithModels(objs, allModels); + return AbstractJavaJAXRSServerCodegen.jaxrsPostProcessOperations(objs); + } + + @Override + public String getHelp() { + return "Generates a MicroProfile Rest Client"; + } + + public void setUseBeanValidation(boolean useBeanValidation) { + this.useBeanValidation = useBeanValidation; + } + + public void setUseGzipFeatureForTests(boolean useGzipFeatureForTests) { + this.useGzipFeatureForTests = useGzipFeatureForTests; + } + + public void setUseLoggingFeatureForTests(boolean useLoggingFeatureForTests) { + this.useLoggingFeatureForTests = useLoggingFeatureForTests; + } + + public void setUseGenericResponse(boolean useGenericResponse) { + this.useGenericResponse = useGenericResponse; + } + +} diff --git a/modules/openapi-generator/src/main/resources/JavaMicroprofile/README.mustache b/modules/openapi-generator/src/main/resources/JavaMicroprofile/README.mustache new file mode 100644 index 000000000000..576e70fe8bae --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaMicroprofile/README.mustache @@ -0,0 +1,10 @@ +# {{appName}} - MicroProfile Rest Client + +{{#appDescription}} +{{{appDescription}}} + +{{/appDescription}} +## Overview +This API client was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. +[MicroProfile Rest Client](https://github.com/eclipse/microprofile-rest-client) is a type-safe way of calling +REST services. The generated client contains an interface which acts as the client, you can inject it into dependent classes. diff --git a/modules/openapi-generator/src/main/resources/JavaMicroprofile/api.mustache b/modules/openapi-generator/src/main/resources/JavaMicroprofile/api.mustache new file mode 100644 index 000000000000..6acd3f8fa711 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaMicroprofile/api.mustache @@ -0,0 +1,61 @@ +{{>licenseInfo}} +package {{package}}; + +{{#imports}}import {{import}}; +{{/imports}} + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.List; +import java.util.Map; +import javax.ws.rs.*; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.MediaType; +{{^disableMultipart}} +import org.apache.cxf.jaxrs.ext.multipart.*; +{{/disableMultipart}} + +import org.eclipse.microprofile.rest.client.annotation.RegisterProvider; +import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; + +{{#appName}} +/** + * {{{appName}}} + * + {{#appDescription}} + *

{{{appDescription}}} + * + {{/appDescription}} + */ +{{/appName}} + +@RegisterRestClient +@RegisterProvider(ApiExceptionMapper.class) +@Path("{{^useAnnotatedBasePath}}/{{/useAnnotatedBasePath}}{{#useAnnotatedBasePath}}{{contextPath}}{{/useAnnotatedBasePath}}") +public interface {{classname}} { +{{#operations}} +{{#operation}} + + {{#summary}} + /** + * {{summary}} + * + {{#notes}} + * {{notes}} + * + {{/notes}} + */ + {{/summary}} + @{{httpMethod}} + {{#subresourceOperation}}@Path("{{{path}}}"){{/subresourceOperation}} +{{#hasConsumes}} + @Consumes({ {{#consumes}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} }) +{{/hasConsumes}} +{{#hasProduces}} + @Produces({ {{#produces}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }) +{{/hasProduces}} + public {{>returnTypes}} {{nickname}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException, ProcessingException; +{{/operation}} +} +{{/operations}} + diff --git a/modules/openapi-generator/src/main/resources/JavaMicroprofile/api_exception.mustache b/modules/openapi-generator/src/main/resources/JavaMicroprofile/api_exception.mustache new file mode 100644 index 000000000000..fc5c5e5000ae --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaMicroprofile/api_exception.mustache @@ -0,0 +1,23 @@ +{{>licenseInfo}} +package {{apiPackage}}; + +import javax.ws.rs.core.Response; + +public class ApiException extends Exception { + + private static final long serialVersionUID = 1L; + private Response response; + + public ApiException() { + super(); + } + + public ApiException(Response response) { + super("Api response has status code " + response.getStatus()); + this.response = response; + } + + public Response getResponse() { + return this.response; + } +} diff --git a/modules/openapi-generator/src/main/resources/JavaMicroprofile/api_exception_mapper.mustache b/modules/openapi-generator/src/main/resources/JavaMicroprofile/api_exception_mapper.mustache new file mode 100644 index 000000000000..9c5988414cd3 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaMicroprofile/api_exception_mapper.mustache @@ -0,0 +1,22 @@ +{{>licenseInfo}} +package {{apiPackage}}; + +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.Provider; +import org.eclipse.microprofile.rest.client.ext.ResponseExceptionMapper; + +@Provider +public class ApiExceptionMapper + implements ResponseExceptionMapper { + + @Override + public boolean handles(int status, MultivaluedMap headers) { + return status >= 400; + } + + @Override + public ApiException toThrowable(Response response) { + return new ApiException(response); + } +} diff --git a/modules/openapi-generator/src/main/resources/JavaMicroprofile/api_test.mustache b/modules/openapi-generator/src/main/resources/JavaMicroprofile/api_test.mustache new file mode 100644 index 000000000000..bb359c52f4da --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaMicroprofile/api_test.mustache @@ -0,0 +1,75 @@ +{{>licenseInfo}} + +package {{package}}; + +{{#imports}}import {{import}}; +{{/imports}} +import org.junit.Test; +import org.junit.Before; +import static org.junit.Assert.*; + +import org.eclipse.microprofile.rest.client.RestClientBuilder; + +import java.net.URL; +import java.net.MalformedURLException; +{{^fullJavaUtil}} +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +{{/fullJavaUtil}} + + + +/** + {{#appName}} + * {{{appName}}} Test + * + {{/appName}} + * API tests for {{classname}} + */ +{{#generateSpringBootApplication}} +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = SpringBootApplication.class) +@WebAppConfiguration +@IntegrationTest("server.port=0") +{{/generateSpringBootApplication}} +public class {{classname}}Test { + + private {{classname}} client; + private String baseUrl = "http://localhost:9080"; + + @Before + public void setup() throws MalformedURLException { + client = RestClientBuilder.newBuilder() + .baseUrl(new URL(baseUrl)) + .register(ApiException.class) + .build({{classname}}.class); + } + + {{#operations}}{{#operation}} + /** + {{#summary}} + * {{summary}} + * + {{#notes}} + * {{notes}} + * + {{/notes}} + {{/summary}} + * @throws ApiException + * if the Api call fails + */ + @Test + public void {{operationId}}Test() { + // TODO: test validations + {{#allParams}} + {{^isFile}}{{{dataType}}} {{paramName}} = null;{{/isFile}}{{#isFile}}org.apache.cxf.jaxrs.ext.multipart.Attachment {{paramName}} = null;{{/isFile}} + {{/allParams}} + //{{^vendorExtensions.x-java-is-response-void}}{{>returnTypes}} response = {{/vendorExtensions.x-java-is-response-void}}api.{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}); + {{^vendorExtensions.x-java-is-response-void}}//assertNotNull(response);{{/vendorExtensions.x-java-is-response-void}} + + + } + {{/operation}}{{/operations}} +} diff --git a/modules/openapi-generator/src/main/resources/JavaMicroprofile/beanValidation.mustache b/modules/openapi-generator/src/main/resources/JavaMicroprofile/beanValidation.mustache new file mode 100644 index 000000000000..c8c6946fef66 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaMicroprofile/beanValidation.mustache @@ -0,0 +1,4 @@ +{{#required}} + @NotNull +{{/required}} +{{>beanValidationCore}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/JavaMicroprofile/beanValidationCore.mustache b/modules/openapi-generator/src/main/resources/JavaMicroprofile/beanValidationCore.mustache new file mode 100644 index 000000000000..8bcdce3df16e --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaMicroprofile/beanValidationCore.mustache @@ -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}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/JavaMicroprofile/beanValidationHeaderParams.mustache b/modules/openapi-generator/src/main/resources/JavaMicroprofile/beanValidationHeaderParams.mustache new file mode 100644 index 000000000000..f8eef8f94c7b --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaMicroprofile/beanValidationHeaderParams.mustache @@ -0,0 +1 @@ +{{#required}} @NotNull{{/required}}{{>beanValidationCore}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/JavaMicroprofile/beanValidationPathParams.mustache b/modules/openapi-generator/src/main/resources/JavaMicroprofile/beanValidationPathParams.mustache new file mode 100644 index 000000000000..051bd53c0a58 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaMicroprofile/beanValidationPathParams.mustache @@ -0,0 +1 @@ +{{! PathParam is always required, no @NotNull necessary }}{{>beanValidationCore}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/JavaMicroprofile/beanValidationQueryParams.mustache b/modules/openapi-generator/src/main/resources/JavaMicroprofile/beanValidationQueryParams.mustache new file mode 100644 index 000000000000..f8eef8f94c7b --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaMicroprofile/beanValidationQueryParams.mustache @@ -0,0 +1 @@ +{{#required}} @NotNull{{/required}}{{>beanValidationCore}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/JavaMicroprofile/bodyParams.mustache b/modules/openapi-generator/src/main/resources/JavaMicroprofile/bodyParams.mustache new file mode 100644 index 000000000000..be56da7535be --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaMicroprofile/bodyParams.mustache @@ -0,0 +1 @@ +{{#isBodyParam}}{{#useBeanValidation}}@Valid {{/useBeanValidation}}{{{dataType}}} {{paramName}}{{/isBodyParam}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/JavaMicroprofile/bodyParamsImpl.mustache b/modules/openapi-generator/src/main/resources/JavaMicroprofile/bodyParamsImpl.mustache new file mode 100644 index 000000000000..c7d1abfe527e --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaMicroprofile/bodyParamsImpl.mustache @@ -0,0 +1 @@ +{{#isBodyParam}}{{{dataType}}} {{paramName}}{{/isBodyParam}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/JavaMicroprofile/enumClass.mustache b/modules/openapi-generator/src/main/resources/JavaMicroprofile/enumClass.mustache new file mode 100644 index 000000000000..5bdcf238a2c1 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaMicroprofile/enumClass.mustache @@ -0,0 +1,33 @@ +@XmlType(name="{{datatypeWithEnum}}") +@XmlEnum({{dataType}}.class) +public enum {{datatypeWithEnum}} { + + {{#allowableValues}} +{{#enumVars}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}) {{name}}({{dataType}}.valueOf({{{value}}})){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}} + {{/allowableValues}} + + + private {{dataType}} value; + + {{datatypeWithEnum}} ({{dataType}} v) { + value = v; + } + + public {{dataType}} value() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + public static {{datatypeWithEnum}} fromValue(String v) { + for ({{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} b : {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.values()) { + if (String.valueOf(b.value).equals(v)) { + return b; + } + } + {{#useNullForUnknownEnumValue}}return null;{{/useNullForUnknownEnumValue}}{{^useNullForUnknownEnumValue}}throw new IllegalArgumentException("Unexpected value '" + v + "'");{{/useNullForUnknownEnumValue}} + } +} diff --git a/modules/openapi-generator/src/main/resources/JavaMicroprofile/enumOuterClass.mustache b/modules/openapi-generator/src/main/resources/JavaMicroprofile/enumOuterClass.mustache new file mode 100644 index 000000000000..df2c72873962 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaMicroprofile/enumOuterClass.mustache @@ -0,0 +1,48 @@ +{{#jackson}} +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +{{/jackson}} + +/** + * {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{description}}{{/description}} + */ +public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} { + {{#gson}} + {{#allowableValues}}{{#enumVars}} + @SerializedName({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}) + {{{name}}}({{{value}}}){{^-last}}, + {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}{{/allowableValues}} + {{/gson}} + {{^gson}} + {{#allowableValues}}{{#enumVars}} + {{{name}}}({{{value}}}){{^-last}}, + {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}{{/allowableValues}} + {{/gson}} + + private {{{dataType}}} value; + + {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}({{{dataType}}} value) { + this.value = value; + } + + @Override +{{#jackson}} + @JsonValue +{{/jackson}} + public String toString() { + return String.valueOf(value); + } + +{{#jackson}} + @JsonCreator +{{/jackson}} + public static {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} fromValue(String text) { + for ({{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} b : {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.values()) { + if (String.valueOf(b.value).equals(text)) { + return b; + } + } + {{#useNullForUnknownEnumValue}}return null;{{/useNullForUnknownEnumValue}}{{^useNullForUnknownEnumValue}}throw new IllegalArgumentException("Unexpected value '" + text + "'");{{/useNullForUnknownEnumValue}} + } + +} diff --git a/modules/openapi-generator/src/main/resources/JavaMicroprofile/formParams.mustache b/modules/openapi-generator/src/main/resources/JavaMicroprofile/formParams.mustache new file mode 100644 index 000000000000..97216dc1806f --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaMicroprofile/formParams.mustache @@ -0,0 +1 @@ +{{#isFormParam}}{{^isFile}}@Multipart(value = "{{baseName}}"{{^required}}, required = false{{/required}}) {{{dataType}}} {{paramName}}{{/isFile}}{{#isFile}} @Multipart(value = "{{baseName}}" {{^required}}, required = false{{/required}}) Attachment {{paramName}}Detail{{/isFile}}{{/isFormParam}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/JavaMicroprofile/formParamsImpl.mustache b/modules/openapi-generator/src/main/resources/JavaMicroprofile/formParamsImpl.mustache new file mode 100644 index 000000000000..2be40e1ddd3d --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaMicroprofile/formParamsImpl.mustache @@ -0,0 +1 @@ +{{#isFormParam}}{{^isFile}}{{{dataType}}} {{paramName}}{{/isFile}}{{#isFile}} Attachment {{paramName}}Detail{{/isFile}}{{/isFormParam}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/JavaMicroprofile/generatedAnnotation.mustache b/modules/openapi-generator/src/main/resources/JavaMicroprofile/generatedAnnotation.mustache new file mode 100644 index 000000000000..49110fc1ad93 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaMicroprofile/generatedAnnotation.mustache @@ -0,0 +1 @@ +@javax.annotation.Generated(value = "{{generatorClass}}", date = "{{generatedDate}}") \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/JavaMicroprofile/headerParams.mustache b/modules/openapi-generator/src/main/resources/JavaMicroprofile/headerParams.mustache new file mode 100644 index 000000000000..4a9009e76a20 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaMicroprofile/headerParams.mustache @@ -0,0 +1 @@ +{{#isHeaderParam}}@HeaderParam("{{baseName}}") {{#useBeanValidation}}{{>beanValidationHeaderParams}}{{/useBeanValidation}} {{{dataType}}} {{paramName}}{{/isHeaderParam}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/JavaMicroprofile/headerParamsImpl.mustache b/modules/openapi-generator/src/main/resources/JavaMicroprofile/headerParamsImpl.mustache new file mode 100644 index 000000000000..bd03573d196e --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaMicroprofile/headerParamsImpl.mustache @@ -0,0 +1 @@ +{{#isHeaderParam}}{{{dataType}}} {{paramName}}{{/isHeaderParam}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/JavaMicroprofile/licenseInfo.mustache b/modules/openapi-generator/src/main/resources/JavaMicroprofile/licenseInfo.mustache new file mode 100644 index 000000000000..02acad802ec0 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaMicroprofile/licenseInfo.mustache @@ -0,0 +1,23 @@ +/** + * {{{appName}}} + * {{{appDescription}}} + * + * {{#version}}The version of the OpenAPI document: {{{version}}}{{/version}} + * {{#infoEmail}}Contact: {{{infoEmail}}}{{/infoEmail}} + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ diff --git a/modules/openapi-generator/src/main/resources/JavaMicroprofile/model.mustache b/modules/openapi-generator/src/main/resources/JavaMicroprofile/model.mustache new file mode 100644 index 000000000000..5272ff094879 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaMicroprofile/model.mustache @@ -0,0 +1,23 @@ +{{>licenseInfo}} +package {{package}}; + +{{#imports}}import {{import}}; +{{/imports}} +{{#serializableModel}} +import java.io.Serializable; +{{/serializableModel}} +{{#useBeanValidation}} +import javax.validation.constraints.*; +import javax.validation.Valid; +{{/useBeanValidation}} + +{{#models}} +{{#model}} +{{#isEnum}} +{{>enumOuterClass}} +{{/isEnum}} +{{^isEnum}} +{{>pojo}} +{{/isEnum}} +{{/model}} +{{/models}} diff --git a/modules/openapi-generator/src/main/resources/JavaMicroprofile/pathParams.mustache b/modules/openapi-generator/src/main/resources/JavaMicroprofile/pathParams.mustache new file mode 100644 index 000000000000..9e8455d5ac7b --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaMicroprofile/pathParams.mustache @@ -0,0 +1 @@ +{{#isPathParam}}@PathParam("{{baseName}}"){{#useBeanValidation}}{{>beanValidationPathParams}}{{/useBeanValidation}} {{{dataType}}} {{paramName}}{{/isPathParam}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/JavaMicroprofile/pathParamsImpl.mustache b/modules/openapi-generator/src/main/resources/JavaMicroprofile/pathParamsImpl.mustache new file mode 100644 index 000000000000..6829cf8c7a67 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaMicroprofile/pathParamsImpl.mustache @@ -0,0 +1 @@ +{{#isPathParam}}{{{dataType}}} {{paramName}}{{/isPathParam}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/JavaMicroprofile/pojo.mustache b/modules/openapi-generator/src/main/resources/JavaMicroprofile/pojo.mustache new file mode 100644 index 000000000000..a7d3ddb77c1c --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaMicroprofile/pojo.mustache @@ -0,0 +1,129 @@ +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlEnum; +import javax.xml.bind.annotation.XmlEnumValue; +import javax.json.bind.annotation.JsonbProperty; + +{{#withXml}} +@XmlAccessorType(XmlAccessType.FIELD) +{{#hasVars}} @XmlType(name = "{{classname}}", propOrder = + { {{#vars}}"{{name}}"{{^-last}}, {{/-last}}{{/vars}} +}){{/hasVars}} +{{^hasVars}}@XmlType(name = "{{classname}}"){{/hasVars}} +{{^parent}}@XmlRootElement(name="{{classname}}"){{/parent}} +{{/withXml}} +{{#description}} +/** + * {{{description}}} + **/ +{{/description}} +public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}}{{#serializableModel}} implements Serializable{{/serializableModel}} { + {{#vars}}{{#isEnum}}{{^isContainer}} +{{>enumClass}}{{/isContainer}}{{#isContainer}}{{#mostInnerItems}} +{{>enumClass}}{{/mostInnerItems}}{{/isContainer}}{{/isEnum}} +{{#withXml}} + @XmlElement(name="{{baseName}}"{{#required}}, required = {{required}}{{/required}}) +{{/withXml}} +{{#description}} + /** + * {{{description}}} + **/ +{{/description}} +{{#isContainer}} + private {{{datatypeWithEnum}}} {{name}}{{#required}} = {{{defaultValue}}}{{/required}}{{^required}} = null{{/required}}; +{{/isContainer}} +{{^isContainer}} + private {{{datatypeWithEnum}}} {{name}}{{#defaultValue}} = {{{.}}}{{/defaultValue}}; +{{/isContainer}} + {{/vars}} + + {{#vars}} + /** + {{#description}} + * {{description}} + {{/description}} + {{^description}} + * Get {{name}} + {{/description}} + {{#minimum}} + * minimum: {{minimum}} + {{/minimum}} + {{#maximum}} + * maximum: {{maximum}} + {{/maximum}} + * @return {{name}} + **/ + @JsonbProperty("{{baseName}}") +{{#vendorExtensions.extraAnnotation}} + {{{vendorExtensions.extraAnnotation}}} +{{/vendorExtensions.extraAnnotation}} +{{#useBeanValidation}}{{>beanValidation}}{{/useBeanValidation}} {{#isEnum}}{{^isListContainer}}{{^isMapContainer}}public {{dataType}} {{getter}}() { + if ({{name}} == null) { + return null; + } + return {{name}}.value(); + }{{/isMapContainer}}{{/isListContainer}}{{/isEnum}}{{#isEnum}}{{#isListContainer}}public {{{datatypeWithEnum}}} {{getter}}() { + return {{name}}; + }{{/isListContainer}}{{/isEnum}}{{#isEnum}}{{#isMapContainer}}public {{{datatypeWithEnum}}} {{getter}}() { + return {{name}}; + }{{/isMapContainer}}{{/isEnum}}{{^isEnum}}public {{{datatypeWithEnum}}} {{getter}}() { + return {{name}}; + }{{/isEnum}} + + {{^isReadOnly}} + /** + * Set {{name}} + **/ + public void {{setter}}({{{datatypeWithEnum}}} {{name}}) { + this.{{name}} = {{name}}; + } + + public {{classname}} {{name}}({{{datatypeWithEnum}}} {{name}}) { + this.{{name}} = {{name}}; + return this; + } + {{#isListContainer}} + + public {{classname}} add{{nameInCamelCase}}Item({{{items.datatypeWithEnum}}} {{name}}Item) { + this.{{name}}.add({{name}}Item); + return this; + } + {{/isListContainer}} + {{#isMapContainer}} + + public {{classname}} put{{nameInCamelCase}}Item(String key, {{{items.datatypeWithEnum}}} {{name}}Item) { + this.{{name}}.put(key, {{name}}Item); + return this; + } + {{/isMapContainer}} + {{/isReadOnly}} + + {{/vars}} + + /** + * Create a string representation of this pojo. + **/ + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class {{classname}} {\n"); + {{#parent}}sb.append(" ").append(toIndentedString(super.toString())).append("\n");{{/parent}} + {{#vars}}sb.append(" {{name}}: ").append(toIndentedString({{name}})).append("\n"); + {{/vars}}sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private static String toIndentedString(java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} diff --git a/modules/openapi-generator/src/main/resources/JavaMicroprofile/pom.mustache b/modules/openapi-generator/src/main/resources/JavaMicroprofile/pom.mustache new file mode 100644 index 000000000000..95ffef033531 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaMicroprofile/pom.mustache @@ -0,0 +1,173 @@ + + 4.0.0 + {{groupId}} + {{artifactId}} + jar + {{artifactId}} + {{#appDescription}} + {{appDescription}} + {{/appDescription}} + {{artifactVersion}} + + src/main/java + + + maven-failsafe-plugin + 2.6 + + + + integration-test + verify + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.9.1 + + + add-source + generate-sources + + add-source + + + + src/gen/java + + + + + + + + + + junit + junit + ${junit-version} + test + +{{#useBeanValidation}} + + + javax.validation + validation-api + ${beanvalidation-version} + provided + +{{/useBeanValidation}} + + + org.eclipse.microprofile.rest.client + microprofile-rest-client-api + 1.2.1 + + + + + javax.ws.rs + javax.ws.rs-api + 2.1.1 + provided + + + + io.smallrye + smallrye-rest-client + 1.2.1 + test + + + + io.smallrye + smallrye-config + 1.3.5 + test + + + {{^disableMultipart}} + + org.apache.cxf + cxf-rt-rs-extension-providers + 3.2.6 + + {{/disableMultipart}} + + + javax.json.bind + javax.json.bind-api + 1.0 + + + javax.xml.bind + jaxb-api + 2.2.11 + + + com.sun.xml.bind + jaxb-core + 2.2.11 + + + com.sun.xml.bind + jaxb-impl + 2.2.11 + + + javax.activation + activation + 1.1.1 + + +{{#java8}} + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + ${jackson-jaxrs-version} + +{{/java8}} +{{^java8}} + + com.fasterxml.jackson.datatype + jackson-datatype-joda + ${jackson-jaxrs-version} + +{{/java8}} +{{#useBeanValidationFeature}} + + org.hibernate + hibernate-validator + 5.2.2.Final + +{{/useBeanValidationFeature}} + + + + sonatype-snapshots + https://oss.sonatype.org/content/repositories/snapshots + + true + + + + + 1.8 + ${java.version} + ${java.version} + 1.5.18 + 9.2.9.v20150224 + 4.12 + 1.1.7 + 2.5 +{{#useBeanValidation}} + 1.1.0.Final +{{/useBeanValidation}} + 3.2.7 + 2.9.7 + UTF-8 + + diff --git a/modules/openapi-generator/src/main/resources/JavaMicroprofile/queryParams.mustache b/modules/openapi-generator/src/main/resources/JavaMicroprofile/queryParams.mustache new file mode 100644 index 000000000000..ca2c6e106f78 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaMicroprofile/queryParams.mustache @@ -0,0 +1 @@ +{{#isQueryParam}}@QueryParam("{{baseName}}"){{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}} {{^isContainer}}{{#defaultValue}}@DefaultValue({{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}) {{/defaultValue}}{{/isContainer}}{{{dataType}}} {{paramName}}{{/isQueryParam}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/JavaMicroprofile/queryParamsImpl.mustache b/modules/openapi-generator/src/main/resources/JavaMicroprofile/queryParamsImpl.mustache new file mode 100644 index 000000000000..ff79730471d9 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaMicroprofile/queryParamsImpl.mustache @@ -0,0 +1 @@ +{{#isQueryParam}}{{{dataType}}} {{paramName}}{{/isQueryParam}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/JavaMicroprofile/returnTypes.mustache b/modules/openapi-generator/src/main/resources/JavaMicroprofile/returnTypes.mustache new file mode 100644 index 000000000000..6af86ffe4e4a --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaMicroprofile/returnTypes.mustache @@ -0,0 +1,4 @@ +{{#useGenericResponse}}Response{{/useGenericResponse}}{{! non-generic response: +}}{{^useGenericResponse}}{{! +}}{{{returnType}}}{{! +}}{{/useGenericResponse}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig b/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig index f6ca902864db..e653360dfc0c 100644 --- a/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig +++ b/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig @@ -110,5 +110,6 @@ org.openapitools.codegen.languages.TypeScriptFetchClientCodegen org.openapitools.codegen.languages.TypeScriptInversifyClientCodegen org.openapitools.codegen.languages.TypeScriptJqueryClientCodegen org.openapitools.codegen.languages.TypeScriptNodeClientCodegen +org.openapitools.codegen.languages.JavaMicroprofileRestClientCodegen org.openapitools.codegen.languages.TypeScriptRxjsClientCodegen org.openapitools.codegen.languages.FsharpGiraffeServerCodegen diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaMicroprofileRestClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaMicroprofileRestClientCodegenTest.java new file mode 100644 index 000000000000..1ef03259a76c --- /dev/null +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaMicroprofileRestClientCodegenTest.java @@ -0,0 +1,125 @@ +/* + * Copyright 2019 OpenAPI-Generator Contributors (https://openapi-generator.tech) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openapitools.codegen.java; + +import io.swagger.v3.oas.models.Operation; +import io.swagger.v3.oas.models.media.ArraySchema; +import io.swagger.v3.oas.models.media.Content; +import io.swagger.v3.oas.models.media.MediaType; +import io.swagger.v3.oas.models.media.ObjectSchema; +import io.swagger.v3.oas.models.media.Schema; +import io.swagger.v3.oas.models.responses.ApiResponse; +import io.swagger.v3.oas.models.responses.ApiResponses; + +import org.openapitools.codegen.CodegenConstants; +import org.openapitools.codegen.CodegenOperation; +import org.openapitools.codegen.CodegenResponse; +import org.openapitools.codegen.languages.JavaCXFClientCodegen; +import org.openapitools.codegen.languages.JavaMicroprofileRestClientCodegen; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +public class JavaMicroprofileRestClientCodegenTest { + + @Test + public void responseWithoutContent() throws Exception { + final Schema listOfPets = new ArraySchema().items(new Schema<>().$ref("#/components/schemas/Pet")); + Operation operation = new Operation() + .responses(new ApiResponses() + .addApiResponse("200", + new ApiResponse().description("Return a list of pets") + .content(new Content().addMediaType("application/json", + new MediaType().schema(listOfPets)))) + .addApiResponse("400", new ApiResponse().description("Error"))); + final Map allDefinitions = Collections.singletonMap("Pet", new ObjectSchema()); + + final JavaMicroprofileRestClientCodegen codegen = new JavaMicroprofileRestClientCodegen(); + final CodegenOperation co = codegen.fromOperation("getAllPets", "GET", operation, null); + + Map objs = new HashMap<>(); + objs.put("operations", Collections.singletonMap("operation", Collections.singletonList(co))); + objs.put("imports", Collections.emptyList()); + codegen.postProcessOperationsWithModels(objs, Collections.emptyList()); + + Assert.assertEquals(co.responses.size(), 2); + CodegenResponse cr1 = co.responses.get(0); + Assert.assertEquals(cr1.code, "200"); + Assert.assertEquals(cr1.baseType, "Pet"); + Assert.assertEquals(cr1.dataType, "List"); + Assert.assertFalse(cr1.vendorExtensions.containsKey("x-java-is-response-void")); + + CodegenResponse cr2 = co.responses.get(1); + Assert.assertEquals(cr2.code, "400"); + Assert.assertEquals(cr2.baseType, "Void"); + Assert.assertEquals(cr2.dataType, "void"); + Assert.assertEquals(cr2.vendorExtensions.get("x-java-is-response-void"), Boolean.TRUE); + } + + @Test + public void testInitialConfigValues() throws Exception { + final JavaMicroprofileRestClientCodegen codegen = new JavaMicroprofileRestClientCodegen(); + codegen.processOpts(); + + Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.HIDE_GENERATION_TIMESTAMP), Boolean.FALSE); + Assert.assertEquals(codegen.isHideGenerationTimestamp(), false); + + 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.getInvokerPackage(), "org.openapitools.api"); + Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.INVOKER_PACKAGE), "org.openapitools.api"); + } + + @Test + public void testSettersForConfigValues() throws Exception { + final JavaMicroprofileRestClientCodegen codegen = new JavaMicroprofileRestClientCodegen(); + codegen.setHideGenerationTimestamp(true); + codegen.setInvokerPackage("org.openapitools.client.xyz.invoker"); + codegen.processOpts(); + + Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.HIDE_GENERATION_TIMESTAMP), Boolean.TRUE); + Assert.assertEquals(codegen.isHideGenerationTimestamp(), true); + 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.getInvokerPackage(), "org.openapitools.client.xyz.invoker"); + Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.INVOKER_PACKAGE), "org.openapitools.client.xyz.invoker"); + } + + @Test + public void testAdditionalPropertiesPutForConfigValues() throws Exception { + final JavaMicroprofileRestClientCodegen codegen = new JavaMicroprofileRestClientCodegen(); + codegen.additionalProperties().put(CodegenConstants.HIDE_GENERATION_TIMESTAMP, "false"); + codegen.additionalProperties().put(CodegenConstants.INVOKER_PACKAGE,"org.openapitools.client.xyz.invoker"); + codegen.processOpts(); + + Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.HIDE_GENERATION_TIMESTAMP), Boolean.FALSE); + Assert.assertEquals(codegen.isHideGenerationTimestamp(), false); + 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.getInvokerPackage(), "org.openapitools.client.xyz.invoker"); + Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.INVOKER_PACKAGE), "org.openapitools.client.xyz.invoker"); + } +}