DATAMONGO-2481 - Improve build time.
Introduce Junit Jupiter extensions. Flush collections instead of dropping them. Apply cursor timeout to change stream and capped collections in tests. Original pull request: #838.
This commit is contained in:
committed by
Mark Paluch
parent
96ffb0b7f4
commit
8029acb3fb
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.messaging;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
|
||||
import org.bson.BsonValue;
|
||||
@@ -167,21 +168,37 @@ public class ChangeStreamRequest<T>
|
||||
|
||||
private final @Nullable String databaseName;
|
||||
private final @Nullable String collectionName;
|
||||
private final @Nullable Duration maxAwaitTime;
|
||||
private final ChangeStreamOptions options;
|
||||
|
||||
/**
|
||||
* Create new {@link ChangeStreamRequestOptions}.
|
||||
*
|
||||
* @param databaseName can be {@literal null}.
|
||||
* @param collectionName can be {@literal null}.
|
||||
* @param options must not be {@literal null}.
|
||||
*/
|
||||
public ChangeStreamRequestOptions(@Nullable String databaseName, @Nullable String collectionName,
|
||||
ChangeStreamOptions options) {
|
||||
this(databaseName, collectionName, null, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new {@link ChangeStreamRequestOptions}.
|
||||
*
|
||||
* @param databaseName can be {@literal null}.
|
||||
* @param collectionName can be {@literal null}.
|
||||
* @param maxAwaitTime can be {@literal null}.
|
||||
* @param options must not be {@literal null}.
|
||||
*/
|
||||
public ChangeStreamRequestOptions(@Nullable String databaseName, @Nullable String collectionName,
|
||||
@Nullable Duration maxAwaitTime, ChangeStreamOptions options) {
|
||||
|
||||
Assert.notNull(options, "Options must not be null!");
|
||||
|
||||
this.collectionName = collectionName;
|
||||
this.databaseName = databaseName;
|
||||
this.maxAwaitTime = maxAwaitTime;
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
@@ -219,6 +236,15 @@ public class ChangeStreamRequest<T>
|
||||
public String getDatabaseName() {
|
||||
return databaseName;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.monitor.SubscriptionRequest.RequestOptions#maxAwaitTime()
|
||||
*/
|
||||
@Override
|
||||
public Duration maxAwaitTime() {
|
||||
return maxAwaitTime != null ? maxAwaitTime : RequestOptions.super.maxAwaitTime();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -232,6 +258,7 @@ public class ChangeStreamRequest<T>
|
||||
|
||||
private @Nullable String databaseName;
|
||||
private @Nullable String collectionName;
|
||||
private @Nullable Duration maxAwaitTime;
|
||||
private @Nullable MessageListener<ChangeStreamDocument<Document>, ? super T> listener;
|
||||
private ChangeStreamOptionsBuilder delegate = ChangeStreamOptions.builder();
|
||||
|
||||
@@ -417,6 +444,20 @@ public class ChangeStreamRequest<T>
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the cursors maximum wait time on the server (for a new Document to be emitted).
|
||||
*
|
||||
* @param timeout must not be {@literal null}.
|
||||
* @since 3.0
|
||||
*/
|
||||
public ChangeStreamRequestBuilder<T> maxAwaitTime(Duration timeout) {
|
||||
|
||||
Assert.notNull(timeout, "timeout not be null!");
|
||||
|
||||
this.maxAwaitTime = timeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the build {@link ChangeStreamRequest}.
|
||||
*/
|
||||
@@ -425,7 +466,7 @@ public class ChangeStreamRequest<T>
|
||||
Assert.notNull(listener, "MessageListener must not be null!");
|
||||
|
||||
return new ChangeStreamRequest<>(listener,
|
||||
new ChangeStreamRequestOptions(databaseName, collectionName, delegate.build()));
|
||||
new ChangeStreamRequestOptions(databaseName, collectionName, maxAwaitTime, delegate.build()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.bson.BsonDocument;
|
||||
import org.bson.BsonTimestamp;
|
||||
@@ -135,6 +136,10 @@ class ChangeStreamTask extends CursorReadingTask<ChangeStreamDocument<Document>,
|
||||
iterable = filter.isEmpty() ? db.watch(Document.class) : db.watch(filter, Document.class);
|
||||
}
|
||||
|
||||
if (!options.maxAwaitTime().isZero()) {
|
||||
iterable = iterable.maxAwaitTime(options.maxAwaitTime().toMillis(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
if (!resumeToken.isEmpty()) {
|
||||
|
||||
if (resumeAfter) {
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.messaging;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import org.springframework.data.mongodb.MongoDatabaseFactory;
|
||||
import org.springframework.data.mongodb.core.messaging.SubscriptionRequest.RequestOptions;
|
||||
import org.springframework.lang.Nullable;
|
||||
@@ -72,6 +74,16 @@ public interface SubscriptionRequest<S, T, O extends RequestOptions> {
|
||||
@Nullable
|
||||
String getCollectionName();
|
||||
|
||||
/**
|
||||
* Get the maximum wait time (the time till the next Document is emitted) to apply when reading from the collection.
|
||||
*
|
||||
* @return never {@literal null}. {@link Duration#ZERO} by default.
|
||||
* @since 3.0
|
||||
*/
|
||||
default Duration maxAwaitTime() {
|
||||
return Duration.ZERO;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create empty options.
|
||||
*
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.messaging;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.convert.QueryMapper;
|
||||
@@ -75,6 +77,10 @@ class TailableCursorTask extends CursorReadingTask<Document, Object> {
|
||||
iterable = iterable.collation(collation);
|
||||
}
|
||||
|
||||
if (!options.maxAwaitTime().isZero()) {
|
||||
iterable = iterable.maxAwaitTime(options.maxAwaitTime().toMillis(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
return iterable.iterator();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration;
|
||||
|
||||
@@ -46,4 +49,9 @@ public class ConfigClassInDefaultPackage extends AbstractMongoClientConfiguratio
|
||||
public MongoClient mongoClient() {
|
||||
return MongoClients.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Class<?>> getInitialEntitySet() throws ClassNotFoundException {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bson.types.ObjectId;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
@@ -238,6 +240,11 @@ public class ReactiveTransactionIntegrationTests {
|
||||
public ReactiveMongoTransactionManager transactionManager(ReactiveMongoDatabaseFactory factory) {
|
||||
return new ReactiveMongoTransactionManager(factory);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Class<?>> getInitialEntitySet() {
|
||||
return Collections.singleton(Person.class);
|
||||
}
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
|
||||
@@ -17,6 +17,9 @@ package org.springframework.data.mongodb.config;
|
||||
|
||||
import static org.springframework.data.mongodb.test.util.Assertions.*;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
@@ -54,6 +57,11 @@ public abstract class AbstractIntegrationTests {
|
||||
public MongoClient mongoClient() {
|
||||
return MongoTestUtils.client();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Class<?>> getInitialEntitySet() throws ClassNotFoundException {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired MongoOperations operations;
|
||||
|
||||
@@ -172,6 +172,7 @@ public class AbstractMongoConfigurationUnitTests {
|
||||
public MongoTypeMapper typeMapper() {
|
||||
return new CustomMongoTypeMapper();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class ConfigurationWithMultipleBasePackages extends AbstractMongoClientConfiguration {
|
||||
|
||||
@@ -18,8 +18,11 @@ package org.springframework.data.mongodb.config;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -28,7 +31,9 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.FilterType;
|
||||
import org.springframework.data.annotation.Version;
|
||||
import org.springframework.data.domain.AuditorAware;
|
||||
import org.springframework.data.mongodb.core.AuditablePerson;
|
||||
@@ -68,7 +73,8 @@ public class AuditingViaJavaConfigRepositoriesTests {
|
||||
|
||||
@Configuration
|
||||
@EnableMongoAuditing(auditorAwareRef = "auditorProvider")
|
||||
@EnableMongoRepositories(basePackageClasses = AuditablePersonRepository.class, considerNestedRepositories = true)
|
||||
@EnableMongoRepositories(basePackageClasses = AuditablePersonRepository.class, considerNestedRepositories = true,
|
||||
includeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = AuditablePersonRepository.class))
|
||||
static class Config extends AbstractMongoClientConfiguration {
|
||||
|
||||
@Override
|
||||
@@ -86,6 +92,12 @@ public class AuditingViaJavaConfigRepositoriesTests {
|
||||
public AuditorAware<AuditablePerson> auditorProvider() {
|
||||
return mock(AuditorAware.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Class<?>> getInitialEntitySet() throws ClassNotFoundException {
|
||||
return new HashSet<>(
|
||||
Arrays.asList(AuditablePerson.class, VersionedAuditablePerson.class, SimpleVersionedAuditablePerson.class));
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
@@ -212,6 +224,11 @@ public class AuditingViaJavaConfigRepositoriesTests {
|
||||
protected String getDatabaseName() {
|
||||
return "database";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Class<?>> getInitialEntitySet() throws ClassNotFoundException {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
static class VersionedAuditablePerson extends AuditablePerson {
|
||||
|
||||
@@ -21,7 +21,10 @@ import static org.mockito.Mockito.*;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Function;
|
||||
|
||||
@@ -29,7 +32,9 @@ import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.FilterType;
|
||||
import org.springframework.data.annotation.Version;
|
||||
import org.springframework.data.domain.AuditorAware;
|
||||
import org.springframework.data.mongodb.core.AuditablePerson;
|
||||
@@ -63,7 +68,8 @@ public class ReactiveAuditingTests {
|
||||
|
||||
@Configuration
|
||||
@EnableMongoAuditing(auditorAwareRef = "auditorProvider")
|
||||
@EnableReactiveMongoRepositories(basePackageClasses = ReactiveAuditingTests.class, considerNestedRepositories = true)
|
||||
@EnableReactiveMongoRepositories(basePackageClasses = ReactiveAuditingTests.class, considerNestedRepositories = true,
|
||||
includeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = ReactiveAuditablePersonRepository.class))
|
||||
static class Config extends AbstractReactiveMongoConfiguration {
|
||||
|
||||
@Override
|
||||
@@ -76,6 +82,12 @@ public class ReactiveAuditingTests {
|
||||
return mongoClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Class<?>> getInitialEntitySet() {
|
||||
return new HashSet<>(
|
||||
Arrays.asList(AuditablePerson.class, VersionedAuditablePerson.class, SimpleVersionedAuditablePerson.class));
|
||||
}
|
||||
|
||||
@Bean
|
||||
@SuppressWarnings("unchecked")
|
||||
public AuditorAware<AuditablePerson> auditorProvider() {
|
||||
|
||||
@@ -23,8 +23,9 @@ import java.net.UnknownHostException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
|
||||
|
||||
import com.mongodb.ServerAddress;
|
||||
|
||||
@@ -38,12 +39,12 @@ public class ServerAddressPropertyEditorUnitTests {
|
||||
|
||||
ServerAddressPropertyEditor editor;
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
editor = new ServerAddressPropertyEditor();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class) // DATAMONGO-454, DATAMONGO-1062
|
||||
@Test // DATAMONGO-454, DATAMONGO-1062
|
||||
public void rejectsAddressConfigWithoutASingleParsableAndResolvableServerAddress() {
|
||||
|
||||
String unknownHost1 = "gugu.nonexistant.example.org";
|
||||
@@ -51,10 +52,12 @@ public class ServerAddressPropertyEditorUnitTests {
|
||||
|
||||
assertUnresolveableHostnames(unknownHost1, unknownHost2);
|
||||
|
||||
editor.setAsText(unknownHost1 + "," + unknownHost2);
|
||||
assertThatExceptionOfType(IllegalArgumentException.class)
|
||||
.isThrownBy(() -> editor.setAsText(unknownHost1 + "," + unknownHost2));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-454
|
||||
@EnabledIfSystemProperty(named = "user.name", matches = "jenkins")
|
||||
public void skipsUnparsableAddressIfAtLeastOneIsParsable() throws UnknownHostException {
|
||||
|
||||
editor.setAsText("foo, localhost");
|
||||
|
||||
@@ -23,10 +23,9 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.data.mongodb.core.BulkOperations.BulkMode;
|
||||
import org.springframework.data.mongodb.core.DefaultBulkOperations.BulkOperationContext;
|
||||
@@ -36,9 +35,10 @@ import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.mongodb.core.query.Update;
|
||||
import org.springframework.data.mongodb.test.util.MongoTemplateExtension;
|
||||
import org.springframework.data.mongodb.test.util.MongoTestTemplate;
|
||||
import org.springframework.data.mongodb.test.util.Template;
|
||||
import org.springframework.data.util.Pair;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import com.mongodb.MongoBulkWriteException;
|
||||
import com.mongodb.WriteConcern;
|
||||
@@ -52,21 +52,17 @@ import com.mongodb.client.MongoCollection;
|
||||
* @author Christoph Strobl
|
||||
* @author Minsu Kim
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration("classpath:infrastructure.xml")
|
||||
@ExtendWith(MongoTemplateExtension.class)
|
||||
public class DefaultBulkOperationsIntegrationTests {
|
||||
|
||||
static final String COLLECTION_NAME = "bulk_ops";
|
||||
|
||||
@Autowired MongoOperations operations;
|
||||
@Template(initialEntitySet = BaseDoc.class) //
|
||||
static MongoTestTemplate operations;
|
||||
|
||||
MongoCollection<Document> collection;
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
|
||||
this.collection = this.operations.getCollection(COLLECTION_NAME);
|
||||
this.collection.deleteMany(new Document());
|
||||
operations.flush(COLLECTION_NAME);
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-934
|
||||
|
||||
@@ -16,27 +16,26 @@
|
||||
package org.springframework.data.mongodb.core;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.assertj.core.api.Assumptions.*;
|
||||
import static org.springframework.data.mongodb.core.index.PartialIndexFilter.*;
|
||||
import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
|
||||
import org.bson.BsonDocument;
|
||||
import org.bson.Document;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.mongodb.core.convert.QueryMapper;
|
||||
import org.springframework.data.mongodb.core.index.Index;
|
||||
import org.springframework.data.mongodb.core.index.IndexDefinition;
|
||||
import org.springframework.data.mongodb.core.index.IndexInfo;
|
||||
import org.springframework.data.mongodb.core.index.IndexOperations;
|
||||
import org.springframework.data.mongodb.core.mapping.Field;
|
||||
import org.springframework.data.mongodb.core.query.Collation;
|
||||
import org.springframework.data.mongodb.core.query.Collation.CaseFirst;
|
||||
import org.springframework.data.util.Version;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.data.mongodb.test.util.MongoTemplateExtension;
|
||||
import org.springframework.data.mongodb.test.util.MongoTestTemplate;
|
||||
import org.springframework.data.mongodb.test.util.Template;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import com.mongodb.client.MongoCollection;
|
||||
@@ -49,43 +48,27 @@ import com.mongodb.client.model.IndexOptions;
|
||||
* @author Oliver Gierke
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration("classpath:infrastructure.xml")
|
||||
@ExtendWith(MongoTemplateExtension.class)
|
||||
public class DefaultIndexOperationsIntegrationTests {
|
||||
|
||||
private static final Version THREE_DOT_TWO = new Version(3, 2);
|
||||
private static final Version THREE_DOT_FOUR = new Version(3, 4);
|
||||
private static Version mongoVersion;
|
||||
static final String COLLECTION_NAME = "default-index-operations-tests";
|
||||
static final org.bson.Document GEO_SPHERE_2D = new org.bson.Document("loaction", "2dsphere");
|
||||
|
||||
@Autowired MongoTemplate template;
|
||||
DefaultIndexOperations indexOps;
|
||||
MongoCollection<org.bson.Document> collection;
|
||||
@Template //
|
||||
static MongoTestTemplate template;
|
||||
|
||||
@Before
|
||||
MongoCollection<org.bson.Document> collection = template.getCollection(COLLECTION_NAME);
|
||||
IndexOperations indexOps = template.indexOps(COLLECTION_NAME);
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
|
||||
queryMongoVersionIfNecessary();
|
||||
String collectionName = this.template.getCollectionName(DefaultIndexOperationsIntegrationTestsSample.class);
|
||||
|
||||
this.collection = this.template.getDb().getCollection(collectionName, Document.class);
|
||||
this.collection.dropIndexes();
|
||||
this.indexOps = new DefaultIndexOperations(template.getMongoDbFactory(), collectionName,
|
||||
new QueryMapper(template.getConverter()));
|
||||
}
|
||||
|
||||
private void queryMongoVersionIfNecessary() {
|
||||
|
||||
if (mongoVersion == null) {
|
||||
Document result = template.executeCommand("{ buildInfo: 1 }");
|
||||
mongoVersion = Version.parse(result.get("version").toString());
|
||||
}
|
||||
template.dropIndexes(COLLECTION_NAME);
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1008
|
||||
public void getIndexInfoShouldBeAbleToRead2dsphereIndex() {
|
||||
|
||||
collection.createIndex(GEO_SPHERE_2D);
|
||||
template.getCollection(COLLECTION_NAME).createIndex(GEO_SPHERE_2D);
|
||||
|
||||
IndexInfo info = findAndReturnIndexInfo(GEO_SPHERE_2D);
|
||||
assertThat(info.getIndexFields().get(0).isGeo()).isEqualTo(true);
|
||||
@@ -94,8 +77,6 @@ public class DefaultIndexOperationsIntegrationTests {
|
||||
@Test // DATAMONGO-1467, DATAMONGO-2198
|
||||
public void shouldApplyPartialFilterCorrectly() {
|
||||
|
||||
assumeThat(mongoVersion.isGreaterThanOrEqualTo(THREE_DOT_TWO)).isTrue();
|
||||
|
||||
IndexDefinition id = new Index().named("partial-with-criteria").on("k3y", Direction.ASC)
|
||||
.partial(of(where("q-t-y").gte(10)));
|
||||
|
||||
@@ -109,12 +90,10 @@ public class DefaultIndexOperationsIntegrationTests {
|
||||
@Test // DATAMONGO-1467, DATAMONGO-2198
|
||||
public void shouldApplyPartialFilterWithMappedPropertyCorrectly() {
|
||||
|
||||
assumeThat(mongoVersion.isGreaterThanOrEqualTo(THREE_DOT_TWO)).isTrue();
|
||||
|
||||
IndexDefinition id = new Index().named("partial-with-mapped-criteria").on("k3y", Direction.ASC)
|
||||
.partial(of(where("quantity").gte(10)));
|
||||
|
||||
indexOps.ensureIndex(id);
|
||||
template.indexOps(DefaultIndexOperationsIntegrationTestsSample.class).ensureIndex(id);
|
||||
|
||||
IndexInfo info = findAndReturnIndexInfo(indexOps.getIndexInfo(), "partial-with-mapped-criteria");
|
||||
assertThat(Document.parse(info.getPartialFilterExpression()))
|
||||
@@ -124,8 +103,6 @@ public class DefaultIndexOperationsIntegrationTests {
|
||||
@Test // DATAMONGO-1467, DATAMONGO-2198
|
||||
public void shouldApplyPartialDBOFilterCorrectly() {
|
||||
|
||||
assumeThat(mongoVersion.isGreaterThanOrEqualTo(THREE_DOT_TWO)).isTrue();
|
||||
|
||||
IndexDefinition id = new Index().named("partial-with-dbo").on("k3y", Direction.ASC)
|
||||
.partial(of(new org.bson.Document("qty", new org.bson.Document("$gte", 10))));
|
||||
|
||||
@@ -139,13 +116,10 @@ public class DefaultIndexOperationsIntegrationTests {
|
||||
@Test // DATAMONGO-1467, DATAMONGO-2198
|
||||
public void shouldFavorExplicitMappingHintViaClass() {
|
||||
|
||||
assumeThat(mongoVersion.isGreaterThanOrEqualTo(THREE_DOT_TWO)).isTrue();
|
||||
|
||||
IndexDefinition id = new Index().named("partial-with-inheritance").on("k3y", Direction.ASC)
|
||||
.partial(of(where("age").gte(10)));
|
||||
|
||||
indexOps = new DefaultIndexOperations(template.getMongoDbFactory(),
|
||||
this.template.getCollectionName(DefaultIndexOperationsIntegrationTestsSample.class),
|
||||
indexOps = new DefaultIndexOperations(template.getMongoDbFactory(), COLLECTION_NAME,
|
||||
new QueryMapper(template.getConverter()), MappingToSameCollection.class);
|
||||
|
||||
indexOps.ensureIndex(id);
|
||||
@@ -173,14 +147,11 @@ public class DefaultIndexOperationsIntegrationTests {
|
||||
@Test // DATAMONGO-1518
|
||||
public void shouldCreateIndexWithCollationCorrectly() {
|
||||
|
||||
assumeThat(mongoVersion.isGreaterThanOrEqualTo(THREE_DOT_FOUR)).isTrue();
|
||||
|
||||
IndexDefinition id = new Index().named("with-collation").on("xyz", Direction.ASC)
|
||||
.collation(Collation.of("de_AT").caseFirst(CaseFirst.off()));
|
||||
|
||||
new DefaultIndexOperations(template.getMongoDbFactory(),
|
||||
this.template.getCollectionName(DefaultIndexOperationsIntegrationTestsSample.class),
|
||||
new QueryMapper(template.getConverter()), MappingToSameCollection.class);
|
||||
new DefaultIndexOperations(template.getMongoDbFactory(), COLLECTION_NAME, new QueryMapper(template.getConverter()),
|
||||
MappingToSameCollection.class);
|
||||
|
||||
indexOps.ensureIndex(id);
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
package org.springframework.data.mongodb.core;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.junit.Assume.*;
|
||||
import static org.springframework.data.mongodb.core.index.PartialIndexFilter.*;
|
||||
import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
|
||||
@@ -25,14 +24,10 @@ import reactor.test.StepVerifier;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.mongodb.config.AbstractReactiveMongoConfiguration;
|
||||
import org.springframework.data.mongodb.core.convert.QueryMapper;
|
||||
import org.springframework.data.mongodb.core.index.Index;
|
||||
import org.springframework.data.mongodb.core.index.IndexDefinition;
|
||||
@@ -40,71 +35,36 @@ import org.springframework.data.mongodb.core.index.IndexInfo;
|
||||
import org.springframework.data.mongodb.core.mapping.Field;
|
||||
import org.springframework.data.mongodb.core.query.Collation;
|
||||
import org.springframework.data.mongodb.core.query.Collation.CaseFirst;
|
||||
import org.springframework.data.mongodb.test.util.MongoTestUtils;
|
||||
import org.springframework.data.util.Version;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.data.mongodb.test.util.MongoTemplateExtension;
|
||||
import org.springframework.data.mongodb.test.util.ReactiveMongoTestTemplate;
|
||||
import org.springframework.data.mongodb.test.util.Template;
|
||||
|
||||
import com.mongodb.reactivestreams.client.MongoClient;
|
||||
import com.mongodb.reactivestreams.client.MongoCollection;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration
|
||||
@ExtendWith(MongoTemplateExtension.class)
|
||||
public class DefaultReactiveIndexOperationsTests {
|
||||
|
||||
@Configuration
|
||||
static class Config extends AbstractReactiveMongoConfiguration {
|
||||
@Template(initialEntitySet = DefaultIndexOperationsIntegrationTestsSample.class)
|
||||
static ReactiveMongoTestTemplate template;
|
||||
|
||||
@Override
|
||||
public MongoClient reactiveMongoClient() {
|
||||
return MongoTestUtils.reactiveClient();
|
||||
}
|
||||
String collectionName = template.getCollectionName(DefaultIndexOperationsIntegrationTestsSample.class);
|
||||
|
||||
@Override
|
||||
protected String getDatabaseName() {
|
||||
return "index-ops-tests";
|
||||
}
|
||||
}
|
||||
MongoCollection<Document> collection = template.getCollection(collectionName);
|
||||
DefaultReactiveIndexOperations indexOps = new DefaultReactiveIndexOperations(template, collectionName,
|
||||
new QueryMapper(template.getConverter()));
|
||||
|
||||
private static final Version THREE_DOT_TWO = new Version(3, 2);
|
||||
private static final Version THREE_DOT_FOUR = new Version(3, 4);
|
||||
private static Version mongoVersion;
|
||||
|
||||
@Autowired ReactiveMongoTemplate template;
|
||||
|
||||
MongoCollection<Document> collection;
|
||||
DefaultReactiveIndexOperations indexOps;
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
|
||||
queryMongoVersionIfNecessary();
|
||||
String collectionName = this.template.getCollectionName(DefaultIndexOperationsIntegrationTestsSample.class);
|
||||
|
||||
this.collection = this.template.getMongoDatabase().getCollection(collectionName, Document.class);
|
||||
this.indexOps = new DefaultReactiveIndexOperations(template, collectionName,
|
||||
new QueryMapper(template.getConverter()));
|
||||
|
||||
StepVerifier.create(this.collection.dropIndexes()).verifyComplete();
|
||||
}
|
||||
|
||||
private void queryMongoVersionIfNecessary() {
|
||||
|
||||
if (mongoVersion == null) {
|
||||
Document result = template.executeCommand("{ buildInfo: 1 }").block();
|
||||
mongoVersion = Version.parse(result.get("version").toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1518
|
||||
public void shouldCreateIndexWithCollationCorrectly() {
|
||||
|
||||
assumeTrue(mongoVersion.isGreaterThanOrEqualTo(THREE_DOT_FOUR));
|
||||
|
||||
IndexDefinition id = new Index().named("with-collation").on("xyz", Direction.ASC)
|
||||
.collation(Collation.of("de_AT").caseFirst(CaseFirst.off()));
|
||||
|
||||
@@ -137,8 +97,6 @@ public class DefaultReactiveIndexOperationsTests {
|
||||
@Test // DATAMONGO-1682, DATAMONGO-2198
|
||||
public void shouldApplyPartialFilterCorrectly() {
|
||||
|
||||
assumeTrue(mongoVersion.isGreaterThanOrEqualTo(THREE_DOT_TWO));
|
||||
|
||||
IndexDefinition id = new Index().named("partial-with-criteria").on("k3y", Direction.ASC)
|
||||
.partial(of(where("q-t-y").gte(10)));
|
||||
|
||||
@@ -155,8 +113,6 @@ public class DefaultReactiveIndexOperationsTests {
|
||||
@Test // DATAMONGO-1682, DATAMONGO-2198
|
||||
public void shouldApplyPartialFilterWithMappedPropertyCorrectly() {
|
||||
|
||||
assumeTrue(mongoVersion.isGreaterThanOrEqualTo(THREE_DOT_TWO));
|
||||
|
||||
IndexDefinition id = new Index().named("partial-with-mapped-criteria").on("k3y", Direction.ASC)
|
||||
.partial(of(where("quantity").gte(10)));
|
||||
|
||||
@@ -172,8 +128,6 @@ public class DefaultReactiveIndexOperationsTests {
|
||||
@Test // DATAMONGO-1682, DATAMONGO-2198
|
||||
public void shouldApplyPartialDBOFilterCorrectly() {
|
||||
|
||||
assumeTrue(mongoVersion.isGreaterThanOrEqualTo(THREE_DOT_TWO));
|
||||
|
||||
IndexDefinition id = new Index().named("partial-with-dbo").on("k3y", Direction.ASC)
|
||||
.partial(of(new org.bson.Document("qty", new org.bson.Document("$gte", 10))));
|
||||
|
||||
@@ -191,8 +145,6 @@ public class DefaultReactiveIndexOperationsTests {
|
||||
@Test // DATAMONGO-1682, DATAMONGO-2198
|
||||
public void shouldFavorExplicitMappingHintViaClass() {
|
||||
|
||||
assumeTrue(mongoVersion.isGreaterThanOrEqualTo(THREE_DOT_TWO));
|
||||
|
||||
IndexDefinition id = new Index().named("partial-with-inheritance").on("k3y", Direction.ASC)
|
||||
.partial(of(where("age").gte(10)));
|
||||
|
||||
|
||||
@@ -44,10 +44,9 @@ import org.springframework.data.mongodb.core.index.GeospatialIndex;
|
||||
import org.springframework.data.mongodb.core.mapping.Field;
|
||||
import org.springframework.data.mongodb.core.query.BasicQuery;
|
||||
import org.springframework.data.mongodb.core.query.NearQuery;
|
||||
import org.springframework.data.mongodb.test.util.Client;
|
||||
import org.springframework.data.mongodb.test.util.MongoClientExtension;
|
||||
|
||||
import com.mongodb.client.MongoClient;
|
||||
import org.springframework.data.mongodb.test.util.MongoTemplateExtension;
|
||||
import org.springframework.data.mongodb.test.util.MongoTestTemplate;
|
||||
import org.springframework.data.mongodb.test.util.Template;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link ExecutableFindOperationSupport}.
|
||||
@@ -55,13 +54,14 @@ import com.mongodb.client.MongoClient;
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@ExtendWith(MongoClientExtension.class)
|
||||
@ExtendWith(MongoTemplateExtension.class)
|
||||
public class ExecutableFindOperationSupportTests {
|
||||
|
||||
private static final String STAR_WARS = "star-wars";
|
||||
private static final String STAR_WARS_PLANETS = "star-wars-universe";
|
||||
static @Client MongoClient mongoClient;
|
||||
MongoTemplate template;
|
||||
|
||||
@Template(database = "executable-find-operation-support-tests", initialEntitySet = { Person.class, Planet.class }) //
|
||||
static MongoTestTemplate template;
|
||||
|
||||
Person han;
|
||||
Person luke;
|
||||
@@ -72,10 +72,7 @@ public class ExecutableFindOperationSupportTests {
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
|
||||
template = new MongoTemplate(
|
||||
new SimpleMongoClientDatabaseFactory(mongoClient, "ExecutableFindOperationSupportTests"));
|
||||
template.dropCollection(STAR_WARS);
|
||||
template.dropCollection(STAR_WARS_PLANETS);
|
||||
template.flush();
|
||||
|
||||
template.indexOps(Planet.class).ensureIndex(
|
||||
new GeospatialIndex("coordinates").typed(GeoSpatialIndexType.GEO_2DSPHERE).named("planet-coordinate-idx"));
|
||||
|
||||
@@ -28,10 +28,10 @@ import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.mapping.Field;
|
||||
import org.springframework.data.mongodb.test.util.Client;
|
||||
import org.springframework.data.mongodb.test.util.MongoClientExtension;
|
||||
import org.springframework.data.mongodb.test.util.MongoTemplateExtension;
|
||||
import org.springframework.data.mongodb.test.util.MongoTestTemplate;
|
||||
import org.springframework.data.mongodb.test.util.Template;
|
||||
|
||||
import com.mongodb.client.MongoClient;
|
||||
import com.mongodb.client.result.DeleteResult;
|
||||
|
||||
/**
|
||||
@@ -40,13 +40,13 @@ import com.mongodb.client.result.DeleteResult;
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@ExtendWith(MongoClientExtension.class)
|
||||
@ExtendWith(MongoTemplateExtension.class)
|
||||
public class ExecutableRemoveOperationSupportTests {
|
||||
|
||||
private static final String STAR_WARS = "star-wars";
|
||||
static @Client MongoClient mongoClient;
|
||||
|
||||
MongoTemplate template;
|
||||
@Template(initialEntitySet = Person.class) //
|
||||
static MongoTestTemplate template;
|
||||
|
||||
Person han;
|
||||
Person luke;
|
||||
@@ -54,9 +54,7 @@ public class ExecutableRemoveOperationSupportTests {
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
|
||||
template = new MongoTemplate(
|
||||
new SimpleMongoClientDatabaseFactory(mongoClient, "ExecutableRemoveOperationSupportTests"));
|
||||
template.dropCollection(STAR_WARS);
|
||||
template.flush();
|
||||
|
||||
han = new Person();
|
||||
han.firstname = "han";
|
||||
|
||||
@@ -31,10 +31,10 @@ import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.mapping.Field;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.mongodb.core.query.Update;
|
||||
import org.springframework.data.mongodb.test.util.Client;
|
||||
import org.springframework.data.mongodb.test.util.MongoClientExtension;
|
||||
import org.springframework.data.mongodb.test.util.MongoTemplateExtension;
|
||||
import org.springframework.data.mongodb.test.util.MongoTestTemplate;
|
||||
import org.springframework.data.mongodb.test.util.Template;
|
||||
|
||||
import com.mongodb.client.MongoClient;
|
||||
import com.mongodb.client.result.UpdateResult;
|
||||
|
||||
/**
|
||||
@@ -43,12 +43,13 @@ import com.mongodb.client.result.UpdateResult;
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@ExtendWith(MongoClientExtension.class)
|
||||
@ExtendWith(MongoTemplateExtension.class)
|
||||
public class ExecutableUpdateOperationSupportTests {
|
||||
|
||||
private static final String STAR_WARS = "star-wars";
|
||||
static @Client MongoClient mongoClient;
|
||||
MongoTemplate template;
|
||||
|
||||
@Template(initialEntitySet = { Human.class, Jedi.class, Person.class }) //
|
||||
static MongoTestTemplate template;
|
||||
|
||||
Person han;
|
||||
Person luke;
|
||||
@@ -56,9 +57,7 @@ public class ExecutableUpdateOperationSupportTests {
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
|
||||
template = new MongoTemplate(
|
||||
new SimpleMongoClientDatabaseFactory(mongoClient, "ExecutableUpdateOperationSupportTests"));
|
||||
template.dropCollection(STAR_WARS);
|
||||
template.flush();
|
||||
|
||||
han = new Person();
|
||||
han.firstname = "han";
|
||||
|
||||
@@ -31,29 +31,30 @@ import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.mapping.Field;
|
||||
import org.springframework.data.mongodb.core.schema.MongoJsonSchema;
|
||||
import org.springframework.data.mongodb.test.util.Client;
|
||||
import org.springframework.data.mongodb.test.util.MongoClientExtension;
|
||||
|
||||
import com.mongodb.client.MongoClient;
|
||||
import org.springframework.data.mongodb.test.util.MongoTemplateExtension;
|
||||
import org.springframework.data.mongodb.test.util.MongoTestTemplate;
|
||||
import org.springframework.data.mongodb.test.util.Template;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@ExtendWith(MongoClientExtension.class)
|
||||
@ExtendWith(MongoTemplateExtension.class)
|
||||
public class JsonSchemaQueryTests {
|
||||
|
||||
public static final String DATABASE_NAME = "json-schema-query-tests";
|
||||
|
||||
static @Client MongoClient client;
|
||||
static @Client com.mongodb.reactivestreams.client.MongoClient reactiveClient;
|
||||
|
||||
MongoTemplate template;
|
||||
@Template(database = DATABASE_NAME, initialEntitySet = Person.class) //
|
||||
static MongoTestTemplate template;
|
||||
|
||||
Person jellyBelly, roseSpringHeart, kazmardBoombub;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
|
||||
template = new MongoTemplate(client, DATABASE_NAME);
|
||||
template.flush();
|
||||
|
||||
jellyBelly = new Person();
|
||||
jellyBelly.id = "1";
|
||||
|
||||
@@ -17,8 +17,10 @@ package org.springframework.data.mongodb.core;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -63,6 +65,11 @@ public class MongoTemplateCollationTests {
|
||||
protected boolean autoIndexCreation() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Class<?>> getInitialEntitySet() throws ClassNotFoundException {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired MongoTemplate template;
|
||||
|
||||
@@ -35,10 +35,10 @@ import org.springframework.data.mongodb.core.convert.LazyLoadingTestUtils;
|
||||
import org.springframework.data.mongodb.core.mapping.DBRef;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoId;
|
||||
import org.springframework.data.mongodb.test.util.Client;
|
||||
import org.springframework.data.mongodb.test.util.MongoClientExtension;
|
||||
import org.springframework.data.mongodb.test.util.MongoTemplateExtension;
|
||||
import org.springframework.data.mongodb.test.util.MongoTestTemplate;
|
||||
import org.springframework.data.mongodb.test.util.Template;
|
||||
|
||||
import com.mongodb.client.MongoClient;
|
||||
import com.mongodb.client.model.Filters;
|
||||
|
||||
/**
|
||||
@@ -47,31 +47,24 @@ import com.mongodb.client.model.Filters;
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
@ExtendWith(MongoClientExtension.class)
|
||||
@ExtendWith(MongoTemplateExtension.class)
|
||||
public class MongoTemplateDbRefTests {
|
||||
|
||||
static @Client MongoClient mongoClient;
|
||||
@Template(database = "mongo-template-dbref-tests",
|
||||
initialEntitySet = { RefCycleLoadingIntoDifferentTypeRoot.class,
|
||||
RefCycleLoadingIntoDifferentTypeIntermediate.class, RefCycleLoadingIntoDifferentTypeRootView.class,
|
||||
WithDBRefOnRawStringId.class, WithLazyDBRefOnRawStringId.class, WithRefToAnotherDb.class,
|
||||
WithLazyRefToAnotherDb.class, WithListRefToAnotherDb.class, WithLazyListRefToAnotherDb.class }) //
|
||||
static MongoTestTemplate template;
|
||||
|
||||
MongoTemplate template;
|
||||
MongoTemplate otherDbTemplate;
|
||||
@Template(database = "mongo-template-dbref-tests-other-db", initialEntitySet = JustSomeType.class) //
|
||||
static MongoTestTemplate otherDbTemplate;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
|
||||
template = new MongoTemplate(mongoClient, "mongo-template-dbref-tests");
|
||||
|
||||
template.dropCollection(RefCycleLoadingIntoDifferentTypeRoot.class);
|
||||
template.dropCollection(RefCycleLoadingIntoDifferentTypeIntermediate.class);
|
||||
template.dropCollection(RefCycleLoadingIntoDifferentTypeRootView.class);
|
||||
template.dropCollection(WithDBRefOnRawStringId.class);
|
||||
template.dropCollection(WithLazyDBRefOnRawStringId.class);
|
||||
template.dropCollection(WithRefToAnotherDb.class);
|
||||
template.dropCollection(WithLazyRefToAnotherDb.class);
|
||||
template.dropCollection(WithListRefToAnotherDb.class);
|
||||
template.dropCollection(WithLazyListRefToAnotherDb.class);
|
||||
|
||||
otherDbTemplate = new MongoTemplate(mongoClient, "mongo-template-dbref-tests-other-db");
|
||||
otherDbTemplate.dropCollection(JustSomeType.class);
|
||||
template.flush();
|
||||
otherDbTemplate.flush();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1703
|
||||
|
||||
@@ -40,14 +40,11 @@ import java.util.stream.IntStream;
|
||||
|
||||
import org.bson.types.ObjectId;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
@@ -64,13 +61,9 @@ import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.mapping.MappingException;
|
||||
import org.springframework.data.mapping.context.PersistentEntities;
|
||||
import org.springframework.data.mongodb.InvalidMongoDbApiUsageException;
|
||||
import org.springframework.data.mongodb.MongoDatabaseFactory;
|
||||
import org.springframework.data.mongodb.core.convert.DbRefResolver;
|
||||
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
|
||||
import org.springframework.data.mongodb.core.convert.LazyLoadingProxy;
|
||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
|
||||
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
|
||||
import org.springframework.data.mongodb.core.index.Index;
|
||||
@@ -78,22 +71,20 @@ import org.springframework.data.mongodb.core.index.IndexField;
|
||||
import org.springframework.data.mongodb.core.index.IndexInfo;
|
||||
import org.springframework.data.mongodb.core.mapping.Field;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoId;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener;
|
||||
import org.springframework.data.mongodb.core.mapping.event.AfterSaveEvent;
|
||||
import org.springframework.data.mongodb.core.mapping.event.AuditingEventListener;
|
||||
import org.springframework.data.mongodb.core.mapping.event.BeforeConvertEvent;
|
||||
import org.springframework.data.mongodb.core.mapping.event.BeforeSaveEvent;
|
||||
import org.springframework.data.mongodb.core.query.BasicQuery;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.mongodb.core.query.Update;
|
||||
import org.springframework.data.mongodb.test.util.Client;
|
||||
import org.springframework.data.mongodb.test.util.MongoClientExtension;
|
||||
import org.springframework.data.mongodb.test.util.MongoTestTemplate;
|
||||
import org.springframework.data.mongodb.test.util.MongoVersion;
|
||||
import org.springframework.data.mongodb.test.util.MongoVersionRule;
|
||||
import org.springframework.data.util.CloseableIterator;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -128,111 +119,72 @@ import com.mongodb.client.result.UpdateResult;
|
||||
* @author Laszlo Csontos
|
||||
* @author duozhilin
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration("classpath:infrastructure.xml")
|
||||
@ExtendWith(MongoClientExtension.class)
|
||||
public class MongoTemplateTests {
|
||||
|
||||
@Autowired MongoTemplate template;
|
||||
@Autowired MongoDatabaseFactory factory;
|
||||
public static final String DB_NAME = "mongo-template-tests";
|
||||
|
||||
ConfigurableApplicationContext context;
|
||||
MongoTemplate mappingTemplate;
|
||||
static @Client MongoClient client;
|
||||
|
||||
@Rule public MongoVersionRule mongoVersion = MongoVersionRule.any();
|
||||
ConfigurableApplicationContext context = new GenericApplicationContext();
|
||||
|
||||
@Autowired
|
||||
public void setApplicationContext(ConfigurableApplicationContext context) {
|
||||
MongoTestTemplate template = new MongoTestTemplate(cfg -> {
|
||||
|
||||
this.context = context;
|
||||
cfg.configureDatabaseFactory(it -> {
|
||||
|
||||
context.addApplicationListener(new PersonWithIdPropertyOfTypeUUIDListener());
|
||||
it.client(client);
|
||||
it.defaultDb(DB_NAME);
|
||||
});
|
||||
|
||||
PersistentEntities entities = PersistentEntities.of(template.getConverter().getMappingContext());
|
||||
cfg.configureMappingContext(it -> {
|
||||
it.autocreateIndex(false);
|
||||
it.intitalEntitySet(AuditablePerson.class);
|
||||
|
||||
context.addApplicationListener(new AuditingEventListener(() -> new IsNewAwareAuditingHandler(entities)));
|
||||
}
|
||||
});
|
||||
|
||||
@Autowired
|
||||
public void setMongoClient(MongoClient mongo) throws Exception {
|
||||
cfg.configureApplicationContext(it -> {
|
||||
it.applicationContext(context);
|
||||
it.addEventListener(new PersonWithIdPropertyOfTypeUUIDListener());
|
||||
});
|
||||
|
||||
CustomConversions conversions = new MongoCustomConversions(
|
||||
Arrays.asList(DateToDateTimeConverter.INSTANCE, DateTimeToDateConverter.INSTANCE));
|
||||
cfg.configureAuditing(it -> {
|
||||
it.auditingHandler(IsNewAwareAuditingHandler::new);
|
||||
});
|
||||
});
|
||||
|
||||
MongoMappingContext mappingContext = new MongoMappingContext();
|
||||
mappingContext.setInitialEntitySet(
|
||||
new HashSet<>(Arrays.asList(PersonWith_idPropertyOfTypeObjectId.class, PersonWith_idPropertyOfTypeString.class,
|
||||
PersonWithIdPropertyOfTypeObjectId.class, PersonWithIdPropertyOfTypeString.class,
|
||||
PersonWithIdPropertyOfTypeInteger.class, PersonWithIdPropertyOfTypeBigInteger.class,
|
||||
PersonWithIdPropertyOfPrimitiveInt.class, PersonWithIdPropertyOfTypeLong.class,
|
||||
PersonWithIdPropertyOfPrimitiveLong.class, PersonWithIdPropertyOfTypeUUID.class)));
|
||||
mappingContext.setSimpleTypeHolder(conversions.getSimpleTypeHolder());
|
||||
mappingContext.initialize();
|
||||
MongoTestTemplate mappingTemplate = new MongoTestTemplate(cfg -> {
|
||||
|
||||
DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);
|
||||
MappingMongoConverter mappingConverter = new MappingMongoConverter(dbRefResolver, mappingContext);
|
||||
mappingConverter.setCustomConversions(conversions);
|
||||
mappingConverter.afterPropertiesSet();
|
||||
cfg.configureDatabaseFactory(it -> {
|
||||
|
||||
this.mappingTemplate = new MongoTemplate(factory, mappingConverter);
|
||||
}
|
||||
it.client(client);
|
||||
it.defaultDb(DB_NAME);
|
||||
});
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
cfg.configureConversion(it -> {
|
||||
it.customConverters(DateToDateTimeConverter.INSTANCE, DateTimeToDateConverter.INSTANCE);
|
||||
});
|
||||
|
||||
cleanDb();
|
||||
cfg.configureMappingContext(it -> {
|
||||
it.autocreateIndex(false);
|
||||
});
|
||||
|
||||
this.mappingTemplate.setApplicationContext(context);
|
||||
}
|
||||
cfg.configureApplicationContext(it -> {
|
||||
it.applicationContext(new GenericApplicationContext());
|
||||
it.addEventListener(new PersonWithIdPropertyOfTypeUUIDListener());
|
||||
});
|
||||
});
|
||||
|
||||
@After
|
||||
MongoDatabaseFactory factory = template.getMongoDbFactory();
|
||||
|
||||
@AfterEach
|
||||
public void cleanUp() {
|
||||
cleanDb();
|
||||
}
|
||||
|
||||
protected void cleanDb() {
|
||||
template.flush();
|
||||
template.flush("collection", "personX", "findandreplace");
|
||||
|
||||
mappingTemplate.flush();
|
||||
|
||||
template.dropCollection(Person.class);
|
||||
template.dropCollection(PersonWithAList.class);
|
||||
template.dropCollection(PersonWith_idPropertyOfTypeObjectId.class);
|
||||
template.dropCollection(PersonWith_idPropertyOfTypeString.class);
|
||||
template.dropCollection(PersonWithIdPropertyOfTypeObjectId.class);
|
||||
template.dropCollection(PersonWithIdPropertyOfTypeString.class);
|
||||
template.dropCollection(PersonWithIdPropertyOfTypeInteger.class);
|
||||
template.dropCollection(PersonWithIdPropertyOfTypeBigInteger.class);
|
||||
template.dropCollection(PersonWithIdPropertyOfPrimitiveInt.class);
|
||||
template.dropCollection(PersonWithIdPropertyOfTypeLong.class);
|
||||
template.dropCollection(PersonWithIdPropertyOfPrimitiveLong.class);
|
||||
template.dropCollection(PersonWithIdPropertyOfTypeUUID.class);
|
||||
template.dropCollection(PersonWithVersionPropertyOfTypeInteger.class);
|
||||
template.dropCollection(TestClass.class);
|
||||
template.dropCollection(Sample.class);
|
||||
template.dropCollection(MyPerson.class);
|
||||
template.dropCollection(TypeWithFieldAnnotation.class);
|
||||
template.dropCollection(TypeWithDate.class);
|
||||
template.dropCollection("collection");
|
||||
template.dropCollection("personX");
|
||||
template.dropCollection("findandreplace");
|
||||
template.dropCollection(Document.class);
|
||||
template.dropCollection(ObjectWith3AliasedFields.class);
|
||||
template.dropCollection(ObjectWith3AliasedFieldsAndNestedAddress.class);
|
||||
template.dropCollection(BaseDoc.class);
|
||||
template.dropCollection(ObjectWithEnumValue.class);
|
||||
template.dropCollection(DocumentWithCollection.class);
|
||||
template.dropCollection(DocumentWithCollectionOfSimpleType.class);
|
||||
template.dropCollection(DocumentWithMultipleCollections.class);
|
||||
template.dropCollection(DocumentWithNestedCollection.class);
|
||||
template.dropCollection(DocumentWithEmbeddedDocumentWithCollection.class);
|
||||
template.dropCollection(DocumentWithNestedList.class);
|
||||
template.dropCollection(DocumentWithDBRefCollection.class);
|
||||
template.dropCollection(SomeContent.class);
|
||||
template.dropCollection(SomeTemplate.class);
|
||||
template.dropCollection(Address.class);
|
||||
template.dropCollection(DocumentWithCollectionOfSamples.class);
|
||||
template.dropCollection(WithGeoJson.class);
|
||||
template.dropCollection(DocumentWithNestedTypeHavingStringIdProperty.class);
|
||||
template.dropCollection(ImmutableAudited.class);
|
||||
template.dropCollection(RawStringId.class);
|
||||
template.dropCollection(Outer.class);
|
||||
template.dropCollection(Message.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -408,7 +360,7 @@ public class MongoTemplateTests {
|
||||
@Test // DATAMONGO-746, DATAMONGO-2264
|
||||
public void testReadIndexInfoForIndicesCreatedViaMongoShellCommands() throws Exception {
|
||||
|
||||
template.indexOps(Person.class).dropAllIndexes();
|
||||
template.dropCollection(Person.class);
|
||||
|
||||
assertThat(template.indexOps(Person.class).getIndexInfo().isEmpty()).isTrue();
|
||||
|
||||
@@ -1314,6 +1266,7 @@ public class MongoTemplateTests {
|
||||
|
||||
@Test // DATADOC-202
|
||||
public void executeDocument() {
|
||||
|
||||
template.insert(new Person("Tom"));
|
||||
template.insert(new Person("Dick"));
|
||||
template.insert(new Person("Harry"));
|
||||
@@ -1487,7 +1440,7 @@ public class MongoTemplateTests {
|
||||
assertThat(result.get(0).getName()).isEqualTo("Oleg");
|
||||
}
|
||||
|
||||
@Test(expected = OptimisticLockingFailureException.class) // DATAMONGO-279
|
||||
@Test // DATAMONGO-279
|
||||
public void optimisticLockingHandling() {
|
||||
|
||||
// Init version
|
||||
@@ -1519,7 +1472,9 @@ public class MongoTemplateTests {
|
||||
person.version = 0;
|
||||
person.firstName = "Patryk3";
|
||||
|
||||
template.save(person);
|
||||
final PersonWithVersionPropertyOfTypeInteger toBeSaved = person;
|
||||
|
||||
assertThatExceptionOfType(OptimisticLockingFailureException.class).isThrownBy(() -> template.save(toBeSaved));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-562
|
||||
@@ -1595,13 +1550,14 @@ public class MongoTemplateTests {
|
||||
assertThat(document.containsKey("_id")).isTrue();
|
||||
}
|
||||
|
||||
@Test(expected = MappingException.class) // DATAMONGO-550, DATAMONGO-1730
|
||||
@Test // DATAMONGO-550, DATAMONGO-1730
|
||||
public void rejectsPlainObjectWithOutExplicitCollection() {
|
||||
|
||||
org.bson.Document document = new org.bson.Document("foo", "bar");
|
||||
template.save(document, "collection");
|
||||
|
||||
template.findById(document.get("_id"), org.bson.Document.class);
|
||||
assertThatExceptionOfType(MappingException.class)
|
||||
.isThrownBy(() -> template.findById(document.get("_id"), org.bson.Document.class));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-550
|
||||
@@ -1709,7 +1665,7 @@ public class MongoTemplateTests {
|
||||
assertThat(person.version).isEqualTo(0L);
|
||||
}
|
||||
|
||||
@Test(expected = DuplicateKeyException.class) // DATAMONGO-622
|
||||
@Test // DATAMONGO-622
|
||||
public void preventsDuplicateInsert() {
|
||||
|
||||
template.setWriteConcern(WriteConcern.ACKNOWLEDGED);
|
||||
@@ -1721,7 +1677,7 @@ public class MongoTemplateTests {
|
||||
assertThat(person.version).isEqualTo(0);
|
||||
|
||||
person.version = null;
|
||||
template.save(person);
|
||||
assertThatExceptionOfType(DuplicateKeyException.class).isThrownBy(() -> template.save(person));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-629
|
||||
|
||||
@@ -23,7 +23,9 @@ import static org.springframework.data.mongodb.test.util.MongoTestUtils.*;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import org.bson.Document;
|
||||
@@ -93,6 +95,11 @@ public class MongoTemplateTransactionTests {
|
||||
MongoTransactionManager txManager(MongoDatabaseFactory dbFactory) {
|
||||
return new MongoTransactionManager(dbFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Class<?>> getInitialEntitySet() throws ClassNotFoundException {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired MongoTemplate template;
|
||||
|
||||
@@ -27,7 +27,6 @@ import java.util.List;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.Version;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationUpdate;
|
||||
@@ -39,34 +38,25 @@ import org.springframework.data.mongodb.core.mapping.Field;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.mongodb.core.query.Update;
|
||||
import org.springframework.data.mongodb.test.util.Client;
|
||||
import org.springframework.data.mongodb.test.util.EnableIfMongoServerVersion;
|
||||
import org.springframework.data.mongodb.test.util.MongoClientExtension;
|
||||
import org.springframework.data.mongodb.test.util.MongoTestUtils;
|
||||
import org.springframework.data.mongodb.test.util.MongoTemplateExtension;
|
||||
import org.springframework.data.mongodb.test.util.MongoTestTemplate;
|
||||
import org.springframework.data.mongodb.test.util.Template;
|
||||
|
||||
import com.mongodb.client.MongoClient;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
@ExtendWith({ MongoClientExtension.class })
|
||||
@ExtendWith({ MongoTemplateExtension.class })
|
||||
class MongoTemplateUpdateTests {
|
||||
|
||||
static final String DB_NAME = "update-test";
|
||||
|
||||
static @Client MongoClient client;
|
||||
|
||||
MongoTemplate template;
|
||||
@Template(initialEntitySet = { Score.class, Versioned.class, Book.class }) //
|
||||
static MongoTestTemplate template;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
|
||||
template = new MongoTemplate(new SimpleMongoClientDatabaseFactory(client, DB_NAME));
|
||||
|
||||
MongoTestUtils.createOrReplaceCollection(DB_NAME, template.getCollectionName(Score.class), client);
|
||||
MongoTestUtils.createOrReplaceCollection(DB_NAME, template.getCollectionName(Versioned.class), client);
|
||||
MongoTestUtils.createOrReplaceCollection(DB_NAME, template.getCollectionName(Book.class), client);
|
||||
template.flush();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2331
|
||||
@@ -305,7 +295,7 @@ class MongoTemplateUpdateTests {
|
||||
}
|
||||
|
||||
private MongoCollection<org.bson.Document> collection(Class<?> type) {
|
||||
return client.getDatabase(DB_NAME).getCollection(template.getCollectionName(type));
|
||||
return template.getCollection(template.getCollectionName(type));
|
||||
}
|
||||
|
||||
@Document("scores")
|
||||
|
||||
@@ -22,7 +22,9 @@ import static org.springframework.data.mongodb.core.validation.Validator.*;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -75,6 +77,11 @@ public class MongoTemplateValidationTests {
|
||||
protected boolean autoIndexCreation() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Class<?>> getInitialEntitySet() throws ClassNotFoundException {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired MongoTemplate template;
|
||||
|
||||
@@ -19,14 +19,18 @@ import static org.assertj.core.api.Assertions.*;
|
||||
import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
import static org.springframework.data.mongodb.core.query.Query.*;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.FilterType;
|
||||
import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration;
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
|
||||
@@ -50,7 +54,7 @@ public class NoExplicitIdTests {
|
||||
static @Client MongoClient mongoClient;
|
||||
|
||||
@Configuration
|
||||
@EnableMongoRepositories(considerNestedRepositories = true)
|
||||
@EnableMongoRepositories(considerNestedRepositories = true, includeFilters=@Filter(type = FilterType.ASSIGNABLE_TYPE, classes = TypeWithoutExplicitIdPropertyRepository.class))
|
||||
static class Config extends AbstractMongoClientConfiguration {
|
||||
|
||||
@Override
|
||||
@@ -67,6 +71,11 @@ public class NoExplicitIdTests {
|
||||
protected boolean autoIndexCreation() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Class<?>> getInitialEntitySet() throws ClassNotFoundException {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired MongoOperations mongoOps;
|
||||
|
||||
@@ -33,10 +33,9 @@ import org.springframework.data.mongodb.core.mapping.Field;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.mongodb.core.query.UntypedExampleMatcher;
|
||||
import org.springframework.data.mongodb.test.util.Client;
|
||||
import org.springframework.data.mongodb.test.util.MongoClientExtension;
|
||||
|
||||
import com.mongodb.client.MongoClient;
|
||||
import org.springframework.data.mongodb.test.util.MongoTemplateExtension;
|
||||
import org.springframework.data.mongodb.test.util.MongoTestTemplate;
|
||||
import org.springframework.data.mongodb.test.util.Template;
|
||||
|
||||
/**
|
||||
* Integration tests for Query-by-example.
|
||||
@@ -45,19 +44,18 @@ import com.mongodb.client.MongoClient;
|
||||
* @author Mark Paluch
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@ExtendWith(MongoClientExtension.class)
|
||||
@ExtendWith(MongoTemplateExtension.class)
|
||||
public class QueryByExampleTests {
|
||||
|
||||
static @Client MongoClient mongoClient;
|
||||
@Template(initialEntitySet = Person.class) //
|
||||
static MongoTestTemplate operations;
|
||||
|
||||
MongoOperations operations;
|
||||
Person p1, p2, p3;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
|
||||
operations = new MongoTemplate(mongoClient, "query-by-example");
|
||||
operations.remove(new Query(), Person.class);
|
||||
operations.flush();
|
||||
|
||||
p1 = new Person();
|
||||
p1.firstname = "bran";
|
||||
|
||||
@@ -21,7 +21,9 @@ import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -61,6 +63,11 @@ public class ReactiveMongoTemplateCollationTests {
|
||||
protected String getDatabaseName() {
|
||||
return "collation-tests";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Class<?>> getInitialEntitySet() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired ReactiveMongoTemplate template;
|
||||
|
||||
@@ -43,20 +43,16 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import org.assertj.core.api.Assumptions;
|
||||
import org.bson.BsonDocument;
|
||||
import org.bson.BsonTimestamp;
|
||||
import org.bson.Document;
|
||||
import org.bson.types.ObjectId;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
@@ -67,6 +63,7 @@ import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.geo.Metrics;
|
||||
import org.springframework.data.mapping.MappingException;
|
||||
import org.springframework.data.mongodb.ReactiveMongoDatabaseFactory;
|
||||
import org.springframework.data.mongodb.core.MongoTemplateTests.Address;
|
||||
import org.springframework.data.mongodb.core.MongoTemplateTests.PersonWithConvertedId;
|
||||
import org.springframework.data.mongodb.core.MongoTemplateTests.VersionedPerson;
|
||||
@@ -80,14 +77,15 @@ import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.NearQuery;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.mongodb.core.query.Update;
|
||||
import org.springframework.data.mongodb.test.util.MongoVersion;
|
||||
import org.springframework.data.mongodb.test.util.MongoVersionRule;
|
||||
import org.springframework.data.mongodb.test.util.ReplicaSet;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.data.mongodb.test.util.Client;
|
||||
import org.springframework.data.mongodb.test.util.EnableIfMongoServerVersion;
|
||||
import org.springframework.data.mongodb.test.util.EnableIfReplicaSetAvailable;
|
||||
import org.springframework.data.mongodb.test.util.MongoClientExtension;
|
||||
import org.springframework.data.mongodb.test.util.MongoServerCondition;
|
||||
import org.springframework.data.mongodb.test.util.ReactiveMongoTestTemplate;
|
||||
|
||||
import com.mongodb.WriteConcern;
|
||||
import com.mongodb.reactivestreams.client.MongoClient;
|
||||
|
||||
/**
|
||||
* Integration test for {@link MongoTemplate}.
|
||||
@@ -95,34 +93,37 @@ import com.mongodb.WriteConcern;
|
||||
* @author Mark Paluch
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration("classpath:reactive-infrastructure.xml")
|
||||
@ExtendWith({ MongoClientExtension.class, MongoServerCondition.class })
|
||||
public class ReactiveMongoTemplateTests {
|
||||
|
||||
@Autowired SimpleReactiveMongoDatabaseFactory factory;
|
||||
@Autowired ReactiveMongoTemplate template;
|
||||
@Autowired ConfigurableApplicationContext context;
|
||||
@Rule public MongoVersionRule mongoVersion = MongoVersionRule.any();
|
||||
public static final String DB_NAME = "reactive-mongo-template-tests";
|
||||
static @Client MongoClient client;
|
||||
|
||||
@Before
|
||||
ConfigurableApplicationContext context = new GenericApplicationContext();
|
||||
ReactiveMongoTestTemplate template = new ReactiveMongoTestTemplate(cfg -> {
|
||||
|
||||
cfg.configureDatabaseFactory(it -> {
|
||||
|
||||
it.client(client);
|
||||
it.defaultDb(DB_NAME);
|
||||
});
|
||||
|
||||
cfg.configureApplicationContext(it -> {
|
||||
it.applicationContext(context);
|
||||
});
|
||||
});
|
||||
|
||||
ReactiveMongoDatabaseFactory factory = template.getDatabaseFactory();
|
||||
|
||||
@AfterEach
|
||||
public void setUp() {
|
||||
|
||||
Flux.merge(template.dropCollection("people"), //
|
||||
template.dropCollection("personX"), //
|
||||
template.dropCollection("collection"), //
|
||||
template.dropCollection(Person.class), //
|
||||
template.dropCollection(Venue.class), //
|
||||
template.dropCollection(PersonWithAList.class), //
|
||||
template.dropCollection(PersonWithIdPropertyOfTypeObjectId.class), //
|
||||
template.dropCollection(PersonWithVersionPropertyOfTypeInteger.class), //
|
||||
template.dropCollection(Sample.class), //
|
||||
template.dropCollection(MyPerson.class)) //
|
||||
.as(StepVerifier::create).verifyComplete();
|
||||
template.flush().as(StepVerifier::create).verifyComplete();
|
||||
template.flush("people", "collection").as(StepVerifier::create).verifyComplete();
|
||||
template.dropCollection(Person.class).as(StepVerifier::create).verifyComplete();
|
||||
template.dropCollection("personX").as(StepVerifier::create).verifyComplete();
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanUp() {}
|
||||
|
||||
@Test // DATAMONGO-1444
|
||||
public void insertSetsId() {
|
||||
|
||||
@@ -952,7 +953,7 @@ public class ReactiveMongoTemplateTests {
|
||||
assertThat(dbObject.containsKey("_id")).isTrue();
|
||||
}
|
||||
|
||||
@Test(expected = MappingException.class) // DATAMONGO-1444, DATAMONGO-1730
|
||||
@Test // DATAMONGO-1444, DATAMONGO-1730
|
||||
public void rejectsPlainObjectWithOutExplicitCollection() {
|
||||
|
||||
Document dbObject = new Document("foo", "bar");
|
||||
@@ -962,9 +963,8 @@ public class ReactiveMongoTemplateTests {
|
||||
.expectNextCount(1) //
|
||||
.verifyComplete();
|
||||
|
||||
template.findById(dbObject.get("_id"), Document.class) //
|
||||
.as(StepVerifier::create) //
|
||||
.verifyError(MappingException.class);
|
||||
assertThatExceptionOfType(MappingException.class)
|
||||
.isThrownBy(() -> template.findById(dbObject.get("_id"), Document.class));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1444
|
||||
@@ -1363,11 +1363,10 @@ public class ReactiveMongoTemplateTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1803
|
||||
@Ignore("Heavily relying on timing assumptions. Cannot test message resumption properly. Too much race for too little time in between.")
|
||||
@Disabled("Heavily relying on timing assumptions. Cannot test message resumption properly. Too much race for too little time in between.")
|
||||
@EnableIfReplicaSetAvailable
|
||||
public void changeStreamEventsShouldBeEmittedCorrectly() throws InterruptedException {
|
||||
|
||||
Assumptions.assumeThat(ReplicaSet.required().runsAsReplicaSet()).isTrue();
|
||||
|
||||
template.createCollection(Person.class).as(StepVerifier::create).expectNextCount(1).verifyComplete();
|
||||
|
||||
BlockingQueue<ChangeStreamEvent<Document>> documents = new LinkedBlockingQueue<>(100);
|
||||
@@ -1396,11 +1395,10 @@ public class ReactiveMongoTemplateTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1803
|
||||
@Ignore("Heavily relying on timing assumptions. Cannot test message resumption properly. Too much race for too little time in between.")
|
||||
@Disabled("Heavily relying on timing assumptions. Cannot test message resumption properly. Too much race for too little time in between.")
|
||||
@EnableIfReplicaSetAvailable
|
||||
public void changeStreamEventsShouldBeConvertedCorrectly() throws InterruptedException {
|
||||
|
||||
Assumptions.assumeThat(ReplicaSet.required().runsAsReplicaSet()).isTrue();
|
||||
|
||||
template.createCollection(Person.class).as(StepVerifier::create).expectNextCount(1).verifyComplete();
|
||||
|
||||
BlockingQueue<ChangeStreamEvent<Person>> documents = new LinkedBlockingQueue<>(100);
|
||||
@@ -1429,11 +1427,10 @@ public class ReactiveMongoTemplateTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1803
|
||||
@Ignore("Heavily relying on timing assumptions. Cannot test message resumption properly. Too much race for too little time in between.")
|
||||
@Disabled("Heavily relying on timing assumptions. Cannot test message resumption properly. Too much race for too little time in between.")
|
||||
@EnableIfReplicaSetAvailable
|
||||
public void changeStreamEventsShouldBeFilteredCorrectly() throws InterruptedException {
|
||||
|
||||
Assumptions.assumeThat(ReplicaSet.required().runsAsReplicaSet()).isTrue();
|
||||
|
||||
template.createCollection(Person.class).as(StepVerifier::create).expectNextCount(1).verifyComplete();
|
||||
|
||||
BlockingQueue<ChangeStreamEvent<Person>> documents = new LinkedBlockingQueue<>(100);
|
||||
@@ -1463,10 +1460,9 @@ public class ReactiveMongoTemplateTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1803
|
||||
@EnableIfReplicaSetAvailable
|
||||
public void mapsReservedWordsCorrectly() throws InterruptedException {
|
||||
|
||||
Assumptions.assumeThat(ReplicaSet.required().runsAsReplicaSet()).isTrue();
|
||||
|
||||
template.createCollection(Person.class).as(StepVerifier::create).expectNextCount(1).verifyComplete();
|
||||
|
||||
BlockingQueue<ChangeStreamEvent<Person>> documents = new LinkedBlockingQueue<>(100);
|
||||
@@ -1506,11 +1502,10 @@ public class ReactiveMongoTemplateTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1803
|
||||
@Ignore("Heavily relying on timing assumptions. Cannot test message resumption properly. Too much race for too little time in between.")
|
||||
@Disabled("Heavily relying on timing assumptions. Cannot test message resumption properly. Too much race for too little time in between.")
|
||||
@EnableIfReplicaSetAvailable
|
||||
public void changeStreamEventsShouldBeResumedCorrectly() throws InterruptedException {
|
||||
|
||||
Assumptions.assumeThat(ReplicaSet.required().runsAsReplicaSet()).isTrue();
|
||||
|
||||
template.createCollection(Person.class).as(StepVerifier::create).expectNextCount(1).verifyComplete();
|
||||
|
||||
BlockingQueue<ChangeStreamEvent<Person>> documents = new LinkedBlockingQueue<>(100);
|
||||
@@ -1586,7 +1581,6 @@ public class ReactiveMongoTemplateTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2189
|
||||
@DirtiesContext
|
||||
public void afterSaveEventContainsSavedObjectUsingInsert() {
|
||||
|
||||
AtomicReference<ImmutableVersioned> saved = createAfterSaveReference();
|
||||
@@ -1602,7 +1596,6 @@ public class ReactiveMongoTemplateTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2189
|
||||
@DirtiesContext
|
||||
public void afterSaveEventContainsSavedObjectUsingInsertAll() {
|
||||
|
||||
AtomicReference<ImmutableVersioned> saved = createAfterSaveReference();
|
||||
@@ -1618,11 +1611,10 @@ public class ReactiveMongoTemplateTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2012
|
||||
@MongoVersion(asOf = "4.0")
|
||||
@EnableIfMongoServerVersion(isGreaterThanEqual = "4.0")
|
||||
@EnableIfReplicaSetAvailable
|
||||
public void watchesDatabaseCorrectly() throws InterruptedException {
|
||||
|
||||
Assumptions.assumeThat(ReplicaSet.required().runsAsReplicaSet()).isTrue();
|
||||
|
||||
template.createCollection(Person.class).as(StepVerifier::create).expectNextCount(1).verifyComplete();
|
||||
template.createCollection("personX").as(StepVerifier::create).expectNextCount(1).verifyComplete();
|
||||
|
||||
@@ -1660,11 +1652,10 @@ public class ReactiveMongoTemplateTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2012, DATAMONGO-2113
|
||||
@MongoVersion(asOf = "4.0")
|
||||
@EnableIfMongoServerVersion(isGreaterThanEqual = "4.0")
|
||||
@EnableIfReplicaSetAvailable
|
||||
public void resumesAtTimestampCorrectly() throws InterruptedException {
|
||||
|
||||
Assumptions.assumeThat(ReplicaSet.required().runsAsReplicaSet()).isTrue();
|
||||
|
||||
template.createCollection(Person.class).as(StepVerifier::create).expectNextCount(1).verifyComplete();
|
||||
|
||||
BlockingQueue<ChangeStreamEvent<Person>> documents = new LinkedBlockingQueue<>(100);
|
||||
@@ -1711,11 +1702,10 @@ public class ReactiveMongoTemplateTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2115
|
||||
@MongoVersion(asOf = "4.0")
|
||||
@EnableIfMongoServerVersion(isGreaterThanEqual = "4.0")
|
||||
@EnableIfReplicaSetAvailable
|
||||
public void resumesAtBsonTimestampCorrectly() throws InterruptedException {
|
||||
|
||||
Assumptions.assumeThat(ReplicaSet.required().runsAsReplicaSet()).isTrue();
|
||||
|
||||
template.createCollection(Person.class).as(StepVerifier::create).expectNextCount(1).verifyComplete();
|
||||
|
||||
BlockingQueue<ChangeStreamEvent<Person>> documents = new LinkedBlockingQueue<>(100);
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
package org.springframework.data.mongodb.core;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
@@ -54,4 +56,9 @@ public class TestMongoConfiguration extends AbstractMongoClientConfiguration {
|
||||
converters.add(new org.springframework.data.mongodb.core.PersonWriteConverter());
|
||||
return new MongoCustomConversions(converters);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Class<?>> getInitialEntitySet() throws ClassNotFoundException {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,15 +38,12 @@ import org.bson.Document;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.DateTimeZone;
|
||||
import org.joda.time.LocalDateTime;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.annotation.Id;
|
||||
@@ -69,14 +66,16 @@ import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.NearQuery;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.mongodb.repository.Person;
|
||||
import org.springframework.data.mongodb.test.util.MongoTemplateExtension;
|
||||
import org.springframework.data.mongodb.test.util.MongoTestTemplate;
|
||||
import org.springframework.data.mongodb.test.util.MongoVersion;
|
||||
import org.springframework.data.mongodb.test.util.MongoVersionRule;
|
||||
import org.springframework.data.mongodb.test.util.Template;
|
||||
import org.springframework.data.util.CloseableIterator;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import com.mongodb.MongoException;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.model.InsertOneModel;
|
||||
import com.mongodb.client.model.WriteModel;
|
||||
|
||||
/**
|
||||
* Tests for {@link MongoTemplate#aggregate(Aggregation, Class, Class)}.
|
||||
@@ -91,8 +90,7 @@ import com.mongodb.client.MongoCollection;
|
||||
* @author Sergey Shcherbakov
|
||||
* @author Minsu Kim
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration("classpath:infrastructure.xml")
|
||||
@ExtendWith(MongoTemplateExtension.class)
|
||||
public class AggregationTests {
|
||||
|
||||
private static final String INPUT_COLLECTION = "aggregation_test_collection";
|
||||
@@ -100,43 +98,29 @@ public class AggregationTests {
|
||||
|
||||
private static boolean initialized = false;
|
||||
|
||||
@Autowired MongoTemplate mongoTemplate;
|
||||
@Template //
|
||||
static MongoTestTemplate mongoTemplate;
|
||||
|
||||
@Rule public MongoVersionRule mongoVersion = MongoVersionRule.any();
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
|
||||
cleanDb();
|
||||
initSampleDataIfNecessary();
|
||||
}
|
||||
|
||||
@After
|
||||
@AfterEach
|
||||
public void cleanUp() {
|
||||
cleanDb();
|
||||
}
|
||||
|
||||
private void cleanDb() {
|
||||
|
||||
mongoTemplate.flush(Product.class, UserWithLikes.class, DATAMONGO753.class, Data.class, DATAMONGO788.class,
|
||||
User.class, Person.class, Reservation.class, Venue.class, MeterData.class, LineItem.class, InventoryItem.class,
|
||||
Sales.class, Sales2.class, Employee.class, Art.class, Venue.class);
|
||||
|
||||
mongoTemplate.dropCollection(INPUT_COLLECTION);
|
||||
mongoTemplate.dropCollection(Product.class);
|
||||
mongoTemplate.dropCollection(UserWithLikes.class);
|
||||
mongoTemplate.dropCollection(DATAMONGO753.class);
|
||||
mongoTemplate.dropCollection(Data.class);
|
||||
mongoTemplate.dropCollection(DATAMONGO788.class);
|
||||
mongoTemplate.dropCollection(User.class);
|
||||
mongoTemplate.dropCollection(Person.class);
|
||||
mongoTemplate.dropCollection(Reservation.class);
|
||||
mongoTemplate.dropCollection(Venue.class);
|
||||
mongoTemplate.dropCollection(MeterData.class);
|
||||
mongoTemplate.dropCollection(LineItem.class);
|
||||
mongoTemplate.dropCollection(InventoryItem.class);
|
||||
mongoTemplate.dropCollection(Sales.class);
|
||||
mongoTemplate.dropCollection(Sales2.class);
|
||||
mongoTemplate.dropCollection(Employee.class);
|
||||
mongoTemplate.dropCollection(Art.class);
|
||||
mongoTemplate.dropCollection("personQueryTemp");
|
||||
mongoTemplate.dropCollection(Venue.class);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -149,20 +133,19 @@ public class AggregationTests {
|
||||
|
||||
if (!initialized) {
|
||||
|
||||
LOGGER.debug("Server uses MongoDB Version: {}", mongoVersion);
|
||||
|
||||
mongoTemplate.dropCollection(ZipInfo.class);
|
||||
mongoTemplate.execute(ZipInfo.class, new CollectionCallback<Void>() {
|
||||
|
||||
@Override
|
||||
public Void doInCollection(MongoCollection<Document> collection) throws MongoException, DataAccessException {
|
||||
|
||||
List<WriteModel<Document>> docs = new ArrayList<>();
|
||||
Scanner scanner = null;
|
||||
try {
|
||||
scanner = new Scanner(new BufferedInputStream(new ClassPathResource("zips.json").getInputStream()));
|
||||
while (scanner.hasNextLine()) {
|
||||
String zipInfoRecord = scanner.nextLine();
|
||||
collection.insertOne(Document.parse(zipInfoRecord));
|
||||
docs.add(new InsertOneModel<>(Document.parse(zipInfoRecord)));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (scanner != null) {
|
||||
@@ -171,6 +154,7 @@ public class AggregationTests {
|
||||
throw new RuntimeException("Could not load mongodb sample dataset!", e);
|
||||
}
|
||||
|
||||
collection.bulkWrite(docs);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
@@ -305,7 +289,6 @@ public class AggregationTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1391
|
||||
@MongoVersion(asOf = "3.2")
|
||||
public void shouldUnwindWithIndex() {
|
||||
|
||||
MongoCollection<Document> coll = mongoTemplate.getCollection(INPUT_COLLECTION);
|
||||
@@ -332,7 +315,6 @@ public class AggregationTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1391
|
||||
@MongoVersion(asOf = "3.2")
|
||||
public void shouldUnwindPreserveEmpty() {
|
||||
|
||||
MongoCollection<Document> coll = mongoTemplate.getCollection(INPUT_COLLECTION);
|
||||
@@ -521,7 +503,7 @@ public class AggregationTests {
|
||||
/*
|
||||
//complex mongodb aggregation framework example from
|
||||
https://docs.mongodb.org/manual/tutorial/aggregation-examples/#largest-and-smallest-cities-by-state
|
||||
|
||||
|
||||
db.zipcodes.aggregate(
|
||||
{
|
||||
$group: {
|
||||
@@ -952,7 +934,6 @@ public class AggregationTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-774
|
||||
@MongoVersion(asOf = "2.4")
|
||||
public void stringExpressionsInProjectionExample() {
|
||||
|
||||
Product product = new Product("P1", "A", 1.99, 3, 0.05, 0.19);
|
||||
@@ -1051,7 +1032,6 @@ public class AggregationTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-774
|
||||
@MongoVersion(asOf = "2.4")
|
||||
public void shouldPerformDateProjectionOperatorsCorrectly() throws ParseException {
|
||||
|
||||
Data data = new Data();
|
||||
@@ -1078,7 +1058,6 @@ public class AggregationTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-774
|
||||
@MongoVersion(asOf = "2.4")
|
||||
public void shouldPerformStringProjectionOperatorsCorrectly() throws ParseException {
|
||||
|
||||
Data data = new Data();
|
||||
@@ -1115,7 +1094,6 @@ public class AggregationTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1550
|
||||
@MongoVersion(asOf = "3.4")
|
||||
public void shouldPerformReplaceRootOperatorCorrectly() throws ParseException {
|
||||
|
||||
Data data = new Data();
|
||||
@@ -1263,7 +1241,6 @@ public class AggregationTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-960
|
||||
@MongoVersion(asOf = "2.6")
|
||||
public void returnFiveMostCommonLikesAggregationFrameworkExampleWithSortOnDiskOptionEnabled() {
|
||||
|
||||
createUserWithLikesDocuments();
|
||||
@@ -1287,7 +1264,6 @@ public class AggregationTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1637
|
||||
@MongoVersion(asOf = "2.6")
|
||||
public void returnFiveMostCommonLikesAggregationFrameworkExampleWithSortOnDiskOptionEnabledWhileStreaming() {
|
||||
|
||||
createUserWithLikesDocuments();
|
||||
@@ -1314,7 +1290,6 @@ public class AggregationTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-960
|
||||
@MongoVersion(asOf = "2.6")
|
||||
public void returnFiveMostCommonLikesShouldReturnStageExecutionInformationWithExplainOptionEnabled() {
|
||||
|
||||
createUserWithLikesDocuments();
|
||||
@@ -1333,7 +1308,6 @@ public class AggregationTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-954, DATAMONGO-2264
|
||||
@MongoVersion(asOf = "2.6")
|
||||
public void shouldSupportReturningCurrentAggregationRoot() {
|
||||
|
||||
mongoTemplate.save(new Person("p1_first", "p1_last", 25));
|
||||
@@ -1359,7 +1333,6 @@ public class AggregationTests {
|
||||
* {@link https://stackoverflow.com/questions/24185987/using-root-inside-spring-data-mongodb-for-retrieving-whole-document}
|
||||
*/
|
||||
@Test // DATAMONGO-954, DATAMONGO-2264
|
||||
@MongoVersion(asOf = "2.6")
|
||||
public void shouldSupportReturningCurrentAggregationRootInReference() {
|
||||
|
||||
mongoTemplate.save(new Reservation("0123", "42", 100));
|
||||
@@ -1379,7 +1352,6 @@ public class AggregationTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1549
|
||||
@MongoVersion(asOf = "3.4")
|
||||
public void shouldApplyCountCorrectly() {
|
||||
|
||||
mongoTemplate.save(new Reservation("0123", "42", 100));
|
||||
@@ -1537,7 +1509,6 @@ public class AggregationTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1326
|
||||
@MongoVersion(asOf = "3.2")
|
||||
public void shouldLookupPeopleCorectly() {
|
||||
|
||||
createUsersWithReferencedPersons();
|
||||
@@ -1557,7 +1528,6 @@ public class AggregationTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1326
|
||||
@MongoVersion(asOf = "3.2")
|
||||
public void shouldGroupByAndLookupPeopleCorectly() {
|
||||
|
||||
createUsersWithReferencedPersons();
|
||||
@@ -1603,7 +1573,6 @@ public class AggregationTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1637
|
||||
@MongoVersion(asOf = "2.6")
|
||||
public void shouldCreateOutputCollectionWhileStreaming() {
|
||||
|
||||
createPersonDocuments();
|
||||
@@ -1626,7 +1595,6 @@ public class AggregationTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1637
|
||||
@MongoVersion(asOf = "2.6")
|
||||
public void shouldReturnDocumentsWithOutputCollectionWhileStreaming() {
|
||||
|
||||
createPersonDocuments();
|
||||
@@ -1666,7 +1634,6 @@ public class AggregationTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1325
|
||||
@MongoVersion(asOf = "3.2")
|
||||
public void shouldApplySampleCorrectly() {
|
||||
|
||||
createUserWithLikesDocuments();
|
||||
@@ -1700,7 +1667,6 @@ public class AggregationTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1491
|
||||
@MongoVersion(asOf = "3.2")
|
||||
public void filterShouldBeAppliedCorrectly() {
|
||||
|
||||
Item item43 = Item.builder().itemId("43").quantity(2).price(2L).build();
|
||||
@@ -1731,7 +1697,6 @@ public class AggregationTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1538
|
||||
@MongoVersion(asOf = "3.2")
|
||||
public void letShouldBeAppliedCorrectly() {
|
||||
|
||||
Sales2 sales1 = Sales2.builder().id("1").price(10).tax(0.5F).applyDiscount(true).build();
|
||||
@@ -1756,7 +1721,6 @@ public class AggregationTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1551, DATAMONGO-2264
|
||||
@MongoVersion(asOf = "3.4")
|
||||
public void graphLookupShouldBeAppliedCorrectly() {
|
||||
|
||||
Employee em1 = Employee.builder().id(1).name("Dev").build();
|
||||
@@ -1789,7 +1753,6 @@ public class AggregationTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1552
|
||||
@MongoVersion(asOf = "3.4")
|
||||
public void bucketShouldCollectDocumentsIntoABucket() {
|
||||
|
||||
Art a1 = Art.builder().id(1).title("The Pillars of Society").artist("Grosz").year(1926).price(199.99).build();
|
||||
@@ -1824,7 +1787,6 @@ public class AggregationTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1552, DATAMONGO-2437
|
||||
@MongoVersion(asOf = "3.4")
|
||||
public void bucketAutoShouldCollectDocumentsIntoABucket() {
|
||||
|
||||
Art a1 = Art.builder().id(1).title("The Pillars of Society").artist("Grosz").year(1926).price(199.99).build();
|
||||
@@ -1858,7 +1820,6 @@ public class AggregationTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1552
|
||||
@MongoVersion(asOf = "3.4")
|
||||
public void facetShouldCreateFacets() {
|
||||
|
||||
Art a1 = Art.builder().id(1).title("The Pillars of Society").artist("Grosz").year(1926).price(199.99).build();
|
||||
|
||||
@@ -19,6 +19,10 @@ import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -61,6 +65,11 @@ public class MongoTemplateAuditingTests {
|
||||
protected String getDatabaseName() {
|
||||
return "mongo-template-audit-tests";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Class<?>> getInitialEntitySet() throws ClassNotFoundException {
|
||||
return new HashSet<>(Arrays.asList(ImmutableAuditableEntityWithVersion.class, KAuditableVersionedEntity.class));
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired MongoTemplate template;
|
||||
|
||||
@@ -23,6 +23,8 @@ import reactor.util.function.Tuples;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -71,6 +73,11 @@ public class ReactiveMongoTemplateAuditingTests {
|
||||
protected String getDatabaseName() {
|
||||
return DB_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Class<?>> getInitialEntitySet() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired ReactiveMongoTemplate template;
|
||||
|
||||
@@ -31,6 +31,7 @@ import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import org.bson.Document;
|
||||
@@ -48,6 +49,7 @@ import org.springframework.data.mongodb.test.util.MongoClientExtension;
|
||||
|
||||
import com.mongodb.client.MongoClient;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.MongoDatabase;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link MappingMongoConverter}.
|
||||
@@ -58,8 +60,11 @@ import com.mongodb.client.MongoCollection;
|
||||
public class MappingMongoConverterTests {
|
||||
|
||||
public static final String DATABASE = "mapping-converter-tests";
|
||||
|
||||
static @Client MongoClient client;
|
||||
|
||||
MongoDatabaseFactory factory = new SimpleMongoClientDatabaseFactory(client, DATABASE);
|
||||
|
||||
MappingMongoConverter converter;
|
||||
MongoMappingContext mappingContext;
|
||||
DbRefResolver dbRefResolver;
|
||||
@@ -67,12 +72,17 @@ public class MappingMongoConverterTests {
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
|
||||
client.getDatabase(DATABASE).drop();
|
||||
MongoDatabase database = client.getDatabase(DATABASE);
|
||||
|
||||
MongoDatabaseFactory factory = new SimpleMongoClientDatabaseFactory(client, DATABASE);
|
||||
database.getCollection("samples").deleteMany(new Document());
|
||||
database.getCollection("java-time-types").deleteMany(new Document());
|
||||
|
||||
dbRefResolver = spy(new DefaultDbRefResolver(factory));
|
||||
|
||||
mappingContext = new MongoMappingContext();
|
||||
mappingContext.setInitialEntitySet(new HashSet<>(
|
||||
Arrays.asList(WithLazyDBRefAsConstructorArg.class, WithLazyDBRef.class, WithJavaTimeTypes.class)));
|
||||
mappingContext.setAutoIndexCreation(false);
|
||||
mappingContext.afterPropertiesSet();
|
||||
|
||||
converter = new MappingMongoConverter(dbRefResolver, mappingContext);
|
||||
|
||||
@@ -41,7 +41,6 @@ import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.beans.ConversionNotSupportedException;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
||||
@@ -24,17 +24,16 @@ import lombok.Data;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bson.types.Binary;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.MongoOperations;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.data.mongodb.test.util.MongoTemplateExtension;
|
||||
import org.springframework.data.mongodb.test.util.MongoTestTemplate;
|
||||
import org.springframework.data.mongodb.test.util.Template;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link MongoConverters}.
|
||||
@@ -43,17 +42,17 @@ import org.springframework.test.context.junit4.SpringRunner;
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration("classpath:infrastructure.xml")
|
||||
@ExtendWith(MongoTemplateExtension.class)
|
||||
public class MongoConvertersIntegrationTests {
|
||||
|
||||
static final String COLLECTION = "converter-tests";
|
||||
|
||||
@Autowired MongoOperations template;
|
||||
@Template //
|
||||
static MongoTestTemplate template;
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
template.dropCollection(COLLECTION);
|
||||
template.flush(COLLECTION);
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-422
|
||||
|
||||
@@ -19,7 +19,9 @@ import static org.assertj.core.api.Assertions.*;
|
||||
import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
import static org.springframework.data.mongodb.core.query.Query.*;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.junit.After;
|
||||
@@ -35,9 +37,11 @@ import org.springframework.data.geo.Metrics;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.geo.Polygon;
|
||||
import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration;
|
||||
import org.springframework.data.mongodb.core.BulkOperations.BulkMode;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.TestEntities;
|
||||
import org.springframework.data.mongodb.core.Venue;
|
||||
import org.springframework.data.mongodb.core.geo.GeoJsonTests.Venue2DSphere;
|
||||
import org.springframework.data.mongodb.core.query.NearQuery;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.mongodb.test.util.MongoTestUtils;
|
||||
@@ -67,6 +71,11 @@ public abstract class AbstractGeoSpatialTests {
|
||||
public MongoClient mongoClient() {
|
||||
return MongoTestUtils.client();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Class<?>> getInitialEntitySet() throws ClassNotFoundException {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired MongoTemplate template;
|
||||
@@ -102,7 +111,10 @@ public abstract class AbstractGeoSpatialTests {
|
||||
}
|
||||
|
||||
protected void addVenues() {
|
||||
template.insertAll(TestEntities.geolocation().newYork());
|
||||
|
||||
|
||||
template.bulkOps(BulkMode.UNORDERED, Venue.class).insert(TestEntities.geolocation().newYork()).execute();
|
||||
// template.insertAll(TestEntities.geolocation().newYork());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -21,15 +21,17 @@ import static org.springframework.data.mongodb.core.query.Query.*;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.assertj.core.data.Percentage;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
@@ -39,6 +41,7 @@ import org.springframework.data.geo.GeoResults;
|
||||
import org.springframework.data.geo.Metrics;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration;
|
||||
import org.springframework.data.mongodb.core.BulkOperations.BulkMode;
|
||||
import org.springframework.data.mongodb.core.CollectionCallback;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.index.GeoSpatialIndexType;
|
||||
@@ -54,7 +57,6 @@ import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
|
||||
import com.mongodb.MongoException;
|
||||
import com.mongodb.WriteConcern;
|
||||
import com.mongodb.client.MongoClient;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
|
||||
@@ -80,6 +82,12 @@ public class GeoJsonTests {
|
||||
public MongoClient mongoClient() {
|
||||
return mongoClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Class<?>> getInitialEntitySet() throws ClassNotFoundException {
|
||||
return new HashSet<>(Arrays.asList(Venue2DSphere.class, VenueWithDistanceField.class, OpenGeoJson.class,
|
||||
DocumentWithPropertyUsingGeoJsonType.class));
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired MongoTemplate template;
|
||||
@@ -87,7 +95,13 @@ public class GeoJsonTests {
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
|
||||
template.setWriteConcern(WriteConcern.JOURNALED);
|
||||
// template.setWriteConcern(WriteConcern.JOURNALED);
|
||||
|
||||
// createIndex();
|
||||
// addVenues();
|
||||
}
|
||||
|
||||
private void createIndexAndAddVenues() {
|
||||
|
||||
createIndex();
|
||||
addVenues();
|
||||
@@ -103,6 +117,8 @@ public class GeoJsonTests {
|
||||
@Test // DATAMONGO-1135, DATAMONGO-2264
|
||||
public void geoNear() {
|
||||
|
||||
createIndexAndAddVenues();
|
||||
|
||||
NearQuery geoNear = NearQuery.near(new GeoJsonPoint(-73, 40), Metrics.KILOMETERS).num(10).maxDistance(150);
|
||||
|
||||
GeoResults<Venue2DSphere> result = template.geoNear(geoNear, Venue2DSphere.class);
|
||||
@@ -115,6 +131,8 @@ public class GeoJsonTests {
|
||||
@Test // DATAMONGO-2264
|
||||
public void geoNearShouldNotOverridePropertyWithDefaultNameForCalculatedDistance/* namely "dis" */() {
|
||||
|
||||
createIndexAndAddVenues();
|
||||
|
||||
NearQuery geoNear = NearQuery.near(new GeoJsonPoint(-73, 40), Metrics.KILOMETERS).num(10).maxDistance(150);
|
||||
|
||||
GeoResults<VenueWithDistanceField> result = template.geoNear(geoNear, VenueWithDistanceField.class);
|
||||
@@ -132,6 +150,8 @@ public class GeoJsonTests {
|
||||
@Test // DATAMONGO-2264
|
||||
public void geoNearShouldAllowToReadBackCalculatedDistanceIntoTargetTypeProperty/* namely "dis" */() {
|
||||
|
||||
createIndexAndAddVenues();
|
||||
|
||||
NearQuery geoNear = NearQuery.near(new GeoJsonPoint(-73, 40), Metrics.KILOMETERS).num(10).maxDistance(150);
|
||||
|
||||
GeoResults<VenueWithDistanceField> result = template.geoNear(geoNear, Venue2DSphere.class,
|
||||
@@ -150,6 +170,7 @@ public class GeoJsonTests {
|
||||
@Test // DATAMONGO-1148
|
||||
public void geoNearShouldReturnDistanceCorrectlyUsingGeoJson/*which is using the meters*/() {
|
||||
|
||||
createIndexAndAddVenues();
|
||||
NearQuery geoNear = NearQuery.near(new GeoJsonPoint(-73.99171, 40.738868), Metrics.KILOMETERS).num(10)
|
||||
.maxDistance(0.4);
|
||||
|
||||
@@ -165,6 +186,7 @@ public class GeoJsonTests {
|
||||
@Test // DATAMONGO-1348
|
||||
public void geoNearShouldReturnDistanceCorrectly/*which is using the meters*/() {
|
||||
|
||||
createIndexAndAddVenues();
|
||||
NearQuery geoNear = NearQuery.near(new Point(-73.99171, 40.738868), Metrics.KILOMETERS).num(10).maxDistance(0.4);
|
||||
|
||||
GeoResults<Venue2DSphere> result = template.geoNear(geoNear, Venue2DSphere.class);
|
||||
@@ -179,6 +201,7 @@ public class GeoJsonTests {
|
||||
@Test // DATAMONGO-1135
|
||||
public void geoNearWithMiles() {
|
||||
|
||||
createIndexAndAddVenues();
|
||||
NearQuery geoNear = NearQuery.near(new GeoJsonPoint(-73, 40), Metrics.MILES).num(10).maxDistance(93.2057);
|
||||
|
||||
GeoResults<Venue2DSphere> result = template.geoNear(geoNear, Venue2DSphere.class);
|
||||
@@ -190,6 +213,8 @@ public class GeoJsonTests {
|
||||
@Test // DATAMONGO-1135
|
||||
public void withinPolygon() {
|
||||
|
||||
createIndexAndAddVenues();
|
||||
|
||||
Point first = new Point(-73.99756, 40.73083);
|
||||
Point second = new Point(-73.99756, 40.741404);
|
||||
Point third = new Point(-73.988135, 40.741404);
|
||||
@@ -204,6 +229,8 @@ public class GeoJsonTests {
|
||||
@Test // DATAMONGO-1135
|
||||
public void nearPoint() {
|
||||
|
||||
createIndexAndAddVenues();
|
||||
|
||||
GeoJsonPoint point = new GeoJsonPoint(-73.99171, 40.738868);
|
||||
|
||||
Query query = query(where("location").near(point).maxDistance(0.01));
|
||||
@@ -214,6 +241,8 @@ public class GeoJsonTests {
|
||||
@Test // DATAMONGO-1135
|
||||
public void nearSphere() {
|
||||
|
||||
createIndexAndAddVenues();
|
||||
|
||||
GeoJsonPoint point = new GeoJsonPoint(-73.99171, 40.738868);
|
||||
|
||||
Query query = query(where("location").nearSphere(point).maxDistance(0.003712240453784));
|
||||
@@ -335,6 +364,8 @@ public class GeoJsonTests {
|
||||
@Test // DATAMONGO-1110
|
||||
public void nearWithMinDistance() {
|
||||
|
||||
createIndexAndAddVenues();
|
||||
|
||||
Point point = new GeoJsonPoint(-73.99171, 40.738868);
|
||||
List<Venue2DSphere> venues = template.find(query(where("location").near(point).minDistance(0.01)),
|
||||
Venue2DSphere.class);
|
||||
@@ -345,6 +376,8 @@ public class GeoJsonTests {
|
||||
@Test // DATAMONGO-1110
|
||||
public void nearSphereWithMinDistance() {
|
||||
|
||||
createIndexAndAddVenues();
|
||||
|
||||
Point point = new GeoJsonPoint(-73.99171, 40.738868);
|
||||
List<Venue2DSphere> venues = template.find(query(where("location").nearSphere(point).minDistance(0.01)),
|
||||
Venue2DSphere.class);
|
||||
@@ -355,6 +388,8 @@ public class GeoJsonTests {
|
||||
@Test // DATAMONGO-1135
|
||||
public void nearWithMinAndMaxDistance() {
|
||||
|
||||
createIndexAndAddVenues();
|
||||
|
||||
GeoJsonPoint point = new GeoJsonPoint(-73.99171, 40.738868);
|
||||
|
||||
Query query = query(where("location").near(point).minDistance(0.01).maxDistance(100));
|
||||
@@ -444,18 +479,22 @@ public class GeoJsonTests {
|
||||
|
||||
private void addVenues() {
|
||||
|
||||
template.insert(new Venue2DSphere("Penn Station", -73.99408, 40.75057));
|
||||
template.insert(new Venue2DSphere("10gen Office", -73.99171, 40.738868));
|
||||
template.insert(new Venue2DSphere("Flatiron Building", -73.988135, 40.741404));
|
||||
template.insert(new Venue2DSphere("Players Club", -73.997812, 40.739128));
|
||||
template.insert(new Venue2DSphere("City Bakery ", -73.992491, 40.738673));
|
||||
template.insert(new Venue2DSphere("Splash Bar", -73.992491, 40.738673));
|
||||
template.insert(new Venue2DSphere("Momofuku Milk Bar", -73.985839, 40.731698));
|
||||
template.insert(new Venue2DSphere("Shake Shack", -73.98820, 40.74164));
|
||||
template.insert(new Venue2DSphere("Penn Station", -73.99408, 40.75057));
|
||||
template.insert(new Venue2DSphere("Empire State Building", -73.98602, 40.74894));
|
||||
template.insert(new Venue2DSphere("Ulaanbaatar, Mongolia", 106.9154, 47.9245));
|
||||
template.insert(new Venue2DSphere("Maplewood, NJ", -74.2713, 40.73137));
|
||||
List<Venue2DSphere> venues = new ArrayList<>();
|
||||
|
||||
venues.add(new Venue2DSphere("Penn Station", -73.99408, 40.75057));
|
||||
venues.add(new Venue2DSphere("10gen Office", -73.99171, 40.738868));
|
||||
venues.add(new Venue2DSphere("Flatiron Building", -73.988135, 40.741404));
|
||||
venues.add(new Venue2DSphere("Players Club", -73.997812, 40.739128));
|
||||
venues.add(new Venue2DSphere("City Bakery ", -73.992491, 40.738673));
|
||||
venues.add(new Venue2DSphere("Splash Bar", -73.992491, 40.738673));
|
||||
venues.add(new Venue2DSphere("Momofuku Milk Bar", -73.985839, 40.731698));
|
||||
venues.add(new Venue2DSphere("Shake Shack", -73.98820, 40.74164));
|
||||
venues.add(new Venue2DSphere("Penn Station", -73.99408, 40.75057));
|
||||
venues.add(new Venue2DSphere("Empire State Building", -73.98602, 40.74894));
|
||||
venues.add(new Venue2DSphere("Ulaanbaatar, Mongolia", 106.9154, 47.9245));
|
||||
venues.add(new Venue2DSphere("Maplewood, NJ", -74.2713, 40.73137));
|
||||
|
||||
template.bulkOps(BulkMode.UNORDERED, Venue2DSphere.class).insert(venues).execute();
|
||||
}
|
||||
|
||||
protected void createIndex() {
|
||||
|
||||
@@ -25,8 +25,10 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -88,6 +90,11 @@ public class IndexingIntegrationTests {
|
||||
TimeoutResolver myTimeoutResolver() {
|
||||
return new TimeoutResolver("11s");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Class<?>> getInitialEntitySet() throws ClassNotFoundException {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
|
||||
@@ -19,36 +19,37 @@ import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.mongodb.config.AbstractIntegrationTests;
|
||||
import org.springframework.data.mongodb.core.CollectionOptions;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
import org.springframework.data.mongodb.core.mapping.Language;
|
||||
import org.springframework.data.mongodb.core.query.Collation;
|
||||
|
||||
import com.mongodb.WriteConcern;
|
||||
import org.springframework.data.mongodb.test.util.MongoTemplateExtension;
|
||||
import org.springframework.data.mongodb.test.util.MongoTestTemplate;
|
||||
import org.springframework.data.mongodb.test.util.Template;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class TextIndexTests extends AbstractIntegrationTests {
|
||||
@ExtendWith(MongoTemplateExtension.class)
|
||||
public class TextIndexTests {
|
||||
|
||||
@Template(initialEntitySet = TextIndexedDocumentRoot.class)
|
||||
static MongoTestTemplate template;
|
||||
|
||||
private @Autowired MongoTemplate template;
|
||||
private IndexOperations indexOps;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
@BeforeEach
|
||||
public void beforeEach() throws Exception {
|
||||
|
||||
template.setWriteConcern(WriteConcern.JOURNALED);
|
||||
this.indexOps = template.indexOps(TextIndexedDocumentRoot.class);
|
||||
|
||||
template.dropCollection(TextIndexedDocumentRoot.class);
|
||||
template.dropDatabase();
|
||||
|
||||
template.createCollection(TextIndexedDocumentRoot.class,
|
||||
CollectionOptions.empty().collation(Collation.of("de_AT")));
|
||||
}
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.mapping;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration;
|
||||
import org.springframework.data.mongodb.core.mapping.event.LoggingEventListener;
|
||||
@@ -47,4 +50,9 @@ public class GeoIndexedAppConfig extends AbstractMongoClientConfiguration {
|
||||
public LoggingEventListener mappingEventsListener() {
|
||||
return new LoggingEventListener();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Class<?>> getInitialEntitySet() throws ClassNotFoundException {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,22 +29,26 @@ import java.util.Map;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.bson.types.ObjectId;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.mongodb.MongoCollectionUtils;
|
||||
import org.springframework.data.mongodb.config.AbstractIntegrationTests;
|
||||
import org.springframework.data.mongodb.core.CollectionCallback;
|
||||
import org.springframework.data.mongodb.core.MongoOperations;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.mongodb.test.util.Client;
|
||||
import org.springframework.data.mongodb.test.util.MongoTemplateExtension;
|
||||
import org.springframework.data.mongodb.test.util.MongoTestTemplate;
|
||||
import org.springframework.data.mongodb.test.util.Template;
|
||||
|
||||
import com.mongodb.MongoException;
|
||||
import com.mongodb.client.MongoClient;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
|
||||
/**
|
||||
@@ -53,9 +57,23 @@ import com.mongodb.client.MongoCollection;
|
||||
* @author Thomas Darimont
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class MappingTests extends AbstractIntegrationTests {
|
||||
@ExtendWith(MongoTemplateExtension.class)
|
||||
public class MappingTests {
|
||||
|
||||
@Autowired MongoOperations template;
|
||||
static final String DB_NAME = "mapping-tests";
|
||||
|
||||
static @Client MongoClient client;
|
||||
|
||||
@Template(database = DB_NAME,
|
||||
initialEntitySet = { PersonWithDbRef.class, GeoLocation.class, PersonPojoStringId.class, Account.class,
|
||||
DetectedCollectionWithIndex.class, Item.class, Container.class, Person.class, PersonCustomCollection1.class,
|
||||
GeneratedId.class, PersonWithObjectId.class, PersonCustomIdName.class, PersonMapProperty.class }) //
|
||||
static MongoTestTemplate template;
|
||||
|
||||
@AfterEach
|
||||
void afterEach() {
|
||||
template.flush();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeneratedId() {
|
||||
@@ -164,10 +182,12 @@ public class MappingTests extends AbstractIntegrationTests {
|
||||
assertThat(result.get(0).getAccounts()).isNotNull();
|
||||
}
|
||||
|
||||
@Test(expected = DuplicateKeyException.class)
|
||||
@Test
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public void testUniqueIndex() {
|
||||
|
||||
MongoTemplate template = new MongoTemplate(client, DB_NAME);
|
||||
|
||||
Address addr = new Address();
|
||||
addr.setLines(new String[] { "1234 W. 1st Street", "Apt. 12" });
|
||||
addr.setCity("Anytown");
|
||||
@@ -177,7 +197,7 @@ public class MappingTests extends AbstractIntegrationTests {
|
||||
Person p1 = new Person(1234567890, "John", "Doe", 37, addr);
|
||||
Person p2 = new Person(1234567890, "Jane", "Doe", 38, addr);
|
||||
|
||||
template.insertAll(Arrays.asList(p1, p2));
|
||||
assertThatExceptionOfType(DuplicateKeyException.class).isThrownBy(() -> template.insertAll(Arrays.asList(p1, p2)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -206,6 +226,9 @@ public class MappingTests extends AbstractIntegrationTests {
|
||||
|
||||
@Test
|
||||
public void testIndexesCreatedInRightCollection() {
|
||||
|
||||
MongoTemplate template = new MongoTemplate(client, DB_NAME);
|
||||
|
||||
CustomCollectionWithIndex ccwi = new CustomCollectionWithIndex("test");
|
||||
template.insert(ccwi);
|
||||
|
||||
|
||||
@@ -21,18 +21,15 @@ import static org.springframework.data.mongodb.core.mapreduce.GroupBy.*;
|
||||
import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.test.util.MongoVersionRule;
|
||||
import org.springframework.data.util.Version;
|
||||
import org.springframework.data.mongodb.test.util.EnableIfMongoServerVersion;
|
||||
import org.springframework.data.mongodb.test.util.MongoServerCondition;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
|
||||
import com.mongodb.client.MongoCollection;
|
||||
|
||||
@@ -43,24 +40,20 @@ import com.mongodb.client.MongoCollection;
|
||||
* @author Oliver Gierke
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@ExtendWith({ SpringExtension.class, MongoServerCondition.class })
|
||||
@EnableIfMongoServerVersion(isLessThan = "4.1")
|
||||
@ContextConfiguration("classpath:infrastructure.xml")
|
||||
public class GroupByTests {
|
||||
|
||||
public static @ClassRule MongoVersionRule REQUIRES_AT_MOST_4_0 = MongoVersionRule.atMost(Version.parse("4.0.999"));
|
||||
static final String GROUP_TEST_COLLECTION = "group_test_collection";
|
||||
|
||||
@Autowired MongoTemplate mongoTemplate;
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
cleanDb();
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanUp() {
|
||||
cleanDb();
|
||||
}
|
||||
|
||||
protected void cleanDb() {
|
||||
mongoTemplate.dropCollection(mongoTemplate.getCollectionName(XObject.class));
|
||||
mongoTemplate.dropCollection("group_test_collection");
|
||||
@@ -96,7 +89,7 @@ public class GroupByTests {
|
||||
public void simpleGroupFunction() {
|
||||
|
||||
createGroupByData();
|
||||
GroupByResults<XObject> results = mongoTemplate.group("group_test_collection", GroupBy.key("x")
|
||||
GroupByResults<XObject> results = mongoTemplate.group(GROUP_TEST_COLLECTION, GroupBy.key("x")
|
||||
.initialDocument(new Document("count", 0)).reduceFunction("function(doc, prev) { prev.count += 1 }"),
|
||||
XObject.class);
|
||||
|
||||
@@ -109,7 +102,7 @@ public class GroupByTests {
|
||||
createGroupByData();
|
||||
GroupByResults<XObject> results = mongoTemplate
|
||||
.group(
|
||||
"group_test_collection", GroupBy.keyFunction("function(doc) { return { x : doc.x }; }")
|
||||
GROUP_TEST_COLLECTION, GroupBy.keyFunction("function(doc) { return { x : doc.x }; }")
|
||||
.initialDocument("{ count: 0 }").reduceFunction("function(doc, prev) { prev.count += 1 }"),
|
||||
XObject.class);
|
||||
|
||||
@@ -120,7 +113,7 @@ public class GroupByTests {
|
||||
public void simpleGroupWithFunctionsAsResources() {
|
||||
|
||||
createGroupByData();
|
||||
GroupByResults<XObject> results = mongoTemplate.group("group_test_collection",
|
||||
GroupByResults<XObject> results = mongoTemplate.group(GROUP_TEST_COLLECTION,
|
||||
GroupBy.keyFunction("classpath:keyFunction.js").initialDocument("{ count: 0 }")
|
||||
.reduceFunction("classpath:groupReduce.js"),
|
||||
XObject.class);
|
||||
@@ -132,7 +125,7 @@ public class GroupByTests {
|
||||
public void simpleGroupWithQueryAndFunctionsAsResources() {
|
||||
|
||||
createGroupByData();
|
||||
GroupByResults<XObject> results = mongoTemplate.group(where("x").gt(0), "group_test_collection",
|
||||
GroupByResults<XObject> results = mongoTemplate.group(where("x").gt(0), GROUP_TEST_COLLECTION,
|
||||
keyFunction("classpath:keyFunction.js").initialDocument("{ count: 0 }")
|
||||
.reduceFunction("classpath:groupReduce.js"),
|
||||
XObject.class);
|
||||
@@ -162,7 +155,7 @@ public class GroupByTests {
|
||||
|
||||
private void createGroupByData() {
|
||||
|
||||
MongoCollection<Document> c = mongoTemplate.getDb().getCollection("group_test_collection", Document.class);
|
||||
MongoCollection<Document> c = mongoTemplate.getDb().getCollection(GROUP_TEST_COLLECTION, Document.class);
|
||||
|
||||
c.insertOne(new Document("x", 1));
|
||||
c.insertOne(new Document("x", 1));
|
||||
|
||||
@@ -25,6 +25,7 @@ import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
@@ -41,8 +42,9 @@ import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.ChangeStreamOptions;
|
||||
import org.springframework.data.mongodb.core.mapping.Field;
|
||||
import org.springframework.data.mongodb.core.messaging.ChangeStreamRequest.ChangeStreamRequestOptions;
|
||||
import org.springframework.data.mongodb.core.messaging.ChangeStreamTask.ChangeStreamEventMessage;
|
||||
import org.springframework.data.mongodb.core.messaging.Message.MessageProperties;
|
||||
import org.springframework.data.mongodb.core.messaging.SubscriptionUtils.*;
|
||||
@@ -50,11 +52,11 @@ import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.Update;
|
||||
import org.springframework.data.mongodb.test.util.EnableIfMongoServerVersion;
|
||||
import org.springframework.data.mongodb.test.util.EnableIfReplicaSetAvailable;
|
||||
import org.springframework.data.mongodb.test.util.MongoClientExtension;
|
||||
import org.springframework.data.mongodb.test.util.MongoTemplateExtension;
|
||||
import org.springframework.data.mongodb.test.util.MongoTestTemplate;
|
||||
import org.springframework.data.mongodb.test.util.MongoVersion;
|
||||
import org.springframework.data.mongodb.test.util.ReplSetClient;
|
||||
import org.springframework.data.mongodb.test.util.Template;
|
||||
|
||||
import com.mongodb.client.MongoClient;
|
||||
import com.mongodb.client.model.changestream.ChangeStreamDocument;
|
||||
import com.mongodb.client.model.changestream.FullDocument;
|
||||
|
||||
@@ -65,14 +67,15 @@ import com.mongodb.client.model.changestream.FullDocument;
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@ExtendWith({ MongoClientExtension.class })
|
||||
@ExtendWith({ MongoTemplateExtension.class })
|
||||
@EnableIfReplicaSetAvailable
|
||||
public class ChangeStreamTests {
|
||||
|
||||
static @ReplSetClient MongoClient mongoClient;
|
||||
|
||||
static ThreadPoolExecutor executor;
|
||||
MongoTemplate template;
|
||||
|
||||
@Template(initialEntitySet = User.class, replicaSet = true) //
|
||||
static MongoTestTemplate template;
|
||||
|
||||
MessageListenerContainer container;
|
||||
|
||||
User jellyBelly;
|
||||
@@ -87,7 +90,6 @@ public class ChangeStreamTests {
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
|
||||
template = new MongoTemplate(mongoClient, "change-stream-tests");
|
||||
template.dropCollection(User.class);
|
||||
|
||||
container = new DefaultMessageListenerContainer(template, executor);
|
||||
@@ -123,7 +125,8 @@ public class ChangeStreamTests {
|
||||
public void readsPlainDocumentMessageCorrectly() throws InterruptedException {
|
||||
|
||||
CollectingMessageListener<ChangeStreamDocument<Document>, Document> messageListener = new CollectingMessageListener<>();
|
||||
ChangeStreamRequest<Document> request = new ChangeStreamRequest<>(messageListener, () -> "user");
|
||||
ChangeStreamRequest<Document> request = new ChangeStreamRequest<>(messageListener,
|
||||
new ChangeStreamRequestOptions(null, "user", Duration.ofMillis(10), ChangeStreamOptions.builder().build()));
|
||||
|
||||
Subscription subscription = container.register(request, Document.class);
|
||||
awaitSubscription(subscription);
|
||||
@@ -148,6 +151,7 @@ public class ChangeStreamTests {
|
||||
ChangeStreamRequest<User> request = ChangeStreamRequest.builder(messageListener) //
|
||||
.collection("user") //
|
||||
.filter(newAggregation(match(where("age").is(7)))) //
|
||||
.maxAwaitTime(Duration.ofMillis(10)) //
|
||||
.build();
|
||||
|
||||
Subscription subscription = container.register(request, User.class);
|
||||
@@ -174,6 +178,7 @@ public class ChangeStreamTests {
|
||||
.collection("user") //
|
||||
.filter(newAggregation(match(
|
||||
new Criteria().orOperator(where("user_name").is("huffyFluffy"), where("user_name").is("jellyBelly"))))) //
|
||||
.maxAwaitTime(Duration.ofMillis(10)) //
|
||||
.build();
|
||||
|
||||
Subscription subscription = container.register(request, User.class);
|
||||
@@ -200,6 +205,7 @@ public class ChangeStreamTests {
|
||||
.publishTo(messageListener) //
|
||||
.filter(newAggregation(User.class,
|
||||
match(new Criteria().orOperator(where("userName").is("huffyFluffy"), where("userName").is("jellyBelly"))))) //
|
||||
.maxAwaitTime(Duration.ofMillis(10)) //
|
||||
.build();
|
||||
|
||||
Subscription subscription = container.register(request, User.class);
|
||||
@@ -209,7 +215,7 @@ public class ChangeStreamTests {
|
||||
template.save(sugarSplashy);
|
||||
template.save(huffyFluffy);
|
||||
|
||||
awaitMessages(messageListener);
|
||||
awaitMessages(messageListener, 2);
|
||||
|
||||
List<User> messageBodies = messageListener.getMessages().stream().map(Message::getBody)
|
||||
.collect(Collectors.toList());
|
||||
@@ -225,6 +231,7 @@ public class ChangeStreamTests {
|
||||
.collection("user") //
|
||||
.publishTo(messageListener) //
|
||||
.filter(newAggregation(User.class, match(where("operationType").is("replace")))) //
|
||||
.maxAwaitTime(Duration.ofMillis(10)) //
|
||||
.build();
|
||||
|
||||
Subscription subscription = container.register(request, User.class);
|
||||
@@ -240,7 +247,7 @@ public class ChangeStreamTests {
|
||||
|
||||
template.save(replacement);
|
||||
|
||||
awaitMessages(messageListener);
|
||||
awaitMessages(messageListener, 1);
|
||||
|
||||
List<User> messageBodies = messageListener.getMessages().stream().map(Message::getBody)
|
||||
.collect(Collectors.toList());
|
||||
@@ -256,6 +263,7 @@ public class ChangeStreamTests {
|
||||
.collection("user") //
|
||||
.publishTo(messageListener) //
|
||||
.filter(new Document("$match", new Document("fullDocument.user_name", "sugarSplashy"))) //
|
||||
.maxAwaitTime(Duration.ofMillis(10)) //
|
||||
.build();
|
||||
|
||||
Subscription subscription = container.register(request, User.class);
|
||||
@@ -265,7 +273,7 @@ public class ChangeStreamTests {
|
||||
template.save(sugarSplashy);
|
||||
template.save(huffyFluffy);
|
||||
|
||||
awaitMessages(messageListener);
|
||||
awaitMessages(messageListener, 1);
|
||||
|
||||
List<User> messageBodies = messageListener.getMessages().stream().map(Message::getBody)
|
||||
.collect(Collectors.toList());
|
||||
@@ -277,7 +285,9 @@ public class ChangeStreamTests {
|
||||
public void resumesCorrectly() throws InterruptedException {
|
||||
|
||||
CollectingMessageListener<ChangeStreamDocument<Document>, User> messageListener1 = new CollectingMessageListener<>();
|
||||
Subscription subscription1 = container.register(new ChangeStreamRequest<>(messageListener1, () -> "user"),
|
||||
Subscription subscription1 = container.register(
|
||||
new ChangeStreamRequest<>(messageListener1,
|
||||
new ChangeStreamRequestOptions(null, "user", Duration.ofMillis(10), ChangeStreamOptions.builder().build())),
|
||||
User.class);
|
||||
|
||||
awaitSubscription(subscription1);
|
||||
@@ -292,12 +302,12 @@ public class ChangeStreamTests {
|
||||
|
||||
CollectingMessageListener<ChangeStreamDocument<Document>, User> messageListener2 = new CollectingMessageListener<>();
|
||||
ChangeStreamRequest<User> subSequentRequest = ChangeStreamRequest.builder().collection("user")
|
||||
.publishTo(messageListener2).resumeToken(resumeToken).build();
|
||||
.publishTo(messageListener2).resumeToken(resumeToken).maxAwaitTime(Duration.ofMillis(10)).build();
|
||||
|
||||
Subscription subscription2 = container.register(subSequentRequest, User.class);
|
||||
awaitSubscription(subscription2);
|
||||
|
||||
awaitMessages(messageListener2);
|
||||
awaitMessages(messageListener2, 2);
|
||||
|
||||
List<User> messageBodies = messageListener2.getMessages().stream().map(Message::getBody)
|
||||
.collect(Collectors.toList());
|
||||
@@ -309,7 +319,8 @@ public class ChangeStreamTests {
|
||||
public void readsAndConvertsMessageBodyCorrectly() throws InterruptedException {
|
||||
|
||||
CollectingMessageListener<ChangeStreamDocument<Document>, User> messageListener = new CollectingMessageListener<>();
|
||||
ChangeStreamRequest<User> request = new ChangeStreamRequest<>(messageListener, () -> "user");
|
||||
ChangeStreamRequest<User> request = new ChangeStreamRequest<>(messageListener,
|
||||
new ChangeStreamRequestOptions(null, "user", Duration.ofMillis(10), ChangeStreamOptions.builder().build()));
|
||||
|
||||
Subscription subscription = container.register(request, User.class);
|
||||
awaitSubscription(subscription);
|
||||
@@ -330,7 +341,8 @@ public class ChangeStreamTests {
|
||||
public void readsAndConvertsUpdateMessageBodyCorrectly() throws InterruptedException {
|
||||
|
||||
CollectingMessageListener<ChangeStreamDocument<Document>, User> messageListener = new CollectingMessageListener<>();
|
||||
ChangeStreamRequest<User> request = new ChangeStreamRequest<>(messageListener, () -> "user");
|
||||
ChangeStreamRequest<User> request = new ChangeStreamRequest<>(messageListener,
|
||||
new ChangeStreamRequestOptions(null, "user", Duration.ofMillis(10), ChangeStreamOptions.builder().build()));
|
||||
|
||||
Subscription subscription = container.register(request, User.class);
|
||||
awaitSubscription(subscription);
|
||||
@@ -349,7 +361,8 @@ public class ChangeStreamTests {
|
||||
public void readsOnlyDiffForUpdateWhenNotMappedToDomainType() throws InterruptedException {
|
||||
|
||||
CollectingMessageListener<ChangeStreamDocument<Document>, Document> messageListener = new CollectingMessageListener<>();
|
||||
ChangeStreamRequest<Document> request = new ChangeStreamRequest<>(messageListener, () -> "user");
|
||||
ChangeStreamRequest<Document> request = new ChangeStreamRequest<>(messageListener,
|
||||
new ChangeStreamRequestOptions(null, "user", Duration.ofMillis(10), ChangeStreamOptions.builder().build()));
|
||||
|
||||
Subscription subscription = container.register(request, Document.class);
|
||||
awaitSubscription(subscription);
|
||||
@@ -372,6 +385,7 @@ public class ChangeStreamTests {
|
||||
ChangeStreamRequest<User> request = ChangeStreamRequest.builder() //
|
||||
.collection("user") //
|
||||
.fullDocumentLookup(FullDocument.DEFAULT) //
|
||||
.maxAwaitTime(Duration.ofMillis(10)) //
|
||||
.publishTo(messageListener).build();
|
||||
|
||||
Subscription subscription = container.register(request, User.class);
|
||||
@@ -395,6 +409,7 @@ public class ChangeStreamTests {
|
||||
ChangeStreamRequest<Document> request = ChangeStreamRequest.builder() //
|
||||
.collection("user") //
|
||||
.fullDocumentLookup(FullDocument.UPDATE_LOOKUP) //
|
||||
.maxAwaitTime(Duration.ofMillis(10)) //
|
||||
.publishTo(messageListener).build();
|
||||
|
||||
Subscription subscription = container.register(request, Document.class);
|
||||
@@ -417,7 +432,9 @@ public class ChangeStreamTests {
|
||||
public void resumeAtTimestampCorrectly() throws InterruptedException {
|
||||
|
||||
CollectingMessageListener<ChangeStreamDocument<Document>, User> messageListener1 = new CollectingMessageListener<>();
|
||||
Subscription subscription1 = container.register(new ChangeStreamRequest<>(messageListener1, () -> "user"),
|
||||
Subscription subscription1 = container.register(
|
||||
new ChangeStreamRequest<>(messageListener1,
|
||||
new ChangeStreamRequestOptions(null, "user", Duration.ofMillis(10), ChangeStreamOptions.builder().build())),
|
||||
User.class);
|
||||
|
||||
awaitSubscription(subscription1);
|
||||
@@ -441,12 +458,13 @@ public class ChangeStreamTests {
|
||||
.collection("user") //
|
||||
.resumeAt(resumeAt) //
|
||||
.publishTo(messageListener2) //
|
||||
.maxAwaitTime(Duration.ofMillis(10)) //
|
||||
.build();
|
||||
|
||||
Subscription subscription2 = container.register(subSequentRequest, User.class);
|
||||
awaitSubscription(subscription2);
|
||||
|
||||
awaitMessages(messageListener2);
|
||||
awaitMessages(messageListener2, 2);
|
||||
|
||||
List<User> messageBodies = messageListener2.getMessages().stream().map(Message::getBody)
|
||||
.collect(Collectors.toList());
|
||||
@@ -461,6 +479,7 @@ public class ChangeStreamTests {
|
||||
ChangeStreamRequest<User> request = ChangeStreamRequest.builder(messageListener) //
|
||||
.collection("user") //
|
||||
.filter(newAggregation(User.class, match(where("address.street").is("flower street")))) //
|
||||
.maxAwaitTime(Duration.ofMillis(10)) //
|
||||
.build();
|
||||
|
||||
Subscription subscription = container.register(request, User.class);
|
||||
@@ -495,6 +514,7 @@ public class ChangeStreamTests {
|
||||
ChangeStreamRequest<User> request = ChangeStreamRequest.builder(messageListener) //
|
||||
.collection("user") //
|
||||
.filter(newAggregation(User.class, match(where("updateDescription.updatedFields.address").exists(true)))) //
|
||||
.maxAwaitTime(Duration.ofMillis(10)) //
|
||||
.fullDocumentLookup(FullDocument.UPDATE_LOOKUP).build();
|
||||
|
||||
Subscription subscription = container.register(request, User.class);
|
||||
|
||||
@@ -30,22 +30,21 @@ import org.bson.Document;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.MongoDatabaseFactory;
|
||||
import org.springframework.data.mongodb.core.ChangeStreamOptions;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;
|
||||
import org.springframework.data.mongodb.core.messaging.ChangeStreamRequest.ChangeStreamRequestOptions;
|
||||
import org.springframework.data.mongodb.core.messaging.SubscriptionRequest.RequestOptions;
|
||||
import org.springframework.data.mongodb.test.util.Client;
|
||||
import org.springframework.data.mongodb.test.util.EnableIfMongoServerVersion;
|
||||
import org.springframework.data.mongodb.test.util.EnableIfReplicaSetAvailable;
|
||||
import org.springframework.data.mongodb.test.util.MongoClientExtension;
|
||||
import org.springframework.data.mongodb.test.util.MongoServerCondition;
|
||||
import org.springframework.data.mongodb.test.util.MongoTemplateExtension;
|
||||
import org.springframework.data.mongodb.test.util.Template;
|
||||
import org.springframework.util.ErrorHandler;
|
||||
|
||||
import com.mongodb.client.MongoClient;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.model.CreateCollectionOptions;
|
||||
import com.mongodb.client.model.changestream.ChangeStreamDocument;
|
||||
@@ -55,36 +54,31 @@ import com.mongodb.client.model.changestream.ChangeStreamDocument;
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
@ExtendWith({ MongoClientExtension.class, MongoServerCondition.class })
|
||||
@ExtendWith({ MongoTemplateExtension.class, MongoServerCondition.class })
|
||||
public class DefaultMessageListenerContainerTests {
|
||||
|
||||
public static final String DATABASE_NAME = "change-stream-events";
|
||||
public static final String COLLECTION_NAME = "collection-1";
|
||||
public static final String COLLECTION_2_NAME = "collection-2";
|
||||
static final String DATABASE_NAME = "change-stream-events";
|
||||
static final String COLLECTION_NAME = "collection-1";
|
||||
static final String COLLECTION_2_NAME = "collection-2";
|
||||
|
||||
public static final Duration TIMEOUT = Duration.ofSeconds(2);
|
||||
static final Duration TIMEOUT = Duration.ofSeconds(2);
|
||||
|
||||
static @Client MongoClient client;
|
||||
@Template(database = DATABASE_NAME, initialEntitySet = Person.class) //
|
||||
static MongoTemplate template;
|
||||
|
||||
MongoDatabaseFactory dbFactory;
|
||||
MongoCollection<Document> collection;
|
||||
MongoCollection<Document> collection2;
|
||||
MongoDatabaseFactory dbFactory = template.getMongoDbFactory();
|
||||
|
||||
MongoCollection<Document> collection = template.getCollection(COLLECTION_NAME);
|
||||
MongoCollection<Document> collection2 = template.getCollection(COLLECTION_2_NAME);
|
||||
|
||||
private CollectingMessageListener<Object, Object> messageListener;
|
||||
private MongoTemplate template;
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
|
||||
dbFactory = new SimpleMongoClientDatabaseFactory(client, DATABASE_NAME);
|
||||
template = new MongoTemplate(dbFactory);
|
||||
|
||||
template.dropCollection(COLLECTION_NAME);
|
||||
template.dropCollection(COLLECTION_2_NAME);
|
||||
|
||||
collection = template.getCollection(COLLECTION_NAME);
|
||||
collection2 = template.getCollection(COLLECTION_2_NAME);
|
||||
|
||||
messageListener = new CollectingMessageListener<>();
|
||||
}
|
||||
|
||||
@@ -94,8 +88,7 @@ public class DefaultMessageListenerContainerTests {
|
||||
public void shouldCollectMappedChangeStreamMessagesCorrectly() throws InterruptedException {
|
||||
|
||||
MessageListenerContainer container = new DefaultMessageListenerContainer(template);
|
||||
Subscription subscription = container.register(new ChangeStreamRequest(messageListener, () -> COLLECTION_NAME),
|
||||
Person.class);
|
||||
Subscription subscription = container.register(new ChangeStreamRequest(messageListener, options()), Person.class);
|
||||
container.start();
|
||||
|
||||
awaitSubscription(subscription, TIMEOUT);
|
||||
@@ -126,7 +119,7 @@ public class DefaultMessageListenerContainerTests {
|
||||
messageListener.onMessage(message);
|
||||
}
|
||||
|
||||
}, () -> COLLECTION_NAME), Person.class, errorHandler);
|
||||
}, options()), Person.class, errorHandler);
|
||||
container.start();
|
||||
|
||||
awaitSubscription(subscription, TIMEOUT);
|
||||
@@ -145,8 +138,7 @@ public class DefaultMessageListenerContainerTests {
|
||||
public void shouldNoLongerReceiveMessagesWhenContainerStopped() throws InterruptedException {
|
||||
|
||||
MessageListenerContainer container = new DefaultMessageListenerContainer(template);
|
||||
Subscription subscription = container.register(new ChangeStreamRequest(messageListener, () -> COLLECTION_NAME),
|
||||
Document.class);
|
||||
Subscription subscription = container.register(new ChangeStreamRequest(messageListener, options()), Document.class);
|
||||
container.start();
|
||||
|
||||
awaitSubscription(subscription, TIMEOUT);
|
||||
@@ -175,8 +167,7 @@ public class DefaultMessageListenerContainerTests {
|
||||
Document unexpected = new Document("_id", "id-1").append("value", "foo");
|
||||
collection.insertOne(unexpected);
|
||||
|
||||
Subscription subscription = container.register(new ChangeStreamRequest(messageListener, () -> COLLECTION_NAME),
|
||||
Document.class);
|
||||
Subscription subscription = container.register(new ChangeStreamRequest(messageListener, options()), Document.class);
|
||||
|
||||
awaitSubscription(subscription, TIMEOUT);
|
||||
|
||||
@@ -195,8 +186,7 @@ public class DefaultMessageListenerContainerTests {
|
||||
public void shouldStartReceivingMessagesWhenContainerStarts() throws InterruptedException {
|
||||
|
||||
MessageListenerContainer container = new DefaultMessageListenerContainer(template);
|
||||
Subscription subscription = container.register(new ChangeStreamRequest(messageListener, () -> COLLECTION_NAME),
|
||||
Document.class);
|
||||
Subscription subscription = container.register(new ChangeStreamRequest(messageListener, options()), Document.class);
|
||||
|
||||
collection.insertOne(new Document("_id", "id-1").append("value", "foo"));
|
||||
|
||||
@@ -228,8 +218,8 @@ public class DefaultMessageListenerContainerTests {
|
||||
MessageListenerContainer container = new DefaultMessageListenerContainer(template);
|
||||
container.start();
|
||||
|
||||
awaitSubscription(
|
||||
container.register(new TailableCursorRequest(messageListener, () -> COLLECTION_NAME), Document.class), TIMEOUT);
|
||||
awaitSubscription(container.register(new TailableCursorRequest(messageListener, options()), Document.class),
|
||||
TIMEOUT);
|
||||
|
||||
collection.insertOne(new Document("_id", "id-2").append("value", "bar"));
|
||||
|
||||
@@ -248,8 +238,8 @@ public class DefaultMessageListenerContainerTests {
|
||||
MessageListenerContainer container = new DefaultMessageListenerContainer(template);
|
||||
container.start();
|
||||
|
||||
awaitSubscription(
|
||||
container.register(new TailableCursorRequest(messageListener, () -> COLLECTION_NAME), Document.class), TIMEOUT);
|
||||
awaitSubscription(container.register(new TailableCursorRequest(messageListener, options()), Document.class),
|
||||
TIMEOUT);
|
||||
|
||||
collection.insertOne(new Document("_id", "id-1").append("value", "foo"));
|
||||
collection.insertOne(new Document("_id", "id-2").append("value", "bar"));
|
||||
@@ -271,7 +261,7 @@ public class DefaultMessageListenerContainerTests {
|
||||
|
||||
collection.insertOne(new Document("_id", "id-1").append("value", "foo"));
|
||||
|
||||
Subscription subscription = container.register(new TailableCursorRequest(messageListener, () -> COLLECTION_NAME),
|
||||
Subscription subscription = container.register(new TailableCursorRequest(messageListener, options()),
|
||||
Document.class);
|
||||
|
||||
awaitSubscription(subscription);
|
||||
@@ -304,7 +294,7 @@ public class DefaultMessageListenerContainerTests {
|
||||
try {
|
||||
container.start();
|
||||
|
||||
Subscription subscription = container.register(new TailableCursorRequest(messageListener, () -> COLLECTION_NAME),
|
||||
Subscription subscription = container.register(new TailableCursorRequest(messageListener, options()),
|
||||
Document.class);
|
||||
|
||||
SubscriptionUtils.awaitSubscription(subscription);
|
||||
@@ -330,12 +320,12 @@ public class DefaultMessageListenerContainerTests {
|
||||
container.start();
|
||||
|
||||
CollectingMessageListener<Document, Document> tailableListener = new CollectingMessageListener<>();
|
||||
Subscription tailableSubscription = container
|
||||
.register(new TailableCursorRequest(tailableListener, () -> COLLECTION_NAME), Document.class);
|
||||
Subscription tailableSubscription = container.register(new TailableCursorRequest(tailableListener, options()),
|
||||
Document.class);
|
||||
|
||||
CollectingMessageListener<ChangeStreamDocument<Document>, Document> changeStreamListener = new CollectingMessageListener<>();
|
||||
Subscription changeStreamSubscription = container
|
||||
.register(new ChangeStreamRequest(changeStreamListener, () -> COLLECTION_NAME), Document.class);
|
||||
Subscription changeStreamSubscription = container.register(new ChangeStreamRequest(changeStreamListener, options()),
|
||||
Document.class);
|
||||
|
||||
awaitSubscriptions(tailableSubscription, changeStreamSubscription);
|
||||
|
||||
@@ -390,4 +380,9 @@ public class DefaultMessageListenerContainerTests {
|
||||
this.firstname = firstname;
|
||||
}
|
||||
}
|
||||
|
||||
static ChangeStreamRequestOptions options() {
|
||||
return new ChangeStreamRequestOptions(DATABASE_NAME, COLLECTION_NAME, Duration.ofMillis(10),
|
||||
ChangeStreamOptions.builder().build());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ public class TailableCursorTests {
|
||||
template.save(sugarSplashy);
|
||||
template.save(huffyFluffy);
|
||||
|
||||
awaitMessages(messageListener);
|
||||
awaitMessages(messageListener, 2);
|
||||
|
||||
assertThat(messageListener.getMessages().stream().map(Message::getBody)).hasSize(2).doesNotContain(sugarSplashy);
|
||||
}
|
||||
@@ -183,7 +183,7 @@ public class TailableCursorTests {
|
||||
template.save(sugarSplashy);
|
||||
template.save(huffyFluffy);
|
||||
|
||||
awaitMessages(messageListener);
|
||||
awaitMessages(messageListener, 1);
|
||||
|
||||
assertThat(messageListener.getMessages().stream().map(Message::getBody)).hasSize(1).containsExactly(sugarSplashy);
|
||||
}
|
||||
@@ -201,7 +201,7 @@ public class TailableCursorTests {
|
||||
|
||||
template.save(sugarSplashy);
|
||||
|
||||
awaitMessages(messageListener);
|
||||
awaitMessages(messageListener, 3);
|
||||
|
||||
assertThat(messageListener.getMessages().stream().map(Message::getBody)).hasSize(3).containsExactly(jellyBelly,
|
||||
huffyFluffy, sugarSplashy);
|
||||
|
||||
@@ -26,29 +26,26 @@ import lombok.EqualsAndHashCode;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.bson.types.Binary;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.MongoOperations;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.test.util.MongoTestUtils;
|
||||
import org.springframework.data.mongodb.test.util.MongoTemplateExtension;
|
||||
import org.springframework.data.mongodb.test.util.MongoTestTemplate;
|
||||
import org.springframework.data.mongodb.test.util.Template;
|
||||
import org.springframework.util.Base64Utils;
|
||||
|
||||
import com.mongodb.client.MongoClient;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link Criteria} usage as part of a {@link Query}.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @author Andreas Zink
|
||||
*/
|
||||
public class CriteriaTests {
|
||||
@ExtendWith(MongoTemplateExtension.class)
|
||||
class CriteriaTests {
|
||||
|
||||
static MongoClient client;
|
||||
MongoOperations ops;
|
||||
@Template(initialEntitySet = { DocumentWithBitmask.class }) //
|
||||
static MongoTestTemplate ops;
|
||||
|
||||
static final DocumentWithBitmask FIFTY_FOUR/*00110110*/ = new DocumentWithBitmask("1", Integer.valueOf(54),
|
||||
Integer.toBinaryString(54));
|
||||
@@ -59,22 +56,10 @@ public class CriteriaTests {
|
||||
static final DocumentWithBitmask ONE_HUNDRED_TWO/*01100110*/ = new DocumentWithBitmask("4",
|
||||
new Binary(Base64Utils.decodeFromString("Zg==")), "01100110");
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() {
|
||||
client = MongoTestUtils.client();
|
||||
}
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() {
|
||||
client.close();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
ops = new MongoTemplate(client, "criteria-tests");
|
||||
|
||||
ops.dropCollection(DocumentWithBitmask.class);
|
||||
ops.flush();
|
||||
|
||||
ops.insert(FIFTY_FOUR);
|
||||
ops.insert(TWENTY_INT);
|
||||
|
||||
@@ -23,26 +23,27 @@ import lombok.ToString;
|
||||
import java.util.List;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.mongodb.config.AbstractIntegrationTests;
|
||||
import org.springframework.data.mongodb.core.MongoOperations;
|
||||
import org.springframework.data.mongodb.core.index.IndexDefinition;
|
||||
import org.springframework.data.mongodb.core.index.IndexOperations;
|
||||
import org.springframework.data.mongodb.core.mapping.Field;
|
||||
import org.springframework.data.mongodb.core.mapping.Language;
|
||||
import org.springframework.data.mongodb.core.mapping.TextScore;
|
||||
import org.springframework.data.mongodb.core.query.TextQueryTests.FullTextDoc.FullTextDocBuilder;
|
||||
import org.springframework.data.mongodb.test.util.MongoTemplateExtension;
|
||||
import org.springframework.data.mongodb.test.util.MongoTestTemplate;
|
||||
import org.springframework.data.mongodb.test.util.Template;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class TextQueryTests extends AbstractIntegrationTests {
|
||||
@ExtendWith(MongoTemplateExtension.class)
|
||||
public class TextQueryTests {
|
||||
|
||||
private static final FullTextDoc BAKE = new FullTextDocBuilder().headline("bake").build();
|
||||
private static final FullTextDoc COFFEE = new FullTextDocBuilder().subHeadline("coffee").build();
|
||||
@@ -53,11 +54,14 @@ public class TextQueryTests extends AbstractIntegrationTests {
|
||||
private static final FullTextDoc FRENCH_MILK = new FullTextDocBuilder().headline("leche").lanugage("french").build();
|
||||
private static final FullTextDoc MILK_AND_SUGAR = new FullTextDocBuilder().headline("milk and sugar").build();
|
||||
|
||||
private @Autowired MongoOperations template;
|
||||
@Template(initialEntitySet = FullTextDoc.class) //
|
||||
static MongoTestTemplate template;
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
|
||||
template.flush();
|
||||
|
||||
IndexOperations indexOps = template.indexOps(FullTextDoc.class);
|
||||
indexOps.dropAllIndexes();
|
||||
|
||||
|
||||
@@ -69,6 +69,8 @@ public class MongoJsonSchemaTests {
|
||||
protected String getDatabaseName() {
|
||||
return "json-schema-tests";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Autowired MongoTemplate template;
|
||||
|
||||
@@ -21,7 +21,9 @@ import lombok.Data;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -65,6 +67,11 @@ public class ReactiveMongoJsonSchemaTests {
|
||||
protected String getDatabaseName() {
|
||||
return "json-schema-tests";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Class<?>> getInitialEntitySet() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired ReactiveMongoTemplate template;
|
||||
|
||||
@@ -19,12 +19,10 @@ import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.data.mongodb.test.util.Client;
|
||||
import org.springframework.data.mongodb.test.util.MongoClientExtension;
|
||||
|
||||
import com.mongodb.client.MongoClient;
|
||||
|
||||
@@ -35,11 +33,10 @@ import com.mongodb.client.MongoClient;
|
||||
* @author Thomas Darimont
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration("classpath:infrastructure.xml")
|
||||
@ExtendWith(MongoClientExtension.class)
|
||||
public class MongoMonitorIntegrationTests {
|
||||
|
||||
@Autowired MongoClient mongoClient;
|
||||
static @Client MongoClient mongoClient;
|
||||
|
||||
@Test
|
||||
public void serverInfo() {
|
||||
|
||||
@@ -21,12 +21,15 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.FilterType;
|
||||
import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
|
||||
@@ -47,7 +50,7 @@ public class ComplexIdRepositoryIntegrationTests {
|
||||
static @Client MongoClient mongoClient;
|
||||
|
||||
@Configuration
|
||||
@EnableMongoRepositories
|
||||
@EnableMongoRepositories(includeFilters=@Filter(type = FilterType.ASSIGNABLE_TYPE, classes = UserWithComplexIdRepository.class))
|
||||
static class Config extends AbstractMongoClientConfiguration {
|
||||
|
||||
@Override
|
||||
@@ -60,6 +63,10 @@ public class ComplexIdRepositoryIntegrationTests {
|
||||
return mongoClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Class<?>> getInitialEntitySet() throws ClassNotFoundException {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired UserWithComplexIdRepository repo;
|
||||
|
||||
@@ -20,35 +20,26 @@ import static org.assertj.core.api.Assertions.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.index.TextIndexDefinition.TextIndexDefinitionBuilder;
|
||||
import org.springframework.data.mongodb.core.index.TextIndexed;
|
||||
import org.springframework.data.mongodb.core.mapping.TextScore;
|
||||
import org.springframework.data.mongodb.core.query.TextCriteria;
|
||||
import org.springframework.data.mongodb.repository.support.MongoRepositoryFactory;
|
||||
import org.springframework.data.mongodb.test.util.MongoTestUtils;
|
||||
import org.springframework.data.mongodb.test.util.MongoVersionRule;
|
||||
import org.springframework.data.util.Version;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.data.mongodb.test.util.MongoTemplateExtension;
|
||||
import org.springframework.data.mongodb.test.util.MongoTestTemplate;
|
||||
import org.springframework.data.mongodb.test.util.Template;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import com.mongodb.client.MongoClient;
|
||||
|
||||
/**
|
||||
* Integration tests for text searches on repository.
|
||||
*
|
||||
@@ -56,12 +47,9 @@ import com.mongodb.client.MongoClient;
|
||||
* @author Oliver Gierke
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration
|
||||
@ExtendWith(MongoTemplateExtension.class)
|
||||
public class MongoRepositoryTextSearchIntegrationTests {
|
||||
|
||||
public static @ClassRule MongoVersionRule versionRule = MongoVersionRule.atLeast(new Version(2, 6, 0));
|
||||
|
||||
private static final FullTextDocument PASSENGER_57 = new FullTextDocument("1", "Passenger 57",
|
||||
"Passenger 57 is an action film that stars Wesley Snipes and Bruce Payne.");
|
||||
private static final FullTextDocument DEMOLITION_MAN = new FullTextDocument("2", "Demolition Man",
|
||||
@@ -69,20 +57,21 @@ public class MongoRepositoryTextSearchIntegrationTests {
|
||||
private static final FullTextDocument DROP_ZONE = new FullTextDocument("3", "Drop Zone",
|
||||
"Drop Zone is an action film featuring Wesley Snipes and Gary Busey.");
|
||||
|
||||
@Autowired MongoTemplate template;
|
||||
FullTextRepository repo;
|
||||
@Template(initialEntitySet = FullTextDocument.class) //
|
||||
static MongoTestTemplate template;
|
||||
|
||||
@Before
|
||||
FullTextRepository repo = new MongoRepositoryFactory(this.template).getRepository(FullTextRepository.class);
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
|
||||
template.indexOps(FullTextDocument.class)
|
||||
.ensureIndex(new TextIndexDefinitionBuilder().onField("title").onField("content").build());
|
||||
this.repo = new MongoRepositoryFactory(this.template).getRepository(FullTextRepository.class);
|
||||
}
|
||||
|
||||
@After
|
||||
@AfterEach
|
||||
public void tearDown() {
|
||||
template.dropCollection(FullTextDocument.class);
|
||||
template.flush();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-973
|
||||
@@ -193,21 +182,6 @@ public class MongoRepositoryTextSearchIntegrationTests {
|
||||
repo.saveAll(Arrays.asList(PASSENGER_57, DEMOLITION_MAN, DROP_ZONE));
|
||||
}
|
||||
|
||||
@org.springframework.context.annotation.Configuration
|
||||
public static class Configuration extends AbstractMongoClientConfiguration {
|
||||
|
||||
@Override
|
||||
protected String getDatabaseName() {
|
||||
return ClassUtils.getShortNameAsProperty(MongoRepositoryTextSearchIntegrationTests.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MongoClient mongoClient() {
|
||||
return MongoTestUtils.client();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class FullTextDocument {
|
||||
|
||||
private @Id String id;
|
||||
|
||||
@@ -19,7 +19,9 @@ import static org.assertj.core.api.Assertions.*;
|
||||
import static org.springframework.data.mongodb.test.util.MongoTestUtils.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import org.bson.Document;
|
||||
@@ -29,7 +31,9 @@ import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.FilterType;
|
||||
import org.springframework.data.domain.Persistable;
|
||||
import org.springframework.data.mongodb.MongoDatabaseFactory;
|
||||
import org.springframework.data.mongodb.MongoTransactionManager;
|
||||
@@ -68,7 +72,7 @@ public class PersonRepositoryTransactionalTests {
|
||||
static @ReplSetClient MongoClient mongoClient;
|
||||
|
||||
@Configuration
|
||||
@EnableMongoRepositories
|
||||
@EnableMongoRepositories(includeFilters=@Filter(type = FilterType.ASSIGNABLE_TYPE, classes = PersonRepository.class))
|
||||
static class Config extends AbstractMongoClientConfiguration {
|
||||
|
||||
@Bean
|
||||
@@ -85,6 +89,11 @@ public class PersonRepositoryTransactionalTests {
|
||||
MongoTransactionManager txManager(MongoDatabaseFactory dbFactory) {
|
||||
return new MongoTransactionManager(dbFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Class<?>> getInitialEntitySet() throws ClassNotFoundException {
|
||||
return Collections.singleton(Person.class);
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired MongoClient client;
|
||||
|
||||
@@ -20,7 +20,9 @@ import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.FilterType;
|
||||
import org.springframework.data.mongodb.core.MongoOperations;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;
|
||||
@@ -39,7 +41,7 @@ import org.springframework.test.context.junit4.SpringRunner;
|
||||
public class MongoRepositoriesRegistrarIntegrationTests {
|
||||
|
||||
@Configuration
|
||||
@EnableMongoRepositories(basePackages = "org.springframework.data.mongodb.repository")
|
||||
@EnableMongoRepositories(basePackages = "org.springframework.data.mongodb.repository", includeFilters=@Filter(type = FilterType.ASSIGNABLE_TYPE, classes = PersonRepository.class))
|
||||
static class Config {
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -20,7 +20,9 @@ import static org.assertj.core.api.Assertions.*;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.FilterType;
|
||||
import org.springframework.context.annotation.ImportResource;
|
||||
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
@@ -36,7 +38,7 @@ import org.springframework.test.context.junit4.SpringRunner;
|
||||
public class ComposedRepositoryImplementationTests {
|
||||
|
||||
@Configuration
|
||||
@EnableMongoRepositories
|
||||
@EnableMongoRepositories(includeFilters=@Filter(type = FilterType.ASSIGNABLE_TYPE, classes = ComposedRepository.class))
|
||||
@ImportResource("classpath:infrastructure.xml")
|
||||
static class Config {}
|
||||
|
||||
|
||||
@@ -23,7 +23,9 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.FilterType;
|
||||
import org.springframework.context.annotation.ImportResource;
|
||||
import org.springframework.data.mongodb.repository.User;
|
||||
import org.springframework.data.mongodb.repository.config.EnableReactiveMongoRepositories;
|
||||
@@ -40,7 +42,7 @@ import org.springframework.test.context.junit4.SpringRunner;
|
||||
public class CustomReactiveRepositoryImplementationTests {
|
||||
|
||||
@Configuration
|
||||
@EnableReactiveMongoRepositories
|
||||
@EnableReactiveMongoRepositories(includeFilters=@Filter(type = FilterType.ASSIGNABLE_TYPE, classes = CustomReactiveMongoRepository.class))
|
||||
@ImportResource("classpath:reactive-infrastructure.xml")
|
||||
static class Config {}
|
||||
|
||||
|
||||
@@ -23,7 +23,9 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.FilterType;
|
||||
import org.springframework.context.annotation.ImportResource;
|
||||
import org.springframework.data.mongodb.repository.User;
|
||||
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
|
||||
@@ -40,7 +42,7 @@ import org.springframework.test.context.junit4.SpringRunner;
|
||||
public class CustomRepositoryImplementationTests {
|
||||
|
||||
@Configuration
|
||||
@EnableMongoRepositories
|
||||
@EnableMongoRepositories(includeFilters=@Filter(type = FilterType.ASSIGNABLE_TYPE, classes = CustomMongoRepository.class))
|
||||
@ImportResource("classpath:infrastructure.xml")
|
||||
static class Config {}
|
||||
|
||||
|
||||
@@ -20,7 +20,9 @@ import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
@@ -84,6 +86,11 @@ public class ReactiveQuerydslMongoPredicateExecutorTests {
|
||||
protected String getDatabaseName() {
|
||||
return "reactive";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Class<?>> getInitialEntitySet() {
|
||||
return Collections.singleton(Person.class);
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
package org.springframework.data.mongodb.repository.support;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.assertj.core.api.Assumptions.*;
|
||||
import static org.springframework.data.domain.ExampleMatcher.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -28,18 +27,15 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.data.domain.Example;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.ExampleMatcher.*;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.mongodb.MongoTransactionManager;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
import org.springframework.data.mongodb.core.query.Collation;
|
||||
@@ -48,11 +44,12 @@ import org.springframework.data.mongodb.repository.Person;
|
||||
import org.springframework.data.mongodb.repository.Person.Sex;
|
||||
import org.springframework.data.mongodb.repository.User;
|
||||
import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
|
||||
import org.springframework.data.mongodb.test.util.MongoVersion;
|
||||
import org.springframework.data.mongodb.test.util.MongoVersionRule;
|
||||
import org.springframework.data.mongodb.test.util.ReplicaSet;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.data.mongodb.test.util.EnableIfMongoServerVersion;
|
||||
import org.springframework.data.mongodb.test.util.EnableIfReplicaSetAvailable;
|
||||
import org.springframework.data.mongodb.test.util.MongoServerCondition;
|
||||
import org.springframework.data.mongodb.test.util.MongoTemplateExtension;
|
||||
import org.springframework.data.mongodb.test.util.MongoTestTemplate;
|
||||
import org.springframework.data.mongodb.test.util.Template;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
@@ -62,22 +59,22 @@ import org.springframework.transaction.support.TransactionTemplate;
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration("classpath:infrastructure.xml")
|
||||
@ExtendWith({ MongoTemplateExtension.class, MongoServerCondition.class })
|
||||
public class SimpleMongoRepositoryTests {
|
||||
|
||||
@Autowired private MongoTemplate template;
|
||||
public @Rule MongoVersionRule mongoVersion = MongoVersionRule.any();
|
||||
@Template(initialEntitySet = Person.class) //
|
||||
static MongoTestTemplate template;
|
||||
|
||||
private Person oliver, dave, carter, boyd, stefan, leroi, alicia;
|
||||
private List<Person> all;
|
||||
|
||||
private MongoEntityInformation<Person, String> personEntityInformation = new CustomizedPersonInformation();
|
||||
private SimpleMongoRepository<Person, String> repository;
|
||||
private SimpleMongoRepository<Person, String> repository = new SimpleMongoRepository<>(personEntityInformation,
|
||||
template);
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
repository = new SimpleMongoRepository<Person, String>(personEntityInformation, template);
|
||||
|
||||
repository.deleteAll();
|
||||
|
||||
oliver = new Person("Oliver August", "Matthews", 4);
|
||||
@@ -393,11 +390,10 @@ public class SimpleMongoRepositoryTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2130
|
||||
@MongoVersion(asOf = "4.0")
|
||||
@EnableIfReplicaSetAvailable
|
||||
@EnableIfMongoServerVersion(isGreaterThanEqual = "4.0")
|
||||
public void countShouldBePossibleInTransaction() {
|
||||
|
||||
assumeThat(ReplicaSet.required().runsAsReplicaSet()).isTrue();
|
||||
|
||||
MongoTransactionManager txmgr = new MongoTransactionManager(template.getMongoDbFactory());
|
||||
TransactionTemplate tt = new TransactionTemplate(txmgr);
|
||||
tt.afterPropertiesSet();
|
||||
@@ -418,11 +414,10 @@ public class SimpleMongoRepositoryTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2130
|
||||
@MongoVersion(asOf = "4.0")
|
||||
@EnableIfReplicaSetAvailable
|
||||
@EnableIfMongoServerVersion(isGreaterThanEqual = "4.0")
|
||||
public void existsShouldBePossibleInTransaction() {
|
||||
|
||||
assumeThat(ReplicaSet.required().runsAsReplicaSet()).isTrue();
|
||||
|
||||
MongoTransactionManager txmgr = new MongoTransactionManager(template.getMongoDbFactory());
|
||||
TransactionTemplate tt = new TransactionTemplate(txmgr);
|
||||
tt.afterPropertiesSet();
|
||||
|
||||
@@ -20,6 +20,11 @@ import static org.assertj.core.api.Assumptions.*;
|
||||
import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
import static org.springframework.data.mongodb.core.query.Query.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
@@ -64,6 +69,11 @@ public class SimpleMongoRepositoryVersionedEntityTests {
|
||||
protected String getDatabaseName() {
|
||||
return "database";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Class<?>> getInitialEntitySet() throws ClassNotFoundException {
|
||||
return new HashSet<>(Arrays.asList(VersionedPerson.class));
|
||||
}
|
||||
}
|
||||
|
||||
@Rule public MongoVersionRule mongoVersion = MongoVersionRule.any();
|
||||
|
||||
@@ -18,6 +18,9 @@ package org.springframework.data.mongodb.repository.support;
|
||||
import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
import static org.springframework.data.mongodb.core.query.Query.*;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -57,6 +60,11 @@ public class SimpleReactiveMongoRepositoryVersionedEntityTests {
|
||||
protected String getDatabaseName() {
|
||||
return "database";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Class<?>> getInitialEntitySet() {
|
||||
return Collections.singleton(VersionedPerson.class);
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired //
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.springframework.data.mongodb.test.util;
|
||||
import static org.junit.platform.commons.util.AnnotationUtils.*;
|
||||
import static org.junit.platform.commons.util.ReflectionUtils.*;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@@ -36,7 +35,6 @@ import org.junit.platform.commons.util.ExceptionUtils;
|
||||
import org.junit.platform.commons.util.ReflectionUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import com.mongodb.client.MongoClient;
|
||||
@@ -52,14 +50,17 @@ public class MongoClientExtension implements Extension, BeforeAllCallback, After
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(MongoClientExtension.class);
|
||||
|
||||
private static final Namespace NAMESPACE = Namespace.create(MongoClientExtension.class);
|
||||
private static final String SYNC_KEY = "mongo.client.sync";
|
||||
private static final String REACTIVE_KEY = "mongo.client.reactive";
|
||||
private static final String SYNC_REPLSET_KEY = "mongo.client.replset.sync";
|
||||
private static final String REACTIVE_REPLSET_KEY = "mongo.client.replset.reactive";
|
||||
private static final Namespace NAMESPACE = MongoExtensions.Client.NAMESPACE;
|
||||
|
||||
private static final String SYNC_KEY = MongoExtensions.Client.SYNC_KEY;
|
||||
private static final String REACTIVE_KEY = MongoExtensions.Client.REACTIVE_KEY;
|
||||
private static final String SYNC_REPLSET_KEY = MongoExtensions.Client.SYNC_REPLSET_KEY;
|
||||
private static final String REACTIVE_REPLSET_KEY = MongoExtensions.Client.REACTIVE_REPLSET_KEY;
|
||||
|
||||
@Override
|
||||
public void afterAll(ExtensionContext extensionContext) throws Exception {}
|
||||
public void afterAll(ExtensionContext extensionContext) throws Exception {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeAll(ExtensionContext context) throws Exception {
|
||||
@@ -87,7 +88,7 @@ public class MongoClientExtension implements Extension, BeforeAllCallback, After
|
||||
});
|
||||
}
|
||||
|
||||
private Object getMongoClient(Class<?> type, ExtensionContext extensionContext, boolean replSet) {
|
||||
protected Object getMongoClient(Class<?> type, ExtensionContext extensionContext, boolean replSet) {
|
||||
|
||||
Store store = extensionContext.getStore(NAMESPACE);
|
||||
|
||||
@@ -120,6 +121,12 @@ public class MongoClientExtension implements Extension, BeforeAllCallback, After
|
||||
return new SyncClientHolder(replSet ? MongoTestUtils.replSetClient() : MongoTestUtils.client());
|
||||
}
|
||||
|
||||
protected boolean holdsReplSetClient(ExtensionContext context) {
|
||||
|
||||
Store store = context.getStore(NAMESPACE);
|
||||
return store.get(SYNC_REPLSET_KEY) != null || store.get(REACTIVE_REPLSET_KEY) != null;
|
||||
}
|
||||
|
||||
private void assertValidFieldCandidate(Field field) {
|
||||
|
||||
assertSupportedType("field", field.getType());
|
||||
@@ -137,14 +144,6 @@ public class MongoClientExtension implements Extension, BeforeAllCallback, After
|
||||
}
|
||||
}
|
||||
|
||||
private void closeClient(Store store, String key) {
|
||||
|
||||
Closeable client = store.remove(key, Closeable.class);
|
||||
if (client != null) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
|
||||
throws ParameterResolutionException {
|
||||
@@ -164,7 +163,7 @@ public class MongoClientExtension implements Extension, BeforeAllCallback, After
|
||||
|
||||
final MongoClient client;
|
||||
|
||||
public SyncClientHolder(MongoClient client) {
|
||||
SyncClientHolder(MongoClient client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
@@ -182,7 +181,7 @@ public class MongoClientExtension implements Extension, BeforeAllCallback, After
|
||||
|
||||
final com.mongodb.reactivestreams.client.MongoClient client;
|
||||
|
||||
public ReactiveClientHolder(com.mongodb.reactivestreams.client.MongoClient client) {
|
||||
ReactiveClientHolder(com.mongodb.reactivestreams.client.MongoClient client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2020 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.data.mongodb.test.util;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtensionContext.Namespace;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
class MongoExtensions {
|
||||
|
||||
static class Client {
|
||||
|
||||
static final Namespace NAMESPACE = Namespace.create(MongoClientExtension.class);
|
||||
static final String SYNC_KEY = "mongo.client.sync";
|
||||
static final String REACTIVE_KEY = "mongo.client.reactive";
|
||||
static final String SYNC_REPLSET_KEY = "mongo.client.replset.sync";
|
||||
static final String REACTIVE_REPLSET_KEY = "mongo.client.replset.reactive";
|
||||
}
|
||||
|
||||
static class Termplate {
|
||||
|
||||
static final Namespace NAMESPACE = Namespace.create(MongoTemplateExtension.class);
|
||||
static final String SYNC = "mongo.template.sync";
|
||||
static final String REACTIVE = "mongo.template.reactive";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright 2020 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.data.mongodb.test.util;
|
||||
|
||||
import static org.junit.platform.commons.util.AnnotationUtils.*;
|
||||
import static org.junit.platform.commons.util.ReflectionUtils.*;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtensionConfigurationException;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext.Store;
|
||||
import org.junit.jupiter.api.extension.ParameterContext;
|
||||
import org.junit.jupiter.api.extension.ParameterResolutionException;
|
||||
import org.junit.platform.commons.util.ExceptionUtils;
|
||||
import org.junit.platform.commons.util.ReflectionUtils;
|
||||
import org.junit.platform.commons.util.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.mapping.model.CamelCaseSplittingFieldNamingStrategy;
|
||||
import org.springframework.data.mongodb.test.util.MongoExtensions.Termplate;
|
||||
import org.springframework.data.util.ParsingUtils;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public class MongoTemplateExtension extends MongoClientExtension {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(MongoTemplateExtension.class);
|
||||
CamelCaseSplittingFieldNamingStrategy splitter = new CamelCaseSplittingFieldNamingStrategy("-");
|
||||
|
||||
@Override
|
||||
public void afterAll(ExtensionContext context) throws Exception {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeAll(ExtensionContext context) throws Exception {
|
||||
super.beforeAll(context);
|
||||
|
||||
injectFields(context, null, ReflectionUtils::isStatic);
|
||||
}
|
||||
|
||||
private void injectFields(ExtensionContext context, Object testInstance, Predicate<Field> predicate) {
|
||||
|
||||
findAnnotatedFields(context.getRequiredTestClass(), Template.class, predicate).forEach(field -> {
|
||||
assertValidFieldCandidate(field);
|
||||
try {
|
||||
|
||||
makeAccessible(field).set(testInstance,
|
||||
getMongoTemplate(field.getType(), field.getAnnotation(Template.class), context));
|
||||
} catch (Throwable t) {
|
||||
ExceptionUtils.throwAsUncheckedException(t);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void assertValidFieldCandidate(Field field) {
|
||||
|
||||
assertSupportedType("field", field.getType());
|
||||
if (isPrivate(field)) {
|
||||
throw new ExtensionConfigurationException("@MongoClient field [" + field + "] must not be private.");
|
||||
}
|
||||
}
|
||||
|
||||
private void assertSupportedType(String target, Class<?> type) {
|
||||
|
||||
if (!ClassUtils.isAssignable(org.springframework.data.mongodb.core.MongoOperations.class, type)
|
||||
&& !ClassUtils.isAssignable(org.springframework.data.mongodb.core.ReactiveMongoOperations.class, type)) {
|
||||
throw new ExtensionConfigurationException("Can only resolve @MongoClient " + target + " of type "
|
||||
+ org.springframework.data.mongodb.core.MongoOperations.class.getName() + " or "
|
||||
+ org.springframework.data.mongodb.core.ReactiveMongoOperations.class.getName() + " but was: "
|
||||
+ type.getName());
|
||||
}
|
||||
}
|
||||
|
||||
private Object getMongoTemplate(Class<?> type, Template options, ExtensionContext extensionContext) {
|
||||
|
||||
Store templateStore = extensionContext.getStore(MongoExtensions.Termplate.NAMESPACE);
|
||||
|
||||
boolean replSetClient = holdsReplSetClient(extensionContext) || options.replicaSet();
|
||||
|
||||
String dbName = StringUtils.isNotBlank(options.database()) ? options.database()
|
||||
: extensionContext.getTestClass().map(it -> {
|
||||
List<String> target = ParsingUtils.splitCamelCaseToLower(it.getSimpleName());
|
||||
return org.springframework.util.StringUtils.collectionToDelimitedString(target, "-");
|
||||
}).orElse("database");
|
||||
|
||||
if (ClassUtils.isAssignable(org.springframework.data.mongodb.core.MongoOperations.class, type)) {
|
||||
|
||||
String key = Termplate.SYNC + "-" + dbName;
|
||||
return templateStore.getOrComputeIfAbsent(key, it -> {
|
||||
|
||||
com.mongodb.client.MongoClient client = (com.mongodb.client.MongoClient) getMongoClient(
|
||||
com.mongodb.client.MongoClient.class, extensionContext, replSetClient);
|
||||
return new MongoTestTemplate(client, dbName, options.initialEntitySet());
|
||||
});
|
||||
}
|
||||
|
||||
if (ClassUtils.isAssignable(org.springframework.data.mongodb.core.ReactiveMongoOperations.class, type)) {
|
||||
|
||||
String key = Termplate.REACTIVE + "-" + dbName;
|
||||
return templateStore.getOrComputeIfAbsent(key, it -> {
|
||||
|
||||
com.mongodb.reactivestreams.client.MongoClient client = (com.mongodb.reactivestreams.client.MongoClient) getMongoClient(
|
||||
com.mongodb.reactivestreams.client.MongoClient.class, extensionContext, replSetClient);
|
||||
return new ReactiveMongoTestTemplate(client, dbName, options.initialEntitySet());
|
||||
});
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Damn - something went wrong.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
|
||||
throws ParameterResolutionException {
|
||||
return super.supportsParameter(parameterContext, extensionContext) || parameterContext.isAnnotated(Template.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
|
||||
throws ParameterResolutionException {
|
||||
|
||||
if (parameterContext.getParameter().getAnnotation(Template.class) == null) {
|
||||
return super.resolveParameter(parameterContext, extensionContext);
|
||||
}
|
||||
Class<?> parameterType = parameterContext.getParameter().getType();
|
||||
return getMongoTemplate(parameterType, parameterContext.getParameter().getAnnotation(Template.class),
|
||||
extensionContext);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright 2020 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.data.mongodb.test.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.data.mapping.context.PersistentEntities;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
|
||||
import com.mongodb.MongoWriteException;
|
||||
import com.mongodb.client.MongoClient;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
|
||||
/**
|
||||
* A {@link MongoTemplate} with configuration hooks and extension suitable for tests.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @since 3.0
|
||||
*/
|
||||
public class MongoTestTemplate extends MongoTemplate {
|
||||
|
||||
private final MongoTestTemplateConfiguration cfg;
|
||||
|
||||
public MongoTestTemplate(MongoClient client, String database, Class<?>... initialEntities) {
|
||||
this(cfg -> {
|
||||
cfg.configureDatabaseFactory(it -> {
|
||||
|
||||
it.client(client);
|
||||
it.defaultDb(database);
|
||||
});
|
||||
|
||||
cfg.configureMappingContext(it -> {
|
||||
|
||||
it.autocreateIndex(false);
|
||||
it.intitalEntitySet(initialEntities);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public MongoTestTemplate(Consumer<MongoTestTemplateConfiguration> cfg) {
|
||||
|
||||
this(new Supplier<MongoTestTemplateConfiguration>() {
|
||||
@Override
|
||||
public MongoTestTemplateConfiguration get() {
|
||||
|
||||
MongoTestTemplateConfiguration config = new MongoTestTemplateConfiguration();
|
||||
cfg.accept(config);
|
||||
return config;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public MongoTestTemplate(Supplier<MongoTestTemplateConfiguration> config) {
|
||||
this(config.get());
|
||||
}
|
||||
|
||||
public MongoTestTemplate(MongoTestTemplateConfiguration config) {
|
||||
super(config.databaseFactory(), config.mongoConverter());
|
||||
|
||||
ApplicationContext applicationContext = config.getApplicationContext();
|
||||
if (applicationContext != null) {
|
||||
setApplicationContext(applicationContext);
|
||||
}
|
||||
|
||||
this.cfg = config;
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
flush(PersistentEntities.of(getConverter().getMappingContext()).stream().map(it -> getCollectionName(it.getType()))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public void flushDatabase() {
|
||||
flush(getDb().listCollectionNames());
|
||||
}
|
||||
|
||||
public void flush(Iterable<String> collections) {
|
||||
|
||||
for (String collection : collections) {
|
||||
MongoCollection<Document> mongoCollection = getCollection(collection);
|
||||
try {
|
||||
mongoCollection.deleteMany(new Document());
|
||||
} catch (MongoWriteException e) {
|
||||
mongoCollection.drop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void flush(Class<?>... entities) {
|
||||
flush(Arrays.asList(entities).stream().map(this::getCollectionName).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public void flush(String... collections) {
|
||||
flush(Arrays.asList(collections));
|
||||
}
|
||||
|
||||
public void flush(Object... objects) {
|
||||
|
||||
flush(Arrays.asList(objects).stream().map(it -> {
|
||||
|
||||
if (it instanceof String) {
|
||||
return (String) it;
|
||||
}
|
||||
if (it instanceof Class) {
|
||||
return getCollectionName((Class<?>) it);
|
||||
}
|
||||
return it.toString();
|
||||
}).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public void dropDatabase() {
|
||||
getDb().drop();
|
||||
}
|
||||
|
||||
public void dropIndexes(String... collections) {
|
||||
for (String collection : collections) {
|
||||
getCollection(collection).dropIndexes();
|
||||
}
|
||||
}
|
||||
|
||||
public void dropIndexes(Class<?>... entities) {
|
||||
for (Class<?> entity : entities) {
|
||||
getCollection(getCollectionName(entity)).dropIndexes();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,285 @@
|
||||
/*
|
||||
* Copyright 2020 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.data.mongodb.test.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.auditing.IsNewAwareAuditingHandler;
|
||||
import org.springframework.data.convert.CustomConversions;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mongodb.MongoDatabaseFactory;
|
||||
import org.springframework.data.mongodb.ReactiveMongoDatabaseFactory;
|
||||
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;
|
||||
import org.springframework.data.mongodb.core.SimpleReactiveMongoDatabaseFactory;
|
||||
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
|
||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.core.mapping.event.AuditingEventListener;
|
||||
import org.springframework.data.mongodb.core.mapping.event.MongoMappingEvent;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @since 3.0
|
||||
*/
|
||||
public class MongoTestTemplateConfiguration {
|
||||
|
||||
private final DatabaseFactoryConfigurer dbFactoryConfig = new DatabaseFactoryConfigurer();
|
||||
private final MappingContextConfigurer mappingContextConfigurer = new MappingContextConfigurer();
|
||||
private final MongoConverterConfigurer mongoConverterConfigurer = new MongoConverterConfigurer();
|
||||
private final AuditingConfigurer auditingConfigurer = new AuditingConfigurer();
|
||||
private final ApplicationContextConfigurer applicationContextConfigurer = new ApplicationContextConfigurer();
|
||||
|
||||
private MongoMappingContext mappingContext;
|
||||
private MappingMongoConverter converter;
|
||||
private ApplicationContext context;
|
||||
|
||||
private com.mongodb.client.MongoClient syncClient;
|
||||
private com.mongodb.reactivestreams.client.MongoClient reactiveClient;
|
||||
private MongoDatabaseFactory syncFactory;
|
||||
private SimpleReactiveMongoDatabaseFactory reactiveFactory;
|
||||
|
||||
MongoConverter mongoConverter() {
|
||||
|
||||
if (converter == null) {
|
||||
|
||||
converter = new MappingMongoConverter(new DefaultDbRefResolver(databaseFactory()), mappingContext());
|
||||
|
||||
if (mongoConverterConfigurer.customConversions != null) {
|
||||
converter.setCustomConversions(mongoConverterConfigurer.customConversions);
|
||||
}
|
||||
converter.afterPropertiesSet();
|
||||
}
|
||||
|
||||
return converter;
|
||||
}
|
||||
|
||||
List<ApplicationListener<?>> getApplicationEventListener() {
|
||||
|
||||
ArrayList<ApplicationListener<?>> listeners = new ArrayList<>(applicationContextConfigurer.listeners);
|
||||
if (auditingConfigurer.hasAuditingHandler()) {
|
||||
listeners.add(new AuditingEventListener(() -> auditingConfigurer.auditingHandlers(mappingContext())));
|
||||
}
|
||||
return listeners;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
ApplicationContext getApplicationContext() {
|
||||
|
||||
if (applicationContextConfigurer.applicationContext == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (context != null) {
|
||||
return context;
|
||||
}
|
||||
|
||||
context = applicationContextConfigurer.applicationContext;
|
||||
|
||||
if (context instanceof ConfigurableApplicationContext) {
|
||||
|
||||
ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) this.context;
|
||||
getApplicationEventListener().forEach(configurableApplicationContext::addApplicationListener);
|
||||
|
||||
configurableApplicationContext.refresh();
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
MongoMappingContext mappingContext() {
|
||||
|
||||
if (mappingContext == null) {
|
||||
|
||||
mappingContext = new MongoMappingContext();
|
||||
mappingContext.setInitialEntitySet(mappingContextConfigurer.initialEntitySet());
|
||||
mappingContext.setAutoIndexCreation(mappingContextConfigurer.autocreateIndex);
|
||||
mappingContext.afterPropertiesSet();
|
||||
}
|
||||
|
||||
return mappingContext;
|
||||
}
|
||||
|
||||
MongoDatabaseFactory databaseFactory() {
|
||||
|
||||
if (syncFactory == null) {
|
||||
syncFactory = new SimpleMongoClientDatabaseFactory(syncClient(), defaultDatabase());
|
||||
}
|
||||
|
||||
return syncFactory;
|
||||
}
|
||||
|
||||
ReactiveMongoDatabaseFactory reactiveDatabaseFactory() {
|
||||
|
||||
if (reactiveFactory == null) {
|
||||
reactiveFactory = new SimpleReactiveMongoDatabaseFactory(reactiveClient(), defaultDatabase());
|
||||
}
|
||||
|
||||
return reactiveFactory;
|
||||
}
|
||||
|
||||
public MongoTestTemplateConfiguration configureDatabaseFactory(Consumer<DatabaseFactoryConfigurer> dbFactory) {
|
||||
|
||||
dbFactory.accept(dbFactoryConfig);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MongoTestTemplateConfiguration configureMappingContext(
|
||||
Consumer<MappingContextConfigurer> mappingContextConfigurerConsumer) {
|
||||
mappingContextConfigurerConsumer.accept(mappingContextConfigurer);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MongoTestTemplateConfiguration configureApplicationContext(
|
||||
Consumer<ApplicationContextConfigurer> applicationContextConfigurerConsumer) {
|
||||
|
||||
applicationContextConfigurerConsumer.accept(applicationContextConfigurer);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MongoTestTemplateConfiguration configureAuditing(Consumer<AuditingConfigurer> auditingConfigurerConsumer) {
|
||||
|
||||
auditingConfigurerConsumer.accept(auditingConfigurer);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MongoTestTemplateConfiguration configureConversion(
|
||||
Consumer<MongoConverterConfigurer> mongoConverterConfigurerConsumer) {
|
||||
|
||||
mongoConverterConfigurerConsumer.accept(mongoConverterConfigurer);
|
||||
return this;
|
||||
}
|
||||
|
||||
com.mongodb.client.MongoClient syncClient() {
|
||||
|
||||
if (syncClient == null) {
|
||||
syncClient = dbFactoryConfig.syncClient != null ? dbFactoryConfig.syncClient : MongoTestUtils.client();
|
||||
}
|
||||
|
||||
return syncClient;
|
||||
}
|
||||
|
||||
com.mongodb.reactivestreams.client.MongoClient reactiveClient() {
|
||||
|
||||
if (reactiveClient == null) {
|
||||
reactiveClient = dbFactoryConfig.reactiveClient != null ? dbFactoryConfig.reactiveClient
|
||||
: MongoTestUtils.reactiveClient();
|
||||
}
|
||||
|
||||
return reactiveClient;
|
||||
}
|
||||
|
||||
String defaultDatabase() {
|
||||
return dbFactoryConfig.defaultDatabase != null ? dbFactoryConfig.defaultDatabase : "test";
|
||||
}
|
||||
|
||||
public static class DatabaseFactoryConfigurer {
|
||||
|
||||
com.mongodb.client.MongoClient syncClient;
|
||||
com.mongodb.reactivestreams.client.MongoClient reactiveClient;
|
||||
String defaultDatabase;
|
||||
|
||||
public void client(com.mongodb.client.MongoClient client) {
|
||||
this.syncClient = client;
|
||||
}
|
||||
|
||||
public void client(com.mongodb.reactivestreams.client.MongoClient client) {
|
||||
this.reactiveClient = client;
|
||||
}
|
||||
|
||||
public void defaultDb(String defaultDatabase) {
|
||||
this.defaultDatabase = defaultDatabase;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MongoConverterConfigurer {
|
||||
|
||||
CustomConversions customConversions;
|
||||
|
||||
public void customConversions(CustomConversions customConversions) {
|
||||
this.customConversions = customConversions;
|
||||
}
|
||||
|
||||
public void customConverters(Converter<?, ?>... converters) {
|
||||
customConversions(new MongoCustomConversions(Arrays.asList(converters)));
|
||||
}
|
||||
}
|
||||
|
||||
public static class MappingContextConfigurer {
|
||||
|
||||
Set<Class<?>> intitalEntitySet;
|
||||
boolean autocreateIndex = false;
|
||||
|
||||
public void autocreateIndex(boolean autocreateIndex) {
|
||||
this.autocreateIndex = autocreateIndex;
|
||||
}
|
||||
|
||||
public void intitalEntitySet(Set<Class<?>> intitalEntitySet) {
|
||||
this.intitalEntitySet = intitalEntitySet;
|
||||
}
|
||||
|
||||
public void intitalEntitySet(Class<?>... initialEntitySet) {
|
||||
this.intitalEntitySet = new HashSet<>(Arrays.asList(initialEntitySet));
|
||||
}
|
||||
|
||||
Set<Class<?>> initialEntitySet() {
|
||||
return intitalEntitySet != null ? intitalEntitySet : Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
public static class AuditingConfigurer {
|
||||
|
||||
Function<MappingContext, IsNewAwareAuditingHandler> auditingHandlerFunction;
|
||||
|
||||
public void auditingHandler(Function<MappingContext, IsNewAwareAuditingHandler> auditingHandlerFunction) {
|
||||
this.auditingHandlerFunction = auditingHandlerFunction;
|
||||
}
|
||||
|
||||
IsNewAwareAuditingHandler auditingHandlers(MongoMappingContext mongoMappingContext) {
|
||||
return auditingHandlerFunction.apply(mongoMappingContext);
|
||||
}
|
||||
|
||||
boolean hasAuditingHandler() {
|
||||
return auditingHandlerFunction != null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ApplicationContextConfigurer {
|
||||
|
||||
List<ApplicationListener<MongoMappingEvent<?>>> listeners = new ArrayList<>();
|
||||
ApplicationContext applicationContext;
|
||||
|
||||
public void applicationContext(ApplicationContext context) {
|
||||
this.applicationContext = context;
|
||||
}
|
||||
|
||||
public void addEventListener(ApplicationListener<MongoMappingEvent<?>> listener) {
|
||||
this.listeners.add(listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -47,9 +47,9 @@ public class MongoTestUtils {
|
||||
private static final Environment ENV = new StandardEnvironment();
|
||||
private static final Duration DEFAULT_TIMEOUT = Duration.ofMillis(10);
|
||||
|
||||
public static final String CONNECTION_STRING = "mongodb://127.0.0.1:27017/?replicaSet=rs0&w=majority";
|
||||
public static final String CONNECTION_STRING = "mongodb://127.0.0.1:27017/?replicaSet=rs0&w=majority&uuidrepresentation=javaLegacy";
|
||||
|
||||
private static final String CONNECTION_STRING_PATTERN = "mongodb://%s:%s/?w=majority";
|
||||
private static final String CONNECTION_STRING_PATTERN = "mongodb://%s:%s/?w=majority&uuidrepresentation=javaLegacy";
|
||||
|
||||
private static final Version ANY = new Version(9999, 9999, 9999);
|
||||
|
||||
@@ -185,6 +185,15 @@ public class MongoTestUtils {
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
public static void flushCollection(String dbName, String collectionName,
|
||||
com.mongodb.client.MongoClient client) {
|
||||
|
||||
com.mongodb.client.MongoDatabase database = client.getDatabase(dbName)
|
||||
.withWriteConcern(WriteConcern.MAJORITY).withReadPreference(ReadPreference.primary());
|
||||
|
||||
database.getCollection(collectionName).deleteMany(new Document());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link com.mongodb.client.MongoClient} with defaults suitable for replica set usage.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright 2020 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.data.mongodb.test.util;
|
||||
|
||||
import com.mongodb.reactivestreams.client.MongoClient;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.reactivestreams.Publisher;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.data.mapping.context.PersistentEntities;
|
||||
import org.springframework.data.mongodb.ReactiveMongoDatabaseFactory;
|
||||
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
|
||||
|
||||
/**
|
||||
* A {@link ReactiveMongoTemplate} with configuration hooks and extension suitable for tests.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @since 3.0
|
||||
*/
|
||||
public class ReactiveMongoTestTemplate extends ReactiveMongoTemplate {
|
||||
|
||||
private final MongoTestTemplateConfiguration cfg;
|
||||
|
||||
public ReactiveMongoTestTemplate(MongoClient client, String database, Class<?>... initialEntities) {
|
||||
this(cfg -> {
|
||||
cfg.configureDatabaseFactory(it -> {
|
||||
|
||||
it.client(client);
|
||||
it.defaultDb(database);
|
||||
});
|
||||
|
||||
cfg.configureMappingContext(it -> {
|
||||
|
||||
it.autocreateIndex(false);
|
||||
it.intitalEntitySet(initialEntities);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public ReactiveMongoTestTemplate(Consumer<MongoTestTemplateConfiguration> cfg) {
|
||||
|
||||
this(new Supplier<MongoTestTemplateConfiguration>() {
|
||||
@Override
|
||||
public MongoTestTemplateConfiguration get() {
|
||||
|
||||
MongoTestTemplateConfiguration config = new MongoTestTemplateConfiguration();
|
||||
cfg.accept(config);
|
||||
return config;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public ReactiveMongoTestTemplate(Supplier<MongoTestTemplateConfiguration> config) {
|
||||
this(config.get());
|
||||
}
|
||||
|
||||
public ReactiveMongoTestTemplate(MongoTestTemplateConfiguration config) {
|
||||
super(config.reactiveDatabaseFactory(), config.mongoConverter());
|
||||
|
||||
ApplicationContext applicationContext = config.getApplicationContext();
|
||||
if (applicationContext != null) {
|
||||
setApplicationContext(applicationContext);
|
||||
}
|
||||
|
||||
this.cfg = config;
|
||||
}
|
||||
|
||||
public ReactiveMongoDatabaseFactory getDatabaseFactory() {
|
||||
return cfg.reactiveDatabaseFactory();
|
||||
}
|
||||
|
||||
public Mono<Void> flush() {
|
||||
return flush(Flux.fromStream(
|
||||
PersistentEntities.of(getConverter().getMappingContext()).stream().map(it -> getCollectionName(it.getType()))));
|
||||
}
|
||||
|
||||
public Mono<Void> flushDatabase() {
|
||||
return flush(getMongoDatabase().listCollectionNames());
|
||||
}
|
||||
|
||||
public Mono<Void> flush(Class<?>... entities) {
|
||||
return flush(Flux.fromStream(Arrays.asList(entities).stream().map(this::getCollectionName)));
|
||||
}
|
||||
|
||||
public Mono<Void> flush(String... collections) {
|
||||
return flush(Flux.fromArray(collections));
|
||||
}
|
||||
|
||||
public Mono<Void> flush(Publisher<String> collectionNames) {
|
||||
|
||||
return Flux.from(collectionNames)
|
||||
.flatMap(collection -> Mono.from(getCollection(collection).deleteMany(new Document())).then()
|
||||
.onErrorResume(it -> Mono.from(getCollection(collection).drop()).then()))
|
||||
.then();
|
||||
}
|
||||
|
||||
public Mono<Void> flush(Object... objects) {
|
||||
|
||||
return flush(Flux.fromStream(Arrays.asList(objects).stream().map(it -> {
|
||||
|
||||
if (it instanceof String) {
|
||||
return (String) it;
|
||||
}
|
||||
if (it instanceof Class) {
|
||||
return getCollectionName((Class<?>) it);
|
||||
}
|
||||
return it.toString();
|
||||
})));
|
||||
}
|
||||
|
||||
public Mono<Void> dropDatabase() {
|
||||
return Mono.from(getMongoDatabase().drop()).then();
|
||||
}
|
||||
|
||||
public void dropIndexes(String... collections) {
|
||||
for (String collection : collections) {
|
||||
getCollection(collection).dropIndexes();
|
||||
}
|
||||
}
|
||||
|
||||
public void dropIndexes(Class<?>... entities) {
|
||||
for (Class<?> entity : entities) {
|
||||
getCollection(getCollectionName(entity)).dropIndexes();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2020 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.data.mongodb.test.util;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @since 3.0
|
||||
*/
|
||||
@Target({ ElementType.FIELD, ElementType.PARAMETER })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@ExtendWith(MongoTemplateExtension.class)
|
||||
public @interface Template {
|
||||
|
||||
/**
|
||||
* @return name of the database to use. Use empty String to generate the database name for the
|
||||
* {@link ExtensionContext#getTestClass() test class}.
|
||||
*/
|
||||
String database() default "";
|
||||
|
||||
/**
|
||||
* Pre initilaize the {@link org.springframework.data.mapping.context.MappingContext} with the given entities.
|
||||
*
|
||||
* @return empty by default.
|
||||
*/
|
||||
Class<?>[] initialEntitySet() default {};
|
||||
|
||||
/**
|
||||
* Use a {@link ReplSetClient} if {@literal true}.
|
||||
*
|
||||
* @return false by default.
|
||||
*/
|
||||
boolean replicaSet() default false;
|
||||
}
|
||||
Reference in New Issue
Block a user