junit
junit
diff --git a/quarkus/runtime/src/main/java/org/keycloak/QuarkusKeycloakApplication.java b/quarkus/runtime/src/main/java/org/keycloak/QuarkusKeycloakApplication.java
index 9964c7099c..fb731cd1ef 100644
--- a/quarkus/runtime/src/main/java/org/keycloak/QuarkusKeycloakApplication.java
+++ b/quarkus/runtime/src/main/java/org/keycloak/QuarkusKeycloakApplication.java
@@ -14,6 +14,7 @@ import org.jboss.resteasy.plugins.server.servlet.ResteasyContextParameters;
import org.jboss.resteasy.spi.ResteasyDeployment;
import org.keycloak.common.util.Resteasy;
import org.keycloak.models.utils.PostMigrationEvent;
+import org.keycloak.provider.quarkus.QuarkusPlatform;
import org.keycloak.services.resources.KeycloakApplication;
import org.keycloak.services.resources.QuarkusWelcomeResource;
import org.keycloak.services.resources.WelcomeResource;
@@ -26,9 +27,13 @@ public class QuarkusKeycloakApplication extends KeycloakApplication {
@Override
protected void startup() {
- forceEntityManagerInitialization();
- initializeKeycloakSessionFactory();
- setupScheduledTasks(sessionFactory);
+ try {
+ forceEntityManagerInitialization();
+ initializeKeycloakSessionFactory();
+ setupScheduledTasks(sessionFactory);
+ } catch (Throwable cause) {
+ QuarkusPlatform.exitOnError(cause);
+ }
}
@Override
diff --git a/quarkus/runtime/src/main/java/org/keycloak/cli/Picocli.java b/quarkus/runtime/src/main/java/org/keycloak/cli/Picocli.java
index 593f27896a..0615f0e576 100644
--- a/quarkus/runtime/src/main/java/org/keycloak/cli/Picocli.java
+++ b/quarkus/runtime/src/main/java/org/keycloak/cli/Picocli.java
@@ -28,7 +28,7 @@ import org.keycloak.common.Profile;
import org.keycloak.configuration.PropertyMapper;
import org.keycloak.configuration.PropertyMappers;
import org.keycloak.platform.Platform;
-import org.keycloak.provider.quarkus.QuarkusConfigurationException;
+import org.keycloak.provider.quarkus.InitializationException;
import org.keycloak.provider.quarkus.QuarkusPlatform;
import org.keycloak.util.Environment;
import picocli.CommandLine;
@@ -136,16 +136,16 @@ final class Picocli {
if (throwable != null) {
boolean verbose = cliArgs.stream().anyMatch((arg) -> "--verbose".equals(arg));
- if (throwable instanceof QuarkusConfigurationException) {
- QuarkusConfigurationException quarkusConfigException = (QuarkusConfigurationException) throwable;
- if (quarkusConfigException.getSuppressed() == null || quarkusConfigException.getSuppressed().length == 0) {
- dumpException(cmd, quarkusConfigException, verbose);
- } else if (quarkusConfigException.getSuppressed().length == 1) {
- dumpException(cmd, quarkusConfigException.getSuppressed()[0], verbose);
+ if (throwable instanceof InitializationException) {
+ InitializationException initializationException = (InitializationException) throwable;
+ if (initializationException.getSuppressed() == null || initializationException.getSuppressed().length == 0) {
+ dumpException(cmd, initializationException, verbose);
+ } else if (initializationException.getSuppressed().length == 1) {
+ dumpException(cmd, initializationException.getSuppressed()[0], verbose);
} else {
logError(cmd, "ERROR: Multiple configuration errors during startup");
int counter = 0;
- for (Throwable inner : quarkusConfigException.getSuppressed()) {
+ for (Throwable inner : initializationException.getSuppressed()) {
counter++;
logError(cmd, "ERROR " + counter);
dumpException(cmd, inner, verbose);
diff --git a/quarkus/runtime/src/main/java/org/keycloak/configuration/PropertyMappers.java b/quarkus/runtime/src/main/java/org/keycloak/configuration/PropertyMappers.java
index 0fe943d335..6452893b03 100644
--- a/quarkus/runtime/src/main/java/org/keycloak/configuration/PropertyMappers.java
+++ b/quarkus/runtime/src/main/java/org/keycloak/configuration/PropertyMappers.java
@@ -21,6 +21,7 @@ import static org.keycloak.configuration.PropertyMapper.MAPPERS;
import static org.keycloak.configuration.PropertyMapper.create;
import static org.keycloak.configuration.PropertyMapper.createWithDefault;
import static org.keycloak.configuration.PropertyMapper.forBuildTimeProperty;
+import static org.keycloak.provider.quarkus.QuarkusPlatform.addInitializationException;
import java.io.File;
import java.nio.file.Paths;
@@ -67,7 +68,7 @@ public final class PropertyMappers {
}
if (proceed == null || proceed.getValue() == null) {
- addDeferredConfigurationException(Messages.httpsConfigurationNotSet());
+ addInitializationException(Messages.httpsConfigurationNotSet());
}
}
@@ -114,7 +115,7 @@ public final class PropertyMappers {
case "passthrough":
return "true";
}
- addDeferredConfigurationException(Messages.invalidProxyMode(mode));
+ addInitializationException(Messages.invalidProxyMode(mode));
return "false";
}, "The proxy mode if the server is behind a reverse proxy. Possible values are: none, edge, reencrypt, and passthrough.");
}
@@ -167,7 +168,7 @@ public final class PropertyMappers {
case "postgres-10":
return "postgresql";
}
- addDeferredConfigurationException(invalidDatabaseVendor(db, "h2-file", "h2-mem", "mariadb", "mysql", "postgres", "postgres-95", "postgres-10"));
+ addInitializationException(invalidDatabaseVendor(db, "h2-file", "h2-mem", "mariadb", "mysql", "postgres", "postgres-95", "postgres-10"));
return "h2";
}, "The database vendor. Possible values are: h2-mem, h2-file, mariadb, mysql, postgres95, postgres10.");
create("db", "quarkus.datasource.jdbc.transactions", (db, context) -> "xa", null);
@@ -197,16 +198,7 @@ public final class PropertyMappers {
}
private static void configureClustering() {
- createWithDefault("cluster", "kc.spi.connections-infinispan.default.config-file", "placeholder", (value, context) -> {
-
- if ("placeholder".equals(value)) {
- // Clustering is disabled by default for the "dev" profile. Otherwise enabled
- value = ("dev".equalsIgnoreCase(ProfileManager.getActiveProfile())) ? "local" : "default";
- }
-
- return "cluster-" + value + ".xml";
-
- }, "Specifies clustering configuration. The specified value points to the infinispan configuration file prefixed with the 'cluster-` "
+ createWithDefault("cluster", "kc.spi.connections-infinispan.default.config-file", "default", (value, context) -> "cluster-" + value + ".xml", "Specifies clustering configuration. The specified value points to the infinispan configuration file prefixed with the 'cluster-` "
+ "inside the distribution configuration directory. Supported values out of the box are 'local' and 'cluster'. Value 'local' points to the file cluster-local.xml and " +
"effectively disables clustering and use infinispan caches in the local mode. Value 'default' points to the file cluster-default.xml, which has clustering enabled for infinispan caches.");
create("cluster-stack", "kc.spi.connections-infinispan.default.stack", "Specified the default stack to use for cluster communication and node discovery. Possible values are: tcp, udp, kubernetes, ec2.");
@@ -268,10 +260,4 @@ public final class PropertyMappers {
}
}).findFirst().orElse(null);
}
-
- // Exception to be thrown later, so that we can properly log it and collect all possible configuration issues (not just the first one)
- private static void addDeferredConfigurationException(Exception e) {
- QuarkusPlatform quarkusPlatform = (QuarkusPlatform) Platform.getPlatform();
- quarkusPlatform.addDeferredException(e);
- }
}
diff --git a/quarkus/runtime/src/main/java/org/keycloak/provider/quarkus/QuarkusConfigurationException.java b/quarkus/runtime/src/main/java/org/keycloak/provider/quarkus/InitializationException.java
similarity index 93%
rename from quarkus/runtime/src/main/java/org/keycloak/provider/quarkus/QuarkusConfigurationException.java
rename to quarkus/runtime/src/main/java/org/keycloak/provider/quarkus/InitializationException.java
index f36ccd3bee..a2d17178a0 100644
--- a/quarkus/runtime/src/main/java/org/keycloak/provider/quarkus/QuarkusConfigurationException.java
+++ b/quarkus/runtime/src/main/java/org/keycloak/provider/quarkus/InitializationException.java
@@ -24,5 +24,5 @@ package org.keycloak.provider.quarkus;
*
* @author Marek Posolda
*/
-public class QuarkusConfigurationException extends RuntimeException {
+public class InitializationException extends RuntimeException {
}
diff --git a/quarkus/runtime/src/main/java/org/keycloak/provider/quarkus/QuarkusLifecycleObserver.java b/quarkus/runtime/src/main/java/org/keycloak/provider/quarkus/QuarkusLifecycleObserver.java
index fa3d722238..c0226a5af9 100644
--- a/quarkus/runtime/src/main/java/org/keycloak/provider/quarkus/QuarkusLifecycleObserver.java
+++ b/quarkus/runtime/src/main/java/org/keycloak/provider/quarkus/QuarkusLifecycleObserver.java
@@ -40,16 +40,7 @@ public class QuarkusLifecycleObserver {
void onStartupEvent(@Observes StartupEvent event) {
QuarkusPlatform platform = (QuarkusPlatform) Platform.getPlatform();
platform.started();
-
- // Check if we had any exceptions during configuration phase
- if (!platform.getDeferredExceptions().isEmpty()) {
- QuarkusConfigurationException quarkusException = new QuarkusConfigurationException();
- for (Throwable inner : platform.getDeferredExceptions()) {
- quarkusException.addSuppressed(inner);
- }
- throw quarkusException;
- }
-
+ QuarkusPlatform.exitOnError();
Runnable startupHook = platform.startupHook;
if (startupHook != null) {
diff --git a/quarkus/runtime/src/main/java/org/keycloak/provider/quarkus/QuarkusPlatform.java b/quarkus/runtime/src/main/java/org/keycloak/provider/quarkus/QuarkusPlatform.java
index 1510937596..c76255d030 100644
--- a/quarkus/runtime/src/main/java/org/keycloak/provider/quarkus/QuarkusPlatform.java
+++ b/quarkus/runtime/src/main/java/org/keycloak/provider/quarkus/QuarkusPlatform.java
@@ -21,10 +21,48 @@ import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
+import org.keycloak.platform.Platform;
import org.keycloak.platform.PlatformProvider;
public class QuarkusPlatform implements PlatformProvider {
+ public static void addInitializationException(Throwable throwable) {
+ QuarkusPlatform platform = (QuarkusPlatform) Platform.getPlatform();
+ platform.addDeferredException(throwable);
+ }
+
+ /**
+ * Throws a {@link InitializationException} exception to indicate errors during the startup.
+ *
+ *
Calling this method after the server is started has no effect but just the exception being thrown.
+ *
+ * @throws InitializationException the exception holding all errors during startup.
+ */
+ public static void exitOnError() throws InitializationException {
+ QuarkusPlatform platform = (QuarkusPlatform) Platform.getPlatform();
+
+ // Check if we had any exceptions during initialization phase
+ if (!platform.getDeferredExceptions().isEmpty()) {
+ InitializationException quarkusException = new InitializationException();
+ for (Throwable inner : platform.getDeferredExceptions()) {
+ quarkusException.addSuppressed(inner);
+ }
+ throw quarkusException;
+ }
+ }
+
+ /**
+ * Similar behavior as per {@code #exitOnError} but convenient to throw a {@link InitializationException} with a single
+ * {@code cause}
+ *
+ * @param cause the cause
+ * @throws InitializationException the initialization exception with the given {@code cause}.
+ */
+ public static void exitOnError(Throwable cause) throws InitializationException{
+ addInitializationException(cause);
+ exitOnError();
+ }
+
Runnable startupHook;
Runnable shutdownHook;
@@ -49,7 +87,7 @@ public class QuarkusPlatform implements PlatformProvider {
/**
* Called when Quarkus platform is started
*/
- public void started() {
+ void started() {
this.started.set(true);
}
@@ -62,11 +100,11 @@ public class QuarkusPlatform implements PlatformProvider {
*
* @param t
*/
- public void addDeferredException(Throwable t) {
+ private void addDeferredException(Throwable t) {
deferredExceptions.add(t);
}
- public List getDeferredExceptions() {
+ List getDeferredExceptions() {
return deferredExceptions;
}
diff --git a/quarkus/runtime/src/test/java/org/keycloak/provider/quarkus/ConfigurationTest.java b/quarkus/runtime/src/test/java/org/keycloak/provider/quarkus/ConfigurationTest.java
index dfe7018b75..7c2b03237f 100644
--- a/quarkus/runtime/src/test/java/org/keycloak/provider/quarkus/ConfigurationTest.java
+++ b/quarkus/runtime/src/test/java/org/keycloak/provider/quarkus/ConfigurationTest.java
@@ -234,8 +234,6 @@ public class ConfigurationTest {
public void testClusterConfig() {
// Cluster enabled by default, but disabled for the "dev" profile
Assert.assertEquals("cluster-default.xml", initConfig("connectionsInfinispan", "default").get("configFile"));
- System.setProperty("kc.profile", "dev");
- Assert.assertEquals("cluster-local.xml", initConfig("connectionsInfinispan", "default").get("configFile"));
// If explicitly set, then it is always used regardless of the profile
System.clearProperty("kc.profile");
diff --git a/quarkus/server/pom.xml b/quarkus/server/pom.xml
index 2a24c5151c..f13145b16a 100644
--- a/quarkus/server/pom.xml
+++ b/quarkus/server/pom.xml
@@ -64,50 +64,4 @@
-
-
- native
-
-
- native
-
-
-
-
-
- io.quarkus
- quarkus-maven-plugin
- ${quarkus.version}
-
-
-
- native-image
-
-
- true
-
-
-
-
-
- maven-failsafe-plugin
- ${surefire-plugin.version}
-
-
-
- integration-test
- verify
-
-
-
- ${project.build.directory}/${project.build.finalName}-runner
-
-
-
-
-
-
-
-
-
diff --git a/quarkus/server/src/main/resources/META-INF/keycloak.properties b/quarkus/server/src/main/resources/META-INF/keycloak.properties
index 4551da2232..93c0d102d5 100644
--- a/quarkus/server/src/main/resources/META-INF/keycloak.properties
+++ b/quarkus/server/src/main/resources/META-INF/keycloak.properties
@@ -4,4 +4,5 @@ db=h2-file
# Default, and insecure, and non-production grade configuration for the development profile
%dev.http.enabled=true
%dev.db.username = sa
-%dev.db.password = keycloak
\ No newline at end of file
+%dev.db.password = keycloak
+%dev.cluster=local
\ No newline at end of file