Skip to content
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

Add support for configuring RestTemplate via RestTemplateBuilder (#4255) #4262

Merged
merged 1 commit into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -34,6 +34,7 @@
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.cloud.configuration.SSLContextFactory;
import org.springframework.cloud.configuration.TlsProperties;
import org.springframework.cloud.netflix.eureka.RestTemplateTimeoutProperties;
Expand Down Expand Up @@ -69,11 +70,11 @@ public TlsProperties tlsProperties() {
@ConditionalOnProperty(prefix = "eureka.client", name = "webclient.enabled", matchIfMissing = true,
havingValue = "false")
public RestTemplateDiscoveryClientOptionalArgs restTemplateDiscoveryClientOptionalArgs(TlsProperties tlsProperties,
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier)
throws GeneralSecurityException, IOException {
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please add your full name and surname with @author tag to the javadoc of all the files you've modified. Please update the year in the license comments of the files you've modified.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@ZIRAKrezovic Actually, I'm just going to do it for you, since I'd like to make sure we include this in the upcoming release.

ObjectProvider<RestTemplateBuilder> restTemplateBuilders) throws GeneralSecurityException, IOException {
logger.info("Eureka HTTP Client uses RestTemplate.");
RestTemplateDiscoveryClientOptionalArgs result = new RestTemplateDiscoveryClientOptionalArgs(
eurekaClientHttpRequestFactorySupplier);
eurekaClientHttpRequestFactorySupplier, restTemplateBuilders::getIfAvailable);
setupTLS(result, tlsProperties);
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration;
import org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.cloud.config.client.ConfigServerInstanceProvider;
import org.springframework.cloud.config.client.ConfigServicePropertySourceLocator;
import org.springframework.cloud.configuration.TlsProperties;
Expand Down Expand Up @@ -70,9 +71,10 @@ public EurekaClientConfigBean eurekaClientConfigBean() {
havingValue = "false")
public RestTemplateEurekaHttpClient configDiscoveryRestTemplateEurekaHttpClient(EurekaClientConfigBean config,
Environment env, @Nullable TlsProperties properties,
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier) {
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier,
ObjectProvider<RestTemplateBuilder> restTemplateBuilders) {
return (RestTemplateEurekaHttpClient) new RestTemplateTransportClientFactory(properties,
eurekaClientHttpRequestFactorySupplier)
eurekaClientHttpRequestFactorySupplier, restTemplateBuilders::getIfAvailable)
.newClient(HostnameBasedUrlRandomizer.randomEndpoint(config, env));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,31 @@

package org.springframework.cloud.netflix.eureka.http;

import java.util.function.Supplier;

import com.netflix.discovery.AbstractDiscoveryClientOptionalArgs;

import org.springframework.boot.web.client.RestTemplateBuilder;

/**
* @author Daniel Lavoie
*/
public class RestTemplateDiscoveryClientOptionalArgs extends AbstractDiscoveryClientOptionalArgs<Void> {

protected final EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier;

protected final Supplier<RestTemplateBuilder> restTemplateBuilderSupplier;

public RestTemplateDiscoveryClientOptionalArgs(
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier) {
this(eurekaClientHttpRequestFactorySupplier, RestTemplateBuilder::new);
}

public RestTemplateDiscoveryClientOptionalArgs(
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier,
Supplier<RestTemplateBuilder> restTemplateBuilderSupplier) {
this.eurekaClientHttpRequestFactorySupplier = eurekaClientHttpRequestFactorySupplier;
this.restTemplateBuilderSupplier = restTemplateBuilderSupplier;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,15 @@ public RestTemplateTransportClientFactories(RestTemplateDiscoveryClientOptionalA
public TransportClientFactory newTransportClientFactory(EurekaClientConfig clientConfig,
Collection<Void> additionalFilters, InstanceInfo myInstanceInfo) {
return new RestTemplateTransportClientFactory(this.args.getSSLContext(), this.args.getHostnameVerifier(),
this.args.eurekaClientHttpRequestFactorySupplier);
this.args.eurekaClientHttpRequestFactorySupplier, this.args.restTemplateBuilderSupplier);
}

@Override
public TransportClientFactory newTransportClientFactory(final EurekaClientConfig clientConfig,
final Collection<Void> additionalFilters, final InstanceInfo myInstanceInfo,
final Optional<SSLContext> sslContext, final Optional<HostnameVerifier> hostnameVerifier) {
return new RestTemplateTransportClientFactory(this.args.getSSLContext(), this.args.getHostnameVerifier(),
this.args.eurekaClientHttpRequestFactorySupplier);
this.args.eurekaClientHttpRequestFactorySupplier, this.args.restTemplateBuilderSupplier);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Optional;
import java.util.function.Supplier;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
Expand All @@ -44,6 +45,7 @@
import com.netflix.discovery.shared.transport.EurekaHttpClient;
import com.netflix.discovery.shared.transport.TransportClientFactory;

import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.cloud.configuration.SSLContextFactory;
import org.springframework.cloud.configuration.TlsProperties;
import org.springframework.http.HttpHeaders;
Expand Down Expand Up @@ -72,11 +74,20 @@ public class RestTemplateTransportClientFactory implements TransportClientFactor

private final EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier;

private final Supplier<RestTemplateBuilder> restTemplateBuilderSupplier;

public RestTemplateTransportClientFactory(TlsProperties tlsProperties,
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier) {
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier,
Supplier<RestTemplateBuilder> restTemplateBuilderSupplier) {
this.sslContext = context(tlsProperties);
this.hostnameVerifier = Optional.empty();
this.eurekaClientHttpRequestFactorySupplier = eurekaClientHttpRequestFactorySupplier;
this.restTemplateBuilderSupplier = restTemplateBuilderSupplier;
}

public RestTemplateTransportClientFactory(TlsProperties tlsProperties,
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier) {
this(tlsProperties, eurekaClientHttpRequestFactorySupplier, RestTemplateBuilder::new);
}

private Optional<SSLContext> context(TlsProperties properties) {
Expand All @@ -93,16 +104,23 @@ private Optional<SSLContext> context(TlsProperties properties) {

public RestTemplateTransportClientFactory(Optional<SSLContext> sslContext,
Optional<HostnameVerifier> hostnameVerifier,
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier) {
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier,
Supplier<RestTemplateBuilder> restTemplateBuilderSupplier) {
this.sslContext = sslContext;
this.hostnameVerifier = hostnameVerifier;
this.eurekaClientHttpRequestFactorySupplier = eurekaClientHttpRequestFactorySupplier;
this.restTemplateBuilderSupplier = restTemplateBuilderSupplier;
}

public RestTemplateTransportClientFactory(Optional<SSLContext> sslContext,
Optional<HostnameVerifier> hostnameVerifier,
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier) {

this(sslContext, hostnameVerifier, eurekaClientHttpRequestFactorySupplier, RestTemplateBuilder::new);
}

public RestTemplateTransportClientFactory() {
this.sslContext = Optional.empty();
this.hostnameVerifier = Optional.empty();
this.eurekaClientHttpRequestFactorySupplier = new DefaultEurekaClientHttpRequestFactorySupplier();
this(Optional.empty(), Optional.empty(), new DefaultEurekaClientHttpRequestFactorySupplier());
}

@Override
Expand All @@ -120,7 +138,15 @@ private String stripUserInfo(String serviceUrl) {
private RestTemplate restTemplate(String serviceUrl) {
ClientHttpRequestFactory requestFactory = this.eurekaClientHttpRequestFactorySupplier
.get(this.sslContext.orElse(null), this.hostnameVerifier.orElse(null));
RestTemplate restTemplate = new RestTemplate(requestFactory);

RestTemplate restTemplate;

if (restTemplateBuilderSupplier != null && restTemplateBuilderSupplier.get() != null) {
restTemplate = restTemplateBuilderSupplier.get().requestFactory(() -> requestFactory).build();
}
else {
restTemplate = new RestTemplate(requestFactory);
}

try {
URI serviceURI = new URI(serviceUrl);
Expand Down