diff --git a/quarkus/deployment/src/main/java/org/keycloak/quarkus/deployment/KeycloakProcessor.java b/quarkus/deployment/src/main/java/org/keycloak/quarkus/deployment/KeycloakProcessor.java index e21390b2b3..d19764df8f 100644 --- a/quarkus/deployment/src/main/java/org/keycloak/quarkus/deployment/KeycloakProcessor.java +++ b/quarkus/deployment/src/main/java/org/keycloak/quarkus/deployment/KeycloakProcessor.java @@ -17,7 +17,12 @@ package org.keycloak.quarkus.deployment; +import static org.keycloak.configuration.Configuration.getPropertyNames; +import static org.keycloak.configuration.Configuration.getRawValue; + import javax.persistence.spi.PersistenceUnitTransactionType; +import java.io.File; +import java.io.FileOutputStream; import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; @@ -25,6 +30,7 @@ import java.util.List; import java.util.Map; import java.util.NoSuchElementException; import java.util.Optional; +import java.util.Properties; import java.util.ServiceLoader; import io.quarkus.deployment.IsDevelopment; @@ -38,6 +44,8 @@ import org.jboss.resteasy.spi.ResteasyDeployment; import org.keycloak.Config; import org.keycloak.common.Profile; import org.keycloak.config.ConfigProviderFactory; +import org.keycloak.configuration.Configuration; +import org.keycloak.configuration.KeycloakConfigSourceProvider; import org.keycloak.connections.jpa.DefaultJpaConnectionProviderFactory; import org.keycloak.connections.jpa.updater.liquibase.LiquibaseJpaUpdaterProviderFactory; import org.keycloak.connections.jpa.updater.liquibase.conn.DefaultLiquibaseConnectionProvider; @@ -129,7 +137,7 @@ class KeycloakProcessor { *

Make the build time configuration available at runtime so that the server can run without having to specify some of * the properties again. * - *

This build step also adds a static call to {@link org.keycloak.cli.ShowConfigCommand#run(Map)} via the recorder + *

This build step also adds a static call to {@link org.keycloak.cli.ShowConfigCommand#run} via the recorder * so that the configuration can be shown when requested. * * @param recorder the recorder @@ -137,21 +145,33 @@ class KeycloakProcessor { @Record(ExecutionTime.STATIC_INIT) @BuildStep void setBuildTimeProperties(KeycloakRecorder recorder) { - Map properties = new HashMap<>(); + Properties properties = new Properties(); - for (String name : KeycloakRecorder.getConfig().getPropertyNames()) { + for (String name : getPropertyNames()) { if (isNotPersistentProperty(name)) { continue; } - Optional value = KeycloakRecorder.getConfig().getOptionalValue(name, String.class); + Optional value = Configuration.getOptionalValue(name); if (value.isPresent()) { properties.put(name, value.get()); } } - recorder.validateAndSetBuildTimeProperties(properties, Environment.isRebuild(), KeycloakRecorder.getConfig().getRawValue("kc.config.args")); + File file = KeycloakConfigSourceProvider.getPersistedConfigFile().toFile(); + + if (file.exists()) { + file.delete(); + } + + try (FileOutputStream fos = new FileOutputStream(file)) { + properties.store(fos, " Auto-generated, DO NOT change this file"); + } catch (Exception e) { + throw new RuntimeException("Failed to generate persisted.properties file", e); + } + + recorder.validateAndSetBuildTimeProperties(Environment.isRebuild(), getRawValue("kc.config.args")); recorder.showConfig(); } diff --git a/quarkus/runtime/src/main/java/org/keycloak/cli/MainCommand.java b/quarkus/runtime/src/main/java/org/keycloak/cli/MainCommand.java index 73c3ccb243..8fceb33eef 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/cli/MainCommand.java +++ b/quarkus/runtime/src/main/java/org/keycloak/cli/MainCommand.java @@ -167,8 +167,9 @@ public class MainCommand { optionListHeading = "%nOptions%n", parameterListHeading = "Available Commands%n") public void start( - @CommandLine.Parameters(paramLabel = "show-config", arity = "0..1", - description = "Print out the configuration options when starting the server.") String showConfig, + @Option(names = "--show-config", arity = "0..1", + description = "Print out the configuration options when starting the server.", + fallbackValue = "show-config") String showConfig, @Option(names = "--verbose", description = "Print out more details when running this command.", required = false) Boolean verbose) { if ("show-config".equals(showConfig)) { System.setProperty("kc.show.config.runtime", Boolean.TRUE.toString()); diff --git a/quarkus/runtime/src/main/java/org/keycloak/cli/ShowConfigCommand.java b/quarkus/runtime/src/main/java/org/keycloak/cli/ShowConfigCommand.java index 2271004fa4..c5a92775e6 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/cli/ShowConfigCommand.java +++ b/quarkus/runtime/src/main/java/org/keycloak/cli/ShowConfigCommand.java @@ -18,32 +18,34 @@ package org.keycloak.cli; import static java.lang.Boolean.parseBoolean; +import static org.keycloak.configuration.Configuration.getConfigValue; +import static org.keycloak.configuration.Configuration.getPropertyNames; import static org.keycloak.configuration.PropertyMappers.canonicalFormat; import static org.keycloak.configuration.PropertyMappers.formatValue; import static org.keycloak.util.Environment.getBuiltTimeProperty; -import static org.keycloak.util.Environment.getConfig; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.function.BiConsumer; +import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.StreamSupport; import org.keycloak.configuration.MicroProfileConfigProvider; +import org.keycloak.configuration.PersistedConfigSource; import org.keycloak.configuration.PropertyMappers; -import org.keycloak.quarkus.KeycloakRecorder; import org.keycloak.util.Environment; import io.smallrye.config.ConfigValue; public final class ShowConfigCommand { - public static void run(Map buildTimeProperties) { + public static void run() { String configArgs = System.getProperty("kc.show.config"); if (configArgs != null) { - Map> properties = getPropertiesByGroup(buildTimeProperties); + Map> properties = getPropertiesByGroup(); Set uniqueNames = new HashSet<>(); String profile = getProfile(); @@ -101,13 +103,20 @@ public final class ShowConfigCommand { return profile; } - private static Map> getPropertiesByGroup(Map buildTimeProperties) { + private static Map> getPropertiesByGroup() { Map> properties = StreamSupport - .stream(getConfig().getPropertyNames().spliterator(), false) + .stream(getPropertyNames().spliterator(), false) .filter(ShowConfigCommand::filterByGroup) .collect(Collectors.groupingBy(ShowConfigCommand::groupProperties, Collectors.toSet())); - buildTimeProperties.keySet().stream() + StreamSupport.stream(getPropertyNames().spliterator(), false) + .filter(new Predicate() { + @Override + public boolean test(String s) { + ConfigValue configValue = getConfigValue(s); + return configValue.getConfigSourceName().equals(PersistedConfigSource.NAME); + } + }) .filter(property -> filterByGroup(property)) .collect(Collectors.groupingBy(ShowConfigCommand::groupProperties, Collectors.toSet())) .forEach(new BiConsumer>() { @@ -122,10 +131,10 @@ public final class ShowConfigCommand { private static void printProperty(String property) { String canonicalFormat = PropertyMappers.canonicalFormat(property); - ConfigValue configValue = KeycloakRecorder.getConfig().getConfigValue(canonicalFormat); + ConfigValue configValue = getConfigValue(canonicalFormat); if (configValue.getValue() == null) { - configValue = getConfig().getConfigValue(property); + configValue = getConfigValue(property); } diff --git a/quarkus/runtime/src/main/java/org/keycloak/configuration/Configuration.java b/quarkus/runtime/src/main/java/org/keycloak/configuration/Configuration.java new file mode 100644 index 0000000000..6e687ac3f9 --- /dev/null +++ b/quarkus/runtime/src/main/java/org/keycloak/configuration/Configuration.java @@ -0,0 +1,72 @@ +/* + * Copyright 2020 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.keycloak.configuration; + +import java.util.Optional; + +import io.smallrye.config.ConfigValue; +import io.smallrye.config.SmallRyeConfig; +import io.smallrye.config.SmallRyeConfigProviderResolver; +import org.keycloak.util.Environment; + +/** + * The entry point for accessing the server configuration + */ +public final class Configuration { + + private static volatile SmallRyeConfig CONFIG; + + public static synchronized SmallRyeConfig getConfig() { + if (CONFIG == null) { + CONFIG = (SmallRyeConfig) SmallRyeConfigProviderResolver.instance().getConfig(); + } + return CONFIG; + } + + public static String getBuiltTimeProperty(String name) { + String value = KeycloakConfigSourceProvider.PERSISTED_CONFIG_SOURCE.getValue(name); + + if (value == null) { + String profile = Environment.getProfile(); + + if (profile == null) { + profile = getConfig().getRawValue("kc.profile"); + } + + value = KeycloakConfigSourceProvider.PERSISTED_CONFIG_SOURCE.getValue("%" + profile + "." + name); + } + + return value; + } + + public static String getRawValue(String propertyName) { + return getConfig().getRawValue(propertyName); + } + + public static Iterable getPropertyNames() { + return getConfig().getPropertyNames(); + } + + public static ConfigValue getConfigValue(String propertyName) { + return getConfig().getConfigValue(propertyName); + } + + public static Optional getOptionalValue(String name) { + return getConfig().getOptionalValue(name, String.class); + } +} diff --git a/quarkus/runtime/src/main/java/org/keycloak/configuration/KeycloakConfigSourceProvider.java b/quarkus/runtime/src/main/java/org/keycloak/configuration/KeycloakConfigSourceProvider.java index cc07d3a039..e355e29acb 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/configuration/KeycloakConfigSourceProvider.java +++ b/quarkus/runtime/src/main/java/org/keycloak/configuration/KeycloakConfigSourceProvider.java @@ -37,7 +37,8 @@ public class KeycloakConfigSourceProvider implements ConfigSourceProvider { public static final String KEYCLOAK_CONFIG_FILE_ENV = "KC_CONFIG_FILE"; public static final String KEYCLOAK_CONFIG_FILE_PROP = NS_KEYCLOAK_PREFIX + "config.file"; private static final List CONFIG_SOURCES = new ArrayList<>(); - + public static PersistedConfigSource PERSISTED_CONFIG_SOURCE; + // we initialize in a static block to avoid discovering the config sources multiple times when starting the application static { initializeSources(); @@ -51,7 +52,8 @@ public class KeycloakConfigSourceProvider implements ConfigSourceProvider { } CONFIG_SOURCES.add(new ConfigArgsConfigSource()); - CONFIG_SOURCES.add(new PersistedConfigSource()); + PERSISTED_CONFIG_SOURCE = new PersistedConfigSource(getPersistedConfigFile()); + CONFIG_SOURCES.add(PERSISTED_CONFIG_SOURCE); CONFIG_SOURCES.add(new SysPropConfigSource()); Path configFile = getConfigurationFile(); @@ -98,6 +100,16 @@ public class KeycloakConfigSourceProvider implements ConfigSourceProvider { return Paths.get(filePath); } + public static Path getPersistedConfigFile() { + String homeDir = Environment.getHomeDir(); + + if (homeDir == null) { + return Paths.get(System.getProperty("java.io.tmpdir"), PersistedConfigSource.KEYCLOAK_PROPERTIES); + } + + return Paths.get(homeDir, "conf", PersistedConfigSource.KEYCLOAK_PROPERTIES); + } + @Override public Iterable getConfigSources(ClassLoader forClassLoader) { return CONFIG_SOURCES; diff --git a/quarkus/runtime/src/main/java/org/keycloak/configuration/PersistedConfigSource.java b/quarkus/runtime/src/main/java/org/keycloak/configuration/PersistedConfigSource.java index d913ec3312..4f96d3eb57 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/configuration/PersistedConfigSource.java +++ b/quarkus/runtime/src/main/java/org/keycloak/configuration/PersistedConfigSource.java @@ -17,20 +17,32 @@ package org.keycloak.configuration; +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; import java.util.Collections; import java.util.Map; -import io.smallrye.config.common.AbstractConfigSource; -import org.keycloak.quarkus.KeycloakRecorder; +import io.smallrye.config.PropertiesConfigSource; +import io.smallrye.config.common.utils.ConfigSourceUtil; +import org.keycloak.util.Environment; /** * A {@link org.eclipse.microprofile.config.spi.ConfigSource} based on the configuration properties persisted into the server * image. */ -public class PersistedConfigSource extends AbstractConfigSource { +public class PersistedConfigSource extends PropertiesConfigSource { - public PersistedConfigSource() { - super("PersistedConfigSource", 300); + public static final String NAME = "PersistedConfigSource"; + static final String KEYCLOAK_PROPERTIES = "persisted.properties"; + + public PersistedConfigSource(Path file) { + super(readProperties(file), "", 300); + } + + @Override + public String getName() { + return NAME; } @Override @@ -40,13 +52,32 @@ public class PersistedConfigSource extends AbstractConfigSource { @Override public String getValue(String propertyName) { - String canonicalFormat = PropertyMappers.canonicalFormat(propertyName); - String value = KeycloakRecorder.getBuiltTimeProperty(canonicalFormat); + String value = super.getValue(propertyName); if (value != null) { return value; } - - return KeycloakRecorder.getBuiltTimeProperty(propertyName); + + if (propertyName.startsWith(MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX)) { + return super.getValue(PropertyMappers.toCLIFormat(propertyName)); + } + + return null; + } + + private static Map readProperties(Path path) { + if (!Environment.isRebuild()) { + File file = path.toFile(); + + if (file.exists()) { + try { + return ConfigSourceUtil.urlToMap(file.toURL()); + } catch (IOException e) { + throw new RuntimeException("Failed to load persisted properties from [" + file.getAbsolutePath() + ".", e); + } + } + } + + return Collections.emptyMap(); } } diff --git a/quarkus/runtime/src/main/java/org/keycloak/configuration/PropertyMapper.java b/quarkus/runtime/src/main/java/org/keycloak/configuration/PropertyMapper.java index 63d27ef62f..97a1b95aa6 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/configuration/PropertyMapper.java +++ b/quarkus/runtime/src/main/java/org/keycloak/configuration/PropertyMapper.java @@ -20,7 +20,6 @@ import static org.keycloak.util.Environment.getBuiltTimeProperty; import java.util.HashMap; import java.util.Map; -import java.util.Optional; import java.util.function.BiFunction; import java.util.function.Supplier; @@ -66,13 +65,6 @@ public class PropertyMapper { static PropertyMapper IDENTITY = new PropertyMapper(null, null, null, null, null) { @Override public ConfigValue getOrDefault(String name, ConfigSourceInterceptorContext context, ConfigValue current) { - if (current == null) { - ConfigValue.builder().withName(name) - .withValue(getBuiltTimeProperty(PropertyMappers.toCLIFormat(name)) - .orElseGet(() -> getBuiltTimeProperty(name) - .orElse(null))).build(); - } - return current; } }; @@ -122,27 +114,17 @@ public class PropertyMapper { ConfigValue config = context.proceed(from); if (config == null) { - Optional buildConfig = getBuiltTimeValue(from, context); - - if (buildConfig.isPresent()) { - return buildConfig.get(); - } - if (mapFrom != null) { // 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 + "." + mapFrom; - ConfigValue parentValue = getBuiltTimeValue(parentKey, context).orElseGet(() -> { - ConfigValue value = context.proceed(parentKey); - - if (value == null) { - return null; - } - - return transformValue(value.getValue(), context); - }); + ConfigValue parentValue = context.proceed(parentKey); if (parentValue != null) { - return parentValue; + ConfigValue value = transformValue(parentValue.getValue(), context); + + if (value != null) { + return value; + } } } @@ -181,18 +163,6 @@ public class PropertyMapper { return description; } - private Optional getBuiltTimeValue(String name, ConfigSourceInterceptorContext context) { - ConfigValue value = transformValue(getBuiltTimeProperty(name) - .orElseGet(() -> getBuiltTimeProperty(PropertyMappers.toCLIFormat(name)) - .orElse(null)), context); - - if (value == null) { - return Optional.empty(); - } - - return Optional.of(value); - } - private ConfigValue transformValue(String value, ConfigSourceInterceptorContext context) { if (value == null) { return null; diff --git a/quarkus/runtime/src/main/java/org/keycloak/configuration/PropertyMappers.java b/quarkus/runtime/src/main/java/org/keycloak/configuration/PropertyMappers.java index a5b790766f..bce4d4d80f 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/configuration/PropertyMappers.java +++ b/quarkus/runtime/src/main/java/org/keycloak/configuration/PropertyMappers.java @@ -30,7 +30,6 @@ import java.util.function.Predicate; import java.util.function.Supplier; import java.util.stream.Collectors; -import io.quarkus.runtime.configuration.ProfileManager; import io.smallrye.config.ConfigSourceInterceptorContext; import io.smallrye.config.ConfigValue; import org.keycloak.util.Environment; @@ -46,6 +45,7 @@ public final class PropertyMappers { configureHttpPropertyMappers(); configureProxyMappers(); configureClustering(); + configureHostnameProviderMappers(); } private static void configureHttpPropertyMappers() { @@ -130,7 +130,7 @@ public final class PropertyMappers { create("db", "quarkus.datasource.jdbc.transactions", (db, context) -> "xa", null); create("db.url", "db", "quarkus.datasource.jdbc.url", (value, context) -> Database.getDefaultUrl(value).orElse(value), "The database JDBC URL. If not provided a default URL is set based on the selected database vendor. For instance, if using 'postgres', the JDBC URL would be 'jdbc:postgresql://localhost/keycloak'. The host, database and properties can be overridden by setting the following system properties, respectively: -Dkc.db.url.host, -Dkc.db.url.database, -Dkc.db.url.properties."); create("db.username", "quarkus.datasource.username", "The database username."); - create("db.password", "quarkus.datasource.password", "The database password", true); + create("db.password", "quarkus.datasource.password", "The database password.", true); create("db.schema", "quarkus.datasource.schema", "The database schema."); create("db.pool.initial-size", "quarkus.datasource.jdbc.initial-size", "The initial size of the connection pool."); create("db.pool.min-size", "quarkus.datasource.jdbc.min-size", "The minimal size of the connection pool."); @@ -144,6 +144,12 @@ public final class PropertyMappers { create("cluster-stack", "kc.spi.connections-infinispan.default.stack", "Specified the default stack to use for cluster communication and node discovery. Possible values are: tcp, udp, kubernetes, ec2."); } + private static void configureHostnameProviderMappers() { + create("hostname-frontend-url", "kc.spi.hostname.default.frontend-url", "The URL that should be used to serve frontend requests that are usually sent through the a public domain."); + create("hostname-admin-url", "kc.spi.hostname.default.admin-url", "The URL that should be used to expose the admin endpoints and console."); + create("hostname-force-backend-url-to-frontend-url ", "kc.spi.hostname.default.force-backend-url-to-frontend-url", "Forces backend requests to go through the URL defined as the frontend-url. Defaults to false. Possible values are true or false."); + } + static ConfigValue getValue(ConfigSourceInterceptorContext context, String name) { return PropertyMapper.MAPPERS.getOrDefault(name, PropertyMapper.IDENTITY) .getOrDefault(name, context, context.proceed(name)); diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/KeycloakRecorder.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/KeycloakRecorder.java index e259a5cecf..9d59b11501 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/KeycloakRecorder.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/KeycloakRecorder.java @@ -17,11 +17,12 @@ package org.keycloak.quarkus; -import java.util.Collections; +import static org.keycloak.configuration.Configuration.getBuiltTimeProperty; +import static org.keycloak.configuration.Configuration.getConfig; + import java.util.List; import java.util.Map; import java.util.function.Predicate; -import java.util.function.Supplier; import java.util.stream.StreamSupport; import io.smallrye.config.ConfigValue; @@ -29,8 +30,9 @@ import org.jboss.logging.Logger; import org.keycloak.QuarkusKeycloakSessionFactory; import org.keycloak.cli.ShowConfigCommand; import org.keycloak.common.Profile; +import org.keycloak.configuration.Configuration; import org.keycloak.configuration.MicroProfileConfigProvider; -import org.keycloak.configuration.PropertyMapper; +import org.keycloak.configuration.PersistedConfigSource; import org.keycloak.configuration.PropertyMappers; import org.keycloak.connections.liquibase.FastServiceLocator; import org.keycloak.connections.liquibase.KeycloakLogger; @@ -39,8 +41,6 @@ import org.keycloak.provider.ProviderFactory; import org.keycloak.provider.Spi; import io.quarkus.runtime.annotations.Recorder; -import io.smallrye.config.SmallRyeConfig; -import io.smallrye.config.SmallRyeConfigProviderResolver; import liquibase.logging.LogFactory; import liquibase.servicelocator.ServiceLocator; import org.keycloak.util.Environment; @@ -49,37 +49,6 @@ import org.keycloak.util.Environment; public class KeycloakRecorder { private static final Logger LOGGER = Logger.getLogger(KeycloakRecorder.class); - - private static SmallRyeConfig CONFIG = null; - - private static Map BUILD_TIME_PROPERTIES = Collections.emptyMap(); - - public static String getBuiltTimeProperty(String name) { - String value = BUILD_TIME_PROPERTIES.get(name); - - if (value == null) { - String profile = Environment.getProfile(); - - if (profile == null) { - profile = BUILD_TIME_PROPERTIES.get("kc.profile"); - } - - value = BUILD_TIME_PROPERTIES.get("%" + profile + "." + name); - } - - if (value == null) { - value = BUILD_TIME_PROPERTIES.get(PropertyMappers.toCLIFormat(name)); - } - - return value; - } - - public static SmallRyeConfig getConfig() { - if (CONFIG == null) { - CONFIG = (SmallRyeConfig) SmallRyeConfigProviderResolver.instance().getConfig(); - } - return CONFIG; - } public void configureLiquibase(Map> services) { LogFactory.setInstance(new LogFactory() { @@ -124,8 +93,7 @@ public class KeycloakRecorder { * @param rebuild indicates whether or not the server was re-augmented * @param configArgs the configuration args if provided when the server was re-augmented */ - public void validateAndSetBuildTimeProperties(Map buildTimeProperties, Boolean rebuild, String configArgs) { - BUILD_TIME_PROPERTIES = buildTimeProperties; + public void validateAndSetBuildTimeProperties(Boolean rebuild, String configArgs) { String configHelpText = configArgs; for (String propertyName : getConfig().getPropertyNames()) { @@ -139,54 +107,53 @@ public class KeycloakRecorder { propertyName = propertyName.substring(propertyName.indexOf('.') + 1); } - String finalPropertyName = propertyName; - String buildValue = Environment.getBuiltTimeProperty(PropertyMappers.toCLIFormat(finalPropertyName)) - .orElseGet(new Supplier() { - @Override - public String get() { - return Environment.getBuiltTimeProperty(finalPropertyName).orElse(null); - } - }); - + String buildValue = Environment.getBuiltTimeProperty(propertyName).orElse(null); ConfigValue value = getConfig().getConfigValue(propertyName); - - // if no value found we try to resolve using the CLI format - if (value == null || value.getValue() == null) { - value = getConfig().getConfigValue(PropertyMappers.toCLIFormat(propertyName)); - } if (value.getValue() != null && !value.getValue().equalsIgnoreCase(buildValue)) { if (configHelpText != null) { + String cliNameFormat = PropertyMappers.toCLIFormat(propertyName); + if (buildValue != null) { - String currentProp = - "--" + PropertyMappers.toCLIFormat(propertyName).substring(3) + "=" + buildValue; - String newProp = - "--" + PropertyMappers.toCLIFormat(propertyName).substring(3) + "=" + value.getValue(); + String currentProp = "--" + cliNameFormat.substring(3) + "=" + buildValue; + String newProp = "--" + cliNameFormat.substring(3) + "=" + value.getValue(); if (configHelpText.contains(currentProp)) { LOGGER.warnf("The new value [%s] of the property [%s] in [%s] differs from the value [%s] set into the server image. The new value will override the value set into the server image.", value.getValue(), propertyName, value.getConfigSourceName(), buildValue); configHelpText = configHelpText.replaceAll(currentProp, newProp); } else if (!configHelpText - .contains("--" + PropertyMappers.toCLIFormat(propertyName).substring(3))) { + .contains("--" + cliNameFormat.substring(3))) { LOGGER.warnf("The new value [%s] of the property [%s] in [%s] differs from the value [%s] set into the server image. The new value will override the value set into the server image.", value.getValue(), propertyName, value.getConfigSourceName(), buildValue); configHelpText += " " + newProp; } - } else if (!BUILD_TIME_PROPERTIES.keySet().stream() - .anyMatch(new Predicate() { - @Override - public boolean test(String s) { - return PropertyMappers.canonicalFormat(finalPropertyName) - .equalsIgnoreCase(PropertyMappers.canonicalFormat(s)); - } - })) { - String prop = "--" + PropertyMappers.toCLIFormat(propertyName).substring(3) + "=" + value.getValue(); + } else { + String finalPropertyName = propertyName; - if (!configHelpText.contains(prop)) { - LOGGER.warnf("New property [%s] set with value [%s] in [%s]. This property is not persisted into the server image.", - propertyName, value.getValue(), value.getConfigSourceName(), buildValue); - configHelpText += " " + prop; + if (!StreamSupport.stream(getConfig().getPropertyNames().spliterator(), false) + .filter(new Predicate() { + @Override + public boolean test(String s) { + ConfigValue configValue = getConfig().getConfigValue(s); + + return configValue.getConfigSourceName().equals(PersistedConfigSource.NAME); + } + }) + .anyMatch(new Predicate() { + @Override + public boolean test(String s) { + return PropertyMappers.canonicalFormat(finalPropertyName) + .equalsIgnoreCase(PropertyMappers.canonicalFormat(s)); + } + })) { + String prop = "--" + cliNameFormat.substring(3) + "=" + value.getValue(); + + if (!configHelpText.contains(prop)) { + LOGGER.warnf("New property [%s] set with value [%s] in [%s]. This property is not persisted into the server image.", + propertyName, value.getValue(), value.getConfigSourceName(), buildValue); + configHelpText += " " + prop; + } } } } @@ -216,7 +183,7 @@ public class KeycloakRecorder { * set from the previous reaugmentation */ public void showConfig() { - ShowConfigCommand.run(BUILD_TIME_PROPERTIES); + ShowConfigCommand.run(); } public static Profile createProfile() { @@ -239,7 +206,7 @@ public class KeycloakRecorder { return value; } - return KeycloakRecorder.getConfig().getRawValue(feature); + return Configuration.getRawValue(feature); } }); } diff --git a/quarkus/runtime/src/main/java/org/keycloak/util/Environment.java b/quarkus/runtime/src/main/java/org/keycloak/util/Environment.java index 0b2912f569..2c074840cd 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/util/Environment.java +++ b/quarkus/runtime/src/main/java/org/keycloak/util/Environment.java @@ -19,8 +19,7 @@ package org.keycloak.util; import java.util.Optional; -import io.smallrye.config.SmallRyeConfig; -import org.keycloak.quarkus.KeycloakRecorder; +import org.keycloak.configuration.Configuration; public final class Environment { @@ -67,7 +66,7 @@ public final class Environment { } public static Optional getBuiltTimeProperty(String name) { - String value = KeycloakRecorder.getBuiltTimeProperty(name); + String value = Configuration.getBuiltTimeProperty(name); if (value == null) { return Optional.empty(); @@ -76,10 +75,6 @@ public final class Environment { return Optional.of(value); } - public static SmallRyeConfig getConfig() { - return KeycloakRecorder.getConfig(); - } - public static boolean isDevMode() { return "dev".equalsIgnoreCase(getProfile()); } diff --git a/quarkus/runtime/src/test/java/org/keycloak/provider/quarkus/ConfigurationTest.java b/quarkus/runtime/src/test/java/org/keycloak/provider/quarkus/ConfigurationTest.java index 7c2b03237f..90f9363122 100644 --- a/quarkus/runtime/src/test/java/org/keycloak/provider/quarkus/ConfigurationTest.java +++ b/quarkus/runtime/src/test/java/org/keycloak/provider/quarkus/ConfigurationTest.java @@ -18,7 +18,6 @@ package org.keycloak.provider.quarkus; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; import java.lang.reflect.Field; import java.util.HashMap; @@ -34,7 +33,6 @@ import org.junit.After; import org.junit.Assert; import org.junit.Test; import org.keycloak.Config; -import org.keycloak.common.util.StringPropertyReplacer; import org.keycloak.configuration.KeycloakConfigSourceProvider; import org.keycloak.configuration.MicroProfileConfigProvider;