Extract RedisSessionMapper

See: #1408
This commit is contained in:
Vedran Pavic
2019-05-01 19:57:57 +02:00
parent 3d03c02924
commit 54859070f3
6 changed files with 290 additions and 162 deletions

View File

@@ -21,7 +21,6 @@ import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Mono;
@@ -47,29 +46,6 @@ public class ReactiveRedisOperationsSessionRepository implements
*/
public static final String DEFAULT_NAMESPACE = "spring:session";
/**
* The key in the Hash representing {@link Session#getCreationTime()}.
*/
static final String CREATION_TIME_KEY = "creationTime";
/**
* The key in the Hash representing {@link Session#getLastAccessedTime()}.
*/
static final String LAST_ACCESSED_TIME_KEY = "lastAccessedTime";
/**
* The key in the Hash representing {@link Session#getMaxInactiveInterval()} .
*/
static final String MAX_INACTIVE_INTERVAL_KEY = "maxInactiveInterval";
/**
* The prefix of the key used for session attributes. The suffix is the name of
* the session attribute. For example, if the session contained an attribute named
* attributeName, then there would be an entry in the hash named
* sessionAttr:attributeName that mapped to its value.
*/
static final String ATTRIBUTE_PREFIX = "sessionAttr:";
private final ReactiveRedisOperations<String, Object> sessionRedisOperations;
/**
@@ -162,7 +138,7 @@ public class ReactiveRedisOperationsSessionRepository implements
return this.sessionRedisOperations.opsForHash().entries(sessionKey)
.collectMap((e) -> e.getKey().toString(), Map.Entry::getValue)
.filter((map) -> !map.isEmpty())
.map(new SessionMapper(id))
.map(new RedisSessionMapper(id))
.filter((session) -> !session.isExpired())
.map(RedisSession::new)
.switchIfEmpty(Mono.defer(() -> deleteById(id).then(Mono.empty())));
@@ -177,7 +153,7 @@ public class ReactiveRedisOperationsSessionRepository implements
}
private static String getAttributeKey(String attributeName) {
return ATTRIBUTE_PREFIX + attributeName;
return RedisSessionMapper.ATTRIBUTE_PREFIX + attributeName;
}
private String getSessionKey(String sessionId) {
@@ -206,10 +182,12 @@ public class ReactiveRedisOperationsSessionRepository implements
*/
RedisSession() {
this(new MapSession());
this.delta.put(CREATION_TIME_KEY, getCreationTime().toEpochMilli());
this.delta.put(MAX_INACTIVE_INTERVAL_KEY,
this.delta.put(RedisSessionMapper.CREATION_TIME_KEY,
getCreationTime().toEpochMilli());
this.delta.put(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY,
(int) getMaxInactiveInterval().getSeconds());
this.delta.put(LAST_ACCESSED_TIME_KEY, getLastAccessedTime().toEpochMilli());
this.delta.put(RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
getLastAccessedTime().toEpochMilli());
this.isNew = true;
this.flushImmediateIfNecessary();
}
@@ -266,7 +244,8 @@ public class ReactiveRedisOperationsSessionRepository implements
@Override
public void setLastAccessedTime(Instant lastAccessedTime) {
this.cached.setLastAccessedTime(lastAccessedTime);
putAndFlush(LAST_ACCESSED_TIME_KEY, getLastAccessedTime().toEpochMilli());
putAndFlush(RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
getLastAccessedTime().toEpochMilli());
}
@Override
@@ -277,7 +256,7 @@ public class ReactiveRedisOperationsSessionRepository implements
@Override
public void setMaxInactiveInterval(Duration interval) {
this.cached.setMaxInactiveInterval(interval);
putAndFlush(MAX_INACTIVE_INTERVAL_KEY,
putAndFlush(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY,
(int) getMaxInactiveInterval().getSeconds());
}
@@ -354,36 +333,4 @@ public class ReactiveRedisOperationsSessionRepository implements
}
private static final class SessionMapper
implements Function<Map<String, Object>, MapSession> {
private final String id;
private SessionMapper(String id) {
this.id = id;
}
@Override
public MapSession apply(Map<String, Object> map) {
MapSession session = new MapSession(this.id);
session.setCreationTime(
Instant.ofEpochMilli((long) map.get(CREATION_TIME_KEY)));
session.setLastAccessedTime(
Instant.ofEpochMilli((long) map.get(LAST_ACCESSED_TIME_KEY)));
session.setMaxInactiveInterval(
Duration.ofSeconds((int) map.get(MAX_INACTIVE_INTERVAL_KEY)));
map.forEach((name, value) -> {
if (name.startsWith(ATTRIBUTE_PREFIX)) {
session.setAttribute(name.substring(ATTRIBUTE_PREFIX.length()),
value);
}
});
return session;
}
}
}

View File

@@ -264,33 +264,6 @@ public class RedisOperationsSessionRepository implements
*/
public static final String DEFAULT_NAMESPACE = "spring:session";
/**
* The key in the Hash representing
* {@link org.springframework.session.Session#getCreationTime()}.
*/
static final String CREATION_TIME_ATTR = "creationTime";
/**
* The key in the Hash representing
* {@link org.springframework.session.Session#getMaxInactiveInterval()}
* .
*/
static final String MAX_INACTIVE_ATTR = "maxInactiveInterval";
/**
* The key in the Hash representing
* {@link org.springframework.session.Session#getLastAccessedTime()}.
*/
static final String LAST_ACCESSED_ATTR = "lastAccessedTime";
/**
* The prefix of the key used for session attributes. The suffix is the name of
* the session attribute. For example, if the session contained an attribute named
* attributeName, then there would be an entry in the hash named
* sessionAttr:attributeName that mapped to its value.
*/
static final String SESSION_ATTR_PREFIX = "sessionAttr:";
private int database = RedisOperationsSessionRepository.DEFAULT_DATABASE;
/**
@@ -480,17 +453,18 @@ public class RedisOperationsSessionRepository implements
MapSession loaded = new MapSession(id);
for (Map.Entry<Object, Object> entry : entries.entrySet()) {
String key = (String) entry.getKey();
if (CREATION_TIME_ATTR.equals(key)) {
if (RedisSessionMapper.CREATION_TIME_KEY.equals(key)) {
loaded.setCreationTime(Instant.ofEpochMilli((long) entry.getValue()));
}
else if (MAX_INACTIVE_ATTR.equals(key)) {
else if (RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY.equals(key)) {
loaded.setMaxInactiveInterval(Duration.ofSeconds((int) entry.getValue()));
}
else if (LAST_ACCESSED_ATTR.equals(key)) {
else if (RedisSessionMapper.LAST_ACCESSED_TIME_KEY.equals(key)) {
loaded.setLastAccessedTime(Instant.ofEpochMilli((long) entry.getValue()));
}
else if (key.startsWith(SESSION_ATTR_PREFIX)) {
loaded.setAttribute(key.substring(SESSION_ATTR_PREFIX.length()),
else if (key.startsWith(RedisSessionMapper.ATTRIBUTE_PREFIX)) {
loaded.setAttribute(
key.substring(RedisSessionMapper.ATTRIBUTE_PREFIX.length()),
entry.getValue());
}
}
@@ -689,7 +663,7 @@ public class RedisOperationsSessionRepository implements
* @return the attribute key name
*/
static String getSessionAttrNameKey(String attributeName) {
return SESSION_ATTR_PREFIX + attributeName;
return RedisSessionMapper.ATTRIBUTE_PREFIX + attributeName;
}
/**
@@ -719,9 +693,12 @@ public class RedisOperationsSessionRepository implements
RedisSession(Duration maxInactiveInterval) {
this(new MapSession());
this.cached.setMaxInactiveInterval(maxInactiveInterval);
this.delta.put(CREATION_TIME_ATTR, getCreationTime().toEpochMilli());
this.delta.put(MAX_INACTIVE_ATTR, (int) getMaxInactiveInterval().getSeconds());
this.delta.put(LAST_ACCESSED_ATTR, getLastAccessedTime().toEpochMilli());
this.delta.put(RedisSessionMapper.CREATION_TIME_KEY,
getCreationTime().toEpochMilli());
this.delta.put(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY,
(int) getMaxInactiveInterval().getSeconds());
this.delta.put(RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
getLastAccessedTime().toEpochMilli());
this.isNew = true;
}
@@ -745,7 +722,8 @@ public class RedisOperationsSessionRepository implements
@Override
public void setLastAccessedTime(Instant lastAccessedTime) {
this.cached.setLastAccessedTime(lastAccessedTime);
this.putAndFlush(LAST_ACCESSED_ATTR, getLastAccessedTime().toEpochMilli());
this.putAndFlush(RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
getLastAccessedTime().toEpochMilli());
}
@Override
@@ -780,7 +758,8 @@ public class RedisOperationsSessionRepository implements
@Override
public void setMaxInactiveInterval(Duration interval) {
this.cached.setMaxInactiveInterval(interval);
this.putAndFlush(MAX_INACTIVE_ATTR, (int) getMaxInactiveInterval().getSeconds());
this.putAndFlush(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY,
(int) getMaxInactiveInterval().getSeconds());
}
@Override

View File

@@ -0,0 +1,97 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.session.data.redis;
import java.time.Duration;
import java.time.Instant;
import java.util.Map;
import java.util.function.Function;
import org.springframework.session.MapSession;
import org.springframework.session.Session;
import org.springframework.util.Assert;
/**
* A {@link Function} that converts a {@link Map} representing Redis hash to a
* {@link MapSession}.
*
* @author Vedran Pavic
* @since 2.2.0
*/
final class RedisSessionMapper implements Function<Map<String, Object>, MapSession> {
/**
* The key in the hash representing {@link Session#getCreationTime()}.
*/
static final String CREATION_TIME_KEY = "creationTime";
/**
* The key in the hash representing {@link Session#getLastAccessedTime()}.
*/
static final String LAST_ACCESSED_TIME_KEY = "lastAccessedTime";
/**
* The key in the hash representing {@link Session#getMaxInactiveInterval()}.
*/
static final String MAX_INACTIVE_INTERVAL_KEY = "maxInactiveInterval";
/**
* The prefix of the key in the hash used for session attributes. For example, if the
* session contained an attribute named {@code attributeName}, then there would be an
* entry in the hash named {@code sessionAttr:attributeName} that mapped to its value.
*/
static final String ATTRIBUTE_PREFIX = "sessionAttr:";
private final String sessionId;
RedisSessionMapper(String sessionId) {
Assert.hasText(sessionId, "sessionId must not be empty");
this.sessionId = sessionId;
}
@Override
public MapSession apply(Map<String, Object> map) {
Assert.notEmpty(map, "map must not be empty");
MapSession session = new MapSession(this.sessionId);
Long creationTime = (Long) map.get(CREATION_TIME_KEY);
if (creationTime == null) {
handleMissingKey(CREATION_TIME_KEY);
}
session.setCreationTime(Instant.ofEpochMilli(creationTime));
Long lastAccessedTime = (Long) map.get(LAST_ACCESSED_TIME_KEY);
if (lastAccessedTime == null) {
handleMissingKey(LAST_ACCESSED_TIME_KEY);
}
session.setLastAccessedTime(Instant.ofEpochMilli(lastAccessedTime));
Integer maxInactiveInterval = (Integer) map.get(MAX_INACTIVE_INTERVAL_KEY);
if (maxInactiveInterval == null) {
handleMissingKey(MAX_INACTIVE_INTERVAL_KEY);
}
session.setMaxInactiveInterval(Duration.ofSeconds(maxInactiveInterval));
map.forEach((name, value) -> {
if (name.startsWith(ATTRIBUTE_PREFIX)) {
session.setAttribute(name.substring(ATTRIBUTE_PREFIX.length()), value);
}
});
return session;
}
private static void handleMissingKey(String key) {
throw new IllegalStateException(key + " key must not be null");
}
}

View File

@@ -167,15 +167,12 @@ public class ReactiveRedisOperationsSessionRepositoryTests {
Map<String, Object> delta = this.delta.getAllValues().get(0);
assertThat(delta.size()).isEqualTo(3);
assertThat(delta.get(ReactiveRedisOperationsSessionRepository.CREATION_TIME_KEY))
assertThat(delta.get(RedisSessionMapper.CREATION_TIME_KEY))
.isEqualTo(newSession.getCreationTime().toEpochMilli());
assertThat(delta
.get(ReactiveRedisOperationsSessionRepository.MAX_INACTIVE_INTERVAL_KEY))
.isEqualTo(
(int) newSession.getMaxInactiveInterval().getSeconds());
assertThat(delta
.get(ReactiveRedisOperationsSessionRepository.LAST_ACCESSED_TIME_KEY))
.isEqualTo(newSession.getLastAccessedTime().toEpochMilli());
assertThat(delta.get(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY))
.isEqualTo((int) newSession.getMaxInactiveInterval().getSeconds());
assertThat(delta.get(RedisSessionMapper.LAST_ACCESSED_TIME_KEY))
.isEqualTo(newSession.getLastAccessedTime().toEpochMilli());
}
@Test
@@ -214,7 +211,7 @@ public class ReactiveRedisOperationsSessionRepositoryTests {
verifyZeroInteractions(this.hashOperations);
assertThat(this.delta.getAllValues().get(0))
.isEqualTo(map(RedisOperationsSessionRepository.LAST_ACCESSED_ATTR,
.isEqualTo(map(RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
session.getLastAccessedTime().toEpochMilli()));
}
@@ -316,16 +313,14 @@ public class ReactiveRedisOperationsSessionRepositoryTests {
expected.setLastAccessedTime(Instant.now().minusSeconds(60));
expected.setAttribute(attribute1, "test");
expected.setAttribute(attribute2, null);
Map map = map(
ReactiveRedisOperationsSessionRepository.ATTRIBUTE_PREFIX + attribute1,
Map map = map(RedisSessionMapper.ATTRIBUTE_PREFIX + attribute1,
expected.getAttribute(attribute1),
ReactiveRedisOperationsSessionRepository.ATTRIBUTE_PREFIX + attribute2,
expected.getAttribute(attribute2),
ReactiveRedisOperationsSessionRepository.CREATION_TIME_KEY,
RedisSessionMapper.ATTRIBUTE_PREFIX + attribute2,
expected.getAttribute(attribute2), RedisSessionMapper.CREATION_TIME_KEY,
expected.getCreationTime().toEpochMilli(),
ReactiveRedisOperationsSessionRepository.MAX_INACTIVE_INTERVAL_KEY,
RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY,
(int) expected.getMaxInactiveInterval().getSeconds(),
ReactiveRedisOperationsSessionRepository.LAST_ACCESSED_TIME_KEY,
RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
expected.getLastAccessedTime().toEpochMilli());
given(this.hashOperations.entries(anyString()))
.willReturn(Flux.fromIterable(map.entrySet()));
@@ -360,9 +355,9 @@ public class ReactiveRedisOperationsSessionRepositoryTests {
@SuppressWarnings("unchecked")
public void getSessionExpired() {
given(this.redisOperations.opsForHash()).willReturn(this.hashOperations);
Map map = map(ReactiveRedisOperationsSessionRepository.CREATION_TIME_KEY, 0L,
ReactiveRedisOperationsSessionRepository.MAX_INACTIVE_INTERVAL_KEY, 1,
ReactiveRedisOperationsSessionRepository.LAST_ACCESSED_TIME_KEY,
Map map = map(RedisSessionMapper.CREATION_TIME_KEY, 0L,
RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY, 1,
RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
Instant.now().minus(5, ChronoUnit.MINUTES).toEpochMilli());
given(this.hashOperations.entries(anyString()))
.willReturn(Flux.fromIterable(map.entrySet()));

View File

@@ -190,14 +190,12 @@ public class RedisOperationsSessionRepositoryTests {
Map<String, Object> delta = getDelta();
assertThat(delta.size()).isEqualTo(3);
Object creationTime = delta
.get(RedisOperationsSessionRepository.CREATION_TIME_ATTR);
Object creationTime = delta.get(RedisSessionMapper.CREATION_TIME_KEY);
assertThat(creationTime).isEqualTo(session.getCreationTime().toEpochMilli());
assertThat(delta.get(RedisOperationsSessionRepository.MAX_INACTIVE_ATTR))
.isEqualTo((int) Duration
.ofSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS)
assertThat(delta.get(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY)).isEqualTo(
(int) Duration.ofSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS)
.getSeconds());
assertThat(delta.get(RedisOperationsSessionRepository.LAST_ACCESSED_ATTR))
assertThat(delta.get(RedisSessionMapper.LAST_ACCESSED_TIME_KEY))
.isEqualTo(session.getCreationTime().toEpochMilli());
}
@@ -283,9 +281,8 @@ public class RedisOperationsSessionRepositoryTests {
this.redisRepository.save(session);
assertThat(getDelta())
.isEqualTo(map(RedisOperationsSessionRepository.LAST_ACCESSED_ATTR,
session.getLastAccessedTime().toEpochMilli()));
assertThat(getDelta()).isEqualTo(map(RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
session.getLastAccessedTime().toEpochMilli()));
}
@Test
@@ -364,12 +361,11 @@ public class RedisOperationsSessionRepositoryTests {
given(this.redisOperations.boundSetOps(anyString()))
.willReturn(this.boundSetOperations);
Map map = map(RedisOperationsSessionRepository.getSessionAttrNameKey(attrName),
expected.getAttribute(attrName),
RedisOperationsSessionRepository.CREATION_TIME_ATTR,
expected.getAttribute(attrName), RedisSessionMapper.CREATION_TIME_KEY,
expected.getCreationTime().toEpochMilli(),
RedisOperationsSessionRepository.MAX_INACTIVE_ATTR,
RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY,
(int) expected.getMaxInactiveInterval().getSeconds(),
RedisOperationsSessionRepository.LAST_ACCESSED_ATTR,
RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
expected.getLastAccessedTime().toEpochMilli());
given(this.boundHashOperations.entries()).willReturn(map);
given(this.redisOperations.boundSetOps(anyString()))
@@ -378,7 +374,7 @@ public class RedisOperationsSessionRepositoryTests {
String id = expected.getId();
this.redisRepository.deleteById(id);
assertThat(getDelta().get(RedisOperationsSessionRepository.MAX_INACTIVE_ATTR))
assertThat(getDelta().get(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY))
.isEqualTo(0);
verify(this.redisOperations, atLeastOnce()).delete(getKey("expires:" + id));
verify(this.redisOperations, never()).boundValueOps(getKey("expires:" + id));
@@ -418,12 +414,11 @@ public class RedisOperationsSessionRepositoryTests {
Map map = map(RedisOperationsSessionRepository.getSessionAttrNameKey(attribute1),
expected.getAttribute(attribute1),
RedisOperationsSessionRepository.getSessionAttrNameKey(attribute2),
expected.getAttribute(attribute2),
RedisOperationsSessionRepository.CREATION_TIME_ATTR,
expected.getAttribute(attribute2), RedisSessionMapper.CREATION_TIME_KEY,
expected.getCreationTime().toEpochMilli(),
RedisOperationsSessionRepository.MAX_INACTIVE_ATTR,
RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY,
(int) expected.getMaxInactiveInterval().getSeconds(),
RedisOperationsSessionRepository.LAST_ACCESSED_ATTR,
RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
expected.getLastAccessedTime().toEpochMilli());
given(this.boundHashOperations.entries()).willReturn(map);
@@ -447,8 +442,8 @@ public class RedisOperationsSessionRepositoryTests {
String expiredId = "expired-id";
given(this.redisOperations.boundHashOps(getKey(expiredId)))
.willReturn(this.boundHashOperations);
Map map = map(RedisOperationsSessionRepository.MAX_INACTIVE_ATTR, 1,
RedisOperationsSessionRepository.LAST_ACCESSED_ATTR,
Map map = map(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY, 1,
RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
Instant.now().minus(5, ChronoUnit.MINUTES).toEpochMilli());
given(this.boundHashOperations.entries()).willReturn(map);
@@ -464,8 +459,8 @@ public class RedisOperationsSessionRepositoryTests {
.willReturn(Collections.singleton(expiredId));
given(this.redisOperations.boundHashOps(getKey(expiredId)))
.willReturn(this.boundHashOperations);
Map map = map(RedisOperationsSessionRepository.MAX_INACTIVE_ATTR, 1,
RedisOperationsSessionRepository.LAST_ACCESSED_ATTR,
Map map = map(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY, 1,
RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
Instant.now().minus(5, ChronoUnit.MINUTES).toEpochMilli());
given(this.boundHashOperations.entries()).willReturn(map);
@@ -486,11 +481,9 @@ public class RedisOperationsSessionRepositoryTests {
.willReturn(Collections.singleton(sessionId));
given(this.redisOperations.boundHashOps(getKey(sessionId)))
.willReturn(this.boundHashOperations);
Map map = map(RedisOperationsSessionRepository.CREATION_TIME_ATTR,
createdTime.toEpochMilli(),
RedisOperationsSessionRepository.MAX_INACTIVE_ATTR,
(int) maxInactive.getSeconds(),
RedisOperationsSessionRepository.LAST_ACCESSED_ATTR,
Map map = map(RedisSessionMapper.CREATION_TIME_KEY, createdTime.toEpochMilli(),
RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY,
(int) maxInactive.getSeconds(), RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
lastAccessed.toEpochMilli());
given(this.boundHashOperations.entries()).willReturn(map);
@@ -572,8 +565,8 @@ public class RedisOperationsSessionRepositoryTests {
String deletedId = "deleted-id";
given(this.redisOperations.boundHashOps(getKey(deletedId)))
.willReturn(this.boundHashOperations);
Map map = map(RedisOperationsSessionRepository.MAX_INACTIVE_ATTR, 0,
RedisOperationsSessionRepository.LAST_ACCESSED_ATTR,
Map map = map(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY, 0,
RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(5));
given(this.boundHashOperations.entries()).willReturn(map);
@@ -625,8 +618,8 @@ public class RedisOperationsSessionRepositoryTests {
String expiredId = "expired-id";
given(this.redisOperations.boundHashOps(getKey(expiredId)))
.willReturn(this.boundHashOperations);
Map map = map(RedisOperationsSessionRepository.MAX_INACTIVE_ATTR, 1,
RedisOperationsSessionRepository.LAST_ACCESSED_ATTR,
Map map = map(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY, 1,
RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(5));
given(this.boundHashOperations.entries()).willReturn(map);
@@ -753,14 +746,12 @@ public class RedisOperationsSessionRepositoryTests {
Map<String, Object> delta = getDelta();
assertThat(delta.size()).isEqualTo(3);
Object creationTime = delta
.get(RedisOperationsSessionRepository.CREATION_TIME_ATTR);
Object creationTime = delta.get(RedisSessionMapper.CREATION_TIME_KEY);
assertThat(creationTime).isEqualTo(session.getCreationTime().toEpochMilli());
assertThat(delta.get(RedisOperationsSessionRepository.MAX_INACTIVE_ATTR))
.isEqualTo((int) Duration
.ofSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS)
assertThat(delta.get(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY)).isEqualTo(
(int) Duration.ofSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS)
.getSeconds());
assertThat(delta.get(RedisOperationsSessionRepository.LAST_ACCESSED_ATTR))
assertThat(delta.get(RedisSessionMapper.LAST_ACCESSED_TIME_KEY))
.isEqualTo(session.getCreationTime().toEpochMilli());
}
@@ -777,8 +768,7 @@ public class RedisOperationsSessionRepositoryTests {
this.redisRepository.createSession();
Map<String, Object> delta = getDelta();
assertThat(delta.size()).isEqualTo(3);
assertThat(delta.get(RedisOperationsSessionRepository.MAX_INACTIVE_ATTR))
.isEqualTo(60);
assertThat(delta.get(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY)).isEqualTo(60);
}
@Test
@@ -858,9 +848,8 @@ public class RedisOperationsSessionRepositoryTests {
Map<String, Object> delta = getDelta(2);
assertThat(delta.size()).isEqualTo(1);
assertThat(delta)
.isEqualTo(map(RedisOperationsSessionRepository.LAST_ACCESSED_ATTR,
session.getLastAccessedTime().toEpochMilli()));
assertThat(delta).isEqualTo(map(RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
session.getLastAccessedTime().toEpochMilli()));
}
@Test

View File

@@ -0,0 +1,121 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.session.data.redis;
import java.time.Duration;
import java.time.Instant;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.session.MapSession;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
/**
* Tests for {@link RedisSessionMapper}.
*
* @author Vedran Pavic
*/
class RedisSessionMapperTests {
private RedisSessionMapper mapper;
@BeforeEach
void setUp() {
this.mapper = new RedisSessionMapper("id");
}
@Test
void constructor_NullId_ShouldThrowException() {
assertThatIllegalArgumentException()
.isThrownBy(() -> new RedisSessionMapper(null))
.withMessage("sessionId must not be empty");
}
@Test
void constructor_EmptyId_ShouldThrowException() {
assertThatIllegalArgumentException().isThrownBy(() -> new RedisSessionMapper(" "))
.withMessage("sessionId must not be empty");
}
@Test
void apply_NullMap_ShouldThrowException() {
assertThatIllegalArgumentException().isThrownBy(() -> this.mapper.apply(null))
.withMessage("map must not be empty");
}
@Test
void apply_EmptyMap_ShouldThrowException() {
assertThatIllegalArgumentException()
.isThrownBy(() -> this.mapper.apply(Collections.emptyMap()))
.withMessage("map must not be empty");
}
@Test
void apply_MapWithoutCreationTime_ShouldThrowException() {
Map<String, Object> sessionMap = new HashMap<>();
sessionMap.put(RedisSessionMapper.LAST_ACCESSED_TIME_KEY, 0L);
sessionMap.put(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY, 1800);
assertThatIllegalStateException().isThrownBy(() -> this.mapper.apply(sessionMap))
.withMessage(
RedisSessionMapper.CREATION_TIME_KEY + " key must not be null");
}
@Test
void apply_MapWithoutLastAccessedTime_ShouldThrowException() {
Map<String, Object> sessionMap = new HashMap<>();
sessionMap.put(RedisSessionMapper.CREATION_TIME_KEY, 0L);
sessionMap.put(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY, 1800);
assertThatIllegalStateException().isThrownBy(() -> this.mapper.apply(sessionMap))
.withMessage(RedisSessionMapper.LAST_ACCESSED_TIME_KEY
+ " key must not be null");
}
@Test
void apply_MapWithoutMaxInactiveInterval_ShouldThrowException() {
Map<String, Object> sessionMap = new HashMap<>();
sessionMap.put(RedisSessionMapper.CREATION_TIME_KEY, 0L);
sessionMap.put(RedisSessionMapper.LAST_ACCESSED_TIME_KEY, 0L);
assertThatIllegalStateException().isThrownBy(() -> this.mapper.apply(sessionMap))
.withMessage(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY
+ " key must not be null");
}
@Test
void apply_ValidMap_ShouldReturnSession() {
Map<String, Object> sessionMap = new HashMap<>();
sessionMap.put(RedisSessionMapper.CREATION_TIME_KEY, 0L);
sessionMap.put(RedisSessionMapper.LAST_ACCESSED_TIME_KEY, 0L);
sessionMap.put(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY, 1800);
sessionMap.put(RedisSessionMapper.ATTRIBUTE_PREFIX + "existing", "value");
sessionMap.put(RedisSessionMapper.ATTRIBUTE_PREFIX + "missing", null);
MapSession session = this.mapper.apply(sessionMap);
assertThat(session.getId()).isEqualTo("id");
assertThat(session.getCreationTime()).isEqualTo(Instant.ofEpochMilli(0));
assertThat(session.getLastAccessedTime()).isEqualTo(Instant.ofEpochMilli(0));
assertThat(session.getMaxInactiveInterval()).isEqualTo(Duration.ofMinutes(30));
assertThat(session.getAttributeNames()).hasSize(1);
assertThat((String) session.getAttribute("existing")).isEqualTo("value");
}
}