Skip to content

spring-http-interface: introduce springHttpClientAdapter, fix paramDoc.mustache #19710

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
814ee9b
spring-http-interface: introduce `springHttpClientAdapter`, fix `para…
ibaranga Sep 29, 2024
f1bbe1b
fix imports
ibaranga Sep 29, 2024
4e03298
Update SpringCodegen.java
ibaranga Sep 29, 2024
0f9bfb1
fix docs and default value
ibaranga Oct 1, 2024
33649f3
Merge remote-tracking branch 'origin/master'
ibaranga Oct 1, 2024
c85e8cd
Merge remote-tracking branch 'myfork/master'
ibaranga Oct 1, 2024
4c3bdae
fix docs and default value
ibaranga Oct 1, 2024
277c928
Merge remote-tracking branch 'origin/master'
ibaranga Oct 9, 2024
6addc9a
revert to HttpServiceProxyFactory.builder for backward compatibility
ibaranga Oct 16, 2024
21e024a
Merge remote-tracking branch 'origin/master'
ibaranga Oct 16, 2024
1ab55cd
Merge remote-tracking branch 'origin/master'
ibaranga Oct 17, 2024
0cd4f75
Merge remote-tracking branch 'origin/master'
ibaranga Nov 30, 2024
6a55e5d
spring-http-interface: introduce `useHttpServiceProxyFactoryInterface…
ibaranga Nov 30, 2024
d84e5f3
Merge remote-tracking branch 'origin/master'
ibaranga Nov 30, 2024
02bb3c7
spring-http-interface: introduce `useHttpServiceProxyFactoryInterface…
ibaranga Nov 30, 2024
c79efb9
spring-http-interface: introduce `useHttpServiceProxyFactoryInterface…
ibaranga Nov 30, 2024
79fbb71
spring-http-interface: fix generated files
ibaranga Nov 30, 2024
176322a
Merge remote-tracking branch 'origin/master'
ibaranga Mar 4, 2025
71e28b3
remove unnecessary imports from httpServiceProxyFactoryInterfacesConf…
ibaranga Mar 4, 2025
3de14ae
Merge branch 'OpenAPITools:master' into master
ibaranga Mar 4, 2025
6408374
remove unnecessary paramDoc.mustache, update `useHttpServiceProxyFact…
ibaranga Mar 6, 2025
ba281f4
Merge remote-tracking branch 'origin/master'
ibaranga Mar 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@
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;
Expand Down Expand Up @@ -102,6 +104,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";
Expand All @@ -126,6 +129,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 = "}";

Expand Down Expand Up @@ -165,6 +187,7 @@ public class SpringCodegen extends AbstractJavaCodegen
protected boolean generatedConstructorWithRequiredArgs = true;
@Getter @Setter
protected RequestMappingMode requestMappingMode = RequestMappingMode.controller;
@Setter SpringHttpClientAdapter springHttpClientAdapter;

public SpringCodegen() {
super();
Expand Down Expand Up @@ -268,6 +291,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.");
Expand Down Expand Up @@ -443,7 +470,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");
Expand Down Expand Up @@ -528,7 +557,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);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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}}

}
Original file line number Diff line number Diff line change
@@ -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}}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is marked as deprecated, replacing it with builderFor, which is also in line with the rest of the httpInterfaces*Configuration.mustache templates

return factory.createClient({{classname}}.class);
}

Expand Down