Polishing.
Apply the formatting plugin to the entire code base. From there, polish up specific sections of code for readability.
This commit is contained in:
@@ -35,9 +35,8 @@ import org.springframework.session.Session;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* Base class for serializing and deserializing session objects. To create custom
|
||||
* serializer you have to implement this interface and simply register your class as a
|
||||
* bean.
|
||||
* Base class for serializing and deserializing session objects. To create custom serializer you have to implement this
|
||||
* interface and simply register your class as a bean.
|
||||
*
|
||||
* @author Jakub Kubrynski
|
||||
* @author Greg Turnquist
|
||||
@@ -45,14 +44,13 @@ import com.mongodb.DBObject;
|
||||
*/
|
||||
public abstract class AbstractMongoSessionConverter implements GenericConverter {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(AbstractMongoSessionConverter.class);
|
||||
|
||||
static final String EXPIRE_AT_FIELD_NAME = "expireAt";
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(AbstractMongoSessionConverter.class);
|
||||
private static final String SPRING_SECURITY_CONTEXT = "SPRING_SECURITY_CONTEXT";
|
||||
|
||||
/**
|
||||
* Returns query to be executed to return sessions based on a particular index.
|
||||
*
|
||||
* @param indexName name of the index
|
||||
* @param indexValue value to query against
|
||||
* @return built query or null if indexName is not supported
|
||||
@@ -60,12 +58,10 @@ public abstract class AbstractMongoSessionConverter implements GenericConverter
|
||||
protected abstract Query getQueryForIndex(String indexName, Object indexValue);
|
||||
|
||||
/**
|
||||
* Method ensures that there is a TTL index on {@literal expireAt} field. It's has
|
||||
* {@literal expireAfterSeconds} set to zero seconds, so the expiration time is
|
||||
* controlled by the application.
|
||||
*
|
||||
* It can be extended in custom converters when there is a need for creating
|
||||
* additional custom indexes.
|
||||
* Method ensures that there is a TTL index on {@literal expireAt} field. It's has {@literal expireAfterSeconds} set
|
||||
* to zero seconds, so the expiration time is controlled by the application. It can be extended in custom converters
|
||||
* when there is a need for creating additional custom indexes.
|
||||
*
|
||||
* @param sessionCollectionIndexes {@link IndexOperations} to use
|
||||
*/
|
||||
protected void ensureIndexes(IndexOperations sessionCollectionIndexes) {
|
||||
@@ -79,7 +75,7 @@ public abstract class AbstractMongoSessionConverter implements GenericConverter
|
||||
|
||||
LOG.info("Creating TTL index on field " + EXPIRE_AT_FIELD_NAME);
|
||||
sessionCollectionIndexes
|
||||
.ensureIndex(new Index(EXPIRE_AT_FIELD_NAME, Sort.Direction.ASC).named(EXPIRE_AT_FIELD_NAME).expire(0));
|
||||
.ensureIndex(new Index(EXPIRE_AT_FIELD_NAME, Sort.Direction.ASC).named(EXPIRE_AT_FIELD_NAME).expire(0));
|
||||
}
|
||||
|
||||
protected String extractPrincipal(Session expiringSession) {
|
||||
@@ -95,13 +91,12 @@ public abstract class AbstractMongoSessionConverter implements GenericConverter
|
||||
|
||||
public Set<ConvertiblePair> getConvertibleTypes() {
|
||||
|
||||
return Collections.singleton(
|
||||
new ConvertiblePair(DBObject.class, MongoSession.class));
|
||||
return Collections.singleton(new ConvertiblePair(DBObject.class, MongoSession.class));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
|
||||
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@ final class AuthenticationParser {
|
||||
|
||||
private static final SpelExpressionParser PARSER = new SpelExpressionParser();
|
||||
|
||||
private AuthenticationParser() {}
|
||||
|
||||
/**
|
||||
* Extracts principal name from authentication.
|
||||
*
|
||||
@@ -46,6 +48,4 @@ final class AuthenticationParser {
|
||||
|
||||
return expression.getValue(authentication, String.class);
|
||||
}
|
||||
|
||||
private AuthenticationParser() {}
|
||||
}
|
||||
|
||||
@@ -77,8 +77,7 @@ public class JacksonMongoSessionConverter extends AbstractMongoSessionConverter
|
||||
if (FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME.equals(indexName)) {
|
||||
return Query.query(Criteria.where(PRINCIPAL_FIELD_NAME).is(indexValue));
|
||||
} else {
|
||||
return Query.query(Criteria.where(ATTRS_FIELD_NAME +
|
||||
MongoSession.coverDot(indexName)).is(indexValue));
|
||||
return Query.query(Criteria.where(ATTRS_FIELD_NAME + MongoSession.coverDot(indexName)).is(indexValue));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,20 +101,6 @@ public class JacksonMongoSessionConverter extends AbstractMongoSessionConverter
|
||||
return objectMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to whitelist {@link MongoSession} for {@link SecurityJackson2Modules}.
|
||||
*/
|
||||
private static class MongoSessionMixin {
|
||||
// Nothing special
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to whitelist {@link HashMap} for {@link SecurityJackson2Modules}.
|
||||
*/
|
||||
private static class HashMapMixin {
|
||||
// Nothing special
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DBObject convert(MongoSession source) {
|
||||
|
||||
@@ -132,7 +117,7 @@ public class JacksonMongoSessionConverter extends AbstractMongoSessionConverter
|
||||
protected MongoSession convert(Document source) {
|
||||
|
||||
String json = source.toJson(JsonWriterSettings.builder().outputMode(JsonMode.RELAXED).build());
|
||||
|
||||
|
||||
try {
|
||||
return this.objectMapper.readValue(json, MongoSession.class);
|
||||
} catch (IOException e) {
|
||||
@@ -141,11 +126,25 @@ public class JacksonMongoSessionConverter extends AbstractMongoSessionConverter
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to whitelist {@link MongoSession} for {@link SecurityJackson2Modules}.
|
||||
*/
|
||||
private static class MongoSessionMixin {
|
||||
// Nothing special
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to whitelist {@link HashMap} for {@link SecurityJackson2Modules}.
|
||||
*/
|
||||
private static class HashMapMixin {
|
||||
// Nothing special
|
||||
}
|
||||
|
||||
private static class MongoIdNamingStrategy extends PropertyNamingStrategy.PropertyNamingStrategyBase {
|
||||
|
||||
@Override
|
||||
public String translate(String propertyName) {
|
||||
|
||||
|
||||
switch (propertyName) {
|
||||
case "id":
|
||||
return "_id";
|
||||
|
||||
@@ -24,7 +24,6 @@ import java.util.Map;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.bson.types.Binary;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.serializer.support.DeserializingConverter;
|
||||
import org.springframework.core.serializer.support.SerializingConverter;
|
||||
@@ -63,8 +62,9 @@ public class JdkMongoSessionConverter extends AbstractMongoSessionConverter {
|
||||
this(new SerializingConverter(), new DeserializingConverter(), maxInactiveInterval);
|
||||
}
|
||||
|
||||
public JdkMongoSessionConverter(Converter<Object, byte[]> serializer,
|
||||
Converter<byte[], Object> deserializer, Duration maxInactiveInterval) {
|
||||
public JdkMongoSessionConverter(Converter<Object, byte[]> serializer, Converter<byte[], Object> deserializer,
|
||||
Duration maxInactiveInterval) {
|
||||
|
||||
Assert.notNull(serializer, "serializer cannot be null");
|
||||
Assert.notNull(deserializer, "deserializer cannot be null");
|
||||
Assert.notNull(maxInactiveInterval, "maxInactiveInterval cannot be null");
|
||||
@@ -76,8 +76,7 @@ public class JdkMongoSessionConverter extends AbstractMongoSessionConverter {
|
||||
@Override
|
||||
public Query getQueryForIndex(String indexName, Object indexValue) {
|
||||
|
||||
if (FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME
|
||||
.equals(indexName)) {
|
||||
if (FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME.equals(indexName)) {
|
||||
return Query.query(Criteria.where(PRINCIPAL_FIELD_NAME).is(indexValue));
|
||||
} else {
|
||||
return null;
|
||||
@@ -88,7 +87,7 @@ public class JdkMongoSessionConverter extends AbstractMongoSessionConverter {
|
||||
protected DBObject convert(MongoSession session) {
|
||||
|
||||
BasicDBObject basicDBObject = new BasicDBObject();
|
||||
|
||||
|
||||
basicDBObject.put(ID, session.getId());
|
||||
basicDBObject.put(CREATION_TIME, session.getCreationTime());
|
||||
basicDBObject.put(LAST_ACCESSED_TIME, session.getLastAccessedTime());
|
||||
@@ -105,12 +104,10 @@ public class JdkMongoSessionConverter extends AbstractMongoSessionConverter {
|
||||
|
||||
Object maxInterval = sessionWrapper.getOrDefault(MAX_INTERVAL, this.maxInactiveInterval);
|
||||
|
||||
Duration maxIntervalDuration = (maxInterval instanceof Duration)
|
||||
? (Duration) maxInterval
|
||||
: Duration.parse(maxInterval.toString());
|
||||
Duration maxIntervalDuration = (maxInterval instanceof Duration) ? (Duration) maxInterval
|
||||
: Duration.parse(maxInterval.toString());
|
||||
|
||||
MongoSession session = new MongoSession(
|
||||
sessionWrapper.getString(ID), maxIntervalDuration.getSeconds());
|
||||
MongoSession session = new MongoSession(sessionWrapper.getString(ID), maxIntervalDuration.getSeconds());
|
||||
|
||||
Object creationTime = sessionWrapper.get(CREATION_TIME);
|
||||
if (creationTime instanceof Instant) {
|
||||
@@ -127,7 +124,7 @@ public class JdkMongoSessionConverter extends AbstractMongoSessionConverter {
|
||||
}
|
||||
|
||||
session.setExpireAt((Date) sessionWrapper.get(EXPIRE_AT_FIELD_NAME));
|
||||
|
||||
|
||||
deserializeAttributes(sessionWrapper, session);
|
||||
|
||||
return session;
|
||||
@@ -140,20 +137,20 @@ public class JdkMongoSessionConverter extends AbstractMongoSessionConverter {
|
||||
for (String attrName : session.getAttributeNames()) {
|
||||
attributes.put(attrName, session.getAttribute(attrName));
|
||||
}
|
||||
|
||||
|
||||
return this.serializer.convert(attributes);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void deserializeAttributes(Document sessionWrapper, Session session) {
|
||||
|
||||
|
||||
Object sessionAttributes = sessionWrapper.get(ATTRIBUTES);
|
||||
|
||||
byte[] attributesBytes = (sessionAttributes instanceof Binary
|
||||
? ((Binary) sessionAttributes).getData() : (byte[]) sessionAttributes);
|
||||
byte[] attributesBytes = (sessionAttributes instanceof Binary ? ((Binary) sessionAttributes).getData()
|
||||
: (byte[]) sessionAttributes);
|
||||
|
||||
Map<String, Object> attributes = (Map<String, Object>) this.deserializer.convert(attributesBytes);
|
||||
|
||||
|
||||
for (Map.Entry<String, Object> entry : attributes.entrySet()) {
|
||||
session.setAttribute(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
@@ -41,12 +41,9 @@ import org.springframework.session.events.SessionDeletedEvent;
|
||||
import org.springframework.session.events.SessionExpiredEvent;
|
||||
|
||||
/**
|
||||
* Session repository implementation which stores sessions in Mongo. Uses
|
||||
* {@link AbstractMongoSessionConverter} to transform session objects from/to native Mongo
|
||||
* representation ({@code DBObject}).
|
||||
*
|
||||
* Repository is also responsible for removing expired sessions from database. Cleanup is
|
||||
* done every minute.
|
||||
* Session repository implementation which stores sessions in Mongo. Uses {@link AbstractMongoSessionConverter} to
|
||||
* transform session objects from/to native Mongo representation ({@code DBObject}). Repository is also responsible for
|
||||
* removing expired sessions from database. Cleanup is done every minute.
|
||||
*
|
||||
* @author Jakub Kubrynski
|
||||
* @author Greg Turnquist
|
||||
@@ -55,24 +52,21 @@ import org.springframework.session.events.SessionExpiredEvent;
|
||||
public class MongoOperationsSessionRepository
|
||||
implements FindByIndexNameSessionRepository<MongoSession>, ApplicationEventPublisherAware, InitializingBean {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(MongoOperationsSessionRepository.class);
|
||||
|
||||
/**
|
||||
* The default time period in seconds in which a session will expire.
|
||||
*/
|
||||
public static final int DEFAULT_INACTIVE_INTERVAL = 1800;
|
||||
|
||||
/**
|
||||
* the default collection name for storing session.
|
||||
*/
|
||||
public static final String DEFAULT_COLLECTION_NAME = "sessions";
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(MongoOperationsSessionRepository.class);
|
||||
private final MongoOperations mongoOperations;
|
||||
|
||||
@Setter private Integer maxInactiveIntervalInSeconds = DEFAULT_INACTIVE_INTERVAL;
|
||||
@Setter private String collectionName = DEFAULT_COLLECTION_NAME;
|
||||
@Setter private AbstractMongoSessionConverter mongoSessionConverter = new JdkMongoSessionConverter(
|
||||
Duration.ofSeconds(this.maxInactiveIntervalInSeconds));
|
||||
Duration.ofSeconds(this.maxInactiveIntervalInSeconds));
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
|
||||
public MongoOperationsSessionRepository(MongoOperations mongoOperations) {
|
||||
@@ -113,19 +107,17 @@ public class MongoOperationsSessionRepository
|
||||
|
||||
publishEvent(new SessionExpiredEvent(this, session));
|
||||
deleteById(id);
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
/**
|
||||
* Currently this repository allows only querying against
|
||||
* {@code PRINCIPAL_NAME_INDEX_NAME}.
|
||||
* Currently this repository allows only querying against {@code PRINCIPAL_NAME_INDEX_NAME}.
|
||||
*
|
||||
* @param indexName the name if the index (i.e.
|
||||
* {@link FindByIndexNameSessionRepository#PRINCIPAL_NAME_INDEX_NAME})
|
||||
* @param indexName the name if the index (i.e. {@link FindByIndexNameSessionRepository#PRINCIPAL_NAME_INDEX_NAME})
|
||||
* @param indexValue the value of the index to search for.
|
||||
* @return sessions map
|
||||
*/
|
||||
@@ -133,21 +125,19 @@ public class MongoOperationsSessionRepository
|
||||
public Map<String, MongoSession> findByIndexNameAndIndexValue(String indexName, String indexValue) {
|
||||
|
||||
return Optional.ofNullable(this.mongoSessionConverter.getQueryForIndex(indexName, indexValue))
|
||||
.map(query -> this.mongoOperations.find(query, Document.class, this.collectionName))
|
||||
.orElse(Collections.emptyList())
|
||||
.stream()
|
||||
.map(dbSession -> convertToSession(this.mongoSessionConverter, dbSession))
|
||||
.collect(Collectors.toMap(MongoSession::getId, mapSession -> mapSession));
|
||||
}
|
||||
.map(query -> this.mongoOperations.find(query, Document.class, this.collectionName))
|
||||
.orElse(Collections.emptyList()).stream()
|
||||
.map(dbSession -> convertToSession(this.mongoSessionConverter, dbSession))
|
||||
.collect(Collectors.toMap(MongoSession::getId, mapSession -> mapSession));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteById(String id) {
|
||||
|
||||
Optional.ofNullable(findSession(id))
|
||||
.ifPresent(document -> {
|
||||
publishEvent(new SessionDeletedEvent(this, convertToSession(this.mongoSessionConverter, document)));
|
||||
this.mongoOperations.remove(document, this.collectionName);
|
||||
});
|
||||
|
||||
Optional.ofNullable(findSession(id)).ifPresent(document -> {
|
||||
publishEvent(new SessionDeletedEvent(this, convertToSession(this.mongoSessionConverter, document)));
|
||||
this.mongoOperations.remove(document, this.collectionName);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -167,10 +157,10 @@ public class MongoOperationsSessionRepository
|
||||
}
|
||||
|
||||
private void publishEvent(ApplicationEvent event) {
|
||||
|
||||
try {
|
||||
this.eventPublisher.publishEvent(event);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
} catch (Throwable ex) {
|
||||
logger.error("Error publishing " + event + ".", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ import org.springframework.session.Session;
|
||||
* @author Greg Turnquist
|
||||
* @since 1.2
|
||||
*/
|
||||
@EqualsAndHashCode(of = {"id"})
|
||||
@EqualsAndHashCode(of = { "id" })
|
||||
public class MongoSession implements Session {
|
||||
|
||||
/**
|
||||
@@ -67,6 +67,14 @@ public class MongoSession implements Session {
|
||||
setLastAccessedTime(Instant.ofEpochMilli(this.createdMillis));
|
||||
}
|
||||
|
||||
static String coverDot(String attributeName) {
|
||||
return attributeName.replace('.', DOT_COVER_CHAR);
|
||||
}
|
||||
|
||||
static String uncoverDot(String attributeName) {
|
||||
return attributeName.replace(DOT_COVER_CHAR, '.');
|
||||
}
|
||||
|
||||
public String changeSessionId() {
|
||||
|
||||
String changedId = UUID.randomUUID().toString();
|
||||
@@ -81,9 +89,7 @@ public class MongoSession implements Session {
|
||||
|
||||
public Set<String> getAttributeNames() {
|
||||
|
||||
return this.attrs.keySet().stream()
|
||||
.map(MongoSession::uncoverDot)
|
||||
.collect(Collectors.toSet());
|
||||
return this.attrs.keySet().stream().map(MongoSession::uncoverDot).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public void setAttribute(String attributeName, Object attributeValue) {
|
||||
@@ -107,33 +113,25 @@ public class MongoSession implements Session {
|
||||
this.createdMillis = created;
|
||||
}
|
||||
|
||||
public Instant getLastAccessedTime() {
|
||||
return Instant.ofEpochMilli(this.accessedMillis);
|
||||
}
|
||||
|
||||
public void setLastAccessedTime(Instant lastAccessedTime) {
|
||||
|
||||
this.accessedMillis = lastAccessedTime.toEpochMilli();
|
||||
this.expireAt = Date.from(lastAccessedTime.plus(Duration.ofSeconds(this.intervalSeconds)));
|
||||
}
|
||||
|
||||
public Instant getLastAccessedTime() {
|
||||
return Instant.ofEpochMilli(this.accessedMillis);
|
||||
public Duration getMaxInactiveInterval() {
|
||||
return Duration.ofSeconds(this.intervalSeconds);
|
||||
}
|
||||
|
||||
public void setMaxInactiveInterval(Duration interval) {
|
||||
this.intervalSeconds = interval.getSeconds();
|
||||
}
|
||||
|
||||
public Duration getMaxInactiveInterval() {
|
||||
return Duration.ofSeconds(this.intervalSeconds);
|
||||
}
|
||||
|
||||
public boolean isExpired() {
|
||||
return this.intervalSeconds >= 0 && new Date().after(this.expireAt);
|
||||
}
|
||||
|
||||
static String coverDot(String attributeName) {
|
||||
return attributeName.replace('.', DOT_COVER_CHAR);
|
||||
}
|
||||
|
||||
static String uncoverDot(String attributeName) {
|
||||
return attributeName.replace(DOT_COVER_CHAR, '.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
package org.springframework.session.data.mongo;
|
||||
|
||||
import org.bson.Document;
|
||||
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
@@ -28,16 +27,14 @@ public final class MongoSessionUtils {
|
||||
|
||||
static DBObject convertToDBObject(AbstractMongoSessionConverter mongoSessionConverter, MongoSession session) {
|
||||
|
||||
return (DBObject) mongoSessionConverter.convert(session,
|
||||
TypeDescriptor.valueOf(MongoSession.class),
|
||||
TypeDescriptor.valueOf(DBObject.class));
|
||||
return (DBObject) mongoSessionConverter.convert(session, TypeDescriptor.valueOf(MongoSession.class),
|
||||
TypeDescriptor.valueOf(DBObject.class));
|
||||
}
|
||||
|
||||
static MongoSession convertToSession(AbstractMongoSessionConverter mongoSessionConverter, Document session) {
|
||||
|
||||
return (MongoSession) mongoSessionConverter.convert(session,
|
||||
TypeDescriptor.valueOf(Document.class),
|
||||
TypeDescriptor.valueOf(MongoSession.class));
|
||||
return (MongoSession) mongoSessionConverter.convert(session, TypeDescriptor.valueOf(Document.class),
|
||||
TypeDescriptor.valueOf(MongoSession.class));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ import org.springframework.session.events.SessionDeletedEvent;
|
||||
* @author Greg Turnquist
|
||||
*/
|
||||
public class ReactiveMongoOperationsSessionRepository
|
||||
implements ReactiveSessionRepository<MongoSession>, ApplicationEventPublisherAware, InitializingBean {
|
||||
implements ReactiveSessionRepository<MongoSession>, ApplicationEventPublisherAware, InitializingBean {
|
||||
|
||||
/**
|
||||
* The default time period in seconds in which a session will expire.
|
||||
@@ -60,7 +60,7 @@ public class ReactiveMongoOperationsSessionRepository
|
||||
@Getter @Setter private Integer maxInactiveIntervalInSeconds = DEFAULT_INACTIVE_INTERVAL;
|
||||
@Getter @Setter private String collectionName = DEFAULT_COLLECTION_NAME;
|
||||
@Setter private AbstractMongoSessionConverter mongoSessionConverter = new JdkMongoSessionConverter(
|
||||
Duration.ofSeconds(this.maxInactiveIntervalInSeconds));
|
||||
Duration.ofSeconds(this.maxInactiveIntervalInSeconds));
|
||||
|
||||
@Setter private MongoOperations blockingMongoOperations;
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
@@ -70,36 +70,29 @@ public class ReactiveMongoOperationsSessionRepository
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link MongoSession} that is capable of being persisted by this
|
||||
* {@link ReactiveSessionRepository}.
|
||||
* Creates a new {@link MongoSession} that is capable of being persisted by this {@link ReactiveSessionRepository}.
|
||||
* <p>
|
||||
* This allows optimizations and customizations in how the {@link MongoSession} is
|
||||
* persisted. For example, the implementation returned might keep track of the changes
|
||||
* ensuring that only the delta needs to be persisted on a save.
|
||||
* This allows optimizations and customizations in how the {@link MongoSession} is persisted. For example, the
|
||||
* implementation returned might keep track of the changes ensuring that only the delta needs to be persisted on a
|
||||
* save.
|
||||
* </p>
|
||||
*
|
||||
* @return a new {@link MongoSession} that is capable of being persisted by this
|
||||
* {@link ReactiveSessionRepository}
|
||||
* @return a new {@link MongoSession} that is capable of being persisted by this {@link ReactiveSessionRepository}
|
||||
*/
|
||||
@Override
|
||||
public Mono<MongoSession> createSession() {
|
||||
|
||||
return Mono.justOrEmpty(this.maxInactiveIntervalInSeconds)
|
||||
.map(MongoSession::new)
|
||||
.map(mongoSession -> {
|
||||
publishEvent(new SessionCreatedEvent(this, mongoSession));
|
||||
return mongoSession;
|
||||
})
|
||||
.switchIfEmpty(Mono.just(new MongoSession()));
|
||||
return Mono.justOrEmpty(this.maxInactiveIntervalInSeconds) //
|
||||
.map(MongoSession::new) //
|
||||
.doOnNext(mongoSession -> publishEvent(new SessionCreatedEvent(this, mongoSession))) //
|
||||
.switchIfEmpty(Mono.just(new MongoSession()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures the {@link MongoSession} created by
|
||||
* {@link ReactiveSessionRepository#createSession()} is saved.
|
||||
* Ensures the {@link MongoSession} created by {@link ReactiveSessionRepository#createSession()} is saved.
|
||||
* <p>
|
||||
* Some implementations may choose to save as the {@link MongoSession} is updated by
|
||||
* returning a {@link MongoSession} that immediately persists any changes. In this case,
|
||||
* this method may not actually do anything.
|
||||
* Some implementations may choose to save as the {@link MongoSession} is updated by returning a {@link MongoSession}
|
||||
* that immediately persists any changes. In this case, this method may not actually do anything.
|
||||
* </p>
|
||||
*
|
||||
* @param session the {@link MongoSession} to save
|
||||
@@ -107,9 +100,8 @@ public class ReactiveMongoOperationsSessionRepository
|
||||
@Override
|
||||
public Mono<Void> save(MongoSession session) {
|
||||
|
||||
return this.mongoOperations
|
||||
.save(convertToDBObject(this.mongoSessionConverter, session), this.collectionName)
|
||||
.then();
|
||||
return this.mongoOperations.save(convertToDBObject(this.mongoSessionConverter, session), this.collectionName)
|
||||
.then();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -118,20 +110,20 @@ public class ReactiveMongoOperationsSessionRepository
|
||||
*
|
||||
* @param id the {@link MongoSession#getId()} to lookup
|
||||
* @return the {@link MongoSession} by the {@link MongoSession#getId()} or {@link Mono#empty()} if no
|
||||
* {@link MongoSession} is found.
|
||||
* {@link MongoSession} is found.
|
||||
*/
|
||||
@Override
|
||||
public Mono<MongoSession> findById(String id) {
|
||||
|
||||
return findSession(id)
|
||||
.map(document -> convertToSession(this.mongoSessionConverter, document))
|
||||
.filter(mongoSession -> !mongoSession.isExpired())
|
||||
.switchIfEmpty(Mono.defer(() -> this.deleteById(id).then(Mono.empty())));
|
||||
return findSession(id) //
|
||||
.map(document -> convertToSession(this.mongoSessionConverter, document)) //
|
||||
.filter(mongoSession -> !mongoSession.isExpired()) //
|
||||
.switchIfEmpty(Mono.defer(() -> this.deleteById(id).then(Mono.empty())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the {@link MongoSession} with the given {@link MongoSession#getId()} or does nothing
|
||||
* if the {@link MongoSession} is not found.
|
||||
* Deletes the {@link MongoSession} with the given {@link MongoSession#getId()} or does nothing if the
|
||||
* {@link MongoSession} is not found.
|
||||
*
|
||||
* @param id the {@link MongoSession#getId()} to delete
|
||||
*/
|
||||
@@ -139,10 +131,10 @@ public class ReactiveMongoOperationsSessionRepository
|
||||
public Mono<Void> deleteById(String id) {
|
||||
|
||||
return findSession(id)
|
||||
.flatMap(document -> this.mongoOperations.remove(document, this.collectionName).then(Mono.just(document)))
|
||||
.map(document -> convertToSession(this.mongoSessionConverter, document))
|
||||
.doOnSuccess(mongoSession -> publishEvent(new SessionDeletedEvent(this, mongoSession)))
|
||||
.then();
|
||||
.flatMap(document -> this.mongoOperations.remove(document, this.collectionName).then(Mono.just(document)))
|
||||
.map(document -> convertToSession(this.mongoSessionConverter, document))
|
||||
.doOnSuccess(mongoSession -> publishEvent(new SessionDeletedEvent(this, mongoSession))) //
|
||||
.then();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -153,6 +145,7 @@ public class ReactiveMongoOperationsSessionRepository
|
||||
public void afterPropertiesSet() {
|
||||
|
||||
if (this.blockingMongoOperations != null) {
|
||||
|
||||
IndexOperations indexOperations = this.blockingMongoOperations.indexOps(this.collectionName);
|
||||
this.mongoSessionConverter.ensureIndexes(indexOperations);
|
||||
}
|
||||
@@ -168,10 +161,10 @@ public class ReactiveMongoOperationsSessionRepository
|
||||
}
|
||||
|
||||
private void publishEvent(ApplicationEvent event) {
|
||||
|
||||
try {
|
||||
this.eventPublisher.publishEvent(event);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
} catch (Throwable ex) {
|
||||
logger.error("Error publishing " + event + ".", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,10 +26,11 @@ import org.springframework.context.annotation.Import;
|
||||
import org.springframework.session.data.mongo.MongoOperationsSessionRepository;
|
||||
|
||||
/**
|
||||
* Add this annotation to a {@code @Configuration} class to expose the
|
||||
* SessionRepositoryFilter as a bean named "springSessionRepositoryFilter" and backed by
|
||||
* Mongo. Use {@code collectionName} to change default name of the collection used to
|
||||
* store sessions. <pre>
|
||||
* Add this annotation to a {@code @Configuration} class to expose the SessionRepositoryFilter as a bean named
|
||||
* "springSessionRepositoryFilter" and backed by Mongo. Use {@code collectionName} to change default name of the
|
||||
* collection used to store sessions.
|
||||
*
|
||||
* <pre>
|
||||
* <code>
|
||||
* {@literal @EnableMongoHttpSession}
|
||||
* public class MongoHttpSessionConfig {
|
||||
@@ -40,7 +41,8 @@ import org.springframework.session.data.mongo.MongoOperationsSessionRepository;
|
||||
* }
|
||||
*
|
||||
* }
|
||||
* </code> </pre>
|
||||
* </code>
|
||||
* </pre>
|
||||
*
|
||||
* @author Jakub Kubrynski
|
||||
* @since 1.2
|
||||
|
||||
@@ -36,8 +36,8 @@ import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.StringValueResolver;
|
||||
|
||||
/**
|
||||
* Configuration class registering {@code MongoSessionRepository} bean. To import this
|
||||
* configuration use {@link EnableMongoHttpSession} annotation.
|
||||
* Configuration class registering {@code MongoSessionRepository} bean. To import this configuration use
|
||||
* {@link EnableMongoHttpSession} annotation.
|
||||
*
|
||||
* @author Jakub Kubrynski
|
||||
* @author Eddú Meléndez
|
||||
@@ -62,10 +62,9 @@ public class MongoHttpSessionConfiguration extends SpringHttpSessionConfiguratio
|
||||
if (this.mongoSessionConverter != null) {
|
||||
repository.setMongoSessionConverter(this.mongoSessionConverter);
|
||||
} else {
|
||||
JdkMongoSessionConverter mongoSessionConverter = new JdkMongoSessionConverter(
|
||||
new SerializingConverter(),
|
||||
new DeserializingConverter(this.classLoader),
|
||||
Duration.ofSeconds(MongoOperationsSessionRepository.DEFAULT_INACTIVE_INTERVAL));
|
||||
JdkMongoSessionConverter mongoSessionConverter = new JdkMongoSessionConverter(new SerializingConverter(),
|
||||
new DeserializingConverter(this.classLoader),
|
||||
Duration.ofSeconds(MongoOperationsSessionRepository.DEFAULT_INACTIVE_INTERVAL));
|
||||
repository.setMongoSessionConverter(mongoSessionConverter);
|
||||
}
|
||||
|
||||
@@ -86,8 +85,8 @@ public class MongoHttpSessionConfiguration extends SpringHttpSessionConfiguratio
|
||||
|
||||
public void setImportMetadata(AnnotationMetadata importMetadata) {
|
||||
|
||||
AnnotationAttributes attributes = AnnotationAttributes.fromMap(
|
||||
importMetadata.getAnnotationAttributes(EnableMongoHttpSession.class.getName()));
|
||||
AnnotationAttributes attributes = AnnotationAttributes
|
||||
.fromMap(importMetadata.getAnnotationAttributes(EnableMongoHttpSession.class.getName()));
|
||||
|
||||
this.maxInactiveIntervalInSeconds = attributes.getNumber("maxInactiveIntervalInSeconds");
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@ import org.springframework.data.mongodb.core.ReactiveMongoOperations;
|
||||
import org.springframework.session.config.annotation.web.server.SpringWebSessionConfiguration;
|
||||
import org.springframework.session.data.mongo.AbstractMongoSessionConverter;
|
||||
import org.springframework.session.data.mongo.JdkMongoSessionConverter;
|
||||
import org.springframework.session.data.mongo.MongoOperationsSessionRepository;
|
||||
import org.springframework.session.data.mongo.ReactiveMongoOperationsSessionRepository;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.StringValueResolver;
|
||||
@@ -52,22 +51,21 @@ public class ReactiveMongoWebSessionConfiguration extends SpringWebSessionConfig
|
||||
private String collectionName;
|
||||
private StringValueResolver embeddedValueResolver;
|
||||
|
||||
@Autowired(required = false)
|
||||
private MongoOperations mongoOperations;
|
||||
@Autowired(required = false) private MongoOperations mongoOperations;
|
||||
private ClassLoader classLoader;
|
||||
|
||||
@Bean
|
||||
public ReactiveMongoOperationsSessionRepository reactiveMongoOperationsSessionRepository(ReactiveMongoOperations operations) {
|
||||
|
||||
public ReactiveMongoOperationsSessionRepository reactiveMongoOperationsSessionRepository(
|
||||
ReactiveMongoOperations operations) {
|
||||
|
||||
ReactiveMongoOperationsSessionRepository repository = new ReactiveMongoOperationsSessionRepository(operations);
|
||||
|
||||
if (this.mongoSessionConverter != null) {
|
||||
repository.setMongoSessionConverter(this.mongoSessionConverter);
|
||||
} else {
|
||||
JdkMongoSessionConverter mongoSessionConverter = new JdkMongoSessionConverter(
|
||||
new SerializingConverter(),
|
||||
new DeserializingConverter(this.classLoader),
|
||||
Duration.ofSeconds(ReactiveMongoOperationsSessionRepository.DEFAULT_INACTIVE_INTERVAL));
|
||||
JdkMongoSessionConverter mongoSessionConverter = new JdkMongoSessionConverter(new SerializingConverter(),
|
||||
new DeserializingConverter(this.classLoader),
|
||||
Duration.ofSeconds(ReactiveMongoOperationsSessionRepository.DEFAULT_INACTIVE_INTERVAL));
|
||||
repository.setMongoSessionConverter(mongoSessionConverter);
|
||||
}
|
||||
|
||||
@@ -82,7 +80,7 @@ public class ReactiveMongoWebSessionConfiguration extends SpringWebSessionConfig
|
||||
if (this.mongoOperations != null) {
|
||||
repository.setBlockingMongoOperations(this.mongoOperations);
|
||||
}
|
||||
|
||||
|
||||
return repository;
|
||||
}
|
||||
|
||||
@@ -94,8 +92,8 @@ public class ReactiveMongoWebSessionConfiguration extends SpringWebSessionConfig
|
||||
@Override
|
||||
public void setImportMetadata(AnnotationMetadata importMetadata) {
|
||||
|
||||
AnnotationAttributes attributes = AnnotationAttributes.fromMap(
|
||||
importMetadata.getAnnotationAttributes(EnableMongoWebSession.class.getName()));
|
||||
AnnotationAttributes attributes = AnnotationAttributes
|
||||
.fromMap(importMetadata.getAnnotationAttributes(EnableMongoWebSession.class.getName()));
|
||||
|
||||
this.maxInactiveIntervalInSeconds = attributes.getNumber("maxInactiveIntervalInSeconds");
|
||||
|
||||
@@ -115,6 +113,7 @@ public class ReactiveMongoWebSessionConfiguration extends SpringWebSessionConfig
|
||||
public void setEmbeddedValueResolver(StringValueResolver embeddedValueResolver) {
|
||||
this.embeddedValueResolver = embeddedValueResolver;
|
||||
}
|
||||
|
||||
public Integer getMaxInactiveIntervalInSeconds() {
|
||||
return maxInactiveIntervalInSeconds;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user