Skip to content

Commit c0d8177

Browse files
committed
Override default dismiss404 config with client-specific config. Fixes gh-1005.
1 parent d2a7d4f commit c0d8177

File tree

3 files changed

+57
-31
lines changed

3 files changed

+57
-31
lines changed

spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientFactoryBean.java

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -171,12 +171,12 @@ protected void configureFeign(FeignClientFactory context, Feign.Builder builder)
171171
if (properties != null && inheritParentContext) {
172172
if (properties.isDefaultToProperties()) {
173173
configureUsingConfiguration(context, builder);
174-
configureUsingProperties(properties.getConfig().get(properties.getDefaultConfig()), builder);
175-
configureUsingProperties(properties.getConfig().get(contextId), builder);
174+
configureUsingProperties(properties.getConfig().get(properties.getDefaultConfig()),
175+
properties.getConfig().get(contextId), builder);
176176
}
177177
else {
178-
configureUsingProperties(properties.getConfig().get(properties.getDefaultConfig()), builder);
179-
configureUsingProperties(properties.getConfig().get(contextId), builder);
178+
configureUsingProperties(properties.getConfig().get(properties.getDefaultConfig()),
179+
properties.getConfig().get(contextId), builder);
180180
configureUsingConfiguration(context, builder);
181181
}
182182
configureDefaultRequestElements(properties.getConfig().get(properties.getDefaultConfig()),
@@ -249,6 +249,19 @@ protected void configureUsingConfiguration(FeignClientFactory context, Feign.Bui
249249
}
250250
}
251251

252+
protected void configureUsingProperties(FeignClientProperties.FeignClientConfiguration baseConfig,
253+
FeignClientProperties.FeignClientConfiguration finalConfig, Feign.Builder builder) {
254+
configureUsingProperties(baseConfig, builder);
255+
configureUsingProperties(finalConfig, builder);
256+
Boolean dismiss404 = finalConfig != null && finalConfig.getDismiss404() != null ? finalConfig.getDismiss404()
257+
: (baseConfig != null && baseConfig.getDismiss404() != null ? baseConfig.getDismiss404() : null);
258+
if (dismiss404 != null) {
259+
if (dismiss404) {
260+
builder.dismiss404();
261+
}
262+
}
263+
}
264+
252265
protected void configureUsingProperties(FeignClientProperties.FeignClientConfiguration config,
253266
Feign.Builder builder) {
254267
if (config == null) {
@@ -291,12 +304,6 @@ protected void configureUsingProperties(FeignClientProperties.FeignClientConfigu
291304
builder.responseInterceptor(getOrInstantiate(config.getResponseInterceptor()));
292305
}
293306

294-
if (config.getDismiss404() != null) {
295-
if (config.getDismiss404()) {
296-
builder.dismiss404();
297-
}
298-
}
299-
300307
if (Objects.nonNull(config.getEncoder())) {
301308
builder.encoder(getOrInstantiate(config.getEncoder()));
302309
}

spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/FeignClientFactoryBeanIntegrationTests.java

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.List;
2121
import java.util.Map;
2222

23+
import feign.FeignException;
2324
import org.junit.jupiter.api.Test;
2425

2526
import org.springframework.beans.factory.annotation.Autowired;
@@ -35,6 +36,8 @@
3536
import org.springframework.context.annotation.Bean;
3637
import org.springframework.context.annotation.Import;
3738
import org.springframework.http.HttpHeaders;
39+
import org.springframework.http.HttpStatus;
40+
import org.springframework.http.ResponseEntity;
3841
import org.springframework.test.context.ActiveProfiles;
3942
import org.springframework.web.bind.annotation.GetMapping;
4043
import org.springframework.web.bind.annotation.RequestHeader;
@@ -44,6 +47,8 @@
4447

4548
import static java.util.Map.entry;
4649
import static org.assertj.core.api.Assertions.assertThat;
50+
import static org.assertj.core.api.Assertions.assertThatCode;
51+
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
4752
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
4853

4954
/**
@@ -52,7 +57,7 @@
5257
* @author Olga Maciaszek-Sharma
5358
*/
5459
@SpringBootTest(classes = FeignClientFactoryBeanIntegrationTests.Application.class,
55-
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
60+
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
5661
@ActiveProfiles("defaultstest")
5762
class FeignClientFactoryBeanIntegrationTests {
5863

@@ -64,51 +69,58 @@ class FeignClientFactoryBeanIntegrationTests {
6469

6570
@Test
6671
void shouldProcessDefaultRequestHeadersPerClient() {
67-
assertThat(testClientA.headers()).isNotNull()
68-
.contains(entry("x-custom-header-2", List.of("2 from default")),
72+
assertThat(testClientA.headers()).isNotNull().contains(entry("x-custom-header-2", List.of("2 from default")),
6973
entry("x-custom-header", List.of("from client A")));
70-
assertThat(testClientB.headers()).isNotNull()
71-
.contains(entry("x-custom-header-2", List.of("2 from default")),
74+
assertThat(testClientB.headers()).isNotNull().contains(entry("x-custom-header-2", List.of("2 from default")),
7275
entry("x-custom-header", List.of("from client B")));
7376
}
7477

7578
@Test
7679
void shouldProcessDefaultQueryParamsPerClient() {
77-
assertThat(testClientA.params()).isNotNull()
78-
.contains(entry("customParam2", "2 from default"),
80+
assertThat(testClientA.params()).isNotNull().contains(entry("customParam2", "2 from default"),
7981
entry("customParam1", "from client A"));
80-
assertThat(testClientB.params()).isNotNull()
81-
.contains(entry("customParam2", "2 from default"),
82+
assertThat(testClientB.params()).isNotNull().contains(entry("customParam2", "2 from default"),
8283
entry("customParam1", "from client B"));
8384
}
8485

86+
@Test
87+
void shouldProcessDismiss404PerClient() {
88+
assertThatExceptionOfType(FeignException.FeignClientException.class).isThrownBy(() -> testClientA.test404());
89+
assertThatCode(() -> {
90+
ResponseEntity<String> response404 = testClientB.test404();
91+
assertThat(response404.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
92+
assertThat(response404.getBody()).isNull();
93+
}).doesNotThrowAnyException();
94+
}
95+
8596
@FeignClient("testClientA")
86-
public interface TestClientA {
97+
public interface TestClientA extends TestClient {
8798

88-
@GetMapping("/headers")
89-
Map<String, List<String>> headers();
99+
}
90100

91-
@GetMapping("/params")
92-
Map<String, String> params();
101+
@FeignClient("testClientB")
102+
public interface TestClientB extends TestClient {
93103

94104
}
95105

96-
@FeignClient("testClientB")
97-
public interface TestClientB {
106+
public interface TestClient {
98107

99108
@GetMapping("/headers")
100109
Map<String, List<String>> headers();
101110

102111
@GetMapping("/params")
103112
Map<String, String> params();
104113

114+
@GetMapping
115+
ResponseEntity<String> test404();
116+
105117
}
106118

107119
@EnableAutoConfiguration
108-
@EnableFeignClients(clients = {TestClientA.class, TestClientB.class})
120+
@EnableFeignClients(clients = { TestClientA.class, TestClientB.class })
109121
@RestController
110-
@LoadBalancerClients({@LoadBalancerClient(name = "testClientA", configuration = TestClientAConfiguration.class),
111-
@LoadBalancerClient(name = "testClientB", configuration = TestClientBConfiguration.class)})
122+
@LoadBalancerClients({ @LoadBalancerClient(name = "testClientA", configuration = TestClientAConfiguration.class),
123+
@LoadBalancerClient(name = "testClientB", configuration = TestClientBConfiguration.class) })
112124
@RequestMapping
113125
@Import(NoSecurityConfiguration.class)
114126
protected static class Application {
@@ -123,6 +135,11 @@ public Map<String, String> headersB(@RequestParam Map<String, String> params) {
123135
return params;
124136
}
125137

138+
@GetMapping
139+
ResponseEntity<String> test404() {
140+
return ResponseEntity.notFound().build();
141+
}
142+
126143
}
127144

128145
// LoadBalancer with fixed server list for "testClientA" pointing to localhost
@@ -134,7 +151,7 @@ static class TestClientAConfiguration {
134151
@Bean
135152
public ServiceInstanceListSupplier testClientAServiceInstanceListSupplier() {
136153
return ServiceInstanceListSuppliers.from("testClientA",
137-
new DefaultServiceInstance("local-1", "testClientA", "localhost", port, false));
154+
new DefaultServiceInstance("local-1", "testClientA", "localhost", port, false));
138155
}
139156

140157
}
@@ -148,7 +165,7 @@ static class TestClientBConfiguration {
148165
@Bean
149166
public ServiceInstanceListSupplier testClientBServiceInstanceListSupplier() {
150167
return ServiceInstanceListSuppliers.from("testClientB",
151-
new DefaultServiceInstance("local-1", "testClientB", "localhost", port, false));
168+
new DefaultServiceInstance("local-1", "testClientB", "localhost", port, false));
152169
}
153170

154171
}

spring-cloud-openfeign-core/src/test/resources/application-defaultstest.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ spring:
55
config:
66
default:
77
logger-level: FULL
8+
dismiss404: true
89
default-request-headers:
910
x-custom-header:
1011
- "default"
@@ -16,6 +17,7 @@ spring:
1617
customParam2:
1718
- "2 from default"
1819
testClientA:
20+
dismiss404: false
1921
default-request-headers:
2022
x-custom-header:
2123
- "from client A"

0 commit comments

Comments
 (0)