diff --git a/spring-cloud/spring-cloud-gateway/pom.xml b/spring-cloud/spring-cloud-gateway/pom.xml
index ada32ae85f..c692eed7ec 100644
--- a/spring-cloud/spring-cloud-gateway/pom.xml
+++ b/spring-cloud/spring-cloud-gateway/pom.xml
@@ -1,7 +1,7 @@
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
spring-cloud-gateway
spring-cloud-gateway
@@ -54,7 +54,21 @@
org.springframework.cloud
spring-cloud-starter-circuitbreaker-reactor-resilience4j
-
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis-reactive
+
+
+
+
+ it.ozimov
+ embedded-redis
+ ${redis.version}
+ test
+
+
org.hibernate
hibernate-validator-cdi
@@ -75,8 +89,8 @@
test
- org.springframework.boot
- spring-boot-devtools
+ org.springframework.boot
+ spring-boot-devtools
@@ -93,6 +107,7 @@
Hoxton.SR3
2.2.6.RELEASE
6.0.2.Final
+ 0.7.2
diff --git a/spring-cloud/spring-cloud-gateway/src/main/java/com/baeldung/springcloudgateway/webfilters/config/RequestRateLimiterResolverConfig.java b/spring-cloud/spring-cloud-gateway/src/main/java/com/baeldung/springcloudgateway/webfilters/config/RequestRateLimiterResolverConfig.java
new file mode 100644
index 0000000000..f80a742fa6
--- /dev/null
+++ b/spring-cloud/spring-cloud-gateway/src/main/java/com/baeldung/springcloudgateway/webfilters/config/RequestRateLimiterResolverConfig.java
@@ -0,0 +1,16 @@
+package com.baeldung.springcloudgateway.webfilters.config;
+
+import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import reactor.core.publisher.Mono;
+
+@Configuration
+public class RequestRateLimiterResolverConfig {
+
+ @Bean
+ KeyResolver userKeyResolver() {
+ return exchange -> Mono.just("1");
+ }
+}
diff --git a/spring-cloud/spring-cloud-gateway/src/main/resources/application-webfilters.yml b/spring-cloud/spring-cloud-gateway/src/main/resources/application-webfilters.yml
index 9b3ec64f96..3348cbbba0 100644
--- a/spring-cloud/spring-cloud-gateway/src/main/resources/application-webfilters.yml
+++ b/spring-cloud/spring-cloud-gateway/src/main/resources/application-webfilters.yml
@@ -1,4 +1,12 @@
+logging:
+ level:
+ org.springframework.cloud.gateway: INFO
+ reactor.netty.http.client: INFO
+
spring:
+ redis:
+ host: localhost
+ port: 6379
cloud:
gateway:
routes:
@@ -81,13 +89,14 @@ spring:
factor: 2
basedOnPreviousValue: false
- - id: circuitbreaker_route
+ - id: request_rate_limiter
uri: https://httpbin.org
predicates:
- - Path=/status/504
+ - Path=/redis/get/**
filters:
- - name: CircuitBreaker
+ - StripPrefix=1
+ - name: RequestRateLimiter
args:
- name: myCircuitBreaker
- fallbackUri: forward:/anything
- - RewritePath=/status/504, /anything
\ No newline at end of file
+ redis-rate-limiter.replenishRate: 10
+ redis-rate-limiter.burstCapacity: 5
+ key-resolver: "#{@userKeyResolver}"
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-gateway/src/test/java/com/baeldung/springcloudgateway/webfilters/RedisWebFilterFactoriesLiveTest.java b/spring-cloud/spring-cloud-gateway/src/test/java/com/baeldung/springcloudgateway/webfilters/RedisWebFilterFactoriesLiveTest.java
new file mode 100644
index 0000000000..a28eb68775
--- /dev/null
+++ b/spring-cloud/spring-cloud-gateway/src/test/java/com/baeldung/springcloudgateway/webfilters/RedisWebFilterFactoriesLiveTest.java
@@ -0,0 +1,64 @@
+package com.baeldung.springcloudgateway.webfilters;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.jupiter.api.RepeatedTest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.boot.test.context.TestConfiguration;
+import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.http.ResponseEntity;
+import org.springframework.test.context.ActiveProfiles;
+
+import redis.embedded.RedisServer;
+
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
+@ActiveProfiles("webfilters")
+@TestConfiguration
+public class RedisWebFilterFactoriesLiveTest {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(RedisWebFilterFactoriesLiveTest.class);
+
+ private RedisServer redisServer;
+
+ public RedisWebFilterFactoriesLiveTest() {
+ }
+
+ @Before
+ public void postConstruct() {
+ this.redisServer = new RedisServer(6379);
+ redisServer.start();
+ }
+
+ @LocalServerPort
+ String port;
+
+ @Autowired
+ private TestRestTemplate restTemplate;
+
+ @Autowired
+ TestRestTemplate template;
+
+ @RepeatedTest(25)
+ public void whenCallRedisGetThroughGateway_thenOKStatusOrIsReceived() {
+ String url = "http://localhost:" + port + "/redis/get";
+
+ ResponseEntity r = restTemplate.getForEntity(url, String.class);
+ // assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
+
+ LOGGER.info("Received: status->{}, reason->{}, remaining->{}",
+ r.getStatusCodeValue(), r.getStatusCode().getReasonPhrase(),
+ r.getHeaders().get("X-RateLimit-Remaining"));
+ }
+
+ @After
+ public void preDestroy() {
+ redisServer.stop();
+ }
+
+}
diff --git a/spring-cloud/spring-cloud-gateway/src/test/resources/logback-test.xml b/spring-cloud/spring-cloud-gateway/src/test/resources/logback-test.xml
index 6fcdb6317f..6980d119b1 100644
--- a/spring-cloud/spring-cloud-gateway/src/test/resources/logback-test.xml
+++ b/spring-cloud/spring-cloud-gateway/src/test/resources/logback-test.xml
@@ -3,7 +3,15 @@
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
\ No newline at end of file