Minor changes to pom files and fixing exception handling

This commit is contained in:
Pedro Igor 2020-10-25 21:55:25 -03:00 committed by Marek Posolda
parent c98048bf64
commit c929f81dd7
11 changed files with 76 additions and 120 deletions

View file

@ -56,6 +56,8 @@
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Override the dependencies below to use the versions used by Quarkus -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
@ -100,33 +102,6 @@
</dependencies>
</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>
<module>deployment</module>
<module>runtime</module>

View file

@ -441,6 +441,14 @@
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-commons</artifactId>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-core</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>

View file

@ -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

View file

@ -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);

View file

@ -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);
}
}

View file

@ -24,5 +24,5 @@ package org.keycloak.provider.quarkus;
*
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class QuarkusConfigurationException extends RuntimeException {
public class InitializationException extends RuntimeException {
}

View file

@ -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) {

View file

@ -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);
}
/**
* <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 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<Throwable> getDeferredExceptions() {
List<Throwable> getDeferredExceptions() {
return deferredExceptions;
}

View file

@ -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");

View file

@ -64,50 +64,4 @@
</plugin>
</plugins>
</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>

View file

@ -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
%dev.db.password = keycloak
%dev.cluster=local