task: refinements to propertymapping

closes: #32724

Signed-off-by: Steve Hawkins <shawkins@redhat.com>
This commit is contained in:
Steve Hawkins 2024-10-04 08:56:49 -04:00 committed by Pedro Igor
parent a276b3bb3d
commit 14e44f7d8c
14 changed files with 159 additions and 262 deletions

View file

@ -1,6 +1,5 @@
package org.keycloak.quarkus.runtime.configuration.mappers; package org.keycloak.quarkus.runtime.configuration.mappers;
import static java.util.Optional.of;
import static org.keycloak.quarkus.runtime.configuration.Configuration.getOptionalKcValue; import static org.keycloak.quarkus.runtime.configuration.Configuration.getOptionalKcValue;
import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption; import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption;
@ -38,7 +37,14 @@ final class CachingPropertyMappers {
.paramLabel("stack") .paramLabel("stack")
.build(), .build(),
fromOption(CachingOptions.CACHE_CONFIG_FILE) fromOption(CachingOptions.CACHE_CONFIG_FILE)
.mapFrom("cache") .mapFrom(CachingOptions.CACHE, (value, context) -> {
if (CachingOptions.Mechanism.local.name().equals(value)) {
return "cache-local.xml";
} else if (CachingOptions.Mechanism.ispn.name().equals(value)) {
return "cache-ispn.xml";
} else
return null;
})
.to("kc.spi-connections-infinispan-quarkus-config-file") .to("kc.spi-connections-infinispan-quarkus-config-file")
.transformer(CachingPropertyMappers::resolveConfigFile) .transformer(CachingPropertyMappers::resolveConfigFile)
.paramLabel("file") .paramLabel("file")
@ -100,13 +106,7 @@ final class CachingPropertyMappers {
return getOptionalKcValue(CachingOptions.CACHE_REMOTE_HOST_PROPERTY).isPresent(); return getOptionalKcValue(CachingOptions.CACHE_REMOTE_HOST_PROPERTY).isPresent();
} }
private static Optional<String> resolveConfigFile(Optional<String> value, ConfigSourceInterceptorContext context) { private static String resolveConfigFile(String value, ConfigSourceInterceptorContext context) {
if ("local".equals(value.get())) {
return of("cache-local.xml");
} else if ("ispn".equals(value.get())) {
return of("cache-ispn.xml");
}
String pathPrefix; String pathPrefix;
String homeDir = Environment.getHomeDir(); String homeDir = Environment.getHomeDir();
@ -116,7 +116,7 @@ final class CachingPropertyMappers {
pathPrefix = homeDir + File.separator + "conf" + File.separator; pathPrefix = homeDir + File.separator + "conf" + File.separator;
} }
return of(pathPrefix + value.get()); return pathPrefix + value;
} }
private static String getDefaultKeystorePathValue() { private static String getDefaultKeystorePathValue() {

View file

@ -5,8 +5,6 @@ import org.keycloak.config.ClassLoaderOptions;
import org.keycloak.quarkus.runtime.Environment; import org.keycloak.quarkus.runtime.Environment;
import org.keycloak.quarkus.runtime.configuration.IgnoredArtifacts; import org.keycloak.quarkus.runtime.configuration.IgnoredArtifacts;
import java.util.Optional;
import static org.keycloak.config.ClassLoaderOptions.QUARKUS_REMOVED_ARTIFACTS_PROPERTY; import static org.keycloak.config.ClassLoaderOptions.QUARKUS_REMOVED_ARTIFACTS_PROPERTY;
import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption; import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption;
@ -23,9 +21,9 @@ final class ClassLoaderPropertyMappers {
}; };
} }
private static Optional<String> resolveIgnoredArtifacts(Optional<String> value, ConfigSourceInterceptorContext context) { private static String resolveIgnoredArtifacts(String value, ConfigSourceInterceptorContext context) {
if (Environment.isRebuildCheck() || Environment.isRebuild()) { if (Environment.isRebuildCheck() || Environment.isRebuild()) {
return Optional.of(String.join(",", IgnoredArtifacts.getDefaultIgnoredArtifacts())); return String.join(",", IgnoredArtifacts.getDefaultIgnoredArtifacts());
} }
return value; return value;

View file

@ -6,7 +6,6 @@ import org.keycloak.config.ConfigKeystoreOptions;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Optional;
import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption; import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption;
@ -38,7 +37,7 @@ final class ConfigKeystorePropertyMappers {
}; };
} }
private static Optional<String> validatePath(Optional<String> option, ConfigSourceInterceptorContext context) { private static String validatePath(String option, ConfigSourceInterceptorContext context) {
ConfigValue path = context.proceed(SMALLRYE_KEYSTORE_PATH); ConfigValue path = context.proceed(SMALLRYE_KEYSTORE_PATH);
boolean isPasswordDefined = context.proceed(SMALLRYE_KEYSTORE_PASSWORD) != null; boolean isPasswordDefined = context.proceed(SMALLRYE_KEYSTORE_PASSWORD) != null;
@ -55,10 +54,10 @@ final class ConfigKeystorePropertyMappers {
throw new IllegalArgumentException("config-keystore path does not exist: " + realPath); throw new IllegalArgumentException("config-keystore path does not exist: " + realPath);
} }
return Optional.of(realPath.toUri().toString()); return realPath.toUri().toString();
} }
private static Optional<String> validatePassword(Optional<String> option, ConfigSourceInterceptorContext context) { private static String validatePassword(String option, ConfigSourceInterceptorContext context) {
boolean isPasswordDefined = context.proceed(SMALLRYE_KEYSTORE_PASSWORD).getValue() != null; boolean isPasswordDefined = context.proceed(SMALLRYE_KEYSTORE_PASSWORD).getValue() != null;
boolean isPathDefined = context.proceed(SMALLRYE_KEYSTORE_PATH) != null; boolean isPathDefined = context.proceed(SMALLRYE_KEYSTORE_PATH) != null;

View file

@ -7,9 +7,6 @@ import org.keycloak.config.DatabaseOptions;
import org.keycloak.config.database.Database; import org.keycloak.config.database.Database;
import org.keycloak.quarkus.runtime.configuration.Configuration; import org.keycloak.quarkus.runtime.configuration.Configuration;
import java.util.Optional;
import static java.util.Optional.of;
import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption; import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption;
final class DatabasePropertyMappers { final class DatabasePropertyMappers {
@ -19,13 +16,11 @@ final class DatabasePropertyMappers {
public static PropertyMapper<?>[] getDatabasePropertyMappers() { public static PropertyMapper<?>[] getDatabasePropertyMappers() {
return new PropertyMapper[] { return new PropertyMapper[] {
fromOption(DatabaseOptions.DB_DIALECT) fromOption(DatabaseOptions.DB_DIALECT)
.mapFrom("db") .mapFrom(DatabaseOptions.DB, DatabasePropertyMappers::transformDialect)
.transformer(DatabasePropertyMappers::transformDialect)
.build(), .build(),
fromOption(DatabaseOptions.DB_DRIVER) fromOption(DatabaseOptions.DB_DRIVER)
.mapFrom("db") .mapFrom(DatabaseOptions.DB, DatabasePropertyMappers::getXaOrNonXaDriver)
.to("quarkus.datasource.jdbc.driver") .to("quarkus.datasource.jdbc.driver")
.transformer(DatabasePropertyMappers::getXaOrNonXaDriver)
.paramLabel("driver") .paramLabel("driver")
.build(), .build(),
fromOption(DatabaseOptions.DB) fromOption(DatabaseOptions.DB)
@ -35,8 +30,7 @@ final class DatabasePropertyMappers {
.build(), .build(),
fromOption(DatabaseOptions.DB_URL) fromOption(DatabaseOptions.DB_URL)
.to("quarkus.datasource.jdbc.url") .to("quarkus.datasource.jdbc.url")
.mapFrom("db") .mapFrom(DatabaseOptions.DB, DatabasePropertyMappers::getDatabaseUrl)
.transformer(DatabasePropertyMappers::getDatabaseUrl)
.paramLabel("jdbc-url") .paramLabel("jdbc-url")
.build(), .build(),
fromOption(DatabaseOptions.DB_URL_HOST) fromOption(DatabaseOptions.DB_URL_HOST)
@ -84,44 +78,32 @@ final class DatabasePropertyMappers {
}; };
} }
private static Optional<String> getDatabaseUrl(Optional<String> value, ConfigSourceInterceptorContext c) { private static String getDatabaseUrl(String value, ConfigSourceInterceptorContext c) {
Optional<String> url = Database.getDefaultUrl(value.get()); return Database.getDefaultUrl(value).orElse(null);
if (url.isPresent()) {
return url;
} }
return value; private static String getXaOrNonXaDriver(String value, ConfigSourceInterceptorContext context) {
}
private static Optional<String> getXaOrNonXaDriver(Optional<String> value, ConfigSourceInterceptorContext context) {
ConfigValue xaEnabledConfigValue = context.proceed("kc.transaction-xa-enabled"); ConfigValue xaEnabledConfigValue = context.proceed("kc.transaction-xa-enabled");
boolean isXaEnabled = xaEnabledConfigValue != null && Boolean.parseBoolean(xaEnabledConfigValue.getValue()); boolean isXaEnabled = xaEnabledConfigValue != null && Boolean.parseBoolean(xaEnabledConfigValue.getValue());
Optional<String> driver = Database.getDriver(value.get(), isXaEnabled); return Database.getDriver(value, isXaEnabled).orElse(null);
}
if (driver.isPresent()) { private static String toDatabaseKind(String db, ConfigSourceInterceptorContext context) {
return driver; return Database.getDatabaseKind(db).orElse(null);
}
private static String resolveUsername(String value, ConfigSourceInterceptorContext context) {
if (isDevModeDatabase(context)) {
return "sa";
} }
return value; return value;
} }
private static Optional<String> toDatabaseKind(Optional<String> db, ConfigSourceInterceptorContext context) { private static String resolvePassword(String value, ConfigSourceInterceptorContext context) {
return Database.getDatabaseKind(db.get());
}
private static Optional<String> resolveUsername(Optional<String> value, ConfigSourceInterceptorContext context) {
if (isDevModeDatabase(context)) { if (isDevModeDatabase(context)) {
return of("sa"); return "password";
}
return value;
}
private static Optional<String> resolvePassword(Optional<String> value, ConfigSourceInterceptorContext context) {
if (isDevModeDatabase(context)) {
return of("password");
} }
return value; return value;
@ -132,20 +114,8 @@ final class DatabasePropertyMappers {
return Database.getDatabaseKind(db).get().equals(DatabaseKind.H2); return Database.getDatabaseKind(db).get().equals(DatabaseKind.H2);
} }
private static Optional<String> transformDialect(Optional<String> db, ConfigSourceInterceptorContext context) { private static String transformDialect(String db, ConfigSourceInterceptorContext context) {
Optional<String> databaseKind = Database.getDatabaseKind(db.get()); return Database.getDialect(db).orElse(null);
if (databaseKind.isEmpty()) {
return db;
}
Optional<String> dialect = Database.getDialect(db.get());
if (dialect.isPresent()) {
return dialect;
}
return Database.getDialect("dev-file");
} }
} }

View file

@ -27,8 +27,6 @@ import org.keycloak.exportimport.UsersExportStrategy;
import org.keycloak.quarkus.runtime.cli.PropertyException; import org.keycloak.quarkus.runtime.cli.PropertyException;
import org.keycloak.quarkus.runtime.configuration.Configuration; import org.keycloak.quarkus.runtime.configuration.Configuration;
import java.util.Optional;
import static org.keycloak.exportimport.ExportImportConfig.PROVIDER; import static org.keycloak.exportimport.ExportImportConfig.PROVIDER;
import static org.keycloak.quarkus.runtime.configuration.Configuration.getOptionalValue; import static org.keycloak.quarkus.runtime.configuration.Configuration.getOptionalValue;
import static org.keycloak.quarkus.runtime.configuration.Configuration.isBlank; import static org.keycloak.quarkus.runtime.configuration.Configuration.isBlank;
@ -117,10 +115,10 @@ public final class ExportPropertyMappers {
.isPresent(); .isPresent();
} }
private static Optional<String> transformExporter(Optional<String> option, ConfigSourceInterceptorContext context) { private static String transformExporter(String option, ConfigSourceInterceptorContext context) {
ConfigValue exporter = context.proceed(EXPORTER_PROPERTY); ConfigValue exporter = context.proceed(EXPORTER_PROPERTY);
if (exporter != null) { if (exporter != null) {
return Optional.of(exporter.getValue()); return exporter.getValue();
} }
var file = Configuration.getOptionalValue("kc.spi-export-single-file-file").map(f -> SINGLE_FILE); var file = Configuration.getOptionalValue("kc.spi-export-single-file-file").map(f -> SINGLE_FILE);
@ -131,7 +129,7 @@ public final class ExportPropertyMappers {
// Only one option can be specified // Only one option can be specified
boolean xor = file.isPresent() ^ dir.isPresent(); boolean xor = file.isPresent() ^ dir.isPresent();
return xor ? file.or(() -> dir) : Optional.empty(); return xor ? file.or(() -> dir).get() : null;
} }
} }

View file

@ -18,8 +18,6 @@ import java.nio.file.Paths;
import java.util.Optional; import java.util.Optional;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import static java.util.Optional.empty;
import static java.util.Optional.of;
import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption; import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption;
public final class HttpPropertyMappers { public final class HttpPropertyMappers {
@ -69,7 +67,7 @@ public final class HttpPropertyMappers {
fromOption(HttpOptions.HTTPS_CERTIFICATES_RELOAD_PERIOD) fromOption(HttpOptions.HTTPS_CERTIFICATES_RELOAD_PERIOD)
.to("quarkus.http.ssl.certificate.reload-period") .to("quarkus.http.ssl.certificate.reload-period")
// -1 means no reload // -1 means no reload
.transformer((value, context) -> "-1".equals(value.get()) ? null : value) .transformer((value, context) -> "-1".equals(value) ? null : value)
.paramLabel("reload period") .paramLabel("reload period")
.build(), .build(),
fromOption(HttpOptions.HTTPS_CERTIFICATE_FILE) fromOption(HttpOptions.HTTPS_CERTIFICATE_FILE)
@ -94,8 +92,7 @@ public final class HttpPropertyMappers {
.build(), .build(),
fromOption(HttpOptions.HTTPS_KEY_STORE_TYPE) fromOption(HttpOptions.HTTPS_KEY_STORE_TYPE)
.to("quarkus.http.ssl.certificate.key-store-file-type") .to("quarkus.http.ssl.certificate.key-store-file-type")
.mapFrom(SecurityOptions.FIPS_MODE.getKey()) .mapFrom(SecurityOptions.FIPS_MODE, HttpPropertyMappers::resolveKeyStoreType)
.transformer(HttpPropertyMappers::resolveKeyStoreType)
.paramLabel("type") .paramLabel("type")
.build(), .build(),
fromOption(HttpOptions.HTTPS_TRUST_STORE_FILE) fromOption(HttpOptions.HTTPS_TRUST_STORE_FILE)
@ -109,8 +106,7 @@ public final class HttpPropertyMappers {
.build(), .build(),
fromOption(HttpOptions.HTTPS_TRUST_STORE_TYPE) fromOption(HttpOptions.HTTPS_TRUST_STORE_TYPE)
.to("quarkus.http.ssl.certificate.trust-store-file-type") .to("quarkus.http.ssl.certificate.trust-store-file-type")
.mapFrom(SecurityOptions.FIPS_MODE.getKey()) .mapFrom(SecurityOptions.FIPS_MODE, HttpPropertyMappers::resolveKeyStoreType)
.transformer(HttpPropertyMappers::resolveKeyStoreType)
.paramLabel("type") .paramLabel("type")
.build(), .build(),
fromOption(HttpOptions.HTTP_MAX_QUEUED_REQUESTS) fromOption(HttpOptions.HTTP_MAX_QUEUED_REQUESTS)
@ -133,7 +129,7 @@ public final class HttpPropertyMappers {
} }
public static void validateConfig() { public static void validateConfig() {
boolean enabled = isHttpEnabled(Configuration.getOptionalKcValue(HttpOptions.HTTP_ENABLED.getKey())); boolean enabled = isHttpEnabled(Configuration.getOptionalKcValue(HttpOptions.HTTP_ENABLED.getKey()).orElse(null));
boolean trustStoreFile = Configuration.getOptionalKcValue(HttpOptions.HTTPS_TRUST_STORE_FILE.getKey()).isPresent(); boolean trustStoreFile = Configuration.getOptionalKcValue(HttpOptions.HTTPS_TRUST_STORE_FILE.getKey()).isPresent();
boolean keyStoreFile = Configuration.getOptionalKcValue(HttpOptions.HTTPS_KEY_STORE_FILE.getKey()).isPresent(); boolean keyStoreFile = Configuration.getOptionalKcValue(HttpOptions.HTTPS_KEY_STORE_FILE.getKey()).isPresent();
@ -194,23 +190,19 @@ public final class HttpPropertyMappers {
} }
} }
private static BiFunction<Optional<String>, ConfigSourceInterceptorContext, Optional<String>> validatePath(String key) { private static BiFunction<String, ConfigSourceInterceptorContext, String> validatePath(String key) {
return (value, context) -> Environment.isWindows() ? value.filter(v -> v.equals(context.proceed(key).getValue())).map(p -> p.replace("\\", "/")) : value; return (value, context) -> Environment.isWindows() && value != null && value.equals(context.proceed(key).getValue()) ? value.replace("\\", "/") : value;
} }
private static Optional<String> getHttpEnabledTransformer(Optional<String> value, ConfigSourceInterceptorContext context) { private static String getHttpEnabledTransformer(String value, ConfigSourceInterceptorContext context) {
return of(isHttpEnabled(value) ? "enabled" : "disabled"); return isHttpEnabled(value) ? "enabled" : "disabled";
} }
private static boolean isHttpEnabled(Optional<String> value) { private static boolean isHttpEnabled(String value) {
boolean enabled = Boolean.parseBoolean(value.get()); if (Environment.isDevMode() || Environment.isNonServerMode()) {
Optional<String> proxy = Configuration.getOptionalKcValue("proxy"); return true;
if (Environment.isDevMode() || Environment.isNonServerMode()
|| ("edge".equalsIgnoreCase(proxy.orElse("")))) {
enabled = true;
} }
return enabled; return Boolean.parseBoolean(value);
} }
private static File getDefaultKeystorePathValue() { private static File getDefaultKeystorePathValue() {
@ -227,24 +219,18 @@ public final class HttpPropertyMappers {
return null; return null;
} }
private static Optional<String> resolveKeyStoreType(Optional<String> value, private static String resolveKeyStoreType(String value,
ConfigSourceInterceptorContext configSourceInterceptorContext) { ConfigSourceInterceptorContext configSourceInterceptorContext) {
if (value.isPresent()) { if (FipsMode.STRICT.toString().equals(value)) {
try { return "BCFKS";
if (FipsMode.valueOfOption(value.get()).equals(FipsMode.STRICT)) {
return of("BCFKS");
} }
return empty(); return null;
} catch (IllegalArgumentException ignore) {
}
}
return value;
} }
private static Optional<String> resolveMaxThreads(Optional<String> value, private static String resolveMaxThreads(String value,
ConfigSourceInterceptorContext configSourceInterceptorContext) { ConfigSourceInterceptorContext configSourceInterceptorContext) {
if (value.isEmpty()) { if (value == null) {
return of(String.valueOf(Math.max(MIN_MAX_THREADS, 4 * Runtime.getRuntime().availableProcessors()))); return String.valueOf(Math.max(MIN_MAX_THREADS, 4 * Runtime.getRuntime().availableProcessors()));
} }
return value; return value;
} }

View file

@ -26,8 +26,6 @@ import org.keycloak.config.OptionCategory;
import org.keycloak.exportimport.Strategy; import org.keycloak.exportimport.Strategy;
import org.keycloak.quarkus.runtime.cli.PropertyException; import org.keycloak.quarkus.runtime.cli.PropertyException;
import java.util.Optional;
import static org.keycloak.exportimport.ExportImportConfig.PROVIDER; import static org.keycloak.exportimport.ExportImportConfig.PROVIDER;
import static org.keycloak.quarkus.runtime.configuration.Configuration.getOptionalValue; import static org.keycloak.quarkus.runtime.configuration.Configuration.getOptionalValue;
import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption; import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption;
@ -95,18 +93,18 @@ public final class ImportPropertyMappers {
.isPresent(); .isPresent();
} }
private static Optional<String> transformOverride(Optional<String> option, ConfigSourceInterceptorContext context) { private static String transformOverride(String option, ConfigSourceInterceptorContext context) {
if (option.isPresent() && Boolean.parseBoolean(option.get())) { if (Boolean.parseBoolean(option)) {
return Optional.of(Strategy.OVERWRITE_EXISTING.name()); return Strategy.OVERWRITE_EXISTING.name();
} else { } else {
return Optional.of(Strategy.IGNORE_EXISTING.name()); return Strategy.IGNORE_EXISTING.name();
} }
} }
private static Optional<String> transformImporter(Optional<String> option, ConfigSourceInterceptorContext context) { private static String transformImporter(String option, ConfigSourceInterceptorContext context) {
ConfigValue importer = context.proceed(IMPORTER_PROPERTY); ConfigValue importer = context.proceed(IMPORTER_PROPERTY);
if (importer != null) { if (importer != null) {
return Optional.of(importer.getValue()); return importer.getValue();
} }
var file = getOptionalValue("kc.spi-import-single-file-file").map(f -> SINGLE_FILE); var file = getOptionalValue("kc.spi-import-single-file-file").map(f -> SINGLE_FILE);
@ -117,7 +115,7 @@ public final class ImportPropertyMappers {
// Only one option can be specified // Only one option can be specified
boolean xor = file.isPresent() ^ dir.isPresent(); boolean xor = file.isPresent() ^ dir.isPresent();
return xor ? file.or(() -> dir) : Optional.empty(); return xor ? file.or(() -> dir).get() : null;
} }
} }

View file

@ -1,13 +1,11 @@
package org.keycloak.quarkus.runtime.configuration.mappers; package org.keycloak.quarkus.runtime.configuration.mappers;
import static java.util.Optional.of;
import static org.keycloak.config.LoggingOptions.DEFAULT_LOG_FORMAT; import static org.keycloak.config.LoggingOptions.DEFAULT_LOG_FORMAT;
import static org.keycloak.quarkus.runtime.configuration.Configuration.isTrue; import static org.keycloak.quarkus.runtime.configuration.Configuration.isTrue;
import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption; import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption;
import java.io.File; import java.io.File;
import java.util.Locale; import java.util.Locale;
import java.util.Optional;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -17,9 +15,9 @@ import org.keycloak.config.LoggingOptions;
import org.keycloak.config.Option; import org.keycloak.config.Option;
import org.keycloak.quarkus.runtime.Messages; import org.keycloak.quarkus.runtime.Messages;
import org.keycloak.quarkus.runtime.cli.PropertyException; import org.keycloak.quarkus.runtime.cli.PropertyException;
import org.keycloak.quarkus.runtime.configuration.Configuration;
import io.smallrye.config.ConfigSourceInterceptorContext; import io.smallrye.config.ConfigSourceInterceptorContext;
import org.keycloak.quarkus.runtime.configuration.Configuration;
public final class LoggingPropertyMappers { public final class LoggingPropertyMappers {
@ -62,15 +60,13 @@ public final class LoggingPropertyMappers {
.to("quarkus.log.console.color") .to("quarkus.log.console.color")
.build(), .build(),
fromOption(LoggingOptions.LOG_CONSOLE_ENABLED) fromOption(LoggingOptions.LOG_CONSOLE_ENABLED)
.mapFrom("log") .mapFrom(LoggingOptions.LOG, LoggingPropertyMappers.resolveLogHandler(LoggingOptions.DEFAULT_LOG_HANDLER.name()))
.to("quarkus.log.console.enable") .to("quarkus.log.console.enable")
.transformer(LoggingPropertyMappers.resolveLogHandler(LoggingOptions.DEFAULT_LOG_HANDLER.name()))
.build(), .build(),
// File // File
fromOption(LoggingOptions.LOG_FILE_ENABLED) fromOption(LoggingOptions.LOG_FILE_ENABLED)
.mapFrom("log") .mapFrom(LoggingOptions.LOG, LoggingPropertyMappers.resolveLogHandler("file"))
.to("quarkus.log.file.enable") .to("quarkus.log.file.enable")
.transformer(LoggingPropertyMappers.resolveLogHandler("file"))
.build(), .build(),
fromOption(LoggingOptions.LOG_FILE) fromOption(LoggingOptions.LOG_FILE)
.isEnabled(LoggingPropertyMappers::isFileEnabled, FILE_ENABLED_MSG) .isEnabled(LoggingPropertyMappers::isFileEnabled, FILE_ENABLED_MSG)
@ -108,9 +104,8 @@ public final class LoggingPropertyMappers {
.build(), .build(),
// Syslog // Syslog
fromOption(LoggingOptions.LOG_SYSLOG_ENABLED) fromOption(LoggingOptions.LOG_SYSLOG_ENABLED)
.mapFrom("log") .mapFrom(LoggingOptions.LOG, LoggingPropertyMappers.resolveLogHandler("syslog"))
.to("quarkus.log.syslog.enable") .to("quarkus.log.syslog.enable")
.transformer(LoggingPropertyMappers.resolveLogHandler("syslog"))
.build(), .build(),
fromOption(LoggingOptions.LOG_SYSLOG_ENDPOINT) fromOption(LoggingOptions.LOG_SYSLOG_ENDPOINT)
.isEnabled(LoggingPropertyMappers::isSyslogEnabled, SYSLOG_ENABLED_MSG) .isEnabled(LoggingPropertyMappers::isSyslogEnabled, SYSLOG_ENABLED_MSG)
@ -175,18 +170,16 @@ public final class LoggingPropertyMappers {
return isTrue(LoggingOptions.LOG_SYSLOG_ENABLED); return isTrue(LoggingOptions.LOG_SYSLOG_ENABLED);
} }
private static BiFunction<Optional<String>, ConfigSourceInterceptorContext, Optional<String>> resolveLogHandler(String handler) { private static BiFunction<String, ConfigSourceInterceptorContext, String> resolveLogHandler(String handler) {
return (parentValue, context) -> { return (handlers, context) -> {
String handlers = parentValue.get();
String[] logHandlerValues = handlers.split(","); String[] logHandlerValues = handlers.split(",");
return of(String.valueOf(Stream.of(logHandlerValues).anyMatch(handler::equals))); return String.valueOf(Stream.of(logHandlerValues).anyMatch(handler::equals));
}; };
} }
private static Optional<String> resolveFileLogLocation(Optional<String> value, ConfigSourceInterceptorContext configSourceInterceptorContext) { private static String resolveFileLogLocation(String value, ConfigSourceInterceptorContext configSourceInterceptorContext) {
return value.map(location -> location.endsWith(File.separator) ? location + LoggingOptions.DEFAULT_LOG_FILENAME : location); return value.endsWith(File.separator) ? value + LoggingOptions.DEFAULT_LOG_FILENAME : value;
} }
private static Level toLevel(String categoryLevel) throws IllegalArgumentException { private static Level toLevel(String categoryLevel) throws IllegalArgumentException {
@ -221,13 +214,13 @@ public final class LoggingPropertyMappers {
} }
} }
private static Optional<String> resolveLogLevel(Optional<String> value, ConfigSourceInterceptorContext configSourceInterceptorContext) { private static String resolveLogLevel(String value, ConfigSourceInterceptorContext configSourceInterceptorContext) {
Optional<String> rootLevel = of(LoggingOptions.DEFAULT_LOG_LEVEL.name()); String rootLevel = LoggingOptions.DEFAULT_LOG_LEVEL.name();
for (String level : value.get().split(",")) { for (String level : value.split(",")) {
var categoryLevel = validateLogLevel(level); var categoryLevel = validateLogLevel(level);
if (categoryLevel.category == null) { if (categoryLevel.category == null) {
rootLevel = of(categoryLevel.levelName); rootLevel = categoryLevel.levelName;
} else { } else {
setCategoryLevel(categoryLevel.category, categoryLevel.levelName); setCategoryLevel(categoryLevel.category, categoryLevel.levelName);
} }
@ -236,26 +229,23 @@ public final class LoggingPropertyMappers {
return rootLevel; return rootLevel;
} }
private static Optional<String> resolveLogOutput(Optional<String> value, ConfigSourceInterceptorContext context) { private static String resolveLogOutput(String value, ConfigSourceInterceptorContext context) {
if (value.get().equals(LoggingOptions.DEFAULT_CONSOLE_OUTPUT.name().toLowerCase(Locale.ROOT))) { boolean isDefault = LoggingOptions.DEFAULT_CONSOLE_OUTPUT.name().toLowerCase(Locale.ROOT).equals(value);
return of(Boolean.FALSE.toString()); return Boolean.valueOf(!isDefault).toString();
}
return of(Boolean.TRUE.toString());
} }
/** /**
* Add tracing info to the log if the format is not explicitly set, and tracing and {@code includeTraceOption} options are enabled * Add tracing info to the log if the format is not explicitly set, and tracing and {@code includeTraceOption} options are enabled
*/ */
private static Optional<String> addTracingInfo(Optional<String> value, Option<Boolean> includeTraceOption) { private static String addTracingInfo(String value, Option<Boolean> includeTraceOption) {
var isTracingEnabled = TracingPropertyMappers.isTracingEnabled(); var isTracingEnabled = TracingPropertyMappers.isTracingEnabled();
var includeTrace = Configuration.isTrue(includeTraceOption); var includeTrace = Configuration.isTrue(includeTraceOption);
var isChangedLogFormat = !DEFAULT_LOG_FORMAT.equals(value.get()); var isChangedLogFormat = !DEFAULT_LOG_FORMAT.equals(value);
if (!isTracingEnabled || !includeTrace || isChangedLogFormat) { if (!isTracingEnabled || !includeTrace || isChangedLogFormat) {
return value; return value;
} }
return Optional.of(LoggingOptions.DEFAULT_LOG_TRACING_FORMAT); return LoggingOptions.DEFAULT_LOG_TRACING_FORMAT;
} }
} }

View file

@ -24,8 +24,6 @@ import org.keycloak.quarkus.runtime.Messages;
import org.keycloak.quarkus.runtime.cli.PropertyException; import org.keycloak.quarkus.runtime.cli.PropertyException;
import org.keycloak.quarkus.runtime.configuration.Configuration; import org.keycloak.quarkus.runtime.configuration.Configuration;
import java.util.Optional;
import static org.keycloak.config.ManagementOptions.LEGACY_OBSERVABILITY_INTERFACE; import static org.keycloak.config.ManagementOptions.LEGACY_OBSERVABILITY_INTERFACE;
import static org.keycloak.quarkus.runtime.configuration.Configuration.isTrue; import static org.keycloak.quarkus.runtime.configuration.Configuration.isTrue;
import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption; import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption;
@ -44,7 +42,7 @@ public class ManagementPropertyMappers {
fromOption(ManagementOptions.LEGACY_OBSERVABILITY_INTERFACE) fromOption(ManagementOptions.LEGACY_OBSERVABILITY_INTERFACE)
.build(), .build(),
fromOption(ManagementOptions.HTTP_MANAGEMENT_RELATIVE_PATH) fromOption(ManagementOptions.HTTP_MANAGEMENT_RELATIVE_PATH)
.mapFrom(HttpOptions.HTTP_RELATIVE_PATH.getKey()) .mapFrom(HttpOptions.HTTP_RELATIVE_PATH)
.to("quarkus.management.root-path") .to("quarkus.management.root-path")
.paramLabel("path") .paramLabel("path")
.build(), .build(),
@ -53,55 +51,54 @@ public class ManagementPropertyMappers {
.paramLabel("port") .paramLabel("port")
.build(), .build(),
fromOption(ManagementOptions.HTTP_MANAGEMENT_HOST) fromOption(ManagementOptions.HTTP_MANAGEMENT_HOST)
.mapFrom(HttpOptions.HTTP_HOST.getKey()) .mapFrom(HttpOptions.HTTP_HOST)
.to("quarkus.management.host") .to("quarkus.management.host")
.paramLabel("host") .paramLabel("host")
.build(), .build(),
// HTTPS // HTTPS
fromOption(ManagementOptions.HTTPS_MANAGEMENT_CLIENT_AUTH) fromOption(ManagementOptions.HTTPS_MANAGEMENT_CLIENT_AUTH)
.mapFrom(HttpOptions.HTTPS_CLIENT_AUTH.getKey()) .mapFrom(HttpOptions.HTTPS_CLIENT_AUTH)
.to("quarkus.management.ssl.client-auth") .to("quarkus.management.ssl.client-auth")
.paramLabel("auth") .paramLabel("auth")
.build(), .build(),
fromOption(ManagementOptions.HTTPS_MANAGEMENT_CIPHER_SUITES) fromOption(ManagementOptions.HTTPS_MANAGEMENT_CIPHER_SUITES)
.mapFrom(HttpOptions.HTTPS_CIPHER_SUITES.getKey()) .mapFrom(HttpOptions.HTTPS_CIPHER_SUITES)
.to("quarkus.management.ssl.cipher-suites") .to("quarkus.management.ssl.cipher-suites")
.paramLabel("ciphers") .paramLabel("ciphers")
.build(), .build(),
fromOption(ManagementOptions.HTTPS_MANAGEMENT_PROTOCOLS) fromOption(ManagementOptions.HTTPS_MANAGEMENT_PROTOCOLS)
.mapFrom(HttpOptions.HTTPS_PROTOCOLS.getKey()) .mapFrom(HttpOptions.HTTPS_PROTOCOLS)
.to("quarkus.management.ssl.protocols") .to("quarkus.management.ssl.protocols")
.paramLabel("protocols") .paramLabel("protocols")
.build(), .build(),
fromOption(ManagementOptions.HTTPS_MANAGEMENT_CERTIFICATE_FILE) fromOption(ManagementOptions.HTTPS_MANAGEMENT_CERTIFICATE_FILE)
.mapFrom(HttpOptions.HTTPS_CERTIFICATE_FILE.getKey()) .mapFrom(HttpOptions.HTTPS_CERTIFICATE_FILE)
.to("quarkus.management.ssl.certificate.files") .to("quarkus.management.ssl.certificate.files")
.validator(value -> validateTlsProperties()) .validator(value -> validateTlsProperties())
.paramLabel("file") .paramLabel("file")
.build(), .build(),
fromOption(ManagementOptions.HTTPS_MANAGEMENT_CERTIFICATE_KEY_FILE) fromOption(ManagementOptions.HTTPS_MANAGEMENT_CERTIFICATE_KEY_FILE)
.mapFrom(HttpOptions.HTTPS_CERTIFICATE_KEY_FILE.getKey()) .mapFrom(HttpOptions.HTTPS_CERTIFICATE_KEY_FILE)
.to("quarkus.management.ssl.certificate.key-files") .to("quarkus.management.ssl.certificate.key-files")
.validator(value -> validateTlsProperties()) .validator(value -> validateTlsProperties())
.paramLabel("file") .paramLabel("file")
.build(), .build(),
fromOption(ManagementOptions.HTTPS_MANAGEMENT_KEY_STORE_FILE) fromOption(ManagementOptions.HTTPS_MANAGEMENT_KEY_STORE_FILE)
.mapFrom(HttpOptions.HTTPS_KEY_STORE_FILE.getKey()) .mapFrom(HttpOptions.HTTPS_KEY_STORE_FILE)
.to("quarkus.management.ssl.certificate.key-store-file") .to("quarkus.management.ssl.certificate.key-store-file")
.validator(value -> validateTlsProperties()) .validator(value -> validateTlsProperties())
.paramLabel("file") .paramLabel("file")
.build(), .build(),
fromOption(ManagementOptions.HTTPS_MANAGEMENT_KEY_STORE_PASSWORD) fromOption(ManagementOptions.HTTPS_MANAGEMENT_KEY_STORE_PASSWORD)
.mapFrom(HttpOptions.HTTPS_KEY_STORE_PASSWORD.getKey()) .mapFrom(HttpOptions.HTTPS_KEY_STORE_PASSWORD)
.to("quarkus.management.ssl.certificate.key-store-password") .to("quarkus.management.ssl.certificate.key-store-password")
.validator(value -> validateTlsProperties()) .validator(value -> validateTlsProperties())
.paramLabel("password") .paramLabel("password")
.isMasked(true) .isMasked(true)
.build(), .build(),
fromOption(ManagementOptions.HTTPS_MANAGEMENT_KEY_STORE_TYPE) fromOption(ManagementOptions.HTTPS_MANAGEMENT_KEY_STORE_TYPE)
.mapFrom(HttpOptions.HTTPS_KEY_STORE_TYPE.getKey()) .mapFrom(HttpOptions.HTTPS_KEY_STORE_TYPE)
.to("quarkus.management.ssl.certificate.key-store-file-type") .to("quarkus.management.ssl.certificate.key-store-file-type")
.transformer((value, config) -> value.or(() -> Configuration.getOptionalKcValue(HttpOptions.HTTPS_KEY_STORE_TYPE.getKey())))
.paramLabel("type") .paramLabel("type")
.build(), .build(),
}; };
@ -115,8 +112,8 @@ public class ManagementPropertyMappers {
return isManagementOccupied; return isManagementOccupied;
} }
private static Optional<String> managementEnabledTransformer() { private static String managementEnabledTransformer() {
return Optional.of(Boolean.toString(isManagementEnabled())); return Boolean.toString(isManagementEnabled());
} }
public static boolean isManagementTlsEnabled() { public static boolean isManagementTlsEnabled() {

View file

@ -42,6 +42,7 @@ import org.keycloak.config.OptionCategory;
import org.keycloak.quarkus.runtime.cli.PropertyException; import org.keycloak.quarkus.runtime.cli.PropertyException;
import org.keycloak.quarkus.runtime.cli.ShortErrorMessageHandler; import org.keycloak.quarkus.runtime.cli.ShortErrorMessageHandler;
import org.keycloak.quarkus.runtime.configuration.ConfigArgsConfigSource; import org.keycloak.quarkus.runtime.configuration.ConfigArgsConfigSource;
import org.keycloak.quarkus.runtime.configuration.Configuration;
import org.keycloak.quarkus.runtime.configuration.KcEnvConfigSource; import org.keycloak.quarkus.runtime.configuration.KcEnvConfigSource;
import org.keycloak.quarkus.runtime.configuration.KeycloakConfigSourceProvider; import org.keycloak.quarkus.runtime.configuration.KeycloakConfigSourceProvider;
import org.keycloak.quarkus.runtime.Environment; import org.keycloak.quarkus.runtime.Environment;
@ -58,6 +59,7 @@ public class PropertyMapper<T> {
null, null,
null, null,
null, null,
null,
false, false,
null, null,
null) { null) {
@ -71,8 +73,9 @@ public class PropertyMapper<T> {
private final String to; private final String to;
private BooleanSupplier enabled; private BooleanSupplier enabled;
private String enabledWhen; private String enabledWhen;
private final BiFunction<Optional<String>, ConfigSourceInterceptorContext, Optional<String>> mapper; private final BiFunction<String, ConfigSourceInterceptorContext, String> mapper;
private final String mapFrom; private final String mapFrom;
private final BiFunction<String, ConfigSourceInterceptorContext, String> parentMapper;
private final boolean mask; private final boolean mask;
private final String paramLabel; private final String paramLabel;
private final String envVarFormat; private final String envVarFormat;
@ -81,14 +84,15 @@ public class PropertyMapper<T> {
private final String description; private final String description;
PropertyMapper(Option<T> option, String to, BooleanSupplier enabled, String enabledWhen, PropertyMapper(Option<T> option, String to, BooleanSupplier enabled, String enabledWhen,
BiFunction<Optional<String>, ConfigSourceInterceptorContext, Optional<String>> mapper, BiFunction<String, ConfigSourceInterceptorContext, String> mapper,
String mapFrom, String paramLabel, boolean mask, BiConsumer<PropertyMapper<T>, ConfigValue> validator, String mapFrom, BiFunction<String, ConfigSourceInterceptorContext, String> parentMapper,
String paramLabel, boolean mask, BiConsumer<PropertyMapper<T>, ConfigValue> validator,
String description) { String description) {
this.option = option; this.option = option;
this.to = to == null ? getFrom() : to; this.to = to == null ? getFrom() : to;
this.enabled = enabled; this.enabled = enabled;
this.enabledWhen = enabledWhen; this.enabledWhen = enabledWhen;
this.mapper = mapper == null ? PropertyMapper::defaultTransformer : mapper; this.mapper = mapper;
this.mapFrom = mapFrom; this.mapFrom = mapFrom;
this.paramLabel = paramLabel; this.paramLabel = paramLabel;
this.mask = mask; this.mask = mask;
@ -96,10 +100,7 @@ public class PropertyMapper<T> {
this.envVarFormat = toEnvVarFormat(getFrom()); this.envVarFormat = toEnvVarFormat(getFrom());
this.validator = validator; this.validator = validator;
this.description = description; this.description = description;
} this.parentMapper = parentMapper;
private static Optional<String> defaultTransformer(Optional<String> value, ConfigSourceInterceptorContext context) {
return value;
} }
ConfigValue getConfigValue(ConfigSourceInterceptorContext context) { ConfigValue getConfigValue(ConfigSourceInterceptorContext context) {
@ -122,53 +123,25 @@ public class PropertyMapper<T> {
// try to obtain the value for the property we want to map first // try to obtain the value for the property we want to map first
ConfigValue config = convertValue(context.proceed(from)); ConfigValue config = convertValue(context.proceed(from));
if (config == null || config.getValue() == null) { boolean parentValue = false;
if (mapFrom != null) { if (mapFrom != null && (config == null || config.getValue() == null)) {
// if the property we want to map depends on another one, we use the value from the other property to call the mapper // if the property we want to map depends on another one, we use the value from the other property to call the mapper
String parentKey = MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX + mapFrom; config = Configuration.getKcConfigValue(mapFrom);
ConfigValue parentValue = convertValue(context.proceed(parentKey)); parentValue = true;
if (parentValue == null) {
// parent value not explicitly set, try to resolve the default value set to the parent property
PropertyMapper<?> parentMapper = PropertyMappers.getMapper(parentKey);
if (parentMapper != null && parentMapper.getDefaultValue().isPresent()) {
parentValue = ConfigValue.builder().withValue(Option.getDefaultValueString(parentMapper.getDefaultValue().get())).build();
}
} }
return transformValue(name, ofNullable(parentValue == null ? null : parentValue.getValue()), context, null); if (config != null && config.getValue() != null) {
config = transformValue(name, config.getValue(), context, config.getConfigSourceName(), parentValue);
} else {
config = transformValue(name, this.option.getDefaultValue().map(Option::getDefaultValueString).orElse(null), context, null, false);
} }
ConfigValue defaultValue = transformValue(name, this.option.getDefaultValue().map(Option::getDefaultValueString), context, null); if (config != null) {
return config;
if (defaultValue != null) {
return defaultValue;
} }
// now tries any defaults from quarkus // now try any defaults from quarkus
ConfigValue current = context.proceed(name); return context.proceed(name);
if (current != null) {
return transformValue(name, ofNullable(current.getValue()), context, current.getConfigSourceName());
}
return current;
}
ConfigValue transformedValue = transformValue(name, ofNullable(config.getValue()), context, config.getConfigSourceName());
// we always fallback to the current value from the property we are mapping
if (transformedValue == null) {
return ConfigValue.builder()
.withName(name)
.withValue(null)
.withRawValue(config.getValue())
.withConfigSourceName(config.getConfigSourceName())
.build();
}
return transformedValue;
} }
public Option<T> getOption() { public Option<T> getOption() {
@ -259,30 +232,22 @@ public class PropertyMapper<T> {
return option.getDeprecatedMetadata(); return option.getDeprecatedMetadata();
} }
private ConfigValue transformValue(String name, Optional<String> value, ConfigSourceInterceptorContext context, String configSourceName) { private ConfigValue transformValue(String name, String value, ConfigSourceInterceptorContext context, String configSourceName, boolean parentValue) {
if (value == null) { String mappedValue = value;
return null;
var theMapper = parentValue ? this.parentMapper : this.mapper;
if (theMapper != null && (!name.equals(getFrom()) || parentValue)) {
mappedValue = theMapper.apply(value, context);
} }
if (mapper == null || (mapFrom == null && name.equals(getFrom()))) { if (value == null && mappedValue == null) {
// no mapper set or requesting a property that does not depend on other property, just return the value from the config source
return ConfigValue.builder()
.withName(name)
.withValue(value.orElse(null))
.withConfigSourceName(configSourceName)
.build();
}
Optional<String> mappedValue = mapper.apply(value, context);
if (mappedValue == null || mappedValue.isEmpty()) {
return null; return null;
} }
return ConfigValue.builder() return ConfigValue.builder()
.withName(name) .withName(name)
.withValue(mappedValue.get()) .withValue(mappedValue)
.withRawValue(value.orElse(null)) .withRawValue(value)
.withConfigSourceName(configSourceName) .withConfigSourceName(configSourceName)
.build(); .build();
} }
@ -299,8 +264,9 @@ public class PropertyMapper<T> {
private final Option<T> option; private final Option<T> option;
private String to; private String to;
private BiFunction<Optional<String>, ConfigSourceInterceptorContext, Optional<String>> mapper; private BiFunction<String, ConfigSourceInterceptorContext, String> mapper;
private String mapFrom = null; private String mapFrom = null;
private BiFunction<String, ConfigSourceInterceptorContext, String> parentMapper;
private boolean isMasked = false; private boolean isMasked = false;
private BooleanSupplier isEnabled = () -> true; private BooleanSupplier isEnabled = () -> true;
private String enabledWhen = ""; private String enabledWhen = "";
@ -318,7 +284,12 @@ public class PropertyMapper<T> {
return this; return this;
} }
public Builder<T> transformer(BiFunction<Optional<String>, ConfigSourceInterceptorContext, Optional<String>> mapper) { /**
* NOTE: This transformer will not apply to the mapFrom value. When using
* {@link #mapFrom} you generally need a transformer specifically for the parent
* value, see {@link #mapFrom(Option, BiFunction)}
*/
public Builder<T> transformer(BiFunction<String, ConfigSourceInterceptorContext, String> mapper) {
this.mapper = mapper; this.mapper = mapper;
return this; return this;
} }
@ -333,8 +304,9 @@ public class PropertyMapper<T> {
return this; return this;
} }
public Builder<T> mapFrom(String mapFrom) { public Builder<T> mapFrom(Option<?> mapFrom, BiFunction<String, ConfigSourceInterceptorContext, String> parentMapper) {
this.mapFrom = mapFrom; this.mapFrom = mapFrom.getKey();
this.parentMapper = parentMapper;
return this; return this;
} }
@ -404,7 +376,7 @@ public class PropertyMapper<T> {
if (paramLabel == null && Boolean.class.equals(option.getType())) { if (paramLabel == null && Boolean.class.equals(option.getType())) {
paramLabel = Boolean.TRUE + "|" + Boolean.FALSE; paramLabel = Boolean.TRUE + "|" + Boolean.FALSE;
} }
return new PropertyMapper<T>(option, to, isEnabled, enabledWhen, mapper, mapFrom, paramLabel, isMasked, validator, description); return new PropertyMapper<T>(option, to, isEnabled, enabledWhen, mapper, mapFrom, parentMapper, paramLabel, isMasked, validator, description);
} }
} }

View file

@ -6,8 +6,6 @@ import org.keycloak.config.ProxyOptions;
import org.keycloak.quarkus.runtime.cli.PropertyException; import org.keycloak.quarkus.runtime.cli.PropertyException;
import org.keycloak.quarkus.runtime.configuration.Configuration; import org.keycloak.quarkus.runtime.configuration.Configuration;
import java.util.Optional;
import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption; import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption;
final class ProxyPropertyMappers { final class ProxyPropertyMappers {
@ -26,18 +24,15 @@ final class ProxyPropertyMappers {
.build(), .build(),
fromOption(ProxyOptions.PROXY_FORWARDED_HOST) fromOption(ProxyOptions.PROXY_FORWARDED_HOST)
.to("quarkus.http.proxy.enable-forwarded-host") .to("quarkus.http.proxy.enable-forwarded-host")
.mapFrom("proxy-headers") .mapFrom(ProxyOptions.PROXY_HEADERS, (v, c) -> proxyEnabled(null, v, c))
.transformer((v, c) -> proxyEnabled(null, v, c))
.build(), .build(),
fromOption(ProxyOptions.PROXY_FORWARDED_HEADER_ENABLED) fromOption(ProxyOptions.PROXY_FORWARDED_HEADER_ENABLED)
.to("quarkus.http.proxy.allow-forwarded") .to("quarkus.http.proxy.allow-forwarded")
.mapFrom("proxy-headers") .mapFrom(ProxyOptions.PROXY_HEADERS, (v, c) -> proxyEnabled(ProxyOptions.Headers.forwarded, v, c))
.transformer((v, c) -> proxyEnabled(ProxyOptions.Headers.forwarded, v, c))
.build(), .build(),
fromOption(ProxyOptions.PROXY_X_FORWARDED_HEADER_ENABLED) fromOption(ProxyOptions.PROXY_X_FORWARDED_HEADER_ENABLED)
.to("quarkus.http.proxy.allow-x-forwarded") .to("quarkus.http.proxy.allow-x-forwarded")
.mapFrom("proxy-headers") .mapFrom(ProxyOptions.PROXY_HEADERS, (v, c) -> proxyEnabled(ProxyOptions.Headers.xforwarded, v, c))
.transformer((v, c) -> proxyEnabled(ProxyOptions.Headers.xforwarded, v, c))
.build(), .build(),
fromOption(ProxyOptions.PROXY_TRUSTED_ADDRESSES) fromOption(ProxyOptions.PROXY_TRUSTED_ADDRESSES)
.to("quarkus.http.proxy.trusted-proxies") .to("quarkus.http.proxy.trusted-proxies")
@ -57,18 +52,18 @@ final class ProxyPropertyMappers {
} }
} }
private static Optional<String> proxyEnabled(ProxyOptions.Headers testHeader, Optional<String> value, ConfigSourceInterceptorContext context) { private static String proxyEnabled(ProxyOptions.Headers testHeader, String value, ConfigSourceInterceptorContext context) {
boolean enabled = false; boolean enabled = false;
if (value.isPresent()) { // proxy-headers explicitly configured if (value != null) { // proxy-headers explicitly configured
if (testHeader != null) { if (testHeader != null) {
enabled = ProxyOptions.Headers.valueOf(value.get()).equals(testHeader); enabled = ProxyOptions.Headers.valueOf(value).equals(testHeader);
} else { } else {
enabled = true; enabled = true;
} }
} }
return Optional.of(String.valueOf(enabled)); return String.valueOf(enabled);
} }
} }

View file

@ -1,10 +1,7 @@
package org.keycloak.quarkus.runtime.configuration.mappers; package org.keycloak.quarkus.runtime.configuration.mappers;
import static java.util.Optional.of;
import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption; import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption;
import java.util.Optional;
import org.keycloak.common.Profile; import org.keycloak.common.Profile;
import org.keycloak.common.Profile.Feature; import org.keycloak.common.Profile.Feature;
import org.keycloak.common.crypto.FipsMode; import org.keycloak.common.crypto.FipsMode;
@ -25,15 +22,15 @@ final class SecurityPropertyMappers {
}; };
} }
private static Optional<String> resolveFipsMode(Optional<String> value, ConfigSourceInterceptorContext context) { private static String resolveFipsMode(String value, ConfigSourceInterceptorContext context) {
if (value.isEmpty()) { if (value == null) {
if (Profile.isFeatureEnabled(Feature.FIPS)) { if (Profile.isFeatureEnabled(Feature.FIPS)) {
return of(FipsMode.NON_STRICT.toString()); return FipsMode.NON_STRICT.toString();
} }
return of(FipsMode.DISABLED.toString()); return FipsMode.DISABLED.toString();
} }
return of(FipsMode.valueOfOption(value.get()).toString()); return value;
} }
} }

View file

@ -4,11 +4,8 @@ import io.smallrye.config.ConfigSourceInterceptorContext;
import org.keycloak.config.TransactionOptions; import org.keycloak.config.TransactionOptions;
import static java.util.Optional.of;
import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption; import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption;
import java.util.Optional;
public class TransactionPropertyMappers { public class TransactionPropertyMappers {
private static final String QUARKUS_TXPROP_TARGET = "quarkus.datasource.jdbc.transactions"; private static final String QUARKUS_TXPROP_TARGET = "quarkus.datasource.jdbc.transactions";
@ -24,13 +21,13 @@ public class TransactionPropertyMappers {
}; };
} }
private static Optional<String> getQuarkusTransactionsValue(Optional<String> txValue, ConfigSourceInterceptorContext context) { private static String getQuarkusTransactionsValue(String txValue, ConfigSourceInterceptorContext context) {
boolean isXaEnabled = Boolean.parseBoolean(txValue.get()); boolean isXaEnabled = Boolean.parseBoolean(txValue);
if (isXaEnabled) { if (isXaEnabled) {
return of("xa"); return "xa";
} }
return of("enabled"); return "enabled";
} }
} }

View file

@ -358,7 +358,7 @@ public class ConfigurationTest extends AbstractConfigurationTest {
// If explicitly set, then it is always used regardless of the profile // If explicitly set, then it is always used regardless of the profile
System.clearProperty(org.keycloak.common.util.Environment.PROFILE); System.clearProperty(org.keycloak.common.util.Environment.PROFILE);
ConfigArgsConfigSource.setCliArgs("--cache=cluster-foo.xml"); ConfigArgsConfigSource.setCliArgs("--cache-config-file=cluster-foo.xml");
Assert.assertEquals("cluster-foo.xml", initConfig("connectionsInfinispan", "quarkus").get("configFile")); Assert.assertEquals("cluster-foo.xml", initConfig("connectionsInfinispan", "quarkus").get("configFile"));
System.setProperty(org.keycloak.common.util.Environment.PROFILE, "dev"); System.setProperty(org.keycloak.common.util.Environment.PROFILE, "dev");
@ -449,7 +449,7 @@ public class ConfigurationTest extends AbstractConfigurationTest {
assertEquals("false", createConfig().getConfigValue("kc.hostname-strict").getValue()); assertEquals("false", createConfig().getConfigValue("kc.hostname-strict").getValue());
Environment.setProfile("prod"); Environment.setProfile("prod");
assertEquals("true", createConfig().getConfigValue("kc.hostname-strict").getValue()); assertEquals("true", createConfig().getConfigValue("kc.spi-hostname-v2-hostname-strict").getValue());
} }
@Test @Test