How to define a default filter for all routes but disable it for a specific route?

Viewed 32

When using Spring Cloud Gateway (v3.1.3), how would one go about defining a default filter to perform retries for all routes, but then disable it for individual routes? I would like something as intuitive as this:

spring:
  cloud:
    gateway:
      default-filters:
      - name: Retry
        args:
          retries: 3
          statuses: BAD_GATEWAY
          methods: GET,POST,PUT,DELETE
          backoff:
            firstBackoff: 10ms
            maxBackoff: 50ms
            factor: 2
            basedOnPreviousValue: false
      routes:
      - id: retry_disabled
        uri: http://localhost:8080/retry_disabled
        filters:
        - name: Retry
          args:
            retries: 0
      - id: retry_enabled
        uri: http://localhost:8080/retry_enabled

I see in the RetryGatewayFilterFactory class that the RetryConfig.validate() method will fail when the number of retries is less than 1 or the other config options are not defined properly:

public void validate() {
    Assert.isTrue(this.retries > 0, "retries must be greater than 0");
    Assert.isTrue(!this.series.isEmpty() || !this.statuses.isEmpty() || !this.exceptions.isEmpty(),
            "series, status and exceptions may not all be empty");
    Assert.notEmpty(this.methods, "methods may not be empty");
    if (this.backoff != null) {
        this.backoff.validate();
    }
}

Edit: I'm considering to implement it like this in code:

@Bean
public Function<GatewayFilterSpec, UriSpec> defaultRetryGatewayFilter() {
    return gatewayFilterSpec -> gatewayFilterSpec
        .retry(retryConfig -> {
            RetryGatewayFilterFactory.BackoffConfig backoffConfig = new RetryGatewayFilterFactory.BackoffConfig();

            backoffConfig.setFirstBackoff(Duration.ofMillis(10));
            backoffConfig.setMaxBackoff(Duration.ofMillis(50));
            backoffConfig.setFactor(2);
            backoffConfig.setBasedOnPreviousValue(false);
            retryConfig
                .setRetries(3)
                .allMethods()
                .setSeries(HttpStatus.Series.SERVER_ERROR)
                .setStatuses(HttpStatus.BAD_GATEWAY)
                .setBackoff(backoffConfig);
        });
}

@Bean
public RouteLocator routes(RouteLocatorBuilder builder, Function<GatewayFilterSpec, UriSpec> defaultRetryGatewayFilter) {
    return builder.routes()
        .route("retry_enabled", r -> r
            .path("/retry_enabled")
            .filters(defaultRetryGatewayFilter)
            .uri("lb://foo"))
        .route("retry_disabled", r -> r
            .path("/retry_disabled")
            // not retryable
            .uri("lb://foo"))
        .build();
}

Will the singleton defaultRetryGatewayFilter be thread safe?

0 Answers
Related