forked from loafle/openapi-generator-original
Add Micronaut server generator (#10270)
* Add micronaut server implementation * Add micronaut server tests and imporovements * Generate samples, docs and verify that tests pass * Update micronaut docs and samples after merging with master * Update micronaut dev server samples * Add micronuat server docs * Update micronaut version * Minor changes to micronaut server and client * Fix documentation generation in samples Co-authored-by: Andriy Dmytruk <andriy.dmytruk@andriy.dmytruk.ca.oracle.com>
This commit is contained in:
@@ -7,3 +7,4 @@ additionalProperties:
|
||||
configureAuth: "false"
|
||||
build: "all"
|
||||
test: "spock"
|
||||
requiredPropertiesInConstructor: "false"
|
||||
|
||||
10
bin/configs/java-micronaut-server.yaml
Normal file
10
bin/configs/java-micronaut-server.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
generatorName: java-micronaut-server
|
||||
outputDir: samples/server/petstore/java-micronaut-server/
|
||||
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
|
||||
additionalProperties:
|
||||
artifactId: petstore-micronaut-server
|
||||
hideGenerationTimestamp: "true"
|
||||
build: "all"
|
||||
test: "spock"
|
||||
requiredPropertiesInConstructor: "true"
|
||||
useAuth: "false"
|
||||
@@ -99,6 +99,7 @@ The following generators are available:
|
||||
* [haskell-yesod (beta)](generators/haskell-yesod.md)
|
||||
* [java-camel](generators/java-camel.md)
|
||||
* [java-inflector](generators/java-inflector.md)
|
||||
* [java-micronaut-server (beta)](generators/java-micronaut-server.md)
|
||||
* [java-msf4j](generators/java-msf4j.md)
|
||||
* [java-pkmst](generators/java-pkmst.md)
|
||||
* [java-play-framework](generators/java-play-framework.md)
|
||||
|
||||
@@ -29,7 +29,6 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|
||||
|bigDecimalAsString|Treat BigDecimal values as Strings to avoid precision loss.| |false|
|
||||
|booleanGetterPrefix|Set booleanGetterPrefix| |get|
|
||||
|build|Specify for which build tool to generate files|<dl><dt>**gradle**</dt><dd>Gradle configuration is generated for the project</dd><dt>**all**</dt><dd>Both Gradle and Maven configurations are generated</dd><dt>**maven**</dt><dd>Maven configuration is generated for the project</dd></dl>|all|
|
||||
|configPackage|Configuration package for generated code| |org.openapitools.configuration|
|
||||
|configureAuth|Configure all the authorization methods as specified in the file| |false|
|
||||
|developerEmail|developer email in generated pom.xml| |team@openapitools.org|
|
||||
|developerName|developer name in generated pom.xml| |OpenAPI-Generator Contributors|
|
||||
@@ -49,12 +48,14 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|
||||
|legacyDiscriminatorBehavior|Set to false for generators with better support for discriminators. (Python, Java, Go, PowerShell, C#have this enabled by default).|<dl><dt>**true**</dt><dd>The mapping in the discriminator includes descendent schemas that allOf inherit from self and the discriminator mapping schemas in the OAS document.</dd><dt>**false**</dt><dd>The mapping in the discriminator includes any descendent schemas that allOf inherit from self, any oneOf schemas, any anyOf schemas, any x-discriminator-values, and the discriminator mapping schemas in the OAS document AND Codegen validates that oneOf and anyOf schemas contain the required discriminator and throws an error if the discriminator is missing.</dd></dl>|true|
|
||||
|licenseName|The name of the license| |Unlicense|
|
||||
|licenseUrl|The URL of the license| |http://unlicense.org|
|
||||
|micronautVersion|Micronaut version, only >=3.0.0 versions are supported| |3.2.6|
|
||||
|modelPackage|package for generated models| |org.openapitools.model|
|
||||
|openApiNullable|Enable OpenAPI Jackson Nullable library| |true|
|
||||
|parentArtifactId|parent artifactId in generated pom N.B. parentGroupId, parentArtifactId and parentVersion must all be specified for any of them to take effect| |null|
|
||||
|parentGroupId|parent groupId 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|
|
||||
|prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false|
|
||||
|requiredPropertiesInConstructor|Allow only to create models with all the required properties provided in constructor| |true|
|
||||
|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|
|
||||
@@ -64,7 +65,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|
||||
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
|
||||
|sourceFolder|source folder for generated code| |src/main/java|
|
||||
|test|Specify which test tool to generate files for|<dl><dt>**junit**</dt><dd>Use JUnit as test tool</dd><dt>**spock**</dt><dd>Use Spock as test tool</dd></dl>|junit|
|
||||
|title|Client service name| |OpenAPI Micronaut Client|
|
||||
|title|Client service name| |null|
|
||||
|useBeanValidation|Use BeanValidation API annotations| |true|
|
||||
|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|
|
||||
|
||||
|
||||
314
docs/generators/java-micronaut-server.md
Normal file
314
docs/generators/java-micronaut-server.md
Normal file
@@ -0,0 +1,314 @@
|
||||
---
|
||||
title: Documentation for the java-micronaut-server Generator
|
||||
---
|
||||
|
||||
## METADATA
|
||||
|
||||
| Property | Value | Notes |
|
||||
| -------- | ----- | ----- |
|
||||
| generator name | java-micronaut-server | pass this to the generate command after -g |
|
||||
| generator stability | BETA | |
|
||||
| generator type | SERVER | |
|
||||
| generator language | Java | |
|
||||
| helpTxt | Generates a Java Micronaut Server. | |
|
||||
|
||||
## CONFIG OPTIONS
|
||||
These options may be applied as additional-properties (cli) or configOptions (plugins). Refer to [configuration docs](https://openapi-generator.tech/docs/configuration) for more details.
|
||||
|
||||
| Option | Description | Values | Default |
|
||||
| ------ | ----------- | ------ | ------- |
|
||||
|additionalEnumTypeAnnotations|Additional annotations for enum type(class level annotations)| |null|
|
||||
|additionalModelTypeAnnotations|Additional annotations for model type(class level annotations). List separated by semicolon(;) or new line (Linux or Windows)| |null|
|
||||
|allowUnicodeIdentifiers|boolean, toggles whether unicode identifiers are allowed in names or not, default is false| |false|
|
||||
|artifactDescription|artifact description in generated pom.xml| |OpenAPI Java|
|
||||
|artifactId|artifactId in generated pom.xml. This also becomes part of the generated library's filename| |openapi-micronaut|
|
||||
|artifactUrl|artifact URL in generated pom.xml| |https://github.com/openapitools/openapi-generator|
|
||||
|artifactVersion|artifact version in generated pom.xml. This also becomes part of the generated library's filename| |1.0.0|
|
||||
|bigDecimalAsString|Treat BigDecimal values as Strings to avoid precision loss.| |false|
|
||||
|booleanGetterPrefix|Set booleanGetterPrefix| |get|
|
||||
|build|Specify for which build tool to generate files|<dl><dt>**gradle**</dt><dd>Gradle configuration is generated for the project</dd><dt>**all**</dt><dd>Both Gradle and Maven configurations are generated</dd><dt>**maven**</dt><dd>Maven configuration is generated for the project</dd></dl>|all|
|
||||
|controllerPackage|The package in which controllers will be generated| |org.openapitools.api|
|
||||
|developerEmail|developer email in generated pom.xml| |team@openapitools.org|
|
||||
|developerName|developer name in generated pom.xml| |OpenAPI-Generator Contributors|
|
||||
|developerOrganization|developer organization in generated pom.xml| |OpenAPITools.org|
|
||||
|developerOrganizationUrl|developer organization URL in generated pom.xml| |http://openapitools.org|
|
||||
|disableHtmlEscaping|Disable HTML escaping of JSON strings when using gson (needed to avoid problems with byte[] fields)| |false|
|
||||
|disallowAdditionalPropertiesIfNotPresent|If false, the 'additionalProperties' implementation (set to true by default) is compliant with the OAS and JSON schema specifications. If true (default), keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.|<dl><dt>**false**</dt><dd>The 'additionalProperties' implementation is compliant with the OAS and JSON schema specifications.</dd><dt>**true**</dt><dd>Keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.</dd></dl>|true|
|
||||
|discriminatorCaseSensitive|Whether the discriminator value lookup should be case-sensitive or not. This option only works for Java API client| |true|
|
||||
|ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true|
|
||||
|enumUnknownDefaultCase|If the server adds new enum cases, that are unknown by an old spec/client, the client will fail to parse the network response.With this option enabled, each enum will have a new case, 'unknown_default_open_api', so that when the server sends an enum case that is not known by the client/spec, they can safely fallback to this case.|<dl><dt>**false**</dt><dd>No changes to the enum's are made, this is the default option.</dd><dt>**true**</dt><dd>With this option enabled, each enum will have a new case, 'unknown_default_open_api', so that when the enum case sent by the server is not known by the client/spec, can safely be decoded to this case.</dd></dl>|false|
|
||||
|fullJavaUtil|whether to use fully qualified name for classes under java.util. This option only works for Java API client| |false|
|
||||
|generateControllerAsAbstract|Generate an abstract class for controller to be extended. (apiPackage is then used for the abstract class, and controllerPackage is used for implementation that extends it.)| |false|
|
||||
|generateControllerFromExamples|Generate the implementation of controller and tests from parameter and return examples that will verify that the api works as desired (for testing)| |false|
|
||||
|groupId|groupId in generated pom.xml| |org.openapitools|
|
||||
|hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |false|
|
||||
|ignoreAnyOfInEnum|Ignore anyOf keyword in enum| |false|
|
||||
|invokerPackage|root package for generated code| |org.openapitools|
|
||||
|java8|Use Java8 classes instead of third party equivalents. Starting in 5.x, JDK8 is the default and the support for JDK7, JDK6 has been dropped|<dl><dt>**true**</dt><dd>Use Java 8 classes such as Base64</dd><dt>**false**</dt><dd>Various third party libraries as needed</dd></dl>|true|
|
||||
|legacyDiscriminatorBehavior|Set to false for generators with better support for discriminators. (Python, Java, Go, PowerShell, C#have this enabled by default).|<dl><dt>**true**</dt><dd>The mapping in the discriminator includes descendent schemas that allOf inherit from self and the discriminator mapping schemas in the OAS document.</dd><dt>**false**</dt><dd>The mapping in the discriminator includes any descendent schemas that allOf inherit from self, any oneOf schemas, any anyOf schemas, any x-discriminator-values, and the discriminator mapping schemas in the OAS document AND Codegen validates that oneOf and anyOf schemas contain the required discriminator and throws an error if the discriminator is missing.</dd></dl>|true|
|
||||
|licenseName|The name of the license| |Unlicense|
|
||||
|licenseUrl|The URL of the license| |http://unlicense.org|
|
||||
|micronautVersion|Micronaut version, only >=3.0.0 versions are supported| |3.2.6|
|
||||
|modelPackage|package for generated models| |org.openapitools.model|
|
||||
|openApiNullable|Enable OpenAPI Jackson Nullable library| |true|
|
||||
|parentArtifactId|parent artifactId in generated pom N.B. parentGroupId, parentArtifactId and parentVersion must all be specified for any of them to take effect| |null|
|
||||
|parentGroupId|parent groupId 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|
|
||||
|prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false|
|
||||
|requiredPropertiesInConstructor|Allow only to create models with all the required properties provided in constructor| |true|
|
||||
|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|
|
||||
|serializableModel|boolean - toggle "implements Serializable" for generated models| |false|
|
||||
|snapshotVersion|Uses a SNAPSHOT version.|<dl><dt>**true**</dt><dd>Use a SnapShot Version</dd><dt>**false**</dt><dd>Use a Release Version</dd></dl>|null|
|
||||
|sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true|
|
||||
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
|
||||
|sourceFolder|source folder for generated code| |src/main/java|
|
||||
|test|Specify which test tool to generate files for|<dl><dt>**junit**</dt><dd>Use JUnit as test tool</dd><dt>**spock**</dt><dd>Use Spock as test tool</dd></dl>|junit|
|
||||
|title|Client service name| |null|
|
||||
|useAuth|Whether to import authorization and to annotate controller methods accordingly| |true|
|
||||
|useBeanValidation|Use BeanValidation API annotations| |true|
|
||||
|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|
|
||||
|
||||
## IMPORT MAPPING
|
||||
|
||||
| Type/Alias | Imports |
|
||||
| ---------- | ------- |
|
||||
|Array|java.util.List|
|
||||
|ArrayList|java.util.ArrayList|
|
||||
|BigDecimal|java.math.BigDecimal|
|
||||
|CompletedFileUpload|io.micronaut.http.multipart.CompletedFileUpload|
|
||||
|Date|java.util.Date|
|
||||
|DateTime|org.joda.time.*|
|
||||
|File|java.io.File|
|
||||
|HashMap|java.util.HashMap|
|
||||
|LinkedHashSet|java.util.LinkedHashSet|
|
||||
|List|java.util.*|
|
||||
|LocalDate|org.joda.time.*|
|
||||
|LocalDateTime|org.joda.time.*|
|
||||
|LocalTime|org.joda.time.*|
|
||||
|Map|java.util.Map|
|
||||
|Set|java.util.*|
|
||||
|Timestamp|java.sql.Timestamp|
|
||||
|URI|java.net.URI|
|
||||
|UUID|java.util.UUID|
|
||||
|
||||
|
||||
## INSTANTIATION TYPES
|
||||
|
||||
| Type/Alias | Instantiated By |
|
||||
| ---------- | --------------- |
|
||||
|array|ArrayList|
|
||||
|map|HashMap|
|
||||
|set|LinkedHashSet|
|
||||
|
||||
|
||||
## LANGUAGE PRIMITIVES
|
||||
|
||||
<ul class="column-ul">
|
||||
<li>Boolean</li>
|
||||
<li>Double</li>
|
||||
<li>Float</li>
|
||||
<li>Integer</li>
|
||||
<li>Long</li>
|
||||
<li>Object</li>
|
||||
<li>String</li>
|
||||
<li>boolean</li>
|
||||
<li>byte[]</li>
|
||||
</ul>
|
||||
|
||||
## RESERVED WORDS
|
||||
|
||||
<ul class="column-ul">
|
||||
<li>abstract</li>
|
||||
<li>apiclient</li>
|
||||
<li>apiexception</li>
|
||||
<li>apiresponse</li>
|
||||
<li>application</li>
|
||||
<li>assert</li>
|
||||
<li>authorization</li>
|
||||
<li>body</li>
|
||||
<li>boolean</li>
|
||||
<li>break</li>
|
||||
<li>byte</li>
|
||||
<li>case</li>
|
||||
<li>catch</li>
|
||||
<li>char</li>
|
||||
<li>class</li>
|
||||
<li>client</li>
|
||||
<li>configuration</li>
|
||||
<li>const</li>
|
||||
<li>continue</li>
|
||||
<li>cookie</li>
|
||||
<li>default</li>
|
||||
<li>do</li>
|
||||
<li>double</li>
|
||||
<li>else</li>
|
||||
<li>enum</li>
|
||||
<li>extends</li>
|
||||
<li>file</li>
|
||||
<li>final</li>
|
||||
<li>finally</li>
|
||||
<li>float</li>
|
||||
<li>for</li>
|
||||
<li>format</li>
|
||||
<li>goto</li>
|
||||
<li>header</li>
|
||||
<li>if</li>
|
||||
<li>implements</li>
|
||||
<li>import</li>
|
||||
<li>instanceof</li>
|
||||
<li>int</li>
|
||||
<li>interface</li>
|
||||
<li>list</li>
|
||||
<li>localreturntype</li>
|
||||
<li>localvaraccept</li>
|
||||
<li>localvaraccepts</li>
|
||||
<li>localvarauthnames</li>
|
||||
<li>localvarcollectionqueryparams</li>
|
||||
<li>localvarcontenttype</li>
|
||||
<li>localvarcontenttypes</li>
|
||||
<li>localvarcookieparams</li>
|
||||
<li>localvarformparams</li>
|
||||
<li>localvarheaderparams</li>
|
||||
<li>localvarpath</li>
|
||||
<li>localvarpostbody</li>
|
||||
<li>localvarqueryparams</li>
|
||||
<li>long</li>
|
||||
<li>native</li>
|
||||
<li>new</li>
|
||||
<li>null</li>
|
||||
<li>object</li>
|
||||
<li>package</li>
|
||||
<li>pathvariable</li>
|
||||
<li>private</li>
|
||||
<li>protected</li>
|
||||
<li>public</li>
|
||||
<li>queryparam</li>
|
||||
<li>queryvalue</li>
|
||||
<li>return</li>
|
||||
<li>short</li>
|
||||
<li>static</li>
|
||||
<li>strictfp</li>
|
||||
<li>stringutil</li>
|
||||
<li>super</li>
|
||||
<li>switch</li>
|
||||
<li>synchronized</li>
|
||||
<li>this</li>
|
||||
<li>throw</li>
|
||||
<li>throws</li>
|
||||
<li>transient</li>
|
||||
<li>try</li>
|
||||
<li>void</li>
|
||||
<li>volatile</li>
|
||||
<li>while</li>
|
||||
</ul>
|
||||
|
||||
## FEATURE SET
|
||||
|
||||
|
||||
### Client Modification Feature
|
||||
| Name | Supported | Defined By |
|
||||
| ---- | --------- | ---------- |
|
||||
|BasePath|✓|ToolingExtension
|
||||
|Authorizations|✗|ToolingExtension
|
||||
|UserAgent|✗|ToolingExtension
|
||||
|MockServer|✗|ToolingExtension
|
||||
|
||||
### Data Type Feature
|
||||
| Name | Supported | Defined By |
|
||||
| ---- | --------- | ---------- |
|
||||
|Custom|✗|OAS2,OAS3
|
||||
|Int32|✓|OAS2,OAS3
|
||||
|Int64|✓|OAS2,OAS3
|
||||
|Float|✓|OAS2,OAS3
|
||||
|Double|✓|OAS2,OAS3
|
||||
|Decimal|✓|ToolingExtension
|
||||
|String|✓|OAS2,OAS3
|
||||
|Byte|✓|OAS2,OAS3
|
||||
|Binary|✓|OAS2,OAS3
|
||||
|Boolean|✓|OAS2,OAS3
|
||||
|Date|✓|OAS2,OAS3
|
||||
|DateTime|✓|OAS2,OAS3
|
||||
|Password|✓|OAS2,OAS3
|
||||
|File|✓|OAS2
|
||||
|Array|✓|OAS2,OAS3
|
||||
|Maps|✓|ToolingExtension
|
||||
|CollectionFormat|✓|OAS2
|
||||
|CollectionFormatMulti|✓|OAS2
|
||||
|Enum|✓|OAS2,OAS3
|
||||
|ArrayOfEnum|✓|ToolingExtension
|
||||
|ArrayOfModel|✓|ToolingExtension
|
||||
|ArrayOfCollectionOfPrimitives|✓|ToolingExtension
|
||||
|ArrayOfCollectionOfModel|✓|ToolingExtension
|
||||
|ArrayOfCollectionOfEnum|✓|ToolingExtension
|
||||
|MapOfEnum|✓|ToolingExtension
|
||||
|MapOfModel|✓|ToolingExtension
|
||||
|MapOfCollectionOfPrimitives|✓|ToolingExtension
|
||||
|MapOfCollectionOfModel|✓|ToolingExtension
|
||||
|MapOfCollectionOfEnum|✓|ToolingExtension
|
||||
|
||||
### Documentation Feature
|
||||
| Name | Supported | Defined By |
|
||||
| ---- | --------- | ---------- |
|
||||
|Readme|✓|ToolingExtension
|
||||
|Model|✓|ToolingExtension
|
||||
|Api|✓|ToolingExtension
|
||||
|
||||
### Global Feature
|
||||
| Name | Supported | Defined By |
|
||||
| ---- | --------- | ---------- |
|
||||
|Host|✓|OAS2,OAS3
|
||||
|BasePath|✓|OAS2,OAS3
|
||||
|Info|✓|OAS2,OAS3
|
||||
|Schemes|✗|OAS2,OAS3
|
||||
|PartialSchemes|✓|OAS2,OAS3
|
||||
|Consumes|✓|OAS2
|
||||
|Produces|✓|OAS2
|
||||
|ExternalDocumentation|✓|OAS2,OAS3
|
||||
|Examples|✓|OAS2,OAS3
|
||||
|XMLStructureDefinitions|✗|OAS2,OAS3
|
||||
|MultiServer|✗|OAS3
|
||||
|ParameterizedServer|✗|OAS3
|
||||
|ParameterStyling|✗|OAS3
|
||||
|Callbacks|✗|OAS3
|
||||
|LinkObjects|✗|OAS3
|
||||
|
||||
### Parameter Feature
|
||||
| Name | Supported | Defined By |
|
||||
| ---- | --------- | ---------- |
|
||||
|Path|✓|OAS2,OAS3
|
||||
|Query|✓|OAS2,OAS3
|
||||
|Header|✓|OAS2,OAS3
|
||||
|Body|✓|OAS2
|
||||
|FormUnencoded|✓|OAS2
|
||||
|FormMultipart|✓|OAS2
|
||||
|Cookie|✓|OAS3
|
||||
|
||||
### Schema Support Feature
|
||||
| Name | Supported | Defined By |
|
||||
| ---- | --------- | ---------- |
|
||||
|Simple|✓|OAS2,OAS3
|
||||
|Composite|✓|OAS2,OAS3
|
||||
|Polymorphism|✗|OAS2,OAS3
|
||||
|Union|✗|OAS3
|
||||
|
||||
### Security Feature
|
||||
| Name | Supported | Defined By |
|
||||
| ---- | --------- | ---------- |
|
||||
|BasicAuth|✓|OAS2,OAS3
|
||||
|ApiKey|✓|OAS2,OAS3
|
||||
|OpenIDConnect|✓|OAS3
|
||||
|BearerToken|✗|OAS3
|
||||
|OAuth2_Implicit|✓|OAS2,OAS3
|
||||
|OAuth2_Password|✓|OAS2,OAS3
|
||||
|OAuth2_ClientCredentials|✓|OAS2,OAS3
|
||||
|OAuth2_AuthorizationCode|✓|OAS2,OAS3
|
||||
|
||||
### Wire Format Feature
|
||||
| Name | Supported | Defined By |
|
||||
| ---- | --------- | ---------- |
|
||||
|JSON|✓|OAS2,OAS3
|
||||
|XML|✓|OAS2,OAS3
|
||||
|PROTOBUF|✗|ToolingExtension
|
||||
|Custom|✗|OAS2,OAS3
|
||||
@@ -0,0 +1,511 @@
|
||||
package org.openapitools.codegen.languages;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openapitools.codegen.*;
|
||||
import org.openapitools.codegen.languages.features.BeanValidationFeatures;
|
||||
import org.openapitools.codegen.meta.features.DocumentationFeature;
|
||||
import org.openapitools.codegen.meta.features.SecurityFeature;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.openapitools.codegen.CodegenConstants.INVOKER_PACKAGE;
|
||||
|
||||
public abstract class JavaMicronautAbstractCodegen extends AbstractJavaCodegen implements BeanValidationFeatures {
|
||||
public static final String OPT_TITLE = "title";
|
||||
public static final String OPT_BUILD = "build";
|
||||
public static final String OPT_BUILD_GRADLE = "gradle";
|
||||
public static final String OPT_BUILD_MAVEN = "maven";
|
||||
public static final String OPT_BUILD_ALL = "all";
|
||||
public static final String OPT_TEST = "test";
|
||||
public static final String OPT_TEST_JUNIT = "junit";
|
||||
public static final String OPT_TEST_SPOCK = "spock";
|
||||
public static final String OPT_REQUIRED_PROPERTIES_IN_CONSTRUCTOR = "requiredPropertiesInConstructor";
|
||||
public static final String OPT_MICRONAUT_VERSION = "micronautVersion";
|
||||
public static final String OPT_USE_AUTH = "useAuth";
|
||||
|
||||
protected String title;
|
||||
protected boolean useBeanValidation;
|
||||
protected String buildTool;
|
||||
protected String testTool;
|
||||
protected boolean requiredPropertiesInConstructor = true;
|
||||
protected String micronautVersion = "3.2.6";
|
||||
|
||||
public static final String CONTENT_TYPE_APPLICATION_FORM_URLENCODED = "application/x-www-form-urlencoded";
|
||||
public static final String CONTENT_TYPE_APPLICATION_JSON = "application/json";
|
||||
public static final String CONTENT_TYPE_MULTIPART_FORM_DATA = "multipart/form-data";
|
||||
public static final String CONTENT_TYPE_ANY = "*/*";
|
||||
|
||||
public JavaMicronautAbstractCodegen() {
|
||||
super();
|
||||
|
||||
// Set all the fields
|
||||
useBeanValidation = true;
|
||||
buildTool = OPT_BUILD_ALL;
|
||||
testTool = OPT_TEST_JUNIT;
|
||||
outputFolder = "generated-code/java-micronaut-client";
|
||||
templateDir = "java-micronaut/client";
|
||||
apiPackage = "org.openapitools.api";
|
||||
modelPackage = "org.openapitools.model";
|
||||
invokerPackage = "org.openapitools";
|
||||
artifactId = "openapi-micronaut";
|
||||
embeddedTemplateDir = templateDir = "java-micronaut";
|
||||
apiDocPath = "docs/apis";
|
||||
modelDocPath = "docs/models";
|
||||
|
||||
// Set implemented features for user information
|
||||
modifyFeatureSet(features -> features
|
||||
.includeDocumentationFeatures(
|
||||
DocumentationFeature.Readme
|
||||
)
|
||||
.securityFeatures(EnumSet.of(
|
||||
SecurityFeature.ApiKey,
|
||||
SecurityFeature.BasicAuth,
|
||||
SecurityFeature.OAuth2_Implicit,
|
||||
SecurityFeature.OAuth2_AuthorizationCode,
|
||||
SecurityFeature.OAuth2_ClientCredentials,
|
||||
SecurityFeature.OAuth2_Password,
|
||||
SecurityFeature.OpenIDConnect
|
||||
))
|
||||
);
|
||||
|
||||
// Set additional properties
|
||||
additionalProperties.put("jackson", "true");
|
||||
additionalProperties.put("openbrace", "{");
|
||||
additionalProperties.put("closebrace", "}");
|
||||
|
||||
// Set client options that will be presented to user
|
||||
updateOption(INVOKER_PACKAGE, this.getInvokerPackage());
|
||||
updateOption(CodegenConstants.ARTIFACT_ID, this.getArtifactId());
|
||||
updateOption(CodegenConstants.API_PACKAGE, apiPackage);
|
||||
updateOption(CodegenConstants.MODEL_PACKAGE, modelPackage);
|
||||
|
||||
cliOptions.add(new CliOption(OPT_TITLE, "Client service name").defaultValue(title));
|
||||
cliOptions.add(new CliOption(OPT_MICRONAUT_VERSION, "Micronaut version, only >=3.0.0 versions are supported").defaultValue(micronautVersion));
|
||||
cliOptions.add(CliOption.newBoolean(USE_BEANVALIDATION, "Use BeanValidation API annotations", useBeanValidation));
|
||||
cliOptions.add(CliOption.newBoolean(OPT_REQUIRED_PROPERTIES_IN_CONSTRUCTOR, "Allow only to create models with all the required properties provided in constructor", requiredPropertiesInConstructor));
|
||||
|
||||
CliOption buildToolOption = new CliOption(OPT_BUILD, "Specify for which build tool to generate files").defaultValue(buildTool);
|
||||
buildToolOption.setEnum(new HashMap<String, String>() {{
|
||||
put(OPT_BUILD_GRADLE, "Gradle configuration is generated for the project");
|
||||
put(OPT_BUILD_MAVEN, "Maven configuration is generated for the project");
|
||||
put(OPT_BUILD_ALL, "Both Gradle and Maven configurations are generated");
|
||||
}});
|
||||
cliOptions.add(buildToolOption);
|
||||
|
||||
CliOption testToolOption = new CliOption(OPT_TEST, "Specify which test tool to generate files for").defaultValue(testTool);
|
||||
testToolOption.setEnum(new HashMap<String, String>() {{
|
||||
put(OPT_TEST_JUNIT, "Use JUnit as test tool");
|
||||
put(OPT_TEST_SPOCK, "Use Spock as test tool");
|
||||
}});
|
||||
cliOptions.add(testToolOption);
|
||||
|
||||
// Remove the date library option
|
||||
cliOptions.stream().filter(o -> o.getOpt().equals("dateLibrary")).findFirst()
|
||||
.ifPresent(v -> cliOptions.remove(v));
|
||||
|
||||
// Add reserved words
|
||||
String[] reservedWordsArray = {
|
||||
"client", "format", "queryvalue", "queryparam", "pathvariable", "header", "cookie",
|
||||
"authorization", "body", "application"
|
||||
};
|
||||
reservedWords.addAll(Arrays.asList(reservedWordsArray));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processOpts() {
|
||||
super.processOpts();
|
||||
|
||||
// Get properties
|
||||
if (additionalProperties.containsKey(OPT_TITLE)) {
|
||||
this.title = (String) additionalProperties.get(OPT_TITLE);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(INVOKER_PACKAGE)) {
|
||||
invokerPackage = (String) additionalProperties.get(INVOKER_PACKAGE);
|
||||
} else {
|
||||
additionalProperties.put(INVOKER_PACKAGE, invokerPackage);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(OPT_MICRONAUT_VERSION)) {
|
||||
micronautVersion = (String) additionalProperties.get(OPT_MICRONAUT_VERSION);
|
||||
} else {
|
||||
additionalProperties.put(OPT_MICRONAUT_VERSION, micronautVersion);
|
||||
}
|
||||
|
||||
// Get boolean properties
|
||||
if (additionalProperties.containsKey(USE_BEANVALIDATION)) {
|
||||
this.setUseBeanValidation(convertPropertyToBoolean(USE_BEANVALIDATION));
|
||||
}
|
||||
writePropertyBack(USE_BEANVALIDATION, useBeanValidation);
|
||||
|
||||
if (additionalProperties.containsKey(OPT_REQUIRED_PROPERTIES_IN_CONSTRUCTOR)) {
|
||||
this.requiredPropertiesInConstructor = convertPropertyToBoolean(OPT_REQUIRED_PROPERTIES_IN_CONSTRUCTOR);
|
||||
}
|
||||
writePropertyBack(OPT_REQUIRED_PROPERTIES_IN_CONSTRUCTOR, requiredPropertiesInConstructor);
|
||||
|
||||
// Get enum properties
|
||||
if (additionalProperties.containsKey(OPT_BUILD)) {
|
||||
switch ((String) additionalProperties.get(OPT_BUILD)) {
|
||||
case OPT_BUILD_GRADLE:
|
||||
case OPT_BUILD_MAVEN:
|
||||
case OPT_BUILD_ALL:
|
||||
this.buildTool = (String) additionalProperties.get(OPT_BUILD);
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Build tool \"" + additionalProperties.get(OPT_BUILD) + "\" is not supported or misspelled.");
|
||||
}
|
||||
}
|
||||
additionalProperties.put(OPT_BUILD, buildTool);
|
||||
|
||||
if (additionalProperties.containsKey(OPT_TEST)) {
|
||||
switch ((String) additionalProperties.get(OPT_TEST)) {
|
||||
case OPT_TEST_JUNIT:
|
||||
case OPT_TEST_SPOCK:
|
||||
this.testTool = (String) additionalProperties.get(OPT_TEST);
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Test tool \"" + additionalProperties.get(OPT_TEST) + "\" is not supported or misspelled.");
|
||||
}
|
||||
}
|
||||
additionalProperties.put(OPT_TEST, testTool);
|
||||
if (testTool.equals(OPT_TEST_JUNIT)) {
|
||||
additionalProperties.put("isTestJunit", true);
|
||||
} else if (testTool.equals(OPT_TEST_SPOCK)) {
|
||||
additionalProperties.put("isTestSpock", true);
|
||||
}
|
||||
|
||||
// Add all the supporting files
|
||||
String resourceFolder = projectFolder + "/resources";
|
||||
supportingFiles.add(new SupportingFile("common/configuration/application.yml.mustache", resourceFolder, "application.yml").doNotOverwrite());
|
||||
supportingFiles.add(new SupportingFile("common/configuration/logback.xml.mustache", resourceFolder, "logback.xml").doNotOverwrite());
|
||||
|
||||
if (buildTool.equals(OPT_BUILD_GRADLE) || buildTool.equals(OPT_BUILD_ALL)) {
|
||||
// Gradle files
|
||||
supportingFiles.add(new SupportingFile("common/configuration/gradle/build.gradle.mustache", "", "build.gradle").doNotOverwrite());
|
||||
supportingFiles.add(new SupportingFile("common/configuration/gradle/settings.gradle.mustache", "", "settings.gradle").doNotOverwrite());
|
||||
supportingFiles.add(new SupportingFile("common/configuration/gradle/gradle.properties.mustache", "", "gradle.properties").doNotOverwrite());
|
||||
|
||||
// Gradlew files
|
||||
final String gradleWrapperFolder = "gradle/wrapper";
|
||||
supportingFiles.add(new SupportingFile("common/configuration/gradlew/gradlew.mustache", "", "gradlew"));
|
||||
supportingFiles.add(new SupportingFile("common/configuration/gradlew/gradlew.bat.mustache", "", "gradlew.bat"));
|
||||
supportingFiles.add(new SupportingFile("common/configuration/gradlew/gradle-wrapper.properties.mustache", gradleWrapperFolder, "gradle-wrapper.properties"));
|
||||
supportingFiles.add(new SupportingFile("common/configuration/gradlew/gradle-wrapper.jar", gradleWrapperFolder, "gradle-wrapper.jar"));
|
||||
}
|
||||
|
||||
if (buildTool.equals(OPT_BUILD_MAVEN) || buildTool.equals(OPT_BUILD_ALL)) {
|
||||
// Maven files
|
||||
supportingFiles.add(new SupportingFile("common/configuration/pom.xml.mustache", "", "pom.xml").doNotOverwrite());
|
||||
|
||||
// Maven wrapper files
|
||||
supportingFiles.add(new SupportingFile("common/configuration/mavenw/mvnw.mustache", "", "mvnw"));
|
||||
supportingFiles.add(new SupportingFile("common/configuration/mavenw/mvnw.bat.mustache", "", "mvnw.bat"));
|
||||
supportingFiles.add(new SupportingFile("common/configuration/mavenw/MavenWrapperDownloader.java.mustache", ".mvn/wrapper", "MavenWrapperDownloader.java"));
|
||||
supportingFiles.add(new SupportingFile("common/configuration/mavenw/maven-wrapper.jar.mustache", ".mvn/wrapper", "maven-wrapper.jar"));
|
||||
supportingFiles.add(new SupportingFile("common/configuration/mavenw/maven-wrapper.properties.mustache", ".mvn/wrapper", "maren-wrapper.properties"));
|
||||
}
|
||||
|
||||
// Git files
|
||||
supportingFiles.add(new SupportingFile("common/configuration/git/gitignore.mustache", "", ".gitignore").doNotOverwrite());
|
||||
|
||||
// Use the default java LocalDate
|
||||
typeMapping.put("date", "LocalDate");
|
||||
typeMapping.put("DateTime", "LocalDateTime");
|
||||
importMapping.put("LocalDate", "java.time.LocalDate");
|
||||
importMapping.put("LocalDateTime", "java.time.LocalDateTime");
|
||||
|
||||
// Add documentation files
|
||||
modelDocTemplateFiles.clear();
|
||||
modelDocTemplateFiles.put("common/doc/model_doc.mustache", ".md");
|
||||
|
||||
// Add model files
|
||||
modelTemplateFiles.clear();
|
||||
modelTemplateFiles.put("common/model/model.mustache", ".java");
|
||||
|
||||
// Add test files
|
||||
modelTestTemplateFiles.clear();
|
||||
if (testTool.equals(OPT_TEST_JUNIT)) {
|
||||
modelTestTemplateFiles.put("common/test/model_test.mustache", ".java");
|
||||
} else if (testTool.equals(OPT_TEST_SPOCK)) {
|
||||
modelTestTemplateFiles.put("common/test/model_test.groovy.mustache", ".groovy");
|
||||
}
|
||||
|
||||
// Set properties for documentation
|
||||
final String invokerFolder = (sourceFolder + '/' + invokerPackage).replace(".", "/");
|
||||
final String apiFolder = (sourceFolder + '/' + apiPackage()).replace('.', '/');
|
||||
final String modelFolder = (sourceFolder + '/' + modelPackage()).replace('.', '/');
|
||||
additionalProperties.put("invokerFolder", invokerFolder);
|
||||
additionalProperties.put("resourceFolder", resourceFolder);
|
||||
additionalProperties.put("apiFolder", apiFolder);
|
||||
additionalProperties.put("modelFolder", modelFolder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apiTestFileFolder() {
|
||||
if (testTool.equals(OPT_TEST_SPOCK)) {
|
||||
return getOutputDir() + "/src/test/groovy/" + apiPackage().replaceAll("\\.", "/");
|
||||
}
|
||||
return getOutputDir() + "/src/test/java/" + apiPackage().replaceAll("\\.", "/");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String modelTestFileFolder() {
|
||||
if (testTool.equals(OPT_TEST_SPOCK)) {
|
||||
return getOutputDir() + "/src/test/groovy/" + modelPackage().replaceAll("\\.", "/");
|
||||
}
|
||||
return getOutputDir() + "/src/test/java/" + modelPackage().replaceAll("\\.", "/");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toApiTestFilename(String name) {
|
||||
if (testTool.equals(OPT_TEST_SPOCK)) {
|
||||
return toApiName(name) + "Spec";
|
||||
}
|
||||
return toApiName(name) + "Test";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toModelTestFilename(String name) {
|
||||
if (testTool.equals(OPT_TEST_SPOCK)) {
|
||||
return toModelName(name) + "Spec";
|
||||
}
|
||||
return toModelName(name) + "Test";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUseBeanValidation(boolean useBeanValidation) {
|
||||
this.useBeanValidation = useBeanValidation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toApiVarName(String name) {
|
||||
String apiVarName = super.toApiVarName(name);
|
||||
if (reservedWords.contains(apiVarName)) {
|
||||
apiVarName = escapeReservedWord(apiVarName);
|
||||
}
|
||||
return apiVarName;
|
||||
}
|
||||
|
||||
public boolean isUseBeanValidation() {
|
||||
return useBeanValidation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) {
|
||||
objs = super.postProcessOperationsWithModels(objs, allModels);
|
||||
|
||||
Map<String, CodegenModel> models = allModels.stream()
|
||||
.map(v -> ((Map<String, CodegenModel>) v).get("model"))
|
||||
.collect(Collectors.toMap(v -> v.classname, v -> v));
|
||||
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
|
||||
List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation");
|
||||
|
||||
for (CodegenOperation op : operationList) {
|
||||
// Set whether body is supported in request
|
||||
op.vendorExtensions.put("methodAllowsBody",
|
||||
op.httpMethod.equals("PUT") || op.httpMethod.equals("POST") || op.httpMethod.equals("PATCH"));
|
||||
|
||||
// Set response example
|
||||
if (op.returnType != null) {
|
||||
String example;
|
||||
String groovyExample;
|
||||
if (models.containsKey(op.returnType)) {
|
||||
CodegenModel m = models.get(op.returnType);
|
||||
List<Object> allowableValues = null;
|
||||
if (m.allowableValues != null && m.allowableValues.containsKey("values")) {
|
||||
allowableValues = (List<Object>) m.allowableValues.get("values");
|
||||
}
|
||||
example = getExampleValue(m.defaultValue, null, m.classname, true,
|
||||
allowableValues, null, null, m.requiredVars, false);
|
||||
groovyExample = getExampleValue(m.defaultValue, null, m.classname, true,
|
||||
allowableValues, null, null, m.requiredVars, true);
|
||||
} else {
|
||||
example = getExampleValue(null, null, op.returnType, false, null,
|
||||
op.returnBaseType, null, null, false);
|
||||
groovyExample = getExampleValue(null, null, op.returnType, false, null,
|
||||
op.returnBaseType, null, null, true);
|
||||
}
|
||||
op.vendorExtensions.put("example", example);
|
||||
op.vendorExtensions.put("groovyExample", groovyExample);
|
||||
}
|
||||
|
||||
// Remove the "*/*" contentType from operations as it is ambiguous
|
||||
if (CONTENT_TYPE_ANY.equals(op.vendorExtensions.get("x-contentType"))) {
|
||||
op.vendorExtensions.put("x-contentType", CONTENT_TYPE_APPLICATION_JSON);
|
||||
}
|
||||
op.consumes = op.consumes == null ? null : op.consumes.stream()
|
||||
.filter(contentType -> !CONTENT_TYPE_ANY.equals(contentType.get("mediaType")))
|
||||
.collect(Collectors.toList());
|
||||
op.produces = op.produces == null ? null : op.produces.stream()
|
||||
.filter(contentType -> !CONTENT_TYPE_ANY.equals(contentType.get("mediaType")))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// Force form parameters are only set if the content-type is according
|
||||
// formParams correspond to urlencoded type
|
||||
// bodyParams correspond to multipart body
|
||||
if (CONTENT_TYPE_APPLICATION_FORM_URLENCODED.equals(op.vendorExtensions.get("x-contentType"))) {
|
||||
op.formParams.addAll(op.bodyParams);
|
||||
op.bodyParams.forEach(p -> {
|
||||
p.isBodyParam = false;
|
||||
p.isFormParam = true;
|
||||
});
|
||||
op.bodyParams.clear();
|
||||
} else if (CONTENT_TYPE_MULTIPART_FORM_DATA.equals(op.vendorExtensions.get("x-contentType"))) {
|
||||
op.bodyParams.addAll(op.formParams);
|
||||
op.formParams.forEach(p -> {
|
||||
p.isBodyParam = true;
|
||||
p.isFormParam = false;
|
||||
});
|
||||
op.formParams.clear();
|
||||
}
|
||||
}
|
||||
|
||||
return objs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> postProcessAllModels(Map<String, Object> objs) {
|
||||
objs = super.postProcessAllModels(objs);
|
||||
|
||||
for (String modelName: objs.keySet()) {
|
||||
CodegenModel model = ((Map<String, List<Map<String, CodegenModel>>>) objs.get(modelName))
|
||||
.get("models").get(0).get("model");
|
||||
if (model.getParentModel() != null) {
|
||||
model.vendorExtensions.put("requiredParentVars", model.getParentModel().requiredVars);
|
||||
}
|
||||
|
||||
List<CodegenProperty> requiredVars = model.vars.stream().filter(v -> v.required).collect(Collectors.toList());
|
||||
model.vendorExtensions.put("requiredVars", requiredVars);
|
||||
}
|
||||
|
||||
return objs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParameterExampleValue(CodegenParameter p) {
|
||||
p.vendorExtensions.put("groovyExample", getParameterExampleValue(p, true));
|
||||
p.example = getParameterExampleValue(p, false);
|
||||
}
|
||||
|
||||
protected String getParameterExampleValue(CodegenParameter p, boolean groovy) {
|
||||
List<Object> allowableValues = p.allowableValues == null ? null : (List<Object>) p.allowableValues.get("values");
|
||||
|
||||
return getExampleValue(p.defaultValue, p.example, p.dataType, p.isModel, allowableValues,
|
||||
p.items == null ? null : p.items.dataType,
|
||||
p.items == null ? null : p.items.defaultValue,
|
||||
p.requiredVars, groovy);
|
||||
}
|
||||
|
||||
protected String getPropertyExampleValue(CodegenProperty p, boolean groovy) {
|
||||
List<Object> allowableValues = p.allowableValues == null ? null : (List<Object>) p.allowableValues.get("values");
|
||||
|
||||
return getExampleValue(p.defaultValue, p.example, p.dataType, p.isModel, allowableValues,
|
||||
p.items == null ? null : p.items.dataType,
|
||||
p.items == null ? null : p.items.defaultValue,
|
||||
null, groovy);
|
||||
}
|
||||
|
||||
public String getExampleValue(
|
||||
String defaultValue, String example, String dataType, Boolean isModel, List<Object> allowableValues,
|
||||
String itemsType, String itemsExample, List<CodegenProperty> requiredVars, boolean groovy
|
||||
) {
|
||||
example = defaultValue != null ? defaultValue : example;
|
||||
String containerType = dataType == null ? null : dataType.split("<")[0];
|
||||
|
||||
if ("String".equals(dataType)) {
|
||||
if (groovy) {
|
||||
example = example != null ? "'" + escapeTextGroovy(example) + "'" : "'example'";
|
||||
} else {
|
||||
example = example != null ? "\"" + escapeText(example) + "\"" : "\"example\"";
|
||||
}
|
||||
} else if ("Integer".equals(dataType) || "Short".equals(dataType)) {
|
||||
example = example != null ? example : "56";
|
||||
} else if ("Long".equals(dataType)) {
|
||||
example = StringUtils.appendIfMissingIgnoreCase(example != null ? example : "56", "L");
|
||||
} else if ("Float".equals(dataType)) {
|
||||
example = StringUtils.appendIfMissingIgnoreCase(example != null ? example : "3.4", "F");
|
||||
} else if ("Double".equals(dataType)) {
|
||||
example = StringUtils.appendIfMissingIgnoreCase(example != null ? example : "3.4", "D");
|
||||
} else if ("Boolean".equals(dataType)) {
|
||||
example = example != null ? example : "false";
|
||||
} else if ("File".equals(dataType)) {
|
||||
example = null;
|
||||
} else if ("LocalDate".equals(dataType)) {
|
||||
example = "LocalDate.of(2001, 2, 3)";
|
||||
} else if ("LocalDateTime".equals(dataType)) {
|
||||
example = "LocalDateTime.of(2001, 2, 3, 4, 5)";
|
||||
} else if ("BigDecimal".equals(dataType)) {
|
||||
example = "new BigDecimal(78)";
|
||||
} else if (allowableValues != null && !allowableValues.isEmpty()) {
|
||||
// This is an enum
|
||||
Object value = example;
|
||||
if (value == null || !allowableValues.contains(value)) {
|
||||
value = allowableValues.get(0);
|
||||
}
|
||||
example = dataType + ".fromValue(\"" + value + "\")";
|
||||
} else if ((isModel != null && isModel) || (isModel == null && !languageSpecificPrimitives.contains(dataType))) {
|
||||
if (requiredVars == null) {
|
||||
example = null;
|
||||
} else {
|
||||
if (requiredPropertiesInConstructor) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("new ").append(dataType).append("(");
|
||||
for (int i = 0; i < requiredVars.size(); ++i) {
|
||||
if (i != 0) {
|
||||
builder.append(", ");
|
||||
}
|
||||
builder.append(getPropertyExampleValue(requiredVars.get(i), groovy));
|
||||
}
|
||||
builder.append(")");
|
||||
example = builder.toString();
|
||||
} else {
|
||||
example = "new " + dataType + "()";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ("List".equals(containerType)) {
|
||||
String innerExample;
|
||||
if ("String".equals(itemsType)) {
|
||||
itemsExample = itemsExample != null ? itemsExample : "example";
|
||||
if (groovy) {
|
||||
innerExample = "'" + escapeTextGroovy(itemsExample) + "'";
|
||||
} else {
|
||||
innerExample = "\"" + escapeText(itemsExample) + "\"";
|
||||
}
|
||||
} else {
|
||||
innerExample = itemsExample != null ? itemsExample : "";
|
||||
}
|
||||
|
||||
if (groovy) {
|
||||
example = "[" + innerExample + "]";
|
||||
} else {
|
||||
example = "Arrays.asList(" + innerExample + ")";
|
||||
}
|
||||
} else if ("Set".equals(containerType)) {
|
||||
if (groovy) {
|
||||
example = "[].asSet()";
|
||||
} else {
|
||||
example = "new HashSet<>()";
|
||||
}
|
||||
} else if ("Map".equals(containerType)) {
|
||||
if (groovy) {
|
||||
example = "[:]";
|
||||
} else {
|
||||
example = "new HashMap<>()";
|
||||
}
|
||||
} else if (example == null) {
|
||||
example = "null";
|
||||
}
|
||||
|
||||
return example;
|
||||
}
|
||||
|
||||
public String escapeTextGroovy(String text) {
|
||||
if (text == null) {
|
||||
return null;
|
||||
}
|
||||
return escapeText(text).replaceAll("'", "\\'");
|
||||
}
|
||||
}
|
||||
@@ -1,127 +1,36 @@
|
||||
package org.openapitools.codegen.languages;
|
||||
|
||||
import org.openapitools.codegen.CliOption;
|
||||
import org.openapitools.codegen.CodegenConstants;
|
||||
import org.openapitools.codegen.CodegenType;
|
||||
import org.openapitools.codegen.SupportingFile;
|
||||
import org.openapitools.codegen.languages.features.BeanValidationFeatures;
|
||||
import org.openapitools.codegen.meta.GeneratorMetadata;
|
||||
import org.openapitools.codegen.meta.Stability;
|
||||
import org.openapitools.codegen.meta.features.DocumentationFeature;
|
||||
import org.openapitools.codegen.meta.features.SecurityFeature;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.openapitools.codegen.CodegenConstants.INVOKER_PACKAGE;
|
||||
|
||||
|
||||
public class JavaMicronautClientCodegen extends AbstractJavaCodegen implements BeanValidationFeatures {
|
||||
public class JavaMicronautClientCodegen extends JavaMicronautAbstractCodegen {
|
||||
|
||||
private final Logger LOGGER = LoggerFactory.getLogger(JavaClientCodegen.class);
|
||||
|
||||
public static final String OPT_TITLE = "title";
|
||||
public static final String OPT_CONFIG_PACKAGE = "configPackage";
|
||||
public static final String OPT_CONFIGURE_AUTH = "configureAuth";
|
||||
public static final String OPT_BUILD = "build";
|
||||
public static final String OPT_BUILD_GRADLE = "gradle";
|
||||
public static final String OPT_BUILD_MAVEN = "maven";
|
||||
public static final String OPT_BUILD_ALL = "all";
|
||||
public static final String OPT_TEST = "test";
|
||||
public static final String OPT_TEST_JUNIT = "junit";
|
||||
public static final String OPT_TEST_SPOCK = "spock";
|
||||
|
||||
public static final String NAME = "java-micronaut-client";
|
||||
|
||||
protected String title;
|
||||
protected String configPackage;
|
||||
protected boolean useBeanValidation;
|
||||
protected boolean configureAuthorization;
|
||||
protected String buildTool;
|
||||
protected String testTool;
|
||||
|
||||
public JavaMicronautClientCodegen() {
|
||||
super();
|
||||
|
||||
title = "OpenAPI Micronaut Client";
|
||||
invokerPackage = "org.openapitools";
|
||||
configPackage = "org.openapitools.configuration";
|
||||
useBeanValidation = true;
|
||||
configureAuthorization = false;
|
||||
buildTool = OPT_BUILD_ALL;
|
||||
testTool = OPT_TEST_JUNIT;
|
||||
|
||||
modifyFeatureSet(features -> features
|
||||
.includeDocumentationFeatures(
|
||||
DocumentationFeature.Readme
|
||||
)
|
||||
.securityFeatures(EnumSet.of(
|
||||
SecurityFeature.ApiKey,
|
||||
SecurityFeature.BasicAuth,
|
||||
SecurityFeature.OAuth2_Implicit,
|
||||
SecurityFeature.OAuth2_AuthorizationCode,
|
||||
SecurityFeature.OAuth2_ClientCredentials,
|
||||
SecurityFeature.OAuth2_Password,
|
||||
SecurityFeature.OpenIDConnect
|
||||
))
|
||||
);
|
||||
|
||||
generatorMetadata = GeneratorMetadata.newBuilder(generatorMetadata)
|
||||
.stability(Stability.BETA)
|
||||
.build();
|
||||
additionalProperties.put("client", "true");
|
||||
|
||||
outputFolder = "generated-code/java-micronaut-client";
|
||||
embeddedTemplateDir = templateDir = "java-micronaut-client";
|
||||
apiPackage = "org.openapitools.api";
|
||||
modelPackage = "org.openapitools.model";
|
||||
invokerPackage = "org.openapitools";
|
||||
artifactId = "openapi-micronaut";
|
||||
|
||||
updateOption(INVOKER_PACKAGE, this.getInvokerPackage());
|
||||
updateOption(CodegenConstants.ARTIFACT_ID, this.getArtifactId());
|
||||
updateOption(CodegenConstants.API_PACKAGE, apiPackage);
|
||||
updateOption(CodegenConstants.MODEL_PACKAGE, modelPackage);
|
||||
|
||||
apiTestTemplateFiles.clear();
|
||||
|
||||
additionalProperties.put("jackson", "true");
|
||||
additionalProperties.put("openbrace", "{");
|
||||
additionalProperties.put("closebrace", "}");
|
||||
|
||||
cliOptions.add(new CliOption(OPT_TITLE, "Client service name").defaultValue(title));
|
||||
cliOptions.add(new CliOption(OPT_CONFIG_PACKAGE, "Configuration package for generated code").defaultValue(configPackage));
|
||||
cliOptions.add(CliOption.newBoolean(OPT_CONFIGURE_AUTH, "Configure all the authorization methods as specified in the file", configureAuthorization));
|
||||
cliOptions.add(CliOption.newBoolean(USE_BEANVALIDATION, "Use BeanValidation API annotations", useBeanValidation));
|
||||
|
||||
CliOption buildToolOption = new CliOption(OPT_BUILD, "Specify for which build tool to generate files").defaultValue(buildTool);
|
||||
Map buildToolOptionMap = new HashMap();
|
||||
buildToolOptionMap.put(OPT_BUILD_GRADLE, "Gradle configuration is generated for the project");
|
||||
buildToolOptionMap.put(OPT_BUILD_MAVEN, "Maven configuration is generated for the project");
|
||||
buildToolOptionMap.put(OPT_BUILD_ALL, "Both Gradle and Maven configurations are generated");
|
||||
buildToolOption.setEnum(buildToolOptionMap);
|
||||
cliOptions.add(buildToolOption);
|
||||
|
||||
CliOption testToolOption = new CliOption(OPT_TEST, "Specify which test tool to generate files for").defaultValue(testTool);
|
||||
Map testToolOptionMap = new HashMap();
|
||||
testToolOptionMap.put(OPT_TEST_JUNIT, "Use JUnit as test tool");
|
||||
testToolOptionMap.put(OPT_TEST_SPOCK, "Use Spock as test tool");
|
||||
testToolOption.setEnum(testToolOptionMap);
|
||||
cliOptions.add(testToolOption);
|
||||
|
||||
// Remove the date library option
|
||||
cliOptions.stream().filter(o -> o.getOpt().equals("dateLibrary")).findFirst()
|
||||
.ifPresent(v -> cliOptions.remove(v));
|
||||
|
||||
// Add reserved words
|
||||
String[] reservedWordsArray = {
|
||||
"client", "format", "queryvalue", "queryparam", "pathvariable", "header", "cookie",
|
||||
"authorization", "body", "application"
|
||||
};
|
||||
reservedWords.addAll(Arrays.asList(reservedWordsArray));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -139,202 +48,53 @@ public class JavaMicronautClientCodegen extends AbstractJavaCodegen implements B
|
||||
return "Generates a Java Micronaut Client.";
|
||||
}
|
||||
|
||||
public boolean isConfigureAuthorization() {
|
||||
return configureAuthorization;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processOpts() {
|
||||
super.processOpts();
|
||||
|
||||
// Get properties
|
||||
if (additionalProperties.containsKey(OPT_TITLE)) {
|
||||
this.title = (String) additionalProperties.get(OPT_TITLE);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(OPT_CONFIG_PACKAGE)) {
|
||||
configPackage = (String) additionalProperties.get(OPT_CONFIG_PACKAGE);
|
||||
} else {
|
||||
additionalProperties.put(OPT_CONFIG_PACKAGE, configPackage);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(INVOKER_PACKAGE)) {
|
||||
invokerPackage = (String) additionalProperties.get(INVOKER_PACKAGE);
|
||||
} else {
|
||||
additionalProperties.put(INVOKER_PACKAGE, invokerPackage);
|
||||
}
|
||||
|
||||
// Get boolean properties
|
||||
if (additionalProperties.containsKey(USE_BEANVALIDATION)) {
|
||||
this.setUseBeanValidation(convertPropertyToBoolean(USE_BEANVALIDATION));
|
||||
}
|
||||
writePropertyBack(USE_BEANVALIDATION, useBeanValidation);
|
||||
|
||||
if (additionalProperties.containsKey(OPT_CONFIGURE_AUTH)) {
|
||||
this.configureAuthorization = convertPropertyToBoolean(OPT_CONFIGURE_AUTH);
|
||||
}
|
||||
writePropertyBack(OPT_CONFIGURE_AUTH, configureAuthorization);
|
||||
|
||||
// Get enum properties
|
||||
if (additionalProperties.containsKey(OPT_BUILD)) {
|
||||
switch ((String) additionalProperties.get(OPT_BUILD)) {
|
||||
case OPT_BUILD_GRADLE:
|
||||
case OPT_BUILD_MAVEN:
|
||||
case OPT_BUILD_ALL:
|
||||
this.buildTool = (String) additionalProperties.get(OPT_BUILD);
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Build tool \"" + additionalProperties.get(OPT_BUILD) + "\" is not supported or misspelled.");
|
||||
}
|
||||
}
|
||||
additionalProperties.put(OPT_BUILD, buildTool);
|
||||
|
||||
if (additionalProperties.containsKey(OPT_TEST)) {
|
||||
switch ((String) additionalProperties.get(OPT_TEST)) {
|
||||
case OPT_TEST_JUNIT:
|
||||
case OPT_TEST_SPOCK:
|
||||
this.testTool = (String) additionalProperties.get(OPT_TEST);
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Test tool \"" + additionalProperties.get(OPT_TEST) + "\" is not supported or misspelled.");
|
||||
}
|
||||
}
|
||||
additionalProperties.put(OPT_TEST, testTool);
|
||||
if (testTool.equals(OPT_TEST_JUNIT)) {
|
||||
additionalProperties.put("isTestJunit", true);
|
||||
} else if (testTool.equals(OPT_TEST_SPOCK)) {
|
||||
additionalProperties.put("isTestSpock", true);
|
||||
}
|
||||
// Write property that is present in server
|
||||
writePropertyBack(OPT_USE_AUTH, true);
|
||||
|
||||
final String invokerFolder = (sourceFolder + '/' + invokerPackage).replace(".", "/");
|
||||
final String apiFolder = (sourceFolder + '/' + apiPackage).replace(".", "/");
|
||||
|
||||
// Add all the supporting files
|
||||
String resourceFolder = projectFolder + "/resources";
|
||||
supportingFiles.add(new SupportingFile("configuration/application.yml.mustache", resourceFolder, "application.yml").doNotOverwrite());
|
||||
|
||||
// Authorization files
|
||||
if (configureAuthorization) {
|
||||
final String authFolder = invokerFolder + "/auth";
|
||||
supportingFiles.add(new SupportingFile("auth/Authorization.mustache", authFolder, "Authorization.java"));
|
||||
supportingFiles.add(new SupportingFile("auth/AuthorizationBinder.mustache", authFolder, "AuthorizationBinder.java"));
|
||||
supportingFiles.add(new SupportingFile("auth/Authorizations.mustache", authFolder, "Authorizations.java"));
|
||||
supportingFiles.add(new SupportingFile("auth/AuthorizationFilter.mustache", authFolder, "AuthorizationFilter.java"));
|
||||
supportingFiles.add(new SupportingFile("client/auth/Authorization.mustache", authFolder, "Authorization.java"));
|
||||
supportingFiles.add(new SupportingFile("client/auth/AuthorizationBinder.mustache", authFolder, "AuthorizationBinder.java"));
|
||||
supportingFiles.add(new SupportingFile("client/auth/Authorizations.mustache", authFolder, "Authorizations.java"));
|
||||
supportingFiles.add(new SupportingFile("client/auth/AuthorizationFilter.mustache", authFolder, "AuthorizationFilter.java"));
|
||||
final String authConfigurationFolder = authFolder + "/configuration";
|
||||
supportingFiles.add(new SupportingFile("auth/configuration/ApiKeyAuthConfiguration.mustache", authConfigurationFolder, "ApiKeyAuthConfiguration.java"));
|
||||
supportingFiles.add(new SupportingFile("auth/configuration/ConfigurableAuthorization.mustache", authConfigurationFolder, "ConfigurableAuthorization.java"));
|
||||
supportingFiles.add(new SupportingFile("auth/configuration/HttpBasicAuthConfiguration.mustache", authConfigurationFolder, "HttpBasicAuthConfiguration.java"));
|
||||
supportingFiles.add(new SupportingFile("client/auth/configuration/ApiKeyAuthConfiguration.mustache", authConfigurationFolder, "ApiKeyAuthConfiguration.java"));
|
||||
supportingFiles.add(new SupportingFile("client/auth/configuration/ConfigurableAuthorization.mustache", authConfigurationFolder, "ConfigurableAuthorization.java"));
|
||||
supportingFiles.add(new SupportingFile("client/auth/configuration/HttpBasicAuthConfiguration.mustache", authConfigurationFolder, "HttpBasicAuthConfiguration.java"));
|
||||
}
|
||||
|
||||
// Query files
|
||||
final String queryFolder = invokerFolder + "/query";
|
||||
supportingFiles.add(new SupportingFile("query/QueryParam.mustache", queryFolder, "QueryParam.java"));
|
||||
supportingFiles.add(new SupportingFile("query/QueryParamBinder.mustache", queryFolder, "QueryParamBinder.java"));
|
||||
|
||||
if (buildTool.equals(OPT_BUILD_GRADLE) || buildTool.equals(OPT_BUILD_ALL)) {
|
||||
// Gradle files
|
||||
supportingFiles.add(new SupportingFile("configuration/gradle/build.gradle.mustache", "", "build.gradle").doNotOverwrite());
|
||||
supportingFiles.add(new SupportingFile("configuration/gradle/settings.gradle.mustache", "", "settings.gradle").doNotOverwrite());
|
||||
supportingFiles.add(new SupportingFile("configuration/gradle/gradle.properties.mustache", "", "gradle.properties").doNotOverwrite());
|
||||
|
||||
// Gradlew files
|
||||
final String gradleWrapperFolder = "gradle/wrapper";
|
||||
supportingFiles.add(new SupportingFile("configuration/gradlew/gradlew.mustache", "", "gradlew"));
|
||||
supportingFiles.add(new SupportingFile("configuration/gradlew/gradlew.bat.mustache", "", "gradlew.bat"));
|
||||
supportingFiles.add(new SupportingFile("configuration/gradlew/gradle-wrapper.properties.mustache", gradleWrapperFolder, "gradle-wrapper.properties"));
|
||||
supportingFiles.add(new SupportingFile("configuration/gradlew/gradle-wrapper.jar", gradleWrapperFolder, "gradle-wrapper.jar"));
|
||||
}
|
||||
|
||||
if (buildTool.equals(OPT_BUILD_MAVEN) || buildTool.equals(OPT_BUILD_ALL)) {
|
||||
// Maven files
|
||||
supportingFiles.add(new SupportingFile("configuration/pom.xml.mustache", "", "pom.xml").doNotOverwrite());
|
||||
|
||||
// Maven wrapper files
|
||||
supportingFiles.add(new SupportingFile("configuration/mavenw/mvnw.mustache", "", "mvnw"));
|
||||
supportingFiles.add(new SupportingFile("configuration/mavenw/mvnw.bat.mustache", "", "mvnw.bat"));
|
||||
supportingFiles.add(new SupportingFile("configuration/mavenw/MavenWrapperDownloader.java.mustache", ".mvn/wrapper", "MavenWrapperDownloader.java"));
|
||||
supportingFiles.add(new SupportingFile("configuration/mavenw/maven-wrapper.jar.mustache", ".mvn/wrapper", "maven-wrapper.jar"));
|
||||
supportingFiles.add(new SupportingFile("configuration/mavenw/maven-wrapper.properties.mustache", ".mvn/wrapper", "maren-wrapper.properties"));
|
||||
}
|
||||
|
||||
// Git files
|
||||
supportingFiles.add(new SupportingFile("configuration/git/gitignore.mustache", "", ".gitignore").doNotOverwrite());
|
||||
|
||||
// Use the default java Date
|
||||
typeMapping.put("date", "LocalDate");
|
||||
typeMapping.put("DateTime", "LocalDateTime");
|
||||
importMapping.put("LocalDate", "java.time.LocalDate");
|
||||
importMapping.put("LocalDateTime", "java.time.LocalDateTime");
|
||||
|
||||
// Add documentation files
|
||||
supportingFiles.add(new SupportingFile("doc/README.mustache", "", "README.md").doNotOverwrite());
|
||||
supportingFiles.add(new SupportingFile("doc/auth.mustache", apiDocPath, "auth.md"));
|
||||
modelDocTemplateFiles.put("doc/model_doc.mustache", ".md");
|
||||
apiDocTemplateFiles.put("doc/api_doc.mustache", ".md");
|
||||
modelDocTemplateFiles.remove("model_doc.mustache");
|
||||
apiDocTemplateFiles.remove("api_doc.mustache");
|
||||
|
||||
// Add model files
|
||||
modelTemplateFiles.remove("model.mustache");
|
||||
modelTemplateFiles.put("model/model.mustache", ".java");
|
||||
// Api file
|
||||
apiTemplateFiles.clear();
|
||||
apiTemplateFiles.put("client/api.mustache", ".java");
|
||||
|
||||
// Add test files
|
||||
apiTestTemplateFiles.clear();
|
||||
if (testTool.equals(OPT_TEST_JUNIT)) {
|
||||
apiTestTemplateFiles.put("api_test.mustache", ".java");
|
||||
modelTestTemplateFiles.put("model_test.mustache", ".java");
|
||||
apiTestTemplateFiles.put("client/test/api_test.mustache", ".java");
|
||||
} else if (testTool.equals(OPT_TEST_SPOCK)) {
|
||||
apiTestTemplateFiles.put("api_test.groovy.mustache", ".groovy");
|
||||
modelTestTemplateFiles.put("model_test.groovy.mustache", ".groovy");
|
||||
apiTestTemplateFiles.put("client/test/api_test.groovy.mustache", ".groovy");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apiTestFileFolder() {
|
||||
if (testTool.equals(OPT_TEST_SPOCK)) {
|
||||
return getOutputDir() + "/src/test/groovy/" + getInvokerPackage().replaceAll("\\.", "/") + "/api";
|
||||
}
|
||||
return getOutputDir() + "/src/test/java/" + getInvokerPackage().replaceAll("\\.", "/") + "/api";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String modelTestFileFolder() {
|
||||
if (testTool.equals(OPT_TEST_SPOCK)) {
|
||||
return getOutputDir() + "/src/test/groovy/" + getInvokerPackage().replaceAll("\\.", "/") + "/model";
|
||||
}
|
||||
return getOutputDir() + "/src/test/java/" + getInvokerPackage().replaceAll("\\.", "/") + "/model";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toApiTestFilename(String name) {
|
||||
if (testTool.equals(OPT_TEST_SPOCK)) {
|
||||
return toApiName(name) + "Spec";
|
||||
}
|
||||
return toApiName(name) + "Test";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toModelTestFilename(String name) {
|
||||
if (testTool.equals(OPT_TEST_SPOCK)) {
|
||||
return toModelName(name) + "Spec";
|
||||
}
|
||||
return toModelName(name) + "Test";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUseBeanValidation(boolean useBeanValidation) {
|
||||
this.useBeanValidation = useBeanValidation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toApiVarName(String name) {
|
||||
String apiVarName = super.toApiVarName(name);
|
||||
if (reservedWords.contains(apiVarName)) {
|
||||
apiVarName = escapeReservedWord(apiVarName);
|
||||
}
|
||||
return apiVarName;
|
||||
}
|
||||
|
||||
public boolean isUseBeanValidation() {
|
||||
return useBeanValidation;
|
||||
}
|
||||
|
||||
public boolean isConfigureAuthorization() {
|
||||
return configureAuthorization;
|
||||
// Add documentation files
|
||||
supportingFiles.add(new SupportingFile("client/doc/README.mustache", "", "README.md").doNotOverwrite());
|
||||
supportingFiles.add(new SupportingFile("client/doc/auth.mustache", apiDocPath, "auth.md"));
|
||||
apiDocTemplateFiles.clear();
|
||||
apiDocTemplateFiles.put("client/doc/api_doc.mustache", ".md");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
package org.openapitools.codegen.languages;
|
||||
|
||||
import org.openapitools.codegen.*;
|
||||
import org.openapitools.codegen.meta.GeneratorMetadata;
|
||||
import org.openapitools.codegen.meta.Stability;
|
||||
import org.openapitools.codegen.utils.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class JavaMicronautServerCodegen extends JavaMicronautAbstractCodegen {
|
||||
public static final String OPT_CONTROLLER_PACKAGE = "controllerPackage";
|
||||
public static final String OPT_GENERATE_CONTROLLER_FROM_EXAMPLES = "generateControllerFromExamples";
|
||||
public static final String OPT_GENERATE_CONTROLLER_AS_ABSTRACT = "generateControllerAsAbstract";
|
||||
|
||||
private final Logger LOGGER = LoggerFactory.getLogger(JavaClientCodegen.class);
|
||||
|
||||
public static final String NAME = "java-micronaut-server";
|
||||
|
||||
protected String controllerPackage = "org.openapitools.controller";
|
||||
protected boolean generateControllerAsAbstract = false;
|
||||
protected boolean generateControllerFromExamples = false;
|
||||
protected boolean useAuth = true;
|
||||
|
||||
protected String controllerPrefix = "";
|
||||
protected String controllerSuffix = "Controller";
|
||||
protected String apiPrefix = "Abstract";
|
||||
protected String apiSuffix = "Controller";
|
||||
|
||||
public JavaMicronautServerCodegen() {
|
||||
super();
|
||||
|
||||
title = "OpenAPI Micronaut Server";;
|
||||
apiPackage = "org.openapitools.api";
|
||||
apiDocPath = "docs/controllers";
|
||||
|
||||
generatorMetadata = GeneratorMetadata.newBuilder(generatorMetadata)
|
||||
.stability(Stability.BETA)
|
||||
.build();
|
||||
additionalProperties.put("server", "true");
|
||||
|
||||
cliOptions.add(new CliOption(OPT_CONTROLLER_PACKAGE, "The package in which controllers will be generated").defaultValue(apiPackage));
|
||||
cliOptions.removeIf(c -> c.getOpt().equals(CodegenConstants.API_PACKAGE));
|
||||
cliOptions.add(CliOption.newBoolean(OPT_GENERATE_CONTROLLER_FROM_EXAMPLES,
|
||||
"Generate the implementation of controller and tests from parameter and return examples that will verify that the api works as desired (for testing)",
|
||||
generateControllerFromExamples));
|
||||
cliOptions.add(CliOption.newBoolean(OPT_GENERATE_CONTROLLER_AS_ABSTRACT,
|
||||
"Generate an abstract class for controller to be extended. (" + CodegenConstants.API_PACKAGE +
|
||||
" is then used for the abstract class, and " + OPT_CONTROLLER_PACKAGE +
|
||||
" is used for implementation that extends it.)",
|
||||
generateControllerAsAbstract));
|
||||
cliOptions.add(CliOption.newBoolean(OPT_USE_AUTH, "Whether to import authorization and to annotate controller methods accordingly", useAuth));
|
||||
|
||||
// Set the type mappings
|
||||
// It could be also StreamingFileUpload
|
||||
typeMapping.put("file", "CompletedFileUpload");
|
||||
importMapping.put("CompletedFileUpload", "io.micronaut.http.multipart.CompletedFileUpload");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodegenType getTag() {
|
||||
return CodegenType.SERVER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp() {
|
||||
return "Generates a Java Micronaut Server.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processOpts() {
|
||||
// Get all the properties that require to know if user specified them directly
|
||||
if (additionalProperties.containsKey(OPT_GENERATE_CONTROLLER_AS_ABSTRACT)) {
|
||||
generateControllerAsAbstract = convertPropertyToBoolean(OPT_GENERATE_CONTROLLER_AS_ABSTRACT);
|
||||
}
|
||||
writePropertyBack(OPT_GENERATE_CONTROLLER_AS_ABSTRACT, generateControllerAsAbstract);
|
||||
|
||||
if (additionalProperties.containsKey(OPT_CONTROLLER_PACKAGE)) {
|
||||
controllerPackage = (String) additionalProperties.get(OPT_CONTROLLER_PACKAGE);
|
||||
} else if (!generateControllerAsAbstract && additionalProperties.containsKey(CodegenConstants.API_PACKAGE)) {
|
||||
controllerPackage = (String) additionalProperties.get(CodegenConstants.API_PACKAGE);
|
||||
}
|
||||
additionalProperties.put(OPT_CONTROLLER_PACKAGE, controllerPackage);
|
||||
|
||||
if (!generateControllerAsAbstract) {
|
||||
apiPackage = controllerPackage;
|
||||
additionalProperties.put(CodegenConstants.API_PACKAGE, apiPackage);
|
||||
}
|
||||
super.processOpts();
|
||||
|
||||
// Get all the other properties after superclass processed everything
|
||||
if (additionalProperties.containsKey(OPT_GENERATE_CONTROLLER_FROM_EXAMPLES)) {
|
||||
generateControllerFromExamples = convertPropertyToBoolean(OPT_GENERATE_CONTROLLER_FROM_EXAMPLES);
|
||||
}
|
||||
writePropertyBack(OPT_GENERATE_CONTROLLER_FROM_EXAMPLES, generateControllerFromExamples);
|
||||
|
||||
if (additionalProperties.containsKey(OPT_USE_AUTH)) {
|
||||
useAuth = convertPropertyToBoolean(OPT_USE_AUTH);
|
||||
}
|
||||
writePropertyBack(OPT_USE_AUTH, useAuth);
|
||||
|
||||
// Api file
|
||||
apiTemplateFiles.clear();
|
||||
if (generateControllerAsAbstract) {
|
||||
setApiNamePrefix(apiPrefix);
|
||||
setApiNameSuffix(apiSuffix);
|
||||
} else {
|
||||
setApiNamePrefix(controllerPrefix);
|
||||
setApiNameSuffix(controllerSuffix);
|
||||
}
|
||||
apiTemplateFiles.put("server/controller.mustache", ".java");
|
||||
|
||||
// Add documentation files
|
||||
supportingFiles.add(new SupportingFile("server/doc/README.mustache", "", "README.md").doNotOverwrite());
|
||||
apiDocTemplateFiles.clear();
|
||||
apiDocTemplateFiles.put("server/doc/controller_doc.mustache", ".md");
|
||||
|
||||
// Add test files
|
||||
apiTestTemplateFiles.clear();
|
||||
// Controller Implementation is generated as a test file - so that it is not overwritten
|
||||
if (generateControllerAsAbstract) {
|
||||
apiTestTemplateFiles.put("server/controllerImplementation.mustache", ".java");
|
||||
}
|
||||
if (testTool.equals(OPT_TEST_JUNIT)) {
|
||||
apiTestTemplateFiles.put("server/test/controller_test.mustache", ".java");
|
||||
} else if (testTool.equals(OPT_TEST_SPOCK)) {
|
||||
apiTestTemplateFiles.put("server/test/controller_test.groovy.mustache", ".groovy");
|
||||
}
|
||||
|
||||
// Add Application.java file
|
||||
String invokerFolder = (sourceFolder + '/' + invokerPackage).replace('.', '/');
|
||||
supportingFiles.add(new SupportingFile("common/configuration/Application.mustache", invokerFolder, "Application.java").doNotOverwrite());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apiTestFilename(String templateName, String tag) {
|
||||
if (generateControllerAsAbstract && templateName.contains("controllerImplementation")) {
|
||||
return (
|
||||
outputFolder + File.separator +
|
||||
sourceFolder + File.separator +
|
||||
controllerPackage.replace('.', File.separatorChar) + File.separator +
|
||||
StringUtils.camelize(controllerPrefix + "_" + tag + "_" + controllerSuffix) + ".java"
|
||||
).replace('/', File.separatorChar);
|
||||
}
|
||||
|
||||
return super.apiTestFilename(templateName, tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParameterExampleValue(CodegenParameter p) {
|
||||
super.setParameterExampleValue(p);
|
||||
|
||||
if (p.isFile) {
|
||||
// The CompletedFileUpload cannot be initialized
|
||||
p.example = "null";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) {
|
||||
objs = super.postProcessOperationsWithModels(objs, allModels);
|
||||
|
||||
// Add the controller classname to operations
|
||||
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
|
||||
String controllerClassname = StringUtils.camelize(controllerPrefix + "_" + operations.get("pathPrefix") + "_" + controllerSuffix);
|
||||
objs.put("controllerClassname", controllerClassname);
|
||||
|
||||
return objs;
|
||||
}
|
||||
}
|
||||
@@ -58,6 +58,7 @@ org.openapitools.codegen.languages.JavaClientCodegen
|
||||
org.openapitools.codegen.languages.JavaCXFClientCodegen
|
||||
org.openapitools.codegen.languages.JavaInflectorServerCodegen
|
||||
org.openapitools.codegen.languages.JavaMicronautClientCodegen
|
||||
org.openapitools.codegen.languages.JavaMicronautServerCodegen
|
||||
org.openapitools.codegen.languages.JavaMSF4JServerCodegen
|
||||
org.openapitools.codegen.languages.JavaPKMSTServerCodegen
|
||||
org.openapitools.codegen.languages.JavaPlayFrameworkCodegen
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
{{>licenseInfo}}
|
||||
package {{package}};
|
||||
|
||||
import io.micronaut.http.annotation.*;
|
||||
import io.micronaut.core.annotation.*;
|
||||
import io.micronaut.http.client.annotation.Client;
|
||||
{{#configureAuth}}
|
||||
import {{invokerPackage}}.auth.Authorization;
|
||||
{{/configureAuth}}
|
||||
import {{invokerPackage}}.query.QueryParam;
|
||||
import io.micronaut.core.convert.format.Format;
|
||||
import reactor.core.publisher.Mono;
|
||||
{{#imports}}import {{import}};
|
||||
{{/imports}}
|
||||
import javax.annotation.Generated;
|
||||
{{^fullJavaUtil}}
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
{{/fullJavaUtil}}{{#useBeanValidation}}
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.*;
|
||||
{{/useBeanValidation}}
|
||||
|
||||
{{>generatedAnnotation}}
|
||||
@Client("${base-path}")
|
||||
public interface {{classname}} {
|
||||
{{#operations}}{{#operation}}
|
||||
/**
|
||||
{{#summary}}
|
||||
* {{summary}}
|
||||
{{/summary}}
|
||||
{{#notes}}
|
||||
* {{notes}}
|
||||
{{/notes}}
|
||||
{{^summary}}
|
||||
{{^notes}}
|
||||
* {{nickname}}
|
||||
{{/notes}}
|
||||
{{/summary}}
|
||||
*
|
||||
{{#allParams}}
|
||||
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
|
||||
{{/allParams}}
|
||||
{{#returnType}}
|
||||
* @return {{returnType}}
|
||||
{{/returnType}}
|
||||
{{#externalDocs}}
|
||||
* {{description}}
|
||||
* @see <a href="{{url}}">{{summary}} Documentation</a>
|
||||
{{/externalDocs}}
|
||||
*/
|
||||
@{{#lambda.pascalcase}}{{#lambda.lowercase}}{{httpMethod}}{{/lambda.lowercase}}{{/lambda.pascalcase}}(uri="{{{path}}}")
|
||||
{{#vendorExtensions.x-contentType}}
|
||||
@Produces(value={"{{vendorExtensions.x-contentType}}"})
|
||||
{{/vendorExtensions.x-contentType}}
|
||||
@Consumes(value={"{{vendorExtensions.x-accepts}}"})
|
||||
{{!auth methods}}
|
||||
{{#configureAuth}}
|
||||
{{#authMethods}}
|
||||
@Authorization(name="{{{name}}}"{{!scopes}}{{#isOAuth}}, scopes={{=< >=}}{<={{ }}=>{{#scopes}}"{{{scope}}}"{{^-last}}, {{/-last}}{{/scopes}}{{=< >=}}}<={{ }}=>{{/isOAuth}})
|
||||
{{/authMethods}}
|
||||
{{/configureAuth}}
|
||||
{{#returnType}}Mono<{{{returnType}}}>{{/returnType}}{{^returnType}}Mono<Object>{{/returnType}} {{nickname}}({{^allParams}});{{/allParams}}{{#allParams}}
|
||||
{{>params/queryParams}}{{>params/pathParams}}{{>params/headerParams}}{{>params/bodyParams}}{{>params/formParams}}{{>params/cookieParams}}{{^-last}}, {{/-last}}{{#-last}}
|
||||
);{{/-last}}{{/allParams}}
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
micronautVersion=3.0.0-M5
|
||||
@@ -1,4 +0,0 @@
|
||||
{{#models}}{{#model}}
|
||||
|
||||
{{#isEnum}}{{>doc/enum_outer_doc}}{{/isEnum}}{{^isEnum}}{{>doc/pojo_doc}}{{/isEnum}}
|
||||
{{/model}}{{/models}}
|
||||
@@ -1,52 +0,0 @@
|
||||
{{#useBeanValidation}}{{!
|
||||
validate all pojos and enums
|
||||
}}{{^isContainer}}{{#isModel}} @Valid
|
||||
{{/isModel}}{{/isContainer}}{{!
|
||||
nullable & nonnull
|
||||
}}{{#required}}{{#isNullable}} @Nullable
|
||||
{{/isNullable}}{{^isNullable}} @NotNull
|
||||
{{/isNullable}}{{/required}}{{^required}} @Nullable
|
||||
{{/required}}{{!
|
||||
pattern
|
||||
}}{{#pattern}}{{^isByteArray}} @Pattern(regexp="{{{pattern}}}")
|
||||
{{/isByteArray}}{{/pattern}}{{!
|
||||
both minLength && maxLength
|
||||
}}{{#minLength}}{{#maxLength}} @Size(min={{minLength}}, max={{maxLength}})
|
||||
{{/maxLength}}{{/minLength}}{{!
|
||||
just minLength
|
||||
}}{{#minLength}}{{^maxLength}} @Size(min={{minLength}})
|
||||
{{/maxLength}}{{/minLength}}{{!
|
||||
just maxLength
|
||||
}}{{^minLength}}{{#maxLength}} @Size(max={{maxLength}})
|
||||
{{/maxLength}}{{/minLength}}{{!
|
||||
@Size: both minItems && maxItems
|
||||
}}{{#minItems}}{{#maxItems}} @Size(min={{minItems}}, max={{maxItems}})
|
||||
{{/maxItems}}{{/minItems}}{{!
|
||||
@Size: just minItems
|
||||
}}{{#minItems}}{{^maxItems}} @Size(min={{minItems}})
|
||||
{{/maxItems}}{{/minItems}}{{!
|
||||
@Size: just maxItems
|
||||
}}{{^minItems}}{{#maxItems}} @Size(max={{maxItems}})
|
||||
{{/maxItems}}{{/minItems}}{{!
|
||||
@Email
|
||||
}}{{#isEmail}} @Email
|
||||
{{/isEmail}}{{!
|
||||
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 for decimal value
|
||||
}}{{#minimum}} @DecimalMin({{#exclusiveMinimum}}value={{/exclusiveMinimum}}"{{minimum}}"{{#exclusiveMinimum}}, inclusive=false{{/exclusiveMinimum}})
|
||||
{{/minimum}}{{!
|
||||
maximal for decimal value
|
||||
}}{{#maximum}} @DecimalMax({{#exclusiveMaximum}}value={{/exclusiveMaximum}}"{{maximum}}"{{#exclusiveMaximum}}, inclusive=false{{/exclusiveMaximum}})
|
||||
{{/maximum}}{{!
|
||||
close decimal values
|
||||
}}{{/isLong}}{{/isInteger}}{{/useBeanValidation}}
|
||||
@@ -1,26 +0,0 @@
|
||||
{{!
|
||||
If this is map and items are nullable, make sure that nulls are included.
|
||||
To determine what JsonInclude.Include method to use, consider the following:
|
||||
* If the field is required, always include it, even if it is null.
|
||||
* Else use custom behaviour, IOW use whatever is defined on the object mapper
|
||||
}}
|
||||
@JsonProperty(JSON_PROPERTY_{{nameInSnakeCase}})
|
||||
@JsonInclude({{#isMap}}{{#items.isNullable}}content = JsonInclude.Include.ALWAYS, {{/items.isNullable}}{{/isMap}}value = JsonInclude.Include.{{#required}}ALWAYS{{/required}}{{^required}}USE_DEFAULTS{{/required}})
|
||||
{{#withXml}}
|
||||
{{^isContainer}}
|
||||
@JacksonXmlProperty({{#isXmlAttribute}}isAttribute = true, {{/isXmlAttribute}}{{#xmlNamespace}}namespace="{{xmlNamespace}}", {{/xmlNamespace}}localName = "{{#xmlName}}{{xmlName}}{{/xmlName}}{{^xmlName}}{{baseName}}{{/xmlName}}")
|
||||
@JacksonXmlProperty({{#isXmlAttribute}}isAttribute = true, {{/isXmlAttribute}}{{#xmlNamespace}}namespace="{{xmlNamespace}}", {{/xmlNamespace}}localName = "{{#xmlName}}{{xmlName}}{{/xmlName}}{{^xmlName}}{{baseName}}{{/xmlName}}")
|
||||
{{/isContainer}}
|
||||
{{#isContainer}}
|
||||
{{#isXmlWrapped}}
|
||||
// items.xmlName={{items.xmlName}}
|
||||
@JacksonXmlElementWrapper(useWrapping = {{isXmlWrapped}}, {{#xmlNamespace}}namespace="{{xmlNamespace}}", {{/xmlNamespace}}localName = "{{#items.xmlName}}{{items.xmlName}}{{/items.xmlName}}{{^items.xmlName}}{{items.baseName}}{{/items.xmlName}}")
|
||||
{{/isXmlWrapped}}
|
||||
{{/isContainer}}
|
||||
{{/withXml}}
|
||||
{{#isDateTime}}
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXX")
|
||||
{{/isDateTime}}
|
||||
{{#isDate}}
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
|
||||
{{/isDate}}
|
||||
@@ -1,61 +0,0 @@
|
||||
{{#jackson}}
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
{{/jackson}}
|
||||
|
||||
/**
|
||||
* {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{description}}{{/description}}
|
||||
*/
|
||||
{{#additionalEnumTypeAnnotations}}
|
||||
{{{.}}}
|
||||
{{/additionalEnumTypeAnnotations}}{{#useBeanValidation}}@Introspected
|
||||
{{/useBeanValidation}}public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} {
|
||||
{{#allowableValues}}
|
||||
{{#enumVars}}
|
||||
{{#enumDescription}}
|
||||
/**
|
||||
* {{enumDescription}}
|
||||
*/
|
||||
{{/enumDescription}}
|
||||
{{#withXml}}
|
||||
@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
|
||||
{{/withXml}}
|
||||
{{{name}}}({{{value}}}){{^-last}},{{/-last}}{{#-last}};{{/-last}}
|
||||
{{/enumVars}}
|
||||
{{/allowableValues}}
|
||||
|
||||
private {{{dataType}}} value;
|
||||
|
||||
{{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}({{{dataType}}} value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
{{#jackson}}
|
||||
@JsonValue
|
||||
{{/jackson}}
|
||||
public {{{dataType}}} getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.valueOf(value);
|
||||
}
|
||||
|
||||
{{#jackson}}
|
||||
@JsonCreator
|
||||
{{/jackson}}
|
||||
public static {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} fromValue({{{dataType}}} value) {
|
||||
for ({{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} b : {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.values()) {
|
||||
if (b.value.equals(value)) {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
{{#isNullable}}
|
||||
return null;
|
||||
{{/isNullable}}
|
||||
{{^isNullable}}
|
||||
throw new IllegalArgumentException("Unexpected value '" + value + "'");
|
||||
{{/isNullable}}
|
||||
}
|
||||
}
|
||||
@@ -1,332 +0,0 @@
|
||||
/**
|
||||
* {{#description}}{{.}}{{/description}}{{^description}}{{classname}}{{/description}}
|
||||
*/
|
||||
{{#description}}
|
||||
@ApiModel(description = "{{{description}}}")
|
||||
{{/description}}
|
||||
{{#jackson}}
|
||||
@JsonPropertyOrder({
|
||||
{{#vars}}
|
||||
{{classname}}.JSON_PROPERTY_{{nameInSnakeCase}}{{^-last}},{{/-last}}
|
||||
{{/vars}}
|
||||
})
|
||||
@JsonTypeName("{{name}}")
|
||||
{{/jackson}}
|
||||
{{#additionalModelTypeAnnotations}}
|
||||
{{{.}}}
|
||||
{{/additionalModelTypeAnnotations}}
|
||||
{{>generatedAnnotation}}{{#discriminator}}{{>model/typeInfoAnnotation}}{{/discriminator}}{{>model/xmlAnnotation}}{{#useBeanValidation}}
|
||||
@Introspected
|
||||
{{/useBeanValidation}}{{!
|
||||
Declare the class with extends and implements
|
||||
}}public class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{{#vendorExtensions.x-implements}}{{#-first}}implements {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{#-last}} {{/-last}}{{/vendorExtensions.x-implements}}{
|
||||
{{#serializableModel}}
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
{{/serializableModel}}
|
||||
{{#vars}}
|
||||
{{#isEnum}}
|
||||
{{^isContainer}}
|
||||
{{>model/modelInnerEnum}}
|
||||
{{/isContainer}}
|
||||
{{#isContainer}}
|
||||
{{#mostInnerItems}}
|
||||
{{>model/modelInnerEnum}}
|
||||
{{/mostInnerItems}}
|
||||
{{/isContainer}}
|
||||
{{/isEnum}}
|
||||
public static final String JSON_PROPERTY_{{nameInSnakeCase}} = "{{baseName}}";
|
||||
{{#withXml}}
|
||||
{{#isXmlAttribute}}
|
||||
@XmlAttribute(name = "{{#xmlName}}{{xmlName}}{{/xmlName}}{{^xmlName}}{{baseName}}{{/xmlName}}"
|
||||
{{/isXmlAttribute}}
|
||||
{{^isXmlAttribute}}
|
||||
{{^isContainer}}
|
||||
@XmlElement({{#xmlNamespace}}namespace="{{xmlNamespace}}", {{/xmlNamespace}}name = "{{#xmlName}}{{xmlName}}{{/xmlName}}{{^xmlName}}{{baseName}}{{/xmlName}}")
|
||||
{{/isContainer}}
|
||||
{{#isContainer}}
|
||||
// Is a container wrapped={{isXmlWrapped}}
|
||||
{{#items}}
|
||||
// items.name={{name}} items.baseName={{baseName}} items.xmlName={{xmlName}} items.xmlNamespace={{xmlNamespace}}
|
||||
// items.example={{example}} items.type={{dataType}}
|
||||
@XmlElement({{#xmlNamespace}}namespace="{{xmlNamespace}}", {{/xmlNamespace}}name = "{{#xmlName}}{{xmlName}}{{/xmlName}}{{^xmlName}}{{baseName}}{{/xmlName}}")
|
||||
{{/items}}
|
||||
{{#isXmlWrapped}}
|
||||
@XmlElementWrapper({{#xmlNamespace}}namespace="{{xmlNamespace}}", {{/xmlNamespace}}name = "{{#xmlName}}{{xmlName}}{{/xmlName}}{{^xmlName}}{{baseName}}{{/xmlName}}")
|
||||
{{/isXmlWrapped}}
|
||||
{{/isContainer}}
|
||||
{{/isXmlAttribute}}
|
||||
{{/withXml}}
|
||||
{{#vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{#isContainer}}
|
||||
private JsonNullable<{{{datatypeWithEnum}}}> {{name}} = JsonNullable.<{{{datatypeWithEnum}}}>undefined();
|
||||
{{/isContainer}}
|
||||
{{^isContainer}}
|
||||
private JsonNullable<{{{datatypeWithEnum}}}> {{name}} = JsonNullable.<{{{datatypeWithEnum}}}>{{#defaultValue}}of({{{.}}}){{/defaultValue}}{{^defaultValue}}undefined(){{/defaultValue}};
|
||||
{{/isContainer}}
|
||||
{{/vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{^vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{#isContainer}}
|
||||
private {{{datatypeWithEnum}}} {{name}}{{#required}}{{#defaultValue}} = {{{.}}}{{/defaultValue}}{{/required}}{{^required}} = null{{/required}};
|
||||
{{/isContainer}}
|
||||
{{^isContainer}}
|
||||
{{#isDiscriminator}}protected{{/isDiscriminator}}{{^isDiscriminator}}private{{/isDiscriminator}} {{{datatypeWithEnum}}} {{name}}{{#defaultValue}} = {{{.}}}{{/defaultValue}};
|
||||
{{/isContainer}}
|
||||
{{/vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
|
||||
{{/vars}}
|
||||
{{#parcelableModel}}
|
||||
public {{classname}}() {
|
||||
{{#parent}}
|
||||
super();
|
||||
{{/parent}}
|
||||
}
|
||||
|
||||
{{/parcelableModel}}
|
||||
{{#vars}}
|
||||
{{^isReadOnly}}
|
||||
public {{classname}} {{name}}({{{datatypeWithEnum}}} {{name}}) {
|
||||
{{#vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
this.{{name}} = JsonNullable.<{{{datatypeWithEnum}}}>of({{name}});
|
||||
{{/vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{^vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
this.{{name}} = {{name}};
|
||||
{{/vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
return this;
|
||||
}
|
||||
|
||||
{{#isArray}}
|
||||
public {{classname}} add{{nameInCamelCase}}Item({{{items.datatypeWithEnum}}} {{name}}Item) {
|
||||
{{#vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
if (this.{{name}} == null || !this.{{name}}.isPresent()) {
|
||||
this.{{name}} = JsonNullable.<{{{datatypeWithEnum}}}>of({{{defaultValue}}});
|
||||
}
|
||||
try {
|
||||
this.{{name}}.get().add({{name}}Item);
|
||||
} catch (java.util.NoSuchElementException e) {
|
||||
// this can never happen, as we make sure above that the value is present
|
||||
}
|
||||
return this;
|
||||
{{/vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{^vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{^required}}
|
||||
if (this.{{name}} == null) {
|
||||
this.{{name}} = {{{defaultValue}}};
|
||||
}
|
||||
{{/required}}
|
||||
this.{{name}}.add({{name}}Item);
|
||||
return this;
|
||||
{{/vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
}
|
||||
|
||||
{{/isArray}}
|
||||
{{#isMap}}
|
||||
public {{classname}} put{{nameInCamelCase}}Item(String key, {{{items.datatypeWithEnum}}} {{name}}Item) {
|
||||
{{#vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
if (this.{{name}} == null || !this.{{name}}.isPresent()) {
|
||||
this.{{name}} = JsonNullable.<{{{datatypeWithEnum}}}>of({{{defaultValue}}});
|
||||
}
|
||||
try {
|
||||
this.{{name}}.get().put(key, {{name}}Item);
|
||||
} catch (java.util.NoSuchElementException e) {
|
||||
// this can never happen, as we make sure above that the value is present
|
||||
}
|
||||
return this;
|
||||
{{/vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{^vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{^required}}
|
||||
if (this.{{name}} == null) {
|
||||
this.{{name}} = {{{defaultValue}}};
|
||||
}
|
||||
{{/required}}
|
||||
this.{{name}}.put(key, {{name}}Item);
|
||||
return this;
|
||||
{{/vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
}
|
||||
|
||||
{{/isMap}}
|
||||
{{/isReadOnly}}
|
||||
/**
|
||||
{{#description}}
|
||||
* {{description}}
|
||||
{{/description}}
|
||||
{{^description}}
|
||||
* Get {{name}}
|
||||
{{/description}}
|
||||
{{#minimum}}
|
||||
* minimum: {{minimum}}
|
||||
{{/minimum}}
|
||||
{{#maximum}}
|
||||
* maximum: {{maximum}}
|
||||
{{/maximum}}
|
||||
* @return {{name}}
|
||||
**/
|
||||
{{>model/beanValidation}} @ApiModelProperty({{#example}}example = "{{{example}}}", {{/example}}{{#required}}required = {{required}}, {{/required}}value = "{{{description}}}")
|
||||
{{#vendorExtensions.x-extra-annotation}}
|
||||
{{{vendorExtensions.x-extra-annotation}}}
|
||||
{{/vendorExtensions.x-extra-annotation}}
|
||||
{{#vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{!unannotated, Jackson would pick this up automatically and add it *in addition* to the _JsonNullable getter field}} @JsonIgnore
|
||||
{{/vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{^vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{#jackson}}
|
||||
{{>model/jackson_annotations}}{{/jackson}}{{/vendorExtensions.x-is-jackson-optional-nullable}} public {{{datatypeWithEnum}}} {{getter}}() {
|
||||
{{#vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{#isReadOnly}}
|
||||
{{! A readonly attribute doesn't have setter => jackson will set null directly if explicitly returned by API, so make sure we have an empty JsonNullable}} if ({{name}} == null) {
|
||||
{{name}} = JsonNullable.<{{{datatypeWithEnum}}}>{{#defaultValue}}of({{{.}}}){{/defaultValue}}{{^defaultValue}}undefined(){{/defaultValue}};
|
||||
}
|
||||
{{/isReadOnly}}
|
||||
return {{name}}.orElse(null);
|
||||
{{/vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{^vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
return {{name}};
|
||||
{{/vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
}
|
||||
|
||||
{{#vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{>model/jackson_annotations}}
|
||||
public JsonNullable<{{{datatypeWithEnum}}}> {{getter}}_JsonNullable() {
|
||||
return {{name}};
|
||||
}
|
||||
|
||||
@JsonProperty(JSON_PROPERTY_{{nameInSnakeCase}})
|
||||
{{#isReadOnly}}private{{/isReadOnly}}{{^isReadOnly}}public{{/isReadOnly}} void {{setter}}_JsonNullable(JsonNullable<{{{datatypeWithEnum}}}> {{name}}) {
|
||||
{{! For getters/setters that have name differing from attribute name, we must include setter (albeit private) for jackson to be able to set the attribute}} this.{{name}} = {{name}};
|
||||
}
|
||||
|
||||
{{/vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{^isReadOnly}}
|
||||
{{#jackson}}
|
||||
{{^vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{>model/jackson_annotations}}{{/vendorExtensions.x-is-jackson-optional-nullable}}{{/jackson}}{{#vendorExtensions.x-setter-extra-annotation}}
|
||||
{{{vendorExtensions.x-setter-extra-annotation}}}
|
||||
{{/vendorExtensions.x-setter-extra-annotation}} public void {{setter}}({{{datatypeWithEnum}}} {{name}}) {
|
||||
{{#vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
this.{{name}} = JsonNullable.<{{{datatypeWithEnum}}}>of({{name}});
|
||||
{{/vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{^vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
this.{{name}} = {{name}};
|
||||
{{/vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
}
|
||||
|
||||
{{/isReadOnly}}
|
||||
{{/vars}}
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
{{#useReflectionEqualsHashCode}}
|
||||
return EqualsBuilder.reflectionEquals(this, o, false, null, true);
|
||||
{{/useReflectionEqualsHashCode}}
|
||||
{{^useReflectionEqualsHashCode}}
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
{{#hasVars}}
|
||||
{{classname}} {{classVarName}} = ({{classname}}) o;
|
||||
return {{#vars}}{{#isByteArray}}Arrays{{/isByteArray}}{{^isByteArray}}Objects{{/isByteArray}}.equals(this.{{name}}, {{classVarName}}.{{name}}){{^-last}} &&
|
||||
{{/-last}}{{/vars}}{{#parent}} &&
|
||||
super.equals(o){{/parent}};
|
||||
{{/hasVars}}
|
||||
{{^hasVars}}
|
||||
return {{#parent}}super.equals(o){{/parent}}{{^parent}}true{{/parent}};
|
||||
{{/hasVars}}
|
||||
{{/useReflectionEqualsHashCode}}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
{{#useReflectionEqualsHashCode}}
|
||||
return HashCodeBuilder.reflectionHashCode(this);
|
||||
{{/useReflectionEqualsHashCode}}
|
||||
{{^useReflectionEqualsHashCode}}
|
||||
return Objects.hash({{#vars}}{{^isByteArray}}{{name}}{{/isByteArray}}{{#isByteArray}}Arrays.hashCode({{name}}){{/isByteArray}}{{^-last}}, {{/-last}}{{/vars}}{{#parent}}{{#hasVars}}, {{/hasVars}}super.hashCode(){{/parent}});
|
||||
{{/useReflectionEqualsHashCode}}
|
||||
}
|
||||
|
||||
@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{{#jsonb}} static{{/jsonb}} String toIndentedString(Object o) {
|
||||
if (o == null) {
|
||||
return "null";
|
||||
}
|
||||
return o.toString().replace("\n", "\n ");
|
||||
}
|
||||
|
||||
{{#parcelableModel}}
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
{{#model}}
|
||||
{{#isArray}}
|
||||
out.writeList(this);
|
||||
{{/isArray}}
|
||||
{{^isArray}}
|
||||
{{#parent}}
|
||||
super.writeToParcel(out, flags);
|
||||
{{/parent}}
|
||||
{{#vars}}
|
||||
out.writeValue({{name}});
|
||||
{{/vars}}
|
||||
{{/isArray}}
|
||||
{{/model}}
|
||||
}
|
||||
|
||||
{{classname}}(Parcel in) {
|
||||
{{#isArray}}
|
||||
in.readTypedList(this, {{arrayModelType}}.CREATOR);
|
||||
{{/isArray}}
|
||||
{{^isArray}}
|
||||
{{#parent}}
|
||||
super(in);
|
||||
{{/parent}}
|
||||
{{#vars}}
|
||||
{{#isPrimitiveType}}
|
||||
{{name}} = ({{{datatypeWithEnum}}})in.readValue(null);
|
||||
{{/isPrimitiveType}}
|
||||
{{^isPrimitiveType}}
|
||||
{{name}} = ({{{datatypeWithEnum}}})in.readValue({{complexType}}.class.getClassLoader());
|
||||
{{/isPrimitiveType}}
|
||||
{{/vars}}
|
||||
{{/isArray}}
|
||||
}
|
||||
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<{{classname}}> CREATOR = new Parcelable.Creator<{{classname}}>() {
|
||||
public {{classname}} createFromParcel(Parcel in) {
|
||||
{{#model}}
|
||||
{{#isArray}}
|
||||
{{classname}} result = new {{classname}}();
|
||||
result.addAll(in.readArrayList({{arrayModelType}}.class.getClassLoader()));
|
||||
return result;
|
||||
{{/isArray}}
|
||||
{{^isArray}}
|
||||
return new {{classname}}(in);
|
||||
{{/isArray}}
|
||||
{{/model}}
|
||||
}
|
||||
public {{classname}}[] newArray(int size) {
|
||||
return new {{classname}}[size];
|
||||
}
|
||||
};
|
||||
{{/parcelableModel}}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
{{#isBodyParam}}@Body {{>params/beanValidation}}{{>params/type}} {{paramName}}{{/isBodyParam}}
|
||||
@@ -1 +0,0 @@
|
||||
{{#isCookieParam}}@CookieValue(value="{{baseName}}"{{#defaultValue}}, defaultValue="{{defaultValue}}"{{/defaultValue}}) {{>params/beanValidationCore}}{{>params/type}} {{paramName}}{{/isCookieParam}}
|
||||
@@ -1 +0,0 @@
|
||||
{{#isFormParam}}{{>params/beanValidation}}{{>params/type}} {{paramName}}{{/isFormParam}}
|
||||
@@ -1 +0,0 @@
|
||||
{{#isHeaderParam}}@Header(name="{{baseName}}"{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) {{>params/beanValidation}}{{>params/type}} {{paramName}}{{/isHeaderParam}}
|
||||
@@ -1 +0,0 @@
|
||||
{{#isPathParam}}@PathVariable(name="{{baseName}}"{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) {{>params/beanValidation}}{{>params/type}} {{paramName}}{{/isPathParam}}
|
||||
@@ -1 +0,0 @@
|
||||
{{#isQueryParam}}@QueryParam(name="{{{baseName}}}"{{!default value}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}{{!multi format}}{{#isCollectionFormatMulti}}, format=QueryParam.Format.MULTI{{/isCollectionFormatMulti}}{{!deep object}}{{#isDeepObject}}, format=QueryParam.Format.DEEP_OBJECT{{/isDeepObject}}{{!other collection formats}}{{^isCollectionFormatMulti}}{{^isDeepObject}}{{#collectionFormat}}, format=QueryParam.Format.{{#lambda.uppercase}}{{collectionFormat}}{{/lambda.uppercase}}{{/collectionFormat}}{{/isDeepObject}}{{/isCollectionFormatMulti}}) {{!validation and type}}{{>params/beanValidation}}{{>params/type}} {{paramName}}{{/isQueryParam}}
|
||||
@@ -1,78 +0,0 @@
|
||||
{{>licenseInfo}}
|
||||
package {{invokerPackage}}.query;
|
||||
|
||||
import io.micronaut.context.annotation.AliasFor;
|
||||
import io.micronaut.core.bind.annotation.Bindable;
|
||||
import javax.annotation.Generated;
|
||||
import java.lang.annotation.*;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
|
||||
/**
|
||||
* Indicates that the parameter is a query parameter
|
||||
*/
|
||||
{{>generatedAnnotation}}
|
||||
@Documented
|
||||
@Retention(RUNTIME)
|
||||
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
|
||||
@Bindable
|
||||
@Inherited
|
||||
public @interface QueryParam {
|
||||
|
||||
/**
|
||||
* @return The name of the parameter
|
||||
*/
|
||||
@AliasFor(annotation = Bindable.class, member = "value")
|
||||
String value() default "";
|
||||
|
||||
/**
|
||||
* @return The name of the parameter
|
||||
*/
|
||||
@AliasFor(annotation = Bindable.class, member = "value")
|
||||
String name() default "";
|
||||
|
||||
/**
|
||||
* @see Bindable#defaultValue()
|
||||
* @return The default value
|
||||
*/
|
||||
@AliasFor(annotation = Bindable.class, member = "defaultValue")
|
||||
String defaultValue() default "";
|
||||
|
||||
/**
|
||||
* @return The format of the given values in the URL
|
||||
*/
|
||||
Format format() default Format.CSV;
|
||||
|
||||
/**
|
||||
* The possible formats of the query parameter in the URL.
|
||||
* The conversion of various types is according to openapi v3 specification:
|
||||
* @see <a href="https://swagger.io/specification/">openapi v3 specification</a>
|
||||
* Values are serialized using Jackson object mapper
|
||||
*/
|
||||
public static enum Format {
|
||||
/**
|
||||
* The values of iterator are comma-delimited.
|
||||
* Ambiguity can arise if values of Iterator contain commas inside themselves. In such case, the MULTI format
|
||||
* should be preferred.
|
||||
* Null values are not supported and will be removed during the conversion process.
|
||||
*/
|
||||
CSV,
|
||||
/**
|
||||
* The values are space-delimited, similarly to comma-delimited format.
|
||||
*/
|
||||
SSV,
|
||||
/**
|
||||
* The values a delimited by pipes "|", similarly to comma-delimited format.
|
||||
*/
|
||||
PIPES,
|
||||
/**
|
||||
* The values are repeated as separate parameters, e.g.: color=blue&color=black&color=brown.
|
||||
*/
|
||||
MULTI,
|
||||
/**
|
||||
* The format supports 1-depth recursion into objects with setting each attribute as a separate parameter, e.g.:
|
||||
* 'color[R]=100&color[G]=200&color[B]=150'.
|
||||
*/
|
||||
DEEP_OBJECT
|
||||
}
|
||||
}
|
||||
@@ -1,164 +0,0 @@
|
||||
{{>licenseInfo}}
|
||||
package {{invokerPackage}}.query;
|
||||
|
||||
import io.micronaut.core.annotation.NonNull;
|
||||
import io.micronaut.core.beans.BeanProperty;
|
||||
import io.micronaut.core.beans.BeanWrapper;
|
||||
import io.micronaut.core.convert.ArgumentConversionContext;
|
||||
import io.micronaut.core.convert.ConversionContext;
|
||||
import io.micronaut.core.convert.ConversionService;
|
||||
import io.micronaut.core.util.StringUtils;
|
||||
import io.micronaut.http.MutableHttpRequest;
|
||||
import io.micronaut.http.client.bind.AnnotatedClientArgumentRequestBinder;
|
||||
import io.micronaut.http.client.bind.ClientRequestUriContext;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
import jakarta.inject.Singleton;
|
||||
import javax.annotation.Generated;
|
||||
|
||||
|
||||
{{>generatedAnnotation}}
|
||||
@Singleton
|
||||
public class QueryParamBinder implements AnnotatedClientArgumentRequestBinder<QueryParam> {
|
||||
private static final Character COMMA_DELIMITER = ',';
|
||||
private static final Character PIPE_DELIMITER = '|';
|
||||
private static final Character SPACE_DELIMITER = ' ';
|
||||
|
||||
private final ConversionService<?> conversionService;
|
||||
|
||||
public QueryParamBinder(ConversionService<?> conversionService) {
|
||||
this.conversionService = conversionService;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Class<QueryParam> getAnnotationType() {
|
||||
return QueryParam.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(@NonNull ArgumentConversionContext<Object> context,
|
||||
@NonNull ClientRequestUriContext uriContext,
|
||||
@NonNull Object value,
|
||||
@NonNull MutableHttpRequest<?> request
|
||||
) {
|
||||
String key = context.getAnnotationMetadata().stringValue(QueryParam.class)
|
||||
.filter(StringUtils::isNotEmpty)
|
||||
.orElse(context.getArgument().getName());
|
||||
|
||||
QueryParam.Format format = context.getAnnotationMetadata()
|
||||
.enumValue(QueryParam.class, "format", QueryParam.Format.class)
|
||||
.orElse(QueryParam.Format.CSV);
|
||||
|
||||
if (format == QueryParam.Format.DEEP_OBJECT) {
|
||||
addDeepObjectParameters(context, value, key, uriContext);
|
||||
} else if (format == QueryParam.Format.MULTI) {
|
||||
addMultiParameters(context, value, key, uriContext);
|
||||
} else {
|
||||
Character delimiter = ' ';
|
||||
switch (format) {
|
||||
case SSV:
|
||||
delimiter = SPACE_DELIMITER;
|
||||
break;
|
||||
case PIPES:
|
||||
delimiter = PIPE_DELIMITER;
|
||||
break;
|
||||
case CSV:
|
||||
delimiter = COMMA_DELIMITER;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
createSeparatedQueryParam(context, value, delimiter)
|
||||
.ifPresent(v -> uriContext.addQueryParameter(key, v));
|
||||
}
|
||||
}
|
||||
|
||||
private void addMultiParameters(
|
||||
ArgumentConversionContext<Object> context, Object value, String key, ClientRequestUriContext uriContext
|
||||
) {
|
||||
if (value instanceof Iterable) {
|
||||
// noinspection unchecked
|
||||
Iterable<?> iterable = (Iterable<?>) value;
|
||||
|
||||
for (Object item : iterable) {
|
||||
convertToString(context, item).ifPresent(v -> uriContext.addQueryParameter(key, v));
|
||||
}
|
||||
} else {
|
||||
convertToString(context, value).ifPresent(v -> uriContext.addQueryParameter(key, v));
|
||||
}
|
||||
}
|
||||
|
||||
private void addDeepObjectParameters(
|
||||
ArgumentConversionContext<Object> context, Object value, String key, ClientRequestUriContext uriContext
|
||||
) {
|
||||
if (value instanceof Iterable) {
|
||||
StringBuilder builder = new StringBuilder(key);
|
||||
|
||||
Iterable<?> iterable = (Iterable<?>) value;
|
||||
|
||||
int i = 0;
|
||||
for (Object item: iterable) {
|
||||
if (item == null) {
|
||||
continue;
|
||||
}
|
||||
String index = String.valueOf(i);
|
||||
|
||||
builder.append('[');
|
||||
builder.append(index);
|
||||
builder.append(']');
|
||||
|
||||
convertToString(context, item).ifPresent(v -> uriContext.addQueryParameter(builder.toString(), v));
|
||||
builder.delete(builder.length() - index.length() - 2, builder.length());
|
||||
i++;
|
||||
}
|
||||
} else if (value != null) {
|
||||
StringBuilder builder = new StringBuilder(key);
|
||||
BeanWrapper<Object> wrapper = BeanWrapper.getWrapper(value);
|
||||
Collection<BeanProperty<Object, Object>> properties = wrapper.getBeanProperties();
|
||||
for (BeanProperty<Object, Object> property: properties) {
|
||||
Object item = property.get(value);
|
||||
if (item == null) {
|
||||
continue;
|
||||
}
|
||||
builder.append('[');
|
||||
builder.append(property.getName());
|
||||
builder.append(']');
|
||||
|
||||
convertToString(context, item).ifPresent(v -> uriContext.addQueryParameter(builder.toString(), v));
|
||||
builder.delete(builder.length() - property.getName().length() - 2, builder.length());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<String> createSeparatedQueryParam(
|
||||
ArgumentConversionContext<Object> context, Object value, Character delimiter
|
||||
) {
|
||||
if (value instanceof Iterable) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
// noinspection unchecked
|
||||
Iterable<?> iterable = (Iterable<?>) value;
|
||||
|
||||
boolean first = true;
|
||||
for (Object item : iterable) {
|
||||
Optional<String> opt = convertToString(context, item);
|
||||
if (opt.isPresent()) {
|
||||
if (!first) {
|
||||
builder.append(delimiter);
|
||||
}
|
||||
first = false;
|
||||
builder.append(opt.get());
|
||||
}
|
||||
}
|
||||
|
||||
return Optional.of(builder.toString());
|
||||
} else {
|
||||
return convertToString(context, value);
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<String> convertToString(ArgumentConversionContext<Object> context, Object value) {
|
||||
return conversionService.convert(value, ConversionContext.STRING.with(context.getAnnotationMetadata()))
|
||||
.filter(StringUtils::isNotEmpty);
|
||||
}
|
||||
}
|
||||
71
modules/openapi-generator/src/main/resources/java-micronaut/client/api.mustache
vendored
Normal file
71
modules/openapi-generator/src/main/resources/java-micronaut/client/api.mustache
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
{{>common/licenseInfo}}
|
||||
package {{package}};
|
||||
|
||||
import io.micronaut.http.annotation.*;
|
||||
import io.micronaut.core.annotation.*;
|
||||
import io.micronaut.http.client.annotation.Client;
|
||||
{{#configureAuth}}
|
||||
import {{invokerPackage}}.auth.Authorization;
|
||||
{{/configureAuth}}
|
||||
import io.micronaut.core.convert.format.Format;
|
||||
import reactor.core.publisher.Mono;
|
||||
{{#imports}}import {{import}};
|
||||
{{/imports}}
|
||||
import javax.annotation.Generated;
|
||||
{{^fullJavaUtil}}
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
{{/fullJavaUtil}}{{#useBeanValidation}}
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.*;
|
||||
{{/useBeanValidation}}
|
||||
|
||||
{{>common/generatedAnnotation}}
|
||||
@Client("${base-path}")
|
||||
public interface {{classname}} {
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
/**
|
||||
{{#summary}}
|
||||
* {{summary}}
|
||||
{{/summary}}
|
||||
{{#notes}}
|
||||
* {{notes}}
|
||||
{{/notes}}
|
||||
{{^summary}}
|
||||
{{^notes}}
|
||||
* {{nickname}}
|
||||
{{/notes}}
|
||||
{{/summary}}
|
||||
*
|
||||
{{#allParams}}
|
||||
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
|
||||
{{/allParams}}
|
||||
{{#returnType}}
|
||||
* @return {{returnType}}
|
||||
{{/returnType}}
|
||||
{{#externalDocs}}
|
||||
* {{description}}
|
||||
* @see <a href="{{url}}">{{summary}} Documentation</a>
|
||||
{{/externalDocs}}
|
||||
*/
|
||||
@{{#lambda.pascalcase}}{{#lambda.lowercase}}{{httpMethod}}{{/lambda.lowercase}}{{/lambda.pascalcase}}(uri="{{{path}}}")
|
||||
{{#vendorExtensions.x-contentType}}
|
||||
@Produces(value={"{{vendorExtensions.x-contentType}}"})
|
||||
{{/vendorExtensions.x-contentType}}
|
||||
@Consumes(value={"{{vendorExtensions.x-accepts}}"})
|
||||
{{!auth methods}}
|
||||
{{#configureAuth}}
|
||||
{{#authMethods}}
|
||||
@Authorization(name="{{{name}}}"{{!scopes}}{{#isOAuth}}, scopes={{openbrace}}{{#scopes}}"{{{scope}}}"{{^-last}}, {{/-last}}{{/scopes}}{{closebrace}}{{/isOAuth}})
|
||||
{{/authMethods}}
|
||||
{{/configureAuth}}
|
||||
{{!the method definition}}
|
||||
{{#returnType}}Mono<{{{returnType}}}>{{/returnType}}{{^returnType}}Mono<Object>{{/returnType}} {{nickname}}({{^allParams}});{{/allParams}}{{#allParams}}
|
||||
{{>client/params/queryParams}}{{>client/params/pathParams}}{{>client/params/headerParams}}{{>client/params/bodyParams}}{{>client/params/formParams}}{{>client/params/cookieParams}}{{^-last}}, {{/-last}}{{#-last}}
|
||||
);{{/-last}}{{/allParams}}
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
{{>licenseInfo}}
|
||||
{{>common/licenseInfo}}
|
||||
package {{invokerPackage}}.auth;
|
||||
|
||||
import io.micronaut.context.annotation.AliasFor;
|
||||
@@ -14,7 +14,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
import javax.annotation.Generated;
|
||||
|
||||
|
||||
{{>generatedAnnotation}}
|
||||
{{>common/generatedAnnotation}}
|
||||
@Documented
|
||||
@Retention(RUNTIME)
|
||||
@Target(METHOD)
|
||||
@@ -1,4 +1,4 @@
|
||||
{{>licenseInfo}}
|
||||
{{>common/licenseInfo}}
|
||||
package {{invokerPackage}}.auth;
|
||||
|
||||
import io.micronaut.aop.MethodInvocationContext;
|
||||
@@ -15,7 +15,7 @@ import java.util.List;
|
||||
import javax.annotation.Generated;
|
||||
|
||||
|
||||
{{>generatedAnnotation}}
|
||||
{{>common/generatedAnnotation}}
|
||||
@Singleton
|
||||
public class AuthorizationBinder implements AnnotatedClientRequestBinder<Authorization> {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{{>licenseInfo}}
|
||||
{{>common/licenseInfo}}
|
||||
package {{invokerPackage}}.auth;
|
||||
|
||||
import io.micronaut.context.BeanContext;
|
||||
@@ -36,7 +36,7 @@ import java.util.stream.Stream;
|
||||
import javax.annotation.Generated;
|
||||
|
||||
|
||||
{{>generatedAnnotation}}
|
||||
{{>common/generatedAnnotation}}
|
||||
@Filter(Filter.MATCH_ALL_PATTERN)
|
||||
public class AuthorizationFilter implements HttpClientFilter {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ClientCredentialsHttpClientFilter.class);
|
||||
@@ -1,4 +1,4 @@
|
||||
{{>licenseInfo}}
|
||||
{{>common/licenseInfo}}
|
||||
package {{invokerPackage}}.auth;
|
||||
|
||||
import io.micronaut.core.bind.annotation.Bindable;
|
||||
@@ -11,7 +11,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
import javax.annotation.Generated;
|
||||
|
||||
|
||||
{{>generatedAnnotation}}
|
||||
{{>common/generatedAnnotation}}
|
||||
@Documented
|
||||
@Retention(RUNTIME)
|
||||
@Target(METHOD)
|
||||
@@ -1,4 +1,4 @@
|
||||
{{>licenseInfo}}
|
||||
{{>common/licenseInfo}}
|
||||
package {{invokerPackage}}.auth.configuration;
|
||||
|
||||
import io.micronaut.context.annotation.ConfigurationInject;
|
||||
@@ -10,7 +10,7 @@ import io.micronaut.http.cookie.Cookie;
|
||||
import javax.annotation.Generated;
|
||||
|
||||
|
||||
{{>generatedAnnotation}}
|
||||
{{>common/generatedAnnotation}}
|
||||
@EachProperty("security.api-key-auth")
|
||||
public class ApiKeyAuthConfiguration implements ConfigurableAuthorization {
|
||||
private final String name;
|
||||
@@ -1,4 +1,4 @@
|
||||
{{>licenseInfo}}
|
||||
{{>common/licenseInfo}}
|
||||
package {{invokerPackage}}.auth.configuration;
|
||||
|
||||
import io.micronaut.core.annotation.NonNull;
|
||||
@@ -6,7 +6,7 @@ import io.micronaut.http.MutableHttpRequest;
|
||||
import javax.annotation.Generated;
|
||||
|
||||
|
||||
{{>generatedAnnotation}}
|
||||
{{>common/generatedAnnotation}}
|
||||
public interface ConfigurableAuthorization {
|
||||
String getName();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{{>licenseInfo}}
|
||||
{{>common/licenseInfo}}
|
||||
package {{invokerPackage}}.auth.configuration;
|
||||
|
||||
import io.micronaut.context.annotation.ConfigurationInject;
|
||||
@@ -9,7 +9,7 @@ import io.micronaut.http.MutableHttpRequest;
|
||||
import javax.annotation.Generated;
|
||||
|
||||
|
||||
{{>generatedAnnotation}}
|
||||
{{>common/generatedAnnotation}}
|
||||
@EachProperty("security.basic-auth")
|
||||
public class HttpBasicAuthConfiguration implements ConfigurableAuthorization {
|
||||
private final String name;
|
||||
@@ -0,0 +1 @@
|
||||
{{#isBodyParam}}@Body {{>common/params/beanValidation}}{{>client/params/type}} {{paramName}}{{/isBodyParam}}
|
||||
@@ -0,0 +1 @@
|
||||
{{#isCookieParam}}@CookieValue(value="{{baseName}}"{{#defaultValue}}, defaultValue="{{defaultValue}}"{{/defaultValue}}) {{>common/params/beanValidation}}{{>client/params/type}} {{paramName}}{{/isCookieParam}}
|
||||
@@ -0,0 +1 @@
|
||||
{{#isFormParam}}{{>common/params/beanValidation}}{{>client/params/type}} {{paramName}}{{/isFormParam}}
|
||||
@@ -0,0 +1 @@
|
||||
{{#isHeaderParam}}@Header(name="{{baseName}}"{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) {{>common/params/beanValidation}}{{>client/params/type}} {{paramName}}{{/isHeaderParam}}
|
||||
@@ -0,0 +1 @@
|
||||
{{#isPathParam}}@PathVariable(name="{{baseName}}"{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) {{>common/params/beanValidation}}{{>client/params/type}} {{paramName}}{{/isPathParam}}
|
||||
@@ -0,0 +1 @@
|
||||
{{#isQueryParam}}@QueryValue(value="{{{baseName}}}"{{!default value}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) {{!validation and type}}{{>common/params/beanValidation}}{{>client/params/type}} {{paramName}}{{/isQueryParam}}
|
||||
@@ -37,7 +37,7 @@ class {{classname}}Spec extends Specification {
|
||||
{{{dataType}}} {{paramName}} = null
|
||||
{{/allParams}}
|
||||
// {{#returnType}}{{{returnType}}} response = {{/returnType}}api.{{operationId}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}).block()
|
||||
// {{#returnType}}Mono<{{{returnType}}}>{{/returnType}}{{^returnType}}Mono<Void>{{/returnType}} asyncResponse = api.{{operationId}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}})
|
||||
// {{#returnType}}Mono<{{{returnType}}}>{{/returnType}}{{^returnType}}Mono<Object>{{/returnType}} asyncResponse = api.{{operationId}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}})
|
||||
|
||||
expect:
|
||||
true
|
||||
@@ -39,7 +39,7 @@ public class {{classname}}Test {
|
||||
{{{dataType}}} {{paramName}} = null;
|
||||
{{/allParams}}
|
||||
// {{#returnType}}{{{returnType}}} response = {{/returnType}}api.{{operationId}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}).block();
|
||||
// {{#returnType}}Mono<{{{returnType}}}>{{/returnType}}{{^returnType}}Mono<Void>{{/returnType}} asyncResponse = api.{{operationId}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}});
|
||||
// {{#returnType}}Mono<{{{returnType}}}>{{/returnType}}{{^returnType}}Mono<Object>{{/returnType}} asyncResponse = api.{{operationId}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}});
|
||||
// TODO: test validations
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
base-path: "{{{basePath}}}"
|
||||
context-path: "{{{contextPath}}}"
|
||||
{{!CLIENT CONFIGURATION}}
|
||||
{{#client}}
|
||||
base-path: "{{{basePath}}}/"
|
||||
context-path: "{{{contextPath}}}/"
|
||||
|
||||
micronaut:
|
||||
application:
|
||||
@@ -51,6 +53,19 @@ micronaut:
|
||||
username:
|
||||
password:
|
||||
{{/isBasic}}{{/authMethods}}{{/configureAuth}}
|
||||
{{/client}}
|
||||
{{!SERVER CONFIGURATION}}
|
||||
{{#server}}
|
||||
context-path: "{{{contextPath}}}/"
|
||||
|
||||
micronaut:
|
||||
application:
|
||||
name: {{artifactId}}
|
||||
server:
|
||||
port: 8080
|
||||
security:
|
||||
# authentication: bearer | cookie | session | idtoken
|
||||
{{/server}}
|
||||
|
||||
jackson:
|
||||
serialization:
|
||||
@@ -2,8 +2,8 @@ plugins {
|
||||
{{#isTestSpock}}
|
||||
id("groovy")
|
||||
{{/isTestSpock}}
|
||||
id("com.github.johnrengelman.shadow") version "7.0.0"
|
||||
id("io.micronaut.application") version "2.0.3"
|
||||
id("com.github.johnrengelman.shadow") version "7.1.1"
|
||||
id("io.micronaut.application") version "3.1.1"
|
||||
}
|
||||
|
||||
version = "{{artifactVersion}}"
|
||||
@@ -30,12 +30,16 @@ micronaut {
|
||||
|
||||
dependencies {
|
||||
annotationProcessor("io.micronaut:micronaut-http-validation")
|
||||
{{#useAuth}}
|
||||
annotationProcessor("io.micronaut.security:micronaut-security-annotations")
|
||||
{{/useAuth}}
|
||||
implementation("io.micronaut:micronaut-http-client")
|
||||
implementation("io.micronaut:micronaut-runtime")
|
||||
implementation("io.micronaut:micronaut-validation")
|
||||
{{#useAuth}}
|
||||
implementation("io.micronaut.security:micronaut-security")
|
||||
implementation("io.micronaut.security:micronaut-security-oauth2")
|
||||
{{/useAuth}}
|
||||
implementation("io.micronaut.reactor:micronaut-reactor")
|
||||
implementation("io.swagger:swagger-annotations:1.5.9")
|
||||
runtimeOnly("ch.qos.logback:logback-classic")
|
||||
@@ -49,3 +53,5 @@ java {
|
||||
sourceCompatibility = JavaVersion.toVersion("1.8")
|
||||
targetCompatibility = JavaVersion.toVersion("1.8")
|
||||
}
|
||||
|
||||
graalvmNative.toolchainDetection = false
|
||||
@@ -0,0 +1 @@
|
||||
micronautVersion={{{micronautVersion}}}
|
||||
@@ -0,0 +1,15 @@
|
||||
<configuration>
|
||||
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<withJansi>false</withJansi>
|
||||
<!-- encoders are assigned the type
|
||||
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
|
||||
<encoder>
|
||||
<pattern>%cyan(%d{HH:mm:ss.SSS}) %gray([%thread]) %highlight(%-5level) %magenta(%logger{36}) - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="info">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
||||
@@ -10,7 +10,7 @@
|
||||
<parent>
|
||||
<groupId>io.micronaut</groupId>
|
||||
<artifactId>micronaut-parent</artifactId>
|
||||
<version>3.0.0-M5</version>
|
||||
<version>{{{micronautVersion}}}</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
@@ -18,7 +18,7 @@
|
||||
<jdk.version>1.8</jdk.version>
|
||||
<!-- If you are building with JDK 9 or higher, you can uncomment the lines below to set the release version -->
|
||||
<!-- <release.version>8</release.version> -->
|
||||
<micronaut.version>3.0.0-M5</micronaut.version>
|
||||
<micronaut.version>{{{micronautVersion}}}</micronaut.version>
|
||||
<exec.mainClass>{{groupId}}.Application</exec.mainClass>
|
||||
<micronaut.runtime>netty</micronaut.runtime>
|
||||
<swagger-annotations-version>1.5.21</swagger-annotations-version>
|
||||
@@ -102,6 +102,7 @@
|
||||
<artifactId>micronaut-reactor</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
{{#useAuth}}
|
||||
<dependency>
|
||||
<groupId>io.micronaut.security</groupId>
|
||||
<artifactId>micronaut-security</artifactId>
|
||||
@@ -112,6 +113,7 @@
|
||||
<artifactId>micronaut-security-oauth2</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
{{/useAuth}}
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
@@ -144,11 +146,13 @@
|
||||
<artifactId>micronaut-http-validation</artifactId>
|
||||
<version>${micronaut.version}</version>
|
||||
</path>
|
||||
{{#useAuth}}
|
||||
<path>
|
||||
<groupId>io.micronaut.security</groupId>
|
||||
<artifactId>micronaut-security-annotations</artifactId>
|
||||
<version>${micronaut.security.version}</version>
|
||||
</path>
|
||||
{{/useAuth}}
|
||||
</annotationProcessorPaths>
|
||||
<compilerArgs>
|
||||
<arg>-Amicronaut.processing.group={{groupId}}</arg>
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
## Enum
|
||||
|
||||
The class is defined in **[{{classname}}.java](../../{{{modelFolder}}}/{{classname}}.java)**
|
||||
|
||||
{{#allowableValues}}{{#enumVars}}
|
||||
* `{{name}}` (value: `{{{value}}}`)
|
||||
{{/enumVars}}{{/allowableValues}}
|
||||
4
modules/openapi-generator/src/main/resources/java-micronaut/common/doc/model_doc.mustache
vendored
Normal file
4
modules/openapi-generator/src/main/resources/java-micronaut/common/doc/model_doc.mustache
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{{#models}}{{#model}}
|
||||
|
||||
{{#isEnum}}{{>common/doc/enum_outer_doc}}{{/isEnum}}{{^isEnum}}{{>common/doc/pojo_doc}}{{/isEnum}}
|
||||
{{/model}}{{/models}}
|
||||
@@ -1,7 +1,10 @@
|
||||
# {{#vendorExtensions.x-is-one-of-interface}}Interface {{/vendorExtensions.x-is-one-of-interface}}{{classname}}
|
||||
{{#description}}
|
||||
|
||||
{{#description}}{{&description}}
|
||||
{{{description}}}
|
||||
{{/description}}
|
||||
|
||||
The class is defined in **[{{classname}}.java](../../{{{modelFolder}}}/{{classname}}.java)**
|
||||
{{^vendorExtensions.x-is-one-of-interface}}
|
||||
|
||||
## Properties
|
||||
@@ -10,30 +13,34 @@ Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
{{#vars}}**{{name}}** | {{#isEnum}}[**{{datatypeWithEnum}}**](#{{datatypeWithEnum}}){{/isEnum}}{{^isEnum}}{{#isContainer}}{{#isArray}}{{#items}}{{#isModel}}[{{/isModel}}{{/items}}`{{baseType}}{{#items}}<{{dataType}}>`{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{#baseType}}{{baseType}}{{/baseType}}.md){{/isModel}}{{/items}}{{/isArray}}{{#isMap}}{{#items}}{{#isModel}}[{{/isModel}}`Map<String, {{dataType}}>`{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{#baseType}}{{baseType}}{{/baseType}}.md){{/isModel}}{{/items}}{{/isMap}}{{/isContainer}}{{^isContainer}}{{#isModel}}[{{/isModel}}`{{dataType}}`{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{#baseType}}{{baseType}}{{/baseType}}.md){{/isModel}}{{/isContainer}}{{/isEnum}} | {{description}} | {{^required}} [optional property]{{/required}}{{#isReadOnly}} [readonly property]{{/isReadOnly}}
|
||||
{{/vars}}
|
||||
{{#vars}}
|
||||
|
||||
{{#vars}}{{#isEnum}}
|
||||
|
||||
## Enum: {{datatypeWithEnum}}
|
||||
{{#isEnum}}
|
||||
## {{datatypeWithEnum}}
|
||||
|
||||
Name | Value
|
||||
---- | -----{{#allowableValues}}{{#enumVars}}
|
||||
{{name}} | `{{value}}`{{/enumVars}}{{/allowableValues}}
|
||||
{{/isEnum}}{{/vars}}
|
||||
|
||||
---- | -----
|
||||
{{#allowableValues}}
|
||||
{{#enumVars}}
|
||||
{{name}} | `{{{value}}}`
|
||||
{{/enumVars}}
|
||||
{{/allowableValues}}
|
||||
{{/isEnum}}
|
||||
{{/vars}}
|
||||
{{#vendorExtensions.x-implements.0}}
|
||||
|
||||
## Implemented Interfaces
|
||||
|
||||
{{#vendorExtensions.x-implements}}
|
||||
{{#vendorExtensions.x-implements}}
|
||||
* `{{{.}}}`
|
||||
{{/vendorExtensions.x-implements}}
|
||||
{{/vendorExtensions.x-implements}}
|
||||
{{/vendorExtensions.x-implements.0}}
|
||||
{{/vendorExtensions.x-is-one-of-interface}}
|
||||
|
||||
{{#vendorExtensions.x-is-one-of-interface}}
|
||||
|
||||
## Implementing Classes
|
||||
|
||||
{{#oneOf}}
|
||||
{{#oneOf}}
|
||||
* `{{{.}}}`
|
||||
{{/oneOf}}
|
||||
{{/oneOf}}
|
||||
{{/vendorExtensions.x-is-one-of-interface}}
|
||||
52
modules/openapi-generator/src/main/resources/java-micronaut/common/model/beanValidation.mustache
vendored
Normal file
52
modules/openapi-generator/src/main/resources/java-micronaut/common/model/beanValidation.mustache
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
{{#useBeanValidation}}{{!
|
||||
validate all pojos and enums
|
||||
}}{{^isContainer}}{{#isModel}} @Valid
|
||||
{{/isModel}}{{/isContainer}}{{!
|
||||
nullable & nonnull
|
||||
}}{{#required}}{{#isNullable}} @Nullable
|
||||
{{/isNullable}}{{^isNullable}} @NotNull
|
||||
{{/isNullable}}{{/required}}{{^required}} @Nullable
|
||||
{{/required}}{{!
|
||||
pattern
|
||||
}}{{#pattern}}{{^isByteArray}} @Pattern(regexp="{{{pattern}}}")
|
||||
{{/isByteArray}}{{/pattern}}{{!
|
||||
both minLength && maxLength
|
||||
}}{{#minLength}}{{#maxLength}} @Size(min={{minLength}}, max={{maxLength}})
|
||||
{{/maxLength}}{{/minLength}}{{!
|
||||
just minLength
|
||||
}}{{#minLength}}{{^maxLength}} @Size(min={{minLength}})
|
||||
{{/maxLength}}{{/minLength}}{{!
|
||||
just maxLength
|
||||
}}{{^minLength}}{{#maxLength}} @Size(max={{maxLength}})
|
||||
{{/maxLength}}{{/minLength}}{{!
|
||||
@Size: both minItems && maxItems
|
||||
}}{{#minItems}}{{#maxItems}} @Size(min={{minItems}}, max={{maxItems}})
|
||||
{{/maxItems}}{{/minItems}}{{!
|
||||
@Size: just minItems
|
||||
}}{{#minItems}}{{^maxItems}} @Size(min={{minItems}})
|
||||
{{/maxItems}}{{/minItems}}{{!
|
||||
@Size: just maxItems
|
||||
}}{{^minItems}}{{#maxItems}} @Size(max={{maxItems}})
|
||||
{{/maxItems}}{{/minItems}}{{!
|
||||
@Email
|
||||
}}{{#isEmail}} @Email
|
||||
{{/isEmail}}{{!
|
||||
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 for decimal value
|
||||
}}{{#minimum}} @DecimalMin({{#exclusiveMinimum}}value={{/exclusiveMinimum}}"{{minimum}}"{{#exclusiveMinimum}}, inclusive=false{{/exclusiveMinimum}})
|
||||
{{/minimum}}{{!
|
||||
maximal for decimal value
|
||||
}}{{#maximum}} @DecimalMax({{#exclusiveMaximum}}value={{/exclusiveMaximum}}"{{maximum}}"{{#exclusiveMaximum}}, inclusive=false{{/exclusiveMaximum}})
|
||||
{{/maximum}}{{!
|
||||
close decimal values
|
||||
}}{{/isLong}}{{/isInteger}}{{/useBeanValidation}}
|
||||
@@ -0,0 +1,26 @@
|
||||
{{!
|
||||
If this is map and items are nullable, make sure that nulls are included.
|
||||
To determine what JsonInclude.Include method to use, consider the following:
|
||||
* If the field is required, always include it, even if it is null.
|
||||
* Else use custom behaviour, IOW use whatever is defined on the object mapper
|
||||
}}
|
||||
@JsonProperty(JSON_PROPERTY_{{nameInSnakeCase}})
|
||||
@JsonInclude({{#isMap}}{{#items.isNullable}}content = JsonInclude.Include.ALWAYS, {{/items.isNullable}}{{/isMap}}value = JsonInclude.Include.{{#required}}ALWAYS{{/required}}{{^required}}USE_DEFAULTS{{/required}})
|
||||
{{#withXml}}
|
||||
{{^isContainer}}
|
||||
@JacksonXmlProperty({{#isXmlAttribute}}isAttribute = true, {{/isXmlAttribute}}{{#xmlNamespace}}namespace="{{xmlNamespace}}", {{/xmlNamespace}}localName = "{{#xmlName}}{{xmlName}}{{/xmlName}}{{^xmlName}}{{baseName}}{{/xmlName}}")
|
||||
@JacksonXmlProperty({{#isXmlAttribute}}isAttribute = true, {{/isXmlAttribute}}{{#xmlNamespace}}namespace="{{xmlNamespace}}", {{/xmlNamespace}}localName = "{{#xmlName}}{{xmlName}}{{/xmlName}}{{^xmlName}}{{baseName}}{{/xmlName}}")
|
||||
{{/isContainer}}
|
||||
{{#isContainer}}
|
||||
{{#isXmlWrapped}}
|
||||
// items.xmlName={{items.xmlName}}
|
||||
@JacksonXmlElementWrapper(useWrapping = {{isXmlWrapped}}, {{#xmlNamespace}}namespace="{{xmlNamespace}}", {{/xmlNamespace}}localName = "{{#items.xmlName}}{{items.xmlName}}{{/items.xmlName}}{{^items.xmlName}}{{items.baseName}}{{/items.xmlName}}")
|
||||
{{/isXmlWrapped}}
|
||||
{{/isContainer}}
|
||||
{{/withXml}}
|
||||
{{#isDateTime}}
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXX")
|
||||
{{/isDateTime}}
|
||||
{{#isDate}}
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
|
||||
{{/isDate}}
|
||||
@@ -1,4 +1,4 @@
|
||||
{{>licenseInfo}}
|
||||
{{>common/licenseInfo}}
|
||||
package {{package}};
|
||||
|
||||
{{#useReflectionEqualsHashCode}}
|
||||
@@ -34,14 +34,14 @@ import javax.annotation.Generated;
|
||||
{{#models}}
|
||||
{{#model}}
|
||||
{{#isEnum}}
|
||||
{{>model/modelEnum}}
|
||||
{{>common/model/modelEnum}}
|
||||
{{/isEnum}}
|
||||
{{^isEnum}}
|
||||
{{#vendorExtensions.x-is-one-of-interface}}
|
||||
{{>model/oneof_interface}}
|
||||
{{>common/model/oneof_interface}}
|
||||
{{/vendorExtensions.x-is-one-of-interface}}
|
||||
{{^vendorExtensions.x-is-one-of-interface}}
|
||||
{{>model/pojo}}
|
||||
{{>common/model/pojo}}
|
||||
{{/vendorExtensions.x-is-one-of-interface}}
|
||||
{{/isEnum}}
|
||||
{{/model}}
|
||||
@@ -1,14 +1,15 @@
|
||||
/**
|
||||
* {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{description}}{{/description}}
|
||||
*/
|
||||
{{#withXml}}
|
||||
@XmlType(name="{{datatypeWithEnum}}")
|
||||
@XmlEnum({{dataType}}.class)
|
||||
{{/withXml}}
|
||||
{{#jackson}}
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
{{/jackson}}
|
||||
|
||||
/**
|
||||
* {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{description}}{{/description}}
|
||||
*/
|
||||
{{#additionalEnumTypeAnnotations}}
|
||||
{{{.}}}
|
||||
{{/additionalEnumTypeAnnotations}}
|
||||
public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} {
|
||||
{{{.}}}
|
||||
{{/additionalEnumTypeAnnotations}}{{#useBeanValidation}}@Introspected
|
||||
{{/useBeanValidation}}public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} {
|
||||
{{#allowableValues}}
|
||||
{{#enumVars}}
|
||||
{{#enumDescription}}
|
||||
@@ -25,36 +26,36 @@
|
||||
|
||||
private {{{dataType}}} value;
|
||||
|
||||
{{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}({{{dataType}}} value) {
|
||||
this.value = value;
|
||||
{{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}({{{dataType}}} value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
{{#jackson}}
|
||||
@JsonValue
|
||||
{{/jackson}}
|
||||
public {{{dataType}}} getValue() {
|
||||
return value;
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.valueOf(value);
|
||||
return String.valueOf(value);
|
||||
}
|
||||
|
||||
{{#jackson}}
|
||||
@JsonCreator
|
||||
{{/jackson}}
|
||||
public static {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} fromValue({{{dataType}}} value) {
|
||||
for ({{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} b : {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.values()) {
|
||||
if (b.value.equals(value)) {
|
||||
return b;
|
||||
for ({{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} b : {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.values()) {
|
||||
if (b.value.equals(value)) {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
}
|
||||
{{#isNullable}}
|
||||
return null;
|
||||
return null;
|
||||
{{/isNullable}}
|
||||
{{^isNullable}}
|
||||
throw new IllegalArgumentException("Unexpected value '" + value + "'");
|
||||
throw new IllegalArgumentException("Unexpected value '" + value + "'");
|
||||
{{/isNullable}}
|
||||
}
|
||||
}
|
||||
}
|
||||
60
modules/openapi-generator/src/main/resources/java-micronaut/common/model/modelInnerEnum.mustache
vendored
Normal file
60
modules/openapi-generator/src/main/resources/java-micronaut/common/model/modelInnerEnum.mustache
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{description}}{{/description}}
|
||||
*/
|
||||
{{#withXml}}
|
||||
@XmlType(name="{{datatypeWithEnum}}")
|
||||
@XmlEnum({{dataType}}.class)
|
||||
{{/withXml}}
|
||||
{{#additionalEnumTypeAnnotations}}
|
||||
{{{.}}}
|
||||
{{/additionalEnumTypeAnnotations}}
|
||||
public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} {
|
||||
{{#allowableValues}}
|
||||
{{#enumVars}}
|
||||
{{#enumDescription}}
|
||||
/**
|
||||
* {{enumDescription}}
|
||||
*/
|
||||
{{/enumDescription}}
|
||||
{{#withXml}}
|
||||
@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
|
||||
{{/withXml}}
|
||||
{{{name}}}({{{value}}}){{^-last}},{{/-last}}{{#-last}};{{/-last}}
|
||||
{{/enumVars}}
|
||||
{{/allowableValues}}
|
||||
|
||||
private {{{dataType}}} value;
|
||||
|
||||
{{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}({{{dataType}}} value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
{{#jackson}}
|
||||
@JsonValue
|
||||
{{/jackson}}
|
||||
public {{{dataType}}} getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.valueOf(value);
|
||||
}
|
||||
|
||||
{{#jackson}}
|
||||
@JsonCreator
|
||||
{{/jackson}}
|
||||
public static {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} fromValue({{{dataType}}} value) {
|
||||
for ({{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} b : {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.values()) {
|
||||
if (b.value.equals(value)) {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
{{#isNullable}}
|
||||
return null;
|
||||
{{/isNullable}}
|
||||
{{^isNullable}}
|
||||
throw new IllegalArgumentException("Unexpected value '" + value + "'");
|
||||
{{/isNullable}}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{{#additionalModelTypeAnnotations}}
|
||||
{{{.}}}
|
||||
{{/additionalModelTypeAnnotations}}
|
||||
{{>generatedAnnotation}}{{>model/typeInfoAnnotation}}{{>model/xmlAnnotation}}
|
||||
{{>common/generatedAnnotation}}{{>common/model/typeInfoAnnotation}}{{>common/model/xmlAnnotation}}
|
||||
public interface {{classname}} {{#vendorExtensions.x-implements}}{{#-first}}extends {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{/vendorExtensions.x-implements}} {
|
||||
{{#discriminator}}
|
||||
public {{propertyType}} {{propertyGetter}}();
|
||||
342
modules/openapi-generator/src/main/resources/java-micronaut/common/model/pojo.mustache
vendored
Normal file
342
modules/openapi-generator/src/main/resources/java-micronaut/common/model/pojo.mustache
vendored
Normal file
@@ -0,0 +1,342 @@
|
||||
/**
|
||||
* {{#description}}{{.}}{{/description}}{{^description}}{{classname}}{{/description}}
|
||||
*/
|
||||
{{#description}}
|
||||
@ApiModel(description = "{{{description}}}")
|
||||
{{/description}}
|
||||
{{#jackson}}
|
||||
@JsonPropertyOrder({
|
||||
{{#vars}}
|
||||
{{classname}}.JSON_PROPERTY_{{nameInSnakeCase}}{{^-last}},{{/-last}}
|
||||
{{/vars}}
|
||||
})
|
||||
@JsonTypeName("{{name}}")
|
||||
{{/jackson}}
|
||||
{{#additionalModelTypeAnnotations}}
|
||||
{{{.}}}
|
||||
{{/additionalModelTypeAnnotations}}
|
||||
{{>common/generatedAnnotation}}{{#discriminator}}{{>common/model/typeInfoAnnotation}}{{/discriminator}}{{>common/model/xmlAnnotation}}{{#useBeanValidation}}
|
||||
@Introspected
|
||||
{{/useBeanValidation}}{{!
|
||||
Declare the class with extends and implements
|
||||
}}public class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{{#vendorExtensions.x-implements}}{{#-first}}implements {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{#-last}} {{/-last}}{{/vendorExtensions.x-implements}}{
|
||||
{{#serializableModel}}
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
{{/serializableModel}}
|
||||
{{#vars}}
|
||||
{{#isEnum}}
|
||||
{{^isContainer}}
|
||||
{{>common/model/modelInnerEnum}}
|
||||
{{/isContainer}}
|
||||
{{#isContainer}}
|
||||
{{#mostInnerItems}}
|
||||
{{>common/model/modelInnerEnum}}
|
||||
{{/mostInnerItems}}
|
||||
{{/isContainer}}
|
||||
{{/isEnum}}
|
||||
public static final String JSON_PROPERTY_{{nameInSnakeCase}} = "{{baseName}}";
|
||||
{{#withXml}}
|
||||
{{#isXmlAttribute}}
|
||||
@XmlAttribute(name = "{{#xmlName}}{{xmlName}}{{/xmlName}}{{^xmlName}}{{baseName}}{{/xmlName}}"
|
||||
{{/isXmlAttribute}}
|
||||
{{^isXmlAttribute}}
|
||||
{{^isContainer}}
|
||||
@XmlElement({{#xmlNamespace}}namespace="{{xmlNamespace}}", {{/xmlNamespace}}name = "{{#xmlName}}{{xmlName}}{{/xmlName}}{{^xmlName}}{{baseName}}{{/xmlName}}")
|
||||
{{/isContainer}}
|
||||
{{#isContainer}}
|
||||
// Is a container wrapped={{isXmlWrapped}}
|
||||
{{#items}}
|
||||
// items.name={{name}} items.baseName={{baseName}} items.xmlName={{xmlName}} items.xmlNamespace={{xmlNamespace}}
|
||||
// items.example={{example}} items.type={{dataType}}
|
||||
@XmlElement({{#xmlNamespace}}namespace="{{xmlNamespace}}", {{/xmlNamespace}}name = "{{#xmlName}}{{xmlName}}{{/xmlName}}{{^xmlName}}{{baseName}}{{/xmlName}}")
|
||||
{{/items}}
|
||||
{{#isXmlWrapped}}
|
||||
@XmlElementWrapper({{#xmlNamespace}}namespace="{{xmlNamespace}}", {{/xmlNamespace}}name = "{{#xmlName}}{{xmlName}}{{/xmlName}}{{^xmlName}}{{baseName}}{{/xmlName}}")
|
||||
{{/isXmlWrapped}}
|
||||
{{/isContainer}}
|
||||
{{/isXmlAttribute}}
|
||||
{{/withXml}}
|
||||
{{#vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{#isContainer}}
|
||||
private JsonNullable<{{{datatypeWithEnum}}}> {{name}} = JsonNullable.<{{{datatypeWithEnum}}}>undefined();
|
||||
{{/isContainer}}
|
||||
{{^isContainer}}
|
||||
private JsonNullable<{{{datatypeWithEnum}}}> {{name}} = JsonNullable.<{{{datatypeWithEnum}}}>{{#defaultValue}}of({{{.}}}){{/defaultValue}}{{^defaultValue}}undefined(){{/defaultValue}};
|
||||
{{/isContainer}}
|
||||
{{/vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{^vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{#isContainer}}
|
||||
private {{{datatypeWithEnum}}} {{name}}{{#required}}{{#defaultValue}} = {{{.}}}{{/defaultValue}}{{/required}}{{^required}} = null{{/required}};
|
||||
{{/isContainer}}
|
||||
{{^isContainer}}
|
||||
{{#isDiscriminator}}protected{{/isDiscriminator}}{{^isDiscriminator}}private{{/isDiscriminator}} {{{datatypeWithEnum}}} {{name}}{{#defaultValue}} = {{{.}}}{{/defaultValue}};
|
||||
{{/isContainer}}
|
||||
{{/vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
|
||||
{{/vars}}
|
||||
{{#requiredPropertiesInConstructor}}
|
||||
public {{classname}}({{#requiredVars}}{{{datatypeWithEnum}}} {{name}}{{^-last}}, {{/-last}}{{/requiredVars}}) {
|
||||
{{#parent}}
|
||||
super({{#vendorExtensions.requiredParentVars}}{{name}}{{^-last}}, {{/-last}}{{/vendorExtensions.requiredParentVars}});
|
||||
{{/parent}}
|
||||
{{#vendorExtensions.requiredVars}}
|
||||
this.{{name}} = {{name}};
|
||||
{{/vendorExtensions.requiredVars}}
|
||||
}
|
||||
|
||||
{{/requiredPropertiesInConstructor}}
|
||||
{{^requiredPropertiesInConstructor}}
|
||||
public {{classname}}() {
|
||||
{{#parent}}
|
||||
super();
|
||||
{{/parent}}
|
||||
}
|
||||
{{/requiredPropertiesInConstructor}}
|
||||
{{#vars}}
|
||||
{{^isReadOnly}}
|
||||
public {{classname}} {{name}}({{{datatypeWithEnum}}} {{name}}) {
|
||||
{{#vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
this.{{name}} = JsonNullable.<{{{datatypeWithEnum}}}>of({{name}});
|
||||
{{/vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{^vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
this.{{name}} = {{name}};
|
||||
{{/vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
return this;
|
||||
}
|
||||
|
||||
{{#isArray}}
|
||||
public {{classname}} add{{nameInCamelCase}}Item({{{items.datatypeWithEnum}}} {{name}}Item) {
|
||||
{{#vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
if (this.{{name}} == null || !this.{{name}}.isPresent()) {
|
||||
this.{{name}} = JsonNullable.<{{{datatypeWithEnum}}}>of({{{defaultValue}}});
|
||||
}
|
||||
try {
|
||||
this.{{name}}.get().add({{name}}Item);
|
||||
} catch (java.util.NoSuchElementException e) {
|
||||
// this can never happen, as we make sure above that the value is present
|
||||
}
|
||||
return this;
|
||||
{{/vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{^vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{^required}}
|
||||
if (this.{{name}} == null) {
|
||||
this.{{name}} = {{{defaultValue}}};
|
||||
}
|
||||
{{/required}}
|
||||
this.{{name}}.add({{name}}Item);
|
||||
return this;
|
||||
{{/vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
}
|
||||
|
||||
{{/isArray}}
|
||||
{{#isMap}}
|
||||
public {{classname}} put{{nameInCamelCase}}Item(String key, {{{items.datatypeWithEnum}}} {{name}}Item) {
|
||||
{{#vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
if (this.{{name}} == null || !this.{{name}}.isPresent()) {
|
||||
this.{{name}} = JsonNullable.<{{{datatypeWithEnum}}}>of({{{defaultValue}}});
|
||||
}
|
||||
try {
|
||||
this.{{name}}.get().put(key, {{name}}Item);
|
||||
} catch (java.util.NoSuchElementException e) {
|
||||
// this can never happen, as we make sure above that the value is present
|
||||
}
|
||||
return this;
|
||||
{{/vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{^vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{^required}}
|
||||
if (this.{{name}} == null) {
|
||||
this.{{name}} = {{{defaultValue}}};
|
||||
}
|
||||
{{/required}}
|
||||
this.{{name}}.put(key, {{name}}Item);
|
||||
return this;
|
||||
{{/vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
}
|
||||
|
||||
{{/isMap}}
|
||||
{{/isReadOnly}}
|
||||
/**
|
||||
{{#description}}
|
||||
* {{description}}
|
||||
{{/description}}
|
||||
{{^description}}
|
||||
* Get {{name}}
|
||||
{{/description}}
|
||||
{{#minimum}}
|
||||
* minimum: {{minimum}}
|
||||
{{/minimum}}
|
||||
{{#maximum}}
|
||||
* maximum: {{maximum}}
|
||||
{{/maximum}}
|
||||
* @return {{name}}
|
||||
**/
|
||||
{{>common/model/beanValidation}} @ApiModelProperty({{#example}}example = "{{{example}}}", {{/example}}{{#required}}required = {{required}}, {{/required}}value = "{{{description}}}")
|
||||
{{#vendorExtensions.x-extra-annotation}}
|
||||
{{{vendorExtensions.x-extra-annotation}}}
|
||||
{{/vendorExtensions.x-extra-annotation}}
|
||||
{{#vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{!unannotated, Jackson would pick this up automatically and add it *in addition* to the _JsonNullable getter field}} @JsonIgnore
|
||||
{{/vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{^vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{#jackson}}
|
||||
{{>common/model/jackson_annotations}}{{/jackson}}{{/vendorExtensions.x-is-jackson-optional-nullable}} public {{{datatypeWithEnum}}} {{getter}}() {
|
||||
{{#vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{#isReadOnly}}
|
||||
{{! A readonly attribute doesn't have setter => jackson will set null directly if explicitly returned by API, so make sure we have an empty JsonNullable}} if ({{name}} == null) {
|
||||
{{name}} = JsonNullable.<{{{datatypeWithEnum}}}>{{#defaultValue}}of({{{.}}}){{/defaultValue}}{{^defaultValue}}undefined(){{/defaultValue}};
|
||||
}
|
||||
{{/isReadOnly}}
|
||||
return {{name}}.orElse(null);
|
||||
{{/vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{^vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
return {{name}};
|
||||
{{/vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
}
|
||||
|
||||
{{#vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{>common/model/jackson_annotations}}
|
||||
public JsonNullable<{{{datatypeWithEnum}}}> {{getter}}_JsonNullable() {
|
||||
return {{name}};
|
||||
}
|
||||
|
||||
@JsonProperty(JSON_PROPERTY_{{nameInSnakeCase}})
|
||||
{{#isReadOnly}}private{{/isReadOnly}}{{^isReadOnly}}public{{/isReadOnly}} void {{setter}}_JsonNullable(JsonNullable<{{{datatypeWithEnum}}}> {{name}}) {
|
||||
{{! For getters/setters that have name differing from attribute name, we must include setter (albeit private) for jackson to be able to set the attribute}} this.{{name}} = {{name}};
|
||||
}
|
||||
|
||||
{{/vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{^isReadOnly}}
|
||||
{{#jackson}}
|
||||
{{^vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{>common/model/jackson_annotations}}{{/vendorExtensions.x-is-jackson-optional-nullable}}{{/jackson}}{{#vendorExtensions.x-setter-extra-annotation}} {{{vendorExtensions.x-setter-extra-annotation}}}
|
||||
{{/vendorExtensions.x-setter-extra-annotation}} public void {{setter}}({{{datatypeWithEnum}}} {{name}}) {
|
||||
{{#vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
this.{{name}} = JsonNullable.<{{{datatypeWithEnum}}}>of({{name}});
|
||||
{{/vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{^vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
this.{{name}} = {{name}};
|
||||
{{/vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
}
|
||||
|
||||
{{/isReadOnly}}
|
||||
{{/vars}}
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
{{#useReflectionEqualsHashCode}}
|
||||
return EqualsBuilder.reflectionEquals(this, o, false, null, true);
|
||||
{{/useReflectionEqualsHashCode}}
|
||||
{{^useReflectionEqualsHashCode}}
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
{{#hasVars}}
|
||||
{{classname}} {{classVarName}} = ({{classname}}) o;
|
||||
return {{#vars}}{{#isByteArray}}Arrays{{/isByteArray}}{{^isByteArray}}Objects{{/isByteArray}}.equals(this.{{name}}, {{classVarName}}.{{name}}){{^-last}} &&
|
||||
{{/-last}}{{/vars}}{{#parent}} &&
|
||||
super.equals(o){{/parent}};
|
||||
{{/hasVars}}
|
||||
{{^hasVars}}
|
||||
return {{#parent}}super.equals(o){{/parent}}{{^parent}}true{{/parent}};
|
||||
{{/hasVars}}
|
||||
{{/useReflectionEqualsHashCode}}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
{{#useReflectionEqualsHashCode}}
|
||||
return HashCodeBuilder.reflectionHashCode(this);
|
||||
{{/useReflectionEqualsHashCode}}
|
||||
{{^useReflectionEqualsHashCode}}
|
||||
return Objects.hash({{#vars}}{{^isByteArray}}{{name}}{{/isByteArray}}{{#isByteArray}}Arrays.hashCode({{name}}){{/isByteArray}}{{^-last}}, {{/-last}}{{/vars}}{{#parent}}{{#hasVars}}, {{/hasVars}}super.hashCode(){{/parent}});
|
||||
{{/useReflectionEqualsHashCode}}
|
||||
}
|
||||
|
||||
@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{{#jsonb}} static{{/jsonb}} String toIndentedString(Object o) {
|
||||
if (o == null) {
|
||||
return "null";
|
||||
}
|
||||
return o.toString().replace("\n", "\n ");
|
||||
}
|
||||
|
||||
{{#parcelableModel}}
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
{{#model}}
|
||||
{{#isArray}}
|
||||
out.writeList(this);
|
||||
{{/isArray}}
|
||||
{{^isArray}}
|
||||
{{#parent}}
|
||||
super.writeToParcel(out, flags);
|
||||
{{/parent}}
|
||||
{{#vars}}
|
||||
out.writeValue({{name}});
|
||||
{{/vars}}
|
||||
{{/isArray}}
|
||||
{{/model}}
|
||||
}
|
||||
|
||||
{{classname}}(Parcel in) {
|
||||
{{#isArray}}
|
||||
in.readTypedList(this, {{arrayModelType}}.CREATOR);
|
||||
{{/isArray}}
|
||||
{{^isArray}}
|
||||
{{#parent}}
|
||||
super(in);
|
||||
{{/parent}}
|
||||
{{#vars}}
|
||||
{{#isPrimitiveType}}
|
||||
{{name}} = ({{{datatypeWithEnum}}})in.readValue(null);
|
||||
{{/isPrimitiveType}}
|
||||
{{^isPrimitiveType}}
|
||||
{{name}} = ({{{datatypeWithEnum}}})in.readValue({{complexType}}.class.getClassLoader());
|
||||
{{/isPrimitiveType}}
|
||||
{{/vars}}
|
||||
{{/isArray}}
|
||||
}
|
||||
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<{{classname}}> CREATOR = new Parcelable.Creator<{{classname}}>() {
|
||||
public {{classname}} createFromParcel(Parcel in) {
|
||||
{{#model}}
|
||||
{{#isArray}}
|
||||
{{classname}} result = new {{classname}}();
|
||||
result.addAll(in.readArrayList({{arrayModelType}}.class.getClassLoader()));
|
||||
return result;
|
||||
{{/isArray}}
|
||||
{{^isArray}}
|
||||
return new {{classname}}(in);
|
||||
{{/isArray}}
|
||||
{{/model}}
|
||||
}
|
||||
|
||||
public {{classname}}[] newArray(int size) {
|
||||
return new {{classname}}[size];
|
||||
}
|
||||
};
|
||||
{{/parcelableModel}}
|
||||
}
|
||||
@@ -1,8 +1,11 @@
|
||||
{{#useBeanValidation}}{{!
|
||||
{{!First handle the nullable - it should be present unless otherwise specified}}
|
||||
{{#isNullable}}@Nullable {{/isNullable}}{{^isNullable}}{{^required}}@Nullable {{/required}}{{/isNullable}}{{!
|
||||
All the validation
|
||||
}}{{#useBeanValidation}}{{!
|
||||
nullable overrides required
|
||||
}}{{^isNullable}}{{#required}}@NotNull {{/required}}{{/isNullable}}{{!
|
||||
validate all pojos and enums
|
||||
}}{{^isContainer}}{{#isModel}}@Valid {{/isModel}}{{/isContainer}}{{!
|
||||
nullable & nonnull
|
||||
}}{{#required}}@NotNull {{/required}}{{#isNullable}}@Nullable {{/isNullable}}{{!
|
||||
pattern
|
||||
}}{{#pattern}}{{^isByteArray}}@Pattern(regexp="{{{pattern}}}") {{/isByteArray}}{{/pattern}}{{!
|
||||
both minLength && maxLength
|
||||
@@ -18,7 +21,7 @@ just maxLength
|
||||
@Size: just maxItems
|
||||
}}{{^minItems}}{{#maxItems}}@Size(max={{maxItems}}) {{/maxItems}}{{/minItems}}{{!
|
||||
@Email
|
||||
}}{{#isEmail}}@Email{{/isEmail}}{{!
|
||||
}}{{#isEmail}}@Email {{/isEmail}}{{!
|
||||
check for integer or long / all others=decimal type with @Decimal*
|
||||
isInteger set
|
||||
}}{{#isInteger}}{{#minimum}}@Min({{minimum}}) {{/minimum}}{{#maximum}}@Max({{maximum}}) {{/maximum}}{{/isInteger}}{{!
|
||||
@@ -0,0 +1,46 @@
|
||||
package {{package}}
|
||||
|
||||
{{#imports}}import {{import}}
|
||||
{{/imports}}
|
||||
import io.micronaut.test.extensions.spock.annotation.MicronautTest
|
||||
import spock.lang.Specification
|
||||
import jakarta.inject.Inject
|
||||
{{#fullJavaUtil}}
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
{{/fullJavaUtil}}
|
||||
|
||||
/**
|
||||
* Model tests for {{classname}}
|
||||
*/
|
||||
@MicronautTest
|
||||
public class {{classname}}Spec extends Specification {
|
||||
{{#models}}
|
||||
{{#model}}
|
||||
{{^vendorExtensions.x-is-one-of-interface}}
|
||||
{{^isEnum}}
|
||||
private final {{classname}} model = null
|
||||
|
||||
{{/isEnum}}
|
||||
/**
|
||||
* Model tests for {{classname}}
|
||||
*/
|
||||
void '{{classname}} test'() {
|
||||
// TODO: test {{classname}}
|
||||
}
|
||||
|
||||
{{#allVars}}
|
||||
/**
|
||||
* Test the property '{{name}}'
|
||||
*/
|
||||
void '{{classname}} property {{name}} test'() {
|
||||
// TODO: test {{name}} property of {{classname}}
|
||||
}
|
||||
|
||||
{{/allVars}}
|
||||
{{/vendorExtensions.x-is-one-of-interface}}
|
||||
{{/model}}
|
||||
{{/models}}
|
||||
}
|
||||
49
modules/openapi-generator/src/main/resources/java-micronaut/common/test/model_test.mustache
vendored
Normal file
49
modules/openapi-generator/src/main/resources/java-micronaut/common/test/model_test.mustache
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
package {{package}};
|
||||
|
||||
{{#imports}}import {{import}};
|
||||
{{/imports}}
|
||||
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
|
||||
{{#fullJavaUtil}}
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
{{/fullJavaUtil}}
|
||||
|
||||
/**
|
||||
* Model tests for {{classname}}
|
||||
*/
|
||||
@MicronautTest
|
||||
public class {{classname}}Test {
|
||||
{{#models}}
|
||||
{{#model}}
|
||||
{{^vendorExtensions.x-is-one-of-interface}}
|
||||
{{^isEnum}}
|
||||
private final {{classname}} model = null;
|
||||
|
||||
{{/isEnum}}
|
||||
/**
|
||||
* Model tests for {{classname}}
|
||||
*/
|
||||
@Test
|
||||
public void test{{classname}}() {
|
||||
// TODO: test {{classname}}
|
||||
}
|
||||
|
||||
{{#allVars}}
|
||||
/**
|
||||
* Test the property '{{name}}'
|
||||
*/
|
||||
@Test
|
||||
public void {{name}}Test() {
|
||||
// TODO: test {{name}}
|
||||
}
|
||||
|
||||
{{/allVars}}
|
||||
{{/vendorExtensions.x-is-one-of-interface}}
|
||||
{{/model}}
|
||||
{{/models}}
|
||||
}
|
||||
129
modules/openapi-generator/src/main/resources/java-micronaut/server/controller.mustache
vendored
Normal file
129
modules/openapi-generator/src/main/resources/java-micronaut/server/controller.mustache
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
{{>common/licenseInfo}}
|
||||
package {{apiPackage}};
|
||||
|
||||
import io.micronaut.http.annotation.*;
|
||||
import io.micronaut.core.annotation.Nullable;
|
||||
import io.micronaut.core.convert.format.Format;
|
||||
{{#useAuth}}
|
||||
import io.micronaut.security.annotation.Secured;
|
||||
import io.micronaut.security.rules.SecurityRule;
|
||||
{{/useAuth}}
|
||||
import reactor.core.publisher.Mono;
|
||||
{{#imports}}
|
||||
import {{import}};
|
||||
{{/imports}}
|
||||
import javax.annotation.Generated;
|
||||
{{^fullJavaUtil}}
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
{{#generateControllerFromExamples}}
|
||||
import java.util.Arrays;
|
||||
{{/generateControllerFromExamples}}
|
||||
{{/fullJavaUtil}}
|
||||
{{#useBeanValidation}}
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.*;
|
||||
{{/useBeanValidation}}
|
||||
import io.swagger.annotations.*;
|
||||
|
||||
{{>common/generatedAnnotation}}
|
||||
{{^generateControllerAsAbstract}}
|
||||
@Controller("${context-path}")
|
||||
{{/generateControllerAsAbstract}}
|
||||
public {{#generateControllerAsAbstract}}abstract {{/generateControllerAsAbstract}}class {{classname}} {
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
/**
|
||||
{{#summary}}
|
||||
* {{summary}}
|
||||
{{/summary}}
|
||||
{{#notes}}
|
||||
* {{notes}}
|
||||
{{/notes}}
|
||||
{{^summary}}
|
||||
{{^notes}}
|
||||
* {{nickname}}
|
||||
{{/notes}}
|
||||
{{/summary}}
|
||||
*
|
||||
{{#allParams}}
|
||||
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
|
||||
{{/allParams}}
|
||||
{{#returnType}}
|
||||
* @return {{returnType}}
|
||||
{{/returnType}}
|
||||
{{#externalDocs}}
|
||||
* {{description}}
|
||||
* @see <a href="{{url}}">{{summary}} Documentation</a>
|
||||
{{/externalDocs}}
|
||||
*/
|
||||
{{!openapi annotations for info}}
|
||||
@ApiOperation(
|
||||
value = "{{{summary}}}",
|
||||
nickname = "{{{operationId}}}"{{#notes}},
|
||||
notes = "{{{notes}}}"{{/notes}}{{#returnBaseType}},
|
||||
response = {{{returnBaseType}}}.class{{/returnBaseType}}{{#returnContainer}},
|
||||
responseContainer = "{{{returnContainer}}}"{{/returnContainer}},
|
||||
authorizations = {{openbrace}}{{#hasAuthMethods}}
|
||||
{{#authMethods}}
|
||||
{{#isOAuth}}
|
||||
@Authorization(value = "{{name}}"{{#scopes}}{{#-first}}, scopes = {
|
||||
{{#scopes}}
|
||||
@AuthorizationScope(scope = "{{scope}}", description = "{{description}}"){{^-last}},{{/-last}}
|
||||
{{/scopes}}
|
||||
}{{/-first}}{{/scopes}}){{^-last}},{{/-last}}
|
||||
{{/isOAuth}}
|
||||
{{^isOAuth}}
|
||||
@Authorization(value = "{{name}}"){{^-last}},{{/-last}}
|
||||
{{/isOAuth}}
|
||||
{{/authMethods}}
|
||||
{{/hasAuthMethods}}{{closebrace}},
|
||||
tags={{openbrace}}{{#vendorExtensions.x-tags}}"{{tag}}"{{^-last}}, {{/-last}}{{/vendorExtensions.x-tags}}{{closebrace}})
|
||||
{{!openapi annotations for info about responses}}
|
||||
@ApiResponses(value = {{openbrace}}{{#responses}}
|
||||
@ApiResponse(code = {{{code}}}, message = "{{{message}}}"{{#baseType}}, response = {{{baseType}}}.class{{/baseType}}{{#containerType}}, responseContainer = "{{{containerType}}}"{{/containerType}}){{^-last}},{{/-last}}{{/responses}}{{closebrace}})
|
||||
{{!micronaut annotations}}
|
||||
@{{#lambda.pascalcase}}{{#lambda.lowercase}}{{httpMethod}}{{/lambda.lowercase}}{{/lambda.pascalcase}}(uri="{{{path}}}")
|
||||
@Produces(value = {{openbrace}}{{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}}{{closebrace}})
|
||||
{{#consumes.0}}
|
||||
@Consumes(value = {{openbrace}}{{#consumes}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}}{{closebrace}})
|
||||
{{/consumes.0}}
|
||||
{{!security annotations}}
|
||||
{{#useAuth}}
|
||||
{{#hasAuthMethods}}
|
||||
@Secured(SecurityRule.IS_AUTHENTICATED)
|
||||
{{/hasAuthMethods}}
|
||||
{{^hasAuthMethods}}
|
||||
@Secured(SecurityRule.IS_ANONYMOUS)
|
||||
{{/hasAuthMethods}}
|
||||
{{/useAuth}}
|
||||
{{!the method definition}}
|
||||
public {{#returnType}}Mono<{{{returnType}}}>{{/returnType}}{{^returnType}}Mono<Object>{{/returnType}} {{nickname}}{{#generateControllerAsAbstract}}Api{{/generateControllerAsAbstract}}({{#allParams}}
|
||||
{{>server/params/queryParams}}{{>server/params/pathParams}}{{>server/params/headerParams}}{{>server/params/bodyParams}}{{>server/params/formParams}}{{>server/params/cookieParams}}{{^-last}}, {{/-last}}{{#-last}}
|
||||
{{/-last}}{{/allParams}}) {
|
||||
{{^generateControllerAsAbstract}}
|
||||
{{>server/controllerOperationBody}} }
|
||||
{{/generateControllerAsAbstract}}
|
||||
{{#generateControllerAsAbstract}}
|
||||
return {{nickname}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}});
|
||||
}
|
||||
{{/generateControllerAsAbstract}}
|
||||
{{#generateControllerAsAbstract}}
|
||||
|
||||
/**
|
||||
{{#summary}}
|
||||
* {{summary}}
|
||||
{{/summary}}
|
||||
*
|
||||
* This method will be delegated to when the controller gets a request
|
||||
*/
|
||||
public abstract {{#returnType}}Mono<{{{returnType}}}>{{/returnType}}{{^returnType}}Mono<Object>{{/returnType}} {{nickname}}({{#allParams}}{{{dataType}}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}});
|
||||
{{/generateControllerAsAbstract}}
|
||||
{{^-last}}
|
||||
|
||||
{{/-last}}
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
{{>common/licenseInfo}}
|
||||
package {{controllerPackage}};
|
||||
|
||||
import io.micronaut.http.annotation.Controller;
|
||||
import reactor.core.publisher.Mono;
|
||||
import {{package}}.{{classname}};
|
||||
{{#imports}}
|
||||
import {{import}};
|
||||
{{/imports}}
|
||||
{{^fullJavaUtil}}
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
{{#generateControllerFromExamples}}
|
||||
import java.util.Arrays;
|
||||
{{/generateControllerFromExamples}}
|
||||
{{/fullJavaUtil}}
|
||||
|
||||
|
||||
@Controller("${context-path}")
|
||||
public class {{controllerClassname}} extends {{classname}} {
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
{{!the method definition}}
|
||||
@Override
|
||||
public {{#returnType}}Mono<{{{returnType}}}>{{/returnType}}{{^returnType}}Mono<Object>{{/returnType}} {{nickname}}({{#allParams}}{{{dataType}}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}) {
|
||||
{{>server/controllerOperationBody}} }
|
||||
{{^-last}}
|
||||
|
||||
{{/-last}}
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{{^generateControllerFromExamples}}
|
||||
{{!The body needs to be implemented by user}}
|
||||
// TODO implement {{nickname}}() body;
|
||||
{{#returnType}}Mono<{{{returnType}}}>{{/returnType}}{{^returnType}}Mono<Object>{{/returnType}} result = Mono.empty();
|
||||
return result;
|
||||
{{/generateControllerFromExamples}}
|
||||
{{#generateControllerFromExamples}}
|
||||
{{!The body is generated to verify that example values are passed correctly}}
|
||||
{{#allParams}}
|
||||
{{^isFile}}
|
||||
{{{dataType}}} {{paramName}}Expected = {{{example}}};
|
||||
assert {{paramName}}.equals({{paramName}}Expected) : "The parameter {{paramName}} was expected to match its example value";
|
||||
{{/isFile}}
|
||||
{{/allParams}}
|
||||
|
||||
return Mono.fromCallable(() -> {{^returnType}}""{{/returnType}}{{#returnType}}{{#vendorExtensions.example}}{{{vendorExtensions.example}}}{{/vendorExtensions.example}}{{^vendorExtensions.example}}null{{/vendorExtensions.example}}{{/returnType}});
|
||||
{{/generateControllerFromExamples}}
|
||||
27
modules/openapi-generator/src/main/resources/java-micronaut/server/doc/README.mustache
vendored
Normal file
27
modules/openapi-generator/src/main/resources/java-micronaut/server/doc/README.mustache
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
# {{artifactId}}
|
||||
|
||||
This is a generated server based on [Micronaut](https://micronaut.io/) framework.
|
||||
|
||||
## Configuration
|
||||
|
||||
To run the whole application, use [Application.java]({{{invokerFolder}}}/Application.java) as main class.
|
||||
|
||||
Read **[Micronaut Guide](https://docs.micronaut.io/latest/guide/#ideSetup)** for detailed description on IDE setup and Micronaut Framework features.
|
||||
|
||||
All the properties can be changed in the [application.yml]({{resourceFolder}}/application.yml) file or when creating micronaut application as described in **[Micronaut Guide - Configuration Section](https://docs.micronaut.io/latest/guide/#config)**.
|
||||
|
||||
## Controller Guides
|
||||
|
||||
Description on how to create Apis is given inside individual api guides:
|
||||
|
||||
{{#apiInfo}}
|
||||
{{#apis}}
|
||||
* [{{classFilename}}]({{apiDocPath}}/{{classFilename}}.md)
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
|
||||
## Author
|
||||
|
||||
{{#apiInfo}}{{#apis}}{{^hasMore}}{{infoEmail}}
|
||||
{{/hasMore}}{{/apis}}{{/apiInfo}}
|
||||
|
||||
63
modules/openapi-generator/src/main/resources/java-micronaut/server/doc/controller_doc.mustache
vendored
Normal file
63
modules/openapi-generator/src/main/resources/java-micronaut/server/doc/controller_doc.mustache
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
# {{classname}}{{#description}}
|
||||
{{description}}{{/description}}
|
||||
|
||||
All URIs are relative to `"{{contextPath}}"`
|
||||
|
||||
The controller class is defined in **[{{classname}}.java](../../{{{apiFolder}}}/{{classname}}.java)**
|
||||
|
||||
Method | HTTP request | Description
|
||||
------------- | ------------- | -------------
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
[**{{operationId}}**](#{{operationId}}) | **{{httpMethod}}** {{path}} | {{#summary}}{{summary}}{{/summary}}
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
<a name="{{operationId}}"></a>
|
||||
# **{{operationId}}**
|
||||
```java
|
||||
{{#returnType}}Mono<{{{returnType}}}>{{/returnType}}{{^returnType}}Mono<Object>{{/returnType}} {{classname}}.{{nickname}}({{#allParams}}{{{paramName}}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
|
||||
```
|
||||
|
||||
{{summary}}{{#notes}}
|
||||
|
||||
{{notes}}{{/notes}}
|
||||
|
||||
{{#allParams}}
|
||||
{{#-last}}
|
||||
### Parameters
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
{{#allParams}}
|
||||
**{{paramName}}** | {{^isPrimitiveType}}[**{{dataType}}**](../../{{modelDocPath}}/{{baseType}}.md){{/isPrimitiveType}}{{#isPrimitiveType}}`{{dataType}}`{{/isPrimitiveType}} | {{description}} |{{^required}} [optional parameter]{{/required}}{{#defaultValue}} [default to `{{defaultValue}}`]{{/defaultValue}}{{#allowableValues}} [enum: {{#values}}`{{{.}}}`{{^-last}}, {{/-last}}{{/values}}]{{/allowableValues}}
|
||||
{{/allParams}}
|
||||
{{/-last}}
|
||||
{{/allParams}}
|
||||
|
||||
{{#returnType}}
|
||||
### Return type
|
||||
{{#returnTypeIsPrimitive}}
|
||||
`{{returnType}}`
|
||||
{{/returnTypeIsPrimitive}}
|
||||
{{^returnTypeIsPrimitive}}
|
||||
[**{{returnType}}**](../../{{modelDocPath}}/{{returnBaseType}}.md)
|
||||
{{/returnTypeIsPrimitive}}
|
||||
{{/returnType}}
|
||||
|
||||
{{#authMethods}}
|
||||
{{#-last}}
|
||||
### Authorization
|
||||
{{#authMethods}}
|
||||
* **{{name}}**{{#scopes}}{{#-last}}, scopes: {{#scopes}}`{{{scope}}}`{{^-last}}, {{/-last}}{{/scopes}}{{/-last}}{{/scopes}}
|
||||
{{/authMethods}}
|
||||
{{/-last}}
|
||||
{{/authMethods}}
|
||||
|
||||
### HTTP request headers
|
||||
- **Accepts Content-Type**: {{#consumes}}`{{{mediaType}}}`{{^-last}}, {{/-last}}{{/consumes}}{{^consumes}}Not defined{{/consumes}}
|
||||
- **Produces Content-Type**: {{#produces}}`{{{mediaType}}}`{{^-last}}, {{/-last}}{{/produces}}{{^produces}}Not defined{{/produces}}
|
||||
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
@@ -0,0 +1,7 @@
|
||||
{{#isBodyParam}}{{!
|
||||
Multi part
|
||||
}}{{#isMultipart}}@Part("{{baseName}}"){{/isMultipart}}{{!
|
||||
Non-multipart body
|
||||
}}{{^isMultipart}}@Body{{/isMultipart}}{{!
|
||||
The type
|
||||
}} {{>common/params/beanValidation}}{{>server/params/type}} {{paramName}}{{/isBodyParam}}
|
||||
@@ -0,0 +1 @@
|
||||
{{#isCookieParam}}@CookieValue(value="{{baseName}}"{{#defaultValue}}, defaultValue="{{defaultValue}}"{{/defaultValue}}) {{>common/params/beanValidation}}{{>server/params/type}} {{paramName}}{{/isCookieParam}}
|
||||
@@ -0,0 +1 @@
|
||||
{{#isFormParam}}{{>common/params/beanValidation}}{{>server/params/type}} {{paramName}}{{/isFormParam}}
|
||||
@@ -0,0 +1 @@
|
||||
{{#isHeaderParam}}@Header(value="{{baseName}}"{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) {{>common/params/beanValidation}}{{>server/params/type}} {{paramName}}{{/isHeaderParam}}
|
||||
@@ -0,0 +1 @@
|
||||
{{#isPathParam}}@PathVariable(value="{{baseName}}"{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) {{>common/params/beanValidation}}{{>server/params/type}} {{paramName}}{{/isPathParam}}
|
||||
@@ -0,0 +1 @@
|
||||
{{#isQueryParam}}@QueryValue(value="{{{baseName}}}"{{!default value}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) {{!validation and type}}{{>common/params/beanValidation}}{{>server/params/type}} {{paramName}}{{/isQueryParam}}
|
||||
7
modules/openapi-generator/src/main/resources/java-micronaut/server/params/type.mustache
vendored
Normal file
7
modules/openapi-generator/src/main/resources/java-micronaut/server/params/type.mustache
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{{!
|
||||
default type
|
||||
}}{{^isDate}}{{^isDateTime}}{{{dataType}}}{{/isDateTime}}{{/isDate}}{{!
|
||||
date-time
|
||||
}}{{#isDateTime}}@Format("yyyy-MM-dd'T'HH:mm:ss.SSSXXXX") {{{dataType}}}{{/isDateTime}}{{!
|
||||
date
|
||||
}}{{#isDate}}@Format("yyyy-MM-dd") {{{dataType}}}{{/isDate}}
|
||||
@@ -0,0 +1,185 @@
|
||||
package {{package}}
|
||||
|
||||
{{#imports}}
|
||||
import {{import}}
|
||||
{{/imports}}
|
||||
import io.micronaut.test.extensions.spock.annotation.MicronautTest
|
||||
import io.micronaut.http.client.HttpClient
|
||||
import io.micronaut.http.client.annotation.Client
|
||||
import io.micronaut.runtime.server.EmbeddedServer
|
||||
import io.micronaut.http.HttpStatus
|
||||
import io.micronaut.http.HttpRequest
|
||||
import io.micronaut.http.MutableHttpRequest;
|
||||
import io.micronaut.http.HttpResponse
|
||||
import io.micronaut.http.MediaType
|
||||
import io.micronaut.http.uri.UriTemplate
|
||||
import io.micronaut.http.cookie.Cookie
|
||||
import io.micronaut.http.client.multipart.MultipartBody
|
||||
import io.micronaut.core.type.Argument
|
||||
import jakarta.inject.Inject
|
||||
import spock.lang.Specification
|
||||
import spock.lang.Ignore
|
||||
import reactor.core.publisher.Mono
|
||||
import java.io.File
|
||||
import java.io.FileReader
|
||||
|
||||
|
||||
/**
|
||||
* Controller tests for {{classname}}
|
||||
*/
|
||||
@MicronautTest
|
||||
class {{classname}}Spec extends Specification {
|
||||
|
||||
@Inject
|
||||
EmbeddedServer server
|
||||
|
||||
@Inject
|
||||
@Client('${context-path}')
|
||||
HttpClient client
|
||||
|
||||
@Inject
|
||||
{{classname}} controller
|
||||
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
/**
|
||||
* This test is used to validate the implementation of {{operationId}}() method
|
||||
*
|
||||
* The method should: {{summary}}
|
||||
{{#notes}}
|
||||
*
|
||||
* {{notes}}
|
||||
{{/notes}}
|
||||
*
|
||||
* TODO fill in the parameters and test return value.
|
||||
*/
|
||||
{{^generateControllerFromExamples}}
|
||||
@Ignore("Not Implemented")
|
||||
{{/generateControllerFromExamples}}
|
||||
def '{{operationId}}() method test'() {
|
||||
given:
|
||||
{{#allParams}}
|
||||
{{{dataType}}} {{paramName}} = {{{vendorExtensions.groovyExample}}}
|
||||
{{/allParams}}
|
||||
|
||||
when:
|
||||
{{#returnType}}{{{returnType}}} result = {{/returnType}}controller.{{operationId}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}).block()
|
||||
|
||||
then:
|
||||
{{^generateControllerFromExamples}}
|
||||
true
|
||||
{{/generateControllerFromExamples}}
|
||||
{{#generateControllerFromExamples}}
|
||||
{{^returnType}}
|
||||
true
|
||||
{{/returnType}}
|
||||
{{#returnType}}
|
||||
result == {{{vendorExtensions.groovyExample}}}
|
||||
{{/returnType}}
|
||||
{{/generateControllerFromExamples}}
|
||||
}
|
||||
|
||||
/**
|
||||
* This test is used to check that the api available to client through
|
||||
* '{{{path}}}' to the features of {{operationId}}() works as desired.
|
||||
*
|
||||
* TODO fill in the request parameters and test response.
|
||||
*/
|
||||
{{^generateControllerFromExamples}}
|
||||
@Ignore("Not Implemented")
|
||||
{{/generateControllerFromExamples}}
|
||||
def '{{operationId}}() test with client through path {{{path}}}'() {
|
||||
given:
|
||||
{{!Create the body}}
|
||||
{{#bodyParam}}
|
||||
{{{dataType}}} body = {{{vendorExtensions.groovyExample}}}
|
||||
{{/bodyParam}}
|
||||
{{#formParams.0}}
|
||||
var form = [
|
||||
// Fill in the body form parameters
|
||||
{{#formParams}}
|
||||
{{^isFile}}
|
||||
'{{{baseName}}}': {{{vendorExtensions.groovyExample}}}{{^-last}},{{/-last}}
|
||||
{{/isFile}}
|
||||
{{#isFile}}
|
||||
'{{{baseName}}}': new FileReader(File.createTempFile('test', '.tmp')){{^-last}},{{/-last}}
|
||||
{{/isFile}}
|
||||
{{/formParams}}
|
||||
]
|
||||
{{/formParams.0}}
|
||||
{{#isMultipart}}
|
||||
{{^formParams}}
|
||||
var body = MultipartBody.builder() // Create multipart body
|
||||
{{#bodyParams}}
|
||||
{{^isFile}}
|
||||
.addPart('{{{baseName}}}', {{{vendorExtensions.groovyExample}}}{{^isString}}.toString(){{/isString}})
|
||||
{{/isFile}}
|
||||
{{#isFile}}
|
||||
{{#contentType}}
|
||||
.addPart('{{{baseName}}}', 'filename', MediaType.of('{{{contentType}}}'), File.createTempFile('test', '.tmp'))
|
||||
{{/contentType}}
|
||||
{{^contentType}}
|
||||
.addPart('{{{baseName}}}', 'filename', File.createTempFile('test', '.tmp'))
|
||||
{{/contentType}}
|
||||
{{/isFile}}
|
||||
{{/bodyParams}}
|
||||
.build()
|
||||
{{/formParams}}
|
||||
{{/isMultipart}}
|
||||
{{!Create the uri with path variables}}
|
||||
var uri = UriTemplate.of('{{{path}}}').expand({{^pathParams}}[:]{{/pathParams}}{{#pathParams.0}}[
|
||||
// Fill in the path variables
|
||||
{{#pathParams}}
|
||||
'{{{baseName}}}': {{{vendorExtensions.groovyExample}}}{{^-last}},{{/-last}}
|
||||
{{/pathParams}}
|
||||
]{{/pathParams.0}})
|
||||
{{!Create the request with body and uri}}
|
||||
MutableHttpRequest request = HttpRequest.{{httpMethod}}{{#vendorExtensions.methodAllowsBody}}{{#bodyParam}}(uri, body){{/bodyParam}}{{#isMultipart}}{{^formParams}}(uri, body){{/formParams}}{{/isMultipart}}{{#formParams.0}}(uri, form){{/formParams.0}}{{^bodyParam}}{{^isMultipart}}{{^formParams}}(uri, null){{/formParams}}{{/isMultipart}}{{/bodyParam}}{{/vendorExtensions.methodAllowsBody}}{{^vendorExtensions.methodAllowsBody}}(uri){{/vendorExtensions.methodAllowsBody}}
|
||||
{{!Fill in all the request parameters}}
|
||||
{{#vendorExtensions.x-contentType}}
|
||||
.contentType('{{vendorExtensions.x-contentType}}')
|
||||
{{/vendorExtensions.x-contentType}}
|
||||
{{#vendorExtensions.x-accepts}}
|
||||
.accept('{{vendorExtensions.x-accepts}}')
|
||||
{{/vendorExtensions.x-accepts}}
|
||||
{{#headerParams}}
|
||||
.header('{{{baseName}}}', {{{vendorExtensions.groovyExample}}}{{^isString}}.toString(){{/isString}})
|
||||
{{/headerParams}}
|
||||
{{#cookieParams}}
|
||||
.cookie(Cookie.of('{{{baseName}}}', {{{vendorExtensions.groovyExample}}}))
|
||||
{{/cookieParams}}
|
||||
{{!Fill in the query parameters}}
|
||||
{{#queryParams.0}}
|
||||
request.getParameters()
|
||||
{{#queryParams}}
|
||||
{{#isCollectionFormatMulti}}
|
||||
.add('{{{baseName}}}', {{{vendorExtensions.groovyExample}}}) // The query format should be multi
|
||||
{{/isCollectionFormatMulti}}
|
||||
{{#isDeepObject}}
|
||||
.add('{{{baseName}}}[property]', 'value') // The query format should be deep-object
|
||||
{{/isDeepObject}}
|
||||
{{^isCollectionFormatMulti}}
|
||||
{{^isDeepObject}}
|
||||
.add('{{{baseName}}}', {{{vendorExtensions.groovyExample}}}{{^isString}}.toString(){{/isString}}){{#collectionFormat}} // The query parameter format should be {{collectionFormat}}{{/collectionFormat}}
|
||||
{{/isDeepObject}}
|
||||
{{/isCollectionFormatMulti}}
|
||||
{{/queryParams}}
|
||||
{{/queryParams.0}}
|
||||
|
||||
when:
|
||||
HttpResponse response = client.toBlocking().exchange(request{{#returnType}}, {{#returnContainer}}Argument.of({{#isArray}}List{{/isArray}}{{#isMap}}Map{{/isMap}}.class, {{#isMap}}String.class, {{/isMap}}{{{returnBaseType}}}.class){{/returnContainer}}{{^returnContainer}}{{{returnType}}}.class{{/returnContainer}}{{/returnType}});{{^returnType}} // To retrieve body you must specify required type (e.g. Map.class) as second argument {{/returnType}}
|
||||
|
||||
then:
|
||||
response.status() == HttpStatus.OK
|
||||
{{#generateControllerFromExamples}}
|
||||
{{#returnType}}
|
||||
{{#vendorExtensions.example}}
|
||||
response.body() == {{{vendorExtensions.groovyExample}}}
|
||||
{{/vendorExtensions.example}}
|
||||
{{/returnType}}
|
||||
{{/generateControllerFromExamples}}
|
||||
}
|
||||
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
}
|
||||
185
modules/openapi-generator/src/main/resources/java-micronaut/server/test/controller_test.mustache
vendored
Normal file
185
modules/openapi-generator/src/main/resources/java-micronaut/server/test/controller_test.mustache
vendored
Normal file
@@ -0,0 +1,185 @@
|
||||
package {{package}};
|
||||
|
||||
{{#imports}}
|
||||
import {{import}};
|
||||
{{/imports}}
|
||||
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
|
||||
import io.micronaut.http.client.HttpClient;
|
||||
import io.micronaut.http.client.annotation.Client;
|
||||
import io.micronaut.runtime.server.EmbeddedServer;
|
||||
import io.micronaut.http.HttpStatus;
|
||||
import io.micronaut.http.MutableHttpRequest;
|
||||
import io.micronaut.http.HttpRequest;
|
||||
import io.micronaut.http.HttpResponse;
|
||||
import io.micronaut.http.MediaType;
|
||||
import io.micronaut.http.uri.UriTemplate;
|
||||
import io.micronaut.http.cookie.Cookie;
|
||||
import io.micronaut.http.client.multipart.MultipartBody;
|
||||
import io.micronaut.core.type.Argument;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import jakarta.inject.Inject;
|
||||
import reactor.core.publisher.Mono;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
{{^fullJavaUtil}}
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.HashSet;
|
||||
{{/fullJavaUtil}}
|
||||
|
||||
|
||||
/**
|
||||
* API tests for {{classname}}
|
||||
*/
|
||||
@MicronautTest
|
||||
public class {{classname}}Test {
|
||||
|
||||
@Inject
|
||||
EmbeddedServer server;
|
||||
|
||||
@Inject
|
||||
@Client("${context-path}")
|
||||
HttpClient client;
|
||||
|
||||
@Inject
|
||||
{{classname}} controller;
|
||||
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
/**
|
||||
* This test is used to validate the implementation of {{operationId}}() method
|
||||
*
|
||||
* The method should: {{summary}}
|
||||
{{#notes}}
|
||||
*
|
||||
* {{notes}}
|
||||
{{/notes}}
|
||||
*
|
||||
* TODO fill in the parameters and test return value.
|
||||
*/
|
||||
@Test
|
||||
{{^generateControllerFromExamples}}
|
||||
@Disabled("Not Implemented")
|
||||
{{/generateControllerFromExamples}}
|
||||
void {{operationId}}MethodTest() {
|
||||
// given
|
||||
{{#allParams}}
|
||||
{{{dataType}}} {{paramName}} = {{{example}}};
|
||||
{{/allParams}}
|
||||
|
||||
// when
|
||||
{{#returnType}}{{{returnType}}} result = {{/returnType}}controller.{{operationId}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}).block();
|
||||
|
||||
// then
|
||||
{{^generateControllerFromExamples}}
|
||||
Assertions.assertTrue(true);
|
||||
{{/generateControllerFromExamples}}
|
||||
{{#generateControllerFromExamples}}
|
||||
{{#returnType}}
|
||||
{{#vendorExtensions.example}}
|
||||
Assertions.assertEquals(result, {{{vendorExtensions.example}}});
|
||||
{{/vendorExtensions.example}}
|
||||
{{/returnType}}
|
||||
{{/generateControllerFromExamples}}
|
||||
}
|
||||
|
||||
/**
|
||||
* This test is used to check that the api available to client through
|
||||
* '{{{path}}}' to the features of {{operationId}}() works as desired.
|
||||
*
|
||||
* TODO fill in the request parameters and test response.
|
||||
*/
|
||||
@Test
|
||||
{{^generateControllerFromExamples}}
|
||||
@Disabled("Not Implemented")
|
||||
{{/generateControllerFromExamples}}
|
||||
void {{operationId}}ClientApiTest() throws IOException {
|
||||
// given
|
||||
{{!Create the body}}
|
||||
{{#bodyParam}}
|
||||
{{{dataType}}} body = {{{example}}};
|
||||
{{/bodyParam}}
|
||||
{{#formParams.0}}
|
||||
Map<String, Object> form = new HashMap<String, Object>(){{openbrace}}{{openbrace}}
|
||||
// Fill in the body form parameters
|
||||
{{#formParams}}
|
||||
{{^isFile}}
|
||||
put("{{{baseName}}}", {{{example}}});
|
||||
{{/isFile}}
|
||||
{{#isFile}}
|
||||
put("{{{baseName}}}", new FileReader(File.createTempFile("test", ".tmp")));
|
||||
{{/isFile}}
|
||||
{{/formParams}}
|
||||
{{closebrace}}{{closebrace}};
|
||||
{{/formParams.0}}
|
||||
{{#isMultipart}}
|
||||
{{^formParams}}
|
||||
MultipartBody body = MultipartBody.builder() // Create multipart body
|
||||
{{#bodyParams}}
|
||||
{{^isFile}}
|
||||
.addPart("{{{baseName}}}", {{^isString}}String.valueOf({{/isString}}{{{example}}}{{^isString}}){{/isString}})
|
||||
{{/isFile}}
|
||||
{{#isFile}}
|
||||
{{#contentType}}
|
||||
.addPart("{{{baseName}}}", "filename", MediaType.of("{{{contentType}}}"), File.createTempFile("test", ".tmp"))
|
||||
{{/contentType}}
|
||||
{{^contentType}}
|
||||
.addPart("{{{baseName}}}", "filename", File.createTempFile("test", ".tmp"))
|
||||
{{/contentType}}
|
||||
{{/isFile}}
|
||||
{{/bodyParams}}
|
||||
.build();
|
||||
{{/formParams}}
|
||||
{{/isMultipart}}
|
||||
{{!Create the uri with path variables}}
|
||||
String uri = UriTemplate.of("{{{path}}}").expand(new HashMap{{^pathParams}}<>(){{/pathParams}}{{#pathParams.0}}<String, Object>(){{openbrace}}{{openbrace}}
|
||||
// Fill in the path variables
|
||||
{{#pathParams}}
|
||||
put("{{{baseName}}}", {{{example}}});
|
||||
{{/pathParams}}
|
||||
{{closebrace}}{{closebrace}}{{/pathParams.0}});
|
||||
{{!Create the request with body and uri}}
|
||||
MutableHttpRequest<?> request = HttpRequest.{{httpMethod}}{{#vendorExtensions.methodAllowsBody}}{{#bodyParam}}(uri, body){{/bodyParam}}{{#isMultipart}}{{^formParams}}(uri, body){{/formParams}}{{/isMultipart}}{{#formParams.0}}(uri, form){{/formParams.0}}{{^bodyParam}}{{^isMultipart}}{{^formParams}}(uri, null){{/formParams}}{{/isMultipart}}{{/bodyParam}}{{/vendorExtensions.methodAllowsBody}}{{^vendorExtensions.methodAllowsBody}}(uri){{/vendorExtensions.methodAllowsBody}}{{!Fill in all the request parameters}}{{#vendorExtensions.x-contentType}}
|
||||
.contentType("{{vendorExtensions.x-contentType}}"){{/vendorExtensions.x-contentType}}{{#vendorExtensions.x-accepts}}
|
||||
.accept("{{vendorExtensions.x-accepts}}"){{/vendorExtensions.x-accepts}}{{#headerParams}}
|
||||
.header("{{{baseName}}}", {{^isString}}String.valueOf({{/isString}}{{{example}}}{{^isString}}){{/isString}}){{/headerParams}}{{#cookieParams}}
|
||||
.cookie(Cookie.of("{{{baseName}}}", {{{example}}})){{/cookieParams}};
|
||||
{{!Fill in the query parameters}}
|
||||
{{#queryParams.0}}
|
||||
request.getParameters()
|
||||
{{#queryParams}}
|
||||
{{#isCollectionFormatMulti}}
|
||||
.add("{{{baseName}}}", {{{example}}}){{#-last}};{{/-last}} // The query format should be multi
|
||||
{{/isCollectionFormatMulti}}
|
||||
{{#isDeepObject}}
|
||||
.add("{{{baseName}}}[property]", "value"){{#-last}};{{/-last}} // The query format should be deep-object
|
||||
{{/isDeepObject}}
|
||||
{{^isCollectionFormatMulti}}
|
||||
{{^isDeepObject}}
|
||||
.add("{{{baseName}}}", {{^isString}}String.valueOf({{/isString}}{{{example}}}{{^isString}}){{/isString}}){{#-last}};{{/-last}} // The query parameter format should be {{collectionFormat}}
|
||||
{{/isDeepObject}}
|
||||
{{/isCollectionFormatMulti}}
|
||||
{{/queryParams}}
|
||||
{{/queryParams.0}}
|
||||
|
||||
// when
|
||||
HttpResponse<?> response = client.toBlocking().exchange(request{{#returnType}}, {{#returnContainer}}Argument.of({{#isArray}}List{{/isArray}}{{#isMap}}Map{{/isMap}}.class, {{#isMap}}String.class, {{/isMap}}{{{returnBaseType}}}.class){{/returnContainer}}{{^returnContainer}}{{{returnType}}}.class{{/returnContainer}}{{/returnType}});{{^returnType}} // To retrieve body you must specify required type (e.g. Map.class) as second argument {{/returnType}}
|
||||
|
||||
// then
|
||||
Assertions.assertEquals(HttpStatus.OK, response.status());
|
||||
{{#generateControllerFromExamples}}
|
||||
{{#returnType}}
|
||||
Assertions.assertEquals(response.body(), {{{vendorExtensions.example}}});
|
||||
{{/returnType}}
|
||||
{{/generateControllerFromExamples}}
|
||||
}
|
||||
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
package org.openapitools.codegen.java.micronaut;
|
||||
|
||||
import io.swagger.parser.OpenAPIParser;
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.parser.core.models.ParseOptions;
|
||||
import org.openapitools.codegen.ClientOptInput;
|
||||
import org.openapitools.codegen.CodegenConstants;
|
||||
import org.openapitools.codegen.DefaultGenerator;
|
||||
import org.openapitools.codegen.languages.JavaMicronautAbstractCodegen;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
|
||||
/**
|
||||
* An abstract class with methods useful for testing
|
||||
*/
|
||||
public abstract class AbstractMicronautCodegenTest {
|
||||
/**
|
||||
* Path to a common test configuration file
|
||||
*/
|
||||
protected final String PETSTORE_PATH = "src/test/resources/petstore.json";
|
||||
|
||||
/**
|
||||
*
|
||||
* @param codegen - the code generator
|
||||
* @param configPath - the path to the config starting from src/test/resources
|
||||
* @param filesToGenerate - which files to generate - can be CodegenConstants.MODELS, APIS, SUPPORTING_FILES, ...
|
||||
* @return - the path to the generated folder
|
||||
*/
|
||||
protected String generateFiles(JavaMicronautAbstractCodegen codegen, String configPath, String... filesToGenerate) {
|
||||
File output = null;
|
||||
try {
|
||||
output = Files.createTempDirectory("test").toFile().getCanonicalFile();
|
||||
} catch (IOException e) {
|
||||
fail("Unable to create temporary directory for output");
|
||||
}
|
||||
output.deleteOnExit();
|
||||
|
||||
// Create parser
|
||||
String outputPath = output.getAbsolutePath().replace('\\', '/');
|
||||
OpenAPI openAPI = new OpenAPIParser()
|
||||
.readLocation(configPath, null, new ParseOptions()).getOpenAPI();
|
||||
|
||||
// Configure codegen
|
||||
codegen.setOutputDir(outputPath);
|
||||
|
||||
// Create input
|
||||
ClientOptInput input = new ClientOptInput();
|
||||
input.openAPI(openAPI);
|
||||
input.config(codegen);
|
||||
|
||||
// Generate
|
||||
DefaultGenerator generator = new DefaultGenerator();
|
||||
// by default nothing is generated
|
||||
generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "false");
|
||||
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false");
|
||||
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false");
|
||||
generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "false");
|
||||
generator.setGeneratorPropertyDefault(CodegenConstants.API_TESTS, "false");
|
||||
generator.setGeneratorPropertyDefault(CodegenConstants.API_DOCS, "false");
|
||||
generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false");
|
||||
// set all the files user wants to generate
|
||||
for (String files: filesToGenerate) {
|
||||
generator.setGeneratorPropertyDefault(files, "true");
|
||||
}
|
||||
|
||||
generator.opts(input).generate();
|
||||
|
||||
return outputPath + "/";
|
||||
}
|
||||
|
||||
public static void assertFileContainsRegex(String path, String... regex) {
|
||||
String file = readFile(path);
|
||||
for (String line: regex)
|
||||
assertTrue(Pattern.compile(line.replace(" ", "\\s+")).matcher(file).find());
|
||||
}
|
||||
|
||||
public static void assertFileNotContainsRegex(String path, String... regex) {
|
||||
String file = readFile(path);
|
||||
for (String line: regex)
|
||||
assertFalse(Pattern.compile(line.replace(" ", "\\s+")).matcher(file).find());
|
||||
}
|
||||
|
||||
public static void assertFileContains(String path, String... lines) {
|
||||
String file = linearize(readFile(path));
|
||||
for (String line : lines)
|
||||
assertTrue(file.contains(linearize(line)), "File does not contain line [" + line + "]");
|
||||
}
|
||||
|
||||
public static void assertFileNotContains(String path, String... lines) {
|
||||
String file = linearize(readFile(path));
|
||||
for (String line : lines)
|
||||
assertFalse(file.contains(linearize(line)), "File contains line [" + line + "]");
|
||||
}
|
||||
|
||||
public static void assertFileExists(String path) {
|
||||
assertTrue(Paths.get(path).toFile().exists(), "File \"" + path + "\" should exist");
|
||||
}
|
||||
|
||||
public static void assertFileNotExists(String path) {
|
||||
assertFalse(Paths.get(path).toFile().exists(), "File \"" + path + "\" should not exist");
|
||||
}
|
||||
|
||||
public static String readFile(String path) {
|
||||
String file = null;
|
||||
try {
|
||||
file = new String(Files.readAllBytes(Paths.get(path)), StandardCharsets.UTF_8);
|
||||
assertNotNull(file, "File \"" + path + "\" does not exist");
|
||||
} catch (IOException e) {
|
||||
fail("Unable to evaluate file " + path);
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
public static String linearize(String target) {
|
||||
return target.replaceAll("\r?\n", "").replaceAll("\\s+", "\\s");
|
||||
}
|
||||
}
|
||||
@@ -1,31 +1,18 @@
|
||||
package org.openapitools.codegen.java.micronaut;
|
||||
|
||||
import io.swagger.parser.OpenAPIParser;
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.oas.models.info.Info;
|
||||
import io.swagger.v3.oas.models.servers.Server;
|
||||
import io.swagger.v3.parser.core.models.ParseOptions;
|
||||
import org.openapitools.codegen.CliOption;
|
||||
import org.openapitools.codegen.ClientOptInput;
|
||||
import org.openapitools.codegen.CodegenConstants;
|
||||
import org.openapitools.codegen.DefaultGenerator;
|
||||
import org.openapitools.codegen.languages.JavaMicronautClientCodegen;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import static java.util.stream.Collectors.groupingBy;
|
||||
import static org.testng.Assert.*;
|
||||
import static org.testng.Assert.fail;
|
||||
|
||||
public class MicronautClientCodegenTest {
|
||||
private final String PETSTORE_PATH = "src/test/resources/petstore.json";
|
||||
|
||||
public class MicronautClientCodegenTest extends AbstractMicronautCodegenTest {
|
||||
@Test
|
||||
public void clientOptsUnicity() {
|
||||
JavaMicronautClientCodegen codegen = new JavaMicronautClientCodegen();
|
||||
@@ -55,6 +42,31 @@ public class MicronautClientCodegenTest {
|
||||
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.INVOKER_PACKAGE), "org.openapitools");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApiAndModelFilesPresent() {
|
||||
JavaMicronautClientCodegen codegen = new JavaMicronautClientCodegen();
|
||||
codegen.additionalProperties().put(CodegenConstants.INVOKER_PACKAGE, "org.test.test");
|
||||
codegen.additionalProperties().put(CodegenConstants.MODEL_PACKAGE, "org.test.test.model");
|
||||
codegen.additionalProperties().put(CodegenConstants.API_PACKAGE, "org.test.test.api");
|
||||
String outputPath = generateFiles(codegen, PETSTORE_PATH,
|
||||
CodegenConstants.SUPPORTING_FILES,
|
||||
CodegenConstants.APIS,
|
||||
CodegenConstants.MODELS);
|
||||
|
||||
String apiFolder = outputPath + "src/main/java/org/test/test/api/";
|
||||
assertFileExists(apiFolder + "PetApi.java");
|
||||
assertFileExists(apiFolder + "StoreApi.java");
|
||||
assertFileExists(apiFolder + "UserApi.java");
|
||||
|
||||
String modelFolder = outputPath + "src/main/java/org/test/test/model/";
|
||||
assertFileExists(modelFolder + "Pet.java");
|
||||
assertFileExists(modelFolder + "User.java");
|
||||
assertFileExists(modelFolder + "Order.java");
|
||||
|
||||
String resources = outputPath + "src/main/resources/";
|
||||
assertFileExists(resources + "application.yml");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doConfigureAuthParam() {
|
||||
JavaMicronautClientCodegen codegen = new JavaMicronautClientCodegen();
|
||||
@@ -85,7 +97,7 @@ public class MicronautClientCodegenTest {
|
||||
@Test
|
||||
public void doUseValidationParam() {
|
||||
JavaMicronautClientCodegen codegen = new JavaMicronautClientCodegen();
|
||||
codegen.additionalProperties().put(JavaMicronautClientCodegen.OPT_CONFIGURE_AUTH, "false");
|
||||
codegen.additionalProperties().put(JavaMicronautClientCodegen.USE_BEANVALIDATION, "true");
|
||||
String outputPath = generateFiles(codegen, PETSTORE_PATH,
|
||||
CodegenConstants.APIS);
|
||||
|
||||
@@ -94,6 +106,18 @@ public class MicronautClientCodegenTest {
|
||||
assertFileContains(outputPath + "/src/main/java/org/openapitools/api/PetApi.java", "@NotNull");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doNotUseValidationParam() {
|
||||
JavaMicronautClientCodegen codegen = new JavaMicronautClientCodegen();
|
||||
codegen.additionalProperties().put(JavaMicronautClientCodegen.USE_BEANVALIDATION, "false");
|
||||
String outputPath = generateFiles(codegen, PETSTORE_PATH,
|
||||
CodegenConstants.APIS);
|
||||
|
||||
// Files are not generated
|
||||
assertFileNotContains(outputPath + "/src/main/java/org/openapitools/api/PetApi.java", "@Valid");
|
||||
assertFileNotContains(outputPath + "/src/main/java/org/openapitools/api/PetApi.java", "@NotNull");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doGenerateForMaven() {
|
||||
JavaMicronautClientCodegen codegen = new JavaMicronautClientCodegen();
|
||||
@@ -162,89 +186,33 @@ public class MicronautClientCodegenTest {
|
||||
assertFileContains(outputPath + "src/test/groovy/org/openapitools/api/PetApiSpec.groovy", "PetApiSpec", "@MicronautTest");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param codegen - the code generator
|
||||
* @param configPath - the path to the config starting from src/test/resources
|
||||
* @param filesToGenerate - which files to generate - can be CodegenConstants.MODELS, APIS, SUPPORTING_FILES, ...
|
||||
* @return - the path to the generated folder
|
||||
*/
|
||||
protected String generateFiles(JavaMicronautClientCodegen codegen, String configPath, String... filesToGenerate) {
|
||||
File output = null;
|
||||
try {
|
||||
output = Files.createTempDirectory("test").toFile().getCanonicalFile();
|
||||
} catch (IOException e) {
|
||||
fail("Unable to create temporary directory for output");
|
||||
}
|
||||
output.deleteOnExit();
|
||||
@Test
|
||||
public void doGenerateRequiredPropertiesInConstructor() {
|
||||
JavaMicronautClientCodegen codegen = new JavaMicronautClientCodegen();
|
||||
codegen.additionalProperties().put(JavaMicronautClientCodegen.OPT_REQUIRED_PROPERTIES_IN_CONSTRUCTOR, "true");
|
||||
String outputPath = generateFiles(codegen, PETSTORE_PATH, CodegenConstants.MODELS, CodegenConstants.APIS);
|
||||
|
||||
// Create parser
|
||||
String outputPath = output.getAbsolutePath().replace('\\', '/');
|
||||
OpenAPI openAPI = new OpenAPIParser()
|
||||
.readLocation(configPath, null, new ParseOptions()).getOpenAPI();
|
||||
|
||||
// Configure codegen
|
||||
codegen.setOutputDir(outputPath);
|
||||
|
||||
// Create input
|
||||
ClientOptInput input = new ClientOptInput();
|
||||
input.openAPI(openAPI);
|
||||
input.config(codegen);
|
||||
|
||||
// Generate
|
||||
DefaultGenerator generator = new DefaultGenerator();
|
||||
// by default nothing is generated
|
||||
generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "false");
|
||||
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false");
|
||||
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false");
|
||||
generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "false");
|
||||
generator.setGeneratorPropertyDefault(CodegenConstants.API_TESTS, "false");
|
||||
generator.setGeneratorPropertyDefault(CodegenConstants.API_DOCS, "false");
|
||||
generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false");
|
||||
// set all the files user wants to generate
|
||||
for (String files: filesToGenerate) {
|
||||
generator.setGeneratorPropertyDefault(files, "true");
|
||||
}
|
||||
|
||||
generator.opts(input).generate();
|
||||
|
||||
return outputPath + "/";
|
||||
// Constructor should have properties
|
||||
String modelPath = outputPath + "src/main/java/org/openapitools/model/";
|
||||
assertFileContains(modelPath + "Pet.java", "public Pet(String name, List<String> photoUrls)");
|
||||
assertFileNotContains(modelPath + "Pet.java", "public Pet()");
|
||||
assertFileContains(modelPath + "User.java", "public User()");
|
||||
assertFileContains(modelPath + "Order.java", "public Order()");
|
||||
}
|
||||
|
||||
public static void assertFileContains(String path, String... lines) {
|
||||
String file = readFile(path);
|
||||
for (String line : lines)
|
||||
assertTrue(file.contains(linearize(line)), "File does not contain line [" + line + "]");
|
||||
}
|
||||
@Test
|
||||
public void doNotGenerateRequiredPropertiesInConstructor() {
|
||||
JavaMicronautClientCodegen codegen = new JavaMicronautClientCodegen();
|
||||
codegen.additionalProperties().put(JavaMicronautClientCodegen.OPT_REQUIRED_PROPERTIES_IN_CONSTRUCTOR, "false");
|
||||
String outputPath = generateFiles(codegen, PETSTORE_PATH, CodegenConstants.MODELS, CodegenConstants.APIS);
|
||||
|
||||
public static void assertFileNotContains(String path, String... lines) {
|
||||
String file = readFile(path);
|
||||
for (String line : lines)
|
||||
assertFalse(file.contains(linearize(line)), "File contains line [" + line + "]");
|
||||
}
|
||||
|
||||
public static void assertFileExists(String path) {
|
||||
assertTrue(Paths.get(path).toFile().exists(), "File \"" + path + "\" should exist");
|
||||
}
|
||||
|
||||
public static void assertFileNotExists(String path) {
|
||||
assertFalse(Paths.get(path).toFile().exists(), "File \"" + path + "\" should not exist");
|
||||
}
|
||||
|
||||
public static String readFile(String path) {
|
||||
String file = null;
|
||||
try {
|
||||
String generatedFile = new String(Files.readAllBytes(Paths.get(path)), StandardCharsets.UTF_8);
|
||||
file = linearize(generatedFile);
|
||||
assertNotNull(file);
|
||||
} catch (IOException e) {
|
||||
fail("Unable to evaluate file " + path);
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
public static String linearize(String target) {
|
||||
return target.replaceAll("\r?\n", "").replaceAll("\\s+", "\\s");
|
||||
// Constructor should have properties
|
||||
String modelPath = outputPath + "src/main/java/org/openapitools/model/";
|
||||
assertFileContains(modelPath + "Pet.java", "public Pet()");
|
||||
assertFileNotContainsRegex(modelPath + "Pet.java", "public Pet\\([^)]+\\)");
|
||||
assertFileContains(modelPath + "User.java", "public User()");
|
||||
assertFileNotContainsRegex(modelPath + "User.java", "public User\\([^)]+\\)");
|
||||
assertFileContains(modelPath + "Order.java", "public Order()");
|
||||
assertFileNotContainsRegex(modelPath + "Order.java", "public Order\\([^)]+\\)");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,195 @@
|
||||
package org.openapitools.codegen.java.micronaut;
|
||||
|
||||
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.CliOption;
|
||||
import org.openapitools.codegen.CodegenConstants;
|
||||
import org.openapitools.codegen.languages.JavaMicronautServerCodegen;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static java.util.stream.Collectors.groupingBy;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
public class MicronautServerCodegenTest extends AbstractMicronautCodegenTest {
|
||||
@Test
|
||||
public void clientOptsUnicity() {
|
||||
JavaMicronautServerCodegen codegen = new JavaMicronautServerCodegen();
|
||||
codegen.cliOptions()
|
||||
.stream()
|
||||
.collect(groupingBy(CliOption::getOpt))
|
||||
.forEach((k, v) -> assertEquals(v.size(), 1, k + " is described multiple times"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitialConfigValues() throws Exception {
|
||||
final JavaMicronautServerCodegen codegen = new JavaMicronautServerCodegen();
|
||||
codegen.processOpts();
|
||||
|
||||
OpenAPI openAPI = new OpenAPI();
|
||||
openAPI.addServersItem(new Server().url("https://one.com/v2"));
|
||||
openAPI.setInfo(new Info());
|
||||
codegen.preprocessOpenAPI(openAPI);
|
||||
|
||||
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.controller");
|
||||
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.API_PACKAGE), "org.openapitools.controller");
|
||||
Assert.assertEquals(codegen.additionalProperties().get(JavaMicronautServerCodegen.OPT_CONTROLLER_PACKAGE), "org.openapitools.controller");
|
||||
Assert.assertEquals(codegen.getInvokerPackage(), "org.openapitools");
|
||||
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.INVOKER_PACKAGE), "org.openapitools");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApiAndModelFilesPresent() {
|
||||
JavaMicronautServerCodegen codegen = new JavaMicronautServerCodegen();
|
||||
codegen.additionalProperties().put(CodegenConstants.INVOKER_PACKAGE, "org.test.test");
|
||||
codegen.additionalProperties().put(CodegenConstants.MODEL_PACKAGE, "org.test.test.model");
|
||||
codegen.additionalProperties().put(JavaMicronautServerCodegen.OPT_CONTROLLER_PACKAGE, "org.test.test.controller");
|
||||
String outputPath = generateFiles(codegen, PETSTORE_PATH,
|
||||
CodegenConstants.SUPPORTING_FILES,
|
||||
CodegenConstants.APIS,
|
||||
CodegenConstants.MODELS);
|
||||
|
||||
String invokerFolder = outputPath + "src/main/java/org/test/test/";
|
||||
assertFileExists(invokerFolder + "Application.java");
|
||||
|
||||
String controllerFolder = outputPath + "src/main/java/org/test/test/controller/";
|
||||
assertFileExists(controllerFolder + "PetController.java");
|
||||
assertFileExists(controllerFolder + "StoreController.java");
|
||||
assertFileExists(controllerFolder + "UserController.java");
|
||||
|
||||
String modelFolder = outputPath + "src/main/java/org/test/test/model/";
|
||||
assertFileExists(modelFolder + "Pet.java");
|
||||
assertFileExists(modelFolder + "User.java");
|
||||
assertFileExists(modelFolder + "Order.java");
|
||||
|
||||
String resources = outputPath + "src/main/resources/";
|
||||
assertFileExists(resources + "application.yml");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doUseValidationParam() {
|
||||
JavaMicronautServerCodegen codegen = new JavaMicronautServerCodegen();
|
||||
codegen.additionalProperties().put(JavaMicronautServerCodegen.USE_BEANVALIDATION, "true");
|
||||
String outputPath = generateFiles(codegen, PETSTORE_PATH,
|
||||
CodegenConstants.APIS);
|
||||
|
||||
// Files are not generated
|
||||
assertFileContains(outputPath + "/src/main/java/org/openapitools/controller/PetController.java", "@Valid");
|
||||
assertFileContains(outputPath + "/src/main/java/org/openapitools/controller/PetController.java", "@NotNull");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doNotUseValidationParam() {
|
||||
JavaMicronautServerCodegen codegen = new JavaMicronautServerCodegen();
|
||||
codegen.additionalProperties().put(JavaMicronautServerCodegen.USE_BEANVALIDATION, "false");
|
||||
String outputPath = generateFiles(codegen, PETSTORE_PATH,
|
||||
CodegenConstants.APIS);
|
||||
|
||||
// Files are not generated
|
||||
assertFileNotContains(outputPath + "/src/main/java/org/openapitools/controller/PetController.java", "@Valid");
|
||||
assertFileNotContains(outputPath + "/src/main/java/org/openapitools/controller/PetController.java", "@NotNull");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doGenerateForMaven() {
|
||||
JavaMicronautServerCodegen codegen = new JavaMicronautServerCodegen();
|
||||
codegen.additionalProperties().put(JavaMicronautServerCodegen.OPT_BUILD,
|
||||
JavaMicronautServerCodegen.OPT_BUILD_MAVEN);
|
||||
String outputPath = generateFiles(codegen, PETSTORE_PATH,
|
||||
CodegenConstants.SUPPORTING_FILES);
|
||||
|
||||
// Files are not generated
|
||||
assertFileExists(outputPath + "/pom.xml");
|
||||
assertFileNotExists(outputPath + "/build.gradle");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doGenerateForGradle() {
|
||||
JavaMicronautServerCodegen codegen = new JavaMicronautServerCodegen();
|
||||
codegen.additionalProperties().put(JavaMicronautServerCodegen.OPT_BUILD,
|
||||
JavaMicronautServerCodegen.OPT_BUILD_GRADLE);
|
||||
String outputPath = generateFiles(codegen, PETSTORE_PATH,
|
||||
CodegenConstants.SUPPORTING_FILES);
|
||||
|
||||
// Files are not generated
|
||||
assertFileExists(outputPath + "/build.gradle");
|
||||
assertFileNotExists(outputPath + "/pom.xml");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doGenerateForTestJUnit() {
|
||||
JavaMicronautServerCodegen codegen = new JavaMicronautServerCodegen();
|
||||
codegen.additionalProperties().put(JavaMicronautServerCodegen.OPT_BUILD,
|
||||
JavaMicronautServerCodegen.OPT_BUILD_ALL);
|
||||
codegen.additionalProperties().put(JavaMicronautServerCodegen.OPT_TEST,
|
||||
JavaMicronautServerCodegen.OPT_TEST_JUNIT);
|
||||
String outputPath = generateFiles(codegen, PETSTORE_PATH,
|
||||
CodegenConstants.SUPPORTING_FILES,
|
||||
CodegenConstants.API_TESTS, CodegenConstants.APIS, CodegenConstants.MODELS);
|
||||
|
||||
// Files are not generated
|
||||
assertFileContains(outputPath + "build.gradle", "testRuntime(\"junit");
|
||||
assertFileContains(outputPath + "pom.xml", "<artifactId>micronaut-test-junit");
|
||||
assertFileNotContains(outputPath + "build.gradle", "testRuntime(\"spock");
|
||||
assertFileNotContains(outputPath + "pom.xml", "<artifactId>micronaut-test-spock");
|
||||
assertFileExists(outputPath + "src/test/java/");
|
||||
assertFileExists(outputPath + "src/test/java/org/openapitools/controller/PetControllerTest.java");
|
||||
assertFileContains(outputPath + "src/test/java/org/openapitools/controller/PetControllerTest.java", "PetControllerTest", "@MicronautTest");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doGenerateForTestSpock() {
|
||||
JavaMicronautServerCodegen codegen = new JavaMicronautServerCodegen();
|
||||
codegen.additionalProperties().put(JavaMicronautServerCodegen.OPT_BUILD,
|
||||
JavaMicronautServerCodegen.OPT_BUILD_ALL);
|
||||
codegen.additionalProperties().put(JavaMicronautServerCodegen.OPT_TEST,
|
||||
JavaMicronautServerCodegen.OPT_TEST_SPOCK);
|
||||
String outputPath = generateFiles(codegen, PETSTORE_PATH,
|
||||
CodegenConstants.SUPPORTING_FILES,
|
||||
CodegenConstants.API_TESTS, CodegenConstants.APIS, CodegenConstants.MODELS);
|
||||
|
||||
// Files are not generated
|
||||
assertFileNotContains(outputPath + "build.gradle", "testRuntime(\"junit");
|
||||
assertFileNotContains(outputPath + "pom.xml", "<artifactId>micronaut-test-junit");
|
||||
assertFileContains(outputPath + "build.gradle", "testRuntime(\"spock");
|
||||
assertFileContains(outputPath + "pom.xml", "<artifactId>micronaut-test-spock");
|
||||
assertFileExists(outputPath + "src/test/groovy");
|
||||
assertFileExists(outputPath + "src/test/groovy/org/openapitools/controller/PetControllerSpec.groovy");
|
||||
assertFileContains(outputPath + "src/test/groovy/org/openapitools/controller/PetControllerSpec.groovy", "PetControllerSpec", "@MicronautTest");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doGenerateRequiredPropertiesInConstructor() {
|
||||
JavaMicronautServerCodegen codegen = new JavaMicronautServerCodegen();
|
||||
codegen.additionalProperties().put(JavaMicronautServerCodegen.OPT_REQUIRED_PROPERTIES_IN_CONSTRUCTOR, "true");
|
||||
String outputPath = generateFiles(codegen, PETSTORE_PATH, CodegenConstants.MODELS, CodegenConstants.APIS);
|
||||
|
||||
// Constructor should have properties
|
||||
String modelPath = outputPath + "src/main/java/org/openapitools/model/";
|
||||
assertFileContains(modelPath + "Pet.java", "public Pet(String name, List<String> photoUrls)");
|
||||
assertFileNotContains(modelPath + "Pet.java", "public Pet()");
|
||||
assertFileContains(modelPath + "User.java", "public User()");
|
||||
assertFileContains(modelPath + "Order.java", "public Order()");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doNotGenerateRequiredPropertiesInConstructor() {
|
||||
JavaMicronautServerCodegen codegen = new JavaMicronautServerCodegen();
|
||||
codegen.additionalProperties().put(JavaMicronautServerCodegen.OPT_REQUIRED_PROPERTIES_IN_CONSTRUCTOR, "false");
|
||||
String outputPath = generateFiles(codegen, PETSTORE_PATH, CodegenConstants.MODELS, CodegenConstants.APIS);
|
||||
|
||||
// Constructor should have properties
|
||||
String modelPath = outputPath + "src/main/java/org/openapitools/model/";
|
||||
assertFileContains(modelPath + "Pet.java", "public Pet()");
|
||||
assertFileNotContainsRegex(modelPath + "Pet.java", "public Pet\\([^)]+\\)");
|
||||
assertFileContains(modelPath + "User.java", "public User()");
|
||||
assertFileNotContainsRegex(modelPath + "User.java", "public User\\([^)]+\\)");
|
||||
assertFileContains(modelPath + "Order.java", "public Order()");
|
||||
assertFileNotContainsRegex(modelPath + "Order.java", "public Order\\([^)]+\\)");
|
||||
}
|
||||
}
|
||||
12
pom.xml
12
pom.xml
@@ -735,6 +735,18 @@
|
||||
<module>samples/client/petstore/java-micronaut-client</module>
|
||||
</modules>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>java-micronaut-server</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>env</name>
|
||||
<value>java</value>
|
||||
</property>
|
||||
</activation>
|
||||
<modules>
|
||||
<module>samples/server/petstore/java-micronaut-server</module>
|
||||
</modules>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>java-msf4j-server</id>
|
||||
<activation>
|
||||
|
||||
@@ -4,61 +4,61 @@
|
||||
.mvn/wrapper/maven-wrapper.jar
|
||||
README.md
|
||||
build.gradle
|
||||
docs/AdditionalPropertiesAnyType.md
|
||||
docs/AdditionalPropertiesArray.md
|
||||
docs/AdditionalPropertiesBoolean.md
|
||||
docs/AdditionalPropertiesClass.md
|
||||
docs/AdditionalPropertiesInteger.md
|
||||
docs/AdditionalPropertiesNumber.md
|
||||
docs/AdditionalPropertiesObject.md
|
||||
docs/AdditionalPropertiesString.md
|
||||
docs/Animal.md
|
||||
docs/AnotherFakeApi.md
|
||||
docs/ArrayOfArrayOfNumberOnly.md
|
||||
docs/ArrayOfNumberOnly.md
|
||||
docs/ArrayTest.md
|
||||
docs/BigCat.md
|
||||
docs/BigCatAllOf.md
|
||||
docs/Capitalization.md
|
||||
docs/Cat.md
|
||||
docs/CatAllOf.md
|
||||
docs/Category.md
|
||||
docs/ClassModel.md
|
||||
docs/Dog.md
|
||||
docs/DogAllOf.md
|
||||
docs/EnumArrays.md
|
||||
docs/EnumClass.md
|
||||
docs/EnumTest.md
|
||||
docs/FakeApi.md
|
||||
docs/FakeClassnameTags123Api.md
|
||||
docs/FileSchemaTestClass.md
|
||||
docs/FormatTest.md
|
||||
docs/HasOnlyReadOnly.md
|
||||
docs/MapTest.md
|
||||
docs/MixedPropertiesAndAdditionalPropertiesClass.md
|
||||
docs/Model200Response.md
|
||||
docs/ModelApiResponse.md
|
||||
docs/ModelClient.md
|
||||
docs/ModelFile.md
|
||||
docs/ModelList.md
|
||||
docs/ModelReturn.md
|
||||
docs/Name.md
|
||||
docs/NumberOnly.md
|
||||
docs/Order.md
|
||||
docs/OuterComposite.md
|
||||
docs/OuterEnum.md
|
||||
docs/Pet.md
|
||||
docs/PetApi.md
|
||||
docs/ReadOnlyFirst.md
|
||||
docs/SpecialModelName.md
|
||||
docs/StoreApi.md
|
||||
docs/Tag.md
|
||||
docs/TypeHolderDefault.md
|
||||
docs/TypeHolderExample.md
|
||||
docs/User.md
|
||||
docs/UserApi.md
|
||||
docs/XmlItem.md
|
||||
docs/auth.md
|
||||
docs/apis/AnotherFakeApi.md
|
||||
docs/apis/FakeApi.md
|
||||
docs/apis/FakeClassnameTags123Api.md
|
||||
docs/apis/PetApi.md
|
||||
docs/apis/StoreApi.md
|
||||
docs/apis/UserApi.md
|
||||
docs/apis/auth.md
|
||||
docs/models/AdditionalPropertiesAnyType.md
|
||||
docs/models/AdditionalPropertiesArray.md
|
||||
docs/models/AdditionalPropertiesBoolean.md
|
||||
docs/models/AdditionalPropertiesClass.md
|
||||
docs/models/AdditionalPropertiesInteger.md
|
||||
docs/models/AdditionalPropertiesNumber.md
|
||||
docs/models/AdditionalPropertiesObject.md
|
||||
docs/models/AdditionalPropertiesString.md
|
||||
docs/models/Animal.md
|
||||
docs/models/ArrayOfArrayOfNumberOnly.md
|
||||
docs/models/ArrayOfNumberOnly.md
|
||||
docs/models/ArrayTest.md
|
||||
docs/models/BigCat.md
|
||||
docs/models/BigCatAllOf.md
|
||||
docs/models/Capitalization.md
|
||||
docs/models/Cat.md
|
||||
docs/models/CatAllOf.md
|
||||
docs/models/Category.md
|
||||
docs/models/ClassModel.md
|
||||
docs/models/Dog.md
|
||||
docs/models/DogAllOf.md
|
||||
docs/models/EnumArrays.md
|
||||
docs/models/EnumClass.md
|
||||
docs/models/EnumTest.md
|
||||
docs/models/FileSchemaTestClass.md
|
||||
docs/models/FormatTest.md
|
||||
docs/models/HasOnlyReadOnly.md
|
||||
docs/models/MapTest.md
|
||||
docs/models/MixedPropertiesAndAdditionalPropertiesClass.md
|
||||
docs/models/Model200Response.md
|
||||
docs/models/ModelApiResponse.md
|
||||
docs/models/ModelClient.md
|
||||
docs/models/ModelFile.md
|
||||
docs/models/ModelList.md
|
||||
docs/models/ModelReturn.md
|
||||
docs/models/Name.md
|
||||
docs/models/NumberOnly.md
|
||||
docs/models/Order.md
|
||||
docs/models/OuterComposite.md
|
||||
docs/models/OuterEnum.md
|
||||
docs/models/Pet.md
|
||||
docs/models/ReadOnlyFirst.md
|
||||
docs/models/SpecialModelName.md
|
||||
docs/models/Tag.md
|
||||
docs/models/TypeHolderDefault.md
|
||||
docs/models/TypeHolderExample.md
|
||||
docs/models/User.md
|
||||
docs/models/XmlItem.md
|
||||
gradle.properties
|
||||
gradle/wrapper/gradle-wrapper.jar
|
||||
gradle/wrapper/gradle-wrapper.properties
|
||||
@@ -122,6 +122,5 @@ src/main/java/org/openapitools/model/TypeHolderDefault.java
|
||||
src/main/java/org/openapitools/model/TypeHolderExample.java
|
||||
src/main/java/org/openapitools/model/User.java
|
||||
src/main/java/org/openapitools/model/XmlItem.java
|
||||
src/main/java/org/openapitools/query/QueryParam.java
|
||||
src/main/java/org/openapitools/query/QueryParamBinder.java
|
||||
src/main/resources/application.yml
|
||||
src/main/resources/logback.xml
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user