Skip to content
This repository has been archived by the owner on Apr 5, 2022. It is now read-only.

OAuth2FeignRequestInterceptor fails with hystrix thread isolation #89

Closed
miguelfgar opened this issue Jan 5, 2016 · 5 comments
Closed
Labels

Comments

@miguelfgar
Copy link

Hi guys,

I'm implenting OAuth2 Token relay with Spring Boot 1.3.1 and Spring Cloud Brixton.M4
Microservice A needs to call Microservice B propagating the same OAuth2 token that comes from ZuulProxy (which is OAuth2 enabled).

I'm using FeignClient (in Microservice A) with OAuth2FeignRequestInterceptor so FeingClient can add the oauth2 token to the call to the Microservice B.
However, I get the following exception:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.oauth2ClientContext': Scope 'request' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.

I've seen that OAuth2ClientContext is by default scoped "session" as is necessary to persist the context between HTTP Request.

How should I config the OAuth2FeignRequestInterceptor so this works? Currently:

@Bean
public RequestInterceptor oauth2FeignRequestInterceptor(OAuth2ClientContext oauth2ClientContext){
    return new OAuth2FeignRequestInterceptor(oauth2ClientContext, resource());
}       

I've been not able to find an example of using OAuth2FeignRequestInterceptor in this scenario (token relay). If you have one, could you send me the link? or could you point me in the right direction with this?

Thanks so much!

@miguelfgar
Copy link
Author

Hi, I have found out that the problem is that Hystrix forces code execution in another thread and so you have no access to request / session scoped beans.
I was using @FeignClient with Hystrix enabled. When I disable Hystrix using feign.hystrix.enabled: false
the call from Microservice A to Microservice B relaying the token (using OAuth2FeignRequestInterceptor) works fine.

However, it would be desirable to be able to keep Hystrix enabled.
I have seen there is a new module that improves Hystrix - Feign (feign-hystrix module) in this regard in this post:
http://stackoverflow.com/questions/32482704/does-spring-cloud-feign-client-call-execute-inside-hystrix-command

However, I don't see how to properly do the setup using feign-hystrix and I was not able to find an example. Please, could you help with this or provide an example using feign-hystrix?

Thanks so much!

@spencergibb
Copy link
Contributor

@miguelfgar If you are using @FeignClient in Brixton and hystrix is on the classpath you are using feign-hystrix.

@dsyer dsyer changed the title OAuth2FeignRequestInterceptor fails implementing OAuth2 Token Relay with feign OAuth2FeignRequestInterceptor fails with hystrix thread isolation Jan 14, 2016
@miguelfgar
Copy link
Author

Hi @spencergibb, @dsyer,

Thanks so much for your help.

@dsyer, now that I understand what the problem is I completely agree with the change of the subject. Thanks for changing it.

@spencergibb yes, I use @FeignClient and I have hystrix on the classpath and so I'm using feign-hystrix module as you say (I have checked that the jar appears on my classpath). All this is OK.
What I meant is that I don't know how to do the proper setup so everything works together in this particular case (Feign, Hystrix, using OAuth2FeignRequestInterceptor with default Hystrix THREAD isolation).
In this particular scenario, the problem is that OAuth2ClientContext will not be created - as it requires Request / Session (I have seen OAuth2ClientContext is scoped "session" by default) - with the default Hystrix isolation "THREAD" because it will open a new thread to excecute the code and so it will not be able to rebuild the OAuth2ClientContext from the current http request.

My code works with the following setups:

  • setup 1 (Hystrix disabled)
    feign.hystrix.enabled=false -> This disables Hystrix (no desirable) and so the interceptor gets the OAuth2ClientContext because the code is executed in the same thread. Obviously is not an option if you want to use Hystrix
  • setup 2 (Hystrix enabled but isolation strategy 'semaphore')
    hystrix.command.default.execution.isolation.strategy: SEMAPHORE -> Instead of using default isolation strategy ('thread') which executes the code in a separate thread, it executes the code in the current thread (and so the OAuth2ClientContext can be retrieved and everything works OK). However for performance reasons I guess this is not desirable either as this is blocking the current thread. I guess in this case the default 'thread' isolation strategy would be recommended.

Summary, what I don't know is how to make OAuth2FeignRequestInterceptor to work with feign-hystrix enabled and 'thread' isolation, which is exactly what Dave has reworded in the title of the issue very well :-)
At the end of the day, I guess it should be common to use feign-hystrix module implementing OAuth2 with 'token relay (from ZuulProxy) technique' and want to use it with 'thread' isolation strategy for performance reasons.
Any idea, guys, to achieve this?

Thanks again for your help :-)

@loesak
Copy link

loesak commented Jul 19, 2016

how do you set the isolation strategy to SEMAPHORE? the property 'hystrix.command.default.execution.isolation.strategy' doesn't seem to exist in the lastest release of spring-cloud-starter-hystrix (1.1.4.RELEASE) and i'm not seeing how to configure the circuit breaker used by spring feign.

Or to be more clean, it may be coded to, but i cannot find where it would be coded to and it doesn't seem to be exposed in a spring-configuration-metadata.json for the project

EDIT: so it looks like its coded in but just not in any configuration metadata file

@dsyer
Copy link
Contributor

dsyer commented Jul 20, 2016

It's not spring configuration, it's Hystrix (via archaius), so the metadata won't reflect it. I believe It is well documented both in the spring cloud user guide and the Hystrix wiki.

@dsyer dsyer closed this as completed Aug 26, 2016
jagpreetstamber added a commit to spring-cloud-native-experiment/config-repo that referenced this issue Aug 31, 2016
This is done as it runs on separate thread when hystrix is enabled which in turn does not work with OAuth2

Gives below error:
No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.

Refer to spring-attic/spring-cloud-security#89 for more details
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Development

No branches or pull requests

4 participants