spring-cloud / spring-cloud-consul

Spring Cloud Consul
http://cloud.spring.io/spring-cloud-consul/
Apache License 2.0
813 stars 541 forks source link

Allow for consul services to be used as configuration #202

Open kesor opened 8 years ago

kesor commented 8 years ago

When services are registered as consul services, the service has several properties that can be queried via consul APIs. For example a MongoDB registered service has an Address, Port, Tags as part of the consul service.

The current configuration of endpoints for Spring Cloud applications is hardcoded in Consul K/V store. But some of these (see examples in http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html) can be Consul services, not hardcoded non-moving parts.

Allow for using Consul services as application configuration.

dsyer commented 8 years ago

Can you be a bit more explicit about the use case? I'm not sure what you mean by "current configuration of endpoints". Is it just that the ServiceInstance doesn't contain "tags" metadata from Consul? Or do you want to bridge from ServiceInstance to the Spring Environment?

kesor commented 8 years ago

@dsyer At the moment, spring-cloud-consul-config loads configuration from the Consul Key-Value store. These configuration values are used by multiple Spring frameworks/libraries, for example MongoDB looks for spring.data.mongodb.host and spring.data.mongodb.port, another example RabbitMQ looks for spring.rabbitmq.host and spring.rabbitmq.port.

On the other hand, you have Consul services, which are not Key-Value entries. The request is to use the service entries as configuration for Spring libraries.

dsyer commented 8 years ago

I see (I think). There are potential lifecycle issues (e.g. MongoDB might be needed before the DiscoveryClient is available), but maybe that's nothing new. You would probably want your MongoDB connection to be @RefreshScope, to protect you against changes in the service catalog (so not the one that is created by Spring Boot). I recommend you play around with that a bit and find out if it at least works for your use case, and then we will have some code to talk about, and we can decide if it is a new feature or just a customization that users can apply if they choose.

P.S. if we can implement something using DiscoveryClient it wouldn't be Consul-specific (that's why I mentioned it). But if Consul has some unique features that make this work better without that abstraction I suppose that's also worth looking into (can't think what they would be though).

spencergibb commented 8 years ago

I don't know that there is anything consul specific about the request, except that it's easier to register services like a db in consul since it's already a sidecar and you just need a bit of configuration.

dhait commented 8 years ago

Currently in Spring Boot, we can use interpolated values in properties:

app.description=${app.name}

Perhaps we could do it this way: Register the database as an external service, so that 'mongodb.service.consul' resolves to the MongoDB service. Then, in the config on consul:

spring:
  data:
    mongodb:
       host: ${service/mongodb/host}

Or something along those lines?
spencergibb commented 8 years ago

@dhait what happens when there is more than one instance registered?