I'm using Quarkus with quarkus-resteasy-reactive
and the quarkus-keycloak-admin-client-reactive
extensions. I'm building a ServerRequestFilter
that queries keycloak for a user attribute, but even though I'm using the reactive client, I'm getting BlockingNotAllowedException
when calling its methods.
Here's the filter:
public class Filters {
@Inject
Keycloak keycloak;
@ServerRequestFilter
public Uni<Response> filter(ContainerRequestContext requestContext) {
return Uni.createFrom().item(() ->
keycloak.realm("my-realm")
.users()
.search("user-that-i-get-from-context")
.stream()
.findFirst()
.orElseThrow()
.firstAttribute("the-attribute")).map(attr -> {
if (attr.equals("some-value")){
return null;
}
return Response.status(403).build();
});
}
}
I've tried adding runSubscriptionOn(Infrastructure.getDefaultWorkerPool())
to the Uni
but the error persists.
Making the requests blocking is not an option, as I want my endpoints to be reactive.
I suspect the problem is somewhere in the context of the filter and in the injection of the Keycloak
client, but I've been unable to pinpoint the problem
Unfortunately, KeycloakClient uses classic ResteasyClient blocking and not ResteasyReactiveClient.
I solved it using Vertx like this:
import io.vertx.mutiny.core.Vertx;
public class Filters {
@Inject Keycloak keycloak;
@Inject Vertx vertx;
@ServerRequestFilter
public Uni<Response> filter(ContainerRequestContext requestContext) {
return vertx.getOrCreateContext().executeBlocking(
Uni.createFrom().emitter(emitter -> {
var attr = keycloak.realm("my-realm")
.users()
.search("user-that-i-get-from-context")
.stream()
.findFirst()
.orElseThrow()
.firstAttribute("the-attribute");
if ("some-value".equals(attr)) {
emitter.complete(null);
} else {
emitter.complete(Response.status(403).build());
}
}));
}
}