diff --git a/quarkus/CONTRIBUTING.md b/quarkus/CONTRIBUTING.md deleted file mode 100644 index ab1bf961ed8..00000000000 --- a/quarkus/CONTRIBUTING.md +++ /dev/null @@ -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: - -``` - - - org.keycloak - keycloak-quarkus-server - - -``` - -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 -``` - -The `set-quarkus-version.sh` script is enough to change the version for all dependencies we are -using from Quarkus. - -The `` 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) \ No newline at end of file diff --git a/quarkus/README.md b/quarkus/README.md index a45a1bee523..d9a3188922c 100644 --- a/quarkus/README.md +++ b/quarkus/README.md @@ -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: + +``` + + + org.keycloak + keycloak-quarkus-server + + +``` + +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: /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: /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. /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=` 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=` 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 +``` + +The `set-quarkus-version.sh` script is enough to change the version for all dependencies we are +using from Quarkus. + +The `` 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) \ No newline at end of file