-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ConsulSubsitutor does not seem to handle default values #71
Comments
I changed this to an investigation because it might be caused by the way the example application is implemented. It explicitly adds an environment variable So, it might be that whenever there is a default value in a template variable, it uses that when it fails to find a value and doesn't consult any other substitutors. This needs more investigation to determine the exact behavior. |
I performed additional investigation using seven different configuration scenarios, and two application runtime configurations. The two application configurations are:
The seven configuration scenarios are:
A value in the private String template = "Hello there, %s!";
private String defaultName = "Stranger"; The literal value in YAML looks like: template: Hello there, %s!
defaultValue: Stranger A template value in YAML looks like: template: ${helloworld/template}
defaultName: ${helloworld/defaultName} And, template value in YAML with default value looks like: template: ${helloworld/template:-Hello, %s!}
defaultName: ${helloworld/defaultName:-Stranger} The table below shows the results of attempting each of the seven configuration scenarios for the two application configurations.
As is shown in the table, only one scenario fails, which occurs when there is a field in the I am fairly sure this occurs because the flowchart LR
ckv(Consul KV) --> ev(Environment Value) --> dvy(Default value in YAML) --> dvcc(Default value in Configuration class)
or maybe you would want to check for the environment variable first and the Consul KV value second: flowchart LR
ev(Environment Value) --> ckv(Consul KV) --> dvy(Default value in YAML) --> dvcc(Default value in Configuration class)
This kind of chained fallback behavior can be implemented, but not without creating additional code and changing the existing public class StringLookupChain implements StringLookup {
private final List<StringLookup> lookups;
public StringLookupChain(List<StringLookup> lookups) {
checkArgument(nonNull(lookups) && !lookups.isEmpty(), "lookups must not be null or empty");
this.lookups = lookups;
}
@Override
public String lookup(String key) {
return lookups.stream()
.map(nextLookup -> nextLookup.lookup(key))
.map(Strings::nullToEmpty)
.filter(str -> !str.isEmpty())
.findFirst()
.orElse(null);
}
} And then the StringLookup envLookup = System::getenv;
var consulLookup = new ConsulLookup(consul, strict);
// In this implementation, environment variables take precedence over Consul KV values
var lookupChain = new StringLookupChain(List.of(envLookup, consulLookup));
this.setVariableResolver(lookupChain); |
Summary
When using the
ConsulSubsitutor
to retrieve configuration values from the Consul KV store, there seems to be a problem when there are default values.I used the
consul-example
application (before removing it from this project, and it's obviously still in git history) to test getting values from Consul's KV store. Here is the YAML config corresponding to thetemplate
anddefaultName
properties in the application'sConfiguration
class:This is a snippet from the
hello-world.yml
file that is in the example application.In this configuration,
helloworld/template
andhelloworld/defaultName
are the keys to look up in Consul, andHello, %s!
andStranger
are the default values when not found in Consul.What should happen:
When the application starts, it should find the values for
helloworld/template
andhelloworld/defaultName
in Consul's KV store, and they should be stored in the application'sConfiguration
object at runtime.What actually happens
The default values are in the
Configuration
object, not the values from Consul.This only happens when there are default values specified in the YAML. If the configuration is:
then the values stored in Consul (I used
Hola %s
forhelloworld/template
andCowgirl
forhelloworld/defaultName
) are stored in theConfiguration
object at runtime.Steps to reproduce:
helloworld/template
andhelloworld/defaultName
in Consul's KV store (e.g.Hola, %s
andCowgirl
)GET
request to the/hello-world
endpointThe output will be:
Hello, Stranger!
instead of the expectedHola, Cowgirl
.Notes
I searched through the issues in the original dropwizard-consul project and found this issue: working with default values failing. So, I was not the first person to find this problem. That issue was reported on Jan 2, 2018 and was automatically closed as stale by a GitHub action.
The text was updated successfully, but these errors were encountered: