Commit d7898297 by Spencer Gibb

add support for feign RequestInterceptors

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