Skip to content

Commit 2845351

Browse files
committed
Extract RedisSessionMapper
1 parent 397d4e5 commit 2845351

File tree

6 files changed

+298
-163
lines changed

6 files changed

+298
-163
lines changed

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

Lines changed: 11 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014-2018 the original author or authors.
2+
* Copyright 2014-2019 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.
@@ -21,7 +21,6 @@
2121
import java.util.HashMap;
2222
import java.util.Map;
2323
import java.util.Set;
24-
import java.util.function.Function;
2524

2625
import org.reactivestreams.Publisher;
2726
import reactor.core.publisher.Mono;
@@ -47,29 +46,6 @@ public class ReactiveRedisOperationsSessionRepository implements
4746
*/
4847
public static final String DEFAULT_NAMESPACE = "spring:session";
4948

50-
/**
51-
* The key in the Hash representing {@link Session#getCreationTime()}.
52-
*/
53-
static final String CREATION_TIME_KEY = "creationTime";
54-
55-
/**
56-
* The key in the Hash representing {@link Session#getLastAccessedTime()}.
57-
*/
58-
static final String LAST_ACCESSED_TIME_KEY = "lastAccessedTime";
59-
60-
/**
61-
* The key in the Hash representing {@link Session#getMaxInactiveInterval()} .
62-
*/
63-
static final String MAX_INACTIVE_INTERVAL_KEY = "maxInactiveInterval";
64-
65-
/**
66-
* The prefix of the key used for session attributes. The suffix is the name of
67-
* the session attribute. For example, if the session contained an attribute named
68-
* attributeName, then there would be an entry in the hash named
69-
* sessionAttr:attributeName that mapped to its value.
70-
*/
71-
static final String ATTRIBUTE_PREFIX = "sessionAttr:";
72-
7349
private final ReactiveRedisOperations<String, Object> sessionRedisOperations;
7450

7551
/**
@@ -170,7 +146,7 @@ public Mono<RedisSession> findById(String id) {
170146
return this.sessionRedisOperations.opsForHash().entries(sessionKey)
171147
.collectMap((e) -> e.getKey().toString(), Map.Entry::getValue)
172148
.filter((map) -> !map.isEmpty())
173-
.map(new SessionMapper(id))
149+
.map(new RedisSessionMapper(id))
174150
.filter((session) -> !session.isExpired())
175151
.map(RedisSession::new)
176152
.switchIfEmpty(Mono.defer(() -> deleteById(id).then(Mono.empty())));
@@ -185,7 +161,7 @@ public Mono<Void> deleteById(String id) {
185161
}
186162

187163
private static String getAttributeKey(String attributeName) {
188-
return ATTRIBUTE_PREFIX + attributeName;
164+
return RedisSessionMapper.ATTRIBUTE_PREFIX + attributeName;
189165
}
190166

191167
private String getSessionKey(String sessionId) {
@@ -214,10 +190,12 @@ final class RedisSession implements Session {
214190
*/
215191
RedisSession() {
216192
this(new MapSession());
217-
this.delta.put(CREATION_TIME_KEY, getCreationTime().toEpochMilli());
218-
this.delta.put(MAX_INACTIVE_INTERVAL_KEY,
193+
this.delta.put(RedisSessionMapper.CREATION_TIME_KEY,
194+
getCreationTime().toEpochMilli());
195+
this.delta.put(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY,
219196
(int) getMaxInactiveInterval().getSeconds());
220-
this.delta.put(LAST_ACCESSED_TIME_KEY, getLastAccessedTime().toEpochMilli());
197+
this.delta.put(RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
198+
getLastAccessedTime().toEpochMilli());
221199
this.isNew = true;
222200
this.flushImmediateIfNecessary();
223201
}
@@ -274,7 +252,8 @@ public Instant getCreationTime() {
274252
@Override
275253
public void setLastAccessedTime(Instant lastAccessedTime) {
276254
this.cached.setLastAccessedTime(lastAccessedTime);
277-
putAndFlush(LAST_ACCESSED_TIME_KEY, getLastAccessedTime().toEpochMilli());
255+
putAndFlush(RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
256+
getLastAccessedTime().toEpochMilli());
278257
}
279258

280259
@Override
@@ -285,7 +264,7 @@ public Instant getLastAccessedTime() {
285264
@Override
286265
public void setMaxInactiveInterval(Duration interval) {
287266
this.cached.setMaxInactiveInterval(interval);
288-
putAndFlush(MAX_INACTIVE_INTERVAL_KEY,
267+
putAndFlush(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY,
289268
(int) getMaxInactiveInterval().getSeconds());
290269
}
291270

@@ -357,36 +336,4 @@ private Mono<Void> saveChangeSessionId() {
357336

358337
}
359338

360-
private static final class SessionMapper
361-
implements Function<Map<String, Object>, MapSession> {
362-
363-
private final String id;
364-
365-
private SessionMapper(String id) {
366-
this.id = id;
367-
}
368-
369-
@Override
370-
public MapSession apply(Map<String, Object> map) {
371-
MapSession session = new MapSession(this.id);
372-
373-
session.setCreationTime(
374-
Instant.ofEpochMilli((long) map.get(CREATION_TIME_KEY)));
375-
session.setLastAccessedTime(
376-
Instant.ofEpochMilli((long) map.get(LAST_ACCESSED_TIME_KEY)));
377-
session.setMaxInactiveInterval(
378-
Duration.ofSeconds((int) map.get(MAX_INACTIVE_INTERVAL_KEY)));
379-
380-
map.forEach((name, value) -> {
381-
if (name.startsWith(ATTRIBUTE_PREFIX)) {
382-
session.setAttribute(name.substring(ATTRIBUTE_PREFIX.length()),
383-
value);
384-
}
385-
});
386-
387-
return session;
388-
}
389-
390-
}
391-
392339
}

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

Lines changed: 17 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -264,33 +264,6 @@ public class RedisOperationsSessionRepository implements
264264
*/
265265
public static final String DEFAULT_NAMESPACE = "spring:session";
266266

267-
/**
268-
* The key in the Hash representing
269-
* {@link org.springframework.session.Session#getCreationTime()}.
270-
*/
271-
static final String CREATION_TIME_ATTR = "creationTime";
272-
273-
/**
274-
* The key in the Hash representing
275-
* {@link org.springframework.session.Session#getMaxInactiveInterval()}
276-
* .
277-
*/
278-
static final String MAX_INACTIVE_ATTR = "maxInactiveInterval";
279-
280-
/**
281-
* The key in the Hash representing
282-
* {@link org.springframework.session.Session#getLastAccessedTime()}.
283-
*/
284-
static final String LAST_ACCESSED_ATTR = "lastAccessedTime";
285-
286-
/**
287-
* The prefix of the key used for session attributes. The suffix is the name of
288-
* the session attribute. For example, if the session contained an attribute named
289-
* attributeName, then there would be an entry in the hash named
290-
* sessionAttr:attributeName that mapped to its value.
291-
*/
292-
static final String SESSION_ATTR_PREFIX = "sessionAttr:";
293-
294267
private int database = RedisOperationsSessionRepository.DEFAULT_DATABASE;
295268

296269
/**
@@ -480,17 +453,18 @@ private MapSession loadSession(String id, Map<Object, Object> entries) {
480453
MapSession loaded = new MapSession(id);
481454
for (Map.Entry<Object, Object> entry : entries.entrySet()) {
482455
String key = (String) entry.getKey();
483-
if (CREATION_TIME_ATTR.equals(key)) {
456+
if (RedisSessionMapper.CREATION_TIME_KEY.equals(key)) {
484457
loaded.setCreationTime(Instant.ofEpochMilli((long) entry.getValue()));
485458
}
486-
else if (MAX_INACTIVE_ATTR.equals(key)) {
459+
else if (RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY.equals(key)) {
487460
loaded.setMaxInactiveInterval(Duration.ofSeconds((int) entry.getValue()));
488461
}
489-
else if (LAST_ACCESSED_ATTR.equals(key)) {
462+
else if (RedisSessionMapper.LAST_ACCESSED_TIME_KEY.equals(key)) {
490463
loaded.setLastAccessedTime(Instant.ofEpochMilli((long) entry.getValue()));
491464
}
492-
else if (key.startsWith(SESSION_ATTR_PREFIX)) {
493-
loaded.setAttribute(key.substring(SESSION_ATTR_PREFIX.length()),
465+
else if (key.startsWith(RedisSessionMapper.ATTRIBUTE_PREFIX)) {
466+
loaded.setAttribute(
467+
key.substring(RedisSessionMapper.ATTRIBUTE_PREFIX.length()),
494468
entry.getValue());
495469
}
496470
}
@@ -688,7 +662,7 @@ private BoundHashOperations<Object, Object, Object> getSessionBoundHashOperation
688662
* @return the attribute key name
689663
*/
690664
static String getSessionAttrNameKey(String attributeName) {
691-
return SESSION_ATTR_PREFIX + attributeName;
665+
return RedisSessionMapper.ATTRIBUTE_PREFIX + attributeName;
692666
}
693667

694668
/**
@@ -714,9 +688,12 @@ final class RedisSession implements Session {
714688
*/
715689
RedisSession() {
716690
this(new MapSession());
717-
this.delta.put(CREATION_TIME_ATTR, getCreationTime().toEpochMilli());
718-
this.delta.put(MAX_INACTIVE_ATTR, (int) getMaxInactiveInterval().getSeconds());
719-
this.delta.put(LAST_ACCESSED_ATTR, getLastAccessedTime().toEpochMilli());
691+
this.delta.put(RedisSessionMapper.CREATION_TIME_KEY,
692+
getCreationTime().toEpochMilli());
693+
this.delta.put(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY,
694+
(int) getMaxInactiveInterval().getSeconds());
695+
this.delta.put(RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
696+
getLastAccessedTime().toEpochMilli());
720697
this.isNew = true;
721698
this.flushImmediateIfNecessary();
722699
}
@@ -741,7 +718,8 @@ public void setNew(boolean isNew) {
741718
@Override
742719
public void setLastAccessedTime(Instant lastAccessedTime) {
743720
this.cached.setLastAccessedTime(lastAccessedTime);
744-
this.putAndFlush(LAST_ACCESSED_ATTR, getLastAccessedTime().toEpochMilli());
721+
this.putAndFlush(RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
722+
getLastAccessedTime().toEpochMilli());
745723
}
746724

747725
@Override
@@ -776,7 +754,8 @@ public Instant getLastAccessedTime() {
776754
@Override
777755
public void setMaxInactiveInterval(Duration interval) {
778756
this.cached.setMaxInactiveInterval(interval);
779-
this.putAndFlush(MAX_INACTIVE_ATTR, (int) getMaxInactiveInterval().getSeconds());
757+
this.putAndFlush(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY,
758+
(int) getMaxInactiveInterval().getSeconds());
780759
}
781760

782761
@Override
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* Copyright 2014-2019 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;
18+
19+
import java.time.Duration;
20+
import java.time.Instant;
21+
import java.util.Map;
22+
import java.util.function.Function;
23+
24+
import org.springframework.session.MapSession;
25+
import org.springframework.session.Session;
26+
import org.springframework.util.Assert;
27+
28+
/**
29+
* A {@link Function} that converts a {@link Map} representing Redis hash to a
30+
* {@link MapSession}.
31+
*
32+
* @author Vedran Pavic
33+
* @since 2.2.0
34+
*/
35+
final class RedisSessionMapper implements Function<Map<String, Object>, MapSession> {
36+
37+
/**
38+
* The key in the hash representing {@link Session#getCreationTime()}.
39+
*/
40+
static final String CREATION_TIME_KEY = "creationTime";
41+
42+
/**
43+
* The key in the hash representing {@link Session#getLastAccessedTime()}.
44+
*/
45+
static final String LAST_ACCESSED_TIME_KEY = "lastAccessedTime";
46+
47+
/**
48+
* The key in the hash representing {@link Session#getMaxInactiveInterval()}.
49+
*/
50+
static final String MAX_INACTIVE_INTERVAL_KEY = "maxInactiveInterval";
51+
52+
/**
53+
* The prefix of the key in the hash used for session attributes. For example, if the
54+
* session contained an attribute named {@code attributeName}, then there would be an
55+
* entry in the hash named {@code sessionAttr:attributeName} that mapped to its value.
56+
*/
57+
static final String ATTRIBUTE_PREFIX = "sessionAttr:";
58+
59+
private final String sessionId;
60+
61+
RedisSessionMapper(String sessionId) {
62+
Assert.hasText(sessionId, "sessionId must not be empty");
63+
this.sessionId = sessionId;
64+
}
65+
66+
@Override
67+
public MapSession apply(Map<String, Object> map) {
68+
Assert.notEmpty(map, "map must not be empty");
69+
MapSession session = new MapSession(this.sessionId);
70+
Long creationTime = (Long) map.get(CREATION_TIME_KEY);
71+
if (creationTime == null) {
72+
handleMissingKey(CREATION_TIME_KEY);
73+
}
74+
session.setCreationTime(Instant.ofEpochMilli(creationTime));
75+
Long lastAccessedTime = (Long) map.get(LAST_ACCESSED_TIME_KEY);
76+
if (lastAccessedTime == null) {
77+
handleMissingKey(LAST_ACCESSED_TIME_KEY);
78+
}
79+
session.setLastAccessedTime(Instant.ofEpochMilli(lastAccessedTime));
80+
Integer maxInactiveInterval = (Integer) map.get(MAX_INACTIVE_INTERVAL_KEY);
81+
if (maxInactiveInterval == null) {
82+
handleMissingKey(MAX_INACTIVE_INTERVAL_KEY);
83+
}
84+
session.setMaxInactiveInterval(Duration.ofSeconds(maxInactiveInterval));
85+
map.forEach((name, value) -> {
86+
if (name.startsWith(ATTRIBUTE_PREFIX)) {
87+
session.setAttribute(name.substring(ATTRIBUTE_PREFIX.length()), value);
88+
}
89+
});
90+
return session;
91+
}
92+
93+
private static void handleMissingKey(String key) {
94+
throw new IllegalStateException(key + " key must not be null");
95+
}
96+
97+
}

0 commit comments

Comments
 (0)