diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
deleted file mode 100644
index 3f0ccf3..0000000
--- a/.github/CODEOWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners#codeowners-syntax
-* @sschnabe @rpahli @fabian-schlegel @jschwarze @wistefan @monotek
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
deleted file mode 100644
index 415bfca..0000000
--- a/.github/dependabot.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-version: 2
-updates:
- - package-ecosystem: maven
- directory: /
- schedule:
- interval: daily
- allow:
- - dependency-name: io.kokuwa.maven:maven-parent
- - dependency-name: org.keycloak:keycloak-quarkus-server
- - package-ecosystem: github-actions
- directory: /
- schedule:
- interval: monthly
- day: monday
diff --git a/.github/settings.xml b/.github/settings.xml
deleted file mode 100644
index 44fd9ea..0000000
--- a/.github/settings.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
- sonatype-nexus
- ${env.SERVER_USERNAME}
- ${env.SERVER_PASSWORD}
-
-
- github.com
- nope
- ${env.GIT_ACTION_TOKEN}
-
-
-
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
deleted file mode 100644
index 5ed003d..0000000
--- a/.github/workflows/build.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
-name: Build
-
-on:
- push:
- branches: [main]
-
-jobs:
-
- build:
- runs-on: ubuntu-latest
- env:
- MAVEN_ARGS: --batch-mode --color=always --no-transfer-progress --settings=.github/settings.xml
- steps:
- - run: git config --global user.name "${{ vars.KOKUWA_IO_BOT_NAME }}"
- - run: git config --global user.email "${{ vars.KOKUWA_IO_BOT_EMAIL }}"
- - uses: actions/checkout@v4
- with:
- token: ${{ secrets.GIT_ACTION_TOKEN }}
- - uses: actions/setup-java@v4
- with:
- distribution: temurin
- java-version: 17
- cache: maven
- - run: mvn $MAVEN_ARGS deploy
- env:
- SERVER_USERNAME: ${{ secrets.SONATYPE_NEXUS_USERNAME }}
- SERVER_PASSWORD: ${{ secrets.SONATYPE_NEXUS_PASSWORD }}
- - run: mvn $MAVEN_ARGS site-deploy
- env:
- GIT_ACTION_TOKEN: ${{ secrets.GIT_ACTION_TOKEN }}
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
deleted file mode 100644
index e3240ed..0000000
--- a/.github/workflows/release.yaml
+++ /dev/null
@@ -1,50 +0,0 @@
-name: Release
-
-on: workflow_dispatch
-
-jobs:
- build:
- runs-on: ubuntu-latest
- env:
- MAVEN_ARGS: --batch-mode --color=always --no-transfer-progress --settings=.github/settings.xml
- steps:
- - name: docker/login-action docker.io
- uses: docker/login-action@v3.4.0
- with:
- registry: docker.io
- username: ${{ secrets.DOCKERIO_USERNAME }}
- password: ${{ secrets.DOCKERIO_TOKEN }}
- - name: docker/login-action ghcr.io
- uses: docker/login-action@v3.4.0
- with:
- registry: ghcr.io
- username: ${{ github.actor }}
- password: ${{ secrets.GIT_ACTION_TOKEN }}
- - run: git config --global user.name "${{ vars.KOKUWA_IO_BOT_NAME }}"
- - run: git config --global user.email "${{ vars.KOKUWA_IO_BOT_EMAIL }}"
- - uses: actions/checkout@v4
- with:
- token: ${{ secrets.GIT_ACTION_TOKEN }}
- - uses: crazy-max/ghaction-import-gpg@v6
- with:
- gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
- passphrase: ${{ secrets.GPG_PASSPHRASE }}
- git_user_signingkey: true
- git_commit_gpgsign: true
- - uses: actions/setup-java@v4
- with:
- distribution: temurin
- java-version: 17
- cache: maven
- server-id: sonatype-nexus
- server-username: SERVER_USERNAME
- server-password: SERVER_PASSWORD
- gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }}
- gpg-passphrase: GPG_PASSPHRASE
- - run: mvn $MAVEN_ARGS release:prepare -Darguments="$MAVEN_ARGS"
- - run: mvn $MAVEN_ARGS release:perform -Darguments="$MAVEN_ARGS"
- env:
- SERVER_USERNAME: ${{ secrets.SONATYPE_NEXUS_USERNAME }}
- SERVER_PASSWORD: ${{ secrets.SONATYPE_NEXUS_PASSWORD }}
- GIT_ACTION_TOKEN: ${{ secrets.GIT_ACTION_TOKEN }}
- GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
diff --git a/.github/workflows/pr.yaml b/.github/workflows/verify.yaml
similarity index 58%
rename from .github/workflows/pr.yaml
rename to .github/workflows/verify.yaml
index 86a8eb1..3238458 100644
--- a/.github/workflows/pr.yaml
+++ b/.github/workflows/verify.yaml
@@ -1,44 +1,43 @@
-name: PullRequest
+name: Verify
-on: pull_request
+on:
+ - pull_request
+ - push:
+ branches: [main]
env:
MAVEN_ARGS: --batch-mode --color=always --no-transfer-progress -Dmaven.test.redirectTestOutputToFile=false
jobs:
- yaml:
+ renovate:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
- - uses: ibiqlik/action-yamllint@v3
- with:
- format: colored
- strict: true
+ - uses: actions/checkout@main
+ - uses: docker://kokuwaio/renovate-config-validator
- markdown:
+ markdownlint:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
- - uses: avto-dev/markdown-lint@v1
- with:
- args: /github/workspace
+ - uses: actions/checkout@main
+ - uses: docker://kokuwaio/markdownlint
+
+ yamllint:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@main
+ - uses: docker://kokuwaio/yamllint
build:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-java@v4
+ - uses: actions/checkout@main
+ - uses: actions/setup-java@main
with:
distribution: temurin
java-version: 17
cache: maven
- run: mvn $MAVEN_ARGS verify
- - run: mvn $MAVEN_ARGS site
- - uses: actions/upload-artifact@v4
- if: always()
- with:
- path: target/site
versions:
runs-on: ubuntu-latest
@@ -54,8 +53,8 @@ jobs:
- 26.1.5
- 26.2.1
steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-java@v4
+ - uses: actions/checkout@main
+ - uses: actions/setup-java@main
with:
distribution: temurin
java-version: 17
diff --git a/.woodpecker/build.yaml b/.woodpecker/build.yaml
new file mode 100644
index 0000000..a738643
--- /dev/null
+++ b/.woodpecker/build.yaml
@@ -0,0 +1,29 @@
+when:
+ event: [manual, push]
+ branch: main
+ path: [.woodpecker/build.yaml, pom.xml, src/**]
+
+services:
+ - name: dockerd
+ image: kokuwaio/dockerd
+ ports: [2375, 8080]
+
+steps:
+
+ build:
+ image: maven:3.9.9-eclipse-temurin-17
+ commands:
+ - env | sort
+ - mvn deploy --settings=.woodpecker/maven/settings.xml -Dmaven.test.redirectTestOutputToFile=true -X
+ environment:
+ NEXUS_USERNAME: {from_secret: nexus_username}
+ NEXUS_PASSWORD: {from_secret: nexus_password}
+
+ debug:
+ image: kokuwaio/dockerd
+ commands:
+ - docker ps --all
+ - docker logs keylcoak
+ - exit 1
+ when:
+ status: failure
diff --git a/.woodpecker/lint.yaml b/.woodpecker/lint.yaml
new file mode 100644
index 0000000..74bb114
--- /dev/null
+++ b/.woodpecker/lint.yaml
@@ -0,0 +1,21 @@
+when:
+ event: [manual, pull_request, push]
+ branch: main
+ path: [.woodpecker/lint.yaml, renovate.json, "**/*.y*ml", "**/*.md"]
+
+steps:
+
+ renovate:
+ image: kokuwaio/renovate-config-validator
+ depends_on: []
+ when: [path: [.woodpecker/lint.yaml, renovate.json]]
+
+ yaml:
+ image: kokuwaio/yamllint
+ depends_on: []
+ when: [path: [.woodpecker/lint.yaml, .yamllint.yaml, "**/*.y*ml"]]
+
+ markdown:
+ image: kokuwaio/markdownlint
+ depends_on: []
+ when: [path: [.woodpecker/lint.yaml, .markdownlint.yaml, "**/*.md"]]
diff --git a/.woodpecker/maven/settings.xml b/.woodpecker/maven/settings.xml
new file mode 100644
index 0000000..9676f61
--- /dev/null
+++ b/.woodpecker/maven/settings.xml
@@ -0,0 +1,18 @@
+
+
+ false
+ /woodpecker/.m2
+
+
+ sonatype-nexus
+ ${env.NEXUS_USERNAME}
+ ${env.NEXUS_PASSWORD}
+
+
+
+
+ http://mirror.woodpecker.svc/maven2
+ central
+
+
+
diff --git a/.woodpecker/verify.yaml b/.woodpecker/verify.yaml
new file mode 100644
index 0000000..3b16e79
--- /dev/null
+++ b/.woodpecker/verify.yaml
@@ -0,0 +1,23 @@
+when:
+ event: [manual, pull_request]
+ path: [.woodpecker/verify.yaml, pom.xml, src/**]
+
+matrix:
+ KEYCLOAK_VERSION:
+ - 22.0.5
+ - 23.0.7
+ - 24.0.5
+ - 25.0.6
+ - 26.0.8
+ - 26.1.5
+ - 26.2.5
+
+services:
+ - name: dockerd
+ image: kokuwaio/dockerd
+ ports: [2375, 8080]
+
+steps:
+ verify:
+ image: maven:3.9.9-eclipse-temurin-17
+ commands: mvn verify --settings=.woodpecker/maven/settings.xml -Dversion.org.keycloak.test=$KEYCLOAK_VERSION
diff --git a/pom.xml b/pom.xml
index 2f4ae93..f4e0738 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2,13 +2,6 @@
4.0.0
-
- io.kokuwa.maven
- maven-parent
- 0.6.18
-
-
-
io.kokuwa.keycloak
keycloak-event-metrics
1.1.2-SNAPSHOT
@@ -31,12 +24,10 @@
- sschnabe
+ stephan.schnabel
Stephan Schnabel
- https://github.com/sschnabe
- stephan@grayc.de
- GrayC GmbH
- https://grayc.de
+ https://schnabel.org
+ stephan@schnabel.org
Europe/Berlin
@@ -55,6 +46,16 @@
github
https://github.com/kokuwaio/keycloak-event-metrics/actions
+
+
+ sonatype-nexus
+ https://oss.sonatype.org/service/local/staging/deploy/maven2/
+
+
+ sonatype-nexus
+ https://oss.sonatype.org/content/repositories/snapshots/
+
+
@@ -62,15 +63,47 @@
- 17
- 17
+ 2025-04-28T12:25:49Z
+ UTF-8
+ ISO-8859-1
- deploy,site,ossrh,release
+ 17
+ ${maven.compiler.release}
+ ${maven.compiler.release}
+ -Xlint:all
+ true
+ true
+ true
+
+ true
+
+ true
+ java.,javax.,jakarta.,org.
+ ${project.basedir}/src/eclipse/formatter.xml
-
+
+ 3.4.1
+ 3.14.0
+ 3.1.4
+ 3.2.7
+ 3.1.4
+ 3.4.2
+ 3.11.2
+ 3.1.1
+ 3.3.1
+ 3.21.0
+ 3.3.1
+ 3.5.3
+ 3.5.1
+ 1.4.0
+ 2.18.0
+ 1.7.0
+ 2.26.0
+ 1.12.0
+
26.2.5
${version.org.keycloak}
1.18.3
@@ -188,12 +221,136 @@
+ ${project.artifactId}
${project.basedir}/src/test/resources
true
+
+
+
+ org.apache.maven.plugins
+ maven-clean-plugin
+ ${version.org.apache.maven.plugins.clean}
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${version.org.apache.maven.plugins.compiler}
+
+ ${maven.compiler.compilerArgument}
+
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+ ${version.org.apache.maven.plugins.deploy}
+
+
+ org.apache.maven.plugins
+ maven-failsafe-plugin
+ ${version.org.apache.maven.plugins.surefire}
+
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+ ${version.org.apache.maven.plugins.gpg}
+
+
+ org.apache.maven.plugins
+ maven-install-plugin
+ ${version.org.apache.maven.plugins.install}
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ ${version.org.apache.maven.plugins.jar}
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ ${version.org.apache.maven.plugins.javadoc}
+
+
+ org.apache.maven.plugins
+ maven-release-plugin
+ ${version.org.apache.maven.plugins.release}
+
+ clean verify
+ check
+ deploy
+ deploy,release
+ true
+ @{prefix} prepare release @{releaseLabel} [CI SKIP]
+ @{project.version}
+
+
+
+ org.apache.maven.plugins
+ maven-resources-plugin
+ ${version.org.apache.maven.plugins.resources}
+
+ ${project.build.propertiesEncoding}
+
+
+
+ org.apache.maven.plugins
+ maven-site-plugin
+ ${version.org.apache.maven.plugins.site}
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ ${version.org.apache.maven.plugins.source}
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ ${version.org.apache.maven.plugins.surefire}
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ ${version.org.codehaus.mojo.exec}
+
+
+ org.codehaus.mojo
+ tidy-maven-plugin
+ ${version.org.codehaus.mojo.tidy}
+
+
+ org.codehaus.mojo
+ versions-maven-plugin
+ ${version.org.codehaus.mojo.versions}
+
+ false
+
+ ^.*-(alpha|beta|M)-?[0-9]+$
+
+
+
+
+ org.sonatype.plugins
+ nexus-staging-maven-plugin
+ ${version.org.sonatype.plugins.nexus}
+
+
+ net.revelc.code.formatter
+ formatter-maven-plugin
+ ${version.net.revelc.code.formatter}
+
+ ${formatter.configFile}
+
+
+
+ net.revelc.code
+ impsort-maven-plugin
+ ${version.net.revelc.code.impsort}
+
+
+
@@ -210,13 +367,13 @@
-
+
- org.codehaus.mojo
- flatten-maven-plugin
+ org.apache.maven.plugins
+ maven-install-plugin
- default
+ default-install
@@ -227,9 +384,136 @@
- release
+ dev
+
+
+ !env.CI
+
+
+
+ org.codehaus.mojo
+ tidy-maven-plugin
+
+
+ validate
+
+ pom
+
+
+
+
+
+ net.revelc.code
+ impsort-maven-plugin
+
+
+ validate
+
+ sort
+
+
+
+
+
+ net.revelc.code.formatter
+ formatter-maven-plugin
+
+
+ validate
+
+ format
+
+
+
+
+
+
+
+
+ check
+
+
+ env.CI
+
+
+
+
+
+ org.codehaus.mojo
+ tidy-maven-plugin
+
+
+ validate
+
+ check
+
+
+
+
+
+ net.revelc.code
+ impsort-maven-plugin
+
+
+ validate
+
+ check
+
+
+
+
+
+ net.revelc.code.formatter
+ formatter-maven-plugin
+
+
+ validate
+
+ validate
+
+
+
+
+
+
+
+
+ deploy
+
+
+ env.CI
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+
+
+
+ jar-no-fork
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+
+
+
+ javadoc-no-fork
+
+
+
+
+
+
org.apache.maven.plugins
maven-resources-plugin
@@ -279,5 +563,38 @@
+
+ release
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+
+
+
+ sign
+
+
+
+
+
+
+
+ org.sonatype.plugins
+ nexus-staging-maven-plugin
+ true
+
+ sonatype-nexus
+ https://oss.sonatype.org/
+ true
+
+
+
+
+
+
diff --git a/renovate.json b/renovate.json
new file mode 100644
index 0000000..942e54b
--- /dev/null
+++ b/renovate.json
@@ -0,0 +1,33 @@
+{
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
+ "labels": ["renovate", "renovate-manager/{{{manager}}}", "renovate-type/{{{updateType}}}"],
+ "dependencyDashboard": true,
+ "dependencyDashboardLabels": ["renovate"],
+ "dependencyDashboardApproval": true,
+ "dependencyDashboardOSVVulnerabilitySummary": "all",
+ "separateMajorMinor": true,
+ "separateMinorPatch": true,
+ "separateMultipleMinor": true,
+ "separateMultipleMajor": true,
+ "pinDigests": true,
+ "automerge": false,
+ "automergeStrategy": "fast-forward",
+ "rebaseWhen": "behind-base-branch",
+ "packageRules": [
+ {
+ "matchUpdateTypes": ["digest"],
+ "dependencyDashboardApproval": false,
+ "automergeType": "branch"
+ },{
+ "matchUpdateTypes": ["patch"],
+ "dependencyDashboardApproval": false,
+ "automerge": true
+ },{
+ "matchUpdateTypes": ["minor"],
+ "dependencyDashboardApproval": false
+ },{
+ "matchManagers": ["woodpecker"],
+ "pinDigests": false
+ }
+ ]
+}
diff --git a/src/eclipse/formatter.xml b/src/eclipse/formatter.xml
new file mode 100644
index 0000000..61186a2
--- /dev/null
+++ b/src/eclipse/formatter.xml
@@ -0,0 +1,404 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/test/java/io/kokuwa/keycloak/metrics/KeycloakIT.java b/src/test/java/io/kokuwa/keycloak/metrics/KeycloakIT.java
index cd4ebf4..a9ffeaa 100644
--- a/src/test/java/io/kokuwa/keycloak/metrics/KeycloakIT.java
+++ b/src/test/java/io/kokuwa/keycloak/metrics/KeycloakIT.java
@@ -10,6 +10,8 @@ import java.time.Instant;
import java.util.UUID;
import java.util.function.Supplier;
+import jakarta.ws.rs.NotAuthorizedException;
+
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -18,7 +20,6 @@ import org.keycloak.events.EventType;
import io.kokuwa.keycloak.metrics.junit.KeycloakClient;
import io.kokuwa.keycloak.metrics.junit.KeycloakExtension;
import io.kokuwa.keycloak.metrics.junit.Prometheus;
-import jakarta.ws.rs.NotAuthorizedException;
/**
* Integration tests with Keycloak.
@@ -87,7 +88,7 @@ public class KeycloakIT {
() -> assertEquals(loginErrorBefore2 + 1, loginErrorAfter2, "login failure #2"),
() -> assertEquals(0, loginErrorAfter3, "login failure #3"),
() -> assertEquals(0, loginErrorAfter4, "login failure #4"),
- () -> assertEquals(loginErrorBeforeUNKNOWN + 2 , loginErrorAfterUNKNOWN, "login failure UNKNOWN"));
+ () -> assertEquals(loginErrorBeforeUNKNOWN + 2, loginErrorAfterUNKNOWN, "login failure UNKNOWN"));
}
@DisplayName("user count")
diff --git a/src/test/java/io/kokuwa/keycloak/metrics/junit/KeycloakClient.java b/src/test/java/io/kokuwa/keycloak/metrics/junit/KeycloakClient.java
index 029ffde..b79ca14 100644
--- a/src/test/java/io/kokuwa/keycloak/metrics/junit/KeycloakClient.java
+++ b/src/test/java/io/kokuwa/keycloak/metrics/junit/KeycloakClient.java
@@ -13,6 +13,10 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
+import jakarta.ws.rs.core.HttpHeaders;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedHashMap;
+
import org.keycloak.OAuth2Constants;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.admin.client.token.TokenService;
@@ -24,10 +28,6 @@ import org.keycloak.representations.idm.UserRepresentation;
import com.fasterxml.jackson.databind.ObjectMapper;
-import jakarta.ws.rs.core.HttpHeaders;
-import jakarta.ws.rs.core.MediaType;
-import jakarta.ws.rs.core.MultivaluedHashMap;
-
/**
* Client for keycloak.
*
diff --git a/src/test/java/io/kokuwa/keycloak/metrics/junit/KeycloakExtension.java b/src/test/java/io/kokuwa/keycloak/metrics/junit/KeycloakExtension.java
index e2b1175..ada9013 100644
--- a/src/test/java/io/kokuwa/keycloak/metrics/junit/KeycloakExtension.java
+++ b/src/test/java/io/kokuwa/keycloak/metrics/junit/KeycloakExtension.java
@@ -7,18 +7,19 @@ import java.time.Duration;
import java.util.Properties;
import java.util.Set;
+import jakarta.ws.rs.client.ClientBuilder;
+
import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.ParameterContext;
import org.junit.jupiter.api.extension.ParameterResolver;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.admin.client.token.TokenService;
+import org.testcontainers.containers.FixedHostPortGenericContainer;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.utility.MountableFile;
-import jakarta.ws.rs.client.ClientBuilder;
-
/**
* JUnit extension to start keycloak.
*
@@ -29,6 +30,7 @@ public class KeycloakExtension implements BeforeAllCallback, ParameterResolver {
private static KeycloakClient client;
private static Prometheus prometheus;
+ @SuppressWarnings({ "resource", "deprecation" })
@Override
public void beforeAll(ExtensionContext context) throws Exception {
@@ -45,14 +47,20 @@ public class KeycloakExtension implements BeforeAllCallback, ParameterResolver {
throw new Exception("Failed to read properties", e);
}
var version = properties.getProperty("version");
+ var image = "quay.io/keycloak/keycloak:" + version;
var jar = properties.getProperty("jar");
var timeout = properties.getProperty("timeout");
// create and start container
- @SuppressWarnings("resource")
- var container = new GenericContainer<>("quay.io/keycloak/keycloak:" + version)
- .withEnv("KEYCLOAK_ADMIN", "admin")
+ var container = new GenericContainer<>(image).withExposedPorts(8080);
+ if (System.getenv("CI") != null) {
+ // use fixed port and hostname in ci
+ container = new FixedHostPortGenericContainer<>(image)
+ .withFixedExposedPort(8080, 8080)
+ .withCreateContainerCmdModifier(c -> c.withName("keycloak"));
+ }
+ container.withEnv("KEYCLOAK_ADMIN", "admin")
.withEnv("KEYCLOAK_ADMIN_PASSWORD", "password")
.withEnv("KC_LOG_LEVEL", "io.kokuwa:trace")
// otherwise port 9000 will be used, with this config we can test different keycloak versions
@@ -63,7 +71,6 @@ public class KeycloakExtension implements BeforeAllCallback, ParameterResolver {
.withEnv("KC_METRICS_STATS_INTERVAL", "PT1s")
.withCopyFileToContainer(MountableFile.forHostPath(jar), "/opt/keycloak/providers/metrics.jar")
.withLogConsumer(out -> System.out.print(out.getUtf8String()))
- .withExposedPorts(8080)
.withStartupTimeout(Duration.parse(timeout))
.waitingFor(Wait.forHttp("/health").forPort(8080))
.withCommand("start-dev");
@@ -76,6 +83,12 @@ public class KeycloakExtension implements BeforeAllCallback, ParameterResolver {
// create client for keycloak container
var url = "http://" + container.getHost() + ":" + container.getMappedPort(8080);
+ System.out.println(container.getHost());
+ System.out.println(container.getHost());
+ System.out.println(container.getHost());
+ System.out.println(container.getExtraHosts());
+ System.out.println(container.getExtraHosts());
+ System.out.println(container.getExtraHosts());
var keycloak = Keycloak.getInstance(url, "master", "admin", "password", "admin-cli");
assertEquals(version, keycloak.serverInfo().getInfo().getSystemInfo().getVersion(), "version invalid");
var target = ClientBuilder.newClient().target(url);