Add a quarkus.properties for unsupported configuration options
Closes #9682
This commit is contained in:
parent
de161d02b9
commit
781ceb24fd
24 changed files with 730 additions and 47 deletions
|
@ -18,6 +18,8 @@
|
||||||
package org.keycloak.quarkus.deployment;
|
package org.keycloak.quarkus.deployment;
|
||||||
|
|
||||||
import static org.keycloak.quarkus.runtime.configuration.Configuration.getPropertyNames;
|
import static org.keycloak.quarkus.runtime.configuration.Configuration.getPropertyNames;
|
||||||
|
import static org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider.NS_QUARKUS;
|
||||||
|
import static org.keycloak.quarkus.runtime.configuration.QuarkusPropertiesConfigSource.QUARKUS_PROPERTY_ENABLED;
|
||||||
import static org.keycloak.quarkus.runtime.storage.database.jpa.QuarkusJpaConnectionProviderFactory.QUERY_PROPERTY_PREFIX;
|
import static org.keycloak.quarkus.runtime.storage.database.jpa.QuarkusJpaConnectionProviderFactory.QUERY_PROPERTY_PREFIX;
|
||||||
import static org.keycloak.connections.jpa.util.JpaUtils.loadSpecificNamedQueries;
|
import static org.keycloak.connections.jpa.util.JpaUtils.loadSpecificNamedQueries;
|
||||||
import static org.keycloak.representations.provider.ScriptProviderDescriptor.AUTHENTICATORS;
|
import static org.keycloak.representations.provider.ScriptProviderDescriptor.AUTHENTICATORS;
|
||||||
|
@ -82,6 +84,7 @@ import org.jboss.resteasy.plugins.server.servlet.ResteasyContextParameters;
|
||||||
import org.jboss.resteasy.spi.ResteasyDeployment;
|
import org.jboss.resteasy.spi.ResteasyDeployment;
|
||||||
import org.keycloak.Config;
|
import org.keycloak.Config;
|
||||||
import org.keycloak.quarkus.runtime.configuration.PersistedConfigSource;
|
import org.keycloak.quarkus.runtime.configuration.PersistedConfigSource;
|
||||||
|
import org.keycloak.quarkus.runtime.configuration.QuarkusPropertiesConfigSource;
|
||||||
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper;
|
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper;
|
||||||
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers;
|
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers;
|
||||||
import org.keycloak.quarkus.runtime.integration.jaxrs.QuarkusKeycloakApplication;
|
import org.keycloak.quarkus.runtime.integration.jaxrs.QuarkusKeycloakApplication;
|
||||||
|
@ -313,14 +316,21 @@ class KeycloakProcessor {
|
||||||
|
|
||||||
for (String name : getPropertyNames()) {
|
for (String name : getPropertyNames()) {
|
||||||
PropertyMapper mapper = PropertyMappers.getMapper(name);
|
PropertyMapper mapper = PropertyMappers.getMapper(name);
|
||||||
|
ConfigValue value = null;
|
||||||
|
|
||||||
if (mapper == null) {
|
if (mapper == null) {
|
||||||
|
if (name.startsWith(NS_QUARKUS)) {
|
||||||
|
value = Configuration.getConfigValue(name);
|
||||||
|
|
||||||
|
if (!QuarkusPropertiesConfigSource.isSameSource(value)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
} else if (mapper.isBuildTime()) {
|
||||||
|
value = Configuration.getConfigValue(mapper.getFrom());
|
||||||
|
}
|
||||||
|
|
||||||
ConfigValue value = Configuration.getConfigValue(mapper.getFrom());
|
if (value != null && value.getValue() != null) {
|
||||||
|
|
||||||
if (mapper.isBuildTime() && value != null && value.getValue() != null) {
|
|
||||||
properties.put(name, value.getValue());
|
properties.put(name, value.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -329,6 +339,8 @@ class KeycloakProcessor {
|
||||||
properties.put(String.format("kc.provider.file.%s.last-modified", jar.getName()), String.valueOf(jar.lastModified()));
|
properties.put(String.format("kc.provider.file.%s.last-modified", jar.getName()), String.valueOf(jar.lastModified()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
properties.put(QUARKUS_PROPERTY_ENABLED, String.valueOf(QuarkusPropertiesConfigSource.getConfigurationFile() != null));
|
||||||
|
|
||||||
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
|
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
|
||||||
properties.store(outputStream, " Auto-generated, DO NOT change this file");
|
properties.store(outputStream, " Auto-generated, DO NOT change this file");
|
||||||
resources.produce(new GeneratedResourceBuildItem(PersistedConfigSource.PERSISTED_PROPERTIES, outputStream.toByteArray()));
|
resources.produce(new GeneratedResourceBuildItem(PersistedConfigSource.PERSISTED_PROPERTIES, outputStream.toByteArray()));
|
||||||
|
|
|
@ -31,6 +31,7 @@ import java.util.Optional;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import io.quarkus.bootstrap.runner.RunnerClassLoader;
|
||||||
import io.quarkus.runtime.LaunchMode;
|
import io.quarkus.runtime.LaunchMode;
|
||||||
import io.quarkus.runtime.configuration.ProfileManager;
|
import io.quarkus.runtime.configuration.ProfileManager;
|
||||||
import org.apache.commons.lang3.SystemUtils;
|
import org.apache.commons.lang3.SystemUtils;
|
||||||
|
@ -48,7 +49,11 @@ public final class Environment {
|
||||||
private Environment() {}
|
private Environment() {}
|
||||||
|
|
||||||
public static Boolean isRebuild() {
|
public static Boolean isRebuild() {
|
||||||
return Boolean.getBoolean("quarkus.launch.rebuild");
|
return !isRuntimeMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Boolean isRuntimeMode() {
|
||||||
|
return Thread.currentThread().getContextClassLoader() instanceof RunnerClassLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getHomeDir() {
|
public static String getHomeDir() {
|
||||||
|
@ -187,4 +192,8 @@ public final class Environment {
|
||||||
public static boolean isDistribution() {
|
public static boolean isDistribution() {
|
||||||
return getHomeDir() != null;
|
return getHomeDir() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isRebuildCheck() {
|
||||||
|
return Boolean.getBoolean("kc.config.rebuild-and-exit");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,7 @@ public final class Picocli {
|
||||||
public static void parseAndRun(List<String> cliArgs) {
|
public static void parseAndRun(List<String> cliArgs) {
|
||||||
CommandLine cmd = createCommandLine(cliArgs);
|
CommandLine cmd = createCommandLine(cliArgs);
|
||||||
|
|
||||||
if (Boolean.getBoolean("kc.config.rebuild-and-exit")) {
|
if (Environment.isRebuildCheck()) {
|
||||||
runReAugmentationIfNeeded(cliArgs, cmd);
|
runReAugmentationIfNeeded(cliArgs, cmd);
|
||||||
Quarkus.asyncExit(cmd.getCommandSpec().exitCodeOnSuccess());
|
Quarkus.asyncExit(cmd.getCommandSpec().exitCodeOnSuccess());
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -43,6 +43,9 @@ public class KeycloakConfigSourceProvider implements ConfigSourceProvider {
|
||||||
|
|
||||||
CONFIG_SOURCES.add(new ConfigArgsConfigSource());
|
CONFIG_SOURCES.add(new ConfigArgsConfigSource());
|
||||||
CONFIG_SOURCES.add(new KcEnvConfigSource());
|
CONFIG_SOURCES.add(new KcEnvConfigSource());
|
||||||
|
|
||||||
|
CONFIG_SOURCES.addAll(new QuarkusPropertiesConfigSource().getConfigSources(Thread.currentThread().getContextClassLoader()));
|
||||||
|
|
||||||
CONFIG_SOURCES.add(PersistedConfigSource.getInstance());
|
CONFIG_SOURCES.add(PersistedConfigSource.getInstance());
|
||||||
|
|
||||||
CONFIG_SOURCES.addAll(new KeycloakPropertiesConfigSource.InFileSystem().getConfigSources(Thread.currentThread().getContextClassLoader()));
|
CONFIG_SOURCES.addAll(new KeycloakPropertiesConfigSource.InFileSystem().getConfigSources(Thread.currentThread().getContextClassLoader()));
|
||||||
|
|
|
@ -28,12 +28,13 @@ import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.eclipse.microprofile.config.spi.ConfigSource;
|
import org.eclipse.microprofile.config.spi.ConfigSource;
|
||||||
import org.eclipse.microprofile.config.spi.ConfigSourceProvider;
|
import org.eclipse.microprofile.config.spi.ConfigSourceProvider;
|
||||||
import org.keycloak.quarkus.runtime.Environment;
|
import org.keycloak.quarkus.runtime.Environment;
|
||||||
|
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper;
|
||||||
|
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers;
|
||||||
|
|
||||||
import io.smallrye.config.AbstractLocationConfigSourceLoader;
|
import io.smallrye.config.AbstractLocationConfigSourceLoader;
|
||||||
import io.smallrye.config.PropertiesConfigSource;
|
import io.smallrye.config.PropertiesConfigSource;
|
||||||
|
@ -62,7 +63,7 @@ public class KeycloakPropertiesConfigSource extends AbstractLocationConfigSource
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ConfigSource loadConfigSource(URL url, int ordinal) throws IOException {
|
protected ConfigSource loadConfigSource(URL url, int ordinal) throws IOException {
|
||||||
return new PropertiesConfigSource(transform(ConfigSourceUtil.urlToMap(url)), KEYCLOAK_CONF_FILE, ordinal);
|
return new PropertiesConfigSource(transform(ConfigSourceUtil.urlToMap(url)), url.toString(), ordinal);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class InClassPath extends KeycloakPropertiesConfigSource implements ConfigSourceProvider {
|
public static class InClassPath extends KeycloakPropertiesConfigSource implements ConfigSourceProvider {
|
||||||
|
@ -143,11 +144,22 @@ public class KeycloakPropertiesConfigSource extends AbstractLocationConfigSource
|
||||||
Map<String, String> result = new HashMap<>(properties.size());
|
Map<String, String> result = new HashMap<>(properties.size());
|
||||||
properties.keySet().forEach(k -> {
|
properties.keySet().forEach(k -> {
|
||||||
String key = transformKey(k);
|
String key = transformKey(k);
|
||||||
|
PropertyMapper mapper = PropertyMappers.getMapper(key);
|
||||||
|
|
||||||
|
//TODO: remove explicit checks for spi and feature options once we have proper support in our config mappers
|
||||||
|
if (mapper != null
|
||||||
|
|| key.contains(NS_KEYCLOAK_PREFIX + "spi")
|
||||||
|
|| key.contains(NS_KEYCLOAK_PREFIX + "feature")) {
|
||||||
String value = replaceProperties(properties.get(k));
|
String value = replaceProperties(properties.get(k));
|
||||||
|
|
||||||
result.put(key, value);
|
result.put(key, value);
|
||||||
|
|
||||||
|
if (mapper != null && key.charAt(0) != '%') {
|
||||||
result.put(getMappedPropertyName(key), value);
|
result.put(getMappedPropertyName(key), value);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,14 @@
|
||||||
*/
|
*/
|
||||||
package org.keycloak.quarkus.runtime.configuration;
|
package org.keycloak.quarkus.runtime.configuration;
|
||||||
|
|
||||||
|
import static org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider.NS_QUARKUS;
|
||||||
|
|
||||||
|
import io.quarkus.runtime.configuration.AbstractRawDefaultConfigSource;
|
||||||
import io.smallrye.config.ConfigSourceInterceptor;
|
import io.smallrye.config.ConfigSourceInterceptor;
|
||||||
import io.smallrye.config.ConfigSourceInterceptorContext;
|
import io.smallrye.config.ConfigSourceInterceptorContext;
|
||||||
import io.smallrye.config.ConfigValue;
|
import io.smallrye.config.ConfigValue;
|
||||||
import org.keycloak.common.util.StringPropertyReplacer;
|
import org.keycloak.common.util.StringPropertyReplacer;
|
||||||
|
import org.keycloak.quarkus.runtime.Environment;
|
||||||
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper;
|
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper;
|
||||||
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers;
|
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers;
|
||||||
|
|
||||||
|
@ -35,6 +39,8 @@ import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers;
|
||||||
*/
|
*/
|
||||||
public class PropertyMappingInterceptor implements ConfigSourceInterceptor {
|
public class PropertyMappingInterceptor implements ConfigSourceInterceptor {
|
||||||
|
|
||||||
|
private final boolean isQuarkusPropertiesEnabled = QuarkusPropertiesConfigSource.isQuarkusPropertiesEnabled();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConfigValue getValue(ConfigSourceInterceptorContext context, String name) {
|
public ConfigValue getValue(ConfigSourceInterceptorContext context, String name) {
|
||||||
ConfigValue value = PropertyMappers.getValue(context, name);
|
ConfigValue value = PropertyMappers.getValue(context, name);
|
||||||
|
@ -43,6 +49,11 @@ public class PropertyMappingInterceptor implements ConfigSourceInterceptor {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isPersistedOnlyProperty(value)) {
|
||||||
|
// quarkus properties values always resolved from persisted config source
|
||||||
|
return value.withValue(PersistedConfigSource.getInstance().getValue(name));
|
||||||
|
}
|
||||||
|
|
||||||
if (value.getValue().indexOf("${") == -1) {
|
if (value.getValue().indexOf("${") == -1) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -59,4 +70,19 @@ public class PropertyMappingInterceptor implements ConfigSourceInterceptor {
|
||||||
return prop.getValue();
|
return prop.getValue();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isPersistedOnlyProperty(ConfigValue value) {
|
||||||
|
if (isQuarkusPropertiesEnabled && value.getName().startsWith(NS_QUARKUS)) {
|
||||||
|
String configSourceName = value.getConfigSourceName();
|
||||||
|
|
||||||
|
return Environment.isRuntimeMode()
|
||||||
|
&& configSourceName != null
|
||||||
|
&& !configSourceName.equals(PersistedConfigSource.NAME)
|
||||||
|
&& !configSourceName.equals(AbstractRawDefaultConfigSource.NAME)
|
||||||
|
&& !configSourceName.contains("Runtime Defaults")
|
||||||
|
&& !configSourceName.contains("application.properties");
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,140 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 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.quarkus.runtime.configuration;
|
||||||
|
|
||||||
|
import static java.lang.Boolean.parseBoolean;
|
||||||
|
import static org.keycloak.quarkus.runtime.configuration.Configuration.getRawPersistedProperty;
|
||||||
|
import static org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider.NS_QUARKUS;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.nio.file.NoSuchFileException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import org.eclipse.microprofile.config.spi.ConfigSource;
|
||||||
|
import org.eclipse.microprofile.config.spi.ConfigSourceProvider;
|
||||||
|
import org.keycloak.quarkus.runtime.Environment;
|
||||||
|
|
||||||
|
import io.smallrye.config.AbstractLocationConfigSourceLoader;
|
||||||
|
import io.smallrye.config.ConfigValue;
|
||||||
|
import io.smallrye.config.PropertiesConfigSource;
|
||||||
|
import io.smallrye.config.common.utils.ConfigSourceUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A configuration source for {@code quarkus.properties}.
|
||||||
|
*/
|
||||||
|
public final class QuarkusPropertiesConfigSource extends AbstractLocationConfigSourceLoader implements ConfigSourceProvider {
|
||||||
|
|
||||||
|
private static final String NAME = "QuarkusProperties";
|
||||||
|
private static final String FILE_NAME = "quarkus.properties";
|
||||||
|
public static final String QUARKUS_PROPERTY_ENABLED = "kc.quarkus-properties-enabled";
|
||||||
|
|
||||||
|
public static boolean isSameSource(ConfigValue value) {
|
||||||
|
if (value == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NAME.equals(value.getConfigSourceName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isQuarkusPropertiesEnabled() {
|
||||||
|
return parseBoolean(getRawPersistedProperty(QUARKUS_PROPERTY_ENABLED).orElse(Boolean.FALSE.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Path getConfigurationFile() {
|
||||||
|
String homeDir = Environment.getHomeDir();
|
||||||
|
|
||||||
|
if (homeDir != null) {
|
||||||
|
File file = Paths.get(homeDir, "conf", FILE_NAME).toFile();
|
||||||
|
|
||||||
|
if (file.exists()) {
|
||||||
|
return file.toPath();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String[] getFileExtensions() {
|
||||||
|
return new String[] { "properties" };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ConfigSource loadConfigSource(URL url, int ordinal) throws IOException {
|
||||||
|
return new PropertiesConfigSource(ConfigSourceUtil.urlToMap(url), FILE_NAME, ordinal) {
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getValue(String propertyName) {
|
||||||
|
if (propertyName.startsWith(NS_QUARKUS)) {
|
||||||
|
String value = super.getValue(propertyName);
|
||||||
|
|
||||||
|
if (value == null) {
|
||||||
|
return PersistedConfigSource.getInstance().getValue(propertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ConfigSource> getConfigSources(final ClassLoader classLoader) {
|
||||||
|
List<ConfigSource> configSources = new ArrayList<>();
|
||||||
|
|
||||||
|
configSources.addAll(loadConfigSources("META-INF/services/" + FILE_NAME, 450, classLoader));
|
||||||
|
|
||||||
|
if (Environment.isRebuild() || Environment.isRebuildCheck()) {
|
||||||
|
Path configFile = getConfigurationFile();
|
||||||
|
|
||||||
|
if (configFile != null) {
|
||||||
|
configSources.addAll(loadConfigSources(configFile.toUri().toString(), 500, classLoader));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return configSources;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<ConfigSource> tryClassPath(URI uri, int ordinal, ClassLoader classLoader) {
|
||||||
|
try {
|
||||||
|
return super.tryClassPath(uri, ordinal, classLoader);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
Throwable cause = e.getCause();
|
||||||
|
if (cause instanceof NoSuchFileException) {
|
||||||
|
// configuration step happens before classpath is updated, and it might happen that
|
||||||
|
// provider JARs are still in classpath index but removed from the providers dir
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -49,7 +49,7 @@ public final class PropertyMappers {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isBuildTimeProperty(String name) {
|
public static boolean isBuildTimeProperty(String name) {
|
||||||
if (isFeaturesBuildTimeProperty(name) || isSpiBuildTimeProperty(name)) {
|
if (isFeaturesBuildTimeProperty(name) || isSpiBuildTimeProperty(name) || name.startsWith(MicroProfileConfigProvider.NS_QUARKUS)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,6 +123,9 @@ public final class PropertyMappers {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PropertyMapper getMapper(String property) {
|
public static PropertyMapper getMapper(String property) {
|
||||||
|
if (property.startsWith("%")) {
|
||||||
|
return MAPPERS.get(property.substring(property.indexOf('.') + 1));
|
||||||
|
}
|
||||||
return MAPPERS.get(property);
|
return MAPPERS.get(property);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,3 @@ metrics-enabled=false
|
||||||
%import_export.hostname-strict=false
|
%import_export.hostname-strict=false
|
||||||
%import_export.hostname-strict-https=false
|
%import_export.hostname-strict-https=false
|
||||||
%import_export.cluster=local
|
%import_export.cluster=local
|
||||||
|
|
||||||
# Logging configuration. INFO is the default level for most of the categories
|
|
||||||
#quarkus.log.level = DEBUG
|
|
||||||
quarkus.log.category."org.jboss.resteasy.resteasy_jaxrs.i18n".level=WARN
|
|
||||||
quarkus.log.category."org.infinispan.transaction.lookup.JBossStandaloneJTAManagerLookup".level=WARN
|
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
#
|
||||||
|
# Copyright 2021 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
# Default options that rely on Quarkus specific options and lacking proper support in Keycloak
|
||||||
|
|
||||||
|
# Logging configuration. INFO is the default level for most of the categories
|
||||||
|
quarkus.log.level = INFO
|
||||||
|
quarkus.log.category."org.jboss.resteasy.resteasy_jaxrs.i18n".level=WARN
|
||||||
|
quarkus.log.category."org.infinispan.transaction.lookup.JBossStandaloneJTAManagerLookup".level=WARN
|
|
@ -391,6 +391,15 @@ public class ConfigurationTest {
|
||||||
assertEquals("my_secret=", config.getConfigValue("kc.db-password").getValue());
|
assertEquals("my_secret=", config.getConfigValue("kc.db-password").getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testResolvePropertyFromDefaultProfile() {
|
||||||
|
Environment.setProfile("import_export");
|
||||||
|
assertEquals("false", createConfig().getConfigValue("kc.hostname-strict").getValue());
|
||||||
|
|
||||||
|
Environment.setProfile("prod");
|
||||||
|
assertEquals("true", createConfig().getConfigValue("kc.hostname-strict").getValue());
|
||||||
|
}
|
||||||
|
|
||||||
private Config.Scope initConfig(String... scope) {
|
private Config.Scope initConfig(String... scope) {
|
||||||
Config.init(new MicroProfileConfigProvider(createConfig()));
|
Config.init(new MicroProfileConfigProvider(createConfig()));
|
||||||
return Config.scope(scope);
|
return Config.scope(scope);
|
||||||
|
|
|
@ -1,15 +1,2 @@
|
||||||
spi-hostname-default-frontend-url = ${keycloak.frontendUrl:http://filepropdefault.unittest}
|
spi-hostname-default-frontend-url = ${keycloak.frontendUrl:http://filepropdefault.unittest}
|
||||||
%user-profile.spi-hostname-default-frontend-url = http://filepropprofile.unittest
|
%user-profile.spi-hostname-default-frontend-url = http://filepropprofile.unittest
|
||||||
|
|
||||||
# Default Non-Production Grade Datasource
|
|
||||||
quarkus.datasource.db-kind=h2
|
|
||||||
quarkus.hibernate-orm.dialect=org.hibernate.dialect.H2Dialect
|
|
||||||
quarkus.datasource.jdbc.driver=org.h2.jdbcx.JdbcDataSource
|
|
||||||
quarkus.datasource.jdbc.url = jdbc:h2:file:${kc.home.dir:~}/data/keycloakdb;;AUTO_SERVER=TRUE
|
|
||||||
quarkus.datasource.username = sa
|
|
||||||
quarkus.datasource.password = keycloak
|
|
||||||
quarkus.datasource.jdbc.transactions=xa
|
|
||||||
|
|
||||||
# For test nested properties
|
|
||||||
quarkus.datasource.foo = jdbc:h2:file:${kc.home.dir:${kc.db.url.path:~}}/data/keycloakdb
|
|
||||||
quarkus.datasource.bar = foo-${kc.prop3:${kc.prop4:${kc.prop5:def}-suffix}}
|
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
# Default options that rely on Quarkus specific options and lacking proper support in Keycloak
|
||||||
|
|
||||||
|
# Logging configuration. INFO is the default level for most of the categories
|
||||||
|
quarkus.log.level = INFO
|
||||||
|
quarkus.log.category."org.jboss.resteasy.resteasy_jaxrs.i18n".level=WARN
|
||||||
|
quarkus.log.category."org.infinispan.transaction.lookup.JBossStandaloneJTAManagerLookup".level=WARN
|
||||||
|
|
||||||
|
# For test nested properties
|
||||||
|
quarkus.datasource.foo = jdbc:h2:file:${kc.home.dir:${kc.db.url.path:~}}/data/keycloakdb
|
||||||
|
quarkus.datasource.bar = foo-${kc.prop3:${kc.prop4:${kc.prop5:def}-suffix}}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 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.it.junit5.extension;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import org.keycloak.it.utils.KeycloakDistribution;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link BeforeStartDistribution} is used to perform additional steps prior to starting the distribution.
|
||||||
|
*/
|
||||||
|
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface BeforeStartDistribution {
|
||||||
|
|
||||||
|
Class<? extends Consumer<KeycloakDistribution>> value();
|
||||||
|
|
||||||
|
}
|
|
@ -81,4 +81,20 @@ public interface CLIResult extends LaunchResult {
|
||||||
default void assertBuild() {
|
default void assertBuild() {
|
||||||
assertMessage("Server configuration updated and persisted");
|
assertMessage("Server configuration updated and persisted");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default void assertNoBuild() {
|
||||||
|
assertFalse(getOutput().contains("Server configuration updated and persisted"));
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean isClustered() {
|
||||||
|
return getOutput().contains("Starting JGroups channel `ISPN`");
|
||||||
|
}
|
||||||
|
|
||||||
|
default void assertLocalCache() {
|
||||||
|
assertFalse(isClustered());
|
||||||
|
}
|
||||||
|
|
||||||
|
default void assertClusteredCache() {
|
||||||
|
assertTrue(isClustered());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,6 +83,10 @@ public class CLITestExtension extends QuarkusMainTestExtension {
|
||||||
if (dist == null) {
|
if (dist == null) {
|
||||||
dist = createDistribution(distConfig);
|
dist = createDistribution(distConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onBeforeStartDistribution(context.getRequiredTestClass().getAnnotation(BeforeStartDistribution.class));
|
||||||
|
onBeforeStartDistribution(context.getRequiredTestMethod().getAnnotation(BeforeStartDistribution.class));
|
||||||
|
|
||||||
dist.start(Arrays.asList(launch.value()));
|
dist.start(Arrays.asList(launch.value()));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -94,6 +98,16 @@ public class CLITestExtension extends QuarkusMainTestExtension {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onBeforeStartDistribution(BeforeStartDistribution annotation) {
|
||||||
|
if (annotation != null) {
|
||||||
|
try {
|
||||||
|
annotation.value().getDeclaredConstructor().newInstance().accept(dist);
|
||||||
|
} catch (Exception cause) {
|
||||||
|
throw new RuntimeException("Error when invoking " + annotation.value() + " instance before starting distribution", cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterEach(ExtensionContext context) throws Exception {
|
public void afterEach(ExtensionContext context) throws Exception {
|
||||||
DistributionTest distConfig = getDistributionConfig(context);
|
DistributionTest distConfig = getDistributionConfig(context);
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 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.it.junit5.extension;
|
||||||
|
|
||||||
|
import org.keycloak.it.utils.KeycloakDistribution;
|
||||||
|
|
||||||
|
public interface DistributionLifecycleManager<D extends KeycloakDistribution> {
|
||||||
|
|
||||||
|
void beforeStart(D distribution);
|
||||||
|
}
|
|
@ -38,4 +38,16 @@ public interface KeycloakDistribution {
|
||||||
|
|
||||||
return commands.toArray(new String[0]);
|
return commands.toArray(new String[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default void setQuarkusProperty(String key, String value) {
|
||||||
|
throw new RuntimeException("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
default void setProperty(String key, String value) {
|
||||||
|
throw new RuntimeException("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
default void deleteQuarkusProperties() {
|
||||||
|
throw new RuntimeException("Not implemented");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@ package org.keycloak.it.utils;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
|
@ -32,6 +34,7 @@ import java.security.SecureRandom;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
@ -60,6 +63,7 @@ public final class RawKeycloakDistribution implements KeycloakDistribution {
|
||||||
private boolean debug;
|
private boolean debug;
|
||||||
private boolean reCreate;
|
private boolean reCreate;
|
||||||
private ExecutorService outputExecutor;
|
private ExecutorService outputExecutor;
|
||||||
|
private boolean inited = false;
|
||||||
|
|
||||||
public RawKeycloakDistribution(boolean debug, boolean manualStop, boolean reCreate) {
|
public RawKeycloakDistribution(boolean debug, boolean manualStop, boolean reCreate) {
|
||||||
this.debug = debug;
|
this.debug = debug;
|
||||||
|
@ -254,7 +258,7 @@ public final class RawKeycloakDistribution implements KeycloakDistribution {
|
||||||
String distDirName = distFile.getName().replace("keycloak-server-x-dist", "keycloak.x");
|
String distDirName = distFile.getName().replace("keycloak-server-x-dist", "keycloak.x");
|
||||||
Path distPath = distRootPath.resolve(distDirName.substring(0, distDirName.lastIndexOf('.')));
|
Path distPath = distRootPath.resolve(distDirName.substring(0, distDirName.lastIndexOf('.')));
|
||||||
|
|
||||||
if (reCreate || !distPath.toFile().exists()) {
|
if (!inited || (reCreate || !distPath.toFile().exists())) {
|
||||||
distPath.toFile().delete();
|
distPath.toFile().delete();
|
||||||
ZipUtils.unzip(distFile.toPath(), distRootPath);
|
ZipUtils.unzip(distFile.toPath(), distRootPath);
|
||||||
}
|
}
|
||||||
|
@ -264,6 +268,8 @@ public final class RawKeycloakDistribution implements KeycloakDistribution {
|
||||||
throw new RuntimeException("Cannot set kc.sh executable");
|
throw new RuntimeException("Cannot set kc.sh executable");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inited = true;
|
||||||
|
|
||||||
return distPath;
|
return distPath;
|
||||||
} catch (Exception cause) {
|
} catch (Exception cause) {
|
||||||
throw new RuntimeException("Failed to prepare distribution", cause);
|
throw new RuntimeException("Failed to prepare distribution", cause);
|
||||||
|
@ -311,4 +317,51 @@ public final class RawKeycloakDistribution implements KeycloakDistribution {
|
||||||
|
|
||||||
keycloak = builder.start();
|
keycloak = builder.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProperty(String key, String value) {
|
||||||
|
setProperty(key, value, distPath.resolve("conf").resolve("keycloak.conf").toFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setQuarkusProperty(String key, String value) {
|
||||||
|
setProperty(key, value, getQuarkusPropertiesFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteQuarkusProperties() {
|
||||||
|
File file = getQuarkusPropertiesFile();
|
||||||
|
|
||||||
|
if (file.exists()) {
|
||||||
|
file.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setProperty(String key, String value, File confFile) {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
|
||||||
|
if (confFile.exists()) {
|
||||||
|
try (
|
||||||
|
FileInputStream in = new FileInputStream(confFile);
|
||||||
|
) {
|
||||||
|
|
||||||
|
properties.load(in);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Failed to update " + confFile, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try (
|
||||||
|
FileOutputStream out = new FileOutputStream(confFile)
|
||||||
|
) {
|
||||||
|
properties.put(key, value);
|
||||||
|
properties.store(out, "");
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Failed to update " + confFile, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private File getQuarkusPropertiesFile() {
|
||||||
|
return distPath.resolve("conf").resolve("quarkus.properties").toFile();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,18 +17,16 @@
|
||||||
|
|
||||||
package org.keycloak.it.cli.dist;
|
package org.keycloak.it.cli.dist;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.junit.jupiter.api.MethodOrderer;
|
|
||||||
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
|
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
|
||||||
import org.junit.jupiter.api.Order;
|
import org.junit.jupiter.api.Order;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.TestMethodOrder;
|
import org.junit.jupiter.api.TestMethodOrder;
|
||||||
import org.junit.jupiter.api.condition.DisabledIf;
|
import org.keycloak.it.junit5.extension.BeforeStartDistribution;
|
||||||
import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
|
|
||||||
import org.keycloak.it.junit5.extension.CLIResult;
|
import org.keycloak.it.junit5.extension.CLIResult;
|
||||||
import org.keycloak.it.junit5.extension.DistributionTest;
|
import org.keycloak.it.junit5.extension.DistributionTest;
|
||||||
import org.keycloak.it.junit5.extension.RawDistOnly;
|
import org.keycloak.it.junit5.extension.RawDistOnly;
|
||||||
|
import org.keycloak.it.utils.KeycloakDistribution;
|
||||||
|
|
||||||
import io.quarkus.test.junit.main.Launch;
|
import io.quarkus.test.junit.main.Launch;
|
||||||
import io.quarkus.test.junit.main.LaunchResult;
|
import io.quarkus.test.junit.main.LaunchResult;
|
||||||
|
@ -41,14 +39,45 @@ public class BuildAndStartDistTest {
|
||||||
@Test
|
@Test
|
||||||
@Launch({ "build", "--cache=local" })
|
@Launch({ "build", "--cache=local" })
|
||||||
@Order(1)
|
@Order(1)
|
||||||
void firstYouBuild(LaunchResult result) {
|
void testBuildWithCliArgs(LaunchResult result) {
|
||||||
|
CLIResult cliResult = (CLIResult) result;
|
||||||
|
cliResult.assertBuild();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Launch({ "start", "--http-enabled=true", "--hostname-strict=false" })
|
@Launch({ "start", "--http-enabled=true", "--hostname-strict=false" })
|
||||||
@Order(2)
|
@Order(2)
|
||||||
void thenYouStart(LaunchResult result) {
|
void testStartUsingCliArgs(LaunchResult result) {
|
||||||
CLIResult cliResult = (CLIResult) result;
|
CLIResult cliResult = (CLIResult) result;
|
||||||
cliResult.assertStarted();
|
cliResult.assertStarted();
|
||||||
|
cliResult.assertLocalCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@BeforeStartDistribution(SetDefaultOptions.class)
|
||||||
|
@Launch({ "build" })
|
||||||
|
@Order(3)
|
||||||
|
void testBuildUsingConfFile(LaunchResult result) {
|
||||||
|
CLIResult cliResult = (CLIResult) result;
|
||||||
|
cliResult.assertBuild();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Launch({ "start" })
|
||||||
|
@Order(4)
|
||||||
|
void testStartUsingConfFile(LaunchResult result) {
|
||||||
|
CLIResult cliResult = (CLIResult) result;
|
||||||
|
cliResult.assertStarted();
|
||||||
|
cliResult.assertLocalCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SetDefaultOptions implements Consumer<KeycloakDistribution> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(KeycloakDistribution distribution) {
|
||||||
|
distribution.setProperty("http-enabled", "true");
|
||||||
|
distribution.setProperty("hostname-strict", "false");
|
||||||
|
distribution.setProperty("cache", "local");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,8 @@ public class ClusterConfigDistTest {
|
||||||
@Test
|
@Test
|
||||||
@Launch({ "start-dev", "--cache=ispn" })
|
@Launch({ "start-dev", "--cache=ispn" })
|
||||||
void changeClusterSetting(LaunchResult result) {
|
void changeClusterSetting(LaunchResult result) {
|
||||||
assertTrue(isClustered(result));
|
CLIResult cliResult = (CLIResult) result;
|
||||||
|
cliResult.assertClusteredCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -61,7 +62,7 @@ public class ClusterConfigDistTest {
|
||||||
void testExplicitCacheConfigFile(LaunchResult result) {
|
void testExplicitCacheConfigFile(LaunchResult result) {
|
||||||
CLIResult cliResult = (CLIResult) result;
|
CLIResult cliResult = (CLIResult) result;
|
||||||
cliResult.assertStartedDevMode();
|
cliResult.assertStartedDevMode();
|
||||||
assertTrue(isClustered(cliResult));
|
cliResult.assertClusteredCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -69,7 +70,7 @@ public class ClusterConfigDistTest {
|
||||||
void testStartDefaultsToClustering(LaunchResult result) {
|
void testStartDefaultsToClustering(LaunchResult result) {
|
||||||
CLIResult cliResult = (CLIResult) result;
|
CLIResult cliResult = (CLIResult) result;
|
||||||
cliResult.assertStarted();
|
cliResult.assertStarted();
|
||||||
assertTrue(isClustered(result));
|
cliResult.assertClusteredCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -77,10 +78,6 @@ public class ClusterConfigDistTest {
|
||||||
void testStartDevDefaultsToLocalCaches(LaunchResult result) {
|
void testStartDevDefaultsToLocalCaches(LaunchResult result) {
|
||||||
CLIResult cliResult = (CLIResult) result;
|
CLIResult cliResult = (CLIResult) result;
|
||||||
cliResult.assertStartedDevMode();
|
cliResult.assertStartedDevMode();
|
||||||
assertFalse(isClustered(result));
|
cliResult.assertLocalCache();
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isClustered(LaunchResult result) {
|
|
||||||
return result.getOutput().contains("Starting JGroups channel `ISPN`");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 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.it.cli.dist;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
|
||||||
|
import org.junit.jupiter.api.Order;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.TestMethodOrder;
|
||||||
|
import org.keycloak.it.junit5.extension.BeforeStartDistribution;
|
||||||
|
import org.keycloak.it.junit5.extension.CLIResult;
|
||||||
|
import org.keycloak.it.junit5.extension.DistributionTest;
|
||||||
|
import org.keycloak.it.junit5.extension.RawDistOnly;
|
||||||
|
import org.keycloak.it.utils.KeycloakDistribution;
|
||||||
|
|
||||||
|
import io.quarkus.test.junit.main.Launch;
|
||||||
|
import io.quarkus.test.junit.main.LaunchResult;
|
||||||
|
|
||||||
|
@DistributionTest(reInstall = DistributionTest.ReInstall.NEVER)
|
||||||
|
@BeforeStartDistribution(QuarkusPropertiesAutoBuildDistTest.SetDebugLogLevel.class)
|
||||||
|
@RawDistOnly(reason = "Containers are immutable")
|
||||||
|
@TestMethodOrder(OrderAnnotation.class)
|
||||||
|
public class QuarkusPropertiesAutoBuildDistTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Launch({ "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
|
||||||
|
@Order(1)
|
||||||
|
void testReAugOnFirstRun(LaunchResult result) {
|
||||||
|
CLIResult cliResult = (CLIResult) result;
|
||||||
|
cliResult.assertBuild();
|
||||||
|
cliResult.assertMessage("DEBUG [");
|
||||||
|
cliResult.assertStarted();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Launch({ "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
|
||||||
|
@Order(2)
|
||||||
|
void testSecondStartDoNotTriggerReAug(LaunchResult result) {
|
||||||
|
CLIResult cliResult = (CLIResult) result;
|
||||||
|
cliResult.assertNoBuild();
|
||||||
|
cliResult.assertMessage("DEBUG [");
|
||||||
|
cliResult.assertStarted();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@BeforeStartDistribution(SetInfoLogLevel.class)
|
||||||
|
@Launch({ "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
|
||||||
|
@Order(3)
|
||||||
|
void testReAugAfterChangingProperty(LaunchResult result) {
|
||||||
|
CLIResult cliResult = (CLIResult) result;
|
||||||
|
cliResult.assertBuild();
|
||||||
|
assertFalse(cliResult.getOutput().contains("DEBUG ["));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SetDebugLogLevel implements Consumer<KeycloakDistribution> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(KeycloakDistribution distribution) {
|
||||||
|
distribution.setQuarkusProperty("quarkus.log.level", "DEBUG");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SetInfoLogLevel implements Consumer<KeycloakDistribution> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(KeycloakDistribution distribution) {
|
||||||
|
distribution.setQuarkusProperty("quarkus.log.level", "INFO");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
104
quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/QuarkusPropertiesDistTest.java
vendored
Normal file
104
quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/QuarkusPropertiesDistTest.java
vendored
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 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.it.cli.dist;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
|
||||||
|
import org.junit.jupiter.api.Order;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.TestMethodOrder;
|
||||||
|
import org.keycloak.it.junit5.extension.BeforeStartDistribution;
|
||||||
|
import org.keycloak.it.junit5.extension.CLIResult;
|
||||||
|
import org.keycloak.it.junit5.extension.DistributionTest;
|
||||||
|
import org.keycloak.it.junit5.extension.RawDistOnly;
|
||||||
|
import org.keycloak.it.utils.KeycloakDistribution;
|
||||||
|
|
||||||
|
import io.quarkus.test.junit.main.Launch;
|
||||||
|
import io.quarkus.test.junit.main.LaunchResult;
|
||||||
|
|
||||||
|
@DistributionTest(reInstall = DistributionTest.ReInstall.NEVER)
|
||||||
|
@BeforeStartDistribution(QuarkusPropertiesDistTest.SetDebugLogLevel.class)
|
||||||
|
@RawDistOnly(reason = "Containers are immutable")
|
||||||
|
@TestMethodOrder(OrderAnnotation.class)
|
||||||
|
public class QuarkusPropertiesDistTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Launch({ "build", "--cache=local" })
|
||||||
|
@Order(1)
|
||||||
|
void testBuildWithPropertyFromQuarkusProperties(LaunchResult result) {
|
||||||
|
CLIResult cliResult = (CLIResult) result;
|
||||||
|
cliResult.assertMessage("DEBUG [");
|
||||||
|
cliResult.assertBuild();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Launch({ "start", "--http-enabled=true", "--hostname-strict=false" })
|
||||||
|
@Order(2)
|
||||||
|
void testPropertyEnabledAtRuntime(LaunchResult result) {
|
||||||
|
CLIResult cliResult = (CLIResult) result;
|
||||||
|
cliResult.assertMessage("DEBUG [");
|
||||||
|
cliResult.assertStarted();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Launch({ "-Dquarkus.log.level=INFO", "start", "--http-enabled=true", "--hostname-strict=false" })
|
||||||
|
@Order(3)
|
||||||
|
void testIgnoreQuarkusSystemPropertiesAtStart(LaunchResult result) {
|
||||||
|
CLIResult cliResult = (CLIResult) result;
|
||||||
|
cliResult.assertMessage("DEBUG [");
|
||||||
|
cliResult.assertStarted();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Launch({ "-Dquarkus.log.level=INFO", "build" })
|
||||||
|
@Order(4)
|
||||||
|
void testIgnoreQuarkusSystemPropertyAtBuild(LaunchResult result) {
|
||||||
|
CLIResult cliResult = (CLIResult) result;
|
||||||
|
cliResult.assertMessage("DEBUG [");
|
||||||
|
cliResult.assertBuild();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@BeforeStartDistribution(SetDebugLogLevelInKeycloakConf.class)
|
||||||
|
@Launch({ "build" })
|
||||||
|
@Order(5)
|
||||||
|
void testIgnoreQuarkusPropertyFromKeycloakConf(LaunchResult result) {
|
||||||
|
CLIResult cliResult = (CLIResult) result;
|
||||||
|
assertFalse(cliResult.getOutput().contains("DEBUG ["));
|
||||||
|
cliResult.assertBuild();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SetDebugLogLevel implements Consumer<KeycloakDistribution> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(KeycloakDistribution distribution) {
|
||||||
|
distribution.setQuarkusProperty("quarkus.log.level", "DEBUG");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SetDebugLogLevelInKeycloakConf implements Consumer<KeycloakDistribution> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(KeycloakDistribution distribution) {
|
||||||
|
distribution.deleteQuarkusProperties();
|
||||||
|
distribution.setProperty("quarkus.log.level", "DEBUG");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
79
quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/StartAutoBuildDistTest.java
vendored
Normal file
79
quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/StartAutoBuildDistTest.java
vendored
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 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.it.cli.dist;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.MethodOrderer;
|
||||||
|
import org.junit.jupiter.api.Order;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.TestMethodOrder;
|
||||||
|
import org.keycloak.it.junit5.extension.CLIResult;
|
||||||
|
import org.keycloak.it.junit5.extension.DistributionTest;
|
||||||
|
import org.keycloak.it.junit5.extension.RawDistOnly;
|
||||||
|
|
||||||
|
import io.quarkus.test.junit.main.Launch;
|
||||||
|
import io.quarkus.test.junit.main.LaunchResult;
|
||||||
|
|
||||||
|
@DistributionTest(reInstall = DistributionTest.ReInstall.NEVER)
|
||||||
|
@RawDistOnly(reason = "Containers are immutable")
|
||||||
|
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||||
|
public class StartAutoBuildDistTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Launch({ "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
|
||||||
|
@Order(1)
|
||||||
|
void testStartAutoBuild(LaunchResult result) {
|
||||||
|
CLIResult cliResult = (CLIResult) result;
|
||||||
|
cliResult.assertMessage("Changes detected in configuration. Updating the server image.");
|
||||||
|
cliResult.assertMessage("Updating the configuration and installing your custom providers, if any. Please wait.");
|
||||||
|
cliResult.assertMessage("Server configuration updated and persisted. Run the following command to review the configuration:");
|
||||||
|
cliResult.assertMessage("kc.sh show-config");
|
||||||
|
cliResult.assertMessage("Next time you run the server, just run:");
|
||||||
|
cliResult.assertMessage("kc.sh start --http-enabled=true --hostname-strict=false");
|
||||||
|
assertFalse(cliResult.getOutput().contains("--cache"));
|
||||||
|
cliResult.assertStarted();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Launch({ "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
|
||||||
|
@Order(2)
|
||||||
|
void testShouldNotReAugIfConfigIsSame(LaunchResult result) {
|
||||||
|
CLIResult cliResult = (CLIResult) result;
|
||||||
|
cliResult.assertNoBuild();
|
||||||
|
cliResult.assertStarted();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Launch({ "start", "--auto-build", "--db=h2-mem", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
|
||||||
|
@Order(3)
|
||||||
|
void testShouldReAugIfConfigChanged(LaunchResult result) {
|
||||||
|
CLIResult cliResult = (CLIResult) result;
|
||||||
|
cliResult.assertBuild();
|
||||||
|
cliResult.assertStarted();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Launch({ "start", "--auto-build", "--db=h2-mem", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
|
||||||
|
@Order(4)
|
||||||
|
void testShouldNotReAugIfSameDatabase(LaunchResult result) {
|
||||||
|
CLIResult cliResult = (CLIResult) result;
|
||||||
|
cliResult.assertNoBuild();
|
||||||
|
cliResult.assertStarted();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue