Commit d7898297 by Spencer Gibb

add support for feign RequestInterceptors

fixes gh-159
parent 6435b73f
...@@ -16,21 +16,18 @@ ...@@ -16,21 +16,18 @@
package org.springframework.cloud.netflix.feign; package org.springframework.cloud.netflix.feign;
import feign.slf4j.Slf4jLogger; import java.util.List;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.archaius.ConfigurableEnvironmentConfiguration; import org.springframework.cloud.netflix.archaius.ConfigurableEnvironmentConfiguration;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import feign.Client; import feign.*;
import feign.Contract;
import feign.Feign;
import feign.Logger;
import feign.Request;
import feign.Retryer;
import feign.codec.Decoder; import feign.codec.Decoder;
import feign.codec.Encoder; import feign.codec.Encoder;
import feign.codec.ErrorDecoder; import feign.codec.ErrorDecoder;
import feign.ribbon.LoadBalancingTarget; import feign.ribbon.LoadBalancingTarget;
import feign.slf4j.Slf4jLogger;
/** /**
* @author Spencer Gibb * @author Spencer Gibb
...@@ -68,6 +65,9 @@ public class FeignConfiguration { ...@@ -68,6 +65,9 @@ public class FeignConfiguration {
@Autowired(required = false) @Autowired(required = false)
private Client ribbonClient; private Client ribbonClient;
@Autowired(required = false)
private List<RequestInterceptor> requestInterceptors;
protected Feign.Builder feign() { protected Feign.Builder feign() {
Feign.Builder builder = Feign.builder() Feign.Builder builder = Feign.builder()
// required values // required values
...@@ -87,6 +87,9 @@ public class FeignConfiguration { ...@@ -87,6 +87,9 @@ public class FeignConfiguration {
if (this.options != null) { if (this.options != null) {
builder.options(this.options); builder.options(this.options);
} }
if (this.requestInterceptors != null) {
builder.requestInterceptors(requestInterceptors);
}
return builder; return builder;
} }
...@@ -96,7 +99,7 @@ public class FeignConfiguration { ...@@ -96,7 +99,7 @@ public class FeignConfiguration {
} }
protected <T> T loadBalance(Feign.Builder builder, Class<T> type, String schemeName) { protected <T> T loadBalance(Feign.Builder builder, Class<T> type, String schemeName) {
builder.logger(new Slf4jLogger(type)); //TODO: how to have choice here? builder.logger(new Slf4jLogger(type)); // TODO: how to have choice here?
if (this.ribbonClient != null) { if (this.ribbonClient != null) {
return builder.client(this.ribbonClient).target(type, schemeName); return builder.client(this.ribbonClient).target(type, schemeName);
} }
......
...@@ -16,9 +16,13 @@ ...@@ -16,9 +16,13 @@
package org.springframework.cloud.netflix.feign; package org.springframework.cloud.netflix.feign;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
...@@ -33,16 +37,25 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; ...@@ -33,16 +37,25 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.test.IntegrationTest; import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import static org.junit.Assert.assertNotNull; import com.netflix.loadbalancer.BaseLoadBalancer;
import static org.junit.Assert.assertTrue; import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import static org.junit.Assert.*;
/** /**
* @author Spencer Gibb * @author Spencer Gibb
...@@ -61,7 +74,7 @@ public class FeignClientTests extends FeignConfiguration { ...@@ -61,7 +74,7 @@ public class FeignClientTests extends FeignConfiguration {
private TestClient testClient; private TestClient testClient;
// @FeignClient(value = "http://localhost:9876", loadbalance = false) // @FeignClient(value = "http://localhost:9876", loadbalance = false)
@FeignClient("feignclienttest") @FeignClient("localapp")
protected static interface TestClient { protected static interface TestClient {
@RequestMapping(method = RequestMethod.GET, value = "/hello") @RequestMapping(method = RequestMethod.GET, value = "/hello")
public Hello getHello(); public Hello getHello();
...@@ -71,14 +84,38 @@ public class FeignClientTests extends FeignConfiguration { ...@@ -71,14 +84,38 @@ public class FeignClientTests extends FeignConfiguration {
@RequestMapping(method = RequestMethod.GET, value = "/hellostrings") @RequestMapping(method = RequestMethod.GET, value = "/hellostrings")
public List<String> getHelloStrings(); public List<String> getHelloStrings();
@RequestMapping(method = RequestMethod.GET, value = "/helloheaders")
public List<String> getHelloHeaders();
} }
@Configuration @Configuration
@EnableAutoConfiguration @EnableAutoConfiguration
@RestController @RestController
@FeignClientScan @FeignClientScan
@RibbonClient(name = "localapp", configuration = LocalRibbonClientConfiguration.class)
protected static class Application { protected static class Application {
@Bean
public RequestInterceptor interceptor1() {
return new RequestInterceptor() {
@Override
public void apply(RequestTemplate template) {
template.header("myheader1", "myheader1value");
}
};
}
@Bean
public RequestInterceptor interceptor2() {
return new RequestInterceptor() {
@Override
public void apply(RequestTemplate template) {
template.header("myheader2", "myheader2value");
}
};
}
@RequestMapping(method = RequestMethod.GET, value = "/hello") @RequestMapping(method = RequestMethod.GET, value = "/hello")
public Hello getHello() { public Hello getHello() {
return new Hello("hello world 1"); return new Hello("hello world 1");
...@@ -86,9 +123,7 @@ public class FeignClientTests extends FeignConfiguration { ...@@ -86,9 +123,7 @@ public class FeignClientTests extends FeignConfiguration {
@RequestMapping(method = RequestMethod.GET, value = "/hellos") @RequestMapping(method = RequestMethod.GET, value = "/hellos")
public List<Hello> getHellos() { public List<Hello> getHellos() {
ArrayList<Hello> hellos = new ArrayList<>(); ArrayList<Hello> hellos = getHelloList();
hellos.add(new Hello("hello world 1"));
hellos.add(new Hello("oi terra 2"));
return hellos; return hellos;
} }
...@@ -100,6 +135,15 @@ public class FeignClientTests extends FeignConfiguration { ...@@ -100,6 +135,15 @@ public class FeignClientTests extends FeignConfiguration {
return hellos; return hellos;
} }
@RequestMapping(method = RequestMethod.GET, value = "/helloheaders")
public List<String> getHelloHeaders(@RequestHeader("myheader1") String myheader1,
@RequestHeader("myheader2") String myheader2) {
ArrayList<String> headers = new ArrayList<>();
headers.add(myheader1);
headers.add(myheader2);
return headers;
}
public static void main(String[] args) { public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).properties( new SpringApplicationBuilder(Application.class).properties(
"spring.application.name=feignclienttest", "spring.application.name=feignclienttest",
...@@ -107,6 +151,13 @@ public class FeignClientTests extends FeignConfiguration { ...@@ -107,6 +151,13 @@ public class FeignClientTests extends FeignConfiguration {
} }
} }
private static ArrayList<Hello> getHelloList() {
ArrayList<Hello> hellos = new ArrayList<>();
hellos.add(new Hello("hello world 1"));
hellos.add(new Hello("oi terra 2"));
return hellos;
}
@Test @Test
public void testClient() { public void testClient() {
assertNotNull("testClient was null", this.testClient); assertNotNull("testClient was null", this.testClient);
...@@ -116,13 +167,27 @@ public class FeignClientTests extends FeignConfiguration { ...@@ -116,13 +167,27 @@ public class FeignClientTests extends FeignConfiguration {
assertNotNull("invocationHandler was null", invocationHandler); assertNotNull("invocationHandler was null", invocationHandler);
} }
// TODO: only works if port is hardcoded cant resolve ${local.server.port} in @Test
// annotation public void testSimpleType() {
/* Hello hello = testClient.getHello();
* @Test public void testSimpleType() { Hello hello = testClient.getHello(); assertNotNull("hello was null", hello);
* assertNotNull("hello was null", hello); assertEquals("first hello didn't match", assertEquals("first hello didn't match", new Hello("hello world 1"), hello);
* new Hello("hello world 1"), hello); } }
*/
@Test
public void testGenericType() {
List<Hello> hellos = testClient.getHellos();
assertNotNull("hellos was null", hellos);
assertEquals("hellos didn't match", hellos, getHelloList());
}
@Test
public void testRequestInterceptors() {
List<String> headers = testClient.getHelloHeaders();
assertNotNull("headers was null", headers);
assertTrue("headers didn't contain myheader1value", headers.contains("myheader1value"));
assertTrue("headers didn't contain myheader2value", headers.contains("myheader2value"));
}
@Data @Data
@AllArgsConstructor @AllArgsConstructor
...@@ -131,3 +196,19 @@ public class FeignClientTests extends FeignConfiguration { ...@@ -131,3 +196,19 @@ public class FeignClientTests extends FeignConfiguration {
private String message; private String message;
} }
} }
// Load balancer with fixed server list for "local" pointing to localhost
@Configuration
class LocalRibbonClientConfiguration {
@Value("${local.server.port}")
private int port = 0;
@Bean
public ILoadBalancer ribbonLoadBalancer() {
BaseLoadBalancer balancer = new BaseLoadBalancer();
balancer.setServersList(Arrays.asList(new Server("localhost", port)));
return balancer;
}
}
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