This is an automated email from the ASF dual-hosted git repository.
jamesnetherton pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
The following commit(s) were added to refs/heads/main by this push:
new aec25ff1d4 Improve container setup for kafka-oauth test
aec25ff1d4 is described below
commit aec25ff1d4aa8f6b211fcef9452d0f6126e5a7cf
Author: James Netherton <[email protected]>
AuthorDate: Thu Nov 16 12:11:12 2023 +0000
Improve container setup for kafka-oauth test
---
integration-tests/kafka-oauth/pom.xml | 11 +--
.../src/main/resources/application.properties | 11 +--
.../kafka/oauth/it/KafkaKeycloakTestResource.java | 80 ++++++++++++++++++++--
.../oauth/it/container/KeycloakContainer.java | 61 -----------------
.../src/test/resources/kafkaServer.properties | 15 +---
pom.xml | 1 +
6 files changed, 84 insertions(+), 95 deletions(-)
diff --git a/integration-tests/kafka-oauth/pom.xml
b/integration-tests/kafka-oauth/pom.xml
index 7542b7eca6..8e01b47e85 100644
--- a/integration-tests/kafka-oauth/pom.xml
+++ b/integration-tests/kafka-oauth/pom.xml
@@ -88,6 +88,11 @@
<artifactId>strimzi-test-container</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-test-keycloak-server</artifactId>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
@@ -126,8 +131,7 @@
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemPropertyVariables>
- <!-- Configure the app to test to resolve
"keycloak" hostname to the Docker hostname -->
-
<jdk.net.hosts.file>target/hosts</jdk.net.hosts.file>
+
<keycloak.docker.image>${keycloak.container.image}</keycloak.docker.image>
</systemPropertyVariables>
</configuration>
</plugin>
@@ -156,9 +160,8 @@
<goal>verify</goal>
</goals>
<configuration>
-
<rerunFailingTestsCount>${rerun.failing.test.count}</rerunFailingTestsCount>
<systemPropertyVariables>
-
<quarkus.test.arg-line>-Djdk.net.hosts.file=target/hosts</quarkus.test.arg-line>
+
<keycloak.docker.image>${keycloak.container.image}</keycloak.docker.image>
</systemPropertyVariables>
</configuration>
</execution>
diff --git
a/integration-tests/kafka-oauth/src/main/resources/application.properties
b/integration-tests/kafka-oauth/src/main/resources/application.properties
index 315c07153a..2dd473ffde 100644
--- a/integration-tests/kafka-oauth/src/main/resources/application.properties
+++ b/integration-tests/kafka-oauth/src/main/resources/application.properties
@@ -23,26 +23,17 @@ kafka.topic.name=test
timer.period = 100
timer.delay = 100
-camel.component.kafka.security-protocol = SASL_PLAINTEXT
-camel.component.kafka.sasl-mechanism = OAUTHBEARER
-camel.component.kafka.sasl-jaas-config =
org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required \
- oauth.client.id="kafka-client" \
- oauth.client.secret="kafka-client-secret" \
-
oauth.token.endpoint.uri="http://keycloak:8080/auth/realms/kafka-authz/protocol/openid-connect/token"
;
-camel.component.kafka.additional-properties[sasl.login.callback.handler.class]
= io.strimzi.kafka.oauth.client.JaasClientOauthLoginCallbackHandler
-
# enable health check
quarkus.kafka.health.enabled=true
# using QuarkusTestResourceLifecycleManager in this test: Kafka configuration
needs to be tuned to work with Keycloak
quarkus.kafka.devservices.enabled=false
-
#
# Quarkus - Log
#
quarkus.log.category."org.apache.camel.quarkus.core.deployment".level = INFO
-quarkus.log.category."org.apache.camel.quarkus.component.kafka".level = DEBUG
+quarkus.log.category."org.apache.camel.quarkus.component.kafka".level = INFO
quarkus.log.category."org.apache.zookeeper".level = WARNING
quarkus.log.category."org.apache.kafka".level = WARNING
diff --git
a/integration-tests/kafka-oauth/src/test/java/org/apache/camel/quarkus/kafka/oauth/it/KafkaKeycloakTestResource.java
b/integration-tests/kafka-oauth/src/test/java/org/apache/camel/quarkus/kafka/oauth/it/KafkaKeycloakTestResource.java
index 6891a565f3..5554d5202e 100644
---
a/integration-tests/kafka-oauth/src/test/java/org/apache/camel/quarkus/kafka/oauth/it/KafkaKeycloakTestResource.java
+++
b/integration-tests/kafka-oauth/src/test/java/org/apache/camel/quarkus/kafka/oauth/it/KafkaKeycloakTestResource.java
@@ -16,13 +16,19 @@
*/
package org.apache.camel.quarkus.kafka.oauth.it;
+import java.io.IOException;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
+import io.quarkus.test.keycloak.client.KeycloakTestClient;
+import io.quarkus.test.keycloak.server.KeycloakContainer;
import io.strimzi.test.container.StrimziKafkaContainer;
-import org.apache.camel.quarkus.kafka.oauth.it.container.KeycloakContainer;
+import org.apache.commons.io.IOUtils;
import org.eclipse.microprofile.config.ConfigProvider;
import org.jboss.logging.Logger;
import org.testcontainers.utility.MountableFile;
@@ -34,7 +40,8 @@ import static
io.strimzi.test.container.StrimziKafkaContainer.KAFKA_PORT;
*/
public class KafkaKeycloakTestResource implements
QuarkusTestResourceLifecycleManager {
- private static final Logger log =
Logger.getLogger(KafkaKeycloakTestResource.class);
+ private static final Logger LOG =
Logger.getLogger(KafkaKeycloakTestResource.class);
+ private static final String REALM_JSON =
"keycloak/realms/kafka-authz-realm.json";
private StrimziKafkaContainer kafka;
private KeycloakContainer keycloak;
@@ -46,23 +53,56 @@ public class KafkaKeycloakTestResource implements
QuarkusTestResourceLifecycleMa
keycloak = new KeycloakContainer();
keycloak.withStartupTimeout(Duration.ofMinutes(5));
keycloak.start();
- log.info(keycloak.getLogs());
- keycloak.createHostsFile();
+ LOG.info(keycloak.getLogs());
+
+ Path realmJson = null;
+ try {
+ URL resource =
Thread.currentThread().getContextClassLoader().getResource(REALM_JSON);
+ if (resource == null) {
+ throw new RuntimeException("Unable to load " + REALM_JSON);
+ }
+
+ realmJson = Files.createTempFile("keycloak-auth", ".json");
+ IOUtils.copy(resource, realmJson.toFile());
+
+ KeycloakTestClient client = new
KeycloakTestClient(keycloak.getServerUrl());
+ client.createRealmFromPath(realmJson.toAbsolutePath().toString());
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ } finally {
+ if (realmJson != null) {
+ try {
+ Files.deleteIfExists(realmJson);
+ } catch (IOException e) {
+ // Ignored
+ }
+ }
+ }
//Start kafka container
String imageName =
ConfigProvider.getConfig().getValue("strimzi-kafka.container.image",
String.class);
this.kafka = new StrimziKafkaContainer(imageName)
.withBrokerId(1)
-
.withKafkaConfigurationMap(Map.of("listener.security.protocol.map",
"JWT:SASL_PLAINTEXT,BROKER1:PLAINTEXT"))
+
.withKafkaConfigurationMap(Map.of("listener.security.protocol.map",
+ "JWT:SASL_PLAINTEXT,BROKER1:PLAINTEXT",
+ "listener.name.jwt.oauthbearer.sasl.jaas.config",
+ getOauthSaslJaasConfig(keycloak.getInternalUrl(),
keycloak.getServerUrl()),
+ "listener.name.jwt.plain.sasl.jaas.config",
+ getPlainSaslJaasConfig(keycloak.getInternalUrl(),
keycloak.getServerUrl())))
.withNetworkAliases("kafka")
.withServerProperties(MountableFile.forClasspathResource("kafkaServer.properties"))
.withBootstrapServers(
c -> String.format("JWT://%s:%s", c.getHost(),
c.getMappedPort(KAFKA_PORT)));
this.kafka.start();
- log.info(this.kafka.getLogs());
+ LOG.info(this.kafka.getLogs());
+
properties.put("kafka.bootstrap.servers",
this.kafka.getBootstrapServers());
properties.put("camel.component.kafka.brokers",
kafka.getBootstrapServers());
-
+ properties.put("camel.component.kafka.security-protocol",
"SASL_PLAINTEXT");
+ properties.put("camel.component.kafka.sasl-mechanism", "OAUTHBEARER");
+
properties.put("camel.component.kafka.additional-properties[sasl.login.callback.handler.class]",
+
"io.strimzi.kafka.oauth.client.JaasClientOauthLoginCallbackHandler");
+ properties.put("camel.component.kafka.sasl-jaas-config",
getClientSaslJaasConfig(keycloak.getServerUrl()));
return properties;
}
@@ -75,4 +115,30 @@ public class KafkaKeycloakTestResource implements
QuarkusTestResourceLifecycleMa
keycloak.stop();
}
}
+
+ private String getClientSaslJaasConfig(String keycloakServerUrl) {
+ return
"org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required" +
+ " oauth.client.id=\"kafka-client\"" +
+ " oauth.client.secret=\"kafka-client-secret\"" +
+ " oauth.token.endpoint.uri=\"" + keycloakServerUrl +
"/realms/kafka-authz/protocol/openid-connect/token\";";
+ }
+
+ private String getPlainSaslJaasConfig(String keycloakInternalUrl, String
keycloakServerUrl) {
+ return "'org.apache.kafka.common.security.plain.PlainLoginModule
required " +
+ "oauth.jwks.endpoint.uri=\"" + keycloakInternalUrl +
"/realms/kafka-authz/protocol/openid-connect/certs\" " +
+ "oauth.valid.issuer.uri=\"" + keycloakServerUrl +
"/realms/kafka-authz\" " +
+ "oauth.token.endpoint.uri=\"" + keycloakInternalUrl +
"/realms/kafka-authz/protocol/openid-connect/token\" " +
+ "oauth.client.id=\"kafka\" " +
+ "oauth.client.secret=\"kafka-secret\" " +
+ "unsecuredLoginStringClaim_sub=\"admin\";'";
+ }
+
+ private String getOauthSaslJaasConfig(String keycloakInternalUrl, String
keycloakServerUrl) {
+ return
"'org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required
" +
+ "oauth.jwks.endpoint.uri=\"" + keycloakInternalUrl +
"/realms/kafka-authz/protocol/openid-connect/certs\" " +
+ "oauth.valid.issuer.uri=\"" + keycloakServerUrl +
"/realms/kafka-authz\" " +
+ "oauth.token.endpoint.uri=\"" + keycloakInternalUrl +
"/realms/kafka-authz/protocol/openid-connect/token\" " +
+ "oauth.client.id=\"kafka\" " +
+ "oauth.client.secret=\"kafka-secret\";'";
+ }
}
diff --git
a/integration-tests/kafka-oauth/src/test/java/org/apache/camel/quarkus/kafka/oauth/it/container/KeycloakContainer.java
b/integration-tests/kafka-oauth/src/test/java/org/apache/camel/quarkus/kafka/oauth/it/container/KeycloakContainer.java
deleted file mode 100644
index dcf86ae383..0000000000
---
a/integration-tests/kafka-oauth/src/test/java/org/apache/camel/quarkus/kafka/oauth/it/container/KeycloakContainer.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.quarkus.kafka.oauth.it.container;
-
-import java.io.FileWriter;
-
-import org.testcontainers.containers.FixedHostPortGenericContainer;
-import org.testcontainers.containers.Network;
-import org.testcontainers.containers.wait.strategy.Wait;
-import org.testcontainers.utility.MountableFile;
-
-/**
- * Inspired from
https://github.com/quarkusio/quarkus/tree/main/integration-tests/kafka-oauth-keycloak/
- */
-public class KeycloakContainer extends
FixedHostPortGenericContainer<KeycloakContainer> {
-
- public KeycloakContainer() {
- super("quay.io/keycloak/keycloak:16.1.1");
- withExposedPorts(8443);
- withFixedExposedPort(8080, 8080);
- withEnv("KEYCLOAK_USER", "admin");
- withEnv("KEYCLOAK_PASSWORD", "admin");
- withEnv("KEYCLOAK_HTTPS_PORT", "8443");
- withEnv("PROXY_ADDRESS_FORWARDING", "true");
- withEnv("KEYCLOAK_IMPORT",
"/opt/jboss/keycloak/realms/kafka-authz-realm.json");
- waitingFor(Wait.forLogMessage(".*WFLYSRV0025.*", 1));
- withNetwork(Network.SHARED);
- withNetworkAliases("keycloak");
-
withCopyFileToContainer(MountableFile.forClasspathResource("keycloak/realms/kafka-authz-realm.json"),
- "/opt/jboss/keycloak/realms/kafka-authz-realm.json");
- withCommand("-Dkeycloak.profile.feature.upload_scripts=enabled", "-b",
"0.0.0.0");
- }
-
- public void createHostsFile() {
- try (FileWriter fileWriter = new FileWriter("target/hosts")) {
- String dockerHost = this.getHost();
- if ("localhost".equals(dockerHost)) {
- fileWriter.write("127.0.0.1 keycloak");
- } else {
- fileWriter.write(dockerHost + " keycloak");
- }
- fileWriter.flush();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-}
diff --git
a/integration-tests/kafka-oauth/src/test/resources/kafkaServer.properties
b/integration-tests/kafka-oauth/src/test/resources/kafkaServer.properties
index efc0bb86d0..cbf18d7404 100644
--- a/integration-tests/kafka-oauth/src/test/resources/kafkaServer.properties
+++ b/integration-tests/kafka-oauth/src/test/resources/kafkaServer.properties
@@ -76,22 +76,11 @@ oauth.username.claim=preferred_username
principal.builder.class=io.strimzi.kafka.oauth.server.OAuthKafkaPrincipalBuilder
listener.name.jwt.sasl.enabled.mechanisms=OAUTHBEARER,PLAIN
-listener.name.jwt.oauthbearer.sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule
required \
-
oauth.jwks.endpoint.uri="http://keycloak:8080/auth/realms/kafka-authz/protocol/openid-connect/certs"
\
- oauth.valid.issuer.uri="http://keycloak:8080/auth/realms/kafka-authz" \
-
oauth.token.endpoint.uri="http://keycloak:8080/auth/realms/kafka-authz/protocol/openid-connect/token"
\
- oauth.client.id="kafka" \
- oauth.client.secret="kafka-secret";
+listener.name.jwt.oauthbearer.sasl.jaas.config=set_by_test
listener.name.jwt.oauthbearer.sasl.server.callback.handler.class=io.strimzi.kafka.oauth.server.JaasServerOauthValidatorCallbackHandler
listener.name.jwt.oauthbearer.sasl.login.callback.handler.class=io.strimzi.kafka.oauth.client.JaasClientOauthLoginCallbackHandler
-listener.name.jwt.plain.sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule
required \
-
oauth.jwks.endpoint.uri="http://keycloak:8080/auth/realms/kafka-authz/protocol/openid-connect/certs"
\
- oauth.valid.issuer.uri="http://keycloak:8080/auth/realms/kafka-authz" \
-
oauth.token.endpoint.uri="http://keycloak:8080/auth/realms/kafka-authz/protocol/openid-connect/token"
\
- oauth.client.id="kafka" \
- oauth.client.secret="kafka-secret" \
- unsecuredLoginStringClaim_sub="admin";
+#listener.name.jwt.plain.sasl.jaas.config=set_by_test
listener.name.jwt.plain.sasl.server.callback.handler.class=io.strimzi.kafka.oauth.server.plain.JaasServerOauthOverPlainValidatorCallbackHandler
diff --git a/pom.xml b/pom.xml
index 23141de3d7..fae0b35589 100644
--- a/pom.xml
+++ b/pom.xml
@@ -230,6 +230,7 @@
<infinispan.container.image>docker.io/infinispan/server:14.0</infinispan.container.image>
<influxdb.container.image>docker.io/influxdb:1.8.10</influxdb.container.image>
<kafka.container.image>confluentinc/cp-kafka:7.4.0</kafka.container.image>
+
<keycloak.container.image>quay.io/keycloak/keycloak:22.0.5</keycloak.container.image>
<kudu.container.image>docker.io/apache/kudu:1.15.0</kudu.container.image>
<localstack.container.image>docker.io/localstack/localstack:2.2.0</localstack.container.image>
<lra-coordinator.container.image>quay.io/jbosstm/lra-coordinator:7.0.0.Final-3.2.2.Final</lra-coordinator.container.image>