diff --git a/pom.xml b/pom.xml
index 4aacfba029..06d9d76578 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.data
spring-data-mongodb-parent
- 2.2.0.BUILD-SNAPSHOT
+ 2.2.0.DATAMONGO-2306-SNAPSHOT
pom
Spring Data MongoDB
diff --git a/spring-data-mongodb-benchmarks/pom.xml b/spring-data-mongodb-benchmarks/pom.xml
index bb7d9f03cc..9fc0ab77b4 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.2.0.BUILD-SNAPSHOT
+ 2.2.0.DATAMONGO-2306-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb-distribution/pom.xml b/spring-data-mongodb-distribution/pom.xml
index b32dcba387..63ed8736d0 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.2.0.BUILD-SNAPSHOT
+ 2.2.0.DATAMONGO-2306-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml
index b611cf01a8..4af3ccf2d5 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.2.0.BUILD-SNAPSHOT
+ 2.2.0.DATAMONGO-2306-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoParsingUtils.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoParsingUtils.java
index 63a294f553..36c2544c48 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoParsingUtils.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoParsingUtils.java
@@ -35,6 +35,7 @@
* @author Oliver Gierke
* @author Thomas Darimont
* @author Christoph Strobl
+ * @author Mark Paluch
*/
@SuppressWarnings("deprecation")
abstract class MongoParsingUtils {
@@ -92,6 +93,7 @@ public static boolean parseMongoClientOptions(Element element, BeanDefinitionBui
setPropertyValue(clientOptionsDefBuilder, optionsElement, "heartbeat-socket-timeout", "heartbeatSocketTimeout");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "ssl", "ssl");
setPropertyReference(clientOptionsDefBuilder, optionsElement, "ssl-socket-factory-ref", "sslSocketFactory");
+ setPropertyReference(clientOptionsDefBuilder, optionsElement, "encryption-settings-ref", "autoEncryptionSettings");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "server-selection-timeout", "serverSelectionTimeout");
mongoClientBuilder.addPropertyValue("mongoClientOptions", clientOptionsDefBuilder.getBeanDefinition());
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoClientOptionsFactoryBean.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoClientOptionsFactoryBean.java
index d3e169a180..249815ccf0 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoClientOptionsFactoryBean.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoClientOptionsFactoryBean.java
@@ -22,6 +22,7 @@
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.lang.Nullable;
+import com.mongodb.AutoEncryptionSettings;
import com.mongodb.DBDecoderFactory;
import com.mongodb.DBEncoderFactory;
import com.mongodb.MongoClient;
@@ -73,6 +74,7 @@ public class MongoClientOptionsFactoryBean extends AbstractFactoryBean {
+
+ private boolean bypassAutoEncryption;
+ private String keyVaultNamespace;
+ private Map extraOptions;
+ private MongoClientSettings keyVaultClientSettings;
+ private Map> kmsProviders;
+ private Map schemaMap;
+
+ /**
+ * @param bypassAutoEncryption
+ * @see AutoEncryptionSettings.Builder#bypassAutoEncryption(boolean)
+ */
+ public void setBypassAutoEncryption(boolean bypassAutoEncryption) {
+ this.bypassAutoEncryption = bypassAutoEncryption;
+ }
+
+ /**
+ * @param extraOptions
+ * @see AutoEncryptionSettings.Builder#extraOptions(Map)
+ */
+ public void setExtraOptions(Map extraOptions) {
+ this.extraOptions = extraOptions;
+ }
+
+ /**
+ * @param keyVaultNamespace
+ * @see AutoEncryptionSettings.Builder#keyVaultNamespace(String)
+ */
+ public void setKeyVaultNamespace(String keyVaultNamespace) {
+ this.keyVaultNamespace = keyVaultNamespace;
+ }
+
+ /**
+ * @param keyVaultClientSettings
+ * @see AutoEncryptionSettings.Builder#keyVaultMongoClientSettings(MongoClientSettings)
+ */
+ public void setKeyVaultClientSettings(MongoClientSettings keyVaultClientSettings) {
+ this.keyVaultClientSettings = keyVaultClientSettings;
+ }
+
+ /**
+ * @param kmsProviders
+ * @see AutoEncryptionSettings.Builder#kmsProviders(Map)
+ */
+ public void setKmsProviders(Map> kmsProviders) {
+ this.kmsProviders = kmsProviders;
+ }
+
+ /**
+ * @param schemaMap
+ * @see AutoEncryptionSettings.Builder#schemaMap(Map)
+ */
+ public void setSchemaMap(Map schemaMap) {
+ this.schemaMap = schemaMap;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.beans.factory.FactoryBean#getObject()
+ */
+ @Override
+ public AutoEncryptionSettings getObject() {
+
+ return AutoEncryptionSettings.builder() //
+ .bypassAutoEncryption(bypassAutoEncryption) //
+ .keyVaultNamespace(keyVaultNamespace) //
+ .keyVaultMongoClientSettings(keyVaultClientSettings) //
+ .kmsProviders(orEmpty(kmsProviders)) //
+ .extraOptions(orEmpty(extraOptions)) //
+ .schemaMap(orEmpty(schemaMap)) //
+ .build();
+ }
+
+ private Map orEmpty(@Nullable Map source) {
+ return source != null ? source : Collections.emptyMap();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.beans.factory.FactoryBean#getObjectType()
+ */
+ @Override
+ public Class> getObjectType() {
+ return AutoEncryptionSettings.class;
+ }
+}
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 bf2e801865..0057d7d06b 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
@@ -30,7 +30,9 @@
import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.ObjectJsonSchemaObject;
import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.StringJsonSchemaObject;
import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.TimestampJsonSchemaObject;
+import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
+import org.springframework.util.ObjectUtils;
/**
* {@link JsonSchemaProperty} implementation.
@@ -1044,4 +1046,140 @@ public boolean isRequired() {
return required;
}
}
+
+ /**
+ * {@link JsonSchemaProperty} implementation for encrypted fields.
+ *
+ * @author Christoph Strobl
+ * @since 2.2
+ */
+ public static class EncryptedJsonSchemaProperty implements JsonSchemaProperty {
+
+ private final JsonSchemaProperty targetProperty;
+ private final @Nullable String algorithm;
+ private final @Nullable String keyId;
+
+ /**
+ * Create new instance of {@link EncryptedJsonSchemaProperty} wrapping the given {@link JsonSchemaProperty target}.
+ *
+ * @param target must not be {@literal null}.
+ */
+ public EncryptedJsonSchemaProperty(JsonSchemaProperty target) {
+ this(target, null, null);
+ }
+
+ private EncryptedJsonSchemaProperty(JsonSchemaProperty target, @Nullable String algorithm, @Nullable String keyId) {
+
+ Assert.notNull(target, "Target must not be null!");
+ this.targetProperty = target;
+ this.algorithm = algorithm;
+ this.keyId = keyId;
+ }
+
+ /**
+ * Create new instance of {@link EncryptedJsonSchemaProperty} wrapping the given {@link JsonSchemaProperty target}.
+ *
+ * @param target must not be {@literal null}.
+ * @return new instance of {@link EncryptedJsonSchemaProperty}.
+ */
+ public static EncryptedJsonSchemaProperty encrypted(JsonSchemaProperty target) {
+ return new EncryptedJsonSchemaProperty(target);
+ }
+
+ /**
+ * Use {@literal AEAD_AES_256_CBC_HMAC_SHA_512-Random} algorithm.
+ *
+ * @return new instance of {@link EncryptedJsonSchemaProperty}.
+ */
+ public EncryptedJsonSchemaProperty aead_aes_256_cbc_hmac_sha_512_random() {
+ return algorithm("AEAD_AES_256_CBC_HMAC_SHA_512-Random");
+ }
+
+ /**
+ * Use {@literal AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic} algorithm.
+ *
+ * @return new instance of {@link EncryptedJsonSchemaProperty}.
+ */
+ public EncryptedJsonSchemaProperty aead_aes_256_cbc_hmac_sha_512_deterministic() {
+ return algorithm("AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic");
+ }
+
+ /**
+ * Use the given algorithm identified via its name.
+ *
+ * @return new instance of {@link EncryptedJsonSchemaProperty}.
+ */
+ public EncryptedJsonSchemaProperty algorithm(String algorithm) {
+ return new EncryptedJsonSchemaProperty(targetProperty, algorithm, keyId);
+ }
+
+ /**
+ * @param key
+ * @return
+ */
+ public EncryptedJsonSchemaProperty keyId(String keyId) {
+ return new EncryptedJsonSchemaProperty(targetProperty, algorithm, keyId);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.mongodb.core.schema.JsonSchemaObject#toDocument()
+ */
+ @Override
+ public Document toDocument() {
+
+ Document doc = targetProperty.toDocument();
+ Document propertySpecification = doc.get(targetProperty.getIdentifier(), Document.class);
+
+ Document enc = new Document();
+
+ if (!ObjectUtils.isEmpty(keyId)) {
+ enc.append("keyId", keyId);
+ }
+
+ Type type = extractPropertyType(propertySpecification);
+ if (type != null) {
+
+ propertySpecification.remove(type.representation());
+ enc.append("bsonType", type.toBsonType().value()); // TODO: no samples with type -> is it bson type all the way?
+ }
+
+ enc.append("algorithm", algorithm);
+
+ propertySpecification.append("encrypt", enc);
+
+ return doc;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.mongodb.core.schema.JsonSchemaProperty#getIdentifier()
+ */
+ @Override
+ public String getIdentifier() {
+ return targetProperty.getIdentifier();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.mongodb.core.schema.JsonSchemaObject#getTypes()
+ */
+ @Override
+ public Set getTypes() {
+ return targetProperty.getTypes();
+ }
+
+ @Nullable
+ private Type extractPropertyType(Document source) {
+
+ if (source.containsKey("type")) {
+ return Type.of(source.get("type", String.class));
+ }
+ if (source.containsKey("bsonType")) {
+ return Type.of(source.get("bsonType", String.class));
+ }
+
+ return null;
+ }
+ }
}
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/JsonSchemaObject.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/JsonSchemaObject.java
index 375845ada8..5f0421272c 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/JsonSchemaObject.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/JsonSchemaObject.java
@@ -15,6 +15,7 @@
*/
package org.springframework.data.mongodb.core.schema;
+import lombok.EqualsAndHashCode;
import lombok.RequiredArgsConstructor;
import java.math.BigDecimal;
@@ -428,6 +429,23 @@ static Type jsonTypeOf(String name) {
return new JsonType(name);
}
+ /**
+ * Create a {@link Type} with its default {@link Type#representation() representation} via the name.
+ *
+ * @param name must not be {@literal null}.
+ * @return the matching type instance.
+ * @since 2.2
+ */
+ static Type of(String name) {
+
+ Type type = jsonTypeOf(name);
+ if (jsonTypes().contains(type)) {
+ return type;
+ }
+
+ return bsonTypeOf(name);
+ }
+
/**
* @return all known JSON types.
*/
@@ -456,11 +474,34 @@ static Set bsonTypes() {
*/
Object value();
+ /**
+ * Get the {@literal bsonType} representation of the given type.
+ *
+ * @return never {@literal null}.
+ * @since 2.2
+ */
+ default Type toBsonType() {
+
+ if (representation().equals("bsonType")) {
+ return this;
+ }
+
+ if (value().equals(Type.booleanType().value())) {
+ return bsonTypeOf("bool");
+ }
+ if (value().equals(Type.numberType().value())) {
+ return bsonTypeOf("long");
+ }
+
+ return bsonTypeOf((String) value());
+ }
+
/**
* @author Christpoh Strobl
* @since 2.1
*/
@RequiredArgsConstructor
+ @EqualsAndHashCode
class JsonType implements Type {
private final String name;
@@ -489,6 +530,7 @@ public String value() {
* @since 2.1
*/
@RequiredArgsConstructor
+ @EqualsAndHashCode
class BsonType implements Type {
private final String name;
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/JsonSchemaProperty.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/JsonSchemaProperty.java
index 36a44eb3f8..3bd149c53a 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/JsonSchemaProperty.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/schema/JsonSchemaProperty.java
@@ -18,18 +18,9 @@
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
-import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.ArrayJsonSchemaProperty;
-import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.BooleanJsonSchemaProperty;
-import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.DateJsonSchemaProperty;
-import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.NullJsonSchemaProperty;
-import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.NumericJsonSchemaProperty;
-import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.ObjectJsonSchemaProperty;
-import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.RequiredJsonSchemaProperty;
-import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.StringJsonSchemaProperty;
-import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.TimestampJsonSchemaProperty;
-import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.UntypedJsonSchemaProperty;
import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.NumericJsonSchemaObject;
import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.ObjectJsonSchemaObject;
+import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.*;
import org.springframework.lang.Nullable;
/**
@@ -68,6 +59,17 @@ static UntypedJsonSchemaProperty untyped(String identifier) {
return new UntypedJsonSchemaProperty(identifier, JsonSchemaObject.untyped());
}
+ /**
+ * Turns the given target property into an {@link EncryptedJsonSchemaProperty ecrypted} one.
+ *
+ * @param property must not be {@literal null}.
+ * @return new instance of {@link EncryptedJsonSchemaProperty}.
+ * @since 2.2
+ */
+ static EncryptedJsonSchemaProperty encrypted(JsonSchemaProperty property) {
+ return EncryptedJsonSchemaProperty.encrypted(property);
+ }
+
/**
* Creates a new {@link StringJsonSchemaProperty} with given {@literal identifier} of {@code type : 'string'}.
*
diff --git a/spring-data-mongodb/src/main/resources/org/springframework/data/mongodb/config/spring-mongo-2.2.xsd b/spring-data-mongodb/src/main/resources/org/springframework/data/mongodb/config/spring-mongo-2.2.xsd
index 3b27d2a2fa..bc1c52091a 100644
--- a/spring-data-mongodb/src/main/resources/org/springframework/data/mongodb/config/spring-mongo-2.2.xsd
+++ b/spring-data-mongodb/src/main/resources/org/springframework/data/mongodb/config/spring-mongo-2.2.xsd
@@ -311,6 +311,20 @@ The name of the MongoClient object that determines what server to monitor. (by d
+
+
+
+
+
+
+
+
+
+
+
+
@@ -546,6 +560,13 @@ The SSLSocketFactory to use for the SSL connection. If none is configured here,
]]>
+
+
+
+
+
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoEncryptionSettingsFactoryBeanTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoEncryptionSettingsFactoryBeanTests.java
new file mode 100644
index 0000000000..c701e7e058
--- /dev/null
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoEncryptionSettingsFactoryBeanTests.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2019 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;
+
+import static org.assertj.core.api.Assertions.*;
+
+import org.junit.Test;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.test.util.ReflectionTestUtils;
+
+import com.mongodb.AutoEncryptionSettings;
+
+/**
+ * Integration tests for {@link MongoEncryptionSettingsFactoryBean}.
+ *
+ * @author Christoph Strobl
+ */
+public class MongoEncryptionSettingsFactoryBeanTests {
+
+ @Test // DATAMONGO-2306
+ public void createsAutoEncryptionSettings() {
+
+ RootBeanDefinition definition = new RootBeanDefinition(MongoEncryptionSettingsFactoryBean.class);
+ definition.getPropertyValues().addPropertyValue("bypassAutoEncryption", true);
+ definition.getPropertyValues().addPropertyValue("keyVaultNamespace", "ns");
+
+ DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
+ factory.registerBeanDefinition("factory", definition);
+
+ MongoEncryptionSettingsFactoryBean bean = factory.getBean("&factory", MongoEncryptionSettingsFactoryBean.class);
+ assertThat(ReflectionTestUtils.getField(bean, "bypassAutoEncryption")).isEqualTo(true);
+
+ AutoEncryptionSettings target = factory.getBean(AutoEncryptionSettings.class);
+ assertThat(target.getKeyVaultNamespace()).isEqualTo("ns");
+ }
+}
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/schema/MongoJsonSchemaUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/schema/MongoJsonSchemaUnitTests.java
index edc2c6f4fd..aa85b01a6c 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/schema/MongoJsonSchemaUnitTests.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/schema/MongoJsonSchemaUnitTests.java
@@ -15,6 +15,7 @@
*/
package org.springframework.data.mongodb.core.schema;
+import static org.springframework.data.mongodb.core.schema.JsonSchemaProperty.*;
import static org.springframework.data.mongodb.test.util.Assertions.*;
import java.util.Arrays;
@@ -71,6 +72,21 @@ public void rendersRequiredPropertiesCorrectly() {
new Document("lastname", new Document("type", "string")))));
}
+ @Test // DATAMONGO-2306
+ public void rendersEncryptedPropertyCorrectly() {
+
+ MongoJsonSchema schema = MongoJsonSchema.builder().properties( //
+ encrypted(string("ssn")) //
+ .aead_aes_256_cbc_hmac_sha_512_deterministic() //
+ .keyId("*key0_id") //
+ ).build();
+
+ assertThat(schema.toDocument()).isEqualTo(new Document("$jsonSchema",
+ new Document("type", "object").append("properties",
+ new Document("ssn", new Document("encrypt", new Document("keyId", "*key0_id")
+ .append("algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic").append("bsonType", "string"))))));
+ }
+
@Test(expected = IllegalArgumentException.class) // DATAMONGO-1835
public void throwsExceptionOnNullRoot() {
MongoJsonSchema.of((JsonSchemaObject) null);
diff --git a/src/main/asciidoc/reference/mongo-json-schema.adoc b/src/main/asciidoc/reference/mongo-json-schema.adoc
index 2f1bcf840a..50e5e430e0 100644
--- a/src/main/asciidoc/reference/mongo-json-schema.adoc
+++ b/src/main/asciidoc/reference/mongo-json-schema.adoc
@@ -205,6 +205,28 @@ template.find(query(matchingDocumentStructure(schema)), Person.class);
----
====
+[[mongo.jsonSchema.encrypted-fields]]
+==== Encrypted Fields
+
+MongoDB 4.2 https://docs.mongodb.com/master/core/security-client-side-encryption/[Field Level Encryption] allows to directly encrypt individual properties.
+
+Properties can be wrapped within an encrypted property when setting up the JSON Schema as shown in the example below.
+
+.Client-Side Field Level Encryption via Json Schema
+====
+[source,java]
+----
+MongoJsonSchema schema = MongoJsonSchema.builder()
+ .properties(
+ encrypted(string("ssn"))
+ .algorithm("AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic")
+ .keyId("*key0_id")
+ ).build();
+----
+====
+
+NOTE: Make sure to set the drivers `com.mongodb.AutoEncryptionSettings` to use client-side encryption.
+
[[mongo.jsonSchema.types]]
==== JSON Schema Types