task: refinements to propertymapping
closes: #32724 Signed-off-by: Steve Hawkins <shawkins@redhat.com>
This commit is contained in:
parent
a276b3bb3d
commit
14e44f7d8c
14 changed files with 159 additions and 262 deletions
|
@ -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() {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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 Optional<String> getXaOrNonXaDriver(Optional<String> value, ConfigSourceInterceptorContext context) {
|
private static String getXaOrNonXaDriver(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");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
|
||||||
} catch (IllegalArgumentException ignore) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return value;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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) {
|
if (config != null && config.getValue() != null) {
|
||||||
// parent value not explicitly set, try to resolve the default value set to the parent property
|
config = transformValue(name, config.getValue(), context, config.getConfigSourceName(), parentValue);
|
||||||
PropertyMapper<?> parentMapper = PropertyMappers.getMapper(parentKey);
|
} else {
|
||||||
|
config = transformValue(name, this.option.getDefaultValue().map(Option::getDefaultValueString).orElse(null), context, null, false);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
ConfigValue defaultValue = transformValue(name, this.option.getDefaultValue().map(Option::getDefaultValueString), context, null);
|
|
||||||
|
|
||||||
if (defaultValue != null) {
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// now tries any defaults from quarkus
|
|
||||||
ConfigValue current = 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());
|
if (config != null) {
|
||||||
|
return config;
|
||||||
// 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;
|
// now try any defaults from quarkus
|
||||||
|
return context.proceed(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue