mirror of
https://github.com/keycloak/keycloak.git
synced 2026-02-18 18:37:54 -05:00
docs(quarkus): merge quarkus/CONTRIBUING.md into quarkus/README.md (#46033)
Closes #45805 Signed-off-by: Michal Vavřík <michal.vavrik@aol.com>
This commit is contained in:
parent
d95f456b4f
commit
0d28b664d3
2 changed files with 226 additions and 299 deletions
|
|
@ -1,279 +0,0 @@
|
|||
# Contributing guide
|
||||
|
||||
## Keycloak Quarkus Extension
|
||||
|
||||
Keycloak on Quarkus is basically a Quarkus Extension. For more details about extensions, please take a look at [Writing Your Own Extension](https://quarkus.io/guides/writing-extensions) guide.
|
||||
|
||||
As an extension, the server can be embedded in any Quarkus application by adding the following dependency:
|
||||
|
||||
```
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-quarkus-server</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
```
|
||||
|
||||
Just like any other extension, the server extension has two main modules:
|
||||
|
||||
* `deployment`
|
||||
* `runtime`
|
||||
|
||||
Within the `deployment` module you'll find the implementation for the build steps that run when (re)augmenting the application. This module
|
||||
is responsible for all metadata processing, such as:
|
||||
|
||||
* Lookup SPIs and their providers and enable/disable them accordingly
|
||||
* Create a closed-world assumption about the providers that should be registered to the `KeycloakSessionFactory`
|
||||
* Customizations to how Hibernate, Resteasy, Liquibase, Infinispan, and other dependencies are configured and bootstrapped
|
||||
* Creating Jandex indexes for some server dependencies
|
||||
|
||||
The output of this module is bytecode generated by Quarkus that improves the server startup time and memory usage so that any processing
|
||||
done during (re)augmentation does not happen again when actually starting the server. Note that the code from this module does
|
||||
not run at all at runtime (when running the server) but only when building the project (the `server` module in particular, more on that later) or when triggering
|
||||
a re-augmentation when running the `build` command.
|
||||
|
||||
Within the `runtime` module you'll find the code that is run at runtime when starting and running the server. The main link between
|
||||
the `deployment` and `runtime` modules is the `org.keycloak.quarkus.runtime.KeycloakRecorder` class. The `KeycloakRecorder` holds
|
||||
a set of methods that are invoked from build steps that will end up in recorded bytecode. The recorded bytecode executes those methods at runtime
|
||||
just like they were called when a build step is run, with the exact same arguments and values, if any.
|
||||
|
||||
As an example, let us look at how the SPIs and their providers are discovered and how the `KeycloakSessionFactory` is created.
|
||||
Quarkus will run the `org.keycloak.quarkus.deployment.KeycloakProcessor.configureProviders` build step whenever you are (re)augmenting the server. The main outcome from this method
|
||||
is to invoke the `org.keycloak.quarkus.runtime.KeycloakRecorder.configSessionFactory` so that the code from this method is executed at
|
||||
*runtime* with a closed-world assumption about the providers that should be registered to the `KeycloakSessionFactory`. At runtime the code from that method is executed
|
||||
and a `KeycloakSessionFactory` is created without any processing to discover SPIs and their providers.
|
||||
|
||||
There are a few reasons why we have Keycloak as a Quarkus extension:
|
||||
|
||||
* More control over the build-time augmentation and runtime stages.
|
||||
* More flexibility when extending Quarkus itself and the extensions used by the server (e.g.: Hibernate, Resteasy, etc.)
|
||||
* Make it easier to embed the server into Quarkus applications
|
||||
* Make it possible to allow Keycloak developers to customize the server distribution
|
||||
|
||||
## Keycloak Server
|
||||
|
||||
The `server` module holds the Keycloak Server itself. It is basically a regular Quarkus application using the `keycloak-quarkus-server` extension. If you look at the
|
||||
[pom.xml](server/pom.xml) from this module you'll notice that it is a very simple Quarkus application with the bare minimum configuration
|
||||
to actually build and run the server.
|
||||
|
||||
As Quarkus application, the server is a [mutable](https://quarkus.io/guides/reaugmentation#how-to-re-augment-a-quarkus-application) application using the
|
||||
[mutable-jar](server/src/main/resources/application.properties) package type. As a mutable application, Keycloak is able to allow
|
||||
users to configure some aspects of the server without having to re-build this module, something impractical from a user perspective.
|
||||
|
||||
The mutability of the server is directly related to the `build` command. As mentioned before, the build steps from the `deployment` module
|
||||
are only run when (re)augmenting the server and when running the `build` command, the server will indicate to Quarkus that the build steps
|
||||
should re-run and the recorded bytecode should be updated to reflect any change to the server configuration.
|
||||
|
||||
From a Quarkus perspective, the server is also a [Command Mode Application](https://quarkus.io/guides/command-mode-reference) and provides
|
||||
a CLI based on [Picocli](https://picocli.info/). As such, there is a single entrypoint that executes the code to execute the CLI and bootstrap the server. This entry point
|
||||
is the `org.keycloak.quarkus.runtime.KeycloakMain` class from the `runtime` module.
|
||||
|
||||
## Keycloak Distribution
|
||||
|
||||
The server distribution is created by build the `dist` module. This module basically consists of packaging the `deployment`, `runtime`,
|
||||
and `server` modules artifacts and their dependencies to a `ZIP` or tarball file.
|
||||
|
||||
Within this directory you'll find the directory structure of the distribution and what is included in it.
|
||||
|
||||
## Running the server in development mode
|
||||
|
||||
As a regular Quarkus application, you are able to run the `server` module in [dev mode](https://quarkus.io/guides/maven-tooling#dev-mode) just like any regular application:
|
||||
|
||||
```
|
||||
cd server
|
||||
mvn clean quarkus:dev -Dquarkus.args="start-dev"
|
||||
```
|
||||
|
||||
You can set any command or configuration option to the server by setting the `quarkus.args` environment variable.
|
||||
|
||||
When running in dev mode, you can benefit from the dev mode capabilities from Quarkus but with some limitations. The main limitations you'll find
|
||||
at the moment are:
|
||||
|
||||
* Changes are only automatically reflected at runtime if you are changing resources from the `deployment`, `runtime`, and `server` modules. Other modules, such as `keycloak-services` still rely on Hot Swap in Java debuggers to reload classes.
|
||||
* There is nothing in the Dev UI related to the server itself, although you can still change some configuration from there.
|
||||
* There are some limitations when passing some options when running in dev mode. You should expect more improvements in this area.
|
||||
|
||||
We are working to improve the dev experience, and you should expect improvements over time.
|
||||
|
||||
## Debugging the server distribution
|
||||
|
||||
The `kc.sh|bat` script allows you to remotely debug the distribution. For that, you should run the server as follows:
|
||||
|
||||
```
|
||||
kc.sh --debug start-dev
|
||||
```
|
||||
|
||||
By default, the debug port is available at `8787` on localhost. Additionally, you can specify IPv4 or bracketed IPv6 addresses with optional ports, e.g. `--debug 127.0.0.1:8786`, `--debug [::1]:8785`. Make sure to exercise caution when setting IP addresses in the `--debug` parameter, since a value such as `--debug 0.0.0.0:8787` will expose the debug port to all network interfaces!
|
||||
|
||||
An additional environment variable `DEBUG_SUSPEND` can be set to suspend the JVM, when launched in debug mode. The `DEBUG_SUSPEND` variable supports the following values:
|
||||
|
||||
* `y` - The debug mode JVM launch is suspended
|
||||
* `n` - The debug mode JVM is started without suspending
|
||||
|
||||
Suspending the JVM when in debug mode is useful if you want to debug the early stages of the bootstrap code.
|
||||
|
||||
When making changes to the `deployment`, `runtime`, or `server` modules, you can update the distribution with the new artifacts by executing
|
||||
the following command:
|
||||
|
||||
```
|
||||
mvn -DskipTests clean install
|
||||
```
|
||||
|
||||
After the `quarkus` module and sub-modules are built, you can update the distribution as follows:
|
||||
|
||||
```
|
||||
cp -r server/target/lib ${KC_HOME_DIR}
|
||||
```
|
||||
|
||||
In the example above, the `${KC_HOME_DIR}` variable points to the root directory of the distribution.
|
||||
|
||||
You should also be able to update a server dependency directly. For that, copy the jar to the following location:
|
||||
|
||||
```
|
||||
cp services/target/keycloak-services-${KC_VERSION}.jar ${KC_HOME_DIR}/lib/lib/main/org.keycloak.keycloak-services-${KC_VERSION}.jar
|
||||
```
|
||||
|
||||
## Running tests
|
||||
|
||||
The distribution has its own distribution and the main tests are within the [tests/integration](tests/integration) module.
|
||||
|
||||
The test suite has two main types of tests:
|
||||
|
||||
* `jvm`
|
||||
* `distribution`
|
||||
|
||||
The `jvm` tests execute both the test class and server within the same JVM. While the `distribution` tests execute the server
|
||||
by running the distribution in a separate JVM.
|
||||
|
||||
The `distribution` tests are marked as such using the `DistributionTest` annotation. If not marked with this annotation, the test is a `JVM` test.
|
||||
|
||||
To run the tests, execute the following command within the `quarkus` module:
|
||||
|
||||
```
|
||||
mvn clean install
|
||||
```
|
||||
|
||||
By default, the tests will run using a raw distribution. If you want to run tests from the [tests/integration](tests/integration) module directly,
|
||||
please make sure the distribution was built with the latest changes you did to it and its dependencies.
|
||||
|
||||
### Running tests using a container
|
||||
|
||||
You can also run tests using a container instead of the raw distribution by setting the `kc.quarkus.tests.dist` property as follows:
|
||||
|
||||
```
|
||||
mvn clean install -Dkc.quarkus.tests.dist=docker
|
||||
```
|
||||
|
||||
When setting the `kc.quarkus.tests.dist` to `docker` tests will run using a container instead of the raw distribution.
|
||||
|
||||
### Running storage tests
|
||||
|
||||
The storage tests are disabled by default but can be activated using the `test-database` profile:
|
||||
|
||||
```
|
||||
mvn clean install -Ptest-database -Dtest=PostgreSQLDistTest
|
||||
```
|
||||
|
||||
### Running tests from the IDE
|
||||
|
||||
You are also able to run tests from your IDE. For that, choose a test from the [tests/integration](tests/integration) module
|
||||
and execute it accordingly.
|
||||
|
||||
### Running tests from the `base` testsuite
|
||||
|
||||
Sometimes you might want to run the tests from the `base` test suite using the distribution. For that, make sure you have built the `quarkus` module
|
||||
and then execute the following command from the project root directory:
|
||||
|
||||
```
|
||||
mvn -f testsuite/integration-arquillian/pom.xml clean install -Pauth-server-quarkus -Dtest=OIDCProtocolMappersTest
|
||||
```
|
||||
|
||||
### Resolving DNS names when running tests
|
||||
|
||||
In order to avoid using external services for DNS resolution, the tests are executed using a local host file by setting the `-Djdk.net.hosts.file=${project.build.testOutputDirectory}/hosts_file` system property.
|
||||
|
||||
## Documentation
|
||||
|
||||
The documentation is a set of guides available from the [docs](../docs/guides/src/main/server) module. Please,
|
||||
look at the this [guide](../docs/building.md) about how to update and build the distribution guides.
|
||||
|
||||
## Before contributing the changes
|
||||
|
||||
Before contributing changes, make to read the main [Keycloak Contributing Guide](https://github.com/keycloak/keycloak/blob/main/CONTRIBUTING.md).
|
||||
|
||||
Please, make sure:
|
||||
|
||||
* Documentation is updated if you are introducing any new behavior or changing an existing one that needs to be communicated
|
||||
* Make sure you have a test within the [tests/integration](tests/integration) module to cover the changes
|
||||
* You probably want to run a full build of the `quarkus` module, including running tests, to make sure you won't be surprised by failures in CI.
|
||||
|
||||
## Upgrading Quarkus Version
|
||||
|
||||
Upgrading Quarkus requires a few steps:
|
||||
|
||||
* Change the Quarkus version
|
||||
* Change the dependencies we are using from Quarkus
|
||||
* Run a build to make sure the server extension is not broken
|
||||
|
||||
The steps still require a lot of manual work, and we should be improving this.
|
||||
|
||||
### Changing the Quarkus version
|
||||
|
||||
To change the Quarkus version, you can run the following script:
|
||||
|
||||
```bash
|
||||
./set-quarkus-version.sh <version>
|
||||
```
|
||||
|
||||
The `set-quarkus-version.sh` script is enough to change the version for all dependencies we are
|
||||
using from Quarkus.
|
||||
|
||||
The `<version>` should point to a branch or a tag from Quarkus repository.
|
||||
|
||||
It is also possible to change to a snapshot version by running:
|
||||
|
||||
```bash
|
||||
./set-quarkus-version.sh
|
||||
```
|
||||
|
||||
After setting the version, please verify that:
|
||||
|
||||
* `org.apache.maven` dependencies used by the test suite (and arquillian) are the same from the new Quarkus version
|
||||
|
||||
### Run a local build
|
||||
|
||||
After changing the dependency versions, you can run a local build to make sure the server extension is not broken by API changes and if
|
||||
all tests are passing:
|
||||
|
||||
```
|
||||
mvn clean install
|
||||
```
|
||||
|
||||
### Changing versions of JDBC Extensions
|
||||
|
||||
It might happen that when upgrading a version for any of the JDBC extensions (e.g.: `quarkus-jdbc-postgresql`) you also need to make sure the server extension is using the same JDBC Drivers.
|
||||
|
||||
For that, you should look at the `deployment` module of the corresponding JDBC extension from Quarkus (e.g.: https://github.com/quarkusio/quarkus/blob/main/extensions/jdbc/jdbc-postgresql/deployment/src/main/java/io/quarkus/jdbc/postgresql/deployment/JDBCPostgreSQLProcessor.java) to check if they match with the drivers used by the server extension by looking at the `org.keycloak.config.database.Database` class.
|
||||
|
||||
### Changing versions of Quarkiverse dependencies
|
||||
|
||||
Make sure the Quarkiverse dependencies are also updated and in sync with the Quarkus version you are upgrading.
|
||||
|
||||
For now, we only have this Quarkiverse dependency:
|
||||
|
||||
* https://github.com/quarkiverse/quarkus-vault
|
||||
|
||||
### What can go wrong when upgrading?
|
||||
|
||||
The perfect scenario is that after performing all the steps above the server extension will compile, the distribution can be built,
|
||||
and all tests will pass.
|
||||
|
||||
However, it is expected breaking changes between Quarkus upgrades that break the integration code we have in both [deployment](deployment) and [runtime](runtime) modules. When this happens,
|
||||
you should understand what is breaking and upgrade the integration code accordingly.
|
||||
|
||||
## References
|
||||
|
||||
* [Configuration Guide](https://www.keycloak.org/server/configuration)
|
||||
* [Re-augmentation](https://quarkus.io/guides/reaugmentation)
|
||||
* [Command Mode Application](https://quarkus.io/guides/command-mode-reference)
|
||||
|
|
@ -8,6 +8,9 @@ and prerequisites](https://github.com/keycloak/keycloak/blob/main/docs/building.
|
|||
This module holds the codebase to run Keycloak on top of [Quarkus](https://quarkus.io/):
|
||||
|
||||
```
|
||||
├── config-api
|
||||
│ ├── Configuration API for modules to avoid direct Quarkus coupling (e.g. for REST services module)
|
||||
│
|
||||
├── container
|
||||
│ ├── Dockerfile, e.g. used by the Testsuite
|
||||
│
|
||||
|
|
@ -15,7 +18,7 @@ This module holds the codebase to run Keycloak on top of [Quarkus](https://quark
|
|||
│ ├── Build-time codebase with all the necessary steps to build and configure the server
|
||||
│
|
||||
├── dist
|
||||
│ ├── Packaging the quarkus distribution
|
||||
│ ├── Packaging the Quarkus distribution
|
||||
│
|
||||
├── runtime
|
||||
│ ├── Runtime codebase with all the runtime code
|
||||
|
|
@ -24,9 +27,85 @@ This module holds the codebase to run Keycloak on top of [Quarkus](https://quark
|
|||
│ ├── The server itself, only responsible for generating the server artifacts
|
||||
│
|
||||
└── tests
|
||||
├── Integration tests for the quarkus distribution
|
||||
├── Integration tests for the Quarkus distribution
|
||||
```
|
||||
|
||||
### Keycloak Quarkus Extension
|
||||
|
||||
Keycloak on Quarkus is basically a Quarkus Extension. For more details about extensions, please take a look at [Writing Your Own Extension](https://quarkus.io/guides/writing-extensions) guide.
|
||||
|
||||
As an extension, the server can be embedded in any Quarkus application by adding the following dependency:
|
||||
|
||||
```
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-quarkus-server</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
```
|
||||
|
||||
Just like any other extension, the server extension has two main modules:
|
||||
|
||||
* `deployment`
|
||||
* `runtime`
|
||||
|
||||
Within the `deployment` module you'll find the implementation for the build steps that run when (re)augmenting the application. This module
|
||||
is responsible for all metadata processing, such as:
|
||||
|
||||
* Lookup SPIs and their providers and enable/disable them accordingly
|
||||
* Create a closed-world assumption about the providers that should be registered to the `KeycloakSessionFactory`
|
||||
* Customizations to how Hibernate, Quarkus REST, Liquibase, Infinispan, and other dependencies are configured and bootstrapped
|
||||
* Creating Jandex indexes for some server dependencies
|
||||
|
||||
The output of this module is bytecode generated by Quarkus that improves the server startup time and memory usage so that any processing
|
||||
done during (re)augmentation does not happen again when actually starting the server. Note that the code from this module does
|
||||
not run at all at runtime (when running the server) but only when building the project (the `server` module in particular, more on that later) or when triggering
|
||||
a re-augmentation when running the `build` command.
|
||||
|
||||
Within the `runtime` module you'll find the code that is run at runtime when starting and running the server. The main link between
|
||||
the `deployment` and `runtime` modules is the `org.keycloak.quarkus.runtime.KeycloakRecorder` class. The `KeycloakRecorder` holds
|
||||
a set of methods that are invoked from build steps that will end up in recorded bytecode. The recorded bytecode executes those methods at runtime
|
||||
just like they were called when a build step was run, with the exact same arguments and values, if any.
|
||||
|
||||
As an example, let us look at how the SPIs and their providers are discovered and how the `KeycloakSessionFactory` is created.
|
||||
Quarkus will run the `org.keycloak.quarkus.deployment.KeycloakProcessor.configSessionFactory` build step whenever you are (re)augmenting the server. The main outcome from this method
|
||||
is to invoke the `org.keycloak.quarkus.runtime.KeycloakRecorder.configSessionFactory` so that the code from this method is executed at
|
||||
*runtime* with a closed-world assumption about the providers that should be registered to the `KeycloakSessionFactory`. At runtime the code from that method is executed
|
||||
and a `KeycloakSessionFactory` is created without any processing to discover SPIs and their providers.
|
||||
|
||||
There are a few reasons why we have Keycloak as a Quarkus extension:
|
||||
|
||||
* More control over the build-time augmentation and runtime stages.
|
||||
* More flexibility when extending Quarkus itself and the extensions used by the server (e.g.: Hibernate, Quarkus REST, etc.)
|
||||
* Make it easier to embed the server into Quarkus applications
|
||||
* Make it possible to allow Keycloak developers to customize the server distribution
|
||||
|
||||
### Keycloak Server
|
||||
|
||||
The `server` module holds the Keycloak Server itself. It is basically a regular Quarkus application using the `keycloak-quarkus-server` extension. If you look at the
|
||||
[pom.xml](server/pom.xml) from this module you'll notice that it is a very simple Quarkus application with the bare minimum configuration
|
||||
to actually build and run the server.
|
||||
|
||||
As Quarkus application, the server is a [mutable](https://quarkus.io/guides/reaugmentation#how-to-re-augment-a-quarkus-application) application using the
|
||||
[mutable-jar](server/src/main/resources/application.properties) package type. As a mutable application, Keycloak is able to allow
|
||||
users to configure some aspects of the server without having to re-build this module, something impractical from a user perspective.
|
||||
|
||||
The mutability of the server is directly related to the `build` command. As mentioned before, the build steps from the `deployment` module
|
||||
are only run when (re)augmenting the server and when running the `build` command, the server will indicate to Quarkus that the build steps
|
||||
should re-run and the recorded bytecode should be updated to reflect any change to the server configuration.
|
||||
|
||||
From a Quarkus perspective, the server is also a [Command Mode Application](https://quarkus.io/guides/command-mode-reference) and provides
|
||||
a CLI based on [Picocli](https://picocli.info/). As such, there is a single entrypoint that executes the code to execute the CLI and bootstrap the server. This entry point
|
||||
is the `org.keycloak.quarkus.runtime.KeycloakMain` class from the `runtime` module.
|
||||
|
||||
### Keycloak Distribution
|
||||
|
||||
The server distribution is created by build the `dist` module. This module basically consists of packaging the `deployment`, `runtime`,
|
||||
and `server` modules artifacts and their dependencies to a `ZIP` or tarball file.
|
||||
|
||||
Within this directory you'll find the directory structure of the distribution and what is included in it.
|
||||
|
||||
## Prerequisites
|
||||
Before using this module, make sure you have a compatible JDK installed. (See [main build instructions](https://github.com/keycloak/keycloak/blob/main/docs/building.md)). Your shell is located at the `quarkus` submodule:
|
||||
|
||||
|
|
@ -34,9 +113,6 @@ Before using this module, make sure you have a compatible JDK installed. (See [m
|
|||
|
||||
* `KEYCLOAK_HOME` is the directory where you cloned the Keycloak repository.
|
||||
|
||||
### Activating the Module from the root directory
|
||||
When a build from the project root directory is started, this module is only enabled if your installed JDK is 11 or newer.
|
||||
|
||||
## Building the project the first time
|
||||
|
||||
To build this module and produce the artifacts to run a server, you first need to build the main codebase once. This step will put required modules of keycloak into your local maven cache in package `org.keycloak`:
|
||||
|
|
@ -47,11 +123,11 @@ This build can take some time, usually around two to four minutes depending on y
|
|||
|
||||
## Building the Keycloak Quarkus distribution
|
||||
|
||||
After the main codebase is built, you can build the quarkus distribution, including the zip and tar.gz files, by invoking the following command:
|
||||
After the main codebase is built, you can build the Quarkus distribution, including the zip and tar.gz files, by invoking the following command:
|
||||
|
||||
<KEYCLOAK_HOME>/quarkus $ ../mvnw clean install -DskipTests
|
||||
|
||||
This command produces the distribution artifacts as ZIP and TAR file. The artifacts for the quarkus distribution will be available at the `/dist/target` subdirectory afterwards.
|
||||
This command produces the distribution artifacts as ZIP and TAR file. The artifacts for the Quarkus distribution will be available at the `/dist/target` subdirectory afterwards.
|
||||
|
||||
As an alternative, you can build the distribution artifacts directly without a rebuild of the code by running the following command:
|
||||
|
||||
|
|
@ -81,6 +157,7 @@ To run the server in Quarkus' development mode, invoke the following command:
|
|||
<KEYCLOAK_HOME>/quarkus $ ../mvnw -f server/pom.xml compile quarkus:dev -Dkc.config.built=true -Dquarkus.args="start-dev"
|
||||
|
||||
You will be able to attach your debugger to port `5005`.
|
||||
You can set any command or configuration option to the server by setting the `quarkus.args` environment variable.
|
||||
|
||||
For debugging the build steps right after start, you can suspend the JVM by running:
|
||||
|
||||
|
|
@ -90,40 +167,94 @@ For debugging the build steps right after start, you can suspend the JVM by runn
|
|||
|
||||
When running using `quarkus:dev` you are able to do live coding whenever you change / add code in the `server` module, for example when creating a new custom provider.
|
||||
|
||||
There are currently limitations when running in development mode that block us to use all capabilities the Quarkus development mode has to offer. For instance, hot-reload of transient dependencies from keycloak (e.g.: keycloak-* dependencies) do not work. Expect more improvements in this area, and feel free to reach out if you want to help, using our [discussions](https://github.com/keycloak/keycloak/discussions/categories/keycloak-x-quarkus-distribution) or the development mailing list.
|
||||
There are currently limitations when running in development mode that block us to use all capabilities the Quarkus development mode has to offer.
|
||||
The main limitations you'll find at the moment are:
|
||||
|
||||
* Changes are only automatically reflected at runtime if you are changing resources from the `deployment`, `runtime`, and `server` modules. Other modules, such as `keycloak-services` still rely on Hot Swap in Java debuggers to reload classes.
|
||||
* There is nothing in the Dev UI related to the server itself, although you can still change some configuration from there.
|
||||
* There are some limitations when passing some options when running in dev mode. You should expect more improvements in this area.
|
||||
|
||||
### Debugging the server distribution
|
||||
|
||||
The `kc.sh|bat` script allows you to remotely debug the distribution. For that, you should run the server as follows:
|
||||
|
||||
```
|
||||
kc.sh --debug start-dev
|
||||
```
|
||||
|
||||
By default, the debug port is available at `8787` on localhost. Additionally, you can specify IPv4 or bracketed IPv6 addresses with optional ports, e.g. `--debug 127.0.0.1:8786`, `--debug [::1]:8785`. Make sure to exercise caution when setting IP addresses in the `--debug` parameter, since a value such as `--debug 0.0.0.0:8787` will expose the debug port to all network interfaces!
|
||||
|
||||
An additional environment variable `DEBUG_SUSPEND` can be set to suspend the JVM, when launched in debug mode. The `DEBUG_SUSPEND` variable supports the following values:
|
||||
|
||||
* `y` - The debug mode JVM launch is suspended
|
||||
* `n` - The debug mode JVM is started without suspending
|
||||
|
||||
Suspending the JVM when in debug mode is useful if you want to debug the early stages of the bootstrap code.
|
||||
|
||||
When making changes to the `deployment`, `runtime`, or `server` modules, you can update the distribution with the new artifacts by executing
|
||||
the following command:
|
||||
|
||||
```
|
||||
mvn -DskipTests clean install
|
||||
```
|
||||
|
||||
After the `quarkus` module and sub-modules are built, you can update the distribution as follows:
|
||||
|
||||
```
|
||||
cp -r server/target/lib ${KC_HOME_DIR}
|
||||
```
|
||||
|
||||
In the example above, the `${KC_HOME_DIR}` variable points to the root directory of the distribution.
|
||||
|
||||
You should also be able to update a server dependency directly. For that, copy the jar to the following location:
|
||||
|
||||
```
|
||||
cp services/target/keycloak-services-${KC_VERSION}.jar ${KC_HOME_DIR}/lib/lib/main/org.keycloak.keycloak-services-${KC_VERSION}.jar
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
The documentation is a set of guides available from the [docs](../docs/guides/server) module.
|
||||
Please, look at the [guide](../docs/building.md) about how to update and build the distribution guides.
|
||||
|
||||
## Contributing
|
||||
Please make sure to read our [Contribution Guidelines](../CONTRIBUTING.md) before contributing.
|
||||
|
||||
Before contributing changes, make sure to read the main [Keycloak Contributing Guide](https://github.com/keycloak/keycloak/blob/main/CONTRIBUTING.md).
|
||||
|
||||
Please, make sure:
|
||||
|
||||
* Documentation is updated if you are introducing any new behavior or changing an existing one that needs to be communicated
|
||||
* Make sure you have a test within the [tests/integration](tests/integration) module to cover the changes
|
||||
* You probably want to run a full build of the `quarkus` module, including running tests, to make sure you won't be surprised by failures in CI.
|
||||
|
||||
## Running tests
|
||||
Keycloaks Quarkus distribution module uses a new testsuite more integrated into the quarkus platform.
|
||||
Keycloak Quarkus distribution module uses a new testsuite more integrated into the Quarkus platform.
|
||||
|
||||
### Running tests from your IDE
|
||||
The tests can also be run from an IDE GUI such as Intellij IDEA. There are different kinds of tests:
|
||||
* Unit tests: Located in the respective module (`deployment`, `runtime`)
|
||||
* Integration tests:
|
||||
* `@CLITest` annotated: These tests have no prerequisites and are whitebox tests, so you can easily debug them.
|
||||
* `@DistributionTest` annotated: These tests need a build of the distribution artifacts first to run. These are blackbox tests, so not as easily debuggable as `@CLITest` annotated tests. Mostly used for scenarios when a `build` is involved or build options need to change, as this invocation happens in a different JVM.
|
||||
* `@DistributionTest` annotated: These tests need a build of the distribution artifacts first to run. These are blackbox tests, so not as easily debuggable as `@CLITest` annotated tests. Mostly used for scenarios when a `build` is involved or build options need to change, as this invocation may happen in a different JVM.
|
||||
|
||||
### Running container-based tests
|
||||
The `@DistributionTest` annotated tests can use different runtimes, e.g. plain JVM or a docker container. Per default, they use the plain JVM mode.
|
||||
The `@DistributionTest` annotated tests can use different runtimes, e.g. plain JVM or a Docker container. Per default, they use the plain JVM mode.
|
||||
|
||||
To run them from a container image instead, you need to build the distribution first. Then you can use the flag `-Dkc.quarkus.tests.dist=docker`. This builds a docker image from the provided distribution archives and runs the `@DistributionTest` annotated tests for them.
|
||||
To run them from a container image instead, you need to build the distribution first. Then you can use the flag `-Dkc.quarkus.tests.dist=docker`. This builds a Docker image from the provided distribution archives and runs the `@DistributionTest` annotated tests for them.
|
||||
|
||||
There are some tests annotated `@RawDistOnly` which prevents them from running in docker. You'll find a short reason in the respective annotation.
|
||||
|
||||
The container based tests are using Testcontainers to spin up the container image and can be considered tech preview.
|
||||
There are some tests annotated `@RawDistOnly` which prevents them from running in Docker. You'll find a short reason in the respective annotation.
|
||||
|
||||
### Running database tests
|
||||
There are also some container based tests to check if Keycloak starts using one of the supported database vendors. They are annotated with `@WithDatabase`.
|
||||
|
||||
These tests are disabled by default. They using Quarkus development mode predefined database containers by default and can be run in the `tests` subdirectory by using e.g.
|
||||
The storage tests are disabled by default but can be activated using the `test-database` profile.
|
||||
They're using Quarkus development mode predefined database containers by default and can be run in the `tests` subdirectory by using e.g.
|
||||
|
||||
<KEYCLOAK_HOME>/quarkus $ ../mvnw clean install -Ptest-database -Dtest=MariaDBDistTest
|
||||
|
||||
to spin up a MariaDB container and start Keycloak with it.
|
||||
|
||||
To use a specific database container image, use the option `-Dkc.db.postgresql.container.image` to specify the image tag of the postgres image to use or `-Dkc.db.mariadb.container.image=<name:tag>` for mariadb.
|
||||
To use a specific database container image, use the option `-Dkc.db.postgresql.container.image` to specify the image tag of the Postgres image to use or `-Dkc.db.mariadb.container.image=<name:tag>` for MariaDB.
|
||||
|
||||
Example:
|
||||
|
||||
|
|
@ -131,8 +262,83 @@ Example:
|
|||
|
||||
### Updating Expectations
|
||||
|
||||
Changing to the help output will cause HelpCommandDistTest to fail. This test uses [ApprovalTests](https://github.com/approvals/ApprovalTests.Java) which creates `.received.txt` files containing the actual output when tests fail. To update the expected output (see [Approving The Result](https://github.com/approvals/ApprovalTests.Java/blob/master/approvaltests/docs/tutorials/GettingStarted.md#approving-the-result)) run:
|
||||
Changing to the help output will cause `HelpCommandDistTest` to fail. This test uses [ApprovalTests](https://github.com/approvals/ApprovalTests.Java) which creates `.received.txt` files containing the actual output when tests fail. To update the expected output (see [Approving The Result](https://github.com/approvals/ApprovalTests.Java/blob/master/approvaltests/docs/tutorials/GettingStarted.md#approving-the-result)) run:
|
||||
|
||||
KEYCLOAK_REPLACE_EXPECTED=true ../mvnw clean install -Dtest=HelpCommandDistTest
|
||||
KEYCLOAK_REPLACE_EXPECTED=true ../mvnw clean install -Dtest=HelpCommandDistTest
|
||||
|
||||
then use a diff to ensure the changes look good.
|
||||
|
||||
### Running tests from the `base` testsuite
|
||||
|
||||
Sometimes you might want to run the tests from the `base` test suite using the distribution. For that, make sure you have built the `quarkus` module
|
||||
and then execute the following command from the project root directory:
|
||||
|
||||
```
|
||||
mvn -f testsuite/integration-arquillian/pom.xml clean install -Pauth-server-quarkus -Dtest=OIDCProtocolMappersTest
|
||||
```
|
||||
|
||||
### Resolving DNS names when running tests
|
||||
|
||||
In order to avoid using external services for DNS resolution, the tests are executed using a local host file by setting the `-Djdk.net.hosts.file=${project.build.testOutputDirectory}/hosts_file` system property.
|
||||
|
||||
## Upgrading Quarkus Version
|
||||
|
||||
Upgrading Quarkus requires a few steps:
|
||||
|
||||
* Change the Quarkus version
|
||||
* Change the dependencies we are using from Quarkus
|
||||
* Run a build to make sure the server extension is not broken
|
||||
|
||||
The steps still require a lot of manual work, and we should be improving this.
|
||||
|
||||
### Changing the Quarkus version
|
||||
|
||||
To change the Quarkus version, you can run the following script:
|
||||
|
||||
```bash
|
||||
./set-quarkus-version.sh <version>
|
||||
```
|
||||
|
||||
The `set-quarkus-version.sh` script is enough to change the version for all dependencies we are
|
||||
using from Quarkus.
|
||||
|
||||
The `<version>` should point to a branch or a tag from Quarkus repository.
|
||||
|
||||
It is also possible to change to a snapshot version by running:
|
||||
|
||||
```bash
|
||||
./set-quarkus-version.sh
|
||||
```
|
||||
|
||||
After setting the version, please verify that:
|
||||
|
||||
* `org.apache.maven` dependencies used by the test suite (and arquillian) are the same from the new Quarkus version
|
||||
|
||||
### Run a local build
|
||||
|
||||
After changing the dependency versions, you can run a local build to make sure the server extension is not broken by API changes and if
|
||||
all tests are passing:
|
||||
|
||||
```
|
||||
mvn clean install
|
||||
```
|
||||
|
||||
### Changing versions of JDBC Extensions
|
||||
|
||||
It might happen that when upgrading a version for any of the JDBC extensions (e.g.: `quarkus-jdbc-postgresql`) you also need to make sure the server extension is using the same JDBC Drivers.
|
||||
|
||||
For that, you should look at the `deployment` module of the corresponding JDBC extension from Quarkus (e.g.: https://github.com/quarkusio/quarkus/blob/main/extensions/jdbc/jdbc-postgresql/deployment/src/main/java/io/quarkus/jdbc/postgresql/deployment/JDBCPostgreSQLProcessor.java) to check if they match with the drivers used by the server extension by looking at the `org.keycloak.config.database.Database` class.
|
||||
|
||||
### What can go wrong when upgrading?
|
||||
|
||||
The perfect scenario is that after performing all the steps above the server extension will compile, the distribution can be built,
|
||||
and all tests will pass.
|
||||
|
||||
However, it is expected breaking changes between Quarkus upgrades that break the integration code we have in both [deployment](deployment) and [runtime](runtime) modules. When this happens,
|
||||
you should understand what is breaking and upgrade the integration code accordingly.
|
||||
|
||||
## References
|
||||
|
||||
* [Configuration Guide](https://www.keycloak.org/server/configuration)
|
||||
* [Re-augmentation](https://quarkus.io/guides/reaugmentation)
|
||||
* [Command Mode Application](https://quarkus.io/guides/command-mode-reference)
|
||||
Loading…
Reference in a new issue