Spring context is not getting updated even after using DelegatingSecurityContextAsyncTaskExecutor

966 Views Asked by At

I ran into some problem with spring contexts and it's really made more confusing after reading all the articles. So, here it is my use case:

I have an application running which needs user's authentication token passed in the request to use it in the the process I will run in background. This token is used to make rest api calls. At first, we were manually creating new thread and to pass on the context I was using MODE_INHERITABLETHREADLOCAL strategy for spring context. But in latest release we started using thread pool. It worked after deployment but token was getting invalidating after a point because thread was not getting the latest context. I read articles and started using DelegatingSecurityContextAsyncTaskExecutor like below:

@Bean public DelegatingSecurityContextAsyncTaskExecutor taskExecutor(ThreadPoolTaskExecutor delegate) { return new DelegatingSecurityContextAsyncTaskExecutor(delegate); }

But I still have the same problem when I checked today. Now tomorrow I might bombarded with mails from tester with failing test cases. One thing I want to add that I am still using MODE_INHERITABLETHREADLOCAL as strategy along with DelegatingSecurityContextAsyncTaskExecutor. Please help me out.

1

There are 1 best solutions below

0
On

First: You should not use MODE_INHERITABLETHREADLOCAL together with pooled threads (to learn more, read this)

Second: From my experience defining DelegatingSecurityContextAsyncTaskExecutor as a @Bean won't work. The default executor will be still used.

You need to extend your @EnableAsync @Configuration from AsyncConfigurer interface and implement getAsyncExecutor, not annotating it with a @Bean. Working example:

@EnableAsync
@Configuration
public class AsyncConfig implements AsyncConfigurer {
    private final ThreadPoolTaskExecutor defaultSpringBootAsyncExecutor;

    public AsyncConfig(ThreadPoolTaskExecutor defaultSpringBootAsyncExecutor) {
        this.defaultSpringBootAsyncExecutor = defaultSpringBootAsyncExecutor;
    }

    @Override
    public Executor getAsyncExecutor() {
        return new DelegatingSecurityContextAsyncTaskExecutor(defaultSpringBootAsyncExecutor);
    }
}