Skip to content

Commit

Permalink
Incorporate review comments
Browse files Browse the repository at this point in the history
Signed-off-by: Václav Muzikář <[email protected]>
  • Loading branch information
vmuzikar committed Dec 3, 2024
1 parent d1f2019 commit 1f01633
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,13 @@ public void accept(String key, String value) {
if (mapper != null) {
String to = mapper.getTo();

String wildcardValue = mapper.getWildcardValue(key).orElse(null);
String mappedKey = mapper.getMappedKey(key).orElse(null);

if (to != null) {
properties.put(mapper.getTo(wildcardValue), value);
properties.put(mapper.getTo(mappedKey), value);
}

properties.put(mapper.getFrom(wildcardValue), value);
properties.put(mapper.getFrom(mappedKey), value);
}
}
}, ignored -> {});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public static ConfigValue getKcConfigValue(String propertyName) {
* @return a map of config values where the key is the resolved wildcard (e.g. category) and the value is the config value
*/
public static Map<String, ConfigValue> getKcConfigValues(PropertyMapper<?> mapper) {
return mapper.getWildcardValues().stream()
return mapper.getWildcardKeys().stream()
.collect(Collectors.toMap(v -> v, v -> getConfigValue(mapper.getFrom(v))));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ private static Map<String, String> buildProperties() {
properties.put(to, value);
}

properties.put(mapper.getFrom(mapper.getWildcardValue(key).orElse(null)), value);
properties.put(mapper.getFrom(mapper.getMappedEnvVarKey(key).orElse(null)), value);
}
else {
// most probably an SPI but could be also something else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public Iterator<String> iterateNames(ConfigSourceInterceptorContext context) {
disableAdditionalNames.set(true);
try {
mappedWildcardNames = PropertyMappers.getWildcardMappers().stream()
.map(PropertyMapper::getMappedWildcardOptionNames)
.map(PropertyMapper::getToWithWildcards)
.flatMap(Set::stream)
.toList();
} finally {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public static PropertyMapper<?>[] getMappers() {
fromOption(LoggingOptions.LOG_LEVEL_CATEGORY)
.to("quarkus.log.category.\"<categories>\".level")
.validator(LoggingPropertyMappers::validateCategoryLogLevel)
.wildcardValuesTransformer(LoggingPropertyMappers::getConfiguredLogCategories)
.wildcardKeysTransformer(LoggingPropertyMappers::getConfiguredLogCategories)
.transformer((v,c) -> toLevel(v).getName())
.mapFrom(LoggingOptions.LOG_LEVEL, LoggingPropertyMappers::resolveCategoryLogLevelFromParentLogLevelOption) // a fallback to log-level
.paramLabel("level")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
Expand Down Expand Up @@ -82,13 +81,13 @@ public class PropertyMapper<T> {
private Pattern envVarNameWildcardPattern;
private Matcher toWildcardMatcher;
private Pattern toWildcardPattern;
private Function<Set<String>, Set<String>> wildcardValuesTransformer;
private Function<Set<String>, Set<String>> wildcardKeysTransformer;

PropertyMapper(Option<T> option, String to, BooleanSupplier enabled, String enabledWhen,
ValueMapper mapper,
String mapFrom, ValueMapper parentMapper,
String paramLabel, boolean mask, BiConsumer<PropertyMapper<T>, ConfigValue> validator,
String description, BooleanSupplier required, String requiredWhen, Function<Set<String>, Set<String>> wildcardValuesTransformer) {
String description, BooleanSupplier required, String requiredWhen, Function<Set<String>, Set<String>> wildcardKeysTransformer) {
this.option = option;
this.to = to == null ? getFrom() : to;
this.enabled = enabled;
Expand Down Expand Up @@ -127,7 +126,7 @@ public class PropertyMapper<T> {
}
}

this.wildcardValuesTransformer = wildcardValuesTransformer;
this.wildcardKeysTransformer = wildcardKeysTransformer;
}
}

Expand All @@ -136,7 +135,7 @@ ConfigValue getConfigValue(ConfigSourceInterceptorContext context) {
}

ConfigValue getConfigValue(String name, ConfigSourceInterceptorContext context) {
String from = getFrom(getWildcardValue(name).orElse(null));
String from = getFrom(getMappedKey(name).orElse(null));

if (to != null && to.endsWith(OPTION_PART_SEPARATOR)) {
// in case mapping is based on prefixes instead of full property names
Expand Down Expand Up @@ -175,32 +174,32 @@ ConfigValue getConfigValue(String name, ConfigSourceInterceptorContext context)
return context.proceed(name);
}

public Set<String> getWildcardValues() {
public Set<String> getWildcardKeys() {
if (!hasWildcard()) {
return Set.of();
}

// this is not optimal
// TODO find an efficient way to get all values that match the wildcard
Set<String> values = StreamSupport.stream(Configuration.getPropertyNames().spliterator(), false)
.map(n -> getWildcardValue(n, false))
.map(n -> getMappedKey(n, true, false, false))
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toSet());

if (wildcardValuesTransformer != null) {
return wildcardValuesTransformer.apply(values);
if (wildcardKeysTransformer != null) {
return wildcardKeysTransformer.apply(values);
}

return values;
}

public Set<String> getMappedWildcardOptionNames() {
public Set<String> getToWithWildcards() {
if (toWildcardMatcher == null) {
return Set.of();
}

return getWildcardValues().stream()
return getWildcardKeys().stream()
.map(v -> toWildcardMatcher.replaceFirst(v))
.collect(Collectors.toSet());
}
Expand Down Expand Up @@ -241,10 +240,10 @@ public Class<T> getType() {
return this.option.getType();
}

public String getFrom(String wildcardValue) {
public String getFrom(String wildcardKey) {
String from = this.option.getKey();
if (hasWildcard() && wildcardValue != null) {
from = fromWildcardMatcher.replaceFirst(wildcardValue);
if (hasWildcard() && wildcardKey != null) {
from = fromWildcardMatcher.replaceFirst(wildcardKey);
}
return MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX + from;
}
Expand Down Expand Up @@ -287,10 +286,10 @@ public boolean isRunTime() {
return !this.option.isBuildTime();
}

public String getTo(String wildcardValue) {
public String getTo(String wildcardKey) {
String to = this.to;
if (hasWildcard() && wildcardValue != null) {
to = toWildcardMatcher.replaceFirst(wildcardValue);
if (hasWildcard() && wildcardKey != null) {
to = toWildcardMatcher.replaceFirst(wildcardKey);
}
return to;
}
Expand Down Expand Up @@ -340,28 +339,34 @@ public boolean matchesWildcardOptionName(String name) {
}

/**
* Extracts the wildcard value from the given option name.
* Returns a mapped key for the given option name if a relevant mapping is available, or empty otherwise.
* Currently, it only attempts to extract the wildcard key from the given option name.
* E.g. for the option "log-level-<category>" and the option name "log-level-io.quarkus",
* the wildcard value would be "io.quarkus".
*/
private Optional<String> getWildcardValue(String option, boolean includeMappedToOptions) {
private Optional<String> getMappedKey(String originalKey, boolean tryFrom, boolean tryEnvVar, boolean tryTo) {
if (!hasWildcard()) {
return Optional.empty();
}

Matcher matcher = fromWildcardPattern.matcher(option);
if (matcher.matches()) {
return Optional.of(matcher.group(1));
if (tryFrom) {
Matcher matcher = fromWildcardPattern.matcher(originalKey);
if (matcher.matches()) {
return Optional.of(matcher.group(1));
}
}

matcher = envVarNameWildcardPattern.matcher(option);
if (matcher.matches()) {
String value = matcher.group(1);
value = value.toLowerCase().replace("_", "."); // we opiniotatedly convert env var names to CLI format with dots
return Optional.of(value);
if (tryEnvVar) {
Matcher matcher = envVarNameWildcardPattern.matcher(originalKey);
if (matcher.matches()) {
String value = matcher.group(1);
value = value.toLowerCase().replace("_", "."); // we opiniotatedly convert env var names to CLI format with dots
return Optional.of(value);
}
}

if (includeMappedToOptions && toWildcardPattern != null && (matcher = toWildcardPattern.matcher(option)).matches()) {
if (tryTo && toWildcardPattern != null) {
Matcher matcher = toWildcardPattern.matcher(originalKey);
if (matcher.matches()) {
return Optional.of(matcher.group(1));
}
Expand All @@ -370,13 +375,12 @@ private Optional<String> getWildcardValue(String option, boolean includeMappedTo
return Optional.empty();
}

/**
* Extracts the wildcard value from the given option name.
* E.g. for the option "log-level-<category>" and the option name "log-level-io.quarkus",
* the wildcard value would be "io.quarkus".
*/
public Optional<String> getWildcardValue(String option) {
return getWildcardValue(option, true);
public Optional<String> getMappedKey(String originalKey) {
return getMappedKey(originalKey, true, false, true);
}

public Optional<String> getMappedEnvVarKey(String originalKey) {
return getMappedKey(originalKey, false, true, false);
}

private ConfigValue transformValue(String name, ConfigValue configValue, ConfigSourceInterceptorContext context, boolean parentValue) {
Expand All @@ -386,7 +390,7 @@ private ConfigValue transformValue(String name, ConfigValue configValue, ConfigS
boolean mapped = false;
var theMapper = parentValue ? this.parentMapper : this.mapper;
if (theMapper != null && (!name.equals(getFrom()) || parentValue)) {
String nameForMapper = hasWildcard() ? getWildcardValue(name).orElse(name) : name;
String nameForMapper = getMappedKey(name).orElse(name);
mappedValue = theMapper.map(nameForMapper, value, context);
mapped = true;
}
Expand Down Expand Up @@ -466,7 +470,7 @@ public static class Builder<T> {
private String description;
private BooleanSupplier isRequired = () -> false;
private String requiredWhen = "";
private Function<Set<String>, Set<String>> wildcardValuesTransformer;
private Function<Set<String>, Set<String>> wildcardKeysTransformer;

public Builder(Option<T> option) {
this.option = option;
Expand Down Expand Up @@ -599,16 +603,16 @@ public Builder<T> addValidateEnabled(BooleanSupplier isEnabled, String enabledWh
return this;
}

public Builder<T> wildcardValuesTransformer(Function<Set<String>, Set<String>> wildcardValuesTransformer) {
this.wildcardValuesTransformer = wildcardValuesTransformer;
public Builder<T> wildcardKeysTransformer(Function<Set<String>, Set<String>> wildcardValuesTransformer) {
this.wildcardKeysTransformer = wildcardValuesTransformer;
return this;
}

public PropertyMapper<T> build() {
if (paramLabel == null && Boolean.class.equals(option.getType())) {
paramLabel = Boolean.TRUE + "|" + Boolean.FALSE;
}
return new PropertyMapper<>(option, to, isEnabled, enabledWhen, mapper, mapFrom, parentMapper, paramLabel, isMasked, validator, description, isRequired, requiredWhen, wildcardValuesTransformer);
return new PropertyMapper<>(option, to, isEnabled, enabledWhen, mapper, mapFrom, parentMapper, paramLabel, isMasked, validator, description, isRequired, requiredWhen, wildcardKeysTransformer);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -557,4 +557,10 @@ public void testWildcardOptionFromConfigFile() {
SmallRyeConfig config = createConfig();
assertEquals("DEBUG", config.getConfigValue("quarkus.log.category.\"io.k8s\".level").getValue());
}

@Test
public void testWildcardPropertiesDontMatchEnvVarsFormat() {
SmallRyeConfig config = createConfig();
assertEquals("INFO", config.getConfigValue("quarkus.log.category.\"io.quarkus\".level").getValue());
}
}
1 change: 1 addition & 0 deletions quarkus/runtime/src/test/resources/META-INF/keycloak.conf
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ spi-hostname-default-frontend-url = ${keycloak.frontendUrl:http://filepropdefaul
%user-profile.spi-hostname-default-frontend-url = http://filepropprofile.unittest
log-level=${SOME_LOG_LEVEL:info}
log-level-io.k8s=${SOME_CATEGORY_LOG_LEVEL}
KC_LOG_LEVEL_IO_QUARKUS=trace
config-keystore=src/test/resources/keystore
config-keystore-password=secret

Expand Down

0 comments on commit 1f01633

Please sign in to comment.