Commit 22b08f1a by Dave Syer

Fix Feign Ribbon with Apache HTTP client

The Apcahe client does not allow empty body for PATCH, nor does it allow a request to be pre-populated with a Content-Length. Spring Cloud tests were trying to do the former, and Feign allows the latter.
parent 65ec7730
...@@ -59,19 +59,19 @@ public class FeignClientsConfiguration { ...@@ -59,19 +59,19 @@ public class FeignClientsConfiguration {
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
public Decoder feignDecoder() { public Decoder feignDecoder() {
return new ResponseEntityDecoder(new SpringDecoder(messageConverters)); return new ResponseEntityDecoder(new SpringDecoder(this.messageConverters));
} }
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
public Encoder feignEncoder() { public Encoder feignEncoder() {
return new SpringEncoder(messageConverters); return new SpringEncoder(this.messageConverters);
} }
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
public Contract feignContract() { public Contract feignContract() {
return new SpringMvcContract(parameterProcessors); return new SpringMvcContract(this.parameterProcessors);
} }
@Configuration @Configuration
...@@ -101,9 +101,10 @@ public class FeignClientsConfiguration { ...@@ -101,9 +101,10 @@ public class FeignClientsConfiguration {
private HttpClient httpClient; private HttpClient httpClient;
@ConditionalOnMissingBean @ConditionalOnMissingBean
@Bean
public Client feignClient() { public Client feignClient() {
if (httpClient != null) { if (this.httpClient != null) {
return new ApacheHttpClient(httpClient); return new ApacheHttpClient(this.httpClient);
} }
return new ApacheHttpClient(); return new ApacheHttpClient();
} }
......
...@@ -19,6 +19,7 @@ package org.springframework.cloud.netflix.feign.ribbon; ...@@ -19,6 +19,7 @@ package org.springframework.cloud.netflix.feign.ribbon;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.util.Collection; import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import org.springframework.cloud.netflix.ribbon.ServerIntrospector; import org.springframework.cloud.netflix.ribbon.ServerIntrospector;
...@@ -39,6 +40,7 @@ import feign.Client; ...@@ -39,6 +40,7 @@ import feign.Client;
import feign.Request; import feign.Request;
import feign.RequestTemplate; import feign.RequestTemplate;
import feign.Response; import feign.Response;
import feign.Util;
public class FeignLoadBalancer extends public class FeignLoadBalancer extends
AbstractLoadBalancerAwareClient<FeignLoadBalancer.RibbonRequest, FeignLoadBalancer.RibbonResponse> { AbstractLoadBalancerAwareClient<FeignLoadBalancer.RibbonRequest, FeignLoadBalancer.RibbonResponse> {
...@@ -112,14 +114,22 @@ public class FeignLoadBalancer extends ...@@ -112,14 +114,22 @@ public class FeignLoadBalancer extends
RibbonRequest(Client client, Request request, URI uri) { RibbonRequest(Client client, Request request, URI uri) {
this.client = client; this.client = client;
this.request = request;
setUri(uri); setUri(uri);
this.request = toRequest(request);
}
private Request toRequest(Request request) {
Map<String, Collection<String>> headers = new LinkedHashMap<>(
request.headers());
// Apache client barfs if you set the content length
headers.remove(Util.CONTENT_LENGTH);
return new RequestTemplate().method(request.method())
.append(getUri().toASCIIString())
.body(request.body(), request.charset()).headers(headers).request();
} }
Request toRequest() { Request toRequest() {
return new RequestTemplate().method(this.request.method()) return toRequest(this.request);
.append(getUri().toASCIIString()).headers(this.request.headers())
.body(this.request.body(), this.request.charset()).request();
} }
Client client() { Client client() {
......
...@@ -63,7 +63,6 @@ public class FeignRibbonClientAutoConfiguration { ...@@ -63,7 +63,6 @@ public class FeignRibbonClientAutoConfiguration {
@Configuration @Configuration
@ConditionalOnClass(ApacheHttpClient.class) @ConditionalOnClass(ApacheHttpClient.class)
@ConditionalOnProperty(value = "feign.httpclient.enabled", matchIfMissing = true) @ConditionalOnProperty(value = "feign.httpclient.enabled", matchIfMissing = true)
@ConditionalOnMissingBean(Client.class)
protected static class HttpClientConfiguration { protected static class HttpClientConfiguration {
@Autowired(required = false) @Autowired(required = false)
...@@ -73,6 +72,7 @@ public class FeignRibbonClientAutoConfiguration { ...@@ -73,6 +72,7 @@ public class FeignRibbonClientAutoConfiguration {
CachingSpringLoadBalancerFactory cachingFactory; CachingSpringLoadBalancerFactory cachingFactory;
@Bean @Bean
@ConditionalOnMissingBean(Client.class)
public Client feignClient() { public Client feignClient() {
ApacheHttpClient delegate; ApacheHttpClient delegate;
if (this.httpClient != null) { if (this.httpClient != null) {
...@@ -88,7 +88,6 @@ public class FeignRibbonClientAutoConfiguration { ...@@ -88,7 +88,6 @@ public class FeignRibbonClientAutoConfiguration {
@Configuration @Configuration
@ConditionalOnClass(OkHttpClient.class) @ConditionalOnClass(OkHttpClient.class)
@ConditionalOnProperty(value = "feign.okhttp.enabled", matchIfMissing = true) @ConditionalOnProperty(value = "feign.okhttp.enabled", matchIfMissing = true)
@ConditionalOnMissingBean(Client.class)
protected static class OkHttpConfiguration { protected static class OkHttpConfiguration {
@Autowired(required = false) @Autowired(required = false)
...@@ -98,6 +97,7 @@ public class FeignRibbonClientAutoConfiguration { ...@@ -98,6 +97,7 @@ public class FeignRibbonClientAutoConfiguration {
CachingSpringLoadBalancerFactory cachingFactory; CachingSpringLoadBalancerFactory cachingFactory;
@Bean @Bean
@ConditionalOnMissingBean(Client.class)
public Client feignClient() { public Client feignClient() {
OkHttpClient delegate; OkHttpClient delegate;
if (this.okHttpClient != null) { if (this.okHttpClient != null) {
......
...@@ -36,7 +36,8 @@ public class LoadBalancerFeignClient implements Client { ...@@ -36,7 +36,8 @@ public class LoadBalancerFeignClient implements Client {
private final Client delegate; private final Client delegate;
private CachingSpringLoadBalancerFactory lbClientFactory; private CachingSpringLoadBalancerFactory lbClientFactory;
public LoadBalancerFeignClient(Client delegate, CachingSpringLoadBalancerFactory lbClientFactory) { public LoadBalancerFeignClient(Client delegate,
CachingSpringLoadBalancerFactory lbClientFactory) {
this.delegate = delegate; this.delegate = delegate;
this.lbClientFactory = lbClientFactory; this.lbClientFactory = lbClientFactory;
} }
...@@ -47,8 +48,8 @@ public class LoadBalancerFeignClient implements Client { ...@@ -47,8 +48,8 @@ public class LoadBalancerFeignClient implements Client {
URI asUri = URI.create(request.url()); URI asUri = URI.create(request.url());
String clientName = asUri.getHost(); String clientName = asUri.getHost();
URI uriWithoutHost = cleanUrl(request.url(), clientName); URI uriWithoutHost = cleanUrl(request.url(), clientName);
FeignLoadBalancer.RibbonRequest ribbonRequest = new FeignLoadBalancer.RibbonRequest(this.delegate, FeignLoadBalancer.RibbonRequest ribbonRequest = new FeignLoadBalancer.RibbonRequest(
request, uriWithoutHost); this.delegate, request, uriWithoutHost);
return lbClient(clientName).executeWithLoadBalancer(ribbonRequest, return lbClient(clientName).executeWithLoadBalancer(ribbonRequest,
new FeignOptionsClientConfig(options)).toResponse(); new FeignOptionsClientConfig(options)).toResponse();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment