Compare commits
7 Commits
4.2.0-M1
...
issue/4393
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b8107216cf | ||
|
|
0ce912ed7e | ||
|
|
6b0aa7a4b3 | ||
|
|
e1986373fd | ||
|
|
5407456973 | ||
|
|
31f0aa348d | ||
|
|
28abf1c15b |
16
pom.xml
16
pom.xml
@@ -5,7 +5,7 @@
|
||||
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>4.2.0-M1</version>
|
||||
<version>4.2.x-4393-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>Spring Data MongoDB</name>
|
||||
@@ -15,7 +15,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data.build</groupId>
|
||||
<artifactId>spring-data-parent</artifactId>
|
||||
<version>3.2.0-M1</version>
|
||||
<version>3.2.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
@@ -26,7 +26,7 @@
|
||||
<properties>
|
||||
<project.type>multi</project.type>
|
||||
<dist.id>spring-data-mongodb</dist.id>
|
||||
<springdata.commons>3.2.0-M1</springdata.commons>
|
||||
<springdata.commons>3.2.0-SNAPSHOT</springdata.commons>
|
||||
<mongo>4.10.2</mongo>
|
||||
<mongo.reactivestreams>${mongo}</mongo.reactivestreams>
|
||||
<jmh.version>1.19</jmh.version>
|
||||
@@ -144,6 +144,16 @@
|
||||
</dependencies>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-snapshot</id>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
<releases>
|
||||
<enabled>false</enabled>
|
||||
</releases>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>4.2.0-M1</version>
|
||||
<version>4.2.x-4393-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>4.2.0-M1</version>
|
||||
<version>4.2.x-4393-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>4.2.0-M1</version>
|
||||
<version>4.2.x-4393-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -104,6 +104,12 @@
|
||||
<version>${mongo}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongodb-driver-kotlin-sync</artifactId>
|
||||
<version>${mongo}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
@@ -111,6 +117,12 @@
|
||||
<version>${mongo.reactivestreams}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongodb-driver-kotlin-coroutine</artifactId>
|
||||
<version>${mongo}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2023 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 com.mongodb.kotlin.client.MongoClient
|
||||
import org.springframework.beans.DirectFieldAccessor
|
||||
|
||||
/**
|
||||
* Extension for [SimpleMongoClientDatabaseFactory] that accepts a [MongoClient].
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @since 4.2
|
||||
*/
|
||||
fun SimpleMongoClientDatabaseFactory(client: MongoClient, database: String): SimpleMongoClientDatabaseFactory =
|
||||
SimpleMongoClientDatabaseFactory(
|
||||
DirectFieldAccessor(client).getPropertyValue("wrapped") as com.mongodb.client.MongoClient,
|
||||
database
|
||||
)
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2023 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 com.mongodb.kotlin.client.coroutine.MongoClient
|
||||
import org.springframework.beans.DirectFieldAccessor
|
||||
|
||||
/**
|
||||
* Extension for [SimpleReactiveMongoDatabaseFactory] that accepts a [MongoClient].
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @since 4.2
|
||||
*/
|
||||
fun SimpleReactiveMongoDatabaseFactory(client: MongoClient, database: String): SimpleReactiveMongoDatabaseFactory =
|
||||
SimpleReactiveMongoDatabaseFactory(
|
||||
DirectFieldAccessor(client).getPropertyValue("wrapped") as com.mongodb.reactivestreams.client.MongoClient,
|
||||
database
|
||||
)
|
||||
@@ -25,7 +25,6 @@ import java.math.BigInteger;
|
||||
import java.net.URL;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.*;
|
||||
|
||||
@@ -106,6 +105,7 @@ import com.mongodb.DBRef;
|
||||
* @author Mark Paluch
|
||||
* @author Roman Puchkovskiy
|
||||
* @author Heesu Jung
|
||||
* @author Julia Lee
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class MappingMongoConverterUnitTests {
|
||||
@@ -2619,7 +2619,7 @@ class MappingMongoConverterUnitTests {
|
||||
void projectShouldReadSimpleInterfaceProjection() {
|
||||
|
||||
org.bson.Document source = new org.bson.Document("birthDate",
|
||||
Date.from(LocalDate.of(1999, 12, 1).atStartOfDay().toInstant(ZoneOffset.UTC))).append("foo", "Walter");
|
||||
Date.from(LocalDate.of(1999, 12, 1).atStartOfDay(systemDefault()).toInstant())).append("foo", "Walter");
|
||||
|
||||
EntityProjectionIntrospector discoverer = EntityProjectionIntrospector.create(converter.getProjectionFactory(),
|
||||
EntityProjectionIntrospector.ProjectionPredicate.typeHierarchy()
|
||||
@@ -2637,7 +2637,7 @@ class MappingMongoConverterUnitTests {
|
||||
void projectShouldReadSimpleDtoProjection() {
|
||||
|
||||
org.bson.Document source = new org.bson.Document("birthDate",
|
||||
Date.from(LocalDate.of(1999, 12, 1).atStartOfDay().toInstant(ZoneOffset.UTC))).append("foo", "Walter");
|
||||
Date.from(LocalDate.of(1999, 12, 1).atStartOfDay(systemDefault()).toInstant())).append("foo", "Walter");
|
||||
|
||||
EntityProjectionIntrospector introspector = EntityProjectionIntrospector.create(converter.getProjectionFactory(),
|
||||
EntityProjectionIntrospector.ProjectionPredicate.typeHierarchy()
|
||||
|
||||
@@ -70,6 +70,7 @@ import com.mongodb.client.vault.ClientEncryptions;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @author Julia Lee
|
||||
*/
|
||||
public abstract class AbstractEncryptionTestBase {
|
||||
|
||||
@@ -450,7 +451,8 @@ public abstract class AbstractEncryptionTestBase {
|
||||
protected void configureConverters(MongoConverterConfigurationAdapter converterConfigurationAdapter) {
|
||||
|
||||
converterConfigurationAdapter
|
||||
.registerPropertyValueConverterFactory(PropertyValueConverterFactory.beanFactoryAware(applicationContext));
|
||||
.registerPropertyValueConverterFactory(PropertyValueConverterFactory.beanFactoryAware(applicationContext))
|
||||
.useNativeDriverJavaTimeCodecs();
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -16,20 +16,10 @@
|
||||
|
||||
package org.springframework.data.mongodb.core.encryption;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.bson.BsonBinary;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.convert.PropertyValueConverterFactory;
|
||||
import org.springframework.data.mongodb.core.convert.MongoCustomConversions.MongoConverterConfigurationAdapter;
|
||||
import org.springframework.data.mongodb.core.convert.encryption.MongoEncryptionConverter;
|
||||
import org.springframework.data.mongodb.core.encryption.BypassAutoEncryptionTest.Config;
|
||||
import org.springframework.data.util.Lazy;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
|
||||
@@ -38,16 +28,15 @@ import com.mongodb.ClientEncryptionSettings;
|
||||
import com.mongodb.MongoClientSettings.Builder;
|
||||
import com.mongodb.client.MongoClient;
|
||||
import com.mongodb.client.MongoClients;
|
||||
import com.mongodb.client.model.vault.DataKeyOptions;
|
||||
import com.mongodb.client.vault.ClientEncryptions;
|
||||
|
||||
/**
|
||||
* Encryption tests for client having {@link AutoEncryptionSettings#isBypassAutoEncryption()}.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @author Julia Lee
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration(classes = Config.class)
|
||||
@ContextConfiguration(classes = BypassAutoEncryptionTest.Config.class)
|
||||
public class BypassAutoEncryptionTest extends AbstractEncryptionTestBase {
|
||||
|
||||
@Disabled
|
||||
@@ -59,8 +48,6 @@ public class BypassAutoEncryptionTest extends AbstractEncryptionTestBase {
|
||||
@Configuration
|
||||
static class Config extends EncryptionConfig {
|
||||
|
||||
@Autowired ApplicationContext applicationContext;
|
||||
|
||||
@Override
|
||||
protected void configureClientSettings(Builder builder) {
|
||||
|
||||
@@ -73,31 +60,5 @@ public class BypassAutoEncryptionTest extends AbstractEncryptionTestBase {
|
||||
.keyVaultNamespace(clientEncryptionSettings.getKeyVaultNamespace()) //
|
||||
.bypassAutoEncryption(true).build());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureConverters(MongoConverterConfigurationAdapter converterConfigurationAdapter) {
|
||||
|
||||
converterConfigurationAdapter
|
||||
.registerPropertyValueConverterFactory(PropertyValueConverterFactory.beanFactoryAware(applicationContext));
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Override
|
||||
MongoEncryptionConverter encryptingConverter(MongoClientEncryption mongoClientEncryption) {
|
||||
|
||||
Lazy<BsonBinary> dataKey = Lazy.of(() -> mongoClientEncryption.getClientEncryption().createDataKey("local",
|
||||
new DataKeyOptions().keyAltNames(Collections.singletonList("mySuperSecretKey"))));
|
||||
|
||||
return new MongoEncryptionConverter(mongoClientEncryption,
|
||||
EncryptionKeyResolver.annotated((ctx) -> EncryptionKey.keyId(dataKey.get())));
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Override
|
||||
CachingMongoClientEncryption clientEncryption(ClientEncryptionSettings encryptionSettings) {
|
||||
return new CachingMongoClientEncryption(() -> ClientEncryptions.create(encryptionSettings));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,108 +15,16 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.encryption;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bson.BsonBinary;
|
||||
import org.bson.Document;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.convert.PropertyValueConverterFactory;
|
||||
import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration;
|
||||
import org.springframework.data.mongodb.core.convert.MongoCustomConversions.MongoConverterConfigurationAdapter;
|
||||
import org.springframework.data.mongodb.core.convert.encryption.MongoEncryptionConverter;
|
||||
import org.springframework.data.mongodb.core.encryption.EncryptionTests.Config;
|
||||
import org.springframework.data.util.Lazy;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
|
||||
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.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.vault.ClientEncryptions;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @author Julia Lee
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration(classes = Config.class)
|
||||
@ContextConfiguration(classes = AbstractEncryptionTestBase.EncryptionConfig.class)
|
||||
public class EncryptionTests extends AbstractEncryptionTestBase {
|
||||
|
||||
@Configuration
|
||||
static class Config extends AbstractMongoClientConfiguration {
|
||||
|
||||
@Autowired ApplicationContext applicationContext;
|
||||
|
||||
@Override
|
||||
protected String getDatabaseName() {
|
||||
return "fle-test";
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Override
|
||||
public MongoClient mongoClient() {
|
||||
return super.mongoClient();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureConverters(MongoConverterConfigurationAdapter converterConfigurationAdapter) {
|
||||
|
||||
converterConfigurationAdapter
|
||||
.registerPropertyValueConverterFactory(PropertyValueConverterFactory.beanFactoryAware(applicationContext));
|
||||
}
|
||||
|
||||
@Bean
|
||||
MongoEncryptionConverter encryptingConverter(MongoClientEncryption mongoClientEncryption) {
|
||||
|
||||
Lazy<BsonBinary> dataKey = Lazy.of(() -> mongoClientEncryption.getClientEncryption().createDataKey("local",
|
||||
new DataKeyOptions().keyAltNames(Collections.singletonList("mySuperSecretKey"))));
|
||||
|
||||
return new MongoEncryptionConverter(mongoClientEncryption,
|
||||
EncryptionKeyResolver.annotated((ctx) -> EncryptionKey.keyId(dataKey.get())));
|
||||
}
|
||||
|
||||
@Bean
|
||||
CachingMongoClientEncryption clientEncryption(ClientEncryptionSettings encryptionSettings) {
|
||||
return new CachingMongoClientEncryption(() -> ClientEncryptions.create(encryptionSettings));
|
||||
}
|
||||
|
||||
@Bean
|
||||
ClientEncryptionSettings encryptionSettings(MongoClient mongoClient) {
|
||||
|
||||
MongoNamespace keyVaultNamespace = new MongoNamespace("encryption.testKeyVault");
|
||||
MongoCollection<Document> keyVaultCollection = mongoClient.getDatabase(keyVaultNamespace.getDatabaseName())
|
||||
.getCollection(keyVaultNamespace.getCollectionName());
|
||||
keyVaultCollection.drop();
|
||||
// Ensure that two data keys cannot share the same keyAltName.
|
||||
keyVaultCollection.createIndex(Indexes.ascending("keyAltNames"),
|
||||
new IndexOptions().unique(true).partialFilterExpression(Filters.exists("keyAltNames")));
|
||||
|
||||
MongoCollection<Document> collection = mongoClient.getDatabase(getDatabaseName()).getCollection("test");
|
||||
collection.drop(); // Clear old data
|
||||
|
||||
byte[] localMasterKey = new byte[96];
|
||||
new SecureRandom().nextBytes(localMasterKey);
|
||||
Map<String, Map<String, Object>> kmsProviders = Map.of("local", Map.of("key", localMasterKey));
|
||||
|
||||
// Create the ClientEncryption instance
|
||||
return ClientEncryptionSettings.builder()
|
||||
.keyVaultMongoClientSettings(
|
||||
MongoClientSettings.builder().applyConnectionString(new ConnectionString("mongodb://localhost")).build()) //
|
||||
.keyVaultNamespace(keyVaultNamespace.getFullName()) //
|
||||
.kmsProviders(kmsProviders) //
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2023 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 com.mongodb.kotlin.client.MongoClient
|
||||
import org.bson.Document
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.springframework.data.mongodb.test.util.Assertions.assertThat
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
class SimpleMongoClientDatabaseFactoryExtensionTests {
|
||||
|
||||
@Test // GH-4393
|
||||
fun `extension allows to create SimpleMongoClientDatabaseFactory with a Kotlin Driver instance`() {
|
||||
|
||||
val factory = SimpleMongoClientDatabaseFactory(MongoClient.create(), "test")
|
||||
|
||||
assertThat(factory.mongoDatabase.runCommand(Document("ping", 1))).containsKey("ok")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2023 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 com.mongodb.kotlin.client.coroutine.MongoClient
|
||||
import org.bson.Document
|
||||
import org.junit.jupiter.api.Test
|
||||
import reactor.core.publisher.Mono
|
||||
import reactor.test.StepVerifier
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
class SimpleReactiveMongoDatabaseFactoryExtensionTests {
|
||||
|
||||
@Test // GH-4393
|
||||
fun `extension allows to create SimpleReactiveMongoDatabaseFactory with a Kotlin Coroutine Driver instance`() {
|
||||
|
||||
val factory = SimpleReactiveMongoDatabaseFactory(MongoClient.create(), "test")
|
||||
|
||||
factory.mongoDatabase.flatMap { Mono.from(it.runCommand(Document("ping", 1))) }
|
||||
.`as` { StepVerifier.create(it) }
|
||||
.expectNextCount(1)
|
||||
.verifyComplete()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user