diff --git a/pom.xml b/pom.xml
index 7cb1d10f85..2abcb6ae8c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.data
spring-data-mongodb-parent
- 3.3.0-SNAPSHOT
+ 3.3.0-GH-3820-SNAPSHOT
pom
Spring Data MongoDB
diff --git a/spring-data-mongodb-benchmarks/pom.xml b/spring-data-mongodb-benchmarks/pom.xml
index 0033bd11d5..ab53e9814c 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
- 3.3.0-SNAPSHOT
+ 3.3.0-GH-3820-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb-distribution/pom.xml b/spring-data-mongodb-distribution/pom.xml
index f62c8dc7f4..39346e58cb 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
- 3.3.0-SNAPSHOT
+ 3.3.0-GH-3820-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml
index 2f73c10eba..95cfa25f50 100644
--- a/spring-data-mongodb/pom.xml
+++ b/spring-data-mongodb/pom.xml
@@ -11,7 +11,7 @@
org.springframework.data
spring-data-mongodb-parent
- 3.3.0-SNAPSHOT
+ 3.3.0-GH-3820-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 cd4d16d91b..935be95500 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
@@ -22,9 +22,12 @@
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.CustomEditorConfigurer;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.BeanDefinitionValidationException;
import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.data.mongodb.core.MongoClientSettingsFactoryBean;
+import org.springframework.data.mongodb.core.MongoServerApiFactoryBean;
+import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Element;
@@ -112,6 +115,20 @@ public static boolean parseMongoClientSettings(Element element, BeanDefinitionBu
// Field level encryption
setPropertyReference(clientOptionsDefBuilder, settingsElement, "encryption-settings-ref", "autoEncryptionSettings");
+ // ServerAPI
+ if (StringUtils.hasText(settingsElement.getAttribute("server-api-version"))) {
+
+ MongoServerApiFactoryBean serverApiFactoryBean = new MongoServerApiFactoryBean();
+ serverApiFactoryBean.setVersion(settingsElement.getAttribute("server-api-version"));
+ try {
+ clientOptionsDefBuilder.addPropertyValue("serverApi", serverApiFactoryBean.getObject());
+ } catch (Exception exception) {
+ throw new BeanDefinitionValidationException("Non parsable server-api.", exception);
+ }
+ } else {
+ setPropertyReference(clientOptionsDefBuilder, settingsElement, "server-api-ref", "serverApi");
+ }
+
// and the rest
mongoClientBuilder.addPropertyValue("mongoClientSettings", clientOptionsDefBuilder.getBeanDefinition());
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoClientSettingsFactoryBean.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoClientSettingsFactoryBean.java
index 162035a45d..818dd45f3f 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoClientSettingsFactoryBean.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoClientSettingsFactoryBean.java
@@ -36,6 +36,7 @@
import com.mongodb.ReadConcern;
import com.mongodb.ReadPreference;
import com.mongodb.ServerAddress;
+import com.mongodb.ServerApi;
import com.mongodb.WriteConcern;
import com.mongodb.connection.ClusterConnectionMode;
import com.mongodb.connection.ClusterType;
@@ -113,6 +114,7 @@ public class MongoClientSettingsFactoryBean extends AbstractFactoryBean getObjectType() {
return MongoClientSettings.class;
@@ -476,9 +487,11 @@ protected MongoClientSettings createInstance() {
if (retryWrites != null) {
builder = builder.retryWrites(retryWrites);
}
-
if (uUidRepresentation != null) {
- builder.uuidRepresentation(uUidRepresentation);
+ builder = builder.uuidRepresentation(uUidRepresentation);
+ }
+ if (serverApi != null) {
+ builder = builder.serverApi(serverApi);
}
return builder.build();
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoServerApiFactoryBean.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoServerApiFactoryBean.java
new file mode 100644
index 0000000000..e2a2fecaec
--- /dev/null
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoServerApiFactoryBean.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2021 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 org.springframework.beans.factory.FactoryBean;
+import org.springframework.lang.Nullable;
+import org.springframework.util.ObjectUtils;
+
+import com.mongodb.ServerApi;
+import com.mongodb.ServerApi.Builder;
+import com.mongodb.ServerApiVersion;
+
+/**
+ * {@link FactoryBean} for creating {@link ServerApi} using the {@link ServerApi.Builder}.
+ *
+ * @author Christoph Strobl
+ * @since 3.3
+ */
+public class MongoServerApiFactoryBean implements FactoryBean {
+
+ private String version;
+ private @Nullable Boolean deprecationErrors;
+ private @Nullable Boolean strict;
+
+ /**
+ * @param version the version string either as the enum name or the server version value.
+ * @see ServerApiVersion
+ */
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ /**
+ * @param deprecationErrors
+ * @see ServerApi.Builder#deprecationErrors(boolean)
+ */
+ public void setDeprecationErrors(@Nullable Boolean deprecationErrors) {
+ this.deprecationErrors = deprecationErrors;
+ }
+
+ /**
+ * @param strict
+ * @see ServerApi.Builder#strict(boolean)
+ */
+ public void setStrict(@Nullable Boolean strict) {
+ this.strict = strict;
+ }
+
+ @Nullable
+ @Override
+ public ServerApi getObject() throws Exception {
+
+ Builder builder = ServerApi.builder().version(version());
+
+ if (deprecationErrors != null) {
+ builder = builder.deprecationErrors(deprecationErrors);
+ }
+ if (strict != null) {
+ builder = builder.strict(strict);
+ }
+ return builder.build();
+ }
+
+ @Nullable
+ @Override
+ public Class> getObjectType() {
+ return ServerApi.class;
+ }
+
+ private ServerApiVersion version() {
+ try {
+ // lookup by name eg. 'V1'
+ return ObjectUtils.caseInsensitiveValueOf(ServerApiVersion.values(), version);
+ } catch (IllegalArgumentException e) {
+ // or just the version number, eg. just '1'
+ return ServerApiVersion.findByValue(version);
+ }
+ }
+}
diff --git a/spring-data-mongodb/src/main/resources/META-INF/spring.schemas b/spring-data-mongodb/src/main/resources/META-INF/spring.schemas
index 1ebb3098c7..c7f3f0ab7b 100644
--- a/spring-data-mongodb/src/main/resources/META-INF/spring.schemas
+++ b/spring-data-mongodb/src/main/resources/META-INF/spring.schemas
@@ -11,7 +11,8 @@ http\://www.springframework.org/schema/data/mongo/spring-mongo-1.10.2.xsd=org/sp
http\://www.springframework.org/schema/data/mongo/spring-mongo-2.0.xsd=org/springframework/data/mongodb/config/spring-mongo-2.0.xsd
http\://www.springframework.org/schema/data/mongo/spring-mongo-2.2.xsd=org/springframework/data/mongodb/config/spring-mongo-2.0.xsd
http\://www.springframework.org/schema/data/mongo/spring-mongo-3.0.xsd=org/springframework/data/mongodb/config/spring-mongo-3.0.xsd
-http\://www.springframework.org/schema/data/mongo/spring-mongo.xsd=org/springframework/data/mongodb/config/spring-mongo-3.0.xsd
+http\://www.springframework.org/schema/data/mongo/spring-mongo-3.3.xsd=org/springframework/data/mongodb/config/spring-mongo-3.3.xsd
+http\://www.springframework.org/schema/data/mongo/spring-mongo.xsd=org/springframework/data/mongodb/config/spring-mongo-3.3.xsd
https\://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd=org/springframework/data/mongodb/config/spring-mongo-1.0.xsd
https\://www.springframework.org/schema/data/mongo/spring-mongo-1.1.xsd=org/springframework/data/mongodb/config/spring-mongo-1.1.xsd
https\://www.springframework.org/schema/data/mongo/spring-mongo-1.2.xsd=org/springframework/data/mongodb/config/spring-mongo-1.2.xsd
@@ -25,4 +26,5 @@ https\://www.springframework.org/schema/data/mongo/spring-mongo-1.10.2.xsd=org/s
https\://www.springframework.org/schema/data/mongo/spring-mongo-2.0.xsd=org/springframework/data/mongodb/config/spring-mongo-2.0.xsd
https\://www.springframework.org/schema/data/mongo/spring-mongo-2.2.xsd=org/springframework/data/mongodb/config/spring-mongo-2.2.xsd
https\://www.springframework.org/schema/data/mongo/spring-mongo-3.0.xsd=org/springframework/data/mongodb/config/spring-mongo-3.0.xsd
-https\://www.springframework.org/schema/data/mongo/spring-mongo.xsd=org/springframework/data/mongodb/config/spring-mongo-3.0.xsd
+https\://www.springframework.org/schema/data/mongo/spring-mongo-3.3.xsd=org/springframework/data/mongodb/config/spring-mongo-3.3.xsd
+https\://www.springframework.org/schema/data/mongo/spring-mongo.xsd=org/springframework/data/mongodb/config/spring-mongo-3.3.xsd
diff --git a/spring-data-mongodb/src/main/resources/org/springframework/data/mongodb/config/spring-mongo-3.3.xsd b/spring-data-mongodb/src/main/resources/org/springframework/data/mongodb/config/spring-mongo-3.3.xsd
new file mode 100644
index 0000000000..80811306f1
--- /dev/null
+++ b/spring-data-mongodb/src/main/resources/org/springframework/data/mongodb/config/spring-mongo-3.3.xsd
@@ -0,0 +1,895 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The WriteConcern that will be the default value used when asking the MongoDatabaseFactory for a DB object
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The reference to a MongoTemplate. Will default to 'mongoTemplate'.
+
+
+
+
+
+
+ Enables creation of indexes for queries that get derived from the method name
+ and thus reference domain class properties. Defaults to false.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The reference to a MongoDatabaseFactory.
+
+
+
+
+
+
+
+
+
+
+
+ The reference to a MongoTypeMapper to be used by this MappingMongoConverter.
+
+
+
+
+
+
+ The reference to a MappingContext. Will default to 'mappingContext'.
+
+
+
+
+
+
+ Disables JSR-303 validation on MongoDB documents before they are saved. By default it is set to false.
+
+
+
+
+
+
+
+
+
+ Enables abbreviating the field names for domain class properties to the
+ first character of their camel case names, e.g. fooBar -> fb. Defaults to false.
+
+
+
+
+
+
+
+
+
+ The reference to a FieldNamingStrategy.
+
+
+
+
+
+
+ Enable/Disable index creation for annotated properties/entities.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ A reference to a custom converter.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The reference to a MongoDatabaseFactory.
+
+
+
+
+
+
+
+
+
+
+
+ The WriteConcern that will be the default value used when asking the MongoDatabaseFactory for a DB object
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The reference to a MongoDatabaseFactory.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MongoClientNamespaceTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MongoClientNamespaceTests.java
index 47dd85e07a..abdd00c2b5 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MongoClientNamespaceTests.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MongoClientNamespaceTests.java
@@ -21,6 +21,7 @@
import java.util.Collections;
import java.util.concurrent.TimeUnit;
+import com.mongodb.ServerApiVersion;
import org.bson.UuidRepresentation;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -147,4 +148,16 @@ public void clientWithUUidSettings() {
MongoClientSettings settings = (MongoClientSettings) getField(factoryBean, "mongoClientSettings");
assertThat(settings.getUuidRepresentation()).isEqualTo(UuidRepresentation.STANDARD);
}
+
+ @Test // DATAMONGO-2427
+ public void clientWithServerVersion() {
+
+ assertThat(ctx.containsBean("client-with-server-api-settings")).isTrue();
+ MongoClientFactoryBean factoryBean = ctx.getBean("&client-with-server-api-settings", MongoClientFactoryBean.class);
+
+ MongoClientSettings settings = (MongoClientSettings) getField(factoryBean, "mongoClientSettings");
+ assertThat(settings.getServerApi()).isNotNull().satisfies(it -> {
+ assertThat(it.getVersion()).isEqualTo(ServerApiVersion.V1);
+ });
+ }
}
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoServerApiFactoryBeanTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoServerApiFactoryBeanTests.java
new file mode 100644
index 0000000000..0c79478fee
--- /dev/null
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoServerApiFactoryBeanTests.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2021 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 com.mongodb.ServerApi;
+import com.mongodb.ServerApiVersion;
+import org.junit.jupiter.api.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 MongoServerApiFactoryBean}.
+ *
+ * @author Christoph Strobl
+ */
+public class MongoServerApiFactoryBeanTests {
+
+ @Test // DATAMONGO-2306
+ public void createsServerApiForVersionString() {
+
+ RootBeanDefinition definition = new RootBeanDefinition(MongoServerApiFactoryBean.class);
+ definition.getPropertyValues().addPropertyValue("version", "V1");
+ definition.getPropertyValues().addPropertyValue("deprecationErrors", "true");
+
+ DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
+ factory.registerBeanDefinition("factory", definition);
+
+ MongoServerApiFactoryBean bean = factory.getBean("&factory", MongoServerApiFactoryBean.class);
+ assertThat(ReflectionTestUtils.getField(bean, "deprecationErrors")).isEqualTo(true);
+
+ ServerApi target = factory.getBean(ServerApi.class);
+ assertThat(target.getVersion()).isEqualTo(ServerApiVersion.V1);
+ assertThat(target.getDeprecationErrors()).contains(true);
+ assertThat(target.getStrict()).isNotPresent();
+ }
+
+ @Test // DATAMONGO-2306
+ public void createsServerApiForVersionNumber() {
+
+ RootBeanDefinition definition = new RootBeanDefinition(MongoServerApiFactoryBean.class);
+ definition.getPropertyValues().addPropertyValue("version", "1");
+ definition.getPropertyValues().addPropertyValue("strict", "true");
+
+ DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
+ factory.registerBeanDefinition("factory", definition);
+
+ MongoServerApiFactoryBean bean = factory.getBean("&factory", MongoServerApiFactoryBean.class);
+ assertThat(ReflectionTestUtils.getField(bean, "strict")).isEqualTo(true);
+
+ ServerApi target = factory.getBean(ServerApi.class);
+ assertThat(target.getVersion()).isEqualTo(ServerApiVersion.V1);
+ assertThat(target.getDeprecationErrors()).isNotPresent();
+ assertThat(target.getStrict()).contains(true);
+ }
+}
diff --git a/spring-data-mongodb/src/test/resources/org/springframework/data/mongodb/config/MongoClientNamespaceTests-context.xml b/spring-data-mongodb/src/test/resources/org/springframework/data/mongodb/config/MongoClientNamespaceTests-context.xml
index 1bd3aa2a05..79e5ac40a0 100644
--- a/spring-data-mongodb/src/test/resources/org/springframework/data/mongodb/config/MongoClientNamespaceTests-context.xml
+++ b/spring-data-mongodb/src/test/resources/org/springframework/data/mongodb/config/MongoClientNamespaceTests-context.xml
@@ -41,4 +41,9 @@
+
+
+
+
+