Track change of MongoSession's id to properly delete.
When a session is made invalid and changed to a new one, the old one must be deleted from MongoDB at the next save(). Resolves #116.
This commit is contained in:
@@ -43,6 +43,7 @@ public class MongoSession implements Session {
|
||||
private static final char DOT_COVER_CHAR = '';
|
||||
|
||||
private String id;
|
||||
private String originalSessionId;
|
||||
private long createdMillis = System.currentTimeMillis();
|
||||
private long accessedMillis;
|
||||
private long intervalSeconds;
|
||||
@@ -60,6 +61,7 @@ public class MongoSession implements Session {
|
||||
public MongoSession(String id, long maxInactiveIntervalInSeconds) {
|
||||
|
||||
this.id = id;
|
||||
this.originalSessionId = id;
|
||||
this.intervalSeconds = maxInactiveIntervalInSeconds;
|
||||
setLastAccessedTime(Instant.ofEpochMilli(this.createdMillis));
|
||||
}
|
||||
@@ -72,6 +74,7 @@ public class MongoSession implements Session {
|
||||
return attributeName.replace(DOT_COVER_CHAR, '.');
|
||||
}
|
||||
|
||||
@Override
|
||||
public String changeSessionId() {
|
||||
|
||||
String changedId = UUID.randomUUID().toString();
|
||||
@@ -85,10 +88,12 @@ public class MongoSession implements Session {
|
||||
return (T) this.attrs.get(coverDot(attributeName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getAttributeNames() {
|
||||
return this.attrs.keySet().stream().map(MongoSession::uncoverDot).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttribute(String attributeName, Object attributeValue) {
|
||||
|
||||
if (attributeValue == null) {
|
||||
@@ -98,10 +103,12 @@ public class MongoSession implements Session {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAttribute(String attributeName) {
|
||||
this.attrs.remove(coverDot(attributeName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instant getCreationTime() {
|
||||
return Instant.ofEpochMilli(this.createdMillis);
|
||||
}
|
||||
@@ -110,24 +117,29 @@ public class MongoSession implements Session {
|
||||
this.createdMillis = created;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instant getLastAccessedTime() {
|
||||
return Instant.ofEpochMilli(this.accessedMillis);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLastAccessedTime(Instant lastAccessedTime) {
|
||||
|
||||
this.accessedMillis = lastAccessedTime.toEpochMilli();
|
||||
this.expireAt = Date.from(lastAccessedTime.plus(Duration.ofSeconds(this.intervalSeconds)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getMaxInactiveInterval() {
|
||||
return Duration.ofSeconds(this.intervalSeconds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxInactiveInterval(Duration interval) {
|
||||
this.intervalSeconds = interval.getSeconds();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExpired() {
|
||||
return this.intervalSeconds >= 0 && new Date().after(this.expireAt);
|
||||
}
|
||||
@@ -140,14 +152,15 @@ public class MongoSession implements Session {
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
MongoSession that = (MongoSession) o;
|
||||
return Objects.equals(id, that.id);
|
||||
return Objects.equals(this.id, that.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id);
|
||||
return Objects.hash(this.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
@@ -159,4 +172,12 @@ public class MongoSession implements Session {
|
||||
public void setExpireAt(final Date expireAt) {
|
||||
this.expireAt = expireAt;
|
||||
}
|
||||
|
||||
boolean hasChangedSessionId() {
|
||||
return !getId().equals(this.originalSessionId);
|
||||
}
|
||||
|
||||
String getOriginalSessionId() {
|
||||
return this.originalSessionId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.session.data.mongo;
|
||||
|
||||
import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
import static org.springframework.data.mongodb.core.query.Query.*;
|
||||
import static org.springframework.session.data.mongo.MongoSessionUtils.*;
|
||||
|
||||
import java.time.Duration;
|
||||
@@ -34,8 +36,6 @@ import org.springframework.session.ReactiveSessionRepository;
|
||||
import org.springframework.session.events.SessionCreatedEvent;
|
||||
import org.springframework.session.events.SessionDeletedEvent;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* A {@link ReactiveSessionRepository} implementation that uses Spring Data MongoDB.
|
||||
*
|
||||
@@ -92,12 +92,20 @@ public class ReactiveMongoSessionRepository
|
||||
@Override
|
||||
public Mono<Void> save(MongoSession session) {
|
||||
|
||||
DBObject dbObject = convertToDBObject(this.mongoSessionConverter, session);
|
||||
if (dbObject != null) {
|
||||
return this.mongoOperations.save(dbObject, this.collectionName).then();
|
||||
} else {
|
||||
return Mono.empty();
|
||||
}
|
||||
return Mono //
|
||||
.justOrEmpty(convertToDBObject(this.mongoSessionConverter, session)) //
|
||||
.flatMap(dbObject -> {
|
||||
if (session.hasChangedSessionId()) {
|
||||
|
||||
return this.mongoOperations
|
||||
.remove(query(where("_id").is(session.getOriginalSessionId())), this.collectionName) //
|
||||
.then(this.mongoOperations.save(dbObject, this.collectionName));
|
||||
} else {
|
||||
|
||||
return this.mongoOperations.save(dbObject, this.collectionName);
|
||||
}
|
||||
}) //
|
||||
.then();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user