All Downloads are FREE. Search and download functionalities are using the official Maven repository.

nl.vpro.api.client.utils.Config Maven / Gradle / Ivy

package nl.vpro.api.client.utils;

import lombok.*;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.net.InetAddress;
import java.util.*;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;

import nl.vpro.poms.shared.Deployment;
import nl.vpro.util.ConfigUtils;
import nl.vpro.util.Env;

/**
 * Represents configuration for an api client.
 * 

* Arranges reading config files from classpath and ~/conf, and have a switcher with {@link Env}. * @author Michiel Meeuwissen */ @Slf4j public class Config { /** * The resource with properties of all known environments */ public static final String URLS_FILE = "poms-urls.properties"; public static final String CONFIG_FILE = "apiclient.properties"; private final Map properties; private final String[] configFiles; private final Map envs= new HashMap<>(); private final Map> mappedProperties = new HashMap<>(); public enum Prefix { api(Deployment.api), media_api_backend(Deployment.media_api_backend), parkpost(null), media_api_backend_rcrs(null), media_api_backend_prepr(null), pages_publisher(Deployment.pages_publisher), media_publisher(Deployment.media_publisher), media(Deployment.media), images(Deployment.images), images_backend(Deployment.images_backend), nep(null); @Nullable @Getter private final Deployment deployment; Prefix(@Nullable Deployment deployment) { this.deployment = deployment; if (this.deployment != null) { assert this.deployment.name().equals(name()); } } public String getKey() { return deployment == null ? name() : "npo-" + name(); } public static Prefix ofKey(String value) { for (Prefix p : values()) { if (value.equals(p.getKey())) { return p; } } throw new IllegalArgumentException(); } } public Config(String... configFiles) { properties = new HashMap<>(); this.configFiles = configFiles; try { Map initial = new HashMap<>(); initial.put(Key.of("localhost"), InetAddress.getLocalHost().getHostName()); String[] configFilesInHome = ConfigUtils.getConfigFilesInHome(configFiles); if (configFilesInHome.length > 0) { log.debug("Reading configuration from {}", Arrays.asList(configFilesInHome)); } ConfigUtils.getProperties( initial, Key::of, configFilesInHome ).forEach((key, value) -> { String previous = properties.put(key, value); if (previous != null) { log.info("replaced {}: {} -> {}", key, previous, value); } }); log.debug("{}", properties); } catch (IOException e) { log.error(e.getMessage(), e); } log.info("Read configuration from {}", Arrays.asList(configFiles)); } public Optional configOption(Prefix pref, String prop) { String value = getProperties(pref).get(prop); return Optional.ofNullable(value); } public String requiredOption(Prefix pref, String prop) { return configOption(pref, prop) .orElseThrow(notSet(pref, prop)); } public String url(Prefix pref, String path) { String base = requiredOption(pref, "baseUrl"); if (! base.endsWith("/")) { base = base + "/"; } return base + path; } private Map getProperties() { return properties.entrySet().stream() .collect(Collectors.toMap((e) -> e.getKey().toString(), Map.Entry::getValue)); } public String getProperty(String key) { String value = getProperties().get(key); if (value == null) { throw new IllegalArgumentException("No such key " + key); } return value; } public Map getProperties(Prefix prefix) { Map result = mappedProperties.get(prefix); if (result == null) { final Map r = new HashMap<>(); final Map strengths = new HashMap<>(); result = r; mappedProperties.put(prefix, result); final Env env = env(prefix); log.info("Env for {}: {}", prefix, env); properties.forEach((key, value) -> { if (key.prefix() == null || prefix.equals(key.prefix())) { Env.Match matches = env.matches(key.env()); if (matches.getAsBoolean()) { Integer existingStrength = strengths.get(key.key()); int strength = key.strength() + matches.getStrength(); if (existingStrength != null && existingStrength == strength) { log.warn("Found the same property twice {} {}", existingStrength, key); } if (existingStrength == null || existingStrength <= strength) { r.put(key.key(), value); strengths.put(key.key(), key.strength()); log.debug("Put {} -> {}", key, value); } else { log.debug("ignored {}", key); } } } }); log.info("Read for {}.{} {}", prefix, env, r.keySet()); } return result; } public Map getPrefixedProperties(Prefix prefix) { return getProperties(prefix) .entrySet() .stream() .map(e -> new AbstractMap.SimpleEntry<>(prefix.getKey() + "." + e.getKey(), e.getValue())) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); } public Supplier notSet(String prop) { return () -> new RuntimeException(prop + " is not set in " + Arrays.asList(configFiles)); } public Supplier notSet(Prefix pref, String prop) { return () -> new RuntimeException(pref.getKey() + "." + prop + " is not set in " + Arrays.asList(configFiles)); } public void setEnv(Prefix prefix, Env env) { if (! Objects.equals(envs.put(prefix, env), env)) { mappedProperties.clear(); } } public void setEnv(Env env) { if (! Objects.equals(envs.put(null, env), env)) { mappedProperties.clear(); } } @NonNull public Env env() { Env env = envs.get(null); if (env == null) { String pref = getEnvProperty("env"); if (pref == null) { env = Env.valueOf(properties.getOrDefault(ENV, "test").toUpperCase()); } else { env = Env.valueOf(pref.toUpperCase()); } envs.put(null, env); } return env; } @NonNull public Env env(Prefix prefix) { Env env = envs.get(prefix); if (env == null) { String pref = getEnvProperty(prefix.name() + ".env"); if (pref != null) { env = Env.valueOf(pref.toUpperCase()); } else { Key keyForPrefix = ENV.copyFor(prefix); String envString = properties.getOrDefault(keyForPrefix, env().name()); env = Env.optionalValueOf(envString).orElse(null); } if (envs.put(prefix, env) != null) { log.warn("Replaced {}", prefix); } } return env; } public static String getEnvProperty(String name) { return getEnvProperty(name, null); } public static String getEnvProperty(String name, String def) { return System.getenv().getOrDefault(name, System.getProperty(name, def)); } private static final Key ENV = new Key(null, "env", null, 1); public record Key(Prefix prefix, String key, Env env, int strength) { public static Key of(String joinedKey) { try { String[] split = joinedKey.split("\\.", 3); Prefix prefix; String key; Env env; if (split.length == 1) { prefix = null; key = split[0]; env = null; } else if (split.length == 2) { try { prefix = Prefix.ofKey(split[0]); key = split[1]; env = null; } catch (IllegalArgumentException iae) { prefix = null; key = split[0]; env = Env.valueOf(split[1].toUpperCase()); } } else { prefix = Prefix.ofKey(split[0]); key = split[1]; try { env = Env.valueOf(split[2].toUpperCase()); } catch (IllegalArgumentException ia) { key += "." + split[2]; env = null; } } return new Key(prefix, key, env, split.length); } catch (IllegalArgumentException iae) { return new Key(null, joinedKey, null, 0); } } @Override public String toString() { StringBuilder builder = new StringBuilder(); if (prefix != null) { builder.append(prefix.getKey()).append('.'); } builder.append(key); if (env != null) { builder.append('.').append(env.name().toLowerCase()); } return builder.toString(); } public Key copyFor(Prefix prefix) { return new Key(prefix, key, env, 2); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy