Add Session.changeSessionId
This commit is contained in:
@@ -50,7 +50,7 @@ public class IndexDocTests {
|
||||
|
||||
@Test
|
||||
public void repositoryDemo() {
|
||||
RepositoryDemo<Session> demo = new RepositoryDemo<>();
|
||||
RepositoryDemo<MapSession> demo = new RepositoryDemo<>();
|
||||
demo.repository = new MapSessionRepository();
|
||||
|
||||
demo.demo();
|
||||
@@ -82,7 +82,7 @@ public class IndexDocTests {
|
||||
|
||||
@Test
|
||||
public void expireRepositoryDemo() {
|
||||
ExpiringRepositoryDemo<Session> demo = new ExpiringRepositoryDemo<>();
|
||||
ExpiringRepositoryDemo<MapSession> demo = new ExpiringRepositoryDemo<>();
|
||||
demo.repository = new MapSessionRepository();
|
||||
|
||||
demo.demo();
|
||||
|
||||
@@ -34,7 +34,6 @@ import com.hazelcast.core.HazelcastInstance;
|
||||
import org.springframework.session.MapSession;
|
||||
import org.springframework.session.MapSessionRepository;
|
||||
import org.springframework.session.Session;
|
||||
import org.springframework.session.SessionRepository;
|
||||
import org.springframework.session.web.http.SessionRepositoryFilter;
|
||||
|
||||
@WebListener
|
||||
@@ -48,8 +47,8 @@ public class Initializer implements ServletContextListener {
|
||||
this.instance = createHazelcastInstance();
|
||||
Map<String, Session> sessions = this.instance.getMap(SESSION_MAP_NAME);
|
||||
|
||||
SessionRepository<Session> sessionRepository = new MapSessionRepository(sessions);
|
||||
SessionRepositoryFilter<Session> filter = new SessionRepositoryFilter<>(
|
||||
MapSessionRepository sessionRepository = new MapSessionRepository(sessions);
|
||||
SessionRepositoryFilter<? extends Session> filter = new SessionRepositoryFilter<>(
|
||||
sessionRepository);
|
||||
|
||||
Dynamic fr = sce.getServletContext().addFilter("springSessionFilter", filter);
|
||||
|
||||
@@ -39,7 +39,7 @@ import org.springframework.session.events.SessionExpiredEvent;
|
||||
* @author Rob Winch
|
||||
* @since 2.0
|
||||
*/
|
||||
public class MapReactorSessionRepository implements ReactorSessionRepository<Session> {
|
||||
public class MapReactorSessionRepository implements ReactorSessionRepository<MapSession> {
|
||||
/**
|
||||
* If non-null, this value is used to override
|
||||
* {@link Session#setMaxInactiveInterval(Duration)}.
|
||||
@@ -80,7 +80,7 @@ public class MapReactorSessionRepository implements ReactorSessionRepository<Ses
|
||||
}
|
||||
this.sessions = new ConcurrentHashMap<>();
|
||||
for (Session session : sessions) {
|
||||
this.performSave(session);
|
||||
this.performSave(new MapSession(session));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ public class MapReactorSessionRepository implements ReactorSessionRepository<Ses
|
||||
}
|
||||
this.sessions = new ConcurrentHashMap<>();
|
||||
for (Session session : sessions) {
|
||||
this.performSave(session);
|
||||
this.performSave(new MapSession(session));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,15 +110,19 @@ public class MapReactorSessionRepository implements ReactorSessionRepository<Ses
|
||||
this.defaultMaxInactiveInterval = Integer.valueOf(defaultMaxInactiveInterval);
|
||||
}
|
||||
|
||||
public Mono<Void> save(Session session) {
|
||||
public Mono<Void> save(MapSession session) {
|
||||
return Mono.fromRunnable(() -> performSave(session));
|
||||
}
|
||||
|
||||
private void performSave(Session session) {
|
||||
private void performSave(MapSession session) {
|
||||
if (!session.getId().equals(session.getOriginalId())) {
|
||||
this.sessions.remove(session.getOriginalId());
|
||||
session.setOriginalId(session.getId());
|
||||
}
|
||||
this.sessions.put(session.getId(), new MapSession(session));
|
||||
}
|
||||
|
||||
public Mono<Session> findById(String id) {
|
||||
public Mono<MapSession> findById(String id) {
|
||||
return Mono.defer(() -> {
|
||||
Session saved = this.sessions.get(id);
|
||||
if (saved == null) {
|
||||
@@ -136,9 +140,9 @@ public class MapReactorSessionRepository implements ReactorSessionRepository<Ses
|
||||
return Mono.fromRunnable(() -> this.sessions.remove(id));
|
||||
}
|
||||
|
||||
public Mono<Session> createSession() {
|
||||
public Mono<MapSession> createSession() {
|
||||
return Mono.defer(() -> {
|
||||
Session result = new MapSession();
|
||||
MapSession result = new MapSession();
|
||||
if (this.defaultMaxInactiveInterval != null) {
|
||||
result.setMaxInactiveInterval(
|
||||
Duration.ofSeconds(this.defaultMaxInactiveInterval));
|
||||
|
||||
@@ -52,6 +52,7 @@ public final class MapSession implements Session, Serializable {
|
||||
public static final int DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS = 1800;
|
||||
|
||||
private String id;
|
||||
private String originalId;
|
||||
private Map<String, Object> sessionAttrs = new HashMap<>();
|
||||
private Instant creationTime = Instant.now();
|
||||
private Instant lastAccessedTime = this.creationTime;
|
||||
@@ -65,9 +66,10 @@ public final class MapSession implements Session, Serializable {
|
||||
* Creates a new instance with a secure randomly generated identifier.
|
||||
*/
|
||||
public MapSession() {
|
||||
this(UUID.randomUUID().toString());
|
||||
this(generateId());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new instance with the specified id. This is preferred to the default
|
||||
* constructor when the id is known to prevent unnecessary consumption on entropy
|
||||
@@ -77,6 +79,7 @@ public final class MapSession implements Session, Serializable {
|
||||
*/
|
||||
public MapSession(String id) {
|
||||
this.id = id;
|
||||
this.originalId = id;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,6 +93,7 @@ public final class MapSession implements Session, Serializable {
|
||||
throw new IllegalArgumentException("session cannot be null");
|
||||
}
|
||||
this.id = session.getId();
|
||||
this.originalId = this.id;
|
||||
this.sessionAttrs = new HashMap<>(
|
||||
session.getAttributeNames().size());
|
||||
for (String attrName : session.getAttributeNames()) {
|
||||
@@ -115,6 +119,20 @@ public final class MapSession implements Session, Serializable {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
String getOriginalId() {
|
||||
return this.originalId;
|
||||
}
|
||||
|
||||
void setOriginalId(String originalId) {
|
||||
this.originalId = originalId;
|
||||
}
|
||||
|
||||
public String changeSessionId() {
|
||||
String changedId = generateId();
|
||||
setId(changedId);
|
||||
return changedId;
|
||||
}
|
||||
|
||||
public Instant getLastAccessedTime() {
|
||||
return this.lastAccessedTime;
|
||||
}
|
||||
@@ -188,5 +206,9 @@ public final class MapSession implements Session, Serializable {
|
||||
return this.id.hashCode();
|
||||
}
|
||||
|
||||
private static String generateId() {
|
||||
return UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 7160779239673823561L;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ import org.springframework.session.events.SessionExpiredEvent;
|
||||
* @author Rob Winch
|
||||
* @since 1.0
|
||||
*/
|
||||
public class MapSessionRepository implements SessionRepository<Session> {
|
||||
public class MapSessionRepository implements SessionRepository<MapSession> {
|
||||
/**
|
||||
* If non-null, this value is used to override
|
||||
* {@link Session#setMaxInactiveInterval(Duration)}.
|
||||
@@ -76,11 +76,15 @@ public class MapSessionRepository implements SessionRepository<Session> {
|
||||
this.defaultMaxInactiveInterval = Integer.valueOf(defaultMaxInactiveInterval);
|
||||
}
|
||||
|
||||
public void save(Session session) {
|
||||
public void save(MapSession session) {
|
||||
if (!session.getId().equals(session.getOriginalId())) {
|
||||
this.sessions.remove(session.getOriginalId());
|
||||
session.setOriginalId(session.getId());
|
||||
}
|
||||
this.sessions.put(session.getId(), new MapSession(session));
|
||||
}
|
||||
|
||||
public Session findById(String id) {
|
||||
public MapSession findById(String id) {
|
||||
Session saved = this.sessions.get(id);
|
||||
if (saved == null) {
|
||||
return null;
|
||||
@@ -96,8 +100,8 @@ public class MapSessionRepository implements SessionRepository<Session> {
|
||||
this.sessions.remove(id);
|
||||
}
|
||||
|
||||
public Session createSession() {
|
||||
Session result = new MapSession();
|
||||
public MapSession createSession() {
|
||||
MapSession result = new MapSession();
|
||||
if (this.defaultMaxInactiveInterval != null) {
|
||||
result.setMaxInactiveInterval(
|
||||
Duration.ofSeconds(this.defaultMaxInactiveInterval));
|
||||
|
||||
@@ -37,6 +37,12 @@ public interface Session {
|
||||
*/
|
||||
String getId();
|
||||
|
||||
/**
|
||||
* Changes the session id. After invoking the {@link #getId()} will return a new identifier.
|
||||
* @return the new session id which {@link #getId()} will now return
|
||||
*/
|
||||
String changeSessionId();
|
||||
|
||||
/**
|
||||
* Gets the Object associated with the specified name or null if no Object is
|
||||
* associated to that name.
|
||||
|
||||
@@ -18,9 +18,6 @@ package org.springframework.session.web.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletContext;
|
||||
@@ -274,30 +271,7 @@ public class SessionRepositoryFilter<S extends Session>
|
||||
"Cannot change session ID. There is no session associated with this request.");
|
||||
}
|
||||
|
||||
// eagerly get session attributes in case implementation lazily loads them
|
||||
Map<String, Object> attrs = new HashMap<>();
|
||||
Enumeration<String> iAttrNames = session.getAttributeNames();
|
||||
while (iAttrNames.hasMoreElements()) {
|
||||
String attrName = iAttrNames.nextElement();
|
||||
Object value = session.getAttribute(attrName);
|
||||
|
||||
attrs.put(attrName, value);
|
||||
}
|
||||
|
||||
SessionRepositoryFilter.this.sessionRepository.deleteById(session.getId());
|
||||
HttpSessionWrapper original = getCurrentSession();
|
||||
setCurrentSession(null);
|
||||
|
||||
HttpSessionWrapper newSession = getSession();
|
||||
original.setSession(newSession.getSession());
|
||||
|
||||
newSession.setMaxInactiveInterval(session.getMaxInactiveInterval());
|
||||
for (Map.Entry<String, Object> attr : attrs.entrySet()) {
|
||||
String attrName = attr.getKey();
|
||||
Object attrValue = attr.getValue();
|
||||
newSession.setAttribute(attrName, attrValue);
|
||||
}
|
||||
return newSession.getId();
|
||||
return getCurrentSession().getSession().changeSessionId();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -145,4 +145,32 @@ public class MapReactorSessionRepositoryTests {
|
||||
assertThat(session.getMaxInactiveInterval())
|
||||
.isEqualTo(expectedMaxInterval);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenNotYetSaved() {
|
||||
MapSession createSession = this.repository.createSession().block();
|
||||
|
||||
String originalId = createSession.getId();
|
||||
createSession.changeSessionId();
|
||||
|
||||
this.repository.save(createSession).block();
|
||||
|
||||
assertThat(this.repository.findById(originalId).block()).isNull();
|
||||
assertThat(this.repository.findById(createSession.getId()).block()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenSaved() {
|
||||
MapSession createSession = this.repository.createSession().block();
|
||||
|
||||
this.repository.save(createSession).block();
|
||||
|
||||
String originalId = createSession.getId();
|
||||
createSession.changeSessionId();
|
||||
|
||||
this.repository.save(createSession).block();
|
||||
|
||||
assertThat(this.repository.findById(originalId).block()).isNull();
|
||||
assertThat(this.repository.findById(createSession.getId()).block()).isNotNull();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,4 +66,32 @@ public class MapSessionRepositoryTests {
|
||||
assertThat(session.getMaxInactiveInterval())
|
||||
.isEqualTo(expectedMaxInterval);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenNotYetSaved() {
|
||||
MapSession createSession = this.repository.createSession();
|
||||
|
||||
String originalId = createSession.getId();
|
||||
createSession.changeSessionId();
|
||||
|
||||
this.repository.save(createSession);
|
||||
|
||||
assertThat(this.repository.findById(originalId)).isNull();
|
||||
assertThat(this.repository.findById(createSession.getId())).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenSaved() {
|
||||
MapSession createSession = this.repository.createSession();
|
||||
|
||||
this.repository.save(createSession);
|
||||
|
||||
String originalId = createSession.getId();
|
||||
createSession.changeSessionId();
|
||||
|
||||
this.repository.save(createSession);
|
||||
|
||||
assertThat(this.repository.findById(originalId)).isNull();
|
||||
assertThat(this.repository.findById(createSession.getId())).isNotNull();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,6 +134,10 @@ public class MapSessionTests {
|
||||
return Instant.EPOCH;
|
||||
}
|
||||
|
||||
public String changeSessionId() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return "id";
|
||||
}
|
||||
|
||||
@@ -76,9 +76,9 @@ public class SessionRepositoryFilterTests {
|
||||
|
||||
private Map<String, Session> sessions;
|
||||
|
||||
private SessionRepository<Session> sessionRepository;
|
||||
private SessionRepository<MapSession> sessionRepository;
|
||||
|
||||
private SessionRepositoryFilter<Session> filter;
|
||||
private SessionRepositoryFilter<MapSession> filter;
|
||||
|
||||
private MockHttpServletRequest request;
|
||||
|
||||
@@ -422,7 +422,7 @@ public class SessionRepositoryFilterTests {
|
||||
public void doFilterSetsCookieIfChanged() throws Exception {
|
||||
this.sessionRepository = new MapSessionRepository() {
|
||||
@Override
|
||||
public Session findById(String id) {
|
||||
public MapSession findById(String id) {
|
||||
return createSession();
|
||||
}
|
||||
};
|
||||
@@ -1256,7 +1256,7 @@ public class SessionRepositoryFilterTests {
|
||||
@SuppressWarnings("unchecked")
|
||||
public void doFilterRequestSessionNoRequestSessionNoSessionRepositoryInteractions()
|
||||
throws Exception {
|
||||
SessionRepository<Session> sessionRepository = spy(new MapSessionRepository());
|
||||
SessionRepository<MapSession> sessionRepository = spy(new MapSessionRepository());
|
||||
|
||||
this.filter = new SessionRepositoryFilter<>(sessionRepository);
|
||||
|
||||
@@ -1283,7 +1283,7 @@ public class SessionRepositoryFilterTests {
|
||||
|
||||
@Test
|
||||
public void doFilterLazySessionCreation() throws Exception {
|
||||
SessionRepository<Session> sessionRepository = spy(new MapSessionRepository());
|
||||
SessionRepository<MapSession> sessionRepository = spy(new MapSessionRepository());
|
||||
|
||||
this.filter = new SessionRepositoryFilter<>(sessionRepository);
|
||||
|
||||
@@ -1299,9 +1299,9 @@ public class SessionRepositoryFilterTests {
|
||||
|
||||
@Test
|
||||
public void doFilterLazySessionUpdates() throws Exception {
|
||||
Session session = this.sessionRepository.createSession();
|
||||
MapSession session = this.sessionRepository.createSession();
|
||||
this.sessionRepository.save(session);
|
||||
SessionRepository<Session> sessionRepository = spy(this.sessionRepository);
|
||||
SessionRepository<MapSession> sessionRepository = spy(this.sessionRepository);
|
||||
setSessionCookie(session.getId());
|
||||
|
||||
this.filter = new SessionRepositoryFilter<>(sessionRepository);
|
||||
|
||||
@@ -455,6 +455,88 @@ public class RedisOperationsSessionRepositoryITests extends AbstractITests {
|
||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenOnlyChangeId() throws Exception {
|
||||
String attrName = "changeSessionId";
|
||||
String attrValue = "changeSessionId-value";
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(attrName, attrValue);
|
||||
|
||||
this.repository.save(toSave);
|
||||
|
||||
RedisSession findById = this.repository.findById(toSave.getId());
|
||||
|
||||
assertThat(findById.<String>getAttribute(attrName)).isEqualTo(attrValue);
|
||||
|
||||
String originalFindById = findById.getId();
|
||||
String changeSessionId = findById.changeSessionId();
|
||||
|
||||
this.repository.save(findById);
|
||||
|
||||
assertThat(this.repository.findById(originalFindById)).isNull();
|
||||
|
||||
RedisSession findByChangeSessionId = this.repository.findById(changeSessionId);
|
||||
|
||||
assertThat(findByChangeSessionId.<String>getAttribute(attrName)).isEqualTo(attrValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenChangeTwice() throws Exception {
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
|
||||
this.repository.save(toSave);
|
||||
|
||||
String originalId = toSave.getId();
|
||||
String changeId1 = toSave.changeSessionId();
|
||||
String changeId2 = toSave.changeSessionId();
|
||||
|
||||
this.repository.save(toSave);
|
||||
|
||||
assertThat(this.repository.findById(originalId)).isNull();
|
||||
assertThat(this.repository.findById(changeId1)).isNull();
|
||||
assertThat(this.repository.findById(changeId2)).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenSetAttributeOnChangedSession() throws Exception {
|
||||
String attrName = "changeSessionId";
|
||||
String attrValue = "changeSessionId-value";
|
||||
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
|
||||
this.repository.save(toSave);
|
||||
|
||||
RedisSession findById = this.repository.findById(toSave.getId());
|
||||
|
||||
findById.setAttribute(attrName, attrValue);
|
||||
|
||||
String originalFindById = findById.getId();
|
||||
String changeSessionId = findById.changeSessionId();
|
||||
|
||||
this.repository.save(findById);
|
||||
|
||||
assertThat(this.repository.findById(originalFindById)).isNull();
|
||||
|
||||
RedisSession findByChangeSessionId = this.repository.findById(changeSessionId);
|
||||
|
||||
assertThat(findByChangeSessionId.<String>getAttribute(attrName)).isEqualTo(attrValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenHasNotSaved() throws Exception {
|
||||
String attrName = "changeSessionId";
|
||||
String attrValue = "changeSessionId-value";
|
||||
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
String originalId = toSave.getId();
|
||||
toSave.changeSessionId();
|
||||
|
||||
this.repository.save(toSave);
|
||||
|
||||
assertThat(this.repository.findById(toSave.getId())).isNotNull();
|
||||
assertThat(this.repository.findById(originalId)).isNull();
|
||||
}
|
||||
|
||||
private String getSecurityName() {
|
||||
return this.context.getAuthentication().getName();
|
||||
}
|
||||
|
||||
@@ -675,6 +675,7 @@ public class RedisOperationsSessionRepository implements
|
||||
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
|
||||
@@ -699,6 +700,7 @@ public class RedisOperationsSessionRepository implements
|
||||
Assert.notNull(cached, "MapSession cannot be null");
|
||||
this.cached = cached;
|
||||
this.originalPrincipalName = PRINCIPAL_NAME_RESOLVER.resolvePrincipal(this);
|
||||
this.originalSessionId = cached.getId();
|
||||
}
|
||||
|
||||
public void setNew(boolean isNew) {
|
||||
@@ -726,6 +728,10 @@ public class RedisOperationsSessionRepository implements
|
||||
return this.cached.getId();
|
||||
}
|
||||
|
||||
public String changeSessionId() {
|
||||
return this.cached.changeSessionId();
|
||||
}
|
||||
|
||||
public Instant getLastAccessedTime() {
|
||||
return this.cached.getLastAccessedTime();
|
||||
}
|
||||
@@ -773,10 +779,11 @@ public class RedisOperationsSessionRepository implements
|
||||
* session.
|
||||
*/
|
||||
private void saveDelta() {
|
||||
String sessionId = getId();
|
||||
saveChangeSessionId(sessionId);
|
||||
if (this.delta.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
String sessionId = getId();
|
||||
getSessionBoundHashOperations(sessionId).putAll(this.delta);
|
||||
String principalSessionKey = getSessionAttrNameKey(
|
||||
FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME);
|
||||
@@ -806,6 +813,15 @@ public class RedisOperationsSessionRepository implements
|
||||
RedisOperationsSessionRepository.this.expirationPolicy
|
||||
.onExpirationUpdated(originalExpiration, this);
|
||||
}
|
||||
|
||||
private void saveChangeSessionId(String sessionId) {
|
||||
if (!isNew() && !sessionId.equals(this.originalSessionId)) {
|
||||
String originalSessionIdKey = getSessionKey(this.originalSessionId);
|
||||
String sessionIdKey = getSessionKey(sessionId);
|
||||
RedisOperationsSessionRepository.this.sessionRedisOperations.rename(originalSessionIdKey, sessionIdKey);
|
||||
this.originalSessionId = sessionId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -131,6 +131,16 @@ public class RedisOperationsSessionRepositoryTests {
|
||||
this.redisRepository.save(session);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionId() {
|
||||
RedisSession createSession = this.redisRepository.createSession();
|
||||
String originalId = createSession.getId();
|
||||
String changeSessionId = createSession.changeSessionId();
|
||||
|
||||
assertThat(originalId).isNotEqualTo(changeSessionId);
|
||||
assertThat(createSession.getId()).isEqualTo(createSession.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createSessionDefaultMaxInactiveInterval() throws Exception {
|
||||
Session session = this.redisRepository.createSession();
|
||||
|
||||
@@ -60,4 +60,93 @@ public abstract class AbstractHazelcastRepositoryITests {
|
||||
assertThat(hazelcastMap.size()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenOnlyChangeId() throws Exception {
|
||||
String attrName = "changeSessionId";
|
||||
String attrValue = "changeSessionId-value";
|
||||
HazelcastSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(attrName, attrValue);
|
||||
|
||||
this.repository.save(toSave);
|
||||
|
||||
HazelcastSession findById = this.repository.findById(toSave.getId());
|
||||
|
||||
assertThat(findById.<String>getAttribute(attrName)).isEqualTo(attrValue);
|
||||
|
||||
String originalFindById = findById.getId();
|
||||
String changeSessionId = findById.changeSessionId();
|
||||
|
||||
this.repository.save(findById);
|
||||
|
||||
assertThat(this.repository.findById(originalFindById)).isNull();
|
||||
|
||||
HazelcastSession findByChangeSessionId = this.repository.findById(changeSessionId);
|
||||
|
||||
assertThat(findByChangeSessionId.<String>getAttribute(attrName)).isEqualTo(attrValue);
|
||||
|
||||
this.repository.deleteById(changeSessionId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenChangeTwice() throws Exception {
|
||||
HazelcastSession toSave = this.repository.createSession();
|
||||
|
||||
this.repository.save(toSave);
|
||||
|
||||
String originalId = toSave.getId();
|
||||
String changeId1 = toSave.changeSessionId();
|
||||
String changeId2 = toSave.changeSessionId();
|
||||
|
||||
this.repository.save(toSave);
|
||||
|
||||
assertThat(this.repository.findById(originalId)).isNull();
|
||||
assertThat(this.repository.findById(changeId1)).isNull();
|
||||
assertThat(this.repository.findById(changeId2)).isNotNull();
|
||||
|
||||
this.repository.deleteById(changeId2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenSetAttributeOnChangedSession() throws Exception {
|
||||
String attrName = "changeSessionId";
|
||||
String attrValue = "changeSessionId-value";
|
||||
|
||||
HazelcastSession toSave = this.repository.createSession();
|
||||
|
||||
this.repository.save(toSave);
|
||||
|
||||
HazelcastSession findById = this.repository.findById(toSave.getId());
|
||||
|
||||
findById.setAttribute(attrName, attrValue);
|
||||
|
||||
String originalFindById = findById.getId();
|
||||
String changeSessionId = findById.changeSessionId();
|
||||
|
||||
this.repository.save(findById);
|
||||
|
||||
assertThat(this.repository.findById(originalFindById)).isNull();
|
||||
|
||||
HazelcastSession findByChangeSessionId = this.repository.findById(changeSessionId);
|
||||
|
||||
assertThat(findByChangeSessionId.<String>getAttribute(attrName)).isEqualTo(attrValue);
|
||||
|
||||
this.repository.deleteById(changeSessionId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenHasNotSaved() throws Exception {
|
||||
String attrName = "changeSessionId";
|
||||
String attrValue = "changeSessionId-value";
|
||||
|
||||
HazelcastSession toSave = this.repository.createSession();
|
||||
String originalId = toSave.getId();
|
||||
toSave.changeSessionId();
|
||||
|
||||
this.repository.save(toSave);
|
||||
|
||||
assertThat(this.repository.findById(toSave.getId())).isNotNull();
|
||||
assertThat(this.repository.findById(originalId)).isNull();
|
||||
|
||||
this.repository.deleteById(toSave.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,6 +202,10 @@ public class HazelcastSessionRepository implements
|
||||
}
|
||||
|
||||
public void save(HazelcastSession session) {
|
||||
if (!session.getId().equals(session.originalId)) {
|
||||
this.sessions.remove(session.originalId);
|
||||
session.originalId = session.getId();
|
||||
}
|
||||
if (session.isChanged()) {
|
||||
this.sessions.put(session.getId(), session.getDelegate(),
|
||||
session.getMaxInactiveInterval().getSeconds(), TimeUnit.SECONDS);
|
||||
@@ -273,6 +277,7 @@ public class HazelcastSessionRepository implements
|
||||
|
||||
private final MapSession delegate;
|
||||
private boolean changed;
|
||||
private String originalId;
|
||||
|
||||
/**
|
||||
* Creates a new instance ensuring to mark all of the new attributes to be
|
||||
@@ -292,6 +297,7 @@ public class HazelcastSessionRepository implements
|
||||
HazelcastSession(MapSession cached) {
|
||||
Assert.notNull(cached, "MapSession cannot be null");
|
||||
this.delegate = cached;
|
||||
this.originalId = cached.getId();
|
||||
}
|
||||
|
||||
public void setLastAccessedTime(Instant lastAccessedTime) {
|
||||
@@ -312,6 +318,12 @@ public class HazelcastSessionRepository implements
|
||||
return this.delegate.getId();
|
||||
}
|
||||
|
||||
public String changeSessionId() {
|
||||
this.changed = true;
|
||||
String result = this.delegate.changeSessionId();
|
||||
return result;
|
||||
}
|
||||
|
||||
public Instant getLastAccessedTime() {
|
||||
return this.delegate.getLastAccessedTime();
|
||||
}
|
||||
|
||||
@@ -83,6 +83,16 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
|
||||
AuthorityUtils.createAuthorityList("ROLE_USER")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveWhenNoAttributesThenCanBeFound() throws Exception {
|
||||
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
|
||||
.createSession();
|
||||
|
||||
this.repository.save(toSave);
|
||||
|
||||
assertThat(this.repository.findById(toSave.getId())).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saves() throws InterruptedException {
|
||||
String username = "saves-" + System.currentTimeMillis();
|
||||
@@ -560,6 +570,88 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
|
||||
assertThat(this.repository.findById(session.getId())).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenOnlyChangeId() throws Exception {
|
||||
String attrName = "changeSessionId";
|
||||
String attrValue = "changeSessionId-value";
|
||||
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(attrName, attrValue);
|
||||
|
||||
this.repository.save(toSave);
|
||||
|
||||
JdbcOperationsSessionRepository.JdbcSession findById = this.repository.findById(toSave.getId());
|
||||
|
||||
assertThat(findById.<String>getAttribute(attrName)).isEqualTo(attrValue);
|
||||
|
||||
String originalFindById = findById.getId();
|
||||
String changeSessionId = findById.changeSessionId();
|
||||
|
||||
this.repository.save(findById);
|
||||
|
||||
assertThat(this.repository.findById(originalFindById)).isNull();
|
||||
|
||||
JdbcOperationsSessionRepository.JdbcSession findByChangeSessionId = this.repository.findById(changeSessionId);
|
||||
|
||||
assertThat(findByChangeSessionId.<String>getAttribute(attrName)).isEqualTo(attrValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenChangeTwice() throws Exception {
|
||||
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
|
||||
|
||||
this.repository.save(toSave);
|
||||
|
||||
String originalId = toSave.getId();
|
||||
String changeId1 = toSave.changeSessionId();
|
||||
String changeId2 = toSave.changeSessionId();
|
||||
|
||||
this.repository.save(toSave);
|
||||
|
||||
assertThat(this.repository.findById(originalId)).isNull();
|
||||
assertThat(this.repository.findById(changeId1)).isNull();
|
||||
assertThat(this.repository.findById(changeId2)).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenSetAttributeOnChangedSession() throws Exception {
|
||||
String attrName = "changeSessionId";
|
||||
String attrValue = "changeSessionId-value";
|
||||
|
||||
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
|
||||
|
||||
this.repository.save(toSave);
|
||||
|
||||
JdbcOperationsSessionRepository.JdbcSession findById = this.repository.findById(toSave.getId());
|
||||
|
||||
findById.setAttribute(attrName, attrValue);
|
||||
|
||||
String originalFindById = findById.getId();
|
||||
String changeSessionId = findById.changeSessionId();
|
||||
|
||||
this.repository.save(findById);
|
||||
|
||||
assertThat(this.repository.findById(originalFindById)).isNull();
|
||||
|
||||
JdbcOperationsSessionRepository.JdbcSession findByChangeSessionId = this.repository.findById(changeSessionId);
|
||||
|
||||
assertThat(findByChangeSessionId.<String>getAttribute(attrName)).isEqualTo(attrValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenHasNotSaved() throws Exception {
|
||||
String attrName = "changeSessionId";
|
||||
String attrValue = "changeSessionId-value";
|
||||
|
||||
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
|
||||
String originalId = toSave.getId();
|
||||
toSave.changeSessionId();
|
||||
|
||||
this.repository.save(toSave);
|
||||
|
||||
assertThat(this.repository.findById(toSave.getId())).isNotNull();
|
||||
assertThat(this.repository.findById(originalId)).isNull();
|
||||
}
|
||||
|
||||
private String getSecurityName() {
|
||||
return this.context.getAuthentication().getName();
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
@@ -95,25 +96,26 @@ import org.springframework.util.StringUtils;
|
||||
*
|
||||
* <pre class="code">
|
||||
* CREATE TABLE SPRING_SESSION (
|
||||
* PRIMARY_ID CHAR(36) NOT NULL,
|
||||
* SESSION_ID CHAR(36),
|
||||
* CREATION_TIME BIGINT NOT NULL,
|
||||
* LAST_ACCESS_TIME BIGINT NOT NULL,
|
||||
* MAX_INACTIVE_INTERVAL INT NOT NULL,
|
||||
* PRINCIPAL_NAME VARCHAR(100),
|
||||
* CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (SESSION_ID)
|
||||
* CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (PRIMARY_ID)
|
||||
* );
|
||||
*
|
||||
* CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (LAST_ACCESS_TIME);
|
||||
*
|
||||
* CREATE TABLE SPRING_SESSION_ATTRIBUTES (
|
||||
* SESSION_ID CHAR(36),
|
||||
* SESSION_PRIMARY_ID CHAR(36) NOT NULL,
|
||||
* ATTRIBUTE_NAME VARCHAR(200),
|
||||
* ATTRIBUTE_BYTES BYTEA,
|
||||
* CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_ID, ATTRIBUTE_NAME),
|
||||
* CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_ID) REFERENCES SPRING_SESSION(SESSION_ID) ON DELETE CASCADE
|
||||
* CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_PRIMARY_ID, ATTRIBUTE_NAME),
|
||||
* CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_PRIMARY_ID) REFERENCES SPRING_SESSION(PRIMARY_ID) ON DELETE CASCADE
|
||||
* );
|
||||
*
|
||||
* CREATE INDEX SPRING_SESSION_ATTRIBUTES_IX1 ON SPRING_SESSION_ATTRIBUTES (SESSION_ID);
|
||||
* CREATE INDEX SPRING_SESSION_ATTRIBUTES_IX1 ON SPRING_SESSION_ATTRIBUTES (SESSION_PRIMARY_ID);
|
||||
* </pre>
|
||||
*
|
||||
* Due to the differences between the various database vendors, especially when it comes
|
||||
@@ -136,31 +138,31 @@ public class JdbcOperationsSessionRepository implements
|
||||
private static final String SPRING_SECURITY_CONTEXT = "SPRING_SECURITY_CONTEXT";
|
||||
|
||||
private static final String CREATE_SESSION_QUERY =
|
||||
"INSERT INTO %TABLE_NAME%(SESSION_ID, CREATION_TIME, LAST_ACCESS_TIME, MAX_INACTIVE_INTERVAL, PRINCIPAL_NAME) " +
|
||||
"VALUES (?, ?, ?, ?, ?)";
|
||||
"INSERT INTO %TABLE_NAME%(PRIMARY_ID, SESSION_ID, CREATION_TIME, LAST_ACCESS_TIME, MAX_INACTIVE_INTERVAL, PRINCIPAL_NAME) " +
|
||||
"VALUES (?, ?, ?, ?, ?, ?)";
|
||||
|
||||
private static final String CREATE_SESSION_ATTRIBUTE_QUERY =
|
||||
"INSERT INTO %TABLE_NAME%_ATTRIBUTES(SESSION_ID, ATTRIBUTE_NAME, ATTRIBUTE_BYTES) " +
|
||||
"INSERT INTO %TABLE_NAME%_ATTRIBUTES(SESSION_PRIMARY_ID, ATTRIBUTE_NAME, ATTRIBUTE_BYTES) " +
|
||||
"VALUES (?, ?, ?)";
|
||||
|
||||
private static final String GET_SESSION_QUERY =
|
||||
"SELECT S.SESSION_ID, S.CREATION_TIME, S.LAST_ACCESS_TIME, S.MAX_INACTIVE_INTERVAL, SA.ATTRIBUTE_NAME, SA.ATTRIBUTE_BYTES " +
|
||||
"SELECT S.PRIMARY_ID, S.SESSION_ID, S.CREATION_TIME, S.LAST_ACCESS_TIME, S.MAX_INACTIVE_INTERVAL, SA.ATTRIBUTE_NAME, SA.ATTRIBUTE_BYTES " +
|
||||
"FROM %TABLE_NAME% S " +
|
||||
"LEFT OUTER JOIN %TABLE_NAME%_ATTRIBUTES SA ON S.SESSION_ID = SA.SESSION_ID " +
|
||||
"LEFT OUTER JOIN %TABLE_NAME%_ATTRIBUTES SA ON S.PRIMARY_ID = SA.SESSION_PRIMARY_ID " +
|
||||
"WHERE S.SESSION_ID = ?";
|
||||
|
||||
private static final String UPDATE_SESSION_QUERY =
|
||||
"UPDATE %TABLE_NAME% SET LAST_ACCESS_TIME = ?, MAX_INACTIVE_INTERVAL = ?, PRINCIPAL_NAME = ? " +
|
||||
"WHERE SESSION_ID = ?";
|
||||
"UPDATE %TABLE_NAME% SET SESSION_ID = ?, LAST_ACCESS_TIME = ?, MAX_INACTIVE_INTERVAL = ?, PRINCIPAL_NAME = ? " +
|
||||
"WHERE PRIMARY_ID = ?";
|
||||
|
||||
private static final String UPDATE_SESSION_ATTRIBUTE_QUERY =
|
||||
"UPDATE %TABLE_NAME%_ATTRIBUTES SET ATTRIBUTE_BYTES = ? " +
|
||||
"WHERE SESSION_ID = ? " +
|
||||
"WHERE SESSION_PRIMARY_ID = ? " +
|
||||
"AND ATTRIBUTE_NAME = ?";
|
||||
|
||||
private static final String DELETE_SESSION_ATTRIBUTE_QUERY =
|
||||
"DELETE FROM %TABLE_NAME%_ATTRIBUTES " +
|
||||
"WHERE SESSION_ID = ? " +
|
||||
"WHERE SESSION_PRIMARY_ID = ? " +
|
||||
"AND ATTRIBUTE_NAME = ?";
|
||||
|
||||
private static final String DELETE_SESSION_QUERY =
|
||||
@@ -168,9 +170,9 @@ public class JdbcOperationsSessionRepository implements
|
||||
"WHERE SESSION_ID = ?";
|
||||
|
||||
private static final String LIST_SESSIONS_BY_PRINCIPAL_NAME_QUERY =
|
||||
"SELECT S.SESSION_ID, S.CREATION_TIME, S.LAST_ACCESS_TIME, S.MAX_INACTIVE_INTERVAL, SA.ATTRIBUTE_NAME, SA.ATTRIBUTE_BYTES " +
|
||||
"SELECT S.PRIMARY_ID, S.SESSION_ID, S.CREATION_TIME, S.LAST_ACCESS_TIME, S.MAX_INACTIVE_INTERVAL, SA.ATTRIBUTE_NAME, SA.ATTRIBUTE_BYTES " +
|
||||
"FROM %TABLE_NAME% S " +
|
||||
"LEFT OUTER JOIN %TABLE_NAME%_ATTRIBUTES SA ON S.SESSION_ID = SA.SESSION_ID " +
|
||||
"LEFT OUTER JOIN %TABLE_NAME%_ATTRIBUTES SA ON S.PRIMARY_ID = SA.SESSION_PRIMARY_ID " +
|
||||
"WHERE S.PRINCIPAL_NAME = ?";
|
||||
|
||||
private static final String DELETE_SESSIONS_BY_LAST_ACCESS_TIME_QUERY =
|
||||
@@ -186,7 +188,7 @@ public class JdbcOperationsSessionRepository implements
|
||||
|
||||
private final TransactionOperations transactionOperations;
|
||||
|
||||
private final ResultSetExtractor<List<Session>> extractor = new SessionResultSetExtractor();
|
||||
private final ResultSetExtractor<List<JdbcSession>> extractor = new SessionResultSetExtractor();
|
||||
|
||||
/**
|
||||
* The name of database table used by Spring Session to store sessions.
|
||||
@@ -378,11 +380,12 @@ public class JdbcOperationsSessionRepository implements
|
||||
JdbcOperationsSessionRepository.this.jdbcOperations.update(
|
||||
JdbcOperationsSessionRepository.this.createSessionQuery,
|
||||
ps -> {
|
||||
ps.setString(1, session.getId());
|
||||
ps.setLong(2, session.getCreationTime().toEpochMilli());
|
||||
ps.setLong(3, session.getLastAccessedTime().toEpochMilli());
|
||||
ps.setInt(4, (int) session.getMaxInactiveInterval().getSeconds());
|
||||
ps.setString(5, session.getPrincipalName());
|
||||
ps.setString(1, session.primaryKey);
|
||||
ps.setString(2, session.getId());
|
||||
ps.setLong(3, session.getCreationTime().toEpochMilli());
|
||||
ps.setLong(4, session.getLastAccessedTime().toEpochMilli());
|
||||
ps.setInt(5, (int) session.getMaxInactiveInterval().getSeconds());
|
||||
ps.setString(6, session.getPrincipalName());
|
||||
});
|
||||
if (!session.getAttributeNames().isEmpty()) {
|
||||
final List<String> attributeNames = new ArrayList<>(session.getAttributeNames());
|
||||
@@ -392,7 +395,7 @@ public class JdbcOperationsSessionRepository implements
|
||||
|
||||
public void setValues(PreparedStatement ps, int i) throws SQLException {
|
||||
String attributeName = attributeNames.get(i);
|
||||
ps.setString(1, session.getId());
|
||||
ps.setString(1, session.primaryKey);
|
||||
ps.setString(2, attributeName);
|
||||
serialize(ps, 3, session.getAttribute(attributeName));
|
||||
}
|
||||
@@ -415,10 +418,11 @@ public class JdbcOperationsSessionRepository implements
|
||||
JdbcOperationsSessionRepository.this.jdbcOperations.update(
|
||||
JdbcOperationsSessionRepository.this.updateSessionQuery,
|
||||
ps -> {
|
||||
ps.setLong(1, session.getLastAccessedTime().toEpochMilli());
|
||||
ps.setInt(2, (int) session.getMaxInactiveInterval().getSeconds());
|
||||
ps.setString(3, session.getPrincipalName());
|
||||
ps.setString(4, session.getId());
|
||||
ps.setString(1, session.getId());
|
||||
ps.setLong(2, session.getLastAccessedTime().toEpochMilli());
|
||||
ps.setInt(3, (int) session.getMaxInactiveInterval().getSeconds());
|
||||
ps.setString(4, session.getPrincipalName());
|
||||
ps.setString(5, session.primaryKey);
|
||||
});
|
||||
}
|
||||
Map<String, Object> delta = session.getDelta();
|
||||
@@ -428,7 +432,7 @@ public class JdbcOperationsSessionRepository implements
|
||||
JdbcOperationsSessionRepository.this.jdbcOperations.update(
|
||||
JdbcOperationsSessionRepository.this.deleteSessionAttributeQuery,
|
||||
ps -> {
|
||||
ps.setString(1, session.getId());
|
||||
ps.setString(1, session.primaryKey);
|
||||
ps.setString(2, entry.getKey());
|
||||
});
|
||||
}
|
||||
@@ -437,14 +441,14 @@ public class JdbcOperationsSessionRepository implements
|
||||
JdbcOperationsSessionRepository.this.updateSessionAttributeQuery,
|
||||
ps -> {
|
||||
serialize(ps, 1, entry.getValue());
|
||||
ps.setString(2, session.getId());
|
||||
ps.setString(2, session.primaryKey);
|
||||
ps.setString(3, entry.getKey());
|
||||
});
|
||||
if (updatedCount == 0) {
|
||||
JdbcOperationsSessionRepository.this.jdbcOperations.update(
|
||||
JdbcOperationsSessionRepository.this.createSessionAttributeQuery,
|
||||
ps -> {
|
||||
ps.setString(1, session.getId());
|
||||
ps.setString(1, session.primaryKey);
|
||||
ps.setString(2, entry.getKey());
|
||||
serialize(ps, 3, entry.getValue());
|
||||
});
|
||||
@@ -460,8 +464,8 @@ public class JdbcOperationsSessionRepository implements
|
||||
}
|
||||
|
||||
public JdbcSession findById(final String id) {
|
||||
final Session session = this.transactionOperations.execute(status -> {
|
||||
List<Session> sessions = JdbcOperationsSessionRepository.this.jdbcOperations.query(
|
||||
final JdbcSession session = this.transactionOperations.execute(status -> {
|
||||
List<JdbcSession> sessions = JdbcOperationsSessionRepository.this.jdbcOperations.query(
|
||||
JdbcOperationsSessionRepository.this.getSessionQuery,
|
||||
ps -> ps.setString(1, id),
|
||||
JdbcOperationsSessionRepository.this.extractor
|
||||
@@ -477,7 +481,7 @@ public class JdbcOperationsSessionRepository implements
|
||||
deleteById(id);
|
||||
}
|
||||
else {
|
||||
return new JdbcSession(session);
|
||||
return session;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -500,7 +504,7 @@ public class JdbcOperationsSessionRepository implements
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
List<Session> sessions = this.transactionOperations.execute(status ->
|
||||
List<JdbcSession> sessions = this.transactionOperations.execute(status ->
|
||||
JdbcOperationsSessionRepository.this.jdbcOperations.query(
|
||||
JdbcOperationsSessionRepository.this.listSessionsByPrincipalNameQuery,
|
||||
ps -> ps.setString(1, indexValue),
|
||||
@@ -509,8 +513,8 @@ public class JdbcOperationsSessionRepository implements
|
||||
Map<String, JdbcSession> sessionMap = new HashMap<>(
|
||||
sessions.size());
|
||||
|
||||
for (Session session : sessions) {
|
||||
sessionMap.put(session.getId(), new JdbcSession(session));
|
||||
for (JdbcSession session : sessions) {
|
||||
sessionMap.put(session.getId(), session);
|
||||
}
|
||||
|
||||
return sessionMap;
|
||||
@@ -596,6 +600,8 @@ public class JdbcOperationsSessionRepository implements
|
||||
|
||||
private final Session delegate;
|
||||
|
||||
private final String primaryKey;
|
||||
|
||||
private boolean isNew;
|
||||
|
||||
private boolean changed;
|
||||
@@ -605,10 +611,13 @@ public class JdbcOperationsSessionRepository implements
|
||||
JdbcSession() {
|
||||
this.delegate = new MapSession();
|
||||
this.isNew = true;
|
||||
this.primaryKey = UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
JdbcSession(Session delegate) {
|
||||
JdbcSession(String primaryKey, Session delegate) {
|
||||
Assert.notNull(primaryKey, "primaryKey cannot be null");
|
||||
Assert.notNull(delegate, "Session cannot be null");
|
||||
this.primaryKey = primaryKey;
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@@ -638,6 +647,11 @@ public class JdbcOperationsSessionRepository implements
|
||||
return this.delegate.getId();
|
||||
}
|
||||
|
||||
public String changeSessionId() {
|
||||
this.changed = true;
|
||||
return this.delegate.changeSessionId();
|
||||
}
|
||||
|
||||
public <T> T getAttribute(String attributeName) {
|
||||
return this.delegate.getAttribute(attributeName);
|
||||
}
|
||||
@@ -713,21 +727,23 @@ public class JdbcOperationsSessionRepository implements
|
||||
|
||||
}
|
||||
|
||||
private class SessionResultSetExtractor implements ResultSetExtractor<List<Session>> {
|
||||
private class SessionResultSetExtractor implements ResultSetExtractor<List<JdbcSession>> {
|
||||
|
||||
public List<Session> extractData(ResultSet rs) throws SQLException, DataAccessException {
|
||||
List<Session> sessions = new ArrayList<>();
|
||||
public List<JdbcSession> extractData(ResultSet rs) throws SQLException, DataAccessException {
|
||||
List<JdbcSession> sessions = new ArrayList<>();
|
||||
while (rs.next()) {
|
||||
String id = rs.getString("SESSION_ID");
|
||||
MapSession session;
|
||||
JdbcSession session;
|
||||
if (sessions.size() > 0 && getLast(sessions).getId().equals(id)) {
|
||||
session = (MapSession) getLast(sessions);
|
||||
session = getLast(sessions);
|
||||
}
|
||||
else {
|
||||
session = new MapSession(id);
|
||||
session.setCreationTime(Instant.ofEpochMilli(rs.getLong("CREATION_TIME")));
|
||||
session.setLastAccessedTime(Instant.ofEpochMilli(rs.getLong("LAST_ACCESS_TIME")));
|
||||
session.setMaxInactiveInterval(Duration.ofSeconds(rs.getInt("MAX_INACTIVE_INTERVAL")));
|
||||
MapSession delegate = new MapSession(id);
|
||||
String primaryKey = rs.getString("PRIMARY_ID");
|
||||
delegate.setCreationTime(Instant.ofEpochMilli(rs.getLong("CREATION_TIME")));
|
||||
delegate.setLastAccessedTime(Instant.ofEpochMilli(rs.getLong("LAST_ACCESS_TIME")));
|
||||
delegate.setMaxInactiveInterval(Duration.ofSeconds(rs.getInt("MAX_INACTIVE_INTERVAL")));
|
||||
session = new JdbcSession(primaryKey, delegate);
|
||||
}
|
||||
String attributeName = rs.getString("ATTRIBUTE_NAME");
|
||||
if (attributeName != null) {
|
||||
@@ -738,7 +754,7 @@ public class JdbcOperationsSessionRepository implements
|
||||
return sessions;
|
||||
}
|
||||
|
||||
private Session getLast(List<Session> sessions) {
|
||||
private JdbcSession getLast(List<JdbcSession> sessions) {
|
||||
return sessions.get(sessions.size() - 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
CREATE TABLE SPRING_SESSION (
|
||||
PRIMARY_ID CHAR(36) NOT NULL,
|
||||
SESSION_ID CHAR(36) NOT NULL,
|
||||
CREATION_TIME BIGINT NOT NULL,
|
||||
LAST_ACCESS_TIME BIGINT NOT NULL,
|
||||
MAX_INACTIVE_INTERVAL INT NOT NULL,
|
||||
PRINCIPAL_NAME VARCHAR(100),
|
||||
CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (SESSION_ID)
|
||||
CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (PRIMARY_ID)
|
||||
);
|
||||
|
||||
CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (LAST_ACCESS_TIME);
|
||||
CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (SESSION_ID);
|
||||
CREATE INDEX SPRING_SESSION_IX2 ON SPRING_SESSION (LAST_ACCESS_TIME);
|
||||
|
||||
CREATE TABLE SPRING_SESSION_ATTRIBUTES (
|
||||
SESSION_ID CHAR(36) NOT NULL,
|
||||
SESSION_PRIMARY_ID CHAR(36) NOT NULL,
|
||||
ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
|
||||
ATTRIBUTE_BYTES BLOB NOT NULL,
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_ID, ATTRIBUTE_NAME),
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_ID) REFERENCES SPRING_SESSION(SESSION_ID) ON DELETE CASCADE
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_PRIMARY_ID, ATTRIBUTE_NAME),
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_PRIMARY_ID) REFERENCES SPRING_SESSION(PRIMARY_ID) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX SPRING_SESSION_ATTRIBUTES_IX1 ON SPRING_SESSION_ATTRIBUTES (SESSION_ID);
|
||||
CREATE INDEX SPRING_SESSION_ATTRIBUTES_IX1 ON SPRING_SESSION_ATTRIBUTES (SESSION_PRIMARY_ID);
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
CREATE TABLE SPRING_SESSION (
|
||||
PRIMARY_ID CHAR(36) NOT NULL,
|
||||
SESSION_ID CHAR(36) NOT NULL,
|
||||
CREATION_TIME BIGINT NOT NULL,
|
||||
LAST_ACCESS_TIME BIGINT NOT NULL,
|
||||
MAX_INACTIVE_INTERVAL INT NOT NULL,
|
||||
PRINCIPAL_NAME VARCHAR(100),
|
||||
CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (SESSION_ID)
|
||||
CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (PRIMARY_ID)
|
||||
);
|
||||
|
||||
CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (LAST_ACCESS_TIME);
|
||||
CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (SESSION_ID);
|
||||
CREATE INDEX SPRING_SESSION_IX2 ON SPRING_SESSION (LAST_ACCESS_TIME);
|
||||
|
||||
CREATE TABLE SPRING_SESSION_ATTRIBUTES (
|
||||
SESSION_ID CHAR(36) NOT NULL,
|
||||
SESSION_PRIMARY_ID CHAR(36) NOT NULL,
|
||||
ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
|
||||
ATTRIBUTE_BYTES BLOB NOT NULL,
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_ID, ATTRIBUTE_NAME),
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_ID) REFERENCES SPRING_SESSION(SESSION_ID) ON DELETE CASCADE
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_PRIMARY_ID, ATTRIBUTE_NAME),
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_PRIMARY_ID) REFERENCES SPRING_SESSION(PRIMARY_ID) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX SPRING_SESSION_ATTRIBUTES_IX1 ON SPRING_SESSION_ATTRIBUTES (SESSION_ID);
|
||||
CREATE INDEX SPRING_SESSION_ATTRIBUTES_IX1 ON SPRING_SESSION_ATTRIBUTES (SESSION_PRIMARY_ID);
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
CREATE TABLE SPRING_SESSION (
|
||||
PRIMARY_ID CHAR(36) NOT NULL,
|
||||
SESSION_ID CHAR(36) NOT NULL,
|
||||
CREATION_TIME BIGINT NOT NULL,
|
||||
LAST_ACCESS_TIME BIGINT NOT NULL,
|
||||
MAX_INACTIVE_INTERVAL INT NOT NULL,
|
||||
PRINCIPAL_NAME VARCHAR(100),
|
||||
CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (SESSION_ID)
|
||||
CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (PRIMARY_ID)
|
||||
);
|
||||
|
||||
CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (LAST_ACCESS_TIME);
|
||||
CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (SESSION_ID);
|
||||
CREATE INDEX SPRING_SESSION_IX2 ON SPRING_SESSION (LAST_ACCESS_TIME);
|
||||
|
||||
CREATE TABLE SPRING_SESSION_ATTRIBUTES (
|
||||
SESSION_ID CHAR(36) NOT NULL,
|
||||
SESSION_PRIMARY_ID CHAR(36) NOT NULL,
|
||||
ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
|
||||
ATTRIBUTE_BYTES LONGVARBINARY NOT NULL,
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_ID, ATTRIBUTE_NAME),
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_ID) REFERENCES SPRING_SESSION(SESSION_ID) ON DELETE CASCADE
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_PRIMARY_ID, ATTRIBUTE_NAME),
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_PRIMARY_ID) REFERENCES SPRING_SESSION(PRIMARY_ID) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX SPRING_SESSION_ATTRIBUTES_IX1 ON SPRING_SESSION_ATTRIBUTES (SESSION_ID);
|
||||
CREATE INDEX SPRING_SESSION_ATTRIBUTES_IX1 ON SPRING_SESSION_ATTRIBUTES (SESSION_PRIMARY_ID);
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
CREATE TABLE SPRING_SESSION (
|
||||
PRIMARY_ID CHAR(36) NOT NULL,
|
||||
SESSION_ID CHAR(36) NOT NULL,
|
||||
CREATION_TIME BIGINT NOT NULL,
|
||||
LAST_ACCESS_TIME BIGINT NOT NULL,
|
||||
MAX_INACTIVE_INTERVAL INT NOT NULL,
|
||||
PRINCIPAL_NAME VARCHAR(100),
|
||||
CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (SESSION_ID)
|
||||
CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (PRIMARY_ID)
|
||||
);
|
||||
|
||||
CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (LAST_ACCESS_TIME);
|
||||
CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (SESSION_ID);
|
||||
CREATE INDEX SPRING_SESSION_IX2 ON SPRING_SESSION (LAST_ACCESS_TIME);
|
||||
|
||||
CREATE TABLE SPRING_SESSION_ATTRIBUTES (
|
||||
SESSION_ID CHAR(36) NOT NULL,
|
||||
SESSION_PRIMARY_ID CHAR(36) NOT NULL,
|
||||
ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
|
||||
ATTRIBUTE_BYTES LONGVARBINARY NOT NULL,
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_ID, ATTRIBUTE_NAME),
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_ID) REFERENCES SPRING_SESSION(SESSION_ID) ON DELETE CASCADE
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_PRIMARY_ID, ATTRIBUTE_NAME),
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_PRIMARY_ID) REFERENCES SPRING_SESSION(PRIMARY_ID) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX SPRING_SESSION_ATTRIBUTES_IX1 ON SPRING_SESSION_ATTRIBUTES (SESSION_ID);
|
||||
CREATE INDEX SPRING_SESSION_ATTRIBUTES_IX1 ON SPRING_SESSION_ATTRIBUTES (SESSION_PRIMARY_ID);
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
CREATE TABLE SPRING_SESSION (
|
||||
PRIMARY_ID CHAR(36) NOT NULL,
|
||||
SESSION_ID CHAR(36) NOT NULL,
|
||||
CREATION_TIME BIGINT NOT NULL,
|
||||
LAST_ACCESS_TIME BIGINT NOT NULL,
|
||||
MAX_INACTIVE_INTERVAL INT NOT NULL,
|
||||
PRINCIPAL_NAME VARCHAR(100),
|
||||
CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (SESSION_ID)
|
||||
CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (PRIMARY_ID)
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (LAST_ACCESS_TIME);
|
||||
CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (SESSION_ID);
|
||||
CREATE INDEX SPRING_SESSION_IX2 ON SPRING_SESSION (LAST_ACCESS_TIME);
|
||||
|
||||
CREATE TABLE SPRING_SESSION_ATTRIBUTES (
|
||||
SESSION_ID CHAR(36) NOT NULL,
|
||||
SESSION_PRIMARY_ID CHAR(36) NOT NULL,
|
||||
ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
|
||||
ATTRIBUTE_BYTES BLOB NOT NULL,
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_ID, ATTRIBUTE_NAME),
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_ID) REFERENCES SPRING_SESSION(SESSION_ID) ON DELETE CASCADE
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_PRIMARY_ID, ATTRIBUTE_NAME),
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_PRIMARY_ID) REFERENCES SPRING_SESSION(PRIMARY_ID) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
CREATE INDEX SPRING_SESSION_ATTRIBUTES_IX1 ON SPRING_SESSION_ATTRIBUTES (SESSION_ID);
|
||||
CREATE INDEX SPRING_SESSION_ATTRIBUTES_IX1 ON SPRING_SESSION_ATTRIBUTES (SESSION_PRIMARY_ID);
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
CREATE TABLE SPRING_SESSION (
|
||||
PRIMARY_ID CHAR(36) NOT NULL,
|
||||
SESSION_ID CHAR(36) NOT NULL,
|
||||
CREATION_TIME NUMBER(19,0) NOT NULL,
|
||||
LAST_ACCESS_TIME NUMBER(19,0) NOT NULL,
|
||||
MAX_INACTIVE_INTERVAL NUMBER(10,0) NOT NULL,
|
||||
PRINCIPAL_NAME VARCHAR2(100 CHAR),
|
||||
CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (SESSION_ID)
|
||||
CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (PRIMARY_ID)
|
||||
);
|
||||
|
||||
CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (LAST_ACCESS_TIME);
|
||||
CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (SESSION_ID);
|
||||
CREATE INDEX SPRING_SESSION_IX2 ON SPRING_SESSION (LAST_ACCESS_TIME);
|
||||
|
||||
CREATE TABLE SPRING_SESSION_ATTRIBUTES (
|
||||
SESSION_ID CHAR(36) NOT NULL,
|
||||
SESSION_PRIMARY_ID CHAR(36) NOT NULL,
|
||||
ATTRIBUTE_NAME VARCHAR2(200 CHAR) NOT NULL,
|
||||
ATTRIBUTE_BYTES BLOB NOT NULL,
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_ID, ATTRIBUTE_NAME),
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_ID) REFERENCES SPRING_SESSION(SESSION_ID) ON DELETE CASCADE
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_PRIMARY_ID, ATTRIBUTE_NAME),
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_PRIMARY_ID) REFERENCES SPRING_SESSION(PRIMARY_ID) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX SPRING_SESSION_ATTRIBUTES_IX1 ON SPRING_SESSION_ATTRIBUTES (SESSION_ID);
|
||||
CREATE INDEX SPRING_SESSION_ATTRIBUTES_IX1 ON SPRING_SESSION_ATTRIBUTES (SESSION_PRIMARY_ID);
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
CREATE TABLE SPRING_SESSION (
|
||||
PRIMARY_ID CHAR(36) NOT NULL,
|
||||
SESSION_ID CHAR(36) NOT NULL,
|
||||
CREATION_TIME BIGINT NOT NULL,
|
||||
LAST_ACCESS_TIME BIGINT NOT NULL,
|
||||
MAX_INACTIVE_INTERVAL INT NOT NULL,
|
||||
PRINCIPAL_NAME VARCHAR(100),
|
||||
CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (SESSION_ID)
|
||||
CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (PRIMARY_ID)
|
||||
);
|
||||
|
||||
CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (LAST_ACCESS_TIME);
|
||||
CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (SESSION_ID);
|
||||
CREATE INDEX SPRING_SESSION_IX2 ON SPRING_SESSION (LAST_ACCESS_TIME);
|
||||
|
||||
CREATE TABLE SPRING_SESSION_ATTRIBUTES (
|
||||
SESSION_ID CHAR(36) NOT NULL,
|
||||
SESSION_PRIMARY_ID CHAR(36) NOT NULL,
|
||||
ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
|
||||
ATTRIBUTE_BYTES BYTEA NOT NULL,
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_ID, ATTRIBUTE_NAME),
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_ID) REFERENCES SPRING_SESSION(SESSION_ID) ON DELETE CASCADE
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_PRIMARY_ID, ATTRIBUTE_NAME),
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_PRIMARY_ID) REFERENCES SPRING_SESSION(PRIMARY_ID) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX SPRING_SESSION_ATTRIBUTES_IX1 ON SPRING_SESSION_ATTRIBUTES (SESSION_ID);
|
||||
CREATE INDEX SPRING_SESSION_ATTRIBUTES_IX1 ON SPRING_SESSION_ATTRIBUTES (SESSION_PRIMARY_ID);
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
CREATE TABLE SPRING_SESSION (
|
||||
PRIMARY_ID CHARACTER(36) NOT NULL,
|
||||
SESSION_ID CHARACTER(36) NOT NULL,
|
||||
CREATION_TIME INTEGER NOT NULL,
|
||||
LAST_ACCESS_TIME INTEGER NOT NULL,
|
||||
MAX_INACTIVE_INTERVAL INTEGER NOT NULL,
|
||||
PRINCIPAL_NAME VARCHAR(100),
|
||||
CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (SESSION_ID)
|
||||
CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (PRIMARY_ID)
|
||||
);
|
||||
|
||||
CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (LAST_ACCESS_TIME);
|
||||
CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (SESSION_ID);
|
||||
CREATE INDEX SPRING_SESSION_IX2 ON SPRING_SESSION (LAST_ACCESS_TIME);
|
||||
|
||||
CREATE TABLE SPRING_SESSION_ATTRIBUTES (
|
||||
SESSION_ID CHAR(36) NOT NULL,
|
||||
SESSION_PRIMARY_ID CHAR(36) NOT NULL,
|
||||
ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
|
||||
ATTRIBUTE_BYTES BLOB NOT NULL,
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_ID, ATTRIBUTE_NAME),
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_ID) REFERENCES SPRING_SESSION(SESSION_ID) ON DELETE CASCADE
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_PRIMARY_ID, ATTRIBUTE_NAME),
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_PRIMARY_ID) REFERENCES SPRING_SESSION(PRIMARY_ID) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX SPRING_SESSION_ATTRIBUTES_IX1 ON SPRING_SESSION_ATTRIBUTES (SESSION_ID);
|
||||
CREATE INDEX SPRING_SESSION_ATTRIBUTES_IX1 ON SPRING_SESSION_ATTRIBUTES (SESSION_PRIMARY_ID);
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
CREATE TABLE SPRING_SESSION (
|
||||
PRIMARY_ID CHAR(36) NOT NULL,
|
||||
SESSION_ID CHAR(36) NOT NULL,
|
||||
CREATION_TIME BIGINT NOT NULL,
|
||||
LAST_ACCESS_TIME BIGINT NOT NULL,
|
||||
MAX_INACTIVE_INTERVAL INT NOT NULL,
|
||||
PRINCIPAL_NAME VARCHAR(100),
|
||||
CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (SESSION_ID)
|
||||
CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (PRIMARY_ID)
|
||||
);
|
||||
|
||||
CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (LAST_ACCESS_TIME);
|
||||
CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (SESSION_ID);
|
||||
CREATE INDEX SPRING_SESSION_IX2 ON SPRING_SESSION (LAST_ACCESS_TIME);
|
||||
|
||||
CREATE TABLE SPRING_SESSION_ATTRIBUTES (
|
||||
SESSION_ID CHAR(36) NOT NULL,
|
||||
SESSION_PRIMARY_ID CHAR(36) NOT NULL,
|
||||
ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
|
||||
ATTRIBUTE_BYTES IMAGE NOT NULL,
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_ID, ATTRIBUTE_NAME),
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_ID) REFERENCES SPRING_SESSION(SESSION_ID) ON DELETE CASCADE
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_PRIMARY_ID, ATTRIBUTE_NAME),
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_PRIMARY_ID) REFERENCES SPRING_SESSION(PRIMARY_ID) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX SPRING_SESSION_ATTRIBUTES_IX1 ON SPRING_SESSION_ATTRIBUTES (SESSION_ID);
|
||||
CREATE INDEX SPRING_SESSION_ATTRIBUTES_IX1 ON SPRING_SESSION_ATTRIBUTES (SESSION_PRIMARY_ID);
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
CREATE TABLE SPRING_SESSION (
|
||||
PRIMARY_ID CHAR(36) NOT NULL,
|
||||
SESSION_ID CHAR(36) NOT NULL,
|
||||
CREATION_TIME BIGINT NOT NULL,
|
||||
LAST_ACCESS_TIME BIGINT NOT NULL,
|
||||
MAX_INACTIVE_INTERVAL INT NOT NULL,
|
||||
PRINCIPAL_NAME VARCHAR(100),
|
||||
CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (SESSION_ID)
|
||||
CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (PRIMARY_ID)
|
||||
) LOCK DATAROWS;
|
||||
|
||||
CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (LAST_ACCESS_TIME);
|
||||
CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (SESSION_ID);
|
||||
CREATE INDEX SPRING_SESSION_IX2 ON SPRING_SESSION (LAST_ACCESS_TIME);
|
||||
|
||||
CREATE TABLE SPRING_SESSION_ATTRIBUTES (
|
||||
SESSION_ID CHAR(36) NOT NULL,
|
||||
SESSION_PRIMARY_ID CHAR(36) NOT NULL,
|
||||
ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
|
||||
ATTRIBUTE_BYTES IMAGE NOT NULL,
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_ID, ATTRIBUTE_NAME),
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_ID) REFERENCES SPRING_SESSION(SESSION_ID) ON DELETE CASCADE
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_PRIMARY_ID, ATTRIBUTE_NAME),
|
||||
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_PRIMARY_ID) REFERENCES SPRING_SESSION(PRIMARY_ID) ON DELETE CASCADE
|
||||
) LOCK DATAROWS;
|
||||
|
||||
CREATE INDEX SPRING_SESSION_ATTRIBUTES_IX1 ON SPRING_SESSION_ATTRIBUTES (SESSION_ID);
|
||||
CREATE INDEX SPRING_SESSION_ATTRIBUTES_IX1 ON SPRING_SESSION_ATTRIBUTES (SESSION_PRIMARY_ID);
|
||||
|
||||
@@ -42,6 +42,7 @@ import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
import org.springframework.session.FindByIndexNameSessionRepository;
|
||||
import org.springframework.session.MapSession;
|
||||
import org.springframework.session.Session;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionDefinition;
|
||||
@@ -357,7 +358,7 @@ public class JdbcOperationsSessionRepositoryTests {
|
||||
|
||||
@Test
|
||||
public void saveUpdatedAttributes() {
|
||||
JdbcOperationsSessionRepository.JdbcSession session = this.repository.new JdbcSession(
|
||||
JdbcOperationsSessionRepository.JdbcSession session = this.repository.new JdbcSession("primaryKey",
|
||||
new MapSession());
|
||||
session.setAttribute("testName", "testValue");
|
||||
|
||||
@@ -372,7 +373,7 @@ public class JdbcOperationsSessionRepositoryTests {
|
||||
|
||||
@Test
|
||||
public void saveUpdatedLastAccessedTime() {
|
||||
JdbcOperationsSessionRepository.JdbcSession session = this.repository.new JdbcSession(
|
||||
JdbcOperationsSessionRepository.JdbcSession session = this.repository.new JdbcSession("primaryKey",
|
||||
new MapSession());
|
||||
session.setLastAccessedTime(Instant.now());
|
||||
|
||||
@@ -387,7 +388,7 @@ public class JdbcOperationsSessionRepositoryTests {
|
||||
|
||||
@Test
|
||||
public void saveUnchanged() {
|
||||
JdbcOperationsSessionRepository.JdbcSession session = this.repository.new JdbcSession(
|
||||
JdbcOperationsSessionRepository.JdbcSession session = this.repository.new JdbcSession("primaryKey",
|
||||
new MapSession());
|
||||
|
||||
this.repository.save(session);
|
||||
@@ -416,7 +417,7 @@ public class JdbcOperationsSessionRepositoryTests {
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void getSessionExpired() {
|
||||
MapSession expired = new MapSession();
|
||||
Session expired = this.repository.new JdbcSession();
|
||||
expired.setLastAccessedTime(Instant.now().minusSeconds(
|
||||
MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS + 1));
|
||||
given(this.jdbcOperations.query(isA(String.class),
|
||||
@@ -437,7 +438,7 @@ public class JdbcOperationsSessionRepositoryTests {
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void getSessionFound() {
|
||||
MapSession saved = new MapSession();
|
||||
Session saved = this.repository.new JdbcSession("primaryKey", new MapSession());
|
||||
saved.setAttribute("savedName", "savedValue");
|
||||
given(this.jdbcOperations.query(isA(String.class),
|
||||
isA(PreparedStatementSetter.class), isA(ResultSetExtractor.class)))
|
||||
@@ -500,11 +501,11 @@ public class JdbcOperationsSessionRepositoryTests {
|
||||
String principal = "username";
|
||||
Authentication authentication = new UsernamePasswordAuthenticationToken(principal,
|
||||
"notused", AuthorityUtils.createAuthorityList("ROLE_USER"));
|
||||
List<MapSession> saved = new ArrayList<>(2);
|
||||
MapSession saved1 = new MapSession();
|
||||
List<Session> saved = new ArrayList<>(2);
|
||||
Session saved1 = this.repository.new JdbcSession();
|
||||
saved1.setAttribute(SPRING_SECURITY_CONTEXT, authentication);
|
||||
saved.add(saved1);
|
||||
MapSession saved2 = new MapSession();
|
||||
Session saved2 = this.repository.new JdbcSession();
|
||||
saved2.setAttribute(SPRING_SECURITY_CONTEXT, authentication);
|
||||
saved.add(saved2);
|
||||
given(this.jdbcOperations.query(isA(String.class),
|
||||
|
||||
Reference in New Issue
Block a user