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 bde4720b4..063bdf819 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 @@ -18,7 +18,10 @@ package org.springframework.data.mongodb.core; import java.nio.charset.StandardCharsets; import java.time.Duration; import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import java.util.Optional; import java.util.function.Consumer; import java.util.function.Function; @@ -26,6 +29,7 @@ import java.util.stream.Collectors; 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; @@ -42,10 +46,10 @@ import org.springframework.data.util.Optionals; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; +import org.springframework.util.StringUtils; import com.mongodb.client.model.ValidationAction; import com.mongodb.client.model.ValidationLevel; -import org.springframework.util.StringUtils; /** * Provides a simple wrapper to encapsulate the variety of settings you can use when creating a collection. @@ -66,12 +70,12 @@ public class CollectionOptions { private ValidationOptions validationOptions; private @Nullable TimeSeriesOptions timeSeriesOptions; private @Nullable CollectionChangeStreamOptions changeStreamOptions; -// private @Nullable Bson encryptedFields; private @Nullable EncryptedCollectionOptions encryptedCollectionOptions; private CollectionOptions(@Nullable Long size, @Nullable Long maxDocuments, @Nullable Boolean capped, @Nullable Collation collation, ValidationOptions validationOptions, @Nullable TimeSeriesOptions timeSeriesOptions, - @Nullable CollectionChangeStreamOptions changeStreamOptions, @Nullable EncryptedCollectionOptions encryptedCollectionOptions) { + @Nullable CollectionChangeStreamOptions changeStreamOptions, + @Nullable EncryptedCollectionOptions encryptedCollectionOptions) { this.maxDocuments = maxDocuments; this.size = size; @@ -350,8 +354,11 @@ public class CollectionOptions { * @since 4.5.0 */ public static CollectionOptions encrypted(@Nullable EncryptedCollectionOptions encryptedCollectionOptions) { - return new CollectionOptions(null, null, null, null, null, null, - null, encryptedCollectionOptions); + return new CollectionOptions(null, null, null, null, null, null, null, encryptedCollectionOptions); + } + + public static CollectionOptions encrypted(MongoJsonSchema schema) { + return encrypted(new EncryptedCollectionOptions(schema)); } public static CollectionOptions encrypted(Consumer options) { @@ -442,10 +449,10 @@ public class CollectionOptions { public String toString() { return "CollectionOptions{" + "maxDocuments=" + maxDocuments + ", size=" + size + ", capped=" + capped + ", collation=" + collation + ", validationOptions=" + validationOptions + ", timeSeriesOptions=" - + timeSeriesOptions + ", changeStreamOptions=" + changeStreamOptions + ", encryptedCollectionOptions=" + encryptedCollectionOptions - + ", disableValidation=" + disableValidation() + ", strictValidation=" + strictValidation() - + ", moderateValidation=" + moderateValidation() + ", warnOnValidationError=" + warnOnValidationError() - + ", failOnValidationError=" + failOnValidationError() + '}'; + + timeSeriesOptions + ", changeStreamOptions=" + changeStreamOptions + ", encryptedCollectionOptions=" + + encryptedCollectionOptions + ", disableValidation=" + disableValidation() + ", strictValidation=" + + strictValidation() + ", moderateValidation=" + moderateValidation() + ", warnOnValidationError=" + + warnOnValidationError() + ", failOnValidationError=" + failOnValidationError() + '}'; } @Override @@ -629,34 +636,111 @@ public class CollectionOptions { public static class EncryptedCollectionOptions { private List queryableProperties = new ArrayList<>(); + private @Nullable MongoJsonSchema schema; + + public EncryptedCollectionOptions() { + this(null); + } + + public EncryptedCollectionOptions(@Nullable MongoJsonSchema schema) { + this.schema = schema; + } - public EncryptedCollectionOptions queryable(JsonSchemaProperty schemaObject, QueryCharacteristic... characteristics) { + public EncryptedCollectionOptions queryable(JsonSchemaProperty schemaObject, + QueryCharacteristic... characteristics) { QueryCharacteristics characteristics1 = new QueryCharacteristics(List.of(characteristics)); queryableProperties.add(JsonSchemaProperty.queryable(schemaObject, characteristics1)); return this; - } public Document toDocument() { + List fields = schema != null ? fromSchema() : new ArrayList<>(queryableProperties.size()); - List fields = new ArrayList<>(queryableProperties.size()); - for(QueryableJsonSchemaProperty property : queryableProperties) { + for (QueryableJsonSchemaProperty property : queryableProperties) { Document field = new Document("path", property.getIdentifier()); - if(!property.getTypes().isEmpty()) { + if (!property.getTypes().isEmpty()) { field.append("bsonType", property.getTypes().iterator().next().toBsonType().value()); } - if(property.getTargetProperty() instanceof IdentifiableJsonSchemaProperty.EncryptedJsonSchemaProperty encrypted) { - if(StringUtils.hasText(encrypted.getKeyId())) { - new BsonBinary(BsonBinarySubType.UUID_STANDARD, encrypted.getKeyId().getBytes(StandardCharsets.UTF_8)); + if (property + .getTargetProperty() instanceof IdentifiableJsonSchemaProperty.EncryptedJsonSchemaProperty encrypted) { + if (StringUtils.hasText(encrypted.getKeyId())) { + field.append("keyId", + new BsonBinary(BsonBinarySubType.UUID_STANDARD, encrypted.getKeyId().getBytes(StandardCharsets.UTF_8))); } } - field.append("queries", property.getCharacteristics().getCharacteristics().stream().map(QueryCharacteristic::toDocument).collect(Collectors.toList())); + field.append("queries", property.getCharacteristics().getCharacteristics().stream() + .map(QueryCharacteristic::toDocument).collect(Collectors.toList())); + if (!field.containsKey("keyId")) { + field.append("keyId", BsonNull.VALUE); + } + fields.add(field); } return new Document("fields", fields); } + + private List fromSchema() { + + Document root = schema.schemaDocument(); + Map paths = new LinkedHashMap<>(); + collectPaths(root, null, paths); + + List fields = new ArrayList<>(); + if (!paths.isEmpty()) { + + for (Entry entry : paths.entrySet()) { + Document field = new Document("path", entry.getKey()); + field.append("keyId", + entry.getValue().containsValue("keyId") ? entry.getValue().get("keyId") : BsonNull.VALUE); + if (entry.getValue().containsKey("bsonType")) { + field.append("bsonType", entry.getValue().get("bsonType")); + } + Document query = new Document("queryType", entry.getValue().get("algorithm", "range").toLowerCase()); + query.append("contention", entry.getValue().get("contention")); + query.append("trimFactor", entry.getValue().get("trimFactor")); + query.append("sparsity", entry.getValue().get("sparsity")); + query.append("min", entry.getValue().get("min")); + query.append("max", entry.getValue().get("max")); + field.append("queries", List.of(query)); + fields.add(field); + } + } + + return fields; + } + + } + + private static void collectPaths(Document document, String currentPath, Map paths) { + + if (document.containsKey("type") && document.get("type").equals("object")) { + Object o = document.get("properties"); + if (o == null) { + 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); + } + } + paths.put(path, target); + } else { + collectPaths(nested, currentPath, paths); + } + } + } + } + } } /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MappingMongoJsonSchemaCreator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MappingMongoJsonSchemaCreator.java index 839f49c7d..e500dcf1f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MappingMongoJsonSchemaCreator.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MappingMongoJsonSchemaCreator.java @@ -31,14 +31,18 @@ import org.springframework.data.mongodb.core.mapping.Encrypted; import org.springframework.data.mongodb.core.mapping.Field; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; +import org.springframework.data.mongodb.core.mapping.RangeEncrypted; import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.ArrayJsonSchemaProperty; import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.EncryptedJsonSchemaProperty; import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.ObjectJsonSchemaProperty; +import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.QueryableJsonSchemaProperty; import org.springframework.data.mongodb.core.schema.JsonSchemaObject; import org.springframework.data.mongodb.core.schema.JsonSchemaObject.Type; import org.springframework.data.mongodb.core.schema.JsonSchemaProperty; import org.springframework.data.mongodb.core.schema.MongoJsonSchema; import org.springframework.data.mongodb.core.schema.MongoJsonSchema.MongoJsonSchemaBuilder; +import org.springframework.data.mongodb.core.schema.QueryCharacteristics; +import org.springframework.data.mongodb.core.schema.QueryCharacteristics.QueryCharacteristic; import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject; import org.springframework.data.util.TypeInformation; import org.springframework.util.Assert; @@ -291,6 +295,28 @@ class MappingMongoJsonSchemaCreator implements MongoJsonSchemaCreator { if (!ObjectUtils.isEmpty(encrypted.keyId())) { enc = enc.keys(property.getEncryptionKeyIds()); } + + RangeEncrypted rangeEncrypted = property.findAnnotation(RangeEncrypted.class); + if (rangeEncrypted != null) { + + QueryCharacteristic characteristic = new QueryCharacteristic() { + + @Override + public String type() { + return "range"; + } + + @Override + public Document toDocument() { + Document options = new Document("queryType", "range"); + if (!rangeEncrypted.rangeOptions().isEmpty()) { + options.putAll(Document.parse(rangeEncrypted.rangeOptions())); + } + return options; + } + }; + return new QueryableJsonSchemaProperty(enc, new QueryCharacteristics(List.of(characteristic))); + } return enc; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/IdentifiableJsonSchemaProperty.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/IdentifiableJsonSchemaProperty.java index 574553cad..4ebc2194f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/IdentifiableJsonSchemaProperty.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/IdentifiableJsonSchemaProperty.java @@ -21,7 +21,6 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import java.util.UUID; -import java.util.stream.Collectors; import org.bson.Document; import org.springframework.data.domain.Range; @@ -91,17 +90,17 @@ public class IdentifiableJsonSchemaProperty implemen this.characteristics = characteristics; } - @Override public Document toDocument() { Document doc = targetProperty.toDocument(); Document propertySpecification = doc.get(targetProperty.getIdentifier(), Document.class); - List queries = characteristics.getCharacteristics().stream().map(QueryCharacteristic::toDocument).toList(); + List queries = characteristics.getCharacteristics().stream().map(QueryCharacteristic::toDocument) + .toList(); propertySpecification.append("queries", queries); - return propertySpecification; + return doc; } @Override 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 24627dbc2..29c8dc732 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,14 +15,10 @@ */ package org.springframework.data.mongodb.core.encryption; -import static java.util.Arrays.*; -import static org.assertj.core.api.Assertions.*; -import static org.springframework.data.mongodb.core.EncryptionAlgorithms.*; -import static org.springframework.data.mongodb.core.query.Criteria.*; -import static org.springframework.data.mongodb.core.schema.JsonSchemaProperty.encrypted; -import static org.springframework.data.mongodb.core.schema.JsonSchemaProperty.int32; -import static org.springframework.data.mongodb.core.schema.JsonSchemaProperty.int64; -import static org.springframework.data.mongodb.core.schema.QueryCharacteristics.range; +import static java.util.Arrays.asList; +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.HashMap; @@ -33,24 +29,6 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.function.Supplier; import java.util.stream.Collectors; -import com.mongodb.AutoEncryptionSettings; -import com.mongodb.ClientEncryptionSettings; -import com.mongodb.ConnectionString; -import com.mongodb.MongoClientSettings; -import com.mongodb.MongoNamespace; -import com.mongodb.client.MongoClient; -import com.mongodb.client.MongoClients; -import com.mongodb.client.MongoCollection; -import com.mongodb.client.MongoDatabase; -import com.mongodb.client.model.CreateCollectionOptions; -import com.mongodb.client.model.CreateEncryptedCollectionParams; -import com.mongodb.client.model.Filters; -import com.mongodb.client.model.IndexOptions; -import com.mongodb.client.model.Indexes; -import com.mongodb.client.model.vault.DataKeyOptions; -import com.mongodb.client.vault.ClientEncryption; -import com.mongodb.client.vault.ClientEncryptions; - import org.bson.BsonArray; import org.bson.BsonBinary; import org.bson.BsonDocument; @@ -60,6 +38,7 @@ import org.bson.BsonNull; import org.bson.BsonString; import org.bson.BsonValue; import org.bson.Document; +import org.bson.json.JsonWriterSettings; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -70,16 +49,14 @@ import org.springframework.context.annotation.Bean; import org.springframework.data.convert.PropertyValueConverterFactory; import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration; import org.springframework.data.mongodb.core.CollectionOptions; -import org.springframework.data.mongodb.core.CollectionOptions.EncryptedCollectionOptions; -import org.springframework.data.mongodb.core.EncryptionAlgorithms; +import org.springframework.data.mongodb.core.MongoJsonSchemaCreator; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.convert.MongoCustomConversions.MongoConverterConfigurationAdapter; import org.springframework.data.mongodb.core.convert.encryption.MongoEncryptionConverter; -import org.springframework.data.mongodb.core.mapping.ExplicitEncrypted; +import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.core.mapping.RangeEncrypted; import org.springframework.data.mongodb.core.query.Query; -import org.springframework.data.mongodb.core.schema.JsonSchemaProperty; -import org.springframework.data.mongodb.core.schema.QueryCharacteristics; +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; @@ -87,6 +64,24 @@ import org.springframework.data.util.Lazy; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; +import com.mongodb.AutoEncryptionSettings; +import com.mongodb.ClientEncryptionSettings; +import com.mongodb.ConnectionString; +import com.mongodb.MongoClientSettings; +import com.mongodb.MongoNamespace; +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoClients; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import com.mongodb.client.model.CreateCollectionOptions; +import com.mongodb.client.model.CreateEncryptedCollectionParams; +import com.mongodb.client.model.Filters; +import com.mongodb.client.model.IndexOptions; +import com.mongodb.client.model.Indexes; +import com.mongodb.client.model.vault.DataKeyOptions; +import com.mongodb.client.vault.ClientEncryption; +import com.mongodb.client.vault.ClientEncryptions; + /** * @author Ross Lawley */ @@ -216,64 +211,81 @@ class RangeEncryptionTests { MongoDatabase database = client.getDatabase(getDatabaseName()); database.getCollection("test").drop(); - ClientEncryption clientEncryption = mongoClientEncryption.getClientEncryption(); - BsonBinary dataKey1 = clientEncryption.createDataKey(LOCAL_KMS_PROVIDER, new DataKeyOptions().keyAltNames(List.of("dek-1"))); -// BsonBinary dataKey2 = clientEncryption.createDataKey(LOCAL_KMS_PROVIDER, new DataKeyOptions().keyAltNames(List.of("dek-2"))); + BsonBinary dataKey1 = clientEncryption.createDataKey(LOCAL_KMS_PROVIDER, + new DataKeyOptions().keyAltNames(List.of("dek-1"))); + // BsonBinary dataKey2 = clientEncryption.createDataKey(LOCAL_KMS_PROVIDER, new + // DataKeyOptions().keyAltNames(List.of("dek-2"))); BsonDocument encryptedFields = new BsonDocument().append("fields", new BsonArray(asList( -// new BsonDocument("keyId", dataKey1).append("path", new BsonString("name")) -// .append("bsonType", new BsonString("string")), - new BsonDocument("keyId", BsonNull.VALUE).append("path", new BsonString("encryptedInt")) .append("bsonType", new BsonString("int")) .append("queries", new BsonDocument("queryType", new BsonString("range")).append("contention", new BsonInt64(0L)) .append("trimFactor", new BsonInt32(1)).append("sparsity", new BsonInt64(1)) .append("min", new BsonInt32(0)).append("max", new BsonInt32(200))), - new BsonDocument("keyId", BsonNull.VALUE).append("path", new BsonString("encryptedLong")) + new BsonDocument("keyId", BsonNull.VALUE).append("path", new BsonString("encryptedLong")) .append("bsonType", new BsonString("long")).append("queries", new BsonDocument("queryType", new BsonString("range")).append("contention", new BsonInt64(0L)) .append("trimFactor", new BsonInt32(1)).append("sparsity", new BsonInt64(1)) .append("min", new BsonInt64(1000)).append("max", new BsonInt64(9999)))))); - -// BsonBinary dataKey2 = clientEncryption.createDataKey(LOCAL_KMS_PROVIDER, new DataKeyOptions().keyAltNames(List.of("dek-2"))); -// -// BsonDocument encryptedFields = new BsonDocument().append("fields", -// new BsonArray(asList( -// new BsonDocument("keyId", dataKey1).append("path", new BsonString("encryptedInt")) -// .append("bsonType", new BsonString("int")) -// .append("queries", -// new BsonDocument("queryType", new BsonString("range")).append("contention", new BsonInt64(0L)) -// .append("trimFactor", new BsonInt32(1)).append("sparsity", new BsonInt64(1)) -// .append("min", new BsonInt32(0)).append("max", new BsonInt32(200))), -// new BsonDocument("keyId", dataKey2).append("path", new BsonString("encryptedLong")) -// .append("bsonType", new BsonString("long")).append("queries", -// new BsonDocument("queryType", new BsonString("range")).append("contention", new BsonInt64(0L)) -// .append("trimFactor", new BsonInt32(1)).append("sparsity", new BsonInt64(1)) -// .append("min", new BsonInt64(1000)).append("max", new BsonInt64(9999)))))); -// - - CollectionOptions.encrypted(options -> - options - .queryable( - encrypted(int32("encryptedInt")), - range().contention(0).trimFactor(1).sparsity(1).min(0).max(200) - ).queryable( - encrypted(int64("encryptedLong")), - range().contention(0).trimFactor(1).sparsity(1).min(1000L).max(9999L) - ) - - ); + // BsonBinary dataKey2 = clientEncryption.createDataKey(LOCAL_KMS_PROVIDER, new + // DataKeyOptions().keyAltNames(List.of("dek-2"))); + // + // BsonDocument encryptedFields = new BsonDocument().append("fields", + // new BsonArray(asList( + // new BsonDocument("keyId", dataKey1).append("path", new BsonString("encryptedInt")) + // .append("bsonType", new BsonString("int")) + // .append("queries", + // new BsonDocument("queryType", new BsonString("range")).append("contention", new BsonInt64(0L)) + // .append("trimFactor", new BsonInt32(1)).append("sparsity", new BsonInt64(1)) + // .append("min", new BsonInt32(0)).append("max", new BsonInt32(200))), + // new BsonDocument("keyId", dataKey2).append("path", new BsonString("encryptedLong")) + // .append("bsonType", new BsonString("long")).append("queries", + // new BsonDocument("queryType", new BsonString("range")).append("contention", new BsonInt64(0L)) + // .append("trimFactor", new BsonInt32(1)).append("sparsity", new BsonInt64(1)) + // .append("min", new BsonInt64(1000)).append("max", new BsonInt64(9999)))))); + // + + // CollectionOptions encOptions = CollectionOptions.encrypted(options -> + // options + // .queryable( + // encrypted(int32("encryptedInt")), + // range().contention(0).trimFactor(1).sparsity(1).min(0).max(200) + // ).queryable( + // encrypted(int64("encryptedLong")), + // range().contention(0).trimFactor(1).sparsity(1).min(1000L).max(9999L) + // ) + // ); + + MongoJsonSchema personSchema = MongoJsonSchemaCreator.create(new MongoMappingContext()) + .filter(MongoJsonSchemaCreator.encryptedOnly()).createSchemaFor(Person.class); + + CollectionOptions options = CollectionOptions.encrypted(personSchema); + System.out.println("encrypted: " + options.getEncryptedFields().get().toDocument() + .toJson(JsonWriterSettings.builder().indent(true).build())); + + // Document document = personSchema.toDocument(); + // System.out.println("document.toJson(): " + + // document.toJson(JsonWriterSettings.builder().indent(true).build())); + // + // Document fromGenerated = encOptions.getEncryptedFields().get().toDocument(); + // System.out.println(fromGenerated.toJson(JsonWriterSettings.builder().indent(true).build())); + // + // System.out.println("-----"); + // + // System.out.println( encryptedFields.toJson(JsonWriterSettings.builder().indent(true).build())); BsonDocument local = clientEncryption.createEncryptedCollection(database, "test", - new CreateCollectionOptions().encryptedFields(encryptedFields), + // new CreateCollectionOptions().encryptedFields(encryptedFields), + // new CreateCollectionOptions().encryptedFields(fromGenerated), + new CreateCollectionOptions().encryptedFields(options.getEncryptedFields().get().toDocument()), new CreateEncryptedCollectionParams(LOCAL_KMS_PROVIDER)); Map x = local.getArray("fields").stream().map(BsonValue::asDocument).collect( - Collectors.toMap(field -> field.getString("path").getValue(), field -> field.getBinary("keyId"))); + Collectors.toMap(field -> field.getString("path").getValue(), field -> field.getBinary("keyId"))); HashMap stringBsonBinaryHashMap = new HashMap<>(x); stringBsonBinaryHashMap.put("name", dataKey1); @@ -297,7 +309,7 @@ class RangeEncryptionTests { builder.autoEncryptionSettings(AutoEncryptionSettings.builder() // .kmsProviders(clientEncryptionSettings.getKmsProviders()) // .keyVaultNamespace(clientEncryptionSettings.getKeyVaultNamespace()) // -// .bypassAutoEncryption(true) + // .bypassAutoEncryption(true) .bypassQueryAnalysis(true).build()); } }