0

I'm building a Quarkus app which handles http requests with resteasy and calls another api with restclient and I need to propagate a header and add another one on the fly so I added a class that implements ClientHeadersFactory.

Here's the code:

@ApplicationScoped
public abstract class MicroServicesHeaderHandler implements ClientHeadersFactory {

    @Inject
    MicroServicesConfig config;

    @Override
    public MultivaluedMap<String, String> update(MultivaluedMap<String, String> incomingHeaders,
                                                 MultivaluedMap<String, String> clientOutgoingHeaders) {

        // Will be merged with outgoing headers
        return new MultivaluedHashMap<>() {{
            put("Authorization", Collections.singletonList("Bearer " + config.getServices().get(getServiceName()).getAccessToken()));
            put("passport", Collections.singletonList(incomingHeaders.getFirst("passport")));
        }};
    }

    protected abstract String getServiceName();

My issue is that the injection of the config doesn't work. I tried both with @Inject and @Context, as mentioned in the javadoc of ClientHeadersFactory. I also tried to make the class non abstract but it doesn't change anything.

MicroServicesConfig is a @Startup bean because it needs to be initialized before Quarkus.run() is called, otherwise the hot reload doesn't work anymore, since it's required to handle requests. Here's the code FYI:

@Getter
@Startup
@ApplicationScoped
public final class MicroServicesConfig {
    
    private final Map<String, MicroService> services;

    MicroServicesConfig(AKV akv, ABS abs) {
                
        // some code to retrieve an encrypted file from a secure storage, decrypt it and initialize the map out of it
    }

It appears to be an issue with ClientHeadersFactory because if I inject my bean in my main class (@QuarkusMain), it works. I'm then able to assign the map to a public static map that I can then access from my HeaderHandler with Application.myPublicStaticMap but that's ugly so I would really prefer to avoid that.

I've searched online and saw several people having the same issue but according to this blogpost, or this one, it should work as of Quarkus 1.3 and MicroProfile 3.3 (RestClient 1.4) and I'm using Quarkus 1.5.2. Even the example in the second link doesn't work for me with the injection of UriInfo so the issue doesn't come from the bean I'm trying to inject.

I've been struggling with this for weeks and I'd really like to get rid of my workaround now. I'm probably just missing something but it's driving me crazy.

Thanks in advance for your help.

Fab
  • 135
  • 9
  • There maybe other way to handle this, for adding new headers try implementing ClientRequestFilter and override method 'filter(ClientRequestContext requestContext)'. You can manipulate headers there. and for header propagation check out this link (https://stackoverflow.com/questions/62691824/how-can-the-authorization-header-be-propagated-in-quarkus-apps-with-the-micropro). Does that sort of solving your problem ? – iabughosh Jul 07 '20 at 11:24
  • Thanks for your answer. I indeed thought of using ClientRequestFilter instead, as last resort, but since ClientHeadersFactory was made for this purpose and, according to my findings, should allow injection since MicroProfile 3.3, I'd really like to make it work. Or at least understand why it doesn't. – Fab Jul 07 '20 at 12:25
  • Just a question, why class MicroServicesHeaderHandler is abstract ?! If it is abstract it wouldn't be initialized by CDI; morever, I believe you should add annotation "@RegisterClientHeaders" to this handler to activate it. – iabughosh Jul 07 '20 at 18:57
  • It's abstract because I have to implement getServiceName in each subclass to get the right value for the header, depending on the service that is called. But it's not the issue because the handler actually works, with or without abstract, it is called and does the job, as long as I don't use injection inside of it. The issue is the @Inject that doesn't work so I always get a NPE when I try to use the object that is supposed to be injected. – Fab Jul 07 '20 at 20:45

1 Answers1

0

This issue has finally been solved in Quarkus 1.8.

Fab
  • 135
  • 9