Skip to content

Commit be49463

Browse files
committed
WIP
1 parent 7850f0e commit be49463

File tree

45 files changed

+1058
-1116
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1058
-1116
lines changed

spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/RedisIndexedSessionRepositoryITests.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014-2021 the original author or authors.
2+
* Copyright 2014-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -39,7 +39,7 @@
3939
import org.springframework.session.data.SessionEventRegistry;
4040
import org.springframework.session.data.redis.RedisIndexedSessionRepository.RedisSession;
4141
import org.springframework.session.data.redis.config.annotation.SpringSessionRedisOperations;
42-
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
42+
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisIndexedHttpSession;
4343
import org.springframework.session.events.SessionCreatedEvent;
4444
import org.springframework.session.events.SessionDestroyedEvent;
4545
import org.springframework.test.context.ContextConfiguration;
@@ -691,7 +691,7 @@ private String getChangedSecurityName() {
691691
}
692692

693693
@Configuration
694-
@EnableRedisHttpSession(redisNamespace = "RedisIndexedSessionRepositoryITests")
694+
@EnableRedisIndexedHttpSession(redisNamespace = "RedisIndexedSessionRepositoryITests")
695695
static class Config extends BaseConfig {
696696

697697
@Bean

spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/RedisSessionRepositoryITests.java

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014-2019 the original author or authors.
2+
* Copyright 2014-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -26,13 +26,10 @@
2626
import org.junit.jupiter.api.extension.ExtendWith;
2727

2828
import org.springframework.beans.factory.annotation.Autowired;
29-
import org.springframework.context.annotation.Bean;
3029
import org.springframework.context.annotation.Configuration;
31-
import org.springframework.data.redis.connection.RedisConnectionFactory;
32-
import org.springframework.data.redis.core.RedisTemplate;
3330
import org.springframework.session.MapSession;
34-
import org.springframework.session.config.annotation.web.http.EnableSpringHttpSession;
3531
import org.springframework.session.data.redis.RedisSessionRepository.RedisSession;
32+
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
3633
import org.springframework.test.context.ContextConfiguration;
3734
import org.springframework.test.context.junit.jupiter.SpringExtension;
3835
import org.springframework.test.context.web.WebAppConfiguration;
@@ -223,17 +220,9 @@ private static void updateSession(RedisSession session, Instant lastAccessedTime
223220
}
224221

225222
@Configuration
226-
@EnableSpringHttpSession
223+
@EnableRedisHttpSession
227224
static class Config extends BaseConfig {
228225

229-
@Bean
230-
RedisSessionRepository sessionRepository(RedisConnectionFactory redisConnectionFactory) {
231-
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
232-
redisTemplate.setConnectionFactory(redisConnectionFactory);
233-
redisTemplate.afterPropertiesSet();
234-
return new RedisSessionRepository(redisTemplate);
235-
}
236-
237226
}
238227

239228
}

spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/config/annotation/web/http/EnableRedisHttpSessionExpireSessionDestroyedTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014-2019 the original author or authors.
2+
* Copyright 2014-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -113,7 +113,7 @@ void setLock(Object lock) {
113113
}
114114

115115
@Configuration
116-
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1)
116+
@EnableRedisIndexedHttpSession(maxInactiveIntervalInSeconds = 1)
117117
static class Config extends BaseConfig {
118118

119119
@Bean

spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/taskexecutor/RedisListenerContainerTaskExecutorITests.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014-2019 the original author or authors.
2+
* Copyright 2014-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -32,7 +32,7 @@
3232
import org.springframework.data.redis.core.RedisOperations;
3333
import org.springframework.session.data.redis.AbstractRedisITests;
3434
import org.springframework.session.data.redis.config.annotation.SpringSessionRedisOperations;
35-
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
35+
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisIndexedHttpSession;
3636
import org.springframework.test.context.ContextConfiguration;
3737
import org.springframework.test.context.junit.jupiter.SpringExtension;
3838
import org.springframework.test.context.web.WebAppConfiguration;
@@ -101,7 +101,7 @@ boolean taskDispatched() throws InterruptedException {
101101
}
102102

103103
@Configuration
104-
@EnableRedisHttpSession(redisNamespace = "RedisListenerContainerTaskExecutorITests")
104+
@EnableRedisIndexedHttpSession(redisNamespace = "RedisListenerContainerTaskExecutorITests")
105105
static class Config extends BaseConfig {
106106

107107
@Bean

spring-session-data-redis/src/main/java/org/springframework/session/data/redis/RedisIndexedSessionRepository.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014-2021 the original author or authors.
2+
* Copyright 2014-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -288,7 +288,7 @@ public class RedisIndexedSessionRepository
288288

289289
private byte[] expiredKeyPrefixBytes;
290290

291-
private final RedisOperations<Object, Object> sessionRedisOperations;
291+
private final RedisOperations<String, Object> sessionRedisOperations;
292292

293293
private final RedisSessionExpirationPolicy expirationPolicy;
294294

@@ -314,7 +314,7 @@ public class RedisIndexedSessionRepository
314314
* @param sessionRedisOperations the {@link RedisOperations} to use for managing the
315315
* sessions. Cannot be null.
316316
*/
317-
public RedisIndexedSessionRepository(RedisOperations<Object, Object> sessionRedisOperations) {
317+
public RedisIndexedSessionRepository(RedisOperations<String, Object> sessionRedisOperations) {
318318
Assert.notNull(sessionRedisOperations, "sessionRedisOperations cannot be null");
319319
this.sessionRedisOperations = sessionRedisOperations;
320320
this.expirationPolicy = new RedisSessionExpirationPolicy(sessionRedisOperations, this::getExpirationsKey,
@@ -406,7 +406,7 @@ private void configureSessionChannels() {
406406
* Returns the {@link RedisOperations} used for sessions.
407407
* @return the {@link RedisOperations} used for sessions
408408
*/
409-
public RedisOperations<Object, Object> getSessionRedisOperations() {
409+
public RedisOperations<String, Object> getSessionRedisOperations() {
410410
return this.sessionRedisOperations;
411411
}
412412

@@ -454,7 +454,7 @@ public Map<String, RedisSession> findByIndexNameAndIndexValue(String indexName,
454454
* @return the Redis session
455455
*/
456456
private RedisSession getSession(String id, boolean allowExpired) {
457-
Map<Object, Object> entries = getSessionBoundHashOperations(id).entries();
457+
Map<String, Object> entries = getSessionBoundHashOperations(id).entries();
458458
if (entries.isEmpty()) {
459459
return null;
460460
}
@@ -467,10 +467,10 @@ private RedisSession getSession(String id, boolean allowExpired) {
467467
return result;
468468
}
469469

470-
private MapSession loadSession(String id, Map<Object, Object> entries) {
470+
private MapSession loadSession(String id, Map<String, Object> entries) {
471471
MapSession loaded = new MapSession(id);
472-
for (Map.Entry<Object, Object> entry : entries.entrySet()) {
473-
String key = (String) entry.getKey();
472+
for (Map.Entry<String, Object> entry : entries.entrySet()) {
473+
String key = entry.getKey();
474474
if (RedisSessionMapper.CREATION_TIME_KEY.equals(key)) {
475475
loaded.setCreationTime(Instant.ofEpochMilli((long) entry.getValue()));
476476
}
@@ -522,7 +522,7 @@ public void onMessage(Message message, byte[] pattern) {
522522
if (ByteUtils.startsWith(messageChannel, this.sessionCreatedChannelPrefixBytes)) {
523523
// TODO: is this thread safe?
524524
@SuppressWarnings("unchecked")
525-
Map<Object, Object> loaded = (Map<Object, Object>) this.defaultSerializer.deserialize(message.getBody());
525+
Map<String, Object> loaded = (Map<String, Object>) this.defaultSerializer.deserialize(message.getBody());
526526
handleCreated(loaded, new String(messageChannel));
527527
return;
528528
}
@@ -571,7 +571,7 @@ private void cleanupPrincipalIndex(RedisSession session) {
571571
}
572572
}
573573

574-
private void handleCreated(Map<Object, Object> loaded, String channel) {
574+
private void handleCreated(Map<String, Object> loaded, String channel) {
575575
String id = channel.substring(channel.lastIndexOf(":") + 1);
576576
Session session = loadSession(id, loaded);
577577
publishEvent(new SessionCreatedEvent(this, session));
@@ -661,7 +661,7 @@ public String getSessionExpiredChannel() {
661661
* @param sessionId the id of the {@link Session} to work with
662662
* @return the {@link BoundHashOperations} to operate on a {@link Session}
663663
*/
664-
private BoundHashOperations<Object, Object, Object> getSessionBoundHashOperations(String sessionId) {
664+
private BoundHashOperations<String, String, Object> getSessionBoundHashOperations(String sessionId) {
665665
String key = getSessionKey(sessionId);
666666
return this.sessionRedisOperations.boundHashOps(key);
667667
}

spring-session-data-redis/src/main/java/org/springframework/session/data/redis/RedisSessionExpirationPolicy.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014-2021 the original author or authors.
2+
* Copyright 2014-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -52,13 +52,13 @@ final class RedisSessionExpirationPolicy {
5252

5353
private static final String SESSION_EXPIRES_PREFIX = "expires:";
5454

55-
private final RedisOperations<Object, Object> redis;
55+
private final RedisOperations<String, Object> redis;
5656

5757
private final Function<Long, String> lookupExpirationKey;
5858

5959
private final Function<String, String> lookupSessionKey;
6060

61-
RedisSessionExpirationPolicy(RedisOperations<Object, Object> sessionRedisOperations,
61+
RedisSessionExpirationPolicy(RedisOperations<String, Object> sessionRedisOperations,
6262
Function<Long, String> lookupExpirationKey, Function<String, String> lookupSessionKey) {
6363
super();
6464
this.redis = sessionRedisOperations;
@@ -96,7 +96,7 @@ void onExpirationUpdated(Long originalExpirationTimeInMilli, Session session) {
9696
}
9797

9898
String expireKey = getExpirationKey(toExpire);
99-
BoundSetOperations<Object, Object> expireOperations = this.redis.boundSetOps(expireKey);
99+
BoundSetOperations<String, Object> expireOperations = this.redis.boundSetOps(expireKey);
100100
expireOperations.add(keyToExpire);
101101

102102
long fiveMinutesAfterExpires = sessionExpireInSeconds + TimeUnit.MINUTES.toSeconds(5);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
/*
2+
* Copyright 2014-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.session.data.redis.config.annotation.web.http;
18+
19+
import java.util.List;
20+
import java.util.stream.Collectors;
21+
22+
import org.springframework.beans.factory.BeanClassLoaderAware;
23+
import org.springframework.beans.factory.ObjectProvider;
24+
import org.springframework.beans.factory.annotation.Autowired;
25+
import org.springframework.beans.factory.annotation.Qualifier;
26+
import org.springframework.context.annotation.Configuration;
27+
import org.springframework.data.redis.connection.RedisConnectionFactory;
28+
import org.springframework.data.redis.core.RedisTemplate;
29+
import org.springframework.data.redis.serializer.RedisSerializer;
30+
import org.springframework.data.redis.serializer.StringRedisSerializer;
31+
import org.springframework.session.FlushMode;
32+
import org.springframework.session.MapSession;
33+
import org.springframework.session.SaveMode;
34+
import org.springframework.session.Session;
35+
import org.springframework.session.SessionRepository;
36+
import org.springframework.session.config.SessionRepositoryCustomizer;
37+
import org.springframework.session.config.annotation.web.http.SpringHttpSessionConfiguration;
38+
import org.springframework.session.data.redis.RedisSessionRepository;
39+
import org.springframework.session.data.redis.config.annotation.SpringSessionRedisConnectionFactory;
40+
import org.springframework.util.Assert;
41+
42+
/**
43+
* Base configuration class for Redis based {@link SessionRepository} implementations.
44+
*
45+
* @param <T> the {@link SessionRepository} type
46+
* @author Rob Winch
47+
* @author Eddú Meléndez
48+
* @author Vedran Pavic
49+
* @since 1.0
50+
* @see RedisHttpSessionConfiguration
51+
* @see RedisIndexedHttpSessionConfiguration
52+
*/
53+
@Configuration(proxyBeanMethods = false)
54+
public abstract class AbstractRedisHttpSessionConfiguration<T extends SessionRepository<? extends Session>>
55+
extends SpringHttpSessionConfiguration implements BeanClassLoaderAware {
56+
57+
private Integer maxInactiveIntervalInSeconds = MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS;
58+
59+
private String redisNamespace = RedisSessionRepository.DEFAULT_KEY_NAMESPACE;
60+
61+
private FlushMode flushMode = FlushMode.ON_SAVE;
62+
63+
private SaveMode saveMode = SaveMode.ON_SET_ATTRIBUTE;
64+
65+
private RedisConnectionFactory redisConnectionFactory;
66+
67+
private RedisSerializer<Object> defaultRedisSerializer;
68+
69+
private List<SessionRepositoryCustomizer<T>> sessionRepositoryCustomizers;
70+
71+
private ClassLoader classLoader;
72+
73+
public abstract T sessionRepository();
74+
75+
public void setMaxInactiveIntervalInSeconds(int maxInactiveIntervalInSeconds) {
76+
this.maxInactiveIntervalInSeconds = maxInactiveIntervalInSeconds;
77+
}
78+
79+
protected Integer getMaxInactiveIntervalInSeconds() {
80+
return this.maxInactiveIntervalInSeconds;
81+
}
82+
83+
public void setRedisNamespace(String namespace) {
84+
this.redisNamespace = namespace;
85+
}
86+
87+
protected String getRedisNamespace() {
88+
return this.redisNamespace;
89+
}
90+
91+
public void setFlushMode(FlushMode flushMode) {
92+
Assert.notNull(flushMode, "flushMode cannot be null");
93+
this.flushMode = flushMode;
94+
}
95+
96+
protected FlushMode getFlushMode() {
97+
return this.flushMode;
98+
}
99+
100+
public void setSaveMode(SaveMode saveMode) {
101+
this.saveMode = saveMode;
102+
}
103+
104+
protected SaveMode getSaveMode() {
105+
return this.saveMode;
106+
}
107+
108+
@Autowired
109+
public void setRedisConnectionFactory(
110+
@SpringSessionRedisConnectionFactory ObjectProvider<RedisConnectionFactory> springSessionRedisConnectionFactory,
111+
ObjectProvider<RedisConnectionFactory> redisConnectionFactory) {
112+
RedisConnectionFactory redisConnectionFactoryToUse = springSessionRedisConnectionFactory.getIfAvailable();
113+
if (redisConnectionFactoryToUse == null) {
114+
redisConnectionFactoryToUse = redisConnectionFactory.getObject();
115+
}
116+
this.redisConnectionFactory = redisConnectionFactoryToUse;
117+
}
118+
119+
protected RedisConnectionFactory getRedisConnectionFactory() {
120+
return this.redisConnectionFactory;
121+
}
122+
123+
@Autowired(required = false)
124+
@Qualifier("springSessionDefaultRedisSerializer")
125+
public void setDefaultRedisSerializer(RedisSerializer<Object> defaultRedisSerializer) {
126+
this.defaultRedisSerializer = defaultRedisSerializer;
127+
}
128+
129+
protected RedisSerializer<Object> getDefaultRedisSerializer() {
130+
return this.defaultRedisSerializer;
131+
}
132+
133+
@Autowired(required = false)
134+
public void setSessionRepositoryCustomizer(
135+
ObjectProvider<SessionRepositoryCustomizer<T>> sessionRepositoryCustomizers) {
136+
this.sessionRepositoryCustomizers = sessionRepositoryCustomizers.orderedStream().collect(Collectors.toList());
137+
}
138+
139+
protected List<SessionRepositoryCustomizer<T>> getSessionRepositoryCustomizers() {
140+
return this.sessionRepositoryCustomizers;
141+
}
142+
143+
@Override
144+
public void setBeanClassLoader(ClassLoader classLoader) {
145+
this.classLoader = classLoader;
146+
}
147+
148+
protected RedisTemplate<String, Object> createRedisTemplate() {
149+
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
150+
redisTemplate.setKeySerializer(new StringRedisSerializer());
151+
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
152+
if (getDefaultRedisSerializer() != null) {
153+
redisTemplate.setDefaultSerializer(getDefaultRedisSerializer());
154+
}
155+
redisTemplate.setConnectionFactory(getRedisConnectionFactory());
156+
redisTemplate.setBeanClassLoader(this.classLoader);
157+
redisTemplate.afterPropertiesSet();
158+
return redisTemplate;
159+
}
160+
161+
}

0 commit comments

Comments
 (0)