From 12fce55a66848bcc7f71430324b3a9051b8ce0d4 Mon Sep 17 00:00:00 2001 From: Jim Hahn Date: Fri, 18 Dec 2020 19:01:52 -0500 Subject: Use annotations to do validation Modified models to use annotations instead of function calls for most field validations. Created a few new validation annotations for use within models. Per review comments: - renamed Key to VerifyKey - enhanced VerifyKey to imply "@Valid", unless disabled Issue-ID: POLICY-2648 Change-Id: I2b53f218b0a2ab1ed1f5e278816a3509f1408972 Signed-off-by: Jim Hahn --- .../policy/models/base/PfConceptContainer.java | 8 +- .../org/onap/policy/models/base/PfConceptKey.java | 3 + .../org/onap/policy/models/base/PfKeyImpl.java | 12 -- .../java/org/onap/policy/models/base/PfKeyUse.java | 15 +- .../java/org/onap/policy/models/base/PfModel.java | 8 +- .../onap/policy/models/base/PfReferenceKey.java | 24 ++-- .../onap/policy/models/base/PfSearchableKey.java | 3 + .../onap/policy/models/base/PfTimestampKey.java | 3 + .../org/onap/policy/models/base/PfValidator.java | 160 +++++++++++++++++++++ .../org/onap/policy/models/base/Validated.java | 9 +- .../base/validation/annotations/PfEntries.java | 45 ++++++ .../base/validation/annotations/PfItems.java | 82 +++++++++++ .../models/base/validation/annotations/PfMin.java | 47 ++++++ .../base/validation/annotations/VerifyKey.java | 57 ++++++++ .../org/onap/policy/models/base/PfKeyImplTest.java | 6 +- .../org/onap/policy/models/base/ValidatedTest.java | 6 +- .../models/base/testconcepts/DummyPfConcept.java | 19 +-- .../models/base/testconcepts/DummyPfKey.java | 4 +- 18 files changed, 450 insertions(+), 61 deletions(-) create mode 100644 models-base/src/main/java/org/onap/policy/models/base/PfValidator.java create mode 100644 models-base/src/main/java/org/onap/policy/models/base/validation/annotations/PfEntries.java create mode 100644 models-base/src/main/java/org/onap/policy/models/base/validation/annotations/PfItems.java create mode 100644 models-base/src/main/java/org/onap/policy/models/base/validation/annotations/PfMin.java create mode 100644 models-base/src/main/java/org/onap/policy/models/base/validation/annotations/VerifyKey.java (limited to 'models-base') diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfConceptContainer.java b/models-base/src/main/java/org/onap/policy/models/base/PfConceptContainer.java index 484632f7c..4c2cf0c4f 100644 --- a/models-base/src/main/java/org/onap/policy/models/base/PfConceptContainer.java +++ b/models-base/src/main/java/org/onap/policy/models/base/PfConceptContainer.java @@ -47,6 +47,8 @@ import lombok.NonNull; import org.apache.commons.lang3.StringUtils; import org.onap.policy.common.parameters.BeanValidationResult; import org.onap.policy.common.parameters.ValidationResult; +import org.onap.policy.common.parameters.annotations.NotNull; +import org.onap.policy.models.base.validation.annotations.VerifyKey; // @formatter:off /** @@ -73,6 +75,8 @@ public class PfConceptContainer ex private static final Pattern KEY_ID_PATTERN = Pattern.compile(PfKey.KEY_ID_REGEXP); @EmbeddedId + @VerifyKey + @NotNull private PfConceptKey key; @ManyToMany(cascade = CascadeType.ALL) @@ -243,9 +247,7 @@ public class PfConceptContainer ex @Override public BeanValidationResult validate(@NonNull String fieldName) { - BeanValidationResult result = new BeanValidationResult(fieldName, this); - - result.addResult(validateKeyNotNull("key", key)); + BeanValidationResult result = new PfValidator().validateTop(fieldName, this); result.addResult(validateConceptMap()); return result; diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfConceptKey.java b/models-base/src/main/java/org/onap/policy/models/base/PfConceptKey.java index 5e3295ec7..d200a693a 100644 --- a/models-base/src/main/java/org/onap/policy/models/base/PfConceptKey.java +++ b/models-base/src/main/java/org/onap/policy/models/base/PfConceptKey.java @@ -26,6 +26,7 @@ import javax.persistence.Embeddable; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; +import org.onap.policy.common.parameters.annotations.Pattern; import org.onap.policy.common.utils.validation.Assertions; /** @@ -43,9 +44,11 @@ public class PfConceptKey extends PfKeyImpl { private static final long serialVersionUID = 8932717618579392561L; @Column(name = NAME_TOKEN, length = 120) + @Pattern(regexp = NAME_REGEXP) private String name; @Column(name = VERSION_TOKEN, length = 20) + @Pattern(regexp = VERSION_REGEXP) private String version; /** diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfKeyImpl.java b/models-base/src/main/java/org/onap/policy/models/base/PfKeyImpl.java index 3cbef75f9..bfeb870c1 100644 --- a/models-base/src/main/java/org/onap/policy/models/base/PfKeyImpl.java +++ b/models-base/src/main/java/org/onap/policy/models/base/PfKeyImpl.java @@ -26,8 +26,6 @@ import java.util.List; import lombok.Getter; import lombok.NonNull; import lombok.ToString; -import org.onap.policy.common.parameters.BeanValidationResult; -import org.onap.policy.common.parameters.ValidationResult; import org.onap.policy.common.utils.validation.Assertions; /** @@ -241,16 +239,6 @@ public abstract class PfKeyImpl extends PfKey { } } - @Override - public ValidationResult validate(@NonNull String fieldName) { - BeanValidationResult result = new BeanValidationResult(fieldName, this); - - result.addResult(validateRegex(NAME_TOKEN, getName(), getNameRegEx())); - result.addResult(validateRegex(VERSION_TOKEN, getVersion(), getVersionRegEx())); - - return result; - } - @Override public void clean() { setName(getName()); diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfKeyUse.java b/models-base/src/main/java/org/onap/policy/models/base/PfKeyUse.java index 616284daf..b753bb14a 100644 --- a/models-base/src/main/java/org/onap/policy/models/base/PfKeyUse.java +++ b/models-base/src/main/java/org/onap/policy/models/base/PfKeyUse.java @@ -23,11 +23,12 @@ package org.onap.policy.models.base; import java.util.List; import lombok.EqualsAndHashCode; +import lombok.Getter; import lombok.NonNull; import lombok.ToString; -import org.onap.policy.common.parameters.BeanValidationResult; -import org.onap.policy.common.parameters.ValidationResult; +import org.onap.policy.common.parameters.annotations.NotNull; import org.onap.policy.common.utils.validation.Assertions; +import org.onap.policy.models.base.validation.annotations.VerifyKey; /** * This class records a usage of a key in the system. When the list of keys being used by a concept @@ -42,6 +43,9 @@ import org.onap.policy.common.utils.validation.Assertions; public class PfKeyUse extends PfKey { private static final long serialVersionUID = 2007147220109881705L; + @VerifyKey + @NotNull + @Getter private PfKey usedKey; /** @@ -134,13 +138,6 @@ public class PfKeyUse extends PfKey { usedKey.clean(); } - @Override - public ValidationResult validate(@NonNull String fieldName) { - BeanValidationResult result = new BeanValidationResult(fieldName, this); - result.addResult(validateKeyNotNull("usedKey", usedKey)); - return result; - } - @Override public int compareTo(final PfConcept otherObj) { Assertions.argumentNotNull(otherObj, "comparison object may not be null"); diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfModel.java b/models-base/src/main/java/org/onap/policy/models/base/PfModel.java index c87874774..82b8f93f6 100644 --- a/models-base/src/main/java/org/onap/policy/models/base/PfModel.java +++ b/models-base/src/main/java/org/onap/policy/models/base/PfModel.java @@ -35,7 +35,9 @@ import lombok.NonNull; import org.onap.policy.common.parameters.BeanValidationResult; import org.onap.policy.common.parameters.ObjectValidationResult; import org.onap.policy.common.parameters.ValidationStatus; +import org.onap.policy.common.parameters.annotations.NotNull; import org.onap.policy.common.utils.validation.Assertions; +import org.onap.policy.models.base.validation.annotations.VerifyKey; /** * This class is the base class for all models in the Policy Framework. All model classes inherit @@ -63,6 +65,8 @@ public abstract class PfModel extends PfConcept { private static final long serialVersionUID = -771659065637205430L; @EmbeddedId + @VerifyKey + @NotNull private PfConceptKey key; /** @@ -113,9 +117,7 @@ public abstract class PfModel extends PfConcept { @Override public BeanValidationResult validate(@NonNull String fieldName) { - BeanValidationResult result = new BeanValidationResult(fieldName, this); - - result.addResult(validateKeyNotNull("key", key)); + BeanValidationResult result = new PfValidator().validateTop(fieldName, this); // Key consistency check final Set artifactKeySet = new TreeSet<>(); diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfReferenceKey.java b/models-base/src/main/java/org/onap/policy/models/base/PfReferenceKey.java index 83403ac43..9a986481b 100644 --- a/models-base/src/main/java/org/onap/policy/models/base/PfReferenceKey.java +++ b/models-base/src/main/java/org/onap/policy/models/base/PfReferenceKey.java @@ -28,8 +28,8 @@ import javax.persistence.Embeddable; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NonNull; -import org.onap.policy.common.parameters.BeanValidationResult; -import org.onap.policy.common.parameters.ValidationResult; +import org.onap.policy.common.parameters.annotations.NotNull; +import org.onap.policy.common.parameters.annotations.Pattern; import org.onap.policy.common.utils.validation.Assertions; /** @@ -73,15 +73,23 @@ public class PfReferenceKey extends PfKey { private static final int LOCAL_NAME_FIELD = 3; @Column(name = PARENT_KEY_NAME, length = 120) + @NotNull + @Pattern(regexp = NAME_REGEXP) private String parentKeyName; @Column(name = PARENT_KEY_VERSION, length = 15) + @NotNull + @Pattern(regexp = VERSION_REGEXP) private String parentKeyVersion; @Column(name = PARENT_LOCAL_NAME, length = 120) + @NotNull + @Pattern(regexp = LOCAL_NAME_REGEXP) private String parentLocalName; @Column(name = LOCAL_NAME, length = 120) + @NotNull + @Pattern(regexp = LOCAL_NAME_REGEXP) private String localName; /** @@ -339,18 +347,6 @@ public class PfReferenceKey extends PfKey { return this.getParentConceptKey().isNewerThan(otherReferenceKey.getParentConceptKey()); } - @Override - public ValidationResult validate(@NonNull String fieldName) { - BeanValidationResult result = new BeanValidationResult(fieldName, this); - - result.addResult(validateRegex(PARENT_KEY_NAME, parentKeyName, NAME_REGEXP)); - result.addResult(validateRegex(PARENT_KEY_VERSION, parentKeyVersion, VERSION_REGEXP)); - result.addResult(validateRegex(PARENT_LOCAL_NAME, parentLocalName, LOCAL_NAME_REGEXP)); - result.addResult(validateRegex(LOCAL_NAME, localName, LOCAL_NAME_REGEXP)); - - return result; - } - @Override public void clean() { parentKeyName = Assertions.validateStringParameter(PARENT_KEY_NAME, parentKeyName, NAME_REGEXP); diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfSearchableKey.java b/models-base/src/main/java/org/onap/policy/models/base/PfSearchableKey.java index bed1a3598..3ff4160a3 100644 --- a/models-base/src/main/java/org/onap/policy/models/base/PfSearchableKey.java +++ b/models-base/src/main/java/org/onap/policy/models/base/PfSearchableKey.java @@ -26,6 +26,7 @@ import javax.persistence.Embeddable; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; +import org.onap.policy.common.parameters.annotations.Pattern; import org.onap.policy.common.utils.validation.Assertions; /** @@ -42,9 +43,11 @@ public class PfSearchableKey extends PfKeyImpl { public static final String WILDCARD_NAME_REGEXP = "^[A-Za-z0-9\\-_\\.]+(?:\\.\\*)?$"; @Column(name = NAME_TOKEN, length = 120) + @Pattern(regexp = NAME_REGEXP) private String name; @Column(name = VERSION_TOKEN, length = 20) + @Pattern(regexp = VERSION_REGEXP) private String version; /** diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfTimestampKey.java b/models-base/src/main/java/org/onap/policy/models/base/PfTimestampKey.java index 5be9b5f58..d12466c60 100644 --- a/models-base/src/main/java/org/onap/policy/models/base/PfTimestampKey.java +++ b/models-base/src/main/java/org/onap/policy/models/base/PfTimestampKey.java @@ -29,6 +29,7 @@ import javax.persistence.Embeddable; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; +import org.onap.policy.common.parameters.annotations.Pattern; import org.onap.policy.common.utils.validation.Assertions; @Embeddable @@ -40,9 +41,11 @@ public class PfTimestampKey extends PfKeyImpl { private static final String TIMESTAMP_TOKEN = "timeStamp"; @Column(name = NAME_TOKEN, length = 120) + @Pattern(regexp = NAME_REGEXP) private String name; @Column(name = VERSION_TOKEN, length = 20) + @Pattern(regexp = VERSION_REGEXP) private String version; @Column(name = TIMESTAMP_TOKEN) diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfValidator.java b/models-base/src/main/java/org/onap/policy/models/base/PfValidator.java new file mode 100644 index 000000000..c4e46e0b5 --- /dev/null +++ b/models-base/src/main/java/org/onap/policy/models/base/PfValidator.java @@ -0,0 +1,160 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.base; + +import java.util.Map; +import org.onap.policy.common.parameters.BeanValidationResult; +import org.onap.policy.common.parameters.BeanValidator; +import org.onap.policy.common.parameters.EntryValidator; +import org.onap.policy.common.parameters.ObjectValidationResult; +import org.onap.policy.common.parameters.ValidationResult; +import org.onap.policy.common.parameters.ValidationStatus; +import org.onap.policy.common.parameters.ValueValidator; +import org.onap.policy.models.base.validation.annotations.PfEntries; +import org.onap.policy.models.base.validation.annotations.PfItems; +import org.onap.policy.models.base.validation.annotations.PfMin; +import org.onap.policy.models.base.validation.annotations.VerifyKey; + +public class PfValidator extends BeanValidator { + + @Override + protected void addValidators(ValueValidator validator) { + super.addValidators(validator); + + validator.addAnnotation(PfItems.class, this::verCollection); + validator.addAnnotation(PfEntries.class, this::verMap); + validator.addAnnotation(VerifyKey.class, this::verKey); + validator.addAnnotation(PfMin.class, this::verPfMin); + } + + /** + * Verifies that the value is >= the minimum value. + * + * @param result where to add the validation result + * @param fieldName field whose value is being verified + * @param annot annotation against which the value is being verified + * @param value value to be verified + * @return {@code true} if the next check should be performed, {@code false} otherwise + */ + public boolean verPfMin(BeanValidationResult result, String fieldName, PfMin annot, Object value) { + if (!(value instanceof Number)) { + return true; + } + + Number num = (Number) value; + if (num.longValue() == annot.allowed()) { + // this value is always allowed + return true; + } + + return verMin(result, fieldName, annot.value(), value); + } + + /** + * Validates the items in a Map. + * + * @param result where to add the validation result + * @param fieldName name of the field containing the collection + * @param annot validation annotations for individual entries + * @param value value to be verified + * @return {@code true} if the next check should be performed, {@code false} otherwise + */ + public boolean verMap(BeanValidationResult result, String fieldName, PfEntries annot, Object value) { + + if (!(value instanceof Map)) { + return true; + } + + EntryValidator entryValidator = makeEntryValidator(annot.key(), annot.value()); + + return verMap(result, fieldName, entryValidator, value); + } + + /** + * Invokes the value's {@link Validated#validate(String) validate()} method, if the + * value is of type {@link Validated}. + */ + @Override + public boolean verCascade(BeanValidationResult result, String fieldName, Object value) { + if (value instanceof Validated) { + ValidationResult result2 = ((Validated) value).validate(fieldName); + result.addResult(result2); + return result2.isValid(); + } + + return super.verCascade(result, fieldName, value); + } + + /** + * Validates a key. + * + * @param result where to add the validation result + * @param fieldName name of the field containing the key + * @param annot validation annotations for the key + * @param value value to be verified + * @return {@code true} if the next check should be performed, {@code false} otherwise + */ + public boolean verKey(BeanValidationResult result, String fieldName, VerifyKey annot, Object value) { + if (!(value instanceof PfKey)) { + return true; + } + + PfKey pfkey = (PfKey) value; + if (annot.keyNotNull() && pfkey.isNullKey()) { + result.addResult(new ObjectValidationResult(fieldName, xlate(pfkey), ValidationStatus.INVALID, + Validated.IS_A_NULL_KEY)); + return false; + } + + if (annot.valid()) { + verCascade(result, fieldName, value); + } + + if (!(pfkey instanceof PfKeyImpl)) { + return true; + } + + BeanValidationResult result2 = new BeanValidationResult(fieldName, value); + + PfKeyImpl keyimpl = (PfKeyImpl) pfkey; + + if (annot.nameNotNull() && keyimpl.isNullName()) { + result2.addResult(new ObjectValidationResult("name", pfkey.getName(), ValidationStatus.INVALID, + Validated.IS_NULL)); + } + + if (annot.versionNotNull() && keyimpl.isNullVersion()) { + result2.addResult(new ObjectValidationResult("version", pfkey.getVersion(), ValidationStatus.INVALID, + Validated.IS_NULL)); + } + + if (!result2.isClean()) { + result.addResult(result2); + } + + return result2.isValid(); + } + + @Override + public Object xlate(Object value) { + return (value instanceof PfKey ? ((PfKey) value).getId() : value); + } +} diff --git a/models-base/src/main/java/org/onap/policy/models/base/Validated.java b/models-base/src/main/java/org/onap/policy/models/base/Validated.java index b962d46ab..2c059ba4b 100644 --- a/models-base/src/main/java/org/onap/policy/models/base/Validated.java +++ b/models-base/src/main/java/org/onap/policy/models/base/Validated.java @@ -37,7 +37,7 @@ import org.onap.policy.common.parameters.ValidationStatus; * Classes that can be validated. This can be used as a super class or as a stand-alone * utility class. */ -public abstract class Validated { +public class Validated { public static final String IS_BLANK = "is blank"; public static final String IS_A_NULL_KEY = "is a null key"; public static final String IS_NULL = "is null"; @@ -48,12 +48,15 @@ public abstract class Validated { public static final String VALUE_TOKEN = "value"; /** - * Validates the fields of the object. + * Validates the fields of the object. The default method uses a {@link PfValidator} + * to validate the object. * * @param fieldName name of the field containing this * @return the result, or {@code null} */ - public abstract ValidationResult validate(String fieldName); + public BeanValidationResult validate(@NonNull String fieldName) { + return new PfValidator().validateTop(fieldName, this); + } /** * Adds a result indicating that a value is invalid. diff --git a/models-base/src/main/java/org/onap/policy/models/base/validation/annotations/PfEntries.java b/models-base/src/main/java/org/onap/policy/models/base/validation/annotations/PfEntries.java new file mode 100644 index 000000000..f3726003b --- /dev/null +++ b/models-base/src/main/java/org/onap/policy/models/base/validation/annotations/PfEntries.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.base.validation.annotations; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Validations on entries within a Map. + */ +@Retention(RUNTIME) +@Target(FIELD) +public @interface PfEntries { + + /** + * Validations to perform on each entry's key. + */ + PfItems key(); + + /** + * Validations to perform on each entry's value. + */ + PfItems value(); +} diff --git a/models-base/src/main/java/org/onap/policy/models/base/validation/annotations/PfItems.java b/models-base/src/main/java/org/onap/policy/models/base/validation/annotations/PfItems.java new file mode 100644 index 000000000..363cf6f34 --- /dev/null +++ b/models-base/src/main/java/org/onap/policy/models/base/validation/annotations/PfItems.java @@ -0,0 +1,82 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.base.validation.annotations; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import org.intellij.lang.annotations.Pattern; +import org.onap.policy.common.parameters.annotations.Max; +import org.onap.policy.common.parameters.annotations.Min; +import org.onap.policy.common.parameters.annotations.NotBlank; +import org.onap.policy.common.parameters.annotations.NotNull; +import org.onap.policy.common.parameters.annotations.Valid; + +/** + * Validations on individual items, typically within a collection. + */ +@Retention(RUNTIME) +@Target(FIELD) +public @interface PfItems { + + /** + * Validates the item is not {@code null}. + */ + NotNull[] notNull() default {}; + + /** + * Validates the item is not blank. + */ + NotBlank[] notBlank() default {}; + + /** + * Validates the item matches a regular expression. + */ + Pattern[] pattern() default {}; + + /** + * Validates the item is not greater than a certain value. + */ + Max[] max() default {}; + + /** + * Validates the item is not less than a certain value. + */ + Min[] min() default {}; + + /** + * Validates the item is not less than a certain value. + */ + PfMin[] pfMin() default {}; + + /** + * Validates the item is valid, using a {@link BeanValidator}. + */ + Valid[] valid() default {}; + + /** + * Validates a key. + */ + VerifyKey[] key() default {}; + +} diff --git a/models-base/src/main/java/org/onap/policy/models/base/validation/annotations/PfMin.java b/models-base/src/main/java/org/onap/policy/models/base/validation/annotations/PfMin.java new file mode 100644 index 000000000..71f001848 --- /dev/null +++ b/models-base/src/main/java/org/onap/policy/models/base/validation/annotations/PfMin.java @@ -0,0 +1,47 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.base.validation.annotations; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Same as the "Min" annotation, but allows an extra value that is not in the range. + */ +@Retention(RUNTIME) +@Target(FIELD) +public @interface PfMin { + + /** + * The minimum value allowed. + * + * @return the minimum value allowed + */ + long value(); + + /** + * Allowed value. + */ + long allowed(); +} diff --git a/models-base/src/main/java/org/onap/policy/models/base/validation/annotations/VerifyKey.java b/models-base/src/main/java/org/onap/policy/models/base/validation/annotations/VerifyKey.java new file mode 100644 index 000000000..cc8c882df --- /dev/null +++ b/models-base/src/main/java/org/onap/policy/models/base/validation/annotations/VerifyKey.java @@ -0,0 +1,57 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.base.validation.annotations; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Validates a key. + */ +@Retention(RUNTIME) +@Target(FIELD) +public @interface VerifyKey { + + /** + * Validates that key.isNullKey() is {@code false}. + */ + boolean keyNotNull() default true; + + /** + * Validates that key.isNullName() is {@code false}. + */ + boolean nameNotNull() default true; + + /** + * Validates that key.isNullVersion() is {@code false}. + */ + boolean versionNotNull() default false; + + /** + * Invokes key.validate(), avoiding the need to include the "Valid" annotation. Note: + * if this is {@code true}, then the "Valid" annotation should not be specified, as + * that would result in duplicate validation checks. + */ + boolean valid() default true; +} diff --git a/models-base/src/test/java/org/onap/policy/models/base/PfKeyImplTest.java b/models-base/src/test/java/org/onap/policy/models/base/PfKeyImplTest.java index 8d6b1b9f4..dc69e2e67 100644 --- a/models-base/src/test/java/org/onap/policy/models/base/PfKeyImplTest.java +++ b/models-base/src/test/java/org/onap/policy/models/base/PfKeyImplTest.java @@ -37,6 +37,7 @@ import lombok.NoArgsConstructor; import lombok.Setter; import org.junit.Test; import org.onap.policy.common.parameters.ValidationResult; +import org.onap.policy.common.parameters.annotations.Pattern; import org.onap.policy.models.base.PfKey.Compatibility; import org.onap.policy.models.base.testconcepts.DummyPfKey; @@ -268,10 +269,13 @@ public class PfKeyImplTest { @Setter @EqualsAndHashCode(callSuper = false) @NoArgsConstructor - private static class MyKey extends PfKeyImpl { + public static class MyKey extends PfKeyImpl { private static final long serialVersionUID = 1L; + @Pattern(regexp = NAME_REGEXP) private String name; + + @Pattern(regexp = VERSION_REGEXP) private String version; public MyKey(String name, String version) { diff --git a/models-base/src/test/java/org/onap/policy/models/base/ValidatedTest.java b/models-base/src/test/java/org/onap/policy/models/base/ValidatedTest.java index 8534d82a6..dab28f636 100644 --- a/models-base/src/test/java/org/onap/policy/models/base/ValidatedTest.java +++ b/models-base/src/test/java/org/onap/policy/models/base/ValidatedTest.java @@ -434,12 +434,14 @@ public class ValidatedTest { private final String text; @Override - public ValidationResult validate(String fieldName) { + public BeanValidationResult validate(String fieldName) { if (TEXT.equals(text)) { return null; } - return new ObjectValidationResult(fieldName, text, ValidationStatus.INVALID, NOT_SAME); + BeanValidationResult result = new BeanValidationResult(fieldName, this); + result.addResult(new ObjectValidationResult(fieldName, text, ValidationStatus.INVALID, NOT_SAME)); + return result; } } } diff --git a/models-base/src/test/java/org/onap/policy/models/base/testconcepts/DummyPfConcept.java b/models-base/src/test/java/org/onap/policy/models/base/testconcepts/DummyPfConcept.java index 67a450702..548c26252 100644 --- a/models-base/src/test/java/org/onap/policy/models/base/testconcepts/DummyPfConcept.java +++ b/models-base/src/test/java/org/onap/policy/models/base/testconcepts/DummyPfConcept.java @@ -27,20 +27,25 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NonNull; import org.apache.commons.lang3.ObjectUtils; -import org.onap.policy.common.parameters.BeanValidationResult; -import org.onap.policy.common.parameters.ValidationResult; +import org.onap.policy.common.parameters.annotations.NotBlank; +import org.onap.policy.common.parameters.annotations.NotNull; import org.onap.policy.models.base.PfAuthorative; import org.onap.policy.models.base.PfConcept; import org.onap.policy.models.base.PfConceptKey; import org.onap.policy.models.base.PfKey; +import org.onap.policy.models.base.validation.annotations.VerifyKey; @Data @EqualsAndHashCode(callSuper = false) public class DummyPfConcept extends PfConcept implements PfAuthorative { private static final long serialVersionUID = 1L; + @EmbeddedId + @VerifyKey + @NotNull private PfConceptKey key; + @NotBlank private String description; @@ -100,16 +105,6 @@ public class DummyPfConcept extends PfConcept implements PfAuthorative