Browse Source

Polishing.

Reformat code, replace known unsupported constructor with UnsupportedOperationException.

See #4432
Original pull request: #4439
4.1.x
Mark Paluch 2 years ago
parent
commit
0b6c9978e6
No known key found for this signature in database
GPG Key ID: 4406B84C1661DCD1
  1. 13
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/MongoEncryptionConverter.java
  2. 63
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java
  3. 43
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/AbstractEncryptionTestBase.java
  4. 9
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/BypassAutoEncryptionTest.java
  5. 61
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/EncryptionTests.java

13
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/MongoEncryptionConverter.java

@ -26,7 +26,6 @@ import org.bson.BsonBinary;
import org.bson.BsonDocument; import org.bson.BsonDocument;
import org.bson.BsonValue; import org.bson.BsonValue;
import org.bson.Document; import org.bson.Document;
import org.bson.conversions.Bson;
import org.bson.types.Binary; import org.bson.types.Binary;
import org.springframework.core.CollectionFactory; import org.springframework.core.CollectionFactory;
import org.springframework.data.mongodb.core.convert.MongoConversionContext; import org.springframework.data.mongodb.core.convert.MongoConversionContext;
@ -96,7 +95,7 @@ public class MongoEncryptionConverter implements EncryptingConverter<Object, Obj
if (!persistentProperty.isEntity()) { if (!persistentProperty.isEntity()) {
Collection<Object> collection = CollectionFactory.createCollection(persistentProperty.getType(), size); Collection<Object> collection = CollectionFactory.createCollection(persistentProperty.getType(), size);
iterable.forEach(it -> { iterable.forEach(it -> {
if(it instanceof BsonValue bsonValue) { if (it instanceof BsonValue bsonValue) {
collection.add(BsonUtils.toJavaType(bsonValue)); collection.add(BsonUtils.toJavaType(bsonValue));
} else { } else {
collection.add(context.read(it, persistentProperty.getActualType())); collection.add(context.read(it, persistentProperty.getActualType()));
@ -107,7 +106,7 @@ public class MongoEncryptionConverter implements EncryptingConverter<Object, Obj
} else { } else {
Collection<Object> collection = CollectionFactory.createCollection(persistentProperty.getType(), size); Collection<Object> collection = CollectionFactory.createCollection(persistentProperty.getType(), size);
iterable.forEach(it -> { iterable.forEach(it -> {
if(it instanceof BsonValue bsonValue) { if (it instanceof BsonValue bsonValue) {
collection.add(context.read(BsonUtils.toJavaType(bsonValue), persistentProperty.getActualType())); collection.add(context.read(BsonUtils.toJavaType(bsonValue), persistentProperty.getActualType()));
} else { } else {
collection.add(context.read(it, persistentProperty.getActualType())); collection.add(context.read(it, persistentProperty.getActualType()));
@ -118,14 +117,14 @@ public class MongoEncryptionConverter implements EncryptingConverter<Object, Obj
} }
if (!persistentProperty.isEntity() && persistentProperty.isMap()) { if (!persistentProperty.isEntity() && persistentProperty.isMap()) {
if(persistentProperty.getType() != Document.class) { if (persistentProperty.getType() != Document.class) {
if(decryptedValue instanceof BsonValue bsonValue) { if (decryptedValue instanceof BsonValue bsonValue) {
return new LinkedHashMap<>((Document) BsonUtils.toJavaType(bsonValue)); return new LinkedHashMap<>((Document) BsonUtils.toJavaType(bsonValue));
} }
if(decryptedValue instanceof Document document) { if (decryptedValue instanceof Document document) {
return new LinkedHashMap<>(document); return new LinkedHashMap<>(document);
} }
if(decryptedValue instanceof Map map) { if (decryptedValue instanceof Map map) {
return map; return map;
} }
} }

63
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java

@ -286,36 +286,22 @@ public class BsonUtils {
*/ */
public static Object toJavaType(BsonValue value) { public static Object toJavaType(BsonValue value) {
switch (value.getBsonType()) { return switch (value.getBsonType()) {
case INT32: case INT32 -> value.asInt32().getValue();
return value.asInt32().getValue(); case INT64 -> value.asInt64().getValue();
case INT64: case STRING -> value.asString().getValue();
return value.asInt64().getValue(); case DECIMAL128 -> value.asDecimal128().doubleValue();
case STRING: case DOUBLE -> value.asDouble().getValue();
return value.asString().getValue(); case BOOLEAN -> value.asBoolean().getValue();
case DECIMAL128: case OBJECT_ID -> value.asObjectId().getValue();
return value.asDecimal128().doubleValue(); case DB_POINTER -> new DBRef(value.asDBPointer().getNamespace(), value.asDBPointer().getId());
case DOUBLE: case BINARY -> value.asBinary().getData();
return value.asDouble().getValue(); case DATE_TIME -> new Date(value.asDateTime().getValue());
case BOOLEAN: case SYMBOL -> value.asSymbol().getSymbol();
return value.asBoolean().getValue(); case ARRAY -> value.asArray().toArray();
case OBJECT_ID: case DOCUMENT -> Document.parse(value.asDocument().toJson());
return value.asObjectId().getValue(); default -> value;
case DB_POINTER: };
return new DBRef(value.asDBPointer().getNamespace(), value.asDBPointer().getId());
case BINARY:
return value.asBinary().getData();
case DATE_TIME:
return new Date(value.asDateTime().getValue());
case SYMBOL:
return value.asSymbol().getSymbol();
case ARRAY:
return value.asArray().toArray();
case DOCUMENT:
return Document.parse(value.asDocument().toJson());
default:
return value;
}
} }
/** /**
@ -364,26 +350,26 @@ public class BsonUtils {
return new BsonDouble(floatValue); return new BsonDouble(floatValue);
} }
if(source instanceof Binary binary) { if (source instanceof Binary binary) {
return new BsonBinary(binary.getType(), binary.getData()); return new BsonBinary(binary.getType(), binary.getData());
} }
if(source instanceof Temporal) { if (source instanceof Temporal) {
if (source instanceof Instant value) { if (source instanceof Instant value) {
return new BsonDateTime(value.toEpochMilli()); return new BsonDateTime(value.toEpochMilli());
} }
if (source instanceof LocalDateTime value) { if (source instanceof LocalDateTime value) {
return new BsonDateTime(value.toInstant(ZoneOffset.UTC).toEpochMilli()); return new BsonDateTime(value.toInstant(ZoneOffset.UTC).toEpochMilli());
} }
if(source instanceof LocalDate value) { if (source instanceof LocalDate value) {
return new BsonDateTime(value.atStartOfDay(ZoneOffset.UTC).toInstant().toEpochMilli()); return new BsonDateTime(value.atStartOfDay(ZoneOffset.UTC).toInstant().toEpochMilli());
} }
if(source instanceof LocalTime value) { if (source instanceof LocalTime value) {
return new BsonDateTime(value.atDate(LocalDate.ofEpochDay(0L)).toInstant(ZoneOffset.UTC).toEpochMilli()); return new BsonDateTime(value.atDate(LocalDate.ofEpochDay(0L)).toInstant(ZoneOffset.UTC).toEpochMilli());
} }
} }
if(source instanceof Date date) { if (source instanceof Date date) {
new BsonDateTime(date.getTime()); new BsonDateTime(date.getTime());
} }
@ -393,7 +379,7 @@ public class BsonUtils {
/** /**
* Merge the given {@link Document documents} into on in the given order. Keys contained within multiple documents are * Merge the given {@link Document documents} into on in the given order. Keys contained within multiple documents are
* overwritten by their follow ups. * overwritten by their follow-ups.
* *
* @param documents must not be {@literal null}. Can be empty. * @param documents must not be {@literal null}. Can be empty.
* @return the document containing all key value pairs. * @return the document containing all key value pairs.
@ -694,7 +680,7 @@ public class BsonUtils {
if (value instanceof Collection<?> collection) { if (value instanceof Collection<?> collection) {
return toString(collection); return toString(collection);
} else if (value instanceof Map<?,?> map) { } else if (value instanceof Map<?, ?> map) {
return toString(map); return toString(map);
} else if (ObjectUtils.isArray(value)) { } else if (ObjectUtils.isArray(value)) {
return toString(Arrays.asList(ObjectUtils.toObjectArray(value))); return toString(Arrays.asList(ObjectUtils.toObjectArray(value)));
@ -716,8 +702,9 @@ public class BsonUtils {
private static String toString(Map<?, ?> source) { private static String toString(Map<?, ?> source) {
// Avoid String.format for performance
return iterableToDelimitedString(source.entrySet(), "{ ", " }", return iterableToDelimitedString(source.entrySet(), "{ ", " }",
entry -> String.format("\"%s\" : %s", entry.getKey(), toJson(entry.getValue()))); entry -> "\"" + entry.getKey() + "\" : " + toJson(entry.getValue()));
} }
private static String toString(Collection<?> source) { private static String toString(Collection<?> source) {

43
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/AbstractEncryptionTestBase.java

@ -25,7 +25,6 @@ import java.time.LocalDate;
import java.time.Month; import java.time.Month;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
@ -34,14 +33,6 @@ import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
import com.mongodb.ClientEncryptionSettings;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.IndexOptions;
import com.mongodb.client.model.Indexes;
import com.mongodb.client.vault.ClientEncryptions;
import org.assertj.core.api.Assertions; import org.assertj.core.api.Assertions;
import org.bson.BsonBinary; import org.bson.BsonBinary;
import org.bson.Document; import org.bson.Document;
@ -61,13 +52,21 @@ import org.springframework.data.mongodb.core.convert.MongoCustomConversions.Mong
import org.springframework.data.mongodb.core.convert.encryption.MongoEncryptionConverter; import org.springframework.data.mongodb.core.convert.encryption.MongoEncryptionConverter;
import org.springframework.data.mongodb.core.mapping.ExplicitEncrypted; import org.springframework.data.mongodb.core.mapping.ExplicitEncrypted;
import org.springframework.data.mongodb.core.query.Update; import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.util.Lazy;
import com.mongodb.ClientEncryptionSettings;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.MongoNamespace; import com.mongodb.MongoNamespace;
import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients; import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
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.model.vault.DataKeyOptions;
import com.mongodb.client.vault.ClientEncryption; import com.mongodb.client.vault.ClientEncryption;
import org.springframework.data.util.Lazy; import com.mongodb.client.vault.ClientEncryptions;
/** /**
* @author Christoph Strobl * @author Christoph Strobl
@ -483,24 +482,17 @@ public abstract class AbstractEncryptionTestBase {
MongoCollection<Document> collection = mongoClient.getDatabase(getDatabaseName()).getCollection("test"); MongoCollection<Document> collection = mongoClient.getDatabase(getDatabaseName()).getCollection("test");
collection.drop(); // Clear old data collection.drop(); // Clear old data
final byte[] localMasterKey = new byte[96]; byte[] localMasterKey = new byte[96];
new SecureRandom().nextBytes(localMasterKey); new SecureRandom().nextBytes(localMasterKey);
Map<String, Map<String, Object>> kmsProviders = new HashMap<>() { Map<String, Map<String, Object>> kmsProviders = Map.of("local", Map.of("key", localMasterKey));
{
put("local", new HashMap<>() {
{
put("key", localMasterKey);
}
});
}
};
// Create the ClientEncryption instance // Create the ClientEncryption instance
ClientEncryptionSettings clientEncryptionSettings = ClientEncryptionSettings.builder() return ClientEncryptionSettings.builder() //
.keyVaultMongoClientSettings( .keyVaultMongoClientSettings(
MongoClientSettings.builder().applyConnectionString(new ConnectionString("mongodb://localhost")).build()) MongoClientSettings.builder().applyConnectionString(new ConnectionString("mongodb://localhost")).build()) //
.keyVaultNamespace(keyVaultNamespace.getFullName()).kmsProviders(kmsProviders).build(); .keyVaultNamespace(keyVaultNamespace.getFullName()) //
return clientEncryptionSettings; .kmsProviders(kmsProviders) //
.build();
} }
} }
@ -693,8 +685,7 @@ public abstract class AbstractEncryptionTestBase {
+ ", wallet=" + this.getWallet() + ", address=" + this.getAddress() + ", encryptedZip=" + ", wallet=" + this.getWallet() + ", address=" + this.getAddress() + ", encryptedZip="
+ this.getEncryptedZip() + ", listOfString=" + this.getListOfString() + ", listOfComplex=" + this.getEncryptedZip() + ", listOfString=" + this.getListOfString() + ", listOfComplex="
+ this.getListOfComplex() + ", viaAltKeyNameField=" + this.getViaAltKeyNameField() + ", mapOfString=" + this.getListOfComplex() + ", viaAltKeyNameField=" + this.getViaAltKeyNameField() + ", mapOfString="
+ this.getMapOfString() + ", mapOfComplex=" + this.getMapOfComplex() + this.getMapOfString() + ", mapOfComplex=" + this.getMapOfComplex() + ", today=" + this.getToday() + ")";
+ ", today=" + this.getToday() + ")";
} }
} }

9
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/BypassAutoEncryptionTest.java

@ -68,9 +68,10 @@ public class BypassAutoEncryptionTest extends AbstractEncryptionTestBase {
ClientEncryptionSettings clientEncryptionSettings = encryptionSettings(mongoClient); ClientEncryptionSettings clientEncryptionSettings = encryptionSettings(mongoClient);
mongoClient.close(); mongoClient.close();
builder.autoEncryptionSettings( builder.autoEncryptionSettings(AutoEncryptionSettings.builder() //
AutoEncryptionSettings.builder().kmsProviders(clientEncryptionSettings.getKmsProviders()) .kmsProviders(clientEncryptionSettings.getKmsProviders()) //
.keyVaultNamespace(clientEncryptionSettings.getKeyVaultNamespace()).bypassAutoEncryption(true).build()); .keyVaultNamespace(clientEncryptionSettings.getKeyVaultNamespace()) //
.bypassAutoEncryption(true).build());
} }
@Override @Override
@ -81,6 +82,7 @@ public class BypassAutoEncryptionTest extends AbstractEncryptionTestBase {
} }
@Bean @Bean
@Override
MongoEncryptionConverter encryptingConverter(MongoClientEncryption mongoClientEncryption) { MongoEncryptionConverter encryptingConverter(MongoClientEncryption mongoClientEncryption) {
Lazy<BsonBinary> dataKey = Lazy.of(() -> mongoClientEncryption.getClientEncryption().createDataKey("local", Lazy<BsonBinary> dataKey = Lazy.of(() -> mongoClientEncryption.getClientEncryption().createDataKey("local",
@ -91,6 +93,7 @@ public class BypassAutoEncryptionTest extends AbstractEncryptionTestBase {
} }
@Bean @Bean
@Override
CachingMongoClientEncryption clientEncryption(ClientEncryptionSettings encryptionSettings) { CachingMongoClientEncryption clientEncryption(ClientEncryptionSettings encryptionSettings) {
return new CachingMongoClientEncryption(() -> ClientEncryptions.create(encryptionSettings)); return new CachingMongoClientEncryption(() -> ClientEncryptions.create(encryptionSettings));
} }

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

@ -15,10 +15,7 @@
*/ */
package org.springframework.data.mongodb.core.encryption; package org.springframework.data.mongodb.core.encryption;
import static org.assertj.core.api.Assertions.*;
import static org.springframework.data.mongodb.core.EncryptionAlgorithms.*; import static org.springframework.data.mongodb.core.EncryptionAlgorithms.*;
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
import static org.springframework.data.mongodb.core.query.Criteria.*;
import lombok.Data; import lombok.Data;
import lombok.Getter; import lombok.Getter;
@ -26,12 +23,8 @@ import lombok.Setter;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import org.bson.BsonBinary; import org.bson.BsonBinary;
import org.bson.Document; import org.bson.Document;
@ -45,6 +38,7 @@ import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration;
import org.springframework.data.mongodb.core.convert.MongoCustomConversions.MongoConverterConfigurationAdapter; import org.springframework.data.mongodb.core.convert.MongoCustomConversions.MongoConverterConfigurationAdapter;
import org.springframework.data.mongodb.core.convert.encryption.MongoEncryptionConverter; import org.springframework.data.mongodb.core.convert.encryption.MongoEncryptionConverter;
import org.springframework.data.mongodb.core.encryption.EncryptionTests.Config; import org.springframework.data.mongodb.core.encryption.EncryptionTests.Config;
import org.springframework.data.mongodb.core.mapping.ExplicitEncrypted;
import org.springframework.data.util.Lazy; import org.springframework.data.util.Lazy;
import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.context.junit.jupiter.SpringExtension;
@ -79,6 +73,7 @@ public class EncryptionTests extends AbstractEncryptionTestBase {
} }
@Bean @Bean
@Override
public MongoClient mongoClient() { public MongoClient mongoClient() {
return super.mongoClient(); return super.mongoClient();
} }
@ -119,55 +114,19 @@ public class EncryptionTests extends AbstractEncryptionTestBase {
MongoCollection<Document> collection = mongoClient.getDatabase(getDatabaseName()).getCollection("test"); MongoCollection<Document> collection = mongoClient.getDatabase(getDatabaseName()).getCollection("test");
collection.drop(); // Clear old data collection.drop(); // Clear old data
final byte[] localMasterKey = new byte[96]; byte[] localMasterKey = new byte[96];
new SecureRandom().nextBytes(localMasterKey); new SecureRandom().nextBytes(localMasterKey);
Map<String, Map<String, Object>> kmsProviders = new HashMap<>() { Map<String, Map<String, Object>> kmsProviders = Map.of("local", Map.of("key", localMasterKey));
{
put("local", new HashMap<>() {
{
put("key", localMasterKey);
}
});
}
};
// Create the ClientEncryption instance // Create the ClientEncryption instance
ClientEncryptionSettings clientEncryptionSettings = ClientEncryptionSettings.builder() return ClientEncryptionSettings.builder()
.keyVaultMongoClientSettings( .keyVaultMongoClientSettings(
MongoClientSettings.builder().applyConnectionString(new ConnectionString("mongodb://localhost")).build()) MongoClientSettings.builder().applyConnectionString(new ConnectionString("mongodb://localhost")).build()) //
.keyVaultNamespace(keyVaultNamespace.getFullName()).kmsProviders(kmsProviders).build(); .keyVaultNamespace(keyVaultNamespace.getFullName()) //
return clientEncryptionSettings; .kmsProviders(kmsProviders) //
} .build();
} }
static class CachingMongoClientEncryption extends MongoClientEncryption implements DisposableBean {
static final AtomicReference<ClientEncryption> cache = new AtomicReference<>();
CachingMongoClientEncryption(Supplier<ClientEncryption> source) {
super(() -> {
if (cache.get() != null) {
return cache.get();
}
ClientEncryption clientEncryption = source.get();
cache.set(clientEncryption);
return clientEncryption;
});
}
@Override
public void destroy() {
ClientEncryption clientEncryption = cache.get();
if (clientEncryption != null) {
clientEncryption.close();
cache.set(null);
}
}
} }
@Data @Data

Loading…
Cancel
Save