@Order in AbstractNameValueGatewayFilterFactory doesn’t work

Tags: , ,



I have 2 classes: filter and class to get response body. As far as I know I need to specify order NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER-1 so filter will get response body.

But when I implement Ordered or use annotation @Order or via OrderedGatewayFilter I cann’t call BodyRewrite class(which gets response body). When I try to use this for global filter(implemented GlobalFilter) it works fine.

May it be because I extend AbstractNameValueGatewayFilterFactory and I can’t specify order for it?

Full code: https://github.com/artem-kurilko/NettyFilter

Jwt filter class:

@Component
public class JWTFilter extends AbstractNameValueGatewayFilterFactory {
    private final ModifyResponseBodyGatewayFilterFactory modifyResponseBodyGatewayFilterFactory;
    private final BodyRewrite bodyRewrite;

    @Autowired
    public JWTFilter(ModifyResponseBodyGatewayFilterFactory modifyResponseBodyGatewayFilterFactory, BodyRewrite bodyRewrite, ErrorWebExceptionHandler errorWebExceptionHandler) {
        this.modifyResponseBodyGatewayFilterFactory = modifyResponseBodyGatewayFilterFactory;
        this.bodyRewrite = bodyRewrite;
    }

    @Override
    public GatewayFilter apply(NameValueConfig config) {
        System.out.println("n          JWT FILTERn");

        return new OrderedGatewayFilter((exchange, chain) -> {
            GatewayFilter delegate = modifyResponseBodyGatewayFilterFactory.apply(new ModifyResponseBodyGatewayFilterFactory.Config()
                    .setRewriteFunction(byte[].class, byte[].class, bodyRewrite));
            return delegate.filter(exchange, chain).then(Mono.fromRunnable(() -> System.out.println("nPost JWTFilter executedn")));
        }, NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER-1);
    }

}

Global filter:

@Component
public class ModifyResponseBodyFilter implements GlobalFilter, Ordered {
    private final ModifyResponseBodyGatewayFilterFactory modifyResponseBodyGatewayFilterFactory;
    private final BodyRewrite bodyRewrite;

    @Autowired
    public ModifyResponseBodyFilter(ModifyResponseBodyGatewayFilterFactory modifyResponseBodyGatewayFilterFactory, BodyRewrite bodyRewrite, ErrorWebExceptionHandler errorWebExceptionHandler) {
        this.modifyResponseBodyGatewayFilterFactory = modifyResponseBodyGatewayFilterFactory;
        this.bodyRewrite = bodyRewrite;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        if (exchange.getRequest().getURI().getPath().equals("/key/login")) {
            return exchange.getResponse().setComplete();
        }

        GatewayFilter delegate=modifyResponseBodyGatewayFilterFactory.apply(new ModifyResponseBodyGatewayFilterFactory.Config()
                .setRewriteFunction(byte[].class, byte[].class, bodyRewrite));
        return delegate.filter(exchange, chain).then(Mono.fromRunnable(() -> System.out.println("nPost GlobalFilter executedn")));
    }

    @Override
    public int getOrder() {
        return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER-1;
    }
}

Class to receive response body:

@Component
class BodyRewrite implements RewriteFunction<byte[], byte[]> {

    @Override
    public Publisher<byte[]> apply(ServerWebExchange exchange, byte[] body) {
        String originalBody = body==null?"":new String(body);
        if (!ServerWebExchangeUtils.isAlreadyRouted(exchange)) {
            return Mono.just(originalBody.getBytes());
        } else {
            System.out.println("------------------------------------");
            System.out.println("got response body: " + originalBody);
            System.out.println("------------------------------------");

            return Mono.just(body);
        }
    }

}

application.yml

spring:
  cloud:
    gateway:
      routes:
        - id: global_route
          uri: http://httbin.org
          predicates:
            - Path=/key/login
          filters:
            - JWTFilter=RSA512,HS512
        - id: global_route
          uri: http://httbin.org
          predicates:
            - Path=/**
          filters:
            - RewritePath=/service(?<segment>/?.*), ${segment}
server:
  port: 8082

Output on jwt filter route

Stopped global filter as it is jwt filter route

Post JWTFilter executed

Output on global filter route

got response body: Something

Post GlobalFilter executed

So when I try to call BodyRewrite via JWTFilter it doesn’t work, but with global filter it works correctly.

Answer

First, you should know GatewayFilter is used for a special route, so that you should bind it to a route.GlobalFilter will take effect for all routes.

And it’s redundant that assembling a GatewayFilter with a GatewayFilter.



Source: stackoverflow