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

io.atleon.core.ConfigProvider Maven / Gradle / Ivy

package io.atleon.core;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;

/**
 * Base class of Config-producing resources. Provided Configs are (typically) based solely on the
 * contents of the {@code properties} Map wrapped by this Provider.
 *
 * 

Config Providers can be named either explicitly or via property introspection. This is useful * when applying {@link ConfigInterceptor}s. By default, Providers should use the default * ConfigInterceptors to transform the properties Map prior to generating the final Config. The * default interceptors allow clients to: *

    *
  • Override named properties via system and/or environment variables: *

    Override the value of "key" in a ConfigProvider with the name "aws" to "overridden" *

    {@code System.setProperty("atleon.config.aws.key", "overridden")}

  • *
  • Randomize properties: *

    Randomize "value" associated with "key" by appending a random UUID *

    {@code configProvider.with("key", "value").with("key.randomize", true)}

  • *
* * @param

The type of this ConfigProducer */ public abstract class ConfigProvider> { private Map properties = Collections.emptyMap(); private Function, Optional> propertiesToName; protected ConfigProvider() { this(properties -> Optional.empty()); } protected ConfigProvider(String name) { this(properties -> Optional.of(name)); } protected ConfigProvider(Function, Optional> propertiesToName) { this.propertiesToName = propertiesToName; } public final V as(Function transformer) { return transformer.apply((P) this); } public final T create() { return propertiesToName.apply(properties) .map(name -> create(name, properties)) .orElseGet(() -> create(properties)); } public final P rename(String name) { P copy = copy(); copy.setPropertiesToName(properties -> Optional.of(name)); return copy; } public P with(String key, Object value) { Map copiedProperties = new HashMap<>(this.properties); copiedProperties.put(key, value); P copy = copy(); copy.setProperties(Collections.unmodifiableMap(copiedProperties)); return copy; } public P withAll(Map properties) { Map copiedProperties = new HashMap<>(this.properties); copiedProperties.putAll(properties); P copy = copy(); copy.setProperties(Collections.unmodifiableMap(copiedProperties)); return copy; } protected abstract T create(String name, Map properties); protected abstract T create(Map properties); protected final P copy() { P copy = initializeCopy(); copy.setProperties(properties); copy.setPropertiesToName(propertiesToName); return copy; } protected abstract P initializeCopy(); protected Collection defaultInterceptors() { return Arrays.asList(new EnvironmentalConfigs(), new ConditionallyRandomizedConfigs()); } protected static void validateNonNullProperty(Map properties, String key) { Objects.requireNonNull(properties.get(key), key + " is a required Configuration"); } protected static void validateAnyNonNullProperty(Map properties, String... keys) { for (String key : keys) { if (properties.get(key) != null) { return; } } throw new IllegalArgumentException("At least one of " + Arrays.toString(keys) + " must be configured"); } protected static > void validateEnumProperty(Map properties, String key, Class enumClass) { try { Enum.valueOf(enumClass, Objects.toString(properties.get(key))); } catch (Exception e) { throw new IllegalArgumentException(key + " must be configured as an Enum value from " + enumClass, e); } } final void setProperties(Map properties) { this.properties = properties; } final void setPropertiesToName(Function, Optional> propertiesToName) { this.propertiesToName = propertiesToName; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy