Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

spring-cloud-consul: Unable to override defaults in ConsulProperties

I am using spring cloud consul 1.0.0.M5 and spring boot 1.3.2. The default host and port that spring cloud consul uses to connect to the consul agent is localhost:8500. I want to change this, but every method I have tried so far does not respect the settings.

I looked at the source for spring cloud consul and ConsulProperties is read using @ConfigurationProperties from spring-boot at property prefix spring.cloud.consul.

Here is the declaration in the spring cloud source for ConsulProperties:

/**
 * @author Spencer Gibb
 */
@ConfigurationProperties("spring.cloud.consul")
@Data
public class ConsulProperties {
    @NotNull
    private String host = "localhost";

    @NotNull
    private int port = 8500;

    private boolean enabled = true;

    private String prefix = "config";
}

and how it is injected in the spring cloud consul source to define the ConsulClient that makes the http request to the consul agent:

/**
 * @author Spencer Gibb
 */
@Configuration
@EnableConfigurationProperties
@ConditionalOnConsulEnabled
public class ConsulAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public ConsulProperties consulProperties() {
        return new ConsulProperties();
    }

    @Bean
    @ConditionalOnMissingBean
    public ConsulClient consulClient() {
        return new ConsulClient(consulProperties().getHost(), consulProperties()
                .getPort());
    }

...

I placed the following in my application.properties but every combination is ignored and the default "localhost" and "8500" is used instead. I would think that "spring.cloud.consul.host" and "spring.cloud.consul.port" would be respected in this case.

spring.cloud.consul.config.host=172.17.42.1
spring.cloud.consul.config.port=8500
config.host=172.17.42.1
config.port=8500
spring.cloud.consul.host=172.17.42.1
spring.cloud.consul.port=8500

I also tried explicitly defining a ConsulProperties bean since it is marked as @ConditionalOnMissingBean in the spring configuration, but this bean is not read either. I had to circumvent the type system in that case because all the fields are private (ugh). Here is the snippet from the configuration class in my code:

...
import org.apache.commons.lang3.reflect.FieldUtils;
...
@Configuration
@EnableDiscoveryClient
@Order(Ordered.HIGHEST_PRECEDENCE)
@Priority(Ordered.HIGHEST_PRECEDENCE)
public class ConsulConfig {
...

    @Bean
    public ConsulProperties consulProperties() {
        ConsulProperties props;

        try {
            props = new ConsulProperties();

            String host = resolveConsulHost();
            int port = this.consulPort;

            FieldUtils.writeField(props, "host", host,true);
            FieldUtils.writeField(props, "port", port,true);

        }
        catch(Exception e) {
            logger.warn("Unable to set ConsulProperties - using defaults",e);
            props = new ConsulProperties();
        }

        logger.info("Using consulProperties={}",props);

        return props;

    }

...
}

@Configuration
@EnableAutoConfiguration
@EnableConfigurationProperties
@ComponentScan
public class Application {

    private final Logger logger = LoggerFactory.getLogger(getClass());
    public static void main(String[] args) {
        ApplicationContext ctx = SpringApplication.run(Application.class, args);
    }
...
}

How can I customize what spring cloud consul uses for the host and port to connect to the consul agent?

like image 845
GameSalutes Avatar asked Jan 29 '16 18:01

GameSalutes


1 Answers

Migrated comment to answer:

If you are using spring-cloud-starter-consul-all or spring-cloud-starter-consul-config, you need to put values in bootstrap.properties.

Here is the documentation. The gist, spring.application.name and whatever is needed to connect to consul.

like image 74
spencergibb Avatar answered Oct 19 '22 22:10

spencergibb