Внедрение bean-компонента внутри ClientHeadersFactory не работает

Я создаю приложение Quarkus, которое обрабатывает HTTP-запросы с рестайлингом и вызывает другой api с помощью restclient, и мне нужно распространить заголовок и добавить еще один на лету, поэтому я добавил класс, реализующий ClientHeadersFactory.

Вот код:

@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();

Моя проблема в том, что внедрение конфигурации не работает. Я пробовал как с @Inject, так и с @Context, как указано в javadoc от ClientHeadersFactory. Я также пытался сделать класс не абстрактным, но это ничего не меняет.

MicroServicesConfig - это @Startup bean, потому что он должен быть инициализирован перед вызовом Quarkus.run(), иначе горячая перезагрузка больше не работает, поскольку требуется для обработки запросов. Вот код, к сведению:

@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
    }

Похоже, это проблема с ClientHeadersFactory, потому что, если я ввожу свой компонент в основной класс (@QuarkusMain), он работает. Затем я могу назначить карту общедоступной статической карте, к которой я затем могу получить доступ из моего HeaderHandler с помощью Application.myPublicStaticMap, но это некрасиво, поэтому я бы предпочел избежать этого.

Я поискал в Интернете и увидел, что у нескольких людей такая же проблема, но согласно этому blogpost или this one, он должен работать с Quarkus 1.3 и MicroProfile 3.3 (RestClient 1.4 ), а я использую Quarkus 1.5.2. Даже пример во второй ссылке не работает для меня с инъекцией UriInfo, поэтому проблема возникает не из-за bean-компонента, который я пытаюсь внедрить.

Я боролся с этим в течение нескольких недель, и я действительно хотел бы избавиться от моего обходного пути сейчас. Я, наверное, просто что-то упускаю, но это сводит меня с ума.

Заранее спасибо за помощь.


person Fab    schedule 07.07.2020    source источник
comment
Возможно, есть другой способ справиться с этим: для добавления новых заголовков попробуйте реализовать ClientRequestFilter и переопределить метод filter (ClientRequestContext requestContext). Здесь вы можете манипулировать заголовками. а для распространения заголовков ознакомьтесь с этой ссылкой (stackoverflow.com/questions/62691824/). Решает ли это вашу проблему?   -  person iabughosh    schedule 07.07.2020
comment
Спасибо за Ваш ответ. Я действительно думал об использовании ClientRequestFilter вместо этого в крайнем случае, но поскольку ClientHeadersFactory был создан для этой цели и, согласно моим выводам, должен позволять инъекцию, начиная с MicroProfile 3.3, мне бы очень хотелось, чтобы он работал. Или хотя бы понять, почему это не так.   -  person Fab    schedule 07.07.2020
comment
Сразу вопрос, почему класс MicroServicesHeaderHandler абстрактный ?! Если он абстрактный, он не будет инициализирован CDI; Более того, я считаю, что вам следует добавить аннотацию @RegisterClientHeaders к этому обработчику, чтобы активировать его.   -  person iabughosh    schedule 07.07.2020
comment
Это абстрактно, потому что мне нужно реализовать getServiceName в каждом подклассе, чтобы получить правильное значение для заголовка, в зависимости от вызываемой службы. Но проблема не в этом, потому что обработчик действительно работает, с абстрактным или без него, он вызывается и выполняет свою работу, если я не использую внутри него инъекцию. Проблема в том, что @Inject не работает, поэтому я всегда получаю NPE, когда пытаюсь использовать объект, который должен быть введен.   -  person Fab    schedule 07.07.2020


Ответы (1)


Эта проблема была окончательно решена в Quarkus 1.8.

person Fab    schedule 02.10.2020