@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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()));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user