mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-10 15:32:05 -03:30
Upgrade to Quarkus 3.19.0.CR1 (#37492)
Closes #37436 Signed-off-by: Martin Bartoš <mabartos@redhat.com>
This commit is contained in:
parent
a3af12cf26
commit
6f0ed46404
@ -13,3 +13,8 @@ would now be `http://example.com`.
|
||||
|
||||
To mitigate that, either make your reverse proxy include the port in the `X-Forwarded-Host` header or configure it to set
|
||||
the `X-Forwarded-Port` header with the desired port.
|
||||
|
||||
=== Changes to installing Oracle JDBC driver
|
||||
|
||||
The required JAR for the Oracle JDBC driver that needs to be explicitly added to the distribution has changed.
|
||||
Instead of providing `ojdbc11` JAR, use `ojdbc17` JAR as stated in the https://www.keycloak.org/server/db#_installing_the_oracle_database_driver[Installing the Oracle Database driver] guide.
|
||||
|
||||
@ -53,15 +53,15 @@ or skip this section if you want to connect to a different database for which th
|
||||
|
||||
To install the Oracle Database driver for {project_name}:
|
||||
|
||||
. Download the `ojdbc11` and `orai18n` JAR files from one of the following sources:
|
||||
. Download the `ojdbc17` and `orai18n` JAR files from one of the following sources:
|
||||
|
||||
.. *Zipped JDBC driver and Companion Jars* version ${properties["oracle-jdbc.version"]} from the https://www.oracle.com/database/technologies/appdev/jdbc-downloads.html[Oracle driver download page].
|
||||
|
||||
.. Maven Central via `link:++https://repo1.maven.org/maven2/com/oracle/database/jdbc/ojdbc11/${properties["oracle-jdbc.version"]}/ojdbc11-${properties["oracle-jdbc.version"]}.jar++[ojdbc11]` and `link:++https://repo1.maven.org/maven2/com/oracle/database/nls/orai18n/${properties["oracle-jdbc.version"]}/orai18n-${properties["oracle-jdbc.version"]}.jar++[orai18n]`.
|
||||
.. Maven Central via `link:++https://repo1.maven.org/maven2/com/oracle/database/jdbc/ojdbc17/${properties["oracle-jdbc.version"]}/ojdbc17-${properties["oracle-jdbc.version"]}.jar++[ojdbc17]` and `link:++https://repo1.maven.org/maven2/com/oracle/database/nls/orai18n/${properties["oracle-jdbc.version"]}/orai18n-${properties["oracle-jdbc.version"]}.jar++[orai18n]`.
|
||||
|
||||
.. Installation media recommended by the database vendor for the specific database in use.
|
||||
|
||||
. When running the unzipped distribution: Place the `ojdbc11` and `orai18n` JAR files in {project_name}'s `providers` folder
|
||||
. When running the unzipped distribution: Place the `ojdbc17` and `orai18n` JAR files in {project_name}'s `providers` folder
|
||||
|
||||
. When running containers: Build a custom {project_name} image and add the JARs in the `providers` folder. When building a custom image for the Operator, those images need to be optimized images with all build-time options of {project_name} set.
|
||||
+
|
||||
@ -70,7 +70,7 @@ A minimal Containerfile to build an image which can be used with the {project_na
|
||||
[source,dockerfile,subs="attributes+"]
|
||||
----
|
||||
FROM quay.io/keycloak/keycloak:{containerlabel}
|
||||
ADD --chown=keycloak:keycloak --chmod=644 https://repo1.maven.org/maven2/com/oracle/database/jdbc/ojdbc11/${properties["oracle-jdbc.version"]}/ojdbc11-${properties["oracle-jdbc.version"]}.jar /opt/keycloak/providers/ojdbc11.jar
|
||||
ADD --chown=keycloak:keycloak --chmod=644 https://repo1.maven.org/maven2/com/oracle/database/jdbc/ojdbc17/${properties["oracle-jdbc.version"]}/ojdbc17-${properties["oracle-jdbc.version"]}.jar /opt/keycloak/providers/ojdbc17.jar
|
||||
ADD --chown=keycloak:keycloak --chmod=644 https://repo1.maven.org/maven2/com/oracle/database/nls/orai18n/${properties["oracle-jdbc.version"]}/orai18n-${properties["oracle-jdbc.version"]}.jar /opt/keycloak/providers/orai18n.jar
|
||||
# Setting the build parameter for the database:
|
||||
ENV KC_DB=oracle
|
||||
|
||||
6
pom.xml
6
pom.xml
@ -52,8 +52,8 @@
|
||||
<jboss.snapshots.repo.id>jboss-snapshots-repository</jboss.snapshots.repo.id>
|
||||
<jboss.snapshots.repo.url>https://s01.oss.sonatype.org/content/repositories/snapshots/</jboss.snapshots.repo.url>
|
||||
|
||||
<quarkus.version>3.18.3</quarkus.version>
|
||||
<quarkus.build.version>3.18.3</quarkus.build.version>
|
||||
<quarkus.version>3.19.0.CR1</quarkus.version>
|
||||
<quarkus.build.version>3.19.0.CR1</quarkus.build.version>
|
||||
|
||||
<project.build-time>${timestamp}</project.build-time>
|
||||
|
||||
@ -176,7 +176,7 @@
|
||||
<oracledb.version>23.5</oracledb.version>
|
||||
<oracledb.container>mirror.gcr.io/gvenzl/oracle-free:${oracledb.version}-slim-faststart</oracledb.container>
|
||||
<!-- this is the oracle driver version also used in the Quarkus BOM -->
|
||||
<oracle-jdbc.version>23.5.0.24.07</oracle-jdbc.version>
|
||||
<oracle-jdbc.version>23.6.0.24.10</oracle-jdbc.version>
|
||||
|
||||
<!-- Test -->
|
||||
<greenmail.version>2.1.0-alpha-1</greenmail.version>
|
||||
|
||||
@ -9,6 +9,7 @@ import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@SuppressWarnings({"unchecked", "OptionalUsedAsFieldOrParameterType", "rawtypes"})
|
||||
public class OptionBuilder<T> {
|
||||
|
||||
private static final List<String> BOOLEAN_TYPE_VALUES = List.of(Boolean.TRUE.toString(), Boolean.FALSE.toString());
|
||||
|
||||
@ -210,8 +210,8 @@ public final class Database {
|
||||
"mssql"
|
||||
),
|
||||
ORACLE("oracle",
|
||||
"oracle.jdbc.xa.client.OracleXADataSource",
|
||||
"oracle.jdbc.driver.OracleDriver",
|
||||
"oracle.jdbc.datasource.OracleXADataSource",
|
||||
"oracle.jdbc.OracleDriver",
|
||||
"org.hibernate.dialect.OracleDialect",
|
||||
"jdbc:oracle:thin:@//${kc.db-url-host:localhost}:${kc.db-url-port:1521}/${kc.db-url-database:keycloak}",
|
||||
asList("liquibase.database.core.OracleDatabase")
|
||||
|
||||
@ -305,7 +305,7 @@ class KeycloakProcessor {
|
||||
@BuildStep
|
||||
@Produce(CheckMultipleDatasourcesBuildStep.class)
|
||||
void checkMultipleDatasourcesUseXA(TransactionManagerBuildTimeConfig transactionManagerConfig, DataSourcesBuildTimeConfig dataSourcesConfig, DataSourcesJdbcBuildTimeConfig jdbcConfig) {
|
||||
if (transactionManagerConfig.unsafeMultipleLastResources
|
||||
if (transactionManagerConfig.unsafeMultipleLastResources()
|
||||
.orElse(UnsafeMultipleLastResourcesMode.DEFAULT) != UnsafeMultipleLastResourcesMode.FAIL) {
|
||||
return;
|
||||
}
|
||||
@ -383,7 +383,7 @@ class KeycloakProcessor {
|
||||
Properties properties = descriptor.getProperties();
|
||||
// register a listener for customizing the unit configuration at runtime
|
||||
runtimeConfigured.produce(new HibernateOrmIntegrationRuntimeConfiguredBuildItem("keycloak", descriptor.getName())
|
||||
.setInitListener(recorder.createUserDefinedUnitListener(properties.getProperty(AvailableSettings.DATASOURCE))));
|
||||
.setInitListener(recorder.createUserDefinedUnitListener(properties.getProperty(AvailableSettings.JAKARTA_JTA_DATASOURCE))));
|
||||
userManagedEntities.addAll(descriptor.getManagedClassNames());
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,7 +81,7 @@
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.oracle.database.jdbc</groupId>
|
||||
<artifactId>ojdbc11</artifactId>
|
||||
<artifactId>ojdbc17</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.oracle.database.nls</groupId>
|
||||
|
||||
@ -23,7 +23,6 @@ import io.quarkus.arc.Arc;
|
||||
import io.quarkus.arc.InstanceHandle;
|
||||
import io.quarkus.hibernate.orm.runtime.integration.HibernateOrmIntegrationRuntimeInitListener;
|
||||
import io.quarkus.runtime.RuntimeValue;
|
||||
import io.quarkus.runtime.ShutdownContext;
|
||||
import io.quarkus.runtime.annotations.Recorder;
|
||||
import io.vertx.core.Handler;
|
||||
import io.vertx.ext.web.RoutingContext;
|
||||
@ -70,9 +69,6 @@ import static org.keycloak.quarkus.runtime.configuration.Configuration.getKcConf
|
||||
@Recorder
|
||||
public class KeycloakRecorder {
|
||||
|
||||
public static final String DEFAULT_HEALTH_ENDPOINT = "/health";
|
||||
public static final String DEFAULT_METRICS_ENDPOINT = "/metrics";
|
||||
|
||||
private static final Logger logger = Logger.getLogger(KeycloakRecorder.class);
|
||||
|
||||
public void initConfig() {
|
||||
@ -169,20 +165,11 @@ public class KeycloakRecorder {
|
||||
DeclarativeUserProfileProviderFactory.setDefaultConfig(configuration);
|
||||
}
|
||||
|
||||
public void registerShutdownHook(ShutdownContext shutdownContext) {
|
||||
shutdownContext.addShutdownTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
QuarkusKeycloakSessionFactory.getInstance().close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public HibernateOrmIntegrationRuntimeInitListener createUserDefinedUnitListener(String name) {
|
||||
return new HibernateOrmIntegrationRuntimeInitListener() {
|
||||
@Override
|
||||
public void contributeRuntimeProperties(BiConsumer<String, Object> propertyCollector) {
|
||||
InstanceHandle<AgroalDataSource> instance = Arc.container().instance(
|
||||
try (InstanceHandle<AgroalDataSource> instance = Arc.container().instance(
|
||||
AgroalDataSource.class, new DataSource() {
|
||||
@Override public Class<? extends Annotation> annotationType() {
|
||||
return DataSource.class;
|
||||
@ -191,8 +178,9 @@ public class KeycloakRecorder {
|
||||
@Override public String value() {
|
||||
return name;
|
||||
}
|
||||
});
|
||||
propertyCollector.accept(AvailableSettings.DATASOURCE, instance.get());
|
||||
})) {
|
||||
propertyCollector.accept(AvailableSettings.JAKARTA_JTA_DATASOURCE, instance.get());
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -32,38 +32,45 @@ import io.smallrye.config.ConfigValue;
|
||||
import picocli.CommandLine;
|
||||
import picocli.CommandLine.ParseResult;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
public final class ExecutionExceptionHandler implements CommandLine.IExecutionExceptionHandler {
|
||||
|
||||
private Logger logger;
|
||||
private static Logger logger;
|
||||
private boolean verbose;
|
||||
private static Map<String, Function<Throwable, Throwable>> exceptionTransformers = new HashMap<>();
|
||||
|
||||
public ExecutionExceptionHandler() {}
|
||||
|
||||
@Override
|
||||
public int handleExecutionException(Exception cause, CommandLine cmd, ParseResult parseResult) {
|
||||
if (cause instanceof PropertyException) {
|
||||
var exception = handleExceptionTransformers(cause);
|
||||
if (exception instanceof PropertyException) {
|
||||
PrintWriter writer = cmd.getErr();
|
||||
writer.println(cmd.getColorScheme().errorText(cause.getMessage()));
|
||||
if (verbose && cause.getCause() != null) {
|
||||
dumpException(writer, cause.getCause());
|
||||
writer.println(cmd.getColorScheme().errorText(exception.getMessage()));
|
||||
if (verbose && exception.getCause() != null) {
|
||||
dumpException(writer, exception.getCause());
|
||||
}
|
||||
return ShortErrorMessageHandler.getInvalidInputExitCode(cause, cmd);
|
||||
return ShortErrorMessageHandler.getInvalidInputExitCode(exception, cmd);
|
||||
}
|
||||
error(cmd.getErr(), "Failed to run '" + parseResult.subcommands().stream()
|
||||
.map(ParseResult::commandSpec)
|
||||
.map(CommandLine.Model.CommandSpec::name)
|
||||
.findFirst()
|
||||
.orElse(Environment.getCommand()) + "' command.", cause);
|
||||
.orElse(Environment.getCommand()) + "' command.", exception);
|
||||
return cmd.getCommandSpec().exitCodeOnExecutionException();
|
||||
}
|
||||
|
||||
public void error(PrintWriter errorWriter, String message, Throwable cause) {
|
||||
var exception = handleExceptionTransformers(cause);
|
||||
if (message != null) {
|
||||
logError(errorWriter, "ERROR: " + message);
|
||||
}
|
||||
|
||||
if (cause != null) {
|
||||
dumpException(errorWriter, cause);
|
||||
if (exception != null) {
|
||||
dumpException(errorWriter, exception);
|
||||
|
||||
if (!verbose) {
|
||||
logError(errorWriter, "For more details run the same command passing the '--verbose' option. Also you can use '--help' to see the details about the usage of the particular command.");
|
||||
@ -121,7 +128,7 @@ public final class ExecutionExceptionHandler implements CommandLine.IExecutionEx
|
||||
}
|
||||
}
|
||||
|
||||
private Logger getLogger() {
|
||||
private static Logger getLogger() {
|
||||
if (logger == null) {
|
||||
logger = Logger.getLogger(ExecutionExceptionHandler.class);
|
||||
}
|
||||
@ -131,4 +138,34 @@ public final class ExecutionExceptionHandler implements CommandLine.IExecutionEx
|
||||
public void setVerbose(boolean verbose) {
|
||||
this.verbose = verbose;
|
||||
}
|
||||
|
||||
public static void addExceptionTransformer(Class<?> fromClass, Function<Throwable, Throwable> transformer) {
|
||||
if (exceptionTransformers.get(fromClass.getName()) != null) {
|
||||
getLogger().warnf("Transformer for the '%s' class is overridden", fromClass.getName());
|
||||
}
|
||||
exceptionTransformers.put(fromClass.getName(), transformer);
|
||||
}
|
||||
|
||||
public static void resetExceptionTransformers() {
|
||||
exceptionTransformers = new HashMap<>();
|
||||
}
|
||||
|
||||
private static Throwable handleExceptionTransformers(Throwable exception) {
|
||||
if (exception == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (exceptionTransformers.isEmpty()) {
|
||||
return exception;
|
||||
}
|
||||
|
||||
var stackTrace = exception.getStackTrace();
|
||||
for (var trace : stackTrace) {
|
||||
var transformer = exceptionTransformers.get(trace.getClassName());
|
||||
if (transformer != null) {
|
||||
return transformer.apply(exception);
|
||||
}
|
||||
}
|
||||
return exception;
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,7 +95,7 @@ public class ShortErrorMessageHandler implements IParameterExceptionHandler {
|
||||
return getInvalidInputExitCode(ex, cmd);
|
||||
}
|
||||
|
||||
static int getInvalidInputExitCode(Exception ex, CommandLine cmd) {
|
||||
static int getInvalidInputExitCode(Throwable ex, CommandLine cmd) {
|
||||
return cmd.getExitCodeExceptionMapper() != null
|
||||
? cmd.getExitCodeExceptionMapper().getExitCode(ex)
|
||||
: cmd.getCommandSpec().exitCodeOnInvalidInput();
|
||||
|
||||
@ -73,7 +73,8 @@ public class IgnoredArtifacts {
|
||||
public static final Set<String> JDBC_H2 = Set.of(
|
||||
"io.quarkus:quarkus-jdbc-h2",
|
||||
"io.quarkus:quarkus-jdbc-h2-deployment",
|
||||
"com.h2database:h2"
|
||||
"com.h2database:h2",
|
||||
"org.locationtech.jts:jts-core"
|
||||
);
|
||||
|
||||
public static final Set<String> JDBC_POSTGRES = Set.of(
|
||||
@ -103,7 +104,7 @@ public class IgnoredArtifacts {
|
||||
public static final Set<String> JDBC_ORACLE = Set.of(
|
||||
"io.quarkus:quarkus-jdbc-oracle",
|
||||
"io.quarkus:quarkus-jdbc-oracle-deployment",
|
||||
"com.oracle.database.jdbc:ojdbc11",
|
||||
"com.oracle.database.jdbc:ojdbc17",
|
||||
"com.oracle.database.nls:orai18n"
|
||||
);
|
||||
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package org.keycloak.quarkus.runtime.configuration.mappers;
|
||||
|
||||
import io.quarkus.runtime.util.ClassPathUtils;
|
||||
import io.quarkus.vertx.http.runtime.CertificateConfig;
|
||||
import io.quarkus.vertx.http.runtime.options.TlsUtils;
|
||||
import io.smallrye.config.ConfigSourceInterceptorContext;
|
||||
|
||||
@ -10,16 +9,17 @@ import org.keycloak.config.HttpOptions;
|
||||
import org.keycloak.config.SecurityOptions;
|
||||
import org.keycloak.quarkus.runtime.Environment;
|
||||
import org.keycloak.quarkus.runtime.Messages;
|
||||
import org.keycloak.quarkus.runtime.cli.ExecutionExceptionHandler;
|
||||
import org.keycloak.quarkus.runtime.cli.PropertyException;
|
||||
import org.keycloak.quarkus.runtime.configuration.Configuration;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.keycloak.quarkus.runtime.configuration.Configuration.getOptionalKcValue;
|
||||
import static org.keycloak.quarkus.runtime.configuration.Configuration.getOptionalValue;
|
||||
import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption;
|
||||
|
||||
public final class HttpPropertyMappers {
|
||||
@ -33,7 +33,28 @@ public final class HttpPropertyMappers {
|
||||
|
||||
private HttpPropertyMappers(){}
|
||||
|
||||
// Transform runtime exceptions obtained from Quarkus to ours with a relevant message
|
||||
private static void setCustomExceptionTransformer() {
|
||||
ExecutionExceptionHandler.addExceptionTransformer(TlsUtils.class, exception -> {
|
||||
if (exception instanceof IOException ioe) {
|
||||
return new PropertyException("Failed to load 'https-trust-store' or 'https-key-' material: " + ioe.getClass().getSimpleName() + " " + ioe.getMessage(), ioe);
|
||||
} else if (exception instanceof IllegalArgumentException iae) {
|
||||
if (iae.getMessage().contains(QUARKUS_HTTPS_TRUST_STORE_FILE_TYPE)) {
|
||||
return new PropertyException("Unable to determine 'https-trust-store-type' automatically. " +
|
||||
"Adjust the file extension or specify the property.", iae);
|
||||
} else if (iae.getMessage().contains(QUARKUS_HTTPS_KEY_STORE_FILE_TYPE)) {
|
||||
return new PropertyException("Unable to determine 'https-key-store-type' automatically. " +
|
||||
"Adjust the file extension or specify the property.", iae);
|
||||
} else {
|
||||
return new PropertyException(iae.getMessage(), iae);
|
||||
}
|
||||
}
|
||||
return exception;
|
||||
});
|
||||
}
|
||||
|
||||
public static PropertyMapper<?>[] getHttpPropertyMappers() {
|
||||
setCustomExceptionTransformer();
|
||||
return new PropertyMapper[] {
|
||||
fromOption(HttpOptions.HTTP_ENABLED)
|
||||
.to("quarkus.http.insecure-requests")
|
||||
@ -138,57 +159,12 @@ public final class HttpPropertyMappers {
|
||||
}
|
||||
|
||||
public static void validateConfig() {
|
||||
boolean enabled = isHttpEnabled(Configuration.getOptionalKcValue(HttpOptions.HTTP_ENABLED.getKey()).orElse(null));
|
||||
Optional<String> certFile = Configuration.getOptionalValue(QUARKUS_HTTPS_CERT_FILES);
|
||||
Optional<String> keystoreFile = Configuration.getOptionalValue(QUARKUS_HTTPS_KEY_STORE_FILE);
|
||||
boolean enabled = isHttpEnabled(getOptionalKcValue(HttpOptions.HTTP_ENABLED.getKey()).orElse(null));
|
||||
Optional<String> certFile = getOptionalValue(QUARKUS_HTTPS_CERT_FILES);
|
||||
Optional<String> keystoreFile = getOptionalValue(QUARKUS_HTTPS_KEY_STORE_FILE);
|
||||
if (!enabled && certFile.isEmpty() && keystoreFile.isEmpty()) {
|
||||
throw new PropertyException(Messages.httpsConfigurationNotSet());
|
||||
}
|
||||
|
||||
CertificateConfig config = new CertificateConfig();
|
||||
|
||||
config.trustStoreFile = Configuration.getOptionalValue(QUARKUS_HTTPS_TRUST_STORE_FILE).map(Paths::get);
|
||||
config.trustStorePassword = Configuration.getOptionalKcValue(HttpOptions.HTTPS_TRUST_STORE_PASSWORD.getKey());
|
||||
config.trustStoreFileType = Configuration.getOptionalValue(QUARKUS_HTTPS_TRUST_STORE_FILE_TYPE);
|
||||
config.trustStoreProvider = Configuration.getOptionalValue("quarkus.http.ssl.certificate.trust-store-provider");
|
||||
config.trustStoreCertAlias = Configuration.getOptionalValue("quarkus.http.ssl.certificate.trust-store-cert-alias");
|
||||
config.trustStoreFiles = Optional.empty();
|
||||
|
||||
config.keyStoreFile = keystoreFile.map(Paths::get);
|
||||
config.keyStorePassword = Configuration.getOptionalKcValue(HttpOptions.HTTPS_KEY_STORE_PASSWORD.getKey());
|
||||
config.keyStoreFileType = Configuration.getOptionalValue(QUARKUS_HTTPS_KEY_STORE_FILE_TYPE);
|
||||
config.keyStoreProvider = Configuration.getOptionalValue("quarkus.http.ssl.certificate.key-store-provider");
|
||||
config.keyStoreAlias = Configuration.getOptionalValue("quarkus.http.ssl.certificate.key-store-alias");
|
||||
config.keyStoreAliasPassword = Configuration.getOptionalValue("quarkus.http.ssl.certificate.key-store-alias-password");
|
||||
config.keyStoreAliasPasswordKey = Configuration.getOptionalValue("quarkus.http.ssl.certificate.key-store-alias-password-key");
|
||||
config.keyStoreKeyAlias = Configuration.getOptionalValue("quarkus.http.ssl.certificate.key-store-key-alias");
|
||||
|
||||
config.keyFiles = Configuration.getOptionalValue(QUARKUS_HTTPS_CERT_KEY_FILES).map(Paths::get).map(List::of);
|
||||
config.files = certFile.map(Paths::get).map(List::of);
|
||||
|
||||
try {
|
||||
TlsUtils.computeTrustOptions(config, config.trustStorePassword);
|
||||
} catch (IOException e) {
|
||||
throw new PropertyException("Failed to load 'https-trust-store' material: " + e.getClass().getSimpleName() + " " + e.getMessage(), e);
|
||||
} catch (IllegalArgumentException e) {
|
||||
if (e.getMessage().contains(QUARKUS_HTTPS_TRUST_STORE_FILE_TYPE)) {
|
||||
throw new PropertyException("Unable to determine 'https-trust-store-type' automatically. " +
|
||||
"Adjust the file extension or specify the property.", e);
|
||||
}
|
||||
throw new PropertyException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
try {
|
||||
TlsUtils.computeKeyStoreOptions(config, config.keyStorePassword, config.keyStoreAliasPassword);
|
||||
} catch (IOException e) {
|
||||
throw new PropertyException("Failed to load 'https-key-' material: " + e.getClass().getSimpleName() + " " + e.getMessage(), e);
|
||||
} catch (IllegalArgumentException e) {
|
||||
if (e.getMessage().contains(QUARKUS_HTTPS_KEY_STORE_FILE_TYPE)) {
|
||||
throw new PropertyException("Unable to determine 'https-key-store-type' automatically. " +
|
||||
"Adjust the file extension or specify the property.", e);
|
||||
}
|
||||
throw new PropertyException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private static String transformPath(String value, ConfigSourceInterceptorContext context) {
|
||||
|
||||
@ -45,7 +45,7 @@ public final class LoggingPropertyMappers {
|
||||
// Console
|
||||
fromOption(LoggingOptions.LOG_CONSOLE_OUTPUT)
|
||||
.isEnabled(LoggingPropertyMappers::isConsoleEnabled, CONSOLE_ENABLED_MSG)
|
||||
.to("quarkus.log.console.json")
|
||||
.to("quarkus.log.console.json.enabled")
|
||||
.paramLabel("output")
|
||||
.transformer(LoggingPropertyMappers::resolveLogOutput)
|
||||
.build(),
|
||||
@ -112,7 +112,7 @@ public final class LoggingPropertyMappers {
|
||||
.build(),
|
||||
fromOption(LoggingOptions.LOG_FILE_OUTPUT)
|
||||
.isEnabled(LoggingPropertyMappers::isFileEnabled, FILE_ENABLED_MSG)
|
||||
.to("quarkus.log.file.json")
|
||||
.to("quarkus.log.file.json.enabled")
|
||||
.paramLabel("output")
|
||||
.transformer(LoggingPropertyMappers::resolveLogOutput)
|
||||
.build(),
|
||||
@ -185,7 +185,7 @@ public final class LoggingPropertyMappers {
|
||||
.build(),
|
||||
fromOption(LoggingOptions.LOG_SYSLOG_OUTPUT)
|
||||
.isEnabled(LoggingPropertyMappers::isSyslogEnabled, SYSLOG_ENABLED_MSG)
|
||||
.to("quarkus.log.syslog.json")
|
||||
.to("quarkus.log.syslog.json.enabled")
|
||||
.paramLabel("output")
|
||||
.transformer(LoggingPropertyMappers::resolveLogOutput)
|
||||
.build(),
|
||||
@ -199,7 +199,7 @@ public final class LoggingPropertyMappers {
|
||||
}
|
||||
|
||||
public static boolean isConsoleJsonEnabled() {
|
||||
return isConsoleEnabled() && Configuration.isTrue("quarkus.log.console.json");
|
||||
return isConsoleEnabled() && Configuration.isTrue("quarkus.log.console.json.enabled");
|
||||
}
|
||||
|
||||
public static boolean isFileEnabled() {
|
||||
@ -207,7 +207,7 @@ public final class LoggingPropertyMappers {
|
||||
}
|
||||
|
||||
public static boolean isFileJsonEnabled() {
|
||||
return isFileEnabled() && Configuration.isTrue("quarkus.log.file.json");
|
||||
return isFileEnabled() && Configuration.isTrue("quarkus.log.file.json.enabled");
|
||||
}
|
||||
|
||||
public static boolean isSyslogEnabled() {
|
||||
@ -215,7 +215,7 @@ public final class LoggingPropertyMappers {
|
||||
}
|
||||
|
||||
public static boolean isSyslogJsonEnabled() {
|
||||
return isSyslogEnabled() && Configuration.isTrue("quarkus.log.syslog.json");
|
||||
return isSyslogEnabled() && Configuration.isTrue("quarkus.log.syslog.json.enabled");
|
||||
}
|
||||
|
||||
private static BiFunction<String, ConfigSourceInterceptorContext, String> resolveLogHandler(String handler) {
|
||||
|
||||
@ -270,6 +270,7 @@ public final class PropertyMappers {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public List<PropertyMapper<?>> get(Object key) {
|
||||
// First check if the requested option matches any wildcard mappers
|
||||
String strKey = (String) key;
|
||||
|
||||
@ -144,7 +144,7 @@ public class QuarkusJpaUpdaterProvider implements JpaUpdaterProvider {
|
||||
|
||||
// create DEPLOYMENT_ID column if it doesn't exist
|
||||
if (!hasDeploymentIdColumn) {
|
||||
ChangeLogHistoryService changelogHistoryService = ChangeLogHistoryServiceFactory.getInstance().getChangeLogService(database);
|
||||
ChangeLogHistoryService changelogHistoryService = getChangeLogHistoryService().getChangeLogService(database);
|
||||
changelogHistoryService.generateDeploymentId();
|
||||
String deploymentId = changelogHistoryService.getDeploymentId();
|
||||
|
||||
@ -281,7 +281,11 @@ public class QuarkusJpaUpdaterProvider implements JpaUpdaterProvider {
|
||||
|
||||
private void resetLiquibaseServices(KeycloakLiquibase liquibase) {
|
||||
liquibase.resetServices();
|
||||
ChangeLogHistoryServiceFactory.getInstance().register(new CustomChangeLogHistoryService());
|
||||
getChangeLogHistoryService().register(new CustomChangeLogHistoryService());
|
||||
}
|
||||
|
||||
private ChangeLogHistoryServiceFactory getChangeLogHistoryService() {
|
||||
return Scope.getCurrentScope().getSingleton(ChangeLogHistoryServiceFactory.class);
|
||||
}
|
||||
|
||||
private List<ChangeSet> getLiquibaseUnrunChangeSets(Liquibase liquibase) {
|
||||
|
||||
@ -25,6 +25,7 @@ import org.keycloak.models.KeycloakSession;
|
||||
/**
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
@SuppressWarnings({"unchecked", "resource"})
|
||||
public final class QuarkusCacheManagerProvider implements ManagedCacheManagerProvider {
|
||||
|
||||
@Override
|
||||
|
||||
@ -244,21 +244,6 @@ public class PicocliTest extends AbstractConfigurationTest {
|
||||
+ "\nPossible solutions: --db-url, --db-url-host, --db-url-database, --db-url-port, --db-url-properties, --db-username, --db-password, --db-schema, --db-pool-initial-size, --db-pool-min-size, --db-pool-max-size, --db-driver, --db"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void httpStoreTypeValidation() {
|
||||
NonRunningPicocli nonRunningPicocli = pseudoLaunch("start", "--https-key-store-file=not-there.ks", "--hostname-strict=false");
|
||||
assertEquals(CommandLine.ExitCode.USAGE, nonRunningPicocli.exitCode);
|
||||
assertThat(nonRunningPicocli.getErrString(), containsString("Unable to determine 'https-key-store-type' automatically. Adjust the file extension or specify the property"));
|
||||
|
||||
nonRunningPicocli = pseudoLaunch("start", "--https-key-store-file=not-there.ks", "--hostname-strict=false", "--https-key-store-type=jdk");
|
||||
assertEquals(CommandLine.ExitCode.USAGE, nonRunningPicocli.exitCode);
|
||||
assertThat(nonRunningPicocli.getErrString(), containsString("Failed to load 'https-key-' material: NoSuchFileException not-there.ks"));
|
||||
|
||||
nonRunningPicocli = pseudoLaunch("start", "--https-trust-store-file=not-there.jks", "--https-key-store-file=not-there.ks", "--hostname-strict=false", "--https-key-store-type=jdk");
|
||||
assertEquals(CommandLine.ExitCode.USAGE, nonRunningPicocli.exitCode);
|
||||
assertThat(nonRunningPicocli.getErrString(), containsString("No trust store password provided"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShowConfigHidesSystemProperties() {
|
||||
setSystemProperty("kc.something", "password", () -> {
|
||||
@ -335,6 +320,7 @@ public class PicocliTest extends AbstractConfigurationTest {
|
||||
/**
|
||||
* Runs a fake build to setup the state of the persisted build properties
|
||||
*/
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
private void build(String... args) {
|
||||
if (Stream.of(args).anyMatch("start-dev"::equals)) {
|
||||
Environment.setRebuildCheck(); // auto-build
|
||||
|
||||
@ -31,6 +31,7 @@ import org.junit.After;
|
||||
import org.junit.BeforeClass;
|
||||
import org.keycloak.Config;
|
||||
import org.keycloak.common.Profile;
|
||||
import org.keycloak.quarkus.runtime.cli.ExecutionExceptionHandler;
|
||||
import org.keycloak.quarkus.runtime.configuration.ConfigArgsConfigSource;
|
||||
import org.keycloak.quarkus.runtime.configuration.Configuration;
|
||||
import org.keycloak.quarkus.runtime.configuration.KeycloakConfigSourceProvider;
|
||||
@ -115,6 +116,7 @@ public abstract class AbstractConfigurationTest {
|
||||
PersistedConfigSource.getInstance().getConfigValueProperties().clear();
|
||||
Profile.reset();
|
||||
Configuration.resetConfig();
|
||||
ExecutionExceptionHandler.resetExceptionTransformers();
|
||||
}
|
||||
|
||||
@After
|
||||
|
||||
@ -88,7 +88,7 @@ public class LoggingConfigurationTest extends AbstractConfigurationTest {
|
||||
"quarkus.log.syslog.app-name", "keycloak",
|
||||
"quarkus.log.syslog.protocol", "tcp",
|
||||
"quarkus.log.syslog.format", DEFAULT_LOG_FORMAT,
|
||||
"quarkus.log.syslog.json", "false"
|
||||
"quarkus.log.syslog.json.enabled", "false"
|
||||
));
|
||||
|
||||
// The default max-length attribute is set in the org.jboss.logmanager.handlers.SyslogHandler if not specified in config
|
||||
@ -129,7 +129,7 @@ public class LoggingConfigurationTest extends AbstractConfigurationTest {
|
||||
"quarkus.log.syslog.app-name", "keycloak2",
|
||||
"quarkus.log.syslog.protocol", "udp",
|
||||
"quarkus.log.syslog.format", "some format",
|
||||
"quarkus.log.syslog.json", "true"
|
||||
"quarkus.log.syslog.json.enabled", "true"
|
||||
));
|
||||
}
|
||||
|
||||
@ -247,11 +247,11 @@ public class LoggingConfigurationTest extends AbstractConfigurationTest {
|
||||
));
|
||||
|
||||
assertExternalConfig(Map.of(
|
||||
"quarkus.log.console.json", "true",
|
||||
"quarkus.log.console.json.enabled", "true",
|
||||
"quarkus.log.console.json.log-format", "ecs",
|
||||
"quarkus.log.file.json", "true",
|
||||
"quarkus.log.file.json.enabled", "true",
|
||||
"quarkus.log.file.json.log-format", "ecs",
|
||||
"quarkus.log.syslog.json", "true",
|
||||
"quarkus.log.syslog.json.enabled", "true",
|
||||
"quarkus.log.syslog.json.log-format", "ecs"
|
||||
));
|
||||
}
|
||||
|
||||
@ -89,7 +89,7 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.oracle.database.jdbc</groupId>
|
||||
<artifactId>ojdbc11</artifactId>
|
||||
<artifactId>ojdbc17</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
@ -149,8 +149,7 @@ public class FipsDistTest {
|
||||
|
||||
CLIResult cliResult = dist.run("--verbose", "start", "--fips-mode=non-strict", "--https-key-store-password=passwordpassword",
|
||||
"--https-trust-store-file=" + truststorePath, "--https-trust-store-password=passwordpassword");
|
||||
cliResult.assertError("Unable to determine 'https-trust-store-type' automatically. Adjust the file extension or specify the property.");
|
||||
|
||||
cliResult.assertMessage("Unable to determine 'https-trust-store-type' automatically. Adjust the file extension or specify the property.");
|
||||
dist.stop();
|
||||
|
||||
dist.copyOrReplaceFileFromClasspath("/server.keystore.pkcs12", Path.of("conf", "server.p12"));
|
||||
|
||||
@ -17,13 +17,17 @@
|
||||
|
||||
package org.keycloak.it.cli.dist;
|
||||
|
||||
import io.quarkus.test.junit.main.Launch;
|
||||
import org.junit.jupiter.api.Test;
|
||||
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.junit5.extension.TestProvider;
|
||||
import org.keycloak.it.resource.realm.TestRealmResourceTestProvider;
|
||||
import org.keycloak.it.utils.KeycloakDistribution;
|
||||
import org.keycloak.it.utils.RawKeycloakDistribution;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@ -31,12 +35,8 @@ import java.util.concurrent.CompletableFuture;
|
||||
import static io.restassured.RestAssured.when;
|
||||
import static org.hamcrest.CoreMatchers.hasItem;
|
||||
import static org.hamcrest.CoreMatchers.not;
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
import io.quarkus.test.junit.main.Launch;
|
||||
import io.quarkus.test.junit.main.LaunchResult;
|
||||
|
||||
/**
|
||||
* @author Vaclav Muzikar <vmuzikar@redhat.com>
|
||||
*/
|
||||
@ -62,7 +62,30 @@ public class HttpDistTest {
|
||||
|
||||
@Test
|
||||
@Launch({"start-dev", "--https-certificates-reload-period=wrong"})
|
||||
public void testHttpCertificateReloadPeriod(LaunchResult result) {
|
||||
assertThat(result.getErrorOutput(), containsString("Text cannot be parsed to a Duration"));
|
||||
public void testHttpCertificateReloadPeriod(CLIResult result) {
|
||||
result.assertError("Text cannot be parsed to a Duration");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void httpStoreTypeValidation(KeycloakDistribution dist) {
|
||||
CLIResult result = dist.run("start", "--https-key-store-file=not-there.ks", "--hostname-strict=false");
|
||||
result.assertExitCode(-1);
|
||||
result.assertMessage("ERROR: Unable to determine 'https-key-store-type' automatically. Adjust the file extension or specify the property");
|
||||
|
||||
result = dist.run("start", "--https-trust-store-file=not-there.ks", "--hostname-strict=false");
|
||||
result.assertExitCode(-1);
|
||||
result.assertMessage("ERROR: Unable to determine 'https-trust-store-type' automatically. Adjust the file extension or specify the property");
|
||||
|
||||
result = dist.run("start", "--https-key-store-file=not-there.ks", "--hostname-strict=false", "--https-key-store-type=jdk");
|
||||
result.assertExitCode(-1);
|
||||
result.assertMessage("ERROR: Failed to load 'https-trust-store' or 'https-key-' material: NoSuchFileException not-there.ks");
|
||||
|
||||
dist.copyOrReplaceFileFromClasspath("/server.keystore.pkcs12", Path.of("conf", "server.p12"));
|
||||
RawKeycloakDistribution rawDist = dist.unwrap(RawKeycloakDistribution.class);
|
||||
Path truststorePath = rawDist.getDistPath().resolve("conf").resolve("server.p12").toAbsolutePath();
|
||||
|
||||
result = dist.run("start", "--https-trust-store-file=" + truststorePath, "--hostname-strict=false");
|
||||
result.assertExitCode(-1);
|
||||
result.assertMessage("ERROR: No trust store password provided");
|
||||
}
|
||||
}
|
||||
|
||||
@ -202,7 +202,8 @@ public class QuarkusPropertiesDistTest {
|
||||
"--https-certificate-key-file=/tmp/kc/bin/../conf/server.key.pem" })
|
||||
@Order(13)
|
||||
void testHttpCertsPathTransformer(CLIResult cliResult) {
|
||||
cliResult.assertError("Failed to load 'https-key-' material: NoSuchFileException /tmp/kc/bin/../conf/server.crt.pem");
|
||||
cliResult.assertExitCode(1);
|
||||
cliResult.assertMessage("Failed to load 'https-trust-store' or 'https-key-' material: NoSuchFileException");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -213,7 +214,8 @@ public class QuarkusPropertiesDistTest {
|
||||
"--https-certificate-key-file=C:\\tmp\\kc\\bin\\..\\conf/server.key.pem" })
|
||||
@Order(14)
|
||||
void testHttpCertsPathTransformerOnWindows(CLIResult cliResult) {
|
||||
cliResult.assertError("Failed to load 'https-key-' material: NoSuchFileException C:\\tmp\\kc\\bin\\..\\conf\\server.crt.pem");
|
||||
cliResult.assertExitCode(1);
|
||||
cliResult.assertMessage("ERROR: Failed to load 'https-trust-store' or 'https-key-' material: NoSuchFileException C:");
|
||||
}
|
||||
|
||||
public static class AddConsoleHandlerFromQuarkusProps implements Consumer<KeycloakDistribution> {
|
||||
|
||||
@ -46,7 +46,7 @@ public class OracleTest extends BasicDatabaseTest {
|
||||
@Override
|
||||
public void accept(KeycloakDistribution distribution) {
|
||||
RawKeycloakDistribution rawDist = distribution.unwrap(RawKeycloakDistribution.class);
|
||||
rawDist.copyProvider("com.oracle.database.jdbc", "ojdbc11");
|
||||
rawDist.copyProvider("com.oracle.database.jdbc", "ojdbc17");
|
||||
rawDist.copyProvider("com.oracle.database.nls", "orai18n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -108,7 +108,7 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.oracle.database.jdbc</groupId>
|
||||
<artifactId>ojdbc11</artifactId>
|
||||
<artifactId>ojdbc17</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.oracle.database.nls</groupId>
|
||||
|
||||
@ -85,6 +85,10 @@ public interface CLIResult extends LaunchResult {
|
||||
getErrorOutput(), not(containsString(msg)));
|
||||
}
|
||||
|
||||
default void assertExitCode(int code) {
|
||||
assertThat("Exit codes do not match: ", exitCode(), is(code));
|
||||
}
|
||||
|
||||
default void assertMessage(String message) {
|
||||
assertThat(getOutput(), containsString(message));
|
||||
}
|
||||
|
||||
@ -138,6 +138,7 @@ public class KeycloakDistributionDecorator implements KeycloakDistribution {
|
||||
}
|
||||
|
||||
if (type.isInstance(delegate)) {
|
||||
//noinspection unchecked
|
||||
return (D) delegate;
|
||||
}
|
||||
|
||||
|
||||
@ -43,7 +43,7 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.oracle.database.jdbc</groupId>
|
||||
<artifactId>ojdbc11</artifactId>
|
||||
<artifactId>ojdbc17</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
@ -19,6 +19,6 @@ public class OracleDatabaseSupplier extends AbstractDatabaseSupplier {
|
||||
@Override
|
||||
public KeycloakServerConfigBuilder intercept(KeycloakServerConfigBuilder serverConfig, InstanceContext<TestDatabase, InjectTestDatabase> instanceContext) {
|
||||
return super.intercept(serverConfig, instanceContext)
|
||||
.dependency("com.oracle.database.jdbc", "ojdbc11");
|
||||
.dependency("com.oracle.database.jdbc", "ojdbc17");
|
||||
}
|
||||
}
|
||||
|
||||
@ -523,7 +523,7 @@
|
||||
<!-- For EAP testing, it is recommended to override those with system properties pointing to GAV of more appropriate JDBC driver -->
|
||||
<!-- for the particular EAP version -->
|
||||
<jdbc.mvn.groupId>com.oracle.database.jdbc</jdbc.mvn.groupId>
|
||||
<jdbc.mvn.artifactId>ojdbc11</jdbc.mvn.artifactId>
|
||||
<jdbc.mvn.artifactId>ojdbc17</jdbc.mvn.artifactId>
|
||||
<jdbc.mvn.version>${oracle-jdbc.version}</jdbc.mvn.version>
|
||||
</properties>
|
||||
</profile>
|
||||
|
||||
@ -201,7 +201,7 @@
|
||||
<artifactItems>
|
||||
<artifactItem>
|
||||
<groupId>com.oracle.database.jdbc</groupId>
|
||||
<artifactId>ojdbc11</artifactId>
|
||||
<artifactId>ojdbc17</artifactId>
|
||||
<version>${oracle-jdbc.version}</version>
|
||||
<type>jar</type>
|
||||
<outputDirectory>${auth.server.home}/providers</outputDirectory>
|
||||
|
||||
@ -24,7 +24,7 @@ import io.opentelemetry.api.trace.StatusCode;
|
||||
import io.opentelemetry.api.trace.TraceFlags;
|
||||
import io.opentelemetry.sdk.trace.ReadableSpan;
|
||||
import io.opentelemetry.sdk.trace.data.StatusData;
|
||||
import io.opentelemetry.sdk.trace.internal.data.ExceptionEventData;
|
||||
import io.opentelemetry.sdk.trace.data.ExceptionEventData;
|
||||
import io.opentelemetry.semconv.ExceptionAttributes;
|
||||
import org.jboss.arquillian.container.test.api.ContainerController;
|
||||
import org.jboss.arquillian.test.api.ArquillianResource;
|
||||
|
||||
@ -259,7 +259,7 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.oracle.database.jdbc</groupId>
|
||||
<artifactId>ojdbc11</artifactId>
|
||||
<artifactId>ojdbc17</artifactId>
|
||||
<version>${oracle-jdbc.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user