Ошибка создания бина с именем scopedTarget.oauth2ClientContext: область действия «запрос» не активна для текущего потока для симулированного клиента - PullRequest
0 голосов
/ 11 января 2019

Я звоню в другой микросервис, когда мой текущий микросервис запущен и готов, используя симулированный клиент в моем текущем микросервисе, построенном с использованием Jhipster. Так что мой интерфейс Feign

package com.persistent.integration.client;

import java.util.List;

import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.persistent.integration.service.dto.DataPipelineDTO;

@AuthorizedFeignClient(name = "Integrationconfiguration") 
public interface DataPipelinesResourceFeign {
     @RequestMapping(value = "/api/data-pipelines", method = RequestMethod.GET)     
     List<DataPipelineDTO> getAllDataPipelines(@RequestParam(value = "pageable") Pageable pageable );       
}

}

И я реализовал ApplicationRunner, где я вызвал метод симуляции клиента.

@Component
public class ApplicationInitializer implements ApplicationRunner {

    @Autowired
    private DataPipelinesResourceFeign dataPipelinesResourceFeign; 

    @Autowired
    private ActiveMQListener activeMqListener;


    @Override
    public void run(ApplicationArguments args) throws Exception {
        // TODO Auto-generated method stub
        Pageable pageable = PageRequest.of(0, 20);
        try {
        List <DataPipelineDTO> allStartedDataPipeLines = dataPipelinesResourceFeign.getAllDataPipelines(pageable);      //.stream().filter(p->p.getState().equals(State.STARTED)).collect(Collectors.toList());

        allStartedDataPipeLines.forEach(datapipe -> 
                {
                    try {
                        activeMqListener.consume(datapipe);
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                });
        } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
        }
    }

Но после запуска это выдает ниже исключение в dataPipelinesResourceFeign.getAllDataPipelines:

com.netflix.hystrix.exception.HystrixRuntimeException: DataPipelinesResourceFeign#getAllDataPipelines(Pageable) failed and no fallback available.
    at com.netflix.hystrix.AbstractCommand$22.call(AbstractCommand.java:819)
    at com.netflix.hystrix.AbstractCommand$22.call(AbstractCommand.java:804)
    at rx.internal.operators.OperatorOnErrorResumeNextViaFunction$4.onError(OperatorOnErrorResumeNextViaFunction.java:140)
    at rx.internal.operators.OnSubscribeDoOnEach$DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87)
    at rx.internal.operators.OnSubscribeDoOnEach$DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87)
    at com.netflix.hystrix.AbstractCommand$DeprecatedOnFallbackHookApplication$1.onError(AbstractCommand.java:1472)

Причина: org.springframework.beans.factory.BeanCreationException: Ошибка создания бина с именем 'scopedTarget.oauth2ClientContext': Область 'запрос' не активна для текущего потока; рассматривать определение прокси области действия для этого компонента, если вы намереваетесь обратиться к нему из синглтона; Вложенное исключение - java.lang.IllegalStateException: Привязанный к потоку запрос не найден: Вы ссылаетесь на атрибуты запроса за пределами фактического веб-запроса или обработки запроса за пределами изначально получающий поток? Если вы на самом деле работаете в веб-запрос и до сих пор получают это сообщение, ваш код, вероятно, работает вне DispatcherServlet / DispatcherPortlet: в этом случае используйте RequestContextListener или RequestContextFilter, чтобы выставить текущий запрос на

org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean (Abstrac> tBeanFactory.java:362) в org.springframework.beans.factory.support.AbstractBeanFactory.getBean (AbstractB> eanFactory.java:199) в org.springframework.aop.target.SimpleBeanTargetSource.getTarget (SimpleBeanTarge> tSource.java:35) в org.springframework.aop.framework.JdkDynamicAopProxy.invoke (. JdkDynamicAopProxy> Java: 193) в com.sun.proxy. $ Proxy147.getAccessToken (неизвестный источник) в com.persistent.integration.security.oauth2.AuthorizationHeaderUtil.getAuthoriza> tionHeaderFromOAuth2Context (AuthorizationHeaderUtil.java:28) в com.persistent.integration.client.TokenRelayRequestInterceptor.apply (TokenRelay> RequestInterceptor.java:23) в feign.SynchronousMethodHandler.targetRequest (SynchronousMethodHandler.java:158) в feign.SynchronousMethodHandler.executeAndDecode (SynchronousMethodHandler.java:88) в feign.SynchronousMethodHandler.invoke (SynchronousMethodHandler.java:76) в feign.hystrix.HystrixInvocationHandler $ 1.run (HystrixInvocationHandler.java:108) на com.netflix.hystrix.HystrixCommand $ 2.call (HystrixCommand.java:302) на com.netflix.hystrix.HystrixCommand $ 2.call (HystrixCommand.java:298) в rx.internal.operators.OnSubscribeDefer.call (OnSubscribeDefer.java:46) ... еще 68 Вызвано: java.lang.IllegalStateException: Нет Обнаружен связанный с потоком запрос: Вы ссылаетесь на атрибуты запроса за пределами фактического веб-запроса или обработки запроса за пределами изначально получающий поток? Если вы на самом деле работаете в веб-запрос и до сих пор получают это сообщение, ваш код, вероятно, работает вне DispatcherServlet / DispatcherPortlet: в этом случае используйте RequestContextListener или RequestContextFilter, чтобы выставить текущий запрос в org.springframework.web.context.request.RequestContextHolder.currentRequestAttr> ibutes (RequestContextHolder.java:131) в org.springframework.web.context.request.AbstractRequestAttributesScope.get (Abst> ractRequestAttributesScope.java:42) в org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean (Abstrac> tBeanFactory.java:350)

Многие предложения в Интернете заключались в добавлении listerner RequestContextListener. Но проблема не исчезла, даже если я добавил слушателя в webConfigurer.java в методе onStartup.

{

* * ServletContext.addListener тысячи двадцать-одина (RequestContextListener.class); * * тысяча двадцать-дв

} Но бесполезно.

Любые выводы будут оценены.

1 Ответ

0 голосов
/ 17 января 2019

Я нашел обходной путь для этого. Я не знаю, почему TokenRelayRequestIntercepton не работает, но вы можете использовать свой собственный RequestInterceptor, основанный на SecurityContext в Spring.

Сначала определите RequestInterceptor:

    public class MyRequestInterceptor implements RequestInterceptor {

    public static final String AUTHORIZATION = "Authorization";
    public static final String BEARER = "Bearer";

    public MyRequestInterceptor() {
        super();
    }

    @Override
    public void apply(RequestTemplate template) {
        // demander un token à keycloak et le joindre à la request
        Optional<String> header = getAuthorizationHeader();
        if (header.isPresent()) {
            template.header(AUTHORIZATION, header.get());
        }
    }

    public static Optional<String> getAuthorizationHeader() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication  != null && authentication.getDetails() != null && authentication.getDetails() instanceof OAuth2AuthenticationDetails) {
            OAuth2AuthenticationDetails oAuth2AuthenticationDetails =
                (OAuth2AuthenticationDetails) authentication.getDetails();

            return Optional.of(String.format("%s %s", oAuth2AuthenticationDetails.getTokenType(),
                oAuth2AuthenticationDetails.getTokenValue()));

        } else {
            return Optional.empty();
        }
    }

}

, а затем объявите класс конфигурации для вашего симулированного клиента, используя ваш RequestInterceptor, он должен содержать что-то вроде этого:

@Bean(name = "myRequestInterceptor")
public RequestInterceptor getMyRequestInterceptor() throws IOException {
    return new MyRequestInterceptor();
}

Ваш клиент Feign должен выглядеть так:

 @FeignClient(name = "SERVICE_NAME", configuration = MyFeignConfiguration.class)
public interface MyRestClient {
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...