fix: consolidating config logic

closes: #42000

Signed-off-by: Steve Hawkins <shawkins@redhat.com>
This commit is contained in:
Steve Hawkins 2025-11-06 08:24:34 -05:00 committed by Pedro Igor
parent 3099cc2294
commit 25186278fc
5 changed files with 122 additions and 230 deletions

View File

@ -20,7 +20,9 @@ package org.keycloak;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import org.keycloak.common.util.StringPropertyReplacer;
import org.keycloak.common.util.StringPropertyReplacer.PropertyResolver;
@ -122,7 +124,7 @@ public class Config {
}
public static class SystemPropertiesScope implements Scope {
public static class SystemPropertiesScope extends AbstractScope {
protected String prefix;
@ -132,66 +134,10 @@ public class Config {
@Override
public String get(String key) {
return get(key, null);
}
@Override
public String get(String key, String defaultValue) {
String v = System.getProperty(prefix + key, defaultValue);
String v = System.getProperty(prefix + key, null);
return v != null && !v.isEmpty() ? v : null;
}
@Override
public String[] getArray(String key) {
String value = get(key);
if (value != null) {
String[] a = value.split(",");
for (int i = 0; i < a.length; i++) {
a[i] = a[i].trim();
}
return a;
} else {
return null;
}
}
@Override
public Integer getInt(String key) {
return getInt(key, null);
}
@Override
public Integer getInt(String key, Integer defaultValue) {
String v = get(key, null);
return v != null ? Integer.valueOf(v) : defaultValue;
}
@Override
public Long getLong(String key) {
return getLong(key, null);
}
@Override
public Long getLong(String key, Long defaultValue) {
String v = get(key, null);
return v != null ? Long.valueOf(v) : defaultValue;
}
@Override
public Boolean getBoolean(String key) {
return getBoolean(key, null);
}
@Override
public Boolean getBoolean(String key, Boolean defaultValue) {
String v = get(key, null);
if (v != null) {
return Boolean.valueOf(v);
} else {
return defaultValue;
}
}
@Override
public Scope scope(String... scope) {
StringBuilder sb = new StringBuilder();
@ -226,15 +172,21 @@ public class Config {
String[] getArray(String key);
Integer getInt(String key);
default Integer getInt(String key) {
return getInt(key, null);
}
Integer getInt(String key, Integer defaultValue);
Long getLong(String key);
default Long getLong(String key) {
return getLong(key, null);
}
Long getLong(String key, Long defaultValue);
Boolean getBoolean(String key);
default Boolean getBoolean(String key) {
return getBoolean(key, null);
}
Boolean getBoolean(String key, Boolean defaultValue);
@ -257,4 +209,36 @@ public class Config {
*/
Scope root();
}
public static abstract class AbstractScope implements Scope {
@Override
public String get(String key, String defaultValue) {
return getValue(key, Function.identity(), String.class, defaultValue);
}
@Override
public Integer getInt(String key, Integer defaultValue) {
return getValue(key, Integer::valueOf, Integer.class, defaultValue);
}
@Override
public String[] getArray(String key) {
return getValue(key, s -> s.split("\\s*,\\s*"), String[].class, null);
}
@Override
public Long getLong(String key, Long defaultValue) {
return getValue(key, Long::valueOf, Long.class, defaultValue);
}
@Override
public Boolean getBoolean(String key, Boolean defaultValue) {
return getValue(key, Boolean::valueOf, Boolean.class, defaultValue);
}
protected <T> T getValue(String key, Function<String, T> conversion, Class<T> type, T defaultValue) {
return Optional.ofNullable(get(key)).map(conversion).orElse(defaultValue);
}
}
}

View File

@ -19,10 +19,12 @@ package org.keycloak.quarkus.runtime.configuration;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import org.keycloak.Config;
import org.keycloak.Config.AbstractScope;
import org.keycloak.Config.Scope;
import io.smallrye.config.SmallRyeConfig;
@ -64,7 +66,7 @@ public class MicroProfileConfigProvider implements Config.ConfigProvider {
return new MicroProfileScope(SPI_PREFIX, scope);
}
public class MicroProfileScope implements Config.Scope {
public class MicroProfileScope extends AbstractScope {
private final String prefix;
private final String separatorPrefix;
@ -80,47 +82,7 @@ public class MicroProfileConfigProvider implements Config.ConfigProvider {
@Override
public String get(String key) {
return getValue(key, String.class, null);
}
@Override
public String get(String key, String defaultValue) {
return getValue(key, String.class, defaultValue);
}
@Override
public String[] getArray(String key) {
return getValue(key, String[].class, null);
}
@Override
public Integer getInt(String key) {
return getValue(key, Integer.class, null);
}
@Override
public Integer getInt(String key, Integer defaultValue) {
return getValue(key, Integer.class, defaultValue);
}
@Override
public Long getLong(String key) {
return getValue(key, Long.class, null);
}
@Override
public Long getLong(String key, Long defaultValue) {
return getValue(key, Long.class, defaultValue);
}
@Override
public Boolean getBoolean(String key) {
return getValue(key, Boolean.class, null);
}
@Override
public Boolean getBoolean(String key, Boolean defaultValue) {
return getValue(key, Boolean.class, defaultValue);
return get(key, null);
}
@Override
@ -135,7 +97,8 @@ public class MicroProfileConfigProvider implements Config.ConfigProvider {
.collect(Collectors.toSet());
}
private <T> T getValue(String key, Class<T> clazz, T defaultValue) {
@Override
protected <T> T getValue(String key, Function<String, T> conversion, Class<T> clazz, T defaultValue) {
if (NS_KEYCLOAK_PREFIX.equals(separatorPrefix)) {
return config.getOptionalValue(separatorPrefix.concat(key), clazz).orElse(defaultValue);
}

View File

@ -18,13 +18,14 @@ package org.keycloak.component;
import java.util.Set;
import org.keycloak.Config.AbstractScope;
import org.keycloak.Config.Scope;
/**
*
* @author hmlnarik
*/
public class ComponentModelScope implements Scope {
public class ComponentModelScope extends AbstractScope {
private final Scope origScope;
private final ComponentModel componentConfig;
@ -62,52 +63,8 @@ public class ComponentModelScope implements Scope {
@Override
public String get(String key) {
return get(key, null);
}
@Override
public String get(String key, String defaultValue) {
final String res = componentConfig.get(prefix + key, null);
return (res == null) ? origScope.get(key, defaultValue) : res;
}
@Override
public String[] getArray(String key) {
final String[] res = get(prefix + key, "").split("\\s*,\\s*");
return (res == null) ? origScope.getArray(key) : res;
}
@Override
public Integer getInt(String key) {
return getInt(key, null);
}
@Override
public Integer getInt(String key, Integer defaultValue) {
final String res = componentConfig.get(prefix + key, null);
return (res == null) ? origScope.getInt(key, defaultValue) : Integer.valueOf(res);
}
@Override
public Long getLong(String key) {
return getLong(key, null);
}
@Override
public Long getLong(String key, Long defaultValue) {
final String res = componentConfig.get(prefix + key, null);
return (res == null) ? origScope.getLong(key, defaultValue) : Long.valueOf(res);
}
@Override
public Boolean getBoolean(String key) {
return getBoolean(key, null);
}
@Override
public Boolean getBoolean(String key, Boolean defaultValue) {
final String res = componentConfig.get(prefix + key, null);
return (res == null) ? origScope.getBoolean(key, defaultValue) : Boolean.valueOf(res);
return (res == null) ? origScope.get(key) : res;
}
@Override

View File

@ -0,0 +1,60 @@
package org.keycloak.component;
import java.util.Set;
import org.keycloak.Config.AbstractScope;
import org.keycloak.Config.Scope;
import org.junit.Test;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
public class ComponentModelScopeTest {
@Test public void testGetters() {
Scope scope = new AbstractScope() {
@Override
public Scope scope(String... scope) {
return null;
}
@Override
public Scope root() {
return null;
}
@Override
public Set<String> getPropertyNames() {
return null;
}
@Override
public String get(String key) {
if (key.equals("base")) {
return "x, y";
}
if (key.equals("int")) {
return "1";
}
return null;
}
};
ComponentModel model = new ComponentModel();
model.put("component", "a");
model.put("string", "abc");
ComponentModelScope componentModelScope = new ComponentModelScope(scope, model);
assertArrayEquals(new String[] {"x", "y"}, componentModelScope.getArray("base"));
assertArrayEquals(new String[] {"a"}, componentModelScope.getArray("component"));
assertEquals(Integer.valueOf(1), componentModelScope.getInt("int"));
assertEquals(Long.valueOf(1), componentModelScope.getLong("int"));
assertEquals("abc", componentModelScope.get("string", "default"));
assertEquals(null, componentModelScope.get("doesn't exist"));
}
}

View File

@ -17,9 +17,11 @@
package org.keycloak.utils;
import java.util.Optional;
import java.util.Set;
import org.keycloak.Config;
import org.keycloak.Config.AbstractScope;
import org.keycloak.Config.Scope;
import org.keycloak.common.util.StringPropertyReplacer;
import org.keycloak.common.util.SystemEnvProperties;
@ -73,7 +75,7 @@ public class JsonConfigProvider implements Config.ConfigProvider {
return StringPropertyReplacer.replaceProperties(value, SystemEnvProperties.UNFILTERED::getProperty);
}
public class JsonScope implements Config.Scope {
public class JsonScope extends AbstractScope {
private JsonNode config;
@ -83,20 +85,12 @@ public class JsonConfigProvider implements Config.ConfigProvider {
@Override
public String get(String key) {
return get(key, null);
return Optional.ofNullable(config).map(c -> c.get(key)).map(this::toString).orElse(null);
}
@Override
public String get(String key, String defaultValue) {
if (config == null) {
return defaultValue;
}
JsonNode n = config.get(key);
if (n == null) {
return defaultValue;
}
private String toString(JsonNode n) {
String v = replaceProperties(n.textValue());
return !v.isEmpty() ? v : defaultValue;
return !v.isEmpty() ? v : null;
}
@Override
@ -111,77 +105,11 @@ public class JsonConfigProvider implements Config.ConfigProvider {
} else if (n.isArray()) {
String[] a = new String[n.size()];
for (int i = 0; i < a.length; i++) {
a[i] = replaceProperties(n.get(i).textValue());
a[i] = toString(n.get(i));
}
return a;
} else {
return new String[] { replaceProperties(n.textValue()) };
}
}
@Override
public Integer getInt(String key) {
return getInt(key, null);
}
@Override
public Integer getInt(String key, Integer defaultValue) {
if (config == null) {
return defaultValue;
}
JsonNode n = config.get(key);
if (n == null) {
return defaultValue;
}
if (n.isTextual()) {
String v = replaceProperties(n.textValue());
return !v.isEmpty() ? Integer.valueOf(v) : defaultValue;
} else {
return n.intValue();
}
}
@Override
public Long getLong(String key) {
return getLong(key, null);
}
@Override
public Long getLong(String key, Long defaultValue) {
if (config == null) {
return defaultValue;
}
JsonNode n = config.get(key);
if (n == null) {
return defaultValue;
}
if (n.isTextual()) {
String v = replaceProperties(n.textValue());
return !v.isEmpty() ? Long.valueOf(v) : defaultValue;
} else {
return n.longValue();
}
}
@Override
public Boolean getBoolean(String key) {
return getBoolean(key, null);
}
@Override
public Boolean getBoolean(String key, Boolean defaultValue) {
if (config == null) {
return defaultValue;
}
JsonNode n = config.get(key);
if (n == null) {
return defaultValue;
}
if (n.isTextual()) {
String v = replaceProperties(n.textValue());
return !v.isEmpty() ? Boolean.valueOf(v) : defaultValue;
} else {
return n.booleanValue();
return new String[] { toString(n) };
}
}