Header Ads Widget

Responsive Advertisement

Deep understand of ThrottlingFilter with RewritePath filter in cloud gateway

 

The YAML configuration snippet provided is using a custom filter called ThrottlingFilter and a RewritePath filter. To ensure that the ThrottlingFilter is properly registered and integrated with your Spring Cloud Gateway, let's break down the configuration steps:

Full YAML Configuration Example:

yaml

spring:

  cloud:

    gateway:

      routes:

        - id: throttled_route

          uri: http://localhost:8083

          predicates:

            - Path=/service/throttle/**

          filters:

            - RewritePath=/service/throttle(?<segment>/?.*), $\{segment}

            - name: ThrottlingFilter   # Custom filter registered in your code

              args:

                maxRequests: 5        # Maximum allowed requests per time window

                timeWindow: 10s       # Time window in seconds

 

Explanation of the Filters:

  1. RewritePath:
    • This filter rewrites the path of incoming requests by using regex.
    • The part /service/throttle(?<segment>/?.*) matches the incoming request path and extracts the remaining part into a named group called segment.
    • $\{segment} dynamically replaces the matched group in the final URL.
  2. ThrottlingFilter:
    • This custom filter applies rate-limiting logic by reading maxRequests and timeWindow from the YAML configuration.
    • You need to implement the actual logic of the ThrottlingFilter in Java.

Custom ThrottlingFilter Implementation in Java:

Here’s an example of how to create a ThrottlingFilter in Java that reads values from the YAML configuration and implements throttling:

java

import org.springframework.cloud.gateway.filter.GatewayFilter;

import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;

import org.springframework.http.HttpStatus;

import org.springframework.stereotype.Component;

import reactor.core.publisher.Mono;

 

import java.time.Duration;

import java.util.concurrent.ConcurrentHashMap;

import java.util.concurrent.atomic.AtomicInteger;

 

@Component

public class ThrottlingFilter extends AbstractGatewayFilterFactory<ThrottlingFilter.Config> {

 

    public static class Config {

        private int maxRequests;

        private Duration timeWindow;

 

        // Getters and setters

        public int getMaxRequests() {

            return maxRequests;

        }

 

        public void setMaxRequests(int maxRequests) {

            this.maxRequests = maxRequests;

        }

 

        public Duration getTimeWindow() {

            return timeWindow;

        }

 

        public void setTimeWindow(Duration timeWindow) {

            this.timeWindow = timeWindow;

        }

    }

 

    // Store request counts and start times per client IP

    private final ConcurrentHashMap<String, AtomicInteger> requestCounts = new ConcurrentHashMap<>();

    private final ConcurrentHashMap<String, Long> windowStartTimes = new ConcurrentHashMap<>();

 

    public ThrottlingFilter() {

        super(Config.class);

    }

 

    @Override

    public GatewayFilter apply(Config config) {

        return (exchange, chain) -> {

            String clientIp = exchange.getRequest().getRemoteAddress().getAddress().getHostAddress();

            long currentTime = System.currentTimeMillis();

 

            windowStartTimes.putIfAbsent(clientIp, currentTime);

            requestCounts.putIfAbsent(clientIp, new AtomicInteger(0));

 

            long windowStartTime = windowStartTimes.get(clientIp);

            AtomicInteger requestCount = requestCounts.get(clientIp);

 

            // Check if time window has expired

            if (currentTime - windowStartTime > config.getTimeWindow().toMillis()) {

                // Reset the window and count

                windowStartTimes.put(clientIp, currentTime);

                requestCount.set(0);

            }

 

            // Increment the request count and check if it exceeds the limit

            if (requestCount.incrementAndGet() > config.getMaxRequests()) {

                // Too many requests, return 429 (Too Many Requests)

                exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS);

                return exchange.getResponse().setComplete();

            }

 

            // Continue the filter chain

            return chain.filter(exchange);

        };

    }

}

 

Key Points:

  • Config class: This class holds the parameters (maxRequests and timeWindow) from the YAML configuration.
  • ConcurrentHashMap: Used to keep track of request counts and time windows for each client IP.
  • Throttling logic: If the number of requests exceeds maxRequests within timeWindow, it returns HTTP 429 (Too Many Requests).

How it Works:

  • The YAML configuration passes maxRequests and timeWindow values to the filter.
  • Each client is tracked by their IP address, and the number of requests made within the time window is counted.
  • If the request count exceeds the configured limit, the filter returns a 429 status to throttle the request.

Dependencies in pom.xml:

Ensure you have the necessary dependencies in your pom.xml:

xml

<dependency>

    <groupId>org.springframework.cloud</groupId>

    <artifactId>spring-cloud-starter-gateway</artifactId>

</dependency>

<dependency>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-webflux</artifactId>

</dependency>

 

This will ensure that the ThrottlingFilter is correctly integrated with Spring Cloud Gateway.

Testing the Setup:

To test, you can send multiple requests to http://localhost:8083/service/throttle/**. After 5 requests within 10 seconds (based on the configuration), subsequent requests should be rejected with a 429 (Too Many Requests) status. After 10 seconds, the request counter resets, and requests can be made again.

 


 

In Spring Cloud Gateway (SCG), the RewritePath filter is used to rewrite the request path before forwarding it to the backend service. This can be useful when your gateway needs to forward requests to backend services where the path structure is different from the incoming requests. You can use regular expressions and path variables to define how the rewriting should work.

Here are some examples of different types of RewritePath usage and explanations:

Basic Syntax of RewritePath:

yaml

filters:

  - RewritePath=/<regex>, /<replacement>

 

  • <regex>: A regular expression used to match the incoming request path.
  • <replacement>: The replacement path that will be sent to the backend service.

Example 1: Simple Path Replacement

YAML Configuration:

yaml

spring:

  cloud:

    gateway:

      routes:

        - id: simple_rewrite

          uri: http://localhost:8080

          predicates:

            - Path=/api/v1/customers/**

          filters:

            - RewritePath=/api/v1/customers/(?<segment>.*), /customers/${segment}

 

Explanation:

  • Incoming Request: /api/v1/customers/123
  • Regex: /api/v1/customers/(?<segment>.*) captures everything after /api/v1/customers/ in the group segment.
  • Replacement: /customers/${segment} rewrites the path by replacing /api/v1/customers/ with /customers/.
  • Forwarded Request: /customers/123

This example rewrites the incoming path so that the backend service receives a cleaner or differently structured URL.

Example 2: Remove a Section of the Path

YAML Configuration:

yaml

spring:

  cloud:

    gateway:

      routes:

        - id: remove_section

          uri: http://localhost:8080

          predicates:

            - Path=/internal/service/**

          filters:

            - RewritePath=/internal/service/(?<segment>.*), /${segment}

 

Explanation:

  • Incoming Request: /internal/service/orders/567
  • Regex: /internal/service/(?<segment>.*) matches the path after /internal/service/ and stores it in the segment.
  • Replacement: /${segment} removes /internal/service and leaves just the remaining part of the path.
  • Forwarded Request: /orders/567

Here, we remove the /internal/service part of the path when forwarding the request to the backend service.

Example 3: Add a Prefix to the Path

YAML Configuration:

yaml

spring:

  cloud:

    gateway:

      routes:

        - id: add_prefix

          uri: http://localhost:8080

          predicates:

            - Path=/products/**

          filters:

            - RewritePath=/products/(?<segment>.*), /api/v2/products/${segment}

 

Explanation:

  • Incoming Request: /products/789
  • Regex: /products/(?<segment>.*) captures the part of the path after /products/.
  • Replacement: /api/v2/products/${segment} adds a prefix (/api/v2/) to the original path.
  • Forwarded Request: /api/v2/products/789

This example shows how to add a new prefix to the request path before it reaches the backend.

Example 4: Change a Subpath Using Regex Groups

YAML Configuration:

yaml

spring:

  cloud:

    gateway:

      routes:

        - id: subpath_rewrite

          uri: http://localhost:8080

          predicates:

            - Path=/store/(category|product)/(?<id>\d+)

          filters:

            - RewritePath=/store/(category|product)/(?<id>\d+), /api/$1/${id}

 

Explanation:

  • Incoming Request: /store/category/42
  • Regex: /store/(category|product)/(?<id>\d+) captures either category or product and stores it in $1. The digits after that are stored in the named group id.
  • Replacement: /api/$1/${id} rewrites the path to /api/category/42.
  • Forwarded Request: /api/category/42

This example demonstrates the use of multiple regex groups to capture different parts of the path and use them in the replacement string.

Example 5: Complex Path Rewriting with Multiple Groups

YAML Configuration:

yaml

spring:

  cloud:

    gateway:

      routes:

        - id: complex_rewrite

          uri: http://localhost:8080

          predicates:

            - Path=/company/(?<companyId>\d+)/employee/(?<employeeId>\d+)

          filters:

            - RewritePath=/company/(?<companyId>\d+)/employee/(?<employeeId>\d+), /employee/${employeeId}/company/${companyId}

 

Explanation:

  • Incoming Request: /company/123/employee/456
  • Regex: /company/(?<companyId>\d+)/employee/(?<employeeId>\d+) captures 123 as companyId and 456 as employeeId.
  • Replacement: /employee/${employeeId}/company/${companyId} swaps the order of companyId and employeeId in the path.
  • Forwarded Request: /employee/456/company/123

Here, we're capturing both companyId and employeeId and changing the order of their appearance in the forwarded path.

Example 6: Redirect Based on Path Segments

YAML Configuration:

yaml

spring:

  cloud:

    gateway:

      routes:

        - id: dynamic_path_rewrite

          uri: http://localhost:8080

          predicates:

            - Path=/app/{section}/{id}

          filters:

            - RewritePath=/app/(?<section>.*)/(?<id>.*), /newapp/${section}/${id}

 

Explanation:

  • Incoming Request: /app/store/789
  • Regex: /app/(?<section>.*)/(?<id>.*) captures the section and id parts.
  • Replacement: /newapp/${section}/${id} changes the URL prefix from /app to /newapp.
  • Forwarded Request: /newapp/store/789

This example changes the prefix of the path and keeps the rest intact.


General Tips:

  • Regex Groups: You can use named capturing groups (?<name>) to capture specific parts of the path and reuse them in the replacement.
  • Replacement: The replacement can be as simple or complex as needed, depending on the requirements of the backend service.
  • Debugging: If you face issues with path rewriting, make sure to test your regular expressions separately to ensure they work as expected.

These examples show how flexible and powerful the RewritePath filter can be in SCG. It allows you to transform the path of the incoming request based on your backend’s requirements, making it easier to work with different services and URLs.

 For more information, visit Microservices: Custom Filters for Debouncing, Throttling, Rate Limiting, and Exponential Backoff on Java Therapy.


Flowchart ThrottlingFilter with RewritePath filter in cloud gateway
Flowchart ThrottlingFilter with RewritePath filter in cloud gateway

Sequence Diagram ThrottlingFilter with RewritePath filter in cloud gateway
Sequence Diagram ThrottlingFilter with RewritePath filter in cloud gateway



For More Related information, visit

Ø  Mastering Debounce, Throttle, Rate Limit & Backoff in Java

Ø  Setting up Custom Filters using Debouncing, Throttling, Rate Limiting, and Exponential Backoff

Ø  Custom gateway filters in Spring Cloud Gateway

Ø  Custom Filters in Microservices

Ø  Mastering Debounce, Throttle, Rate Limit & Backoff in Java

Ø  Microservices: Custom Filters for Debouncing, Throttling, Rate Limits & Backoff

Ø  Spring Cloud Gateway uses a RewritePath filter

 

For More DSA Related information, visit

Ø  Bench mark of compiler using Ackerman function

Ø  Find the Missing Number

Ø  To check if the rows of a matrix are circularly identical in Java

Ø  how to check loop in array

Ø  100 door puzzle programs

Ø  Frequency Weaving Logic & Spiral Printing of a Rectangle

Ø  Zig Zag Matrix print multiple way

Ø  Gready Algorithm’s or knapsack algorithms

Ø  understanding recursive method for binary tree

Ø  Dynamic Programming: Max Square Sub-matrix of 1s in a Matrix

Ø  Previous and Next Date Palindrome

Ø  Karatsuba's Algorithm for multiplying two large numbers

Ø  Multiplication In different Way

Ø  Division by Different way

Ø  Time Analysis for Congested Routes Using Shortest Path Algorithms

Ø  Sorting of country

Ø  Sorting Of a list multiple attribute wise two technique

Ø  Seat Arrangement in Sorting Order Like 1A-1E, 3C-3G etc

 

For More Java Related information, visit

Ø  Streams Lambdas Collectors and Functional Interfaces in Java 8

Ø  Java 8 support static method or default method or both in the interface

Ø  Inheritance Understand

Ø  Serialization understanding

Ø  Clone Under standing

Ø  Exception understanding

Ø  Garbage Collection Under Standing

Ø  How work Garbage Collection in Java

Ø  Under Standing Of Mutable and Immutable Class

Ø  enum understand

 

For Other information, visit

Ø  How to get the neighbor of binary tree

Ø  OWASP (Open Web Application Security Project)

Ø  Mastering Debounce, Throttle, Rate Limit & Backoff in Java

Ø  How to draw sequence diagram and other diagrams using plantuml

Ø  Pascal Triangle

Ø  Molecular weight of chemistry in Java code

Ø  String to xml or html Beautifier

Ø  Key Components of Apache Kafka for Scalable Messaging

Ø  Build a Video Stream Microservice with Kafka & REST API in Java

Ø  Kafka general questions and answers

Ø  How to convert XML to Object and Object to XML

Ø  To securely obtain employee information utilizing TLS 1.3 or TLS 1.2

Ø  TLS 1.3 Configuration

Ø  Convert Floating-Point Values from SQL Server to Oracle in Java

Ø  Design pattern

Ø  Mastering Design Patterns Practical Implementation Tips





Post a Comment

0 Comments