Spring-cloud-gateway: Auto-routing through Consul [Question]

Created on 24 Jul 2018  路  13Comments  路  Source: spring-cloud/spring-cloud-gateway

I'm using Zuul gateway and I'd like to migrate to this solution but I'd need to know if it's possible that SCG can auto-routing services registered (without edit any configuration file) in a Consul service discovery as Zuul does.

bug

Most helpful comment

Finally, I could achieve it! :clap:

I need to define the following bean: DiscoveryClientRouteDefinitionLocator (reference) and then, the gateway works like magic. I'll paste my configuration bean if someone would need it.

@Configuration
@EnableDiscoveryClient
public class AutoRouting {

  @Bean
  public DiscoveryClientRouteDefinitionLocator discoveryClientRouteDefinitionLocator(DiscoveryClient discoveryClient, DiscoveryLocatorProperties properties) {
    return new DiscoveryClientRouteDefinitionLocator(discoveryClient, properties);
  }
}

All 13 comments

Thanks for your response @ryanjbaxter. Given that chapter of the documentation, I supposed the same and I've made a project as POC. When I run it, SCG doesn't declare any route for my services which are registered in Consul. I'm using "Finchley" version of Spring Cloud. I attach my pom.xml, application.yml and bootstrap.yml, maybe I made a mistake.

pom.xml

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.3.RELEASE</version>
</parent>
<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
</properties>
<dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- Consul -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-all</artifactId>
        </dependency>
</dependencies>

<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
</dependencyManagement>

application.yml

server:
  port: 8080

logging:
  level:
    org: DEBUG
    com.epgpay: INFO, ERROR


spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true

bootstrap.yml

spring:
  application:
    name: spring-cloud-gateway
  cloud:
    consul:
      enabled: true
      host: localhost
      port: 8500
      discovery:
        register: false
        enabled: true

Finally, I could achieve it! :clap:

I need to define the following bean: DiscoveryClientRouteDefinitionLocator (reference) and then, the gateway works like magic. I'll paste my configuration bean if someone would need it.

@Configuration
@EnableDiscoveryClient
public class AutoRouting {

  @Bean
  public DiscoveryClientRouteDefinitionLocator discoveryClientRouteDefinitionLocator(DiscoveryClient discoveryClient, DiscoveryLocatorProperties properties) {
    return new DiscoveryClientRouteDefinitionLocator(discoveryClient, properties);
  }
}

@spencergibb is defining a DiscoveryClientRouteDefinitionLocator bean necessary? If so we should add it to the documentation I think.

No it isn't

Hi @ryanjbaxter and @spencergibb, running the project in debug mode I could see the following:

GatewayDiscoveryClientAutoConfiguration#discoveryClientRouteDefinitionLocator:
      Did not match:
         - @ConditionalOnBean (types: org.springframework.cloud.client.discovery.DiscoveryClient; SearchStrategy: all) did not find any beans of type org.springframework.cloud.client.discovery.DiscoveryClient (OnBeanCondition)
      Matched:
         - @ConditionalOnProperty (spring.cloud.gateway.discovery.locator.enabled) matched (OnPropertyCondition)

GatewayDiscoveryClientAutoConfiguration class is the unique point where DiscoveryClientRouteDefinitionLocator is referenced and as you can see at the previous log, the bean is not created due a validation error. Searching through the web I could see other developer with the same issue as me.

_Bean Def._

@Bean
@ConditionalOnBean(DiscoveryClient.class)
@ConditionalOnProperty(name = "spring.cloud.gateway.discovery.locator.enabled")
public DiscoveryClientRouteDefinitionLocator discoveryClientRouteDefinitionLocator(DiscoveryClient discoveryClient, DiscoveryLocatorProperties properties) {
    return new DiscoveryClientRouteDefinitionLocator(discoveryClient, properties);
}

P.S: Thanks to actuator, I can see that there is a bean named "consulDiscoveryClient"

This works fine for me without adding the bean to my application using Finchley.BUILD-SNAPSHOT.

By default routes are added with the service id in uppercase, so the service id in the path needs to be uppercase. You can change this by setting spring.cloud.gateway.discovery.locator.lower-case-service-id to false.

Only eureka upper cases the service ids

@ryanjbaxter , have you tested with Eureka or Consul? I've re-created the project following this tutorial from spring's youtube channel: tutorial, but the issue still appearing.

I've created a github's repository where you can check my project's configuration if you want.

Thanks for the support :+1:

Yes I tested with Eureka. Can you link to the GitHub repo?

Yes, for sure: repository (sorry, I forget the link)

I think the problem is that GatewayDiscoveryClientAutoConfiguration is being configured before CompositeDiscoveryClientAutoConfiguration, therefore the DiscoveryClient bean is not present. It seems to be fine when using Eureka but with Consul the ordering is different.

That is my suspicion. For curiosity, I'll check the difference between eureka and consul clients :nerd_face: Thanks for your support!

Was this page helpful?
0 / 5 - 0 ratings