[BAEL-6276] Exploring the New Filters on Spring Cloud Gateway (#16341)
* BAEL-6276: Fix the broken tests * BAEL-6276: Add request header AddRequestHeadersIfNotPresent * BAEL-6276: Add response header RemoveJsonAttributesResponseBody * BAEL-6276: Example for CacheRequestBody * BAEL-6276: Example for LocalResponseCache * BAEL-6276: Add `redis-rate-limiter.requestedTokens` for `RequestRateLimiter`
This commit is contained in:
parent
60ce9ba95f
commit
ed6d85a620
|
@ -65,6 +65,14 @@
|
|||
<artifactId>jakarta.validation-api</artifactId>
|
||||
<version>${jakarta.validation-api.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-cache</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.ben-manes.caffeine</groupId>
|
||||
<artifactId>caffeine</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
|
@ -179,11 +187,12 @@
|
|||
</profiles>
|
||||
|
||||
<properties>
|
||||
<spring-boot.version>3.2.3</spring-boot.version>
|
||||
<spring-cloud-dependencies.version>2023.0.0</spring-cloud-dependencies.version>
|
||||
<hibernate-validator.version>8.0.1.Final</hibernate-validator.version>
|
||||
<redis.version>0.7.2</redis.version>
|
||||
<oauth2-oidc-sdk.version>9.19</oauth2-oidc-sdk.version>
|
||||
<!-- <junit-bom.version>5.5.2</junit-bom.version> -->
|
||||
<junit-jupiter.version>5.10.2</junit-jupiter.version>
|
||||
<jakarta.validation-api.version>3.0.2</jakarta.validation-api.version>
|
||||
</properties>
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package com.baeldung.springcloudgateway.webfilters;
|
||||
|
||||
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
||||
import org.springframework.cloud.gateway.filter.GlobalFilter;
|
||||
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@Component
|
||||
public class CacheEvaluationFilter implements GlobalFilter {
|
||||
|
||||
@Override
|
||||
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
||||
String body = exchange.getAttribute(ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR);
|
||||
if (body != null) {
|
||||
exchange.getResponse().getHeaders().add("My-Header-Cache", body);
|
||||
}
|
||||
return chain.filter(exchange);
|
||||
}
|
||||
}
|
|
@ -9,6 +9,11 @@ spring:
|
|||
port: 6379
|
||||
cloud:
|
||||
gateway:
|
||||
filter:
|
||||
local-response-cache:
|
||||
enabled: true
|
||||
timeToLive: 20m
|
||||
size: 6MB
|
||||
routes:
|
||||
- id: request_header_route
|
||||
uri: https://httpbin.org
|
||||
|
@ -17,6 +22,7 @@ spring:
|
|||
filters:
|
||||
- AddRequestHeader=My-Header-Good,Good
|
||||
- AddRequestHeader=My-Header-Remove,Remove
|
||||
- AddRequestHeadersIfNotPresent=My-Header-Absent:Absent
|
||||
- AddRequestParameter=var, good
|
||||
- AddRequestParameter=var2, remove
|
||||
- MapRequestHeader=My-Header-Good, My-Header-Bad
|
||||
|
@ -31,17 +37,18 @@ spring:
|
|||
predicates:
|
||||
- Path=/header/post/**
|
||||
filters:
|
||||
- AddResponseHeader=My-Header-Good,Good
|
||||
- AddResponseHeader=My-Header-Set,Good
|
||||
- AddResponseHeader=My-Header-Rewrite, password=12345678
|
||||
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
|
||||
- AddResponseHeader=My-Header-Remove,Remove
|
||||
- SetResponseHeader=My-Header-Set, Set
|
||||
- RemoveResponseHeader=My-Header-Remove
|
||||
- RewriteResponseHeader=My-Header-Rewrite, password=[^&]+, password=***
|
||||
- RewriteLocationResponseHeader=AS_IN_REQUEST, Location, ,
|
||||
- RemoveJsonAttributesResponseBody=form,Accept,true
|
||||
- AddResponseHeader=My-Header-Good,Good
|
||||
- AddResponseHeader=My-Header-Set,Good
|
||||
- AddResponseHeader=My-Header-Remove,Remove
|
||||
- AddResponseHeader=My-Header-Rewrite,password=12345678
|
||||
- StripPrefix=1
|
||||
|
||||
|
||||
- id: path_route
|
||||
uri: https://httpbin.org
|
||||
predicates:
|
||||
|
@ -88,7 +95,18 @@ spring:
|
|||
maxBackoff: 50ms
|
||||
factor: 2
|
||||
basedOnPreviousValue: false
|
||||
|
||||
|
||||
- id: circuitbreaker_route
|
||||
uri: https://httpbin.org
|
||||
predicates:
|
||||
- Path=/status/504
|
||||
filters:
|
||||
- name: CircuitBreaker
|
||||
args:
|
||||
name: myCircuitBreaker
|
||||
fallbackUri: forward:/anything
|
||||
- RewritePath=/status/504, /anything
|
||||
|
||||
- id: request_rate_limiter
|
||||
uri: https://httpbin.org
|
||||
predicates:
|
||||
|
@ -99,4 +117,23 @@ spring:
|
|||
args:
|
||||
redis-rate-limiter.replenishRate: 10
|
||||
redis-rate-limiter.burstCapacity: 5
|
||||
key-resolver: "#{@userKeyResolver}"
|
||||
redis-rate-limiter.requestedTokens: 1
|
||||
key-resolver: "#{@userKeyResolver}"
|
||||
|
||||
- id: cache_request_body_route
|
||||
uri: https://httpbin.org
|
||||
predicates:
|
||||
- Path=/cache/post/**
|
||||
filters:
|
||||
- StripPrefix=1
|
||||
- name: CacheRequestBody
|
||||
args:
|
||||
bodyClass: java.lang.String
|
||||
|
||||
- id: cache_response_body_route
|
||||
uri: https://httpbin.org
|
||||
predicates:
|
||||
- Path=/cache/get/**
|
||||
filters:
|
||||
- StripPrefix=1
|
||||
- LocalResponseCache=10s,20MB
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
package com.baeldung.springcloudgateway.webfilters;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.assertj.core.api.Condition;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
@ -23,9 +20,10 @@ import org.springframework.http.ResponseEntity;
|
|||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec;
|
||||
import org.springframework.web.reactive.function.BodyInserters;
|
||||
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
|
||||
@ActiveProfiles("webfilters")
|
||||
@ActiveProfiles({"webfilters","nosecurity"})
|
||||
public class WebFilterFactoriesLiveTest {
|
||||
|
||||
@LocalServerPort
|
||||
|
@ -55,6 +53,7 @@ public class WebFilterFactoriesLiveTest {
|
|||
assertThat(headers.getString("My-Header-Good")).isEqualTo("Good");
|
||||
assertThat(headers.getString("My-Header-Bad")).isEqualTo("Good");
|
||||
assertThat(headers.getString("My-Header-Set")).isEqualTo("Set");
|
||||
assertThat(headers.getString("My-Header-Absent")).isEqualTo("Absent");
|
||||
assertTrue(headers.isNull("My-Header-Remove"));
|
||||
JSONObject vars = json.getJSONObject("args");
|
||||
assertThat(vars.getString("var")).isEqualTo("good");
|
||||
|
@ -75,7 +74,10 @@ public class WebFilterFactoriesLiveTest {
|
|||
.expectHeader()
|
||||
.valueEquals("My-Header-Good", "Good")
|
||||
.expectHeader()
|
||||
.doesNotExist("My-Header-Remove");
|
||||
.doesNotExist("My-Header-Remove")
|
||||
.expectBody()
|
||||
.jsonPath("$.headers.Accept").doesNotExist()
|
||||
.jsonPath("form").doesNotExist();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -133,4 +135,28 @@ public class WebFilterFactoriesLiveTest {
|
|||
JSONObject json = new JSONObject(response.getBody());
|
||||
assertThat(json.getString("url")).contains("anything");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCallCachePostThroughGateway_thenMyHeaderCacheIsSet() {
|
||||
ResponseSpec response = client.post()
|
||||
.uri("/cache/post")
|
||||
.body(BodyInserters.fromValue("CachedBody"))
|
||||
.exchange();
|
||||
|
||||
response.expectStatus()
|
||||
.isOk()
|
||||
.expectHeader()
|
||||
.valueEquals("My-Header-Cache", "CachedBody");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCallCacheGetThroughGateway_thenCacheControlIsSet() {
|
||||
ResponseSpec response = client.get()
|
||||
.uri("/cache/get")
|
||||
.exchange();
|
||||
|
||||
response.expectStatus().isOk()
|
||||
.expectHeader()
|
||||
.valueEquals("Cache-Control", "max-age=10");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue