Add basic model object concepts 86/79186/9
authorliamfallon <liam.fallon@est.tech>
Tue, 26 Feb 2019 13:57:39 +0000 (13:57 +0000)
committerliamfallon <liam.fallon@est.tech>
Thu, 28 Feb 2019 10:32:01 +0000 (10:32 +0000)
This review introduces the basic concepts that all model objects
inherit from. Using this approach, all concepts that inherit from
these types can use standardized DAO handling and marrshal/unmarshal
handling

This approach is a more generic version of the approach used in the
APEX PDP for model handling. The APEX model handling will inherit this
module.

Issue-ID: POLICY-1264
Change-Id: I35b76659ab66cf3f33bee59a5528e49c7edf7796
Signed-off-by: liamfallon <liam.fallon@est.tech>
17 files changed:
INFO.yaml
models-base/pom.xml [new file with mode: 0644]
models-base/src/main/java/org/onap/policy/models/base/PfConcept.java [new file with mode: 0644]
models-base/src/main/java/org/onap/policy/models/base/PfConceptKey.java [new file with mode: 0644]
models-base/src/main/java/org/onap/policy/models/base/PfKey.java [new file with mode: 0644]
models-base/src/main/java/org/onap/policy/models/base/PfModelException.java [new file with mode: 0644]
models-base/src/main/java/org/onap/policy/models/base/PfModelRuntimeException.java [new file with mode: 0644]
models-base/src/main/java/org/onap/policy/models/base/PfValidationMessage.java [new file with mode: 0644]
models-base/src/main/java/org/onap/policy/models/base/PfValidationResult.java [new file with mode: 0644]
models-base/src/main/java/org/onap/policy/models/base/package-info.java [new file with mode: 0644]
models-base/src/test/java/org/onap/policy/models/base/ExceptionsTest.java [new file with mode: 0644]
models-base/src/test/java/org/onap/policy/models/base/PfKeyTest.java [new file with mode: 0644]
models-base/src/test/java/org/onap/policy/models/base/ValidationTest.java [new file with mode: 0644]
models-base/src/test/java/org/onap/policy/models/base/testpojos/DummyPfConcept.java [new file with mode: 0644]
models-base/src/test/java/org/onap/policy/models/base/testpojos/DummyPfKey.java [new file with mode: 0644]
models-dao/pom.xml [new file with mode: 0644]
pom.xml

index 500e2fd..7e56338 100644 (file)
--- a/INFO.yaml
+++ b/INFO.yaml
@@ -29,7 +29,7 @@ committers:
       id: 'jhh'
       timezone: 'America/Illinois'
     - name: 'Liam Fallon'
-      email: 'liam.fallon@ericsson.com'
+      email: 'liam.fallon@est.tech'
       company: 'Ericsson'
       id: 'liamfallon'
       timezone: 'Europe/Ireland'
diff --git a/models-base/pom.xml b/models-base/pom.xml
new file mode 100644 (file)
index 0000000..d2f8d87
--- /dev/null
@@ -0,0 +1,45 @@
+<!--
+  ============LICENSE_START=======================================================
+   Copyright (C) 2019 Nordix Foundation.
+  ================================================================================
+  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.
+
+  SPDX-License-Identifier: Apache-2.0
+  ============LICENSE_END=========================================================
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.onap.policy.models</groupId>
+        <artifactId>policy-models</artifactId>
+        <version>2.0.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>policy-models-base</artifactId>
+    <name>${project.artifactId}</name>
+    <description>[${project.parent.artifactId}] module provides basic model handling for the ONAP Policy Framework</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.onap.policy.common</groupId>
+            <artifactId>utils</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfConcept.java b/models-base/src/main/java/org/onap/policy/models/base/PfConcept.java
new file mode 100644 (file)
index 0000000..99eee8d
--- /dev/null
@@ -0,0 +1,139 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.models.base;
+
+import java.io.Serializable;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlType;
+
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * This class is the base class for all model concept classes. It enforces implementation of
+ * abstract methods and interfaces on all concepts that are sub-classes of this class.
+ */
+
+@XmlType(name = "PfConcept", namespace = "http://www.onap.org/policy/models")
+
+public abstract class PfConcept implements Serializable, Comparable<PfConcept> {
+    private static final long serialVersionUID = -7434939557282697490L;
+
+    /**
+     * Default constructor.
+     */
+    public PfConcept() {}
+
+    /**
+     * Copy constructor.
+     *
+     * @param copyConcept the concept to copy from
+     */
+    public PfConcept(final PfConcept copyConcept) {
+        Assertions.argumentNotNull(copyConcept, "copy concept may not be null");
+        copyConcept.copyTo(this);
+    }
+
+    /**
+     * Gets the key of this concept.
+     *
+     * @return the concept key
+     */
+    public abstract PfKey getKey();
+
+    /**
+     * Gets a list of all keys for this concept and all concepts that are defined or referenced by
+     * this concept and its sub-concepts.
+     *
+     * @return the keys used by this concept and it's contained concepts
+     */
+    public abstract List<PfKey> getKeys();
+
+    /**
+     * Validate that this concept is structurally correct.
+     *
+     * @param result the parameter in which the result of the validation will be returned
+     * @return the validation result that was passed in in the @{link result} field with the result
+     *         of this validation added
+     */
+    public abstract PfValidationResult validate(PfValidationResult result);
+
+    /**
+     * Clean this concept, tidy up any superfluous information such as leading and trailing white
+     * space.
+     */
+    public abstract void clean();
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public abstract boolean equals(Object otherObject);
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public abstract String toString();
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public abstract int hashCode();
+
+    /**
+     * Copy this concept to another object. The target object must have the same class as the source
+     * object.
+     *
+     * @param target the target object to which this object is copied
+     * @return the copied object
+     */
+    public abstract PfConcept copyTo(PfConcept target);
+
+    /**
+     * Gets the ID string of this concept.
+     *
+     * @return the ID string of this concept
+     */
+    public String getId() {
+        return getKey().getId();
+    }
+
+    /**
+     * Checks if this key matches the given key ID.
+     *
+     * @param id the key ID to match against
+     * @return true, if this key matches the ID
+     */
+    public final boolean matchesId(final String id) {
+        Assertions.argumentNotNull(id, "id may not be null");
+
+        // Check the ID
+        return getId().equals(id);
+    }
+}
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
new file mode 100644 (file)
index 0000000..6ebb888
--- /dev/null
@@ -0,0 +1,317 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.models.base;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.Column;
+import javax.persistence.Embeddable;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+import org.onap.policy.common.utils.validation.Assertions;
+import org.onap.policy.models.base.PfValidationResult.ValidationResult;
+
+/**
+ * An artifact key uniquely identifies every first order entity in the system. Every first order
+ * concept in the system must have an {@link PfConceptKey} to identify it. Concepts that are wholly
+ * contained in another concept are identified using a {@link AxReferenceKey} key.
+ *
+ * <p>Key validation checks that the name and version fields match the NAME_REGEXP and VERSION_REGEXP
+ * regular expressions respectively.
+ */
+@Embeddable
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlRootElement(name = "pfConceptKey", namespace = "http://www.onap.org/policy/models")
+
+@XmlType(name = "PfConceptKey", namespace = "http://www.onap.org/policy/models", propOrder = {"name", "version"})
+
+public class PfConceptKey extends PfKey {
+    private static final long serialVersionUID = 8932717618579392561L;
+
+    private static final String NAME_TOKEN = "name";
+    private static final String VERSION_TOKEN = "version";
+
+    @Column(name = NAME_TOKEN)
+    @XmlElement(required = true)
+    private String name;
+
+    @Column(name = VERSION_TOKEN)
+    @XmlElement(required = true)
+    private String version;
+
+    /**
+     * The default constructor creates a null artifact key.
+     */
+    public PfConceptKey() {
+        this(NULL_KEY_NAME, NULL_KEY_VERSION);
+    }
+
+    /**
+     * Copy constructor.
+     *
+     * @param copyConcept the concept to copy from
+     */
+    public PfConceptKey(final PfConceptKey copyConcept) {
+        super(copyConcept);
+    }
+
+    /**
+     * Constructor to create a key with the specified name and version.
+     *
+     * @param name the key name
+     * @param version the key version
+     */
+    public PfConceptKey(final String name, final String version) {
+        super();
+        this.name = Assertions.validateStringParameter(NAME_TOKEN, name, NAME_REGEXP);
+        this.version = Assertions.validateStringParameter(VERSION_TOKEN, version, VERSION_REGEXP);
+    }
+
+    /**
+     * Constructor to create a key using the key and version from the specified key ID.
+     *
+     * @param id the key ID in a format that respects the KEY_ID_REGEXP
+     */
+    public PfConceptKey(final String id) {
+        Assertions.argumentNotNull(id, "id may not be null");
+
+        // Check the incoming ID is valid
+        Assertions.validateStringParameter("id", id, KEY_ID_REGEXP);
+
+        // Split on colon, if the id passes the regular expression test above
+        // it'll have just one colon separating the name and version
+        // No need for range checks or size checks on the array
+        final String[] nameVersionArray = id.split(":");
+
+        // Return the new key
+        name = Assertions.validateStringParameter(NAME_TOKEN, nameVersionArray[0], NAME_REGEXP);
+        version = Assertions.validateStringParameter(VERSION_TOKEN, nameVersionArray[1], VERSION_REGEXP);
+    }
+
+    /**
+     * Get a null artifact key.
+     *
+     * @return a null artifact key
+     */
+    public static final PfConceptKey getNullKey() {
+        return new PfConceptKey(PfKey.NULL_KEY_NAME, PfKey.NULL_KEY_VERSION);
+    }
+
+    @Override
+    public PfConceptKey getKey() {
+        return this;
+    }
+
+    @Override
+    public List<PfKey> getKeys() {
+        final List<PfKey> keyList = new ArrayList<>();
+        keyList.add(getKey());
+        return keyList;
+    }
+
+    @Override
+    public String getId() {
+        return name + ':' + version;
+    }
+
+    /**
+     * Gets the key name.
+     *
+     * @return the key name
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Sets the key name.
+     *
+     * @param name the key name
+     */
+    public void setName(final String name) {
+        this.name = Assertions.validateStringParameter(NAME_TOKEN, name, NAME_REGEXP);
+    }
+
+    /**
+     * Gets the key version.
+     *
+     * @return the key version
+     */
+    public String getVersion() {
+        return version;
+    }
+
+    /**
+     * Sets the key version.
+     *
+     * @param version the key version
+     */
+    public void setVersion(final String version) {
+        this.version = Assertions.validateStringParameter(VERSION_TOKEN, version, VERSION_REGEXP);
+    }
+
+    @Override
+    public PfKey.Compatibility getCompatibility(final PfKey otherKey) {
+        if (!(otherKey instanceof PfConceptKey)) {
+            return Compatibility.DIFFERENT;
+        }
+        final PfConceptKey otherArtifactKey = (PfConceptKey) otherKey;
+
+        if (this.equals(otherArtifactKey)) {
+            return Compatibility.IDENTICAL;
+        }
+        if (!this.getName().equals(otherArtifactKey.getName())) {
+            return Compatibility.DIFFERENT;
+        }
+
+        final String[] thisVersionArray = getVersion().split("\\.");
+        final String[] otherVersionArray = otherArtifactKey.getVersion().split("\\.");
+
+        // There must always be at least one element in each version
+        if (!thisVersionArray[0].equals(otherVersionArray[0])) {
+            return Compatibility.MAJOR;
+        }
+
+        if (thisVersionArray.length >= 2 && otherVersionArray.length >= 2
+                && !thisVersionArray[1].equals(otherVersionArray[1])) {
+            return Compatibility.MINOR;
+        }
+
+        return Compatibility.PATCH;
+    }
+
+    @Override
+    public boolean isCompatible(final PfKey otherKey) {
+        if (!(otherKey instanceof PfConceptKey)) {
+            return false;
+        }
+        final PfConceptKey otherArtifactKey = (PfConceptKey) otherKey;
+
+        final Compatibility compatibility = this.getCompatibility(otherArtifactKey);
+
+        return !(compatibility == Compatibility.DIFFERENT || compatibility == Compatibility.MAJOR);
+    }
+
+    @Override
+    public PfValidationResult validate(final PfValidationResult result) {
+        final String nameValidationErrorMessage =
+                Assertions.getStringParameterValidationMessage(NAME_TOKEN, name, NAME_REGEXP);
+        if (nameValidationErrorMessage != null) {
+            result.addValidationMessage(new PfValidationMessage(this, this.getClass(), ValidationResult.INVALID,
+                    "name invalid-" + nameValidationErrorMessage));
+        }
+
+        final String versionValidationErrorMessage =
+                Assertions.getStringParameterValidationMessage(VERSION_TOKEN, version, VERSION_REGEXP);
+        if (versionValidationErrorMessage != null) {
+            result.addValidationMessage(new PfValidationMessage(this, this.getClass(), ValidationResult.INVALID,
+                    "version invalid-" + versionValidationErrorMessage));
+        }
+
+        return result;
+    }
+
+    @Override
+    public void clean() {
+        name = Assertions.validateStringParameter(NAME_TOKEN, name, NAME_REGEXP);
+        version = Assertions.validateStringParameter(VERSION_TOKEN, version, VERSION_REGEXP);
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder builder = new StringBuilder();
+        builder.append(this.getClass().getSimpleName());
+        builder.append(":(");
+        builder.append("name=");
+        builder.append(name);
+        builder.append(",version=");
+        builder.append(version);
+        builder.append(")");
+        return builder.toString();
+    }
+
+    @Override
+    public PfConcept copyTo(final PfConcept target) {
+        Assertions.argumentNotNull(target, "target may not be null");
+
+        final PfConcept copyObject = target;
+        Assertions.instanceOf(copyObject, PfConceptKey.class);
+
+        final PfConceptKey copy = ((PfConceptKey) copyObject);
+        copy.setName(name);
+        copy.setVersion(version);
+
+        return copyObject;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + name.hashCode();
+        result = prime * result + version.hashCode();
+        return result;
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (this == obj) {
+            return true;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+
+        final PfConceptKey other = (PfConceptKey) obj;
+
+        if (!name.equals(other.name)) {
+            return false;
+        }
+        return version.equals(other.version);
+    }
+
+    @Override
+    public int compareTo(final PfConcept otherObj) {
+        Assertions.argumentNotNull(otherObj, "comparison object may not be null");
+
+        if (this == otherObj) {
+            return 0;
+        }
+        if (getClass() != otherObj.getClass()) {
+            return this.hashCode() - otherObj.hashCode();
+        }
+
+        final PfConceptKey other = (PfConceptKey) otherObj;
+
+        if (!name.equals(other.name)) {
+            return name.compareTo(other.name);
+        }
+        return version.compareTo(other.version);
+    }
+}
diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfKey.java b/models-base/src/main/java/org/onap/policy/models/base/PfKey.java
new file mode 100644 (file)
index 0000000..16e70a2
--- /dev/null
@@ -0,0 +1,105 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.models.base;
+
+/**
+ * The key uniquely identifies every entity in the system. This class is an abstract class to give a
+ * common parent for all key types in the system.
+ */
+public abstract class PfKey extends PfConcept {
+    private static final long serialVersionUID = 6281159885962014041L;
+
+    /** Regular expression to specify the structure of key names. */
+    public static final String NAME_REGEXP = "[A-Za-z0-9\\-_\\.]+";
+
+    /** Regular expression to specify the structure of key versions. */
+    public static final String VERSION_REGEXP = "[A-Za-z0-9.]+";
+
+    /** Regular expression to specify the structure of key IDs. */
+    public static final String KEY_ID_REGEXP = "[A-Za-z0-9\\-_\\.]+:[0-9].[0-9].[0-9]";
+
+    /** Specifies the value for names in NULL keys. */
+    public static final String NULL_KEY_NAME = "NULL";
+
+    /** Specifies the value for versions in NULL keys. */
+    public static final String NULL_KEY_VERSION = "0.0.0";
+
+    /**
+     * This enumeration is returned on key compatibility checks.
+     */
+    public enum Compatibility {
+        /** The keys have different names. */
+        DIFFERENT,
+        /**
+         * The name of the key matches but the Major version number of the keys is different (x in
+         * x.y.z do not match).
+         */
+        MAJOR,
+        /**
+         * The name of the key matches but the Minor version number of the keys is different (y in
+         * x.y.z do not match).
+         */
+        MINOR,
+        /**
+         * The name of the key matches but the Patch version number of the keys is different (z in
+         * x.y.z do not match).
+         */
+        PATCH,
+        /** The keys match completely. */
+        IDENTICAL
+    }
+
+    /**
+     * Default constructor.
+     */
+    public PfKey() {
+        super();
+    }
+
+    /**
+     * Copy constructor.
+     *
+     * @param copyConcept the concept to copy from
+     */
+    public PfKey(final PfKey copyConcept) {
+        super(copyConcept);
+    }
+
+    @Override
+    public abstract String getId();
+
+    /**
+     * Return the result of a compatibility check of two keys.
+     *
+     * @param otherKey the key to check compatibility against
+     * @return the compatibility result of the check
+     */
+    public abstract Compatibility getCompatibility(PfKey otherKey);
+
+    /**
+     * Check if two keys are compatible, that is the keys are IDENTICAL or have only MINOR, PATCH
+     * differences.
+     *
+     * @param otherKey the key to check compatibility against
+     * @return true, if the keys are compatible
+     */
+    public abstract boolean isCompatible(PfKey otherKey);
+}
diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfModelException.java b/models-base/src/main/java/org/onap/policy/models/base/PfModelException.java
new file mode 100644 (file)
index 0000000..3d1bb17
--- /dev/null
@@ -0,0 +1,109 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.models.base;
+
+/**
+ * This class is a base exception from which all model exceptions are sub classes.
+ */
+public class PfModelException extends Exception {
+    private static final long serialVersionUID = -8507246953751956974L;
+
+    // The object on which the exception was thrown
+    private final transient Object object;
+
+    /**
+     * Instantiates a new model exception.
+     *
+     * @param message the message on the exception
+     */
+    public PfModelException(final String message) {
+        this(message, null);
+    }
+
+    /**
+     * Instantiates a new model exception.
+     *
+     * @param message the message on the exception
+     * @param object the object that the exception was thrown on
+     */
+    public PfModelException(final String message, final Object object) {
+        super(message);
+        this.object = object;
+    }
+
+    /**
+     * Instantiates a new model exception.
+     *
+     * @param message the message on the exception
+     * @param exception the exception that caused this exception
+     */
+    public PfModelException(final String message, final Exception exception) {
+        this(message, exception, null);
+    }
+
+    /**
+     * Instantiates a new exception.
+     *
+     * @param message the message on the exception
+     * @param exception the exception that caused this exception
+     * @param object the object that the exception was thrown on
+     */
+    public PfModelException(final String message, final Exception exception, final Object object) {
+        super(message, exception);
+        this.object = object;
+    }
+
+    /**
+     * Get the message from this exception and its causes.
+     *
+     * @return the cascaded messages from this exception and the exceptions that caused it
+     */
+    public String getCascadedMessage() {
+        return buildCascadedMessage(this);
+    }
+
+    /**
+     * Build a cascaded message from an exception and all its nested exceptions.
+     *
+     * @param throwable the top level exception
+     * @return cascaded message string
+     */
+    public static String buildCascadedMessage(Throwable throwable) {
+        final StringBuilder builder = new StringBuilder();
+        builder.append(throwable.getMessage());
+
+        for (Throwable t = throwable; t != null; t = t.getCause()) {
+            builder.append("\ncaused by: ");
+            builder.append(t.getMessage());
+        }
+
+        return builder.toString();
+    }
+
+    /**
+     * Get the object on which the exception was thrown.
+     *
+     * @return The object on which the exception was thrown
+     */
+    public Object getObject() {
+        return object;
+    }
+}
diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfModelRuntimeException.java b/models-base/src/main/java/org/onap/policy/models/base/PfModelRuntimeException.java
new file mode 100644 (file)
index 0000000..0780a9e
--- /dev/null
@@ -0,0 +1,92 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.models.base;
+
+/**
+ * This class is a base model run time exception from which all model run time exceptions are sub
+ * classes.
+ */
+public class PfModelRuntimeException extends RuntimeException {
+    private static final long serialVersionUID = -8507246953751956974L;
+
+    // The object on which the exception was thrown
+    private final transient Object object;
+
+    /**
+     * Instantiates a new model runtime exception.
+     *
+     * @param message the message on the exception
+     */
+    public PfModelRuntimeException(final String message) {
+        this(message, null);
+    }
+
+    /**
+     * Instantiates a new model runtime exception.
+     *
+     * @param message the message on the exception
+     * @param object the object that the exception was thrown on
+     */
+    public PfModelRuntimeException(final String message, final Object object) {
+        super(message);
+        this.object = object;
+    }
+
+    /**
+     * Instantiates a new model runtime exception.
+     *
+     * @param message the message on the exception
+     * @param exception the exception that caused this model exception
+     */
+    public PfModelRuntimeException(final String message, final Exception exception) {
+        this(message, exception, null);
+    }
+
+    /**
+     * Instantiates a new model runtime exception.
+     *
+     * @param message the message on the exception
+     * @param exception the exception that caused this model exception
+     * @param object the object that the exception was thrown on
+     */
+    public PfModelRuntimeException(final String message, final Exception exception, final Object object) {
+        super(message, exception);
+        this.object = object;
+    }
+
+    /**
+     * Get the message from this exception and its causes.
+     *
+     * @return the message of this exception and all the exceptions that caused this exception
+     */
+    public String getCascadedMessage() {
+        return PfModelException.buildCascadedMessage(this);
+    }
+
+    /**
+     * Get the object on which the exception was thrown.
+     *
+     * @return The object
+     */
+    public Object getObject() {
+        return object;
+    }
+}
diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfValidationMessage.java b/models-base/src/main/java/org/onap/policy/models/base/PfValidationMessage.java
new file mode 100644 (file)
index 0000000..708bfdd
--- /dev/null
@@ -0,0 +1,103 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.models.base;
+
+import org.onap.policy.common.utils.validation.Assertions;
+import org.onap.policy.models.base.PfValidationResult.ValidationResult;
+
+/**
+ * A validation message is created for each validation observation observed during validation of a
+ * concept. The message holds the key and the class of the concept on which the observation was made
+ * as well as the type of observation and a message describing the observation.
+ */
+public class PfValidationMessage {
+    private final PfKey observedKey;
+    private ValidationResult validationResult = ValidationResult.VALID;
+    private final String observedClass;
+    private final String message;
+
+    /**
+     * Create an validation observation with the given fields.
+     *
+     * @param observedKey the key of the class on which the validation observation was made
+     * @param observedClass the class on which the validation observation was made
+     * @param validationResult the type of observation made
+     * @param message a message describing the observation
+     */
+    public PfValidationMessage(final PfKey observedKey, final Class<?> observedClass,
+            final ValidationResult validationResult, final String message) {
+        Assertions.argumentNotNull(observedKey, "observedKey may not be null");
+        Assertions.argumentNotNull(observedClass, "observedClass may not be null");
+        Assertions.argumentNotNull(validationResult, "validationResult may not be null");
+        Assertions.argumentNotNull(message, "message may not be null");
+
+        this.observedKey = observedKey;
+        this.observedClass = observedClass.getCanonicalName();
+        this.validationResult = validationResult;
+        this.message = message;
+    }
+
+    /**
+     * Gets the key of the observation.
+     *
+     * @return the key of the observation
+     */
+    public PfKey getObservedKey() {
+        return observedKey;
+    }
+
+    /**
+     * Gets the observed class.
+     *
+     * @return the observed class
+     */
+    public String getObservedClass() {
+        return observedClass;
+    }
+
+    /**
+     * Gets the type of observation made.
+     *
+     * @return the type of observation made
+     */
+    public ValidationResult getValidationResult() {
+        return validationResult;
+    }
+
+    /**
+     * Get a description of the observation.
+     *
+     * @return the observation description
+     */
+    public String getMessage() {
+        return message;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return observedKey.toString() + ':' + observedClass + ':' + validationResult.name() + ':' + message;
+    }
+}
diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfValidationResult.java b/models-base/src/main/java/org/onap/policy/models/base/PfValidationResult.java
new file mode 100644 (file)
index 0000000..284c11a
--- /dev/null
@@ -0,0 +1,151 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.models.base;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * This class records the result of a validation and holds all validatino observation messages.
+ */
+public class PfValidationResult {
+    /**
+     * The ValidationResult enumeration describes the severity of a validation result.
+     */
+    public enum ValidationResult {
+    /** No problems or observations were detected during validation. */
+    VALID,
+    /**
+     * Observations were made on a concept (such as blank descriptions) of a nature that will not
+     * affect the use of the concept.
+     */
+    OBSERVATION,
+    /**
+     * Warnings were made on a concept (such as defined but unused concepts) of a nature that may
+     * affect the use of the concept.
+     */
+    WARNING,
+    /**
+     * Errors were detected on a concept (such as referenced but undefined concepts) of a nature
+     * that will affect the use of the concept.
+     */
+    INVALID
+    }
+
+    // The actual verification result
+    private ValidationResult validationResult = ValidationResult.VALID;
+
+    // Messages collected during the verification process
+    private final List<PfValidationMessage> messageList = new LinkedList<>();
+
+    /**
+     * Check if a validation reported a valid concept, returns true if the model is usable (that is,
+     * even if the model has warnings or observations).
+     *
+     * @return true, if the concept is reported as valid and can be used
+     */
+    public boolean isValid() {
+        return validationResult != ValidationResult.INVALID;
+    }
+
+    /**
+     * Check if a validation reported a concept with no errors or warnings, returns true if the
+     * model is OK to use.
+     *
+     * @return true, if the concept has no warnings or errors
+     */
+    public boolean isOk() {
+        return validationResult == ValidationResult.VALID || validationResult == ValidationResult.OBSERVATION;
+    }
+
+    /**
+     * Gets the validation result.
+     *
+     * @return the validation result on a concept
+     */
+    public ValidationResult getValidationResult() {
+        return validationResult;
+    }
+
+    /**
+     * Gets the list of validation results on the concept.
+     *
+     * @return the list of validaiton results
+     */
+    public List<PfValidationMessage> getMessageList() {
+        return messageList;
+    }
+
+    /**
+     * Adds a validation message to the validation result, used by validate() implementations on
+     * {@link PfConcept} subclasses to report validaiton observations.
+     *
+     * @param validationMessage the validation message
+     */
+    public void addValidationMessage(final PfValidationMessage validationMessage) {
+        messageList.add(validationMessage);
+
+        // Check if the incoming message has a more sever status than the
+        // current one on the overall validation result,
+        // if so, the overall result goes to that level
+        if (validationMessage.getValidationResult().ordinal() > validationResult.ordinal()) {
+            validationResult = validationMessage.getValidationResult();
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        final StringBuilder builder = new StringBuilder();
+
+        switch (validationResult) {
+            case VALID:
+
+                builder.append("***validation of model successful***");
+                return builder.toString();
+            case OBSERVATION:
+
+                builder.append("\n***observations noted during validation of model***\n");
+                break;
+            case WARNING:
+
+                builder.append("\n***warnings issued during validation of model***\n");
+                break;
+            case INVALID:
+                builder.append("\n***validation of model failed***\n");
+                break;
+            default:
+                break;
+        }
+
+        for (final PfValidationMessage message : messageList) {
+            builder.append(message);
+            builder.append("\n");
+        }
+
+        builder.append("********************************");
+        return builder.toString();
+    }
+}
diff --git a/models-base/src/main/java/org/onap/policy/models/base/package-info.java b/models-base/src/main/java/org/onap/policy/models/base/package-info.java
new file mode 100644 (file)
index 0000000..a71dce6
--- /dev/null
@@ -0,0 +1,25 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ * Defines and implements the basic concepts for all models in the Policy Framework.
+ */
+
+package org.onap.policy.models.base;
diff --git a/models-base/src/test/java/org/onap/policy/models/base/ExceptionsTest.java b/models-base/src/test/java/org/onap/policy/models/base/ExceptionsTest.java
new file mode 100644 (file)
index 0000000..92e928e
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.models.base;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.IOException;
+
+import org.junit.Test;
+
+public class ExceptionsTest {
+
+    @Test
+    public void test() {
+        assertNotNull(new PfModelException("Message"));
+        assertNotNull(new PfModelException("Message", "String"));
+        assertNotNull(new PfModelException("Message", new IOException()));
+        assertNotNull(new PfModelException("Message", new IOException(), "String"));
+
+        String key = "A String";
+        PfModelException ae = new PfModelException("Message", new IOException("IO exception message"), key);
+        assertEquals("Message\ncaused by: Message\ncaused by: IO exception message", ae.getCascadedMessage());
+        assertEquals(key, ae.getObject());
+
+        assertNotNull(new PfModelRuntimeException("Message"));
+        assertNotNull(new PfModelRuntimeException("Message", "String"));
+        assertNotNull(new PfModelRuntimeException("Message", new IOException()));
+        assertNotNull(new PfModelRuntimeException("Message", new IOException(), "String"));
+
+        String rkey = "A String";
+        PfModelRuntimeException re = new PfModelRuntimeException("Runtime Message",
+                        new IOException("IO runtime exception message"), rkey);
+        assertEquals("Runtime Message\ncaused by: Runtime Message\ncaused by: IO runtime exception message",
+                        re.getCascadedMessage());
+        assertEquals(key, re.getObject());
+    }
+}
diff --git a/models-base/src/test/java/org/onap/policy/models/base/PfKeyTest.java b/models-base/src/test/java/org/onap/policy/models/base/PfKeyTest.java
new file mode 100644 (file)
index 0000000..dd28f33
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.models.base;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.lang.reflect.Field;
+
+import org.junit.Test;
+
+import org.onap.policy.models.base.PfKey.Compatibility;
+import org.onap.policy.models.base.testpojos.DummyPfConcept;
+import org.onap.policy.models.base.testpojos.DummyPfKey;
+
+public class PfKeyTest {
+
+    @Test
+    public void testArtifactKey() {
+        try {
+            new PfConceptKey("some bad key id");
+            fail("This test should throw an exception");
+        } catch (IllegalArgumentException e) {
+            assertEquals("parameter \"id\": value \"some bad key id\", "
+                            + "does not match regular expression \"[A-Za-z0-9\\-_\\.]+:[0-9].[0-9].[0-9]\"",
+                            e.getMessage());
+        }
+
+        PfConceptKey someKey0 = new PfConceptKey();
+        assertEquals(PfConceptKey.getNullKey(), someKey0);
+
+        PfConceptKey someKey1 = new PfConceptKey("name", "0.0.1");
+        PfConceptKey someKey2 = new PfConceptKey(someKey1);
+        PfConceptKey someKey3 = new PfConceptKey(someKey1.getId());
+        assertEquals(someKey1, someKey2);
+        assertEquals(someKey1, someKey3);
+
+        assertEquals(someKey2, someKey1.getKey());
+        assertEquals(1, someKey1.getKeys().size());
+
+        someKey0.setName("zero");
+        someKey0.setVersion("0.0.2");
+
+        someKey3.setVersion("0.0.2");
+
+        PfConceptKey someKey4 = new PfConceptKey(someKey1);
+        someKey4.setVersion("0.1.2");
+
+        PfConceptKey someKey5 = new PfConceptKey(someKey1);
+        someKey5.setVersion("1.2.2");
+
+        PfConceptKey someKey6 = new PfConceptKey(someKey1);
+        someKey6.setVersion("3");
+
+        assertEquals("name:0.1.2", someKey4.getId());
+
+        PfConcept pfc = new DummyPfConcept();
+        assertEquals(PfConceptKey.getNullKey().getId(), pfc.getId());
+        assertTrue(PfConceptKey.getNullKey().matchesId(pfc.getId()));
+
+        assertEquals(Compatibility.DIFFERENT, someKey0.getCompatibility(new DummyPfKey()));
+        assertEquals(Compatibility.DIFFERENT, someKey0.getCompatibility(someKey1));
+        assertEquals(Compatibility.IDENTICAL, someKey2.getCompatibility(someKey1));
+        assertEquals(Compatibility.PATCH, someKey3.getCompatibility(someKey1));
+        assertEquals(Compatibility.MINOR, someKey4.getCompatibility(someKey1));
+        assertEquals(Compatibility.MAJOR, someKey5.getCompatibility(someKey1));
+        assertEquals(Compatibility.MAJOR, someKey6.getCompatibility(someKey1));
+
+        assertTrue(someKey1.isCompatible(someKey2));
+        assertTrue(someKey1.isCompatible(someKey3));
+        assertTrue(someKey1.isCompatible(someKey4));
+        assertFalse(someKey1.isCompatible(someKey0));
+        assertFalse(someKey1.isCompatible(someKey5));
+        assertFalse(someKey1.isCompatible(new DummyPfKey()));
+
+        assertEquals(PfValidationResult.ValidationResult.VALID,
+                        someKey0.validate(new PfValidationResult()).getValidationResult());
+        assertEquals(PfValidationResult.ValidationResult.VALID,
+                        someKey1.validate(new PfValidationResult()).getValidationResult());
+        assertEquals(PfValidationResult.ValidationResult.VALID,
+                        someKey2.validate(new PfValidationResult()).getValidationResult());
+        assertEquals(PfValidationResult.ValidationResult.VALID,
+                        someKey3.validate(new PfValidationResult()).getValidationResult());
+        assertEquals(PfValidationResult.ValidationResult.VALID,
+                        someKey4.validate(new PfValidationResult()).getValidationResult());
+        assertEquals(PfValidationResult.ValidationResult.VALID,
+                        someKey5.validate(new PfValidationResult()).getValidationResult());
+        assertEquals(PfValidationResult.ValidationResult.VALID,
+                        someKey6.validate(new PfValidationResult()).getValidationResult());
+
+        someKey0.clean();
+        assertNotNull(someKey0.toString());
+
+        PfConceptKey someKey7 = new PfConceptKey(someKey1);
+        assertEquals(150332875, someKey7.hashCode());
+        assertEquals(0, someKey7.compareTo(someKey1));
+        assertEquals(-12, someKey7.compareTo(someKey0));
+
+        try {
+            someKey0.compareTo(null);
+        } catch (IllegalArgumentException e) {
+            assertEquals("comparison object may not be null", e.getMessage());
+        }
+
+        assertEquals(0, someKey0.compareTo(someKey0));
+        assertEquals(161539407, someKey0.compareTo(new DummyPfKey()));
+
+        assertFalse(someKey0.equals(null));
+        assertTrue(someKey0.equals(someKey0));
+        assertFalse(((PfKey) someKey0).equals(new DummyPfKey()));
+    }
+
+
+    @Test
+    public void testValidation() {
+        PfConceptKey testKey = new PfConceptKey("TheKey", "0.0.1");
+        assertEquals("TheKey:0.0.1", testKey.getId());
+
+        try {
+            Field nameField = testKey.getClass().getDeclaredField("name");
+            nameField.setAccessible(true);
+            nameField.set(testKey, "Key Name");
+            PfValidationResult validationResult = new PfValidationResult();
+            testKey.validate(validationResult);
+            nameField.set(testKey, "TheKey");
+            nameField.setAccessible(false);
+            assertEquals(
+                "name invalid-parameter name with value Key Name "
+                    + "does not match regular expression [A-Za-z0-9\\-_\\.]+",
+                validationResult.getMessageList().get(0).getMessage());
+        } catch (Exception validationException) {
+            fail("test should not throw an exception");
+        }
+
+        try {
+            Field versionField = testKey.getClass().getDeclaredField("version");
+            versionField.setAccessible(true);
+            versionField.set(testKey, "Key Version");
+            PfValidationResult validationResult = new PfValidationResult();
+            testKey.validate(validationResult);
+            versionField.set(testKey, "0.0.1");
+            versionField.setAccessible(false);
+            assertEquals(
+                "version invalid-parameter version with value Key Version "
+                    + "does not match regular expression [A-Za-z0-9.]+",
+                validationResult.getMessageList().get(0).getMessage());
+        } catch (Exception validationException) {
+            fail("test should not throw an exception");
+        }
+    }
+}
diff --git a/models-base/src/test/java/org/onap/policy/models/base/ValidationTest.java b/models-base/src/test/java/org/onap/policy/models/base/ValidationTest.java
new file mode 100644 (file)
index 0000000..385039c
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.models.base;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.onap.policy.models.base.PfValidationResult.ValidationResult;
+
+public class ValidationTest {
+
+    @Test
+    public void test() {
+        PfValidationResult result = new PfValidationResult();
+        PfConceptKey pfKeyey = new PfConceptKey("PK", "0.0.1");
+        result = pfKeyey.validate(result);
+
+        assertNotNull(result);
+        assertTrue(result.isOk());
+        assertTrue(result.isValid());
+        assertEquals(PfValidationResult.ValidationResult.VALID, result.getValidationResult());
+        assertNotNull(result.getMessageList());
+
+        PfValidationMessage vmess0 = new PfValidationMessage(PfConceptKey.getNullKey(), PfConceptKey.class,
+                        ValidationResult.VALID, "Some message");
+        result.addValidationMessage(vmess0);
+
+        assertTrue(result.isOk());
+        assertTrue(result.isValid());
+        assertEquals(PfValidationResult.ValidationResult.VALID, result.getValidationResult());
+        assertNotNull(result.getMessageList());
+        assertNotNull("hello", result.toString());
+
+        PfValidationMessage vmess1 = new PfValidationMessage(PfConceptKey.getNullKey(), PfConceptKey.class,
+                        ValidationResult.OBSERVATION, "Some message");
+        result.addValidationMessage(vmess1);
+
+        assertTrue(result.isOk());
+        assertTrue(result.isValid());
+        assertEquals(PfValidationResult.ValidationResult.OBSERVATION, result.getValidationResult());
+        assertNotNull(result.getMessageList());
+        assertNotNull("hello", result.toString());
+
+        PfValidationMessage vmess2 = new PfValidationMessage(PfConceptKey.getNullKey(), PfConceptKey.class,
+                        ValidationResult.WARNING, "Some message");
+        result.addValidationMessage(vmess2);
+
+        assertFalse(result.isOk());
+        assertTrue(result.isValid());
+        assertEquals(PfValidationResult.ValidationResult.WARNING, result.getValidationResult());
+        assertNotNull(result.getMessageList());
+        assertNotNull("hello", result.toString());
+
+        PfValidationMessage vmess3 = new PfValidationMessage(PfConceptKey.getNullKey(), PfConceptKey.class,
+                        ValidationResult.INVALID, "Some message");
+        result.addValidationMessage(vmess3);
+
+        assertFalse(result.isOk());
+        assertFalse(result.isValid());
+        assertEquals(PfValidationResult.ValidationResult.INVALID, result.getValidationResult());
+        assertNotNull(result.getMessageList());
+        assertNotNull("hello", result.toString());
+
+        assertEquals(PfValidationResult.ValidationResult.INVALID, result.getMessageList().get(3).getValidationResult());
+        assertEquals("Some message", result.getMessageList().get(3).getMessage());
+        assertEquals(PfConceptKey.class.getCanonicalName(), result.getMessageList().get(3).getObservedClass());
+        assertEquals(PfConceptKey.getNullKey(), result.getMessageList().get(3).getObservedKey());
+    }
+}
diff --git a/models-base/src/test/java/org/onap/policy/models/base/testpojos/DummyPfConcept.java b/models-base/src/test/java/org/onap/policy/models/base/testpojos/DummyPfConcept.java
new file mode 100644 (file)
index 0000000..85727f4
--- /dev/null
@@ -0,0 +1,76 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.models.base.testpojos;
+
+import java.util.List;
+
+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.PfValidationResult;
+
+public class DummyPfConcept extends PfConcept {
+    private static final long serialVersionUID = 1L;
+
+    @Override
+    public int compareTo(PfConcept concept) {
+        return 0;
+    }
+
+    @Override
+    public PfKey getKey() {
+        return new PfConceptKey();
+    }
+
+    @Override
+    public List<PfKey> getKeys() {
+        return null;
+    }
+
+    @Override
+    public PfValidationResult validate(PfValidationResult result) {
+        return null;
+    }
+
+    @Override
+    public void clean() {
+    }
+
+    @Override
+    public boolean equals(Object otherObject) {
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return null;
+    }
+
+    @Override
+    public int hashCode() {
+        return 0;
+    }
+
+    @Override
+    public PfConcept copyTo(PfConcept target) {
+        return null;
+    }
+}
diff --git a/models-base/src/test/java/org/onap/policy/models/base/testpojos/DummyPfKey.java b/models-base/src/test/java/org/onap/policy/models/base/testpojos/DummyPfKey.java
new file mode 100644 (file)
index 0000000..19358a1
--- /dev/null
@@ -0,0 +1,91 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.models.base.testpojos;
+
+import java.util.List;
+
+import org.onap.policy.models.base.PfConcept;
+import org.onap.policy.models.base.PfKey;
+import org.onap.policy.models.base.PfValidationResult;
+
+public class DummyPfKey  extends PfKey {
+    private static final long serialVersionUID = 1L;
+
+    @Override
+    public int compareTo(PfConcept arg0) {
+        return 0;
+    }
+
+    @Override
+    public String getId() {
+        return null;
+    }
+
+    @Override
+    public Compatibility getCompatibility(PfKey otherKey) {
+        return null;
+    }
+
+    @Override
+    public boolean isCompatible(PfKey otherKey) {
+        return false;
+    }
+
+    @Override
+    public PfKey getKey() {
+        return null;
+    }
+
+    @Override
+    public List<PfKey> getKeys() {
+        return null;
+    }
+
+    @Override
+    public PfValidationResult validate(PfValidationResult result) {
+        return null;
+    }
+
+    @Override
+    public void clean() {
+
+    }
+
+    @Override
+    public boolean equals(Object otherObject) {
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return null;
+    }
+
+    @Override
+    public int hashCode() {
+        return 0;
+    }
+
+    @Override
+    public PfConcept copyTo(PfConcept target) {
+        return null;
+    }
+}
diff --git a/models-dao/pom.xml b/models-dao/pom.xml
new file mode 100644 (file)
index 0000000..90b9801
--- /dev/null
@@ -0,0 +1,33 @@
+<!--
+  ============LICENSE_START=======================================================
+   Copyright (C) 2019 Nordix Foundation.
+  ================================================================================
+  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.
+
+  SPDX-License-Identifier: Apache-2.0
+  ============LICENSE_END=========================================================
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.onap.policy.models</groupId>
+        <artifactId>policy-models</artifactId>
+        <version>2.0.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>policy-models-dao</artifactId>
+    <name>${project.artifactId}</name>
+    <description>[${project.parent.artifactId}] module provides common DAO (Data Access Object) model handling for the ONAP Policy Framework</description>
+</project>
diff --git a/pom.xml b/pom.xml
index bb299c4..f337726 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -27,7 +27,6 @@
         <groupId>org.onap.policy.parent</groupId>
         <artifactId>integration</artifactId>
         <version>2.1.0-SNAPSHOT</version>
-        <relativePath />
     </parent>
 
     <groupId>org.onap.policy.models</groupId>
@@ -35,7 +34,6 @@
     <version>2.0.0-SNAPSHOT</version>
 
     <packaging>pom</packaging>
-
     <name>policy-models</name>
     <description>This repo holds model code agnostic to PDP engines</description>
 
@@ -51,6 +49,8 @@
 
     <modules>
         <module>platform</module>
+        <module>models-base</module>
+        <module>models-dao</module>
     </modules>
 
     <dependencies>
         </site>
     </distributionManagement>
 
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.onap.policy.common</groupId>
+                <artifactId>utils</artifactId>
+                <version>${policy.common.version}</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
     <build>
         <plugins>
             <plugin>