Minor changes to pom files and fixing exception handling
This commit is contained in:
parent
c98048bf64
commit
c929f81dd7
11 changed files with 76 additions and 120 deletions
|
@ -56,6 +56,8 @@
|
||||||
<type>pom</type>
|
<type>pom</type>
|
||||||
<scope>import</scope>
|
<scope>import</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Override the dependencies below to use the versions used by Quarkus -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.hibernate</groupId>
|
<groupId>org.hibernate</groupId>
|
||||||
<artifactId>hibernate-core</artifactId>
|
<artifactId>hibernate-core</artifactId>
|
||||||
|
@ -100,33 +102,6 @@
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.hibernate</groupId>
|
|
||||||
<artifactId>hibernate-core</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.infinispan</groupId>
|
|
||||||
<artifactId>infinispan-core</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.infinispan</groupId>
|
|
||||||
<artifactId>infinispan-commons</artifactId>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<pluginManagement>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.jboss.jandex</groupId>
|
|
||||||
<artifactId>jandex-maven-plugin</artifactId>
|
|
||||||
<version>1.0.8</version>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</pluginManagement>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
<module>deployment</module>
|
<module>deployment</module>
|
||||||
<module>runtime</module>
|
<module>runtime</module>
|
||||||
|
|
|
@ -441,6 +441,14 @@
|
||||||
<groupId>org.liquibase</groupId>
|
<groupId>org.liquibase</groupId>
|
||||||
<artifactId>liquibase-core</artifactId>
|
<artifactId>liquibase-core</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.infinispan</groupId>
|
||||||
|
<artifactId>infinispan-commons</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.infinispan</groupId>
|
||||||
|
<artifactId>infinispan-core</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
|
|
|
@ -14,6 +14,7 @@ import org.jboss.resteasy.plugins.server.servlet.ResteasyContextParameters;
|
||||||
import org.jboss.resteasy.spi.ResteasyDeployment;
|
import org.jboss.resteasy.spi.ResteasyDeployment;
|
||||||
import org.keycloak.common.util.Resteasy;
|
import org.keycloak.common.util.Resteasy;
|
||||||
import org.keycloak.models.utils.PostMigrationEvent;
|
import org.keycloak.models.utils.PostMigrationEvent;
|
||||||
|
import org.keycloak.provider.quarkus.QuarkusPlatform;
|
||||||
import org.keycloak.services.resources.KeycloakApplication;
|
import org.keycloak.services.resources.KeycloakApplication;
|
||||||
import org.keycloak.services.resources.QuarkusWelcomeResource;
|
import org.keycloak.services.resources.QuarkusWelcomeResource;
|
||||||
import org.keycloak.services.resources.WelcomeResource;
|
import org.keycloak.services.resources.WelcomeResource;
|
||||||
|
@ -26,9 +27,13 @@ public class QuarkusKeycloakApplication extends KeycloakApplication {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void startup() {
|
protected void startup() {
|
||||||
forceEntityManagerInitialization();
|
try {
|
||||||
initializeKeycloakSessionFactory();
|
forceEntityManagerInitialization();
|
||||||
setupScheduledTasks(sessionFactory);
|
initializeKeycloakSessionFactory();
|
||||||
|
setupScheduledTasks(sessionFactory);
|
||||||
|
} catch (Throwable cause) {
|
||||||
|
QuarkusPlatform.exitOnError(cause);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -28,7 +28,7 @@ import org.keycloak.common.Profile;
|
||||||
import org.keycloak.configuration.PropertyMapper;
|
import org.keycloak.configuration.PropertyMapper;
|
||||||
import org.keycloak.configuration.PropertyMappers;
|
import org.keycloak.configuration.PropertyMappers;
|
||||||
import org.keycloak.platform.Platform;
|
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.provider.quarkus.QuarkusPlatform;
|
||||||
import org.keycloak.util.Environment;
|
import org.keycloak.util.Environment;
|
||||||
import picocli.CommandLine;
|
import picocli.CommandLine;
|
||||||
|
@ -136,16 +136,16 @@ final class Picocli {
|
||||||
if (throwable != null) {
|
if (throwable != null) {
|
||||||
boolean verbose = cliArgs.stream().anyMatch((arg) -> "--verbose".equals(arg));
|
boolean verbose = cliArgs.stream().anyMatch((arg) -> "--verbose".equals(arg));
|
||||||
|
|
||||||
if (throwable instanceof QuarkusConfigurationException) {
|
if (throwable instanceof InitializationException) {
|
||||||
QuarkusConfigurationException quarkusConfigException = (QuarkusConfigurationException) throwable;
|
InitializationException initializationException = (InitializationException) throwable;
|
||||||
if (quarkusConfigException.getSuppressed() == null || quarkusConfigException.getSuppressed().length == 0) {
|
if (initializationException.getSuppressed() == null || initializationException.getSuppressed().length == 0) {
|
||||||
dumpException(cmd, quarkusConfigException, verbose);
|
dumpException(cmd, initializationException, verbose);
|
||||||
} else if (quarkusConfigException.getSuppressed().length == 1) {
|
} else if (initializationException.getSuppressed().length == 1) {
|
||||||
dumpException(cmd, quarkusConfigException.getSuppressed()[0], verbose);
|
dumpException(cmd, initializationException.getSuppressed()[0], verbose);
|
||||||
} else {
|
} else {
|
||||||
logError(cmd, "ERROR: Multiple configuration errors during startup");
|
logError(cmd, "ERROR: Multiple configuration errors during startup");
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
for (Throwable inner : quarkusConfigException.getSuppressed()) {
|
for (Throwable inner : initializationException.getSuppressed()) {
|
||||||
counter++;
|
counter++;
|
||||||
logError(cmd, "ERROR " + counter);
|
logError(cmd, "ERROR " + counter);
|
||||||
dumpException(cmd, inner, verbose);
|
dumpException(cmd, inner, verbose);
|
||||||
|
|
|
@ -21,6 +21,7 @@ import static org.keycloak.configuration.PropertyMapper.MAPPERS;
|
||||||
import static org.keycloak.configuration.PropertyMapper.create;
|
import static org.keycloak.configuration.PropertyMapper.create;
|
||||||
import static org.keycloak.configuration.PropertyMapper.createWithDefault;
|
import static org.keycloak.configuration.PropertyMapper.createWithDefault;
|
||||||
import static org.keycloak.configuration.PropertyMapper.forBuildTimeProperty;
|
import static org.keycloak.configuration.PropertyMapper.forBuildTimeProperty;
|
||||||
|
import static org.keycloak.provider.quarkus.QuarkusPlatform.addInitializationException;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
@ -67,7 +68,7 @@ public final class PropertyMappers {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proceed == null || proceed.getValue() == null) {
|
if (proceed == null || proceed.getValue() == null) {
|
||||||
addDeferredConfigurationException(Messages.httpsConfigurationNotSet());
|
addInitializationException(Messages.httpsConfigurationNotSet());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +115,7 @@ public final class PropertyMappers {
|
||||||
case "passthrough":
|
case "passthrough":
|
||||||
return "true";
|
return "true";
|
||||||
}
|
}
|
||||||
addDeferredConfigurationException(Messages.invalidProxyMode(mode));
|
addInitializationException(Messages.invalidProxyMode(mode));
|
||||||
return "false";
|
return "false";
|
||||||
}, "The proxy mode if the server is behind a reverse proxy. Possible values are: none, edge, reencrypt, and passthrough.");
|
}, "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":
|
case "postgres-10":
|
||||||
return "postgresql";
|
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";
|
return "h2";
|
||||||
}, "The database vendor. Possible values are: h2-mem, h2-file, mariadb, mysql, postgres95, postgres10.");
|
}, "The database vendor. Possible values are: h2-mem, h2-file, mariadb, mysql, postgres95, postgres10.");
|
||||||
create("db", "quarkus.datasource.jdbc.transactions", (db, context) -> "xa", null);
|
create("db", "quarkus.datasource.jdbc.transactions", (db, context) -> "xa", null);
|
||||||
|
@ -197,16 +198,7 @@ public final class PropertyMappers {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void configureClustering() {
|
private static void configureClustering() {
|
||||||
createWithDefault("cluster", "kc.spi.connections-infinispan.default.config-file", "placeholder", (value, context) -> {
|
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-` "
|
||||||
|
|
||||||
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-` "
|
|
||||||
+ "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 " +
|
+ "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.");
|
"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.");
|
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);
|
}).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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,5 +24,5 @@ package org.keycloak.provider.quarkus;
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
*/
|
*/
|
||||||
public class QuarkusConfigurationException extends RuntimeException {
|
public class InitializationException extends RuntimeException {
|
||||||
}
|
}
|
|
@ -40,16 +40,7 @@ public class QuarkusLifecycleObserver {
|
||||||
void onStartupEvent(@Observes StartupEvent event) {
|
void onStartupEvent(@Observes StartupEvent event) {
|
||||||
QuarkusPlatform platform = (QuarkusPlatform) Platform.getPlatform();
|
QuarkusPlatform platform = (QuarkusPlatform) Platform.getPlatform();
|
||||||
platform.started();
|
platform.started();
|
||||||
|
QuarkusPlatform.exitOnError();
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
Runnable startupHook = platform.startupHook;
|
Runnable startupHook = platform.startupHook;
|
||||||
|
|
||||||
if (startupHook != null) {
|
if (startupHook != null) {
|
||||||
|
|
|
@ -21,10 +21,48 @@ import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
import org.keycloak.platform.Platform;
|
||||||
import org.keycloak.platform.PlatformProvider;
|
import org.keycloak.platform.PlatformProvider;
|
||||||
|
|
||||||
public class QuarkusPlatform implements PlatformProvider {
|
public class QuarkusPlatform implements PlatformProvider {
|
||||||
|
|
||||||
|
public static void addInitializationException(Throwable throwable) {
|
||||||
|
QuarkusPlatform platform = (QuarkusPlatform) Platform.getPlatform();
|
||||||
|
platform.addDeferredException(throwable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Throws a {@link InitializationException} exception to indicate errors during the startup.
|
||||||
|
*
|
||||||
|
* <p>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 startupHook;
|
||||||
Runnable shutdownHook;
|
Runnable shutdownHook;
|
||||||
|
|
||||||
|
@ -49,7 +87,7 @@ public class QuarkusPlatform implements PlatformProvider {
|
||||||
/**
|
/**
|
||||||
* Called when Quarkus platform is started
|
* Called when Quarkus platform is started
|
||||||
*/
|
*/
|
||||||
public void started() {
|
void started() {
|
||||||
this.started.set(true);
|
this.started.set(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,11 +100,11 @@ public class QuarkusPlatform implements PlatformProvider {
|
||||||
*
|
*
|
||||||
* @param t
|
* @param t
|
||||||
*/
|
*/
|
||||||
public void addDeferredException(Throwable t) {
|
private void addDeferredException(Throwable t) {
|
||||||
deferredExceptions.add(t);
|
deferredExceptions.add(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Throwable> getDeferredExceptions() {
|
List<Throwable> getDeferredExceptions() {
|
||||||
return deferredExceptions;
|
return deferredExceptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -234,8 +234,6 @@ public class ConfigurationTest {
|
||||||
public void testClusterConfig() {
|
public void testClusterConfig() {
|
||||||
// Cluster enabled by default, but disabled for the "dev" profile
|
// Cluster enabled by default, but disabled for the "dev" profile
|
||||||
Assert.assertEquals("cluster-default.xml", initConfig("connectionsInfinispan", "default").get("configFile"));
|
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
|
// If explicitly set, then it is always used regardless of the profile
|
||||||
System.clearProperty("kc.profile");
|
System.clearProperty("kc.profile");
|
||||||
|
|
|
@ -64,50 +64,4 @@
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
<profiles>
|
|
||||||
<profile>
|
|
||||||
<id>native</id>
|
|
||||||
<activation>
|
|
||||||
<property>
|
|
||||||
<name>native</name>
|
|
||||||
</property>
|
|
||||||
</activation>
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>io.quarkus</groupId>
|
|
||||||
<artifactId>quarkus-maven-plugin</artifactId>
|
|
||||||
<version>${quarkus.version}</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<goals>
|
|
||||||
<goal>native-image</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<enableHttpUrlHandler>true</enableHttpUrlHandler>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<artifactId>maven-failsafe-plugin</artifactId>
|
|
||||||
<version>${surefire-plugin.version}</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<goals>
|
|
||||||
<goal>integration-test</goal>
|
|
||||||
<goal>verify</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<systemProperties>
|
|
||||||
<native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
|
|
||||||
</systemProperties>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
</profile>
|
|
||||||
</profiles>
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -4,4 +4,5 @@ db=h2-file
|
||||||
# Default, and insecure, and non-production grade configuration for the development profile
|
# Default, and insecure, and non-production grade configuration for the development profile
|
||||||
%dev.http.enabled=true
|
%dev.http.enabled=true
|
||||||
%dev.db.username = sa
|
%dev.db.username = sa
|
||||||
%dev.db.password = keycloak
|
%dev.db.password = keycloak
|
||||||
|
%dev.cluster=local
|
Loading…
Reference in a new issue