From 12fce55a66848bcc7f71430324b3a9051b8ce0d4 Mon Sep 17 00:00:00 2001 From: Jim Hahn Date: Fri, 18 Dec 2020 19:01:52 -0500 Subject: [PATCH] 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 +- .../models/pdp/persistence/concepts/JpaPdp.java | 15 +- .../pdp/persistence/concepts/JpaPdpGroup.java | 32 ++--- .../pdp/persistence/concepts/JpaPdpStatistics.java | 14 +- .../pdp/persistence/concepts/JpaPdpSubGroup.java | 43 +++--- .../pdp/persistence/provider/PdpProviderTest.java | 2 +- .../concepts/JpaToscaCapabilityAssignment.java | 22 ++- .../simple/concepts/JpaToscaCapabilityType.java | 8 +- .../tosca/simple/concepts/JpaToscaDataType.java | 18 +-- .../tosca/simple/concepts/JpaToscaEntityType.java | 29 ++-- .../tosca/simple/concepts/JpaToscaEventFilter.java | 22 ++- .../tosca/simple/concepts/JpaToscaModel.java | 12 +- .../simple/concepts/JpaToscaNodeTemplate.java | 25 ++-- .../tosca/simple/concepts/JpaToscaNodeType.java | 10 +- .../tosca/simple/concepts/JpaToscaParameter.java | 17 +-- .../tosca/simple/concepts/JpaToscaPolicy.java | 15 +- .../tosca/simple/concepts/JpaToscaPolicyType.java | 12 +- .../tosca/simple/concepts/JpaToscaProperty.java | 30 ++-- .../simple/concepts/JpaToscaRelationshipType.java | 8 +- .../tosca/simple/concepts/JpaToscaRequirement.java | 19 +-- .../simple/concepts/JpaToscaSchemaDefinition.java | 22 ++- .../simple/concepts/JpaToscaServiceTemplate.java | 20 +-- .../simple/concepts/JpaToscaTimeInterval.java | 8 +- .../simple/concepts/JpaToscaTopologyTemplate.java | 29 ++-- .../tosca/simple/concepts/JpaToscaTrigger.java | 41 +++--- .../concepts/JpaToscaServiceTemplateTest.java | 2 +- 43 files changed, 660 insertions(+), 326 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 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, Serializabl private static final long serialVersionUID = -357224425637789775L; @EmbeddedId + @VerifyKey + @NotNull private PfReferenceKey key; @Column + @NotNull private PdpState pdpState; @Column + @NotNull private PdpHealthStatus healthy; @Column + @NotBlank private String message; /** @@ -161,19 +169,14 @@ public class JpaPdp extends PfConcept implements PfAuthorative, Serializabl @Override public BeanValidationResult validate(@NonNull String fieldName) { - BeanValidationResult result = new BeanValidationResult(fieldName, this); + BeanValidationResult result = super.validate(fieldName); - result.addResult(validateKeyNotNull("key", key)); result.addResult(validateKeyNotNull("parent of key", key.getParentConceptKey())); if (PfKey.NULL_KEY_NAME.equals(key.getParentLocalName())) { addResult(result, "local name of parent of key", key.getParentLocalName(), IS_NULL); } - result.addResult(validateNotNull("pdpState", pdpState)); - result.addResult(validateNotNull("healthy", healthy)); - result.addResult(validateNotBlank("message", message, false)); - return result; } diff --git a/models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/concepts/JpaPdpGroup.java b/models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/concepts/JpaPdpGroup.java index 66d36d8d6..5e078bccb 100644 --- a/models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/concepts/JpaPdpGroup.java +++ b/models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/concepts/JpaPdpGroup.java @@ -44,14 +44,18 @@ 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.annotations.Entries; +import org.onap.policy.common.parameters.annotations.Items; +import org.onap.policy.common.parameters.annotations.NotBlank; +import org.onap.policy.common.parameters.annotations.NotNull; +import org.onap.policy.common.parameters.annotations.Valid; 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.PfReferenceKey; import org.onap.policy.models.base.PfUtils; -import org.onap.policy.models.base.Validated; +import org.onap.policy.models.base.validation.annotations.VerifyKey; import org.onap.policy.models.pdp.concepts.PdpGroup; import org.onap.policy.models.pdp.concepts.PdpSubGroup; import org.onap.policy.models.pdp.enums.PdpState; @@ -70,15 +74,21 @@ public class JpaPdpGroup extends PfConcept implements PfAuthorative { private static final long serialVersionUID = -357224425637789775L; @EmbeddedId + @VerifyKey + @NotNull private PfConceptKey key; @Column + @NotBlank private String description; @Column + @NotNull private PdpState pdpGroupState; @ElementCollection + @Entries(key = @Items(notNull = {@NotNull}, notBlank = {@NotBlank}), + value = @Items(notNull = {@NotNull}, notBlank = {@NotBlank})) private Map properties; // @formatter:off @@ -90,6 +100,8 @@ public class JpaPdpGroup extends PfConcept implements PfAuthorative { @JoinColumn(name = "pdpGroupLocalName", referencedColumnName = "localName") }) // @formatter:on + @NotNull + @Items(notNull = {@NotNull}, valid = {@Valid}) private List pdpSubGroups; /** @@ -214,22 +226,6 @@ public class JpaPdpGroup extends PfConcept implements PfAuthorative { } } - @Override - public BeanValidationResult validate(@NonNull String fieldName) { - BeanValidationResult result = new BeanValidationResult(fieldName, this); - - result.addResult(validateKeyNotNull("key", key)); - result.addResult(validateNotBlank("description", description, false)); - result.addResult(validateNotNull("pdpGroupState", pdpGroupState)); - - validateMap(result, "properties", properties, Validated::validateEntryNotBlankNotBlank); - - result.addResult(validateNotNull("pdpSubGroups", pdpSubGroups)); - validateList(result, "pdpSubGroups", pdpSubGroups, Validated::validateNotNull); - - return result; - } - @Override public int compareTo(final PfConcept otherConcept) { if (otherConcept == null) { diff --git a/models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/concepts/JpaPdpStatistics.java b/models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/concepts/JpaPdpStatistics.java index 49163ee8c..90cf4e468 100644 --- a/models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/concepts/JpaPdpStatistics.java +++ b/models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/concepts/JpaPdpStatistics.java @@ -38,12 +38,13 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NonNull; import org.apache.commons.lang3.builder.CompareToBuilder; -import org.onap.policy.common.parameters.BeanValidationResult; +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.PfKey; import org.onap.policy.models.base.PfTimestampKey; import org.onap.policy.models.base.PfUtils; +import org.onap.policy.models.base.validation.annotations.VerifyKey; import org.onap.policy.models.pdp.concepts.PdpEngineWorkerStatistics; import org.onap.policy.models.pdp.concepts.PdpStatistics; @@ -63,6 +64,8 @@ public class JpaPdpStatistics extends PfConcept implements PfAuthorative supportedPolicyTypes; @ElementCollection + @NotNull + @Items(notNull = {@NotNull}, valid = {@Valid}) private List policies; @Column + @Min(0) private int currentInstanceCount; @Column + @Min(0) private int desiredInstanceCount; @ElementCollection + @Entries(key = @Items(notNull = {@NotNull}, notBlank = {@NotBlank}), + value = @Items(notNull = {@NotNull}, notBlank = {@NotBlank})) private Map properties; // @formatter:off @@ -100,6 +116,8 @@ public class JpaPdpSubGroup extends PfConcept implements PfAuthorative pdpInstances; /** @@ -278,33 +296,14 @@ public class JpaPdpSubGroup extends PfConcept implements PfAuthorative { new PdpProvider().updatePdpSubGroup(pfDao, PDP_GROUP0, existingSubGroup); }).hasMessageContaining("PDP sub group").hasMessageContaining("desiredInstanceCount") - .hasMessageContaining("is negative"); + .hasMessageContaining("below the minimum value"); existingSubGroup.setDesiredInstanceCount(10); } diff --git a/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaCapabilityAssignment.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaCapabilityAssignment.java index 81c46423a..28e4cdc2a 100644 --- a/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaCapabilityAssignment.java +++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaCapabilityAssignment.java @@ -34,13 +34,16 @@ import javax.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NonNull; -import org.onap.policy.common.parameters.BeanValidationResult; +import org.onap.policy.common.parameters.annotations.Entries; +import org.onap.policy.common.parameters.annotations.Items; +import org.onap.policy.common.parameters.annotations.NotNull; import org.onap.policy.common.utils.coder.YamlJsonTranslator; 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.PfUtils; -import org.onap.policy.models.base.Validated; +import org.onap.policy.models.base.validation.annotations.PfItems; +import org.onap.policy.models.base.validation.annotations.PfMin; import org.onap.policy.models.tosca.authorative.concepts.ToscaCapabilityAssignment; /** @@ -63,13 +66,16 @@ public class JpaToscaCapabilityAssignment extends JpaToscaEntityType properties; @ElementCollection @Lob + @Entries(key = @Items(notNull = {@NotNull}), value = @Items(notNull = {@NotNull})) private Map attributes; @ElementCollection + @PfItems(notNull = {@NotNull}, pfMin = {@PfMin(value = 0, allowed = -1)}) private List occurrences; /** @@ -158,18 +164,6 @@ public class JpaToscaCapabilityAssignment extends JpaToscaEntityType properties; /** @@ -161,8 +165,6 @@ public class JpaToscaCapabilityType extends JpaToscaEntityType implemen private static final long serialVersionUID = -3922690413436539164L; @ElementCollection + @Items(notNull = {@NotNull}, valid = {@Valid}) private List constraints; @ElementCollection @Lob + @Entries(key = @Items(notNull = {@NotNull}), value = @Items(notNull = {@NotNull}, valid = {@Valid})) private Map properties; /** @@ -163,16 +167,6 @@ public class JpaToscaDataType extends JpaToscaEntityType implemen } } - @Override - public BeanValidationResult validate(String fieldName) { - BeanValidationResult result = super.validate(fieldName); - - validateList(result, "constraints", constraints, Validated::validateNotNull); - validateMap(result, "properties", properties, Validated::validateEntryValueNotNull); - - return result; - } - @Override public int compareTo(final PfConcept otherConcept) { if (otherConcept == null) { diff --git a/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaEntityType.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaEntityType.java index 169d7f244..de3279ec4 100644 --- a/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaEntityType.java +++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaEntityType.java @@ -35,13 +35,16 @@ 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.annotations.Entries; +import org.onap.policy.common.parameters.annotations.Items; +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.PfUtils; -import org.onap.policy.models.base.Validated; +import org.onap.policy.models.base.validation.annotations.VerifyKey; import org.onap.policy.models.tosca.authorative.concepts.ToscaEntity; /** @@ -54,6 +57,8 @@ public class JpaToscaEntityType extends PfConcept impleme private static final long serialVersionUID = -1330661834220739393L; @EmbeddedId + @VerifyKey + @NotNull private PfConceptKey key; // @formatter:off @@ -64,12 +69,16 @@ public class JpaToscaEntityType extends PfConcept impleme @AttributeOverride(name = "version", column = @Column(name = "derived_from_version")) }) + @VerifyKey private PfConceptKey derivedFrom; @ElementCollection + @Entries(key = @Items(notNull = {@NotNull}, notBlank = {@NotBlank}), + value = @Items(notNull = {@NotNull}, notBlank = {@NotBlank})) private Map metadata; @Column + @NotBlank private String description; private transient T toscaEntity; @@ -185,22 +194,6 @@ public class JpaToscaEntityType extends PfConcept impleme description = (description != null ? description.trim() : null); } - @Override - public BeanValidationResult validate(@NonNull String fieldName) { - BeanValidationResult result = new BeanValidationResult(fieldName, this); - - result.addResult(validateKeyNotNull("key", key)); - - if (derivedFrom != null) { - result.addResult(validateKeyNotNull("derivedFrom", derivedFrom)); - } - - validateMap(result, "metadata", metadata, Validated::validateEntryNotBlankNotBlank); - result.addResult(validateNotBlank("description", description, false)); - - return result; - } - @Override public int compareTo(final PfConcept otherConcept) { if (otherConcept == null) { diff --git a/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaEventFilter.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaEventFilter.java index f0d7b9caa..e879a1305 100644 --- a/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaEventFilter.java +++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaEventFilter.java @@ -34,11 +34,13 @@ 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.annotations.NotBlank; +import org.onap.policy.common.parameters.annotations.NotNull; 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.PfReferenceKey; +import org.onap.policy.models.base.validation.annotations.VerifyKey; /** * Class to represent the EventFilter in TOSCA definition. @@ -55,15 +57,21 @@ public class JpaToscaEventFilter extends PfConcept { private static final long serialVersionUID = 8769020537228210247L; @EmbeddedId + @VerifyKey + @NotNull private PfReferenceKey key; @Column + @VerifyKey + @NotNull private PfConceptKey node; @Column + @NotBlank private String requirement; @Column + @NotBlank private String capability; /** @@ -121,18 +129,6 @@ public class JpaToscaEventFilter extends PfConcept { capability = (capability != null ? capability.trim() : capability); } - @Override - public BeanValidationResult validate(@NonNull String fieldName) { - BeanValidationResult result = new BeanValidationResult(fieldName, this); - - result.addResult(validateKeyNotNull("key", key)); - result.addResult(validateKeyNotNull("node", node)); - result.addResult(validateNotBlank("requirement", requirement, false)); - result.addResult(validateNotBlank("capability", capability, false)); - - return result; - } - @Override public int compareTo(final PfConcept otherConcept) { if (otherConcept == null) { diff --git a/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaModel.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaModel.java index c86c34b92..cd6656b4c 100644 --- a/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaModel.java +++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaModel.java @@ -32,7 +32,7 @@ import javax.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NonNull; -import org.onap.policy.common.parameters.BeanValidationResult; +import org.onap.policy.common.parameters.annotations.Valid; import org.onap.policy.models.base.PfConcept; import org.onap.policy.models.base.PfConceptKey; import org.onap.policy.models.base.PfKey; @@ -55,6 +55,7 @@ public class JpaToscaModel extends PfModel { private static final long serialVersionUID = 8800599637708309945L; @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true) + @Valid private JpaToscaServiceTemplates serviceTemplates; /** @@ -116,15 +117,6 @@ public class JpaToscaModel extends PfModel { serviceTemplates.clean(); } - @Override - public BeanValidationResult validate(String fieldName) { - BeanValidationResult result = super.validate(fieldName); - - result.addResult(serviceTemplates.validate("serviceTemplates")); - - return result; - } - @Override public int compareTo(final PfConcept otherConcept) { if (otherConcept == null) { diff --git a/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaNodeTemplate.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaNodeTemplate.java index 05aefa797..c2dcab1ec 100644 --- a/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaNodeTemplate.java +++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaNodeTemplate.java @@ -42,7 +42,11 @@ 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.annotations.Entries; +import org.onap.policy.common.parameters.annotations.Items; +import org.onap.policy.common.parameters.annotations.NotBlank; +import org.onap.policy.common.parameters.annotations.NotNull; +import org.onap.policy.common.parameters.annotations.Valid; import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.common.utils.coder.StandardCoder; import org.onap.policy.models.base.PfAuthorative; @@ -51,7 +55,6 @@ import org.onap.policy.models.base.PfConceptKey; import org.onap.policy.models.base.PfKey; import org.onap.policy.models.base.PfModelRuntimeException; import org.onap.policy.models.base.PfUtils; -import org.onap.policy.models.base.Validated; import org.onap.policy.models.tosca.authorative.concepts.ToscaCapabilityAssignment; import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; @@ -70,21 +73,26 @@ public class JpaToscaNodeTemplate extends JpaToscaEntityType private static final StandardCoder STANDARD_CODER = new StandardCoder(); @Column + @NotNull + @NotBlank private String type; @ElementCollection @Lob + @Entries(key = @Items(notNull = {@NotNull}), value = @Items(notNull = {@NotNull})) private Map properties; // formatter:off @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true) @JoinColumns({@JoinColumn(name = "requirementsName", referencedColumnName = "name"), @JoinColumn(name = "requirementsVersion", referencedColumnName = "version")}) + @Valid private JpaToscaRequirements requirements; @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true) @JoinColumns({@JoinColumn(name = "capabilitiesName", referencedColumnName = "name"), @JoinColumn(name = "capabilitiesVersion", referencedColumnName = "version")}) + @Valid private JpaToscaCapabilityAssignments capabilities; // @formatter:on @@ -229,19 +237,6 @@ public class JpaToscaNodeTemplate extends JpaToscaEntityType } } - @Override - public BeanValidationResult validate(String fieldName) { - BeanValidationResult result = super.validate(fieldName); - - result.addResult(validateNotBlank("type", type, true)); - - validateMap(result, "properties", properties, Validated::validateEntryValueNotNull); - validateOptional(result, "requirements", requirements); - validateOptional(result, "capabilities", capabilities); - - return result; - } - @Override public int compareTo(final PfConcept otherConcept) { if (otherConcept == null) { diff --git a/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaNodeType.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaNodeType.java index f39f9b914..0965d8b44 100644 --- a/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaNodeType.java +++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaNodeType.java @@ -45,13 +45,16 @@ import lombok.NonNull; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.ObjectUtils; import org.onap.policy.common.parameters.BeanValidationResult; +import org.onap.policy.common.parameters.annotations.Entries; +import org.onap.policy.common.parameters.annotations.Items; +import org.onap.policy.common.parameters.annotations.NotNull; +import org.onap.policy.common.parameters.annotations.Valid; 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.PfReferenceKey; import org.onap.policy.models.base.PfUtils; -import org.onap.policy.models.base.Validated; import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeType; import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty; import org.onap.policy.models.tosca.utils.ToscaUtils; @@ -70,6 +73,7 @@ public class JpaToscaNodeType extends JpaToscaEntityType implemen @ElementCollection @Lob + @Entries(key = @Items(notNull = {@NotNull}), value = @Items(notNull = {@NotNull}, valid = {@Valid})) private Map properties; @@ -78,6 +82,7 @@ public class JpaToscaNodeType extends JpaToscaEntityType implemen @JoinColumns({@JoinColumn(name = "requirementsName", referencedColumnName = "name"), @JoinColumn(name = "requirementsVersion", referencedColumnName = "version")}) // @formatter:on + @Valid private JpaToscaRequirements requirements; /** @@ -190,9 +195,6 @@ public class JpaToscaNodeType extends JpaToscaEntityType implemen result.addResult(validateKeyVersionNotNull("key", getKey())); - validateMap(result, "properties", properties, Validated::validateEntryValueNotNull); - validateOptional(result, "requirements", requirements); - return result; } diff --git a/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaParameter.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaParameter.java index 19e0e5fd5..0348bb1d4 100644 --- a/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaParameter.java +++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaParameter.java @@ -32,13 +32,14 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NonNull; import org.apache.commons.lang3.StringUtils; -import org.onap.policy.common.parameters.BeanValidationResult; +import org.onap.policy.common.parameters.annotations.NotNull; import org.onap.policy.common.utils.coder.YamlJsonTranslator; 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.PfReferenceKey; +import org.onap.policy.models.base.validation.annotations.VerifyKey; import org.onap.policy.models.tosca.authorative.concepts.ToscaParameter; /** @@ -53,9 +54,13 @@ public class JpaToscaParameter extends PfConcept implements PfAuthorative implements P @AttributeOverride(name = "version", column = @Column(name = "type_version")) }) + @VerifyKey + @NotNull private PfConceptKey type; @ElementCollection @Lob + @Entries(key = @Items(notNull = {@NotNull}, notBlank = {@NotBlank}), value = @Items(notNull = {@NotNull})) private Map properties; @ElementCollection + @Items(notNull = {@NotNull}, valid = {@Valid}) private List targets; // @formatter:on @@ -235,10 +244,6 @@ public class JpaToscaPolicy extends JpaToscaEntityType implements P BeanValidationResult result = super.validate(fieldName); result.addResult(validateKeyVersionNotNull("key", getKey())); - result.addResult(validateKeyNotNull("type", type)); - - validateMap(result, "properties", properties, Validated::validateEntryNotBlankNotNull); - validateList(result, "targets", targets, Validated::validateNotNull); return result; } diff --git a/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaPolicyType.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaPolicyType.java index 665c79d1f..07850f9de 100644 --- a/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaPolicyType.java +++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaPolicyType.java @@ -41,13 +41,16 @@ import lombok.EqualsAndHashCode; import lombok.NonNull; import org.apache.commons.collections4.CollectionUtils; import org.onap.policy.common.parameters.BeanValidationResult; +import org.onap.policy.common.parameters.annotations.Entries; +import org.onap.policy.common.parameters.annotations.Items; +import org.onap.policy.common.parameters.annotations.NotNull; +import org.onap.policy.common.parameters.annotations.Valid; 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.PfReferenceKey; import org.onap.policy.models.base.PfUtils; -import org.onap.policy.models.base.Validated; import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyType; import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty; import org.onap.policy.models.tosca.utils.ToscaUtils; @@ -69,12 +72,15 @@ public class JpaToscaPolicyType extends JpaToscaEntityType impl @ElementCollection @Lob + @Entries(key = @Items(notNull = {@NotNull}), value = @Items(notNull = {@NotNull}, valid = {@Valid})) private Map properties; @ElementCollection + @Items(notNull = {@NotNull}, valid = {@Valid}) private List targets; @ElementCollection + @Items(notNull = {@NotNull}, valid = {@Valid}) private List triggers; /** @@ -192,10 +198,6 @@ public class JpaToscaPolicyType extends JpaToscaEntityType impl result.addResult(validateKeyVersionNotNull("key", getKey())); - validateMap(result, "properties", properties, Validated::validateEntryValueNotNull); - validateList(result, "targets", targets, Validated::validateNotNull); - validateList(result, "triggers", triggers, Validated::validateNotNull); - return result; } diff --git a/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaProperty.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaProperty.java index a7156bbab..711fcd2cb 100644 --- a/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaProperty.java +++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaProperty.java @@ -38,7 +38,10 @@ 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.annotations.Items; +import org.onap.policy.common.parameters.annotations.NotBlank; +import org.onap.policy.common.parameters.annotations.NotNull; +import org.onap.policy.common.parameters.annotations.Valid; import org.onap.policy.common.utils.coder.YamlJsonTranslator; import org.onap.policy.models.base.PfAuthorative; import org.onap.policy.models.base.PfConcept; @@ -46,7 +49,7 @@ import org.onap.policy.models.base.PfConceptKey; import org.onap.policy.models.base.PfKey; import org.onap.policy.models.base.PfReferenceKey; import org.onap.policy.models.base.PfUtils; -import org.onap.policy.models.base.Validated; +import org.onap.policy.models.base.validation.annotations.VerifyKey; import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty; import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty.Status; @@ -65,27 +68,35 @@ public class JpaToscaProperty extends PfConcept implements PfAuthorative constraints; @Column + @Valid private JpaToscaSchemaDefinition entrySchema; @ElementCollection @@ -239,21 +250,6 @@ public class JpaToscaProperty extends PfConcept implements PfAuthorative properties; /** @@ -158,8 +162,6 @@ public class JpaToscaRelationshipType extends JpaToscaEntityType private String relationship; @ElementCollection + @PfItems(notNull = {@NotNull}, pfMin = {@PfMin(value = 0, allowed = -1)}) private List occurrences; @ElementCollection @Lob + @Entries(key = @Items(notNull = {@NotNull}), value = @Items(notNull = {@NotNull})) private Map properties; /** @@ -195,16 +200,6 @@ public class JpaToscaRequirement extends JpaToscaEntityType properties = PfUtils.mapMap(properties, String::trim); } - @Override - public BeanValidationResult validate(String fieldName) { - BeanValidationResult result = super.validate(fieldName); - - validateMap(result, "properties", properties, Validated::validateEntryValueNotNull); - validateList(result, "occurrences", occurrences, validateMin(0, JPA_UNBOUNDED_VALUE, true)); - - return result; - } - @Override public int compareTo(final PfConcept otherConcept) { if (otherConcept == null) { diff --git a/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaSchemaDefinition.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaSchemaDefinition.java index bae36299a..1651d1a93 100644 --- a/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaSchemaDefinition.java +++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaSchemaDefinition.java @@ -33,13 +33,17 @@ import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.NonNull; import org.apache.commons.lang3.ObjectUtils; -import org.onap.policy.common.parameters.BeanValidationResult; +import org.onap.policy.common.parameters.annotations.Items; +import org.onap.policy.common.parameters.annotations.NotBlank; +import org.onap.policy.common.parameters.annotations.NotNull; +import org.onap.policy.common.parameters.annotations.Valid; import org.onap.policy.common.utils.validation.Assertions; import org.onap.policy.models.base.PfAuthorative; import org.onap.policy.models.base.PfConceptKey; import org.onap.policy.models.base.PfKey; import org.onap.policy.models.base.PfUtils; import org.onap.policy.models.base.Validated; +import org.onap.policy.models.base.validation.annotations.VerifyKey; import org.onap.policy.models.tosca.authorative.concepts.ToscaConstraint; import org.onap.policy.models.tosca.authorative.concepts.ToscaSchemaDefinition; @@ -58,12 +62,16 @@ public class JpaToscaSchemaDefinition extends Validated private static final long serialVersionUID = 3645882081163287058L; @Column + @VerifyKey + @NotNull private PfConceptKey type; @Column + @NotBlank private String description; @ElementCollection + @Items(notNull = {@NotNull}, valid = {@Valid}) private List constraints; /** @@ -143,18 +151,6 @@ public class JpaToscaSchemaDefinition extends Validated description = (description != null ? description.trim() : null); } - @Override - public BeanValidationResult validate(@NonNull String fieldName) { - BeanValidationResult result = new BeanValidationResult(fieldName, this); - - result.addResult(validateKeyNotNull("type", type)); - result.addResult(validateNotBlank("description", description, false)); - - validateList(result, "constraints", constraints, Validated::validateNotNull); - - return result; - } - @Override public int compareTo(final JpaToscaSchemaDefinition other) { if (other == null) { diff --git a/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaServiceTemplate.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaServiceTemplate.java index d4e51840b..c0a5cdf75 100644 --- a/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaServiceTemplate.java +++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaServiceTemplate.java @@ -42,6 +42,9 @@ 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.annotations.NotBlank; +import org.onap.policy.common.parameters.annotations.NotNull; +import org.onap.policy.common.parameters.annotations.Valid; import org.onap.policy.models.base.PfAuthorative; import org.onap.policy.models.base.PfConcept; import org.onap.policy.models.base.PfConceptKey; @@ -76,6 +79,8 @@ public class JpaToscaServiceTemplate extends JpaToscaEntityType inputs; @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true) @@ -89,6 +97,7 @@ public class JpaToscaTopologyTemplate extends PfConcept implements PfAuthorative } ) @SerializedName("data_types") + @Valid private JpaToscaNodeTemplates nodeTemplates; @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true) @@ -99,6 +108,7 @@ public class JpaToscaTopologyTemplate extends PfConcept implements PfAuthorative } ) // @formatter:on + @Valid private JpaToscaPolicies policies; /** @@ -239,21 +249,6 @@ public class JpaToscaTopologyTemplate extends PfConcept implements PfAuthorative } } - @Override - public BeanValidationResult validate(@NonNull String fieldName) { - BeanValidationResult result = new BeanValidationResult(fieldName, this); - - result.addResult(validateKeyNotNull("key", key)); - result.addResult(validateNotBlank("description", description, false)); - - validateMap(result, "inputs", inputs, Validated::validateEntryValueNotNull); - - validateOptional(result, "nodeTemplates", nodeTemplates); - validateOptional(result, "policies", policies); - - return result; - } - @Override public int compareTo(final PfConcept otherConcept) { int result = compareToWithoutEntities(otherConcept); diff --git a/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaTrigger.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaTrigger.java index e30754007..677354d8a 100644 --- a/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaTrigger.java +++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaTrigger.java @@ -36,10 +36,14 @@ 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.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; import org.onap.policy.models.base.PfConcept; import org.onap.policy.models.base.PfKey; import org.onap.policy.models.base.PfReferenceKey; +import org.onap.policy.models.base.validation.annotations.VerifyKey; /** * Class to represent the trigger of policy type in TOSCA definition. @@ -56,27 +60,36 @@ public class JpaToscaTrigger extends PfConcept { private static final long serialVersionUID = -6515211640208986971L; @EmbeddedId + @VerifyKey + @NotNull private PfReferenceKey key; @Column + @NotBlank private String description; @Column @SerializedName("event_type") + @NotNull + @NotBlank private String eventType; @Column @SerializedName("schedule") + @Valid private JpaToscaTimeInterval schedule; @Column @SerializedName("target_filter") + @Valid private JpaToscaEventFilter targetFilter; @Column + @Valid private JpaToscaConstraint condition; @Column + @Valid private JpaToscaConstraint constraint; @Column @@ -84,12 +97,16 @@ public class JpaToscaTrigger extends PfConcept { private Duration period; @Column + @Min(0) private int evaluations = 0; @Column + @NotBlank private String method; @Column + @NotNull + @NotBlank private String action; /** @@ -173,28 +190,6 @@ public class JpaToscaTrigger extends PfConcept { action = action.trim(); } - @Override - public BeanValidationResult validate(@NonNull String fieldName) { - BeanValidationResult result = new BeanValidationResult(fieldName, this); - - result.addResult(validateKeyNotNull("key", key)); - - result.addResult(validateNotBlank("description", description, false)); - result.addResult(validateNotBlank("eventType", eventType, true)); - - validateOptional(result, "schedule", schedule); - validateOptional(result, "targetFilter", targetFilter); - - if (evaluations < 0) { - addResult(result, "evaluations", evaluations, "is negative"); - } - - result.addResult(validateNotBlank("method", method, false)); - result.addResult(validateNotBlank("action", action, true)); - - return result; - } - @Override public int compareTo(final PfConcept otherConcept) { if (otherConcept == null) { diff --git a/models-tosca/src/test/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaServiceTemplateTest.java b/models-tosca/src/test/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaServiceTemplateTest.java index d6266b49a..8f366b321 100644 --- a/models-tosca/src/test/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaServiceTemplateTest.java +++ b/models-tosca/src/test/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaServiceTemplateTest.java @@ -141,7 +141,7 @@ public class JpaToscaServiceTemplateTest { tst.setToscaDefinitionsVersion(null); BeanValidationResult result = tst.validate(""); - assertThat(result.getResult()).contains("toscaDefinitionsVersion").contains(Validated.IS_BLANK); + assertThat(result.getResult()).contains("toscaDefinitionsVersion").contains(Validated.IS_NULL); tst.setToscaDefinitionsVersion(JpaToscaServiceTemplate.DEFAULT_TOSCA_DEFINTIONS_VERISON); tst.setDataTypes(null); -- 2.16.6