Skip to content

Commit

Permalink
Strimzi OAuth substitutions
Browse files Browse the repository at this point in the history
  • Loading branch information
ozangunalp committed Oct 25, 2023
1 parent 81d9000 commit 4308428
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 28 deletions.
5 changes: 5 additions & 0 deletions bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4256,6 +4256,11 @@
<artifactId>kafka-oauth-client</artifactId>
<version>${strimzi-oauth.version}</version>
</dependency>
<dependency>
<groupId>io.strimzi</groupId>
<artifactId>kafka-oauth-common</artifactId>
<version>${strimzi-oauth.version}</version>
</dependency>
<dependency>
<groupId>io.strimzi</groupId>
<artifactId>strimzi-test-container</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,6 @@ public void build(

handleAvro(reflectiveClass, proxies, serviceProviders, sslNativeSupport, capabilities);
handleOpenTracing(reflectiveClass, capabilities);
handleStrimziOAuth(curateOutcomeBuildItem, reflectiveClass);

}

Expand Down Expand Up @@ -330,31 +329,6 @@ private void handleOpenTracing(BuildProducer<ReflectiveClassBuildItem> reflectiv
.build());
}

private void handleStrimziOAuth(CurateOutcomeBuildItem curateOutcomeBuildItem,
BuildProducer<ReflectiveClassBuildItem> reflectiveClass) {
if (!QuarkusClassLoader.isClassPresentAtRuntime("io.strimzi.kafka.oauth.client.JaasClientOauthLoginCallbackHandler")) {
return;
}

reflectiveClass
.produce(ReflectiveClassBuildItem.builder("io.strimzi.kafka.oauth.client.JaasClientOauthLoginCallbackHandler")
.methods().fields().build());

if (curateOutcomeBuildItem.getApplicationModel().getDependencies().stream().anyMatch(
x -> x.getGroupId().equals("org.keycloak") && x.getArtifactId().equals("keycloak-core"))) {
reflectiveClass.produce(ReflectiveClassBuildItem.builder("org.keycloak.jose.jws.JWSHeader",
"org.keycloak.representations.AccessToken",
"org.keycloak.representations.AccessToken$Access",
"org.keycloak.representations.AccessTokenResponse",
"org.keycloak.representations.IDToken",
"org.keycloak.representations.JsonWebToken",
"org.keycloak.jose.jwk.JSONWebKeySet",
"org.keycloak.jose.jwk.JWK",
"org.keycloak.json.StringOrArrayDeserializer",
"org.keycloak.json.StringListMapDeserializer").methods().fields().build());
}
}

private void handleAvro(BuildProducer<ReflectiveClassBuildItem> reflectiveClass,
BuildProducer<NativeImageProxyDefinitionBuildItem> proxies,
BuildProducer<ServiceProviderBuildItem> serviceProviders,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package io.quarkus.kafka.client.deployment;

import io.quarkus.bootstrap.classloading.QuarkusClassLoader;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem;

public class StrimziOAuthProcessor {

@BuildStep
public void handleStrimziOAuth(CurateOutcomeBuildItem curateOutcomeBuildItem,
BuildProducer<ReflectiveClassBuildItem> reflectiveClass) {
if (!QuarkusClassLoader.isClassPresentAtRuntime("io.strimzi.kafka.oauth.client.JaasClientOauthLoginCallbackHandler")) {
return;
}

reflectiveClass
.produce(ReflectiveClassBuildItem.builder(
"io.strimzi.kafka.oauth.client.JaasClientOauthLoginCallbackHandler")
.methods().fields().build());

if (curateOutcomeBuildItem.getApplicationModel().getDependencies().stream().anyMatch(
x -> x.getGroupId().equals("org.keycloak") && x.getArtifactId().equals("keycloak-core"))) {
reflectiveClass.produce(ReflectiveClassBuildItem.builder("org.keycloak.jose.jws.JWSHeader",
"org.keycloak.representations.AccessToken",
"org.keycloak.representations.AccessToken$Access",
"org.keycloak.representations.AccessTokenResponse",
"org.keycloak.representations.IDToken",
"org.keycloak.representations.JsonWebToken",
"org.keycloak.jose.jwk.JSONWebKeySet",
"org.keycloak.jose.jwk.JWK",
"org.keycloak.json.StringOrArrayDeserializer",
"org.keycloak.json.StringListMapDeserializer").methods().fields().build());
}
}

}
5 changes: 5 additions & 0 deletions extensions/kafka-client/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@
<artifactId>quarkus-kubernetes-service-binding</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.strimzi</groupId>
<artifactId>kafka-oauth-common</artifactId>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
package io.smallrye.reactive.kafka.graal;

import java.lang.reflect.InvocationTargetException;
import java.util.function.BooleanSupplier;

import com.jayway.jsonpath.Predicate;
import com.jayway.jsonpath.spi.json.JacksonJsonNodeJsonProvider;
import com.jayway.jsonpath.spi.json.JacksonJsonProvider;
import com.jayway.jsonpath.spi.json.JsonProvider;
import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider;
import com.jayway.jsonpath.spi.mapper.MappingProvider;
import com.oracle.svm.core.annotate.Alias;
import com.oracle.svm.core.annotate.RecomputeFieldValue;
import com.oracle.svm.core.annotate.Substitute;
import com.oracle.svm.core.annotate.TargetClass;

Expand All @@ -17,6 +26,81 @@ private static String defaultKerberosRealm() throws ClassNotFoundException, NoSu

}

@TargetClass(className = "com.jayway.jsonpath.internal.filter.ValueNodes", innerClass = "JsonNode", onlyWith = HasStrimzi.class)
final class Target_com_jayway_jsonpath_internal_filter_ValueNodes_JsonNode {
@Alias
private Object json;
@Alias
private boolean parsed;

@Substitute
public Object parse(Predicate.PredicateContext ctx) {
try {
return parsed ? json : new JacksonJsonProvider().parse(json.toString());
} catch (Throwable e) {
throw new IllegalArgumentException(e);
}
}
}

@TargetClass(className = "com.jayway.jsonpath.internal.filter.ValueNode", onlyWith = HasStrimzi.class)
final class Target_com_jayway_jsonpath_internal_filter_ValueNode {

@Substitute
private static boolean isJson(Object o) {
if (o == null || !(o instanceof String)) {
return false;
}
String str = o.toString().trim();
if (str.length() <= 1) {
return false;
}
char c0 = str.charAt(0);
char c1 = str.charAt(str.length() - 1);
if ((c0 == '[' && c1 == ']') || (c0 == '{' && c1 == '}')) {
try {
new JacksonJsonProvider().parse(str);
return true;
} catch (Exception e) {
return false;
}
}
return false;
}
}

@TargetClass(className = "com.jayway.jsonpath.internal.DefaultsImpl", onlyWith = HasStrimzi.class)
final class Target_com_jayway_jsonpath_internal_DefaultsImpl {

@RecomputeFieldValue(kind = RecomputeFieldValue.Kind.FromAlias)
@Alias
public static Target_com_jayway_jsonpath_internal_DefaultsImpl INSTANCE = new Target_com_jayway_jsonpath_internal_DefaultsImpl();

@Substitute
public JsonProvider jsonProvider() {
return new JacksonJsonNodeJsonProvider();
}

@Substitute
public MappingProvider mappingProvider() {
return new JacksonMappingProvider();
}
}

final class HasStrimzi implements BooleanSupplier {

@Override
public boolean getAsBoolean() {
try {
KafkaSubstitutions.class.getClassLoader()
.loadClass("io.strimzi.kafka.oauth.client.JaasClientOauthLoginCallbackHandler");
return true;
} catch (Exception e) {
return false;
}
}
}

class KafkaSubstitutions {

}
15 changes: 13 additions & 2 deletions integration-tests/kafka-oauth-keycloak/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@
<groupId>io.strimzi</groupId>
<artifactId>kafka-oauth-client</artifactId>
</dependency>
<dependency>
<groupId>io.strimzi</groupId>
<artifactId>kafka-oauth-common</artifactId>
</dependency>

<!-- test dependencies -->
<dependency>
Expand Down Expand Up @@ -71,6 +75,11 @@
<artifactId>awaitility</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-test-keycloak-server</artifactId>
<scope>test</scope>
</dependency>

<!-- Minimal test dependencies to *-deployment artifacts for consistent build order -->
<dependency>
Expand Down Expand Up @@ -174,7 +183,8 @@
<skip>false</skip>
<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.docker.image}</keycloak.docker.image>
<keycloak.realm.json>${project.basedir}/src/test/resources/keycloak/realms/kafka-authz-realm.json</keycloak.realm.json>
</systemPropertyVariables>
</configuration>
</plugin>
Expand All @@ -183,7 +193,8 @@
<configuration>
<skip>false</skip>
<systemPropertyVariables>
<quarkus.test.arg-line>-Djdk.net.hosts.file=${basedir}/target/hosts</quarkus.test.arg-line>
<keycloak.docker.image>${keycloak.docker.image}</keycloak.docker.image>
<keycloak.realm.json>${project.basedir}/src/test/resources/keycloak/realms/kafka-authz-realm.json</keycloak.realm.json>
</systemPropertyVariables>
</configuration>
</plugin>
Expand Down

0 comments on commit 4308428

Please sign in to comment.