From cc79b500baebc5481bfa5cd9c94da39142091493 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Fri, 16 May 2025 11:31:35 +0200 Subject: [PATCH 01/21] Prepare next development iteration. See #4954 --- pom.xml | 2 +- spring-data-mongodb-distribution/pom.xml | 2 +- spring-data-mongodb/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 9f10d7846f..877d44bbb3 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-mongodb-parent - 4.5.0 + 4.5.1-SNAPSHOT pom Spring Data MongoDB diff --git a/spring-data-mongodb-distribution/pom.xml b/spring-data-mongodb-distribution/pom.xml index c0bdd90d4a..d758cf196b 100644 --- a/spring-data-mongodb-distribution/pom.xml +++ b/spring-data-mongodb-distribution/pom.xml @@ -15,7 +15,7 @@ org.springframework.data spring-data-mongodb-parent - 4.5.0 + 4.5.1-SNAPSHOT ../pom.xml diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml index ad6132cb01..1299895c91 100644 --- a/spring-data-mongodb/pom.xml +++ b/spring-data-mongodb/pom.xml @@ -13,7 +13,7 @@ org.springframework.data spring-data-mongodb-parent - 4.5.0 + 4.5.1-SNAPSHOT ../pom.xml From 030035cd4fecec5599b39187d59b5cfbcbdd74c9 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Fri, 16 May 2025 11:31:36 +0200 Subject: [PATCH 02/21] After release cleanups. See #4954 --- Jenkinsfile | 2 +- pom.xml | 20 ++++++++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 0e83b47e2f..9581c9dec8 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -9,7 +9,7 @@ pipeline { triggers { pollSCM 'H/10 * * * *' - upstream(upstreamProjects: "spring-data-commons/main", threshold: hudson.model.Result.SUCCESS) + upstream(upstreamProjects: "spring-data-commons/3.5.x", threshold: hudson.model.Result.SUCCESS) } options { diff --git a/pom.xml b/pom.xml index 877d44bbb3..97c17fdfaa 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ org.springframework.data.build spring-data-parent - 3.5.0 + 3.5.1-SNAPSHOT @@ -26,7 +26,7 @@ multi spring-data-mongodb - 3.5.0 + 3.5.1-SNAPSHOT 5.5.0 1.19 @@ -157,8 +157,20 @@ - - + + spring-snapshot + https://repo.spring.io/snapshot + + true + + + false + + + + spring-milestone + https://repo.spring.io/milestone + From 0e169aa23e56d63245237eb0278084629a25be20 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Mon, 19 May 2025 14:32:01 +0200 Subject: [PATCH 03/21] =?UTF-8?q?Document=20`createCollection(=E2=80=A6)`?= =?UTF-8?q?=20annotation=20usage.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes: #4978 Original Pull Request: #4979 --- .../data/mongodb/core/MongoOperations.java | 12 ++++++++++++ .../data/mongodb/core/ReactiveMongoOperations.java | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java index 65396bc7fe..22b8e930ae 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java @@ -259,9 +259,21 @@ public T execute(SessionCallback action, Consumer onComple /** * Create an uncapped collection with a name based on the provided entity class. + *

+ * This method derives {@link CollectionOptions} from the given {@code entityClass} using + * {@link org.springframework.data.mongodb.core.mapping.Document} and + * {@link org.springframework.data.mongodb.core.mapping.TimeSeries} annotations to determine: + *

    + *
  • Collation
  • + *
  • TimeSeries time and meta fields, granularity and {@code expireAfter}
  • + *
+ * Any other options such as change stream options, schema-based details (validation, encryption) are not considered + * and must be provided through {@link #createCollection(Class, CollectionOptions)} or + * {@link #createCollection(String, CollectionOptions)}. * * @param entityClass class that determines the collection to create. * @return the created collection. + * @see #createCollection(Class, CollectionOptions) */ MongoCollection createCollection(Class entityClass); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoOperations.java index 90f2d2345d..19802b47f2 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoOperations.java @@ -214,9 +214,21 @@ default ReactiveSessionScoped withSession(Supplier sessionProvide /** * Create an uncapped collection with a name based on the provided entity class. + *

+ * This method derives {@link CollectionOptions} from the given {@code entityClass} using + * {@link org.springframework.data.mongodb.core.mapping.Document} and + * {@link org.springframework.data.mongodb.core.mapping.TimeSeries} annotations to determine: + *

    + *
  • Collation
  • + *
  • TimeSeries time and meta fields, granularity and {@code expireAfter}
  • + *
+ * Any other options such as change stream options, schema-based details (validation, encryption) are not considered + * and must be provided through {@link #createCollection(Class, CollectionOptions)} or + * {@link #createCollection(String, CollectionOptions)}. * * @param entityClass class that determines the collection to create. * @return the created collection. + * @see #createCollection(Class, CollectionOptions) */ Mono> createCollection(Class entityClass); From b4865e99650c6ef051be07cb8b43a00a129faf9b Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Wed, 28 May 2025 15:09:42 +0200 Subject: [PATCH 04/21] Update `$out` stage rendering to documented format. This commit makes sure to use the documented command format when rendering the $out aggregation stage. Original pull request: #4986 Closes #4969 --- .../core/aggregation/OutOperation.java | 27 +++++++++++++------ .../aggregation/OutOperationUnitTest.java | 14 +++++----- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/OutOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/OutOperation.java index 51520f0868..ce5faca4e4 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/OutOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/OutOperation.java @@ -96,11 +96,12 @@ public OutOperation in(@Nullable String database) { * .uniqueKey("{ 'field-1' : 1, 'field-2' : 1}") * * - * NOTE: Requires MongoDB 4.2 or later. + * NOTE: Only suitable for 4.2+ to (not including) 5.0. * * @param key can be {@literal null}. Server uses {@literal _id} when {@literal null}. * @return new instance of {@link OutOperation}. * @since 2.2 + * @deprecated no longer applicable for MongoDB 5+ */ public OutOperation uniqueKey(@Nullable String key) { @@ -120,11 +121,12 @@ public OutOperation uniqueKey(@Nullable String key) { * .uniqueKeyOf(Arrays.asList("field-1", "field-2")) * * - * NOTE: Requires MongoDB 4.2 or later. + * NOTE: Only suitable for 4.2+ to (not including) 5.0. * * @param fields must not be {@literal null}. * @return new instance of {@link OutOperation}. * @since 2.2 + * @deprecated no longer applicable for MongoDB 5+ */ public OutOperation uniqueKeyOf(Iterable fields) { @@ -138,11 +140,12 @@ public OutOperation uniqueKeyOf(Iterable fields) { /** * Specify how to merge the aggregation output with the target collection.
- * NOTE: Requires MongoDB 4.2 or later. + * NOTE: Only suitable for 4.2+ to (not including) 5.0. * * @param mode must not be {@literal null}. * @return new instance of {@link OutOperation}. * @since 2.2 + * @deprecated no longer applicable for MongoDB 5+ */ public OutOperation mode(OutMode mode) { @@ -152,11 +155,12 @@ public OutOperation mode(OutMode mode) { /** * Replace the target collection.
- * NOTE: Requires MongoDB 4.2 or later. + * NOTE: Only suitable for 4.2+ to (not including) 5.0. * * @return new instance of {@link OutOperation}. * @see OutMode#REPLACE_COLLECTION * @since 2.2 + * @deprecated no longer applicable for MongoDB 5+ */ public OutOperation replaceCollection() { return mode(OutMode.REPLACE_COLLECTION); @@ -164,11 +168,12 @@ public OutOperation replaceCollection() { /** * Replace/Upsert documents in the target collection.
- * NOTE: Requires MongoDB 4.2 or later. + * NOTE: Only suitable for 4.2+ to (not including) 5.0. * * @return new instance of {@link OutOperation}. * @see OutMode#REPLACE * @since 2.2 + * @deprecated no longer applicable for MongoDB 5+ */ public OutOperation replaceDocuments() { return mode(OutMode.REPLACE); @@ -176,11 +181,12 @@ public OutOperation replaceDocuments() { /** * Insert documents to the target collection.
- * NOTE: Requires MongoDB 4.2 or later. + * NOTE: Only suitable for 4.2+ to (not including) 5.0. * * @return new instance of {@link OutOperation}. * @see OutMode#INSERT * @since 2.2 + * @deprecated no longer applicable for MongoDB 5+ */ public OutOperation insertDocuments() { return mode(OutMode.INSERT); @@ -190,7 +196,10 @@ public OutOperation insertDocuments() { public Document toDocument(AggregationOperationContext context) { if (!requiresMongoDb42Format()) { - return new Document("$out", collectionName); + if (!StringUtils.hasText(databaseName)) { + return new Document(getOperator(), collectionName); + } + return new Document(getOperator(), new Document("db", databaseName).append("coll", collectionName)); } Assert.state(mode != null, "Mode must not be null"); @@ -215,7 +224,7 @@ public String getOperator() { } private boolean requiresMongoDb42Format() { - return StringUtils.hasText(databaseName) || mode != null || uniqueKey != null; + return mode != null || uniqueKey != null; } /** @@ -223,7 +232,9 @@ private boolean requiresMongoDb42Format() { * * @author Christoph Strobl * @since 2.2 + * @deprecated no longer applicable for MongoDB 5+ */ + @Deprecated public enum OutMode { /** diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/OutOperationUnitTest.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/OutOperationUnitTest.java index f8812448b3..51f6b84f19 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/OutOperationUnitTest.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/OutOperationUnitTest.java @@ -15,8 +15,9 @@ */ package org.springframework.data.mongodb.core.aggregation; -import static org.springframework.data.mongodb.core.aggregation.Aggregation.*; -import static org.springframework.data.mongodb.test.util.Assertions.*; +import static org.springframework.data.mongodb.core.aggregation.Aggregation.out; +import static org.springframework.data.mongodb.test.util.Assertions.assertThat; +import static org.springframework.data.mongodb.test.util.Assertions.assertThatIllegalArgumentException; import java.util.Arrays; @@ -84,11 +85,12 @@ public void shouldRenderExtendedFormatWithMultiFieldKey() { .containsEntry("$out.uniqueKey", new Document("field-1", 1).append("field-2", 1)); } - @Test // DATAMONGO-2259 - public void shouldErrorOnExtendedFormatWithoutMode() { + @Test // DATAMONGO-2259, GH-4969 + public void shouldRenderNewExtendedFormatWithoutMode() { - assertThatThrownBy(() -> out("out-col").in("database-2").toDocument(Aggregation.DEFAULT_CONTEXT)) - .isInstanceOf(IllegalStateException.class); + assertThat(out("out-col").in("database-2").toDocument(Aggregation.DEFAULT_CONTEXT)) + .containsEntry("$out.coll", "out-col") // + .containsEntry("$out.db", "database-2"); } } From c3695d9d5a336b55f57fcfd56fead0911935fd6a Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Mon, 2 Jun 2025 09:38:47 +0200 Subject: [PATCH 05/21] Polishing. Guard Queryable Encryption tests against standalone server usage. Original pull request: #4986 See #4969 --- .../MongoQueryableEncryptionCollectionCreationTests.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/MongoQueryableEncryptionCollectionCreationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/MongoQueryableEncryptionCollectionCreationTests.java index dd9e459e78..b801d1770b 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/MongoQueryableEncryptionCollectionCreationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/MongoQueryableEncryptionCollectionCreationTests.java @@ -41,6 +41,7 @@ import org.springframework.data.mongodb.core.schema.MongoJsonSchema; 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.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; @@ -54,6 +55,7 @@ */ @ExtendWith({ MongoClientExtension.class, SpringExtension.class }) @EnableIfMongoServerVersion(isGreaterThanEqual = "8.0") +@EnableIfReplicaSetAvailable @ContextConfiguration public class MongoQueryableEncryptionCollectionCreationTests { From d27f4a683dd139a301bed7fa4905305fc0b69d07 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Mon, 2 Jun 2025 09:38:59 +0200 Subject: [PATCH 06/21] Polishing. Refine deprecations. Original pull request: #4986 See #4969 --- .../core/aggregation/OutOperation.java | 39 +++++++++++++------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/OutOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/OutOperation.java index ce5faca4e4..c60186afeb 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/OutOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/OutOperation.java @@ -49,7 +49,8 @@ public OutOperation(String outCollectionName) { /** * @param databaseName Optional database name the target collection is located in. Can be {@literal null}. * @param collectionName Collection name to export the results. Must not be {@literal null}. Can be {@literal null}. - * @param uniqueKey Optional unique key spec identify a document in the to collection for replacement or merge. + * @param uniqueKey Optional unique key spec identify a document in the {@code to} collection for replacement or + * merge. * @param mode The mode for merging the aggregation pipeline output with the target collection. Can be * {@literal null}. {@literal null}. * @since 2.2 @@ -101,8 +102,10 @@ public OutOperation in(@Nullable String database) { * @param key can be {@literal null}. Server uses {@literal _id} when {@literal null}. * @return new instance of {@link OutOperation}. * @since 2.2 - * @deprecated no longer applicable for MongoDB 5+ + * @deprecated extended {@code $out} syntax was superseded by {@code $merge}. Support for the extended syntax has been + * removed with MongoDB 5, use {@link MergeOperation} instead. */ + @Deprecated(since = "4.5.1", forRemoval = true) public OutOperation uniqueKey(@Nullable String key) { Document uniqueKey = key == null ? null : BsonUtils.toDocumentOrElse(key, it -> new Document(it, 1)); @@ -126,8 +129,10 @@ public OutOperation uniqueKey(@Nullable String key) { * @param fields must not be {@literal null}. * @return new instance of {@link OutOperation}. * @since 2.2 - * @deprecated no longer applicable for MongoDB 5+ + * @deprecated extended {@code $out} syntax was superseded by {@code $merge}. Support for the extended syntax has been + * removed with MongoDB 5, use {@link MergeOperation} instead. */ + @Deprecated(since = "4.5.1", forRemoval = true) public OutOperation uniqueKeyOf(Iterable fields) { Assert.notNull(fields, "Fields must not be null"); @@ -145,8 +150,10 @@ public OutOperation uniqueKeyOf(Iterable fields) { * @param mode must not be {@literal null}. * @return new instance of {@link OutOperation}. * @since 2.2 - * @deprecated no longer applicable for MongoDB 5+ + * @deprecated extended {@code $out} syntax was superseded by {@code $merge}. Support for the extended syntax has been + * removed with MongoDB 5, use {@link MergeOperation} instead. */ + @Deprecated(since = "4.5.1", forRemoval = true) public OutOperation mode(OutMode mode) { Assert.notNull(mode, "Mode must not be null"); @@ -160,8 +167,10 @@ public OutOperation mode(OutMode mode) { * @return new instance of {@link OutOperation}. * @see OutMode#REPLACE_COLLECTION * @since 2.2 - * @deprecated no longer applicable for MongoDB 5+ + * @deprecated extended {@code $out} syntax was superseded by {@code $merge}. Support for the extended syntax has been + * removed with MongoDB 5, use {@link MergeOperation} instead. */ + @Deprecated(since = "4.5.1", forRemoval = true) public OutOperation replaceCollection() { return mode(OutMode.REPLACE_COLLECTION); } @@ -173,8 +182,10 @@ public OutOperation replaceCollection() { * @return new instance of {@link OutOperation}. * @see OutMode#REPLACE * @since 2.2 - * @deprecated no longer applicable for MongoDB 5+ + * @deprecated extended {@code $out} syntax was superseded by {@code $merge}. Support for the extended syntax has been + * removed with MongoDB 5, use {@link MergeOperation} instead. */ + @Deprecated(since = "4.5.1", forRemoval = true) public OutOperation replaceDocuments() { return mode(OutMode.REPLACE); } @@ -186,8 +197,10 @@ public OutOperation replaceDocuments() { * @return new instance of {@link OutOperation}. * @see OutMode#INSERT * @since 2.2 - * @deprecated no longer applicable for MongoDB 5+ + * @deprecated extended {@code $out} syntax was superseded by {@code $merge}. Support for the extended syntax has been + * removed with MongoDB 5, use {@link MergeOperation} instead. */ + @Deprecated(since = "4.5.1", forRemoval = true) public OutOperation insertDocuments() { return mode(OutMode.INSERT); } @@ -195,7 +208,7 @@ public OutOperation insertDocuments() { @Override public Document toDocument(AggregationOperationContext context) { - if (!requiresMongoDb42Format()) { + if (!requiresExtendedFormat()) { if (!StringUtils.hasText(databaseName)) { return new Document(getOperator(), collectionName); } @@ -223,7 +236,7 @@ public String getOperator() { return "$out"; } - private boolean requiresMongoDb42Format() { + private boolean requiresExtendedFormat() { return mode != null || uniqueKey != null; } @@ -232,9 +245,10 @@ private boolean requiresMongoDb42Format() { * * @author Christoph Strobl * @since 2.2 - * @deprecated no longer applicable for MongoDB 5+ + * @deprecated extended {@code $out} syntax was superseded by {@code $merge}. Support for the extended syntax has been + * removed with MongoDB 5, use {@link MergeOperation} instead. */ - @Deprecated + @Deprecated(since = "4.5.1", forRemoval = true) public enum OutMode { /** @@ -248,7 +262,8 @@ public enum OutMode { REPLACE("replaceDocuments"), /** - * Replaces the to collection with the output from the aggregation pipeline. Cannot be in a different database. + * Replaces the {@code to} collection with the output from the aggregation pipeline. Cannot be in a different + * database. */ REPLACE_COLLECTION("replaceCollection"); From 1a3e8aa0d677110103ad5a5aef7767c1cf583493 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Wed, 4 Jun 2025 09:56:31 +0200 Subject: [PATCH 07/21] Fix missing precision value when creating encryption settings. Original pull request: #4993 Closes: #4989 --- .../mongodb/core/schema/QueryCharacteristics.java | 4 +++- ...ueryableEncryptionCollectionCreationTests.java | 15 ++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/QueryCharacteristics.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/QueryCharacteristics.java index 4ec775c5e7..430449b50a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/QueryCharacteristics.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/QueryCharacteristics.java @@ -253,10 +253,12 @@ public Document toDocument() { target.append("min", valueRange.getLowerBound().getValue().orElse((T) BsonNull.VALUE)).append("max", valueRange.getUpperBound().getValue().orElse((T) BsonNull.VALUE)); } + if (precision != null) { + target.append("precision", precision); + } if (sparsity != null) { target.append("sparsity", sparsity); } - return target; } } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/MongoQueryableEncryptionCollectionCreationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/MongoQueryableEncryptionCollectionCreationTests.java index b801d1770b..f369e5541c 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/MongoQueryableEncryptionCollectionCreationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/MongoQueryableEncryptionCollectionCreationTests.java @@ -31,7 +31,6 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration; @@ -84,7 +83,7 @@ void beforeEach() { template.dropCollection(COLLECTION_NAME); } - @ParameterizedTest // GH-4185 + @ParameterizedTest // GH-4185, GH-4989 @MethodSource("collectionOptions") public void createsCollectionWithEncryptedFieldsCorrectly(CollectionOptions collectionOptions) { @@ -103,23 +102,33 @@ public void createsCollectionWithEncryptedFieldsCorrectly(CollectionOptions coll .containsEntry("bsonType", "long") // .containsEntry("queries", List.of(Document.parse( "{'queryType': 'range', 'contention': { '$numberLong' : '0' }, 'min': { '$numberLong' : '-1' }, 'max': { '$numberLong' : '1' }}"))); + + assertThat(fields.get(2)).containsEntry("path", "encryptedDouble") // + .containsEntry("bsonType", "double") // + .containsEntry("queries", List.of(Document.parse( + "{'queryType': 'range', 'contention': { '$numberLong' : '1' }, 'min': { '$numberDouble' : '-1.123' }, 'max': { '$numberDouble' : '1.123' }, 'precision': { '$numberInt' : '5'}}"))); } private static Stream collectionOptions() { BsonBinary key1 = new BsonBinary(UUID.randomUUID(), UuidRepresentation.STANDARD); BsonBinary key2 = new BsonBinary(UUID.randomUUID(), UuidRepresentation.STANDARD); + BsonBinary key3 = new BsonBinary(UUID.randomUUID(), UuidRepresentation.STANDARD); CollectionOptions manualOptions = CollectionOptions.encryptedCollection(options -> options // .queryable(encrypted(int32("encryptedInt")).keys(key1), range().min(5).max(100).contention(1)) // .queryable(encrypted(JsonSchemaProperty.int64("nested.encryptedLong")).keys(key2), - range().min(-1L).max(1L).contention(0))); + range().min(-1L).max(1L).contention(0)) // + .queryable(encrypted(JsonSchemaProperty.float64("encryptedDouble")).keys(key3), + range().min(-1.123D).max(1.123D).precision(5).contention(1))); CollectionOptions schemaOptions = CollectionOptions.encryptedCollection(MongoJsonSchema.builder() .property( queryable(encrypted(int32("encryptedInt")).keyId(key1), List.of(range().min(5).max(100).contention(1)))) .property(queryable(encrypted(int64("nested.encryptedLong")).keyId(key2), List.of(range().min(-1L).max(1L).contention(0)))) + .property(queryable(encrypted(float64("encryptedDouble")).keyId(key3), + List.of(range().min(-1.123D).max(1.123D).precision(5).contention(1)))) .build()); return Stream.of(Arguments.of(manualOptions), Arguments.of(schemaOptions)); From b7d7d455d1d6a703aaec0bc8c5a7513a1699e901 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Tue, 3 Jun 2025 16:15:59 +0200 Subject: [PATCH 08/21] Add support for non-queryable encrypted fields in `CollectionOptions`. Closes #4988 Original pull request: #4992 --- .../data/mongodb/core/CollectionOptions.java | 79 +++++++++++++++---- .../core/CollectionOptionsUnitTests.java | 11 ++- ...ableEncryptionCollectionCreationTests.java | 21 +++-- .../core/encryption/RangeEncryptionTests.java | 36 ++++++--- .../ROOT/pages/mongodb/mongo-encryption.adoc | 17 +++- 5 files changed, 124 insertions(+), 40 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionOptions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionOptions.java index 5df30e0b92..819d9280aa 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionOptions.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionOptions.java @@ -33,6 +33,7 @@ import org.springframework.data.mongodb.core.mapping.Field; import org.springframework.data.mongodb.core.query.Collation; import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty; +import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.EncryptedJsonSchemaProperty; import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.QueryableJsonSchemaProperty; import org.springframework.data.mongodb.core.schema.JsonSchemaProperty; import org.springframework.data.mongodb.core.schema.MongoJsonSchema; @@ -678,17 +679,16 @@ public static class EncryptedFieldsOptions { private static final EncryptedFieldsOptions NONE = new EncryptedFieldsOptions(); private final @Nullable MongoJsonSchema schema; - private final List queryableProperties; + private final List properties; EncryptedFieldsOptions() { this(null, List.of()); } - private EncryptedFieldsOptions(@Nullable MongoJsonSchema schema, - List queryableProperties) { + private EncryptedFieldsOptions(@Nullable MongoJsonSchema schema, List queryableProperties) { this.schema = schema; - this.queryableProperties = queryableProperties; + this.properties = queryableProperties; } /** @@ -708,7 +708,7 @@ public static EncryptedFieldsOptions fromSchema(MongoJsonSchema schema) { /** * @return new instance of {@link EncryptedFieldsOptions}. */ - public static EncryptedFieldsOptions fromProperties(List properties) { + public static EncryptedFieldsOptions fromProperties(List properties) { return new EncryptedFieldsOptions(null, List.copyOf(properties)); } @@ -728,13 +728,50 @@ public static EncryptedFieldsOptions fromProperties(List targetPropertyList = new ArrayList<>(queryableProperties.size() + 1); - targetPropertyList.addAll(queryableProperties); + List targetPropertyList = new ArrayList<>(properties.size() + 1); + targetPropertyList.addAll(properties); targetPropertyList.add(JsonSchemaProperty.queryable(property, List.of(characteristics))); return new EncryptedFieldsOptions(schema, targetPropertyList); } + /** + * Add an {@link EncryptedJsonSchemaProperty encrypted property} that should not be queryable. + * + * @param property must not be {@literal null}. + * @return new instance of {@link EncryptedFieldsOptions}. + */ + @Contract("_ -> new") + @CheckReturnValue + public EncryptedFieldsOptions with(EncryptedJsonSchemaProperty property) { + return encrypted(property, null); + } + + /** + * Add a {@link JsonSchemaProperty property} that should not be encrypted but not queryable. + * + * @param property must not be {@literal null}. + * @param key can be {@literal null}. + * @return new instance of {@link EncryptedFieldsOptions}. + */ + @Contract("_, _ -> new") + @CheckReturnValue + public EncryptedFieldsOptions encrypted(JsonSchemaProperty property, @Nullable Object key) { + + List targetPropertyList = new ArrayList<>(properties.size() + 1); + targetPropertyList.addAll(properties); + if (property instanceof IdentifiableJsonSchemaProperty.EncryptedJsonSchemaProperty) { + targetPropertyList.add(property); + } else { + EncryptedJsonSchemaProperty encryptedJsonSchemaProperty = new EncryptedJsonSchemaProperty(property); + if (key != null) { + targetPropertyList.add(encryptedJsonSchemaProperty.keyId(key)); + } + } + + return new EncryptedFieldsOptions(schema, targetPropertyList); + } + public Document toDocument() { return new Document("fields", selectPaths()); } @@ -753,12 +790,12 @@ private List selectPaths() { private List fromProperties() { - if (queryableProperties.isEmpty()) { + if (properties.isEmpty()) { return List.of(); } - List converted = new ArrayList<>(queryableProperties.size()); - for (QueryableJsonSchemaProperty property : queryableProperties) { + List converted = new ArrayList<>(properties.size()); + for (JsonSchemaProperty property : properties) { Document field = new Document("path", property.getIdentifier()); @@ -766,7 +803,7 @@ private List fromProperties() { field.append("bsonType", property.getTypes().iterator().next().toBsonType().value()); } - if (property + if (property instanceof QueryableJsonSchemaProperty qproperty && qproperty .getTargetProperty() instanceof IdentifiableJsonSchemaProperty.EncryptedJsonSchemaProperty encrypted) { if (encrypted.getKeyId() != null) { if (encrypted.getKeyId() instanceof String stringKey) { @@ -776,11 +813,21 @@ private List fromProperties() { field.append("keyId", encrypted.getKeyId()); } } + } else if (property instanceof IdentifiableJsonSchemaProperty.EncryptedJsonSchemaProperty encrypted) { + if (encrypted.getKeyId() != null) { + if (encrypted.getKeyId() instanceof String stringKey) { + field.append("keyId", + new BsonBinary(BsonBinarySubType.UUID_STANDARD, stringKey.getBytes(StandardCharsets.UTF_8))); + } else { + field.append("keyId", encrypted.getKeyId()); + } + } } - field.append("queries", StreamSupport.stream(property.getCharacteristics().spliterator(), false) - .map(QueryCharacteristic::toDocument).toList()); - + if (property instanceof QueryableJsonSchemaProperty qproperty) { + field.append("queries", StreamSupport.stream(qproperty.getCharacteristics().spliterator(), false) + .map(QueryCharacteristic::toDocument).toList()); + } if (!field.containsKey("keyId")) { field.append("keyId", BsonNull.VALUE); } @@ -809,7 +856,9 @@ private List fromSchema() { if (entry.getValue().containsKey("bsonType")) { field.append("bsonType", entry.getValue().get("bsonType")); } - field.put("queries", entry.getValue().get("queries")); + if (entry.getValue().containsKey("queries")) { + field.put("queries", entry.getValue().get("queries")); + } fields.add(field); } } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/CollectionOptionsUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/CollectionOptionsUnitTests.java index 9de0863cd2..fd8c9fb972 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/CollectionOptionsUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/CollectionOptionsUnitTests.java @@ -89,22 +89,25 @@ void validatorEquals() { .isNotEqualTo(empty().validator(Validator.document(new Document("one", "two"))).moderateValidation()); } - @Test // GH-4185 + @Test // GH-4185, GH-4988 @SuppressWarnings("unchecked") void queryableEncryptionOptionsFromSchemaRenderCorrectly() { MongoJsonSchema schema = MongoJsonSchema.builder() .property(JsonSchemaProperty.object("spring") .properties(queryable(JsonSchemaProperty.encrypted(JsonSchemaProperty.int32("data")), List.of()))) - .property(queryable(JsonSchemaProperty.encrypted(JsonSchemaProperty.int64("mongodb")), List.of())).build(); + .property(queryable(JsonSchemaProperty.encrypted(JsonSchemaProperty.int64("mongodb")), List.of())) + .property(JsonSchemaProperty.encrypted(JsonSchemaProperty.string("rocks"))).build(); EncryptedFieldsOptions encryptionOptions = EncryptedFieldsOptions.fromSchema(schema); - assertThat(encryptionOptions.toDocument().get("fields", List.class)).hasSize(2) + assertThat(encryptionOptions.toDocument().get("fields", List.class)).hasSize(3) .contains(new Document("path", "mongodb").append("bsonType", "long").append("queries", List.of()) .append("keyId", BsonNull.VALUE)) .contains(new Document("path", "spring.data").append("bsonType", "int").append("queries", List.of()) - .append("keyId", BsonNull.VALUE)); + .append("keyId", BsonNull.VALUE)) + .contains(new Document("path", "rocks").append("bsonType", "string").append("keyId", BsonNull.VALUE)); + } @Test // GH-4185 diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/MongoQueryableEncryptionCollectionCreationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/MongoQueryableEncryptionCollectionCreationTests.java index f369e5541c..7b935e2044 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/MongoQueryableEncryptionCollectionCreationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/MongoQueryableEncryptionCollectionCreationTests.java @@ -31,6 +31,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration; @@ -93,12 +94,16 @@ public void createsCollectionWithEncryptedFieldsCorrectly(CollectionOptions coll assertThat(encryptedFields).containsKey("fields"); List fields = encryptedFields.get("fields", List.of()); - assertThat(fields.get(0)).containsEntry("path", "encryptedInt") // + assertThat(fields.get(0)).containsEntry("path", "encrypted-but-not-queryable") // + .containsEntry("bsonType", "int") // + .doesNotContainKey("queries"); + + assertThat(fields.get(1)).containsEntry("path", "encryptedInt") // .containsEntry("bsonType", "int") // .containsEntry("queries", List .of(Document.parse("{'queryType': 'range', 'contention': { '$numberLong' : '1' }, 'min': 5, 'max': 100}"))); - assertThat(fields.get(1)).containsEntry("path", "nested.encryptedLong") // + assertThat(fields.get(2)).containsEntry("path", "nested.encryptedLong") // .containsEntry("bsonType", "long") // .containsEntry("queries", List.of(Document.parse( "{'queryType': 'range', 'contention': { '$numberLong' : '0' }, 'min': { '$numberLong' : '-1' }, 'max': { '$numberLong' : '1' }}"))); @@ -116,16 +121,18 @@ private static Stream collectionOptions() { BsonBinary key3 = new BsonBinary(UUID.randomUUID(), UuidRepresentation.STANDARD); CollectionOptions manualOptions = CollectionOptions.encryptedCollection(options -> options // - .queryable(encrypted(int32("encryptedInt")).keys(key1), range().min(5).max(100).contention(1)) // - .queryable(encrypted(JsonSchemaProperty.int64("nested.encryptedLong")).keys(key2), + .encrypted(int32("encrypted-but-not-queryable"), key1) // + .queryable(encrypted(int32("encryptedInt")).keyId(key2), range().min(5).max(100).contention(1)) // + .queryable(encrypted(JsonSchemaProperty.int64("nested.encryptedLong")).keyId(key3), range().min(-1L).max(1L).contention(0)) // .queryable(encrypted(JsonSchemaProperty.float64("encryptedDouble")).keys(key3), range().min(-1.123D).max(1.123D).precision(5).contention(1))); - CollectionOptions schemaOptions = CollectionOptions.encryptedCollection(MongoJsonSchema.builder() + CollectionOptions schemaOptions = CollectionOptions.encryptedCollection(MongoJsonSchema.builder() // + .property(encrypted(int32("encrypted-but-not-queryable")).keyId(key1)) // .property( - queryable(encrypted(int32("encryptedInt")).keyId(key1), List.of(range().min(5).max(100).contention(1)))) - .property(queryable(encrypted(int64("nested.encryptedLong")).keyId(key2), + queryable(encrypted(int32("encryptedInt")).keyId(key2), List.of(range().min(5).max(100).contention(1)))) + .property(queryable(encrypted(int64("nested.encryptedLong")).keyId(key3), List.of(range().min(-1L).max(1L).contention(0)))) .property(queryable(encrypted(float64("encryptedDouble")).keyId(key3), List.of(range().min(-1.123D).max(1.123D).precision(5).contention(1)))) diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/RangeEncryptionTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/RangeEncryptionTests.java index e4e760cc91..01cbdec9d5 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/RangeEncryptionTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/RangeEncryptionTests.java @@ -15,8 +15,9 @@ */ package org.springframework.data.mongodb.core.encryption; -import static org.assertj.core.api.Assertions.*; -import static org.springframework.data.mongodb.core.query.Criteria.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.springframework.data.mongodb.core.query.Criteria.where; import java.security.SecureRandom; import java.util.LinkedHashMap; @@ -32,13 +33,10 @@ import org.bson.BsonInt32; import org.bson.BsonString; import org.bson.Document; -import org.junit.Before; import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; - import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; @@ -125,11 +123,11 @@ void manuallyEncryptedValuesCanBeSavedAndRetrievedCorrectly() { EncryptOptions equalityEncOptions = new EncryptOptions("Indexed").contentionFactor(0L) .keyId(keyHolder.getEncryptionKey("age")); - ; EncryptOptions equalityEncOptionsString = new EncryptOptions("Indexed").contentionFactor(0L) .keyId(keyHolder.getEncryptionKey("name")); - ; + + EncryptOptions justEncryptOptions = new EncryptOptions("Unindexed").keyId(keyHolder.getEncryptionKey("ssn")); Document source = new Document("_id", "id-1"); @@ -137,6 +135,7 @@ void manuallyEncryptedValuesCanBeSavedAndRetrievedCorrectly() { clientEncryption.getClientEncryption().encrypt(new BsonString("It's a Me, Mario!"), equalityEncOptionsString)); source.put("age", clientEncryption.getClientEncryption().encrypt(new BsonInt32(101), equalityEncOptions)); source.put("encryptedInt", clientEncryption.getClientEncryption().encrypt(new BsonInt32(101), encryptOptions)); + source.put("ssn", clientEncryption.getClientEncryption().encrypt(new BsonString("6-4-20"), justEncryptOptions)); source.put("_class", Person.class.getName()); template.execute(Person.class, col -> col.insertOne(source)); @@ -151,6 +150,8 @@ void manuallyEncryptedValuesCanBeSavedAndRetrievedCorrectly() { }); assertThat(result).containsEntry("encryptedInt", 101); + assertThat(result).containsEntry("age", 101); + assertThat(result).containsEntry("ssn", "6-4-20"); } @Test // GH-4185 @@ -283,6 +284,7 @@ private Person createPerson() { source.encryptedLong = 1001L; source.nested = new NestedWithQEFields(); source.nested.value = "Luigi time!"; + source.ssn = "6-4-20"; return source; } @@ -480,6 +482,10 @@ static class Person { rangeOptions = "{\"min\": {\"$numberLong\": \"1000\"}, \"max\": {\"$numberLong\": \"9999\"}, \"trimFactor\": 1, \"sparsity\": 1}") // Long encryptedLong; + @ValueConverter(MongoEncryptionConverter.class) + @Encrypted(algorithm = "Unindexed") // encrypted, nothing else! + String ssn; + NestedWithQEFields nested; public String getId() { @@ -514,6 +520,14 @@ public void setEncryptedLong(Long encryptedLong) { this.encryptedLong = encryptedLong; } + public String getSsn() { + return ssn; + } + + public void setSsn(String ssn) { + this.ssn = ssn; + } + @Override public boolean equals(Object o) { if (o == this) { @@ -525,18 +539,20 @@ public boolean equals(Object o) { Person person = (Person) o; return Objects.equals(id, person.id) && Objects.equals(unencryptedValue, person.unencryptedValue) && Objects.equals(name, person.name) && Objects.equals(age, person.age) - && Objects.equals(encryptedInt, person.encryptedInt) && Objects.equals(encryptedLong, person.encryptedLong); + && Objects.equals(encryptedInt, person.encryptedInt) && Objects.equals(encryptedLong, person.encryptedLong) + && Objects.equals(ssn, person.ssn); } @Override public int hashCode() { - return Objects.hash(id, unencryptedValue, name, age, encryptedInt, encryptedLong); + return Objects.hash(id, unencryptedValue, name, age, encryptedInt, encryptedLong, ssn); } @Override public String toString() { return "Person{" + "id='" + id + '\'' + ", unencryptedValue='" + unencryptedValue + '\'' + ", name='" + name - + '\'' + ", age=" + age + ", encryptedInt=" + encryptedInt + ", encryptedLong=" + encryptedLong + '}'; + + '\'' + ", age=" + age + ", encryptedInt=" + encryptedInt + ", encryptedLong=" + encryptedLong + ", ssn=" + + ssn + '}'; } } diff --git a/src/main/antora/modules/ROOT/pages/mongodb/mongo-encryption.adoc b/src/main/antora/modules/ROOT/pages/mongodb/mongo-encryption.adoc index 14e866cf14..04e0cb9838 100644 --- a/src/main/antora/modules/ROOT/pages/mongodb/mongo-encryption.adoc +++ b/src/main/antora/modules/ROOT/pages/mongodb/mongo-encryption.adoc @@ -141,9 +141,10 @@ Manual Collection Setup:: [source,java,indent=0,subs="verbatim,quotes",role="primary"] ---- CollectionOptions collectionOptions = CollectionOptions.encryptedCollection(options -> options - .queryable(encrypted(string("ssn")).algorithm("Indexed"), equality().contention(0)) - .queryable(encrypted(int32("age")).algorithm("Range"), range().contention(8).min(0).max(150)) - .queryable(encrypted(int64("address.sign")).algorithm("Range"), range().contention(2).min(-10L).max(10L)) + .queryable(encrypted(string("ssn")).algorithm("Indexed"), equality().contention(0)) + .queryable(encrypted(int32("age")).algorithm("Range"), range().contention(8).min(0).max(150)) + .encrypted(string("pin")) + .queryable(encrypted(int64("address.sign")).algorithm("Range"), range().contention(2).min(-10L).max(10L)) ); mongoTemplate.createCollection(Patient.class, collectionOptions); <1> @@ -160,13 +161,16 @@ class Patient { @Id String id; - @Encrypted(algorithm = "Indexed") // + @Encrypted(algorithm = "Indexed") @Queryable(queryType = "equality", contentionFactor = 0) String ssn; @RangeEncrypted(contentionFactor = 8, rangeOptions = "{ 'min' : 0, 'max' : 150 }") Integer age; + @Encrypted(algorithm = "Unindexed") + String pin; + Address address; } @@ -210,6 +214,11 @@ MongoDB Collection Info:: bsonType: 'int', queries: [ { queryType: 'range', contention: Long('8'), min: 0, max: 150 } ] }, + { + keyId: ..., + path: 'pin', + bsonType: 'string' + }, { keyId: ..., path: 'address.sign', From 4904a9ce356c27487f26bb163b90b3c72334f2ef Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 4 Jun 2025 15:07:15 +0200 Subject: [PATCH 09/21] Polishing. Fix Javadoc, make QueryCharacteristics a Streamable for easier usage during mapping, reformat code for reduced nesting levels. See #4988 Original pull request: #4992 --- .../data/mongodb/core/CollectionOptions.java | 144 ++++++++++-------- .../core/schema/QueryCharacteristics.java | 3 +- 2 files changed, 81 insertions(+), 66 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionOptions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionOptions.java index 819d9280aa..9f5eff7fb1 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionOptions.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionOptions.java @@ -24,12 +24,12 @@ import java.util.Map.Entry; import java.util.Optional; import java.util.function.Function; -import java.util.stream.StreamSupport; import org.bson.BsonBinary; import org.bson.BsonBinarySubType; import org.bson.BsonNull; import org.bson.Document; + import org.springframework.data.mongodb.core.mapping.Field; import org.springframework.data.mongodb.core.query.Collation; import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty; @@ -391,6 +391,7 @@ public CollectionOptions changeStream(CollectionChangeStreamOptions changeStream * * @param encryptedFieldsOptions must not be {@literal null}. * @return new instance of {@link CollectionOptions}. + * @since 4.5 */ @Contract("_ -> new") @CheckReturnValue @@ -708,7 +709,7 @@ public static EncryptedFieldsOptions fromSchema(MongoJsonSchema schema) { /** * @return new instance of {@link EncryptedFieldsOptions}. */ - public static EncryptedFieldsOptions fromProperties(List properties) { + public static EncryptedFieldsOptions fromProperties(List properties) { return new EncryptedFieldsOptions(null, List.copyOf(properties)); } @@ -740,6 +741,7 @@ public EncryptedFieldsOptions queryable(JsonSchemaProperty property, QueryCharac * * @param property must not be {@literal null}. * @return new instance of {@link EncryptedFieldsOptions}. + * @since 4.5.1 */ @Contract("_ -> new") @CheckReturnValue @@ -748,24 +750,26 @@ public EncryptedFieldsOptions with(EncryptedJsonSchemaProperty property) { } /** - * Add a {@link JsonSchemaProperty property} that should not be encrypted but not queryable. + * Add a {@link JsonSchemaProperty property} that should be encrypted but not queryable. * * @param property must not be {@literal null}. - * @param key can be {@literal null}. + * @param keyId the key identifier to be used, can be {@literal null}. * @return new instance of {@link EncryptedFieldsOptions}. + * @since 4.5.1 */ @Contract("_, _ -> new") @CheckReturnValue - public EncryptedFieldsOptions encrypted(JsonSchemaProperty property, @Nullable Object key) { + public EncryptedFieldsOptions encrypted(JsonSchemaProperty property, @Nullable Object keyId) { List targetPropertyList = new ArrayList<>(properties.size() + 1); targetPropertyList.addAll(properties); + if (property instanceof IdentifiableJsonSchemaProperty.EncryptedJsonSchemaProperty) { targetPropertyList.add(property); } else { EncryptedJsonSchemaProperty encryptedJsonSchemaProperty = new EncryptedJsonSchemaProperty(property); - if (key != null) { - targetPropertyList.add(encryptedJsonSchemaProperty.keyId(key)); + if (keyId != null) { + targetPropertyList.add(encryptedJsonSchemaProperty.keyId(keyId)); } } @@ -796,45 +800,48 @@ private List fromProperties() { List converted = new ArrayList<>(properties.size()); for (JsonSchemaProperty property : properties) { + converted.add(getEncryptedField(property)); + } + return converted; + } - Document field = new Document("path", property.getIdentifier()); + private Document getEncryptedField(JsonSchemaProperty property) { - if (!property.getTypes().isEmpty()) { - field.append("bsonType", property.getTypes().iterator().next().toBsonType().value()); - } + Document field = new Document("path", property.getIdentifier()); - if (property instanceof QueryableJsonSchemaProperty qproperty && qproperty - .getTargetProperty() instanceof IdentifiableJsonSchemaProperty.EncryptedJsonSchemaProperty encrypted) { - if (encrypted.getKeyId() != null) { - if (encrypted.getKeyId() instanceof String stringKey) { - field.append("keyId", - new BsonBinary(BsonBinarySubType.UUID_STANDARD, stringKey.getBytes(StandardCharsets.UTF_8))); - } else { - field.append("keyId", encrypted.getKeyId()); - } - } - } else if (property instanceof IdentifiableJsonSchemaProperty.EncryptedJsonSchemaProperty encrypted) { - if (encrypted.getKeyId() != null) { - if (encrypted.getKeyId() instanceof String stringKey) { - field.append("keyId", - new BsonBinary(BsonBinarySubType.UUID_STANDARD, stringKey.getBytes(StandardCharsets.UTF_8))); - } else { - field.append("keyId", encrypted.getKeyId()); - } - } - } + if (!property.getTypes().isEmpty()) { + field.append("bsonType", property.getTypes().iterator().next().toBsonType().value()); + } + + if (property instanceof QueryableJsonSchemaProperty qp + && qp.getTargetProperty() instanceof IdentifiableJsonSchemaProperty.EncryptedJsonSchemaProperty encrypted + && encrypted.getKeyId() != null) { - if (property instanceof QueryableJsonSchemaProperty qproperty) { - field.append("queries", StreamSupport.stream(qproperty.getCharacteristics().spliterator(), false) - .map(QueryCharacteristic::toDocument).toList()); + if (encrypted.getKeyId() instanceof String stringKey) { + field.append("keyId", + new BsonBinary(BsonBinarySubType.UUID_STANDARD, stringKey.getBytes(StandardCharsets.UTF_8))); + } else { + field.append("keyId", encrypted.getKeyId()); } - if (!field.containsKey("keyId")) { - field.append("keyId", BsonNull.VALUE); + } else if (property instanceof IdentifiableJsonSchemaProperty.EncryptedJsonSchemaProperty encrypted + && encrypted.getKeyId() != null) { + if (encrypted.getKeyId() instanceof String stringKey) { + field.append("keyId", + new BsonBinary(BsonBinarySubType.UUID_STANDARD, stringKey.getBytes(StandardCharsets.UTF_8))); + } else { + field.append("keyId", encrypted.getKeyId()); } + } - converted.add(field); + if (property instanceof QueryableJsonSchemaProperty qp) { + field.append("queries", qp.getCharacteristics().map(QueryCharacteristic::toDocument).toList()); } - return converted; + + if (!field.containsKey("keyId")) { + field.append("keyId", BsonNull.VALUE); + } + + return field; } private List fromSchema() { @@ -848,19 +855,25 @@ private List fromSchema() { collectPaths(root, null, paths); List fields = new ArrayList<>(); - if (!paths.isEmpty()) { + if (paths.isEmpty()) { + return fields; + } - for (Entry entry : paths.entrySet()) { - Document field = new Document("path", entry.getKey()); - field.append("keyId", entry.getValue().getOrDefault("keyId", BsonNull.VALUE)); - if (entry.getValue().containsKey("bsonType")) { - field.append("bsonType", entry.getValue().get("bsonType")); - } - if (entry.getValue().containsKey("queries")) { - field.put("queries", entry.getValue().get("queries")); - } - fields.add(field); + for (Entry entry : paths.entrySet()) { + + Document field = new Document("path", entry.getKey()); + + field.append("keyId", entry.getValue().getOrDefault("keyId", BsonNull.VALUE)); + + if (entry.getValue().containsKey("bsonType")) { + field.append("bsonType", entry.getValue().get("bsonType")); + } + + if (entry.getValue().containsKey("queries")) { + field.put("queries", entry.getValue().get("queries")); } + + fields.add(field); } return fields; @@ -870,28 +883,29 @@ private List fromSchema() { private static void collectPaths(Document document, @Nullable String currentPath, Map paths) { if (document.containsKey("type") && document.get("type").equals("object")) { + Object o = document.get("properties"); - if (o == null) { + + if (!(o instanceof Document properties)) { return; } - if (o instanceof Document properties) { - for (Entry entry : properties.entrySet()) { - if (entry.getValue() instanceof Document nested) { - - String path = currentPath == null ? entry.getKey() : (currentPath + "." + entry.getKey()); - if (nested.containsKey("encrypt")) { - Document target = new Document(nested.get("encrypt", Document.class)); - if (nested.containsKey("queries")) { - List queries = nested.get("queries", List.class); - if (!queries.isEmpty() && queries.iterator().next() instanceof Document qd) { - target.putAll(qd); - } + for (Entry entry : properties.entrySet()) { + + if (entry.getValue() instanceof Document nested) { + + String path = currentPath == null ? entry.getKey() : (currentPath + "." + entry.getKey()); + if (nested.containsKey("encrypt")) { + Document target = new Document(nested.get("encrypt", Document.class)); + if (nested.containsKey("queries")) { + List queries = nested.get("queries", List.class); + if (!queries.isEmpty() && queries.iterator().next() instanceof Document qd) { + target.putAll(qd); } - paths.put(path, target); - } else { - collectPaths(nested, path, paths); } + paths.put(path, target); + } else { + collectPaths(nested, path, paths); } } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/QueryCharacteristics.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/QueryCharacteristics.java index 430449b50a..800e2e54e4 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/QueryCharacteristics.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/QueryCharacteristics.java @@ -24,6 +24,7 @@ import org.bson.Document; import org.springframework.data.domain.Range; import org.springframework.data.domain.Range.Bound; +import org.springframework.data.util.Streamable; import org.springframework.lang.Nullable; /** @@ -33,7 +34,7 @@ * @author Christoph Strobl * @since 4.5 */ -public class QueryCharacteristics implements Iterable { +public class QueryCharacteristics implements Streamable { /** * instance indicating none From effeab47f4c3af115085249b7cf4041233d98929 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Thu, 5 Jun 2025 09:28:32 +0200 Subject: [PATCH 10/21] Polishing. Fix test. See #4988 Original pull request: #4992 # Conflicts: # spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionOptions.java # spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/QueryCharacteristics.java --- .../MongoQueryableEncryptionCollectionCreationTests.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/MongoQueryableEncryptionCollectionCreationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/MongoQueryableEncryptionCollectionCreationTests.java index 7b935e2044..46c7b235e6 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/MongoQueryableEncryptionCollectionCreationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/MongoQueryableEncryptionCollectionCreationTests.java @@ -108,7 +108,7 @@ public void createsCollectionWithEncryptedFieldsCorrectly(CollectionOptions coll .containsEntry("queries", List.of(Document.parse( "{'queryType': 'range', 'contention': { '$numberLong' : '0' }, 'min': { '$numberLong' : '-1' }, 'max': { '$numberLong' : '1' }}"))); - assertThat(fields.get(2)).containsEntry("path", "encryptedDouble") // + assertThat(fields.get(3)).containsEntry("path", "encryptedDouble") // .containsEntry("bsonType", "double") // .containsEntry("queries", List.of(Document.parse( "{'queryType': 'range', 'contention': { '$numberLong' : '1' }, 'min': { '$numberDouble' : '-1.123' }, 'max': { '$numberDouble' : '1.123' }, 'precision': { '$numberInt' : '5'}}"))); @@ -119,13 +119,14 @@ private static Stream collectionOptions() { BsonBinary key1 = new BsonBinary(UUID.randomUUID(), UuidRepresentation.STANDARD); BsonBinary key2 = new BsonBinary(UUID.randomUUID(), UuidRepresentation.STANDARD); BsonBinary key3 = new BsonBinary(UUID.randomUUID(), UuidRepresentation.STANDARD); + BsonBinary key4 = new BsonBinary(UUID.randomUUID(), UuidRepresentation.STANDARD); CollectionOptions manualOptions = CollectionOptions.encryptedCollection(options -> options // .encrypted(int32("encrypted-but-not-queryable"), key1) // .queryable(encrypted(int32("encryptedInt")).keyId(key2), range().min(5).max(100).contention(1)) // .queryable(encrypted(JsonSchemaProperty.int64("nested.encryptedLong")).keyId(key3), range().min(-1L).max(1L).contention(0)) // - .queryable(encrypted(JsonSchemaProperty.float64("encryptedDouble")).keys(key3), + .queryable(encrypted(JsonSchemaProperty.float64("encryptedDouble")).keys(key4), range().min(-1.123D).max(1.123D).precision(5).contention(1))); CollectionOptions schemaOptions = CollectionOptions.encryptedCollection(MongoJsonSchema.builder() // @@ -134,7 +135,7 @@ private static Stream collectionOptions() { queryable(encrypted(int32("encryptedInt")).keyId(key2), List.of(range().min(5).max(100).contention(1)))) .property(queryable(encrypted(int64("nested.encryptedLong")).keyId(key3), List.of(range().min(-1L).max(1L).contention(0)))) - .property(queryable(encrypted(float64("encryptedDouble")).keyId(key3), + .property(queryable(encrypted(float64("encryptedDouble")).keyId(key4), List.of(range().min(-1.123D).max(1.123D).precision(5).contention(1)))) .build()); From ab7f6450229c62b8acbefc80bf1d7b4577b7803b Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Tue, 10 Jun 2025 08:03:03 +0200 Subject: [PATCH 11/21] Upgrade to MongoDB driver 5.5.1 Closes: #4996 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 97c17fdfaa..94b990efb7 100644 --- a/pom.xml +++ b/pom.xml @@ -27,7 +27,7 @@ multi spring-data-mongodb 3.5.1-SNAPSHOT - 5.5.0 + 5.5.1 1.19 From 7293d578ea92cae43f3649dd95fae07cf3c5bdd7 Mon Sep 17 00:00:00 2001 From: michaldo Date: Wed, 4 Jun 2025 23:32:49 +0200 Subject: [PATCH 12/21] Always include Collection tag in MongoDB observations. Use default "none" collection name when command doesn't define a collection. Signed-off-by: michaldo Closes: #4994 --- .../DefaultMongoHandlerObservationConvention.java | 3 +++ .../MongoObservationCommandListenerTests.java | 15 +++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/DefaultMongoHandlerObservationConvention.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/DefaultMongoHandlerObservationConvention.java index b823ce223b..84b31e5da4 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/DefaultMongoHandlerObservationConvention.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/DefaultMongoHandlerObservationConvention.java @@ -15,6 +15,7 @@ */ package org.springframework.data.mongodb.observability; +import io.micrometer.common.KeyValue; import io.micrometer.common.KeyValues; import java.net.InetSocketAddress; @@ -65,6 +66,8 @@ public KeyValues getLowCardinalityKeyValues(MongoHandlerContext context) { if (!ObjectUtils.isEmpty(context.getCollectionName())) { keyValues = keyValues .and(LowCardinalityCommandKeyNames.MONGODB_COLLECTION.withValue(context.getCollectionName())); + } else { + keyValues = keyValues.and(LowCardinalityCommandKeyNames.MONGODB_COLLECTION.withValue(KeyValue.NONE_VALUE)); } ConnectionDescription connectionDescription = context.getCommandStartedEvent().getConnectionDescription(); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/observability/MongoObservationCommandListenerTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/observability/MongoObservationCommandListenerTests.java index 5c2cb0b701..981e48a8e1 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/observability/MongoObservationCommandListenerTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/observability/MongoObservationCommandListenerTests.java @@ -20,6 +20,7 @@ import io.micrometer.common.KeyValues; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Tags; import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import io.micrometer.observation.Observation; @@ -98,6 +99,20 @@ void commandStartedShouldNotInstrumentWhenNoParentSampleInRequestContext() { assertThat(meterRegistry).hasMeterWithName("spring.data.mongodb.command.active"); } + @Test + void commandStartedShouldIncludeCollectionIfMissing() { + + // when + listener.commandStarted(new CommandStartedEvent(new MapRequestContext(), 0, 0, null, "some name", "hello", null)); + + // then + // although command 'hello' is collection-less, metric must have tag "db.mongodb.collection" + assertThat(meterRegistry).hasMeterWithNameAndTags( + "spring.data.mongodb.command.active", + Tags.of("db.mongodb.collection", "none")); + + } + @Test void successfullyCompletedCommandShouldCreateTimerWhenParentSampleInRequestContext() { From 772a359b415882894c6f662f6ece9c84bc7ae410 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 11 Jun 2025 14:35:01 +0200 Subject: [PATCH 13/21] Polishing. Replace if statement with ternary operator. See #4994 --- .../DefaultMongoHandlerObservationConvention.java | 10 +++------- .../MongoObservationCommandListenerTests.java | 6 +++--- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/DefaultMongoHandlerObservationConvention.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/DefaultMongoHandlerObservationConvention.java index 84b31e5da4..5767b50f28 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/DefaultMongoHandlerObservationConvention.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/DefaultMongoHandlerObservationConvention.java @@ -35,6 +35,7 @@ * * @author Greg Turnquist * @author Mark Paluch + * @author Michal Domagala * @since 4.0 */ class DefaultMongoHandlerObservationConvention implements MongoHandlerObservationConvention { @@ -56,19 +57,14 @@ public KeyValues getLowCardinalityKeyValues(MongoHandlerContext context) { if (!ObjectUtils.isEmpty(user)) { keyValues = keyValues.and(LowCardinalityCommandKeyNames.DB_USER.withValue(user)); } - } if (!ObjectUtils.isEmpty(context.getDatabaseName())) { keyValues = keyValues.and(LowCardinalityCommandKeyNames.DB_NAME.withValue(context.getDatabaseName())); } - if (!ObjectUtils.isEmpty(context.getCollectionName())) { - keyValues = keyValues - .and(LowCardinalityCommandKeyNames.MONGODB_COLLECTION.withValue(context.getCollectionName())); - } else { - keyValues = keyValues.and(LowCardinalityCommandKeyNames.MONGODB_COLLECTION.withValue(KeyValue.NONE_VALUE)); - } + keyValues = keyValues.and(LowCardinalityCommandKeyNames.MONGODB_COLLECTION.withValue( + ObjectUtils.isEmpty(context.getCollectionName()) ? KeyValue.NONE_VALUE : context.getCollectionName())); ConnectionDescription connectionDescription = context.getCommandStartedEvent().getConnectionDescription(); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/observability/MongoObservationCommandListenerTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/observability/MongoObservationCommandListenerTests.java index 981e48a8e1..35536e3921 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/observability/MongoObservationCommandListenerTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/observability/MongoObservationCommandListenerTests.java @@ -51,6 +51,7 @@ * @author Greg Turnquist * @author Mark Paluch * @author François Kha + * @author Michal Domagala */ class MongoObservationCommandListenerTests { @@ -99,8 +100,8 @@ void commandStartedShouldNotInstrumentWhenNoParentSampleInRequestContext() { assertThat(meterRegistry).hasMeterWithName("spring.data.mongodb.command.active"); } - @Test - void commandStartedShouldIncludeCollectionIfMissing() { + @Test // GH-4994 + void commandStartedShouldAlwaysIncludeCollection() { // when listener.commandStarted(new CommandStartedEvent(new MapRequestContext(), 0, 0, null, "some name", "hello", null)); @@ -110,7 +111,6 @@ void commandStartedShouldIncludeCollectionIfMissing() { assertThat(meterRegistry).hasMeterWithNameAndTags( "spring.data.mongodb.command.active", Tags.of("db.mongodb.collection", "none")); - } @Test From d0ee28155f6f9aff1602d9567cf1512cd24c0bef Mon Sep 17 00:00:00 2001 From: Ricardo Mello Date: Thu, 5 Jun 2025 12:18:59 -0300 Subject: [PATCH 14/21] Update Documentation. Updated code sample so that it includes the required `keyId(...)` configuration for Queryable Encryption using the Range algorithm. Closes: #4991 Signed-off-by: Ricardo Mello --- .../ROOT/pages/mongodb/mongo-encryption.adoc | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/antora/modules/ROOT/pages/mongodb/mongo-encryption.adoc b/src/main/antora/modules/ROOT/pages/mongodb/mongo-encryption.adoc index 04e0cb9838..e55c584ce0 100644 --- a/src/main/antora/modules/ROOT/pages/mongodb/mongo-encryption.adoc +++ b/src/main/antora/modules/ROOT/pages/mongodb/mongo-encryption.adoc @@ -140,11 +140,17 @@ Manual Collection Setup:: ==== [source,java,indent=0,subs="verbatim,quotes",role="primary"] ---- + +BsonBinary pinDK = clientEncryption.createDataKey("local", new com.mongodb.client.model.vault.DataKeyOptions()); +BsonBinary ssnDK = clientEncryption.createDataKey("local", new com.mongodb.client.model.vault.DataKeyOptions()); +BsonBinary ageDK = clientEncryption.createDataKey("local", new com.mongodb.client.model.vault.DataKeyOptions()); +BsonBinary signDK = clientEncryption.createDataKey("local", new com.mongodb.client.model.vault.DataKeyOptions()); + CollectionOptions collectionOptions = CollectionOptions.encryptedCollection(options -> options - .queryable(encrypted(string("ssn")).algorithm("Indexed"), equality().contention(0)) - .queryable(encrypted(int32("age")).algorithm("Range"), range().contention(8).min(0).max(150)) - .encrypted(string("pin")) - .queryable(encrypted(int64("address.sign")).algorithm("Range"), range().contention(2).min(-10L).max(10L)) + .encrypted(string("pin"), pinDK) + .queryable(encrypted(string("ssn")).algorithm("Indexed").keyId(ssnDK.asUuid()), equality().contention(0)) + .queryable(encrypted(int32("age")).algorithm("Range").keyId(ageDK.asUuid()), range().contention(8).min(0).max(150)) + .queryable(encrypted(int64("address.sign")).algorithm("Range").keyId(signDK.asUuid()), range().contention(2).min(-10L).max(10L)) ); mongoTemplate.createCollection(Patient.class, collectionOptions); <1> From 9fbf0f2fb8cd645370980c2bab484b49e5c32dcb Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Fri, 13 Jun 2025 13:39:13 +0200 Subject: [PATCH 15/21] Prepare 4.5.1 (2025.0.1). See #4974 --- pom.xml | 20 ++++---------------- src/main/resources/notice.txt | 3 ++- 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/pom.xml b/pom.xml index 94b990efb7..9a1a0cabc1 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ org.springframework.data.build spring-data-parent - 3.5.1-SNAPSHOT + 3.5.1 @@ -26,7 +26,7 @@ multi spring-data-mongodb - 3.5.1-SNAPSHOT + 3.5.1 5.5.1 1.19 @@ -157,20 +157,8 @@ - - spring-snapshot - https://repo.spring.io/snapshot - - true - - - false - - - - spring-milestone - https://repo.spring.io/milestone - + + diff --git a/src/main/resources/notice.txt b/src/main/resources/notice.txt index 3b6fc5c998..659f332b22 100644 --- a/src/main/resources/notice.txt +++ b/src/main/resources/notice.txt @@ -1,4 +1,4 @@ -Spring Data MongoDB 4.5 GA (2025.0.0) +Spring Data MongoDB 4.5.1 (2025.0.1) Copyright (c) [2010-2019] Pivotal Software, Inc. This product is licensed to you under the Apache License, Version 2.0 (the "License"). @@ -61,5 +61,6 @@ conditions of the subcomponent's license, as noted in the LICENSE file. + From 0c578029de293493956352c8862be388e071f01c Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Fri, 13 Jun 2025 13:39:34 +0200 Subject: [PATCH 16/21] Release version 4.5.1 (2025.0.1). See #4974 --- pom.xml | 2 +- spring-data-mongodb-distribution/pom.xml | 2 +- spring-data-mongodb/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 9a1a0cabc1..fec3e035d7 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-mongodb-parent - 4.5.1-SNAPSHOT + 4.5.1 pom Spring Data MongoDB diff --git a/spring-data-mongodb-distribution/pom.xml b/spring-data-mongodb-distribution/pom.xml index d758cf196b..c1af9f9ce8 100644 --- a/spring-data-mongodb-distribution/pom.xml +++ b/spring-data-mongodb-distribution/pom.xml @@ -15,7 +15,7 @@ org.springframework.data spring-data-mongodb-parent - 4.5.1-SNAPSHOT + 4.5.1 ../pom.xml diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml index 1299895c91..cc27dd7662 100644 --- a/spring-data-mongodb/pom.xml +++ b/spring-data-mongodb/pom.xml @@ -13,7 +13,7 @@ org.springframework.data spring-data-mongodb-parent - 4.5.1-SNAPSHOT + 4.5.1 ../pom.xml From 98a25fe5a4e623616cfa22a274275de834cb8456 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Fri, 13 Jun 2025 13:42:18 +0200 Subject: [PATCH 17/21] Prepare next development iteration. See #4974 --- pom.xml | 2 +- spring-data-mongodb-distribution/pom.xml | 2 +- spring-data-mongodb/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index fec3e035d7..daf569f7f9 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-mongodb-parent - 4.5.1 + 4.5.2-SNAPSHOT pom Spring Data MongoDB diff --git a/spring-data-mongodb-distribution/pom.xml b/spring-data-mongodb-distribution/pom.xml index c1af9f9ce8..55dee13dfb 100644 --- a/spring-data-mongodb-distribution/pom.xml +++ b/spring-data-mongodb-distribution/pom.xml @@ -15,7 +15,7 @@ org.springframework.data spring-data-mongodb-parent - 4.5.1 + 4.5.2-SNAPSHOT ../pom.xml diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml index cc27dd7662..7bb6ee73e9 100644 --- a/spring-data-mongodb/pom.xml +++ b/spring-data-mongodb/pom.xml @@ -13,7 +13,7 @@ org.springframework.data spring-data-mongodb-parent - 4.5.1 + 4.5.2-SNAPSHOT ../pom.xml From b4f4176040067842f5c348ed242f7455f5630977 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Fri, 13 Jun 2025 13:42:19 +0200 Subject: [PATCH 18/21] After release cleanups. See #4974 --- pom.xml | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index daf569f7f9..fe29d0570e 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ org.springframework.data.build spring-data-parent - 3.5.1 + 3.5.2-SNAPSHOT @@ -26,7 +26,7 @@ multi spring-data-mongodb - 3.5.1 + 3.5.2-SNAPSHOT 5.5.1 1.19 @@ -157,8 +157,20 @@ - - + + spring-snapshot + https://repo.spring.io/snapshot + + true + + + false + + + + spring-milestone + https://repo.spring.io/milestone + From 9e578a16dfca6c4c1307ab41bc7fc0abf5947d52 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Fri, 4 Jul 2025 14:31:30 +0200 Subject: [PATCH 19/21] Introduce `@EnableIfVectorSearchAvailable` to wait and conditionally skip tests. We now wait until a search index becomes available. If the search index doesn't come alive within 60 seconds, we skip that test (or test class). Closes: #5013 Original pull request: #5014 --- .../core/aggregation/VectorSearchTests.java | 4 +- .../index/VectorIndexIntegrationTests.java | 24 +++++-- .../mongodb/test/util/AtlasContainer.java | 25 ++++++- .../util/EnableIfVectorSearchAvailable.java | 19 +++++- .../mongodb/test/util/MongoExtensions.java | 2 +- .../test/util/MongoServerCondition.java | 67 +++++++++++++++++-- .../test/util/MongoTemplateExtension.java | 24 +++---- .../mongodb/test/util/MongoTestTemplate.java | 56 +++++++++++++++- .../mongodb/test/util/MongoTestUtils.java | 56 +++++++++++----- .../data/mongodb/test/util/ReplSetClient.java | 3 + 10 files changed, 233 insertions(+), 47 deletions(-) diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/VectorSearchTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/VectorSearchTests.java index 18991c1768..d5285701ab 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/VectorSearchTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/VectorSearchTests.java @@ -167,8 +167,8 @@ static void initIndexes() { template.searchIndexOps(WithVectorFields.class).createIndex(rawIndex); template.searchIndexOps(WithVectorFields.class).createIndex(wrapperIndex); - template.awaitIndexCreation(WithVectorFields.class, rawIndex.getName()); - template.awaitIndexCreation(WithVectorFields.class, wrapperIndex.getName()); + template.awaitSearchIndexCreation(WithVectorFields.class, rawIndex.getName()); + template.awaitSearchIndexCreation(WithVectorFields.class, wrapperIndex.getName()); } private static void assertScoreIsDecreasing(Iterable documents) { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/VectorIndexIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/VectorIndexIntegrationTests.java index dcd447f81a..1892264649 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/VectorIndexIntegrationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/VectorIndexIntegrationTests.java @@ -15,23 +15,26 @@ */ package org.springframework.data.mongodb.core.index; -import static org.assertj.core.api.Assertions.*; -import static org.awaitility.Awaitility.*; +import static org.assertj.core.api.Assertions.assertThatRuntimeException; +import static org.awaitility.Awaitility.await; import static org.springframework.data.mongodb.test.util.Assertions.assertThat; +import java.time.Duration; import java.util.List; import org.bson.Document; 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.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; - import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.index.VectorIndex.SimilarityFunction; import org.springframework.data.mongodb.core.mapping.Field; import org.springframework.data.mongodb.test.util.AtlasContainer; +import org.springframework.data.mongodb.test.util.EnableIfVectorSearchAvailable; +import org.springframework.data.mongodb.test.util.MongoServerCondition; import org.springframework.data.mongodb.test.util.MongoTestTemplate; import org.springframework.data.mongodb.test.util.MongoTestUtils; import org.springframework.lang.Nullable; @@ -48,6 +51,7 @@ * @author Christoph Strobl * @author Mark Paluch */ +@ExtendWith(MongoServerCondition.class) @Testcontainers(disabledWithoutDocker = true) class VectorIndexIntegrationTests { @@ -66,19 +70,22 @@ class VectorIndexIntegrationTests { @BeforeEach void init() { - template.createCollection(Movie.class); + + template.createCollectionIfNotExists(Movie.class); indexOps = template.searchIndexOps(Movie.class); } @AfterEach void cleanup() { + template.flush(Movie.class); template.searchIndexOps(Movie.class).dropAllIndexes(); - template.dropCollection(Movie.class); + template.awaitNoSearchIndexAvailable(Movie.class, Duration.ofSeconds(30)); } @ParameterizedTest // GH-4706 @ValueSource(strings = { "euclidean", "cosine", "dotProduct" }) + @EnableIfVectorSearchAvailable(collection = Movie.class) void createsSimpleVectorIndex(String similarityFunction) { VectorIndex idx = new VectorIndex("vector_index").addVector("plotEmbedding", @@ -98,6 +105,7 @@ void createsSimpleVectorIndex(String similarityFunction) { } @Test // GH-4706 + @EnableIfVectorSearchAvailable(collection = Movie.class) void dropIndex() { VectorIndex idx = new VectorIndex("vector_index").addVector("plotEmbedding", @@ -105,7 +113,7 @@ void dropIndex() { indexOps.createIndex(idx); - template.awaitIndexCreation(Movie.class, idx.getName()); + template.awaitSearchIndexCreation(Movie.class, idx.getName()); indexOps.dropIndex(idx.getName()); @@ -113,6 +121,7 @@ void dropIndex() { } @Test // GH-4706 + @EnableIfVectorSearchAvailable(collection = Movie.class) void statusChanges() throws InterruptedException { String indexName = "vector_index"; @@ -131,6 +140,7 @@ void statusChanges() throws InterruptedException { } @Test // GH-4706 + @EnableIfVectorSearchAvailable(collection = Movie.class) void exists() throws InterruptedException { String indexName = "vector_index"; @@ -148,6 +158,7 @@ void exists() throws InterruptedException { } @Test // GH-4706 + @EnableIfVectorSearchAvailable(collection = Movie.class) void updatesVectorIndex() throws InterruptedException { String indexName = "vector_index"; @@ -177,6 +188,7 @@ void updatesVectorIndex() throws InterruptedException { } @Test // GH-4706 + @EnableIfVectorSearchAvailable(collection = Movie.class) void createsVectorIndexWithFilters() throws InterruptedException { VectorIndex idx = new VectorIndex("vector_index") diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/AtlasContainer.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/AtlasContainer.java index c3a97a03bc..71fecd29b9 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/AtlasContainer.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/AtlasContainer.java @@ -16,12 +16,14 @@ package org.springframework.data.mongodb.test.util; import org.springframework.core.env.StandardEnvironment; - import org.testcontainers.mongodb.MongoDBAtlasLocalContainer; import org.testcontainers.utility.DockerImageName; +import com.github.dockerjava.api.command.InspectContainerResponse; + /** - * Extension to MongoDBAtlasLocalContainer. + * Extension to {@link MongoDBAtlasLocalContainer}. Registers mapped host an port as system properties + * ({@link #ATLAS_HOST}, {@link #ATLAS_PORT}). * * @author Christoph Strobl */ @@ -31,6 +33,9 @@ public class AtlasContainer extends MongoDBAtlasLocalContainer { private static final String DEFAULT_TAG = "8.0.0"; private static final String LATEST = "latest"; + public static final String ATLAS_HOST = "docker.mongodb.atlas.host"; + public static final String ATLAS_PORT = "docker.mongodb.atlas.port"; + private AtlasContainer(String dockerImageName) { super(DockerImageName.parse(dockerImageName)); } @@ -55,4 +60,20 @@ public static AtlasContainer tagged(String tag) { return new AtlasContainer(DEFAULT_IMAGE_NAME.withTag(tag)); } + @Override + protected void containerIsStarted(InspectContainerResponse containerInfo) { + + super.containerIsStarted(containerInfo); + + System.setProperty(ATLAS_HOST, getHost()); + System.setProperty(ATLAS_PORT, getMappedPort(27017).toString()); + } + + @Override + protected void containerIsStopping(InspectContainerResponse containerInfo) { + + System.clearProperty(ATLAS_HOST); + System.clearProperty(ATLAS_PORT); + super.containerIsStopping(containerInfo); + } } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/EnableIfVectorSearchAvailable.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/EnableIfVectorSearchAvailable.java index da008d9ee4..c81e197fec 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/EnableIfVectorSearchAvailable.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/EnableIfVectorSearchAvailable.java @@ -25,13 +25,30 @@ import org.junit.jupiter.api.extension.ExtendWith; /** + * {@link EnableIfVectorSearchAvailable} indicates a specific method can only be run in an environment that has a search + * server available. This means that not only the mongodb instance needs to have a + * {@literal searchIndexManagementHostAndPort} configured, but also that the search index sever is actually up and + * running, responding to a {@literal $listSearchIndexes} aggregation. + * * @author Christoph Strobl + * @since 5.0 + * @see Tag */ -@Target({ ElementType.TYPE, ElementType.METHOD }) +@Target({ ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @Documented @Tag("vector-search") @ExtendWith(MongoServerCondition.class) public @interface EnableIfVectorSearchAvailable { + /** + * @return the name of the collection used to run the {@literal $listSearchIndexes} aggregation. + */ + String collectionName() default ""; + + /** + * @return the type for resolving the name of the collection used to run the {@literal $listSearchIndexes} + * aggregation. The {@link #collectionName()} has precedence over the type. + */ + Class collection() default Object.class; } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoExtensions.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoExtensions.java index c90f7e999b..864bb6aa5d 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoExtensions.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoExtensions.java @@ -31,7 +31,7 @@ static class Client { static final String REACTIVE_REPLSET_KEY = "mongo.client.replset.reactive"; } - static class Termplate { + static class Template { static final Namespace NAMESPACE = Namespace.create(MongoTemplateExtension.class); static final String SYNC = "mongo.template.sync"; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoServerCondition.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoServerCondition.java index d811e0a1ef..35ca65c30a 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoServerCondition.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoServerCondition.java @@ -15,12 +15,21 @@ */ package org.springframework.data.mongodb.test.util; +import java.time.Duration; + import org.junit.jupiter.api.extension.ConditionEvaluationResult; import org.junit.jupiter.api.extension.ExecutionCondition; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.ExtensionContext.Namespace; import org.springframework.core.annotation.AnnotatedElementUtils; +import org.springframework.data.mongodb.MongoCollectionUtils; import org.springframework.data.util.Version; +import org.springframework.util.NumberUtils; +import org.springframework.util.StringUtils; +import org.testcontainers.shaded.org.awaitility.Awaitility; + +import com.mongodb.Function; +import com.mongodb.client.MongoClient; /** * @author Christoph Strobl @@ -42,10 +51,13 @@ public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext con } } - if(context.getTags().contains("vector-search")) { - if(!atlasEnvironment(context)) { + if (context.getTags().contains("vector-search")) { + if (!atlasEnvironment(context)) { return ConditionEvaluationResult.disabled("Disabled for servers not supporting Vector Search."); } + if (!isSearchIndexAvailable(context)) { + return ConditionEvaluationResult.disabled("Search index unavailable."); + } } if (context.getTags().contains("version-specific") && context.getElement().isPresent()) { @@ -90,8 +102,55 @@ private Version serverVersion(ExtensionContext context) { Version.class); } + private boolean isSearchIndexAvailable(ExtensionContext context) { + + EnableIfVectorSearchAvailable vectorSearchAvailable = AnnotatedElementUtils + .findMergedAnnotation(context.getElement().get(), EnableIfVectorSearchAvailable.class); + + if (vectorSearchAvailable == null) { + return true; + } + + String collectionName = StringUtils.hasText(vectorSearchAvailable.collectionName()) + ? vectorSearchAvailable.collectionName() + : MongoCollectionUtils.getPreferredCollectionName(vectorSearchAvailable.collection()); + + return context.getStore(NAMESPACE).getOrComputeIfAbsent("search-index-%s-available".formatted(collectionName), + (key) -> { + try { + doWithClient(client -> { + Awaitility.await().atMost(Duration.ofSeconds(60)).pollInterval(Duration.ofMillis(200)).until(() -> { + return MongoTestUtils.isSearchIndexReady(client, null, collectionName); + }); + return "done waiting for search index"; + }); + } catch (Exception e) { + return false; + } + return true; + }, Boolean.class); + + } + private boolean atlasEnvironment(ExtensionContext context) { - return context.getStore(NAMESPACE).getOrComputeIfAbsent(Version.class, (key) -> MongoTestUtils.isVectorSearchEnabled(), - Boolean.class); + + return context.getStore(NAMESPACE).getOrComputeIfAbsent("mongodb-atlas", + (key) -> doWithClient(MongoTestUtils::isVectorSearchEnabled), Boolean.class); + } + + private T doWithClient(Function function) { + + String host = System.getProperty(AtlasContainer.ATLAS_HOST); + String port = System.getProperty(AtlasContainer.ATLAS_PORT); + + if (StringUtils.hasText(host) && StringUtils.hasText(port)) { + try (MongoClient client = MongoTestUtils.client(host, NumberUtils.parseNumber(port, Integer.class))) { + return function.apply(client); + } + } + + try (MongoClient client = MongoTestUtils.client()) { + return function.apply(client); + } } } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoTemplateExtension.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoTemplateExtension.java index 301d1ef499..23e4a3db77 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoTemplateExtension.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoTemplateExtension.java @@ -33,7 +33,7 @@ import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.data.mongodb.core.ReactiveMongoOperations; -import org.springframework.data.mongodb.test.util.MongoExtensions.Termplate; +import org.springframework.data.mongodb.test.util.MongoExtensions.Template; import org.springframework.data.util.ParsingUtils; import org.springframework.util.ClassUtils; @@ -41,7 +41,7 @@ * JUnit {@link Extension} providing parameter resolution for synchronous and reactive MongoDB Template API objects. * * @author Christoph Strobl - * @see Template + * @see org.springframework.data.mongodb.test.util.Template * @see MongoTestTemplate * @see ReactiveMongoTestTemplate */ @@ -65,32 +65,32 @@ public void postProcessTestInstance(Object testInstance, ExtensionContext contex @Override public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException { - return super.supportsParameter(parameterContext, extensionContext) || parameterContext.isAnnotated(Template.class); + return super.supportsParameter(parameterContext, extensionContext) || parameterContext.isAnnotated(org.springframework.data.mongodb.test.util.Template.class); } @Override public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException { - if (parameterContext.getParameter().getAnnotation(Template.class) == null) { + if (parameterContext.getParameter().getAnnotation(org.springframework.data.mongodb.test.util.Template.class) == null) { return super.resolveParameter(parameterContext, extensionContext); } Class parameterType = parameterContext.getParameter().getType(); - return getMongoTemplate(parameterType, parameterContext.getParameter().getAnnotation(Template.class), + return getMongoTemplate(parameterType, parameterContext.getParameter().getAnnotation(org.springframework.data.mongodb.test.util.Template.class), extensionContext); } private void injectFields(ExtensionContext context, Object testInstance, Predicate predicate) { - AnnotationUtils.findAnnotatedFields(context.getRequiredTestClass(), Template.class, predicate).forEach(field -> { + AnnotationUtils.findAnnotatedFields(context.getRequiredTestClass(), org.springframework.data.mongodb.test.util.Template.class, predicate).forEach(field -> { assertValidFieldCandidate(field); try { ReflectionUtils.makeAccessible(field).set(testInstance, - getMongoTemplate(field.getType(), field.getAnnotation(Template.class), context)); + getMongoTemplate(field.getType(), field.getAnnotation(org.springframework.data.mongodb.test.util.Template.class), context)); } catch (Throwable t) { ExceptionUtils.throwAsUncheckedException(t); } @@ -107,14 +107,14 @@ private void assertSupportedType(String target, Class type) { if (!ClassUtils.isAssignable(MongoOperations.class, type) && !ClassUtils.isAssignable(ReactiveMongoOperations.class, type)) { throw new ExtensionConfigurationException( - String.format("Can only resolve @%s %s of type %s or %s but was: %s", Template.class.getSimpleName(), target, + String.format("Can only resolve @%s %s of type %s or %s but was: %s", org.springframework.data.mongodb.test.util.Template.class.getSimpleName(), target, MongoOperations.class.getName(), ReactiveMongoOperations.class.getName(), type.getName())); } } - private Object getMongoTemplate(Class type, Template options, ExtensionContext extensionContext) { + private Object getMongoTemplate(Class type, org.springframework.data.mongodb.test.util.Template options, ExtensionContext extensionContext) { - Store templateStore = extensionContext.getStore(MongoExtensions.Termplate.NAMESPACE); + Store templateStore = extensionContext.getStore(Template.NAMESPACE); boolean replSetClient = holdsReplSetClient(extensionContext) || options.replicaSet(); @@ -126,7 +126,7 @@ private Object getMongoTemplate(Class type, Template options, ExtensionContex if (ClassUtils.isAssignable(MongoOperations.class, type)) { - String key = Termplate.SYNC + "-" + dbName; + String key = Template.SYNC + "-" + dbName; return templateStore.getOrComputeIfAbsent(key, it -> { com.mongodb.client.MongoClient client = (com.mongodb.client.MongoClient) getMongoClient( @@ -137,7 +137,7 @@ private Object getMongoTemplate(Class type, Template options, ExtensionContex if (ClassUtils.isAssignable(ReactiveMongoOperations.class, type)) { - String key = Termplate.REACTIVE + "-" + dbName; + String key = Template.REACTIVE + "-" + dbName; return templateStore.getOrComputeIfAbsent(key, it -> { com.mongodb.reactivestreams.client.MongoClient client = (com.mongodb.reactivestreams.client.MongoClient) getMongoClient( diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoTestTemplate.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoTestTemplate.java index 40948a0e22..b296623062 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoTestTemplate.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoTestTemplate.java @@ -32,8 +32,12 @@ import org.testcontainers.shaded.org.awaitility.Awaitility; import com.mongodb.MongoWriteException; +import com.mongodb.ReadPreference; +import com.mongodb.WriteConcern; import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoClients; import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; /** * A {@link MongoTemplate} with configuration hooks and extension suitable for tests. @@ -133,6 +137,21 @@ public void flush(Object... objects) { }).collect(Collectors.toList())); } + public void createCollectionIfNotExists(Class type) { + createCollectionIfNotExists(getCollectionName(type)); + } + + public void createCollectionIfNotExists(String collectionName) { + + MongoDatabase database = getDb().withWriteConcern(WriteConcern.MAJORITY) + .withReadPreference(ReadPreference.primary()); + + boolean collectionExists = database.listCollections().filter(new Document("name", collectionName)).first() != null; + if (!collectionExists) { + createCollection(collectionName); + } + } + public void dropDatabase() { getDb().drop(); } @@ -156,11 +175,11 @@ public void doInCollection(Class entityClass, Consumer type, String indexName) { - awaitIndexCreation(getCollectionName(type), indexName, Duration.ofSeconds(10)); + public void awaitSearchIndexCreation(Class type, String indexName) { + awaitSearchIndexCreation(getCollectionName(type), indexName, Duration.ofSeconds(30)); } - public void awaitIndexCreation(String collectionName, String indexName, Duration timeout) { + public void awaitSearchIndexCreation(String collectionName, String indexName, Duration timeout) { Awaitility.await().atMost(timeout).pollInterval(Duration.ofMillis(200)).until(() -> { @@ -176,4 +195,35 @@ public void awaitIndexCreation(String collectionName, String indexName, Duration return false; }); } + + public void awaitIndexDeletion(String collectionName, String indexName, Duration timeout) { + + Awaitility.await().atMost(timeout).pollInterval(Duration.ofMillis(200)).until(() -> { + + List execute = this.execute(collectionName, + coll -> coll + .aggregate(List.of(Document.parse("{'$listSearchIndexes': { 'name' : '%s'}}".formatted(indexName)))) + .into(new ArrayList<>())); + for (Document doc : execute) { + if (doc.getString("name").equals(indexName)) { + return false; + } + } + return true; + }); + } + + public void awaitNoSearchIndexAvailable(String collectionName, Duration timeout) { + + Awaitility.await().atMost(timeout).pollInterval(Duration.ofMillis(200)).until(() -> { + + return this.execute(collectionName, coll -> coll.aggregate(List.of(Document.parse("{'$listSearchIndexes': {}}"))) + .into(new ArrayList<>()).isEmpty()); + + }); + } + + public void awaitNoSearchIndexAvailable(Class type, Duration timeout) { + awaitNoSearchIndexAvailable(getCollectionName(type), timeout); + } } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoTestUtils.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoTestUtils.java index f88caf80dd..742fd5b446 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoTestUtils.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoTestUtils.java @@ -15,12 +15,15 @@ */ package org.springframework.data.mongodb.test.util; +import org.jspecify.annotations.Nullable; +import org.springframework.util.StringUtils; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; import reactor.util.retry.Retry; import java.time.Duration; import java.util.List; +import java.util.concurrent.TimeUnit; import org.bson.Document; import org.springframework.core.env.Environment; @@ -30,6 +33,7 @@ import org.springframework.util.ObjectUtils; import com.mongodb.ConnectionString; +import com.mongodb.MongoClientSettings; import com.mongodb.ReadPreference; import com.mongodb.WriteConcern; import com.mongodb.client.MongoClient; @@ -68,6 +72,10 @@ public static MongoClient client(String host, int port) { } public static MongoClient client(ConnectionString connectionString) { + MongoClientSettings settings = MongoClientSettings.builder().applyConnectionString(connectionString) + .applyToSocketSettings(builder -> { + builder.connectTimeout(120, TimeUnit.SECONDS); + }).build(); return com.mongodb.client.MongoClients.create(connectionString, SpringDataMongoDB.driverInformation()); } @@ -176,11 +184,10 @@ public static void dropCollectionNow(String dbName, String collectionName, * @param collectionName must not be {@literal null}. * @param client must not be {@literal null}. */ - public static void dropCollectionNow(String dbName, String collectionName, - com.mongodb.client.MongoClient client) { + public static void dropCollectionNow(String dbName, String collectionName, com.mongodb.client.MongoClient client) { - com.mongodb.client.MongoDatabase database = client.getDatabase(dbName) - .withWriteConcern(WriteConcern.MAJORITY).withReadPreference(ReadPreference.primary()); + com.mongodb.client.MongoDatabase database = client.getDatabase(dbName).withWriteConcern(WriteConcern.MAJORITY) + .withReadPreference(ReadPreference.primary()); database.getCollection(collectionName).drop(); } @@ -205,11 +212,10 @@ public static void flushCollection(String dbName, String collectionName, .verifyComplete(); } - public static void flushCollection(String dbName, String collectionName, - com.mongodb.client.MongoClient client) { + 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()); + com.mongodb.client.MongoDatabase database = client.getDatabase(dbName).withWriteConcern(WriteConcern.MAJORITY) + .withReadPreference(ReadPreference.primary()); database.getCollection(collectionName).deleteMany(new Document()); } @@ -267,19 +273,36 @@ public static boolean serverIsReplSet() { @SuppressWarnings("unchecked") public static boolean isVectorSearchEnabled() { try (MongoClient client = MongoTestUtils.client()) { + return isVectorSearchEnabled(client); + } + } + public static boolean isVectorSearchEnabled(MongoClient client) { + try { return client.getDatabase("admin").runCommand(new Document("getCmdLineOpts", "1")).get("argv", List.class) - .stream().anyMatch(it -> { - if(it instanceof String cfgString) { - return cfgString.startsWith("searchIndexManagementHostAndPort"); - } - return false; - }); + .stream().anyMatch(it -> { + if (it instanceof String cfgString) { + return cfgString.startsWith("searchIndexManagementHostAndPort"); + } + return false; + }); } catch (Exception e) { return false; } } + public static boolean isSearchIndexReady(MongoClient client, @Nullable String database, String collectionName) { + + try { + MongoCollection collection = client.getDatabase(StringUtils.hasText(database) ? database : "test").getCollection(collectionName); + collection.aggregate(List.of(new Document("$listSearchIndexes", new Document()))); + } catch (Exception e) { + return false; + } + return true; + + } + public static Duration getTimeout() { return ObjectUtils.nullSafeEquals("jenkins", ENV.getProperty("user.name")) ? Duration.ofMillis(100) @@ -297,10 +320,11 @@ private static void giveTheServerALittleTimeToThink() { public static CollectionInfo readCollectionInfo(MongoDatabase db, String collectionName) { - List list = db.runCommand(new Document().append("listCollections", 1).append("filter", new Document("name", collectionName))) + List list = db + .runCommand(new Document().append("listCollections", 1).append("filter", new Document("name", collectionName))) .get("cursor", Document.class).get("firstBatch", List.class); - if(list.isEmpty()) { + if (list.isEmpty()) { throw new IllegalStateException(String.format("Collection %s not found.", collectionName)); } return CollectionInfo.from(list.get(0)); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/ReplSetClient.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/ReplSetClient.java index 8342c5b5ee..ede3687f70 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/ReplSetClient.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/ReplSetClient.java @@ -21,6 +21,8 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.junit.jupiter.api.extension.ExtendWith; + /** * Marks a field or method as to be autowired by JUnit's dependency injection facilities for injection of a MongoDB * client instance connected to a replica set. Depends on {@link MongoClientExtension}. @@ -34,6 +36,7 @@ @Target({ ElementType.FIELD, ElementType.PARAMETER }) @Retention(RetentionPolicy.RUNTIME) @Documented +@ExtendWith(MongoClientExtension.class) public @interface ReplSetClient { } From 9c21cb0fbd1bd98ba37b2bbed1ad5becaf0b5638 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Mon, 7 Jul 2025 14:55:09 +0200 Subject: [PATCH 20/21] Polishing. Simplify tests by using JUnit's meta-annotation pickup of ExtendWith. Hide extensions. See: #5013 Original pull request: #5014 --- .../ReactiveTransactionIntegrationTests.java | 4 +- ...uditingViaJavaConfigRepositoriesTests.java | 4 +- .../mongodb/config/ReactiveAuditingTests.java | 15 +++--- .../data/mongodb/core/ClientSessionTests.java | 4 +- ...DefaultBulkOperationsIntegrationTests.java | 6 +-- ...efaultIndexOperationsIntegrationTests.java | 10 ++-- .../DefaultReactiveBulkOperationsTests.java | 12 ++--- .../DefaultReactiveIndexOperationsTests.java | 4 +- .../core/DefaultScriptOperationsTests.java | 3 +- .../ExecutableFindOperationSupportTests.java | 3 +- ...ExecutableRemoveOperationSupportTests.java | 4 +- ...ExecutableUpdateOperationSupportTests.java | 4 +- .../mongodb/core/JsonSchemaQueryTests.java | 46 +++++++++---------- .../core/MongoTemplateCollationTests.java | 4 +- .../mongodb/core/MongoTemplateDbRefTests.java | 4 +- .../MongoTemplateDocumentReferenceTests.java | 5 +- .../MongoTemplateFieldProjectionTests.java | 4 +- .../core/MongoTemplateReplaceTests.java | 6 +-- .../core/MongoTemplateScrollTests.java | 5 +- .../data/mongodb/core/MongoTemplateTests.java | 5 +- .../core/MongoTemplateTransactionTests.java | 4 +- .../core/MongoTemplateUnwrappedTests.java | 4 +- .../core/MongoTemplateUpdateTests.java | 8 ++-- .../core/MongoTemplateValidationTests.java | 4 +- .../mongodb/core/MongoTemplateViewTests.java | 5 +- .../data/mongodb/core/NoExplicitIdTests.java | 4 +- .../mongodb/core/QueryByExampleTests.java | 4 +- ...tiveChangeStreamOperationSupportTests.java | 4 +- .../core/ReactiveClientSessionTests.java | 3 -- .../ReactiveFindOperationSupportTests.java | 4 +- .../ReactiveMongoTemplateCollationTests.java | 4 +- .../core/ReactiveMongoTemplateIndexTests.java | 6 +-- .../ReactiveMongoTemplateReplaceTests.java | 7 ++- .../ReactiveMongoTemplateScrollTests.java | 5 +- .../core/ReactiveMongoTemplateTests.java | 4 -- ...ReactiveMongoTemplateTransactionTests.java | 5 +- .../ReactiveMongoTemplateUpdateTests.java | 5 +- .../core/ReactiveMongoTemplateViewTests.java | 5 +- .../ReactiveRemoveOperationSupportTests.java | 5 +- .../ReactiveUpdateOperationSupportTests.java | 5 +- .../core/SessionBoundMongoTemplateTests.java | 4 +- .../core/aggregation/AggregationTests.java | 4 +- .../SetWindowFieldsOperationTests.java | 4 +- .../auditing/MongoTemplateAuditingTests.java | 3 +- .../ReactiveMongoTemplateAuditingTests.java | 3 +- .../convert/MappingMongoConverterTests.java | 6 +-- .../MongoConvertersIntegrationTests.java | 4 +- ...ableEncryptionCollectionCreationTests.java | 3 +- .../core/encryption/RangeEncryptionTests.java | 9 ++-- .../data/mongodb/core/geo/GeoJsonTests.java | 4 +- .../core/index/IndexingIntegrationTests.java | 4 +- .../mongodb/core/index/TextIndexTests.java | 4 +- .../index/VectorIndexIntegrationTests.java | 9 ++-- .../mongodb/core/mapping/MappingTests.java | 4 +- .../event/ApplicationContextEventTests.java | 4 +- .../core/messaging/ChangeStreamTests.java | 4 +- .../DefaultMessageListenerContainerTests.java | 5 +- .../core/messaging/TailableCursorTests.java | 4 +- .../mongodb/core/query/CriteriaTests.java | 4 +- .../mongodb/core/query/TextQueryTests.java | 4 +- .../core/schema/MongoJsonSchemaTests.java | 4 +- .../schema/ReactiveMongoJsonSchemaTests.java | 4 +- .../monitor/MongoMonitorIntegrationTests.java | 4 +- .../ComplexIdRepositoryIntegrationTests.java | 4 +- ...oRepositoryTextSearchIntegrationTests.java | 4 +- .../PersonRepositoryTransactionalTests.java | 4 +- ...ionedPersonRepositoryIntegrationTests.java | 3 +- .../support/SimpleMongoRepositoryTests.java | 5 +- .../util/EnableIfVectorSearchAvailable.java | 6 ++- .../test/util/MongoClientExtension.java | 6 +-- .../test/util/MongoServerCondition.java | 4 +- .../test/util/MongoTemplateExtension.java | 2 +- .../mongodb/test/util/MongoTestUtils.java | 5 +- 73 files changed, 152 insertions(+), 240 deletions(-) diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/ReactiveTransactionIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/ReactiveTransactionIntegrationTests.java index a6135939de..813012ab41 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/ReactiveTransactionIntegrationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/ReactiveTransactionIntegrationTests.java @@ -33,8 +33,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledIfSystemProperty; -import org.junit.jupiter.api.extension.ExtendWith; import org.junitpioneer.jupiter.SetSystemProperty; + import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -47,7 +47,6 @@ 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.MongoTestUtils; import org.springframework.transaction.TransactionSystemException; import org.springframework.transaction.annotation.EnableTransactionManagement; @@ -67,7 +66,6 @@ * @author Christoph Strobl * @author Yan Kardziyaka */ -@ExtendWith(MongoClientExtension.class) @EnableIfMongoServerVersion(isGreaterThanEqual = "4.0") @EnableIfReplicaSetAvailable @DisabledIfSystemProperty(named = "user.name", matches = "jenkins") diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/AuditingViaJavaConfigRepositoriesTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/AuditingViaJavaConfigRepositoriesTests.java index c3122d2850..4f9cab6011 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/AuditingViaJavaConfigRepositoriesTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/AuditingViaJavaConfigRepositoriesTests.java @@ -29,6 +29,7 @@ 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.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; @@ -48,7 +49,6 @@ import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; import org.springframework.data.mongodb.test.util.Client; -import org.springframework.data.mongodb.test.util.MongoClientExtension; import org.springframework.data.mongodb.test.util.MongoClientClosingTestConfiguration; import org.springframework.data.mongodb.test.util.MongoTestUtils; import org.springframework.stereotype.Repository; @@ -65,7 +65,7 @@ * @author Oliver Gierke * @author Mark Paluch */ -@ExtendWith({ MongoClientExtension.class, SpringExtension.class }) +@ExtendWith({ SpringExtension.class }) @ContextConfiguration class AuditingViaJavaConfigRepositoriesTests { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/ReactiveAuditingTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/ReactiveAuditingTests.java index fc47fd0572..2491677f01 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/ReactiveAuditingTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/ReactiveAuditingTests.java @@ -17,12 +17,6 @@ import static org.assertj.core.api.Assertions.*; -import org.springframework.core.ResolvableType; -import org.springframework.data.mapping.callback.EntityCallback; -import org.springframework.data.mongodb.core.mapping.event.AuditingEntityCallback; -import org.springframework.data.mongodb.core.mapping.event.ReactiveAuditingEntityCallback; -import org.springframework.data.mongodb.test.util.ReactiveMongoClientClosingTestConfiguration; -import org.springframework.test.util.ReflectionTestUtils; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; @@ -42,18 +36,23 @@ import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; +import org.springframework.core.ResolvableType; import org.springframework.data.annotation.Version; import org.springframework.data.domain.ReactiveAuditorAware; +import org.springframework.data.mapping.callback.EntityCallback; import org.springframework.data.mongodb.core.AuditablePerson; import org.springframework.data.mongodb.core.ReactiveMongoOperations; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; +import org.springframework.data.mongodb.core.mapping.event.AuditingEntityCallback; +import org.springframework.data.mongodb.core.mapping.event.ReactiveAuditingEntityCallback; import org.springframework.data.mongodb.repository.ReactiveMongoRepository; import org.springframework.data.mongodb.repository.config.EnableReactiveMongoRepositories; import org.springframework.data.mongodb.test.util.Client; -import org.springframework.data.mongodb.test.util.MongoClientExtension; +import org.springframework.data.mongodb.test.util.ReactiveMongoClientClosingTestConfiguration; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.util.ReflectionTestUtils; import com.mongodb.reactivestreams.client.MongoClient; @@ -62,7 +61,7 @@ * * @author Mark Paluch */ -@ExtendWith({ MongoClientExtension.class, SpringExtension.class }) +@ExtendWith({ SpringExtension.class }) @ContextConfiguration class ReactiveAuditingTests { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ClientSessionTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ClientSessionTests.java index 7fb1cddafb..dce9a838c1 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ClientSessionTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ClientSessionTests.java @@ -24,14 +24,13 @@ 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.data.annotation.Id; import org.springframework.data.mongodb.core.convert.MappingMongoConverter; import org.springframework.data.mongodb.core.mapping.DBRef; import org.springframework.data.mongodb.core.query.Query; 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.MongoTestUtils; import org.springframework.data.mongodb.test.util.ReplSetClient; import org.springframework.test.util.ReflectionTestUtils; @@ -46,7 +45,6 @@ * @author Christoph Strobl * @author Mark Paluch */ -@ExtendWith({ MongoClientExtension.class }) @EnableIfReplicaSetAvailable @EnableIfMongoServerVersion(isGreaterThanEqual = "4.0") class ClientSessionTests { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultBulkOperationsIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultBulkOperationsIntegrationTests.java index f0e7eb67b0..b3933cb373 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultBulkOperationsIntegrationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultBulkOperationsIntegrationTests.java @@ -16,7 +16,7 @@ package org.springframework.data.mongodb.core; import static org.assertj.core.api.Assertions.*; -import static org.springframework.data.domain.Sort.Direction.DESC; +import static org.springframework.data.domain.Sort.Direction.*; import java.util.ArrayList; import java.util.Arrays; @@ -27,10 +27,10 @@ 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.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; + import org.springframework.data.domain.Sort; import org.springframework.data.mongodb.BulkOperationException; import org.springframework.data.mongodb.core.BulkOperations.BulkMode; @@ -45,7 +45,6 @@ import org.springframework.data.mongodb.core.query.Update; import org.springframework.data.mongodb.core.query.UpdateDefinition; import org.springframework.data.mongodb.test.util.EnableIfMongoServerVersion; -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; @@ -63,7 +62,6 @@ * @author Christoph Strobl * @author Minsu Kim */ -@ExtendWith(MongoTemplateExtension.class) public class DefaultBulkOperationsIntegrationTests { static final String COLLECTION_NAME = "bulk_ops"; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultIndexOperationsIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultIndexOperationsIntegrationTests.java index 78a6e6b496..3907841dd2 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultIndexOperationsIntegrationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultIndexOperationsIntegrationTests.java @@ -15,15 +15,15 @@ */ package org.springframework.data.mongodb.core; -import static org.springframework.data.mongodb.core.index.PartialIndexFilter.of; -import static org.springframework.data.mongodb.core.query.Criteria.where; -import static org.springframework.data.mongodb.test.util.Assertions.assertThat; +import static org.springframework.data.mongodb.core.index.PartialIndexFilter.*; +import static org.springframework.data.mongodb.core.query.Criteria.*; +import static org.springframework.data.mongodb.test.util.Assertions.*; import org.bson.BsonDocument; 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.data.domain.Sort.Direction; import org.springframework.data.mongodb.core.index.Index; import org.springframework.data.mongodb.core.index.IndexDefinition; @@ -32,7 +32,6 @@ 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.MongoTemplateExtension; import org.springframework.data.mongodb.test.util.MongoTestTemplate; import org.springframework.data.mongodb.test.util.Template; import org.springframework.util.ObjectUtils; @@ -47,7 +46,6 @@ * @author Oliver Gierke * @author Mark Paluch */ -@ExtendWith(MongoTemplateExtension.class) public class DefaultIndexOperationsIntegrationTests { static final String COLLECTION_NAME = "default-index-operations-tests"; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultReactiveBulkOperationsTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultReactiveBulkOperationsTests.java index 79bf563159..0db2f8be91 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultReactiveBulkOperationsTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultReactiveBulkOperationsTests.java @@ -16,11 +16,8 @@ package org.springframework.data.mongodb.core; import static org.assertj.core.api.Assertions.*; -import static org.springframework.data.domain.Sort.Direction.DESC; +import static org.springframework.data.domain.Sort.Direction.*; -import org.springframework.data.domain.Sort; -import org.springframework.data.mongodb.core.mapping.Field; -import org.springframework.data.mongodb.test.util.EnableIfMongoServerVersion; import reactor.core.publisher.Flux; import reactor.test.StepVerifier; @@ -32,21 +29,23 @@ 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.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.EnumSource; import org.junit.jupiter.params.provider.MethodSource; + import org.springframework.dao.DuplicateKeyException; +import org.springframework.data.domain.Sort; import org.springframework.data.mongodb.core.BulkOperations.BulkMode; import org.springframework.data.mongodb.core.DefaultReactiveBulkOperations.ReactiveBulkOperationContext; import org.springframework.data.mongodb.core.convert.QueryMapper; import org.springframework.data.mongodb.core.convert.UpdateMapper; +import org.springframework.data.mongodb.core.mapping.Field; 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.EnableIfMongoServerVersion; import org.springframework.data.mongodb.test.util.ReactiveMongoTestTemplate; import org.springframework.data.mongodb.test.util.Template; @@ -59,7 +58,6 @@ * * @author Christoph Strobl */ -@ExtendWith(MongoTemplateExtension.class) class DefaultReactiveBulkOperationsTests { static final String COLLECTION_NAME = "reactive-bulk-ops"; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultReactiveIndexOperationsTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultReactiveIndexOperationsTests.java index 5ecce43102..58ded58983 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultReactiveIndexOperationsTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultReactiveIndexOperationsTests.java @@ -26,7 +26,7 @@ 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.data.domain.Sort.Direction; import org.springframework.data.mongodb.core.convert.QueryMapper; import org.springframework.data.mongodb.core.index.Index; @@ -35,7 +35,6 @@ 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.MongoTemplateExtension; import org.springframework.data.mongodb.test.util.ReactiveMongoTestTemplate; import org.springframework.data.mongodb.test.util.Template; @@ -47,7 +46,6 @@ * @author Mark Paluch * @author Mathieu Ouellet */ -@ExtendWith(MongoTemplateExtension.class) public class DefaultReactiveIndexOperationsTests { @Template(initialEntitySet = DefaultIndexOperationsIntegrationTestsSample.class) // diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultScriptOperationsTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultScriptOperationsTests.java index 6331e1dbc7..15ea5ddbf5 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultScriptOperationsTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultScriptOperationsTests.java @@ -33,7 +33,6 @@ import org.springframework.data.mongodb.core.script.NamedMongoScript; 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.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; @@ -46,7 +45,7 @@ * @author Oliver Gierke * @since 1.7 */ -@ExtendWith({ MongoClientExtension.class, SpringExtension.class }) +@ExtendWith({ SpringExtension.class }) @EnableIfMongoServerVersion(isLessThan = "4.1.0") @ContextConfiguration public class DefaultScriptOperationsTests { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ExecutableFindOperationSupportTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ExecutableFindOperationSupportTests.java index eac248e69a..89af16c252 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ExecutableFindOperationSupportTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ExecutableFindOperationSupportTests.java @@ -46,7 +46,6 @@ import org.springframework.data.mongodb.core.query.BasicQuery; import org.springframework.data.mongodb.core.query.NearQuery; import org.springframework.data.mongodb.test.util.DirtiesStateExtension; -import org.springframework.data.mongodb.test.util.MongoTemplateExtension; import org.springframework.data.mongodb.test.util.MongoTestTemplate; import org.springframework.data.mongodb.test.util.Template; @@ -56,7 +55,7 @@ * @author Christoph Strobl * @author Mark Paluch */ -@ExtendWith({ MongoTemplateExtension.class, DirtiesStateExtension.class }) +@ExtendWith({ DirtiesStateExtension.class }) @TestInstance(TestInstance.Lifecycle.PER_CLASS) class ExecutableFindOperationSupportTests implements StateFunctions { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ExecutableRemoveOperationSupportTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ExecutableRemoveOperationSupportTests.java index 621e2a0764..703ead5e95 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ExecutableRemoveOperationSupportTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ExecutableRemoveOperationSupportTests.java @@ -24,10 +24,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.mapping.Field; -import org.springframework.data.mongodb.test.util.MongoTemplateExtension; import org.springframework.data.mongodb.test.util.MongoTestTemplate; import org.springframework.data.mongodb.test.util.Template; @@ -39,7 +38,6 @@ * @author Christoph Strobl * @author Mark Paluch */ -@ExtendWith(MongoTemplateExtension.class) class ExecutableRemoveOperationSupportTests { private static final String STAR_WARS = "star-wars"; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ExecutableUpdateOperationSupportTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ExecutableUpdateOperationSupportTests.java index e7f50dab53..dd99fe224b 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ExecutableUpdateOperationSupportTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ExecutableUpdateOperationSupportTests.java @@ -25,12 +25,11 @@ import org.bson.BsonString; 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.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.MongoTemplateExtension; import org.springframework.data.mongodb.test.util.MongoTestTemplate; import org.springframework.data.mongodb.test.util.Template; @@ -42,7 +41,6 @@ * @author Christoph Strobl * @author Mark Paluch */ -@ExtendWith(MongoTemplateExtension.class) class ExecutableUpdateOperationSupportTests { private static final String STAR_WARS = "star-wars"; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/JsonSchemaQueryTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/JsonSchemaQueryTests.java index 3afcef93d0..9ec050a955 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/JsonSchemaQueryTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/JsonSchemaQueryTests.java @@ -27,14 +27,13 @@ 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.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Field; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.schema.JsonSchemaProperty; import org.springframework.data.mongodb.core.schema.MongoJsonSchema; 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; @@ -42,20 +41,19 @@ * @author Christoph Strobl * @author Mark Paluch */ -@ExtendWith(MongoTemplateExtension.class) public class JsonSchemaQueryTests { - public static final String DATABASE_NAME = "json-schema-query-tests"; + private static final String DATABASE_NAME = "json-schema-query-tests"; - static @Client com.mongodb.reactivestreams.client.MongoClient reactiveClient; + private static @Client com.mongodb.reactivestreams.client.MongoClient reactiveClient; @Template(database = DATABASE_NAME, initialEntitySet = Person.class) // - static MongoTestTemplate template; + private static MongoTestTemplate template; - Person jellyBelly, roseSpringHeart, kazmardBoombub; + private Person jellyBelly, roseSpringHeart, kazmardBoombub; @BeforeEach - public void setUp() { + void setUp() { template.flush(); @@ -90,7 +88,7 @@ public void setUp() { } @Test // DATAMONGO-1835 - public void createsWorkingSchema() { + void createsWorkingSchema() { try { template.dropCollection("person_schema"); @@ -102,7 +100,7 @@ public void createsWorkingSchema() { } @Test // DATAMONGO-1835 - public void queriesBooleanType() { + void queriesBooleanType() { MongoJsonSchema schema = MongoJsonSchema.builder().properties(JsonSchemaProperty.bool("alive")).build(); @@ -111,7 +109,7 @@ public void queriesBooleanType() { } @Test // DATAMONGO-1835 - public void findsDocumentsWithRequiredFieldsCorrectly() { + void findsDocumentsWithRequiredFieldsCorrectly() { MongoJsonSchema schema = MongoJsonSchema.builder().required("address").build(); @@ -120,7 +118,7 @@ public void findsDocumentsWithRequiredFieldsCorrectly() { } @Test // DATAMONGO-1835 - public void findsDocumentsWithRequiredFieldsReactively() { + void findsDocumentsWithRequiredFieldsReactively() { MongoJsonSchema schema = MongoJsonSchema.builder().required("address").build(); @@ -130,7 +128,7 @@ public void findsDocumentsWithRequiredFieldsReactively() { } @Test // DATAMONGO-1835 - public void findsDocumentsWithBsonFieldTypesCorrectly() { + void findsDocumentsWithBsonFieldTypesCorrectly() { MongoJsonSchema schema = MongoJsonSchema.builder().property(int32("value")).build(); @@ -139,7 +137,7 @@ public void findsDocumentsWithBsonFieldTypesCorrectly() { } @Test // DATAMONGO-1835 - public void findsDocumentsWithJsonFieldTypesCorrectly() { + void findsDocumentsWithJsonFieldTypesCorrectly() { MongoJsonSchema schema = MongoJsonSchema.builder().property(number("value")).build(); @@ -148,7 +146,7 @@ public void findsDocumentsWithJsonFieldTypesCorrectly() { } @Test // DATAMONGO-1835 - public void combineSchemaWithOtherCriteria() { + void combineSchemaWithOtherCriteria() { MongoJsonSchema schema = MongoJsonSchema.builder().property(number("value")).build(); @@ -158,7 +156,7 @@ public void combineSchemaWithOtherCriteria() { } @Test // DATAMONGO-1835 - public void usesMappedFieldNameForRequiredProperties() { + void usesMappedFieldNameForRequiredProperties() { MongoJsonSchema schema = MongoJsonSchema.builder().required("name").build(); @@ -167,7 +165,7 @@ public void usesMappedFieldNameForRequiredProperties() { } @Test // DATAMONGO-1835 - public void usesMappedFieldNameForProperties() { + void usesMappedFieldNameForProperties() { MongoJsonSchema schema = MongoJsonSchema.builder().property(string("name").matching("^R.*")).build(); @@ -176,7 +174,7 @@ public void usesMappedFieldNameForProperties() { } @Test // DATAMONGO-1835 - public void mapsNestedFieldName() { + void mapsNestedFieldName() { MongoJsonSchema schema = MongoJsonSchema.builder() // .required("address") // @@ -187,7 +185,7 @@ public void mapsNestedFieldName() { } @Test // DATAMONGO-1835 - public void mapsEnumValuesCorrectly() { + void mapsEnumValuesCorrectly() { MongoJsonSchema schema = MongoJsonSchema.builder() .property(untyped("gender").possibleValues(Gender.PIXY, Gender.GOBLIN)).build(); @@ -197,19 +195,19 @@ public void mapsEnumValuesCorrectly() { } @Test // DATAMONGO-1835 - public void useTypeOperatorOnFieldLevel() { + void useTypeOperatorOnFieldLevel() { assertThat(template.find(query(where("value").type(Type.intType())), Person.class)).containsExactly(jellyBelly); } @Test // DATAMONGO-1835 - public void useTypeOperatorWithMultipleTypesOnFieldLevel() { + void useTypeOperatorWithMultipleTypesOnFieldLevel() { assertThat(template.find(query(where("value").type(Type.intType(), Type.stringType())), Person.class)) .containsExactlyInAnyOrder(jellyBelly, kazmardBoombub); } @Test // DATAMONGO-1835 - public void findsWithSchemaReturningRawDocument() { + void findsWithSchemaReturningRawDocument() { MongoJsonSchema schema = MongoJsonSchema.builder().required("address").build(); @@ -237,7 +235,7 @@ public String getName() { return this.name; } - public Gender getGender() { + Gender getGender() { return this.gender; } @@ -249,7 +247,7 @@ public Object getValue() { return this.value; } - public boolean isAlive() { + boolean isAlive() { return this.alive; } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateCollationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateCollationTests.java index deaffab4b2..bbb3c0eaef 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateCollationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateCollationTests.java @@ -26,6 +26,7 @@ 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.data.mongodb.config.AbstractMongoClientConfiguration; @@ -33,7 +34,6 @@ import org.springframework.data.mongodb.core.query.Collation.Alternate; import org.springframework.data.mongodb.core.query.Collation.ComparisonLevel; import org.springframework.data.mongodb.test.util.Client; -import org.springframework.data.mongodb.test.util.MongoClientExtension; import org.springframework.test.context.junit.jupiter.SpringExtension; import com.mongodb.client.MongoClient; @@ -42,7 +42,7 @@ * @author Christoph Strobl * @author Mark Paluch */ -@ExtendWith({ MongoClientExtension.class, SpringExtension.class }) +@ExtendWith({ SpringExtension.class }) public class MongoTemplateCollationTests { public static final String COLLECTION_NAME = "collation-1"; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateDbRefTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateDbRefTests.java index 498bfec17a..9cfe924256 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateDbRefTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateDbRefTests.java @@ -27,7 +27,7 @@ import org.bson.types.ObjectId; 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.convert.LazyLoadingProxy; import org.springframework.data.mongodb.core.convert.LazyLoadingTestUtils; @@ -35,7 +35,6 @@ import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.MongoId; import org.springframework.data.mongodb.core.query.Query; -import org.springframework.data.mongodb.test.util.MongoTemplateExtension; import org.springframework.data.mongodb.test.util.MongoTestTemplate; import org.springframework.data.mongodb.test.util.Template; @@ -47,7 +46,6 @@ * * @author Christoph Strobl */ -@ExtendWith(MongoTemplateExtension.class) public class MongoTemplateDbRefTests { @Template(database = "mongo-template-dbref-tests", diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateDocumentReferenceTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateDocumentReferenceTests.java index 51b3b005a5..6628bd91ca 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateDocumentReferenceTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateDocumentReferenceTests.java @@ -32,7 +32,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; + import org.springframework.core.convert.converter.Converter; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.ReadOnlyProperty; @@ -46,7 +46,6 @@ import org.springframework.data.mongodb.core.mapping.MongoId; 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.lang.Nullable; @@ -59,7 +58,7 @@ * @author Christoph Strobl * @author Julia Lee */ -@ExtendWith(MongoClientExtension.class) + public class MongoTemplateDocumentReferenceTests { public static final String DB_NAME = "document-reference-tests"; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateFieldProjectionTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateFieldProjectionTests.java index 1cbb5ab519..18f268124b 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateFieldProjectionTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateFieldProjectionTests.java @@ -23,7 +23,7 @@ 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.mongodb.MongoExpression; import org.springframework.data.mongodb.core.aggregation.AggregationSpELExpression; @@ -33,7 +33,6 @@ import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.test.util.EnableIfMongoServerVersion; -import org.springframework.data.mongodb.test.util.MongoTemplateExtension; import org.springframework.data.mongodb.test.util.MongoTestTemplate; import org.springframework.data.mongodb.test.util.Template; @@ -44,7 +43,6 @@ * @author Mark Paluch * @author Giacomo Baso */ -@ExtendWith(MongoTemplateExtension.class) @EnableIfMongoServerVersion(isGreaterThanEqual = "4.4") class MongoTemplateFieldProjectionTests { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateReplaceTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateReplaceTests.java index 6b8e158e55..32068e1efc 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateReplaceTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateReplaceTests.java @@ -32,16 +32,14 @@ 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.dao.DataIntegrityViolationException; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Direction; -import org.springframework.data.mongodb.core.aggregation.AggregationUpdate; import org.springframework.data.mongodb.core.mapping.Field; import org.springframework.data.mongodb.core.query.Query; 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 com.mongodb.client.MongoClient; import com.mongodb.client.MongoCollection; @@ -51,7 +49,7 @@ /** * @author Christoph Strobl */ -@ExtendWith(MongoClientExtension.class) + public class MongoTemplateReplaceTests { static final String DB_NAME = "mongo-template-replace-tests"; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateScrollTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateScrollTests.java index 766929c732..baca2f0411 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateScrollTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateScrollTests.java @@ -28,10 +28,10 @@ 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.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; + import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.support.GenericApplicationContext; import org.springframework.data.annotation.PersistenceCreator; @@ -45,7 +45,6 @@ import org.springframework.data.mongodb.core.mapping.Field; import org.springframework.data.mongodb.core.query.Query; 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.lang.Nullable; import org.springframework.util.ObjectUtils; @@ -58,7 +57,7 @@ * @author Mark Paluch * @author Christoph Strobl */ -@ExtendWith(MongoClientExtension.class) + class MongoTemplateScrollTests { static @Client MongoClient client; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java index 6aaec4011e..e1666e372d 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java @@ -34,11 +34,10 @@ import java.util.stream.IntStream; import java.util.stream.Stream; -import org.bson.Document; import org.bson.types.ObjectId; 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; @@ -87,7 +86,6 @@ 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.MongoTestTemplate; import org.springframework.data.mongodb.test.util.MongoTestUtils; import org.springframework.data.mongodb.test.util.MongoVersion; @@ -129,7 +127,6 @@ * @author Jakub Zurawa * @author Florian Lüdiger */ -@ExtendWith(MongoClientExtension.class) public class MongoTemplateTests { public static final String DB_NAME = "mongo-template-tests"; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTransactionTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTransactionTests.java index ec0ab192fa..1d9688cef6 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTransactionTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTransactionTests.java @@ -33,6 +33,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junitpioneer.jupiter.SetSystemProperty; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -49,7 +50,6 @@ import org.springframework.data.mongodb.test.util.AfterTransactionAssertion; 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.ReplSetClient; import org.springframework.test.annotation.Rollback; import org.springframework.test.context.ContextConfiguration; @@ -74,7 +74,7 @@ * @author Yan Kardziyaka * @currentRead Shadow's Edge - Brent Weeks */ -@ExtendWith({ MongoClientExtension.class, SpringExtension.class }) +@ExtendWith({ SpringExtension.class }) @EnableIfReplicaSetAvailable @EnableIfMongoServerVersion(isGreaterThanEqual = "4.0") @ContextConfiguration diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnwrappedTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnwrappedTests.java index b8fc2986c2..bb392d0a0a 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnwrappedTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnwrappedTests.java @@ -24,11 +24,10 @@ import java.util.Objects; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; + import org.springframework.data.mongodb.core.mapping.Field; import org.springframework.data.mongodb.core.mapping.Unwrapped; import org.springframework.data.mongodb.core.query.Query; -import org.springframework.data.mongodb.test.util.MongoTemplateExtension; import org.springframework.data.mongodb.test.util.Template; /** @@ -36,7 +35,6 @@ * * @author Christoph Strobl */ -@ExtendWith(MongoTemplateExtension.class) class MongoTemplateUnwrappedTests { private static @Template MongoTemplate template; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUpdateTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUpdateTests.java index 4249506d77..6f13481a64 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUpdateTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUpdateTests.java @@ -15,7 +15,7 @@ */ package org.springframework.data.mongodb.core; -import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.*; import java.util.ArrayList; import java.util.Arrays; @@ -24,13 +24,12 @@ import java.util.Objects; import java.util.stream.Stream; -import com.mongodb.client.result.UpdateResult; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; + import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Version; import org.springframework.data.domain.Sort; @@ -47,16 +46,15 @@ import org.springframework.data.mongodb.core.query.Update; import org.springframework.data.mongodb.core.query.UpdateDefinition; import org.springframework.data.mongodb.test.util.EnableIfMongoServerVersion; -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.MongoCollection; +import com.mongodb.client.result.UpdateResult; /** * @author Christoph Strobl */ -@ExtendWith({ MongoTemplateExtension.class }) class MongoTemplateUpdateTests { @Template(initialEntitySet = { Score.class, Versioned.class, Book.class }) // diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateValidationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateValidationTests.java index 18da8c516d..1e22f79113 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateValidationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateValidationTests.java @@ -28,6 +28,7 @@ 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.DataIntegrityViolationException; @@ -38,7 +39,6 @@ import org.springframework.data.mongodb.core.query.Criteria; 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 org.springframework.lang.Nullable; import org.springframework.test.context.junit.jupiter.SpringExtension; @@ -56,7 +56,7 @@ * @author Christoph Strobl * @author Julia Lee */ -@ExtendWith({ MongoClientExtension.class, SpringExtension.class }) +@ExtendWith({ SpringExtension.class }) public class MongoTemplateValidationTests { static final String COLLECTION_NAME = "validation-1"; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateViewTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateViewTests.java index 15fe90a34a..b630ed19c6 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateViewTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateViewTests.java @@ -27,13 +27,12 @@ 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.mongodb.core.aggregation.AggregationPipeline; import org.springframework.data.mongodb.core.mapping.Field; import org.springframework.data.mongodb.core.query.Collation; import org.springframework.data.mongodb.test.util.Client; import org.springframework.data.mongodb.test.util.CollectionInfo; -import org.springframework.data.mongodb.test.util.MongoClientExtension; import org.springframework.data.mongodb.test.util.MongoTestUtils; import com.mongodb.client.MongoClient; @@ -43,7 +42,7 @@ * * @author Christoph Strobl */ -@ExtendWith(MongoClientExtension.class) + public class MongoTemplateViewTests { static @Client MongoClient client; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/NoExplicitIdTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/NoExplicitIdTests.java index 8604fd960d..bbd53a8b1f 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/NoExplicitIdTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/NoExplicitIdTests.java @@ -27,6 +27,7 @@ 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; @@ -35,7 +36,6 @@ import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; import org.springframework.data.mongodb.test.util.Client; -import org.springframework.data.mongodb.test.util.MongoClientExtension; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; @@ -47,7 +47,7 @@ * @author Christoph Strobl * @author Mark Paluch */ -@ExtendWith({ MongoClientExtension.class, SpringExtension.class }) +@ExtendWith({ SpringExtension.class }) @ContextConfiguration public class NoExplicitIdTests { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/QueryByExampleTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/QueryByExampleTests.java index 52ee79aa1f..f27e4774ed 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/QueryByExampleTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/QueryByExampleTests.java @@ -22,7 +22,7 @@ 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.Example; import org.springframework.data.domain.ExampleMatcher; @@ -31,7 +31,6 @@ 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.MongoTemplateExtension; import org.springframework.data.mongodb.test.util.MongoTestTemplate; import org.springframework.data.mongodb.test.util.Template; @@ -42,7 +41,6 @@ * @author Mark Paluch * @author Oliver Gierke */ -@ExtendWith(MongoTemplateExtension.class) public class QueryByExampleTests { @Template(initialEntitySet = Person.class) // diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveChangeStreamOperationSupportTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveChangeStreamOperationSupportTests.java index 23d1d03b43..4263902240 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveChangeStreamOperationSupportTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveChangeStreamOperationSupportTests.java @@ -31,11 +31,9 @@ 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.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.MongoTestUtils; import org.springframework.data.mongodb.test.util.ReplSetClient; @@ -47,7 +45,7 @@ * @author Christoph Strobl * @currentRead Dawn Cook - The Decoy Princess */ -@ExtendWith(MongoClientExtension.class) + @EnableIfReplicaSetAvailable public class ReactiveChangeStreamOperationSupportTests { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveClientSessionTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveClientSessionTests.java index 9c49a3a743..b1d1d992f5 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveClientSessionTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveClientSessionTests.java @@ -28,12 +28,10 @@ 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.data.mongodb.core.query.Query; 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.MongoTestUtils; import com.mongodb.ClientSessionOptions; @@ -45,7 +43,6 @@ * @author Mark Paluch * @currentRead Beyond the Shadows - Brent Weeks */ -@ExtendWith(MongoClientExtension.class) @EnableIfReplicaSetAvailable public class ReactiveClientSessionTests { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveFindOperationSupportTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveFindOperationSupportTests.java index f23e973202..3a6279cd53 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveFindOperationSupportTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveFindOperationSupportTests.java @@ -37,6 +37,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.extension.ExtendWith; + import org.springframework.beans.factory.annotation.Value; import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.dao.InvalidDataAccessApiUsageException; @@ -50,7 +51,6 @@ import org.springframework.data.mongodb.core.query.NearQuery; import org.springframework.data.mongodb.test.util.Client; import org.springframework.data.mongodb.test.util.DirtiesStateExtension; -import org.springframework.data.mongodb.test.util.MongoClientExtension; import com.mongodb.client.MongoClient; @@ -61,7 +61,7 @@ * @author Christoph Strobl * @author Juergen Zimmermann */ -@ExtendWith({ MongoClientExtension.class, DirtiesStateExtension.class }) +@ExtendWith({ DirtiesStateExtension.class }) @TestInstance(TestInstance.Lifecycle.PER_CLASS) class ReactiveFindOperationSupportTests implements StateFunctions { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateCollationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateCollationTests.java index effdc931df..d4e80db6b4 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateCollationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateCollationTests.java @@ -29,12 +29,12 @@ 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.data.mongodb.config.AbstractReactiveMongoConfiguration; import org.springframework.data.mongodb.core.query.Collation; import org.springframework.data.mongodb.test.util.Client; -import org.springframework.data.mongodb.test.util.MongoClientExtension; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; @@ -44,7 +44,7 @@ * @author Mark Paluch * @author Christoph Strobl */ -@ExtendWith({ MongoClientExtension.class, SpringExtension.class }) +@ExtendWith({ SpringExtension.class }) @ContextConfiguration public class ReactiveMongoTemplateCollationTests { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateIndexTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateIndexTests.java index 75b38390cb..c0ecdcb35a 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateIndexTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateIndexTests.java @@ -15,6 +15,7 @@ */ package org.springframework.data.mongodb.core; +import static org.assertj.core.data.Index.*; import static org.assertj.core.data.Index.atIndex; import static org.springframework.data.mongodb.test.util.Assertions.*; @@ -29,8 +30,8 @@ import org.bson.Document; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.extension.ExtendWith; import org.junitpioneer.jupiter.RepeatFailedTest; + import org.springframework.dao.DataIntegrityViolationException; import org.springframework.data.annotation.Id; import org.springframework.data.domain.Sort.Direction; @@ -42,7 +43,6 @@ import org.springframework.data.mongodb.core.index.Indexed; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.test.util.Client; -import org.springframework.data.mongodb.test.util.MongoClientExtension; import org.springframework.data.mongodb.test.util.MongoTestUtils; import com.mongodb.client.model.IndexOptions; @@ -56,7 +56,7 @@ * @author Christoph Strobl * @author Mathieu Ouellet */ -@ExtendWith(MongoClientExtension.class) + public class ReactiveMongoTemplateIndexTests { private static @Client MongoClient client; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateReplaceTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateReplaceTests.java index 86433ab338..035f45b0b5 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateReplaceTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateReplaceTests.java @@ -20,7 +20,6 @@ import static org.springframework.data.mongodb.core.query.Criteria.*; import static org.springframework.data.mongodb.core.query.Query.*; -import org.springframework.data.mongodb.test.util.EnableIfMongoServerVersion; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; @@ -35,15 +34,15 @@ 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.reactivestreams.Publisher; + import org.springframework.dao.DataIntegrityViolationException; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Direction; import org.springframework.data.mongodb.core.mapping.Field; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.test.util.Client; -import org.springframework.data.mongodb.test.util.MongoClientExtension; +import org.springframework.data.mongodb.test.util.EnableIfMongoServerVersion; import com.mongodb.client.model.Filters; import com.mongodb.client.result.UpdateResult; @@ -53,7 +52,7 @@ /** * @author Christoph Strobl */ -@ExtendWith(MongoClientExtension.class) + public class ReactiveMongoTemplateReplaceTests { static final String DB_NAME = "mongo-template-replace-tests"; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateScrollTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateScrollTests.java index 0e6e94bdf7..01ca84fa02 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateScrollTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateScrollTests.java @@ -28,10 +28,10 @@ import org.bson.Document; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; + import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.support.GenericApplicationContext; import org.springframework.data.domain.ScrollPosition; @@ -40,7 +40,6 @@ import org.springframework.data.mongodb.core.mapping.Field; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.test.util.Client; -import org.springframework.data.mongodb.test.util.MongoClientExtension; import org.springframework.data.mongodb.test.util.ReactiveMongoTestTemplate; import com.mongodb.reactivestreams.client.MongoClient; @@ -51,7 +50,7 @@ * @author Mark Paluch * @author Christoph Strobl */ -@ExtendWith(MongoClientExtension.class) + class ReactiveMongoTemplateScrollTests { static @Client MongoClient client; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateTests.java index f87227cdde..30472a6088 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateTests.java @@ -47,7 +47,6 @@ import org.junit.jupiter.api.BeforeEach; 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; @@ -79,8 +78,6 @@ 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; @@ -93,7 +90,6 @@ * @author Mark Paluch * @author Christoph Strobl */ -@ExtendWith({ MongoClientExtension.class, MongoServerCondition.class }) public class ReactiveMongoTemplateTests { private static final String DB_NAME = "reactive-mongo-template-tests"; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateTransactionTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateTransactionTests.java index 5a7271e2b4..daf3ff5d80 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateTransactionTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateTransactionTests.java @@ -28,15 +28,14 @@ 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.reactivestreams.Publisher; + import org.springframework.data.domain.Sort; import org.springframework.data.mongodb.ReactiveMongoTransactionManager; import org.springframework.data.mongodb.core.query.Query; 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.MongoTestUtils; import org.springframework.transaction.ReactiveTransaction; import org.springframework.transaction.reactive.TransactionCallback; @@ -55,7 +54,7 @@ * @author Mathieu Ouellet * @currentRead The Core - Peter V. Brett */ -@ExtendWith(MongoClientExtension.class) + @EnableIfReplicaSetAvailable @EnableIfMongoServerVersion(isGreaterThanEqual = "4.0") public class ReactiveMongoTemplateTransactionTests { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateUpdateTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateUpdateTests.java index 35c27815ff..46be132f23 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateUpdateTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateUpdateTests.java @@ -30,10 +30,10 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; + import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Version; import org.springframework.data.domain.Sort; @@ -50,7 +50,6 @@ import org.springframework.data.mongodb.core.query.UpdateDefinition; 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 com.mongodb.reactivestreams.client.MongoClient; @@ -59,7 +58,7 @@ /** * @author Christoph Strobl */ -@ExtendWith(MongoClientExtension.class) + @EnableIfMongoServerVersion(isGreaterThanEqual = "4.2") public class ReactiveMongoTemplateUpdateTests { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateViewTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateViewTests.java index 0841ddc37f..03f1bacbf4 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateViewTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateViewTests.java @@ -29,13 +29,12 @@ 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.mongodb.core.aggregation.AggregationPipeline; import org.springframework.data.mongodb.core.mapping.Field; import org.springframework.data.mongodb.core.query.Collation; import org.springframework.data.mongodb.test.util.Client; import org.springframework.data.mongodb.test.util.CollectionInfo; -import org.springframework.data.mongodb.test.util.MongoClientExtension; import org.springframework.data.mongodb.test.util.MongoTestUtils; import com.mongodb.reactivestreams.client.MongoClient; @@ -43,7 +42,7 @@ /** * @author Christoph Strobl */ -@ExtendWith(MongoClientExtension.class) + public class ReactiveMongoTemplateViewTests { static @Client com.mongodb.client.MongoClient client; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveRemoveOperationSupportTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveRemoveOperationSupportTests.java index 5659869705..60ecce902b 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveRemoveOperationSupportTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveRemoveOperationSupportTests.java @@ -25,11 +25,10 @@ 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.mapping.Field; import org.springframework.data.mongodb.test.util.Client; -import org.springframework.data.mongodb.test.util.MongoClientExtension; import com.mongodb.client.MongoClient; @@ -38,7 +37,7 @@ * * @author Mark Paluch */ -@ExtendWith(MongoClientExtension.class) + class ReactiveRemoveOperationSupportTests { private static final String STAR_WARS = "star-wars"; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveUpdateOperationSupportTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveUpdateOperationSupportTests.java index 3ac99c2b6d..d1b0809d34 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveUpdateOperationSupportTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveUpdateOperationSupportTests.java @@ -26,13 +26,12 @@ import org.bson.BsonString; 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.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 com.mongodb.client.MongoClient; @@ -41,7 +40,7 @@ * * @author Mark Paluch */ -@ExtendWith(MongoClientExtension.class) + class ReactiveUpdateOperationSupportTests { private static final String STAR_WARS = "star-wars"; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/SessionBoundMongoTemplateTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/SessionBoundMongoTemplateTests.java index 8769656537..63325d4cc3 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/SessionBoundMongoTemplateTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/SessionBoundMongoTemplateTests.java @@ -37,8 +37,8 @@ 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.mockito.Mockito; + import org.springframework.aop.Advisor; import org.springframework.aop.framework.Advised; import org.springframework.dao.DataAccessException; @@ -60,7 +60,6 @@ import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.test.util.EnableIfReplicaSetAvailable; -import org.springframework.data.mongodb.test.util.MongoClientExtension; import org.springframework.data.mongodb.test.util.MongoVersion; import org.springframework.data.mongodb.test.util.ReplSetClient; import org.springframework.test.util.ReflectionTestUtils; @@ -76,7 +75,6 @@ * * @author Christoph Strobl */ -@ExtendWith(MongoClientExtension.class) @EnableIfReplicaSetAvailable public class SessionBoundMongoTemplateTests { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationTests.java index 99579b34a7..1f7df8d520 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationTests.java @@ -45,7 +45,7 @@ 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.core.io.ClassPathResource; import org.springframework.data.annotation.Id; import org.springframework.data.domain.Sort; @@ -70,7 +70,6 @@ import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.repository.Person; import org.springframework.data.mongodb.test.util.EnableIfMongoServerVersion; -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.Template; @@ -93,7 +92,6 @@ * @author Sangyong Choi * @author Julia Lee */ -@ExtendWith(MongoTemplateExtension.class) public class AggregationTests { private static final String INPUT_COLLECTION = "aggregation_test_collection"; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperationTests.java index bc0edcea0b..77dc4d89a5 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperationTests.java @@ -24,7 +24,7 @@ import org.bson.Document; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; + import org.springframework.data.annotation.Id; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Direction; @@ -32,7 +32,6 @@ import org.springframework.data.mongodb.core.aggregation.SetWindowFieldsOperation.Windows; import org.springframework.data.mongodb.core.mapping.Field; import org.springframework.data.mongodb.test.util.EnableIfMongoServerVersion; -import org.springframework.data.mongodb.test.util.MongoTemplateExtension; import org.springframework.data.mongodb.test.util.MongoTestTemplate; import org.springframework.data.mongodb.test.util.Template; @@ -41,7 +40,6 @@ * * @author Christoph Strobl */ -@ExtendWith(MongoTemplateExtension.class) @EnableIfMongoServerVersion(isGreaterThanEqual = "5.0") class SetWindowFieldsOperationTests { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/auditing/MongoTemplateAuditingTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/auditing/MongoTemplateAuditingTests.java index e2e1937da6..2f8a9d0209 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/auditing/MongoTemplateAuditingTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/auditing/MongoTemplateAuditingTests.java @@ -39,7 +39,6 @@ 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.MongoClientExtension; import org.springframework.test.context.junit.jupiter.SpringExtension; import com.mongodb.client.MongoClient; @@ -47,7 +46,7 @@ /** * @author Christoph Strobl */ -@ExtendWith({ MongoClientExtension.class, SpringExtension.class }) +@ExtendWith({ SpringExtension.class }) public class MongoTemplateAuditingTests { static @Client MongoClient mongoClient; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/auditing/ReactiveMongoTemplateAuditingTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/auditing/ReactiveMongoTemplateAuditingTests.java index 28429b53dc..f5bcc7dd1d 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/auditing/ReactiveMongoTemplateAuditingTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/auditing/ReactiveMongoTemplateAuditingTests.java @@ -44,7 +44,6 @@ 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.MongoClientExtension; import org.springframework.data.mongodb.test.util.MongoTestUtils; import org.springframework.test.context.junit.jupiter.SpringExtension; @@ -56,7 +55,7 @@ * @author Christoph Strobl * @author Mark Paluch */ -@ExtendWith({ MongoClientExtension.class, SpringExtension.class }) +@ExtendWith(SpringExtension.class) class ReactiveMongoTemplateAuditingTests { static final String DB_NAME = "mongo-template-audit-tests"; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterTests.java index 1ce58eeb47..be8dbced9e 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterTests.java @@ -27,7 +27,6 @@ import java.time.temporal.ChronoUnit; import java.util.Arrays; import java.util.Collections; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; @@ -36,7 +35,7 @@ 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.data.annotation.Id; import org.springframework.data.mongodb.MongoDatabaseFactory; import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory; @@ -44,7 +43,6 @@ import org.springframework.data.mongodb.core.mapping.DBRef; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.test.util.Client; -import org.springframework.data.mongodb.test.util.MongoClientExtension; import com.mongodb.client.MongoClient; import com.mongodb.client.MongoCollection; @@ -55,7 +53,7 @@ * * @author Christoph Strobl */ -@ExtendWith(MongoClientExtension.class) + public class MappingMongoConverterTests { private static final String DATABASE = "mapping-converter-tests"; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MongoConvertersIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MongoConvertersIntegrationTests.java index a1c2fc0897..ee8705fcdd 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MongoConvertersIntegrationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MongoConvertersIntegrationTests.java @@ -28,14 +28,13 @@ import org.bson.types.ObjectId; 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.Vector; import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.MongoVector; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; -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; @@ -47,7 +46,6 @@ * @author Christoph Strobl * @author Mark Paluch */ -@ExtendWith(MongoTemplateExtension.class) public class MongoConvertersIntegrationTests { static final String COLLECTION = "converter-tests"; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/MongoQueryableEncryptionCollectionCreationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/MongoQueryableEncryptionCollectionCreationTests.java index 46c7b235e6..c41e246a9c 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/MongoQueryableEncryptionCollectionCreationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/MongoQueryableEncryptionCollectionCreationTests.java @@ -42,7 +42,6 @@ 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.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; @@ -53,7 +52,7 @@ * * @author Christoph Strobl */ -@ExtendWith({ MongoClientExtension.class, SpringExtension.class }) +@ExtendWith({ SpringExtension.class }) @EnableIfMongoServerVersion(isGreaterThanEqual = "8.0") @EnableIfReplicaSetAvailable @ContextConfiguration diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/RangeEncryptionTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/RangeEncryptionTests.java index 01cbdec9d5..5369d0d70d 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/RangeEncryptionTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/RangeEncryptionTests.java @@ -15,9 +15,8 @@ */ package org.springframework.data.mongodb.core.encryption; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.springframework.data.mongodb.core.query.Criteria.where; +import static org.assertj.core.api.Assertions.*; +import static org.springframework.data.mongodb.core.query.Criteria.*; import java.security.SecureRandom; import java.util.LinkedHashMap; @@ -37,6 +36,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; + import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; @@ -59,7 +59,6 @@ import org.springframework.data.mongodb.core.schema.MongoJsonSchema; 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.util.MongoClientVersion; import org.springframework.data.util.Lazy; import org.springframework.test.context.ContextConfiguration; @@ -90,7 +89,7 @@ * @author Ross Lawley * @author Christoph Strobl */ -@ExtendWith({ MongoClientExtension.class, SpringExtension.class }) +@ExtendWith({ SpringExtension.class }) @EnableIfMongoServerVersion(isGreaterThanEqual = "8.0") @EnableIfReplicaSetAvailable @ContextConfiguration(classes = RangeEncryptionTests.EncryptionConfig.class) diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/GeoJsonTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/GeoJsonTests.java index b81b51abd5..6a792a40f6 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/GeoJsonTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/GeoJsonTests.java @@ -29,6 +29,7 @@ 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; @@ -49,7 +50,6 @@ import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.test.util.BasicDbListBuilder; import org.springframework.data.mongodb.test.util.Client; -import org.springframework.data.mongodb.test.util.MongoClientExtension; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; @@ -62,7 +62,7 @@ * @author Mark Paluch * @author Ivan Volzhev */ -@ExtendWith({ MongoClientExtension.class, SpringExtension.class }) +@ExtendWith({ SpringExtension.class }) @ContextConfiguration public class GeoJsonTests { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/IndexingIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/IndexingIntegrationTests.java index caa40e96c0..c8b11b8ef5 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/IndexingIntegrationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/IndexingIntegrationTests.java @@ -31,6 +31,7 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; @@ -48,7 +49,6 @@ import org.springframework.data.mongodb.core.mapping.TimeSeries; 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.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; @@ -64,7 +64,7 @@ * @author Mark Paluch * @author Ben Foster */ -@ExtendWith({ MongoClientExtension.class, SpringExtension.class }) +@ExtendWith({ SpringExtension.class }) @ContextConfiguration public class IndexingIntegrationTests { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/TextIndexTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/TextIndexTests.java index aa37b8bced..0abb357bfd 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/TextIndexTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/TextIndexTests.java @@ -21,13 +21,12 @@ 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.CollectionOptions; 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 org.springframework.data.mongodb.test.util.MongoTemplateExtension; import org.springframework.data.mongodb.test.util.MongoTestTemplate; import org.springframework.data.mongodb.test.util.Template; @@ -35,7 +34,6 @@ * @author Christoph Strobl * @author Mark Paluch */ -@ExtendWith(MongoTemplateExtension.class) public class TextIndexTests { @Template(initialEntitySet = TextIndexedDocumentRoot.class) diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/VectorIndexIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/VectorIndexIntegrationTests.java index 1892264649..fcf4cc328d 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/VectorIndexIntegrationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/VectorIndexIntegrationTests.java @@ -15,8 +15,9 @@ */ package org.springframework.data.mongodb.core.index; -import static org.assertj.core.api.Assertions.assertThatRuntimeException; -import static org.awaitility.Awaitility.await; +import static org.assertj.core.api.Assertions.*; +import static org.awaitility.Awaitility.*; +import static org.springframework.data.mongodb.test.util.Assertions.*; import static org.springframework.data.mongodb.test.util.Assertions.assertThat; import java.time.Duration; @@ -26,15 +27,14 @@ 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.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; + import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.index.VectorIndex.SimilarityFunction; import org.springframework.data.mongodb.core.mapping.Field; import org.springframework.data.mongodb.test.util.AtlasContainer; import org.springframework.data.mongodb.test.util.EnableIfVectorSearchAvailable; -import org.springframework.data.mongodb.test.util.MongoServerCondition; import org.springframework.data.mongodb.test.util.MongoTestTemplate; import org.springframework.data.mongodb.test.util.MongoTestUtils; import org.springframework.lang.Nullable; @@ -51,7 +51,6 @@ * @author Christoph Strobl * @author Mark Paluch */ -@ExtendWith(MongoServerCondition.class) @Testcontainers(disabledWithoutDocker = true) class VectorIndexIntegrationTests { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/MappingTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/MappingTests.java index eee407701c..82be189f70 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/MappingTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/MappingTests.java @@ -31,7 +31,7 @@ import org.bson.types.ObjectId; 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; @@ -46,7 +46,6 @@ 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; @@ -60,7 +59,6 @@ * @author Thomas Darimont * @author Mark Paluch */ -@ExtendWith(MongoTemplateExtension.class) public class MappingTests { static final String DB_NAME = "mapping-tests"; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/ApplicationContextEventTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/ApplicationContextEventTests.java index 9bc1dc78aa..cb92e3bae7 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/ApplicationContextEventTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/ApplicationContextEventTests.java @@ -28,7 +28,7 @@ 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.context.ConfigurableApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.data.annotation.Id; @@ -42,7 +42,6 @@ import org.springframework.data.mongodb.repository.support.MongoRepositoryFactory; import org.springframework.data.mongodb.repository.support.QuerydslMongoPredicateExecutor; import org.springframework.data.mongodb.test.util.Client; -import org.springframework.data.mongodb.test.util.MongoClientExtension; import org.springframework.test.annotation.DirtiesContext; import com.mongodb.WriteConcern; @@ -57,7 +56,6 @@ * @author Jordi Llach * @author Mark Paluch */ -@ExtendWith({ MongoClientExtension.class }) public class ApplicationContextEventTests { private static final String COLLECTION_NAME = "personPojoStringId"; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/messaging/ChangeStreamTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/messaging/ChangeStreamTests.java index 53d093897e..62195239e3 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/messaging/ChangeStreamTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/messaging/ChangeStreamTests.java @@ -38,8 +38,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.junitpioneer.jupiter.RepeatFailedTest; + import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.ChangeStreamOptions; import org.springframework.data.mongodb.core.CollectionOptions; @@ -51,7 +51,6 @@ 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.MongoTemplateExtension; import org.springframework.data.mongodb.test.util.MongoTestTemplate; import org.springframework.data.mongodb.test.util.MongoVersion; import org.springframework.data.mongodb.test.util.Template; @@ -68,7 +67,6 @@ * @author Mark Paluch * @author Myroslav Kosinskyi */ -@ExtendWith({ MongoTemplateExtension.class }) @EnableIfReplicaSetAvailable class ChangeStreamTests { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/messaging/DefaultMessageListenerContainerTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/messaging/DefaultMessageListenerContainerTests.java index 9373845a89..bcae19d32a 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/messaging/DefaultMessageListenerContainerTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/messaging/DefaultMessageListenerContainerTests.java @@ -28,7 +28,7 @@ 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; @@ -40,8 +40,6 @@ 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.MongoServerCondition; -import org.springframework.data.mongodb.test.util.MongoTemplateExtension; import org.springframework.data.mongodb.test.util.MongoTestUtils; import org.springframework.data.mongodb.test.util.Template; import org.springframework.util.ErrorHandler; @@ -56,7 +54,6 @@ * * @author Christoph Strobl */ -@ExtendWith({ MongoTemplateExtension.class, MongoServerCondition.class }) public class DefaultMessageListenerContainerTests { static final String DATABASE_NAME = "change-stream-events"; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/messaging/TailableCursorTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/messaging/TailableCursorTests.java index 60d9153212..8b41f9120d 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/messaging/TailableCursorTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/messaging/TailableCursorTests.java @@ -31,7 +31,7 @@ import org.junit.jupiter.api.BeforeAll; 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.CollectionOptions; import org.springframework.data.mongodb.core.MongoTemplate; @@ -39,7 +39,6 @@ import org.springframework.data.mongodb.core.messaging.Message.MessageProperties; import org.springframework.data.mongodb.core.messaging.TailableCursorRequest.TailableCursorRequestOptions; import org.springframework.data.mongodb.test.util.Client; -import org.springframework.data.mongodb.test.util.MongoClientExtension; import com.mongodb.client.MongoClient; @@ -50,7 +49,6 @@ * @author Christoph Strobl * @author Mark Paluch */ -@ExtendWith({ MongoClientExtension.class }) public class TailableCursorTests { static final String COLLECTION_NAME = "user"; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/CriteriaTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/CriteriaTests.java index 72f42db9b5..869d6d67c8 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/CriteriaTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/CriteriaTests.java @@ -25,9 +25,8 @@ import org.bson.types.Binary; 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.test.util.MongoTemplateExtension; import org.springframework.data.mongodb.test.util.MongoTestTemplate; import org.springframework.data.mongodb.test.util.Template; @@ -37,7 +36,6 @@ * @author Christoph Strobl * @author Andreas Zink */ -@ExtendWith(MongoTemplateExtension.class) class CriteriaTests { @Template(initialEntitySet = { DocumentWithBitmask.class }) // diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/TextQueryTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/TextQueryTests.java index 6ea0f5aa9c..6aa97f53bc 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/TextQueryTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/TextQueryTests.java @@ -23,7 +23,7 @@ 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.data.annotation.Id; import org.springframework.data.domain.PageRequest; import org.springframework.data.mongodb.core.index.IndexDefinition; @@ -32,7 +32,6 @@ 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; import org.springframework.lang.Nullable; @@ -41,7 +40,6 @@ * @author Christoph Strobl * @author Mark Paluch */ -@ExtendWith(MongoTemplateExtension.class) public class TextQueryTests { private static final FullTextDoc BAKE = new FullTextDocBuilder().headline("bake").build(); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/schema/MongoJsonSchemaTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/schema/MongoJsonSchemaTests.java index a7cf75366f..2dc7cd0f5f 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/schema/MongoJsonSchemaTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/schema/MongoJsonSchemaTests.java @@ -24,6 +24,7 @@ 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.data.mongodb.config.AbstractMongoClientConfiguration; @@ -33,7 +34,6 @@ import org.springframework.data.mongodb.core.mapping.Field; import org.springframework.data.mongodb.core.validation.Validator; import org.springframework.data.mongodb.test.util.Client; -import org.springframework.data.mongodb.test.util.MongoClientExtension; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; @@ -49,7 +49,7 @@ * * @author Christoph Strobl */ -@ExtendWith({ MongoClientExtension.class, SpringExtension.class }) +@ExtendWith({ SpringExtension.class }) @ContextConfiguration public class MongoJsonSchemaTests { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/schema/ReactiveMongoJsonSchemaTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/schema/ReactiveMongoJsonSchemaTests.java index 4615568d10..20cbbe9dfd 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/schema/ReactiveMongoJsonSchemaTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/schema/ReactiveMongoJsonSchemaTests.java @@ -28,6 +28,7 @@ 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.DataRetrievalFailureException; @@ -36,7 +37,6 @@ import org.springframework.data.mongodb.core.convert.MongoJsonSchemaMapper; 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.ReactiveMongoClientClosingTestConfiguration; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; @@ -48,7 +48,7 @@ * * @author Mark Paluch */ -@ExtendWith({ MongoClientExtension.class, SpringExtension.class }) +@ExtendWith({ SpringExtension.class }) @ContextConfiguration public class ReactiveMongoJsonSchemaTests { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/monitor/MongoMonitorIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/monitor/MongoMonitorIntegrationTests.java index e70b398f7f..4cc99b0f27 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/monitor/MongoMonitorIntegrationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/monitor/MongoMonitorIntegrationTests.java @@ -20,9 +20,8 @@ import java.net.UnknownHostException; 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; @@ -33,7 +32,6 @@ * @author Thomas Darimont * @author Mark Paluch */ -@ExtendWith(MongoClientExtension.class) public class MongoMonitorIntegrationTests { static @Client MongoClient mongoClient; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/ComplexIdRepositoryIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/ComplexIdRepositoryIntegrationTests.java index a4f533f0be..15776510fd 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/ComplexIdRepositoryIntegrationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/ComplexIdRepositoryIntegrationTests.java @@ -26,6 +26,7 @@ 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; @@ -34,7 +35,6 @@ import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; import org.springframework.data.mongodb.test.util.Client; -import org.springframework.data.mongodb.test.util.MongoClientExtension; import org.springframework.test.context.junit.jupiter.SpringExtension; import com.mongodb.client.MongoClient; @@ -44,7 +44,7 @@ * @author Oliver Gierke * @author Mark Paluch */ -@ExtendWith({ MongoClientExtension.class, SpringExtension.class }) +@ExtendWith({ SpringExtension.class }) public class ComplexIdRepositoryIntegrationTests { static @Client MongoClient mongoClient; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/MongoRepositoryTextSearchIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/MongoRepositoryTextSearchIntegrationTests.java index c41abf4aa1..d598c8a207 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/MongoRepositoryTextSearchIntegrationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/MongoRepositoryTextSearchIntegrationTests.java @@ -23,7 +23,7 @@ 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; @@ -35,7 +35,6 @@ 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.MongoTemplateExtension; import org.springframework.data.mongodb.test.util.MongoTestTemplate; import org.springframework.data.mongodb.test.util.Template; import org.springframework.lang.Nullable; @@ -48,7 +47,6 @@ * @author Oliver Gierke * @author Mark Paluch */ -@ExtendWith(MongoTemplateExtension.class) class MongoRepositoryTextSearchIntegrationTests { private static final FullTextDocument PASSENGER_57 = new FullTextDocument("1", "Passenger 57", diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepositoryTransactionalTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepositoryTransactionalTests.java index 0af684b9c1..ae4a3c57f1 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepositoryTransactionalTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepositoryTransactionalTests.java @@ -30,6 +30,7 @@ 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.Bean; import org.springframework.context.annotation.ComponentScan.Filter; @@ -44,7 +45,6 @@ import org.springframework.data.mongodb.test.util.AfterTransactionAssertion; 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.ReplSetClient; import org.springframework.lang.Nullable; import org.springframework.test.annotation.Rollback; @@ -63,7 +63,7 @@ * @author Christoph Strobl * @currentRead Shadow's Edge - Brent Weeks */ -@ExtendWith({ MongoClientExtension.class, SpringExtension.class }) +@ExtendWith({ SpringExtension.class }) @EnableIfReplicaSetAvailable @EnableIfMongoServerVersion(isGreaterThanEqual = "4.0") @Transactional(transactionManager = "txManager") diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/VersionedPersonRepositoryIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/VersionedPersonRepositoryIntegrationTests.java index f4e1e0282e..d0b89795ca 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/VersionedPersonRepositoryIntegrationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/VersionedPersonRepositoryIntegrationTests.java @@ -31,7 +31,6 @@ import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; import org.springframework.data.mongodb.test.util.Client; -import org.springframework.data.mongodb.test.util.MongoClientExtension; import org.springframework.data.mongodb.test.util.MongoTestUtils; import org.springframework.data.repository.CrudRepository; import org.springframework.lang.Nullable; @@ -45,7 +44,7 @@ * * @author Christoph Strobl */ -@ExtendWith({ MongoClientExtension.class, SpringExtension.class }) +@ExtendWith({ SpringExtension.class }) @ContextConfiguration class VersionedPersonRepositoryIntegrationTests { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepositoryTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepositoryTests.java index 60c02ee775..3dbb0b3890 100755 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepositoryTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepositoryTests.java @@ -32,6 +32,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.extension.ExtendWith; + import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.data.domain.Example; import org.springframework.data.domain.ExampleMatcher; @@ -53,8 +54,6 @@ import org.springframework.data.mongodb.test.util.DirtiesStateExtension; 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.data.repository.query.FluentQuery; @@ -68,7 +67,7 @@ * @author Mark Paluch * @author Jens Schauder */ -@ExtendWith({ MongoTemplateExtension.class, MongoServerCondition.class, DirtiesStateExtension.class }) +@ExtendWith({ DirtiesStateExtension.class }) @TestInstance(TestInstance.Lifecycle.PER_CLASS) class SimpleMongoRepositoryTests implements StateFunctions { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/EnableIfVectorSearchAvailable.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/EnableIfVectorSearchAvailable.java index c81e197fec..7570d6fc50 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/EnableIfVectorSearchAvailable.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/EnableIfVectorSearchAvailable.java @@ -29,9 +29,11 @@ * server available. This means that not only the mongodb instance needs to have a * {@literal searchIndexManagementHostAndPort} configured, but also that the search index sever is actually up and * running, responding to a {@literal $listSearchIndexes} aggregation. - * + *

+ * Using this annotation will wait up to {@code 60 seconds} for the search index to become available. + * * @author Christoph Strobl - * @since 5.0 + * @since 4.5.3 * @see Tag */ @Target({ ElementType.METHOD }) diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoClientExtension.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoClientExtension.java index 357a87168e..6e2c694ed7 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoClientExtension.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoClientExtension.java @@ -47,7 +47,7 @@ * @see Client * @see ReplSetClient */ -public class MongoClientExtension implements Extension, BeforeAllCallback, AfterAllCallback, ParameterResolver { +class MongoClientExtension implements Extension, BeforeAllCallback, AfterAllCallback, ParameterResolver { private static final Log LOGGER = LogFactory.getLog(MongoClientExtension.class); @@ -157,7 +157,7 @@ public Object resolveParameter(ParameterContext parameterContext, ExtensionConte return getMongoClient(parameterType, extensionContext, replSet); } - static class SyncClientHolder implements Store.CloseableResource { + static class SyncClientHolder implements AutoCloseable { final MongoClient client; @@ -175,7 +175,7 @@ public void close() { } } - static class ReactiveClientHolder implements Store.CloseableResource { + static class ReactiveClientHolder implements AutoCloseable { final com.mongodb.reactivestreams.client.MongoClient client; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoServerCondition.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoServerCondition.java index 35ca65c30a..a1536d01d2 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoServerCondition.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoServerCondition.java @@ -34,7 +34,7 @@ /** * @author Christoph Strobl */ -public class MongoServerCondition implements ExecutionCondition { +class MongoServerCondition implements ExecutionCondition { private static final Namespace NAMESPACE = Namespace.create("mongodb", "server"); @@ -52,9 +52,11 @@ public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext con } if (context.getTags().contains("vector-search")) { + if (!atlasEnvironment(context)) { return ConditionEvaluationResult.disabled("Disabled for servers not supporting Vector Search."); } + if (!isSearchIndexAvailable(context)) { return ConditionEvaluationResult.disabled("Search index unavailable."); } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoTemplateExtension.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoTemplateExtension.java index 23e4a3db77..c91bdb4d5d 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoTemplateExtension.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoTemplateExtension.java @@ -45,7 +45,7 @@ * @see MongoTestTemplate * @see ReactiveMongoTestTemplate */ -public class MongoTemplateExtension extends MongoClientExtension implements TestInstancePostProcessor { +class MongoTemplateExtension extends MongoClientExtension implements TestInstancePostProcessor { private static final String DEFAULT_DATABASE = "database"; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoTestUtils.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoTestUtils.java index 742fd5b446..93993f5769 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoTestUtils.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoTestUtils.java @@ -15,8 +15,6 @@ */ package org.springframework.data.mongodb.test.util; -import org.jspecify.annotations.Nullable; -import org.springframework.util.StringUtils; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; import reactor.util.retry.Retry; @@ -26,11 +24,14 @@ import java.util.concurrent.TimeUnit; import org.bson.Document; + import org.springframework.core.env.Environment; import org.springframework.core.env.StandardEnvironment; import org.springframework.data.mongodb.SpringDataMongoDB; import org.springframework.data.util.Version; +import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; +import org.springframework.util.StringUtils; import com.mongodb.ConnectionString; import com.mongodb.MongoClientSettings; From 859ce08edcf6980046d1bbe2ad42662c43581cc7 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 8 Jul 2025 15:31:22 +0200 Subject: [PATCH 21/21] Polishing. Consider listen port in addition to shell command. See: #5013 Original pull request: #5014 --- .../data/mongodb/test/util/AtlasContainer.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/AtlasContainer.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/AtlasContainer.java index 71fecd29b9..c9c23c16ab 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/AtlasContainer.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/AtlasContainer.java @@ -16,6 +16,9 @@ package org.springframework.data.mongodb.test.util; import org.springframework.core.env.StandardEnvironment; + +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.containers.wait.strategy.WaitAllStrategy; import org.testcontainers.mongodb.MongoDBAtlasLocalContainer; import org.testcontainers.utility.DockerImageName; @@ -36,12 +39,18 @@ public class AtlasContainer extends MongoDBAtlasLocalContainer { public static final String ATLAS_HOST = "docker.mongodb.atlas.host"; public static final String ATLAS_PORT = "docker.mongodb.atlas.port"; + public static final WaitAllStrategy WAIT_STRATEGY = new WaitAllStrategy( + WaitAllStrategy.Mode.WITH_MAXIMUM_OUTER_TIMEOUT).withStrategy(Wait.forListeningPort()) + .withStrategy(Wait.forSuccessfulCommand("runner healthcheck")); + private AtlasContainer(String dockerImageName) { super(DockerImageName.parse(dockerImageName)); + this.waitingFor(WAIT_STRATEGY); } private AtlasContainer(DockerImageName dockerImageName) { super(dockerImageName); + this.waitingFor(WAIT_STRATEGY); } public static AtlasContainer bestMatch() {