Java tutorial
/** * Copyright 2016, 2019 Nitor Creations Oy * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.nitor.api.backend; import io.vertx.core.DeploymentOptions; import io.vertx.core.Launcher; import io.vertx.core.json.JsonObject; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.util.Map; import static io.nitor.api.backend.util.Helpers.toBytes; import static java.lang.System.getProperty; import static java.lang.System.getenv; import static java.nio.charset.StandardCharsets.UTF_8; import static java.util.Locale.US; /** * A launcher which enables overriding properties in the deployment config * by using system properties and environment variables. * <p> * The launcher also looks for a default config in the classpath at /config.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. * <p> * https://gist.github.com/atorstling/d2669ba477924adac88d3caff6a36e8d **/ public class PropertiesLauncher extends Launcher { public static void main(String[] args) { new PropertiesLauncher().dispatch(args); } @Override public void beforeDeployingVerticle(DeploymentOptions deploymentOptions) { JsonObject conf = readDefaultsConf(); JsonObject inputConf = deploymentOptions.getConfig(); if (inputConf != null) { conf.mergeIn(inputConf); } override(conf, ""); deploymentOptions.setConfig(conf); } private void override(JsonObject conf, String root) { for (Map.Entry<String, Object> e : conf) { String key = root + e.getKey(); Object value = e.getValue(); if (value instanceof JsonObject) { override((JsonObject) value, key + '.'); return; } Prop prop = getProp(key); if (prop != null) { conf.put(e.getKey(), convertType(value.getClass(), prop.value)); } } } private JsonObject readDefaultsConf() { try (InputStream defaultsConf = getClass().getResourceAsStream("/config.json")) { return defaultsConf == null ? null : new JsonObject(toStr(defaultsConf)); } catch (IOException e) { throw new RuntimeException(e); } } private String toStr(InputStream is) throws IOException { return new String(toBytes(is), UTF_8); } 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 { final String source; final String key; final 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 = getProperty(name); if (sysPropValue != null) { return new Prop("system property", name, sysPropValue); } String envKey = name.toUpperCase(US).replaceAll("\\.", "_"); String envValue = getenv(envKey); if (envValue != null) { return new Prop("environment variable", envKey, envValue); } return null; } }