5
votes

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?

1
If you are using spring-cloud-starter-consul-all or spring-cloud-starter-consul-config, you need to put values in bootstrap.properties .spencergibb
@spencergibb This did it for me! Did not know about bootstrap properties. From reading around a bit, It's not clear to me which properties I should put in application.properties and which go in bootstrap.properties. Are all spring.cloud.* supposed to be in bootstrap?GameSalutes

1 Answers

10
votes

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.