From 814ee9b78c192f60628f05a483f1490109bed10d Mon Sep 17 00:00:00 2001 From: Ionut Baranga Date: Sun, 29 Sep 2024 17:52:03 +0300 Subject: [PATCH 1/6] spring-http-interface: introduce `springHttpClientAdapter`, fix `paramDoc.mustache` --- ### What - Introduce `springHttpClientAdapter` for `spring-http-interface` - This property is used for selecting HTTP client implementation in Spring HTTP interfaces, with separate templates for each client configuration - Added an `spring-http-interface`-specific **empty** `paramDoc.mustache` --- ### Why - Enable selecting different HTTP client implementations when generating Spring HTTP client interfaces - Provides additional flexibility for users who want to generate non-reactive Spring Boot applications. --- ### How - `springHttpClientAdapter`: Allows users to choose between different HTTP client implementations used in `HttpInterfacesAbstractConfigurator`: - `web-client` (set by default, to ensure **backward compatibility**) - `rest-client` - `rest-template` - Separate templates for each `HttpInterfacesAbstractConfigurator` implementation: - `httpInterfacesRestClientConfiguration.mustache` - `httpInterfacesRestTemplateConfiguration.mustache` - `httpInterfacesWebClientConfiguration.mustache` - Log warning for configuration mismatch - When `reactive: false` is used in combination with the reactive `web-client`, it warns users of potential configuration mismatches, and suggests switching to `rest-template` or `rest-client` for non-reactive configurations. - Remove unnecessary paramDoc - Added an `spring-http-interface`-specific **empty** `paramDoc.mustache` in `JavaSpring/libraries/spring-http-interface/paramDoc.mustache` - This prevents inheriting the `@Parameter` annotations from the default Spring template located at `JavaSpring/paramDoc.mustache`. - Otherwise, the generated code includes `@Parameter` annotations on request body parameters, which were causing compile errors due to missing imports --- ### Testing Done - **Manual testing**: Verified that the generated code uses `WebClient`, `RestTemplate`, or `RestClient` based on the value of the `springHttpClientAdapter` property. - **Tested different configurations**: - **`reactive: false` & `web-client`**: Logs a warning, suggesting the use of `rest-client` or `rest-template`. - **`springHttpClientAdapter: rest-template`**: Generates code with `RestTemplateAdapter` using the `httpInterfacesRestTemplateConfiguration.mustache`. - **`springHttpClientAdapter: web-client` (default)**: Generates code using `WebClientAdapter` from `httpInterfacesWebClientConfiguration.mustache` and ensures backward compatibility. - **Tested `paramDoc.mustache` change**: Verified that the empty `paramDoc.mustache` prevents the generation of `@Parameter` annotations on request body parameters and resolves the compile errors caused by missing imports. --- ### PR checklist - [ ] Read the [contribution guidelines](https://github.com/openapitools/openapi-generator/blob/master/CONTRIBUTING.md). - [ ] Pull Request title clearly describes the work in the pull request and Pull Request description provides details about how to validate the work. Missing information here may result in delayed response from the community. - [ ] Run the following to [build the project](https://github.com/OpenAPITools/openapi-generator#14---build-projects) and update samples: ``` ./mvnw clean package ./bin/generate-samples.sh ./bin/configs/*.yaml ./bin/utils/export_docs_generators.sh ``` (For Windows users, please run the script in [Git BASH](https://gitforwindows.org/)) Commit all changed files. This is important, as CI jobs will verify _all_ generator outputs of your HEAD commit as it would merge with master. These must match the expectations made by your contribution. You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example `./bin/generate-samples.sh bin/configs/java*`. IMPORTANT: Do **NOT** purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed. - [ ] File the PR against the [correct branch](https://github.com/OpenAPITools/openapi-generator/wiki/Git-Branches): `master` (upcoming `7.x.0` minor release - breaking changes with fallbacks), `8.0.x` (breaking changes without fallbacks) - [ ] If your PR is targeting a particular programming language, @mention the [technical committee](https://github.com/openapitools/openapi-generator/#62---openapi-generator-technical-committee) members, so they are more likely to review the pull request. --- .../codegen/languages/SpringCodegen.java | 83 +++++++++++-------- ...InterfacesRestClientConfiguration.mustache | 38 +++++++++ ...terfacesRestTemplateConfiguration.mustache | 38 +++++++++ ...InterfacesWebClientConfiguration.mustache} | 2 +- .../spring-http-interface/paramDoc.mustache | 0 5 files changed, 126 insertions(+), 35 deletions(-) create mode 100644 modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpInterfacesRestClientConfiguration.mustache create mode 100644 modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpInterfacesRestTemplateConfiguration.mustache rename modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/{httpInterfacesConfiguration.mustache => httpInterfacesWebClientConfiguration.mustache} (94%) create mode 100644 modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/paramDoc.mustache 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 cb3c52a99c75..db4301b7c47b 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 @@ -17,10 +17,6 @@ package org.openapitools.codegen.languages; -import static org.apache.commons.lang3.StringUtils.isNotEmpty; -import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER; -import static org.openapitools.codegen.utils.StringUtils.camelize; - import com.samskivert.mustache.Mustache; import io.swagger.v3.oas.models.Components; import io.swagger.v3.oas.models.OpenAPI; @@ -30,39 +26,14 @@ import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.servers.Server; import io.swagger.v3.oas.models.tags.Tag; -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 lombok.Getter; +import lombok.RequiredArgsConstructor; import lombok.Setter; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; -import org.openapitools.codegen.CliOption; -import org.openapitools.codegen.CodegenConstants; -import org.openapitools.codegen.CodegenModel; -import org.openapitools.codegen.CodegenOperation; -import org.openapitools.codegen.CodegenParameter; -import org.openapitools.codegen.CodegenProperty; -import org.openapitools.codegen.CodegenResponse; -import org.openapitools.codegen.CodegenSecurity; -import org.openapitools.codegen.CodegenType; -import org.openapitools.codegen.SupportingFile; -import org.openapitools.codegen.VendorExtension; -import org.openapitools.codegen.languages.features.BeanValidationFeatures; -import org.openapitools.codegen.languages.features.DocumentationProviderFeatures; -import org.openapitools.codegen.languages.features.OptionalFeatures; -import org.openapitools.codegen.languages.features.PerformBeanValidationFeatures; -import org.openapitools.codegen.languages.features.SwaggerUIFeatures; -import org.openapitools.codegen.meta.features.DocumentationFeature; -import org.openapitools.codegen.meta.features.GlobalFeature; -import org.openapitools.codegen.meta.features.ParameterFeature; -import org.openapitools.codegen.meta.features.SchemaSupportFeature; -import org.openapitools.codegen.meta.features.SecurityFeature; -import org.openapitools.codegen.meta.features.WireFormatFeature; +import org.openapitools.codegen.*; +import org.openapitools.codegen.languages.features.*; +import org.openapitools.codegen.meta.features.*; import org.openapitools.codegen.model.ModelMap; import org.openapitools.codegen.model.ModelsMap; import org.openapitools.codegen.model.OperationMap; @@ -75,6 +46,18 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +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 java.util.stream.Stream; + +import static org.apache.commons.lang3.StringUtils.isNotEmpty; +import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER; +import static org.openapitools.codegen.utils.StringUtils.camelize; + public class SpringCodegen extends AbstractJavaCodegen implements BeanValidationFeatures, PerformBeanValidationFeatures, OptionalFeatures, SwaggerUIFeatures { private final Logger LOGGER = LoggerFactory.getLogger(SpringCodegen.class); @@ -102,6 +85,7 @@ public class SpringCodegen extends AbstractJavaCodegen public static final String SPRING_BOOT = "spring-boot"; public static final String SPRING_CLOUD_LIBRARY = "spring-cloud"; public static final String SPRING_HTTP_INTERFACE = "spring-http-interface"; + public static final String SPRING_HTTP_CLIENT_ADAPTER = "springHttpClientAdapter"; public static final String API_FIRST = "apiFirst"; public static final String SPRING_CONTROLLER = "useSpringController"; public static final String HATEOAS = "hateoas"; @@ -126,6 +110,25 @@ public class SpringCodegen extends AbstractJavaCodegen } } + @Getter + @RequiredArgsConstructor + public enum SpringHttpClientAdapter { + web_client("web-client", "Use RestClientAdapter", "httpInterfacesWebClientConfiguration.mustache"), + rest_client("rest-client", "Use RestClientAdapter", "httpInterfacesRestClientConfiguration.mustache"), + rest_template("rest-template", "Use RestTemplateAdapter", "httpInterfacesRestTemplateConfiguration.mustache"); + + private final String key; + private final String description; + private final String templateFileName; + + static SpringHttpClientAdapter fromKey(String key) { + return Stream.of(values()).filter(value -> value.getKey().equals(key)).findFirst().orElseThrow( + () -> new IllegalArgumentException("Invalid SpringHttpClientAdapter key: " + key) + ); + } + + } + public static final String OPEN_BRACE = "{"; public static final String CLOSE_BRACE = "}"; @@ -165,6 +168,7 @@ public class SpringCodegen extends AbstractJavaCodegen protected boolean generatedConstructorWithRequiredArgs = true; @Getter @Setter protected RequestMappingMode requestMappingMode = RequestMappingMode.controller; + @Setter SpringHttpClientAdapter springHttpClientAdapter; public SpringCodegen() { super(); @@ -268,6 +272,10 @@ public SpringCodegen() { generatedConstructorWithRequiredArgs)); cliOptions.add(new CliOption(RESOURCE_FOLDER, RESOURCE_FOLDER_DESC).defaultValue(this.getResourceFolder())); + cliOptions.add(CliOption.newString(SPRING_HTTP_CLIENT_ADAPTER, + "Allows users to choose between different HTTP client implementations for Spring HTTP interfaces (`web-client`, `rest-client`, `rest-template`).") + .defaultValue(SpringHttpClientAdapter.web_client.getKey() + )); supportedLibraries.put(SPRING_BOOT, "Spring-boot Server application."); supportedLibraries.put(SPRING_CLOUD_LIBRARY, "Spring-Cloud-Feign client with Spring-Boot auto-configured settings."); @@ -443,7 +451,9 @@ public void processOpts() { useJakartaEe=true; applyJakartaPackage(); } + convertPropertyToStringAndWriteBack(RESOURCE_FOLDER, this::setResourceFolder); + convertPropertyToTypeAndWriteBack(SPRING_HTTP_CLIENT_ADAPTER, SpringHttpClientAdapter::fromKey, this::setSpringHttpClientAdapter); typeMapping.put("file", "org.springframework.core.io.Resource"); importMapping.put("org.springframework.core.io.Resource", "org.springframework.core.io.Resource"); @@ -528,7 +538,12 @@ public void processOpts() { } } } else if (SPRING_HTTP_INTERFACE.equals(library)) { - supportingFiles.add(new SupportingFile("httpInterfacesConfiguration.mustache", + if (!reactive && springHttpClientAdapter == SpringHttpClientAdapter.web_client) { + LOGGER.warn("Configuration mismatch: The 'web-client' is selected as the HTTP client adapter, " + + "but 'reactive' is set to 'false'. " + + "Consider using 'rest-template' or 'rest-client' for non-reactive configurations."); + } + supportingFiles.add(new SupportingFile(springHttpClientAdapter.getTemplateFileName(), (sourceFolder + File.separator + configPackage).replace(".", java.io.File.separator), "HttpInterfacesAbstractConfigurator.java")); writePropertyBack(USE_BEANVALIDATION, false); } diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpInterfacesRestClientConfiguration.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpInterfacesRestClientConfiguration.mustache new file mode 100644 index 000000000000..47aae980e77a --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpInterfacesRestClientConfiguration.mustache @@ -0,0 +1,38 @@ +/** +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) ({{{generatorVersion}}}). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +package {{configPackage}}; + +{{#apiInfo}} + {{#apis}} +import {{apiPackage}}.{{classname}}; + {{/apis}} +{{/apiInfo}} + +import org.springframework.context.annotation.Bean; +import org.springframework.web.client.RestClient; +import org.springframework.web.client.support.RestClientAdapter; +import org.springframework.web.service.invoker.HttpServiceProxyFactory; + +public abstract class HttpInterfacesAbstractConfigurator { + + private final RestClient restClient; + + public HttpInterfacesAbstractConfigurator(final RestClient restClient) { + this.restClient = restClient; + } + +{{#apiInfo}} +{{#apis}} + @Bean(name = "{{configPackage}}.HttpInterfacesAbstractConfigurator.{{classVarName}}") + {{classname}} {{classVarName}}HttpProxy() { + HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(RestClientAdapter.create(restClient)).build(); + return factory.createClient({{classname}}.class); + } + +{{/apis}} +{{/apiInfo}} + +} diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpInterfacesRestTemplateConfiguration.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpInterfacesRestTemplateConfiguration.mustache new file mode 100644 index 000000000000..aaee8c724370 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpInterfacesRestTemplateConfiguration.mustache @@ -0,0 +1,38 @@ +/** +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) ({{{generatorVersion}}}). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +package {{configPackage}}; + +{{#apiInfo}} + {{#apis}} +import {{apiPackage}}.{{classname}}; + {{/apis}} +{{/apiInfo}} + +import org.springframework.context.annotation.Bean; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.client.support.RestTemplateAdapter; +import org.springframework.web.service.invoker.HttpServiceProxyFactory; + +public abstract class HttpInterfacesAbstractConfigurator { + + private final RestTemplate restTemplate; + + public HttpInterfacesAbstractConfigurator(final RestTemplate restTemplate) { + this.restTemplate = restTemplate; + } + +{{#apiInfo}} +{{#apis}} + @Bean(name = "{{configPackage}}.HttpInterfacesAbstractConfigurator.{{classVarName}}") + {{classname}} {{classVarName}}HttpProxy() { + HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(RestTemplateAdapter.create(restTemplate)).build(); + return factory.createClient({{classname}}.class); + } + +{{/apis}} +{{/apiInfo}} + +} diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpInterfacesConfiguration.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpInterfacesWebClientConfiguration.mustache similarity index 94% rename from modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpInterfacesConfiguration.mustache rename to modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpInterfacesWebClientConfiguration.mustache index 6e92c83f51c8..26a44b106557 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpInterfacesConfiguration.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpInterfacesWebClientConfiguration.mustache @@ -28,7 +28,7 @@ public abstract class HttpInterfacesAbstractConfigurator { {{#apis}} @Bean(name = "{{configPackage}}.HttpInterfacesAbstractConfigurator.{{classVarName}}") {{classname}} {{classVarName}}HttpProxy() { - HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).build(); + HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(WebClientAdapter.forClient(webClient)).build(); return factory.createClient({{classname}}.class); } diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/paramDoc.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/paramDoc.mustache new file mode 100644 index 000000000000..e69de29bb2d1 From f1bbe1b6eb6d7d9004c44dacd5307235b31ec20a Mon Sep 17 00:00:00 2001 From: Ionut Baranga Date: Sun, 29 Sep 2024 18:44:52 +0300 Subject: [PATCH 2/6] fix imports --- .../codegen/languages/SpringCodegen.java | 49 +++++++++++++------ 1 file changed, 34 insertions(+), 15 deletions(-) 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 db4301b7c47b..70afcfc1bd3c 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 @@ -17,6 +17,10 @@ package org.openapitools.codegen.languages; +import static org.apache.commons.lang3.StringUtils.isNotEmpty; +import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER; +import static org.openapitools.codegen.utils.StringUtils.camelize; + import com.samskivert.mustache.Mustache; import io.swagger.v3.oas.models.Components; import io.swagger.v3.oas.models.OpenAPI; @@ -26,14 +30,41 @@ import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.servers.Server; import io.swagger.v3.oas.models.tags.Tag; +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 java.util.stream.Stream; + import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.Setter; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; -import org.openapitools.codegen.*; -import org.openapitools.codegen.languages.features.*; -import org.openapitools.codegen.meta.features.*; +import org.openapitools.codegen.CliOption; +import org.openapitools.codegen.CodegenConstants; +import org.openapitools.codegen.CodegenModel; +import org.openapitools.codegen.CodegenOperation; +import org.openapitools.codegen.CodegenParameter; +import org.openapitools.codegen.CodegenProperty; +import org.openapitools.codegen.CodegenResponse; +import org.openapitools.codegen.CodegenSecurity; +import org.openapitools.codegen.CodegenType; +import org.openapitools.codegen.SupportingFile; +import org.openapitools.codegen.VendorExtension; +import org.openapitools.codegen.languages.features.BeanValidationFeatures; +import org.openapitools.codegen.languages.features.DocumentationProviderFeatures; +import org.openapitools.codegen.languages.features.OptionalFeatures; +import org.openapitools.codegen.languages.features.PerformBeanValidationFeatures; +import org.openapitools.codegen.languages.features.SwaggerUIFeatures; +import org.openapitools.codegen.meta.features.DocumentationFeature; +import org.openapitools.codegen.meta.features.GlobalFeature; +import org.openapitools.codegen.meta.features.ParameterFeature; +import org.openapitools.codegen.meta.features.SchemaSupportFeature; +import org.openapitools.codegen.meta.features.SecurityFeature; +import org.openapitools.codegen.meta.features.WireFormatFeature; import org.openapitools.codegen.model.ModelMap; import org.openapitools.codegen.model.ModelsMap; import org.openapitools.codegen.model.OperationMap; @@ -46,18 +77,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -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 java.util.stream.Stream; - -import static org.apache.commons.lang3.StringUtils.isNotEmpty; -import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER; -import static org.openapitools.codegen.utils.StringUtils.camelize; - public class SpringCodegen extends AbstractJavaCodegen implements BeanValidationFeatures, PerformBeanValidationFeatures, OptionalFeatures, SwaggerUIFeatures { private final Logger LOGGER = LoggerFactory.getLogger(SpringCodegen.class); From 4e03298fe4bc7ad0bdf54c57e56ea2b07f819e4a Mon Sep 17 00:00:00 2001 From: Ionut Baranga <1544344+ibaranga@users.noreply.github.com> Date: Sun, 29 Sep 2024 19:41:58 +0300 Subject: [PATCH 3/6] Update SpringCodegen.java --- .../java/org/openapitools/codegen/languages/SpringCodegen.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 70afcfc1bd3c..47b26002c3f1 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 @@ -132,7 +132,7 @@ public class SpringCodegen extends AbstractJavaCodegen @Getter @RequiredArgsConstructor public enum SpringHttpClientAdapter { - web_client("web-client", "Use RestClientAdapter", "httpInterfacesWebClientConfiguration.mustache"), + web_client("web-client", "Use WebClientAdapter", "httpInterfacesWebClientConfiguration.mustache"), rest_client("rest-client", "Use RestClientAdapter", "httpInterfacesRestClientConfiguration.mustache"), rest_template("rest-template", "Use RestTemplateAdapter", "httpInterfacesRestTemplateConfiguration.mustache"); From 0f9bfb14f0d0bc3e46045347b664fa54bc090da8 Mon Sep 17 00:00:00 2001 From: Ionut Baranga Date: Tue, 1 Oct 2024 15:30:34 +0300 Subject: [PATCH 4/6] fix docs and default value --- docs/generators/java-camel.md | 1 + docs/generators/spring.md | 1 + .../org/openapitools/codegen/languages/SpringCodegen.java | 6 +++--- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/generators/java-camel.md b/docs/generators/java-camel.md index e77c38151eb3..055498e71fae 100644 --- a/docs/generators/java-camel.md +++ b/docs/generators/java-camel.md @@ -92,6 +92,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |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| +|springHttpClientAdapter|Allows users to choose between different HTTP client implementations for Spring HTTP interfaces (`web-client`, `rest-client`, `rest-template`).| |web-client| |testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi| |title|server title name or client service name| |OpenAPI Spring| |unhandledException|Declare operation methods to throw a generic exception and allow unhandled exceptions (useful for Spring `@ControllerAdvice` directives).| |false| diff --git a/docs/generators/spring.md b/docs/generators/spring.md index b71cefb3c126..2673ed2f54c0 100644 --- a/docs/generators/spring.md +++ b/docs/generators/spring.md @@ -85,6 +85,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |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| +|springHttpClientAdapter|Allows users to choose between different HTTP client implementations for Spring HTTP interfaces (`web-client`, `rest-client`, `rest-template`).| |web-client| |testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi| |title|server title name or client service name| |OpenAPI Spring| |unhandledException|Declare operation methods to throw a generic exception and allow unhandled exceptions (useful for Spring `@ControllerAdvice` directives).| |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 70afcfc1bd3c..5a4aabe9c457 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 @@ -187,7 +187,7 @@ static SpringHttpClientAdapter fromKey(String key) { protected boolean generatedConstructorWithRequiredArgs = true; @Getter @Setter protected RequestMappingMode requestMappingMode = RequestMappingMode.controller; - @Setter SpringHttpClientAdapter springHttpClientAdapter; + @Setter SpringHttpClientAdapter springHttpClientAdapter = SpringHttpClientAdapter.web_client; public SpringCodegen() { super(); @@ -293,8 +293,8 @@ public SpringCodegen() { cliOptions.add(CliOption.newString(SPRING_HTTP_CLIENT_ADAPTER, "Allows users to choose between different HTTP client implementations for Spring HTTP interfaces (`web-client`, `rest-client`, `rest-template`).") - .defaultValue(SpringHttpClientAdapter.web_client.getKey() - )); + .defaultValue(SpringHttpClientAdapter.web_client.getKey()) + ); supportedLibraries.put(SPRING_BOOT, "Spring-boot Server application."); supportedLibraries.put(SPRING_CLOUD_LIBRARY, "Spring-Cloud-Feign client with Spring-Boot auto-configured settings."); From 4c3bdaecdf301fcaa5c7fecf3c8a454204283bb0 Mon Sep 17 00:00:00 2001 From: Ionut Baranga Date: Tue, 1 Oct 2024 17:34:10 +0300 Subject: [PATCH 5/6] fix docs and default value --- .../HttpInterfacesAbstractConfigurator.java | 12 ++++++------ .../HttpInterfacesAbstractConfigurator.java | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/samples/client/petstore/spring-http-interface-reactive/src/main/java/org/openapitools/configuration/HttpInterfacesAbstractConfigurator.java b/samples/client/petstore/spring-http-interface-reactive/src/main/java/org/openapitools/configuration/HttpInterfacesAbstractConfigurator.java index d54d21f28851..70c2dc3733b8 100644 --- a/samples/client/petstore/spring-http-interface-reactive/src/main/java/org/openapitools/configuration/HttpInterfacesAbstractConfigurator.java +++ b/samples/client/petstore/spring-http-interface-reactive/src/main/java/org/openapitools/configuration/HttpInterfacesAbstractConfigurator.java @@ -27,37 +27,37 @@ public HttpInterfacesAbstractConfigurator(final WebClient webClient) { @Bean(name = "org.openapitools.configuration.HttpInterfacesAbstractConfigurator.anotherFake") AnotherFakeApi anotherFakeHttpProxy() { - HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).build(); + HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(WebClientAdapter.forClient(webClient)).build(); return factory.createClient(AnotherFakeApi.class); } @Bean(name = "org.openapitools.configuration.HttpInterfacesAbstractConfigurator.fake") FakeApi fakeHttpProxy() { - HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).build(); + HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(WebClientAdapter.forClient(webClient)).build(); return factory.createClient(FakeApi.class); } @Bean(name = "org.openapitools.configuration.HttpInterfacesAbstractConfigurator.fakeClassnameTags123") FakeClassnameTags123Api fakeClassnameTags123HttpProxy() { - HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).build(); + HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(WebClientAdapter.forClient(webClient)).build(); return factory.createClient(FakeClassnameTags123Api.class); } @Bean(name = "org.openapitools.configuration.HttpInterfacesAbstractConfigurator.pet") PetApi petHttpProxy() { - HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).build(); + HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(WebClientAdapter.forClient(webClient)).build(); return factory.createClient(PetApi.class); } @Bean(name = "org.openapitools.configuration.HttpInterfacesAbstractConfigurator.store") StoreApi storeHttpProxy() { - HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).build(); + HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(WebClientAdapter.forClient(webClient)).build(); return factory.createClient(StoreApi.class); } @Bean(name = "org.openapitools.configuration.HttpInterfacesAbstractConfigurator.user") UserApi userHttpProxy() { - HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).build(); + HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(WebClientAdapter.forClient(webClient)).build(); return factory.createClient(UserApi.class); } diff --git a/samples/client/petstore/spring-http-interface/src/main/java/org/openapitools/configuration/HttpInterfacesAbstractConfigurator.java b/samples/client/petstore/spring-http-interface/src/main/java/org/openapitools/configuration/HttpInterfacesAbstractConfigurator.java index d54d21f28851..70c2dc3733b8 100644 --- a/samples/client/petstore/spring-http-interface/src/main/java/org/openapitools/configuration/HttpInterfacesAbstractConfigurator.java +++ b/samples/client/petstore/spring-http-interface/src/main/java/org/openapitools/configuration/HttpInterfacesAbstractConfigurator.java @@ -27,37 +27,37 @@ public HttpInterfacesAbstractConfigurator(final WebClient webClient) { @Bean(name = "org.openapitools.configuration.HttpInterfacesAbstractConfigurator.anotherFake") AnotherFakeApi anotherFakeHttpProxy() { - HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).build(); + HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(WebClientAdapter.forClient(webClient)).build(); return factory.createClient(AnotherFakeApi.class); } @Bean(name = "org.openapitools.configuration.HttpInterfacesAbstractConfigurator.fake") FakeApi fakeHttpProxy() { - HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).build(); + HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(WebClientAdapter.forClient(webClient)).build(); return factory.createClient(FakeApi.class); } @Bean(name = "org.openapitools.configuration.HttpInterfacesAbstractConfigurator.fakeClassnameTags123") FakeClassnameTags123Api fakeClassnameTags123HttpProxy() { - HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).build(); + HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(WebClientAdapter.forClient(webClient)).build(); return factory.createClient(FakeClassnameTags123Api.class); } @Bean(name = "org.openapitools.configuration.HttpInterfacesAbstractConfigurator.pet") PetApi petHttpProxy() { - HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).build(); + HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(WebClientAdapter.forClient(webClient)).build(); return factory.createClient(PetApi.class); } @Bean(name = "org.openapitools.configuration.HttpInterfacesAbstractConfigurator.store") StoreApi storeHttpProxy() { - HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).build(); + HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(WebClientAdapter.forClient(webClient)).build(); return factory.createClient(StoreApi.class); } @Bean(name = "org.openapitools.configuration.HttpInterfacesAbstractConfigurator.user") UserApi userHttpProxy() { - HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).build(); + HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(WebClientAdapter.forClient(webClient)).build(); return factory.createClient(UserApi.class); } From 6addc9a67e8c5c0363bab67dc885ca2a734b4866 Mon Sep 17 00:00:00 2001 From: Ionut Baranga Date: Wed, 16 Oct 2024 20:42:49 +0300 Subject: [PATCH 6/6] revert to HttpServiceProxyFactory.builder for backward compatibility --- .../httpInterfacesRestClientConfiguration.mustache | 2 +- .../httpInterfacesRestTemplateConfiguration.mustache | 2 +- .../httpInterfacesWebClientConfiguration.mustache | 2 +- .../HttpInterfacesAbstractConfigurator.java | 12 ++++++------ .../HttpInterfacesAbstractConfigurator.java | 12 ++++++------ 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpInterfacesRestClientConfiguration.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpInterfacesRestClientConfiguration.mustache index 47aae980e77a..9a1b2cec2843 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpInterfacesRestClientConfiguration.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpInterfacesRestClientConfiguration.mustache @@ -28,7 +28,7 @@ public abstract class HttpInterfacesAbstractConfigurator { {{#apis}} @Bean(name = "{{configPackage}}.HttpInterfacesAbstractConfigurator.{{classVarName}}") {{classname}} {{classVarName}}HttpProxy() { - HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(RestClientAdapter.create(restClient)).build(); + HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(RestClientAdapter.create(restClient)).build(); return factory.createClient({{classname}}.class); } diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpInterfacesRestTemplateConfiguration.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpInterfacesRestTemplateConfiguration.mustache index aaee8c724370..1540cf43bc13 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpInterfacesRestTemplateConfiguration.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpInterfacesRestTemplateConfiguration.mustache @@ -28,7 +28,7 @@ public abstract class HttpInterfacesAbstractConfigurator { {{#apis}} @Bean(name = "{{configPackage}}.HttpInterfacesAbstractConfigurator.{{classVarName}}") {{classname}} {{classVarName}}HttpProxy() { - HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(RestTemplateAdapter.create(restTemplate)).build(); + HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(RestTemplateAdapter.create(restTemplate)).build(); return factory.createClient({{classname}}.class); } diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpInterfacesWebClientConfiguration.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpInterfacesWebClientConfiguration.mustache index 26a44b106557..6e92c83f51c8 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpInterfacesWebClientConfiguration.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpInterfacesWebClientConfiguration.mustache @@ -28,7 +28,7 @@ public abstract class HttpInterfacesAbstractConfigurator { {{#apis}} @Bean(name = "{{configPackage}}.HttpInterfacesAbstractConfigurator.{{classVarName}}") {{classname}} {{classVarName}}HttpProxy() { - HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(WebClientAdapter.forClient(webClient)).build(); + HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).build(); return factory.createClient({{classname}}.class); } diff --git a/samples/client/petstore/spring-http-interface-reactive/src/main/java/org/openapitools/configuration/HttpInterfacesAbstractConfigurator.java b/samples/client/petstore/spring-http-interface-reactive/src/main/java/org/openapitools/configuration/HttpInterfacesAbstractConfigurator.java index 450eb8fbb04e..0b4b212d8677 100644 --- a/samples/client/petstore/spring-http-interface-reactive/src/main/java/org/openapitools/configuration/HttpInterfacesAbstractConfigurator.java +++ b/samples/client/petstore/spring-http-interface-reactive/src/main/java/org/openapitools/configuration/HttpInterfacesAbstractConfigurator.java @@ -27,37 +27,37 @@ public HttpInterfacesAbstractConfigurator(final WebClient webClient) { @Bean(name = "org.openapitools.configuration.HttpInterfacesAbstractConfigurator.anotherFake") AnotherFakeApi anotherFakeHttpProxy() { - HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(WebClientAdapter.forClient(webClient)).build(); + HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).build(); return factory.createClient(AnotherFakeApi.class); } @Bean(name = "org.openapitools.configuration.HttpInterfacesAbstractConfigurator.fake") FakeApi fakeHttpProxy() { - HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(WebClientAdapter.forClient(webClient)).build(); + HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).build(); return factory.createClient(FakeApi.class); } @Bean(name = "org.openapitools.configuration.HttpInterfacesAbstractConfigurator.fakeClassnameTags123") FakeClassnameTags123Api fakeClassnameTags123HttpProxy() { - HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(WebClientAdapter.forClient(webClient)).build(); + HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).build(); return factory.createClient(FakeClassnameTags123Api.class); } @Bean(name = "org.openapitools.configuration.HttpInterfacesAbstractConfigurator.pet") PetApi petHttpProxy() { - HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(WebClientAdapter.forClient(webClient)).build(); + HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).build(); return factory.createClient(PetApi.class); } @Bean(name = "org.openapitools.configuration.HttpInterfacesAbstractConfigurator.store") StoreApi storeHttpProxy() { - HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(WebClientAdapter.forClient(webClient)).build(); + HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).build(); return factory.createClient(StoreApi.class); } @Bean(name = "org.openapitools.configuration.HttpInterfacesAbstractConfigurator.user") UserApi userHttpProxy() { - HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(WebClientAdapter.forClient(webClient)).build(); + HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).build(); return factory.createClient(UserApi.class); } diff --git a/samples/client/petstore/spring-http-interface/src/main/java/org/openapitools/configuration/HttpInterfacesAbstractConfigurator.java b/samples/client/petstore/spring-http-interface/src/main/java/org/openapitools/configuration/HttpInterfacesAbstractConfigurator.java index 450eb8fbb04e..0b4b212d8677 100644 --- a/samples/client/petstore/spring-http-interface/src/main/java/org/openapitools/configuration/HttpInterfacesAbstractConfigurator.java +++ b/samples/client/petstore/spring-http-interface/src/main/java/org/openapitools/configuration/HttpInterfacesAbstractConfigurator.java @@ -27,37 +27,37 @@ public HttpInterfacesAbstractConfigurator(final WebClient webClient) { @Bean(name = "org.openapitools.configuration.HttpInterfacesAbstractConfigurator.anotherFake") AnotherFakeApi anotherFakeHttpProxy() { - HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(WebClientAdapter.forClient(webClient)).build(); + HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).build(); return factory.createClient(AnotherFakeApi.class); } @Bean(name = "org.openapitools.configuration.HttpInterfacesAbstractConfigurator.fake") FakeApi fakeHttpProxy() { - HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(WebClientAdapter.forClient(webClient)).build(); + HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).build(); return factory.createClient(FakeApi.class); } @Bean(name = "org.openapitools.configuration.HttpInterfacesAbstractConfigurator.fakeClassnameTags123") FakeClassnameTags123Api fakeClassnameTags123HttpProxy() { - HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(WebClientAdapter.forClient(webClient)).build(); + HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).build(); return factory.createClient(FakeClassnameTags123Api.class); } @Bean(name = "org.openapitools.configuration.HttpInterfacesAbstractConfigurator.pet") PetApi petHttpProxy() { - HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(WebClientAdapter.forClient(webClient)).build(); + HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).build(); return factory.createClient(PetApi.class); } @Bean(name = "org.openapitools.configuration.HttpInterfacesAbstractConfigurator.store") StoreApi storeHttpProxy() { - HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(WebClientAdapter.forClient(webClient)).build(); + HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).build(); return factory.createClient(StoreApi.class); } @Bean(name = "org.openapitools.configuration.HttpInterfacesAbstractConfigurator.user") UserApi userHttpProxy() { - HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(WebClientAdapter.forClient(webClient)).build(); + HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).build(); return factory.createClient(UserApi.class); }