Enable body caching in CircuitBreakerFilterFactory.

Signed-off-by: qnnn <65326092+qnnn@users.noreply.github.com>
This commit is contained in:
qnnn
2025-03-14 13:23:37 +08:00
parent 9816b1adfe
commit fcba3da5d3
6 changed files with 38 additions and 5 deletions

View File

@@ -16,6 +16,7 @@
package org.springframework.cloud.gateway.filter.factory;
import org.springframework.cloud.gateway.event.EnableBodyCachingEvent;
import org.springframework.cloud.gateway.support.AbstractConfigurable;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
@@ -43,6 +44,13 @@ public abstract class AbstractGatewayFilterFactory<C> extends AbstractConfigurab
return this.publisher;
}
protected void enableBodyCaching(String routeId) {
if (routeId != null && getPublisher() != null) {
// send an event to enable caching
getPublisher().publishEvent(new EnableBodyCachingEvent(this, routeId));
}
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
this.publisher = publisher;

View File

@@ -35,7 +35,6 @@ import reactor.retry.RepeatContext;
import reactor.retry.Retry;
import reactor.retry.RetryContext;
import org.springframework.cloud.gateway.event.EnableBodyCachingEvent;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.support.HasRouteId;
@@ -229,10 +228,7 @@ public class RetryGatewayFilterFactory extends AbstractGatewayFilterFactory<Retr
}
public GatewayFilter apply(String routeId, Repeat<ServerWebExchange> repeat, Retry<ServerWebExchange> retry) {
if (routeId != null && getPublisher() != null) {
// send an event to enable caching
getPublisher().publishEvent(new EnableBodyCachingEvent(this, routeId));
}
enableBodyCaching(routeId);
return (exchange, chain) -> {
trace("Entering retry-filter");

View File

@@ -89,6 +89,7 @@ public abstract class SpringCloudCircuitBreakerFilterFactory
@Override
public GatewayFilter apply(Config config) {
enableBodyCaching(config.getRouteId());
ReactiveCircuitBreaker cb = reactiveCircuitBreakerFactory.create(config.getId());
Set<HttpStatus> statuses = config.getStatusCodes()
.stream()

View File

@@ -21,6 +21,7 @@ import org.junit.jupiter.api.condition.DisabledIfEnvironmentVariable;
import org.springframework.cloud.gateway.test.BaseWebClientTests;
import org.springframework.http.HttpStatus;
import org.springframework.web.reactive.function.BodyInserters;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.http.MediaType.APPLICATION_JSON;
@@ -243,4 +244,11 @@ public abstract class SpringCloudCircuitBreakerFilterFactoryTests extends BaseWe
.valueEquals(ROUTE_ID_HEADER, "circuitbreaker_resume_without_error");
}
@Test
public void filterPostFallback() {
testClient.post().uri("/post").body(BodyInserters.fromValue("hello"))
.header("Host", "www.circuitbreakerfallbackpost.org").exchange().expectStatus()
.isOk().expectBody().json("{\"body\":\"hello\"}");
}
}

View File

@@ -38,6 +38,8 @@ import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@@ -68,6 +70,11 @@ public class SpringCloudCircuitBreakerTestConfig {
return Collections.singletonMap("from", "circuitbreakerfallbackcontroller");
}
@PostMapping("/circuitbreakerPostFallbackController")
public Map<String, String> postFallbackController(@RequestBody String body) {
return Collections.singletonMap("body", body);
}
@GetMapping("/circuitbreakerUriFallbackController/**")
public Map<String, String> uriFallbackcontroller(ServerWebExchange exchange, @RequestParam("a") String a) {
return Collections.singletonMap("uri", exchange.getRequest().getURI().toString());

View File

@@ -104,6 +104,19 @@ spring:
name: fallbackcmd
fallbackUri: forward:/circuitbreakerFallbackController
# =====================================
- id: circuitbreaker_fallback_test_post
uri: ${test.uri}
predicates:
- Host=**.circuitbreakerfallbackpost.org
filters:
- name: CircuitBreaker
args:
name: fallbackcmd
statusCodes:
- 200
fallbackUri: forward:/circuitbreakerPostFallbackController
# =====================================
- id: circuitbreaker_fallback_test_variables
uri: ${test.uri}