parent
ddb38eefee
commit
70a3dbff24
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2018 the original author or authors.
|
* Copyright 2002-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -29,6 +29,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
import reactor.core.scheduler.Schedulers;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.IdGenerator;
|
import org.springframework.util.IdGenerator;
|
||||||
|
@ -111,9 +112,14 @@ public class InMemoryWebSessionStore implements WebSessionStore {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<WebSession> createWebSession() {
|
public Mono<WebSession> createWebSession() {
|
||||||
|
|
||||||
|
// Opportunity to clean expired sessions
|
||||||
Instant now = this.clock.instant();
|
Instant now = this.clock.instant();
|
||||||
this.expiredSessionChecker.checkIfNecessary(now);
|
this.expiredSessionChecker.checkIfNecessary(now);
|
||||||
return Mono.fromSupplier(() -> new InMemoryWebSession(now));
|
|
||||||
|
return Mono.fromSupplier(() -> new InMemoryWebSession(now))
|
||||||
|
.subscribeOn(Schedulers.boundedElastic())
|
||||||
|
.cast(WebSession.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -22,7 +22,10 @@ import java.time.Instant;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.IntStream;
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Disabled;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
import reactor.core.scheduler.Schedulers;
|
||||||
|
|
||||||
import org.springframework.beans.DirectFieldAccessor;
|
import org.springframework.beans.DirectFieldAccessor;
|
||||||
import org.springframework.web.server.WebSession;
|
import org.springframework.web.server.WebSession;
|
||||||
|
@ -56,6 +59,14 @@ public class InMemoryWebSessionStoreTests {
|
||||||
assertThat(session.isStarted()).isTrue();
|
assertThat(session.isStarted()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Disabled // TODO: remove if/when Blockhound is enabled
|
||||||
|
@Test // gh-24027
|
||||||
|
public void createSessionDoesNotBlock() {
|
||||||
|
Mono.defer(() -> this.store.createWebSession())
|
||||||
|
.subscribeOn(Schedulers.parallel())
|
||||||
|
.block();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void retrieveExpiredSession() {
|
public void retrieveExpiredSession() {
|
||||||
WebSession session = this.store.createWebSession().block();
|
WebSession session = this.store.createWebSession().block();
|
||||||
|
|
|
@ -64,6 +64,9 @@ import static org.mockito.Mockito.mock;
|
||||||
*/
|
*/
|
||||||
public class ModelInitializerTests {
|
public class ModelInitializerTests {
|
||||||
|
|
||||||
|
private static final Duration TIMEOUT = Duration.ofMillis(5000);
|
||||||
|
|
||||||
|
|
||||||
private ModelInitializer modelInitializer;
|
private ModelInitializer modelInitializer;
|
||||||
|
|
||||||
private final ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/path"));
|
private final ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/path"));
|
||||||
|
@ -93,7 +96,7 @@ public class ModelInitializerTests {
|
||||||
|
|
||||||
Method method = ResolvableMethod.on(TestController.class).annotPresent(GetMapping.class).resolveMethod();
|
Method method = ResolvableMethod.on(TestController.class).annotPresent(GetMapping.class).resolveMethod();
|
||||||
HandlerMethod handlerMethod = new HandlerMethod(controller, method);
|
HandlerMethod handlerMethod = new HandlerMethod(controller, method);
|
||||||
this.modelInitializer.initModel(handlerMethod, context, this.exchange).block(Duration.ofMillis(5000));
|
this.modelInitializer.initModel(handlerMethod, context, this.exchange).block(TIMEOUT);
|
||||||
|
|
||||||
WebExchangeDataBinder binder = context.createDataBinder(this.exchange, "name");
|
WebExchangeDataBinder binder = context.createDataBinder(this.exchange, "name");
|
||||||
assertThat(binder.getValidators()).isEqualTo(Collections.singletonList(validator));
|
assertThat(binder.getValidators()).isEqualTo(Collections.singletonList(validator));
|
||||||
|
@ -107,7 +110,7 @@ public class ModelInitializerTests {
|
||||||
|
|
||||||
Method method = ResolvableMethod.on(TestController.class).annotPresent(GetMapping.class).resolveMethod();
|
Method method = ResolvableMethod.on(TestController.class).annotPresent(GetMapping.class).resolveMethod();
|
||||||
HandlerMethod handlerMethod = new HandlerMethod(controller, method);
|
HandlerMethod handlerMethod = new HandlerMethod(controller, method);
|
||||||
this.modelInitializer.initModel(handlerMethod, context, this.exchange).block(Duration.ofMillis(5000));
|
this.modelInitializer.initModel(handlerMethod, context, this.exchange).block(TIMEOUT);
|
||||||
|
|
||||||
Map<String, Object> model = context.getModel().asMap();
|
Map<String, Object> model = context.getModel().asMap();
|
||||||
assertThat(model.size()).isEqualTo(5);
|
assertThat(model.size()).isEqualTo(5);
|
||||||
|
@ -116,7 +119,7 @@ public class ModelInitializerTests {
|
||||||
assertThat(((TestBean) value).getName()).isEqualTo("Bean");
|
assertThat(((TestBean) value).getName()).isEqualTo("Bean");
|
||||||
|
|
||||||
value = model.get("monoBean");
|
value = model.get("monoBean");
|
||||||
assertThat(((Mono<TestBean>) value).block(Duration.ofMillis(5000)).getName()).isEqualTo("Mono Bean");
|
assertThat(((Mono<TestBean>) value).block(TIMEOUT).getName()).isEqualTo("Mono Bean");
|
||||||
|
|
||||||
value = model.get("singleBean");
|
value = model.get("singleBean");
|
||||||
assertThat(((Single<TestBean>) value).toBlocking().value().getName()).isEqualTo("Single Bean");
|
assertThat(((Single<TestBean>) value).toBlocking().value().getName()).isEqualTo("Single Bean");
|
||||||
|
@ -135,7 +138,7 @@ public class ModelInitializerTests {
|
||||||
|
|
||||||
Method method = ResolvableMethod.on(TestController.class).annotPresent(GetMapping.class).resolveMethod();
|
Method method = ResolvableMethod.on(TestController.class).annotPresent(GetMapping.class).resolveMethod();
|
||||||
HandlerMethod handlerMethod = new HandlerMethod(controller, method);
|
HandlerMethod handlerMethod = new HandlerMethod(controller, method);
|
||||||
this.modelInitializer.initModel(handlerMethod, context, this.exchange).block(Duration.ofMillis(5000));
|
this.modelInitializer.initModel(handlerMethod, context, this.exchange).block(TIMEOUT);
|
||||||
|
|
||||||
WebSession session = this.exchange.getSession().block(Duration.ZERO);
|
WebSession session = this.exchange.getSession().block(Duration.ZERO);
|
||||||
assertThat(session).isNotNull();
|
assertThat(session).isNotNull();
|
||||||
|
@ -148,7 +151,7 @@ public class ModelInitializerTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void retrieveModelAttributeFromSession() {
|
public void retrieveModelAttributeFromSession() {
|
||||||
WebSession session = this.exchange.getSession().block(Duration.ZERO);
|
WebSession session = this.exchange.getSession().block(TIMEOUT);
|
||||||
assertThat(session).isNotNull();
|
assertThat(session).isNotNull();
|
||||||
|
|
||||||
TestBean testBean = new TestBean("Session Bean");
|
TestBean testBean = new TestBean("Session Bean");
|
||||||
|
@ -159,7 +162,7 @@ public class ModelInitializerTests {
|
||||||
|
|
||||||
Method method = ResolvableMethod.on(TestController.class).annotPresent(GetMapping.class).resolveMethod();
|
Method method = ResolvableMethod.on(TestController.class).annotPresent(GetMapping.class).resolveMethod();
|
||||||
HandlerMethod handlerMethod = new HandlerMethod(controller, method);
|
HandlerMethod handlerMethod = new HandlerMethod(controller, method);
|
||||||
this.modelInitializer.initModel(handlerMethod, context, this.exchange).block(Duration.ofMillis(5000));
|
this.modelInitializer.initModel(handlerMethod, context, this.exchange).block(TIMEOUT);
|
||||||
|
|
||||||
context.saveModel();
|
context.saveModel();
|
||||||
assertThat(session.getAttributes().size()).isEqualTo(1);
|
assertThat(session.getAttributes().size()).isEqualTo(1);
|
||||||
|
@ -174,13 +177,13 @@ public class ModelInitializerTests {
|
||||||
Method method = ResolvableMethod.on(TestController.class).annotPresent(PostMapping.class).resolveMethod();
|
Method method = ResolvableMethod.on(TestController.class).annotPresent(PostMapping.class).resolveMethod();
|
||||||
HandlerMethod handlerMethod = new HandlerMethod(controller, method);
|
HandlerMethod handlerMethod = new HandlerMethod(controller, method);
|
||||||
assertThatIllegalArgumentException().isThrownBy(() ->
|
assertThatIllegalArgumentException().isThrownBy(() ->
|
||||||
this.modelInitializer.initModel(handlerMethod, context, this.exchange).block(Duration.ofMillis(5000)))
|
this.modelInitializer.initModel(handlerMethod, context, this.exchange).block(TIMEOUT))
|
||||||
.withMessage("Required attribute 'missing-bean' is missing.");
|
.withMessage("Required attribute 'missing-bean' is missing.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void clearModelAttributeFromSession() {
|
public void clearModelAttributeFromSession() {
|
||||||
WebSession session = this.exchange.getSession().block(Duration.ZERO);
|
WebSession session = this.exchange.getSession().block(TIMEOUT);
|
||||||
assertThat(session).isNotNull();
|
assertThat(session).isNotNull();
|
||||||
|
|
||||||
TestBean testBean = new TestBean("Session Bean");
|
TestBean testBean = new TestBean("Session Bean");
|
||||||
|
@ -191,7 +194,7 @@ public class ModelInitializerTests {
|
||||||
|
|
||||||
Method method = ResolvableMethod.on(TestController.class).annotPresent(GetMapping.class).resolveMethod();
|
Method method = ResolvableMethod.on(TestController.class).annotPresent(GetMapping.class).resolveMethod();
|
||||||
HandlerMethod handlerMethod = new HandlerMethod(controller, method);
|
HandlerMethod handlerMethod = new HandlerMethod(controller, method);
|
||||||
this.modelInitializer.initModel(handlerMethod, context, this.exchange).block(Duration.ofMillis(5000));
|
this.modelInitializer.initModel(handlerMethod, context, this.exchange).block(TIMEOUT);
|
||||||
|
|
||||||
context.getSessionStatus().setComplete();
|
context.getSessionStatus().setComplete();
|
||||||
context.saveModel();
|
context.saveModel();
|
||||||
|
|
Loading…
Reference in New Issue