Skip to content

Commit 6a55e5d

Browse files
committed
spring-http-interface: introduce useHttpServiceProxyFactoryInterfacesConfiguration config
1 parent 0cd4f75 commit 6a55e5d

71 files changed

Lines changed: 9315 additions & 80 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/samples-jdk17.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ on:
1010
- samples/client/petstore/spring-http-interface/**
1111
- samples/client/petstore/spring-http-interface-reactive-noResponseEntity/**
1212
- samples/client/petstore/spring-http-interface-noResponseEntity/**
13+
- samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfiguration/**
1314
- samples/client/petstore/java/webclient-jakarta/**
1415
- samples/client/petstore/java/microprofile-rest-client-outer-enum/**
1516
# servers
@@ -27,6 +28,7 @@ on:
2728
- samples/client/petstore/spring-http-interface/**
2829
- samples/client/petstore/spring-http-interface-reactive-noResponseEntity/**
2930
- samples/client/petstore/spring-http-interface-noResponseEntity/**
31+
- samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfiguration/**
3032
- samples/client/petstore/java/webclient-jakarta/**
3133
- samples/client/petstore/java/microprofile-rest-client-outer-enum/**
3234
# servers
@@ -50,6 +52,7 @@ jobs:
5052
- samples/client/petstore/spring-http-interface
5153
- samples/client/petstore/spring-http-interface-reactive-noResponseEntity
5254
- samples/client/petstore/spring-http-interface-noResponseEntity
55+
- samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfiguration
5356
- samples/client/petstore/java/webclient-jakarta
5457
- samples/client/petstore/java/microprofile-rest-client-outer-enum
5558
# servers
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
generatorName: spring
2+
library: spring-http-interface
3+
outputDir: samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfiguration
4+
inputSpec: modules/openapi-generator/src/test/resources/3_0/spring/petstore-with-fake-endpoints-models-for-testing.yaml
5+
templateDir: modules/openapi-generator/src/main/resources/JavaSpring
6+
additionalProperties:
7+
artifactId: spring-http-interface-useHttpServiceProxyFactoryInterfacesConfiguration
8+
snapshotVersion: "true"
9+
hideGenerationTimestamp: "true"
10+
# documentation provider should be ignored
11+
documentationProvider: "springdoc"
12+
# annotation provider should be ignored
13+
annotationLibrary: "swagger2"
14+
# validation should be ignored
15+
useBeanValidation: "true"
16+
performBeanValidation: "true"
17+
useHttpServiceProxyFactoryInterfacesConfiguration: "true"
18+
# needed until updating the default parentVersion (3.1.3) to 3.2+
19+
parentGroupId: "org.springframework.boot"
20+
parentArtifactId: "spring-boot-starter-parent"
21+
parentVersion: "3.2.0"

docs/generators/java-camel.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,13 @@ These options may be applied as additional-properties (cli) or configOptions (pl
9393
|sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true|
9494
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
9595
|sourceFolder|source folder for generated code| |src/main/java|
96-
|springHttpClientAdapter|Allows users to choose between different HTTP client implementations for Spring HTTP interfaces (`web-client`, `rest-client`, `rest-template`).| |web-client|
9796
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
9897
|title|server title name or client service name| |OpenAPI Spring|
9998
|unhandledException|Declare operation methods to throw a generic exception and allow unhandled exceptions (useful for Spring `@ControllerAdvice` directives).| |false|
10099
|useBeanValidation|Use BeanValidation API annotations| |true|
101100
|useEnumCaseInsensitive|Use `equalsIgnoreCase` when String for enum comparison| |false|
102101
|useFeignClientUrl|Whether to generate Feign client with url parameter.| |true|
102+
|useHttpServiceProxyFactoryInterfacesConfiguration|Generate HttpInterfacesAbstractConfigurator based on an HttpServiceProxyFactory instance (as opposed to a WebClient instance, when disabled) for generating Spring HTTP interfaces. Requires spring-web 6.1+.| |false|
103103
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
104104
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
105105
|useOptional|Use Optional container for optional parameters| |false|

docs/generators/spring.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,13 @@ These options may be applied as additional-properties (cli) or configOptions (pl
8686
|sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true|
8787
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
8888
|sourceFolder|source folder for generated code| |src/main/java|
89-
|springHttpClientAdapter|Allows users to choose between different HTTP client implementations for Spring HTTP interfaces (`web-client`, `rest-client`, `rest-template`).| |web-client|
9089
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
9190
|title|server title name or client service name| |OpenAPI Spring|
9291
|unhandledException|Declare operation methods to throw a generic exception and allow unhandled exceptions (useful for Spring `@ControllerAdvice` directives).| |false|
9392
|useBeanValidation|Use BeanValidation API annotations| |true|
9493
|useEnumCaseInsensitive|Use `equalsIgnoreCase` when String for enum comparison| |false|
9594
|useFeignClientUrl|Whether to generate Feign client with url parameter.| |true|
95+
|useHttpServiceProxyFactoryInterfacesConfiguration|Generate HttpInterfacesAbstractConfigurator based on an HttpServiceProxyFactory instance (as opposed to a WebClient instance, when disabled) for generating Spring HTTP interfaces. Requires spring-web 6.1+.| |false|
9696
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
9797
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
9898
|useOptional|Use Optional container for optional parameters| |false|

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java

Lines changed: 19 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,8 @@
3636
import java.util.regex.Matcher;
3737
import java.util.regex.Pattern;
3838
import java.util.stream.Collectors;
39-
import java.util.stream.Stream;
4039

4140
import lombok.Getter;
42-
import lombok.RequiredArgsConstructor;
4341
import lombok.Setter;
4442
import org.apache.commons.lang3.StringUtils;
4543
import org.apache.commons.lang3.tuple.Pair;
@@ -104,7 +102,8 @@ public class SpringCodegen extends AbstractJavaCodegen
104102
public static final String SPRING_BOOT = "spring-boot";
105103
public static final String SPRING_CLOUD_LIBRARY = "spring-cloud";
106104
public static final String SPRING_HTTP_INTERFACE = "spring-http-interface";
107-
public static final String SPRING_HTTP_CLIENT_ADAPTER = "springHttpClientAdapter";
105+
public static final String USE_HTTP_SERVICE_PROXY_FACTORY_INTERFACES_CONFIGURATION = "useHttpServiceProxyFactoryInterfacesConfiguration";
106+
public static final String HTTP_INTERFACES_CONFIGURATOR_DEPENDENCY = "httpInterfacesConfiguratorDependency";
108107
public static final String API_FIRST = "apiFirst";
109108
public static final String SPRING_CONTROLLER = "useSpringController";
110109
public static final String HATEOAS = "hateoas";
@@ -129,25 +128,6 @@ public class SpringCodegen extends AbstractJavaCodegen
129128
}
130129
}
131130

132-
@Getter
133-
@RequiredArgsConstructor
134-
public enum SpringHttpClientAdapter {
135-
web_client("web-client", "Use WebClientAdapter", "httpInterfacesWebClientConfiguration.mustache"),
136-
rest_client("rest-client", "Use RestClientAdapter", "httpInterfacesRestClientConfiguration.mustache"),
137-
rest_template("rest-template", "Use RestTemplateAdapter", "httpInterfacesRestTemplateConfiguration.mustache");
138-
139-
private final String key;
140-
private final String description;
141-
private final String templateFileName;
142-
143-
static SpringHttpClientAdapter fromKey(String key) {
144-
return Stream.of(values()).filter(value -> value.getKey().equals(key)).findFirst().orElseThrow(
145-
() -> new IllegalArgumentException("Invalid SpringHttpClientAdapter key: " + key)
146-
);
147-
}
148-
149-
}
150-
151131
public static final String OPEN_BRACE = "{";
152132
public static final String CLOSE_BRACE = "}";
153133

@@ -187,7 +167,7 @@ static SpringHttpClientAdapter fromKey(String key) {
187167
protected boolean generatedConstructorWithRequiredArgs = true;
188168
@Getter @Setter
189169
protected RequestMappingMode requestMappingMode = RequestMappingMode.controller;
190-
@Setter SpringHttpClientAdapter springHttpClientAdapter = SpringHttpClientAdapter.web_client;
170+
@Setter boolean useHttpServiceProxyFactoryInterfacesConfiguration = false;
191171

192172
public SpringCodegen() {
193173
super();
@@ -291,9 +271,9 @@ public SpringCodegen() {
291271
generatedConstructorWithRequiredArgs));
292272
cliOptions.add(new CliOption(RESOURCE_FOLDER, RESOURCE_FOLDER_DESC).defaultValue(this.getResourceFolder()));
293273

294-
cliOptions.add(CliOption.newString(SPRING_HTTP_CLIENT_ADAPTER,
295-
"Allows users to choose between different HTTP client implementations for Spring HTTP interfaces (`web-client`, `rest-client`, `rest-template`).")
296-
.defaultValue(SpringHttpClientAdapter.web_client.getKey())
274+
cliOptions.add(CliOption.newString(USE_HTTP_SERVICE_PROXY_FACTORY_INTERFACES_CONFIGURATION,
275+
"Generate HttpInterfacesAbstractConfigurator based on an HttpServiceProxyFactory instance (as opposed to a WebClient instance, when disabled) for generating Spring HTTP interfaces. Requires spring-web 6.1+.")
276+
.defaultValue("false")
297277
);
298278
supportedLibraries.put(SPRING_BOOT, "Spring-boot Server application.");
299279
supportedLibraries.put(SPRING_CLOUD_LIBRARY,
@@ -472,7 +452,7 @@ public void processOpts() {
472452
}
473453

474454
convertPropertyToStringAndWriteBack(RESOURCE_FOLDER, this::setResourceFolder);
475-
convertPropertyToTypeAndWriteBack(SPRING_HTTP_CLIENT_ADAPTER, SpringHttpClientAdapter::fromKey, this::setSpringHttpClientAdapter);
455+
convertPropertyToBooleanAndWriteBack(USE_HTTP_SERVICE_PROXY_FACTORY_INTERFACES_CONFIGURATION, this::setUseHttpServiceProxyFactoryInterfacesConfiguration);
476456

477457
typeMapping.put("file", "org.springframework.core.io.Resource");
478458
importMapping.put("org.springframework.core.io.Resource", "org.springframework.core.io.Resource");
@@ -557,14 +537,20 @@ public void processOpts() {
557537
}
558538
}
559539
} else if (SPRING_HTTP_INTERFACE.equals(library)) {
560-
if (!reactive && springHttpClientAdapter == SpringHttpClientAdapter.web_client) {
561-
LOGGER.warn("Configuration mismatch: The 'web-client' is selected as the HTTP client adapter, "
562-
+ "but 'reactive' is set to 'false'. "
563-
+ "Consider using 'rest-template' or 'rest-client' for non-reactive configurations.");
564-
}
565-
supportingFiles.add(new SupportingFile(springHttpClientAdapter.getTemplateFileName(),
540+
String httpInterfacesAbstractConfiguratorFile = useHttpServiceProxyFactoryInterfacesConfiguration ?
541+
"httpServiceProxyFactoryInterfacesConfiguration.mustache" :
542+
"httpInterfacesConfiguration.mustache";
543+
544+
supportingFiles.add(new SupportingFile(httpInterfacesAbstractConfiguratorFile,
566545
(sourceFolder + File.separator + configPackage).replace(".", java.io.File.separator), "HttpInterfacesAbstractConfigurator.java"));
546+
567547
writePropertyBack(USE_BEANVALIDATION, false);
548+
549+
writePropertyBack(HTTP_INTERFACES_CONFIGURATOR_DEPENDENCY,
550+
useHttpServiceProxyFactoryInterfacesConfiguration ?
551+
"HttpServiceProxyFactory" :
552+
"WebClient"
553+
);
568554
}
569555
}
570556

modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/README.mustache

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ By using the [OpenAPI-Spec](https://openapis.org), you can easily generate an AP
99
This is an example of building API stub interfaces in Java using the Spring framework.
1010

1111
The stubs generated can be used in your existing Spring application for HTTP integration with other REST services
12-
To use auto-generated interfaces you have to create your own configuration which extends default abstract configurator & provide `WebClient` instance via constructor
12+
To use auto-generated interfaces you have to create your own configuration which extends default abstract configurator & provide `{{httpInterfacesConfiguratorDependency}}` instance via constructor
1313
```java
1414
@Configuration
1515
public class MyConfiguration extends {{configPackage}}.HttpInterfacesAbstractConfigurator {
1616
17-
public MyConfiguration(WebClient myWebClient) { // separately created WebClient instance
18-
super(myWebClient);
17+
public MyConfiguration({{httpInterfacesConfiguratorDependency}} my{{httpInterfacesConfiguratorDependency}}) { // separately created {{httpInterfacesConfiguratorDependency}} instance
18+
super(my{{httpInterfacesConfiguratorDependency}});
1919
}
2020
}
2121
```

modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpInterfacesWebClientConfiguration.mustache renamed to modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpInterfacesConfiguration.mustache

File renamed without changes.

modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpInterfacesRestTemplateConfiguration.mustache

Lines changed: 0 additions & 38 deletions
This file was deleted.

modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpInterfacesRestClientConfiguration.mustache renamed to modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpServiceProxyFactoryInterfacesConfiguration.mustache

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,16 @@ import org.springframework.web.service.invoker.HttpServiceProxyFactory;
1818

1919
public abstract class HttpInterfacesAbstractConfigurator {
2020
21-
private final RestClient restClient;
21+
private final HttpServiceProxyFactory factory;
2222
23-
public HttpInterfacesAbstractConfigurator(final RestClient restClient) {
24-
this.restClient = restClient;
23+
public HttpInterfacesAbstractConfigurator(final HttpServiceProxyFactory factory) {
24+
this.factory = factory;
2525
}
2626

2727
{{#apiInfo}}
2828
{{#apis}}
2929
@Bean(name = "{{configPackage}}.HttpInterfacesAbstractConfigurator.{{classVarName}}")
3030
{{classname}} {{classVarName}}HttpProxy() {
31-
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(RestClientAdapter.create(restClient)).build();
3231
return factory.createClient({{classname}}.class);
3332
}
3433

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# OpenAPI Generator Ignore
2+
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
3+
4+
# Use this file to prevent files from being overwritten by the generator.
5+
# The patterns follow closely to .gitignore or .dockerignore.
6+
7+
# As an example, the C# client generator defines ApiClient.cs.
8+
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
9+
#ApiClient.cs
10+
11+
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
12+
#foo/*/qux
13+
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
14+
15+
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
16+
#foo/**/qux
17+
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
18+
19+
# You can also negate patterns with an exclamation (!).
20+
# For example, you can ignore all files in a docs folder with the file extension .md:
21+
#docs/*.md
22+
# Then explicitly reverse the ignore rule for a single file:
23+
#!docs/README.md

0 commit comments

Comments
 (0)