spring-cloud-openfeign
spring-cloud-openfeign copied to clipboard
SpringBoot OpenFeign Ignores Custom CloseablehttpClient
I am trying to create a custom closeablehttpclient using OpenFeign that is behind an NTLM proxy. After searching thru internet I finally discovered an example of a Closeablehttpclient that supposedly works going thru NTLM proxy. When I create a bean of the client ... Spring Boot Simply ignores it ... I THINK. Now This is what I observed:
- if I used the exact same bean in a tiny standalone java application .... it works and connects to an external client thru the NTLM proxy.
- if I used the exact same bean in a SpringBoot Openfeign client , spring seems to use some other default client ?
Question: If there a bug or limitation in SpringBoot when it comes to using CloseableHttpClients ? I am looking for a simple, clear and concise answer to this if there is such an answer. I can supply additional information if required, however my source code is proprietary and basically illegal for me to share it exactly. I have updated properties file as follows: feign.httpclient.enabled=true feign.httpclient.disableSslValidation=true
Mave Pom as followsI added these dependencies: feign-httpclient httpclient ( 4.5.13 ) Spring boot version 2.6.1
Now the code I use for the http client works stand alone ... but is not called if I try to use it as a custom feign client .. Thanks for any info you can supply.
I think there is a bug.
in FeignAutoConfiguration
class, defined how to inject HttpClient:
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(ApacheHttpClient.class)
@ConditionalOnMissingBean(CloseableHttpClient.class)
@ConditionalOnProperty(value = "spring.cloud.openfeign.httpclient.enabled", matchIfMissing = true)
@Conditional(HttpClient5DisabledConditions.class)
protected static class HttpClientFeignConfiguration {
private final Timer connectionManagerTimer = new Timer(
"FeignApacheHttpClientConfiguration.connectionManagerTimer", true);
@Autowired(required = false)
private RegistryBuilder registryBuilder;
private CloseableHttpClient httpClient;
@Bean
@ConditionalOnMissingBean(HttpClientConnectionManager.class)
public HttpClientConnectionManager connectionManager(
ApacheHttpClientConnectionManagerFactory connectionManagerFactory,
FeignHttpClientProperties httpClientProperties) {
final HttpClientConnectionManager connectionManager = connectionManagerFactory.newConnectionManager(
httpClientProperties.isDisableSslValidation(), httpClientProperties.getMaxConnections(),
httpClientProperties.getMaxConnectionsPerRoute(), httpClientProperties.getTimeToLive(),
httpClientProperties.getTimeToLiveUnit(), this.registryBuilder);
this.connectionManagerTimer.schedule(new TimerTask() {
@Override
public void run() {
connectionManager.closeExpiredConnections();
}
}, 30000, httpClientProperties.getConnectionTimerRepeat());
return connectionManager;
}
@Bean
public CloseableHttpClient httpClient(ApacheHttpClientFactory httpClientFactory,
HttpClientConnectionManager httpClientConnectionManager,
FeignHttpClientProperties httpClientProperties) {
RequestConfig defaultRequestConfig = RequestConfig.custom()
.setConnectTimeout(httpClientProperties.getConnectionTimeout())
.setRedirectsEnabled(httpClientProperties.isFollowRedirects()).build();
this.httpClient = httpClientFactory.createBuilder().setConnectionManager(httpClientConnectionManager)
.setDefaultRequestConfig(defaultRequestConfig).build();
return this.httpClient;
}
@Bean
@ConditionalOnMissingBean(Client.class)
public Client feignClient(HttpClient httpClient) {
return new ApacheHttpClient(httpClient);
}
@PreDestroy
public void destroy() {
this.connectionManagerTimer.cancel();
if (this.httpClient != null) {
try {
this.httpClient.close();
}
catch (IOException e) {
if (LOG.isErrorEnabled()) {
LOG.error("Could not correctly close httpClient.");
}
}
}
}
}
this class not inject bean otherwise has some Condition like annotation.
be attention of ConditionalOnMissingBean
annotation, this annotation means that only inject httpClient when spring context dose not have CloseableHttpClient
, so if u declare other Configuration that include CloseableHttpClient bean, openfeign config feign.httpclient.disableSslValidation will be invalid.
from version 4.0.0-SNAPSHOT
Not sure if this helps you but I have openfeign use apache httpclient4 ( and httclient5 ) to connect through an outbound proxy that requires NTLM authentication.
Below is a snapshot on how to use hc5 with NTLM proxy :
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-hc5</artifactId>
</dependency>
@Bean
public ApacheHttp5Client feignClient() {
....
// Proxy credentials
BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(new AuthScope(proxyHost, proxyPort),
new NTCredentials(proxyUser, proxyPwd.toCharArray(), "", proxyDomain));
// Proxy
clientBuilder.setProxy(new HttpHost(proxyHost, proxyPort));
clientBuilder.setDefaultCredentialsProvider(credentialsProvider);
clientBuilder.setProxyAuthenticationStrategy(new DefaultAuthenticationStrategy());
....
return new ApacheHttp5Client(clientBuilder.build());
}
You can also use HttpClient4 if you want.
thanks for he info. I did manage to figure out the NTLM issue using openfeign with apatche http client. However, since that time we changed from NtlM to a NON-NTLM proxy and everything works smoothly
Closing as confirmed as resolved by the reporter.