@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2018 the original author or authors.
|
||||
* 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.
|
||||
@@ -25,7 +25,9 @@ import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.session.events.AbstractSessionEvent;
|
||||
|
||||
public class SessionEventRegistry implements ApplicationListener<AbstractSessionEvent> {
|
||||
|
||||
private Map<String, AbstractSessionEvent> events = new HashMap<>();
|
||||
|
||||
private ConcurrentMap<String, Object> locks = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
@@ -48,14 +50,12 @@ public class SessionEventRegistry implements ApplicationListener<AbstractSession
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <E extends AbstractSessionEvent> E getEvent(String sessionId)
|
||||
throws InterruptedException {
|
||||
public <E extends AbstractSessionEvent> E getEvent(String sessionId) throws InterruptedException {
|
||||
return (E) waitForEvent(sessionId);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <E extends AbstractSessionEvent> E waitForEvent(String sessionId)
|
||||
throws InterruptedException {
|
||||
private <E extends AbstractSessionEvent> E waitForEvent(String sessionId) throws InterruptedException {
|
||||
Object lock = getLock(sessionId);
|
||||
synchronized (lock) {
|
||||
if (!this.events.containsKey(sessionId)) {
|
||||
@@ -68,4 +68,5 @@ public class SessionEventRegistry implements ApplicationListener<AbstractSession
|
||||
private Object getLock(String sessionId) {
|
||||
return this.locks.computeIfAbsent(sessionId, (k) -> new Object());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -35,8 +35,7 @@ public abstract class AbstractRedisITests {
|
||||
|
||||
@Bean
|
||||
public GenericContainer redisContainer() {
|
||||
GenericContainer redisContainer = new GenericContainer(DOCKER_IMAGE)
|
||||
.withExposedPorts(6379);
|
||||
GenericContainer redisContainer = new GenericContainer(DOCKER_IMAGE).withExposedPorts(6379);
|
||||
redisContainer.start();
|
||||
return redisContainer;
|
||||
}
|
||||
@@ -44,8 +43,7 @@ public abstract class AbstractRedisITests {
|
||||
@Bean
|
||||
public LettuceConnectionFactory redisConnectionFactory() {
|
||||
RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration(
|
||||
redisContainer().getContainerIpAddress(),
|
||||
redisContainer().getFirstMappedPort());
|
||||
redisContainer().getContainerIpAddress(), redisContainer().getFirstMappedPort());
|
||||
return new LettuceConnectionFactory(configuration);
|
||||
}
|
||||
|
||||
|
||||
@@ -41,15 +41,14 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration
|
||||
@WebAppConfiguration
|
||||
public class ReactiveRedisOperationsSessionRepositoryITests extends AbstractRedisITests {
|
||||
class ReactiveRedisOperationsSessionRepositoryITests extends AbstractRedisITests {
|
||||
|
||||
@Autowired
|
||||
private ReactiveRedisOperationsSessionRepository repository;
|
||||
|
||||
@Test
|
||||
public void saves() throws InterruptedException {
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession toSave = this.repository
|
||||
.createSession().block();
|
||||
void saves() throws InterruptedException {
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession toSave = this.repository.createSession().block();
|
||||
|
||||
String expectedAttributeName = "a";
|
||||
String expectedAttributeValue = "b";
|
||||
@@ -70,9 +69,8 @@ public class ReactiveRedisOperationsSessionRepositoryITests extends AbstractRedi
|
||||
}
|
||||
|
||||
@Test // gh-1399
|
||||
public void saveMultipleTimes() {
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession session = this.repository
|
||||
.createSession().block();
|
||||
void saveMultipleTimes() {
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession session = this.repository.createSession().block();
|
||||
session.setAttribute("attribute1", "value1");
|
||||
Mono<Void> save1 = this.repository.save(session);
|
||||
session.setAttribute("attribute2", "value2");
|
||||
@@ -81,9 +79,8 @@ public class ReactiveRedisOperationsSessionRepositoryITests extends AbstractRedi
|
||||
}
|
||||
|
||||
@Test
|
||||
public void putAllOnSingleAttrDoesNotRemoveOld() {
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession toSave = this.repository
|
||||
.createSession().block();
|
||||
void putAllOnSingleAttrDoesNotRemoveOld() {
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession toSave = this.repository.createSession().block();
|
||||
toSave.setAttribute("a", "b");
|
||||
|
||||
this.repository.save(toSave).block();
|
||||
@@ -103,17 +100,16 @@ public class ReactiveRedisOperationsSessionRepositoryITests extends AbstractRedi
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenOnlyChangeId() throws Exception {
|
||||
void changeSessionIdWhenOnlyChangeId() throws Exception {
|
||||
String attrName = "changeSessionId";
|
||||
String attrValue = "changeSessionId-value";
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession toSave = this.repository
|
||||
.createSession().block();
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession toSave = this.repository.createSession().block();
|
||||
toSave.setAttribute(attrName, attrValue);
|
||||
|
||||
this.repository.save(toSave).block();
|
||||
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession findById = this.repository
|
||||
.findById(toSave.getId()).block();
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession findById = this.repository.findById(toSave.getId())
|
||||
.block();
|
||||
|
||||
assertThat(findById.<String>getAttribute(attrName)).isEqualTo(attrValue);
|
||||
|
||||
@@ -127,14 +123,12 @@ public class ReactiveRedisOperationsSessionRepositoryITests extends AbstractRedi
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession findByChangeSessionId = this.repository
|
||||
.findById(changeSessionId).block();
|
||||
|
||||
assertThat(findByChangeSessionId.<String>getAttribute(attrName))
|
||||
.isEqualTo(attrValue);
|
||||
assertThat(findByChangeSessionId.<String>getAttribute(attrName)).isEqualTo(attrValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenChangeTwice() throws Exception {
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession toSave = this.repository
|
||||
.createSession().block();
|
||||
void changeSessionIdWhenChangeTwice() throws Exception {
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession toSave = this.repository.createSession().block();
|
||||
|
||||
this.repository.save(toSave).block();
|
||||
|
||||
@@ -150,17 +144,16 @@ public class ReactiveRedisOperationsSessionRepositoryITests extends AbstractRedi
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenSetAttributeOnChangedSession() throws Exception {
|
||||
void changeSessionIdWhenSetAttributeOnChangedSession() throws Exception {
|
||||
String attrName = "changeSessionId";
|
||||
String attrValue = "changeSessionId-value";
|
||||
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession toSave = this.repository
|
||||
.createSession().block();
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession toSave = this.repository.createSession().block();
|
||||
|
||||
this.repository.save(toSave).block();
|
||||
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession findById = this.repository
|
||||
.findById(toSave.getId()).block();
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession findById = this.repository.findById(toSave.getId())
|
||||
.block();
|
||||
|
||||
findById.setAttribute(attrName, attrValue);
|
||||
|
||||
@@ -174,14 +167,12 @@ public class ReactiveRedisOperationsSessionRepositoryITests extends AbstractRedi
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession findByChangeSessionId = this.repository
|
||||
.findById(changeSessionId).block();
|
||||
|
||||
assertThat(findByChangeSessionId.<String>getAttribute(attrName))
|
||||
.isEqualTo(attrValue);
|
||||
assertThat(findByChangeSessionId.<String>getAttribute(attrName)).isEqualTo(attrValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenHasNotSaved() throws Exception {
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession toSave = this.repository
|
||||
.createSession().block();
|
||||
void changeSessionIdWhenHasNotSaved() throws Exception {
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession toSave = this.repository.createSession().block();
|
||||
String originalId = toSave.getId();
|
||||
toSave.changeSessionId();
|
||||
|
||||
@@ -193,9 +184,8 @@ public class ReactiveRedisOperationsSessionRepositoryITests extends AbstractRedi
|
||||
|
||||
// gh-954
|
||||
@Test
|
||||
public void changeSessionIdSaveTwice() {
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession toSave = this.repository
|
||||
.createSession().block();
|
||||
void changeSessionIdSaveTwice() {
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession toSave = this.repository.createSession().block();
|
||||
String originalId = toSave.getId();
|
||||
toSave.changeSessionId();
|
||||
|
||||
@@ -208,23 +198,20 @@ public class ReactiveRedisOperationsSessionRepositoryITests extends AbstractRedi
|
||||
|
||||
// gh-1111
|
||||
@Test
|
||||
public void changeSessionSaveOldSessionInstance() {
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession toSave = this.repository
|
||||
.createSession().block();
|
||||
void changeSessionSaveOldSessionInstance() {
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession toSave = this.repository.createSession().block();
|
||||
String sessionId = toSave.getId();
|
||||
|
||||
this.repository.save(toSave).block();
|
||||
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession session = this.repository
|
||||
.findById(sessionId).block();
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession session = this.repository.findById(sessionId).block();
|
||||
session.changeSessionId();
|
||||
session.setLastAccessedTime(Instant.now());
|
||||
this.repository.save(session).block();
|
||||
|
||||
toSave.setLastAccessedTime(Instant.now());
|
||||
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> this.repository.save(toSave).block())
|
||||
assertThatIllegalStateException().isThrownBy(() -> this.repository.save(toSave).block())
|
||||
.withMessage("Session was invalidated");
|
||||
|
||||
assertThat(this.repository.findById(sessionId).block()).isNull();
|
||||
|
||||
@@ -51,7 +51,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration
|
||||
@WebAppConfiguration
|
||||
public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests {
|
||||
class RedisOperationsSessionRepositoryITests extends AbstractRedisITests {
|
||||
|
||||
private static final String SPRING_SECURITY_CONTEXT = "SPRING_SECURITY_CONTEXT";
|
||||
|
||||
@@ -71,34 +71,31 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
private SecurityContext changedContext;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
void setup() {
|
||||
if (this.registry != null) {
|
||||
this.registry.clear();
|
||||
}
|
||||
this.context = SecurityContextHolder.createEmptyContext();
|
||||
this.context.setAuthentication(
|
||||
new UsernamePasswordAuthenticationToken("username-" + UUID.randomUUID(),
|
||||
"na", AuthorityUtils.createAuthorityList("ROLE_USER")));
|
||||
this.context.setAuthentication(new UsernamePasswordAuthenticationToken("username-" + UUID.randomUUID(), "na",
|
||||
AuthorityUtils.createAuthorityList("ROLE_USER")));
|
||||
|
||||
this.changedContext = SecurityContextHolder.createEmptyContext();
|
||||
this.changedContext.setAuthentication(new UsernamePasswordAuthenticationToken(
|
||||
"changedContext-" + UUID.randomUUID(), "na",
|
||||
AuthorityUtils.createAuthorityList("ROLE_USER")));
|
||||
"changedContext-" + UUID.randomUUID(), "na", AuthorityUtils.createAuthorityList("ROLE_USER")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saves() throws InterruptedException {
|
||||
void saves() throws InterruptedException {
|
||||
String username = "saves-" + System.currentTimeMillis();
|
||||
|
||||
String usernameSessionKey = "RedisOperationsSessionRepositoryITests:index:"
|
||||
+ INDEX_NAME + ":" + username;
|
||||
String usernameSessionKey = "RedisOperationsSessionRepositoryITests:index:" + INDEX_NAME + ":" + username;
|
||||
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
String expectedAttributeName = "a";
|
||||
String expectedAttributeValue = "b";
|
||||
toSave.setAttribute(expectedAttributeName, expectedAttributeValue);
|
||||
Authentication toSaveToken = new UsernamePasswordAuthenticationToken(username,
|
||||
"password", AuthorityUtils.createAuthorityList("ROLE_USER"));
|
||||
Authentication toSaveToken = new UsernamePasswordAuthenticationToken(username, "password",
|
||||
AuthorityUtils.createAuthorityList("ROLE_USER"));
|
||||
SecurityContext toSaveContext = SecurityContextHolder.createEmptyContext();
|
||||
toSaveContext.setAuthentication(toSaveToken);
|
||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, toSaveContext);
|
||||
@@ -108,10 +105,8 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
this.repository.save(toSave);
|
||||
|
||||
assertThat(this.registry.receivedEvent(toSave.getId())).isTrue();
|
||||
assertThat(this.registry.<SessionCreatedEvent>getEvent(toSave.getId()))
|
||||
.isInstanceOf(SessionCreatedEvent.class);
|
||||
assertThat(this.redis.boundSetOps(usernameSessionKey).members())
|
||||
.contains(toSave.getId());
|
||||
assertThat(this.registry.<SessionCreatedEvent>getEvent(toSave.getId())).isInstanceOf(SessionCreatedEvent.class);
|
||||
assertThat(this.redis.boundSetOps(usernameSessionKey).members()).contains(toSave.getId());
|
||||
|
||||
Session session = this.repository.findById(toSave.getId());
|
||||
|
||||
@@ -127,16 +122,14 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
assertThat(this.repository.findById(toSave.getId())).isNull();
|
||||
assertThat(this.registry.<SessionDestroyedEvent>getEvent(toSave.getId()))
|
||||
.isInstanceOf(SessionDestroyedEvent.class);
|
||||
assertThat(this.redis.boundSetOps(usernameSessionKey).members())
|
||||
.doesNotContain(toSave.getId());
|
||||
assertThat(this.redis.boundSetOps(usernameSessionKey).members()).doesNotContain(toSave.getId());
|
||||
|
||||
assertThat(this.registry.getEvent(toSave.getId()).getSession()
|
||||
.<String>getAttribute(expectedAttributeName))
|
||||
assertThat(this.registry.getEvent(toSave.getId()).getSession().<String>getAttribute(expectedAttributeName))
|
||||
.isEqualTo(expectedAttributeValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void putAllOnSingleAttrDoesNotRemoveOld() {
|
||||
void putAllOnSingleAttrDoesNotRemoveOld() {
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute("a", "b");
|
||||
|
||||
@@ -157,15 +150,15 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByPrincipalName() throws Exception {
|
||||
void findByPrincipalName() throws Exception {
|
||||
String principalName = "findByPrincipalName" + UUID.randomUUID();
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(INDEX_NAME, principalName);
|
||||
|
||||
this.repository.save(toSave);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
principalName);
|
||||
|
||||
assertThat(findByPrincipalName).hasSize(1);
|
||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||
@@ -173,7 +166,28 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
this.repository.deleteById(toSave.getId());
|
||||
assertThat(this.registry.receivedEvent(toSave.getId())).isTrue();
|
||||
|
||||
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||
|
||||
assertThat(findByPrincipalName).hasSize(0);
|
||||
assertThat(findByPrincipalName.keySet()).doesNotContain(toSave.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void findByPrincipalNameExpireRemovesIndex() throws Exception {
|
||||
String principalName = "findByPrincipalNameExpireRemovesIndex" + UUID.randomUUID();
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(INDEX_NAME, principalName);
|
||||
|
||||
this.repository.save(toSave);
|
||||
|
||||
String body = "RedisOperationsSessionRepositoryITests:sessions:expires:" + toSave.getId();
|
||||
String channel = "__keyevent@0__:expired";
|
||||
DefaultMessage message = new DefaultMessage(channel.getBytes(StandardCharsets.UTF_8),
|
||||
body.getBytes(StandardCharsets.UTF_8));
|
||||
byte[] pattern = new byte[] {};
|
||||
this.repository.onMessage(message, pattern);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
principalName);
|
||||
|
||||
assertThat(findByPrincipalName).hasSize(0);
|
||||
@@ -181,34 +195,8 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByPrincipalNameExpireRemovesIndex() throws Exception {
|
||||
String principalName = "findByPrincipalNameExpireRemovesIndex"
|
||||
+ UUID.randomUUID();
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(INDEX_NAME, principalName);
|
||||
|
||||
this.repository.save(toSave);
|
||||
|
||||
String body = "RedisOperationsSessionRepositoryITests:sessions:expires:"
|
||||
+ toSave.getId();
|
||||
String channel = "__keyevent@0__:expired";
|
||||
DefaultMessage message = new DefaultMessage(
|
||||
channel.getBytes(StandardCharsets.UTF_8),
|
||||
body.getBytes(StandardCharsets.UTF_8));
|
||||
byte[] pattern = new byte[] {};
|
||||
this.repository.onMessage(message, pattern);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||
|
||||
assertThat(findByPrincipalName).hasSize(0);
|
||||
assertThat(findByPrincipalName.keySet()).doesNotContain(toSave.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByPrincipalNameNoPrincipalNameChange() throws Exception {
|
||||
String principalName = "findByPrincipalNameNoPrincipalNameChange"
|
||||
+ UUID.randomUUID();
|
||||
void findByPrincipalNameNoPrincipalNameChange() throws Exception {
|
||||
String principalName = "findByPrincipalNameNoPrincipalNameChange" + UUID.randomUUID();
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(INDEX_NAME, principalName);
|
||||
|
||||
@@ -217,17 +205,16 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
toSave.setAttribute("other", "value");
|
||||
this.repository.save(toSave);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
principalName);
|
||||
|
||||
assertThat(findByPrincipalName).hasSize(1);
|
||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByPrincipalNameNoPrincipalNameChangeReload() throws Exception {
|
||||
String principalName = "findByPrincipalNameNoPrincipalNameChangeReload"
|
||||
+ UUID.randomUUID();
|
||||
void findByPrincipalNameNoPrincipalNameChangeReload() throws Exception {
|
||||
String principalName = "findByPrincipalNameNoPrincipalNameChangeReload" + UUID.randomUUID();
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(INDEX_NAME, principalName);
|
||||
|
||||
@@ -238,15 +225,15 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
toSave.setAttribute("other", "value");
|
||||
this.repository.save(toSave);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
principalName);
|
||||
|
||||
assertThat(findByPrincipalName).hasSize(1);
|
||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByDeletedPrincipalName() throws Exception {
|
||||
void findByDeletedPrincipalName() throws Exception {
|
||||
String principalName = "findByDeletedPrincipalName" + UUID.randomUUID();
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(INDEX_NAME, principalName);
|
||||
@@ -256,14 +243,14 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
toSave.setAttribute(INDEX_NAME, null);
|
||||
this.repository.save(toSave);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
principalName);
|
||||
|
||||
assertThat(findByPrincipalName).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByChangedPrincipalName() throws Exception {
|
||||
void findByChangedPrincipalName() throws Exception {
|
||||
String principalName = "findByChangedPrincipalName" + UUID.randomUUID();
|
||||
String principalNameChanged = "findByChangedPrincipalName" + UUID.randomUUID();
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
@@ -274,19 +261,18 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
toSave.setAttribute(INDEX_NAME, principalNameChanged);
|
||||
this.repository.save(toSave);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
principalName);
|
||||
assertThat(findByPrincipalName).isEmpty();
|
||||
|
||||
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
principalNameChanged);
|
||||
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME, principalNameChanged);
|
||||
|
||||
assertThat(findByPrincipalName).hasSize(1);
|
||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByDeletedPrincipalNameReload() throws Exception {
|
||||
void findByDeletedPrincipalNameReload() throws Exception {
|
||||
String principalName = "findByDeletedPrincipalName" + UUID.randomUUID();
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(INDEX_NAME, principalName);
|
||||
@@ -297,14 +283,14 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
getSession.setAttribute(INDEX_NAME, null);
|
||||
this.repository.save(getSession);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
principalName);
|
||||
|
||||
assertThat(findByPrincipalName).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByChangedPrincipalNameReload() throws Exception {
|
||||
void findByChangedPrincipalNameReload() throws Exception {
|
||||
String principalName = "findByChangedPrincipalName" + UUID.randomUUID();
|
||||
String principalNameChanged = "findByChangedPrincipalName" + UUID.randomUUID();
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
@@ -317,26 +303,25 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
getSession.setAttribute(INDEX_NAME, principalNameChanged);
|
||||
this.repository.save(getSession);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
principalName);
|
||||
assertThat(findByPrincipalName).isEmpty();
|
||||
|
||||
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
principalNameChanged);
|
||||
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME, principalNameChanged);
|
||||
|
||||
assertThat(findByPrincipalName).hasSize(1);
|
||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findBySecurityPrincipalName() throws Exception {
|
||||
void findBySecurityPrincipalName() throws Exception {
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||
|
||||
this.repository.save(toSave);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
getSecurityName());
|
||||
|
||||
assertThat(findByPrincipalName).hasSize(1);
|
||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||
@@ -344,7 +329,27 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
this.repository.deleteById(toSave.getId());
|
||||
assertThat(this.registry.receivedEvent(toSave.getId())).isTrue();
|
||||
|
||||
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||
|
||||
assertThat(findByPrincipalName).hasSize(0);
|
||||
assertThat(findByPrincipalName.keySet()).doesNotContain(toSave.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void findBySecurityPrincipalNameExpireRemovesIndex() throws Exception {
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||
|
||||
this.repository.save(toSave);
|
||||
|
||||
String body = "RedisOperationsSessionRepositoryITests:sessions:expires:" + toSave.getId();
|
||||
String channel = "__keyevent@0__:expired";
|
||||
DefaultMessage message = new DefaultMessage(channel.getBytes(StandardCharsets.UTF_8),
|
||||
body.getBytes(StandardCharsets.UTF_8));
|
||||
byte[] pattern = new byte[] {};
|
||||
this.repository.onMessage(message, pattern);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
getSecurityName());
|
||||
|
||||
assertThat(findByPrincipalName).hasSize(0);
|
||||
@@ -352,30 +357,7 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findBySecurityPrincipalNameExpireRemovesIndex() throws Exception {
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||
|
||||
this.repository.save(toSave);
|
||||
|
||||
String body = "RedisOperationsSessionRepositoryITests:sessions:expires:"
|
||||
+ toSave.getId();
|
||||
String channel = "__keyevent@0__:expired";
|
||||
DefaultMessage message = new DefaultMessage(
|
||||
channel.getBytes(StandardCharsets.UTF_8),
|
||||
body.getBytes(StandardCharsets.UTF_8));
|
||||
byte[] pattern = new byte[] {};
|
||||
this.repository.onMessage(message, pattern);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||
|
||||
assertThat(findByPrincipalName).hasSize(0);
|
||||
assertThat(findByPrincipalName.keySet()).doesNotContain(toSave.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByPrincipalNameNoSecurityPrincipalNameChange() throws Exception {
|
||||
void findByPrincipalNameNoSecurityPrincipalNameChange() throws Exception {
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||
|
||||
@@ -384,16 +366,15 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
toSave.setAttribute("other", "value");
|
||||
this.repository.save(toSave);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
getSecurityName());
|
||||
|
||||
assertThat(findByPrincipalName).hasSize(1);
|
||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByPrincipalNameNoSecurityPrincipalNameChangeReload()
|
||||
throws Exception {
|
||||
void findByPrincipalNameNoSecurityPrincipalNameChangeReload() throws Exception {
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||
|
||||
@@ -404,15 +385,15 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
toSave.setAttribute("other", "value");
|
||||
this.repository.save(toSave);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
getSecurityName());
|
||||
|
||||
assertThat(findByPrincipalName).hasSize(1);
|
||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByDeletedSecurityPrincipalName() throws Exception {
|
||||
void findByDeletedSecurityPrincipalName() throws Exception {
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||
|
||||
@@ -421,14 +402,14 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, null);
|
||||
this.repository.save(toSave);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
getSecurityName());
|
||||
|
||||
assertThat(findByPrincipalName).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByChangedSecurityPrincipalName() throws Exception {
|
||||
void findByChangedSecurityPrincipalName() throws Exception {
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||
|
||||
@@ -437,19 +418,18 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.changedContext);
|
||||
this.repository.save(toSave);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
getSecurityName());
|
||||
assertThat(findByPrincipalName).isEmpty();
|
||||
|
||||
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
getChangedSecurityName());
|
||||
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME, getChangedSecurityName());
|
||||
|
||||
assertThat(findByPrincipalName).hasSize(1);
|
||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByDeletedSecurityPrincipalNameReload() throws Exception {
|
||||
void findByDeletedSecurityPrincipalNameReload() throws Exception {
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||
|
||||
@@ -459,14 +439,14 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
getSession.setAttribute(INDEX_NAME, null);
|
||||
this.repository.save(getSession);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||
.findByIndexNameAndIndexValue(INDEX_NAME, getChangedSecurityName());
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
getChangedSecurityName());
|
||||
|
||||
assertThat(findByPrincipalName).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByChangedSecurityPrincipalNameReload() throws Exception {
|
||||
void findByChangedSecurityPrincipalNameReload() throws Exception {
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||
|
||||
@@ -477,19 +457,18 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
getSession.setAttribute(SPRING_SECURITY_CONTEXT, this.changedContext);
|
||||
this.repository.save(getSession);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
getSecurityName());
|
||||
assertThat(findByPrincipalName).isEmpty();
|
||||
|
||||
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
getChangedSecurityName());
|
||||
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME, getChangedSecurityName());
|
||||
|
||||
assertThat(findByPrincipalName).hasSize(1);
|
||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenOnlyChangeId() throws Exception {
|
||||
void changeSessionIdWhenOnlyChangeId() throws Exception {
|
||||
String attrName = "changeSessionId";
|
||||
String attrValue = "changeSessionId-value";
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
@@ -514,7 +493,7 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenChangeTwice() throws Exception {
|
||||
void changeSessionIdWhenChangeTwice() throws Exception {
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
|
||||
this.repository.save(toSave);
|
||||
@@ -531,7 +510,7 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenSetAttributeOnChangedSession() throws Exception {
|
||||
void changeSessionIdWhenSetAttributeOnChangedSession() throws Exception {
|
||||
String attrName = "changeSessionId";
|
||||
String attrValue = "changeSessionId-value";
|
||||
|
||||
@@ -556,7 +535,7 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenHasNotSaved() throws Exception {
|
||||
void changeSessionIdWhenHasNotSaved() throws Exception {
|
||||
String attrName = "changeSessionId";
|
||||
String attrValue = "changeSessionId-value";
|
||||
|
||||
@@ -572,7 +551,7 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
|
||||
// gh-962
|
||||
@Test
|
||||
public void changeSessionIdSaveTwice() {
|
||||
void changeSessionIdSaveTwice() {
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
String originalId = toSave.getId();
|
||||
toSave.changeSessionId();
|
||||
@@ -586,7 +565,7 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
|
||||
// gh-1137
|
||||
@Test
|
||||
public void changeSessionIdWhenSessionIsDeleted() {
|
||||
void changeSessionIdWhenSessionIsDeleted() {
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
String sessionId = toSave.getId();
|
||||
this.repository.save(toSave);
|
||||
@@ -601,7 +580,7 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
}
|
||||
|
||||
@Test // gh-1270
|
||||
public void changeSessionIdSaveConcurrently() {
|
||||
void changeSessionIdSaveConcurrently() {
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
String originalId = toSave.getId();
|
||||
this.repository.save(toSave);
|
||||
|
||||
@@ -56,10 +56,9 @@ class SimpleRedisOperationsSessionRepositoryITests extends AbstractRedisITests {
|
||||
@Test
|
||||
void save_NewSession_ShouldSaveSession() {
|
||||
RedisSession session = createAndSaveSession(Instant.now());
|
||||
assertThat(session.getMaxInactiveInterval()).isEqualTo(
|
||||
Duration.ofSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS));
|
||||
assertThat(session.getAttributeNames())
|
||||
.isEqualTo(Collections.singleton("attribute1"));
|
||||
assertThat(session.getMaxInactiveInterval())
|
||||
.isEqualTo(Duration.ofSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS));
|
||||
assertThat(session.getAttributeNames()).isEqualTo(Collections.singleton("attribute1"));
|
||||
assertThat(session.<String>getAttribute("attribute1")).isEqualTo("value1");
|
||||
}
|
||||
|
||||
@@ -72,8 +71,7 @@ class SimpleRedisOperationsSessionRepositoryITests extends AbstractRedisITests {
|
||||
void save_DeletedSession_ShouldThrowException() {
|
||||
RedisSession session = createAndSaveSession(Instant.now());
|
||||
this.sessionRepository.deleteById(session.getId());
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> this.sessionRepository.save(session))
|
||||
assertThatIllegalStateException().isThrownBy(() -> this.sessionRepository.save(session))
|
||||
.withMessage("Session was invalidated");
|
||||
}
|
||||
|
||||
@@ -164,8 +162,7 @@ class SimpleRedisOperationsSessionRepositoryITests extends AbstractRedisITests {
|
||||
this.sessionRepository.deleteById(originalSessionId);
|
||||
updateSession(session, Instant.now(), "attribute1", "value1");
|
||||
String newSessionId = session.changeSessionId();
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> this.sessionRepository.save(session))
|
||||
assertThatIllegalStateException().isThrownBy(() -> this.sessionRepository.save(session))
|
||||
.withMessage("Session was invalidated");
|
||||
assertThat(this.sessionRepository.findById(newSessionId)).isNull();
|
||||
assertThat(this.sessionRepository.findById(originalSessionId)).isNull();
|
||||
@@ -182,8 +179,7 @@ class SimpleRedisOperationsSessionRepositoryITests extends AbstractRedisITests {
|
||||
this.sessionRepository.save(copy1);
|
||||
updateSession(copy2, now.plusSeconds(2L), "attribute3", "value3");
|
||||
String newSessionId2 = copy2.changeSessionId();
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> this.sessionRepository.save(copy2))
|
||||
assertThatIllegalStateException().isThrownBy(() -> this.sessionRepository.save(copy2))
|
||||
.withMessage("Session was invalidated");
|
||||
assertThat(this.sessionRepository.findById(newSessionId1)).isNotNull();
|
||||
assertThat(this.sessionRepository.findById(newSessionId2)).isNull();
|
||||
@@ -220,8 +216,8 @@ class SimpleRedisOperationsSessionRepositoryITests extends AbstractRedisITests {
|
||||
return this.sessionRepository.findById(session.getId());
|
||||
}
|
||||
|
||||
private static void updateSession(RedisSession session, Instant lastAccessedTime,
|
||||
String attributeName, Object attributeValue) {
|
||||
private static void updateSession(RedisSession session, Instant lastAccessedTime, String attributeName,
|
||||
Object attributeValue) {
|
||||
session.setLastAccessedTime(lastAccessedTime);
|
||||
session.setAttribute(attributeName, attributeValue);
|
||||
}
|
||||
@@ -231,8 +227,7 @@ class SimpleRedisOperationsSessionRepositoryITests extends AbstractRedisITests {
|
||||
static class Config extends BaseConfig {
|
||||
|
||||
@Bean
|
||||
public SimpleRedisOperationsSessionRepository sessionRepository(
|
||||
RedisConnectionFactory redisConnectionFactory) {
|
||||
public SimpleRedisOperationsSessionRepository sessionRepository(RedisConnectionFactory redisConnectionFactory) {
|
||||
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
|
||||
redisTemplate.setConnectionFactory(redisConnectionFactory);
|
||||
redisTemplate.afterPropertiesSet();
|
||||
|
||||
@@ -44,8 +44,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration
|
||||
@WebAppConfiguration
|
||||
public class EnableRedisHttpSessionExpireSessionDestroyedTests<S extends Session>
|
||||
extends AbstractRedisITests {
|
||||
class EnableRedisHttpSessionExpireSessionDestroyedTests<S extends Session> extends AbstractRedisITests {
|
||||
|
||||
@Autowired
|
||||
private SessionRepository<S> repository;
|
||||
@@ -56,16 +55,16 @@ public class EnableRedisHttpSessionExpireSessionDestroyedTests<S extends Session
|
||||
private final Object lock = new Object();
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
void setup() {
|
||||
this.registry.setLock(this.lock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void expireFiresSessionExpiredEvent() throws InterruptedException {
|
||||
void expireFiresSessionExpiredEvent() throws InterruptedException {
|
||||
S toSave = this.repository.createSession();
|
||||
toSave.setAttribute("a", "b");
|
||||
Authentication toSaveToken = new UsernamePasswordAuthenticationToken("user",
|
||||
"password", AuthorityUtils.createAuthorityList("ROLE_USER"));
|
||||
Authentication toSaveToken = new UsernamePasswordAuthenticationToken("user", "password",
|
||||
AuthorityUtils.createAuthorityList("ROLE_USER"));
|
||||
SecurityContext toSaveContext = SecurityContextHolder.createEmptyContext();
|
||||
toSaveContext.setAuthentication(toSaveToken);
|
||||
toSave.setAttribute("SPRING_SECURITY_CONTEXT", toSaveContext);
|
||||
@@ -89,9 +88,10 @@ public class EnableRedisHttpSessionExpireSessionDestroyedTests<S extends Session
|
||||
assertThat(this.registry.receivedEvent()).isTrue();
|
||||
}
|
||||
|
||||
static class SessionExpiredEventRegistry
|
||||
implements ApplicationListener<SessionExpiredEvent> {
|
||||
static class SessionExpiredEventRegistry implements ApplicationListener<SessionExpiredEvent> {
|
||||
|
||||
private boolean receivedEvent;
|
||||
|
||||
private Object lock;
|
||||
|
||||
@Override
|
||||
@@ -109,6 +109,7 @@ public class EnableRedisHttpSessionExpireSessionDestroyedTests<S extends Session
|
||||
public void setLock(Object lock) {
|
||||
this.lock = lock;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
|
||||
@@ -35,14 +35,13 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration
|
||||
@WebAppConfiguration
|
||||
public class RedisOperationsSessionRepositoryFlushImmediatelyITests<S extends Session>
|
||||
extends AbstractRedisITests {
|
||||
class RedisOperationsSessionRepositoryFlushImmediatelyITests<S extends Session> extends AbstractRedisITests {
|
||||
|
||||
@Autowired
|
||||
private SessionRepository<S> sessionRepository;
|
||||
|
||||
@Test
|
||||
public void savesOnCreate() throws InterruptedException {
|
||||
void savesOnCreate() throws InterruptedException {
|
||||
S created = this.sessionRepository.createSession();
|
||||
|
||||
S getSession = this.sessionRepository.findById(created.getId());
|
||||
|
||||
@@ -45,7 +45,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration
|
||||
@WebAppConfiguration
|
||||
public class RedisListenerContainerTaskExecutorITests extends AbstractRedisITests {
|
||||
class RedisListenerContainerTaskExecutorITests extends AbstractRedisITests {
|
||||
|
||||
@Autowired
|
||||
private SessionTaskExecutor executor;
|
||||
@@ -54,10 +54,9 @@ public class RedisListenerContainerTaskExecutorITests extends AbstractRedisITest
|
||||
private RedisOperations<Object, Object> redis;
|
||||
|
||||
@Test
|
||||
public void testRedisDelEventsAreDispatchedInSessionTaskExecutor()
|
||||
throws InterruptedException {
|
||||
BoundSetOperations<Object, Object> ops = this.redis.boundSetOps(
|
||||
"spring:session:RedisListenerContainerTaskExecutorITests:expirations:dummy");
|
||||
void testRedisDelEventsAreDispatchedInSessionTaskExecutor() throws InterruptedException {
|
||||
BoundSetOperations<Object, Object> ops = this.redis
|
||||
.boundSetOps("spring:session:RedisListenerContainerTaskExecutorITests:expirations:dummy");
|
||||
ops.add("value");
|
||||
ops.remove("value");
|
||||
assertThat(this.executor.taskDispatched()).isTrue();
|
||||
@@ -65,6 +64,7 @@ public class RedisListenerContainerTaskExecutorITests extends AbstractRedisITest
|
||||
}
|
||||
|
||||
static class SessionTaskExecutor implements TaskExecutor {
|
||||
|
||||
private Object lock = new Object();
|
||||
|
||||
private final Executor executor;
|
||||
@@ -97,6 +97,7 @@ public class RedisListenerContainerTaskExecutorITests extends AbstractRedisITest
|
||||
}
|
||||
return (this.taskDispatched != null) ? this.taskDispatched : Boolean.FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
|
||||
@@ -38,8 +38,8 @@ import org.springframework.util.Assert;
|
||||
* @author Vedran Pavic
|
||||
* @since 2.0
|
||||
*/
|
||||
public class ReactiveRedisOperationsSessionRepository implements
|
||||
ReactiveSessionRepository<ReactiveRedisOperationsSessionRepository.RedisSession> {
|
||||
public class ReactiveRedisOperationsSessionRepository
|
||||
implements ReactiveSessionRepository<ReactiveRedisOperationsSessionRepository.RedisSession> {
|
||||
|
||||
/**
|
||||
* The default namespace for each key and channel in Redis used by Spring Session.
|
||||
@@ -61,8 +61,7 @@ public class ReactiveRedisOperationsSessionRepository implements
|
||||
|
||||
private RedisFlushMode redisFlushMode = RedisFlushMode.ON_SAVE;
|
||||
|
||||
public ReactiveRedisOperationsSessionRepository(
|
||||
ReactiveRedisOperations<String, Object> sessionRedisOperations) {
|
||||
public ReactiveRedisOperationsSessionRepository(ReactiveRedisOperations<String, Object> sessionRedisOperations) {
|
||||
Assert.notNull(sessionRedisOperations, "sessionRedisOperations cannot be null");
|
||||
this.sessionRedisOperations = sessionRedisOperations;
|
||||
}
|
||||
@@ -76,7 +75,6 @@ public class ReactiveRedisOperationsSessionRepository implements
|
||||
* Sets the maximum inactive interval in seconds between requests before newly created
|
||||
* sessions will be invalidated. A negative time indicates that the session will never
|
||||
* timeout. The default is 1800 (30 minutes).
|
||||
*
|
||||
* @param defaultMaxInactiveInterval the number of seconds that the {@link Session}
|
||||
* should be kept alive between client requests.
|
||||
*/
|
||||
@@ -86,7 +84,6 @@ public class ReactiveRedisOperationsSessionRepository implements
|
||||
|
||||
/**
|
||||
* Sets the redis flush mode. Default flush mode is {@link RedisFlushMode#ON_SAVE}.
|
||||
*
|
||||
* @param redisFlushMode the new redis flush mode
|
||||
*/
|
||||
public void setRedisFlushMode(RedisFlushMode redisFlushMode) {
|
||||
@@ -109,8 +106,7 @@ public class ReactiveRedisOperationsSessionRepository implements
|
||||
RedisSession session = new RedisSession();
|
||||
|
||||
if (this.defaultMaxInactiveInterval != null) {
|
||||
session.setMaxInactiveInterval(
|
||||
Duration.ofSeconds(this.defaultMaxInactiveInterval));
|
||||
session.setMaxInactiveInterval(Duration.ofSeconds(this.defaultMaxInactiveInterval));
|
||||
}
|
||||
|
||||
return Mono.just(session);
|
||||
@@ -122,12 +118,9 @@ public class ReactiveRedisOperationsSessionRepository implements
|
||||
if (session.isNew) {
|
||||
return session.save();
|
||||
}
|
||||
String sessionKey = getSessionKey(
|
||||
session.hasChangedSessionId() ? session.originalSessionId
|
||||
: session.getId());
|
||||
return this.sessionRedisOperations.hasKey(sessionKey).flatMap((exists) -> exists
|
||||
? session.save()
|
||||
: Mono.error(new IllegalStateException("Session was invalidated")));
|
||||
String sessionKey = getSessionKey(session.hasChangedSessionId() ? session.originalSessionId : session.getId());
|
||||
return this.sessionRedisOperations.hasKey(sessionKey).flatMap(
|
||||
(exists) -> exists ? session.save() : Mono.error(new IllegalStateException("Session was invalidated")));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -182,19 +175,15 @@ public class ReactiveRedisOperationsSessionRepository implements
|
||||
*/
|
||||
RedisSession() {
|
||||
this(new MapSession());
|
||||
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.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;
|
||||
this.flushImmediateIfNecessary();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance from the provided {@link MapSession}.
|
||||
*
|
||||
* @param mapSession the {@link MapSession} that represents the persisted session
|
||||
* that was retrieved. Cannot be null.
|
||||
*/
|
||||
@@ -244,8 +233,7 @@ public class ReactiveRedisOperationsSessionRepository implements
|
||||
@Override
|
||||
public void setLastAccessedTime(Instant lastAccessedTime) {
|
||||
this.cached.setLastAccessedTime(lastAccessedTime);
|
||||
putAndFlush(RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
|
||||
getLastAccessedTime().toEpochMilli());
|
||||
putAndFlush(RedisSessionMapper.LAST_ACCESSED_TIME_KEY, getLastAccessedTime().toEpochMilli());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -256,8 +244,7 @@ public class ReactiveRedisOperationsSessionRepository implements
|
||||
@Override
|
||||
public void setMaxInactiveInterval(Duration interval) {
|
||||
this.cached.setMaxInactiveInterval(interval);
|
||||
putAndFlush(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY,
|
||||
(int) getMaxInactiveInterval().getSeconds());
|
||||
putAndFlush(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY, (int) getMaxInactiveInterval().getSeconds());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -286,8 +273,7 @@ public class ReactiveRedisOperationsSessionRepository implements
|
||||
}
|
||||
|
||||
private Mono<Void> save() {
|
||||
return Mono.defer(() -> saveChangeSessionId().then(saveDelta())
|
||||
.doOnSuccess((aVoid) -> this.isNew = false));
|
||||
return Mono.defer(() -> saveChangeSessionId().then(saveDelta()).doOnSuccess((aVoid) -> this.isNew = false));
|
||||
}
|
||||
|
||||
private Mono<Void> saveDelta() {
|
||||
@@ -296,8 +282,8 @@ public class ReactiveRedisOperationsSessionRepository implements
|
||||
}
|
||||
|
||||
String sessionKey = getSessionKey(getId());
|
||||
Mono<Boolean> update = ReactiveRedisOperationsSessionRepository.this.sessionRedisOperations
|
||||
.opsForHash().putAll(sessionKey, new HashMap<>(this.delta));
|
||||
Mono<Boolean> update = ReactiveRedisOperationsSessionRepository.this.sessionRedisOperations.opsForHash()
|
||||
.putAll(sessionKey, new HashMap<>(this.delta));
|
||||
Mono<Boolean> setTtl = ReactiveRedisOperationsSessionRepository.this.sessionRedisOperations
|
||||
.expire(sessionKey, getMaxInactiveInterval());
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2016 the original author or authors.
|
||||
* 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.
|
||||
@@ -25,6 +25,7 @@ import org.springframework.session.SessionRepository;
|
||||
* @since 1.1
|
||||
*/
|
||||
public enum RedisFlushMode {
|
||||
|
||||
/**
|
||||
* Only writes to Redis when
|
||||
* {@link SessionRepository#save(org.springframework.session.Session)} is invoked. In
|
||||
@@ -39,4 +40,5 @@ public enum RedisFlushMode {
|
||||
* immediately.
|
||||
*/
|
||||
IMMEDIATE
|
||||
|
||||
}
|
||||
|
||||
@@ -72,8 +72,8 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* <p>
|
||||
* For additional information on how to create a RedisTemplate, refer to the
|
||||
* <a href = "https://docs.spring.io/spring-data/data-redis/docs/current/reference/html/" >
|
||||
* Spring Data Redis Reference</a>.
|
||||
* <a href = "https://docs.spring.io/spring-data/data-redis/docs/current/reference/html/"
|
||||
* > Spring Data Redis Reference</a>.
|
||||
* </p>
|
||||
*
|
||||
* <h2>Storage Details</h2>
|
||||
@@ -123,10 +123,12 @@ import org.springframework.util.Assert;
|
||||
* <h3>Optimized Writes</h3>
|
||||
*
|
||||
* <p>
|
||||
* The {@link org.springframework.session.data.redis.RedisOperationsSessionRepository.RedisSession} keeps track of the properties that have changed and only
|
||||
* updates those. This means if an attribute is written once and read many times we only
|
||||
* need to write that attribute once. For example, assume the session attribute
|
||||
* "sessionAttr2" from earlier was updated. The following would be executed upon saving:
|
||||
* The
|
||||
* {@link org.springframework.session.data.redis.RedisOperationsSessionRepository.RedisSession}
|
||||
* keeps track of the properties that have changed and only updates those. This means if
|
||||
* an attribute is written once and read many times we only need to write that attribute
|
||||
* once. For example, assume the session attribute "sessionAttr2" from earlier was
|
||||
* updated. The following would be executed upon saving:
|
||||
* </p>
|
||||
*
|
||||
* <pre>
|
||||
@@ -170,15 +172,14 @@ import org.springframework.util.Assert;
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* <b>NOTE:</b> The {@link #findById(String)} method ensures that no expired sessions
|
||||
* will be returned. This means there is no need to check the expiration before using a
|
||||
* session
|
||||
* <b>NOTE:</b> The {@link #findById(String)} method ensures that no expired sessions will
|
||||
* be returned. This means there is no need to check the expiration before using a session
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Spring Session relies on the expired and delete
|
||||
* <a href="https://redis.io/topics/notifications">keyspace notifications</a> from Redis to
|
||||
* fire a SessionDestroyedEvent. It is the SessionDestroyedEvent that ensures resources
|
||||
* <a href="https://redis.io/topics/notifications">keyspace notifications</a> from Redis
|
||||
* to fire a SessionDestroyedEvent. It is the SessionDestroyedEvent that ensures resources
|
||||
* associated with the Session are cleaned up. For example, when using Spring Session's
|
||||
* WebSocket support the Redis expired or delete event is what triggers any WebSocket
|
||||
* connections associated with the session to be closed.
|
||||
@@ -244,11 +245,10 @@ import org.springframework.util.Assert;
|
||||
* @author Vedran Pavic
|
||||
* @since 1.0
|
||||
*/
|
||||
public class RedisOperationsSessionRepository implements
|
||||
FindByIndexNameSessionRepository<RedisOperationsSessionRepository.RedisSession>,
|
||||
MessageListener {
|
||||
private static final Log logger = LogFactory
|
||||
.getLog(RedisOperationsSessionRepository.class);
|
||||
public class RedisOperationsSessionRepository
|
||||
implements FindByIndexNameSessionRepository<RedisOperationsSessionRepository.RedisSession>, MessageListener {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(RedisOperationsSessionRepository.class);
|
||||
|
||||
private static final String SPRING_SECURITY_CONTEXT = "SPRING_SECURITY_CONTEXT";
|
||||
|
||||
@@ -303,16 +303,14 @@ public class RedisOperationsSessionRepository implements
|
||||
|
||||
/**
|
||||
* Creates a new instance. For an example, refer to the class level javadoc.
|
||||
*
|
||||
* @param sessionRedisOperations the {@link RedisOperations} to use for managing the
|
||||
* sessions. Cannot be null.
|
||||
*/
|
||||
public RedisOperationsSessionRepository(
|
||||
RedisOperations<Object, Object> sessionRedisOperations) {
|
||||
public RedisOperationsSessionRepository(RedisOperations<Object, Object> sessionRedisOperations) {
|
||||
Assert.notNull(sessionRedisOperations, "sessionRedisOperations cannot be null");
|
||||
this.sessionRedisOperations = sessionRedisOperations;
|
||||
this.expirationPolicy = new RedisSessionExpirationPolicy(sessionRedisOperations,
|
||||
this::getExpirationsKey, this::getSessionKey);
|
||||
this.expirationPolicy = new RedisSessionExpirationPolicy(sessionRedisOperations, this::getExpirationsKey,
|
||||
this::getSessionKey);
|
||||
configureSessionChannels();
|
||||
}
|
||||
|
||||
@@ -320,14 +318,11 @@ public class RedisOperationsSessionRepository implements
|
||||
* Sets the {@link ApplicationEventPublisher} that is used to publish
|
||||
* {@link SessionDestroyedEvent}. The default is to not publish a
|
||||
* {@link SessionDestroyedEvent}.
|
||||
*
|
||||
* @param applicationEventPublisher the {@link ApplicationEventPublisher} that is used
|
||||
* to publish {@link SessionDestroyedEvent}. Cannot be null.
|
||||
*/
|
||||
public void setApplicationEventPublisher(
|
||||
ApplicationEventPublisher applicationEventPublisher) {
|
||||
Assert.notNull(applicationEventPublisher,
|
||||
"applicationEventPublisher cannot be null");
|
||||
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
|
||||
Assert.notNull(applicationEventPublisher, "applicationEventPublisher cannot be null");
|
||||
this.eventPublisher = applicationEventPublisher;
|
||||
}
|
||||
|
||||
@@ -335,7 +330,6 @@ public class RedisOperationsSessionRepository implements
|
||||
* Sets the maximum inactive interval in seconds between requests before newly created
|
||||
* sessions will be invalidated. A negative time indicates that the session will never
|
||||
* timeout. The default is 1800 (30 minutes).
|
||||
*
|
||||
* @param defaultMaxInactiveInterval the number of seconds that the {@link Session}
|
||||
* should be kept alive between client requests.
|
||||
*/
|
||||
@@ -346,7 +340,6 @@ public class RedisOperationsSessionRepository implements
|
||||
/**
|
||||
* Sets the default redis serializer. Replaces default serializer which is based on
|
||||
* {@link JdkSerializationRedisSerializer}.
|
||||
*
|
||||
* @param defaultSerializer the new default redis serializer
|
||||
*/
|
||||
public void setDefaultSerializer(RedisSerializer<Object> defaultSerializer) {
|
||||
@@ -356,7 +349,6 @@ public class RedisOperationsSessionRepository implements
|
||||
|
||||
/**
|
||||
* Sets the redis flush mode. Default flush mode is {@link RedisFlushMode#ON_SAVE}.
|
||||
*
|
||||
* @param redisFlushMode the new redis flush mode
|
||||
*/
|
||||
public void setRedisFlushMode(RedisFlushMode redisFlushMode) {
|
||||
@@ -374,8 +366,7 @@ public class RedisOperationsSessionRepository implements
|
||||
}
|
||||
|
||||
private void configureSessionChannels() {
|
||||
this.sessionCreatedChannelPrefix = this.namespace + "event:" + this.database
|
||||
+ ":created:";
|
||||
this.sessionCreatedChannelPrefix = this.namespace + "event:" + this.database + ":created:";
|
||||
this.sessionDeletedChannel = "__keyevent@" + this.database + "__:del";
|
||||
this.sessionExpiredChannel = "__keyevent@" + this.database + "__:expired";
|
||||
}
|
||||
@@ -409,16 +400,13 @@ public class RedisOperationsSessionRepository implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, RedisSession> findByIndexNameAndIndexValue(String indexName,
|
||||
String indexValue) {
|
||||
public Map<String, RedisSession> findByIndexNameAndIndexValue(String indexName, String indexValue) {
|
||||
if (!PRINCIPAL_NAME_INDEX_NAME.equals(indexName)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
String principalKey = getPrincipalKey(indexValue);
|
||||
Set<Object> sessionIds = this.sessionRedisOperations.boundSetOps(principalKey)
|
||||
.members();
|
||||
Map<String, RedisSession> sessions = new HashMap<>(
|
||||
sessionIds.size());
|
||||
Set<Object> sessionIds = this.sessionRedisOperations.boundSetOps(principalKey).members();
|
||||
Map<String, RedisSession> sessions = new HashMap<>(sessionIds.size());
|
||||
for (Object id : sessionIds) {
|
||||
RedisSession session = findById((String) id);
|
||||
if (session != null) {
|
||||
@@ -463,9 +451,7 @@ public class RedisOperationsSessionRepository implements
|
||||
loaded.setLastAccessedTime(Instant.ofEpochMilli((long) entry.getValue()));
|
||||
}
|
||||
else if (key.startsWith(RedisSessionMapper.ATTRIBUTE_PREFIX)) {
|
||||
loaded.setAttribute(
|
||||
key.substring(RedisSessionMapper.ATTRIBUTE_PREFIX.length()),
|
||||
entry.getValue());
|
||||
loaded.setAttribute(key.substring(RedisSessionMapper.ATTRIBUTE_PREFIX.length()), entry.getValue());
|
||||
}
|
||||
}
|
||||
return loaded;
|
||||
@@ -490,10 +476,8 @@ public class RedisOperationsSessionRepository implements
|
||||
|
||||
@Override
|
||||
public RedisSession createSession() {
|
||||
Duration maxInactiveInterval = Duration
|
||||
.ofSeconds((this.defaultMaxInactiveInterval != null)
|
||||
? this.defaultMaxInactiveInterval
|
||||
: MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS);
|
||||
Duration maxInactiveInterval = Duration.ofSeconds((this.defaultMaxInactiveInterval != null)
|
||||
? this.defaultMaxInactiveInterval : MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS);
|
||||
RedisSession session = new RedisSession(maxInactiveInterval);
|
||||
session.flushImmediateIfNecessary();
|
||||
return session;
|
||||
@@ -509,8 +493,7 @@ public class RedisOperationsSessionRepository implements
|
||||
|
||||
if (channel.startsWith(this.sessionCreatedChannelPrefix)) {
|
||||
// TODO: is this thread safe?
|
||||
Map<Object, Object> loaded = (Map<Object, Object>) this.defaultSerializer
|
||||
.deserialize(message.getBody());
|
||||
Map<Object, Object> loaded = (Map<Object, Object>) this.defaultSerializer.deserialize(message.getBody());
|
||||
handleCreated(loaded, channel);
|
||||
return;
|
||||
}
|
||||
@@ -529,8 +512,7 @@ public class RedisOperationsSessionRepository implements
|
||||
RedisSession session = getSession(sessionId, true);
|
||||
|
||||
if (session == null) {
|
||||
logger.warn("Unable to publish SessionDestroyedEvent for session "
|
||||
+ sessionId);
|
||||
logger.warn("Unable to publish SessionDestroyedEvent for session " + sessionId);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -553,8 +535,7 @@ public class RedisOperationsSessionRepository implements
|
||||
String sessionId = session.getId();
|
||||
String principal = PRINCIPAL_NAME_RESOLVER.resolvePrincipal(session);
|
||||
if (principal != null) {
|
||||
this.sessionRedisOperations.boundSetOps(getPrincipalKey(principal))
|
||||
.remove(sessionId);
|
||||
this.sessionRedisOperations.boundSetOps(getPrincipalKey(principal)).remove(sessionId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -589,7 +570,6 @@ public class RedisOperationsSessionRepository implements
|
||||
|
||||
/**
|
||||
* Gets the Hash key for this session by prefixing it appropriately.
|
||||
*
|
||||
* @param sessionId the session id
|
||||
* @return the Hash key for this session by prefixing it appropriately.
|
||||
*/
|
||||
@@ -598,8 +578,7 @@ public class RedisOperationsSessionRepository implements
|
||||
}
|
||||
|
||||
String getPrincipalKey(String principalName) {
|
||||
return this.namespace + "index:"
|
||||
+ FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME + ":"
|
||||
return this.namespace + "index:" + FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME + ":"
|
||||
+ principalName;
|
||||
}
|
||||
|
||||
@@ -650,15 +629,13 @@ public class RedisOperationsSessionRepository implements
|
||||
* @param sessionId the id of the {@link Session} to work with
|
||||
* @return the {@link BoundHashOperations} to operate on a {@link Session}
|
||||
*/
|
||||
private BoundHashOperations<Object, Object, Object> getSessionBoundHashOperations(
|
||||
String sessionId) {
|
||||
private BoundHashOperations<Object, Object, Object> getSessionBoundHashOperations(String sessionId) {
|
||||
String key = getSessionKey(sessionId);
|
||||
return this.sessionRedisOperations.boundHashOps(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the key for the specified session attribute.
|
||||
*
|
||||
* @param attributeName the attribute name
|
||||
* @return the attribute key name
|
||||
*/
|
||||
@@ -676,35 +653,36 @@ public class RedisOperationsSessionRepository implements
|
||||
* @since 1.0
|
||||
*/
|
||||
final class RedisSession implements Session {
|
||||
|
||||
private final MapSession cached;
|
||||
|
||||
private Instant originalLastAccessTime;
|
||||
|
||||
private Map<String, Object> delta = new HashMap<>();
|
||||
|
||||
private boolean isNew;
|
||||
|
||||
private String originalPrincipalName;
|
||||
|
||||
private String originalSessionId;
|
||||
|
||||
/**
|
||||
* Creates a new instance ensuring to mark all of the new attributes to be
|
||||
* persisted in the next save operation.
|
||||
*
|
||||
* @param maxInactiveInterval the amount of time that the {@link Session} should
|
||||
* be kept alive between client requests.
|
||||
*/
|
||||
RedisSession(Duration maxInactiveInterval) {
|
||||
this(new MapSession());
|
||||
this.cached.setMaxInactiveInterval(maxInactiveInterval);
|
||||
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.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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance from the provided {@link MapSession}.
|
||||
*
|
||||
* @param cached the {@link MapSession} that represents the persisted session that
|
||||
* was retrieved. Cannot be null.
|
||||
*/
|
||||
@@ -722,8 +700,7 @@ public class RedisOperationsSessionRepository implements
|
||||
@Override
|
||||
public void setLastAccessedTime(Instant lastAccessedTime) {
|
||||
this.cached.setLastAccessedTime(lastAccessedTime);
|
||||
this.putAndFlush(RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
|
||||
getLastAccessedTime().toEpochMilli());
|
||||
this.putAndFlush(RedisSessionMapper.LAST_ACCESSED_TIME_KEY, getLastAccessedTime().toEpochMilli());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -758,8 +735,7 @@ public class RedisOperationsSessionRepository implements
|
||||
@Override
|
||||
public void setMaxInactiveInterval(Duration interval) {
|
||||
this.cached.setMaxInactiveInterval(interval);
|
||||
this.putAndFlush(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY,
|
||||
(int) getMaxInactiveInterval().getSeconds());
|
||||
this.putAndFlush(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY, (int) getMaxInactiveInterval().getSeconds());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -817,33 +793,27 @@ public class RedisOperationsSessionRepository implements
|
||||
getSessionBoundHashOperations(sessionId).putAll(this.delta);
|
||||
String principalSessionKey = getSessionAttrNameKey(
|
||||
FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME);
|
||||
String securityPrincipalSessionKey = getSessionAttrNameKey(
|
||||
SPRING_SECURITY_CONTEXT);
|
||||
if (this.delta.containsKey(principalSessionKey)
|
||||
|| this.delta.containsKey(securityPrincipalSessionKey)) {
|
||||
String securityPrincipalSessionKey = getSessionAttrNameKey(SPRING_SECURITY_CONTEXT);
|
||||
if (this.delta.containsKey(principalSessionKey) || this.delta.containsKey(securityPrincipalSessionKey)) {
|
||||
if (this.originalPrincipalName != null) {
|
||||
String originalPrincipalRedisKey = getPrincipalKey(
|
||||
this.originalPrincipalName);
|
||||
RedisOperationsSessionRepository.this.sessionRedisOperations
|
||||
.boundSetOps(originalPrincipalRedisKey).remove(sessionId);
|
||||
String originalPrincipalRedisKey = getPrincipalKey(this.originalPrincipalName);
|
||||
RedisOperationsSessionRepository.this.sessionRedisOperations.boundSetOps(originalPrincipalRedisKey)
|
||||
.remove(sessionId);
|
||||
}
|
||||
String principal = PRINCIPAL_NAME_RESOLVER.resolvePrincipal(this);
|
||||
this.originalPrincipalName = principal;
|
||||
if (principal != null) {
|
||||
String principalRedisKey = getPrincipalKey(principal);
|
||||
RedisOperationsSessionRepository.this.sessionRedisOperations
|
||||
.boundSetOps(principalRedisKey).add(sessionId);
|
||||
RedisOperationsSessionRepository.this.sessionRedisOperations.boundSetOps(principalRedisKey)
|
||||
.add(sessionId);
|
||||
}
|
||||
}
|
||||
|
||||
this.delta = new HashMap<>(this.delta.size());
|
||||
|
||||
Long originalExpiration = (this.originalLastAccessTime != null)
|
||||
? this.originalLastAccessTime.plus(getMaxInactiveInterval())
|
||||
.toEpochMilli()
|
||||
: null;
|
||||
RedisOperationsSessionRepository.this.expirationPolicy
|
||||
.onExpirationUpdated(originalExpiration, this);
|
||||
? this.originalLastAccessTime.plus(getMaxInactiveInterval()).toEpochMilli() : null;
|
||||
RedisOperationsSessionRepository.this.expirationPolicy.onExpirationUpdated(originalExpiration, this);
|
||||
}
|
||||
|
||||
private void saveChangeSessionId() {
|
||||
@@ -855,8 +825,8 @@ public class RedisOperationsSessionRepository implements
|
||||
String originalSessionIdKey = getSessionKey(this.originalSessionId);
|
||||
String sessionIdKey = getSessionKey(sessionId);
|
||||
try {
|
||||
RedisOperationsSessionRepository.this.sessionRedisOperations
|
||||
.rename(originalSessionIdKey, sessionIdKey);
|
||||
RedisOperationsSessionRepository.this.sessionRedisOperations.rename(originalSessionIdKey,
|
||||
sessionIdKey);
|
||||
}
|
||||
catch (NonTransientDataAccessException ex) {
|
||||
handleErrNoSuchKeyError(ex);
|
||||
@@ -864,8 +834,7 @@ public class RedisOperationsSessionRepository implements
|
||||
String originalExpiredKey = getExpiredKey(this.originalSessionId);
|
||||
String expiredKey = getExpiredKey(sessionId);
|
||||
try {
|
||||
RedisOperationsSessionRepository.this.sessionRedisOperations
|
||||
.rename(originalExpiredKey, expiredKey);
|
||||
RedisOperationsSessionRepository.this.sessionRedisOperations.rename(originalExpiredKey, expiredKey);
|
||||
}
|
||||
catch (NonTransientDataAccessException ex) {
|
||||
handleErrNoSuchKeyError(ex);
|
||||
@@ -875,8 +844,7 @@ public class RedisOperationsSessionRepository implements
|
||||
}
|
||||
|
||||
private void handleErrNoSuchKeyError(NonTransientDataAccessException ex) {
|
||||
if (!"ERR no such key"
|
||||
.equals(NestedExceptionUtils.getMostSpecificCause(ex).getMessage())) {
|
||||
if (!"ERR no such key".equals(NestedExceptionUtils.getMostSpecificCause(ex).getMessage())) {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
@@ -887,6 +855,7 @@ public class RedisOperationsSessionRepository implements
|
||||
* Principal name resolver helper class.
|
||||
*/
|
||||
static class PrincipalNameResolver {
|
||||
|
||||
private SpelExpressionParser parser = new SpelExpressionParser();
|
||||
|
||||
public String resolvePrincipal(Session session) {
|
||||
@@ -896,12 +865,12 @@ public class RedisOperationsSessionRepository implements
|
||||
}
|
||||
Object authentication = session.getAttribute(SPRING_SECURITY_CONTEXT);
|
||||
if (authentication != null) {
|
||||
Expression expression = this.parser
|
||||
.parseExpression("authentication?.name");
|
||||
Expression expression = this.parser.parseExpression("authentication?.name");
|
||||
return expression.getValue(authentication, String.class);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2017 the original author or authors.
|
||||
* 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.
|
||||
@@ -48,11 +48,12 @@ import org.springframework.session.data.redis.RedisOperationsSessionRepository.R
|
||||
*/
|
||||
final class RedisSessionExpirationPolicy {
|
||||
|
||||
private static final Log logger = LogFactory
|
||||
.getLog(RedisSessionExpirationPolicy.class);
|
||||
private static final Log logger = LogFactory.getLog(RedisSessionExpirationPolicy.class);
|
||||
|
||||
private final RedisOperations<Object, Object> redis;
|
||||
|
||||
private final Function<Long, String> lookupExpirationKey;
|
||||
|
||||
private final Function<String, String> lookupSessionKey;
|
||||
|
||||
RedisSessionExpirationPolicy(RedisOperations<Object, Object> sessionRedisOperations,
|
||||
@@ -92,12 +93,10 @@ final class RedisSessionExpirationPolicy {
|
||||
}
|
||||
|
||||
String expireKey = getExpirationKey(toExpire);
|
||||
BoundSetOperations<Object, Object> expireOperations = this.redis
|
||||
.boundSetOps(expireKey);
|
||||
BoundSetOperations<Object, Object> expireOperations = this.redis.boundSetOps(expireKey);
|
||||
expireOperations.add(keyToExpire);
|
||||
|
||||
long fiveMinutesAfterExpires = sessionExpireInSeconds
|
||||
+ TimeUnit.MINUTES.toSeconds(5);
|
||||
long fiveMinutesAfterExpires = sessionExpireInSeconds + TimeUnit.MINUTES.toSeconds(5);
|
||||
|
||||
expireOperations.expire(fiveMinutesAfterExpires, TimeUnit.SECONDS);
|
||||
if (sessionExpireInSeconds == 0) {
|
||||
@@ -105,11 +104,9 @@ final class RedisSessionExpirationPolicy {
|
||||
}
|
||||
else {
|
||||
this.redis.boundValueOps(sessionKey).append("");
|
||||
this.redis.boundValueOps(sessionKey).expire(sessionExpireInSeconds,
|
||||
TimeUnit.SECONDS);
|
||||
this.redis.boundValueOps(sessionKey).expire(sessionExpireInSeconds, TimeUnit.SECONDS);
|
||||
}
|
||||
this.redis.boundHashOps(getSessionKey(session.getId()))
|
||||
.expire(fiveMinutesAfterExpires, TimeUnit.SECONDS);
|
||||
this.redis.boundHashOps(getSessionKey(session.getId())).expire(fiveMinutesAfterExpires, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
String getExpirationKey(long expires) {
|
||||
@@ -141,7 +138,6 @@ final class RedisSessionExpirationPolicy {
|
||||
* By trying to access the session we only trigger a deletion if it the TTL is
|
||||
* expired. This is done to handle
|
||||
* https://github.com/spring-projects/spring-session/issues/93
|
||||
*
|
||||
* @param key the key
|
||||
*/
|
||||
private void touch(String key) {
|
||||
@@ -171,4 +167,5 @@ final class RedisSessionExpirationPolicy {
|
||||
date.clear(Calendar.MILLISECOND);
|
||||
return date.getTimeInMillis();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,15 +38,14 @@ import org.springframework.util.Assert;
|
||||
* @author Vedran Pavic
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public class SimpleRedisOperationsSessionRepository implements
|
||||
SessionRepository<SimpleRedisOperationsSessionRepository.RedisSession> {
|
||||
public class SimpleRedisOperationsSessionRepository
|
||||
implements SessionRepository<SimpleRedisOperationsSessionRepository.RedisSession> {
|
||||
|
||||
private static final String DEFAULT_KEY_NAMESPACE = "spring:session:";
|
||||
|
||||
private final RedisOperations<String, Object> sessionRedisOperations;
|
||||
|
||||
private Duration defaultMaxInactiveInterval = Duration
|
||||
.ofSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS);
|
||||
private Duration defaultMaxInactiveInterval = Duration.ofSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS);
|
||||
|
||||
private String keyNamespace = DEFAULT_KEY_NAMESPACE;
|
||||
|
||||
@@ -55,10 +54,9 @@ public class SimpleRedisOperationsSessionRepository implements
|
||||
/**
|
||||
* Create a new {@link SimpleRedisOperationsSessionRepository} instance.
|
||||
* @param sessionRedisOperations the {@link RedisOperations} to use for managing
|
||||
* sessions
|
||||
* sessions
|
||||
*/
|
||||
public SimpleRedisOperationsSessionRepository(
|
||||
RedisOperations<String, Object> sessionRedisOperations) {
|
||||
public SimpleRedisOperationsSessionRepository(RedisOperations<String, Object> sessionRedisOperations) {
|
||||
Assert.notNull(sessionRedisOperations, "sessionRedisOperations mut not be null");
|
||||
this.sessionRedisOperations = sessionRedisOperations;
|
||||
}
|
||||
@@ -68,8 +66,7 @@ public class SimpleRedisOperationsSessionRepository implements
|
||||
* @param defaultMaxInactiveInterval the default maxInactiveInterval
|
||||
*/
|
||||
public void setDefaultMaxInactiveInterval(Duration defaultMaxInactiveInterval) {
|
||||
Assert.notNull(defaultMaxInactiveInterval,
|
||||
"defaultMaxInactiveInterval must not be null");
|
||||
Assert.notNull(defaultMaxInactiveInterval, "defaultMaxInactiveInterval must not be null");
|
||||
this.defaultMaxInactiveInterval = defaultMaxInactiveInterval;
|
||||
}
|
||||
|
||||
@@ -101,9 +98,7 @@ public class SimpleRedisOperationsSessionRepository implements
|
||||
@Override
|
||||
public void save(RedisSession session) {
|
||||
if (!session.isNew) {
|
||||
String key = getSessionKey(
|
||||
session.hasChangedSessionId() ? session.originalSessionId
|
||||
: session.getId());
|
||||
String key = getSessionKey(session.hasChangedSessionId() ? session.originalSessionId : session.getId());
|
||||
Boolean sessionExists = this.sessionRedisOperations.hasKey(key);
|
||||
if (sessionExists == null || !sessionExists) {
|
||||
throw new IllegalStateException("Session was invalidated");
|
||||
@@ -115,8 +110,7 @@ public class SimpleRedisOperationsSessionRepository implements
|
||||
@Override
|
||||
public RedisSession findById(String sessionId) {
|
||||
String key = getSessionKey(sessionId);
|
||||
Map<String, Object> entries = this.sessionRedisOperations
|
||||
.<String, Object>opsForHash().entries(key);
|
||||
Map<String, Object> entries = this.sessionRedisOperations.<String, Object>opsForHash().entries(key);
|
||||
if (entries.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
@@ -162,12 +156,9 @@ public class SimpleRedisOperationsSessionRepository implements
|
||||
RedisSession(Duration maxInactiveInterval) {
|
||||
this(new MapSession());
|
||||
this.cached.setMaxInactiveInterval(maxInactiveInterval);
|
||||
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.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;
|
||||
}
|
||||
|
||||
@@ -199,8 +190,7 @@ public class SimpleRedisOperationsSessionRepository implements
|
||||
@Override
|
||||
public void setAttribute(String attributeName, Object attributeValue) {
|
||||
this.cached.setAttribute(attributeName, attributeValue);
|
||||
putAttribute(RedisSessionMapper.ATTRIBUTE_PREFIX + attributeName,
|
||||
attributeValue);
|
||||
putAttribute(RedisSessionMapper.ATTRIBUTE_PREFIX + attributeName, attributeValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -216,8 +206,7 @@ public class SimpleRedisOperationsSessionRepository implements
|
||||
@Override
|
||||
public void setLastAccessedTime(Instant lastAccessedTime) {
|
||||
this.cached.setLastAccessedTime(lastAccessedTime);
|
||||
putAttribute(RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
|
||||
getLastAccessedTime().toEpochMilli());
|
||||
putAttribute(RedisSessionMapper.LAST_ACCESSED_TIME_KEY, getLastAccessedTime().toEpochMilli());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -228,8 +217,7 @@ public class SimpleRedisOperationsSessionRepository implements
|
||||
@Override
|
||||
public void setMaxInactiveInterval(Duration interval) {
|
||||
this.cached.setMaxInactiveInterval(interval);
|
||||
putAttribute(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY,
|
||||
(int) getMaxInactiveInterval().getSeconds());
|
||||
putAttribute(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY, (int) getMaxInactiveInterval().getSeconds());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -265,8 +253,8 @@ public class SimpleRedisOperationsSessionRepository implements
|
||||
if (!this.isNew) {
|
||||
String originalSessionIdKey = getSessionKey(this.originalSessionId);
|
||||
String sessionIdKey = getSessionKey(getId());
|
||||
SimpleRedisOperationsSessionRepository.this.sessionRedisOperations
|
||||
.rename(originalSessionIdKey, sessionIdKey);
|
||||
SimpleRedisOperationsSessionRepository.this.sessionRedisOperations.rename(originalSessionIdKey,
|
||||
sessionIdKey);
|
||||
}
|
||||
this.originalSessionId = getId();
|
||||
}
|
||||
@@ -277,13 +265,11 @@ public class SimpleRedisOperationsSessionRepository implements
|
||||
return;
|
||||
}
|
||||
String key = getSessionKey(getId());
|
||||
SimpleRedisOperationsSessionRepository.this.sessionRedisOperations
|
||||
.opsForHash().putAll(key, new HashMap<>(this.delta));
|
||||
SimpleRedisOperationsSessionRepository.this.sessionRedisOperations
|
||||
.expireAt(key,
|
||||
Date.from(Instant
|
||||
.ofEpochMilli(getLastAccessedTime().toEpochMilli())
|
||||
.plusSeconds(getMaxInactiveInterval().getSeconds())));
|
||||
SimpleRedisOperationsSessionRepository.this.sessionRedisOperations.opsForHash().putAll(key,
|
||||
new HashMap<>(this.delta));
|
||||
SimpleRedisOperationsSessionRepository.this.sessionRedisOperations.expireAt(key,
|
||||
Date.from(Instant.ofEpochMilli(getLastAccessedTime().toEpochMilli())
|
||||
.plusSeconds(getMaxInactiveInterval().getSeconds())));
|
||||
this.delta.clear();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2017 the original author or authors.
|
||||
* 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.
|
||||
@@ -33,8 +33,7 @@ import org.springframework.session.data.redis.RedisOperationsSessionRepository;
|
||||
* @author Vedran Pavic
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE,
|
||||
ElementType.ANNOTATION_TYPE })
|
||||
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Qualifier
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2018 the original author or authors.
|
||||
* 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.
|
||||
@@ -33,8 +33,7 @@ import org.springframework.beans.factory.annotation.Value;
|
||||
* @see org.springframework.session.data.redis.ReactiveRedisOperationsSessionRepository#getSessionRedisOperations()
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER,
|
||||
ElementType.ANNOTATION_TYPE })
|
||||
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Value("#{sessionRepository.sessionRedisOperations}")
|
||||
|
||||
@@ -75,8 +75,7 @@ import org.springframework.util.StringValueResolver;
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableScheduling
|
||||
public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguration
|
||||
implements BeanClassLoaderAware, EmbeddedValueResolverAware, ImportAware,
|
||||
SchedulingConfigurer {
|
||||
implements BeanClassLoaderAware, EmbeddedValueResolverAware, ImportAware, SchedulingConfigurer {
|
||||
|
||||
static final String DEFAULT_CLEANUP_CRON = "0 * * * * *";
|
||||
|
||||
@@ -107,14 +106,12 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio
|
||||
@Bean
|
||||
public RedisOperationsSessionRepository sessionRepository() {
|
||||
RedisTemplate<Object, Object> redisTemplate = createRedisTemplate();
|
||||
RedisOperationsSessionRepository sessionRepository = new RedisOperationsSessionRepository(
|
||||
redisTemplate);
|
||||
RedisOperationsSessionRepository sessionRepository = new RedisOperationsSessionRepository(redisTemplate);
|
||||
sessionRepository.setApplicationEventPublisher(this.applicationEventPublisher);
|
||||
if (this.defaultRedisSerializer != null) {
|
||||
sessionRepository.setDefaultSerializer(this.defaultRedisSerializer);
|
||||
}
|
||||
sessionRepository
|
||||
.setDefaultMaxInactiveInterval(this.maxInactiveIntervalInSeconds);
|
||||
sessionRepository.setDefaultMaxInactiveInterval(this.maxInactiveIntervalInSeconds);
|
||||
if (StringUtils.hasText(this.redisNamespace)) {
|
||||
sessionRepository.setRedisKeyNamespace(this.redisNamespace);
|
||||
}
|
||||
@@ -136,19 +133,16 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio
|
||||
container.setSubscriptionExecutor(this.redisSubscriptionExecutor);
|
||||
}
|
||||
container.addMessageListener(sessionRepository,
|
||||
Arrays.asList(
|
||||
new ChannelTopic(sessionRepository.getSessionDeletedChannel()),
|
||||
Arrays.asList(new ChannelTopic(sessionRepository.getSessionDeletedChannel()),
|
||||
new ChannelTopic(sessionRepository.getSessionExpiredChannel())));
|
||||
container.addMessageListener(sessionRepository,
|
||||
Collections.singletonList(new PatternTopic(
|
||||
sessionRepository.getSessionCreatedChannelPrefix() + "*")));
|
||||
Collections.singletonList(new PatternTopic(sessionRepository.getSessionCreatedChannelPrefix() + "*")));
|
||||
return container;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public InitializingBean enableRedisKeyspaceNotificationsInitializer() {
|
||||
return new EnableRedisKeyspaceNotificationsInitializer(
|
||||
this.redisConnectionFactory, this.configureRedisAction);
|
||||
return new EnableRedisKeyspaceNotificationsInitializer(this.redisConnectionFactory, this.configureRedisAction);
|
||||
}
|
||||
|
||||
public void setMaxInactiveIntervalInSeconds(int maxInactiveIntervalInSeconds) {
|
||||
@@ -170,7 +164,6 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio
|
||||
|
||||
/**
|
||||
* Sets the action to perform for configuring Redis.
|
||||
*
|
||||
* @param configureRedisAction the configureRedis to set. The default is
|
||||
* {@link ConfigureNotifyKeyspaceEventsAction}.
|
||||
*/
|
||||
@@ -183,8 +176,7 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio
|
||||
public void setRedisConnectionFactory(
|
||||
@SpringSessionRedisConnectionFactory ObjectProvider<RedisConnectionFactory> springSessionRedisConnectionFactory,
|
||||
ObjectProvider<RedisConnectionFactory> redisConnectionFactory) {
|
||||
RedisConnectionFactory redisConnectionFactoryToUse = springSessionRedisConnectionFactory
|
||||
.getIfAvailable();
|
||||
RedisConnectionFactory redisConnectionFactoryToUse = springSessionRedisConnectionFactory.getIfAvailable();
|
||||
if (redisConnectionFactoryToUse == null) {
|
||||
redisConnectionFactoryToUse = redisConnectionFactory.getObject();
|
||||
}
|
||||
@@ -193,14 +185,12 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio
|
||||
|
||||
@Autowired(required = false)
|
||||
@Qualifier("springSessionDefaultRedisSerializer")
|
||||
public void setDefaultRedisSerializer(
|
||||
RedisSerializer<Object> defaultRedisSerializer) {
|
||||
public void setDefaultRedisSerializer(RedisSerializer<Object> defaultRedisSerializer) {
|
||||
this.defaultRedisSerializer = defaultRedisSerializer;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setApplicationEventPublisher(
|
||||
ApplicationEventPublisher applicationEventPublisher) {
|
||||
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
|
||||
this.applicationEventPublisher = applicationEventPublisher;
|
||||
}
|
||||
|
||||
@@ -231,12 +221,10 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio
|
||||
Map<String, Object> attributeMap = importMetadata
|
||||
.getAnnotationAttributes(EnableRedisHttpSession.class.getName());
|
||||
AnnotationAttributes attributes = AnnotationAttributes.fromMap(attributeMap);
|
||||
this.maxInactiveIntervalInSeconds = attributes
|
||||
.getNumber("maxInactiveIntervalInSeconds");
|
||||
this.maxInactiveIntervalInSeconds = attributes.getNumber("maxInactiveIntervalInSeconds");
|
||||
String redisNamespaceValue = attributes.getString("redisNamespace");
|
||||
if (StringUtils.hasText(redisNamespaceValue)) {
|
||||
this.redisNamespace = this.embeddedValueResolver
|
||||
.resolveStringValue(redisNamespaceValue);
|
||||
this.redisNamespace = this.embeddedValueResolver.resolveStringValue(redisNamespaceValue);
|
||||
}
|
||||
this.redisFlushMode = attributes.getEnum("redisFlushMode");
|
||||
String cleanupCron = attributes.getString("cleanupCron");
|
||||
@@ -247,8 +235,7 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio
|
||||
|
||||
@Override
|
||||
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
|
||||
taskRegistrar.addCronTask(() -> sessionRepository().cleanupExpiredSessions(),
|
||||
this.cleanupCron);
|
||||
taskRegistrar.addCronTask(() -> sessionRepository().cleanupExpiredSessions(), this.cleanupCron);
|
||||
}
|
||||
|
||||
private RedisTemplate<Object, Object> createRedisTemplate() {
|
||||
@@ -289,8 +276,7 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio
|
||||
|
||||
private ConfigureRedisAction configure;
|
||||
|
||||
EnableRedisKeyspaceNotificationsInitializer(
|
||||
RedisConnectionFactory connectionFactory,
|
||||
EnableRedisKeyspaceNotificationsInitializer(RedisConnectionFactory connectionFactory,
|
||||
ConfigureRedisAction configure) {
|
||||
this.connectionFactory = connectionFactory;
|
||||
this.configure = configure;
|
||||
@@ -310,8 +296,7 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio
|
||||
connection.close();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
LogFactory.getLog(getClass()).error("Error closing RedisConnection",
|
||||
ex);
|
||||
LogFactory.getLog(getClass()).error("Error closing RedisConnection", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,8 +76,7 @@ public class RedisWebSessionConfiguration extends SpringWebSessionConfiguration
|
||||
ReactiveRedisTemplate<String, Object> reactiveRedisTemplate = createReactiveRedisTemplate();
|
||||
ReactiveRedisOperationsSessionRepository sessionRepository = new ReactiveRedisOperationsSessionRepository(
|
||||
reactiveRedisTemplate);
|
||||
sessionRepository
|
||||
.setDefaultMaxInactiveInterval(this.maxInactiveIntervalInSeconds);
|
||||
sessionRepository.setDefaultMaxInactiveInterval(this.maxInactiveIntervalInSeconds);
|
||||
if (StringUtils.hasText(this.redisNamespace)) {
|
||||
sessionRepository.setRedisKeyNamespace(this.redisNamespace);
|
||||
}
|
||||
@@ -112,8 +111,7 @@ public class RedisWebSessionConfiguration extends SpringWebSessionConfiguration
|
||||
|
||||
@Autowired(required = false)
|
||||
@Qualifier("springSessionDefaultRedisSerializer")
|
||||
public void setDefaultRedisSerializer(
|
||||
RedisSerializer<Object> defaultRedisSerializer) {
|
||||
public void setDefaultRedisSerializer(RedisSerializer<Object> defaultRedisSerializer) {
|
||||
this.defaultRedisSerializer = defaultRedisSerializer;
|
||||
}
|
||||
|
||||
@@ -132,26 +130,22 @@ public class RedisWebSessionConfiguration extends SpringWebSessionConfiguration
|
||||
Map<String, Object> attributeMap = importMetadata
|
||||
.getAnnotationAttributes(EnableRedisWebSession.class.getName());
|
||||
AnnotationAttributes attributes = AnnotationAttributes.fromMap(attributeMap);
|
||||
this.maxInactiveIntervalInSeconds = attributes
|
||||
.getNumber("maxInactiveIntervalInSeconds");
|
||||
this.maxInactiveIntervalInSeconds = attributes.getNumber("maxInactiveIntervalInSeconds");
|
||||
String redisNamespaceValue = attributes.getString("redisNamespace");
|
||||
if (StringUtils.hasText(redisNamespaceValue)) {
|
||||
this.redisNamespace = this.embeddedValueResolver
|
||||
.resolveStringValue(redisNamespaceValue);
|
||||
this.redisNamespace = this.embeddedValueResolver.resolveStringValue(redisNamespaceValue);
|
||||
}
|
||||
this.redisFlushMode = attributes.getEnum("redisFlushMode");
|
||||
}
|
||||
|
||||
private ReactiveRedisTemplate<String, Object> createReactiveRedisTemplate() {
|
||||
RedisSerializer<String> keySerializer = new StringRedisSerializer();
|
||||
RedisSerializer<Object> defaultSerializer = (this.defaultRedisSerializer != null)
|
||||
? this.defaultRedisSerializer
|
||||
RedisSerializer<Object> defaultSerializer = (this.defaultRedisSerializer != null) ? this.defaultRedisSerializer
|
||||
: new JdkSerializationRedisSerializer(this.classLoader);
|
||||
RedisSerializationContext<String, Object> serializationContext = RedisSerializationContext
|
||||
.<String, Object>newSerializationContext(defaultSerializer)
|
||||
.key(keySerializer).hashKey(keySerializer).build();
|
||||
return new ReactiveRedisTemplate<>(this.redisConnectionFactory,
|
||||
serializationContext);
|
||||
.<String, Object>newSerializationContext(defaultSerializer).key(keySerializer).hashKey(keySerializer)
|
||||
.build();
|
||||
return new ReactiveRedisTemplate<>(this.redisConnectionFactory, serializationContext);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -49,28 +49,24 @@ import static org.mockito.Mockito.verifyZeroInteractions;
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
public class ReactiveRedisOperationsSessionRepositoryTests {
|
||||
class ReactiveRedisOperationsSessionRepositoryTests {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private ReactiveRedisOperations<String, Object> redisOperations = mock(
|
||||
ReactiveRedisOperations.class);
|
||||
private ReactiveRedisOperations<String, Object> redisOperations = mock(ReactiveRedisOperations.class);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private ReactiveHashOperations<String, Object, Object> hashOperations = mock(
|
||||
ReactiveHashOperations.class);
|
||||
private ReactiveHashOperations<String, Object, Object> hashOperations = mock(ReactiveHashOperations.class);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private ArgumentCaptor<Map<String, Object>> delta = ArgumentCaptor
|
||||
.forClass(Map.class);
|
||||
private ArgumentCaptor<Map<String, Object>> delta = ArgumentCaptor.forClass(Map.class);
|
||||
|
||||
private ReactiveRedisOperationsSessionRepository repository;
|
||||
|
||||
private MapSession cached;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
this.repository = new ReactiveRedisOperationsSessionRepository(
|
||||
this.redisOperations);
|
||||
void setUp() {
|
||||
this.repository = new ReactiveRedisOperationsSessionRepository(this.redisOperations);
|
||||
|
||||
this.cached = new MapSession();
|
||||
this.cached.setId("session-id");
|
||||
@@ -79,82 +75,73 @@ public class ReactiveRedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorWithNullReactiveRedisOperations() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new ReactiveRedisOperationsSessionRepository(null))
|
||||
void constructorWithNullReactiveRedisOperations() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new ReactiveRedisOperationsSessionRepository(null))
|
||||
.withMessageContaining("sessionRedisOperations cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customRedisKeyNamespace() {
|
||||
void customRedisKeyNamespace() {
|
||||
this.repository.setRedisKeyNamespace("test");
|
||||
|
||||
assertThat(ReflectionTestUtils.getField(this.repository, "namespace"))
|
||||
.isEqualTo("test:");
|
||||
assertThat(ReflectionTestUtils.getField(this.repository, "namespace")).isEqualTo("test:");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullRedisKeyNamespace() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> this.repository.setRedisKeyNamespace(null))
|
||||
void nullRedisKeyNamespace() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.repository.setRedisKeyNamespace(null))
|
||||
.withMessage("namespace cannot be null or empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void emptyRedisKeyNamespace() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> this.repository.setRedisKeyNamespace(""))
|
||||
void emptyRedisKeyNamespace() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.repository.setRedisKeyNamespace(""))
|
||||
.withMessage("namespace cannot be null or empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customMaxInactiveInterval() {
|
||||
void customMaxInactiveInterval() {
|
||||
this.repository.setDefaultMaxInactiveInterval(600);
|
||||
|
||||
assertThat(ReflectionTestUtils.getField(this.repository,
|
||||
"defaultMaxInactiveInterval")).isEqualTo(600);
|
||||
assertThat(ReflectionTestUtils.getField(this.repository, "defaultMaxInactiveInterval")).isEqualTo(600);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customRedisFlushMode() {
|
||||
void customRedisFlushMode() {
|
||||
this.repository.setRedisFlushMode(RedisFlushMode.IMMEDIATE);
|
||||
|
||||
assertThat(ReflectionTestUtils.getField(this.repository, "redisFlushMode"))
|
||||
.isEqualTo(RedisFlushMode.IMMEDIATE);
|
||||
assertThat(ReflectionTestUtils.getField(this.repository, "redisFlushMode")).isEqualTo(RedisFlushMode.IMMEDIATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullRedisFlushMode() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> this.repository.setRedisFlushMode(null))
|
||||
void nullRedisFlushMode() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.repository.setRedisFlushMode(null))
|
||||
.withMessage("redisFlushMode cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createSessionDefaultMaxInactiveInterval() {
|
||||
void createSessionDefaultMaxInactiveInterval() {
|
||||
StepVerifier.create(this.repository.createSession())
|
||||
.consumeNextWith((session) -> assertThat(session.getMaxInactiveInterval())
|
||||
.isEqualTo(Duration.ofSeconds(
|
||||
MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS)))
|
||||
.isEqualTo(Duration.ofSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS)))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createSessionCustomMaxInactiveInterval() {
|
||||
void createSessionCustomMaxInactiveInterval() {
|
||||
this.repository.setDefaultMaxInactiveInterval(600);
|
||||
|
||||
StepVerifier.create(this.repository.createSession())
|
||||
.consumeNextWith((session) -> assertThat(session.getMaxInactiveInterval())
|
||||
.isEqualTo(Duration.ofSeconds(600)))
|
||||
.consumeNextWith(
|
||||
(session) -> assertThat(session.getMaxInactiveInterval()).isEqualTo(Duration.ofSeconds(600)))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveNewSession() {
|
||||
void saveNewSession() {
|
||||
given(this.redisOperations.opsForHash()).willReturn(this.hashOperations);
|
||||
given(this.hashOperations.putAll(anyString(), any())).willReturn(Mono.just(true));
|
||||
given(this.redisOperations.expire(anyString(), any()))
|
||||
.willReturn(Mono.just(true));
|
||||
given(this.redisOperations.expire(anyString(), any())).willReturn(Mono.just(true));
|
||||
|
||||
RedisSession newSession = this.repository.new RedisSession();
|
||||
StepVerifier.create(this.repository.save(newSession)).verifyComplete();
|
||||
@@ -176,13 +163,11 @@ public class ReactiveRedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveSessionNothingChanged() {
|
||||
void saveSessionNothingChanged() {
|
||||
given(this.redisOperations.hasKey(anyString())).willReturn(Mono.just(true));
|
||||
given(this.redisOperations.expire(anyString(), any()))
|
||||
.willReturn(Mono.just(true));
|
||||
given(this.redisOperations.expire(anyString(), any())).willReturn(Mono.just(true));
|
||||
|
||||
RedisSession session = this.repository.new RedisSession(
|
||||
new MapSession(this.cached));
|
||||
RedisSession session = this.repository.new RedisSession(new MapSession(this.cached));
|
||||
|
||||
StepVerifier.create(this.repository.save(session)).verifyComplete();
|
||||
|
||||
@@ -192,12 +177,11 @@ public class ReactiveRedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveLastAccessChanged() {
|
||||
void saveLastAccessChanged() {
|
||||
given(this.redisOperations.hasKey(anyString())).willReturn(Mono.just(true));
|
||||
given(this.redisOperations.opsForHash()).willReturn(this.hashOperations);
|
||||
given(this.hashOperations.putAll(anyString(), any())).willReturn(Mono.just(true));
|
||||
given(this.redisOperations.expire(anyString(), any()))
|
||||
.willReturn(Mono.just(true));
|
||||
given(this.redisOperations.expire(anyString(), any())).willReturn(Mono.just(true));
|
||||
|
||||
RedisSession session = this.repository.new RedisSession(this.cached);
|
||||
session.setLastAccessedTime(Instant.ofEpochMilli(12345678L));
|
||||
@@ -210,18 +194,16 @@ public class ReactiveRedisOperationsSessionRepositoryTests {
|
||||
verifyZeroInteractions(this.redisOperations);
|
||||
verifyZeroInteractions(this.hashOperations);
|
||||
|
||||
assertThat(this.delta.getAllValues().get(0))
|
||||
.isEqualTo(map(RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
|
||||
session.getLastAccessedTime().toEpochMilli()));
|
||||
assertThat(this.delta.getAllValues().get(0)).isEqualTo(
|
||||
map(RedisSessionMapper.LAST_ACCESSED_TIME_KEY, session.getLastAccessedTime().toEpochMilli()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveSetAttribute() {
|
||||
void saveSetAttribute() {
|
||||
given(this.redisOperations.hasKey(anyString())).willReturn(Mono.just(true));
|
||||
given(this.redisOperations.opsForHash()).willReturn(this.hashOperations);
|
||||
given(this.hashOperations.putAll(anyString(), any())).willReturn(Mono.just(true));
|
||||
given(this.redisOperations.expire(anyString(), any()))
|
||||
.willReturn(Mono.just(true));
|
||||
given(this.redisOperations.expire(anyString(), any())).willReturn(Mono.just(true));
|
||||
|
||||
String attrName = "attrName";
|
||||
RedisSession session = this.repository.new RedisSession(this.cached);
|
||||
@@ -236,17 +218,15 @@ public class ReactiveRedisOperationsSessionRepositoryTests {
|
||||
verifyZeroInteractions(this.hashOperations);
|
||||
|
||||
assertThat(this.delta.getAllValues().get(0)).isEqualTo(
|
||||
map(RedisOperationsSessionRepository.getSessionAttrNameKey(attrName),
|
||||
session.getAttribute(attrName)));
|
||||
map(RedisOperationsSessionRepository.getSessionAttrNameKey(attrName), session.getAttribute(attrName)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveRemoveAttribute() {
|
||||
void saveRemoveAttribute() {
|
||||
given(this.redisOperations.hasKey(anyString())).willReturn(Mono.just(true));
|
||||
given(this.redisOperations.opsForHash()).willReturn(this.hashOperations);
|
||||
given(this.hashOperations.putAll(anyString(), any())).willReturn(Mono.just(true));
|
||||
given(this.redisOperations.expire(anyString(), any()))
|
||||
.willReturn(Mono.just(true));
|
||||
given(this.redisOperations.expire(anyString(), any())).willReturn(Mono.just(true));
|
||||
|
||||
String attrName = "attrName";
|
||||
RedisSession session = this.repository.new RedisSession(new MapSession());
|
||||
@@ -260,12 +240,12 @@ public class ReactiveRedisOperationsSessionRepositoryTests {
|
||||
verifyZeroInteractions(this.redisOperations);
|
||||
verifyZeroInteractions(this.hashOperations);
|
||||
|
||||
assertThat(this.delta.getAllValues().get(0)).isEqualTo(map(
|
||||
RedisOperationsSessionRepository.getSessionAttrNameKey(attrName), null));
|
||||
assertThat(this.delta.getAllValues().get(0))
|
||||
.isEqualTo(map(RedisOperationsSessionRepository.getSessionAttrNameKey(attrName), null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void redisSessionGetAttributes() {
|
||||
void redisSessionGetAttributes() {
|
||||
String attrName = "attrName";
|
||||
RedisSession session = this.repository.new RedisSession(this.cached);
|
||||
assertThat(session.getAttributeNames()).isEmpty();
|
||||
@@ -278,7 +258,7 @@ public class ReactiveRedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void delete() {
|
||||
void delete() {
|
||||
given(this.redisOperations.delete(anyString())).willReturn(Mono.just(1L));
|
||||
|
||||
StepVerifier.create(this.repository.deleteById("test")).verifyComplete();
|
||||
@@ -289,7 +269,7 @@ public class ReactiveRedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSessionNotFound() {
|
||||
void getSessionNotFound() {
|
||||
given(this.redisOperations.opsForHash()).willReturn(this.hashOperations);
|
||||
given(this.hashOperations.entries(anyString())).willReturn(Flux.empty());
|
||||
given(this.redisOperations.delete(anyString())).willReturn(Mono.just(0L));
|
||||
@@ -305,7 +285,7 @@ public class ReactiveRedisOperationsSessionRepositoryTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void getSessionFound() {
|
||||
void getSessionFound() {
|
||||
given(this.redisOperations.opsForHash()).willReturn(this.hashOperations);
|
||||
String attribute1 = "attribute1";
|
||||
String attribute2 = "attribute2";
|
||||
@@ -313,54 +293,38 @@ public class ReactiveRedisOperationsSessionRepositoryTests {
|
||||
expected.setLastAccessedTime(Instant.now().minusSeconds(60));
|
||||
expected.setAttribute(attribute1, "test");
|
||||
expected.setAttribute(attribute2, null);
|
||||
Map map = map(RedisSessionMapper.ATTRIBUTE_PREFIX + attribute1,
|
||||
expected.getAttribute(attribute1),
|
||||
RedisSessionMapper.ATTRIBUTE_PREFIX + attribute2,
|
||||
expected.getAttribute(attribute2), RedisSessionMapper.CREATION_TIME_KEY,
|
||||
expected.getCreationTime().toEpochMilli(),
|
||||
RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY,
|
||||
(int) expected.getMaxInactiveInterval().getSeconds(),
|
||||
RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
|
||||
expected.getLastAccessedTime().toEpochMilli());
|
||||
given(this.hashOperations.entries(anyString()))
|
||||
.willReturn(Flux.fromIterable(map.entrySet()));
|
||||
Map map = map(RedisSessionMapper.ATTRIBUTE_PREFIX + attribute1, expected.getAttribute(attribute1),
|
||||
RedisSessionMapper.ATTRIBUTE_PREFIX + attribute2, expected.getAttribute(attribute2),
|
||||
RedisSessionMapper.CREATION_TIME_KEY, expected.getCreationTime().toEpochMilli(),
|
||||
RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY, (int) expected.getMaxInactiveInterval().getSeconds(),
|
||||
RedisSessionMapper.LAST_ACCESSED_TIME_KEY, expected.getLastAccessedTime().toEpochMilli());
|
||||
given(this.hashOperations.entries(anyString())).willReturn(Flux.fromIterable(map.entrySet()));
|
||||
|
||||
StepVerifier.create(this.repository.findById("test"))
|
||||
.consumeNextWith((session) -> {
|
||||
verify(this.redisOperations).opsForHash();
|
||||
verify(this.hashOperations).entries(anyString());
|
||||
verifyZeroInteractions(this.redisOperations);
|
||||
verifyZeroInteractions(this.hashOperations);
|
||||
StepVerifier.create(this.repository.findById("test")).consumeNextWith((session) -> {
|
||||
verify(this.redisOperations).opsForHash();
|
||||
verify(this.hashOperations).entries(anyString());
|
||||
verifyZeroInteractions(this.redisOperations);
|
||||
verifyZeroInteractions(this.hashOperations);
|
||||
|
||||
assertThat(session.getId()).isEqualTo(expected.getId());
|
||||
assertThat(session.getAttributeNames())
|
||||
.isEqualTo(expected.getAttributeNames());
|
||||
assertThat(session.<String>getAttribute(attribute1))
|
||||
.isEqualTo(expected.getAttribute(attribute1));
|
||||
assertThat(session.<String>getAttribute(attribute2))
|
||||
.isEqualTo(expected.getAttribute(attribute2));
|
||||
assertThat(session.getCreationTime().truncatedTo(ChronoUnit.MILLIS))
|
||||
.isEqualTo(expected.getCreationTime()
|
||||
.truncatedTo(ChronoUnit.MILLIS));
|
||||
assertThat(session.getMaxInactiveInterval())
|
||||
.isEqualTo(expected.getMaxInactiveInterval());
|
||||
assertThat(
|
||||
session.getLastAccessedTime().truncatedTo(ChronoUnit.MILLIS))
|
||||
.isEqualTo(expected.getLastAccessedTime()
|
||||
.truncatedTo(ChronoUnit.MILLIS));
|
||||
}).verifyComplete();
|
||||
assertThat(session.getId()).isEqualTo(expected.getId());
|
||||
assertThat(session.getAttributeNames()).isEqualTo(expected.getAttributeNames());
|
||||
assertThat(session.<String>getAttribute(attribute1)).isEqualTo(expected.getAttribute(attribute1));
|
||||
assertThat(session.<String>getAttribute(attribute2)).isEqualTo(expected.getAttribute(attribute2));
|
||||
assertThat(session.getCreationTime().truncatedTo(ChronoUnit.MILLIS))
|
||||
.isEqualTo(expected.getCreationTime().truncatedTo(ChronoUnit.MILLIS));
|
||||
assertThat(session.getMaxInactiveInterval()).isEqualTo(expected.getMaxInactiveInterval());
|
||||
assertThat(session.getLastAccessedTime().truncatedTo(ChronoUnit.MILLIS))
|
||||
.isEqualTo(expected.getLastAccessedTime().truncatedTo(ChronoUnit.MILLIS));
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void getSessionExpired() {
|
||||
void getSessionExpired() {
|
||||
given(this.redisOperations.opsForHash()).willReturn(this.hashOperations);
|
||||
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()));
|
||||
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()));
|
||||
given(this.redisOperations.delete(anyString())).willReturn(Mono.just(0L));
|
||||
|
||||
StepVerifier.create(this.repository.findById("test")).verifyComplete();
|
||||
@@ -373,7 +337,7 @@ public class ReactiveRedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test // gh-1120
|
||||
public void getAttributeNamesAndRemove() {
|
||||
void getAttributeNamesAndRemove() {
|
||||
RedisSession session = this.repository.new RedisSession(this.cached);
|
||||
session.setAttribute("attribute1", "value1");
|
||||
session.setAttribute("attribute2", "value2");
|
||||
|
||||
@@ -72,27 +72,37 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public class RedisOperationsSessionRepositoryTests {
|
||||
static final String SPRING_SECURITY_CONTEXT_KEY = "SPRING_SECURITY_CONTEXT";
|
||||
class RedisOperationsSessionRepositoryTests {
|
||||
|
||||
private static final String SPRING_SECURITY_CONTEXT_KEY = "SPRING_SECURITY_CONTEXT";
|
||||
|
||||
@Mock
|
||||
RedisConnectionFactory factory;
|
||||
|
||||
@Mock
|
||||
RedisConnection connection;
|
||||
|
||||
@Mock
|
||||
RedisOperations<Object, Object> redisOperations;
|
||||
|
||||
@Mock
|
||||
BoundValueOperations<Object, Object> boundValueOperations;
|
||||
|
||||
@Mock
|
||||
BoundHashOperations<Object, Object, Object> boundHashOperations;
|
||||
|
||||
@Mock
|
||||
BoundSetOperations<Object, Object> boundSetOperations;
|
||||
|
||||
@Mock
|
||||
ApplicationEventPublisher publisher;
|
||||
|
||||
@Mock
|
||||
RedisSerializer<Object> defaultSerializer;
|
||||
|
||||
@Captor
|
||||
ArgumentCaptor<AbstractSessionEvent> event;
|
||||
|
||||
@Captor
|
||||
ArgumentCaptor<Map<String, Object>> delta;
|
||||
|
||||
@@ -101,7 +111,7 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
private RedisOperationsSessionRepository redisRepository;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
this.redisRepository = new RedisOperationsSessionRepository(this.redisOperations);
|
||||
this.redisRepository.setDefaultSerializer(this.defaultSerializer);
|
||||
@@ -113,20 +123,16 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setApplicationEventPublisherNull() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> this.redisRepository.setApplicationEventPublisher(null))
|
||||
void setApplicationEventPublisherNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.redisRepository.setApplicationEventPublisher(null))
|
||||
.withMessage("applicationEventPublisher cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenNotSaved() {
|
||||
given(this.redisOperations.boundHashOps(anyString()))
|
||||
.willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString()))
|
||||
.willReturn(this.boundSetOperations);
|
||||
given(this.redisOperations.boundValueOps(anyString()))
|
||||
.willReturn(this.boundValueOperations);
|
||||
void changeSessionIdWhenNotSaved() {
|
||||
given(this.redisOperations.boundHashOps(anyString())).willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString())).willReturn(this.boundSetOperations);
|
||||
given(this.redisOperations.boundValueOps(anyString())).willReturn(this.boundValueOperations);
|
||||
|
||||
RedisSession createSession = this.redisRepository.createSession();
|
||||
String originalId = createSession.getId();
|
||||
@@ -140,13 +146,10 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenSaved() {
|
||||
given(this.redisOperations.boundHashOps(anyString()))
|
||||
.willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString()))
|
||||
.willReturn(this.boundSetOperations);
|
||||
given(this.redisOperations.boundValueOps(anyString()))
|
||||
.willReturn(this.boundValueOperations);
|
||||
void changeSessionIdWhenSaved() {
|
||||
given(this.redisOperations.boundHashOps(anyString())).willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString())).willReturn(this.boundSetOperations);
|
||||
given(this.redisOperations.boundValueOps(anyString())).willReturn(this.boundValueOperations);
|
||||
|
||||
RedisSession session = this.redisRepository.new RedisSession(this.cached);
|
||||
session.setLastAccessedTime(session.getLastAccessedTime());
|
||||
@@ -161,30 +164,25 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createSessionDefaultMaxInactiveInterval() throws Exception {
|
||||
void createSessionDefaultMaxInactiveInterval() throws Exception {
|
||||
Session session = this.redisRepository.createSession();
|
||||
assertThat(session.getMaxInactiveInterval())
|
||||
.isEqualTo(new MapSession().getMaxInactiveInterval());
|
||||
assertThat(session.getMaxInactiveInterval()).isEqualTo(new MapSession().getMaxInactiveInterval());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createSessionCustomMaxInactiveInterval() throws Exception {
|
||||
void createSessionCustomMaxInactiveInterval() throws Exception {
|
||||
int interval = 1;
|
||||
this.redisRepository.setDefaultMaxInactiveInterval(interval);
|
||||
Session session = this.redisRepository.createSession();
|
||||
assertThat(session.getMaxInactiveInterval())
|
||||
.isEqualTo(Duration.ofSeconds(interval));
|
||||
assertThat(session.getMaxInactiveInterval()).isEqualTo(Duration.ofSeconds(interval));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveNewSession() {
|
||||
void saveNewSession() {
|
||||
RedisSession session = this.redisRepository.createSession();
|
||||
given(this.redisOperations.boundHashOps(anyString()))
|
||||
.willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString()))
|
||||
.willReturn(this.boundSetOperations);
|
||||
given(this.redisOperations.boundValueOps(anyString()))
|
||||
.willReturn(this.boundValueOperations);
|
||||
given(this.redisOperations.boundHashOps(anyString())).willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString())).willReturn(this.boundSetOperations);
|
||||
given(this.redisOperations.boundValueOps(anyString())).willReturn(this.boundValueOperations);
|
||||
|
||||
this.redisRepository.save(session);
|
||||
|
||||
@@ -192,16 +190,15 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
assertThat(delta.size()).isEqualTo(3);
|
||||
Object creationTime = delta.get(RedisSessionMapper.CREATION_TIME_KEY);
|
||||
assertThat(creationTime).isEqualTo(session.getCreationTime().toEpochMilli());
|
||||
assertThat(delta.get(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY)).isEqualTo(
|
||||
(int) Duration.ofSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS)
|
||||
.getSeconds());
|
||||
assertThat(delta.get(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY))
|
||||
.isEqualTo((int) Duration.ofSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS).getSeconds());
|
||||
assertThat(delta.get(RedisSessionMapper.LAST_ACCESSED_TIME_KEY))
|
||||
.isEqualTo(session.getCreationTime().toEpochMilli());
|
||||
}
|
||||
|
||||
// gh-467
|
||||
@Test
|
||||
public void saveSessionNothingChanged() {
|
||||
void saveSessionNothingChanged() {
|
||||
RedisSession session = this.redisRepository.new RedisSession(this.cached);
|
||||
|
||||
this.redisRepository.save(session);
|
||||
@@ -210,21 +207,17 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveJavadocSummary() {
|
||||
void saveJavadocSummary() {
|
||||
RedisSession session = this.redisRepository.createSession();
|
||||
|
||||
String sessionKey = "spring:session:sessions:" + session.getId();
|
||||
String backgroundExpireKey = "spring:session:expirations:"
|
||||
+ RedisSessionExpirationPolicy.roundUpToNextMinute(
|
||||
RedisSessionExpirationPolicy.expiresInMillis(session));
|
||||
String backgroundExpireKey = "spring:session:expirations:" + RedisSessionExpirationPolicy
|
||||
.roundUpToNextMinute(RedisSessionExpirationPolicy.expiresInMillis(session));
|
||||
String destroyedTriggerKey = "spring:session:sessions:expires:" + session.getId();
|
||||
|
||||
given(this.redisOperations.boundHashOps(sessionKey))
|
||||
.willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(backgroundExpireKey))
|
||||
.willReturn(this.boundSetOperations);
|
||||
given(this.redisOperations.boundValueOps(destroyedTriggerKey))
|
||||
.willReturn(this.boundValueOperations);
|
||||
given(this.redisOperations.boundHashOps(sessionKey)).willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(backgroundExpireKey)).willReturn(this.boundSetOperations);
|
||||
given(this.redisOperations.boundValueOps(destroyedTriggerKey)).willReturn(this.boundValueOperations);
|
||||
|
||||
this.redisRepository.save(session);
|
||||
|
||||
@@ -232,10 +225,8 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
// can be accessed in expiration events
|
||||
// if the session is retrieved and expired it will not be returned since
|
||||
// findById checks if it is expired
|
||||
long fiveMinutesAfterExpires = session.getMaxInactiveInterval().plusMinutes(5)
|
||||
.getSeconds();
|
||||
verify(this.boundHashOperations).expire(fiveMinutesAfterExpires,
|
||||
TimeUnit.SECONDS);
|
||||
long fiveMinutesAfterExpires = session.getMaxInactiveInterval().plusMinutes(5).getSeconds();
|
||||
verify(this.boundHashOperations).expire(fiveMinutesAfterExpires, TimeUnit.SECONDS);
|
||||
verify(this.boundSetOperations).expire(fiveMinutesAfterExpires, TimeUnit.SECONDS);
|
||||
verify(this.boundSetOperations).add("expires:" + session.getId());
|
||||
verify(this.boundValueOperations).expire(1800L, TimeUnit.SECONDS);
|
||||
@@ -243,18 +234,16 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveJavadoc() {
|
||||
void saveJavadoc() {
|
||||
RedisSession session = this.redisRepository.new RedisSession(this.cached);
|
||||
session.setLastAccessedTime(session.getLastAccessedTime());
|
||||
|
||||
given(this.redisOperations.boundHashOps("spring:session:sessions:session-id"))
|
||||
.willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations
|
||||
.boundSetOps("spring:session:expirations:1404361860000"))
|
||||
.willReturn(this.boundSetOperations);
|
||||
given(this.redisOperations
|
||||
.boundValueOps("spring:session:sessions:expires:session-id"))
|
||||
.willReturn(this.boundValueOperations);
|
||||
given(this.redisOperations.boundSetOps("spring:session:expirations:1404361860000"))
|
||||
.willReturn(this.boundSetOperations);
|
||||
given(this.redisOperations.boundValueOps("spring:session:sessions:expires:session-id"))
|
||||
.willReturn(this.boundValueOperations);
|
||||
|
||||
this.redisRepository.save(session);
|
||||
|
||||
@@ -262,74 +251,59 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
// can be accessed in expiration events
|
||||
// if the session is retrieved and expired it will not be returned since
|
||||
// findById checks if it is expired
|
||||
verify(this.boundHashOperations).expire(
|
||||
session.getMaxInactiveInterval().plusMinutes(5).getSeconds(),
|
||||
verify(this.boundHashOperations).expire(session.getMaxInactiveInterval().plusMinutes(5).getSeconds(),
|
||||
TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveLastAccessChanged() {
|
||||
RedisSession session = this.redisRepository.new RedisSession(
|
||||
new MapSession(this.cached));
|
||||
void saveLastAccessChanged() {
|
||||
RedisSession session = this.redisRepository.new RedisSession(new MapSession(this.cached));
|
||||
session.setLastAccessedTime(Instant.ofEpochMilli(12345678L));
|
||||
given(this.redisOperations.boundHashOps(anyString()))
|
||||
.willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString()))
|
||||
.willReturn(this.boundSetOperations);
|
||||
given(this.redisOperations.boundValueOps(anyString()))
|
||||
.willReturn(this.boundValueOperations);
|
||||
|
||||
this.redisRepository.save(session);
|
||||
|
||||
assertThat(getDelta()).isEqualTo(map(RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
|
||||
session.getLastAccessedTime().toEpochMilli()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveSetAttribute() {
|
||||
String attrName = "attrName";
|
||||
RedisSession session = this.redisRepository.new RedisSession(new MapSession());
|
||||
session.setAttribute(attrName, "attrValue");
|
||||
given(this.redisOperations.boundHashOps(anyString()))
|
||||
.willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString()))
|
||||
.willReturn(this.boundSetOperations);
|
||||
given(this.redisOperations.boundValueOps(anyString()))
|
||||
.willReturn(this.boundValueOperations);
|
||||
given(this.redisOperations.boundHashOps(anyString())).willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString())).willReturn(this.boundSetOperations);
|
||||
given(this.redisOperations.boundValueOps(anyString())).willReturn(this.boundValueOperations);
|
||||
|
||||
this.redisRepository.save(session);
|
||||
|
||||
assertThat(getDelta()).isEqualTo(
|
||||
map(RedisOperationsSessionRepository.getSessionAttrNameKey(attrName),
|
||||
session.getAttribute(attrName)));
|
||||
map(RedisSessionMapper.LAST_ACCESSED_TIME_KEY, session.getLastAccessedTime().toEpochMilli()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveRemoveAttribute() {
|
||||
void saveSetAttribute() {
|
||||
String attrName = "attrName";
|
||||
RedisSession session = this.redisRepository.new RedisSession(new MapSession());
|
||||
session.removeAttribute(attrName);
|
||||
given(this.redisOperations.boundHashOps(anyString()))
|
||||
.willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString()))
|
||||
.willReturn(this.boundSetOperations);
|
||||
given(this.redisOperations.boundValueOps(anyString()))
|
||||
.willReturn(this.boundValueOperations);
|
||||
session.setAttribute(attrName, "attrValue");
|
||||
given(this.redisOperations.boundHashOps(anyString())).willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString())).willReturn(this.boundSetOperations);
|
||||
given(this.redisOperations.boundValueOps(anyString())).willReturn(this.boundValueOperations);
|
||||
|
||||
this.redisRepository.save(session);
|
||||
|
||||
assertThat(getDelta()).isEqualTo(map(
|
||||
RedisOperationsSessionRepository.getSessionAttrNameKey(attrName), null));
|
||||
assertThat(getDelta()).isEqualTo(
|
||||
map(RedisOperationsSessionRepository.getSessionAttrNameKey(attrName), session.getAttribute(attrName)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveExpired() {
|
||||
void saveRemoveAttribute() {
|
||||
String attrName = "attrName";
|
||||
RedisSession session = this.redisRepository.new RedisSession(new MapSession());
|
||||
session.removeAttribute(attrName);
|
||||
given(this.redisOperations.boundHashOps(anyString())).willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString())).willReturn(this.boundSetOperations);
|
||||
given(this.redisOperations.boundValueOps(anyString())).willReturn(this.boundValueOperations);
|
||||
|
||||
this.redisRepository.save(session);
|
||||
|
||||
assertThat(getDelta()).isEqualTo(map(RedisOperationsSessionRepository.getSessionAttrNameKey(attrName), null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void saveExpired() {
|
||||
RedisSession session = this.redisRepository.new RedisSession(new MapSession());
|
||||
session.setMaxInactiveInterval(Duration.ZERO);
|
||||
given(this.redisOperations.boundHashOps(anyString()))
|
||||
.willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString()))
|
||||
.willReturn(this.boundSetOperations);
|
||||
given(this.redisOperations.boundHashOps(anyString())).willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString())).willReturn(this.boundSetOperations);
|
||||
|
||||
this.redisRepository.save(session);
|
||||
|
||||
@@ -339,7 +313,7 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void redisSessionGetAttributes() {
|
||||
void redisSessionGetAttributes() {
|
||||
String attrName = "attrName";
|
||||
RedisSession session = this.redisRepository.new RedisSession(
|
||||
Duration.ofSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS));
|
||||
@@ -351,39 +325,31 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void delete() {
|
||||
void delete() {
|
||||
String attrName = "attrName";
|
||||
MapSession expected = new MapSession();
|
||||
expected.setLastAccessedTime(Instant.now().minusSeconds(60));
|
||||
expected.setAttribute(attrName, "attrValue");
|
||||
given(this.redisOperations.boundHashOps(anyString()))
|
||||
.willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString()))
|
||||
.willReturn(this.boundSetOperations);
|
||||
Map map = map(RedisOperationsSessionRepository.getSessionAttrNameKey(attrName),
|
||||
expected.getAttribute(attrName), RedisSessionMapper.CREATION_TIME_KEY,
|
||||
expected.getCreationTime().toEpochMilli(),
|
||||
RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY,
|
||||
(int) expected.getMaxInactiveInterval().getSeconds(),
|
||||
RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
|
||||
expected.getLastAccessedTime().toEpochMilli());
|
||||
given(this.redisOperations.boundHashOps(anyString())).willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString())).willReturn(this.boundSetOperations);
|
||||
Map map = map(RedisOperationsSessionRepository.getSessionAttrNameKey(attrName), expected.getAttribute(attrName),
|
||||
RedisSessionMapper.CREATION_TIME_KEY, expected.getCreationTime().toEpochMilli(),
|
||||
RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY, (int) expected.getMaxInactiveInterval().getSeconds(),
|
||||
RedisSessionMapper.LAST_ACCESSED_TIME_KEY, expected.getLastAccessedTime().toEpochMilli());
|
||||
given(this.boundHashOperations.entries()).willReturn(map);
|
||||
given(this.redisOperations.boundSetOps(anyString()))
|
||||
.willReturn(this.boundSetOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString())).willReturn(this.boundSetOperations);
|
||||
|
||||
String id = expected.getId();
|
||||
this.redisRepository.deleteById(id);
|
||||
|
||||
assertThat(getDelta().get(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY))
|
||||
.isEqualTo(0);
|
||||
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));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteNullSession() {
|
||||
given(this.redisOperations.boundHashOps(anyString()))
|
||||
.willReturn(this.boundHashOperations);
|
||||
void deleteNullSession() {
|
||||
given(this.redisOperations.boundHashOps(anyString())).willReturn(this.boundHashOperations);
|
||||
|
||||
String id = "abc";
|
||||
this.redisRepository.deleteById(id);
|
||||
@@ -392,58 +358,48 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSessionNotFound() {
|
||||
void getSessionNotFound() {
|
||||
String id = "abc";
|
||||
given(this.redisOperations.boundHashOps(getKey(id)))
|
||||
.willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundHashOps(getKey(id))).willReturn(this.boundHashOperations);
|
||||
given(this.boundHashOperations.entries()).willReturn(map());
|
||||
|
||||
assertThat(this.redisRepository.findById(id)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSessionFound() {
|
||||
void getSessionFound() {
|
||||
String attribute1 = "attribute1";
|
||||
String attribute2 = "attribute2";
|
||||
MapSession expected = new MapSession();
|
||||
expected.setLastAccessedTime(Instant.now().minusSeconds(60));
|
||||
expected.setAttribute(attribute1, "test");
|
||||
expected.setAttribute(attribute2, null);
|
||||
given(this.redisOperations.boundHashOps(getKey(expected.getId())))
|
||||
.willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundHashOps(getKey(expected.getId()))).willReturn(this.boundHashOperations);
|
||||
Map map = map(RedisOperationsSessionRepository.getSessionAttrNameKey(attribute1),
|
||||
expected.getAttribute(attribute1),
|
||||
RedisOperationsSessionRepository.getSessionAttrNameKey(attribute2),
|
||||
expected.getAttribute(attribute1), RedisOperationsSessionRepository.getSessionAttrNameKey(attribute2),
|
||||
expected.getAttribute(attribute2), RedisSessionMapper.CREATION_TIME_KEY,
|
||||
expected.getCreationTime().toEpochMilli(),
|
||||
RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY,
|
||||
(int) expected.getMaxInactiveInterval().getSeconds(),
|
||||
RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
|
||||
expected.getCreationTime().toEpochMilli(), RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY,
|
||||
(int) expected.getMaxInactiveInterval().getSeconds(), RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
|
||||
expected.getLastAccessedTime().toEpochMilli());
|
||||
given(this.boundHashOperations.entries()).willReturn(map);
|
||||
|
||||
RedisSession session = this.redisRepository.findById(expected.getId());
|
||||
assertThat(session.getId()).isEqualTo(expected.getId());
|
||||
assertThat(session.getAttributeNames()).isEqualTo(expected.getAttributeNames());
|
||||
assertThat(session.<String>getAttribute(attribute1))
|
||||
.isEqualTo(expected.getAttribute(attribute1));
|
||||
assertThat(session.<String>getAttribute(attribute2))
|
||||
.isEqualTo(expected.getAttribute(attribute2));
|
||||
assertThat(session.<String>getAttribute(attribute1)).isEqualTo(expected.getAttribute(attribute1));
|
||||
assertThat(session.<String>getAttribute(attribute2)).isEqualTo(expected.getAttribute(attribute2));
|
||||
assertThat(session.getCreationTime().truncatedTo(ChronoUnit.MILLIS))
|
||||
.isEqualTo(expected.getCreationTime().truncatedTo(ChronoUnit.MILLIS));
|
||||
assertThat(session.getMaxInactiveInterval())
|
||||
.isEqualTo(expected.getMaxInactiveInterval());
|
||||
assertThat(session.getMaxInactiveInterval()).isEqualTo(expected.getMaxInactiveInterval());
|
||||
assertThat(session.getLastAccessedTime().truncatedTo(ChronoUnit.MILLIS))
|
||||
.isEqualTo(expected.getLastAccessedTime().truncatedTo(ChronoUnit.MILLIS));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSessionExpired() {
|
||||
void getSessionExpired() {
|
||||
String expiredId = "expired-id";
|
||||
given(this.redisOperations.boundHashOps(getKey(expiredId)))
|
||||
.willReturn(this.boundHashOperations);
|
||||
Map map = map(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY, 1,
|
||||
RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
|
||||
given(this.redisOperations.boundHashOps(getKey(expiredId))).willReturn(this.boundHashOperations);
|
||||
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);
|
||||
|
||||
@@ -451,46 +407,36 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByPrincipalNameExpired() {
|
||||
void findByPrincipalNameExpired() {
|
||||
String expiredId = "expired-id";
|
||||
given(this.redisOperations.boundSetOps(anyString()))
|
||||
.willReturn(this.boundSetOperations);
|
||||
given(this.boundSetOperations.members())
|
||||
.willReturn(Collections.singleton(expiredId));
|
||||
given(this.redisOperations.boundHashOps(getKey(expiredId)))
|
||||
.willReturn(this.boundHashOperations);
|
||||
Map map = map(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY, 1,
|
||||
RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
|
||||
given(this.redisOperations.boundSetOps(anyString())).willReturn(this.boundSetOperations);
|
||||
given(this.boundSetOperations.members()).willReturn(Collections.singleton(expiredId));
|
||||
given(this.redisOperations.boundHashOps(getKey(expiredId))).willReturn(this.boundHashOperations);
|
||||
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);
|
||||
|
||||
assertThat(this.redisRepository.findByIndexNameAndIndexValue(
|
||||
FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, "principal"))
|
||||
assertThat(this.redisRepository
|
||||
.findByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, "principal"))
|
||||
.isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByPrincipalName() {
|
||||
void findByPrincipalName() {
|
||||
Instant lastAccessed = Instant.now().minusMillis(10);
|
||||
Instant createdTime = lastAccessed.minusMillis(10);
|
||||
Duration maxInactive = Duration.ofHours(1);
|
||||
String sessionId = "some-id";
|
||||
given(this.redisOperations.boundSetOps(anyString()))
|
||||
.willReturn(this.boundSetOperations);
|
||||
given(this.boundSetOperations.members())
|
||||
.willReturn(Collections.singleton(sessionId));
|
||||
given(this.redisOperations.boundHashOps(getKey(sessionId)))
|
||||
.willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString())).willReturn(this.boundSetOperations);
|
||||
given(this.boundSetOperations.members()).willReturn(Collections.singleton(sessionId));
|
||||
given(this.redisOperations.boundHashOps(getKey(sessionId))).willReturn(this.boundHashOperations);
|
||||
Map map = map(RedisSessionMapper.CREATION_TIME_KEY, createdTime.toEpochMilli(),
|
||||
RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY,
|
||||
(int) maxInactive.getSeconds(), RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
|
||||
lastAccessed.toEpochMilli());
|
||||
RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY, (int) maxInactive.getSeconds(),
|
||||
RedisSessionMapper.LAST_ACCESSED_TIME_KEY, lastAccessed.toEpochMilli());
|
||||
given(this.boundHashOperations.entries()).willReturn(map);
|
||||
|
||||
Map<String, RedisSession> sessionIdToSessions = this.redisRepository
|
||||
.findByIndexNameAndIndexValue(
|
||||
FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME,
|
||||
"principal");
|
||||
.findByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, "principal");
|
||||
|
||||
assertThat(sessionIdToSessions).hasSize(1);
|
||||
RedisSession session = sessionIdToSessions.get(sessionId);
|
||||
@@ -504,13 +450,11 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cleanupExpiredSessions() {
|
||||
void cleanupExpiredSessions() {
|
||||
String expiredId = "expired-id";
|
||||
given(this.redisOperations.boundSetOps(anyString()))
|
||||
.willReturn(this.boundSetOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString())).willReturn(this.boundSetOperations);
|
||||
|
||||
Set<Object> expiredIds = new HashSet<>(
|
||||
Arrays.asList("expired-key1", "expired-key2"));
|
||||
Set<Object> expiredIds = new HashSet<>(Arrays.asList("expired-key1", "expired-key2"));
|
||||
given(this.boundSetOperations.members()).willReturn(expiredIds);
|
||||
|
||||
this.redisRepository.cleanupExpiredSessions();
|
||||
@@ -523,15 +467,14 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onMessageCreated() {
|
||||
void onMessageCreated() {
|
||||
MapSession session = this.cached;
|
||||
byte[] pattern = "".getBytes(StandardCharsets.UTF_8);
|
||||
String channel = "spring:session:event:0:created:" + session.getId();
|
||||
JdkSerializationRedisSerializer defaultSerailizer = new JdkSerializationRedisSerializer();
|
||||
this.redisRepository.setDefaultSerializer(defaultSerailizer);
|
||||
byte[] body = defaultSerailizer.serialize(new HashMap());
|
||||
DefaultMessage message = new DefaultMessage(
|
||||
channel.getBytes(StandardCharsets.UTF_8), body);
|
||||
DefaultMessage message = new DefaultMessage(channel.getBytes(StandardCharsets.UTF_8), body);
|
||||
|
||||
this.redisRepository.setApplicationEventPublisher(this.publisher);
|
||||
|
||||
@@ -542,15 +485,13 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test // gh-309
|
||||
public void onMessageCreatedCustomSerializer() {
|
||||
void onMessageCreatedCustomSerializer() {
|
||||
MapSession session = this.cached;
|
||||
byte[] pattern = "".getBytes(StandardCharsets.UTF_8);
|
||||
byte[] body = new byte[0];
|
||||
String channel = "spring:session:event:0:created:" + session.getId();
|
||||
given(this.defaultSerializer.deserialize(body))
|
||||
.willReturn(new HashMap<String, Object>());
|
||||
DefaultMessage message = new DefaultMessage(
|
||||
channel.getBytes(StandardCharsets.UTF_8), body);
|
||||
given(this.defaultSerializer.deserialize(body)).willReturn(new HashMap<String, Object>());
|
||||
DefaultMessage message = new DefaultMessage(channel.getBytes(StandardCharsets.UTF_8), body);
|
||||
this.redisRepository.setApplicationEventPublisher(this.publisher);
|
||||
|
||||
this.redisRepository.onMessage(message, pattern);
|
||||
@@ -561,19 +502,16 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onMessageDeletedSessionFound() {
|
||||
void onMessageDeletedSessionFound() {
|
||||
String deletedId = "deleted-id";
|
||||
given(this.redisOperations.boundHashOps(getKey(deletedId)))
|
||||
.willReturn(this.boundHashOperations);
|
||||
Map map = map(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY, 0,
|
||||
RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
|
||||
given(this.redisOperations.boundHashOps(getKey(deletedId))).willReturn(this.boundHashOperations);
|
||||
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);
|
||||
|
||||
String channel = "__keyevent@0__:del";
|
||||
String body = "spring:session:sessions:expires:" + deletedId;
|
||||
DefaultMessage message = new DefaultMessage(
|
||||
channel.getBytes(StandardCharsets.UTF_8),
|
||||
DefaultMessage message = new DefaultMessage(channel.getBytes(StandardCharsets.UTF_8),
|
||||
body.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
this.redisRepository.setApplicationEventPublisher(this.publisher);
|
||||
@@ -590,16 +528,14 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onMessageDeletedSessionNotFound() {
|
||||
void onMessageDeletedSessionNotFound() {
|
||||
String deletedId = "deleted-id";
|
||||
given(this.redisOperations.boundHashOps(getKey(deletedId)))
|
||||
.willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundHashOps(getKey(deletedId))).willReturn(this.boundHashOperations);
|
||||
given(this.boundHashOperations.entries()).willReturn(map());
|
||||
|
||||
String channel = "__keyevent@0__:del";
|
||||
String body = "spring:session:sessions:expires:" + deletedId;
|
||||
DefaultMessage message = new DefaultMessage(
|
||||
channel.getBytes(StandardCharsets.UTF_8),
|
||||
DefaultMessage message = new DefaultMessage(channel.getBytes(StandardCharsets.UTF_8),
|
||||
body.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
this.redisRepository.setApplicationEventPublisher(this.publisher);
|
||||
@@ -614,19 +550,16 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onMessageExpiredSessionFound() {
|
||||
void onMessageExpiredSessionFound() {
|
||||
String expiredId = "expired-id";
|
||||
given(this.redisOperations.boundHashOps(getKey(expiredId)))
|
||||
.willReturn(this.boundHashOperations);
|
||||
Map map = map(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY, 1,
|
||||
RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
|
||||
given(this.redisOperations.boundHashOps(getKey(expiredId))).willReturn(this.boundHashOperations);
|
||||
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);
|
||||
|
||||
String channel = "__keyevent@0__:expired";
|
||||
String body = "spring:session:sessions:expires:" + expiredId;
|
||||
DefaultMessage message = new DefaultMessage(
|
||||
channel.getBytes(StandardCharsets.UTF_8),
|
||||
DefaultMessage message = new DefaultMessage(channel.getBytes(StandardCharsets.UTF_8),
|
||||
body.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
this.redisRepository.setApplicationEventPublisher(this.publisher);
|
||||
@@ -643,16 +576,14 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onMessageExpiredSessionNotFound() {
|
||||
void onMessageExpiredSessionNotFound() {
|
||||
String expiredId = "expired-id";
|
||||
given(this.redisOperations.boundHashOps(getKey(expiredId)))
|
||||
.willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundHashOps(getKey(expiredId))).willReturn(this.boundHashOperations);
|
||||
given(this.boundHashOperations.entries()).willReturn(map());
|
||||
|
||||
String channel = "__keyevent@0__:expired";
|
||||
String body = "spring:session:sessions:expires:" + expiredId;
|
||||
DefaultMessage message = new DefaultMessage(
|
||||
channel.getBytes(StandardCharsets.UTF_8),
|
||||
DefaultMessage message = new DefaultMessage(channel.getBytes(StandardCharsets.UTF_8),
|
||||
body.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
this.redisRepository.setApplicationEventPublisher(this.publisher);
|
||||
@@ -667,21 +598,20 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolvePrincipalIndex() {
|
||||
void resolvePrincipalIndex() {
|
||||
PrincipalNameResolver resolver = RedisOperationsSessionRepository.PRINCIPAL_NAME_RESOLVER;
|
||||
String username = "username";
|
||||
RedisSession session = this.redisRepository.createSession();
|
||||
session.setAttribute(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME,
|
||||
username);
|
||||
session.setAttribute(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, username);
|
||||
|
||||
assertThat(resolver.resolvePrincipal(session)).isEqualTo(username);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveIndexOnSecurityContext() {
|
||||
void resolveIndexOnSecurityContext() {
|
||||
String principal = "resolveIndexOnSecurityContext";
|
||||
Authentication authentication = new UsernamePasswordAuthenticationToken(principal,
|
||||
"notused", AuthorityUtils.createAuthorityList("ROLE_USER"));
|
||||
Authentication authentication = new UsernamePasswordAuthenticationToken(principal, "notused",
|
||||
AuthorityUtils.createAuthorityList("ROLE_USER"));
|
||||
SecurityContext context = new SecurityContextImpl();
|
||||
context.setAuthentication(authentication);
|
||||
|
||||
@@ -694,14 +624,14 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void flushModeOnSaveCreate() {
|
||||
void flushModeOnSaveCreate() {
|
||||
this.redisRepository.createSession();
|
||||
|
||||
verifyZeroInteractions(this.boundHashOperations);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void flushModeOnSaveSetAttribute() {
|
||||
void flushModeOnSaveSetAttribute() {
|
||||
RedisSession session = this.redisRepository.createSession();
|
||||
session.setAttribute("something", "here");
|
||||
|
||||
@@ -709,7 +639,7 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void flushModeOnSaveRemoveAttribute() {
|
||||
void flushModeOnSaveRemoveAttribute() {
|
||||
RedisSession session = this.redisRepository.createSession();
|
||||
session.removeAttribute("remove");
|
||||
|
||||
@@ -717,7 +647,7 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void flushModeOnSaveSetLastAccessedTime() {
|
||||
void flushModeOnSaveSetLastAccessedTime() {
|
||||
RedisSession session = this.redisRepository.createSession();
|
||||
session.setLastAccessedTime(Instant.ofEpochMilli(1L));
|
||||
|
||||
@@ -725,7 +655,7 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void flushModeOnSaveSetMaxInactiveIntervalInSeconds() {
|
||||
void flushModeOnSaveSetMaxInactiveIntervalInSeconds() {
|
||||
RedisSession session = this.redisRepository.createSession();
|
||||
session.setMaxInactiveInterval(Duration.ofSeconds(1));
|
||||
|
||||
@@ -733,13 +663,10 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void flushModeImmediateCreate() {
|
||||
given(this.redisOperations.boundHashOps(anyString()))
|
||||
.willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString()))
|
||||
.willReturn(this.boundSetOperations);
|
||||
given(this.redisOperations.boundValueOps(anyString()))
|
||||
.willReturn(this.boundValueOperations);
|
||||
void flushModeImmediateCreate() {
|
||||
given(this.redisOperations.boundHashOps(anyString())).willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString())).willReturn(this.boundSetOperations);
|
||||
given(this.redisOperations.boundValueOps(anyString())).willReturn(this.boundValueOperations);
|
||||
|
||||
this.redisRepository.setRedisFlushMode(RedisFlushMode.IMMEDIATE);
|
||||
RedisSession session = this.redisRepository.createSession();
|
||||
@@ -748,21 +675,17 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
assertThat(delta.size()).isEqualTo(3);
|
||||
Object creationTime = delta.get(RedisSessionMapper.CREATION_TIME_KEY);
|
||||
assertThat(creationTime).isEqualTo(session.getCreationTime().toEpochMilli());
|
||||
assertThat(delta.get(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY)).isEqualTo(
|
||||
(int) Duration.ofSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS)
|
||||
.getSeconds());
|
||||
assertThat(delta.get(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY))
|
||||
.isEqualTo((int) Duration.ofSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS).getSeconds());
|
||||
assertThat(delta.get(RedisSessionMapper.LAST_ACCESSED_TIME_KEY))
|
||||
.isEqualTo(session.getCreationTime().toEpochMilli());
|
||||
}
|
||||
|
||||
@Test // gh-1409
|
||||
public void flushModeImmediateCreateWithCustomMaxInactiveInterval() {
|
||||
given(this.redisOperations.boundHashOps(anyString()))
|
||||
.willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString()))
|
||||
.willReturn(this.boundSetOperations);
|
||||
given(this.redisOperations.boundValueOps(anyString()))
|
||||
.willReturn(this.boundValueOperations);
|
||||
void flushModeImmediateCreateWithCustomMaxInactiveInterval() {
|
||||
given(this.redisOperations.boundHashOps(anyString())).willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString())).willReturn(this.boundSetOperations);
|
||||
given(this.redisOperations.boundValueOps(anyString())).willReturn(this.boundValueOperations);
|
||||
this.redisRepository.setDefaultMaxInactiveInterval(60);
|
||||
this.redisRepository.setRedisFlushMode(RedisFlushMode.IMMEDIATE);
|
||||
this.redisRepository.createSession();
|
||||
@@ -772,13 +695,10 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void flushModeImmediateSetAttribute() {
|
||||
given(this.redisOperations.boundHashOps(anyString()))
|
||||
.willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString()))
|
||||
.willReturn(this.boundSetOperations);
|
||||
given(this.redisOperations.boundValueOps(anyString()))
|
||||
.willReturn(this.boundValueOperations);
|
||||
void flushModeImmediateSetAttribute() {
|
||||
given(this.redisOperations.boundHashOps(anyString())).willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString())).willReturn(this.boundSetOperations);
|
||||
given(this.redisOperations.boundValueOps(anyString())).willReturn(this.boundValueOperations);
|
||||
|
||||
this.redisRepository.setRedisFlushMode(RedisFlushMode.IMMEDIATE);
|
||||
RedisSession session = this.redisRepository.createSession();
|
||||
@@ -788,18 +708,14 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
Map<String, Object> delta = getDelta(2);
|
||||
assertThat(delta.size()).isEqualTo(1);
|
||||
assertThat(delta).isEqualTo(
|
||||
map(RedisOperationsSessionRepository.getSessionAttrNameKey(attrName),
|
||||
session.getAttribute(attrName)));
|
||||
map(RedisOperationsSessionRepository.getSessionAttrNameKey(attrName), session.getAttribute(attrName)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void flushModeImmediateRemoveAttribute() {
|
||||
given(this.redisOperations.boundHashOps(anyString()))
|
||||
.willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString()))
|
||||
.willReturn(this.boundSetOperations);
|
||||
given(this.redisOperations.boundValueOps(anyString()))
|
||||
.willReturn(this.boundValueOperations);
|
||||
void flushModeImmediateRemoveAttribute() {
|
||||
given(this.redisOperations.boundHashOps(anyString())).willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString())).willReturn(this.boundSetOperations);
|
||||
given(this.redisOperations.boundValueOps(anyString())).willReturn(this.boundValueOperations);
|
||||
|
||||
this.redisRepository.setRedisFlushMode(RedisFlushMode.IMMEDIATE);
|
||||
RedisSession session = this.redisRepository.createSession();
|
||||
@@ -809,18 +725,14 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
Map<String, Object> delta = getDelta(2);
|
||||
assertThat(delta.size()).isEqualTo(1);
|
||||
assertThat(delta).isEqualTo(
|
||||
map(RedisOperationsSessionRepository.getSessionAttrNameKey(attrName),
|
||||
session.getAttribute(attrName)));
|
||||
map(RedisOperationsSessionRepository.getSessionAttrNameKey(attrName), session.getAttribute(attrName)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void flushModeSetMaxInactiveIntervalInSeconds() {
|
||||
given(this.redisOperations.boundHashOps(anyString()))
|
||||
.willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString()))
|
||||
.willReturn(this.boundSetOperations);
|
||||
given(this.redisOperations.boundValueOps(anyString()))
|
||||
.willReturn(this.boundValueOperations);
|
||||
void flushModeSetMaxInactiveIntervalInSeconds() {
|
||||
given(this.redisOperations.boundHashOps(anyString())).willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString())).willReturn(this.boundSetOperations);
|
||||
given(this.redisOperations.boundValueOps(anyString())).willReturn(this.boundValueOperations);
|
||||
|
||||
this.redisRepository.setRedisFlushMode(RedisFlushMode.IMMEDIATE);
|
||||
RedisSession session = this.redisRepository.createSession();
|
||||
@@ -833,13 +745,10 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void flushModeSetLastAccessedTime() {
|
||||
given(this.redisOperations.boundHashOps(anyString()))
|
||||
.willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString()))
|
||||
.willReturn(this.boundSetOperations);
|
||||
given(this.redisOperations.boundValueOps(anyString()))
|
||||
.willReturn(this.boundValueOperations);
|
||||
void flushModeSetLastAccessedTime() {
|
||||
given(this.redisOperations.boundHashOps(anyString())).willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString())).willReturn(this.boundSetOperations);
|
||||
given(this.redisOperations.boundValueOps(anyString())).willReturn(this.boundValueOperations);
|
||||
|
||||
this.redisRepository.setRedisFlushMode(RedisFlushMode.IMMEDIATE);
|
||||
RedisSession session = this.redisRepository.createSession();
|
||||
@@ -848,53 +757,46 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
|
||||
Map<String, Object> delta = getDelta(2);
|
||||
assertThat(delta.size()).isEqualTo(1);
|
||||
assertThat(delta).isEqualTo(map(RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
|
||||
session.getLastAccessedTime().toEpochMilli()));
|
||||
assertThat(delta).isEqualTo(
|
||||
map(RedisSessionMapper.LAST_ACCESSED_TIME_KEY, session.getLastAccessedTime().toEpochMilli()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setRedisFlushModeNull() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> this.redisRepository.setRedisFlushMode(null))
|
||||
void setRedisFlushModeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.redisRepository.setRedisFlushMode(null))
|
||||
.withMessage("redisFlushMode cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeRedisNamespace() {
|
||||
void changeRedisNamespace() {
|
||||
String namespace = "foo:bar";
|
||||
this.redisRepository.setRedisKeyNamespace(namespace);
|
||||
RedisSession session = this.redisRepository.new RedisSession(new MapSession());
|
||||
session.setMaxInactiveInterval(Duration.ZERO);
|
||||
given(this.redisOperations.boundHashOps(anyString()))
|
||||
.willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString()))
|
||||
.willReturn(this.boundSetOperations);
|
||||
given(this.redisOperations.boundHashOps(anyString())).willReturn(this.boundHashOperations);
|
||||
given(this.redisOperations.boundSetOps(anyString())).willReturn(this.boundSetOperations);
|
||||
|
||||
this.redisRepository.save(session);
|
||||
|
||||
String id = session.getId();
|
||||
verify(this.redisOperations, atLeastOnce())
|
||||
.delete(namespace + ":sessions:expires:" + id);
|
||||
verify(this.redisOperations, never())
|
||||
.boundValueOps(namespace + ":sessions:expires:" + id);
|
||||
verify(this.redisOperations, atLeastOnce()).delete(namespace + ":sessions:expires:" + id);
|
||||
verify(this.redisOperations, never()).boundValueOps(namespace + ":sessions:expires:" + id);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setRedisKeyNamespaceNullNamespace() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> this.redisRepository.setRedisKeyNamespace(null))
|
||||
void setRedisKeyNamespaceNullNamespace() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.redisRepository.setRedisKeyNamespace(null))
|
||||
.withMessage("namespace cannot be null or empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setRedisKeyNamespaceEmptyNamespace() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> this.redisRepository.setRedisKeyNamespace(" "))
|
||||
void setRedisKeyNamespaceEmptyNamespace() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.redisRepository.setRedisKeyNamespace(" "))
|
||||
.withMessage("namespace cannot be null or empty");
|
||||
}
|
||||
|
||||
@Test // gh-1120
|
||||
public void getAttributeNamesAndRemove() {
|
||||
void getAttributeNamesAndRemove() {
|
||||
RedisSession session = this.redisRepository.new RedisSession(this.cached);
|
||||
session.setAttribute("attribute1", "value1");
|
||||
session.setAttribute("attribute2", "value2");
|
||||
@@ -907,7 +809,7 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onMessageCreatedInOtherDatabase() {
|
||||
void onMessageCreatedInOtherDatabase() {
|
||||
JdkSerializationRedisSerializer serializer = new JdkSerializationRedisSerializer();
|
||||
this.redisRepository.setApplicationEventPublisher(this.publisher);
|
||||
this.redisRepository.setDefaultSerializer(serializer);
|
||||
@@ -915,8 +817,7 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
MapSession session = this.cached;
|
||||
String channel = "spring:session:event:created:1:" + session.getId();
|
||||
byte[] body = serializer.serialize(new HashMap());
|
||||
DefaultMessage message = new DefaultMessage(
|
||||
channel.getBytes(StandardCharsets.UTF_8), body);
|
||||
DefaultMessage message = new DefaultMessage(channel.getBytes(StandardCharsets.UTF_8), body);
|
||||
|
||||
this.redisRepository.onMessage(message, "".getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
@@ -925,7 +826,7 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onMessageDeletedInOtherDatabase() {
|
||||
void onMessageDeletedInOtherDatabase() {
|
||||
JdkSerializationRedisSerializer serializer = new JdkSerializationRedisSerializer();
|
||||
this.redisRepository.setApplicationEventPublisher(this.publisher);
|
||||
this.redisRepository.setDefaultSerializer(serializer);
|
||||
@@ -933,8 +834,7 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
MapSession session = this.cached;
|
||||
String channel = "__keyevent@1__:del";
|
||||
String body = "spring:session:sessions:expires:" + session.getId();
|
||||
DefaultMessage message = new DefaultMessage(
|
||||
channel.getBytes(StandardCharsets.UTF_8),
|
||||
DefaultMessage message = new DefaultMessage(channel.getBytes(StandardCharsets.UTF_8),
|
||||
body.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
this.redisRepository.onMessage(message, "".getBytes(StandardCharsets.UTF_8));
|
||||
@@ -944,7 +844,7 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onMessageExpiredInOtherDatabase() {
|
||||
void onMessageExpiredInOtherDatabase() {
|
||||
JdkSerializationRedisSerializer serializer = new JdkSerializationRedisSerializer();
|
||||
this.redisRepository.setApplicationEventPublisher(this.publisher);
|
||||
this.redisRepository.setDefaultSerializer(serializer);
|
||||
@@ -952,8 +852,7 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
MapSession session = this.cached;
|
||||
String channel = "__keyevent@1__:expired";
|
||||
String body = "spring:session:sessions:expires:" + session.getId();
|
||||
DefaultMessage message = new DefaultMessage(
|
||||
channel.getBytes(StandardCharsets.UTF_8),
|
||||
DefaultMessage message = new DefaultMessage(channel.getBytes(StandardCharsets.UTF_8),
|
||||
body.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
this.redisRepository.onMessage(message, "".getBytes(StandardCharsets.UTF_8));
|
||||
@@ -985,4 +884,5 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
verify(this.boundHashOperations, times(times)).putAll(this.delta.capture());
|
||||
return this.delta.getAllValues().get(times - 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -39,54 +39,52 @@ import static org.mockito.Mockito.verify;
|
||||
/**
|
||||
* @author Rob Winch
|
||||
*/
|
||||
public class RedisSessionExpirationPolicyTests {
|
||||
class RedisSessionExpirationPolicyTests {
|
||||
|
||||
// Wed Apr 15 10:28:32 CDT 2015
|
||||
static final Long NOW = 1429111712346L;
|
||||
|
||||
// Wed Apr 15 10:27:32 CDT 2015
|
||||
static final Long ONE_MINUTE_AGO = 1429111652346L;
|
||||
private static final Long ONE_MINUTE_AGO = 1429111652346L;
|
||||
|
||||
@Mock
|
||||
RedisOperations<Object, Object> sessionRedisOperations;
|
||||
|
||||
@Mock
|
||||
BoundSetOperations<Object, Object> setOperations;
|
||||
|
||||
@Mock
|
||||
BoundHashOperations<Object, Object, Object> hashOperations;
|
||||
|
||||
@Mock
|
||||
BoundValueOperations<Object, Object> valueOperations;
|
||||
|
||||
RedisSessionExpirationPolicy policy;
|
||||
private RedisSessionExpirationPolicy policy;
|
||||
|
||||
private MapSession session;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
RedisOperationsSessionRepository repository = new RedisOperationsSessionRepository(
|
||||
this.sessionRedisOperations);
|
||||
this.policy = new RedisSessionExpirationPolicy(this.sessionRedisOperations,
|
||||
repository::getExpirationsKey, repository::getSessionKey);
|
||||
RedisOperationsSessionRepository repository = new RedisOperationsSessionRepository(this.sessionRedisOperations);
|
||||
this.policy = new RedisSessionExpirationPolicy(this.sessionRedisOperations, repository::getExpirationsKey,
|
||||
repository::getSessionKey);
|
||||
this.session = new MapSession();
|
||||
this.session.setLastAccessedTime(Instant.ofEpochMilli(1429116694675L));
|
||||
this.session.setId("12345");
|
||||
|
||||
given(this.sessionRedisOperations.boundSetOps(anyString()))
|
||||
.willReturn(this.setOperations);
|
||||
given(this.sessionRedisOperations.boundHashOps(anyString()))
|
||||
.willReturn(this.hashOperations);
|
||||
given(this.sessionRedisOperations.boundValueOps(anyString()))
|
||||
.willReturn(this.valueOperations);
|
||||
given(this.sessionRedisOperations.boundSetOps(anyString())).willReturn(this.setOperations);
|
||||
given(this.sessionRedisOperations.boundHashOps(anyString())).willReturn(this.hashOperations);
|
||||
given(this.sessionRedisOperations.boundValueOps(anyString())).willReturn(this.valueOperations);
|
||||
}
|
||||
|
||||
// gh-169
|
||||
@Test
|
||||
public void onExpirationUpdatedRemovesOriginalExpirationTimeRoundedUp()
|
||||
throws Exception {
|
||||
void onExpirationUpdatedRemovesOriginalExpirationTimeRoundedUp() throws Exception {
|
||||
long originalExpirationTimeInMs = ONE_MINUTE_AGO;
|
||||
long originalRoundedToNextMinInMs = RedisSessionExpirationPolicy
|
||||
.roundUpToNextMinute(originalExpirationTimeInMs);
|
||||
String originalExpireKey = this.policy
|
||||
.getExpirationKey(originalRoundedToNextMinInMs);
|
||||
String originalExpireKey = this.policy.getExpirationKey(originalRoundedToNextMinInMs);
|
||||
|
||||
this.policy.onExpirationUpdated(originalExpirationTimeInMs, this.session);
|
||||
|
||||
@@ -96,14 +94,11 @@ public class RedisSessionExpirationPolicyTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onExpirationUpdatedDoNotSendDeleteWhenExpirationTimeDoesNotChange()
|
||||
throws Exception {
|
||||
long originalExpirationTimeInMs = RedisSessionExpirationPolicy
|
||||
.expiresInMillis(this.session) - 10;
|
||||
void onExpirationUpdatedDoNotSendDeleteWhenExpirationTimeDoesNotChange() throws Exception {
|
||||
long originalExpirationTimeInMs = RedisSessionExpirationPolicy.expiresInMillis(this.session) - 10;
|
||||
long originalRoundedToNextMinInMs = RedisSessionExpirationPolicy
|
||||
.roundUpToNextMinute(originalExpirationTimeInMs);
|
||||
String originalExpireKey = this.policy
|
||||
.getExpirationKey(originalRoundedToNextMinInMs);
|
||||
String originalExpireKey = this.policy.getExpirationKey(originalRoundedToNextMinInMs);
|
||||
|
||||
this.policy.onExpirationUpdated(originalExpirationTimeInMs, this.session);
|
||||
|
||||
@@ -113,36 +108,32 @@ public class RedisSessionExpirationPolicyTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onExpirationUpdatedAddsExpirationTimeRoundedUp() throws Exception {
|
||||
long expirationTimeInMs = RedisSessionExpirationPolicy
|
||||
.expiresInMillis(this.session);
|
||||
long expirationRoundedUpInMs = RedisSessionExpirationPolicy
|
||||
.roundUpToNextMinute(expirationTimeInMs);
|
||||
void onExpirationUpdatedAddsExpirationTimeRoundedUp() throws Exception {
|
||||
long expirationTimeInMs = RedisSessionExpirationPolicy.expiresInMillis(this.session);
|
||||
long expirationRoundedUpInMs = RedisSessionExpirationPolicy.roundUpToNextMinute(expirationTimeInMs);
|
||||
String expectedExpireKey = this.policy.getExpirationKey(expirationRoundedUpInMs);
|
||||
|
||||
this.policy.onExpirationUpdated(null, this.session);
|
||||
|
||||
verify(this.sessionRedisOperations).boundSetOps(expectedExpireKey);
|
||||
verify(this.setOperations).add("expires:" + this.session.getId());
|
||||
verify(this.setOperations).expire(
|
||||
this.session.getMaxInactiveInterval().plusMinutes(5).getSeconds(),
|
||||
verify(this.setOperations).expire(this.session.getMaxInactiveInterval().plusMinutes(5).getSeconds(),
|
||||
TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onExpirationUpdatedSetExpireSession() throws Exception {
|
||||
void onExpirationUpdatedSetExpireSession() throws Exception {
|
||||
String sessionKey = this.policy.getSessionKey(this.session.getId());
|
||||
|
||||
this.policy.onExpirationUpdated(null, this.session);
|
||||
|
||||
verify(this.sessionRedisOperations).boundHashOps(sessionKey);
|
||||
verify(this.hashOperations).expire(
|
||||
this.session.getMaxInactiveInterval().plusMinutes(5).getSeconds(),
|
||||
verify(this.hashOperations).expire(this.session.getMaxInactiveInterval().plusMinutes(5).getSeconds(),
|
||||
TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onExpirationUpdatedDeleteOnZero() throws Exception {
|
||||
void onExpirationUpdatedDeleteOnZero() throws Exception {
|
||||
String sessionKey = this.policy.getSessionKey("expires:" + this.session.getId());
|
||||
|
||||
long originalExpirationTimeInMs = ONE_MINUTE_AGO;
|
||||
@@ -155,13 +146,12 @@ public class RedisSessionExpirationPolicyTests {
|
||||
verify(this.setOperations).remove("expires:" + this.session.getId());
|
||||
verify(this.setOperations).add("expires:" + this.session.getId());
|
||||
verify(this.sessionRedisOperations).delete(sessionKey);
|
||||
verify(this.setOperations).expire(
|
||||
this.session.getMaxInactiveInterval().plusMinutes(5).getSeconds(),
|
||||
verify(this.setOperations).expire(this.session.getMaxInactiveInterval().plusMinutes(5).getSeconds(),
|
||||
TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onExpirationUpdatedPersistOnNegativeExpiration() throws Exception {
|
||||
void onExpirationUpdatedPersistOnNegativeExpiration() throws Exception {
|
||||
long originalExpirationTimeInMs = ONE_MINUTE_AGO;
|
||||
|
||||
this.session.setMaxInactiveInterval(Duration.ofSeconds(-1));
|
||||
@@ -173,4 +163,5 @@ public class RedisSessionExpirationPolicyTests {
|
||||
verify(this.valueOperations).persist();
|
||||
verify(this.hashOperations).persist();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -47,8 +47,7 @@ class RedisSessionMapperTests {
|
||||
|
||||
@Test
|
||||
void constructor_NullId_ShouldThrowException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new RedisSessionMapper(null))
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new RedisSessionMapper(null))
|
||||
.withMessage("sessionId must not be empty");
|
||||
}
|
||||
|
||||
@@ -66,8 +65,7 @@ class RedisSessionMapperTests {
|
||||
|
||||
@Test
|
||||
void apply_EmptyMap_ShouldThrowException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> this.mapper.apply(Collections.emptyMap()))
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.mapper.apply(Collections.emptyMap()))
|
||||
.withMessage("map must not be empty");
|
||||
}
|
||||
|
||||
@@ -77,8 +75,7 @@ class RedisSessionMapperTests {
|
||||
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");
|
||||
.withMessage(RedisSessionMapper.CREATION_TIME_KEY + " key must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -87,8 +84,7 @@ class RedisSessionMapperTests {
|
||||
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");
|
||||
.withMessage(RedisSessionMapper.LAST_ACCESSED_TIME_KEY + " key must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -97,8 +93,7 @@ class RedisSessionMapperTests {
|
||||
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");
|
||||
.withMessage(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY + " key must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -70,52 +70,45 @@ class SimpleRedisOperationsSessionRepositoryTests {
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
given(this.sessionRedisOperations.<String, Object>opsForHash())
|
||||
.willReturn(this.sessionHashOperations);
|
||||
this.sessionRepository = new SimpleRedisOperationsSessionRepository(
|
||||
this.sessionRedisOperations);
|
||||
given(this.sessionRedisOperations.<String, Object>opsForHash()).willReturn(this.sessionHashOperations);
|
||||
this.sessionRepository = new SimpleRedisOperationsSessionRepository(this.sessionRedisOperations);
|
||||
}
|
||||
|
||||
@Test
|
||||
void constructor_NullRedisOperations_ShouldThrowException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new ReactiveRedisOperationsSessionRepository(null))
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new ReactiveRedisOperationsSessionRepository(null))
|
||||
.withMessageContaining("sessionRedisOperations cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void setDefaultMaxInactiveInterval_ValidInterval_ShouldSetInterval() {
|
||||
this.sessionRepository.setDefaultMaxInactiveInterval(Duration.ofMinutes(10));
|
||||
assertThat(ReflectionTestUtils.getField(this.sessionRepository,
|
||||
"defaultMaxInactiveInterval")).isEqualTo(Duration.ofMinutes(10));
|
||||
assertThat(ReflectionTestUtils.getField(this.sessionRepository, "defaultMaxInactiveInterval"))
|
||||
.isEqualTo(Duration.ofMinutes(10));
|
||||
}
|
||||
|
||||
@Test
|
||||
void setDefaultMaxInactiveInterval_NullInterval_ShouldThrowException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(
|
||||
() -> this.sessionRepository.setDefaultMaxInactiveInterval(null))
|
||||
.isThrownBy(() -> this.sessionRepository.setDefaultMaxInactiveInterval(null))
|
||||
.withMessage("defaultMaxInactiveInterval must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void setKeyNamespace_ValidNamespace_ShouldSetNamespace() {
|
||||
this.sessionRepository.setKeyNamespace("test:");
|
||||
assertThat(ReflectionTestUtils.getField(this.sessionRepository, "keyNamespace"))
|
||||
.isEqualTo("test:");
|
||||
assertThat(ReflectionTestUtils.getField(this.sessionRepository, "keyNamespace")).isEqualTo("test:");
|
||||
}
|
||||
|
||||
@Test
|
||||
void setKeyNamespace_NullNamespace_ShouldThrowException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> this.sessionRepository.setKeyNamespace(null))
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.sessionRepository.setKeyNamespace(null))
|
||||
.withMessage("keyNamespace must not be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
void setKeyNamespace_EmptyNamespace_ShouldThrowException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> this.sessionRepository.setKeyNamespace(" "))
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.sessionRepository.setKeyNamespace(" "))
|
||||
.withMessage("keyNamespace must not be empty");
|
||||
}
|
||||
|
||||
@@ -128,16 +121,15 @@ class SimpleRedisOperationsSessionRepositoryTests {
|
||||
|
||||
@Test
|
||||
void setFlushMode_NullFlushMode_ShouldThrowException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> this.sessionRepository.setFlushMode(null))
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.sessionRepository.setFlushMode(null))
|
||||
.withMessage("flushMode must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createSession_DefaultMaxInactiveInterval_ShouldCreateSession() {
|
||||
RedisSession redisSession = this.sessionRepository.createSession();
|
||||
assertThat(redisSession.getMaxInactiveInterval()).isEqualTo(
|
||||
Duration.ofSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS));
|
||||
assertThat(redisSession.getMaxInactiveInterval())
|
||||
.isEqualTo(Duration.ofSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS));
|
||||
verifyNoMoreInteractions(this.sessionRedisOperations);
|
||||
verifyNoMoreInteractions(this.sessionHashOperations);
|
||||
}
|
||||
@@ -146,8 +138,7 @@ class SimpleRedisOperationsSessionRepositoryTests {
|
||||
void createSession_CustomMaxInactiveInterval_ShouldCreateSession() {
|
||||
this.sessionRepository.setDefaultMaxInactiveInterval(Duration.ofMinutes(10));
|
||||
RedisSession redisSession = this.sessionRepository.createSession();
|
||||
assertThat(redisSession.getMaxInactiveInterval())
|
||||
.isEqualTo(Duration.ofMinutes(10));
|
||||
assertThat(redisSession.getMaxInactiveInterval()).isEqualTo(Duration.ofMinutes(10));
|
||||
verifyNoMoreInteractions(this.sessionRedisOperations);
|
||||
verifyNoMoreInteractions(this.sessionHashOperations);
|
||||
}
|
||||
@@ -215,10 +206,8 @@ class SimpleRedisOperationsSessionRepositoryTests {
|
||||
this.sessionRepository.save(session);
|
||||
verify(this.sessionRedisOperations).hasKey(eq(TEST_SESSION_KEY));
|
||||
verify(this.sessionRedisOperations).opsForHash();
|
||||
verify(this.sessionRedisOperations).expireAt(eq(TEST_SESSION_KEY),
|
||||
eq(getExpiry(session)));
|
||||
verify(this.sessionHashOperations).putAll(eq(TEST_SESSION_KEY),
|
||||
this.delta.capture());
|
||||
verify(this.sessionRedisOperations).expireAt(eq(TEST_SESSION_KEY), eq(getExpiry(session)));
|
||||
verify(this.sessionHashOperations).putAll(eq(TEST_SESSION_KEY), this.delta.capture());
|
||||
assertThat(this.delta.getValue()).hasSize(2);
|
||||
verifyNoMoreInteractions(this.sessionRedisOperations);
|
||||
verifyNoMoreInteractions(this.sessionHashOperations);
|
||||
@@ -237,8 +226,7 @@ class SimpleRedisOperationsSessionRepositoryTests {
|
||||
@Test
|
||||
void save_SessionNotExists_ShouldThrowException() {
|
||||
RedisSession session = createTestSession();
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> this.sessionRepository.save(session))
|
||||
assertThatIllegalStateException().isThrownBy(() -> this.sessionRepository.save(session))
|
||||
.withMessage("Session was invalidated");
|
||||
verify(this.sessionRedisOperations).hasKey(eq(TEST_SESSION_KEY));
|
||||
verifyNoMoreInteractions(this.sessionRedisOperations);
|
||||
@@ -249,20 +237,18 @@ class SimpleRedisOperationsSessionRepositoryTests {
|
||||
@SuppressWarnings("unchecked")
|
||||
void findById_SessionExists_ShouldReturnSession() {
|
||||
Instant now = Instant.now().truncatedTo(ChronoUnit.MILLIS);
|
||||
given(this.sessionHashOperations.entries(eq(TEST_SESSION_KEY))).willReturn(
|
||||
mapOf(RedisSessionMapper.CREATION_TIME_KEY, Instant.EPOCH.toEpochMilli(),
|
||||
given(this.sessionHashOperations.entries(eq(TEST_SESSION_KEY)))
|
||||
.willReturn(mapOf(RedisSessionMapper.CREATION_TIME_KEY, Instant.EPOCH.toEpochMilli(),
|
||||
RedisSessionMapper.LAST_ACCESSED_TIME_KEY, now.toEpochMilli(),
|
||||
RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY,
|
||||
MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS,
|
||||
RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY, MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS,
|
||||
RedisSessionMapper.ATTRIBUTE_PREFIX + "attribute1", "value1"));
|
||||
RedisSession session = this.sessionRepository.findById(TEST_SESSION_ID);
|
||||
assertThat(session.getId()).isEqualTo(TEST_SESSION_ID);
|
||||
assertThat(session.getCreationTime()).isEqualTo(Instant.EPOCH);
|
||||
assertThat(session.getLastAccessedTime()).isEqualTo(now);
|
||||
assertThat(session.getMaxInactiveInterval()).isEqualTo(
|
||||
Duration.ofSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS));
|
||||
assertThat(session.getAttributeNames())
|
||||
.isEqualTo(Collections.singleton("attribute1"));
|
||||
assertThat(session.getMaxInactiveInterval())
|
||||
.isEqualTo(Duration.ofSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS));
|
||||
assertThat(session.getAttributeNames()).isEqualTo(Collections.singleton("attribute1"));
|
||||
assertThat(session.<String>getAttribute("attribute1")).isEqualTo("value1");
|
||||
verify(this.sessionRedisOperations).opsForHash();
|
||||
verify(this.sessionHashOperations).entries(eq(TEST_SESSION_KEY));
|
||||
@@ -273,12 +259,11 @@ class SimpleRedisOperationsSessionRepositoryTests {
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void findById_SessionExistsAndIsExpired_ShouldReturnNull() {
|
||||
given(this.sessionHashOperations.entries(eq(TEST_SESSION_KEY))).willReturn(mapOf(
|
||||
RedisSessionMapper.CREATION_TIME_KEY, Instant.EPOCH.toEpochMilli(),
|
||||
RedisSessionMapper.LAST_ACCESSED_TIME_KEY, Instant.EPOCH.toEpochMilli(),
|
||||
RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY,
|
||||
MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS,
|
||||
RedisSessionMapper.ATTRIBUTE_PREFIX + "attribute1", "value1"));
|
||||
given(this.sessionHashOperations.entries(eq(TEST_SESSION_KEY)))
|
||||
.willReturn(mapOf(RedisSessionMapper.CREATION_TIME_KEY, Instant.EPOCH.toEpochMilli(),
|
||||
RedisSessionMapper.LAST_ACCESSED_TIME_KEY, Instant.EPOCH.toEpochMilli(),
|
||||
RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY, MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS,
|
||||
RedisSessionMapper.ATTRIBUTE_PREFIX + "attribute1", "value1"));
|
||||
assertThat(this.sessionRepository.findById(TEST_SESSION_ID)).isNull();
|
||||
verify(this.sessionRedisOperations).opsForHash();
|
||||
verify(this.sessionHashOperations).entries(eq(TEST_SESSION_KEY));
|
||||
@@ -306,8 +291,7 @@ class SimpleRedisOperationsSessionRepositoryTests {
|
||||
|
||||
@Test
|
||||
void getSessionRedisOperations__ShouldReturnRedisOperations() {
|
||||
assertThat(this.sessionRepository.getSessionRedisOperations())
|
||||
.isEqualTo(this.sessionRedisOperations);
|
||||
assertThat(this.sessionRepository.getSessionRedisOperations()).isEqualTo(this.sessionRedisOperations);
|
||||
verifyNoMoreInteractions(this.sessionRedisOperations);
|
||||
verifyNoMoreInteractions(this.sessionHashOperations);
|
||||
}
|
||||
@@ -317,9 +301,8 @@ class SimpleRedisOperationsSessionRepositoryTests {
|
||||
}
|
||||
|
||||
private static Date getExpiry(RedisSession session) {
|
||||
return Date
|
||||
.from(Instant.ofEpochMilli(session.getLastAccessedTime().toEpochMilli())
|
||||
.plusSeconds(session.getMaxInactiveInterval().getSeconds()));
|
||||
return Date.from(Instant.ofEpochMilli(session.getLastAccessedTime().toEpochMilli())
|
||||
.plusSeconds(session.getMaxInactiveInterval().getSeconds()));
|
||||
}
|
||||
|
||||
private static Map mapOf(Object... objects) {
|
||||
|
||||
@@ -36,20 +36,23 @@ import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
public class EnableRedisKeyspaceNotificationsInitializerTests {
|
||||
static final String CONFIG_NOTIFY_KEYSPACE_EVENTS = "notify-keyspace-events";
|
||||
class EnableRedisKeyspaceNotificationsInitializerTests {
|
||||
|
||||
private static final String CONFIG_NOTIFY_KEYSPACE_EVENTS = "notify-keyspace-events";
|
||||
|
||||
@Mock
|
||||
RedisConnectionFactory connectionFactory;
|
||||
|
||||
@Mock
|
||||
RedisConnection connection;
|
||||
|
||||
@Captor
|
||||
ArgumentCaptor<String> options;
|
||||
|
||||
RedisHttpSessionConfiguration.EnableRedisKeyspaceNotificationsInitializer initializer;
|
||||
private RedisHttpSessionConfiguration.EnableRedisKeyspaceNotificationsInitializer initializer;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
given(this.connectionFactory.getConnection()).willReturn(this.connection);
|
||||
|
||||
@@ -58,7 +61,7 @@ public class EnableRedisKeyspaceNotificationsInitializerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void afterPropertiesSetUnset() throws Exception {
|
||||
void afterPropertiesSetUnset() throws Exception {
|
||||
setConfigNotification("");
|
||||
|
||||
this.initializer.afterPropertiesSet();
|
||||
@@ -67,7 +70,7 @@ public class EnableRedisKeyspaceNotificationsInitializerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void afterPropertiesSetA() throws Exception {
|
||||
void afterPropertiesSetA() throws Exception {
|
||||
setConfigNotification("A");
|
||||
|
||||
this.initializer.afterPropertiesSet();
|
||||
@@ -76,7 +79,7 @@ public class EnableRedisKeyspaceNotificationsInitializerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void afterPropertiesSetE() throws Exception {
|
||||
void afterPropertiesSetE() throws Exception {
|
||||
setConfigNotification("E");
|
||||
|
||||
this.initializer.afterPropertiesSet();
|
||||
@@ -85,7 +88,7 @@ public class EnableRedisKeyspaceNotificationsInitializerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void afterPropertiesSetK() throws Exception {
|
||||
void afterPropertiesSetK() throws Exception {
|
||||
setConfigNotification("K");
|
||||
|
||||
this.initializer.afterPropertiesSet();
|
||||
@@ -94,7 +97,7 @@ public class EnableRedisKeyspaceNotificationsInitializerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void afterPropertiesSetAE() throws Exception {
|
||||
void afterPropertiesSetAE() throws Exception {
|
||||
setConfigNotification("AE");
|
||||
|
||||
this.initializer.afterPropertiesSet();
|
||||
@@ -103,7 +106,7 @@ public class EnableRedisKeyspaceNotificationsInitializerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void afterPropertiesSetAK() throws Exception {
|
||||
void afterPropertiesSetAK() throws Exception {
|
||||
setConfigNotification("AK");
|
||||
|
||||
this.initializer.afterPropertiesSet();
|
||||
@@ -112,7 +115,7 @@ public class EnableRedisKeyspaceNotificationsInitializerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void afterPropertiesSetEK() throws Exception {
|
||||
void afterPropertiesSetEK() throws Exception {
|
||||
setConfigNotification("EK");
|
||||
|
||||
this.initializer.afterPropertiesSet();
|
||||
@@ -121,7 +124,7 @@ public class EnableRedisKeyspaceNotificationsInitializerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void afterPropertiesSetEg() throws Exception {
|
||||
void afterPropertiesSetEg() throws Exception {
|
||||
setConfigNotification("Eg");
|
||||
|
||||
this.initializer.afterPropertiesSet();
|
||||
@@ -130,7 +133,7 @@ public class EnableRedisKeyspaceNotificationsInitializerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void afterPropertiesSetE$() throws Exception {
|
||||
void afterPropertiesSetE$() throws Exception {
|
||||
setConfigNotification("E$");
|
||||
|
||||
this.initializer.afterPropertiesSet();
|
||||
@@ -139,7 +142,7 @@ public class EnableRedisKeyspaceNotificationsInitializerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void afterPropertiesSetKg() throws Exception {
|
||||
void afterPropertiesSetKg() throws Exception {
|
||||
setConfigNotification("Kg");
|
||||
|
||||
this.initializer.afterPropertiesSet();
|
||||
@@ -148,7 +151,7 @@ public class EnableRedisKeyspaceNotificationsInitializerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void afterPropertiesSetAEK() throws Exception {
|
||||
void afterPropertiesSetAEK() throws Exception {
|
||||
setConfigNotification("AEK");
|
||||
|
||||
this.initializer.afterPropertiesSet();
|
||||
@@ -157,8 +160,7 @@ public class EnableRedisKeyspaceNotificationsInitializerTests {
|
||||
}
|
||||
|
||||
private void assertOptionsContains(String... expectedValues) {
|
||||
verify(this.connection).setConfig(eq(CONFIG_NOTIFY_KEYSPACE_EVENTS),
|
||||
this.options.capture());
|
||||
verify(this.connection).setConfig(eq(CONFIG_NOTIFY_KEYSPACE_EVENTS), this.options.capture());
|
||||
for (String expectedValue : expectedValues) {
|
||||
assertThat(this.options.getValue()).contains(expectedValue);
|
||||
}
|
||||
@@ -168,7 +170,7 @@ public class EnableRedisKeyspaceNotificationsInitializerTests {
|
||||
private void setConfigNotification(String value) {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(CONFIG_NOTIFY_KEYSPACE_EVENTS, value);
|
||||
given(this.connection.getConfig(CONFIG_NOTIFY_KEYSPACE_EVENTS))
|
||||
.willReturn(properties);
|
||||
given(this.connection.getConfig(CONFIG_NOTIFY_KEYSPACE_EVENTS)).willReturn(properties);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public class RedisHttpSessionConfigurationClassPathXmlApplicationContextTests {
|
||||
|
||||
// gh-318
|
||||
@Test
|
||||
public void contextLoads() {
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
static RedisConnectionFactory connectionFactory() {
|
||||
@@ -52,4 +52,5 @@ public class RedisHttpSessionConfigurationClassPathXmlApplicationContextTests {
|
||||
|
||||
return factory;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -32,23 +32,25 @@ import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||
|
||||
public class RedisHttpSessionConfigurationMockTests {
|
||||
class RedisHttpSessionConfigurationMockTests {
|
||||
|
||||
@Mock
|
||||
RedisConnectionFactory factory;
|
||||
|
||||
@Mock
|
||||
RedisConnection connection;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
given(this.factory.getConnection()).willReturn(this.connection);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enableRedisKeyspaceNotificationsInitializerAfterPropertiesSetWhenNoOpThenNoInteractionWithConnectionFactory()
|
||||
void enableRedisKeyspaceNotificationsInitializerAfterPropertiesSetWhenNoOpThenNoInteractionWithConnectionFactory()
|
||||
throws Exception {
|
||||
EnableRedisKeyspaceNotificationsInitializer init = new EnableRedisKeyspaceNotificationsInitializer(
|
||||
this.factory, ConfigureRedisAction.NO_OP);
|
||||
EnableRedisKeyspaceNotificationsInitializer init = new EnableRedisKeyspaceNotificationsInitializer(this.factory,
|
||||
ConfigureRedisAction.NO_OP);
|
||||
|
||||
init.afterPropertiesSet();
|
||||
|
||||
@@ -56,13 +58,13 @@ public class RedisHttpSessionConfigurationMockTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enableRedisKeyspaceNotificationsInitializerAfterPropertiesSetWhenExceptionThenCloseConnection()
|
||||
void enableRedisKeyspaceNotificationsInitializerAfterPropertiesSetWhenExceptionThenCloseConnection()
|
||||
throws Exception {
|
||||
ConfigureRedisAction action = mock(ConfigureRedisAction.class);
|
||||
willThrow(new RuntimeException()).given(action).configure(this.connection);
|
||||
|
||||
EnableRedisKeyspaceNotificationsInitializer init = new EnableRedisKeyspaceNotificationsInitializer(
|
||||
this.factory, action);
|
||||
EnableRedisKeyspaceNotificationsInitializer init = new EnableRedisKeyspaceNotificationsInitializer(this.factory,
|
||||
action);
|
||||
|
||||
try {
|
||||
init.afterPropertiesSet();
|
||||
@@ -75,15 +77,16 @@ public class RedisHttpSessionConfigurationMockTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enableRedisKeyspaceNotificationsInitializerAfterPropertiesSetWhenNoExceptionThenCloseConnection()
|
||||
void enableRedisKeyspaceNotificationsInitializerAfterPropertiesSetWhenNoExceptionThenCloseConnection()
|
||||
throws Exception {
|
||||
ConfigureRedisAction action = mock(ConfigureRedisAction.class);
|
||||
|
||||
EnableRedisKeyspaceNotificationsInitializer init = new EnableRedisKeyspaceNotificationsInitializer(
|
||||
this.factory, action);
|
||||
EnableRedisKeyspaceNotificationsInitializer init = new EnableRedisKeyspaceNotificationsInitializer(this.factory,
|
||||
action);
|
||||
|
||||
init.afterPropertiesSet();
|
||||
|
||||
verify(this.connection).close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -35,10 +35,10 @@ import static org.mockito.Mockito.mock;
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration
|
||||
@WebAppConfiguration
|
||||
public class RedisHttpSessionConfigurationNoOpConfigureRedisActionTests {
|
||||
class RedisHttpSessionConfigurationNoOpConfigureRedisActionTests {
|
||||
|
||||
@Test
|
||||
public void redisConnectionFactoryNotUsedSinceNoValidation() {
|
||||
void redisConnectionFactoryNotUsedSinceNoValidation() {
|
||||
}
|
||||
|
||||
@EnableRedisHttpSession
|
||||
@@ -54,5 +54,7 @@ public class RedisHttpSessionConfigurationNoOpConfigureRedisActionTests {
|
||||
public RedisConnectionFactory redisConnectionFactory() {
|
||||
return mock(RedisConnectionFactory.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ import static org.mockito.Mockito.mock;
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration
|
||||
@WebAppConfiguration
|
||||
public class RedisHttpSessionConfigurationOverrideDefaultSerializerTests {
|
||||
class RedisHttpSessionConfigurationOverrideDefaultSerializerTests {
|
||||
|
||||
@SpringSessionRedisOperations
|
||||
RedisTemplate<Object, Object> template;
|
||||
@@ -55,14 +55,14 @@ public class RedisHttpSessionConfigurationOverrideDefaultSerializerTests {
|
||||
RedisSerializer<Object> defaultRedisSerializer;
|
||||
|
||||
@Test
|
||||
public void overrideDefaultRedisTemplate() {
|
||||
assertThat(this.template.getDefaultSerializer())
|
||||
.isSameAs(this.defaultRedisSerializer);
|
||||
void overrideDefaultRedisTemplate() {
|
||||
assertThat(this.template.getDefaultSerializer()).isSameAs(this.defaultRedisSerializer);
|
||||
}
|
||||
|
||||
@EnableRedisHttpSession
|
||||
@Configuration
|
||||
static class Config {
|
||||
|
||||
@Bean
|
||||
@SuppressWarnings("unchecked")
|
||||
public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
|
||||
@@ -78,5 +78,7 @@ public class RedisHttpSessionConfigurationOverrideDefaultSerializerTests {
|
||||
|
||||
return factory;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ import static org.mockito.Mockito.verify;
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration
|
||||
@WebAppConfiguration
|
||||
public class RedisHttpSessionConfigurationOverrideSessionTaskExecutor {
|
||||
class RedisHttpSessionConfigurationOverrideSessionTaskExecutor {
|
||||
|
||||
@Autowired
|
||||
RedisMessageListenerContainer redisMessageListenerContainer;
|
||||
@@ -56,14 +56,14 @@ public class RedisHttpSessionConfigurationOverrideSessionTaskExecutor {
|
||||
Executor springSessionRedisTaskExecutor;
|
||||
|
||||
@Test
|
||||
public void overrideSessionTaskExecutor() {
|
||||
verify(this.springSessionRedisTaskExecutor, times(1))
|
||||
.execute(any(SchedulingAwareRunnable.class));
|
||||
void overrideSessionTaskExecutor() {
|
||||
verify(this.springSessionRedisTaskExecutor, times(1)).execute(any(SchedulingAwareRunnable.class));
|
||||
}
|
||||
|
||||
@EnableRedisHttpSession
|
||||
@Configuration
|
||||
static class Config {
|
||||
|
||||
@Bean
|
||||
public Executor springSessionRedisTaskExecutor() {
|
||||
return mock(Executor.class);
|
||||
@@ -78,5 +78,7 @@ public class RedisHttpSessionConfigurationOverrideSessionTaskExecutor {
|
||||
|
||||
return factory;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ import static org.mockito.Mockito.verify;
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration
|
||||
@WebAppConfiguration
|
||||
public class RedisHttpSessionConfigurationOverrideSessionTaskExecutors {
|
||||
class RedisHttpSessionConfigurationOverrideSessionTaskExecutors {
|
||||
|
||||
@Autowired
|
||||
RedisMessageListenerContainer redisMessageListenerContainer;
|
||||
@@ -61,15 +61,15 @@ public class RedisHttpSessionConfigurationOverrideSessionTaskExecutors {
|
||||
Executor springSessionRedisSubscriptionExecutor;
|
||||
|
||||
@Test
|
||||
public void overrideSessionTaskExecutors() {
|
||||
verify(this.springSessionRedisSubscriptionExecutor, times(1))
|
||||
.execute(any(SchedulingAwareRunnable.class));
|
||||
void overrideSessionTaskExecutors() {
|
||||
verify(this.springSessionRedisSubscriptionExecutor, times(1)).execute(any(SchedulingAwareRunnable.class));
|
||||
verify(this.springSessionRedisTaskExecutor, never()).execute(any(Runnable.class));
|
||||
}
|
||||
|
||||
@EnableRedisHttpSession
|
||||
@Configuration
|
||||
static class Config {
|
||||
|
||||
@Bean
|
||||
public Executor springSessionRedisTaskExecutor() {
|
||||
return mock(Executor.class);
|
||||
@@ -89,5 +89,7 @@ public class RedisHttpSessionConfigurationOverrideSessionTaskExecutors {
|
||||
|
||||
return factory;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -51,156 +51,137 @@ import static org.mockito.Mockito.mock;
|
||||
* @author Mark Paluch
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
public class RedisHttpSessionConfigurationTests {
|
||||
class RedisHttpSessionConfigurationTests {
|
||||
|
||||
private static final String CLEANUP_CRON_EXPRESSION = "0 0 * * * *";
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@BeforeEach
|
||||
public void before() {
|
||||
void before() {
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void after() {
|
||||
void after() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveValue() {
|
||||
void resolveValue() {
|
||||
registerAndRefresh(RedisConfig.class, CustomRedisHttpSessionConfiguration.class);
|
||||
RedisHttpSessionConfiguration configuration = this.context
|
||||
.getBean(RedisHttpSessionConfiguration.class);
|
||||
assertThat(ReflectionTestUtils.getField(configuration, "redisNamespace"))
|
||||
.isEqualTo("myRedisNamespace");
|
||||
RedisHttpSessionConfiguration configuration = this.context.getBean(RedisHttpSessionConfiguration.class);
|
||||
assertThat(ReflectionTestUtils.getField(configuration, "redisNamespace")).isEqualTo("myRedisNamespace");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveValueByPlaceholder() {
|
||||
this.context.setEnvironment(new MockEnvironment()
|
||||
.withProperty("session.redis.namespace", "customRedisNamespace"));
|
||||
void resolveValueByPlaceholder() {
|
||||
this.context
|
||||
.setEnvironment(new MockEnvironment().withProperty("session.redis.namespace", "customRedisNamespace"));
|
||||
registerAndRefresh(RedisConfig.class, PropertySourceConfiguration.class,
|
||||
CustomRedisHttpSessionConfiguration2.class);
|
||||
RedisHttpSessionConfiguration configuration = this.context
|
||||
.getBean(RedisHttpSessionConfiguration.class);
|
||||
assertThat(ReflectionTestUtils.getField(configuration, "redisNamespace"))
|
||||
.isEqualTo("customRedisNamespace");
|
||||
RedisHttpSessionConfiguration configuration = this.context.getBean(RedisHttpSessionConfiguration.class);
|
||||
assertThat(ReflectionTestUtils.getField(configuration, "redisNamespace")).isEqualTo("customRedisNamespace");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customCleanupCronAnnotation() {
|
||||
registerAndRefresh(RedisConfig.class,
|
||||
CustomCleanupCronExpressionAnnotationConfiguration.class);
|
||||
void customCleanupCronAnnotation() {
|
||||
registerAndRefresh(RedisConfig.class, CustomCleanupCronExpressionAnnotationConfiguration.class);
|
||||
|
||||
RedisHttpSessionConfiguration configuration = this.context
|
||||
.getBean(RedisHttpSessionConfiguration.class);
|
||||
RedisHttpSessionConfiguration configuration = this.context.getBean(RedisHttpSessionConfiguration.class);
|
||||
assertThat(configuration).isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(configuration, "cleanupCron"))
|
||||
.isEqualTo(CLEANUP_CRON_EXPRESSION);
|
||||
assertThat(ReflectionTestUtils.getField(configuration, "cleanupCron")).isEqualTo(CLEANUP_CRON_EXPRESSION);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customCleanupCronSetter() {
|
||||
registerAndRefresh(RedisConfig.class,
|
||||
CustomCleanupCronExpressionSetterConfiguration.class);
|
||||
void customCleanupCronSetter() {
|
||||
registerAndRefresh(RedisConfig.class, CustomCleanupCronExpressionSetterConfiguration.class);
|
||||
|
||||
RedisHttpSessionConfiguration configuration = this.context
|
||||
.getBean(RedisHttpSessionConfiguration.class);
|
||||
RedisHttpSessionConfiguration configuration = this.context.getBean(RedisHttpSessionConfiguration.class);
|
||||
assertThat(configuration).isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(configuration, "cleanupCron"))
|
||||
.isEqualTo(CLEANUP_CRON_EXPRESSION);
|
||||
assertThat(ReflectionTestUtils.getField(configuration, "cleanupCron")).isEqualTo(CLEANUP_CRON_EXPRESSION);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void qualifiedConnectionFactoryRedisConfig() {
|
||||
registerAndRefresh(RedisConfig.class,
|
||||
QualifiedConnectionFactoryRedisConfig.class);
|
||||
void qualifiedConnectionFactoryRedisConfig() {
|
||||
registerAndRefresh(RedisConfig.class, QualifiedConnectionFactoryRedisConfig.class);
|
||||
|
||||
RedisOperationsSessionRepository repository = this.context
|
||||
.getBean(RedisOperationsSessionRepository.class);
|
||||
RedisConnectionFactory redisConnectionFactory = this.context
|
||||
.getBean("qualifiedRedisConnectionFactory", RedisConnectionFactory.class);
|
||||
RedisOperationsSessionRepository repository = this.context.getBean(RedisOperationsSessionRepository.class);
|
||||
RedisConnectionFactory redisConnectionFactory = this.context.getBean("qualifiedRedisConnectionFactory",
|
||||
RedisConnectionFactory.class);
|
||||
assertThat(repository).isNotNull();
|
||||
assertThat(redisConnectionFactory).isNotNull();
|
||||
RedisOperations redisOperations = (RedisOperations) ReflectionTestUtils
|
||||
.getField(repository, "sessionRedisOperations");
|
||||
RedisOperations redisOperations = (RedisOperations) ReflectionTestUtils.getField(repository,
|
||||
"sessionRedisOperations");
|
||||
assertThat(redisOperations).isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(redisOperations, "connectionFactory"))
|
||||
.isEqualTo(redisConnectionFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void primaryConnectionFactoryRedisConfig() {
|
||||
void primaryConnectionFactoryRedisConfig() {
|
||||
registerAndRefresh(RedisConfig.class, PrimaryConnectionFactoryRedisConfig.class);
|
||||
|
||||
RedisOperationsSessionRepository repository = this.context
|
||||
.getBean(RedisOperationsSessionRepository.class);
|
||||
RedisConnectionFactory redisConnectionFactory = this.context
|
||||
.getBean("primaryRedisConnectionFactory", RedisConnectionFactory.class);
|
||||
RedisOperationsSessionRepository repository = this.context.getBean(RedisOperationsSessionRepository.class);
|
||||
RedisConnectionFactory redisConnectionFactory = this.context.getBean("primaryRedisConnectionFactory",
|
||||
RedisConnectionFactory.class);
|
||||
assertThat(repository).isNotNull();
|
||||
assertThat(redisConnectionFactory).isNotNull();
|
||||
RedisOperations redisOperations = (RedisOperations) ReflectionTestUtils
|
||||
.getField(repository, "sessionRedisOperations");
|
||||
RedisOperations redisOperations = (RedisOperations) ReflectionTestUtils.getField(repository,
|
||||
"sessionRedisOperations");
|
||||
assertThat(redisOperations).isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(redisOperations, "connectionFactory"))
|
||||
.isEqualTo(redisConnectionFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void qualifiedAndPrimaryConnectionFactoryRedisConfig() {
|
||||
registerAndRefresh(RedisConfig.class,
|
||||
QualifiedAndPrimaryConnectionFactoryRedisConfig.class);
|
||||
void qualifiedAndPrimaryConnectionFactoryRedisConfig() {
|
||||
registerAndRefresh(RedisConfig.class, QualifiedAndPrimaryConnectionFactoryRedisConfig.class);
|
||||
|
||||
RedisOperationsSessionRepository repository = this.context
|
||||
.getBean(RedisOperationsSessionRepository.class);
|
||||
RedisConnectionFactory redisConnectionFactory = this.context
|
||||
.getBean("qualifiedRedisConnectionFactory", RedisConnectionFactory.class);
|
||||
RedisOperationsSessionRepository repository = this.context.getBean(RedisOperationsSessionRepository.class);
|
||||
RedisConnectionFactory redisConnectionFactory = this.context.getBean("qualifiedRedisConnectionFactory",
|
||||
RedisConnectionFactory.class);
|
||||
assertThat(repository).isNotNull();
|
||||
assertThat(redisConnectionFactory).isNotNull();
|
||||
RedisOperations redisOperations = (RedisOperations) ReflectionTestUtils
|
||||
.getField(repository, "sessionRedisOperations");
|
||||
RedisOperations redisOperations = (RedisOperations) ReflectionTestUtils.getField(repository,
|
||||
"sessionRedisOperations");
|
||||
assertThat(redisOperations).isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(redisOperations, "connectionFactory"))
|
||||
.isEqualTo(redisConnectionFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void namedConnectionFactoryRedisConfig() {
|
||||
void namedConnectionFactoryRedisConfig() {
|
||||
registerAndRefresh(RedisConfig.class, NamedConnectionFactoryRedisConfig.class);
|
||||
|
||||
RedisOperationsSessionRepository repository = this.context
|
||||
.getBean(RedisOperationsSessionRepository.class);
|
||||
RedisConnectionFactory redisConnectionFactory = this.context
|
||||
.getBean("redisConnectionFactory", RedisConnectionFactory.class);
|
||||
RedisOperationsSessionRepository repository = this.context.getBean(RedisOperationsSessionRepository.class);
|
||||
RedisConnectionFactory redisConnectionFactory = this.context.getBean("redisConnectionFactory",
|
||||
RedisConnectionFactory.class);
|
||||
assertThat(repository).isNotNull();
|
||||
assertThat(redisConnectionFactory).isNotNull();
|
||||
RedisOperations redisOperations = (RedisOperations) ReflectionTestUtils
|
||||
.getField(repository, "sessionRedisOperations");
|
||||
RedisOperations redisOperations = (RedisOperations) ReflectionTestUtils.getField(repository,
|
||||
"sessionRedisOperations");
|
||||
assertThat(redisOperations).isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(redisOperations, "connectionFactory"))
|
||||
.isEqualTo(redisConnectionFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleConnectionFactoryRedisConfig() {
|
||||
void multipleConnectionFactoryRedisConfig() {
|
||||
assertThatExceptionOfType(BeanCreationException.class)
|
||||
.isThrownBy(() -> registerAndRefresh(RedisConfig.class,
|
||||
MultipleConnectionFactoryRedisConfig.class))
|
||||
.isThrownBy(() -> registerAndRefresh(RedisConfig.class, MultipleConnectionFactoryRedisConfig.class))
|
||||
.withMessageContaining("expected single matching bean but found 2");
|
||||
}
|
||||
|
||||
@Test // gh-1252
|
||||
public void customRedisMessageListenerContainerConfig() {
|
||||
registerAndRefresh(RedisConfig.class,
|
||||
CustomRedisMessageListenerContainerConfig.class);
|
||||
void customRedisMessageListenerContainerConfig() {
|
||||
registerAndRefresh(RedisConfig.class, CustomRedisMessageListenerContainerConfig.class);
|
||||
Map<String, RedisMessageListenerContainer> beans = this.context
|
||||
.getBeansOfType(RedisMessageListenerContainer.class);
|
||||
assertThat(beans).hasSize(2);
|
||||
assertThat(beans).containsKeys("springSessionRedisMessageListenerContainer",
|
||||
"redisMessageListenerContainer");
|
||||
assertThat(beans).containsKeys("springSessionRedisMessageListenerContainer", "redisMessageListenerContainer");
|
||||
}
|
||||
|
||||
private void registerAndRefresh(Class<?>... annotatedClasses) {
|
||||
@@ -242,8 +223,7 @@ public class RedisHttpSessionConfigurationTests {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class CustomCleanupCronExpressionSetterConfiguration
|
||||
extends RedisHttpSessionConfiguration {
|
||||
static class CustomCleanupCronExpressionSetterConfiguration extends RedisHttpSessionConfiguration {
|
||||
|
||||
CustomCleanupCronExpressionSetterConfiguration() {
|
||||
setCleanupCron(CLEANUP_CRON_EXPRESSION);
|
||||
|
||||
@@ -37,7 +37,7 @@ import static org.mockito.Mockito.mock;
|
||||
public class RedisHttpSessionConfigurationXmlCustomExpireTests {
|
||||
|
||||
@Test
|
||||
public void contextLoads() {
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
static RedisConnectionFactory connectionFactory() {
|
||||
@@ -48,4 +48,5 @@ public class RedisHttpSessionConfigurationXmlCustomExpireTests {
|
||||
|
||||
return factory;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ import static org.mockito.Mockito.mock;
|
||||
public class RedisHttpSessionConfigurationXmlTests {
|
||||
|
||||
@Test
|
||||
public void contextLoads() {
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
static RedisConnectionFactory connectionFactory() {
|
||||
@@ -48,4 +48,5 @@ public class RedisHttpSessionConfigurationXmlTests {
|
||||
|
||||
return factory;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -47,10 +47,10 @@ import static org.mockito.Mockito.mock;
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration
|
||||
@WebAppConfiguration
|
||||
public class Gh109Tests {
|
||||
class Gh109Tests {
|
||||
|
||||
@Test
|
||||
public void loads() {
|
||||
void loads() {
|
||||
|
||||
}
|
||||
|
||||
@@ -63,8 +63,7 @@ public class Gh109Tests {
|
||||
* override sessionRepository construction to set the custom session-timeout
|
||||
*/
|
||||
@Bean
|
||||
public RedisOperationsSessionRepository sessionRepository(
|
||||
RedisOperations<Object, Object> sessionRedisTemplate,
|
||||
public RedisOperationsSessionRepository sessionRepository(RedisOperations<Object, Object> sessionRedisTemplate,
|
||||
ApplicationEventPublisher applicationEventPublisher) {
|
||||
RedisOperationsSessionRepository sessionRepository = new RedisOperationsSessionRepository(
|
||||
sessionRedisTemplate);
|
||||
@@ -80,5 +79,7 @@ public class Gh109Tests {
|
||||
given(connection.getConfig(anyString())).willReturn(new Properties());
|
||||
return factory;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ import static org.mockito.Mockito.mock;
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
public class RedisWebSessionConfigurationTests {
|
||||
class RedisWebSessionConfigurationTests {
|
||||
|
||||
private static final String REDIS_NAMESPACE = "testNamespace";
|
||||
|
||||
@@ -53,19 +53,19 @@ public class RedisWebSessionConfigurationTests {
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@BeforeEach
|
||||
public void before() {
|
||||
void before() {
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void after() {
|
||||
void after() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultConfiguration() {
|
||||
void defaultConfiguration() {
|
||||
registerAndRefresh(RedisConfig.class, DefaultConfig.class);
|
||||
|
||||
ReactiveRedisOperationsSessionRepository repository = this.context
|
||||
@@ -74,34 +74,31 @@ public class RedisWebSessionConfigurationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void springSessionRedisOperationsResolvingConfiguration() {
|
||||
registerAndRefresh(RedisConfig.class,
|
||||
SpringSessionRedisOperationsResolvingConfig.class);
|
||||
void springSessionRedisOperationsResolvingConfiguration() {
|
||||
registerAndRefresh(RedisConfig.class, SpringSessionRedisOperationsResolvingConfig.class);
|
||||
|
||||
ReactiveRedisOperationsSessionRepository repository = this.context
|
||||
.getBean(ReactiveRedisOperationsSessionRepository.class);
|
||||
assertThat(repository).isNotNull();
|
||||
ReactiveRedisOperations<String, Object> springSessionRedisOperations = this.context
|
||||
.getBean(SpringSessionRedisOperationsResolvingConfig.class)
|
||||
.getSpringSessionRedisOperations();
|
||||
.getBean(SpringSessionRedisOperationsResolvingConfig.class).getSpringSessionRedisOperations();
|
||||
assertThat(springSessionRedisOperations).isNotNull();
|
||||
assertThat((ReactiveRedisOperations) ReflectionTestUtils.getField(repository,
|
||||
"sessionRedisOperations")).isEqualTo(springSessionRedisOperations);
|
||||
assertThat((ReactiveRedisOperations) ReflectionTestUtils.getField(repository, "sessionRedisOperations"))
|
||||
.isEqualTo(springSessionRedisOperations);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customNamespace() {
|
||||
void customNamespace() {
|
||||
registerAndRefresh(RedisConfig.class, CustomNamespaceConfig.class);
|
||||
|
||||
ReactiveRedisOperationsSessionRepository repository = this.context
|
||||
.getBean(ReactiveRedisOperationsSessionRepository.class);
|
||||
assertThat(repository).isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(repository, "namespace"))
|
||||
.isEqualTo(REDIS_NAMESPACE + ":");
|
||||
assertThat(ReflectionTestUtils.getField(repository, "namespace")).isEqualTo(REDIS_NAMESPACE + ":");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customMaxInactiveInterval() {
|
||||
void customMaxInactiveInterval() {
|
||||
registerAndRefresh(RedisConfig.class, CustomMaxInactiveIntervalConfig.class);
|
||||
|
||||
ReactiveRedisOperationsSessionRepository repository = this.context
|
||||
@@ -112,121 +109,112 @@ public class RedisWebSessionConfigurationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customFlushMode() {
|
||||
void customFlushMode() {
|
||||
registerAndRefresh(RedisConfig.class, CustomFlushModeConfig.class);
|
||||
|
||||
ReactiveRedisOperationsSessionRepository repository = this.context
|
||||
.getBean(ReactiveRedisOperationsSessionRepository.class);
|
||||
assertThat(repository).isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(repository, "redisFlushMode"))
|
||||
.isEqualTo(RedisFlushMode.IMMEDIATE);
|
||||
assertThat(ReflectionTestUtils.getField(repository, "redisFlushMode")).isEqualTo(RedisFlushMode.IMMEDIATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void qualifiedConnectionFactoryRedisConfig() {
|
||||
registerAndRefresh(RedisConfig.class,
|
||||
QualifiedConnectionFactoryRedisConfig.class);
|
||||
void qualifiedConnectionFactoryRedisConfig() {
|
||||
registerAndRefresh(RedisConfig.class, QualifiedConnectionFactoryRedisConfig.class);
|
||||
|
||||
ReactiveRedisOperationsSessionRepository repository = this.context
|
||||
.getBean(ReactiveRedisOperationsSessionRepository.class);
|
||||
ReactiveRedisConnectionFactory redisConnectionFactory = this.context.getBean(
|
||||
"qualifiedRedisConnectionFactory", ReactiveRedisConnectionFactory.class);
|
||||
ReactiveRedisConnectionFactory redisConnectionFactory = this.context.getBean("qualifiedRedisConnectionFactory",
|
||||
ReactiveRedisConnectionFactory.class);
|
||||
assertThat(repository).isNotNull();
|
||||
assertThat(redisConnectionFactory).isNotNull();
|
||||
ReactiveRedisOperations redisOperations = (ReactiveRedisOperations) ReflectionTestUtils
|
||||
.getField(repository, "sessionRedisOperations");
|
||||
ReactiveRedisOperations redisOperations = (ReactiveRedisOperations) ReflectionTestUtils.getField(repository,
|
||||
"sessionRedisOperations");
|
||||
assertThat(redisOperations).isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(redisOperations, "connectionFactory"))
|
||||
.isEqualTo(redisConnectionFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void primaryConnectionFactoryRedisConfig() {
|
||||
void primaryConnectionFactoryRedisConfig() {
|
||||
registerAndRefresh(RedisConfig.class, PrimaryConnectionFactoryRedisConfig.class);
|
||||
|
||||
ReactiveRedisOperationsSessionRepository repository = this.context
|
||||
.getBean(ReactiveRedisOperationsSessionRepository.class);
|
||||
ReactiveRedisConnectionFactory redisConnectionFactory = this.context.getBean(
|
||||
"primaryRedisConnectionFactory", ReactiveRedisConnectionFactory.class);
|
||||
ReactiveRedisConnectionFactory redisConnectionFactory = this.context.getBean("primaryRedisConnectionFactory",
|
||||
ReactiveRedisConnectionFactory.class);
|
||||
assertThat(repository).isNotNull();
|
||||
assertThat(redisConnectionFactory).isNotNull();
|
||||
ReactiveRedisOperations redisOperations = (ReactiveRedisOperations) ReflectionTestUtils
|
||||
.getField(repository, "sessionRedisOperations");
|
||||
ReactiveRedisOperations redisOperations = (ReactiveRedisOperations) ReflectionTestUtils.getField(repository,
|
||||
"sessionRedisOperations");
|
||||
assertThat(redisOperations).isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(redisOperations, "connectionFactory"))
|
||||
.isEqualTo(redisConnectionFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void qualifiedAndPrimaryConnectionFactoryRedisConfig() {
|
||||
registerAndRefresh(RedisConfig.class,
|
||||
QualifiedAndPrimaryConnectionFactoryRedisConfig.class);
|
||||
void qualifiedAndPrimaryConnectionFactoryRedisConfig() {
|
||||
registerAndRefresh(RedisConfig.class, QualifiedAndPrimaryConnectionFactoryRedisConfig.class);
|
||||
|
||||
ReactiveRedisOperationsSessionRepository repository = this.context
|
||||
.getBean(ReactiveRedisOperationsSessionRepository.class);
|
||||
ReactiveRedisConnectionFactory redisConnectionFactory = this.context.getBean(
|
||||
"qualifiedRedisConnectionFactory", ReactiveRedisConnectionFactory.class);
|
||||
ReactiveRedisConnectionFactory redisConnectionFactory = this.context.getBean("qualifiedRedisConnectionFactory",
|
||||
ReactiveRedisConnectionFactory.class);
|
||||
assertThat(repository).isNotNull();
|
||||
assertThat(redisConnectionFactory).isNotNull();
|
||||
ReactiveRedisOperations redisOperations = (ReactiveRedisOperations) ReflectionTestUtils
|
||||
.getField(repository, "sessionRedisOperations");
|
||||
ReactiveRedisOperations redisOperations = (ReactiveRedisOperations) ReflectionTestUtils.getField(repository,
|
||||
"sessionRedisOperations");
|
||||
assertThat(redisOperations).isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(redisOperations, "connectionFactory"))
|
||||
.isEqualTo(redisConnectionFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void namedConnectionFactoryRedisConfig() {
|
||||
void namedConnectionFactoryRedisConfig() {
|
||||
registerAndRefresh(RedisConfig.class, NamedConnectionFactoryRedisConfig.class);
|
||||
|
||||
ReactiveRedisOperationsSessionRepository repository = this.context
|
||||
.getBean(ReactiveRedisOperationsSessionRepository.class);
|
||||
ReactiveRedisConnectionFactory redisConnectionFactory = this.context
|
||||
.getBean("redisConnectionFactory", ReactiveRedisConnectionFactory.class);
|
||||
ReactiveRedisConnectionFactory redisConnectionFactory = this.context.getBean("redisConnectionFactory",
|
||||
ReactiveRedisConnectionFactory.class);
|
||||
assertThat(repository).isNotNull();
|
||||
assertThat(redisConnectionFactory).isNotNull();
|
||||
ReactiveRedisOperations redisOperations = (ReactiveRedisOperations) ReflectionTestUtils
|
||||
.getField(repository, "sessionRedisOperations");
|
||||
ReactiveRedisOperations redisOperations = (ReactiveRedisOperations) ReflectionTestUtils.getField(repository,
|
||||
"sessionRedisOperations");
|
||||
assertThat(redisOperations).isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(redisOperations, "connectionFactory"))
|
||||
.isEqualTo(redisConnectionFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleConnectionFactoryRedisConfig() {
|
||||
void multipleConnectionFactoryRedisConfig() {
|
||||
assertThatExceptionOfType(BeanCreationException.class)
|
||||
.isThrownBy(() -> registerAndRefresh(RedisConfig.class,
|
||||
MultipleConnectionFactoryRedisConfig.class))
|
||||
.isThrownBy(() -> registerAndRefresh(RedisConfig.class, MultipleConnectionFactoryRedisConfig.class))
|
||||
.withMessageContaining("expected single matching bean but found 2");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void customRedisSerializerConfig() {
|
||||
void customRedisSerializerConfig() {
|
||||
registerAndRefresh(RedisConfig.class, CustomRedisSerializerConfig.class);
|
||||
|
||||
ReactiveRedisOperationsSessionRepository repository = this.context
|
||||
.getBean(ReactiveRedisOperationsSessionRepository.class);
|
||||
RedisSerializer<Object> redisSerializer = this.context
|
||||
.getBean("springSessionDefaultRedisSerializer", RedisSerializer.class);
|
||||
RedisSerializer<Object> redisSerializer = this.context.getBean("springSessionDefaultRedisSerializer",
|
||||
RedisSerializer.class);
|
||||
assertThat(repository).isNotNull();
|
||||
assertThat(redisSerializer).isNotNull();
|
||||
ReactiveRedisOperations redisOperations = (ReactiveRedisOperations) ReflectionTestUtils
|
||||
.getField(repository, "sessionRedisOperations");
|
||||
ReactiveRedisOperations redisOperations = (ReactiveRedisOperations) ReflectionTestUtils.getField(repository,
|
||||
"sessionRedisOperations");
|
||||
assertThat(redisOperations).isNotNull();
|
||||
RedisSerializationContext serializationContext = redisOperations
|
||||
.getSerializationContext();
|
||||
assertThat(ReflectionTestUtils.getField(
|
||||
serializationContext.getValueSerializationPair().getReader(),
|
||||
RedisSerializationContext serializationContext = redisOperations.getSerializationContext();
|
||||
assertThat(ReflectionTestUtils.getField(serializationContext.getValueSerializationPair().getReader(),
|
||||
"serializer")).isEqualTo(redisSerializer);
|
||||
assertThat(ReflectionTestUtils.getField(
|
||||
serializationContext.getValueSerializationPair().getWriter(),
|
||||
assertThat(ReflectionTestUtils.getField(serializationContext.getValueSerializationPair().getWriter(),
|
||||
"serializer")).isEqualTo(redisSerializer);
|
||||
assertThat(ReflectionTestUtils.getField(
|
||||
serializationContext.getHashValueSerializationPair().getReader(),
|
||||
assertThat(ReflectionTestUtils.getField(serializationContext.getHashValueSerializationPair().getReader(),
|
||||
"serializer")).isEqualTo(redisSerializer);
|
||||
assertThat(ReflectionTestUtils.getField(
|
||||
serializationContext.getHashValueSerializationPair().getWriter(),
|
||||
assertThat(ReflectionTestUtils.getField(serializationContext.getHashValueSerializationPair().getWriter(),
|
||||
"serializer")).isEqualTo(redisSerializer);
|
||||
}
|
||||
|
||||
@@ -256,7 +244,7 @@ public class RedisWebSessionConfigurationTests {
|
||||
@SpringSessionRedisOperations
|
||||
private ReactiveRedisOperations<String, Object> springSessionRedisOperations;
|
||||
|
||||
public ReactiveRedisOperations<String, Object> getSpringSessionRedisOperations() {
|
||||
ReactiveRedisOperations<String, Object> getSpringSessionRedisOperations() {
|
||||
return this.springSessionRedisOperations;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user