Skip to content

Commit

Permalink
Options now work
Browse files Browse the repository at this point in the history
Signed-off-by: Václav Muzikář <[email protected]>
  • Loading branch information
vmuzikar committed Nov 19, 2024
1 parent 76eb1fe commit 24f7af5
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 38 deletions.
33 changes: 0 additions & 33 deletions quarkus/config-api/src/main/java/org/keycloak/config/Option.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ public class Option<T> {
private final boolean strictExpectedValues;
private final boolean caseInsensitiveExpectedValues;
private final DeprecatedMetadata deprecatedMetadata;
private Pattern optionNameWildcardPattern;

public Option(Class<T> type, String key, OptionCategory category, boolean hidden, boolean buildTime, String description, Optional<T> defaultValue, List<String> expectedValues, boolean strictExpectedValues, boolean caseInsensitiveExpectedValues, DeprecatedMetadata deprecatedMetadata) {
this.type = type;
Expand All @@ -34,14 +33,6 @@ public Option(Class<T> type, String key, OptionCategory category, boolean hidden
this.strictExpectedValues = strictExpectedValues;
this.caseInsensitiveExpectedValues = caseInsensitiveExpectedValues;
this.deprecatedMetadata = deprecatedMetadata;


if (key != null) {
Matcher matcher = WILDCARD_PLACEHOLDER_PATTERN.matcher(key);
if (matcher.find()) {
this.optionNameWildcardPattern = Pattern.compile(matcher.replaceFirst("([-\\\\\\\\.a-zA-Z0-9]+)"));
}
}
}

public Class<T> getType() {
Expand Down Expand Up @@ -94,30 +85,6 @@ public Optional<DeprecatedMetadata> getDeprecatedMetadata() {
return Optional.ofNullable(deprecatedMetadata);
}

public boolean hasWildcard() {
return optionNameWildcardPattern != null;
}

public boolean matchesWildcardOptionName(String name) {
if (!hasWildcard()) {
throw new IllegalStateException("Option does not have wildcard");
}
return optionNameWildcardPattern.matcher(name).matches();
}

// Expects an option name without the "kc." prefix
public Optional<String> getWildcardValue(String option) {
if (!hasWildcard()) {
throw new IllegalStateException("Option does not have wildcard");
}
Matcher matcher = optionNameWildcardPattern.matcher(option);
if (matcher.matches()) {
return Optional.of(matcher.group(1));
} else {
return Optional.empty();
}
}

public Option<T> withRuntimeSpecificDefault(T defaultValue) {
return new Option<T>(
this.type,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,12 @@ private static boolean wasBuildEverRun() {
* @param abstractCommand
*/
public void validateConfig(List<String> cliArgs, AbstractCommand abstractCommand) {
uncrecognizedArgs.removeIf(arg -> {
if (arg.contains("=")) {
arg = arg.substring(0, arg.indexOf("="));
}
return PropertyMappers.getMapper(arg) != null;
});
if (!uncrecognizedArgs.isEmpty()) {
throw new KcUnmatchedArgumentException(abstractCommand.getCommandLine().orElseThrow(), uncrecognizedArgs);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,16 +121,17 @@ 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(Option<?> option) {
if (!option.hasWildcard()) {
PropertyMapper<?> mapper = PropertyMappers.getMapper(NS_KEYCLOAK_PREFIX + option.getKey());

if (!mapper.hasWildcard()) {
throw new IllegalArgumentException("Option does not have wildcard");
}

// this is not optimal
// TODO find an efficient way to get all values that match the wildcard
Map<String, ConfigValue> values = new HashMap<>();
getPropertyNames().forEach(name -> {
String nameWithoutPrefix = name.startsWith(NS_KEYCLOAK_PREFIX) ? name.substring(NS_KEYCLOAK_PREFIX.length()) : name;
option.getWildcardValue(nameWithoutPrefix)
mapper.getWildcardValue(name)
.ifPresent(s -> values.put(s, getConfigValue(name)));
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@
package org.keycloak.quarkus.runtime.configuration.mappers;

import static java.util.Optional.ofNullable;
import static org.keycloak.config.Option.WILDCARD_PLACEHOLDER_PATTERN;
import static org.keycloak.quarkus.runtime.Environment.isRebuild;
import static org.keycloak.quarkus.runtime.cli.Picocli.ARG_PREFIX;
import static org.keycloak.quarkus.runtime.configuration.Configuration.OPTION_PART_SEPARATOR;
import static org.keycloak.quarkus.runtime.configuration.Configuration.OPTION_PART_SEPARATOR_CHAR;
import static org.keycloak.quarkus.runtime.configuration.Configuration.toCliFormat;
import static org.keycloak.quarkus.runtime.configuration.Configuration.toEnvVarFormat;
import static org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX;

import java.util.Iterator;
import java.util.List;
Expand All @@ -31,6 +34,8 @@
import java.util.function.BiFunction;
import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;

import io.smallrye.config.ConfigSourceInterceptorContext;
Expand Down Expand Up @@ -90,6 +95,8 @@ public ConfigValue getConfigValue(String name, ConfigSourceInterceptorContext co
private final String description;
private final BooleanSupplier required;
private final String requiredWhen;
private Pattern optionNameWildcardPattern;
private Pattern envVarNameWildcardPattern;

PropertyMapper(Option<T> option, String to, BooleanSupplier enabled, String enabledWhen,
BiFunction<String, ConfigSourceInterceptorContext, String> mapper,
Expand All @@ -111,6 +118,17 @@ public ConfigValue getConfigValue(String name, ConfigSourceInterceptorContext co
this.validator = validator;
this.description = description;
this.parentMapper = parentMapper;


if (option.getKey() != null) {
Matcher matcher = WILDCARD_PLACEHOLDER_PATTERN.matcher(option.getKey());
if (matcher.find()) {
this.optionNameWildcardPattern = Pattern.compile("(?:" + ARG_PREFIX + "|kc\\.)" + matcher.replaceFirst("([\\\\\\\\.a-zA-Z0-9]+)")); // "--" prefix is to accommodate for CLI options

Matcher envVarMatcher = WILDCARD_PLACEHOLDER_PATTERN.matcher(option.getKey().toUpperCase().replace("-", "_")); // not using toEnvVarFormat because it would process the whole string incl the <...> wildcard
this.envVarNameWildcardPattern = Pattern.compile("KC_" + envVarMatcher.replaceFirst("([_A-Z0-9]+)"));
}
}
}

ConfigValue getConfigValue(ConfigSourceInterceptorContext context) {
Expand Down Expand Up @@ -256,11 +274,35 @@ public Optional<DeprecatedMetadata> getDeprecatedMetadata() {
}

public boolean hasWildcard() {
return option.hasWildcard();
return optionNameWildcardPattern != null && envVarNameWildcardPattern != null;
}

public boolean matchesWildcardOptionName(String name) {
return option.matchesWildcardOptionName(name);
if (!hasWildcard()) {
throw new IllegalStateException("Option does not have wildcard");
}
return optionNameWildcardPattern.matcher(name).matches() || envVarNameWildcardPattern.matcher(name).matches();
}

// Expects an option name without the "kc." prefix
public Optional<String> getWildcardValue(String option) {
if (!hasWildcard()) {
throw new IllegalStateException("Option does not have wildcard");
}

Matcher matcher = optionNameWildcardPattern.matcher(option);
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);
}

return Optional.empty();
}

private ConfigValue transformValue(String name, ConfigValue configValue, ConfigSourceInterceptorContext context, boolean parentValue) {
Expand Down

0 comments on commit 24f7af5

Please sign in to comment.