From 4a0ab21ba42f4895cd0497486d1fe979ac874f9d Mon Sep 17 00:00:00 2001 From: dabdirb Date: Thu, 5 Oct 2023 11:11:55 +0800 Subject: [PATCH] [Spring] resolves #16054, resolves #15088 add vendor extension x-spring-provide-args (#16663) * add vendor extenstion x-spring-provide-args * add vendor extenstion x-spring-provide-args * Revert "add vendor extenstion x-spring-provide-args" This reverts commit 8a0cbc93eb5825651e4b97cbe83054adbaa1acce. * catch up latest main and re-generate samples * remove un-used import * add vendor extenstion x-spring-provide-args (#16054,#15088) * update X_SPRING_PROVIDE_ARGS for better description --------- Co-authored-by: xiangxi.chen --- .github/workflows/samples-spring.yaml | 1 + ...t-petstore-server-spring-provide-args.yaml | 8 + .../openapitools/codegen/VendorExtension.java | 1 + .../codegen/languages/SpringCodegen.java | 44 +++ .../main/resources/JavaSpring/api.mustache | 4 +- .../petstore-with-spring-provide-args.yaml | 229 +++++++++++++++ .../.openapi-generator-ignore | 23 ++ .../.openapi-generator/FILES | 18 ++ .../.openapi-generator/VERSION | 1 + .../springboot-spring-provide-args/README.md | 21 ++ .../springboot-spring-provide-args/pom.xml | 80 +++++ .../OpenApiGeneratorApplication.java | 30 ++ .../org/openapitools/RFC3339DateFormat.java | 38 +++ .../java/org/openapitools/api/ApiUtil.java | 19 ++ .../java/org/openapitools/api/UserApi.java | 117 ++++++++ .../openapitools/api/UserApiController.java | 51 ++++ .../configuration/HomeController.java | 20 ++ .../configuration/SpringDocConfiguration.java | 48 +++ .../java/org/openapitools/model/Category.java | 107 +++++++ .../openapitools/model/ModelApiResponse.java | 133 +++++++++ .../java/org/openapitools/model/Order.java | 244 ++++++++++++++++ .../main/java/org/openapitools/model/Pet.java | 276 ++++++++++++++++++ .../main/java/org/openapitools/model/Tag.java | 107 +++++++ .../java/org/openapitools/model/User.java | 251 ++++++++++++++++ .../src/main/resources/application.properties | 3 + .../src/main/resources/openapi.yaml | 235 +++++++++++++++ .../OpenApiGeneratorApplicationTests.java | 13 + 27 files changed, 2121 insertions(+), 1 deletion(-) create mode 100644 bin/configs/springboot-petstore-server-spring-provide-args.yaml create mode 100644 modules/openapi-generator/src/test/resources/3_0/spring/petstore-with-spring-provide-args.yaml create mode 100644 samples/server/petstore/springboot-spring-provide-args/.openapi-generator-ignore create mode 100644 samples/server/petstore/springboot-spring-provide-args/.openapi-generator/FILES create mode 100644 samples/server/petstore/springboot-spring-provide-args/.openapi-generator/VERSION create mode 100644 samples/server/petstore/springboot-spring-provide-args/README.md create mode 100644 samples/server/petstore/springboot-spring-provide-args/pom.xml create mode 100644 samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/OpenApiGeneratorApplication.java create mode 100644 samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/RFC3339DateFormat.java create mode 100644 samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/api/ApiUtil.java create mode 100644 samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/api/UserApi.java create mode 100644 samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/api/UserApiController.java create mode 100644 samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/configuration/HomeController.java create mode 100644 samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/configuration/SpringDocConfiguration.java create mode 100644 samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/model/Category.java create mode 100644 samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/model/ModelApiResponse.java create mode 100644 samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/model/Order.java create mode 100644 samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/model/Pet.java create mode 100644 samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/model/Tag.java create mode 100644 samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/model/User.java create mode 100644 samples/server/petstore/springboot-spring-provide-args/src/main/resources/application.properties create mode 100644 samples/server/petstore/springboot-spring-provide-args/src/main/resources/openapi.yaml create mode 100644 samples/server/petstore/springboot-spring-provide-args/src/test/java/org/openapitools/OpenApiGeneratorApplicationTests.java diff --git a/.github/workflows/samples-spring.yaml b/.github/workflows/samples-spring.yaml index 2ead09e5957..8baf85b44b6 100644 --- a/.github/workflows/samples-spring.yaml +++ b/.github/workflows/samples-spring.yaml @@ -55,6 +55,7 @@ jobs: - samples/server/petstore/springboot-spring-pageable-delegatePattern - samples/server/petstore/springboot-spring-pageable-without-j8 - samples/server/petstore/springboot-spring-pageable + - samples/server/petstore/springboot-spring-provide-args steps: - uses: actions/checkout@v4 - uses: actions/setup-java@v3 diff --git a/bin/configs/springboot-petstore-server-spring-provide-args.yaml b/bin/configs/springboot-petstore-server-spring-provide-args.yaml new file mode 100644 index 00000000000..09ed7ec421b --- /dev/null +++ b/bin/configs/springboot-petstore-server-spring-provide-args.yaml @@ -0,0 +1,8 @@ +generatorName: spring +outputDir: samples/server/petstore/springboot-spring-provide-args +library: spring-boot +inputSpec: modules/openapi-generator/src/test/resources/3_0/spring/petstore-with-spring-provide-args.yaml +templateDir: modules/openapi-generator/src/main/resources/JavaSpring +additionalProperties: + artifactId: springboot-spring-provide-args + hideGenerationTimestamp: 'true' diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/VendorExtension.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/VendorExtension.java index 8ca9f11663a..8fb9ce1bdae 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/VendorExtension.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/VendorExtension.java @@ -7,6 +7,7 @@ public enum VendorExtension { X_IMPLEMENTS("x-implements", ExtensionLevel.MODEL, "Ability to specify interfaces that model must implements", "empty array"), X_SPRING_PAGINATED("x-spring-paginated", ExtensionLevel.OPERATION, "Add org.springframework.data.domain.Pageable to controller method. Can be used to handle page & size query parameters", "false"), + X_SPRING_PROVIDE_ARGS("x-spring-provide-args", ExtensionLevel.OPERATION, "Allows adding additional hidden parameters in the API specification to allow access to content such as header values or properties", "empty array"), X_DISCRIMINATOR_VALUE("x-discriminator-value", ExtensionLevel.MODEL, "Used with model inheritance to specify value for discriminator that identifies current model", ""), X_SETTER_EXTRA_ANNOTATION("x-setter-extra-annotation", ExtensionLevel.FIELD, "Custom annotation that can be specified over java setter for specific field", "When field is array & uniqueItems, then this extension is used to add `@JsonDeserialize(as = LinkedHashSet.class)` over setter, otherwise no value"), X_WEBCLIENT_BLOCKING("x-webclient-blocking", ExtensionLevel.OPERATION, "Specifies if method for specific operation should be blocking or non-blocking(ex: return `Mono/Flux` or `return T/List/Set` & execute `.block()` inside generated method)", "false"), diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java index 8d10dbd6484..92a8883d33f 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java @@ -25,6 +25,7 @@ import java.io.File; import java.net.URL; import java.util.*; import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; @@ -1238,6 +1239,8 @@ public class SpringCodegen extends AbstractJavaCodegen importMapping.put("Pageable", "org.springframework.data.domain.Pageable"); } + Set provideArgsClassSet = reformatProvideArgsParams(operation); + CodegenOperation codegenOperation = super.fromOperation(path, httpMethod, operation, servers); // add org.springframework.format.annotation.DateTimeFormat when needed @@ -1254,6 +1257,9 @@ public class SpringCodegen extends AbstractJavaCodegen codegenOperation.imports.add("ParameterObject"); } } + if (codegenOperation.vendorExtensions.containsKey("x-spring-provide-args") && !provideArgsClassSet.isEmpty()) { + codegenOperation.imports.addAll(provideArgsClassSet); + } if (reactive) { if (DocumentationProvider.SPRINGFOX.equals(getDocumentationProvider())) { @@ -1307,6 +1313,44 @@ public class SpringCodegen extends AbstractJavaCodegen return codegenOperation; } + private Set reformatProvideArgsParams(Operation operation) { + Set provideArgsClassSet = new HashSet<>(); + Object argObj = operation.getExtensions().get("x-spring-provide-args"); + if (argObj instanceof List) { + List provideArgs = (List) argObj; + if (!provideArgs.isEmpty()) { + List formatedArgs = new ArrayList<>(); + for (String oneArg : provideArgs) { + if (StringUtils.isNotEmpty(oneArg)) { + String regexp = "(?@)?(?(?(\\w+\\.)*)(?\\w+))(?\\(.*?\\))?\\s?"; + Matcher matcher = Pattern.compile(regexp).matcher(oneArg); + List newArgs = new ArrayList<>(); + while (matcher.find()) { + String className = matcher.group("ClassName"); + String classPath = matcher.group("ClassPath"); + String packageName = matcher.group("PackageName"); + String params = matcher.group("Params"); + String annoTag = matcher.group("AnnotationTag"); + String shortPhrase = StringUtils.join(annoTag, className, params); + newArgs.add(shortPhrase); + if (StringUtils.isNotEmpty(packageName)) { + importMapping.put(className, classPath); + provideArgsClassSet.add(className); + LOGGER.trace("put import mapping {} {}", className, classPath); + } + } + String newArg = String.join(" ", newArgs); + LOGGER.trace("new arg {} {}", newArg); + formatedArgs.add(newArg); + } + } + operation.getExtensions().put("x-spring-provide-args", formatedArgs); + } + } + return provideArgsClassSet; + } + + @Override public ModelsMap postProcessModelsEnum(ModelsMap objs) { objs = super.postProcessModelsEnum(objs); diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/api.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/api.mustache index 9c74f70469e..712b7b6ccc5 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/api.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/api.mustache @@ -251,7 +251,9 @@ public interface {{classname}} { {{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{>cookieParams}}{{^-last}}, {{/-last}}{{/allParams}}{{#reactive}}{{#hasParams}}, {{/hasParams}}{{#swagger2AnnotationLibrary}}@Parameter(hidden = true){{/swagger2AnnotationLibrary}}{{#springFoxDocumentationProvider}}@ApiIgnore{{/springFoxDocumentationProvider}} final ServerWebExchange exchange{{/reactive}}{{#vendorExtensions.x-spring-paginated}}{{#hasParams}}, - {{/hasParams}}{{^hasParams}}{{#reactive}},{{/reactive}}{{/hasParams}}{{#springFoxDocumentationProvider}}@ApiIgnore {{/springFoxDocumentationProvider}}{{#springDocDocumentationProvider}}@ParameterObject {{/springDocDocumentationProvider}}final Pageable pageable{{/vendorExtensions.x-spring-paginated}} + {{/hasParams}}{{^hasParams}}{{#reactive}},{{/reactive}}{{/hasParams}}{{#springFoxDocumentationProvider}}@ApiIgnore {{/springFoxDocumentationProvider}}{{#springDocDocumentationProvider}}@ParameterObject {{/springDocDocumentationProvider}}final Pageable pageable{{/vendorExtensions.x-spring-paginated}}{{#vendorExtensions.x-spring-provide-args}}{{#hasParams}}, + {{/hasParams}}{{^hasParams}}{{#reactive}},{{/reactive}}{{/hasParams}}{{#swagger2AnnotationLibrary}}@Parameter(hidden = true){{/swagger2AnnotationLibrary}}{{#springFoxDocumentationProvider}}@ApiIgnore{{/springFoxDocumentationProvider}} {{{.}}}{{^hasParams}}{{^-last}}{{^reactive}},{{/reactive}} + {{/-last}}{{/hasParams}}{{/vendorExtensions.x-spring-provide-args}} ){{#unhandledException}} throws Exception{{/unhandledException}}{{^jdk8-default-interface}};{{/jdk8-default-interface}}{{#jdk8-default-interface}} { {{#delegate-method}} {{^isVoid}}return {{/isVoid}}{{#isVoid}}{{#useResponseEntity}}return {{/useResponseEntity}}{{^useResponseEntity}}{{#reactive}}return {{/reactive}}{{/useResponseEntity}}{{/isVoid}}{{operationId}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#reactive}}{{#hasParams}}, {{/hasParams}}exchange{{/reactive}}{{#vendorExtensions.x-spring-paginated}}{{#hasParams}}, {{/hasParams}}{{^hasParams}}{{#reactive}}, {{/reactive}}{{/hasParams}}pageable{{/vendorExtensions.x-spring-paginated}}); diff --git a/modules/openapi-generator/src/test/resources/3_0/spring/petstore-with-spring-provide-args.yaml b/modules/openapi-generator/src/test/resources/3_0/spring/petstore-with-spring-provide-args.yaml new file mode 100644 index 00000000000..b425f5b1325 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/spring/petstore-with-spring-provide-args.yaml @@ -0,0 +1,229 @@ +swagger: '2.0' +info: + description: 'This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.' + version: 1.0.6 + title: Swagger Petstore + termsOfService: http://swagger.io/terms/ + contact: + email: apiteam@swagger.io + license: + name: Apache 2.0 + url: http://www.apache.org/licenses/LICENSE-2.0.html +host: petstore.swagger.io +basePath: /v2 +tags: + - name: pet + description: Everything about your Pets + externalDocs: + description: Find out more + url: http://swagger.io + - name: store + description: Access to Petstore orders + - name: user + description: Operations about user + externalDocs: + description: Find out more about our store + url: http://swagger.io +schemes: + - https + - http +paths: + /user/login: + get: + tags: + - user + summary: Logs user into the system + description: '' + operationId: loginUser + produces: + - application/json + parameters: + - name: username + in: query + description: The user name for login + required: true + type: string + - name: password + in: query + description: The password for login in clear text + required: true + type: string + responses: + '200': + description: successful operation + headers: + X-Expires-After: + type: string + format: date-time + description: date in UTC when token expires + X-Rate-Limit: + type: integer + format: int32 + description: calls per hour allowed by the user + schema: + type: string + '400': + description: Invalid username/password supplied + x-spring-provide-args: + - '@org.springframework.beans.factory.annotation.Value("${server.port}") String someValue' + - '@RequestHeader(value="x-project-id", required = false) String someHeaderValue' + - '@RequestHeader final HttpHeaders headers' + - 'java.security.Principal principal' + - '@org.springframework.beans.factory.annotation.Qualifier("jacksonObjectMapper") com.fasterxml.jackson.databind.ObjectMapper mapper' + + /user/logout: + get: + tags: + - user + summary: Logs out current logged in user session + description: '' + operationId: logoutUser + produces: + - application/json + parameters: [] + responses: + default: + description: successful operation + x-spring-provide-args: + - '@org.springframework.beans.factory.annotation.Value("${server.port}") String somePropertyValue' + - '@RequestHeader(value="x-project-id", required = false) String someHeaderValue' + - '@RequestHeader final org.springframework.http.HttpHeaders headers' + - 'java.security.Principal principal' + - '@org.springframework.beans.factory.annotation.Qualifier("jacksonObjectMapper") com.fasterxml.jackson.databind.ObjectMapper mapper' + + +securityDefinitions: + api_key: + type: apiKey + name: api_key + in: header + petstore_auth: + type: oauth2 + authorizationUrl: https://petstore.swagger.io/oauth/authorize + flow: implicit + scopes: + read:pets: read your pets + write:pets: modify pets in your account +definitions: + ApiResponse: + type: object + properties: + code: + type: integer + format: int32 + type: + type: string + message: + type: string + Category: + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + xml: + name: Category + Pet: + type: object + required: + - name + - photoUrls + properties: + id: + type: integer + format: int64 + category: + $ref: '#/definitions/Category' + name: + type: string + example: doggie + photoUrls: + type: array + xml: + wrapped: true + items: + type: string + xml: + name: photoUrl + tags: + type: array + xml: + wrapped: true + items: + xml: + name: tag + $ref: '#/definitions/Tag' + status: + type: string + description: pet status in the store + enum: + - available + - pending + - sold + xml: + name: Pet + Tag: + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + xml: + name: Tag + Order: + type: object + properties: + id: + type: integer + format: int64 + petId: + type: integer + format: int64 + quantity: + type: integer + format: int32 + shipDate: + type: string + format: date-time + status: + type: string + description: Order Status + enum: + - placed + - approved + - delivered + complete: + type: boolean + xml: + name: Order + User: + type: object + properties: + id: + type: integer + format: int64 + username: + type: string + firstName: + type: string + lastName: + type: string + email: + type: string + password: + type: string + phone: + type: string + userStatus: + type: integer + format: int32 + description: User Status + xml: + name: User +externalDocs: + description: Find out more about Swagger + url: http://swagger.io diff --git a/samples/server/petstore/springboot-spring-provide-args/.openapi-generator-ignore b/samples/server/petstore/springboot-spring-provide-args/.openapi-generator-ignore new file mode 100644 index 00000000000..7484ee590a3 --- /dev/null +++ b/samples/server/petstore/springboot-spring-provide-args/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/server/petstore/springboot-spring-provide-args/.openapi-generator/FILES b/samples/server/petstore/springboot-spring-provide-args/.openapi-generator/FILES new file mode 100644 index 00000000000..86abe7f3936 --- /dev/null +++ b/samples/server/petstore/springboot-spring-provide-args/.openapi-generator/FILES @@ -0,0 +1,18 @@ +README.md +pom.xml +src/main/java/org/openapitools/OpenApiGeneratorApplication.java +src/main/java/org/openapitools/RFC3339DateFormat.java +src/main/java/org/openapitools/api/ApiUtil.java +src/main/java/org/openapitools/api/UserApi.java +src/main/java/org/openapitools/api/UserApiController.java +src/main/java/org/openapitools/configuration/HomeController.java +src/main/java/org/openapitools/configuration/SpringDocConfiguration.java +src/main/java/org/openapitools/model/Category.java +src/main/java/org/openapitools/model/ModelApiResponse.java +src/main/java/org/openapitools/model/Order.java +src/main/java/org/openapitools/model/Pet.java +src/main/java/org/openapitools/model/Tag.java +src/main/java/org/openapitools/model/User.java +src/main/resources/application.properties +src/main/resources/openapi.yaml +src/test/java/org/openapitools/OpenApiGeneratorApplicationTests.java diff --git a/samples/server/petstore/springboot-spring-provide-args/.openapi-generator/VERSION b/samples/server/petstore/springboot-spring-provide-args/.openapi-generator/VERSION new file mode 100644 index 00000000000..40e36364ab2 --- /dev/null +++ b/samples/server/petstore/springboot-spring-provide-args/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.1.0-SNAPSHOT \ No newline at end of file diff --git a/samples/server/petstore/springboot-spring-provide-args/README.md b/samples/server/petstore/springboot-spring-provide-args/README.md new file mode 100644 index 00000000000..5cd22b6081a --- /dev/null +++ b/samples/server/petstore/springboot-spring-provide-args/README.md @@ -0,0 +1,21 @@ +# OpenAPI generated server + +Spring Boot Server + +## Overview +This server was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. +By using the [OpenAPI-Spec](https://openapis.org), you can easily generate a server stub. +This is an example of building a OpenAPI-enabled server in Java using the SpringBoot framework. + + +The underlying library integrating OpenAPI to Spring Boot is [springdoc](https://springdoc.org). +Springdoc will generate an OpenAPI v3 specification based on the generated Controller and Model classes. +The specification is available to download using the following url: +http://localhost:8080/v3/api-docs/ + +Start your server as a simple java application + +You can view the api documentation in swagger-ui by pointing to +http://localhost:8080/swagger-ui.html + +Change default port value in application.properties \ No newline at end of file diff --git a/samples/server/petstore/springboot-spring-provide-args/pom.xml b/samples/server/petstore/springboot-spring-provide-args/pom.xml new file mode 100644 index 00000000000..9ae17d6bf86 --- /dev/null +++ b/samples/server/petstore/springboot-spring-provide-args/pom.xml @@ -0,0 +1,80 @@ + + 4.0.0 + org.openapitools + springboot-spring-provide-args + jar + springboot-spring-provide-args + 1.0.6 + + 1.8 + ${java.version} + ${java.version} + UTF-8 + 1.6.14 + 4.15.5 + + + org.springframework.boot + spring-boot-starter-parent + 2.7.6 + + + + src/main/java + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.data + spring-data-commons + + + + org.springdoc + springdoc-openapi-ui + ${springdoc.version} + + + + com.google.code.findbugs + jsr305 + 3.0.2 + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + + + org.openapitools + jackson-databind-nullable + 0.2.6 + + + + org.springframework.boot + spring-boot-starter-validation + + + com.fasterxml.jackson.core + jackson-databind + + + org.springframework.boot + spring-boot-starter-test + test + + + diff --git a/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/OpenApiGeneratorApplication.java b/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/OpenApiGeneratorApplication.java new file mode 100644 index 00000000000..97252a8a940 --- /dev/null +++ b/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/OpenApiGeneratorApplication.java @@ -0,0 +1,30 @@ +package org.openapitools; + +import com.fasterxml.jackson.databind.Module; +import org.openapitools.jackson.nullable.JsonNullableModule; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.FilterType; +import org.springframework.context.annotation.FullyQualifiedAnnotationBeanNameGenerator; + +@SpringBootApplication( + nameGenerator = FullyQualifiedAnnotationBeanNameGenerator.class +) +@ComponentScan( + basePackages = {"org.openapitools", "org.openapitools.api" , "org.openapitools.configuration"}, + nameGenerator = FullyQualifiedAnnotationBeanNameGenerator.class +) +public class OpenApiGeneratorApplication { + + public static void main(String[] args) { + SpringApplication.run(OpenApiGeneratorApplication.class, args); + } + + @Bean(name = "org.openapitools.OpenApiGeneratorApplication.jsonNullableModule") + public Module jsonNullableModule() { + return new JsonNullableModule(); + } + +} \ No newline at end of file diff --git a/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/RFC3339DateFormat.java b/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/RFC3339DateFormat.java new file mode 100644 index 00000000000..bcd3936d8b3 --- /dev/null +++ b/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/RFC3339DateFormat.java @@ -0,0 +1,38 @@ +package org.openapitools; + +import com.fasterxml.jackson.databind.util.StdDateFormat; + +import java.text.DateFormat; +import java.text.FieldPosition; +import java.text.ParsePosition; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.TimeZone; + +public class RFC3339DateFormat extends DateFormat { + private static final long serialVersionUID = 1L; + private static final TimeZone TIMEZONE_Z = TimeZone.getTimeZone("UTC"); + + private final StdDateFormat fmt = new StdDateFormat() + .withTimeZone(TIMEZONE_Z) + .withColonInTimeZone(true); + + public RFC3339DateFormat() { + this.calendar = new GregorianCalendar(); + } + + @Override + public Date parse(String source, ParsePosition pos) { + return fmt.parse(source, pos); + } + + @Override + public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) { + return fmt.format(date, toAppendTo, fieldPosition); + } + + @Override + public Object clone() { + return this; + } +} \ No newline at end of file diff --git a/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/api/ApiUtil.java b/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/api/ApiUtil.java new file mode 100644 index 00000000000..1245b1dd0cc --- /dev/null +++ b/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/api/ApiUtil.java @@ -0,0 +1,19 @@ +package org.openapitools.api; + +import org.springframework.web.context.request.NativeWebRequest; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class ApiUtil { + public static void setExampleResponse(NativeWebRequest req, String contentType, String example) { + try { + HttpServletResponse res = req.getNativeResponse(HttpServletResponse.class); + res.setCharacterEncoding("UTF-8"); + res.addHeader("Content-Type", contentType); + res.getWriter().print(example); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/api/UserApi.java b/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/api/UserApi.java new file mode 100644 index 00000000000..a7bef45dc8a --- /dev/null +++ b/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/api/UserApi.java @@ -0,0 +1,117 @@ +/** + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) (7.1.0-SNAPSHOT). + * https://openapi-generator.tech + * Do not edit the class manually. + */ +package org.openapitools.api; + +import org.springframework.http.HttpHeaders; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.time.OffsetDateTime; +import java.security.Principal; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import io.swagger.v3.oas.annotations.ExternalDocumentation; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.enums.ParameterIn; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.multipart.MultipartFile; + +import javax.validation.Valid; +import javax.validation.constraints.*; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import javax.annotation.Generated; + +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen") +@Validated +@Tag(name = "user", description = "Operations about user") +public interface UserApi { + + default Optional getRequest() { + return Optional.empty(); + } + + /** + * GET /user/login : Logs user into the system + * + * @param username The user name for login (required) + * @param password The password for login in clear text (required) + * @return successful operation (status code 200) + * or Invalid username/password supplied (status code 400) + */ + @Operation( + operationId = "loginUser", + summary = "Logs user into the system", + tags = { "user" }, + responses = { + @ApiResponse(responseCode = "200", description = "successful operation", content = { + @Content(mediaType = "application/json", schema = @Schema(implementation = String.class)) + }), + @ApiResponse(responseCode = "400", description = "Invalid username/password supplied") + } + ) + @RequestMapping( + method = RequestMethod.GET, + value = "/user/login", + produces = { "application/json" } + ) + + default ResponseEntity loginUser( + @NotNull @Parameter(name = "username", description = "The user name for login", required = true, in = ParameterIn.QUERY) @Valid @RequestParam(value = "username", required = true) String username, + @NotNull @Parameter(name = "password", description = "The password for login in clear text", required = true, in = ParameterIn.QUERY) @Valid @RequestParam(value = "password", required = true) String password, + @Parameter(hidden = true) @Value("${server.port}") String someValue, + @Parameter(hidden = true) @RequestHeader(value="x-project-id", required = false) String someHeaderValue, + @Parameter(hidden = true) @RequestHeader final HttpHeaders headers, + @Parameter(hidden = true) Principal principal, + @Parameter(hidden = true) @Qualifier("jacksonObjectMapper") ObjectMapper mapper + ) { + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + + } + + + /** + * GET /user/logout : Logs out current logged in user session + * + * @return successful operation (status code 200) + */ + @Operation( + operationId = "logoutUser", + summary = "Logs out current logged in user session", + tags = { "user" }, + responses = { + @ApiResponse(responseCode = "default", description = "successful operation") + } + ) + @RequestMapping( + method = RequestMethod.GET, + value = "/user/logout" + ) + + default ResponseEntity logoutUser( + @Parameter(hidden = true) @Value("${server.port}") String somePropertyValue, + @Parameter(hidden = true) @RequestHeader(value="x-project-id", required = false) String someHeaderValue, + @Parameter(hidden = true) @RequestHeader final HttpHeaders headers, + @Parameter(hidden = true) Principal principal, + @Parameter(hidden = true) @Qualifier("jacksonObjectMapper") ObjectMapper mapper + ) { + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + + } + +} diff --git a/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/api/UserApiController.java b/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/api/UserApiController.java new file mode 100644 index 00000000000..17e1190b4ee --- /dev/null +++ b/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/api/UserApiController.java @@ -0,0 +1,51 @@ +package org.openapitools.api; + +import org.springframework.http.HttpHeaders; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.time.OffsetDateTime; +import java.security.Principal; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; + + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.CookieValue; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.context.request.NativeWebRequest; + +import javax.validation.constraints.*; +import javax.validation.Valid; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import javax.annotation.Generated; + +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen") +@Controller +@RequestMapping("${openapi.swaggerPetstore.base-path:/v2}") +public class UserApiController implements UserApi { + + private final NativeWebRequest request; + + @Autowired + public UserApiController(NativeWebRequest request) { + this.request = request; + } + + @Override + public Optional getRequest() { + return Optional.ofNullable(request); + } + +} diff --git a/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/configuration/HomeController.java b/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/configuration/HomeController.java new file mode 100644 index 00000000000..9aa29284ab5 --- /dev/null +++ b/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/configuration/HomeController.java @@ -0,0 +1,20 @@ +package org.openapitools.configuration; + +import org.springframework.context.annotation.Bean; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.GetMapping; + +/** + * Home redirection to OpenAPI api documentation + */ +@Controller +public class HomeController { + + @RequestMapping("/") + public String index() { + return "redirect:swagger-ui.html"; + } + +} \ No newline at end of file diff --git a/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/configuration/SpringDocConfiguration.java b/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/configuration/SpringDocConfiguration.java new file mode 100644 index 00000000000..f2d486ac4de --- /dev/null +++ b/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/configuration/SpringDocConfiguration.java @@ -0,0 +1,48 @@ +package org.openapitools.configuration; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.info.Contact; +import io.swagger.v3.oas.models.info.License; +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.security.SecurityScheme; + +@Configuration +public class SpringDocConfiguration { + + @Bean(name = "org.openapitools.configuration.SpringDocConfiguration.apiInfo") + OpenAPI apiInfo() { + return new OpenAPI() + .info( + new Info() + .title("Swagger Petstore") + .description("This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.") + .termsOfService("http://swagger.io/terms/") + .contact( + new Contact() + .email("apiteam@swagger.io") + ) + .license( + new License() + .name("Apache 2.0") + .url("http://www.apache.org/licenses/LICENSE-2.0.html") + ) + .version("1.0.6") + ) + .components( + new Components() + .addSecuritySchemes("api_key", new SecurityScheme() + .type(SecurityScheme.Type.APIKEY) + .in(SecurityScheme.In.HEADER) + .name("api_key") + ) + .addSecuritySchemes("petstore_auth", new SecurityScheme() + .type(SecurityScheme.Type.OAUTH2) + ) + ) + ; + } +} \ No newline at end of file diff --git a/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/model/Category.java b/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/model/Category.java new file mode 100644 index 00000000000..3ed41dcb7d1 --- /dev/null +++ b/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/model/Category.java @@ -0,0 +1,107 @@ +package org.openapitools.model; + +import java.net.URI; +import java.util.Objects; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import org.openapitools.jackson.nullable.JsonNullable; +import java.time.OffsetDateTime; +import javax.validation.Valid; +import javax.validation.constraints.*; +import io.swagger.v3.oas.annotations.media.Schema; + + +import java.util.*; +import javax.annotation.Generated; + +/** + * Category + */ + +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen") +public class Category { + + private Long id; + + private String name; + + public Category id(Long id) { + this.id = id; + return this; + } + + /** + * Get id + * @return id + */ + + @Schema(name = "id", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("id") + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Category name(String name) { + this.name = name; + return this; + } + + /** + * Get name + * @return name + */ + + @Schema(name = "name", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("name") + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Category category = (Category) o; + return Objects.equals(this.id, category.id) && + Objects.equals(this.name, category.name); + } + + @Override + public int hashCode() { + return Objects.hash(id, name); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Category {\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/model/ModelApiResponse.java b/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/model/ModelApiResponse.java new file mode 100644 index 00000000000..0a803038551 --- /dev/null +++ b/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/model/ModelApiResponse.java @@ -0,0 +1,133 @@ +package org.openapitools.model; + +import java.net.URI; +import java.util.Objects; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import org.openapitools.jackson.nullable.JsonNullable; +import java.time.OffsetDateTime; +import javax.validation.Valid; +import javax.validation.constraints.*; +import io.swagger.v3.oas.annotations.media.Schema; + + +import java.util.*; +import javax.annotation.Generated; + +/** + * ModelApiResponse + */ + +@JsonTypeName("ApiResponse") +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen") +public class ModelApiResponse { + + private Integer code; + + private String type; + + private String message; + + public ModelApiResponse code(Integer code) { + this.code = code; + return this; + } + + /** + * Get code + * @return code + */ + + @Schema(name = "code", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("code") + public Integer getCode() { + return code; + } + + public void setCode(Integer code) { + this.code = code; + } + + public ModelApiResponse type(String type) { + this.type = type; + return this; + } + + /** + * Get type + * @return type + */ + + @Schema(name = "type", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("type") + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public ModelApiResponse message(String message) { + this.message = message; + return this; + } + + /** + * Get message + * @return message + */ + + @Schema(name = "message", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("message") + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ModelApiResponse _apiResponse = (ModelApiResponse) o; + return Objects.equals(this.code, _apiResponse.code) && + Objects.equals(this.type, _apiResponse.type) && + Objects.equals(this.message, _apiResponse.message); + } + + @Override + public int hashCode() { + return Objects.hash(code, type, message); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ModelApiResponse {\n"); + sb.append(" code: ").append(toIndentedString(code)).append("\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append(" message: ").append(toIndentedString(message)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/model/Order.java b/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/model/Order.java new file mode 100644 index 00000000000..92f77c39e51 --- /dev/null +++ b/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/model/Order.java @@ -0,0 +1,244 @@ +package org.openapitools.model; + +import java.net.URI; +import java.util.Objects; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import java.time.OffsetDateTime; +import org.springframework.format.annotation.DateTimeFormat; +import org.openapitools.jackson.nullable.JsonNullable; +import java.time.OffsetDateTime; +import javax.validation.Valid; +import javax.validation.constraints.*; +import io.swagger.v3.oas.annotations.media.Schema; + + +import java.util.*; +import javax.annotation.Generated; + +/** + * Order + */ + +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen") +public class Order { + + private Long id; + + private Long petId; + + private Integer quantity; + + @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) + private OffsetDateTime shipDate; + + /** + * Order Status + */ + public enum StatusEnum { + PLACED("placed"), + + APPROVED("approved"), + + DELIVERED("delivered"); + + private String value; + + StatusEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static StatusEnum fromValue(String value) { + for (StatusEnum b : StatusEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + } + + private StatusEnum status; + + private Boolean complete; + + public Order id(Long id) { + this.id = id; + return this; + } + + /** + * Get id + * @return id + */ + + @Schema(name = "id", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("id") + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Order petId(Long petId) { + this.petId = petId; + return this; + } + + /** + * Get petId + * @return petId + */ + + @Schema(name = "petId", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("petId") + public Long getPetId() { + return petId; + } + + public void setPetId(Long petId) { + this.petId = petId; + } + + public Order quantity(Integer quantity) { + this.quantity = quantity; + return this; + } + + /** + * Get quantity + * @return quantity + */ + + @Schema(name = "quantity", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("quantity") + public Integer getQuantity() { + return quantity; + } + + public void setQuantity(Integer quantity) { + this.quantity = quantity; + } + + public Order shipDate(OffsetDateTime shipDate) { + this.shipDate = shipDate; + return this; + } + + /** + * Get shipDate + * @return shipDate + */ + @Valid + @Schema(name = "shipDate", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("shipDate") + public OffsetDateTime getShipDate() { + return shipDate; + } + + public void setShipDate(OffsetDateTime shipDate) { + this.shipDate = shipDate; + } + + public Order status(StatusEnum status) { + this.status = status; + return this; + } + + /** + * Order Status + * @return status + */ + + @Schema(name = "status", description = "Order Status", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("status") + public StatusEnum getStatus() { + return status; + } + + public void setStatus(StatusEnum status) { + this.status = status; + } + + public Order complete(Boolean complete) { + this.complete = complete; + return this; + } + + /** + * Get complete + * @return complete + */ + + @Schema(name = "complete", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("complete") + public Boolean getComplete() { + return complete; + } + + public void setComplete(Boolean complete) { + this.complete = complete; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Order order = (Order) o; + return Objects.equals(this.id, order.id) && + Objects.equals(this.petId, order.petId) && + Objects.equals(this.quantity, order.quantity) && + Objects.equals(this.shipDate, order.shipDate) && + Objects.equals(this.status, order.status) && + Objects.equals(this.complete, order.complete); + } + + @Override + public int hashCode() { + return Objects.hash(id, petId, quantity, shipDate, status, complete); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Order {\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" petId: ").append(toIndentedString(petId)).append("\n"); + sb.append(" quantity: ").append(toIndentedString(quantity)).append("\n"); + sb.append(" shipDate: ").append(toIndentedString(shipDate)).append("\n"); + sb.append(" status: ").append(toIndentedString(status)).append("\n"); + sb.append(" complete: ").append(toIndentedString(complete)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/model/Pet.java b/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/model/Pet.java new file mode 100644 index 00000000000..9d47cc0f584 --- /dev/null +++ b/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/model/Pet.java @@ -0,0 +1,276 @@ +package org.openapitools.model; + +import java.net.URI; +import java.util.Objects; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.openapitools.model.Category; +import org.openapitools.model.Tag; +import org.openapitools.jackson.nullable.JsonNullable; +import java.time.OffsetDateTime; +import javax.validation.Valid; +import javax.validation.constraints.*; +import io.swagger.v3.oas.annotations.media.Schema; + + +import java.util.*; +import javax.annotation.Generated; + +/** + * Pet + */ + +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen") +public class Pet { + + private Long id; + + private Category category; + + private String name; + + @Valid + private List photoUrls = new ArrayList<>(); + + @Valid + private List<@Valid Tag> tags; + + /** + * pet status in the store + */ + public enum StatusEnum { + AVAILABLE("available"), + + PENDING("pending"), + + SOLD("sold"); + + private String value; + + StatusEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static StatusEnum fromValue(String value) { + for (StatusEnum b : StatusEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + } + + private StatusEnum status; + + public Pet() { + super(); + } + + /** + * Constructor with only required parameters + */ + public Pet(String name, List photoUrls) { + this.name = name; + this.photoUrls = photoUrls; + } + + public Pet id(Long id) { + this.id = id; + return this; + } + + /** + * Get id + * @return id + */ + + @Schema(name = "id", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("id") + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Pet category(Category category) { + this.category = category; + return this; + } + + /** + * Get category + * @return category + */ + @Valid + @Schema(name = "category", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("category") + public Category getCategory() { + return category; + } + + public void setCategory(Category category) { + this.category = category; + } + + public Pet name(String name) { + this.name = name; + return this; + } + + /** + * Get name + * @return name + */ + @NotNull + @Schema(name = "name", example = "doggie", requiredMode = Schema.RequiredMode.REQUIRED) + @JsonProperty("name") + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Pet photoUrls(List photoUrls) { + this.photoUrls = photoUrls; + return this; + } + + public Pet addPhotoUrlsItem(String photoUrlsItem) { + if (this.photoUrls == null) { + this.photoUrls = new ArrayList<>(); + } + this.photoUrls.add(photoUrlsItem); + return this; + } + + /** + * Get photoUrls + * @return photoUrls + */ + @NotNull + @Schema(name = "photoUrls", requiredMode = Schema.RequiredMode.REQUIRED) + @JsonProperty("photoUrls") + public List getPhotoUrls() { + return photoUrls; + } + + public void setPhotoUrls(List photoUrls) { + this.photoUrls = photoUrls; + } + + public Pet tags(List<@Valid Tag> tags) { + this.tags = tags; + return this; + } + + public Pet addTagsItem(Tag tagsItem) { + if (this.tags == null) { + this.tags = new ArrayList<>(); + } + this.tags.add(tagsItem); + return this; + } + + /** + * Get tags + * @return tags + */ + @Valid + @Schema(name = "tags", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("tags") + public List<@Valid Tag> getTags() { + return tags; + } + + public void setTags(List<@Valid Tag> tags) { + this.tags = tags; + } + + public Pet status(StatusEnum status) { + this.status = status; + return this; + } + + /** + * pet status in the store + * @return status + */ + + @Schema(name = "status", description = "pet status in the store", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("status") + public StatusEnum getStatus() { + return status; + } + + public void setStatus(StatusEnum status) { + this.status = status; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Pet pet = (Pet) o; + return Objects.equals(this.id, pet.id) && + Objects.equals(this.category, pet.category) && + Objects.equals(this.name, pet.name) && + Objects.equals(this.photoUrls, pet.photoUrls) && + Objects.equals(this.tags, pet.tags) && + Objects.equals(this.status, pet.status); + } + + @Override + public int hashCode() { + return Objects.hash(id, category, name, photoUrls, tags, status); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Pet {\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" category: ").append(toIndentedString(category)).append("\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" photoUrls: ").append(toIndentedString(photoUrls)).append("\n"); + sb.append(" tags: ").append(toIndentedString(tags)).append("\n"); + sb.append(" status: ").append(toIndentedString(status)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/model/Tag.java b/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/model/Tag.java new file mode 100644 index 00000000000..b6dd153652a --- /dev/null +++ b/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/model/Tag.java @@ -0,0 +1,107 @@ +package org.openapitools.model; + +import java.net.URI; +import java.util.Objects; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import org.openapitools.jackson.nullable.JsonNullable; +import java.time.OffsetDateTime; +import javax.validation.Valid; +import javax.validation.constraints.*; +import io.swagger.v3.oas.annotations.media.Schema; + + +import java.util.*; +import javax.annotation.Generated; + +/** + * Tag + */ + +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen") +public class Tag { + + private Long id; + + private String name; + + public Tag id(Long id) { + this.id = id; + return this; + } + + /** + * Get id + * @return id + */ + + @Schema(name = "id", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("id") + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Tag name(String name) { + this.name = name; + return this; + } + + /** + * Get name + * @return name + */ + + @Schema(name = "name", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("name") + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Tag tag = (Tag) o; + return Objects.equals(this.id, tag.id) && + Objects.equals(this.name, tag.name); + } + + @Override + public int hashCode() { + return Objects.hash(id, name); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Tag {\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/model/User.java b/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/model/User.java new file mode 100644 index 00000000000..cf6f9233680 --- /dev/null +++ b/samples/server/petstore/springboot-spring-provide-args/src/main/java/org/openapitools/model/User.java @@ -0,0 +1,251 @@ +package org.openapitools.model; + +import java.net.URI; +import java.util.Objects; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import org.openapitools.jackson.nullable.JsonNullable; +import java.time.OffsetDateTime; +import javax.validation.Valid; +import javax.validation.constraints.*; +import io.swagger.v3.oas.annotations.media.Schema; + + +import java.util.*; +import javax.annotation.Generated; + +/** + * User + */ + +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen") +public class User { + + private Long id; + + private String username; + + private String firstName; + + private String lastName; + + private String email; + + private String password; + + private String phone; + + private Integer userStatus; + + public User id(Long id) { + this.id = id; + return this; + } + + /** + * Get id + * @return id + */ + + @Schema(name = "id", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("id") + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public User username(String username) { + this.username = username; + return this; + } + + /** + * Get username + * @return username + */ + + @Schema(name = "username", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("username") + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public User firstName(String firstName) { + this.firstName = firstName; + return this; + } + + /** + * Get firstName + * @return firstName + */ + + @Schema(name = "firstName", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("firstName") + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public User lastName(String lastName) { + this.lastName = lastName; + return this; + } + + /** + * Get lastName + * @return lastName + */ + + @Schema(name = "lastName", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("lastName") + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public User email(String email) { + this.email = email; + return this; + } + + /** + * Get email + * @return email + */ + + @Schema(name = "email", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("email") + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public User password(String password) { + this.password = password; + return this; + } + + /** + * Get password + * @return password + */ + + @Schema(name = "password", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("password") + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public User phone(String phone) { + this.phone = phone; + return this; + } + + /** + * Get phone + * @return phone + */ + + @Schema(name = "phone", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("phone") + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public User userStatus(Integer userStatus) { + this.userStatus = userStatus; + return this; + } + + /** + * User Status + * @return userStatus + */ + + @Schema(name = "userStatus", description = "User Status", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("userStatus") + public Integer getUserStatus() { + return userStatus; + } + + public void setUserStatus(Integer userStatus) { + this.userStatus = userStatus; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + User user = (User) o; + return Objects.equals(this.id, user.id) && + Objects.equals(this.username, user.username) && + Objects.equals(this.firstName, user.firstName) && + Objects.equals(this.lastName, user.lastName) && + Objects.equals(this.email, user.email) && + Objects.equals(this.password, user.password) && + Objects.equals(this.phone, user.phone) && + Objects.equals(this.userStatus, user.userStatus); + } + + @Override + public int hashCode() { + return Objects.hash(id, username, firstName, lastName, email, password, phone, userStatus); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class User {\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" username: ").append(toIndentedString(username)).append("\n"); + sb.append(" firstName: ").append(toIndentedString(firstName)).append("\n"); + sb.append(" lastName: ").append(toIndentedString(lastName)).append("\n"); + sb.append(" email: ").append(toIndentedString(email)).append("\n"); + sb.append(" password: ").append(toIndentedString(password)).append("\n"); + sb.append(" phone: ").append(toIndentedString(phone)).append("\n"); + sb.append(" userStatus: ").append(toIndentedString(userStatus)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/samples/server/petstore/springboot-spring-provide-args/src/main/resources/application.properties b/samples/server/petstore/springboot-spring-provide-args/src/main/resources/application.properties new file mode 100644 index 00000000000..7e90813e59b --- /dev/null +++ b/samples/server/petstore/springboot-spring-provide-args/src/main/resources/application.properties @@ -0,0 +1,3 @@ +server.port=8080 +spring.jackson.date-format=org.openapitools.RFC3339DateFormat +spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false diff --git a/samples/server/petstore/springboot-spring-provide-args/src/main/resources/openapi.yaml b/samples/server/petstore/springboot-spring-provide-args/src/main/resources/openapi.yaml new file mode 100644 index 00000000000..4ea192cdbb1 --- /dev/null +++ b/samples/server/petstore/springboot-spring-provide-args/src/main/resources/openapi.yaml @@ -0,0 +1,235 @@ +openapi: 3.0.1 +info: + contact: + email: apiteam@swagger.io + description: "This is a sample server Petstore server. You can find out more about\ + \ Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/).\ + \ For this sample, you can use the api key `special-key` to test the authorization\ + \ filters." + license: + name: Apache 2.0 + url: http://www.apache.org/licenses/LICENSE-2.0.html + termsOfService: http://swagger.io/terms/ + title: Swagger Petstore + version: 1.0.6 +externalDocs: + description: Find out more about Swagger + url: http://swagger.io +servers: +- url: https://petstore.swagger.io/v2 +- url: http://petstore.swagger.io/v2 +tags: +- description: Everything about your Pets + externalDocs: + description: Find out more + url: http://swagger.io + name: pet +- description: Access to Petstore orders + name: store +- description: Operations about user + externalDocs: + description: Find out more about our store + url: http://swagger.io + name: user +paths: + /user/login: + get: + operationId: loginUser + parameters: + - description: The user name for login + in: query + name: username + required: true + schema: + type: string + - description: The password for login in clear text + in: query + name: password + required: true + schema: + type: string + responses: + "200": + content: + application/json: + schema: + type: string + description: successful operation + headers: + X-Rate-Limit: + description: calls per hour allowed by the user + schema: + format: int32 + type: integer + X-Expires-After: + description: date in UTC when token expires + schema: + format: date-time + type: string + "400": + content: {} + description: Invalid username/password supplied + summary: Logs user into the system + tags: + - user + x-spring-provide-args: + - "@Value(\"${server.port}\") String someValue" + - "@RequestHeader(value=\"x-project-id\", required = false) String someHeaderValue" + - '@RequestHeader final HttpHeaders headers' + - Principal principal + - '@Qualifier("jacksonObjectMapper") ObjectMapper mapper' + x-accepts: application/json + x-tags: + - tag: user + /user/logout: + get: + operationId: logoutUser + responses: + default: + content: {} + description: successful operation + summary: Logs out current logged in user session + tags: + - user + x-spring-provide-args: + - "@Value(\"${server.port}\") String somePropertyValue" + - "@RequestHeader(value=\"x-project-id\", required = false) String someHeaderValue" + - '@RequestHeader final HttpHeaders headers' + - Principal principal + - '@Qualifier("jacksonObjectMapper") ObjectMapper mapper' + x-accepts: application/json + x-tags: + - tag: user +components: + schemas: + ApiResponse: + properties: + code: + format: int32 + type: integer + type: + type: string + message: + type: string + type: object + Category: + properties: + id: + format: int64 + type: integer + name: + type: string + type: object + xml: + name: Category + Pet: + properties: + id: + format: int64 + type: integer + category: + $ref: '#/components/schemas/Category' + name: + example: doggie + type: string + photoUrls: + items: + type: string + xml: + name: photoUrl + type: array + xml: + wrapped: true + tags: + items: + $ref: '#/components/schemas/Tag' + type: array + xml: + wrapped: true + status: + description: pet status in the store + enum: + - available + - pending + - sold + type: string + required: + - name + - photoUrls + type: object + xml: + name: Pet + Tag: + properties: + id: + format: int64 + type: integer + name: + type: string + type: object + xml: + name: Tag + Order: + properties: + id: + format: int64 + type: integer + petId: + format: int64 + type: integer + quantity: + format: int32 + type: integer + shipDate: + format: date-time + type: string + status: + description: Order Status + enum: + - placed + - approved + - delivered + type: string + complete: + type: boolean + type: object + xml: + name: Order + User: + properties: + id: + format: int64 + type: integer + username: + type: string + firstName: + type: string + lastName: + type: string + email: + type: string + password: + type: string + phone: + type: string + userStatus: + description: User Status + format: int32 + type: integer + type: object + xml: + name: User + securitySchemes: + api_key: + in: header + name: api_key + type: apiKey + petstore_auth: + flows: + implicit: + authorizationUrl: https://petstore.swagger.io/oauth/authorize + scopes: + read:pets: read your pets + write:pets: modify pets in your account + type: oauth2 +x-original-swagger-version: "2.0" diff --git a/samples/server/petstore/springboot-spring-provide-args/src/test/java/org/openapitools/OpenApiGeneratorApplicationTests.java b/samples/server/petstore/springboot-spring-provide-args/src/test/java/org/openapitools/OpenApiGeneratorApplicationTests.java new file mode 100644 index 00000000000..3681f67e770 --- /dev/null +++ b/samples/server/petstore/springboot-spring-provide-args/src/test/java/org/openapitools/OpenApiGeneratorApplicationTests.java @@ -0,0 +1,13 @@ +package org.openapitools; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class OpenApiGeneratorApplicationTests { + + @Test + void contextLoads() { + } + +} \ No newline at end of file