Skip to content
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
6 changes: 1 addition & 5 deletions docs/modules/ROOT/pages/spring-cloud-openfeign.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,10 @@ If none of them is on the classpath, the default Feign client is used.

NOTE: `spring-cloud-starter-openfeign` supports `spring-cloud-starter-loadbalancer`. However, as is an optional dependency, you need to make sure it has been added to your project if you want to use it.

To use OkHttpClient-backed Feign clients and Http2Client Feign clients, make sure that the client you want to use is on the classpath and set `spring.cloud.openfeign.okhttp.enabled` or `spring.cloud.openfeign.http2client.enabled` to `true` respectively.

When it comes to the Apache HttpClient 5-backed Feign clients, it's enough to ensure HttpClient 5 is on the classpath, but you can still disable its use for Feign Clients by setting `spring.cloud.openfeign.httpclient.hc5.enabled` to `false`.
You can customize the HTTP client used by providing a bean of either `org.apache.hc.client5.http.impl.classic.CloseableHttpClient` when using Apache HC5.

You can further customise http clients by setting values in the `spring.cloud.openfeign.httpclient.xxx` properties. The ones prefixed just with `httpclient` will work for all the clients, the ones prefixed with `httpclient.hc5` to Apache HttpClient 5, the ones prefixed with `httpclient.okhttp` to OkHttpClient and the ones prefixed with `httpclient.http2` to Http2Client. You can find a full list of properties you can customise in the appendix.
You can further customise http clients by setting values in the `spring.cloud.openfeign.httpclient.xxx` properties. The ones prefixed just with `httpclient` will work for all the clients, the ones prefixed with `httpclient.hc5` to Apache HttpClient 5, and the ones prefixed with `httpclient.http2` to Http2Client. You can find a full list of properties you can customise in the appendix.
If you can not configure Apache HttpClient 5 by using properties, there is an `HttpClient5FeignConfiguration.HttpClientBuilderCustomizer` interface for programmatic configuration.

TIP: Apache HTTP Components `5.4` have changed defaults in the HttpClient relating to HTTP/1.1 TLS upgrades. Most proxy servers handle upgrades without issue, however, you may encounter issues with Envoy or Istio. If you need to restore previous behaviour, you can use `HttpClient5FeignConfiguration.HttpClientBuilderCustomizer` to do it, as shown in the example below.
Expand Down Expand Up @@ -613,8 +611,6 @@ These properties allow you to be selective about the compressed media types and
When the request matches the mime type set in `spring.cloud.openfeign.compression.request.mime-types` and the size set in `spring.cloud.openfeign.compression.request.min-request-size`, `spring.cloud.openfeign.compression.request.enabled=true` results in compression headers being added to the request.
The functionality of the headers is to signal to the server that a compressed body is expected by the client. It is the responsibility of the server-side app to provide the compressed body based on the headers provided by the client.

TIP: Since the OkHttpClient uses "transparent" compression, that is disabled if the `content-encoding` or `accept-encoding` header is present, we do not enable compression when `feign.okhttp.OkHttpClient` is present on the classpath and `spring.cloud.openfeign.okhttp.enabled` is set to `true`.

[[feign-logging]]
=== Feign logging

Expand Down
6 changes: 2 additions & 4 deletions docs/modules/ROOT/partials/_configprops.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,12 @@
|spring.cloud.openfeign.httpclient.max-connections | `+++200+++` |
|spring.cloud.openfeign.httpclient.max-connections-per-route | `+++50+++` |
|spring.cloud.openfeign.httpclient.ok-http.protocols | | Configure the protocols used by this client to communicate with remote servers. Uses {@link String} values of {@link Protocol}.
|spring.cloud.openfeign.httpclient.ok-http.read-timeout | `+++60s+++` | {@link OkHttpClient} read timeout; defaults to 60 seconds.
|spring.cloud.openfeign.httpclient.time-to-live | `+++900+++` |
|spring.cloud.openfeign.httpclient.time-to-live | `+++900+++` |
|spring.cloud.openfeign.httpclient.time-to-live-unit | `+++seconds+++` |
|spring.cloud.openfeign.lazy-attributes-resolution | `+++false+++` | Switches @FeignClient attributes resolution mode to lazy.
|spring.cloud.openfeign.micrometer.enabled | `+++true+++` | Enables Micrometer capabilities for Feign.
|spring.cloud.openfeign.oauth2.clientRegistrationId | | Provides a clientId to be used with OAuth2.
|spring.cloud.openfeign.oauth2.enabled | `+++false+++` | Enables feign interceptor for managing oauth2 access token.
|spring.cloud.openfeign.okhttp.enabled | `+++false+++` | Enables the use of the OK HTTP Client by Feign.
|spring.cloud.refresh.additional-property-sources-to-retain | | Additional property sources to retain during a refresh. Typically only system property sources are retained. This property allows property sources, such as property sources created by EnvironmentPostProcessors to be retained as well.
|spring.cloud.refresh.enabled | `+++true+++` | Enables autoconfiguration for the refresh scope and associated features.
|spring.cloud.refresh.extra-refreshable | `+++true+++` | Additional bean names or class names for beans to post process into refresh scope.
Expand All @@ -114,4 +112,4 @@
|spring.cloud.service-registry.auto-registration.register-management | `+++true+++` | Whether to register the management as a service. Defaults to true.
|spring.cloud.util.enabled | `+++true+++` | Enables creation of Spring Cloud utility beans.

|===
|===
10 changes: 0 additions & 10 deletions spring-cloud-openfeign-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -134,21 +134,11 @@
<artifactId>feign-hc5</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-java11</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure-processor</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,9 @@

import java.lang.reflect.Method;
import java.net.http.HttpClient;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import feign.Capability;
import feign.Client;
Expand All @@ -42,10 +29,6 @@
import feign.Target;
import feign.hc5.ApacheHttp5Client;
import feign.http2client.Http2Client;
import feign.okhttp.OkHttpClient;
import jakarta.annotation.PreDestroy;
import okhttp3.ConnectionPool;
import okhttp3.Protocol;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

Expand Down Expand Up @@ -231,121 +214,6 @@ public String resolveCircuitBreakerName(String feignClientName, Target<?> target

}

// the following configuration is for alternate feign clients if
// SC loadbalancer is not on the class path.
// see corresponding configurations in FeignLoadBalancerAutoConfiguration
// for load-balanced clients.
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(OkHttpClient.class)
@ConditionalOnMissingBean(okhttp3.OkHttpClient.class)
@ConditionalOnProperty("spring.cloud.openfeign.okhttp.enabled")
protected static class OkHttpFeignConfiguration {

private okhttp3.OkHttpClient okHttpClient;

@Bean
@ConditionalOnMissingBean
public okhttp3.OkHttpClient.Builder okHttpClientBuilder() {
return new okhttp3.OkHttpClient.Builder();
}

@Bean
@ConditionalOnMissingBean(ConnectionPool.class)
public ConnectionPool httpClientConnectionPool(FeignHttpClientProperties httpClientProperties) {
int maxTotalConnections = httpClientProperties.getMaxConnections();
long timeToLive = httpClientProperties.getTimeToLive();
TimeUnit ttlUnit = httpClientProperties.getTimeToLiveUnit();
return new ConnectionPool(maxTotalConnections, timeToLive, ttlUnit);
}

@Bean
public okhttp3.OkHttpClient okHttpClient(okhttp3.OkHttpClient.Builder builder, ConnectionPool connectionPool,
FeignHttpClientProperties httpClientProperties) {
boolean followRedirects = httpClientProperties.isFollowRedirects();
int connectTimeout = httpClientProperties.getConnectionTimeout();
boolean disableSslValidation = httpClientProperties.isDisableSslValidation();
Duration readTimeout = httpClientProperties.getOkHttp().getReadTimeout();
List<Protocol> protocols = httpClientProperties.getOkHttp()
.getProtocols()
.stream()
.map(Protocol::valueOf)
.collect(Collectors.toList());
if (disableSslValidation) {
disableSsl(builder);
}
this.okHttpClient = builder.connectTimeout(connectTimeout, TimeUnit.MILLISECONDS)
.followRedirects(followRedirects)
.readTimeout(readTimeout)
.connectionPool(connectionPool)
.protocols(protocols)
.build();
return this.okHttpClient;
}

private void disableSsl(okhttp3.OkHttpClient.Builder builder) {
try {
X509TrustManager disabledTrustManager = new DisableValidationTrustManager();
TrustManager[] trustManagers = new TrustManager[1];
trustManagers[0] = disabledTrustManager;
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustManagers, new java.security.SecureRandom());
SSLSocketFactory disabledSSLSocketFactory = sslContext.getSocketFactory();
builder.sslSocketFactory(disabledSSLSocketFactory, disabledTrustManager);
builder.hostnameVerifier(new TrustAllHostnames());
}
catch (NoSuchAlgorithmException | KeyManagementException e) {
LOG.warn("Error setting SSLSocketFactory in OKHttpClient", e);
}
}

@PreDestroy
public void destroy() {
if (this.okHttpClient != null) {
this.okHttpClient.dispatcher().executorService().shutdown();
this.okHttpClient.connectionPool().evictAll();
}
}

@Bean
@ConditionalOnMissingBean(Client.class)
public Client feignClient(okhttp3.OkHttpClient client) {
return new OkHttpClient(client);
}

/**
* A {@link X509TrustManager} that does not validate SSL certificates.
*/
class DisableValidationTrustManager implements X509TrustManager {

@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) {
}

@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) {
}

@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}

}

/**
* A {@link HostnameVerifier} that does not validate any hostnames.
*/
class TrustAllHostnames implements HostnameVerifier {

@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}

}

}

// the following configuration is for alternate feign clients if
// SC loadbalancer is not on the class path.
// see corresponding configurations in FeignLoadBalancerAutoConfiguration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.openfeign.FeignAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;

/**
Expand All @@ -41,9 +40,6 @@
@ConditionalOnClass(Feign.class)
@ConditionalOnBean(Client.class)
@ConditionalOnProperty("spring.cloud.openfeign.compression.response.enabled")
// The OK HTTP client uses "transparent" compression.
// If the accept-encoding header is present, it disables transparent compression.
@Conditional(OkHttpFeignClientBeanMissingCondition.class)
@AutoConfigureAfter(FeignAutoConfiguration.class)
public class FeignAcceptGzipEncodingAutoConfiguration {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.openfeign.FeignAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;

/**
Expand All @@ -37,9 +36,6 @@
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(FeignClientEncodingProperties.class)
@ConditionalOnClass(Feign.class)
// The OK HTTP client uses "transparent" compression.
// If the content-encoding header is present, it disables transparent compression.
@Conditional(OkHttpFeignClientBeanMissingCondition.class)
@ConditionalOnProperty("spring.cloud.openfeign.compression.request.enabled")
@AutoConfigureAfter(FeignAutoConfiguration.class)
public class FeignContentGzipEncodingAutoConfiguration {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@
// Order is important here, last should be the default, first should be optional
// see
// https://github.com/spring-cloud/spring-cloud-netflix/issues/2086#issuecomment-316281653
@Import({ OkHttpFeignLoadBalancerConfiguration.class, HttpClient5FeignLoadBalancerConfiguration.class,
Http2ClientFeignLoadBalancerConfiguration.class, DefaultFeignLoadBalancerConfiguration.class })
@Import({ HttpClient5FeignLoadBalancerConfiguration.class, Http2ClientFeignLoadBalancerConfiguration.class,
DefaultFeignLoadBalancerConfiguration.class })
public class FeignLoadBalancerAutoConfiguration {

@Bean
Expand Down
Loading