Support for configuring the ExceptionPropagationPolicy (#261)

Can be configured via properties or as a `@Bean`.

Fixes GH-243
This commit is contained in:
Aaron Whiteside
2020-01-14 12:02:40 +11:00
committed by Spencer Gibb
parent b1e38db1e2
commit 90400b9e43
5 changed files with 71 additions and 2 deletions

View File

@@ -21,6 +21,7 @@ import java.util.Objects;
import feign.Client;
import feign.Contract;
import feign.ExceptionPropagationPolicy;
import feign.Feign;
import feign.Logger;
import feign.QueryMapEncoder;
@@ -156,6 +157,11 @@ class FeignClientFactoryBean
if (this.decode404) {
builder.decode404();
}
ExceptionPropagationPolicy exceptionPropagationPolicy = getOptional(context,
ExceptionPropagationPolicy.class);
if (exceptionPropagationPolicy != null) {
builder.exceptionPropagationPolicy(exceptionPropagationPolicy);
}
}
protected void configureUsingProperties(
@@ -210,6 +216,10 @@ class FeignClientFactoryBean
if (Objects.nonNull(config.getContract())) {
builder.contract(getOrInstantiate(config.getContract()));
}
if (Objects.nonNull(config.getExceptionPropagationPolicy())) {
builder.exceptionPropagationPolicy(config.getExceptionPropagationPolicy());
}
}
private <T> T getOrInstantiate(Class<T> tClass) {

View File

@@ -22,6 +22,7 @@ import java.util.Map;
import java.util.Objects;
import feign.Contract;
import feign.ExceptionPropagationPolicy;
import feign.Logger;
import feign.RequestInterceptor;
import feign.Retryer;
@@ -111,6 +112,8 @@ public class FeignClientProperties {
private Class<Contract> contract;
private ExceptionPropagationPolicy exceptionPropagationPolicy;
public Logger.Level getLoggerLevel() {
return this.loggerLevel;
}
@@ -192,6 +195,15 @@ public class FeignClientProperties {
this.contract = contract;
}
public ExceptionPropagationPolicy getExceptionPropagationPolicy() {
return exceptionPropagationPolicy;
}
public void setExceptionPropagationPolicy(
ExceptionPropagationPolicy exceptionPropagationPolicy) {
this.exceptionPropagationPolicy = exceptionPropagationPolicy;
}
@Override
public boolean equals(Object o) {
if (this == o) {
@@ -210,14 +222,17 @@ public class FeignClientProperties {
&& Objects.equals(this.decode404, that.decode404)
&& Objects.equals(this.encoder, that.encoder)
&& Objects.equals(this.decoder, that.decoder)
&& Objects.equals(this.contract, that.contract);
&& Objects.equals(this.contract, that.contract)
&& Objects.equals(this.exceptionPropagationPolicy,
that.exceptionPropagationPolicy);
}
@Override
public int hashCode() {
return Objects.hash(this.loggerLevel, this.connectTimeout, this.readTimeout,
this.retryer, this.errorDecoder, this.requestInterceptors,
this.decode404, this.encoder, this.decoder, this.contract);
this.decode404, this.encoder, this.decoder, this.contract,
this.exceptionPropagationPolicy);
}
}

View File

@@ -17,6 +17,7 @@
package org.springframework.cloud.openfeign;
import feign.Contract;
import feign.ExceptionPropagationPolicy;
import feign.Feign;
import feign.Logger;
import feign.QueryMapEncoder;
@@ -151,6 +152,14 @@ public class FeignClientOverrideDefaultsTests {
.isEqualTo(2);
}
@Test
public void exceptionPropagationPolicy() {
assertThat(this.context.getInstances("foo", ExceptionPropagationPolicy.class))
.isNull();
assertThat(this.context.getInstances("bar", ExceptionPropagationPolicy.class))
.containsValues(ExceptionPropagationPolicy.UNWRAP);
}
@FeignClient(name = "foo", url = "https://foo",
configuration = FooConfiguration.class)
interface FooClient {
@@ -252,6 +261,11 @@ public class FeignClientOverrideDefaultsTests {
return new BeanQueryMapEncoder();
}
@Bean
public ExceptionPropagationPolicy exceptionPropagationPolicy() {
return ExceptionPropagationPolicy.UNWRAP;
}
}
}

View File

@@ -16,7 +16,9 @@
package org.springframework.cloud.openfeign;
import java.io.IOException;
import java.lang.reflect.Type;
import java.net.SocketTimeoutException;
import java.util.Collections;
import java.util.Map;
@@ -78,6 +80,8 @@ public class FeignClientUsingPropertiesTests {
private FeignClientFactoryBean barFactoryBean;
private FeignClientFactoryBean unwrapFactoryBean;
private FeignClientFactoryBean formFactoryBean;
public FeignClientUsingPropertiesTests() {
@@ -89,6 +93,10 @@ public class FeignClientUsingPropertiesTests {
this.barFactoryBean.setContextId("bar");
this.barFactoryBean.setType(FeignClientFactoryBean.class);
this.unwrapFactoryBean = new FeignClientFactoryBean();
this.unwrapFactoryBean.setContextId("unwrap");
this.unwrapFactoryBean.setType(FeignClientFactoryBean.class);
this.formFactoryBean = new FeignClientFactoryBean();
this.formFactoryBean.setContextId("form");
this.formFactoryBean.setType(FeignClientFactoryBean.class);
@@ -106,6 +114,12 @@ public class FeignClientUsingPropertiesTests {
"http://localhost:" + this.port);
}
public UnwrapClient unwrapClient() {
this.unwrapFactoryBean.setApplicationContext(this.applicationContext);
return this.unwrapFactoryBean.feign(this.context).target(UnwrapClient.class,
"http://localhost:" + this.port);
}
public FormClient formClient() {
this.formFactoryBean.setApplicationContext(this.applicationContext);
return this.formFactoryBean.feign(this.context).target(FormClient.class,
@@ -124,6 +138,12 @@ public class FeignClientUsingPropertiesTests {
fail("it should timeout");
}
@Test(expected = SocketTimeoutException.class)
public void testUnwrap() throws Exception {
unwrapClient().unwrap();
fail("it should timeout");
}
@Test
public void testForm() {
Map<String, String> request = Collections.singletonMap("form", "Data");
@@ -145,6 +165,13 @@ public class FeignClientUsingPropertiesTests {
}
protected interface UnwrapClient {
@RequestMapping(method = RequestMethod.GET, value = "/bar") // intentionally /bar
String unwrap() throws IOException;
}
protected interface FormClient {
@RequestMapping(value = "/form", method = RequestMethod.POST,

View File

@@ -13,3 +13,6 @@ feign.client.config.foo.requestInterceptors[1]=org.springframework.cloud.openfei
feign.client.config.bar.connectTimeout=1000
feign.client.config.bar.readTimeout=1000
feign.client.config.form.encoder=org.springframework.cloud.openfeign.FeignClientUsingPropertiesTests.FormEncoder
feign.client.config.unwrap.connectTimeout=1000
feign.client.config.unwrap.readTimeout=1000
feign.client.config.unwrap.exceptionPropagationPolicy=unwrap