Browse Source

you shall pass!

issue/4185-light
Christoph Strobl 9 months ago
parent
commit
05b94f5253
No known key found for this signature in database
GPG Key ID: E6054036D0C37A4B
  1. 15
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionOptions.java
  2. 12
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/IdentifiableJsonSchemaProperty.java
  3. 20
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultIndexOperationsIntegrationTests.java
  4. 141
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/MongoQueryableEncryptionCollectionCreationTests.java
  5. 61
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/RangeEncryptionTests.java

15
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionOptions.java

@ -46,7 +46,6 @@ import org.springframework.data.util.Optionals;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import com.mongodb.client.model.ValidationAction; import com.mongodb.client.model.ValidationAction;
import com.mongodb.client.model.ValidationLevel; import com.mongodb.client.model.ValidationLevel;
@ -354,7 +353,8 @@ public class CollectionOptions {
* @since 4.5.0 * @since 4.5.0
*/ */
public static CollectionOptions encrypted(@Nullable EncryptedCollectionOptions encryptedCollectionOptions) { 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, ValidationOptions.NONE, null, null,
encryptedCollectionOptions);
} }
public static CollectionOptions encrypted(MongoJsonSchema schema) { public static CollectionOptions encrypted(MongoJsonSchema schema) {
@ -665,9 +665,13 @@ public class CollectionOptions {
} }
if (property if (property
.getTargetProperty() instanceof IdentifiableJsonSchemaProperty.EncryptedJsonSchemaProperty encrypted) { .getTargetProperty() instanceof IdentifiableJsonSchemaProperty.EncryptedJsonSchemaProperty encrypted) {
if (StringUtils.hasText(encrypted.getKeyId())) { if (encrypted.getKeyId() != null) {
if (encrypted.getKeyId() instanceof String stringKey) {
field.append("keyId", field.append("keyId",
new BsonBinary(BsonBinarySubType.UUID_STANDARD, encrypted.getKeyId().getBytes(StandardCharsets.UTF_8))); new BsonBinary(BsonBinarySubType.UUID_STANDARD, stringKey.getBytes(StandardCharsets.UTF_8)));
} else {
field.append("keyId", encrypted.getKeyId());
}
} }
} }
field.append("queries", property.getCharacteristics().getCharacteristics().stream() field.append("queries", property.getCharacteristics().getCharacteristics().stream()
@ -692,8 +696,7 @@ public class CollectionOptions {
for (Entry<String, Document> entry : paths.entrySet()) { for (Entry<String, Document> entry : paths.entrySet()) {
Document field = new Document("path", entry.getKey()); Document field = new Document("path", entry.getKey());
field.append("keyId", field.append("keyId", entry.getValue().getOrDefault("keyId", BsonNull.VALUE));
entry.getValue().containsValue("keyId") ? entry.getValue().get("keyId") : BsonNull.VALUE);
if (entry.getValue().containsKey("bsonType")) { if (entry.getValue().containsKey("bsonType")) {
field.append("bsonType", entry.getValue().get("bsonType")); field.append("bsonType", entry.getValue().get("bsonType"));
} }

12
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/IdentifiableJsonSchemaProperty.java

@ -1179,8 +1179,12 @@ public class IdentifiableJsonSchemaProperty<T extends JsonSchemaObject> implemen
if (!ObjectUtils.isEmpty(keyId)) { if (!ObjectUtils.isEmpty(keyId)) {
enc.append("keyId", keyId); enc.append("keyId", keyId);
} else if (!ObjectUtils.isEmpty(keyIds)) { } else if (!ObjectUtils.isEmpty(keyIds)) {
if(keyIds.size() == 1) {
enc.append("keyId", keyIds.iterator().next());
} else {
enc.append("keyId", keyIds); enc.append("keyId", keyIds);
} }
}
Type type = extractPropertyType(propertySpecification); Type type = extractPropertyType(propertySpecification);
if (type != null) { if (type != null) {
@ -1221,8 +1225,14 @@ public class IdentifiableJsonSchemaProperty<T extends JsonSchemaObject> implemen
return null; return null;
} }
public String getKeyId() { public Object getKeyId() {
if(keyId != null) {
return keyId; return keyId;
} }
if(keyIds != null && keyIds.size() == 1) {
return keyIds.iterator().next();
}
return null;
}
} }
} }

20
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultIndexOperationsIntegrationTests.java

@ -15,9 +15,9 @@
*/ */
package org.springframework.data.mongodb.core; package org.springframework.data.mongodb.core;
import static org.assertj.core.api.Assertions.*; import static org.springframework.data.mongodb.core.index.PartialIndexFilter.of;
import static org.springframework.data.mongodb.core.index.PartialIndexFilter.*; import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Criteria.*; import static org.springframework.data.mongodb.test.util.Assertions.assertThat;
import org.bson.BsonDocument; import org.bson.BsonDocument;
import org.bson.Document; import org.bson.Document;
@ -79,7 +79,7 @@ public class DefaultIndexOperationsIntegrationTests {
IndexDefinition id = new Index().named("partial-with-criteria").on("k3y", Direction.ASC) IndexDefinition id = new Index().named("partial-with-criteria").on("k3y", Direction.ASC)
.partial(of(where("q-t-y").gte(10))); .partial(of(where("q-t-y").gte(10)));
indexOps.ensureIndex(id); indexOps.createIndex(id);
IndexInfo info = findAndReturnIndexInfo(indexOps.getIndexInfo(), "partial-with-criteria"); IndexInfo info = findAndReturnIndexInfo(indexOps.getIndexInfo(), "partial-with-criteria");
assertThat(Document.parse(info.getPartialFilterExpression())) assertThat(Document.parse(info.getPartialFilterExpression()))
@ -92,7 +92,7 @@ public class DefaultIndexOperationsIntegrationTests {
IndexDefinition id = new Index().named("partial-with-mapped-criteria").on("k3y", Direction.ASC) IndexDefinition id = new Index().named("partial-with-mapped-criteria").on("k3y", Direction.ASC)
.partial(of(where("quantity").gte(10))); .partial(of(where("quantity").gte(10)));
template.indexOps(DefaultIndexOperationsIntegrationTestsSample.class).ensureIndex(id); template.indexOps(DefaultIndexOperationsIntegrationTestsSample.class).createIndex(id);
IndexInfo info = findAndReturnIndexInfo(indexOps.getIndexInfo(), "partial-with-mapped-criteria"); IndexInfo info = findAndReturnIndexInfo(indexOps.getIndexInfo(), "partial-with-mapped-criteria");
assertThat(Document.parse(info.getPartialFilterExpression())) assertThat(Document.parse(info.getPartialFilterExpression()))
@ -105,7 +105,7 @@ public class DefaultIndexOperationsIntegrationTests {
IndexDefinition id = new Index().named("partial-with-dbo").on("k3y", Direction.ASC) IndexDefinition id = new Index().named("partial-with-dbo").on("k3y", Direction.ASC)
.partial(of(new org.bson.Document("qty", new org.bson.Document("$gte", 10)))); .partial(of(new org.bson.Document("qty", new org.bson.Document("$gte", 10))));
indexOps.ensureIndex(id); indexOps.createIndex(id);
IndexInfo info = findAndReturnIndexInfo(indexOps.getIndexInfo(), "partial-with-dbo"); IndexInfo info = findAndReturnIndexInfo(indexOps.getIndexInfo(), "partial-with-dbo");
assertThat(Document.parse(info.getPartialFilterExpression())) assertThat(Document.parse(info.getPartialFilterExpression()))
@ -120,7 +120,7 @@ public class DefaultIndexOperationsIntegrationTests {
indexOps = new DefaultIndexOperations(template, COLLECTION_NAME, MappingToSameCollection.class); indexOps = new DefaultIndexOperations(template, COLLECTION_NAME, MappingToSameCollection.class);
indexOps.ensureIndex(id); indexOps.createIndex(id);
IndexInfo info = findAndReturnIndexInfo(indexOps.getIndexInfo(), "partial-with-inheritance"); IndexInfo info = findAndReturnIndexInfo(indexOps.getIndexInfo(), "partial-with-inheritance");
assertThat(Document.parse(info.getPartialFilterExpression())) assertThat(Document.parse(info.getPartialFilterExpression()))
@ -150,7 +150,7 @@ public class DefaultIndexOperationsIntegrationTests {
new DefaultIndexOperations(template, COLLECTION_NAME, MappingToSameCollection.class); new DefaultIndexOperations(template, COLLECTION_NAME, MappingToSameCollection.class);
indexOps.ensureIndex(id); indexOps.createIndex(id);
Document expected = new Document("locale", "de_AT") // Document expected = new Document("locale", "de_AT") //
.append("caseLevel", false) // .append("caseLevel", false) //
@ -179,7 +179,7 @@ public class DefaultIndexOperationsIntegrationTests {
IndexDefinition index = new Index().named("my-index").on("a", Direction.ASC); IndexDefinition index = new Index().named("my-index").on("a", Direction.ASC);
indexOps = new DefaultIndexOperations(template, COLLECTION_NAME, MappingToSameCollection.class); indexOps = new DefaultIndexOperations(template, COLLECTION_NAME, MappingToSameCollection.class);
indexOps.ensureIndex(index); indexOps.createIndex(index);
IndexInfo info = findAndReturnIndexInfo(indexOps.getIndexInfo(), "my-index"); IndexInfo info = findAndReturnIndexInfo(indexOps.getIndexInfo(), "my-index");
assertThat(info.isHidden()).isFalse(); assertThat(info.isHidden()).isFalse();
@ -191,7 +191,7 @@ public class DefaultIndexOperationsIntegrationTests {
IndexDefinition index = new Index().named("my-hidden-index").on("a", Direction.ASC).hidden(); IndexDefinition index = new Index().named("my-hidden-index").on("a", Direction.ASC).hidden();
indexOps = new DefaultIndexOperations(template, COLLECTION_NAME, MappingToSameCollection.class); indexOps = new DefaultIndexOperations(template, COLLECTION_NAME, MappingToSameCollection.class);
indexOps.ensureIndex(index); indexOps.createIndex(index);
IndexInfo info = findAndReturnIndexInfo(indexOps.getIndexInfo(), "my-hidden-index"); IndexInfo info = findAndReturnIndexInfo(indexOps.getIndexInfo(), "my-hidden-index");
assertThat(info.isHidden()).isTrue(); assertThat(info.isHidden()).isTrue();

141
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/MongoQueryableEncryptionCollectionCreationTests.java

@ -0,0 +1,141 @@
/*
* Copyright 2025. the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.mongodb.core.encryption;
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.JsonSchemaProperty.queryable;
import static org.springframework.data.mongodb.core.schema.QueryCharacteristics.range;
import static org.springframework.data.mongodb.test.util.Assertions.assertThat;
import java.util.List;
import java.util.UUID;
import java.util.stream.Stream;
import org.bson.BsonBinary;
import org.bson.Document;
import org.bson.UuidRepresentation;
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.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration;
import org.springframework.data.mongodb.core.CollectionOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.schema.JsonSchemaProperty;
import org.springframework.data.mongodb.core.schema.MongoJsonSchema;
import org.springframework.data.mongodb.core.schema.QueryCharacteristics;
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;
import com.mongodb.client.MongoClient;
/**
* @author Christoph Strobl
*/
@ExtendWith({ MongoClientExtension.class, SpringExtension.class })
@ContextConfiguration
public class MongoQueryableEncryptionCollectionCreationTests {
public static final String COLLECTION_NAME = "enc-collection";
static @Client MongoClient mongoClient;
@Configuration
static class Config extends AbstractMongoClientConfiguration {
@Override
public MongoClient mongoClient() {
return mongoClient;
}
@Override
protected String getDatabaseName() {
return "encryption-schema-tests";
}
}
@Autowired MongoTemplate template;
@BeforeEach
void beforeEach() {
template.dropCollection(COLLECTION_NAME);
}
@ParameterizedTest // GH-4185
@MethodSource("collectionOptions")
public void createsCollectionWithEncryptedFieldsCorrectly(CollectionOptions collectionOptions) {
template.createCollection(COLLECTION_NAME, collectionOptions);
Document encryptedFields = readEncryptedFieldsFromDatabase(COLLECTION_NAME);
assertThat(encryptedFields).containsKey("fields");
List<Document> fields = encryptedFields.get("fields", List.of());
assertThat(fields.get(0)).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") //
.containsEntry("bsonType", "long") //
.containsEntry("queries", List.of(Document.parse(
"{'queryType': 'range', 'contention': { '$numberLong' : '0' }, 'min': { '$numberLong' : '-1' }, 'max': { '$numberLong' : '1' }}")));
}
private static Stream<Arguments> collectionOptions() {
BsonBinary key1 = new BsonBinary(UUID.randomUUID(), UuidRepresentation.STANDARD);
BsonBinary key2 = new BsonBinary(UUID.randomUUID(), UuidRepresentation.STANDARD);
CollectionOptions manualOptions = CollectionOptions.encrypted(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)));
CollectionOptions schemaOptions = CollectionOptions.encrypted(MongoJsonSchema.builder()
.property(queryable(encrypted(int32("encryptedInt")).keys(key1),
new QueryCharacteristics(List.of(range().min(5).max(100).contention(1)))))
.property(queryable(encrypted(int64("nested.encryptedLong")).keys(key2),
new QueryCharacteristics(List.of(range().min(-1L).max(1L).contention(0)))))
.build());
return Stream.of(Arguments.of(manualOptions), Arguments.of(schemaOptions));
}
Document readEncryptedFieldsFromDatabase(String collectionName) {
Document collectionInfo = template
.executeCommand(new Document("listCollections", 1).append("filter", new Document("name", collectionName)));
if (collectionInfo.containsKey("cursor")) {
collectionInfo = (Document) collectionInfo.get("cursor", Document.class).get("firstBatch", List.class).iterator()
.next();
}
if (!collectionInfo.containsKey("options")) {
return new Document();
}
return collectionInfo.get("options", Document.class).get("encryptedFields", Document.class);
}
}

61
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/RangeEncryptionTests.java

@ -15,7 +15,6 @@
*/ */
package org.springframework.data.mongodb.core.encryption; package org.springframework.data.mongodb.core.encryption;
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.springframework.data.mongodb.core.query.Criteria.where; import static org.springframework.data.mongodb.core.query.Criteria.where;
@ -28,13 +27,9 @@ import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.bson.BsonArray;
import org.bson.BsonBinary; import org.bson.BsonBinary;
import org.bson.BsonDocument; import org.bson.BsonDocument;
import org.bson.BsonInt32; import org.bson.BsonInt32;
import org.bson.BsonInt64;
import org.bson.BsonNull;
import org.bson.BsonString;
import org.bson.BsonValue; import org.bson.BsonValue;
import org.bson.Document; import org.bson.Document;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
@ -47,6 +42,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.data.convert.PropertyValueConverterFactory; import org.springframework.data.convert.PropertyValueConverterFactory;
import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration; import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration;
import org.springframework.data.mongodb.core.CollectionOptions; import org.springframework.data.mongodb.core.CollectionOptions;
import org.springframework.data.mongodb.core.CollectionOptions.EncryptedCollectionOptions;
import org.springframework.data.mongodb.core.MongoJsonSchemaCreator; import org.springframework.data.mongodb.core.MongoJsonSchemaCreator;
import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.convert.MongoCustomConversions.MongoConverterConfigurationAdapter; import org.springframework.data.mongodb.core.convert.MongoCustomConversions.MongoConverterConfigurationAdapter;
@ -120,9 +116,8 @@ class RangeEncryptionTests {
Document result = template.execute(Person.class, col -> { Document result = template.execute(Person.class, col -> {
BsonDocument filterSource = new BsonDocument("encryptedInt", new BsonDocument("$gte", new BsonInt32(100))); BsonDocument filterSource = new BsonDocument("encryptedInt", new BsonDocument("$gte", new BsonInt32(100)));
BsonDocument filter = clientEncryption.getClientEncryption().encryptExpression( BsonDocument filter = clientEncryption.getClientEncryption()
new Document("$and", List.of(filterSource)), .encryptExpression(new Document("$and", List.of(filterSource)), encryptExpressionOptions);
encryptExpressionOptions);
Document first = col.find(filter).first(); Document first = col.find(filter).first();
// Document first = col.find(filterSource).first(); // Document first = col.find(filterSource).first();
System.out.println("first.toJson(): " + first.toJson()); System.out.println("first.toJson(): " + first.toJson());
@ -240,29 +235,36 @@ class RangeEncryptionTests {
ClientEncryption clientEncryption = mongoClientEncryption.getClientEncryption(); ClientEncryption clientEncryption = mongoClientEncryption.getClientEncryption();
BsonDocument encryptedFields = new BsonDocument().append("fields", // BsonDocument encryptedFields = new BsonDocument().append("fields",
new BsonArray(asList( // new BsonArray(asList(
new BsonDocument("keyId", BsonNull.VALUE).append("path", new BsonString("encryptedInt")) // new BsonDocument("keyId", BsonNull.VALUE).append("path", new BsonString("encryptedInt"))
.append("bsonType", new BsonString("int")) // .append("bsonType", new BsonString("int"))
.append("queries", // .append("queries",
new BsonDocument("queryType", new BsonString("range")).append("contention", new BsonInt64(0L)) // new BsonDocument("queryType", new BsonString("range")).append("contention", new BsonInt64(0L))
.append("trimFactor", new BsonInt32(1)).append("sparsity", new BsonInt64(1)) // .append("trimFactor", new BsonInt32(1)).append("sparsity", new BsonInt64(1))
.append("min", new BsonInt32(0)).append("max", new BsonInt32(200))), // .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", // .append("bsonType", new BsonString("long")).append("queries",
new BsonDocument("queryType", new BsonString("range")).append("contention", new BsonInt64(0L)) // new BsonDocument("queryType", new BsonString("range")).append("contention", new BsonInt64(0L))
.append("trimFactor", new BsonInt32(1)).append("sparsity", new BsonInt64(1)) // .append("trimFactor", new BsonInt32(1)).append("sparsity", new BsonInt64(1))
.append("min", new BsonInt64(1000)).append("max", new BsonInt64(9999)))))); // .append("min", new BsonInt64(1000)).append("max", new BsonInt64(9999))))));
MongoJsonSchema personSchema = MongoJsonSchemaCreator.create(new MongoMappingContext()) MongoJsonSchema personSchema = MongoJsonSchemaCreator.create(new MongoMappingContext()) // init schema creator
.filter(MongoJsonSchemaCreator.encryptedOnly()).createSchemaFor(Person.class); .filter(MongoJsonSchemaCreator.encryptedOnly()) // should be obvious
.createSchemaFor(Person.class); // create it for given type
CollectionOptions options = CollectionOptions.encrypted(personSchema);
Document encryptedFields = CollectionOptions.encrypted(personSchema) // pass in the schema
.getEncryptedFields() // get the fields just because we need to use createEncryptedCollection which not
// part of the driver
.map(EncryptedCollectionOptions::toDocument) // now map them into the raw format
.orElseThrow();
CreateCollectionOptions createCollectionOptions = new CreateCollectionOptions()
.encryptedFields(encryptedFields); // that's it
BsonDocument local = clientEncryption.createEncryptedCollection(database, "test", BsonDocument local = clientEncryption.createEncryptedCollection(database, "test",
// new CreateCollectionOptions().encryptedFields(encryptedFields), // new CreateCollectionOptions().encryptedFields(encryptedFields),
new CreateCollectionOptions().encryptedFields(options.getEncryptedFields().get().toDocument()), createCollectionOptions, new CreateEncryptedCollectionParams(LOCAL_KMS_PROVIDER));
new CreateEncryptedCollectionParams(LOCAL_KMS_PROVIDER));
return local.getArray("fields").stream().map(BsonValue::asDocument).collect( return 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")));
@ -292,8 +294,7 @@ class RangeEncryptionTests {
builder.autoEncryptionSettings(AutoEncryptionSettings.builder() // builder.autoEncryptionSettings(AutoEncryptionSettings.builder() //
.kmsProviders(clientEncryptionSettings.getKmsProviders()) // .kmsProviders(clientEncryptionSettings.getKmsProviders()) //
.keyVaultNamespace(clientEncryptionSettings.getKeyVaultNamespace()) // .keyVaultNamespace(clientEncryptionSettings.getKeyVaultNamespace()) //
.bypassQueryAnalysis(true) .bypassQueryAnalysis(true).build());
.build());
} }
} }

Loading…
Cancel
Save