Introduce ReactiveMongoSessionRepository.
This commit is contained in:
@@ -15,183 +15,20 @@
|
||||
*/
|
||||
package org.springframework.session.data.mongo;
|
||||
|
||||
import static org.springframework.session.data.mongo.MongoSessionUtils.*;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import reactor.core.publisher.Mono;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ApplicationEventPublisherAware;
|
||||
import org.springframework.data.mongodb.core.MongoOperations;
|
||||
import org.springframework.data.mongodb.core.ReactiveMongoOperations;
|
||||
import org.springframework.data.mongodb.core.index.IndexOperations;
|
||||
import org.springframework.session.ReactiveSessionRepository;
|
||||
import org.springframework.session.events.SessionCreatedEvent;
|
||||
import org.springframework.session.events.SessionDeletedEvent;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* This {@link ReactiveSessionRepository} implementation is kept to support migration to
|
||||
* {@link ReactiveMongoSessionRepository} in a backwards compatible manner.
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
* @deprecated since 2.2.0 in favor of {@link ReactiveMongoSessionRepository}.
|
||||
*/
|
||||
public class ReactiveMongoOperationsSessionRepository
|
||||
implements ReactiveSessionRepository<MongoSession>, ApplicationEventPublisherAware, InitializingBean {
|
||||
|
||||
/**
|
||||
* 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(ReactiveMongoOperationsSessionRepository.class);
|
||||
|
||||
private final ReactiveMongoOperations mongoOperations;
|
||||
|
||||
private Integer maxInactiveIntervalInSeconds = DEFAULT_INACTIVE_INTERVAL;
|
||||
private String collectionName = DEFAULT_COLLECTION_NAME;
|
||||
private AbstractMongoSessionConverter mongoSessionConverter = new JdkMongoSessionConverter(
|
||||
Duration.ofSeconds(this.maxInactiveIntervalInSeconds));
|
||||
private MongoOperations blockingMongoOperations;
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
@Deprecated
|
||||
public class ReactiveMongoOperationsSessionRepository extends ReactiveMongoSessionRepository {
|
||||
|
||||
public ReactiveMongoOperationsSessionRepository(ReactiveMongoOperations mongoOperations) {
|
||||
this.mongoOperations = mongoOperations;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* </p>
|
||||
*
|
||||
* @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) //
|
||||
.doOnNext(mongoSession -> publishEvent(new SessionCreatedEvent(this, mongoSession))) //
|
||||
.switchIfEmpty(Mono.just(new MongoSession()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* </p>
|
||||
*
|
||||
* @param session the {@link MongoSession} to save
|
||||
*/
|
||||
@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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link MongoSession} by the {@link MongoSession#getId()} or {@link Mono#empty()} if no
|
||||
* {@link MongoSession} is found.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
@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())));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
@Override
|
||||
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)) //
|
||||
.doOnNext(mongoSession -> publishEvent(new SessionDeletedEvent(this, mongoSession))) //
|
||||
.then();
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not use {@link org.springframework.data.mongodb.core.index.ReactiveIndexOperations} to ensure indexes exist.
|
||||
* Instead, get a blocking {@link IndexOperations} and use that instead, if possible.
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
|
||||
if (this.blockingMongoOperations != null) {
|
||||
IndexOperations indexOperations = this.blockingMongoOperations.indexOps(this.collectionName);
|
||||
this.mongoSessionConverter.ensureIndexes(indexOperations);
|
||||
}
|
||||
}
|
||||
|
||||
private Mono<Document> findSession(String id) {
|
||||
return this.mongoOperations.findById(id, Document.class, this.collectionName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationEventPublisher(ApplicationEventPublisher eventPublisher) {
|
||||
this.eventPublisher = eventPublisher;
|
||||
}
|
||||
|
||||
private void publishEvent(ApplicationEvent event) {
|
||||
|
||||
try {
|
||||
this.eventPublisher.publishEvent(event);
|
||||
} catch (Throwable ex) {
|
||||
logger.error("Error publishing " + event + ".", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public Integer getMaxInactiveIntervalInSeconds() {
|
||||
return this.maxInactiveIntervalInSeconds;
|
||||
}
|
||||
|
||||
public void setMaxInactiveIntervalInSeconds(final Integer maxInactiveIntervalInSeconds) {
|
||||
this.maxInactiveIntervalInSeconds = maxInactiveIntervalInSeconds;
|
||||
}
|
||||
|
||||
public String getCollectionName() {
|
||||
return this.collectionName;
|
||||
}
|
||||
|
||||
public void setCollectionName(final String collectionName) {
|
||||
this.collectionName = collectionName;
|
||||
}
|
||||
|
||||
public void setMongoSessionConverter(final AbstractMongoSessionConverter mongoSessionConverter) {
|
||||
this.mongoSessionConverter = mongoSessionConverter;
|
||||
}
|
||||
|
||||
public void setBlockingMongoOperations(final MongoOperations blockingMongoOperations) {
|
||||
this.blockingMongoOperations = blockingMongoOperations;
|
||||
super(mongoOperations);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright 2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.session.data.mongo;
|
||||
|
||||
import static org.springframework.session.data.mongo.MongoSessionUtils.*;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import reactor.core.publisher.Mono;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ApplicationEventPublisherAware;
|
||||
import org.springframework.data.mongodb.core.MongoOperations;
|
||||
import org.springframework.data.mongodb.core.ReactiveMongoOperations;
|
||||
import org.springframework.data.mongodb.core.index.IndexOperations;
|
||||
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.
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public class ReactiveMongoSessionRepository
|
||||
implements ReactiveSessionRepository<MongoSession>, ApplicationEventPublisherAware, InitializingBean {
|
||||
|
||||
/**
|
||||
* 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(ReactiveMongoSessionRepository.class);
|
||||
|
||||
private final ReactiveMongoOperations mongoOperations;
|
||||
|
||||
private Integer maxInactiveIntervalInSeconds = DEFAULT_INACTIVE_INTERVAL;
|
||||
private String collectionName = DEFAULT_COLLECTION_NAME;
|
||||
private AbstractMongoSessionConverter mongoSessionConverter = new JdkMongoSessionConverter(
|
||||
Duration.ofSeconds(this.maxInactiveIntervalInSeconds));
|
||||
private MongoOperations blockingMongoOperations;
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
|
||||
public ReactiveMongoSessionRepository(ReactiveMongoOperations mongoOperations) {
|
||||
this.mongoOperations = mongoOperations;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* </p>
|
||||
*
|
||||
* @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) //
|
||||
.doOnNext(mongoSession -> publishEvent(new SessionCreatedEvent(this, mongoSession))) //
|
||||
.switchIfEmpty(Mono.just(new MongoSession()));
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
|
||||
@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())));
|
||||
}
|
||||
|
||||
@Override
|
||||
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)) //
|
||||
.doOnNext(mongoSession -> publishEvent(new SessionDeletedEvent(this, mongoSession))) //
|
||||
.then();
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not use {@link org.springframework.data.mongodb.core.index.ReactiveIndexOperations} to ensure indexes exist.
|
||||
* Instead, get a blocking {@link IndexOperations} and use that instead, if possible.
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
|
||||
if (this.blockingMongoOperations != null) {
|
||||
IndexOperations indexOperations = this.blockingMongoOperations.indexOps(this.collectionName);
|
||||
this.mongoSessionConverter.ensureIndexes(indexOperations);
|
||||
}
|
||||
}
|
||||
|
||||
private Mono<Document> findSession(String id) {
|
||||
return this.mongoOperations.findById(id, Document.class, this.collectionName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationEventPublisher(ApplicationEventPublisher eventPublisher) {
|
||||
this.eventPublisher = eventPublisher;
|
||||
}
|
||||
|
||||
private void publishEvent(ApplicationEvent event) {
|
||||
|
||||
try {
|
||||
this.eventPublisher.publishEvent(event);
|
||||
} catch (Throwable ex) {
|
||||
logger.error("Error publishing " + event + ".", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public Integer getMaxInactiveIntervalInSeconds() {
|
||||
return this.maxInactiveIntervalInSeconds;
|
||||
}
|
||||
|
||||
public void setMaxInactiveIntervalInSeconds(final Integer maxInactiveIntervalInSeconds) {
|
||||
this.maxInactiveIntervalInSeconds = maxInactiveIntervalInSeconds;
|
||||
}
|
||||
|
||||
public String getCollectionName() {
|
||||
return this.collectionName;
|
||||
}
|
||||
|
||||
public void setCollectionName(final String collectionName) {
|
||||
this.collectionName = collectionName;
|
||||
}
|
||||
|
||||
public void setMongoSessionConverter(final AbstractMongoSessionConverter mongoSessionConverter) {
|
||||
this.mongoSessionConverter = mongoSessionConverter;
|
||||
}
|
||||
|
||||
public void setBlockingMongoOperations(final MongoOperations blockingMongoOperations) {
|
||||
this.blockingMongoOperations = blockingMongoOperations;
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.session.data.mongo.ReactiveMongoOperationsSessionRepository;
|
||||
import org.springframework.session.data.mongo.ReactiveMongoSessionRepository;
|
||||
|
||||
/**
|
||||
* Add this annotation to a {@code @Configuration} class to configure a MongoDB-based {@code WebSessionManager} for a
|
||||
@@ -59,12 +59,12 @@ public @interface EnableMongoWebSession {
|
||||
*
|
||||
* @return default max inactive interval in seconds
|
||||
*/
|
||||
int maxInactiveIntervalInSeconds() default ReactiveMongoOperationsSessionRepository.DEFAULT_INACTIVE_INTERVAL;
|
||||
int maxInactiveIntervalInSeconds() default ReactiveMongoSessionRepository.DEFAULT_INACTIVE_INTERVAL;
|
||||
|
||||
/**
|
||||
* The collection name to use.
|
||||
*
|
||||
* @return name of the collection to store session
|
||||
*/
|
||||
String collectionName() default ReactiveMongoOperationsSessionRepository.DEFAULT_COLLECTION_NAME;
|
||||
String collectionName() default ReactiveMongoSessionRepository.DEFAULT_COLLECTION_NAME;
|
||||
}
|
||||
|
||||
@@ -32,12 +32,12 @@ 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.ReactiveMongoOperationsSessionRepository;
|
||||
import org.springframework.session.data.mongo.ReactiveMongoSessionRepository;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.StringValueResolver;
|
||||
|
||||
/**
|
||||
* Configure a {@link ReactiveMongoOperationsSessionRepository} using a provided {@link ReactiveMongoOperations}.
|
||||
* Configure a {@link ReactiveMongoSessionRepository} using a provided {@link ReactiveMongoOperations}.
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
* @author Vedran Pavić
|
||||
@@ -55,17 +55,16 @@ public class ReactiveMongoWebSessionConfiguration extends SpringWebSessionConfig
|
||||
private ClassLoader classLoader;
|
||||
|
||||
@Bean
|
||||
public ReactiveMongoOperationsSessionRepository reactiveMongoOperationsSessionRepository(
|
||||
ReactiveMongoOperations operations) {
|
||||
public ReactiveMongoSessionRepository reactiveMongoSessionRepository(ReactiveMongoOperations operations) {
|
||||
|
||||
ReactiveMongoOperationsSessionRepository repository = new ReactiveMongoOperationsSessionRepository(operations);
|
||||
ReactiveMongoSessionRepository repository = new ReactiveMongoSessionRepository(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));
|
||||
Duration.ofSeconds(ReactiveMongoSessionRepository.DEFAULT_INACTIVE_INTERVAL));
|
||||
repository.setMongoSessionConverter(mongoSessionConverter);
|
||||
}
|
||||
|
||||
@@ -98,7 +97,7 @@ public class ReactiveMongoWebSessionConfiguration extends SpringWebSessionConfig
|
||||
if (attributes != null) {
|
||||
this.maxInactiveIntervalInSeconds = attributes.getNumber("maxInactiveIntervalInSeconds");
|
||||
} else {
|
||||
this.maxInactiveIntervalInSeconds = ReactiveMongoOperationsSessionRepository.DEFAULT_INACTIVE_INTERVAL;
|
||||
this.maxInactiveIntervalInSeconds = ReactiveMongoSessionRepository.DEFAULT_INACTIVE_INTERVAL;
|
||||
}
|
||||
|
||||
String collectionNameValue = attributes != null ? attributes.getString("collectionName") : "";
|
||||
|
||||
@@ -17,12 +17,7 @@
|
||||
package org.springframework.session.data.mongo;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.mockito.BDDMockito.any;
|
||||
import static org.mockito.BDDMockito.eq;
|
||||
import static org.mockito.BDDMockito.*;
|
||||
import static org.mockito.BDDMockito.mock;
|
||||
import static org.mockito.BDDMockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -46,14 +41,14 @@ import com.mongodb.DBObject;
|
||||
import com.mongodb.client.result.DeleteResult;
|
||||
|
||||
/**
|
||||
* Tests for {@link ReactiveMongoOperationsSessionRepository}.
|
||||
* Tests for {@link ReactiveMongoSessionRepository}.
|
||||
*
|
||||
* @author Jakub Kubrynski
|
||||
* @author Vedran Pavic
|
||||
* @author Greg Turnquist
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class ReactiveMongoOperationsSessionRepositoryTest {
|
||||
public class ReactiveMongoSessionRepositoryTest {
|
||||
|
||||
@Mock private AbstractMongoSessionConverter converter;
|
||||
@Mock private ReactiveMongoOperations mongoOperations;
|
||||
@@ -61,12 +56,12 @@ public class ReactiveMongoOperationsSessionRepositoryTest {
|
||||
@Mock private MongoOperations blockingMongoOperations;
|
||||
@Mock private ApplicationEventPublisher eventPublisher;
|
||||
|
||||
private ReactiveMongoOperationsSessionRepository repository;
|
||||
private ReactiveMongoSessionRepository repository;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
|
||||
this.repository = new ReactiveMongoOperationsSessionRepository(this.mongoOperations);
|
||||
this.repository = new ReactiveMongoSessionRepository(this.mongoOperations);
|
||||
this.repository.setMongoSessionConverter(this.converter);
|
||||
this.repository.setApplicationEventPublisher(this.eventPublisher);
|
||||
}
|
||||
@@ -79,7 +74,7 @@ public class ReactiveMongoOperationsSessionRepositoryTest {
|
||||
.expectNextMatches(mongoSession -> {
|
||||
assertThat(mongoSession.getId()).isNotEmpty();
|
||||
assertThat(mongoSession.getMaxInactiveInterval().getSeconds())
|
||||
.isEqualTo(ReactiveMongoOperationsSessionRepository.DEFAULT_INACTIVE_INTERVAL);
|
||||
.isEqualTo(ReactiveMongoSessionRepository.DEFAULT_INACTIVE_INTERVAL);
|
||||
return true;
|
||||
}) //
|
||||
.verifyComplete();
|
||||
@@ -97,7 +92,7 @@ public class ReactiveMongoOperationsSessionRepositoryTest {
|
||||
.expectNextMatches(mongoSession -> {
|
||||
assertThat(mongoSession.getId()).isNotEmpty();
|
||||
assertThat(mongoSession.getMaxInactiveInterval().getSeconds())
|
||||
.isEqualTo(ReactiveMongoOperationsSessionRepository.DEFAULT_INACTIVE_INTERVAL);
|
||||
.isEqualTo(ReactiveMongoSessionRepository.DEFAULT_INACTIVE_INTERVAL);
|
||||
return true;
|
||||
}) //
|
||||
.verifyComplete();
|
||||
@@ -120,7 +115,7 @@ public class ReactiveMongoOperationsSessionRepositoryTest {
|
||||
.as(StepVerifier::create) //
|
||||
.verifyComplete();
|
||||
|
||||
verify(this.mongoOperations).save(dbSession, ReactiveMongoOperationsSessionRepository.DEFAULT_COLLECTION_NAME);
|
||||
verify(this.mongoOperations).save(dbSession, ReactiveMongoSessionRepository.DEFAULT_COLLECTION_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -131,7 +126,7 @@ public class ReactiveMongoOperationsSessionRepositoryTest {
|
||||
Document sessionDocument = new Document();
|
||||
|
||||
given(this.mongoOperations.findById(sessionId, Document.class,
|
||||
ReactiveMongoOperationsSessionRepository.DEFAULT_COLLECTION_NAME)).willReturn(Mono.just(sessionDocument));
|
||||
ReactiveMongoSessionRepository.DEFAULT_COLLECTION_NAME)).willReturn(Mono.just(sessionDocument));
|
||||
|
||||
MongoSession session = new MongoSession();
|
||||
|
||||
@@ -153,11 +148,10 @@ public class ReactiveMongoOperationsSessionRepositoryTest {
|
||||
Document sessionDocument = new Document();
|
||||
|
||||
given(this.mongoOperations.findById(sessionId, Document.class,
|
||||
ReactiveMongoOperationsSessionRepository.DEFAULT_COLLECTION_NAME)).willReturn(Mono.just(sessionDocument));
|
||||
ReactiveMongoSessionRepository.DEFAULT_COLLECTION_NAME)).willReturn(Mono.just(sessionDocument));
|
||||
|
||||
given(
|
||||
this.mongoOperations.remove(sessionDocument, ReactiveMongoOperationsSessionRepository.DEFAULT_COLLECTION_NAME))
|
||||
.willReturn(Mono.just(DeleteResult.acknowledged(1)));
|
||||
given(this.mongoOperations.remove(sessionDocument, ReactiveMongoSessionRepository.DEFAULT_COLLECTION_NAME))
|
||||
.willReturn(Mono.just(DeleteResult.acknowledged(1)));
|
||||
|
||||
MongoSession session = mock(MongoSession.class);
|
||||
|
||||
@@ -172,7 +166,7 @@ public class ReactiveMongoOperationsSessionRepositoryTest {
|
||||
|
||||
// then
|
||||
verify(this.mongoOperations).remove(any(Document.class),
|
||||
eq(ReactiveMongoOperationsSessionRepository.DEFAULT_COLLECTION_NAME));
|
||||
eq(ReactiveMongoSessionRepository.DEFAULT_COLLECTION_NAME));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -183,7 +177,7 @@ public class ReactiveMongoOperationsSessionRepositoryTest {
|
||||
Document sessionDocument = new Document();
|
||||
|
||||
given(this.mongoOperations.findById(sessionId, Document.class,
|
||||
ReactiveMongoOperationsSessionRepository.DEFAULT_COLLECTION_NAME)).willReturn(Mono.just(sessionDocument));
|
||||
ReactiveMongoSessionRepository.DEFAULT_COLLECTION_NAME)).willReturn(Mono.just(sessionDocument));
|
||||
|
||||
given(this.mongoOperations.remove(sessionDocument, "sessions")).willReturn(Mono.just(DeleteResult.acknowledged(1)));
|
||||
|
||||
@@ -198,7 +192,7 @@ public class ReactiveMongoOperationsSessionRepositoryTest {
|
||||
.verifyComplete();
|
||||
|
||||
verify(this.mongoOperations).remove(any(Document.class),
|
||||
eq(ReactiveMongoOperationsSessionRepository.DEFAULT_COLLECTION_NAME));
|
||||
eq(ReactiveMongoSessionRepository.DEFAULT_COLLECTION_NAME));
|
||||
|
||||
verify(this.eventPublisher).publishEvent(any(SessionDeletedEvent.class));
|
||||
}
|
||||
@@ -17,10 +17,6 @@ package org.springframework.session.data.mongo.config.annotation.web.reactive;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.mockito.BDDMockito.*;
|
||||
import static org.mockito.BDDMockito.times;
|
||||
import static org.mockito.BDDMockito.verify;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collections;
|
||||
@@ -38,7 +34,7 @@ import org.springframework.session.config.annotation.web.server.EnableSpringWebS
|
||||
import org.springframework.session.data.mongo.AbstractMongoSessionConverter;
|
||||
import org.springframework.session.data.mongo.JacksonMongoSessionConverter;
|
||||
import org.springframework.session.data.mongo.JdkMongoSessionConverter;
|
||||
import org.springframework.session.data.mongo.ReactiveMongoOperationsSessionRepository;
|
||||
import org.springframework.session.data.mongo.ReactiveMongoSessionRepository;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.web.server.adapter.WebHttpHandlerBuilder;
|
||||
import org.springframework.web.server.session.WebSessionManager;
|
||||
@@ -85,7 +81,7 @@ public class ReactiveMongoWebSessionConfigurationTest {
|
||||
this.context.register(BadConfig.class);
|
||||
|
||||
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(this.context::refresh)
|
||||
.withMessageContaining("Error creating bean with name 'reactiveMongoOperationsSessionRepository'")
|
||||
.withMessageContaining("Error creating bean with name 'reactiveMongoSessionRepository'")
|
||||
.withMessageContaining("No qualifying bean of type '" + ReactiveMongoOperations.class.getCanonicalName());
|
||||
}
|
||||
|
||||
@@ -96,8 +92,7 @@ public class ReactiveMongoWebSessionConfigurationTest {
|
||||
this.context.register(GoodConfig.class);
|
||||
this.context.refresh();
|
||||
|
||||
ReactiveMongoOperationsSessionRepository repository = this.context
|
||||
.getBean(ReactiveMongoOperationsSessionRepository.class);
|
||||
ReactiveMongoSessionRepository repository = this.context.getBean(ReactiveMongoSessionRepository.class);
|
||||
|
||||
AbstractMongoSessionConverter converter = findMongoSessionConverter(repository);
|
||||
|
||||
@@ -111,8 +106,7 @@ public class ReactiveMongoWebSessionConfigurationTest {
|
||||
this.context.register(OverrideSessionConverterConfig.class);
|
||||
this.context.refresh();
|
||||
|
||||
ReactiveMongoOperationsSessionRepository repository = this.context
|
||||
.getBean(ReactiveMongoOperationsSessionRepository.class);
|
||||
ReactiveMongoSessionRepository repository = this.context.getBean(ReactiveMongoSessionRepository.class);
|
||||
|
||||
AbstractMongoSessionConverter converter = findMongoSessionConverter(repository);
|
||||
|
||||
@@ -126,16 +120,14 @@ public class ReactiveMongoWebSessionConfigurationTest {
|
||||
this.context.register(OverrideMongoParametersConfig.class);
|
||||
this.context.refresh();
|
||||
|
||||
ReactiveMongoOperationsSessionRepository repository = this.context
|
||||
.getBean(ReactiveMongoOperationsSessionRepository.class);
|
||||
ReactiveMongoSessionRepository repository = this.context.getBean(ReactiveMongoSessionRepository.class);
|
||||
|
||||
Field inactiveField = ReflectionUtils.findField(ReactiveMongoOperationsSessionRepository.class,
|
||||
Field inactiveField = ReflectionUtils.findField(ReactiveMongoSessionRepository.class,
|
||||
"maxInactiveIntervalInSeconds");
|
||||
ReflectionUtils.makeAccessible(inactiveField);
|
||||
Integer inactiveSeconds = (Integer) inactiveField.get(repository);
|
||||
|
||||
Field collectionNameField = ReflectionUtils.findField(ReactiveMongoOperationsSessionRepository.class,
|
||||
"collectionName");
|
||||
Field collectionNameField = ReflectionUtils.findField(ReactiveMongoSessionRepository.class, "collectionName");
|
||||
ReflectionUtils.makeAccessible(collectionNameField);
|
||||
String collectionName = (String) collectionNameField.get(repository);
|
||||
|
||||
@@ -165,23 +157,22 @@ public class ReactiveMongoWebSessionConfigurationTest {
|
||||
this.context.register(CustomizedReactiveConfiguration.class);
|
||||
this.context.refresh();
|
||||
|
||||
ReactiveMongoOperationsSessionRepository repository = this.context
|
||||
.getBean(ReactiveMongoOperationsSessionRepository.class);
|
||||
ReactiveMongoSessionRepository repository = this.context.getBean(ReactiveMongoSessionRepository.class);
|
||||
|
||||
assertThat(repository.getCollectionName()).isEqualTo("custom-collection");
|
||||
assertThat(repository.getMaxInactiveIntervalInSeconds()).isEqualTo(123);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reflectively extract the {@link AbstractMongoSessionConverter} from the
|
||||
* {@link ReactiveMongoOperationsSessionRepository}. This is to avoid expanding the surface area of the API.
|
||||
* Reflectively extract the {@link AbstractMongoSessionConverter} from the {@link ReactiveMongoSessionRepository}.
|
||||
* This is to avoid expanding the surface area of the API.
|
||||
*
|
||||
* @param repository
|
||||
* @return
|
||||
*/
|
||||
private AbstractMongoSessionConverter findMongoSessionConverter(ReactiveMongoOperationsSessionRepository repository) {
|
||||
private AbstractMongoSessionConverter findMongoSessionConverter(ReactiveMongoSessionRepository repository) {
|
||||
|
||||
Field field = ReflectionUtils.findField(ReactiveMongoOperationsSessionRepository.class, "mongoSessionConverter");
|
||||
Field field = ReflectionUtils.findField(ReactiveMongoSessionRepository.class, "mongoSessionConverter");
|
||||
ReflectionUtils.makeAccessible(field);
|
||||
try {
|
||||
return (AbstractMongoSessionConverter) field.get(repository);
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.DependsOn;
|
||||
import org.springframework.data.mongodb.core.ReactiveMongoOperations;
|
||||
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
|
||||
import org.springframework.session.data.mongo.ReactiveMongoOperationsSessionRepository;
|
||||
import org.springframework.session.data.mongo.ReactiveMongoSessionRepository;
|
||||
import org.springframework.session.data.mongo.config.annotation.web.reactive.EnableMongoWebSession;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.util.SocketUtils;
|
||||
@@ -35,7 +35,7 @@ import com.mongodb.reactivestreams.client.MongoClients;
|
||||
* @author Greg Turnquist
|
||||
*/
|
||||
@ContextConfiguration
|
||||
public class ReactiveConfigurationTest extends AbstractClassLoaderTest<ReactiveMongoOperationsSessionRepository> {
|
||||
public class ReactiveConfigurationTest extends AbstractClassLoaderTest<ReactiveMongoSessionRepository> {
|
||||
|
||||
@Configuration
|
||||
@EnableMongoWebSession
|
||||
|
||||
Reference in New Issue
Block a user