Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A Vert.x 3 launcher which overrides root level JSON config properties with values from system properties and/or environment variables
import io.vertx.core.DeploymentOptions;
import io.vertx.core.Launcher;
import io.vertx.core.json.JsonObject;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.Scanner;
/**
* A launcher which enables overriding properties in the deployment config
* by using system properties and environment variables.
*
* The launcher also looks for a default config in the classpath at /defaults-conf.json.
* If you define sensible defaults in this file you get a nice setup where you aren't required
* to send in any conf, but can if you want to. And you are able to override properties.
**/
public class PropertiesLauncher extends Launcher {
public static void main(String[] args) {
new PropertiesLauncher().dispatch(args);
}
@Override
public void beforeDeployingVerticle(DeploymentOptions deploymentOptions) {
JsonObject inputConf = deploymentOptions.getConfig();
final JsonObject conf = inputConf == null ? readDefaultsConf() : inputConf;
if (conf != null) {
JsonObject moddedConf = conf.copy();
for (Map.Entry<String, Object> e : moddedConf) {
String key = e.getKey();
Prop prop = getProp(key);
if (prop != null) {
Class<?> type = e.getValue().getClass();
Object value = convertType(type, prop.value);
System.out.println(String.format(
"Overriding %s=%s of type %s with %s %s=%s. New converted value is '%s'",
key, e.getValue(), type.getName(), prop.source, prop.key, prop.value, value)
);
moddedConf.put(key, value);
}
}
deploymentOptions.setConfig(moddedConf);
}
}
private JsonObject readDefaultsConf() {
InputStream defaultsConf = getClass().getResourceAsStream("/defaults-conf.json");
return defaultsConf == null ? null: new JsonObject(toStr(defaultsConf));
}
private String toStr(InputStream is) {
// http://stackoverflow.com/a/5445161/83741
Scanner s = new Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
private Object convertType(Class<?> type, String value) {
// http://stackoverflow.com/a/13569408/83741
try {
return type.getConstructor( String.class ).newInstance(value);
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
throw new IllegalStateException(String.format("Could not convert value %s into type %s, tried finding a " +
"String constructor", value, type), e);
}
}
static class Prop {
String source;
String key;
String value;
public Prop(String source, String key, String value) {
this.source = source;
this.key = key;
this.value = value;
}
}
static Prop getProp(final String name) {
String sysPropValue = System.getProperty(name);
if (sysPropValue != null) {
return new Prop("system property", name, sysPropValue);
}
String envKey = name.toUpperCase().replaceAll("\\.", "_");
String envValue = System.getenv(envKey);
if (envValue != null) {
return new Prop("environment variable", envKey, envValue);
}
return null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.