I am trying to transform annotation data using BuildStep as stated on the link below
https://quarkus.io/guides/cdi-integration#annotations_transformer_build_item
However, I am not seeing any indication this is working. I can't verify during build time what is wrong and there is no change at runtime. Below is the sample code:
public class TestTelemetryBuilder {
@BuildStep
AnnotationsTransformerBuildItem transform() {
return new AnnotationsTransformerBuildItem(new AnnotationsTransformer() {
@Override
public boolean appliesTo(final org.jboss.jandex.AnnotationTarget.Kind kind) {
return kind == org.jboss.jandex.AnnotationTarget.Kind.CLASS;
}
@Override
public void transform(final TransformationContext context) {
if ("io.quarkus.redis.datasource.value.ValueCommands"
.equals(context.getTarget().asClass().name().toString())) {
List<MethodInfo> methods = context.getTarget().asClass().methods();
AnnotationInstance annot = AnnotationInstance.builder(DotName.createSimple(
"io.opentelemetry.instrumentation.annotations.WithSpan")).build();
methods.forEach(t -> t.annotations()
.add(annot));
}
}
});
}
}
I want to add the WithSpan annotation to all the methods on the Redis ValueCommands class whenever called. Does this work only when the class is injected? I tried with RedisDataSource which is injected but couldn't get it to work. Is there anything else I need to setup/configure?
So the
AnnotationsTransformerBuildItemis used to modify the internal model of classes that the given Quarkus component uses. It doesn't modify bytecode or anything like that, so you can't observe the changes directly, only indirectly (through changed behavior).There are 2 classes named
AnnotationsTransformerBuildItem:io.quarkus.arc.deployment.AnnotationsTransformerBuildItemfor ArC, the CDI container in Quarkusio.quarkus.resteasy.reactive.server.spi.AnnotationsTransformerBuildItemfor RESTEasy Reactive, the JAX-RS implementation in QuarkusSince
@WithSpanis treated as an interceptor binding in Quarkus, you need the ArC'sAnnotationsTransformerBuildItem.Assuming you have the ArC's
AnnotationsTransformerBuildItem, there are 3 problems:You're using the transformation API incorrectly. Adding an annotation to the set of annotations returned from
MethodInfois not supposed to work and it's not going to work. The transformation API is basically a callback. You're called with aTransformationContextfor any given element, and you have to modify the annotations through theTransformationContext. Since you're trying to modify annotations on the methods ofio.quarkus.redis.datasource.value.ValueCommands, yourappliesTomethod should bereturn kind == AnnotationTarget.Kind.METHODand thetransformmethod should check if the method it is given is declared on the class you need.But even if you used the transformation API correctly, it still wouldn't work. You're trying to modify annotations on
io.quarkus.redis.datasource.value.ValueCommands, which is an interface. An interface is never a bean class, and CDI never inherits annotations from interfaces, so such transformation is useless.Even if you found the concrete implementation of
ValueCommands, it still wouldn't work. Adding an interceptor binding to a class only makes sense if that class is a CDI managed bean (also known as class-based bean). Most of the API exposed by the Redis client are not CDI beans at all, and those that are (such asRedisDataSourcethat you can inject) are not managed beans (they are synthetic beans actually). So none of that can actually be intercepted.To sum up, making sure that the Redis calls are properly traced is not possible using annotation transformations.
The good news is, the underlying Vert.x Redis client implementation has gained native support for tracing in version 4.4.5. This version is used in Quarkus since version 3.4 (which was released a few days ago), so it should either work out of the box once you upgrade, or it should be fairly simple to implement on the Quarkus side. If Redis command tracing doesn't work with Quarkus 3.4, please file a feature request.