DefaultWebSessionManager supports multiple sessions

Issue: #64
This commit is contained in:
Rossen Stoyanchev 2016-03-07 08:32:24 -05:00
parent 1eadee5655
commit b2648f84ad
5 changed files with 40 additions and 34 deletions

View File

@ -75,7 +75,7 @@ public class CookieWebSessionIdResolver implements WebSessionIdResolver {
@Override
public List<String> resolveSessionId(ServerWebExchange exchange) {
public List<String> resolveSessionIds(ServerWebExchange exchange) {
MultiValueMap<String, HttpCookie> cookieMap = exchange.getRequest().getCookies();
List<HttpCookie> cookies = cookieMap.get(getCookieName());
if (cookies == null) {

View File

@ -99,9 +99,9 @@ public class DefaultWebSessionManager implements WebSessionManager {
@Override
public Mono<WebSession> getSession(ServerWebExchange exchange) {
return Flux.fromIterable(getSessionIdResolver().resolveSessionId(exchange))
return Flux.fromIterable(getSessionIdResolver().resolveSessionIds(exchange))
.concatMap(this.sessionStore::retrieveSession)
.next()
.then(this.sessionStore::retrieveSession)
.then(session -> validateSession(exchange, session))
.otherwiseIfEmpty(createSession(exchange))
.map(session -> extendSession(exchange, session));
@ -147,7 +147,7 @@ public class DefaultWebSessionManager implements WebSessionManager {
// Force explicit start
session.start();
List<String> requestedIds = getSessionIdResolver().resolveSessionId(exchange);
List<String> requestedIds = getSessionIdResolver().resolveSessionIds(exchange);
if (requestedIds.isEmpty() || !session.getId().equals(requestedIds.get(0))) {
this.sessionIdResolver.setSessionId(exchange, session.getId());
}

View File

@ -35,7 +35,7 @@ public interface WebSessionIdResolver {
* @param exchange the current exchange
* @return the session id's or an empty list
*/
List<String> resolveSessionId(ServerWebExchange exchange);
List<String> resolveSessionIds(ServerWebExchange exchange);
/**
* Send the given session id to the client or if the session id is "null"

View File

@ -20,6 +20,7 @@ import java.time.Clock;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@ -45,17 +46,15 @@ import static org.junit.Assert.assertSame;
*/
public class DefaultWebSessionManagerTests {
private DefaultWebSessionManager manager;
private final DefaultWebSessionManager manager = new DefaultWebSessionManager();
private TestWebSessionIdResolver idResolver;
private final TestWebSessionIdResolver idResolver = new TestWebSessionIdResolver();
private DefaultServerWebExchange exchange;
@Before
public void setUp() throws Exception {
this.idResolver = new TestWebSessionIdResolver();
this.manager = new DefaultWebSessionManager();
this.manager.setSessionIdResolver(this.idResolver);
MockServerHttpRequest request = new MockServerHttpRequest(HttpMethod.GET, new URI("/path"));
@ -65,66 +64,73 @@ public class DefaultWebSessionManagerTests {
@Test
public void getSessionPassive() throws Exception {
public void getSessionWithoutStarting() throws Exception {
this.idResolver.setIdsToResolve(Collections.emptyList());
WebSession session = this.manager.getSession(this.exchange).get();
assertNotNull(session);
assertFalse(session.isStarted());
assertFalse(session.isExpired());
session.save();
assertNull(this.idResolver.getId());
assertFalse(session.isStarted());
assertFalse(session.isExpired());
assertNull(this.idResolver.getSavedId());
assertNull(this.manager.getSessionStore().retrieveSession(session.getId()).get());
}
@Test
public void getSessionForceCreate() throws Exception {
public void startSessionExplicitly() throws Exception {
this.idResolver.setIdsToResolve(Collections.emptyList());
WebSession session = this.manager.getSession(this.exchange).get();
session.start();
session.save();
String id = session.getId();
assertNotNull(this.idResolver.getId());
assertEquals(id, this.idResolver.getId());
assertNotNull(this.idResolver.getSavedId());
assertEquals(id, this.idResolver.getSavedId());
assertSame(session, this.manager.getSessionStore().retrieveSession(id).get());
}
@Test
public void getSessionAddAttribute() throws Exception {
public void startSessionImplicitly() throws Exception {
this.idResolver.setIdsToResolve(Collections.emptyList());
WebSession session = this.manager.getSession(this.exchange).get();
session.getAttributes().put("foo", "bar");
session.save();
assertNotNull(this.idResolver.getId());
assertNotNull(this.idResolver.getSavedId());
}
@Test
public void getSessionExisting() throws Exception {
public void existingSession() throws Exception {
DefaultWebSession existing = new DefaultWebSession("1", Clock.systemDefaultZone());
this.manager.getSessionStore().storeSession(existing);
this.idResolver.setIdsToResolve(Collections.singletonList("1"));
WebSession actual = this.manager.getSession(this.exchange).get();
assertSame(existing, actual);
}
@Test
public void getSessionExistingExpired() throws Exception {
public void existingSessionIsExpired() throws Exception {
Clock clock = Clock.systemDefaultZone();
DefaultWebSession existing = new DefaultWebSession("1", clock);
existing.start();
existing.setLastAccessTime(Instant.now(clock).minus(Duration.ofMinutes(31)));
this.manager.getSessionStore().storeSession(existing);
this.idResolver.setIdsToResolve(Collections.singletonList("1"));
WebSession actual = this.manager.getSession(this.exchange).get();
assertNotSame(existing, actual);
}
@Test
public void multipleSessions() throws Exception {
DefaultWebSession existing = new DefaultWebSession("3", Clock.systemDefaultZone());
this.manager.getSessionStore().storeSession(existing);
this.idResolver.setIdsToResolve(Arrays.asList("1", "2", "3"));
WebSession actual = this.manager.getSession(this.exchange).get();
assertSame(existing, actual);
}
private static class TestWebSessionIdResolver implements WebSessionIdResolver {
@ -137,12 +143,12 @@ public class DefaultWebSessionManagerTests {
this.idsToResolve = idsToResolve;
}
public String getId() {
public String getSavedId() {
return this.id;
}
@Override
public List<String> resolveSessionId(ServerWebExchange exchange) {
public List<String> resolveSessionIds(ServerWebExchange exchange) {
return this.idsToResolve;
}

View File

@ -43,8 +43,9 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
/**
* Integration tests for with a server-side session.
*
* @author Rossen Stoyanchev
*/
public class WebSessionIntegrationTests extends AbstractHttpHandlerIntegrationTests {
@ -95,6 +96,8 @@ public class WebSessionIntegrationTests extends AbstractHttpHandlerIntegrationTe
@Test
public void expiredSession() throws Exception {
// First request: no session yet, new session created
RequestEntity<Void> request = RequestEntity.get(createUri("/")).build();
ResponseEntity<Void> response = this.restTemplate.exchange(request, Void.class);
@ -103,11 +106,11 @@ public class WebSessionIntegrationTests extends AbstractHttpHandlerIntegrationTe
assertNotNull(id);
assertEquals(1, this.handler.getCount());
// Set clock back 31 minutes
// Set (server-side) clock back 31 minutes
Clock clock = this.sessionManager.getClock();
this.sessionManager.setClock(Clock.offset(clock, Duration.ofMinutes(-31)));
// Access again to update lastAccessTime
// Second request: lastAccessTime updated (with offset clock)
request = RequestEntity.get(createUri("/")).header("Cookie", "SESSION=" + id).build();
response = this.restTemplate.exchange(request, Void.class);
@ -115,7 +118,7 @@ public class WebSessionIntegrationTests extends AbstractHttpHandlerIntegrationTe
assertNull(response.getHeaders().get("Set-Cookie"));
assertEquals(2, this.handler.getCount());
// Now it should be expired
// Third request: new session replaces expired session
request = RequestEntity.get(createUri("/")).header("Cookie", "SESSION=" + id).build();
response = this.restTemplate.exchange(request, Void.class);
@ -125,9 +128,6 @@ public class WebSessionIntegrationTests extends AbstractHttpHandlerIntegrationTe
assertEquals("Expected new session attribute", 1, this.handler.getCount());
}
// No client side HttpCookie support yet
private String extractSessionId(HttpHeaders headers) {
List<String> headerValues = headers.get("Set-Cookie");
assertNotNull(headerValues);