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

io.debezium.operator.api.config.ConfigMapping Maven / Gradle / Ivy

/*
 * Copyright Debezium Authors.
 *
 * Licensed under the Apache Software License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
 */
package io.debezium.operator.api.config;

import static java.util.function.Predicate.not;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

import io.fabric8.kubernetes.api.model.HasMetadata;

/**
 * Convenience wrapper used to build properties-like configuration from arbitrary map
 */
public final class ConfigMapping

{ private final P primary; /** * Represents a key in the configuration */ public enum KeyType { /** * The key is relative to the current prefix */ RELATIVE, /** * The key is absolute and will never be prefixed (unless specifically documented), * including situations when the mapping is put into another mapping */ ABSOLUTE; } public record Key(String name, KeyType type) { public static Key rel(String key) { return new Key(key, KeyType.RELATIVE); } public static Key abs(String key) { return new Key(key, KeyType.ABSOLUTE); } public static Key root() { return new Key(null, null); } public Key asAbs() { return abs(name); } public Key asRel() { return rel(name); } @Override public String toString() { return name; } } private final Map config; private final String prefix; public static

ConfigMapping

from(P primary, Map properties) { var config = ConfigMapping.empty(primary); config.putAll(properties); return config; } public static

ConfigMapping

empty(P primary) { return new ConfigMapping<>(primary, null); } public static

ConfigMapping

prefixed(P primary, String prefix) { return new ConfigMapping<>(primary, prefix); } public ConfigMapping(P primary, String prefix) { this.config = new HashMap<>(); this.prefix = prefix; this.primary = primary; } /** * Creates new ConfigMapping, with the same prefix as this one, but sets all keys as absolute * * @return new ConfigMapping with all keys as absolute */ public ConfigMapping

asAbsolute() { return ConfigMapping.prefixed(primary, prefix).putAllAbs(this); } /** * Creates new ConfigMapping, with the same prefix as this one, but sets all keys as relative * * @return new ConfigMapping with all keys as relative */ public ConfigMapping

asRelative() { return ConfigMapping.prefixed(primary, prefix).putAllRel(this); } public Map getAsMapSimple() { return config.entrySet() .stream() .collect(Collectors.toMap(e -> e.getKey().name(), Map.Entry::getValue)); } public Map getAsMap() { return config; } public String getAsString() { return config.entrySet().stream() .map(e -> e.getKey() + "=" + e.getValue()) .sorted() .collect(Collectors.joining(System.lineSeparator())); } public ConfigMapping

rootValue(Object value) { putInternal(value, Key.root()); return this; } public ConfigMapping

put(String key, Object value) { putInternal(value, Key.rel(key)); return this; } /** * Puts the value with the given key as absolute key (that is the key will never be prefixed) * * @param key the absolute key to put the value under * @param value the value to put * @return this mapping */ public ConfigMapping

putAbs(String key, Object value) { putInternal(value, Key.abs(key)); return this; } public ConfigMapping

putAll(ConfigMappable

resource) { return putAll(resource.asConfiguration(primary)); } public ConfigMapping

putAll(String key, ConfigMappable

resource) { return putAll(key, resource.asConfiguration(primary)); } public ConfigMapping

putAll(ConfigMapping config) { config.getAsMap().forEach((key, value) -> putInternal(value, key)); return this; } public ConfigMapping

putAll(String key, ConfigMapping config) { config.getAsMap().forEach((subKey, value) -> putInternal(value, key, subKey)); return this; } public ConfigMapping

putAll(Map props) { props.forEach((key, value) -> putInternal(value, Key.rel(key))); return this; } /** * Puts all values from the given configuration, but sets all keys as absolute * @param config the configuration to put * @return this mapping */ public ConfigMapping

putAllAbs(ConfigMapping config) { config.getAsMap().forEach((key, value) -> putInternal(value, key.asAbs())); return this; } /** * Puts all values from the given configuration, but sets all keys as relative * @param config the configuration to put * @return this mapping */ public ConfigMapping

putAllRel(ConfigMapping config) { config.getAsMap().forEach((key, value) -> putInternal(value, key.asRel())); return this; } @SuppressWarnings("unchecked") public ConfigMapping

putList(String key, List> items, String name) { if (items.isEmpty()) { return this; } record NamedItem(String name, ConfigMappable item) { } var named = IntStream. range(0, items.size()) .mapToObj(i -> new NamedItem(name + i, items.get(i))) .toList(); named.stream() .map(NamedItem::name) .reduce((x, y) -> x + "," + y) .ifPresent(names -> put(key, names)); named.forEach(item -> putAll(key + "." + item.name, (ConfigMappable

) item.item)); return this; } public ConfigMapping

putMap(String key, Map> items) { items.keySet().stream() .reduce((x, y) -> String.join(",")) .ifPresent(names -> put(key, names)); items.forEach((name, item) -> putAll(key + "." + name, item)); return this; } private void putInternal(Object value, Key key) { putInternal(value, null, key); } private void putInternal(Object value, String key, Key subKey) { if (value == null) { return; } var combined = prefix(key, subKey); config.put(combined, String.valueOf(value)); } private Key prefix(String key, Key subKey) { if (subKey.type == KeyType.ABSOLUTE) { return subKey; } var combined = Stream.concat(Stream.of(prefix), Stream.of(key, subKey.name)) .filter(Objects::nonNull) .filter(not(String::isBlank)) .collect(Collectors.joining(".")); return Key.rel(combined); } public String md5Sum() { byte[] digest = new byte[0]; try { var md = MessageDigest.getInstance("MD5"); digest = md.digest(getAsString().getBytes()); } catch (NoSuchAlgorithmException e) { // This will never happen } return toHex(digest); } private String toHex(byte[] bytes) { var hex = new StringBuilder(); for (byte b : bytes) { hex.append(String.format("%02x", b)); } return hex.toString(); } @Override public String toString() { return config.toString(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy