From 4dc13973cf046757f812788b374745752670e0ea Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Thu, 17 Oct 2019 08:53:39 +0200 Subject: [PATCH 1/3] DATAMONGO-2388 - Prepare issue branch. --- pom.xml | 2 +- spring-data-mongodb-benchmarks/pom.xml | 2 +- spring-data-mongodb-distribution/pom.xml | 2 +- spring-data-mongodb/pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 15b2d67f47..d4095ea505 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-mongodb-parent - 2.3.0.BUILD-SNAPSHOT + 2.2.0.DATAMONGO-2388-SNAPSHOT pom Spring Data MongoDB diff --git a/spring-data-mongodb-benchmarks/pom.xml b/spring-data-mongodb-benchmarks/pom.xml index c4766040c1..77174680f8 100644 --- a/spring-data-mongodb-benchmarks/pom.xml +++ b/spring-data-mongodb-benchmarks/pom.xml @@ -7,7 +7,7 @@ org.springframework.data spring-data-mongodb-parent - 2.3.0.BUILD-SNAPSHOT + 2.2.0.DATAMONGO-2388-SNAPSHOT ../pom.xml diff --git a/spring-data-mongodb-distribution/pom.xml b/spring-data-mongodb-distribution/pom.xml index ed39c63e76..8bea297f7d 100644 --- a/spring-data-mongodb-distribution/pom.xml +++ b/spring-data-mongodb-distribution/pom.xml @@ -14,7 +14,7 @@ org.springframework.data spring-data-mongodb-parent - 2.3.0.BUILD-SNAPSHOT + 2.2.0.DATAMONGO-2388-SNAPSHOT ../pom.xml diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml index 25cf02b5d5..08b7932482 100644 --- a/spring-data-mongodb/pom.xml +++ b/spring-data-mongodb/pom.xml @@ -11,7 +11,7 @@ org.springframework.data spring-data-mongodb-parent - 2.3.0.BUILD-SNAPSHOT + 2.2.0.DATAMONGO-2388-SNAPSHOT ../pom.xml From c18090f79ba22dcafd79d29e40d4224f4e9735d8 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Wed, 16 Oct 2019 11:14:46 +0200 Subject: [PATCH 2/3] DATAMONGO-2388 - Fix test issues related to JUnit5 upgrade. Execution time and test order changed by using JUnit5. This commit fixes some of the issues related to index creation where actually not needed. --- .../data/mongodb/core/MongoTemplateCollationTests.java | 5 +++++ .../data/mongodb/core/MongoTemplateTransactionTests.java | 5 +++++ .../data/mongodb/core/MongoTemplateValidationTests.java | 5 +++++ .../springframework/data/mongodb/core/NoExplicitIdTests.java | 5 +++++ 4 files changed, 20 insertions(+) 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 70bf70777c..8950571c0c 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 @@ -60,6 +60,11 @@ public MongoClient mongoClient() { protected String getDatabaseName() { return "collation-tests"; } + + @Override + protected boolean autoIndexCreation() { + return false; + } } @Autowired MongoTemplate template; 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 92654379a4..da8ab558ee 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 @@ -85,6 +85,11 @@ protected String getDatabaseName() { return DB_NAME; } + @Override + protected boolean autoIndexCreation() { + return false; + } + @Bean MongoTransactionManager txManager(MongoDbFactory dbFactory) { return new MongoTransactionManager(dbFactory); 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 d0b68acf2e..1983634d06 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 @@ -74,6 +74,11 @@ public MongoClient mongoClient() { protected String getDatabaseName() { return "validation-tests"; } + + @Override + protected boolean autoIndexCreation() { + return false; + } } @Autowired MongoTemplate template; 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 19a373068e..5e74309c05 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 @@ -59,6 +59,11 @@ protected String getDatabaseName() { public MongoClient mongoClient() { return MongoTestUtils.client(); } + + @Override + protected boolean autoIndexCreation() { + return false; + } } @Autowired MongoOperations mongoOps; From c493a3d01baed5d9b5c7ffb12f58ca4faf5bf452 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Thu, 17 Oct 2019 14:30:34 +0200 Subject: [PATCH 3/3] DATAMONGO-2388 - Fix CodecConfigurationException when reading index info that contains DbRef. Provide the default CodecRegistry when converting partial index data to its String representation used in IndexInfo. --- .../data/mongodb/core/index/IndexInfo.java | 21 ++++- .../data/mongodb/util/BsonUtils.java | 79 +++++++++++++++++++ ...efaultIndexOperationsIntegrationTests.java | 17 ++++ 3 files changed, 114 insertions(+), 3 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexInfo.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexInfo.java index 7554a546e2..20468c5d31 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexInfo.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexInfo.java @@ -26,6 +26,7 @@ import java.util.Optional; import org.bson.Document; +import org.springframework.data.mongodb.util.BsonUtils; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.NumberUtils; @@ -117,9 +118,8 @@ public static IndexInfo indexInfoOf(Document sourceDocument) { boolean sparse = sourceDocument.containsKey("sparse") ? (Boolean) sourceDocument.get("sparse") : false; String language = sourceDocument.containsKey("default_language") ? (String) sourceDocument.get("default_language") : ""; - String partialFilter = sourceDocument.containsKey("partialFilterExpression") - ? ((Document) sourceDocument.get("partialFilterExpression")).toJson() - : null; + + String partialFilter = extractPartialFilterString(sourceDocument); IndexInfo info = new IndexInfo(indexFields, name, unique, sparse, language); info.partialFilterExpression = partialFilter; @@ -134,6 +134,21 @@ public static IndexInfo indexInfoOf(Document sourceDocument) { return info; } + /** + * @param sourceDocument + * @return the {@link String} representation of the partial filter {@link Document}. + * @since 2.1.11 + */ + @Nullable + private static String extractPartialFilterString(Document sourceDocument) { + + if (!sourceDocument.containsKey("partialFilterExpression")) { + return null; + } + + return BsonUtils.toJson(sourceDocument.get("partialFilterExpression", Document.class)); + } + /** * Returns the individual index fields of the index. * diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java index 34c85cbc70..fe9e865d20 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java @@ -16,13 +16,18 @@ package org.springframework.data.mongodb.util; import java.util.Arrays; +import java.util.Collection; import java.util.Date; import java.util.Map; import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; import org.bson.BsonValue; import org.bson.Document; import org.bson.conversions.Bson; +import org.bson.json.JsonParseException; +import org.springframework.core.convert.converter.Converter; import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -30,6 +35,7 @@ import com.mongodb.BasicDBObject; import com.mongodb.DBObject; import com.mongodb.DBRef; +import com.mongodb.MongoClientSettings; /** * @author Christoph Strobl @@ -147,4 +153,77 @@ public static Document toDocumentOrElse(String source, Function) value); + } else if (value instanceof Map) { + return toString((Map) value); + } else if (ObjectUtils.isArray(value)) { + return toString(Arrays.asList(ObjectUtils.toObjectArray(value))); + } + + throw e instanceof JsonParseException ? (JsonParseException) e : new JsonParseException(e); + } + } + + private static String serializeValue(@Nullable Object value) { + + if (value == null) { + return "null"; + } + + String documentJson = new Document("toBeEncoded", value).toJson(); + return documentJson.substring(documentJson.indexOf(':') + 1, documentJson.length() - 1).trim(); + } + + private static String toString(Map source) { + + return iterableToDelimitedString(source.entrySet(), "{ ", " }", + entry -> String.format("\"%s\" : %s", entry.getKey(), toJson(entry.getValue()))); + } + + private static String toString(Collection source) { + return iterableToDelimitedString(source, "[ ", " ]", BsonUtils::toJson); + } + + private static String iterableToDelimitedString(Iterable source, String prefix, String postfix, + Converter transformer) { + + return prefix + + StringUtils.collectionToCommaDelimitedString( + StreamSupport.stream(source.spliterator(), false).map(transformer::convert).collect(Collectors.toList())) + + postfix; + } } 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 516fcdbac2..d9f548bdd3 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 @@ -20,6 +20,7 @@ import static org.springframework.data.mongodb.core.index.PartialIndexFilter.*; import static org.springframework.data.mongodb.core.query.Criteria.*; +import org.bson.BsonDocument; import org.bson.Document; import org.junit.Before; import org.junit.Test; @@ -39,6 +40,7 @@ import org.springframework.util.ObjectUtils; import com.mongodb.client.MongoCollection; +import com.mongodb.client.model.IndexOptions; /** * Integration tests for {@link DefaultIndexOperations}. @@ -153,6 +155,21 @@ public void shouldFavorExplicitMappingHintViaClass() { .isEqualTo(Document.parse("{ \"a_g_e\" : { \"$gte\" : 10 } }")); } + @Test // DATAMONGO-2388 + public void shouldReadIndexWithPartialFilterContainingDbRefCorrectly() { + + BsonDocument partialFilter = BsonDocument.parse( + "{ \"the-ref\" : { \"$ref\" : \"other-collection\", \"$id\" : { \"$oid\" : \"59ce08baf264b906810fe8c5\"} } }"); + IndexOptions indexOptions = new IndexOptions(); + indexOptions.name("partial-with-dbref"); + indexOptions.partialFilterExpression(partialFilter); + + collection.createIndex(BsonDocument.parse("{ \"key-1\" : 1, \"key-2\": 1}"), indexOptions); + + IndexInfo info = findAndReturnIndexInfo(indexOps.getIndexInfo(), "partial-with-dbref"); + assertThat(BsonDocument.parse(info.getPartialFilterExpression())).isEqualTo(partialFilter); + } + @Test // DATAMONGO-1518 public void shouldCreateIndexWithCollationCorrectly() {