Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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() );
like image 496
Simi Avatar asked Oct 26 '18 18:10

Simi


People also ask

How does Spring Cloud gateway works?

Spring Cloud Gateway makes use of the Actuator API, a well-known Spring Boot library that provides several out-of-the-box services for monitoring the application. Once the Actuator API is installed and configured, the gateway monitoring features can be visualized by accessing /gateway/ endpoint.

Is Spring cloud gateway an API gateway?

Spring Cloud Gateway provides a library for building API gateways on top of Spring and Java. It provides a flexible way of routing requests based on a number of criteria, as well as focuses on cross-cutting concerns such as security, resiliency, and monitoring.

What is the difference between ZUUL and spring cloud gateway?

Zuul is built on servlet 2.5 (works with 3. x), using blocking APIs. It doesn't support any long lived connections, like websockets. Gateway is built on Spring Framework 5, Project Reactor and Spring Boot 2 using non-blocking APIs.


1 Answers

@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);
    }
}
like image 171
srikanth Avatar answered Sep 23 '22 04:09

srikanth