Using the default property file in @Source mode + multiple keys
ledebroux opened this issue · 4 comments
Hello,
I want to specify several sources for a config (which honestly is super easy, that's great).
But I would like to be able to fall back on my dedicated .properties file.
Is there a way not to provide the whole path of the file ?
As an example, say I have path/to/package/MyConfig.java
in my src/main
and the corresponding path/to/package/MyConfig.properties
in src/resources
.
It works like a charm without @Source
, but what if I use it like so:
@Sources({
"file:~/my/project/path/foo.config",
"system:env",
"classpath:path/to/package/MyConfig.properties"
})
Is there a way not to give path/to/package
?
Second question is, is there a way to specify several keys (I guess there isn't) ?
What would be the workaround as env var are most of the time in CAPS and formatted differently than what a properties file might be ?
For example: CORE_THREAD_NUMBER
vs core.thread_number
.
Thanks ! (great framework btw)
I'm in the same boat. Using Java properties style names (property.name
) but would like to be able to override with environment variable PROPERTY_NAME
since dot isn't usually allowed in a system environment variable name.
I changed the SystemLoader load()
to lowercase and change underscores to periods. I'm not overly thrilled with it but it serves the purpose for now.
public void load(Properties result, URI uri) throws IOException {
String path = uri.toString();
if (SYSTEM_PROPERTIES_URI.equals(path))
result.putAll(system().getProperties());
if (ENVIRONMENT_VARIABLES_URI.equals(path)) {
for(String key : system().getenv().keySet()) {
result.put(key.toLowerCase().replace("_", "."), system().getenv().get(key));
}
}
}
Looking at it more, I think it would be better if users could provide their own implementations of Loader
and register them with the LoadersManager
.
Hi.
There are several solutions to the above problem.
- using variable expansion, as explained here:
// notice ${mypath} here
@Sources("file:${mypath}/myconfig.properties");
interface MyConfig extends Config { ... }
MyConfig cfg = ConfigFactory.create(MyConfig.class);
-
If you want to specify a relative path to the current working directory (the directory from which the java interpreter is launched to start your application), I think you can also specify a relative path to
file:
: "file:./foo.config" or "file:foo.config" , in this way the file should be searched locally to current work dir. (please verify) -
Do it programmatically:
// define sources to a variable
@Sources("${my.config.uri}")
@LoadPolicy(FIRST)
public interface MyConfig extends Config { ... }
// then set the variable before first usage
private String defaultConfigURI = "classpath:foo/bar/baz.properties";
Config getConfig() {
String configURI = defaultConfigURI;
// configFileName is specified at the command line in my case
if (configFileName != null) {
configURI = "file:" + configFileName;
}
ConfigFactory.setProperty("my.config.uri", configURI);
LOGGER.info("Loading configuration from URI '{}'.", configURI);
Config config = ConfigFactory.create(Config.class);
verify(config);
LOGGER.info("Successfully loaded configuration with description '{}'.",
config.configDescription());
return config;
}
I know, this can be improved.
FYI:
file:./foo.config
is working just fine to get the file from the current working directory.
Hi, sorry I'm from Mexico and English is not my primary language.
I will try to explain a problem that I have using Dropwizard (microservice), dropwizard generates a jar file and I need to change some properties in the fly (owner is good for this).
java -Downer.config.file=/Users/fernando/git/RHBridge/recursos/bridge.properties -jar target/bridge-1.0.0.jar server config.yml
- I have OWNER interface that works fine, this has my local path and dev server path into
@Sources
@Sources({ "file:/Users/fernando/git/RHBridge/recursos/bridge.properties",
"file:/opt/aplicaciones/dev/Bridge/config/bridge.properties" })
@HotReload
public interface OwnerConfig extends Config {
...
}
- When I try to deploy to test and production environments these are 2 different servers and paths, this makes to compile again with different
@Sources
values - I have few experience in develop, but I use
-Downer.config.file=xxx
and http://owner.aeonbits.org/docs/importing-properties/ (Interactions with loading strategies) and it is ignoring@HotReload
when takes import strategy
public OwnerConfig ownerConfig() {
try {
if (System.getProperty("owner.config.file") != null
&& System.getProperty("owner.config.file").length() > 0) {
Properties props = new Properties();
props.load(new FileInputStream(new File(System.getProperty("owner.config.file"))));
LOG.info("Using properties file from Java System Property -Downer.config.file={}",
System.getProperty("owner.config.file"));
return ConfigFactory.create(OwnerConfig.class, props);
} else {
LOG.info("Using properties from owner @Sources");
return ConfigFactory.create(OwnerConfig.class);
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
Do you have a recommendation or way to do this with OWNER?
Something like this:
@Sources({ "file:/Users/fernando/git/RHBridge/recursos/bridge.properties",
System.getProperty("owner.config.file"))
@HotReload
public interface OwnerConfig extends Config {
...
}
Thanks