io.quarkus
quarkus-bootstrap-core
diff --git a/quarkus/deployment/src/main/java/org/keycloak/quarkus/deployment/KeycloakProcessor.java b/quarkus/deployment/src/main/java/org/keycloak/quarkus/deployment/KeycloakProcessor.java
index afe956a144..287430a4f8 100644
--- a/quarkus/deployment/src/main/java/org/keycloak/quarkus/deployment/KeycloakProcessor.java
+++ b/quarkus/deployment/src/main/java/org/keycloak/quarkus/deployment/KeycloakProcessor.java
@@ -50,8 +50,11 @@ import java.util.jar.JarFile;
import io.quarkus.deployment.IsDevelopment;
import io.quarkus.deployment.builditem.HotDeploymentWatchedFileBuildItem;
import io.quarkus.deployment.builditem.IndexDependencyBuildItem;
+import io.quarkus.deployment.builditem.LaunchModeBuildItem;
+import io.quarkus.deployment.builditem.StaticInitConfigSourceProviderBuildItem;
import io.quarkus.hibernate.orm.deployment.HibernateOrmConfig;
import io.quarkus.resteasy.server.common.deployment.ResteasyDeploymentCustomizerBuildItem;
+import io.quarkus.runtime.LaunchMode;
import io.quarkus.smallrye.health.runtime.SmallRyeHealthHandler;
import io.quarkus.vertx.http.deployment.RouteBuildItem;
import io.vertx.core.Handler;
@@ -85,6 +88,7 @@ import org.keycloak.provider.ProviderFactory;
import org.keycloak.provider.ProviderManager;
import org.keycloak.provider.Spi;
import org.keycloak.provider.quarkus.QuarkusRequestFilter;
+import org.keycloak.provider.quarkus.dev.QuarkusDevRequestFilter;
import org.keycloak.quarkus.KeycloakRecorder;
import io.quarkus.deployment.annotations.BuildProducer;
@@ -191,6 +195,16 @@ class KeycloakProcessor {
recorder.configSessionFactory(factories, defaultProviders, preConfiguredProviders, Environment.isRebuild());
}
+ /**
+ * Register the custom {@link org.eclipse.microprofile.config.spi.ConfigSource} implementations.
+ *
+ * @param configSources
+ */
+ @BuildStep
+ void configureConfigSources(BuildProducer configSources) {
+ configSources.produce(new StaticInitConfigSourceProviderBuildItem(KeycloakConfigSourceProvider.class.getName()));
+ }
+
/**
* Make the build time configuration available at runtime so that the server can run without having to specify some of
* the properties again.
@@ -253,8 +267,15 @@ class KeycloakProcessor {
}
@BuildStep
- void initializeFilter(BuildProducer filters) {
- filters.produce(new FilterBuildItem(new QuarkusRequestFilter(),FilterBuildItem.AUTHORIZATION - 10));
+ void initializeFilter(BuildProducer filters, LaunchModeBuildItem launchModeBuildItem) {
+ QuarkusRequestFilter filter = new QuarkusRequestFilter();
+ LaunchMode launchMode = launchModeBuildItem.getLaunchMode();
+
+ if (launchMode.isDevOrTest()) {
+ filter = new QuarkusDevRequestFilter();
+ }
+
+ filters.produce(new FilterBuildItem(filter,FilterBuildItem.AUTHORIZATION - 10));
}
/**
@@ -283,10 +304,10 @@ class KeycloakProcessor {
metricsHandler = new NotFoundHandler();
}
- routes.produce(new RouteBuildItem(DEFAULT_HEALTH_ENDPOINT, healthHandler));
- routes.produce(new RouteBuildItem(DEFAULT_HEALTH_ENDPOINT.concat("/live"), healthHandler));
- routes.produce(new RouteBuildItem(DEFAULT_HEALTH_ENDPOINT.concat("/ready"), healthHandler));
- routes.produce(new RouteBuildItem(KeycloakMetricsHandler.DEFAULT_METRICS_ENDPOINT, metricsHandler));
+ routes.produce(RouteBuildItem.builder().route(DEFAULT_HEALTH_ENDPOINT).handler(healthHandler).build());
+ routes.produce(RouteBuildItem.builder().route(DEFAULT_HEALTH_ENDPOINT.concat("/live")).handler(healthHandler).build());
+ routes.produce(RouteBuildItem.builder().route(DEFAULT_HEALTH_ENDPOINT.concat("/ready")).handler(healthHandler).build());
+ routes.produce(RouteBuildItem.builder().route(KeycloakMetricsHandler.DEFAULT_METRICS_ENDPOINT).handler(metricsHandler).build());
}
@BuildStep
@@ -310,7 +331,7 @@ class KeycloakProcessor {
private Map, Map>> loadFactories(
Map preConfiguredProviders) {
- loadConfig();
+ Config.init(new MicroProfileConfigProvider());
BuildClassLoader providerClassLoader = new BuildClassLoader();
ProviderManager pm = new ProviderManager(KeycloakDeploymentInfo.create().services(), providerClassLoader);
Map, Map>> factories = new HashMap<>();
@@ -485,18 +506,6 @@ class KeycloakProcessor {
}
}
- protected void loadConfig() {
- ServiceLoader loader = ServiceLoader.load(ConfigProviderFactory.class, KeycloakApplication.class.getClassLoader());
-
- try {
- ConfigProviderFactory factory = loader.iterator().next();
- logger.debugv("ConfigProvider: {0}", factory.getClass().getName());
- Config.init(factory.create().orElseThrow(() -> new RuntimeException("Failed to load Keycloak configuration")));
- } catch (NoSuchElementException e) {
- throw new RuntimeException("No valid ConfigProvider found");
- }
- }
-
private boolean isMetricsEnabled() {
return Configuration.getOptionalBooleanValue(MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX.concat("metrics.enabled")).orElse(false);
}
diff --git a/quarkus/deployment/src/test/resources/application.properties b/quarkus/deployment/src/test/resources/application.properties
index 6aab7835e4..2b2f40dea2 100644
--- a/quarkus/deployment/src/test/resources/application.properties
+++ b/quarkus/deployment/src/test/resources/application.properties
@@ -2,4 +2,5 @@ quarkus.http.root-path=/
quarkus.application.name=Keycloak
quarkus.banner.enabled=false
-quarkus.resteasy.ignore-application-classes=true
\ No newline at end of file
+quarkus.resteasy.ignore-application-classes=true
+quarkus.arc.ignored-split-packages=org.keycloak.*
\ No newline at end of file
diff --git a/quarkus/pom.xml b/quarkus/pom.xml
index b6761dd4e2..1898dd0e81 100755
--- a/quarkus/pom.xml
+++ b/quarkus/pom.xml
@@ -31,21 +31,37 @@
pom
- 1.13.3.Final
- 4.5.9.Final
- 2.12.1
+
+ 2.2.2.Final
+
+
+ 4.7.0.Final
+ 2.12.5
${jackson.version}
- 5.4.29.Final
- 8.0.24
- 42.2.20
- 4.6.1
- 1.28
- 3.0.0-M5
- 1.5.4.Final-format-001
- 1.8
+ 5.6.0.Beta1
+ 8.0.26
+ 42.2.23
+ 3.0
+ 1.5.4.Final-format-001
+
+
+ 2.0.1.Final
+ 1.4.1.SP1
+ 1.8.3
+
UTF-8
- 1.8
- true
+ 3.8.1
+ 11
+ 11
+ 11
+
+ 3.0.0-M5
@@ -58,12 +74,7 @@
import
-
-
diff --git a/quarkus/server/src/main/java/org/keycloak/quarkus/_private/IDELauncher.java b/quarkus/server/src/main/java/org/keycloak/quarkus/_private/IDELauncher.java
new file mode 100644
index 0000000000..64766b36bd
--- /dev/null
+++ b/quarkus/server/src/main/java/org/keycloak/quarkus/_private/IDELauncher.java
@@ -0,0 +1,39 @@
+package org.keycloak.quarkus._private;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import io.quarkus.runtime.Quarkus;
+import org.keycloak.util.Environment;
+
+/**
+ * This main class should be used to start the server in dev mode for development purposes. By running this class,
+ * developers should be able to mimic any server behavior and configuration as if they were using the CLI.
+ *
+ *
There are some limitations during development such as:
+ *
+ *
+ * - Transient dependencies from the keycloak server extension (runtime module) are not eligible for hot-reload
+ * - Code changes such as changing the structure of classes (e.g.: new/change methods) should still require a JVM restart
+ *
+ *
+ * Despite the limitations, it should be possible to debug the extension (e.g.: deployment steps) as well as perform changes at runtime
+ * without having to restart the JVM.
+ *
+ * @author Pedro Igor
+ */
+public class IDELauncher {
+
+ public static void main(String[] args) {
+ List devArgs = new ArrayList<>();
+
+ devArgs.addAll(Arrays.asList(args));
+
+ if (devArgs.isEmpty()) {
+ devArgs.add("start-dev");
+ }
+
+ Quarkus.run(devArgs.toArray(new String[devArgs.size()]));
+ }
+}
diff --git a/quarkus/server/src/main/resources/META-INF/keycloak.properties b/quarkus/server/src/main/resources/META-INF/keycloak.properties
index 99881c49f0..55585939d5 100644
--- a/quarkus/server/src/main/resources/META-INF/keycloak.properties
+++ b/quarkus/server/src/main/resources/META-INF/keycloak.properties
@@ -1,14 +1,10 @@
# Default and non-production grade database vendor
db=h2-file
+db.username = sa
+db.password = keycloak
-# 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.cluster=local
-%dev.spi.theme.cache-themes=false
-%dev.spi.theme.cache-templates=false
-%dev.spi.theme.static-max-age=-1
+# Insecure requests are disabled by default
+http.enabled=false
# Metrics and healthcheck are disabled by default
metrics.enabled=false
@@ -16,6 +12,13 @@ metrics.enabled=false
# Themes
spi.theme.folder.dir=${kc.home.dir:}/themes
+# Default, and insecure, and non-production grade configuration for the development profile
+%dev.http.enabled=true
+%dev.cluster=local
+%dev.spi.theme.cache-themes=false
+%dev.spi.theme.cache-templates=false
+%dev.spi.theme.static-max-age=-1
+
# 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
diff --git a/quarkus/server/src/main/resources/application.properties b/quarkus/server/src/main/resources/application.properties
index e5a595bd94..aabcb3fefc 100644
--- a/quarkus/server/src/main/resources/application.properties
+++ b/quarkus/server/src/main/resources/application.properties
@@ -20,3 +20,6 @@ quarkus.transaction-manager.default-transaction-timeout=300
# application classes are no longer supported by resteasy extension
quarkus.resteasy.ignore-application-classes=true
+# Ignore split packages for Keycloak related packages
+quarkus.arc.ignored-split-packages=org.keycloak.*
+
diff --git a/testsuite/integration-arquillian/servers/auth-server/pom.xml b/testsuite/integration-arquillian/servers/auth-server/pom.xml
index 802fd490bb..e5099541e2 100644
--- a/testsuite/integration-arquillian/servers/auth-server/pom.xml
+++ b/testsuite/integration-arquillian/servers/auth-server/pom.xml
@@ -42,7 +42,7 @@
- quarkus
+ auth-server-quarkus
quarkus
diff --git a/testsuite/integration-arquillian/servers/auth-server/quarkus/ant/configure.xml b/testsuite/integration-arquillian/servers/auth-server/quarkus/ant/configure.xml
index 026e748d18..4e0296a02e 100644
--- a/testsuite/integration-arquillian/servers/auth-server/quarkus/ant/configure.xml
+++ b/testsuite/integration-arquillian/servers/auth-server/quarkus/ant/configure.xml
@@ -6,6 +6,7 @@
+
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/KeycloakQuarkusServerDeployableContainer.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/KeycloakQuarkusServerDeployableContainer.java
index 0d6eee7159..90f03014dc 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/KeycloakQuarkusServerDeployableContainer.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/KeycloakQuarkusServerDeployableContainer.java
@@ -126,7 +126,7 @@ public class KeycloakQuarkusServerDeployableContainer implements DeployableConta
}
if (isReaugmentBeforeStart()) {
- List commands = new ArrayList<>(Arrays.asList("./kc.sh", "config", "-Dquarkus.http.root-path=/auth"));
+ List commands = new ArrayList<>(Arrays.asList("./kc.sh", "config", "-Dquarkus.http.root-path=/auth", "--http-enabled=true"));
addAdditionalCommands(commands);
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/AbstractAdminTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/AbstractAdminTest.java
index ba4f5cb030..e5fb1a4c36 100755
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/AbstractAdminTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/AbstractAdminTest.java
@@ -34,6 +34,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import com.fasterxml.jackson.core.type.TypeReference;
/**
* This class adapts the functionality from the old testsuite to make tests
@@ -100,4 +101,12 @@ public abstract class AbstractAdminTest extends AbstractTestRealmKeycloakTest {
}
}
+ public static T loadJson(InputStream is, TypeReference type) {
+ try {
+ return JsonSerialization.readValue(is, type);
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to parse json", e);
+ }
+ }
+
}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/admin/KcAdmSessionTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/admin/KcAdmSessionTest.java
index 11fe86cdfb..16434f9535 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/admin/KcAdmSessionTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/admin/KcAdmSessionTest.java
@@ -1,5 +1,6 @@
package org.keycloak.testsuite.cli.admin;
+import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.junit.Assert;
import org.junit.Test;
@@ -26,7 +27,7 @@ import static org.keycloak.testsuite.cli.KcAdmExec.execute;
@AuthServerContainerExclude({AuthServer.REMOTE, AuthServer.QUARKUS})
public class KcAdmSessionTest extends AbstractAdmCliTest {
- static Class extends List> LIST_OF_JSON = new ArrayList() {}.getClass();
+ static TypeReference> LIST_OF_JSON = new TypeReference>() {};
@Test
public void test() throws IOException {
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/VerifyProfileTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/VerifyProfileTest.java
index b6e9646cef..b91ab8f31d 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/VerifyProfileTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/VerifyProfileTest.java
@@ -943,9 +943,10 @@ public class VerifyProfileTest extends AbstractTestRealmKeycloakTest {
public static void setUserProfileConfiguration(RealmResource testRealm, String configuration) {
- Response r = testRealm.users().userProfile().update(configuration);
- if (r.getStatus() != 200) {
- Assert.fail("UserProfile Configuration not set due to error: " + r.readEntity(String.class));
+ try (Response r = testRealm.users().userProfile().update(configuration)) {
+ if (r.getStatus() != 200) {
+ Assert.fail("UserProfile Configuration not set due to error: " + r.readEntity(String.class));
+ }
}
}