OpenLiberty / open-liberty

Open Liberty is a highly composable, fast to start, dynamic application server runtime environment
https://openliberty.io
Eclipse Public License 2.0
1.15k stars 591 forks source link

MP Rest Client should use CDI AnnotatedType information to find interceptor binding annotations rather than reflection #19625

Open Azquelt opened 2 years ago

Azquelt commented 2 years ago

Currently, MP Rest Client looks for interceptor bindings on the rest client interface using reflection in order to call interceptors annotated with @AroundInvoke when methods on the rest client bean are called.

However, CDI is required to use it's AnnotatedType information to find interceptor bindings, not reflection (so that CDI Extensions have an opportunity to add or modify them).

The container must use the operations of Annotated and its subinterfaces to discover program element types and annotations. The container must not directly call the Java Reflection API. In particular, the container must:

  • call Annotated.getAnnotations() to determine the scope, qualifiers, stereotypes and interceptor bindings of a bean,

CDI 11.4

MP Rest Client should do the same so that interceptor bindings work consistently between rest client beans and other CDI beans.

This is the cause of the additional code we currently have in MP Rest Client to handle Fault Tolerance interceptors.

Azquelt commented 2 years ago

I think this is what we need to do:

In the CDI extension, have a @Observes @WithAnnotations(RegisterRestClient.class) ProcessAnnotatedType<?> method which will be called for each class annotated with RegiterRestClient. Build a collection of all of the rest client interfaces. Do not veto the type (it's an interface, so it shouldn't be treated as a bean by CDI anyway, and we want to give other extensions the chance to modify it).

In the CDI extension, have a @Observes AfterBeanDiscovery method which will be called once after all the beans have been discovered. For each rest client interface:

Side note: although we should use AnnotatedType for the interceptor bindings, we should still use reflection to find the rest client annotations, since rest client can also be used without CDI and we want that to be consistent.