in winegrower-core/src/main/java/org/apache/winegrower/service/DefaultConfigurationAdmin.java [202:269]
private void loadConfig(final String pid) {
final String prefix = "winegrower.service." + pid + "."; // for "global" registries like system props
// we first read the config from the classpath (lowest priority)
try (final InputStream embedConfig = Thread.currentThread().getContextClassLoader()
.getResourceAsStream(pid + WINEGROWER_CONFIG_EXTENSION)) {
if (embedConfig != null) {
defaultConfig.putAll(load(embedConfig));
}
} catch (final IOException e) {
throw new IllegalArgumentException(e);
}
properties.putAll(defaultConfig);
// then the default registry which is considered "in JVM" so less prioritized than external config
configRegistry.entrySet().stream().filter(it -> it.getKey().startsWith(prefix))
.forEach(entry -> properties.put(entry.getKey().substring(prefix.length()), entry.getValue()));
// then from an external file
if (defaultExternalConfigLocation.isFile()) {
try (final InputStream stream = new FileInputStream(defaultExternalConfigLocation)) {
this.properties.putAll(load(stream));
} catch (final IOException e) {
throw new IllegalArgumentException(e);
}
}
final Map<String, String> placeholders = new HashMap<>(Map.class.cast(properties));
placeholders.putAll(Map.class.cast(System.getProperties()));
placeholders.putAll(System.getenv());
final Substitutor substitutor = new Substitutor(placeholders);
// and finally from system properties and env variables
// (env is for the machine so less precise than system props so set first)
final String envPrefix = prefix.toUpperCase(ROOT).replace('.', '_');
System.getenv().keySet().stream()
.filter(it -> it.length() > prefix.length() && envPrefix.equalsIgnoreCase(it.substring(0, envPrefix.length())))
.forEach(key -> {
final String k = key.substring(envPrefix.length());
// env keys loose the case so in case it is important, enable to force the key name
// ex: to set configuration{pid=a.b.c, key=fooBar, value=dummy} you would set:
// A_B_C_FOOBAR_NAME=fooBar
// A_B_C_FOOBAR=dummy
// note that the FOOBAR in the key is not important, previous config is the same than:
// A_B_C_1_NAME=fooBar
// A_B_C_1=dummy
// but when there key is not ambiguous (all lowercase) it is simpler to set (key=foobar):
// A_B_C_FOOBAR=dummy
final String value = System.getenv(key);
properties.put(
ofNullable(System.getenv(key + "_NAME")).orElseGet(() -> k.toLowerCase(ROOT)),
value.contains("${") && value.contains("}") ? substitutor.replace(value) : value);
});
System.getProperties().stringPropertyNames().stream()
.filter(it -> it.startsWith(prefix))
.forEach(key -> {
final String value = System.getProperty(key);
properties.put(
key.substring(prefix.length()),
value.contains("${") && value.contains("}") ? substitutor.replace(value) : value);
});
// ensure the factoryPid/pid is there if exists
ofNullable(pid).ifPresent(v -> properties.putIfAbsent("service.pid", v));
ofNullable(factoryPid).ifPresent(v -> properties.putIfAbsent("service.factoryPid", v));
ofNullable(name).ifPresent(v -> properties.putIfAbsent("name", v));
}