Merge pull request #7493 from robotmrv/gh-7492

Dispose default Scheduler
This commit is contained in:
Rob Winch 2019-09-30 14:40:28 -05:00
commit e0414e5cbe
2 changed files with 45 additions and 2 deletions

View File

@ -18,6 +18,7 @@ package org.springframework.security.authentication;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.DisposableBean;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import reactor.core.scheduler.Scheduler; import reactor.core.scheduler.Scheduler;
import reactor.core.scheduler.Schedulers; import reactor.core.scheduler.Schedulers;
@ -45,7 +46,7 @@ import org.springframework.util.Assert;
* @author Eddú Meléndez * @author Eddú Meléndez
* @since 5.2 * @since 5.2
*/ */
public abstract class AbstractUserDetailsReactiveAuthenticationManager implements ReactiveAuthenticationManager { public abstract class AbstractUserDetailsReactiveAuthenticationManager implements ReactiveAuthenticationManager, DisposableBean {
protected final Log logger = LogFactory.getLog(getClass()); protected final Log logger = LogFactory.getLog(getClass());
@ -55,7 +56,8 @@ public abstract class AbstractUserDetailsReactiveAuthenticationManager implement
private ReactiveUserDetailsPasswordService userDetailsPasswordService; private ReactiveUserDetailsPasswordService userDetailsPasswordService;
private Scheduler scheduler = Schedulers.newParallel("password-encoder"); Scheduler scheduler = Schedulers.newParallel("password-encoder");
private boolean defaultScheduler = true;
private UserDetailsChecker preAuthenticationChecks = user -> { private UserDetailsChecker preAuthenticationChecks = user -> {
if (!user.isAccountNonLocked()) { if (!user.isAccountNonLocked()) {
@ -138,6 +140,10 @@ public abstract class AbstractUserDetailsReactiveAuthenticationManager implement
*/ */
public void setScheduler(Scheduler scheduler) { public void setScheduler(Scheduler scheduler) {
Assert.notNull(scheduler, "scheduler cannot be null"); Assert.notNull(scheduler, "scheduler cannot be null");
if (this.defaultScheduler) {
this.defaultScheduler = false;
this.scheduler.dispose();
}
this.scheduler = scheduler; this.scheduler = scheduler;
} }
@ -171,4 +177,10 @@ public abstract class AbstractUserDetailsReactiveAuthenticationManager implement
*/ */
protected abstract Mono<UserDetails> retrieveUser(String username); protected abstract Mono<UserDetails> retrieveUser(String username);
@Override
public void destroy() {
if (this.defaultScheduler) {
this.scheduler.dispose();
}
}
} }

View File

@ -33,6 +33,8 @@ import org.springframework.security.core.userdetails.ReactiveUserDetailsService;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import reactor.core.scheduler.Scheduler;
import reactor.core.scheduler.Schedulers;
import reactor.test.StepVerifier; import reactor.test.StepVerifier;
/** /**
@ -136,4 +138,33 @@ public class ReactiveUserDetailsServiceAuthenticationManagerTests {
.expectError(BadCredentialsException.class) .expectError(BadCredentialsException.class)
.verify(); .verify();
} }
@Test
public void destroyWhenDefaultSchedulerThenShouldDispose() {
assertThat(manager.scheduler.isDisposed()).isFalse();
manager.destroy();
assertThat(manager.scheduler.isDisposed())
.as("default Scheduler should be disposed")
.isTrue();
}
@Test
public void destroyWhenCustomSchedulerThenShouldNotDispose() {
manager.setScheduler(Schedulers.parallel());
manager.destroy();
assertThat(manager.scheduler.isDisposed())
.as("custom Scheduler should not be disposed")
.isFalse();
}
@Test
public void setSchedulerWhenSetCustomSchedulerThenDisposeDefault() {
Scheduler defaultScheduler = manager.scheduler;
assertThat(defaultScheduler.isDisposed()).isFalse();
manager.setScheduler(Schedulers.parallel());
assertThat(defaultScheduler.isDisposed())
.as("default Scheduler should be disposed")
.isTrue();
}
} }