From 2024b30059bd27c12491c6bea12307782bdd36c4 Mon Sep 17 00:00:00 2001 From: Andreas Zink Date: Sun, 22 Oct 2017 19:06:12 +0200 Subject: [PATCH] DATAMONGO-1322 - Add support for Criteria-based validator for collection creation. Extended the CollectionOptions with a ValidationOptions property which corresponds to the MongoDB createCollection() parameters. A validator object can be defined using the Criteria API, or by writing a custom provider. Original pull request: #511. Related pull request: #525. Related ticket: DATACMNS-1835. --- .../data/mongodb/core/CollectionOptions.java | 22 ++- .../data/mongodb/core/MongoTemplate.java | 10 +- .../core/validation/CriteriaValidator.java | 65 +++++++ .../core/validation/ValidationAction.java | 46 +++++ .../core/validation/ValidationLevel.java | 50 +++++ .../core/validation/ValidationOptions.java | 74 +++++++ .../core/validation/ValidatorDefinition.java | 35 ++++ .../core/MongoTemplateValidationTests.java | 183 ++++++++++++++++++ .../core/schema/MongoJsonSchemaTests.java | 1 - .../validation/CriteriaValidatorTest.java | 43 ++++ 10 files changed, 521 insertions(+), 8 deletions(-) create mode 100644 spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/CriteriaValidator.java create mode 100644 spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/ValidationAction.java create mode 100644 spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/ValidationLevel.java create mode 100644 spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/ValidationOptions.java create mode 100644 spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/ValidatorDefinition.java create mode 100644 spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateValidationTests.java create mode 100644 spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/validation/CriteriaValidatorTest.java diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionOptions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionOptions.java index b1a7d8214..0f28588d5 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionOptions.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionOptions.java @@ -21,6 +21,7 @@ import java.util.Optional; import org.springframework.data.mongodb.core.query.Collation; import org.springframework.data.mongodb.core.schema.MongoJsonSchema; +import org.springframework.data.mongodb.core.validation.ValidatorDefinition; import org.springframework.data.util.Optionals; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -34,6 +35,7 @@ import com.mongodb.client.model.ValidationLevel; * @author Thomas Risberg * @author Christoph Strobl * @author Mark Paluch + * @author Andreas Zink */ public class CollectionOptions { @@ -144,7 +146,11 @@ public class CollectionOptions { * @since 2.1 */ public CollectionOptions schema(@Nullable MongoJsonSchema schema) { - return validation(new Validator(schema, validator.validationLevel, validator.validationAction)); + return validation(new Validator(schema, null, validator.validationLevel, validator.validationAction)); + } + + public CollectionOptions validatorDefinition(@Nullable ValidatorDefinition definition) { + return validation(new Validator(null, definition, validator.validationLevel, validator.validationAction)); } /** @@ -213,7 +219,7 @@ public class CollectionOptions { public CollectionOptions schemaValidationLevel(ValidationLevel validationLevel) { Assert.notNull(validationLevel, "ValidationLevel must not be null!"); - return validation(new Validator(validator.schema, validationLevel, validator.validationAction)); + return validation(new Validator(validator.schema, validator.validatorDefinition, validationLevel, validator.validationAction)); } /** @@ -227,7 +233,7 @@ public class CollectionOptions { public CollectionOptions schemaValidationAction(ValidationAction validationAction) { Assert.notNull(validationAction, "ValidationAction must not be null!"); - return validation(new Validator(validator.schema, validator.validationLevel, validationAction)); + return validation(new Validator(validator.schema, validator.validatorDefinition, validator.validationLevel, validationAction)); } /** @@ -295,14 +301,16 @@ public class CollectionOptions { * Encapsulation of Validator options. * * @author Christoph Strobl + * @author Andreas Zink * @since 2.1 */ @RequiredArgsConstructor public static class Validator { - private static final Validator NONE = new Validator(null, null, null); + private static final Validator NONE = new Validator(null, null, null, null); private final @Nullable MongoJsonSchema schema; + private final @Nullable ValidatorDefinition validatorDefinition; private final @Nullable ValidationLevel validationLevel; private final @Nullable ValidationAction validationAction; @@ -324,6 +332,10 @@ public class CollectionOptions { return Optional.ofNullable(schema); } + public Optional getValidatorDefinition() { + return Optional.ofNullable(validatorDefinition); + } + /** * Get the {@code validationLevel} to apply. * @@ -346,7 +358,7 @@ public class CollectionOptions { * @return {@literal true} if no arguments set. */ boolean isEmpty() { - return !Optionals.isAnyPresent(getSchema(), getValidationAction(), getValidationLevel()); + return !Optionals.isAnyPresent(getSchema(), getValidatorDefinition(), getValidationAction(), getValidationLevel()); } } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java index 6b0612d55..2d2f7d5a2 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java @@ -140,6 +140,9 @@ import com.mongodb.client.MongoCursor; import com.mongodb.client.MongoDatabase; import com.mongodb.client.MongoIterable; import com.mongodb.client.model.*; +import com.mongodb.client.model.ValidationAction; +import com.mongodb.client.model.ValidationLevel; +import com.mongodb.client.model.ValidationOptions; import com.mongodb.client.result.DeleteResult; import com.mongodb.client.result.UpdateResult; import com.mongodb.util.JSONParseException; @@ -165,6 +168,7 @@ import com.mongodb.util.JSONParseException; * @author Maninder Singh * @author Borislav Rangelov * @author duozhilin + * @author Andreas Zink */ @SuppressWarnings("deprecation") public class MongoTemplate implements MongoOperations, ApplicationContextAware, IndexOperationsProvider { @@ -2374,6 +2378,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, Document doc = convertToDocument(collectionOptions); if (collectionOptions != null && collectionOptions.getValidator().isPresent()) { + Validator v = collectionOptions.getValidator().get(); v.getSchema().ifPresent(val -> doc.put("validator", schemaMapper.mapSchema(val.toDocument(), targetType))); } @@ -2398,10 +2403,11 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, if (collectionOptions.getValidator().isPresent()) { Validator v = collectionOptions.getValidator().get(); - v.getValidationLevel().ifPresent(val -> document.append("validationLevel", val)); - v.getValidationAction().ifPresent(val -> document.append("validationAction", val)); + v.getValidationLevel().ifPresent(val -> document.append("validationLevel", val.getValue())); + v.getValidationAction().ifPresent(val -> document.append("validationAction", val.getValue())); v.getSchema().ifPresent(val -> document.append("validator", new MongoJsonSchemaMapper(getConverter()).mapSchema(val.toDocument(), Object.class))); + v.getValidatorDefinition().ifPresent(val -> document.put("validator", val.toDocument())); } } return document; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/CriteriaValidator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/CriteriaValidator.java new file mode 100644 index 000000000..c6cc30385 --- /dev/null +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/CriteriaValidator.java @@ -0,0 +1,65 @@ +/* + * Copyright 2017 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 + * + * http://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.validation; + +import lombok.EqualsAndHashCode; + +import org.bson.Document; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.query.CriteriaDefinition; +import org.springframework.lang.NonNull; +import org.springframework.util.Assert; + +/** + * Utility to build a MongoDB {@code validator} based on a {@link CriteriaDefinition}. + * + * @author Andreas Zink + * @since 2.1 + * @see Criteria + */ +@EqualsAndHashCode +public class CriteriaValidator implements ValidatorDefinition { + + private final Document document; + + private CriteriaValidator(Document document) { + Assert.notNull(document, "Document must not be null!"); + this.document = document; + } + + /** + * Builds a {@code validator} object, which is basically setup of query operators, based on a + * {@link CriteriaDefinition} instance. + * + * @param criteria the criteria to build the {@code validator} from + * @return + */ + public static CriteriaValidator fromCriteria(@NonNull CriteriaDefinition criteria) { + Assert.notNull(criteria, "Criteria must not be null!"); + return new CriteriaValidator(criteria.getCriteriaObject()); + } + + @Override + public Document toDocument() { + return this.document; + } + + @Override + public String toString() { + return document.toString(); + } + +} diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/ValidationAction.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/ValidationAction.java new file mode 100644 index 000000000..199e00a7d --- /dev/null +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/ValidationAction.java @@ -0,0 +1,46 @@ +/* + * Copyright 2017 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 + * + * http://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.validation; + +import lombok.Getter; + +/** + * Determines whether to error on invalid documents or just warn about the violations but allow invalid documents to be + * inserted. + * + * @author Andreas Zink + * @since 2.1 + * @see MongoDB Collection Options + */ +public enum ValidationAction { + + /** + * Documents must pass validation before the write occurs. Otherwise, the write operation fails. (MongoDB default) + */ + ERROR("error"), + + /** + * Documents do not have to pass validation. If the document fails validation, the write operation logs the validation + * failure. + */ + WARN("warn"); + + @Getter private String value; + + private ValidationAction(String value) { + this.value = value; + } +} diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/ValidationLevel.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/ValidationLevel.java new file mode 100644 index 000000000..187c63ca1 --- /dev/null +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/ValidationLevel.java @@ -0,0 +1,50 @@ +/* + * Copyright 2017 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 + * + * http://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.validation; + +import lombok.Getter; + +/** + * Determines how strictly MongoDB applies the validation rules to existing documents during an update. + * + * @author Andreas Zink + * @since 2.1 + * @see MongoDB Collection Options + */ +public enum ValidationLevel { + + /** + * No validation for inserts or updates. + */ + OFF("off"), + + /** + * Apply validation rules to all inserts and all updates. (MongoDB default) + */ + STRICT("strict"), + + /** + * Apply validation rules to inserts and to updates on existing valid documents. Do not apply rules to updates on + * existing invalid documents. + */ + MODERATE("moderate"); + + @Getter private String value; + + private ValidationLevel(String value) { + this.value = value; + } +} diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/ValidationOptions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/ValidationOptions.java new file mode 100644 index 000000000..ebb9c0baa --- /dev/null +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/ValidationOptions.java @@ -0,0 +1,74 @@ +/* + * Copyright 2017 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 + * + * http://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.validation; + +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.util.Optional; + +import org.springframework.data.mongodb.core.CollectionOptions; +import org.springframework.lang.NonNull; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; + +/** + * Wraps the collection validation options. + * + * @author Andreas Zink + * @since 2.1 + * @see {@link CollectionOptions} + * @see MongoDB Document Validation + * @see MongoDB Collection Options + */ +@EqualsAndHashCode +@ToString +public class ValidationOptions { + private ValidatorDefinition validator; + private ValidationLevel validationLevel; + private ValidationAction validationAction; + + private ValidationOptions(ValidatorDefinition validator) { + Assert.notNull(validator, "ValidatorDefinition must not be null!"); + this.validator = validator; + } + + public static ValidationOptions validator(@NonNull ValidatorDefinition validator) { + return new ValidationOptions(validator); + } + + public ValidationOptions validationLevel(@Nullable ValidationLevel validationLevel) { + this.validationLevel = validationLevel; + return this; + } + + public ValidationOptions validationAction(@Nullable ValidationAction validationAction) { + this.validationAction = validationAction; + return this; + } + + public ValidatorDefinition getValidator() { + return validator; + } + + public Optional getValidationLevel() { + return Optional.ofNullable(validationLevel); + } + + public Optional getValidationAction() { + return Optional.ofNullable(validationAction); + } +} diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/ValidatorDefinition.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/ValidatorDefinition.java new file mode 100644 index 000000000..50bcbb579 --- /dev/null +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/validation/ValidatorDefinition.java @@ -0,0 +1,35 @@ +/* + * Copyright 2017 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 + * + * http://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.validation; + +import org.bson.Document; +import org.springframework.lang.NonNull; + +/** + * Provides a {@code validator} object to be used for collection validation. + * + * @author Andreas Zink + * @since 2.1 + * @see MongoDB Collection Options + */ +public interface ValidatorDefinition { + + /** + * @return a MongoDB {@code validator} document + */ + public @NonNull Document toDocument(); + +} diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateValidationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateValidationTests.java new file mode 100644 index 000000000..10db45c82 --- /dev/null +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateValidationTests.java @@ -0,0 +1,183 @@ +/* + * Copyright 2017 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 + * + * http://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.assertThat; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +import org.bson.Document; +import org.junit.Assert; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.mongodb.config.AbstractMongoConfiguration; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.validation.CriteriaValidator; +import org.springframework.data.mongodb.core.validation.ValidationAction; +import org.springframework.data.mongodb.core.validation.ValidationLevel; +import org.springframework.data.mongodb.core.validation.ValidationOptions; +import org.springframework.data.mongodb.test.util.MongoVersionRule; +import org.springframework.data.util.Version; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.mongodb.MongoClient; + +/** + * @author Andreas Zink + */ +@RunWith(SpringJUnit4ClassRunner.class) +public class MongoTemplateValidationTests { + + public static @ClassRule MongoVersionRule REQUIRES_AT_LEAST_3_2_0 = MongoVersionRule.atLeast(Version.parse("3.2.0")); + public static final String COLLECTION_NAME = "validation-1"; + + @Configuration + static class Config extends AbstractMongoConfiguration { + + @Override + public MongoClient mongoClient() { + return new MongoClient(); + } + + @Override + protected String getDatabaseName() { + return "validation-tests"; + } + } + + @Autowired MongoTemplate template; + + @Before + public void setUp() { + template.dropCollection(COLLECTION_NAME); + } + + @Test // DATAMONGO-1322 + public void testCollectionWithSimpleCriteriaBasedValidation() { + Criteria criteria = Criteria.where("nonNullString").ne(null).type(2).and("rangedInteger").ne(null).type(16).gte(0) + .lte(122); + template.createCollection(COLLECTION_NAME, CollectionOptions.empty().validatorDefinition(CriteriaValidator.fromCriteria(criteria))); + + Document validator = getValidatorInfo(COLLECTION_NAME); + assertThat(validator.get("nonNullString")).isEqualTo(new Document("$ne", null).append("$type", 2)); + assertThat(validator.get("rangedInteger")) + .isEqualTo(new Document("$ne", null).append("$type", 16).append("$gte", 0).append("$lte", 122)); + + template.save(new SimpleBean("hello", 101), COLLECTION_NAME); + try { + template.save(new SimpleBean(null, 101), COLLECTION_NAME); + Assert.fail("The collection validation was setup to check for non-null string"); + } catch (Exception e) { + // ignore + } + try { + template.save(new SimpleBean("hello", -1), COLLECTION_NAME); + Assert.fail("The collection validation was setup to check for non-negative int"); + } catch (Exception e) { + // ignore + } + } + + @Test // DATAMONGO-1322 + public void testCollectionValidationActionError() { + Criteria criteria = Criteria.where("name").type(2); + template.createCollection(COLLECTION_NAME, CollectionOptions.empty().schemaValidationAction(com.mongodb.client.model.ValidationAction.ERROR).validatorDefinition(CriteriaValidator.fromCriteria(criteria))); + + String validationAction = getValidationActionInfo(COLLECTION_NAME); + assertThat(ValidationAction.ERROR.getValue()).isEqualTo(validationAction); + } + + @Test // DATAMONGO-1322 + public void testCollectionValidationActionWarn() { + Criteria criteria = Criteria.where("name").type(2); + template.createCollection(COLLECTION_NAME, CollectionOptions.empty().schemaValidationAction(com.mongodb.client.model.ValidationAction.WARN).validatorDefinition(CriteriaValidator.fromCriteria(criteria))); + + String validationAction = getValidationActionInfo(COLLECTION_NAME); + assertThat(ValidationAction.WARN.getValue()).isEqualTo(validationAction); + } + + @Test // DATAMONGO-1322 + public void testCollectionValidationLevelOff() { + Criteria criteria = Criteria.where("name").type(2); + template.createCollection(COLLECTION_NAME, CollectionOptions.empty().schemaValidationLevel(com.mongodb.client.model.ValidationLevel.OFF).validatorDefinition(CriteriaValidator.fromCriteria(criteria))); + + String validationAction = getValidationLevelInfo(COLLECTION_NAME); + assertThat(ValidationLevel.OFF.getValue()).isEqualTo(validationAction); + } + + @Test // DATAMONGO-1322 + public void testCollectionValidationLevelModerate() { + Criteria criteria = Criteria.where("name").type(2); + template.createCollection(COLLECTION_NAME, CollectionOptions.empty().schemaValidationLevel(com.mongodb.client.model.ValidationLevel.MODERATE).validatorDefinition(CriteriaValidator.fromCriteria(criteria))); + + String validationAction = getValidationLevelInfo(COLLECTION_NAME); + assertThat(ValidationLevel.MODERATE.getValue()).isEqualTo(validationAction); + } + + @Test // DATAMONGO-1322 + public void testCollectionValidationLevelStrict() { + Criteria criteria = Criteria.where("name").type(2); + template.createCollection(COLLECTION_NAME, CollectionOptions.empty().schemaValidationLevel(com.mongodb.client.model.ValidationLevel.STRICT).validatorDefinition(CriteriaValidator.fromCriteria(criteria))); + + String validationAction = getValidationLevelInfo(COLLECTION_NAME); + assertThat(ValidationLevel.STRICT.getValue()).isEqualTo(validationAction); + } + + private Document getCollectionOptions(String collectionName) { + return getCollectionInfo(collectionName).get("options", Document.class); + } + + private Document getValidatorInfo(String collectionName) { + return getCollectionOptions(collectionName).get("validator", Document.class); + } + + private String getValidationActionInfo(String collectionName) { + return getCollectionOptions(collectionName).get("validationAction", String.class); + } + + private String getValidationLevelInfo(String collectionName) { + return getCollectionOptions(collectionName).get("validationLevel", String.class); + } + + private Document getCollectionInfo(String collectionName) { + return template.execute(db -> { + Document result = db.runCommand( + new Document().append("listCollections", 1).append("filter", new Document("name", collectionName))); + return (Document) result.get("cursor", Document.class).get("firstBatch", List.class).get(0); + }); + } + + @Data + @AllArgsConstructor + @NoArgsConstructor + static class SimpleBean { + @NotNull private String nonNullString; + @NotNull @Min(0) @Max(122) private Integer rangedInteger; + } + +} diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/schema/MongoJsonSchemaTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/schema/MongoJsonSchemaTests.java index 0eabe3bd4..0ce070ae2 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/schema/MongoJsonSchemaTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/schema/MongoJsonSchemaTests.java @@ -28,7 +28,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; -import org.springframework.dao.DataRetrievalFailureException; import org.springframework.data.mongodb.config.AbstractMongoConfiguration; import org.springframework.data.mongodb.core.CollectionOptions; import org.springframework.data.mongodb.core.MongoTemplate; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/validation/CriteriaValidatorTest.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/validation/CriteriaValidatorTest.java new file mode 100644 index 000000000..127968043 --- /dev/null +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/validation/CriteriaValidatorTest.java @@ -0,0 +1,43 @@ +/* + * Copyright 2017 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 + * + * http://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.validation; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.bson.Document; +import org.junit.Test; +import org.springframework.data.mongodb.core.query.Criteria; + +/** + * @author Andreas Zink + */ +public class CriteriaValidatorTest { + + @Test // DATAMONGO-1322 + public void testSimpleCriteria() { + Criteria criteria = Criteria.where("nonNullString").ne(null).type(2).and("rangedInteger").type(16).gte(0).lte(122); + Document validator = CriteriaValidator.fromCriteria(criteria).toDocument(); + + assertThat(validator.get("nonNullString")).isEqualTo(new Document("$ne", null).append("$type", 2)); + assertThat(validator.get("rangedInteger")) + .isEqualTo(new Document("$type", 16).append("$gte", 0).append("$lte", 122)); + } + + @Test(expected = IllegalArgumentException.class) // DATAMONGO-1322 + public void testFailOnNull() { + CriteriaValidator.fromCriteria(null); + } +}