[KEYCLOAK-17866] - Upgrade to Quarkus v2
This commit is contained in:
parent
47484c1aed
commit
aa018295c4
32 changed files with 339 additions and 132 deletions
21
.github/workflows/ci.yml
vendored
21
.github/workflows/ci.yml
vendored
|
@ -2,6 +2,9 @@ name: Keycloak CI
|
||||||
|
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
env:
|
||||||
|
DEFAULT_JDK_VERSION: 11
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: Build
|
name: Build
|
||||||
|
@ -10,7 +13,7 @@ jobs:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: actions/setup-java@v1
|
- uses: actions/setup-java@v1
|
||||||
with:
|
with:
|
||||||
java-version: 1.8
|
java-version: ${{ env.DEFAULT_JDK_VERSION }}
|
||||||
- name: Update maven settings
|
- name: Update maven settings
|
||||||
run: mkdir -p ~/.m2 ; cp .github/settings.xml ~/.m2/
|
run: mkdir -p ~/.m2 ; cp .github/settings.xml ~/.m2/
|
||||||
- name: Cache Maven packages
|
- name: Cache Maven packages
|
||||||
|
@ -24,7 +27,7 @@ jobs:
|
||||||
|
|
||||||
- name: Build Keycloak
|
- name: Build Keycloak
|
||||||
run: |
|
run: |
|
||||||
mvn clean install -nsu -B -e -DskipTests -Pquarkus,distribution
|
mvn clean install -nsu -B -e -DskipTests -Pdistribution
|
||||||
mvn clean install -nsu -B -e -f testsuite/integration-arquillian/servers/auth-server -Pauth-server-quarkus
|
mvn clean install -nsu -B -e -f testsuite/integration-arquillian/servers/auth-server -Pauth-server-quarkus
|
||||||
mvn clean install -nsu -B -e -f testsuite/integration-arquillian/servers/auth-server -Pauth-server-wildfly
|
mvn clean install -nsu -B -e -f testsuite/integration-arquillian/servers/auth-server -Pauth-server-wildfly
|
||||||
mvn clean install -nsu -B -e -f testsuite/integration-arquillian/servers/auth-server -Pauth-server-undertow
|
mvn clean install -nsu -B -e -f testsuite/integration-arquillian/servers/auth-server -Pauth-server-undertow
|
||||||
|
@ -53,7 +56,7 @@ jobs:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: actions/setup-java@v1
|
- uses: actions/setup-java@v1
|
||||||
with:
|
with:
|
||||||
java-version: 1.8
|
java-version: ${{ env.DEFAULT_JDK_VERSION }}
|
||||||
- name: Update maven settings
|
- name: Update maven settings
|
||||||
run: mkdir -p ~/.m2 ; cp .github/settings.xml ~/.m2/
|
run: mkdir -p ~/.m2 ; cp .github/settings.xml ~/.m2/
|
||||||
- name: Cache Maven packages
|
- name: Cache Maven packages
|
||||||
|
@ -94,7 +97,7 @@ jobs:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: actions/setup-java@v1
|
- uses: actions/setup-java@v1
|
||||||
with:
|
with:
|
||||||
java-version: 1.8
|
java-version: ${{ env.DEFAULT_JDK_VERSION }}
|
||||||
- name: Update maven settings
|
- name: Update maven settings
|
||||||
run: mkdir -p ~/.m2 ; cp .github/settings.xml ~/.m2/
|
run: mkdir -p ~/.m2 ; cp .github/settings.xml ~/.m2/
|
||||||
- name: Cache Maven packages
|
- name: Cache Maven packages
|
||||||
|
@ -160,7 +163,7 @@ jobs:
|
||||||
|
|
||||||
- uses: actions/setup-java@v1
|
- uses: actions/setup-java@v1
|
||||||
with:
|
with:
|
||||||
java-version: 1.8
|
java-version: ${{ env.DEFAULT_JDK_VERSION }}
|
||||||
- name: Update maven settings
|
- name: Update maven settings
|
||||||
run: mkdir -p ~/.m2 ; cp .github/settings.xml ~/.m2/
|
run: mkdir -p ~/.m2 ; cp .github/settings.xml ~/.m2/
|
||||||
|
|
||||||
|
@ -224,7 +227,7 @@ jobs:
|
||||||
- uses: actions/setup-java@v1
|
- uses: actions/setup-java@v1
|
||||||
if: ${{ github.event_name != 'pull_request' || env.GIT_DIFF != 0 }}
|
if: ${{ github.event_name != 'pull_request' || env.GIT_DIFF != 0 }}
|
||||||
with:
|
with:
|
||||||
java-version: 1.8
|
java-version: ${{ env.DEFAULT_JDK_VERSION }}
|
||||||
- name: Update maven settings
|
- name: Update maven settings
|
||||||
if: ${{ github.event_name != 'pull_request' || env.GIT_DIFF != 0 }}
|
if: ${{ github.event_name != 'pull_request' || env.GIT_DIFF != 0 }}
|
||||||
run: mkdir -p ~/.m2 ; cp .github/settings.xml ~/.m2/
|
run: mkdir -p ~/.m2 ; cp .github/settings.xml ~/.m2/
|
||||||
|
@ -263,7 +266,7 @@ jobs:
|
||||||
- uses: actions/setup-java@v1
|
- uses: actions/setup-java@v1
|
||||||
if: ${{ github.event_name != 'pull_request' || env.GIT_DIFF != 0 }}
|
if: ${{ github.event_name != 'pull_request' || env.GIT_DIFF != 0 }}
|
||||||
with:
|
with:
|
||||||
java-version: 1.8
|
java-version: ${{ env.DEFAULT_JDK_VERSION }}
|
||||||
- name: Update maven settings
|
- name: Update maven settings
|
||||||
if: ${{ github.event_name != 'pull_request' || env.GIT_DIFF != 0 }}
|
if: ${{ github.event_name != 'pull_request' || env.GIT_DIFF != 0 }}
|
||||||
run: mkdir -p ~/.m2 ; cp .github/settings.xml ~/.m2/
|
run: mkdir -p ~/.m2 ; cp .github/settings.xml ~/.m2/
|
||||||
|
@ -336,7 +339,7 @@ jobs:
|
||||||
name: keycloak-artifacts.zip
|
name: keycloak-artifacts.zip
|
||||||
- uses: actions/setup-java@v1
|
- uses: actions/setup-java@v1
|
||||||
with:
|
with:
|
||||||
java-version: 1.8
|
java-version: ${{ env.DEFAULT_JDK_VERSION }}
|
||||||
- name: Update maven settings
|
- name: Update maven settings
|
||||||
run: mkdir -p ~/.m2 ; cp .github/settings.xml ~/.m2/
|
run: mkdir -p ~/.m2 ; cp .github/settings.xml ~/.m2/
|
||||||
- name: Run Quarkus cluster tests
|
- name: Run Quarkus cluster tests
|
||||||
|
@ -374,7 +377,7 @@ jobs:
|
||||||
|
|
||||||
- uses: actions/setup-java@v1
|
- uses: actions/setup-java@v1
|
||||||
with:
|
with:
|
||||||
java-version: 1.8
|
java-version: 8
|
||||||
- name: Update maven settings
|
- name: Update maven settings
|
||||||
run: mkdir -p ~/.m2 ; cp .github/settings.xml ~/.m2/
|
run: mkdir -p ~/.m2 ; cp .github/settings.xml ~/.m2/
|
||||||
- name: Cache Maven packages
|
- name: Cache Maven packages
|
||||||
|
|
|
@ -78,8 +78,9 @@
|
||||||
</modules>
|
</modules>
|
||||||
</profile>
|
</profile>
|
||||||
<profile>
|
<profile>
|
||||||
<id>community</id>
|
<id>quarkus</id>
|
||||||
<activation>
|
<activation>
|
||||||
|
<jdk>[11,)</jdk>
|
||||||
<property>
|
<property>
|
||||||
<name>!product</name>
|
<name>!product</name>
|
||||||
</property>
|
</property>
|
||||||
|
|
|
@ -51,6 +51,10 @@ Classes from `org.keycloak.testsuite.*` packages aren't suitable to be used in p
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### Building Quarkus Distribution
|
||||||
|
|
||||||
|
Please, take a look at this [documentation](../quarkus/README.md).
|
||||||
|
|
||||||
## Starting Keycloak
|
## Starting Keycloak
|
||||||
|
|
||||||
To start Keycloak during development first build as specified above, then run:
|
To start Keycloak during development first build as specified above, then run:
|
||||||
|
|
10
pom.xml
10
pom.xml
|
@ -1897,6 +1897,16 @@
|
||||||
<ee.maven.version>${wildfly.version}</ee.maven.version>
|
<ee.maven.version>${wildfly.version}</ee.maven.version>
|
||||||
<product.filename.version>${project.version}</product.filename.version>
|
<product.filename.version>${project.version}</product.filename.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
</profile>
|
||||||
|
|
||||||
|
<profile>
|
||||||
|
<id>quarkus</id>
|
||||||
|
<activation>
|
||||||
|
<jdk>[11,)</jdk>
|
||||||
|
<property>
|
||||||
|
<name>!product</name>
|
||||||
|
</property>
|
||||||
|
</activation>
|
||||||
<modules>
|
<modules>
|
||||||
<module>quarkus</module>
|
<module>quarkus</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
|
@ -13,12 +13,22 @@ The module holds the codebase to run Keycloak on top of [Quarkus](https://quarku
|
||||||
├── The server itself, only responsible for generating the server artifacts
|
├── The server itself, only responsible for generating the server artifacts
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Activating the Module
|
||||||
|
|
||||||
|
When build from the project root directory, this module is only enabled if the installed JDK is 11 or newer.
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
|
Ensure you have JDK 11 (or newer) installed.
|
||||||
|
|
||||||
To build the module and produce the artifacts to run a server:
|
To build the module and produce the artifacts to run a server:
|
||||||
|
|
||||||
mvn -f ../pom.xml clean install -DskipTestsuite -DskipExamples -DskipTests
|
mvn -f ../pom.xml clean install -DskipTestsuite -DskipExamples -DskipTests
|
||||||
|
|
||||||
|
If you already built Keycloak artifacts using JDK 8, you should be able to skip the previous step and just build this module as follows:
|
||||||
|
|
||||||
|
mvn clean install
|
||||||
|
|
||||||
### Building the Distribution
|
### Building the Distribution
|
||||||
|
|
||||||
To build the module as well as the distribution packages:
|
To build the module as well as the distribution packages:
|
||||||
|
@ -27,12 +37,16 @@ To build the module as well as the distribution packages:
|
||||||
|
|
||||||
The distribution packages (ZIP and TAR) should be available at [../distribution/server-x-dist](../distribution/server-x-dist/target).
|
The distribution packages (ZIP and TAR) should be available at [../distribution/server-x-dist](../distribution/server-x-dist/target).
|
||||||
|
|
||||||
|
Alternatively, you can also build the distribution directly by running the following command:
|
||||||
|
|
||||||
|
mvn -f ../distribution/server-x-dist/pom.xml clean install
|
||||||
|
|
||||||
## Running
|
## Running
|
||||||
|
|
||||||
By default, the HTTP port is disabled and you need to provide the key material to configure HTTPS. If you want to enable
|
By default, the HTTP port is disabled and you need to provide the key material to configure HTTPS. If you want to enable
|
||||||
the HTTP port, run the server in development mode as follows:
|
the HTTP port, run the server in development mode as follows:
|
||||||
|
|
||||||
java -jar server/target/lib/quarkus-run.jar --profile=dev
|
java -jar server/target/lib/quarkus-run.jar start-dev
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
|
@ -40,17 +54,19 @@ the HTTP port, run the server in development mode as follows:
|
||||||
|
|
||||||
To run the server in development mode:
|
To run the server in development mode:
|
||||||
|
|
||||||
cd server
|
mvn -f server/pom.xml compile quarkus:dev
|
||||||
mvn compile quarkus:dev
|
|
||||||
|
|
||||||
You should be able to attach your debugger to port `5005`.
|
You should be able to attach your debugger to port `5005`.
|
||||||
|
|
||||||
Changes to files such as `server/src/main/resources` or `server/src/main/resources/META-INF/keycloak.properties` should
|
For debugging the build steps, you can suspend the JVM by running:
|
||||||
be recognized automatically when running in development mode.
|
|
||||||
|
|
||||||
However, considering that there is no real code in the `server` module (but from `runtime` and its dependencies), changes you make to
|
mvn -f server/pom.xml -Dsuspend=true compile quarkus:dev
|
||||||
dependencies (e.g: services, model, etc) won't be reflected into the running server. However, you can still leverage the
|
|
||||||
hot reload capabilities from your IDE to make changes at runtime.
|
|
||||||
|
|
||||||
NOTE: We need to improve DevX and figure out why changes to dependencies are not being recognized when running tests or running
|
When running using `quarkus:dev` you should be able to do live coding whenever code changes within the `server` module. Changes you make to transient dependencies from the server extension (e.g: services, model, etc) won't be reflected into the running server. However, you can still leverage the hot swapping capabilities from your IDE to make changes at runtime.
|
||||||
Quarkus Dev Mode.
|
|
||||||
|
NOTE: Although still very handy during development, there are some limitations when running in dev mode that
|
||||||
|
blocks us to leverage all the capabilities from Quarkus dev mode. For instance, hot-reload of transient dependencies from the server extension (e.g.: keycloak-* dependencies) does not work. More improvements should be expected to improve the experience.
|
||||||
|
|
||||||
|
NOTE: When developing custom providers, you should be able to benefit from live coding as long as you keep changes within the `server` module.
|
||||||
|
|
||||||
|
Alternatively, you can run the server in development mode from your IDE. For that, run the `org.keycloak.quarkus._private.IDELauncher` main class.
|
|
@ -58,10 +58,6 @@
|
||||||
<groupId>io.quarkus</groupId>
|
<groupId>io.quarkus</groupId>
|
||||||
<artifactId>quarkus-jdbc-mysql-deployment</artifactId>
|
<artifactId>quarkus-jdbc-mysql-deployment</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>io.quarkus</groupId>
|
|
||||||
<artifactId>quarkus-vertx-web-deployment</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.quarkus</groupId>
|
<groupId>io.quarkus</groupId>
|
||||||
<artifactId>quarkus-bootstrap-core</artifactId>
|
<artifactId>quarkus-bootstrap-core</artifactId>
|
||||||
|
|
|
@ -50,8 +50,11 @@ import java.util.jar.JarFile;
|
||||||
import io.quarkus.deployment.IsDevelopment;
|
import io.quarkus.deployment.IsDevelopment;
|
||||||
import io.quarkus.deployment.builditem.HotDeploymentWatchedFileBuildItem;
|
import io.quarkus.deployment.builditem.HotDeploymentWatchedFileBuildItem;
|
||||||
import io.quarkus.deployment.builditem.IndexDependencyBuildItem;
|
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.hibernate.orm.deployment.HibernateOrmConfig;
|
||||||
import io.quarkus.resteasy.server.common.deployment.ResteasyDeploymentCustomizerBuildItem;
|
import io.quarkus.resteasy.server.common.deployment.ResteasyDeploymentCustomizerBuildItem;
|
||||||
|
import io.quarkus.runtime.LaunchMode;
|
||||||
import io.quarkus.smallrye.health.runtime.SmallRyeHealthHandler;
|
import io.quarkus.smallrye.health.runtime.SmallRyeHealthHandler;
|
||||||
import io.quarkus.vertx.http.deployment.RouteBuildItem;
|
import io.quarkus.vertx.http.deployment.RouteBuildItem;
|
||||||
import io.vertx.core.Handler;
|
import io.vertx.core.Handler;
|
||||||
|
@ -85,6 +88,7 @@ import org.keycloak.provider.ProviderFactory;
|
||||||
import org.keycloak.provider.ProviderManager;
|
import org.keycloak.provider.ProviderManager;
|
||||||
import org.keycloak.provider.Spi;
|
import org.keycloak.provider.Spi;
|
||||||
import org.keycloak.provider.quarkus.QuarkusRequestFilter;
|
import org.keycloak.provider.quarkus.QuarkusRequestFilter;
|
||||||
|
import org.keycloak.provider.quarkus.dev.QuarkusDevRequestFilter;
|
||||||
import org.keycloak.quarkus.KeycloakRecorder;
|
import org.keycloak.quarkus.KeycloakRecorder;
|
||||||
|
|
||||||
import io.quarkus.deployment.annotations.BuildProducer;
|
import io.quarkus.deployment.annotations.BuildProducer;
|
||||||
|
@ -191,6 +195,16 @@ class KeycloakProcessor {
|
||||||
recorder.configSessionFactory(factories, defaultProviders, preConfiguredProviders, Environment.isRebuild());
|
recorder.configSessionFactory(factories, defaultProviders, preConfiguredProviders, Environment.isRebuild());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the custom {@link org.eclipse.microprofile.config.spi.ConfigSource} implementations.
|
||||||
|
*
|
||||||
|
* @param configSources
|
||||||
|
*/
|
||||||
|
@BuildStep
|
||||||
|
void configureConfigSources(BuildProducer<StaticInitConfigSourceProviderBuildItem> configSources) {
|
||||||
|
configSources.produce(new StaticInitConfigSourceProviderBuildItem(KeycloakConfigSourceProvider.class.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Make the build time configuration available at runtime so that the server can run without having to specify some of
|
* <p>Make the build time configuration available at runtime so that the server can run without having to specify some of
|
||||||
* the properties again.
|
* the properties again.
|
||||||
|
@ -253,8 +267,15 @@ class KeycloakProcessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@BuildStep
|
@BuildStep
|
||||||
void initializeFilter(BuildProducer<FilterBuildItem> filters) {
|
void initializeFilter(BuildProducer<FilterBuildItem> filters, LaunchModeBuildItem launchModeBuildItem) {
|
||||||
filters.produce(new FilterBuildItem(new QuarkusRequestFilter(),FilterBuildItem.AUTHORIZATION - 10));
|
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();
|
metricsHandler = new NotFoundHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
routes.produce(new RouteBuildItem(DEFAULT_HEALTH_ENDPOINT, healthHandler));
|
routes.produce(RouteBuildItem.builder().route(DEFAULT_HEALTH_ENDPOINT).handler(healthHandler).build());
|
||||||
routes.produce(new RouteBuildItem(DEFAULT_HEALTH_ENDPOINT.concat("/live"), healthHandler));
|
routes.produce(RouteBuildItem.builder().route(DEFAULT_HEALTH_ENDPOINT.concat("/live")).handler(healthHandler).build());
|
||||||
routes.produce(new RouteBuildItem(DEFAULT_HEALTH_ENDPOINT.concat("/ready"), healthHandler));
|
routes.produce(RouteBuildItem.builder().route(DEFAULT_HEALTH_ENDPOINT.concat("/ready")).handler(healthHandler).build());
|
||||||
routes.produce(new RouteBuildItem(KeycloakMetricsHandler.DEFAULT_METRICS_ENDPOINT, metricsHandler));
|
routes.produce(RouteBuildItem.builder().route(KeycloakMetricsHandler.DEFAULT_METRICS_ENDPOINT).handler(metricsHandler).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
@BuildStep
|
@BuildStep
|
||||||
|
@ -310,7 +331,7 @@ class KeycloakProcessor {
|
||||||
|
|
||||||
private Map<Spi, Map<Class<? extends Provider>, Map<String, ProviderFactory>>> loadFactories(
|
private Map<Spi, Map<Class<? extends Provider>, Map<String, ProviderFactory>>> loadFactories(
|
||||||
Map<String, ProviderFactory> preConfiguredProviders) {
|
Map<String, ProviderFactory> preConfiguredProviders) {
|
||||||
loadConfig();
|
Config.init(new MicroProfileConfigProvider());
|
||||||
BuildClassLoader providerClassLoader = new BuildClassLoader();
|
BuildClassLoader providerClassLoader = new BuildClassLoader();
|
||||||
ProviderManager pm = new ProviderManager(KeycloakDeploymentInfo.create().services(), providerClassLoader);
|
ProviderManager pm = new ProviderManager(KeycloakDeploymentInfo.create().services(), providerClassLoader);
|
||||||
Map<Spi, Map<Class<? extends Provider>, Map<String, ProviderFactory>>> factories = new HashMap<>();
|
Map<Spi, Map<Class<? extends Provider>, Map<String, ProviderFactory>>> factories = new HashMap<>();
|
||||||
|
@ -485,18 +506,6 @@ class KeycloakProcessor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void loadConfig() {
|
|
||||||
ServiceLoader<ConfigProviderFactory> 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() {
|
private boolean isMetricsEnabled() {
|
||||||
return Configuration.getOptionalBooleanValue(MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX.concat("metrics.enabled")).orElse(false);
|
return Configuration.getOptionalBooleanValue(MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX.concat("metrics.enabled")).orElse(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,4 +2,5 @@ quarkus.http.root-path=/
|
||||||
quarkus.application.name=Keycloak
|
quarkus.application.name=Keycloak
|
||||||
quarkus.banner.enabled=false
|
quarkus.banner.enabled=false
|
||||||
|
|
||||||
quarkus.resteasy.ignore-application-classes=true
|
quarkus.resteasy.ignore-application-classes=true
|
||||||
|
quarkus.arc.ignored-split-packages=org.keycloak.*
|
120
quarkus/pom.xml
120
quarkus/pom.xml
|
@ -31,21 +31,37 @@
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<quarkus.version>1.13.3.Final</quarkus.version>
|
<!-- Quarkus version -->
|
||||||
<resteasy.version>4.5.9.Final</resteasy.version>
|
<quarkus.version>2.2.2.Final</quarkus.version>
|
||||||
<jackson.version>2.12.1</jackson.version>
|
|
||||||
|
<!--
|
||||||
|
Override versions based on Quarkus dependencies.
|
||||||
|
Make sure to update these dependencies when Quarkus version changes.
|
||||||
|
-->
|
||||||
|
<resteasy.version>4.7.0.Final</resteasy.version>
|
||||||
|
<jackson.version>2.12.5</jackson.version>
|
||||||
<jackson.databind.version>${jackson.version}</jackson.databind.version>
|
<jackson.databind.version>${jackson.version}</jackson.databind.version>
|
||||||
<hibernate.version>5.4.29.Final</hibernate.version>
|
<hibernate.core.version>5.6.0.Beta1</hibernate.core.version>
|
||||||
<mysql.driver.version>8.0.24</mysql.driver.version>
|
<mysql.driver.version>8.0.26</mysql.driver.version>
|
||||||
<postgresql.driver.version>42.2.20</postgresql.driver.version>
|
<postgresql.version>42.2.23</postgresql.version>
|
||||||
<picocli.version>4.6.1</picocli.version>
|
<microprofile-metrics-api.version>3.0</microprofile-metrics-api.version>
|
||||||
<snakeyaml.version>1.28</snakeyaml.version>
|
<wildfly.common.version>1.5.4.Final-format-001</wildfly.common.version>
|
||||||
<surefire-plugin.version>3.0.0-M5</surefire-plugin.version>
|
|
||||||
<wildfly.common.format.version>1.5.4.Final-format-001</wildfly.common.format.version>
|
<!--
|
||||||
<maven.compiler.source>1.8</maven.compiler.source>
|
Java EE dependencies. Not available from JDK 11+.
|
||||||
|
The dependencies and their versions are the same used by Wildfly distribution.
|
||||||
|
-->
|
||||||
|
<org.jboss.spec.javax.xml.bind.jboss-jaxb-api_2.3_spec.version>2.0.1.Final</org.jboss.spec.javax.xml.bind.jboss-jaxb-api_2.3_spec.version>
|
||||||
|
<sun.saaj-impl.version>1.4.1.SP1</sun.saaj-impl.version>
|
||||||
|
<org.jvnet.staxex.version>1.8.3</org.jvnet.staxex.version>
|
||||||
|
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<maven.compiler.target>1.8</maven.compiler.target>
|
<maven.compiler.plugin.version>3.8.1</maven.compiler.plugin.version>
|
||||||
<noDeps>true</noDeps>
|
<maven.compiler.release>11</maven.compiler.release>
|
||||||
|
<maven.compiler.source>11</maven.compiler.source>
|
||||||
|
<maven.compiler.target>11</maven.compiler.target>
|
||||||
|
|
||||||
|
<surefire-plugin.version>3.0.0-M5</surefire-plugin.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
|
@ -58,12 +74,7 @@
|
||||||
<scope>import</scope>
|
<scope>import</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Override the dependencies below to use the versions used by Quarkus -->
|
<!-- Override the dependencies below to use the versions used by Keycloak -->
|
||||||
<dependency>
|
|
||||||
<groupId>org.hibernate</groupId>
|
|
||||||
<artifactId>hibernate-core</artifactId>
|
|
||||||
<version>${hibernate.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.infinispan</groupId>
|
<groupId>org.infinispan</groupId>
|
||||||
<artifactId>infinispan-core</artifactId>
|
<artifactId>infinispan-core</artifactId>
|
||||||
|
@ -79,45 +90,74 @@
|
||||||
<artifactId>infinispan-client-hotrod</artifactId>
|
<artifactId>infinispan-client-hotrod</artifactId>
|
||||||
<version>${infinispan.version}</version>
|
<version>${infinispan.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Dependencies removed from JDK 11 and in compliance with those used by Wildfly. -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.wildfly.common</groupId>
|
<groupId>org.jboss.spec.javax.xml.bind</groupId>
|
||||||
<artifactId>wildfly-common</artifactId>
|
<artifactId>jboss-jaxb-api_2.3_spec</artifactId>
|
||||||
<version>${wildfly.common.format.version}</version>
|
<version>${org.jboss.spec.javax.xml.bind.jboss-jaxb-api_2.3_spec.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.sun.xml.messaging.saaj</groupId>
|
||||||
|
<artifactId>saaj-impl</artifactId>
|
||||||
|
<version>${sun.saaj-impl.version}</version>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<groupId>*</groupId>
|
<groupId>javax.xml.soap</groupId>
|
||||||
<artifactId>*</artifactId>
|
<artifactId>saaj-api</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.jvnet.mimepull</groupId>
|
||||||
|
<artifactId>mimepull</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.jvnet.staxex</groupId>
|
||||||
|
<artifactId>stax-ex</artifactId>
|
||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.yaml</groupId>
|
<groupId>org.jvnet.staxex</groupId>
|
||||||
<artifactId>snakeyaml</artifactId>
|
<artifactId>stax-ex</artifactId>
|
||||||
<version>${snakeyaml.version}</version>
|
<version>${org.jvnet.staxex.version}</version>
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>mysql</groupId>
|
|
||||||
<artifactId>mysql-connector-java</artifactId>
|
|
||||||
<version>${mysql.driver.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.postgresql</groupId>
|
|
||||||
<artifactId>postgresql</artifactId>
|
|
||||||
<version>${postgresql.driver.version}</version>
|
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<groupId>org.checkerframework</groupId>
|
<groupId>javax.xml.stream</groupId>
|
||||||
<artifactId>checker-qual</artifactId>
|
<artifactId>stax-api</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>javax.activation</groupId>
|
||||||
|
<artifactId>activation</artifactId>
|
||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<pluginManagement>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>${maven.compiler.plugin.version}</version>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
|
</build>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
<module>deployment</module>
|
|
||||||
<module>runtime</module>
|
<module>runtime</module>
|
||||||
|
<module>deployment</module>
|
||||||
<module>server</module>
|
<module>server</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>jboss-public-repository</id>
|
||||||
|
<name>Jboss Public</name>
|
||||||
|
<url>https://repository.jboss.org/nexus/content/groups/public/</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
<name>Keycloak Quarkus Server Extension</name>
|
<name>Keycloak Quarkus Server Extension</name>
|
||||||
<artifactId>keycloak-quarkus-server</artifactId>
|
<artifactId>keycloak-quarkus-server</artifactId>
|
||||||
|
<description>Keycloak Server</description>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<!-- Quarkus -->
|
<!-- Quarkus -->
|
||||||
|
@ -76,7 +77,6 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>info.picocli</groupId>
|
<groupId>info.picocli</groupId>
|
||||||
<artifactId>picocli</artifactId>
|
<artifactId>picocli</artifactId>
|
||||||
<version>${picocli.version}</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Keycloak -->
|
<!-- Keycloak -->
|
||||||
|
@ -461,6 +461,19 @@
|
||||||
<groupId>org.infinispan</groupId>
|
<groupId>org.infinispan</groupId>
|
||||||
<artifactId>infinispan-jboss-marshalling</artifactId>
|
<artifactId>infinispan-jboss-marshalling</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jboss.spec.javax.xml.bind</groupId>
|
||||||
|
<artifactId>jboss-jaxb-api_2.3_spec</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.sun.xml.messaging.saaj</groupId>
|
||||||
|
<artifactId>saaj-impl</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jvnet.staxex</groupId>
|
||||||
|
<artifactId>stax-ex</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
|
|
|
@ -22,6 +22,7 @@ import static org.keycloak.cli.Picocli.error;
|
||||||
import static org.keycloak.cli.Picocli.getCliArgs;
|
import static org.keycloak.cli.Picocli.getCliArgs;
|
||||||
import static org.keycloak.cli.Picocli.parseConfigArgs;
|
import static org.keycloak.cli.Picocli.parseConfigArgs;
|
||||||
import static org.keycloak.util.Environment.getProfileOrDefault;
|
import static org.keycloak.util.Environment.getProfileOrDefault;
|
||||||
|
import static org.keycloak.util.Environment.isDevMode;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -51,7 +52,10 @@ public class KeycloakMain {
|
||||||
if (cliArgs.length == 0) {
|
if (cliArgs.length == 0) {
|
||||||
// no arguments, just start the server
|
// no arguments, just start the server
|
||||||
start(Collections.emptyList(), new PrintWriter(System.err));
|
start(Collections.emptyList(), new PrintWriter(System.err));
|
||||||
System.exit(CommandLine.ExitCode.OK);
|
if (!isDevMode()) {
|
||||||
|
System.exit(CommandLine.ExitCode.OK);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse arguments and execute any of the configured commands
|
// parse arguments and execute any of the configured commands
|
||||||
|
@ -63,9 +67,20 @@ public class KeycloakMain {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void start(List<String> cliArgs, PrintWriter errorWriter) {
|
private static void start(List<String> cliArgs, PrintWriter errorWriter) {
|
||||||
Quarkus.run(null, (integer, throwable) -> {
|
try {
|
||||||
error(cliArgs, errorWriter, String.format("Failed to start server using profile (%s).", getProfileOrDefault("none")), throwable.getCause());
|
Quarkus.run(null, (integer, cause) -> {
|
||||||
});
|
if (cause != null) {
|
||||||
|
error(cliArgs, errorWriter,
|
||||||
|
String.format("Failed to start server using profile (%s)", getProfileOrDefault("none")),
|
||||||
|
cause.getCause());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Throwable cause) {
|
||||||
|
error(cliArgs, errorWriter,
|
||||||
|
String.format("Unexpected error when starting the server using profile (%s)", getProfileOrDefault("none")),
|
||||||
|
cause.getCause());
|
||||||
|
}
|
||||||
|
|
||||||
Quarkus.waitForExit();
|
Quarkus.waitForExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,6 +111,10 @@ public class KeycloakMain {
|
||||||
System.exit(cmd.getCommandSpec().exitCodeOnExecutionException());
|
System.exit(cmd.getCommandSpec().exitCodeOnExecutionException());
|
||||||
}
|
}
|
||||||
|
|
||||||
System.exit(cmd.execute(cliArgs.toArray(new String[cliArgs.size()])));
|
int exitCode = cmd.execute(cliArgs.toArray(new String[cliArgs.size()]));
|
||||||
|
|
||||||
|
if (!isDevMode()) {
|
||||||
|
System.exit(exitCode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,7 +114,12 @@ public final class ShowConfigCommand {
|
||||||
@Override
|
@Override
|
||||||
public boolean test(String s) {
|
public boolean test(String s) {
|
||||||
ConfigValue configValue = getConfigValue(s);
|
ConfigValue configValue = getConfigValue(s);
|
||||||
return configValue.getConfigSourceName().equals(PersistedConfigSource.NAME);
|
|
||||||
|
if (configValue == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PersistedConfigSource.NAME.equals(configValue.getConfigSourceName());
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter(property -> filterByGroup(property))
|
.filter(property -> filterByGroup(property))
|
||||||
|
|
|
@ -105,7 +105,7 @@ public class KeycloakConfigSourceProvider implements ConfigSourceProvider {
|
||||||
String homeDir = Environment.getHomeDir();
|
String homeDir = Environment.getHomeDir();
|
||||||
|
|
||||||
if (homeDir == null) {
|
if (homeDir == null) {
|
||||||
return Paths.get(Platform.getPlatform().getTmpDirectory().toString(), PersistedConfigSource.KEYCLOAK_PROPERTIES);
|
return Paths.get(System.getProperty("java.io.tmpdir"), PersistedConfigSource.KEYCLOAK_PROPERTIES);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Paths.get(homeDir, "conf", PersistedConfigSource.KEYCLOAK_PROPERTIES);
|
return Paths.get(homeDir, "conf", PersistedConfigSource.KEYCLOAK_PROPERTIES);
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
package org.keycloak.configuration;
|
package org.keycloak.configuration;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
import org.eclipse.microprofile.config.spi.ConfigSource;
|
import org.eclipse.microprofile.config.spi.ConfigSource;
|
||||||
|
@ -44,6 +45,11 @@ public class SysPropConfigSource implements ConfigSource {
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> getPropertyNames() {
|
||||||
|
return properties.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
public String getValue(final String propertyName) {
|
public String getValue(final String propertyName) {
|
||||||
return System.getProperty(propertyName);
|
return System.getProperty(propertyName);
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,7 @@ import org.keycloak.Config;
|
||||||
import org.keycloak.ServerStartupError;
|
import org.keycloak.ServerStartupError;
|
||||||
import org.keycloak.common.Version;
|
import org.keycloak.common.Version;
|
||||||
import org.keycloak.connections.jpa.updater.JpaUpdaterProvider;
|
import org.keycloak.connections.jpa.updater.JpaUpdaterProvider;
|
||||||
|
import org.keycloak.exportimport.ExportImportConfig;
|
||||||
import org.keycloak.connections.jpa.updater.liquibase.conn.LiquibaseConnectionProvider;
|
import org.keycloak.connections.jpa.updater.liquibase.conn.LiquibaseConnectionProvider;
|
||||||
import org.keycloak.connections.jpa.util.JpaUtils;
|
import org.keycloak.connections.jpa.util.JpaUtils;
|
||||||
import org.keycloak.exportimport.ExportImportManager;
|
import org.keycloak.exportimport.ExportImportManager;
|
||||||
|
@ -152,14 +153,14 @@ public final class QuarkusJpaConnectionProviderFactory implements JpaConnectionP
|
||||||
session.close();
|
session.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (initSchema) {
|
if (initSchema || ExportImportConfig.ACTION_EXPORT.equals(ExportImportConfig.getAction())) {
|
||||||
runJobInTransaction(factory, this::initSchemaOrExport);
|
runJobInTransaction(factory, this::initSchemaOrExport);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Connection getConnection() {
|
public Connection getConnection() {
|
||||||
SessionFactoryImpl entityManagerFactory = SessionFactoryImpl.class.cast(emf);
|
SessionFactoryImpl entityManagerFactory = emf.unwrap(SessionFactoryImpl.class);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return entityManagerFactory.getJdbcServices().getBootstrapJdbcConnectionAccess().obtainConnection();
|
return entityManagerFactory.getJdbcServices().getBootstrapJdbcConnectionAccess().obtainConnection();
|
||||||
|
|
|
@ -31,7 +31,13 @@ public class ResteasyVertxProvider implements ResteasyProvider {
|
||||||
R data = ResteasyContext.getContextData(type);
|
R data = ResteasyContext.getContextData(type);
|
||||||
|
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
return (R) ResteasyContext.getContextData(RoutingContext.class).data().get(type.getName());
|
RoutingContext contextData = ResteasyContext.getContextData(RoutingContext.class);
|
||||||
|
|
||||||
|
if (contextData == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (R) contextData.data().get(type.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
package org.keycloak.provider.quarkus.dev;
|
||||||
|
|
||||||
|
import io.vertx.ext.web.RoutingContext;
|
||||||
|
import org.keycloak.provider.quarkus.QuarkusRequestFilter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
*/
|
||||||
|
public class QuarkusDevRequestFilter extends QuarkusRequestFilter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(RoutingContext context) {
|
||||||
|
if (context.request().uri().startsWith("/q/")) {
|
||||||
|
// do not go through Keycloak request filter if serving Quarkus resources such as dev console
|
||||||
|
context.next();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
super.handle(context);
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,6 +19,7 @@ package org.keycloak.quarkus;
|
||||||
|
|
||||||
import static org.keycloak.configuration.Configuration.getBuiltTimeProperty;
|
import static org.keycloak.configuration.Configuration.getBuiltTimeProperty;
|
||||||
import static org.keycloak.configuration.Configuration.getConfig;
|
import static org.keycloak.configuration.Configuration.getConfig;
|
||||||
|
import static org.keycloak.configuration.Configuration.getConfigValue;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -135,17 +136,21 @@ public class KeycloakRecorder {
|
||||||
if (!StreamSupport.stream(getConfig().getPropertyNames().spliterator(), false)
|
if (!StreamSupport.stream(getConfig().getPropertyNames().spliterator(), false)
|
||||||
.filter(new Predicate<String>() {
|
.filter(new Predicate<String>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean test(String s) {
|
public boolean test(String propertyName) {
|
||||||
ConfigValue configValue = getConfig().getConfigValue(s);
|
ConfigValue configValue = getConfigValue(propertyName);
|
||||||
|
|
||||||
return configValue.getConfigSourceName().equals(PersistedConfigSource.NAME);
|
if (configValue == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PersistedConfigSource.NAME.equals(configValue.getSourceName());
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.anyMatch(new Predicate<String>() {
|
.anyMatch(new Predicate<String>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean test(String s) {
|
public boolean test(String propertyName) {
|
||||||
return PropertyMappers.canonicalFormat(finalPropertyName)
|
return PropertyMappers.canonicalFormat(finalPropertyName)
|
||||||
.equalsIgnoreCase(PropertyMappers.canonicalFormat(s));
|
.equalsIgnoreCase(PropertyMappers.canonicalFormat(propertyName));
|
||||||
}
|
}
|
||||||
})) {
|
})) {
|
||||||
String prop = "--" + cliNameFormat.substring(3) + "=" + value.getValue();
|
String prop = "--" + cliNameFormat.substring(3) + "=" + value.getValue();
|
||||||
|
|
|
@ -59,7 +59,7 @@ public class KeycloakReadyHealthCheck extends DataSourceHealthCheck {
|
||||||
long invalidCount = agroalDataSource.getMetrics().invalidCount();
|
long invalidCount = agroalDataSource.getMetrics().invalidCount();
|
||||||
if (activeCount < 1 || invalidCount > 0) {
|
if (activeCount < 1 || invalidCount > 0) {
|
||||||
HealthCheckResponse activeCheckResult = super.call();
|
HealthCheckResponse activeCheckResult = super.call();
|
||||||
if (activeCheckResult.getState() == HealthCheckResponse.State.DOWN) {
|
if (activeCheckResult.getStatus() == HealthCheckResponse.Status.DOWN) {
|
||||||
builder.down();
|
builder.down();
|
||||||
Instant failingTime = failingSince.updateAndGet(this::createInstanceIfNeeded);
|
Instant failingTime = failingSince.updateAndGet(this::createInstanceIfNeeded);
|
||||||
builder.withData("Failing since", DATE_FORMATTER.format(failingTime));
|
builder.withData("Failing since", DATE_FORMATTER.format(failingTime));
|
||||||
|
|
|
@ -19,6 +19,8 @@ package org.keycloak.util;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import io.quarkus.runtime.LaunchMode;
|
||||||
|
import io.quarkus.runtime.configuration.ProfileManager;
|
||||||
import org.apache.commons.lang3.SystemUtils;
|
import org.apache.commons.lang3.SystemUtils;
|
||||||
import org.keycloak.configuration.Configuration;
|
import org.keycloak.configuration.Configuration;
|
||||||
|
|
||||||
|
@ -80,7 +82,12 @@ public final class Environment {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isDevMode() {
|
public static boolean isDevMode() {
|
||||||
return "dev".equalsIgnoreCase(getProfile());
|
if ("dev".equalsIgnoreCase(getProfile())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if running in quarkus:dev mode
|
||||||
|
return ProfileManager.getLaunchMode() == LaunchMode.DEVELOPMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isWindows() {
|
public static boolean isWindows() {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
---
|
---
|
||||||
|
artifact: ${project.groupId}:${project.artifactId}:${project.version}
|
||||||
name: "Keycloak"
|
name: "Keycloak"
|
||||||
metadata:
|
metadata:
|
||||||
keywords:
|
keywords:
|
||||||
|
|
|
@ -26,6 +26,7 @@ import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import io.quarkus.hibernate.orm.runtime.dialect.QuarkusH2Dialect;
|
import io.quarkus.hibernate.orm.runtime.dialect.QuarkusH2Dialect;
|
||||||
|
import io.quarkus.runtime.LaunchMode;
|
||||||
import io.smallrye.config.SmallRyeConfig;
|
import io.smallrye.config.SmallRyeConfig;
|
||||||
import org.eclipse.microprofile.config.ConfigProvider;
|
import org.eclipse.microprofile.config.ConfigProvider;
|
||||||
import org.eclipse.microprofile.config.spi.ConfigProviderResolver;
|
import org.eclipse.microprofile.config.spi.ConfigProviderResolver;
|
||||||
|
@ -272,6 +273,6 @@ public class ConfigurationTest {
|
||||||
|
|
||||||
private SmallRyeConfig createConfig() {
|
private SmallRyeConfig createConfig() {
|
||||||
KeycloakConfigSourceProvider.reload();
|
KeycloakConfigSourceProvider.reload();
|
||||||
return ConfigUtils.configBuilder(true, true).build();
|
return ConfigUtils.configBuilder(true, LaunchMode.NORMAL).build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,20 +19,6 @@
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<artifactId>keycloak-quarkus-server</artifactId>
|
<artifactId>keycloak-quarkus-server</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- This dependency should not be here but due to the structure of the modules we need to make sure it is built
|
|
||||||
before this module -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.keycloak</groupId>
|
|
||||||
<artifactId>keycloak-quarkus-server-deployment</artifactId>
|
|
||||||
<scope>compile</scope>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>*</groupId>
|
|
||||||
<artifactId>*</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>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.
|
||||||
|
*
|
||||||
|
* <p>There are some limitations during development such as:
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li>Transient dependencies from the keycloak server extension (runtime module) are not eligible for hot-reload</li>
|
||||||
|
* <li>Code changes such as changing the structure of classes (e.g.: new/change methods) should still require a JVM restart</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* <p>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 <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
*/
|
||||||
|
public class IDELauncher {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
List<String> devArgs = new ArrayList<>();
|
||||||
|
|
||||||
|
devArgs.addAll(Arrays.asList(args));
|
||||||
|
|
||||||
|
if (devArgs.isEmpty()) {
|
||||||
|
devArgs.add("start-dev");
|
||||||
|
}
|
||||||
|
|
||||||
|
Quarkus.run(devArgs.toArray(new String[devArgs.size()]));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,14 +1,10 @@
|
||||||
# Default and non-production grade database vendor
|
# Default and non-production grade database vendor
|
||||||
db=h2-file
|
db=h2-file
|
||||||
|
db.username = sa
|
||||||
|
db.password = keycloak
|
||||||
|
|
||||||
# Default, and insecure, and non-production grade configuration for the development profile
|
# Insecure requests are disabled by default
|
||||||
%dev.http.enabled=true
|
http.enabled=false
|
||||||
%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
|
|
||||||
|
|
||||||
# Metrics and healthcheck are disabled by default
|
# Metrics and healthcheck are disabled by default
|
||||||
metrics.enabled=false
|
metrics.enabled=false
|
||||||
|
@ -16,6 +12,13 @@ metrics.enabled=false
|
||||||
# Themes
|
# Themes
|
||||||
spi.theme.folder.dir=${kc.home.dir:}/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
|
# Logging configuration. INFO is the default level for most of the categories
|
||||||
#quarkus.log.level = DEBUG
|
#quarkus.log.level = DEBUG
|
||||||
quarkus.log.category."org.jboss.resteasy.resteasy_jaxrs.i18n".level=WARN
|
quarkus.log.category."org.jboss.resteasy.resteasy_jaxrs.i18n".level=WARN
|
||||||
|
|
|
@ -20,3 +20,6 @@ quarkus.transaction-manager.default-transaction-timeout=300
|
||||||
# application classes are no longer supported by resteasy extension
|
# application classes are no longer supported by resteasy extension
|
||||||
quarkus.resteasy.ignore-application-classes=true
|
quarkus.resteasy.ignore-application-classes=true
|
||||||
|
|
||||||
|
# Ignore split packages for Keycloak related packages
|
||||||
|
quarkus.arc.ignored-split-packages=org.keycloak.*
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
|
|
||||||
<profiles>
|
<profiles>
|
||||||
<profile>
|
<profile>
|
||||||
<id>quarkus</id>
|
<id>auth-server-quarkus</id>
|
||||||
<modules>
|
<modules>
|
||||||
<module>quarkus</module>
|
<module>quarkus</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
<exec osfamily="unix" dir="${auth.server.home}/bin" executable="./kc.sh" failonerror="true">
|
<exec osfamily="unix" dir="${auth.server.home}/bin" executable="./kc.sh" failonerror="true">
|
||||||
<arg value="config"/>
|
<arg value="config"/>
|
||||||
<arg value="-Dquarkus.http.root-path=/auth"/>
|
<arg value="-Dquarkus.http.root-path=/auth"/>
|
||||||
|
<arg value="--http-enabled=true"/>
|
||||||
</exec>
|
</exec>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
|
|
|
@ -126,7 +126,7 @@ public class KeycloakQuarkusServerDeployableContainer implements DeployableConta
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isReaugmentBeforeStart()) {
|
if (isReaugmentBeforeStart()) {
|
||||||
List<String> commands = new ArrayList<>(Arrays.asList("./kc.sh", "config", "-Dquarkus.http.root-path=/auth"));
|
List<String> commands = new ArrayList<>(Arrays.asList("./kc.sh", "config", "-Dquarkus.http.root-path=/auth", "--http-enabled=true"));
|
||||||
|
|
||||||
addAdditionalCommands(commands);
|
addAdditionalCommands(commands);
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class adapts the functionality from the old testsuite to make tests
|
* 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> T loadJson(InputStream is, TypeReference<T> type) {
|
||||||
|
try {
|
||||||
|
return JsonSerialization.readValue(is, type);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Failed to parse json", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.keycloak.testsuite.cli.admin;
|
package org.keycloak.testsuite.cli.admin;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -26,7 +27,7 @@ import static org.keycloak.testsuite.cli.KcAdmExec.execute;
|
||||||
@AuthServerContainerExclude({AuthServer.REMOTE, AuthServer.QUARKUS})
|
@AuthServerContainerExclude({AuthServer.REMOTE, AuthServer.QUARKUS})
|
||||||
public class KcAdmSessionTest extends AbstractAdmCliTest {
|
public class KcAdmSessionTest extends AbstractAdmCliTest {
|
||||||
|
|
||||||
static Class<? extends List<ObjectNode>> LIST_OF_JSON = new ArrayList<ObjectNode>() {}.getClass();
|
static TypeReference<List<ObjectNode>> LIST_OF_JSON = new TypeReference<List<ObjectNode>>() {};
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() throws IOException {
|
public void test() throws IOException {
|
||||||
|
|
|
@ -943,9 +943,10 @@ public class VerifyProfileTest extends AbstractTestRealmKeycloakTest {
|
||||||
|
|
||||||
|
|
||||||
public static void setUserProfileConfiguration(RealmResource testRealm, String configuration) {
|
public static void setUserProfileConfiguration(RealmResource testRealm, String configuration) {
|
||||||
Response r = testRealm.users().userProfile().update(configuration);
|
try (Response r = testRealm.users().userProfile().update(configuration)) {
|
||||||
if (r.getStatus() != 200) {
|
if (r.getStatus() != 200) {
|
||||||
Assert.fail("UserProfile Configuration not set due to error: " + r.readEntity(String.class));
|
Assert.fail("UserProfile Configuration not set due to error: " + r.readEntity(String.class));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue