Architecture/MSA

Spring Cloud Gateway - Custom Predicate with AbstractRoutePredicateFactory

체리필터 2021. 1. 6. 15:44
728x90
반응형

특정 조건에 특정 route를 적용할 것인지 정의 내리는 것을 predicate 라고 하는데 이미 정의 된 predicate 말고 Custom predicate를 만들 수 있다.

AbstractRoutePredicateFactory 추상 클래스를 상속받아 몇 가지만 구현해 주면 된다.

import lombok.Getter;
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.server.ServerWebExchange;

import javax.validation.constraints.NotEmpty;
import java.util.function.Predicate;

public class MacaronRoutePredicateFactory extends AbstractRoutePredicateFactory<MacaronRoutePredicateFactory.Config> {
    public MacaronRoutePredicateFactory() {
        super(Config.class);
    }

    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        return (ServerWebExchange t) -> {
            return config.isGolden();
        };
    }

    @Validated
    @Getter
    public static class Config {
        private boolean isGolden = true;

        @NotEmpty
        String customerIdCookie = "customerId";
    }
}

apply 메소드를 통해서 true, false를 리턴하면 되는데 true를 리턴하면 해당 routing rule을 적용한다는 의미이다.

기존에 적용되어져 있던 Route rule을 다음과 같이 적용하면 잘 적용 됨을 알 수 있다.

    @Bean
    public RouteLocator chauffeurRoutes(RouteLocatorBuilder builder, UriConfiguration uriConfiguration, MacaronRoutePredicateFactory macaronRoutePredicateFactory) {
        String chauffeurUrl = uriConfiguration.getChauffeur();

        RouteLocator routeLocator = builder.routes()
                .route("macaronRoute", p -> p
                        .path("/chauffeur/**")
                        .filters(f -> f.stripPrefix(1))
                        .uri(chauffeurUrl)
                        .predicate(macaronRoutePredicateFactory.apply(new MacaronRoutePredicateFactory.Config()))
                )
                .build();

        return routeLocator;

//        return builder.routes()
//                .route(p -> p
//                        .path("/chauffeur/**")
//                        .filters(f -> f.stripPrefix(1))
//                        .uri(chauffeurUrl)
//                )
//                .build();
    }

predicate 부분에 내용이 항상 true를 리턴하기 때문에 해당 호출은 uri로 routing 된다.

하지만 위의 MacaronRoutePredicateFactory 에서 isGolden 값을 false로 바꾸어 실행해 보면 path predicate가 true일 지라도 custom predicate가 false가 나면서 gateway를 호출해도 404 not found가 나오게 된다.

모든 predicate 값은 and 조건으로 동작한다.

728x90
반응형