Simi
Simi

Reputation: 91

Spring Cloud Gateway Dynamic Routing

Really new to Spring Cloud Gateway - but it "seems" easy enough. One issue I'm really struggling with. My requirement is to prefix the path, inspect a header variable, look up the URI based on that variable, and chug along after that.

The problem is the uri is ALWAYS the DEFAULT_IMPLEMENTION below, even though I'm changing this in the idResolvingGatewayFilter. How can I accomplish this? New ids can be added at any time - so that's the "dynamic" portion. So in the gateway filter I'm reading the header and looking up the uri (the datasource I'm looking at can be updated at any time). But the code below appears to be overriding whatever I'm assigning in the filter - and you can't do this without providing the URI. For example:

header-id=123
uri=http://www.somedestination.com/something/services/v1.0

header-id=999
uri=http://www.anotherdestination.com/something/services/v1.0

  @Bean
  public RouteLocator rosterRouteLocator( RouteLocatorBuilder builder )
  {
    log.info( "Establishing Gateway Routes" );
    return builder.routes()
        .route( r -> r.path( "/**" ).filters( f -> f.prefixPath( "/something/services/v1.0" ).filter( idResolvingGatewayFilter() ) )
            .uri( resolver.buildDestinationEndpoint( IdUrlResolver.DEFAULT_IMPLEMENTATION ) ) )
        .build();
  }

And in the idResolvingGatewatFilter I'm making the changes (and the log statement look right-one...it just doesn't GO there!

public Mono<Void> filter( ServerWebExchange exchange, GatewayFilterChain chain )
  {
    try
    {
      URI newUri = buildURI( exchange );
      ServerHttpRequest request = exchange.getRequest().mutate().uri( newUri ).build();
      exchange = exchange.mutate().request( request ).build();
      log.debug( "Modified URI: " + exchange.getRequest().getURI() );

Upvotes: 8

Views: 12862

Answers (1)

srikanth
srikanth

Reputation: 171

@SpringBootApplication
public class SpringCloudGatewayApplication {

    @Autowired
    private CustomerFilter filter;

    public static void main(String[] args) {
        SpringApplication.run(SpringCloudGatewayApplication.class, args);
    }

    @Bean
    public RouteLocator myRoutes(RouteLocatorBuilder builder) {

        return builder.routes().route(p -> p.path("/**").filters(f -> f.filter(filter)).uri("no://op")).build();
    }
}

class CustomerFilter implements GatewayFilter, Ordered {

    @Override
    public int getOrder() {
        return RouteToRequestUrlFilter.ROUTE_TO_URL_FILTER_ORDER + 1;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String newUrl = null;

        if (exchange.getRequest().getHeaders().getHost().toString().equals("localhost:8080")) {
            newUrl = "http://ip1/path1";
        } else {
            newUrl = "http://ip2/path2";
        }

        exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR, new URI(newUrl));
        return chain.filter(exchange);
    }
}

Upvotes: 17

Related Questions