diff options
51 files changed, 3642 insertions, 253 deletions
diff --git a/.gitignore b/.gitignore index 7d310720a..21a4ea971 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ target .metadata/ /bin/ +bin/ .idea *.iml *.ipr diff --git a/models-base/pom.xml b/models-base/pom.xml index d2f8d87d4..712bc9108 100644 --- a/models-base/pom.xml +++ b/models-base/pom.xml @@ -30,16 +30,4 @@ <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 index 99eee8d7f..b74b0374d 100644 --- 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 @@ -23,17 +23,13 @@ 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. + * This class is the base class for all Policy Framework 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; @@ -63,7 +59,7 @@ public abstract class PfConcept implements Serializable, Comparable<PfConcept> { * 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 + * @return the keys used by this concept and its contained concepts */ public abstract List<PfKey> getKeys(); diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfConceptGetter.java b/models-base/src/main/java/org/onap/policy/models/base/PfConceptGetter.java new file mode 100644 index 000000000..b1b8984f9 --- /dev/null +++ b/models-base/src/main/java/org/onap/policy/models/base/PfConceptGetter.java @@ -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; + +import java.util.Set; + +/** + * This interface is used to allow get methods to be placed on concepts that have embedded maps. + * + * <p>It forces those concepts with maps to implement the get methods specified on this interface as convenience methods + * to avoid concept users having to use a second level of referencing to access concepts in the maps. + * + * @param <C> the type of concept on which the interface is applied. + */ +public interface PfConceptGetter<C> { + + /** + * Get the latest version for a concept with the given key. + * + * @param conceptKey The key of the concept + * @return The concept + */ + C get(PfConceptKey conceptKey); + + /** + * Get the latest version for a concept with the given key name. + * + * @param conceptKeyName The name of the concept + * @return The concept + */ + C get(String conceptKeyName); + + /** + * Get the latest version for a concept with the given key name and version. + * + * @param conceptKeyName The name of the concept + * @param conceptKeyVersion The version of the concept + * @return The concept + */ + C get(String conceptKeyName, String conceptKeyVersion); + + /** + * Get the all versions for a concept with the given key name. + * + * @param conceptKeyName The name of the concept + * @return The concepts + */ + Set<C> getAll(String conceptKeyName); + + /** + * Get the all versions for a concept with the given key name and starting version. + * + * @param conceptKeyName The name of the concept + * @param conceptKeyVersion The first version version of the concept to get + * @return The concepts + */ + Set<C> getAll(String conceptKeyName, String conceptKeyVersion); +} diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfConceptGetterImpl.java b/models-base/src/main/java/org/onap/policy/models/base/PfConceptGetterImpl.java new file mode 100644 index 000000000..f07713a1e --- /dev/null +++ b/models-base/src/main/java/org/onap/policy/models/base/PfConceptGetterImpl.java @@ -0,0 +1,129 @@ +/*- + * ============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.NavigableMap; +import java.util.Set; +import java.util.TreeSet; + +import org.onap.policy.common.utils.validation.Assertions; + +/** + * Implements concept getting from navigable maps. + * + * @param <C> the type of concept on which the interface implementation is applied. + */ +public class PfConceptGetterImpl<C> implements PfConceptGetter<C> { + + // The map from which to get concepts + private final NavigableMap<PfConceptKey, C> conceptMap; + + /** + * Constructor that sets the concept map on which the getter methods in the interface will operate.. + * + * @param conceptMap the concept map on which the method will operate + */ + public PfConceptGetterImpl(final NavigableMap<PfConceptKey, C> conceptMap) { + this.conceptMap = conceptMap; + } + + @Override + public C get(final PfConceptKey conceptKey) { + return conceptMap.get(conceptKey); + } + + @Override + public C get(final String conceptKeyName) { + Assertions.argumentNotNull(conceptKeyName, "conceptKeyName may not be null"); + + // The very fist key that could have this name + final PfConceptKey lowestArtifactKey = new PfConceptKey(conceptKeyName, "0.0.1"); + + // Check if we found a key for our name + PfConceptKey foundKey = conceptMap.ceilingKey(lowestArtifactKey); + if (foundKey == null || !foundKey.getName().equals(conceptKeyName)) { + return null; + } + + // Look for higher versions of the key + do { + final PfConceptKey nextkey = conceptMap.higherKey(foundKey); + if (nextkey == null || !nextkey.getName().equals(conceptKeyName)) { + break; + } + foundKey = nextkey; + } + while (true); + + return conceptMap.get(foundKey); + } + + @Override + public C get(final String conceptKeyName, final String conceptKeyVersion) { + Assertions.argumentNotNull(conceptKeyName, "conceptKeyName may not be null"); + + if (conceptKeyVersion != null) { + return conceptMap.get(new PfConceptKey(conceptKeyName, conceptKeyVersion)); + } else { + return this.get(conceptKeyName); + } + } + + @Override + public Set<C> getAll(final String conceptKeyName) { + return getAll(conceptKeyName, null); + } + + @Override + public Set<C> getAll(final String conceptKeyName, final String conceptKeyVersion) { + final Set<C> returnSet = new TreeSet<>(); + + if (conceptKeyName == null) { + returnSet.addAll(conceptMap.values()); + return returnSet; + } + + // The very fist key that could have this name + final PfConceptKey lowestArtifactKey = new PfConceptKey(conceptKeyName, "0.0.1"); + if (conceptKeyVersion != null) { + lowestArtifactKey.setVersion(conceptKeyVersion); + } + + // Check if we found a key for our name + PfConceptKey foundKey = conceptMap.ceilingKey(lowestArtifactKey); + if (foundKey == null || !foundKey.getName().equals(conceptKeyName)) { + return returnSet; + } + returnSet.add(conceptMap.get(foundKey)); + + // Look for higher versions of the key + do { + foundKey = conceptMap.higherKey(foundKey); + if (foundKey == null || !foundKey.getName().equals(conceptKeyName)) { + break; + } + returnSet.add(conceptMap.get(foundKey)); + } + while (true); + + return returnSet; + } +} 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 6ebb8886a..efcbe392c 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 @@ -25,29 +25,24 @@ 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 lombok.Data; +import lombok.EqualsAndHashCode; 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. + * An concept 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 PfReferenceKey} 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"}) - +@Data +@EqualsAndHashCode(callSuper = false) public class PfConceptKey extends PfKey { private static final long serialVersionUID = 8932717618579392561L; @@ -55,15 +50,13 @@ public class PfConceptKey extends PfKey { 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. + * The default constructor creates a null concept key. */ public PfConceptKey() { this(NULL_KEY_NAME, NULL_KEY_VERSION); @@ -112,9 +105,9 @@ public class PfConceptKey extends PfKey { } /** - * Get a null artifact key. + * Get a null concept key. * - * @return a null artifact key + * @return a null concept key */ public static final PfConceptKey getNullKey() { return new PfConceptKey(PfKey.NULL_KEY_NAME, PfKey.NULL_KEY_VERSION); @@ -137,58 +130,22 @@ public class PfConceptKey extends PfKey { 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; + final PfConceptKey otherConceptKey = (PfConceptKey) otherKey; - if (this.equals(otherArtifactKey)) { + if (this.equals(otherConceptKey)) { return Compatibility.IDENTICAL; } - if (!this.getName().equals(otherArtifactKey.getName())) { + if (!this.getName().equals(otherConceptKey.getName())) { return Compatibility.DIFFERENT; } final String[] thisVersionArray = getVersion().split("\\."); - final String[] otherVersionArray = otherArtifactKey.getVersion().split("\\."); + final String[] otherVersionArray = otherConceptKey.getVersion().split("\\."); // There must always be at least one element in each version if (!thisVersionArray[0].equals(otherVersionArray[0])) { @@ -196,7 +153,7 @@ public class PfConceptKey extends PfKey { } if (thisVersionArray.length >= 2 && otherVersionArray.length >= 2 - && !thisVersionArray[1].equals(otherVersionArray[1])) { + && !thisVersionArray[1].equals(otherVersionArray[1])) { return Compatibility.MINOR; } @@ -208,27 +165,27 @@ public class PfConceptKey extends PfKey { if (!(otherKey instanceof PfConceptKey)) { return false; } - final PfConceptKey otherArtifactKey = (PfConceptKey) otherKey; + final PfConceptKey otherConceptKey = (PfConceptKey) otherKey; - final Compatibility compatibility = this.getCompatibility(otherArtifactKey); + final Compatibility compatibility = this.getCompatibility(otherConceptKey); return !(compatibility == Compatibility.DIFFERENT || compatibility == Compatibility.MAJOR); } @Override public PfValidationResult validate(final PfValidationResult result) { - final String nameValidationErrorMessage = - Assertions.getStringParameterValidationMessage(NAME_TOKEN, name, NAME_REGEXP); + 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)); + "name invalid-" + nameValidationErrorMessage)); } - final String versionValidationErrorMessage = - Assertions.getStringParameterValidationMessage(VERSION_TOKEN, version, VERSION_REGEXP); + 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)); + "version invalid-" + versionValidationErrorMessage)); } return result; @@ -241,19 +198,6 @@ public class PfConceptKey extends PfKey { } @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"); @@ -268,35 +212,6 @@ public class PfConceptKey extends PfKey { } @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"); 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 index 16e70a2c0..dda4cdc03 100644 --- 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 @@ -21,8 +21,8 @@ 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. + * 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; @@ -49,18 +49,15 @@ public abstract class PfKey extends PfConcept { /** 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). + * 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). + * 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). + * 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. */ @@ -95,8 +92,7 @@ public abstract class PfKey extends PfConcept { public abstract Compatibility getCompatibility(PfKey otherKey); /** - * Check if two keys are compatible, that is the keys are IDENTICAL or have only MINOR, PATCH - * differences. + * 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 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 new file mode 100644 index 000000000..0eb55a711 --- /dev/null +++ b/models-base/src/main/java/org/onap/policy/models/base/PfKeyUse.java @@ -0,0 +1,153 @@ +/*- + * ============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.List; + +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import org.onap.policy.common.utils.validation.Assertions; +import org.onap.policy.models.base.PfValidationResult.ValidationResult; + +/** + * This class records a usage of a key in the system. When the list of keys being used by a concept is built using the + * getKeys() method of the {@link PfConcept} class, an instance of this class is created for every key occurrence. The + * list of keys returned by the getKeys() method is a list of {@link PfKeyUse} objects. + * + * <p>Validation checks that each key is valid. + */ +@EqualsAndHashCode(callSuper = false) +@ToString +public class PfKeyUse extends PfKey { + private static final long serialVersionUID = 2007147220109881705L; + + private PfKey usedKey; + + /** + * The Default Constructor creates this concept with a null key. + */ + public PfKeyUse() { + this(new PfConceptKey()); + } + + /** + * Copy constructor. + * + * @param copyConcept the concept to copy from + */ + public PfKeyUse(final PfKeyUse copyConcept) { + super(copyConcept); + } + + /** + * This constructor creates an instance of this class, and holds a reference to a used key. + * + * @param usedKey a used key + */ + public PfKeyUse(final PfKey usedKey) { + Assertions.argumentNotNull(usedKey, "usedKey may not be null"); + this.usedKey = usedKey; + } + + @Override + public PfKey getKey() { + return usedKey; + } + + @Override + public List<PfKey> getKeys() { + return usedKey.getKeys(); + } + + @Override + public String getId() { + return usedKey.getId(); + } + + /** + * Sets the key. + * + * @param key the key + */ + public void setKey(final PfKey key) { + Assertions.argumentNotNull(key, "usedKey may not be null"); + this.usedKey = key; + } + + @Override + public PfKey.Compatibility getCompatibility(final PfKey otherKey) { + return usedKey.getCompatibility(otherKey); + } + + @Override + public boolean isCompatible(final PfKey otherKey) { + return usedKey.isCompatible(otherKey); + } + + @Override + public PfValidationResult validate(final PfValidationResult result) { + if (usedKey.equals(PfConceptKey.getNullKey())) { + result.addValidationMessage(new PfValidationMessage(usedKey, this.getClass(), ValidationResult.INVALID, + "usedKey is a null key")); + } + return usedKey.validate(result); + } + + @Override + public void clean() { + usedKey.clean(); + } + + @Override + public PfConcept copyTo(final PfConcept target) { + Assertions.argumentNotNull(target, "target may not be null"); + + final Object copyObject = target; + Assertions.instanceOf(copyObject, PfKeyUse.class); + + final PfKeyUse copy = ((PfKeyUse) copyObject); + try { + copy.usedKey = usedKey.getClass().newInstance(); + } catch (final Exception e) { + throw new PfModelRuntimeException("error copying concept key: " + e.getMessage(), e); + } + usedKey.copyTo(copy.usedKey); + + return copy; + } + + @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 PfKeyUse other = (PfKeyUse) otherObj; + + return usedKey.compareTo(other.usedKey); + } +} 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 new file mode 100644 index 000000000..c9174bde8 --- /dev/null +++ b/models-base/src/main/java/org/onap/policy/models/base/PfModel.java @@ -0,0 +1,303 @@ +/*- + * ============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.List; +import java.util.Set; +import java.util.TreeSet; + +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; +import javax.persistence.Table; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NonNull; + +import org.onap.policy.common.utils.validation.Assertions; +import org.onap.policy.models.base.PfValidationResult.ValidationResult; + +/** + * This class is the base class for all models in the Policy Framework. All model classes inherit + * from this model so all models must have a key and have key information. + * + * <p>Validation checks that the model key is valid. It goes on to check for null keys and checks + * each key for uniqueness in the model. A check is carried out to ensure that an {@link PfKeyInfo} + * instance exists for every {@link PfConceptKey} key. For each {@link PfReferenceKey} instance, a + * check is made that its parent and local name are nut null and that a {@link PfKeyInfo} entry + * exists for its parent. Then a check is made that each used {@link PfConceptKey} and + * {@link PfReferenceKey} usage references a key that exists. Finally, a check is made to ensure + * that an {@link PfConceptKey} instance exists for every {@link PfKeyInfo} instance. + * + * @param <C> the type of concept on which the interface is applied. + */ + +@Entity +@Table(name = "PfModel") +@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) +@Data +@EqualsAndHashCode(callSuper = false) +public abstract class PfModel extends PfConcept { + private static final String IS_A_NULL_KEY = " is a null key"; + + private static final long serialVersionUID = -771659065637205430L; + + @EmbeddedId + @NonNull + private PfConceptKey key = PfConceptKey.getNullKey(); + + /** + * The Default Constructor creates this concept with a NULL artifact key. + */ + public PfModel() { + this(new PfConceptKey()); + } + + /** + * Copy constructor. + * + * @param copyConcept the concept to copy from + */ + public PfModel(final PfModel copyConcept) { + super(copyConcept); + } + + /** + * Constructor to create this concept with the specified key. + * + * @param key the key of this concept + */ + public PfModel(final PfConceptKey key) { + super(); + Assertions.argumentNotNull(key, "key may not be null"); + + this.key = key; + } + + /** + * Registers this model with the {@link PfModelService}. All models are registered with the + * model service so that models can be references from anywhere in the Policy Framework system + * without being passed as references through deep call chains. + */ + public abstract void register(); + + @Override + public List<PfKey> getKeys() { + return key.getKeys(); + } + + @Override + public PfValidationResult validate(final PfValidationResult resultIn) { + PfValidationResult result = resultIn; + + if (key.equals(PfConceptKey.getNullKey())) { + result.addValidationMessage( + new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key")); + } + + result = key.validate(result); + + // Key consistency check + final Set<PfConceptKey> artifactKeySet = new TreeSet<>(); + final Set<PfReferenceKey> referenceKeySet = new TreeSet<>(); + final Set<PfKeyUse> usedKeySet = new TreeSet<>(); + + for (final PfKey pfKey : this.getKeys()) { + // Check for the two type of keys we have + if (pfKey instanceof PfConceptKey) { + result = validateArtifactKeyInModel((PfConceptKey) pfKey, artifactKeySet, result); + } else if (pfKey instanceof PfReferenceKey) { + result = validateReferenceKeyInModel((PfReferenceKey) pfKey, referenceKeySet, result); + } + // It must be an PfKeyUse, nothing else is legal + else { + usedKeySet.add((PfKeyUse) pfKey); + } + } + + // Check all reference keys have correct parent keys + for (final PfReferenceKey referenceKey : referenceKeySet) { + if (!artifactKeySet.contains(referenceKey.getParentConceptKey())) { + result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, + "parent artifact key not found for reference key " + referenceKey)); + } + } + + result = validateKeyUses(usedKeySet, artifactKeySet, referenceKeySet, result); + + return result; + } + + /** + * Check for consistent usage of an artifact key in the model. + * + * @param artifactKey The artifact key to check + * @param artifactKeySet The set of artifact keys encountered so far, this key is appended to + * the set + * @param result The validation result to append to + * @return the result of the validation + */ + private PfValidationResult validateArtifactKeyInModel(final PfConceptKey artifactKey, + final Set<PfConceptKey> artifactKeySet, final PfValidationResult result) { + // Null key check + if (artifactKey.equals(PfConceptKey.getNullKey())) { + result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, + "key " + artifactKey + IS_A_NULL_KEY)); + } + + // Null key name start check + if (artifactKey.getName().toUpperCase().startsWith(PfKey.NULL_KEY_NAME)) { + result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, + "key " + artifactKey + " name starts with keyword " + PfKey.NULL_KEY_NAME)); + } + + // Unique key check + if (artifactKeySet.contains(artifactKey)) { + result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, + "duplicate key " + artifactKey + " found")); + } else { + artifactKeySet.add(artifactKey); + } + + return result; + } + + /** + * Check for consistent usage of a reference key in the model. + * + * @param artifactKey The reference key to check + * @param referenceKeySet The set of reference keys encountered so far, this key is appended to + * the set + * @param result The validation result to append to + * @return the result of the validation + */ + private PfValidationResult validateReferenceKeyInModel(final PfReferenceKey referenceKey, + final Set<PfReferenceKey> referenceKeySet, final PfValidationResult result) { + // Null key check + if (referenceKey.equals(PfReferenceKey.getNullKey())) { + result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, + "key " + referenceKey + IS_A_NULL_KEY)); + } + + // Null parent key check + if (referenceKey.getParentConceptKey().equals(PfConceptKey.getNullKey())) { + result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, + "parent artifact key of key " + referenceKey + IS_A_NULL_KEY)); + } + + // Null local name check + if (referenceKey.getLocalName().equals(PfKey.NULL_KEY_NAME)) { + result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, + "key " + referenceKey + " has a null local name")); + } + + // Null key name start check + if (referenceKey.getParentConceptKey().getName().toUpperCase().startsWith(PfKey.NULL_KEY_NAME)) { + result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, + "key " + referenceKey + " parent name starts with keyword " + PfKey.NULL_KEY_NAME)); + } + + // Unique key check + if (referenceKeySet.contains(referenceKey)) { + result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, + "duplicate key " + referenceKey + " found")); + } else { + referenceKeySet.add(referenceKey); + } + + return result; + } + + /** + * Check for consistent usage of cross-key references in the model. + * + * @param usedKeySet The set of all keys used in the model + * @param artifactKeySet The set of artifact keys encountered so far, this key is appended to + * the set + * @param referenceKeySet The set of reference keys encountered so far, this key is appended to + * the set + * @param result The validation result to append to + * @return the result of the validation + */ + private PfValidationResult validateKeyUses(final Set<PfKeyUse> usedKeySet, final Set<PfConceptKey> artifactKeySet, + final Set<PfReferenceKey> referenceKeySet, final PfValidationResult result) { + // Check all key uses + for (final PfKeyUse usedKey : usedKeySet) { + if (usedKey.getKey() instanceof PfConceptKey) { + // PfConceptKey usage, check the key exists + if (!artifactKeySet.contains(usedKey.getKey())) { + result.addValidationMessage(new PfValidationMessage(usedKey.getKey(), this.getClass(), + ValidationResult.INVALID, "an artifact key used in the model is not defined")); + } + } else { + // PfReferenceKey usage, check the key exists + if (!referenceKeySet.contains(usedKey.getKey())) { + result.addValidationMessage(new PfValidationMessage(usedKey.getKey(), this.getClass(), + ValidationResult.INVALID, "a reference key used in the model is not defined")); + } + } + } + + return result; + } + + @Override + public void clean() { + key.clean(); + } + + @Override + public PfConcept copyTo(final PfConcept target) { + Assertions.argumentNotNull(target, "target may not be null"); + + final Object copyObject = target; + Assertions.instanceOf(copyObject, PfModel.class); + + final PfModel copy = ((PfModel) copyObject); + copy.setKey(new PfConceptKey(key)); + + return copy; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Comparable#compareTo(java.lang.Object) + */ + @Override + public int compareTo(final PfConcept otherObj) { + if (otherObj == null) { + return -1; + } + if (this == otherObj) { + return 0; + } + if (getClass() != otherObj.getClass()) { + return this.hashCode() - otherObj.hashCode(); + } + + final PfModel other = (PfModel) otherObj; + + return key.compareTo(other.key); + } +} diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfModelService.java b/models-base/src/main/java/org/onap/policy/models/base/PfModelService.java new file mode 100644 index 000000000..c02de6aa7 --- /dev/null +++ b/models-base/src/main/java/org/onap/policy/models/base/PfModelService.java @@ -0,0 +1,104 @@ +/*- + * ============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.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * The model service makes Policy Framework models available to all classes in a JVM. + * + * <p>The reason for having a model service is to avoid having to pass concept and model definitions + * down long call chains in modules such as the Policy Framework engine and editor. The model + * service makes the model and concept definitions available statically. + * + * <p>Note that the use of the model service means that only a single Policy Framework model of a + * particular type may exist in Policy Framework (particularly the engine) at any time. Of course + * the model in a JVM can be changed at any time provided all users of the model are stopped and + * restarted in an orderly manner. + */ +public abstract class PfModelService { + // The map holding the models + private static Map<Class<?>, PfConcept> modelMap = new ConcurrentHashMap<>(); + + /** + * This class is an abstract static class that cannot be extended. + */ + private PfModelService() {} + + /** + * Register a model with the model service. + * + * @param <M> the generic type + * @param modelClass the class of the model, used to index the model + * @param model The model + */ + public static <M extends PfConcept> void registerModel(final Class<M> modelClass, final M model) { + modelMap.put(modelClass, model); + } + + /** + * Remove a model from the model service. + * + * @param <M> the generic type + * @param modelClass the class of the model, used to index the model + */ + public static <M extends PfConcept> void deregisterModel(final Class<M> modelClass) { + modelMap.remove(modelClass); + } + + /** + * Get a model from the model service. + * + * @param <M> the generic type + * @param modelClass the class of the model, used to index the model + * @return The model + */ + @SuppressWarnings("unchecked") + public static <M extends PfConcept> M getModel(final Class<M> modelClass) { + final M model = (M) modelMap.get(modelClass); + + if (model == null) { + throw new PfModelRuntimeException( + "Model for " + modelClass.getCanonicalName() + " not found in model service"); + } + + return model; + } + + /** + * Check if a model is defined on the model service. + * + * @param <M> the generic type + * @param modelClass the class of the model, used to index the model + * @return true if the model is defined + */ + public static <M extends PfConcept> boolean existsModel(final Class<M> modelClass) { + return modelMap.get(modelClass) != null; + } + + /** + * Clear all models in the model service. + */ + public static void clear() { + modelMap.clear(); + } +} 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 new file mode 100644 index 000000000..e3b92c0e9 --- /dev/null +++ b/models-base/src/main/java/org/onap/policy/models/base/PfReferenceKey.java @@ -0,0 +1,392 @@ +/*- + * ============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 lombok.Data; +import lombok.EqualsAndHashCode; + +import org.onap.policy.common.utils.validation.Assertions; +import org.onap.policy.models.base.PfValidationResult.ValidationResult; + +/** + * A reference key identifies entities in the system that are contained in other entities. Every contained concept in + * the system must have an {@link PfReferenceKey} to identify it. Non-contained first order concepts are identified + * using an {@link PfConceptKey} key. + * + * <p>An {@link PfReferenceKey} contains an {@link PfConceptKey} key reference to the first order entity that contains + * it. The local name of the reference key must uniquely identify the referenced concept among those concepts contained + * in the reference key's parent. In other words, if a parent concept has more than one child, the local name in the key + * of all its children must be unique. + * + * <p>If a reference key's parent is itself a reference key, then the parent's local name must be set in the reference + * key. If the parent is a first order concept, then the parent's local name in the key will be set to NULL. + * + * <p>Key validation checks that the parent name and parent version fields match the NAME_REGEXP and + * VERSION_REGEXP regular expressions respectively and that the local name fields match the + * LOCAL_NAME_REGEXP regular expression. + */ +@Embeddable +@Data +@EqualsAndHashCode(callSuper = false) +public class PfReferenceKey extends PfKey { + private static final String PARENT_KEY_NAME = "parentKeyName"; + private static final String PARENT_KEY_VERSION = "parentKeyVersion"; + private static final String PARENT_LOCAL_NAME = "parentLocalName"; + private static final String LOCAL_NAME = "localName"; + + private static final long serialVersionUID = 8932717618579392561L; + + /** Regular expression to specify the structure of local names in reference keys. */ + public static final String LOCAL_NAME_REGEXP = "[A-Za-z0-9\\-_\\.]+|^$"; + + /** Regular expression to specify the structure of IDs in reference keys. */ + public static final String REFERENCE_KEY_ID_REGEXP = + "[A-Za-z0-9\\-_]+:[0-9].[0-9].[0-9]:[A-Za-z0-9\\-_]+:[A-Za-z0-9\\-_]+"; + + private static final int PARENT_NAME_FIELD = 0; + private static final int PARENT_VERSION_FIELD = 1; + private static final int PARENT_LOCAL_NAME_FIELD = 2; + private static final int LOCAL_NAME_FIELD = 3; + + @Column(name = PARENT_KEY_NAME) + private String parentKeyName; + + @Column(name = PARENT_KEY_VERSION) + private String parentKeyVersion; + + @Column(name = PARENT_LOCAL_NAME) + private String parentLocalName; + + @Column(name = LOCAL_NAME) + private String localName; + + /** + * The default constructor creates a null reference key. + */ + public PfReferenceKey() { + this(NULL_KEY_NAME, NULL_KEY_VERSION, NULL_KEY_NAME, NULL_KEY_NAME); + } + + /** + * The Copy Constructor creates a key by copying another key. + * + * @param referenceKey + * the reference key to copy from + */ + public PfReferenceKey(final PfReferenceKey referenceKey) { + this(referenceKey.getParentKeyName(), referenceKey.getParentKeyVersion(), referenceKey.getParentLocalName(), + referenceKey.getLocalName()); + } + + /** + * Constructor to create a null reference key for the specified parent concept key. + * + * @param pfConceptKey + * the parent concept key of this reference key + */ + public PfReferenceKey(final PfConceptKey pfConceptKey) { + this(pfConceptKey.getName(), pfConceptKey.getVersion(), NULL_KEY_NAME, NULL_KEY_NAME); + } + + /** + * Constructor to create a reference key for the given parent concept key with the given local name. + * + * @param pfConceptKey + * the parent concept key of this reference key + * @param localName + * the local name of this reference key + */ + public PfReferenceKey(final PfConceptKey pfConceptKey, final String localName) { + this(pfConceptKey, NULL_KEY_NAME, localName); + } + + /** + * Constructor to create a reference key for the given parent reference key with the given local name. + * + * @param parentReferenceKey + * the parent reference key of this reference key + * @param localName + * the local name of this reference key + */ + public PfReferenceKey(final PfReferenceKey parentReferenceKey, final String localName) { + this(parentReferenceKey.getParentConceptKey(), parentReferenceKey.getLocalName(), localName); + } + + /** + * Constructor to create a reference key for the given parent reference key (specified by the parent reference key's + * concept key and local name) with the given local name. + * + * @param pfConceptKey + * the concept key of the parent reference key of this reference key + * @param parentLocalName + * the local name of the parent reference key of this reference key + * @param localName + * the local name of this reference key + */ + public PfReferenceKey(final PfConceptKey pfConceptKey, final String parentLocalName, final String localName) { + this(pfConceptKey.getName(), pfConceptKey.getVersion(), parentLocalName, localName); + } + + /** + * Constructor to create a reference key for the given parent concept key (specified by the parent concept key's + * name and version) with the given local name. + * + * @param parentKeyName + * the name of the parent concept key of this reference key + * @param parentKeyVersion + * the version of the parent concept key of this reference key + * @param localName + * the local name of this reference key + */ + public PfReferenceKey(final String parentKeyName, final String parentKeyVersion, final String localName) { + this(parentKeyName, parentKeyVersion, NULL_KEY_NAME, localName); + } + + /** + * Constructor to create a reference key for the given parent key (specified by the parent key's name, version nad + * local name) with the given local name. + * + * @param parentKeyName + * the parent key name of this reference key + * @param parentKeyVersion + * the parent key version of this reference key + * @param parentLocalName + * the parent local name of this reference key + * @param localName + * the local name of this reference key + */ + public PfReferenceKey(final String parentKeyName, final String parentKeyVersion, final String parentLocalName, + final String localName) { + super(); + this.parentKeyName = Assertions.validateStringParameter(PARENT_KEY_NAME, parentKeyName, NAME_REGEXP); + this.parentKeyVersion = Assertions.validateStringParameter(PARENT_KEY_VERSION, parentKeyVersion, + VERSION_REGEXP); + this.parentLocalName = Assertions.validateStringParameter(PARENT_LOCAL_NAME, parentLocalName, + LOCAL_NAME_REGEXP); + this.localName = Assertions.validateStringParameter(LOCAL_NAME, localName, LOCAL_NAME_REGEXP); + } + + /** + * Constructor to create a key from the specified key ID. + * + * @param id + * the key ID in a format that respects the KEY_ID_REGEXP + */ + public PfReferenceKey(final String id) { + final String conditionedId = Assertions.validateStringParameter("id", id, REFERENCE_KEY_ID_REGEXP); + + // Split on colon, if the id passes the regular expression test above + // it'll have just three colons separating the parent name, + // parent version, parent local name, and and local name + // No need for range checks or size checks on the array + final String[] nameVersionNameArray = conditionedId.split(":"); + + // Initiate the new key + parentKeyName = Assertions.validateStringParameter(PARENT_KEY_NAME, nameVersionNameArray[PARENT_NAME_FIELD], + NAME_REGEXP); + parentKeyVersion = Assertions.validateStringParameter(PARENT_KEY_VERSION, + nameVersionNameArray[PARENT_VERSION_FIELD], VERSION_REGEXP); + parentLocalName = Assertions.validateStringParameter(PARENT_LOCAL_NAME, + nameVersionNameArray[PARENT_LOCAL_NAME_FIELD], LOCAL_NAME_REGEXP); + localName = Assertions.validateStringParameter(LOCAL_NAME, nameVersionNameArray[LOCAL_NAME_FIELD], + LOCAL_NAME_REGEXP); + } + + /** + * Get a null reference key. + * + * @return a null reference key + */ + public static PfReferenceKey getNullKey() { + return new PfReferenceKey(PfKey.NULL_KEY_NAME, PfKey.NULL_KEY_VERSION, PfKey.NULL_KEY_NAME, + PfKey.NULL_KEY_NAME); + } + + @Override + public PfReferenceKey getKey() { + return this; + } + + @Override + public List<PfKey> getKeys() { + final List<PfKey> keyList = new ArrayList<>(); + keyList.add(getKey()); + return keyList; + } + + @Override + public String getId() { + return parentKeyName + ':' + parentKeyVersion + ':' + parentLocalName + ':' + localName; + } + + /** + * Gets the parent concept key of this reference key. + * + * @return the parent concept key of this reference key + */ + public PfConceptKey getParentConceptKey() { + return new PfConceptKey(parentKeyName, parentKeyVersion); + } + + /** + * Gets the parent reference key of this reference key. + * + * @return the parent reference key of this reference key + */ + public PfReferenceKey getParentReferenceKey() { + return new PfReferenceKey(parentKeyName, parentKeyVersion, parentLocalName); + } + + /** + * Sets the parent concept key of this reference key. + * + * @param parentKey + * the parent concept key of this reference key + */ + public void setParentConceptKey(final PfConceptKey parentKey) { + Assertions.argumentNotNull(parentKey, "parentKey may not be null"); + + parentKeyName = parentKey.getName(); + parentKeyVersion = parentKey.getVersion(); + parentLocalName = NULL_KEY_NAME; + } + + /** + * Sets the parent reference key of this reference key. + * + * @param parentKey + * the parent reference key of this reference key + */ + public void setParentReferenceKey(final PfReferenceKey parentKey) { + Assertions.argumentNotNull(parentKey, "parentKey may not be null"); + + parentKeyName = parentKey.getParentKeyName(); + parentKeyVersion = parentKey.getParentKeyVersion(); + parentLocalName = parentKey.getLocalName(); + } + + @Override + public PfKey.Compatibility getCompatibility(final PfKey otherKey) { + if (!(otherKey instanceof PfReferenceKey)) { + return Compatibility.DIFFERENT; + } + final PfReferenceKey otherReferenceKey = (PfReferenceKey) otherKey; + + return this.getParentConceptKey().getCompatibility(otherReferenceKey.getParentConceptKey()); + } + + @Override + public boolean isCompatible(final PfKey otherKey) { + if (!(otherKey instanceof PfReferenceKey)) { + return false; + } + final PfReferenceKey otherReferenceKey = (PfReferenceKey) otherKey; + + return this.getParentConceptKey().isCompatible(otherReferenceKey.getParentConceptKey()); + } + + @Override + public PfValidationResult validate(final PfValidationResult result) { + final String parentNameValidationErrorMessage = Assertions.getStringParameterValidationMessage(PARENT_KEY_NAME, + parentKeyName, NAME_REGEXP); + if (parentNameValidationErrorMessage != null) { + result.addValidationMessage(new PfValidationMessage(this, this.getClass(), ValidationResult.INVALID, + "parentKeyName invalid-" + parentNameValidationErrorMessage)); + } + + final String parentKeyVersionValidationErrorMessage = Assertions + .getStringParameterValidationMessage(PARENT_KEY_VERSION, parentKeyVersion, VERSION_REGEXP); + if (parentKeyVersionValidationErrorMessage != null) { + result.addValidationMessage(new PfValidationMessage(this, this.getClass(), ValidationResult.INVALID, + "parentKeyVersion invalid-" + parentKeyVersionValidationErrorMessage)); + } + + final String parentLocalNameValidationErrorMessage = Assertions + .getStringParameterValidationMessage(PARENT_LOCAL_NAME, parentLocalName, LOCAL_NAME_REGEXP); + if (parentLocalNameValidationErrorMessage != null) { + result.addValidationMessage(new PfValidationMessage(this, this.getClass(), ValidationResult.INVALID, + "parentLocalName invalid-" + parentLocalNameValidationErrorMessage)); + } + + final String localNameValidationErrorMessage = Assertions.getStringParameterValidationMessage(LOCAL_NAME, + localName, LOCAL_NAME_REGEXP); + if (localNameValidationErrorMessage != null) { + result.addValidationMessage(new PfValidationMessage(this, this.getClass(), ValidationResult.INVALID, + "localName invalid-" + localNameValidationErrorMessage)); + } + + return result; + } + + @Override + public void clean() { + parentKeyName = Assertions.validateStringParameter(PARENT_KEY_NAME, parentKeyName, NAME_REGEXP); + parentKeyVersion = Assertions.validateStringParameter(PARENT_KEY_VERSION, parentKeyVersion, VERSION_REGEXP); + parentLocalName = Assertions.validateStringParameter(PARENT_LOCAL_NAME, parentLocalName, LOCAL_NAME_REGEXP); + localName = Assertions.validateStringParameter(LOCAL_NAME, localName, LOCAL_NAME_REGEXP); + } + + @Override + public PfConcept copyTo(final PfConcept target) { + Assertions.argumentNotNull(target, "target may not be null"); + + final Object copyObject = target; + Assertions.instanceOf(copyObject, PfReferenceKey.class); + + final PfReferenceKey copy = ((PfReferenceKey) copyObject); + copy.setParentKeyName(parentKeyName); + copy.setParentKeyVersion(parentKeyVersion); + copy.setLocalName(localName); + copy.setParentLocalName(parentLocalName); + + return copy; + } + + @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 PfReferenceKey other = (PfReferenceKey) otherObj; + if (!parentKeyName.equals(other.parentKeyName)) { + return parentKeyName.compareTo(other.parentKeyName); + } + if (!parentKeyVersion.equals(other.parentKeyVersion)) { + return parentKeyVersion.compareTo(other.parentKeyVersion); + } + if (!parentLocalName.equals(other.parentLocalName)) { + return parentLocalName.compareTo(other.parentLocalName); + } + return localName.compareTo(other.localName); + } +} 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 index 92e928e2e..c0898c187 100644 --- 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 @@ -1,4 +1,4 @@ -/* +/*- * ============LICENSE_START======================================================= * Copyright (C) 2019 Nordix Foundation. * ================================================================================ diff --git a/models-base/src/test/java/org/onap/policy/models/base/PfConceptGetterImplTest.java b/models-base/src/test/java/org/onap/policy/models/base/PfConceptGetterImplTest.java new file mode 100644 index 000000000..0a5ccdc5a --- /dev/null +++ b/models-base/src/test/java/org/onap/policy/models/base/PfConceptGetterImplTest.java @@ -0,0 +1,96 @@ +/*- + * ============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 static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; + +import java.util.NavigableMap; +import java.util.TreeMap; +import java.util.TreeSet; + +import org.junit.Test; + +/** + * Test the AxConceptGetterImpl class. + */ +public class PfConceptGetterImplTest { + + @Test + public void testAxConceptGetterImpl() { + NavigableMap<PfConceptKey, PfConceptKey> keyMap = new TreeMap<>(); + + PfConceptGetterImpl<PfConceptKey> getter = new PfConceptGetterImpl<>(keyMap); + assertNotNull(getter); + + PfConceptKey keyA = new PfConceptKey("A", "0.0.1"); + assertNull(getter.get(keyA)); + + try { + getter.get((String)null); + fail("test should throw an exception here"); + } + catch (Exception getException) { + assertEquals("conceptKeyName may not be null", getException.getMessage()); + } + + assertNull(getter.get("W")); + + PfConceptKey keyZ = new PfConceptKey("Z", "0.0.1"); + keyMap.put(keyZ, keyZ); + assertNull(getter.get("W")); + + PfConceptKey keyW001 = new PfConceptKey("W", "0.0.1"); + keyMap.put(keyW001, keyW001); + assertEquals(keyW001, getter.get("W")); + + PfConceptKey keyW002 = new PfConceptKey("W", "0.0.2"); + keyMap.put(keyW002, keyW002); + assertEquals(keyW002, getter.get("W")); + + keyMap.remove(keyZ); + assertEquals(keyW002, getter.get("W")); + + try { + getter.get((String)null, "0.0.1"); + fail("test should throw an exception here"); + } + catch (Exception getException) { + assertEquals("conceptKeyName may not be null", getException.getMessage()); + } + + assertEquals(keyW002, getter.get("W", "0.0.2")); + assertEquals(keyW002, getter.get("W", (String)null)); + + assertEquals(new TreeSet<PfConceptKey>(keyMap.values()), getter.getAll(null)); + assertEquals(new TreeSet<PfConceptKey>(keyMap.values()), getter.getAll(null, null)); + + assertEquals(keyW001, getter.getAll("W", null).iterator().next()); + assertEquals(keyW002, getter.getAll("W", "0.0.2").iterator().next()); + assertEquals(0, getter.getAll("A", null).size()); + assertEquals(0, getter.getAll("Z", null).size()); + + keyMap.put(keyZ, keyZ); + assertEquals(keyW002, getter.getAll("W", "0.0.2").iterator().next()); + } +} 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 index dd28f33ba..1ffc5d262 100644 --- 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 @@ -1,4 +1,4 @@ -/* +/*- * ============LICENSE_START======================================================= * Copyright (C) 2019 Nordix Foundation. * ================================================================================ @@ -37,7 +37,7 @@ import org.onap.policy.models.base.testpojos.DummyPfKey; public class PfKeyTest { @Test - public void testArtifactKey() { + public void testConceptKey() { try { new PfConceptKey("some bad key id"); fail("This test should throw an exception"); @@ -113,7 +113,7 @@ public class PfKeyTest { assertNotNull(someKey0.toString()); PfConceptKey someKey7 = new PfConceptKey(someKey1); - assertEquals(150332875, someKey7.hashCode()); + assertEquals(244799191, someKey7.hashCode()); assertEquals(0, someKey7.compareTo(someKey1)); assertEquals(-12, someKey7.compareTo(someKey0)); @@ -124,7 +124,7 @@ public class PfKeyTest { } assertEquals(0, someKey0.compareTo(someKey0)); - assertEquals(161539407, someKey0.compareTo(new DummyPfKey())); + assertEquals(266127751, someKey0.compareTo(new DummyPfKey())); assertFalse(someKey0.equals(null)); assertTrue(someKey0.equals(someKey0)); diff --git a/models-base/src/test/java/org/onap/policy/models/base/PfKeyUseTest.java b/models-base/src/test/java/org/onap/policy/models/base/PfKeyUseTest.java new file mode 100644 index 000000000..7dbde7414 --- /dev/null +++ b/models-base/src/test/java/org/onap/policy/models/base/PfKeyUseTest.java @@ -0,0 +1,78 @@ +/* + * ============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.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.onap.policy.models.base.PfKey.Compatibility; + +public class PfKeyUseTest { + + @Test + public void test() { + assertNotNull(new PfKeyUse()); + assertNotNull(new PfKeyUse(new PfConceptKey())); + assertNotNull(new PfKeyUse(new PfReferenceKey())); + + PfConceptKey key = new PfConceptKey("Key", "0.0.1"); + PfKeyUse keyUse = new PfKeyUse(); + keyUse.setKey(key); + assertEquals(key, keyUse.getKey()); + assertEquals("Key:0.0.1", keyUse.getId()); + assertEquals(key, keyUse.getKeys().get(0)); + + assertEquals(Compatibility.IDENTICAL, keyUse.getCompatibility(key)); + assertTrue(keyUse.isCompatible(key)); + + keyUse.clean(); + assertNotNull(keyUse); + + PfValidationResult result = new PfValidationResult(); + result = keyUse.validate(result); + assertNotNull(result); + + assertNotEquals(0, keyUse.hashCode()); + + PfKeyUse clonedKeyUse = new PfKeyUse(keyUse); + assertEquals("PfKeyUse(usedKey=PfConceptKey(name=Key, version=0.0.1))", clonedKeyUse.toString()); + + assertFalse(keyUse.hashCode() == 0); + + assertTrue(keyUse.equals(keyUse)); + assertTrue(keyUse.equals(clonedKeyUse)); + assertFalse(keyUse.equals("Hello")); + assertTrue(keyUse.equals(new PfKeyUse(key))); + + assertEquals(0, keyUse.compareTo(keyUse)); + assertEquals(0, keyUse.compareTo(clonedKeyUse)); + assertNotEquals(0, keyUse.compareTo(new PfConceptKey())); + assertEquals(0, keyUse.compareTo(new PfKeyUse(key))); + + PfKeyUse keyUseNull = new PfKeyUse(PfConceptKey.getNullKey()); + PfValidationResult resultNull = new PfValidationResult(); + assertEquals(false, keyUseNull.validate(resultNull).isValid()); + } +} diff --git a/models-base/src/test/java/org/onap/policy/models/base/PfReferenceKeyTest.java b/models-base/src/test/java/org/onap/policy/models/base/PfReferenceKeyTest.java new file mode 100644 index 000000000..feedc2cc3 --- /dev/null +++ b/models-base/src/test/java/org/onap/policy/models/base/PfReferenceKeyTest.java @@ -0,0 +1,198 @@ +/*- + * ============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.assertNotEquals; +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; + +public class PfReferenceKeyTest { + + @Test + public void testPfReferenceKey() { + assertNotNull(new PfReferenceKey()); + assertNotNull(new PfReferenceKey(new PfConceptKey())); + assertNotNull(new PfReferenceKey(new PfConceptKey(), "LocalName")); + assertNotNull(new PfReferenceKey(new PfReferenceKey())); + assertNotNull(new PfReferenceKey(new PfReferenceKey(), "LocalName")); + assertNotNull(new PfReferenceKey(new PfConceptKey(), "ParentLocalName", "LocalName")); + assertNotNull(new PfReferenceKey("ParentKeyName", "0.0.1", "LocalName")); + assertNotNull(new PfReferenceKey("ParentKeyName", "0.0.1", "ParentLocalName", "LocalName")); + assertNotNull(new PfReferenceKey("ParentKeyName:0.0.1:ParentLocalName:LocalName")); + assertEquals(PfReferenceKey.getNullKey().getKey(), PfReferenceKey.getNullKey()); + assertEquals("NULL:0.0.0:NULL:NULL", PfReferenceKey.getNullKey().getId()); + + PfReferenceKey testReferenceKey = new PfReferenceKey(); + testReferenceKey.setParentConceptKey(new PfConceptKey("PN", "0.0.1")); + assertEquals("PN:0.0.1", testReferenceKey.getParentConceptKey().getId()); + + testReferenceKey.setParentReferenceKey(new PfReferenceKey("PN", "0.0.1", "LN")); + assertEquals("PN:0.0.1:NULL:LN", testReferenceKey.getParentReferenceKey().getId()); + + testReferenceKey.setParentKeyName("NPKN"); + assertEquals("NPKN", testReferenceKey.getParentKeyName()); + + testReferenceKey.setParentKeyVersion("0.0.1"); + assertEquals("0.0.1", testReferenceKey.getParentKeyVersion()); + + testReferenceKey.setParentLocalName("NPKLN"); + assertEquals("NPKLN", testReferenceKey.getParentLocalName()); + + testReferenceKey.setLocalName("NLN"); + assertEquals("NLN", testReferenceKey.getLocalName()); + + assertFalse(testReferenceKey.isCompatible(PfConceptKey.getNullKey())); + assertFalse(testReferenceKey.isCompatible(PfReferenceKey.getNullKey())); + assertTrue(testReferenceKey.isCompatible(testReferenceKey)); + + assertEquals(PfKey.Compatibility.DIFFERENT, testReferenceKey.getCompatibility(PfConceptKey.getNullKey())); + assertEquals(PfKey.Compatibility.DIFFERENT, testReferenceKey.getCompatibility(PfReferenceKey.getNullKey())); + assertEquals(PfKey.Compatibility.IDENTICAL, testReferenceKey.getCompatibility(testReferenceKey)); + + PfValidationResult result = new PfValidationResult(); + result = testReferenceKey.validate(result); + assertEquals(PfValidationResult.ValidationResult.VALID, result.getValidationResult()); + + testReferenceKey.clean(); + + PfReferenceKey clonedReferenceKey = new PfReferenceKey(testReferenceKey); + assertEquals("PfReferenceKey(parentKeyName=NPKN, parentKeyVersion=0.0.1, parentLocalName=NPKLN, localName=NLN)", + clonedReferenceKey.toString()); + + assertFalse(testReferenceKey.hashCode() == 0); + + assertTrue(testReferenceKey.equals(testReferenceKey)); + assertTrue(testReferenceKey.equals(clonedReferenceKey)); + assertFalse(testReferenceKey.equals("Hello")); + assertFalse(testReferenceKey.equals(new PfReferenceKey("PKN", "0.0.2", "PLN", "LN"))); + assertFalse(testReferenceKey.equals(new PfReferenceKey("NPKN", "0.0.2", "PLN", "LN"))); + assertFalse(testReferenceKey.equals(new PfReferenceKey("NPKN", "0.0.1", "PLN", "LN"))); + assertFalse(testReferenceKey.equals(new PfReferenceKey("NPKN", "0.0.1", "NPLN", "LN"))); + assertTrue(testReferenceKey.equals(new PfReferenceKey("NPKN", "0.0.1", "NPKLN", "NLN"))); + + assertEquals(0, testReferenceKey.compareTo(testReferenceKey)); + assertEquals(0, testReferenceKey.compareTo(clonedReferenceKey)); + assertNotEquals(0, testReferenceKey.compareTo(new PfConceptKey())); + assertNotEquals(0, testReferenceKey.compareTo(new PfReferenceKey("PKN", "0.0.2", "PLN", "LN"))); + assertNotEquals(0, testReferenceKey.compareTo(new PfReferenceKey("NPKN", "0.0.2", "PLN", "LN"))); + assertNotEquals(0, testReferenceKey.compareTo(new PfReferenceKey("NPKN", "0.0.1", "PLN", "LN"))); + assertNotEquals(0, testReferenceKey.compareTo(new PfReferenceKey("NPKN", "0.0.1", "NPLN", "LN"))); + assertEquals(0, testReferenceKey.compareTo(new PfReferenceKey("NPKN", "0.0.1", "NPKLN", "NLN"))); + + assertFalse(testReferenceKey.equals(null)); + + try { + testReferenceKey.copyTo(null); + fail("test should throw an exception here"); + } catch (Exception iae) { + assertEquals("target may not be null", iae.getMessage()); + } + + try { + testReferenceKey.copyTo(new PfConceptKey("Key", "0.0.1")); + fail("test should throw an exception here"); + } catch (Exception iae) { + assertEquals("org.onap.policy.models.base.PfConceptKey" + + " is not an instance of org.onap.policy.models.base.PfReferenceKey", iae.getMessage()); + } + + PfReferenceKey targetRefKey = new PfReferenceKey(); + assertEquals(testReferenceKey, testReferenceKey.copyTo(targetRefKey)); + } + + @Test + public void testValidation() { + PfReferenceKey testReferenceKey = new PfReferenceKey(); + testReferenceKey.setParentConceptKey(new PfConceptKey("PN", "0.0.1")); + assertEquals("PN:0.0.1", testReferenceKey.getParentConceptKey().getId()); + + try { + Field parentNameField = testReferenceKey.getClass().getDeclaredField("parentKeyName"); + parentNameField.setAccessible(true); + parentNameField.set(testReferenceKey, "Parent Name"); + PfValidationResult validationResult = new PfValidationResult(); + testReferenceKey.validate(validationResult); + parentNameField.set(testReferenceKey, "ParentName"); + parentNameField.setAccessible(false); + assertEquals( + "parentKeyName invalid-parameter parentKeyName with value Parent 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 parentVersionField = testReferenceKey.getClass().getDeclaredField("parentKeyVersion"); + parentVersionField.setAccessible(true); + parentVersionField.set(testReferenceKey, "Parent Version"); + PfValidationResult validationResult = new PfValidationResult(); + testReferenceKey.validate(validationResult); + parentVersionField.set(testReferenceKey, "0.0.1"); + parentVersionField.setAccessible(false); + assertEquals( + "parentKeyVersion invalid-parameter parentKeyVersion with value Parent 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"); + } + + try { + Field parentLocalNameField = testReferenceKey.getClass().getDeclaredField("parentLocalName"); + parentLocalNameField.setAccessible(true); + parentLocalNameField.set(testReferenceKey, "Parent Local Name"); + PfValidationResult validationResult = new PfValidationResult(); + testReferenceKey.validate(validationResult); + parentLocalNameField.set(testReferenceKey, "ParentLocalName"); + parentLocalNameField.setAccessible(false); + assertEquals( + "parentLocalName invalid-parameter parentLocalName with value " + + "Parent Local 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 localNameField = testReferenceKey.getClass().getDeclaredField("localName"); + localNameField.setAccessible(true); + localNameField.set(testReferenceKey, "Local Name"); + PfValidationResult validationResult = new PfValidationResult(); + testReferenceKey.validate(validationResult); + localNameField.set(testReferenceKey, "LocalName"); + localNameField.setAccessible(false); + assertEquals( + "localName invalid-parameter localName with value Local 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"); + } + } +} 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 index 385039c5b..0d4f2a7ee 100644 --- 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 @@ -1,4 +1,4 @@ -/* +/*- * ============LICENSE_START======================================================= * Copyright (C) 2019 Nordix Foundation. * ================================================================================ 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 index 85727f45e..f28477f70 100644 --- 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 @@ -20,6 +20,7 @@ package org.onap.policy.models.base.testpojos; +import java.util.Arrays; import java.util.List; import org.onap.policy.models.base.PfConcept; @@ -42,7 +43,7 @@ public class DummyPfConcept extends PfConcept { @Override public List<PfKey> getKeys() { - return null; + return Arrays.asList(getKey()); } @Override 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 index 19358a1de..247ea88d1 100644 --- 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 @@ -20,6 +20,7 @@ package org.onap.policy.models.base.testpojos; +import java.util.Arrays; import java.util.List; import org.onap.policy.models.base.PfConcept; @@ -56,7 +57,7 @@ public class DummyPfKey extends PfKey { @Override public List<PfKey> getKeys() { - return null; + return Arrays.asList(getKey()); } @Override diff --git a/models-dao/pom.xml b/models-dao/pom.xml index 90b98015d..d71fce868 100644 --- a/models-dao/pom.xml +++ b/models-dao/pom.xml @@ -30,4 +30,19 @@ <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> + + <dependencies> + <dependency> + <groupId>org.onap.policy.models</groupId> + <artifactId>policy-models-base</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> + <scope>test</scope> + </dependency> + + </dependencies> </project> diff --git a/models-dao/src/main/java/org/onap/policy/models/dao/DaoParameters.java b/models-dao/src/main/java/org/onap/policy/models/dao/DaoParameters.java new file mode 100644 index 000000000..18ae74ae1 --- /dev/null +++ b/models-dao/src/main/java/org/onap/policy/models/dao/DaoParameters.java @@ -0,0 +1,126 @@ +/*- + * ============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.dao; + +import java.util.Properties; + +/** + * This class is a POJO that holds properties for PF DAOs. + */ +public class DaoParameters { + /** The default PF DAO plugin class. */ + public static final String DEFAULT_PLUGIN_CLASS = "org.onap.policy.models.dao.impl.DefaultPfDao"; + + private String pluginClass = DEFAULT_PLUGIN_CLASS; + private String persistenceUnit; + + private Properties jdbcProperties = new Properties(); + + /** + * Gets the DAO plugin class, this is the DAO class to use and it must implement the + * {@link PfDao} interface. + * + * @return the DAO plugin class + */ + public String getPluginClass() { + return pluginClass; + } + + /** + * Sets the DAO plugin class, a class that implements the {@link PfDao} interface. + * + * @param daoPluginClass the DAO plugin class + */ + public void setPluginClass(final String daoPluginClass) { + pluginClass = daoPluginClass; + } + + /** + * Gets the persistence unit for the DAO. The persistence unit defines the JDBC properties the + * DAO will use. The persistence unit must defined in the {@code META-INF/persistence.xml} + * resource file + * + * @return the persistence unit to use for JDBC access + */ + public String getPersistenceUnit() { + return persistenceUnit; + } + + /** + * Sets the persistence unit for the DAO. The persistence unit defines the JDBC properties the + * DAO will use. The persistence unit must defined in the {@code META-INF/persistence.xml} + * resource file + * + * @param daoPersistenceUnit the persistence unit to use for JDBC access + */ + public void setPersistenceUnit(final String daoPersistenceUnit) { + persistenceUnit = daoPersistenceUnit; + } + + /** + * Gets the JDBC properties. + * + * @return the JDBC properties + */ + public Properties getJdbcProperties() { + return jdbcProperties; + } + + /** + * Sets the JDBC properties. + * + * @param jdbcProperties the JDBC properties + */ + public void setJdbcProperties(final Properties jdbcProperties) { + this.jdbcProperties = jdbcProperties; + } + + /** + * Gets a single JDBC property. + * + * @param key the key of the property + * @return the JDBC property + */ + public String getJdbcProperty(final String key) { + return jdbcProperties.getProperty(key); + } + + /** + * Sets a single JDBC property. + * + * @param key the key of the property + * @param value the value of the JDBC property + */ + public void setJdbcProperty(final String key, final String value) { + jdbcProperties.setProperty(key, value); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "DAOParameters [pluginClass=" + pluginClass + ", persistenceUnit=" + persistenceUnit + + ", jdbcProperties=" + jdbcProperties + "]"; + } +} diff --git a/models-dao/src/main/java/org/onap/policy/models/dao/PfDao.java b/models-dao/src/main/java/org/onap/policy/models/dao/PfDao.java new file mode 100644 index 000000000..85c971ce7 --- /dev/null +++ b/models-dao/src/main/java/org/onap/policy/models/dao/PfDao.java @@ -0,0 +1,205 @@ +/*- + * ============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.dao; + +import java.util.Collection; +import java.util.List; + +import org.onap.policy.models.base.PfConcept; +import org.onap.policy.models.base.PfConceptKey; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.base.PfReferenceKey; + +/** + * The Interface PfDao describes the DAO interface for reading and writing Policy Framework + * {@link PfConcept} concepts to and from databases using JDBC. + */ +public interface PfDao { + + /** + * Initialize the Policy Framework DAO with the given parameters. + * + * @param daoParameters parameters to use to access the database + * @throws PfModelException on initialization errors + */ + void init(DaoParameters daoParameters) throws PfModelException; + + /** + * Close the Policy Framework DAO. + */ + void close(); + + /** + * Creates an Policy Framework concept on the database. + * + * @param <T> the type of the object to create, a subclass of {@link PfConcept} + * @param obj the object to create + */ + <T extends PfConcept> void create(T obj); + + /** + * Delete an Policy Framework concept on the database. + * + * @param <T> the type of the object to delete, a subclass of {@link PfConcept} + * @param obj the object to delete + */ + <T extends PfConcept> void delete(T obj); + + /** + * Delete an Policy Framework concept on the database. + * + * @param <T> the type of the object to delete, a subclass of {@link PfConcept} + * @param someClass the class of the object to delete, a subclass of {@link PfConcept} + * @param key the key of the object to delete + */ + <T extends PfConcept> void delete(Class<T> someClass, PfConceptKey key); + + /** + * Delete an Policy Framework concept on the database. + * + * @param <T> the type of the object to delete, a subclass of {@link PfConcept} + * @param someClass the class of the object to delete, a subclass of {@link PfConcept} + * @param key the key of the object to delete + */ + <T extends PfConcept> void delete(Class<T> someClass, PfReferenceKey key); + + /** + * Create a collection of objects in the database. + * + * @param <T> the type of the object to create, a subclass of {@link PfConcept} + * @param objs the objects to create + */ + <T extends PfConcept> void createCollection(Collection<T> objs); + + /** + * Delete a collection of objects in the database. + * + * @param <T> the type of the objects to delete, a subclass of {@link PfConcept} + * @param objs the objects to delete + */ + <T extends PfConcept> void deleteCollection(Collection<T> objs); + + /** + * Delete a collection of objects in the database referred to by concept key. + * + * @param <T> the type of the objects to delete, a subclass of {@link PfConcept} + * @param someClass the class of the objects to delete, a subclass of {@link PfConcept} + * @param keys the keys of the objects to delete + * @return the number of objects deleted + */ + <T extends PfConcept> int deleteByConceptKey(Class<T> someClass, Collection<PfConceptKey> keys); + + /** + * Delete a collection of objects in the database referred to by reference key. + * + * @param <T> the type of the objects to delete, a subclass of {@link PfConcept} + * @param someClass the class of the objects to delete, a subclass of {@link PfConcept} + * @param keys the keys of the objects to delete + * @return the number of objects deleted + */ + <T extends PfConcept> int deleteByReferenceKey(Class<T> someClass, Collection<PfReferenceKey> keys); + + /** + * Delete all objects of a given class in the database. + * + * @param <T> the type of the objects to delete, a subclass of {@link PfConcept} + * @param someClass the class of the objects to delete, a subclass of {@link PfConcept} + */ + <T extends PfConcept> void deleteAll(Class<T> someClass); + + /** + * Get an object from the database, referred to by concept key. + * + * @param <T> the type of the object to get, a subclass of {@link PfConcept} + * @param someClass the class of the object to get, a subclass of {@link PfConcept} + * @param key the key of the object to get + * @return the object that was retrieved from the database + */ + <T extends PfConcept> T get(Class<T> someClass, PfConceptKey key); + + /** + * Get an object from the database, referred to by reference key. + * + * @param <T> the type of the object to get, a subclass of {@link PfConcept} + * @param someClass the class of the object to get, a subclass of {@link PfConcept} + * @param key the key of the object to get + * @return the object that was retrieved from the database or null if the object was not + * retrieved + */ + <T extends PfConcept> T get(Class<T> someClass, PfReferenceKey key); + + /** + * Get all the objects in the database of a given type. + * + * @param <T> the type of the objects to get, a subclass of {@link PfConcept} + * @param someClass the class of the objects to get, a subclass of {@link PfConcept} + * @return the objects or null if no objects were retrieved + */ + <T extends PfConcept> List<T> getAll(Class<T> someClass); + + /** + * Get all the objects in the database of the given type with the given parent concept key. + * + * @param <T> the type of the objects to get, a subclass of {@link PfConcept} + * @param someClass the class of the objects to get, a subclass of {@link PfConcept} + * @param parentKey the parent key of the concepts to get + * @return the all + */ + <T extends PfConcept> List<T> getAll(Class<T> someClass, PfConceptKey parentKey); + + /** + * Get a concept from the database with the given concept key. + * + * @param <T> the type of the object to get, a subclass of {@link PfConcept} + * @param someClass the class of the object to get, a subclass of {@link PfConcept} + * @param conceptId the concept key of the concept to get + * @return the concept that matches the key or null if the concept is not retrieved + */ + <T extends PfConcept> T getConcept(Class<T> someClass, PfConceptKey conceptId); + + /** + * Get a concept from the database with the given reference key. + * + * @param <T> the type of the object to get, a subclass of {@link PfConcept} + * @param someClass the class of the object to get, a subclass of {@link PfConcept} + * @param conceptId the concept key of the concept to get + * @return the concept that matches the key or null if the concept is not retrieved + */ + <T extends PfConcept> T getConcept(Class<T> someClass, PfReferenceKey conceptId); + + /** + * Get the number of instances of a concept that exist in the database. + * + * @param <T> the type of the object to get, a subclass of {@link PfConcept} + * @param someClass the class of the object to get, a subclass of {@link PfConcept} + * @return the number of instances of the concept in the database + */ + <T extends PfConcept> long size(Class<T> someClass); + + /** + * Update a concept in the database. + * + * @param <T> the type of the object to get, a subclass of {@link PfConcept} + * @param obj the object to update + * @return the updated object + */ + <T extends PfConcept> T update(T obj); +} diff --git a/models-dao/src/main/java/org/onap/policy/models/dao/PfDaoFactory.java b/models-dao/src/main/java/org/onap/policy/models/dao/PfDaoFactory.java new file mode 100644 index 000000000..3b7e31eb8 --- /dev/null +++ b/models-dao/src/main/java/org/onap/policy/models/dao/PfDaoFactory.java @@ -0,0 +1,68 @@ +/*- + * ============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.dao; + +import org.onap.policy.common.utils.validation.Assertions; +import org.onap.policy.models.base.PfModelException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This factory class returns a Policy Framework DAO for the configured persistence mechanism. The + * factory uses the plugin class specified in {@link DaoParameters} to instantiate a DAO instance. + */ +public class PfDaoFactory { + // Get a reference to the logger + private static final Logger LOGGER = LoggerFactory.getLogger(PfDaoFactory.class); + + /** + * Return a Policy Framework DAO for the required Policy Framework DAO plugin class. + * + * @param daoParameters parameters to use to read the database configuration information + * @return the Policy Framework DAO + * @throws PfModelException on invalid JPA plugins + */ + public PfDao createPfDao(final DaoParameters daoParameters) throws PfModelException { + Assertions.argumentOfClassNotNull(daoParameters, PfModelException.class, + "Parameter \"daoParameters\" may not be null"); + + // Get the class for the DAO using reflection + Object pfDaoObject = null; + try { + pfDaoObject = Class.forName(daoParameters.getPluginClass()).newInstance(); + } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { + String errorMessage = + "Policy Framework DAO class not found for DAO plugin \"" + daoParameters.getPluginClass() + "\""; + LOGGER.error(errorMessage, e); + throw new PfModelException(errorMessage, e); + } + + // Check the class is a Policy Framework DAO + if (!(pfDaoObject instanceof PfDao)) { + String errorMessage = "Specified DAO plugin class \"" + daoParameters.getPluginClass() + + "\" does not implement the PfDao interface"; + LOGGER.error(errorMessage); + throw new PfModelException(errorMessage); + } + + return (PfDao) pfDaoObject; + } +} diff --git a/models-dao/src/main/java/org/onap/policy/models/dao/converters/CDataConditioner.java b/models-dao/src/main/java/org/onap/policy/models/dao/converters/CDataConditioner.java new file mode 100644 index 000000000..327f65ece --- /dev/null +++ b/models-dao/src/main/java/org/onap/policy/models/dao/converters/CDataConditioner.java @@ -0,0 +1,69 @@ +/*- + * ============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.dao.converters; + +import javax.persistence.AttributeConverter; +import javax.persistence.Converter; +import javax.xml.bind.annotation.adapters.XmlAdapter; + +/** + * The Class CDATAConditioner converts a CDATA String to and from database format by removing spaces + * at the ends of lines and platform-specific new line endings. + */ +@Converter +public class CDataConditioner extends XmlAdapter<String, String> implements AttributeConverter<String, String> { + + private static final String NL = "\n"; + + @Override + public String convertToDatabaseColumn(final String raw) { + return clean(raw); + } + + @Override + public String convertToEntityAttribute(final String db) { + return clean(db); + } + + @Override + public String unmarshal(final String value) throws Exception { + return this.convertToEntityAttribute(value); + } + + @Override + public String marshal(final String value) throws Exception { + return this.convertToDatabaseColumn(value); + } + + /** + * Clean. + * + * @param in the in + * @return the string + */ + public static final String clean(final String in) { + if (in == null) { + return null; + } else { + return in.replaceAll("\\s+$", "").replaceAll("\\r?\\n", NL); + } + } +} diff --git a/models-dao/src/main/java/org/onap/policy/models/dao/converters/Uuid2String.java b/models-dao/src/main/java/org/onap/policy/models/dao/converters/Uuid2String.java new file mode 100644 index 000000000..a2b1c085a --- /dev/null +++ b/models-dao/src/main/java/org/onap/policy/models/dao/converters/Uuid2String.java @@ -0,0 +1,60 @@ +/*- + * ============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.dao.converters; + +import java.util.UUID; + +import javax.persistence.AttributeConverter; +import javax.persistence.Converter; +import javax.xml.bind.annotation.adapters.XmlAdapter; + +/** + * The Class UUIDConverter converts a UUID to and from database format. + */ +@Converter +public class Uuid2String extends XmlAdapter<String, UUID> implements AttributeConverter<UUID, String> { + + @Override + public String convertToDatabaseColumn(final UUID uuid) { + String returnString; + if (uuid == null) { + returnString = ""; + } else { + returnString = uuid.toString(); + } + return returnString; + } + + @Override + public UUID convertToEntityAttribute(final String uuidString) { + return UUID.fromString(uuidString); + } + + @Override + public UUID unmarshal(final String value) throws Exception { + return this.convertToEntityAttribute(value); + } + + @Override + public String marshal(final UUID value) throws Exception { + return this.convertToDatabaseColumn(value); + } +} diff --git a/models-dao/src/main/java/org/onap/policy/models/dao/converters/package-info.java b/models-dao/src/main/java/org/onap/policy/models/dao/converters/package-info.java new file mode 100644 index 000000000..416eff20c --- /dev/null +++ b/models-dao/src/main/java/org/onap/policy/models/dao/converters/package-info.java @@ -0,0 +1,26 @@ +/*- + * ============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========================================================= + */ + +/** + * Contains converters used by PF EclipseLink marshaling and unmarshaling of + * {@link org.onap.policy.models.base.PfConcept} instances to and from files and databases. + */ + +package org.onap.policy.models.dao.converters; diff --git a/models-dao/src/main/java/org/onap/policy/models/dao/impl/DefaultPfDao.java b/models-dao/src/main/java/org/onap/policy/models/dao/impl/DefaultPfDao.java new file mode 100644 index 000000000..429632db0 --- /dev/null +++ b/models-dao/src/main/java/org/onap/policy/models/dao/impl/DefaultPfDao.java @@ -0,0 +1,415 @@ +/*- + * ============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.dao.impl; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.onap.policy.models.base.PfConcept; +import org.onap.policy.models.base.PfConceptKey; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.base.PfModelRuntimeException; +import org.onap.policy.models.base.PfReferenceKey; +import org.onap.policy.models.dao.DaoParameters; +import org.onap.policy.models.dao.PfDao; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The Class DefaultPfDao is an JPA implementation of the {@link PfDao} class for Policy Framework + * concepts ({@link PfConcept}). It uses the default JPA implementation in the javax + * {@link Persistence} class. + */ +public class DefaultPfDao implements PfDao { + private static final Logger LOGGER = LoggerFactory.getLogger(DefaultPfDao.class); + + private static final String SELECT_C_FROM = "SELECT c FROM "; + private static final String AND_C_KEY_LOCAL_NAME = "' AND c.key.localName='"; + private static final String AND_C_KEY_PARENT_KEY_VERSION = "' AND c.key.parentKeyVersion='"; + private static final String C_WHERE_C_KEY_PARENT_KEY_NAME = " c WHERE c.key.parentKeyName='"; + private static final String AND_C_KEY_VERSION = "' AND c.key.version='"; + private static final String C_WHERE_C_KEY_NAME = " c WHERE c.key.name='"; + private static final String DELETE_FROM = "DELETE FROM "; + + // Entity manager for JPA + private EntityManagerFactory emf = null; + + @Override + public void init(final DaoParameters daoParameters) throws PfModelException { + if (daoParameters == null || daoParameters.getPersistenceUnit() == null) { + LOGGER.error("Policy Framework persistence unit parameter not set"); + throw new PfModelException("Policy Framework persistence unit parameter not set"); + } + + LOGGER.debug("Creating Policy Framework persistence unit \"{}\" . . .", daoParameters.getPersistenceUnit()); + try { + emf = Persistence.createEntityManagerFactory(daoParameters.getPersistenceUnit(), + daoParameters.getJdbcProperties()); + } catch (final Exception ex) { + String errorMessage = "Creation of Policy Framework persistence unit \"" + + daoParameters.getPersistenceUnit() + "\" failed"; + LOGGER.warn(errorMessage, ex); + throw new PfModelException(errorMessage, ex); + } + LOGGER.debug("Created Policy Framework persistence unit \"{}\"", daoParameters.getPersistenceUnit()); + } + + /** + * Gets the entity manager for this DAO. + * + * @return the entity manager + */ + protected final synchronized EntityManager getEntityManager() { + if (emf == null) { + LOGGER.warn("Policy Framework DAO has not been initialized"); + throw new PfModelRuntimeException("Policy Framework DAO has not been initialized"); + } + + return emf.createEntityManager(); + } + + @Override + public final void close() { + if (emf != null) { + emf.close(); + } + } + + @Override + public <T extends PfConcept> void create(final T obj) { + if (obj == null) { + return; + } + final EntityManager mg = getEntityManager(); + try { + mg.getTransaction().begin(); + mg.merge(obj); + mg.getTransaction().commit(); + } finally { + mg.close(); + } + } + + @Override + public <T extends PfConcept> void delete(final T obj) { + if (obj == null) { + return; + } + final EntityManager mg = getEntityManager(); + try { + mg.getTransaction().begin(); + mg.remove(mg.contains(obj) ? obj : mg.merge(obj)); + mg.getTransaction().commit(); + } finally { + mg.close(); + } + } + + @Override + public <T extends PfConcept> void delete(final Class<T> someClass, final PfConceptKey key) { + if (key == null) { + return; + } + final EntityManager mg = getEntityManager(); + try { + mg.getTransaction().begin(); + mg.createQuery(DELETE_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_NAME + key.getName() + + AND_C_KEY_VERSION + key.getVersion() + "'", someClass).executeUpdate(); + mg.getTransaction().commit(); + } finally { + mg.close(); + } + } + + @Override + public <T extends PfConcept> void delete(final Class<T> someClass, final PfReferenceKey key) { + if (key == null) { + return; + } + final EntityManager mg = getEntityManager(); + try { + mg.getTransaction().begin(); + mg.createQuery(DELETE_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_PARENT_KEY_NAME + + key.getParentKeyName() + AND_C_KEY_PARENT_KEY_VERSION + key.getParentKeyVersion() + + AND_C_KEY_LOCAL_NAME + key.getLocalName() + "'", someClass).executeUpdate(); + mg.getTransaction().commit(); + } finally { + mg.close(); + } + } + + @Override + public <T extends PfConcept> void createCollection(final Collection<T> objs) { + if (objs == null || objs.isEmpty()) { + return; + } + final EntityManager mg = getEntityManager(); + try { + mg.getTransaction().begin(); + for (final T t : objs) { + mg.merge(t); + } + mg.getTransaction().commit(); + } finally { + mg.close(); + } + } + + @Override + public <T extends PfConcept> void deleteCollection(final Collection<T> objs) { + if (objs == null || objs.isEmpty()) { + return; + } + final EntityManager mg = getEntityManager(); + try { + mg.getTransaction().begin(); + for (final T t : objs) { + mg.remove(mg.contains(t) ? t : mg.merge(t)); + } + mg.getTransaction().commit(); + } finally { + mg.close(); + } + } + + @Override + public <T extends PfConcept> int deleteByConceptKey(final Class<T> someClass, + final Collection<PfConceptKey> keys) { + if (keys == null || keys.isEmpty()) { + return 0; + } + int deletedCount = 0; + final EntityManager mg = getEntityManager(); + try { + mg.getTransaction().begin(); + for (final PfConceptKey key : keys) { + deletedCount += mg.createQuery(DELETE_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_NAME + + key.getName() + AND_C_KEY_VERSION + key.getVersion() + "'", someClass).executeUpdate(); + } + mg.getTransaction().commit(); + } finally { + mg.close(); + } + return deletedCount; + } + + @Override + public <T extends PfConcept> int deleteByReferenceKey(final Class<T> someClass, + final Collection<PfReferenceKey> keys) { + if (keys == null || keys.isEmpty()) { + return 0; + } + int deletedCount = 0; + final EntityManager mg = getEntityManager(); + try { + mg.getTransaction().begin(); + for (final PfReferenceKey key : keys) { + deletedCount += + mg.createQuery( + DELETE_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_PARENT_KEY_NAME + + key.getParentKeyName() + AND_C_KEY_PARENT_KEY_VERSION + + key.getParentKeyVersion() + AND_C_KEY_LOCAL_NAME + key.getLocalName() + "'", + someClass).executeUpdate(); + } + mg.getTransaction().commit(); + } finally { + mg.close(); + } + return deletedCount; + } + + @Override + public <T extends PfConcept> void deleteAll(final Class<T> someClass) { + final EntityManager mg = getEntityManager(); + try { + mg.getTransaction().begin(); + mg.createQuery(DELETE_FROM + someClass.getSimpleName() + " c ", someClass).executeUpdate(); + mg.getTransaction().commit(); + } finally { + mg.close(); + } + } + + @Override + public <T extends PfConcept> T get(final Class<T> someClass, final PfConceptKey key) { + if (someClass == null) { + return null; + } + final EntityManager mg = getEntityManager(); + try { + final T t = mg.find(someClass, key); + if (t != null) { + // This clone is created to force the JPA DAO to recurse down through the object + try { + final T clonedT = someClass.newInstance(); + t.copyTo(clonedT); + return clonedT; + } catch (final Exception e) { + LOGGER.warn("Could not clone object of class \"" + someClass.getCanonicalName() + "\"", e); + return null; + } + } else { + return null; + } + } finally { + mg.close(); + } + } + + @Override + public <T extends PfConcept> T get(final Class<T> someClass, final PfReferenceKey key) { + if (someClass == null) { + return null; + } + final EntityManager mg = getEntityManager(); + try { + final T t = mg.find(someClass, key); + if (t != null) { + try { + final T clonedT = someClass.newInstance(); + t.copyTo(clonedT); + return clonedT; + } catch (final Exception e) { + LOGGER.warn("Could not clone object of class \"" + someClass.getCanonicalName() + "\"", e); + return null; + } + } else { + return null; + } + } finally { + mg.close(); + } + } + + @Override + public <T extends PfConcept> List<T> getAll(final Class<T> someClass) { + if (someClass == null) { + return Collections.emptyList(); + } + final EntityManager mg = getEntityManager(); + try { + return mg.createQuery(SELECT_C_FROM + someClass.getSimpleName() + " c", someClass).getResultList(); + } finally { + mg.close(); + } + } + + @Override + public <T extends PfConcept> List<T> getAll(final Class<T> someClass, final PfConceptKey parentKey) { + if (someClass == null) { + return Collections.emptyList(); + } + final EntityManager mg = getEntityManager(); + try { + return mg + .createQuery( + SELECT_C_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_PARENT_KEY_NAME + + parentKey.getName() + AND_C_KEY_PARENT_KEY_VERSION + parentKey.getVersion() + "'", + someClass) + .getResultList(); + } finally { + mg.close(); + } + } + + @Override + public <T extends PfConcept> T getConcept(final Class<T> someClass, final PfConceptKey key) { + if (someClass == null || key == null) { + return null; + } + final EntityManager mg = getEntityManager(); + List<T> ret; + try { + ret = mg.createQuery(SELECT_C_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_NAME + key.getName() + + AND_C_KEY_VERSION + key.getVersion() + "'", someClass).getResultList(); + } finally { + mg.close(); + } + if (ret == null || ret.isEmpty()) { + return null; + } + if (ret.size() > 1) { + throw new IllegalArgumentException("More than one result was returned for search for " + someClass + + " with key " + key.getId() + ": " + ret); + } + return ret.get(0); + } + + @Override + public <T extends PfConcept> T getConcept(final Class<T> someClass, final PfReferenceKey key) { + if (someClass == null || key == null) { + return null; + } + final EntityManager mg = getEntityManager(); + List<T> ret; + try { + ret = mg.createQuery(SELECT_C_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_PARENT_KEY_NAME + + key.getParentKeyName() + AND_C_KEY_PARENT_KEY_VERSION + key.getParentKeyVersion() + + AND_C_KEY_LOCAL_NAME + key.getLocalName() + "'", someClass).getResultList(); + } finally { + mg.close(); + } + if (ret == null || ret.isEmpty()) { + return null; + } + if (ret.size() > 1) { + throw new IllegalArgumentException("More than one result was returned for search for " + someClass + + " with key " + key.getId() + ": " + ret); + } + return ret.get(0); + } + + @Override + public <T extends PfConcept> T update(final T obj) { + final EntityManager mg = getEntityManager(); + T ret; + try { + mg.getTransaction().begin(); + ret = mg.merge(obj); + mg.flush(); + mg.getTransaction().commit(); + } finally { + mg.close(); + } + return ret; + } + + @Override + public <T extends PfConcept> long size(final Class<T> someClass) { + if (someClass == null) { + return 0; + } + final EntityManager mg = getEntityManager(); + long size = 0; + try { + size = mg.createQuery("SELECT COUNT(c) FROM " + someClass.getSimpleName() + " c", Long.class) + .getSingleResult(); + } finally { + mg.close(); + } + return size; + } +} diff --git a/models-dao/src/main/java/org/onap/policy/models/dao/impl/package-info.java b/models-dao/src/main/java/org/onap/policy/models/dao/impl/package-info.java new file mode 100644 index 000000000..0d27628a0 --- /dev/null +++ b/models-dao/src/main/java/org/onap/policy/models/dao/impl/package-info.java @@ -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========================================================= + */ + +/** + * Contains a default DAO implementation for the PF {@link org.onap.policy.models.base.PfConcept} + * classes that uses javax persistence. + */ +package org.onap.policy.models.dao.impl; diff --git a/models-dao/src/main/java/org/onap/policy/models/dao/package-info.java b/models-dao/src/main/java/org/onap/policy/models/dao/package-info.java new file mode 100644 index 000000000..e8cfbe4e7 --- /dev/null +++ b/models-dao/src/main/java/org/onap/policy/models/dao/package-info.java @@ -0,0 +1,27 @@ +/*- + * ============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 Data Access Object (DAO) that allows Apex + * {@link org.onap.policy.apex.model.basicmodel.concepts.AxConcept} concepts to be read from and written to databases + * over JDBC. + */ + +package org.onap.policy.models.dao; diff --git a/models-dao/src/test/java/org/onap/policy/models/dao/DaoMiscTest.java b/models-dao/src/test/java/org/onap/policy/models/dao/DaoMiscTest.java new file mode 100644 index 000000000..4dd70cee9 --- /dev/null +++ b/models-dao/src/test/java/org/onap/policy/models/dao/DaoMiscTest.java @@ -0,0 +1,89 @@ +/*- + * ============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.dao; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; + +import java.util.Properties; + +import org.junit.Test; +import org.onap.policy.models.dao.DaoParameters; +import org.onap.policy.models.dao.PfDaoFactory; +import org.onap.policy.models.dao.converters.CDataConditioner; +import org.onap.policy.models.dao.converters.Uuid2String; + +public class DaoMiscTest { + + @Test + public void testUuid2StringMopUp() { + final Uuid2String uuid2String = new Uuid2String(); + assertEquals("", uuid2String.convertToDatabaseColumn(null)); + } + + @Test + public void testCDataConditionerMopUp() { + assertNull(CDataConditioner.clean(null)); + } + + @Test + public void testDaoFactory() { + final DaoParameters daoParameters = new DaoParameters(); + + daoParameters.setPluginClass("somewhere.over.the.rainbow"); + try { + new PfDaoFactory().createPfDao(daoParameters); + fail("test shold throw an exception here"); + } catch (final Exception e) { + assertEquals("Policy Framework DAO class not found for DAO plugin \"somewhere.over.the.rainbow\"", + e.getMessage()); + } + + daoParameters.setPluginClass("java.lang.String"); + try { + new PfDaoFactory().createPfDao(daoParameters); + fail("test shold throw an exception here"); + } catch (final Exception e) { + assertEquals("Specified DAO plugin class \"java.lang.String\" " + "does not implement the PfDao interface", + e.getMessage()); + } + } + + @Test + public void testDaoParameters() { + final DaoParameters pars = new DaoParameters(); + pars.setJdbcProperties(new Properties()); + assertEquals(0, pars.getJdbcProperties().size()); + + pars.setJdbcProperty("name", "Dorothy"); + assertEquals("Dorothy", pars.getJdbcProperty("name")); + + pars.setPersistenceUnit("Kansas"); + assertEquals("Kansas", pars.getPersistenceUnit()); + + pars.setPluginClass("somewhere.over.the.rainbow"); + assertEquals("somewhere.over.the.rainbow", pars.getPluginClass()); + + assertEquals("DAOParameters [pluginClass=somewhere.over.the.rainbow, " + + "persistenceUnit=Kansas, jdbcProperties={name=Dorothy}]", pars.toString()); + } +} diff --git a/models-dao/src/test/java/org/onap/policy/models/dao/DummyConceptEntity.java b/models-dao/src/test/java/org/onap/policy/models/dao/DummyConceptEntity.java new file mode 100644 index 000000000..fa2e71a08 --- /dev/null +++ b/models-dao/src/test/java/org/onap/policy/models/dao/DummyConceptEntity.java @@ -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.dao; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import javax.persistence.Column; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.Table; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NonNull; + +import org.onap.policy.common.utils.validation.Assertions; +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; + +@Entity +@Table(name = "DummyConceptEntity") +@Data +@EqualsAndHashCode(callSuper = false) +public class DummyConceptEntity extends PfConcept { + private static final long serialVersionUID = -2962570563281067894L; + + @EmbeddedId() + @NonNull + private PfConceptKey key; + + @Column + @NonNull + private UUID uuid; + + @Column + @NonNull + private String description; + + public DummyConceptEntity() { + this.key = new PfConceptKey(); + } + + public DummyConceptEntity(final Double doubleValue) { + this.key = new PfConceptKey(); + } + + public DummyConceptEntity(final PfConceptKey key, final Double doubleValue) { + this.key = key; + } + + /** + * Constructor. + * + * @param key the key + * @param uuid the uuid + * @param description the description + */ + public DummyConceptEntity(PfConceptKey key, UUID uuid, String description) { + this.key = key; + this.uuid = uuid; + this.description = description; + } + + @Override + public List<PfKey> getKeys() { + final List<PfKey> keyList = new ArrayList<>(); + keyList.add(getKey()); + return keyList; + } + + @Override + public PfValidationResult validate(final PfValidationResult result) { + return key.validate(result); + } + + @Override + public void clean() { + key.clean(); + } + + @Override + public PfConcept copyTo(final PfConcept target) { + Assertions.argumentNotNull(target, "target may not be null"); + + final PfConcept copyObject = target; + Assertions.instanceOf(copyObject, DummyConceptEntity.class); + + final DummyConceptEntity copy = ((DummyConceptEntity) copyObject); + copy.setKey(key); + copy.setUuid(uuid); + copy.setDescription(description); + + return copyObject; + } + + @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 DummyConceptEntity other = (DummyConceptEntity) otherObj; + + if (!key.equals(other.key)) { + return key.compareTo(other.key); + } + if (!uuid.equals(other.uuid)) { + return uuid.compareTo(other.uuid); + } + return description.compareTo(other.description); + } +} diff --git a/models-dao/src/test/java/org/onap/policy/models/dao/DummyReferenceEntity.java b/models-dao/src/test/java/org/onap/policy/models/dao/DummyReferenceEntity.java new file mode 100644 index 000000000..044a63dc5 --- /dev/null +++ b/models-dao/src/test/java/org/onap/policy/models/dao/DummyReferenceEntity.java @@ -0,0 +1,121 @@ +/*- + * ============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.dao; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.Column; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.Table; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NonNull; + +import org.onap.policy.common.utils.validation.Assertions; +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.PfValidationResult; + +@Entity +@Table(name = "DummyReferenceEntity") +@Data +@EqualsAndHashCode(callSuper = false) +public class DummyReferenceEntity extends PfConcept { + private static final long serialVersionUID = -2962570563281067894L; + + @EmbeddedId() + @NonNull + private PfReferenceKey key; + + @Column + private double doubleValue; + + /** + * Default constructor. + */ + public DummyReferenceEntity() { + this.key = new PfReferenceKey(); + this.doubleValue = 123.45; + } + + /** + * Constructor. + * + * @param key the key + * @param doubleValue the double value + */ + public DummyReferenceEntity(final PfReferenceKey key, final double doubleValue) { + this.key = key; + this.doubleValue = doubleValue; + } + + @Override + public List<PfKey> getKeys() { + final List<PfKey> keyList = new ArrayList<>(); + keyList.add(getKey()); + return keyList; + } + + @Override + public PfValidationResult validate(final PfValidationResult result) { + return key.validate(result); + } + + @Override + public void clean() { + key.clean(); + } + + @Override + public PfConcept copyTo(final PfConcept target) { + Assertions.argumentNotNull(target, "target may not be null"); + + final PfConcept copyObject = target; + Assertions.instanceOf(copyObject, DummyReferenceEntity.class); + + final DummyReferenceEntity copy = ((DummyReferenceEntity) copyObject); + copy.setKey(key); + copy.setDoubleValue(doubleValue); + + return copyObject; + } + + + @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 DummyReferenceEntity other = (DummyReferenceEntity) otherObj; + + return new Double(doubleValue).compareTo(new Double(other.doubleValue)); + } +} diff --git a/models-dao/src/test/java/org/onap/policy/models/dao/EntityTest.java b/models-dao/src/test/java/org/onap/policy/models/dao/EntityTest.java new file mode 100644 index 000000000..8278cfe20 --- /dev/null +++ b/models-dao/src/test/java/org/onap/policy/models/dao/EntityTest.java @@ -0,0 +1,299 @@ +/*- + * ============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.dao; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.File; +import java.sql.Connection; +import java.sql.DriverManager; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; +import java.util.UUID; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onap.policy.models.base.PfConceptKey; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.base.PfReferenceKey; +import org.onap.policy.models.dao.DaoParameters; +import org.onap.policy.models.dao.PfDao; +import org.onap.policy.models.dao.PfDaoFactory; +import org.onap.policy.models.dao.impl.DefaultPfDao; + +/** + * JUnit test class. + */ +public class EntityTest { + private Connection connection; + private PfDao pfDao; + + @Before + public void setup() throws Exception { + connection = DriverManager.getConnection("jdbc:h2:mem:test"); + } + + @After + public void teardown() throws Exception { + connection.close(); + new File("derby.log").delete(); + } + + @Test + public void testEntityTestSanity() throws PfModelException { + final DaoParameters daoParameters = new DaoParameters(); + + pfDao = new PfDaoFactory().createPfDao(daoParameters); + + try { + pfDao.init(null); + fail("Test should throw an exception here"); + } catch (final Exception e) { + assertEquals("Policy Framework persistence unit parameter not set", e.getMessage()); + } + + try { + pfDao.init(daoParameters); + fail("Test should throw an exception here"); + } catch (final Exception e) { + assertEquals("Policy Framework persistence unit parameter not set", e.getMessage()); + } + + daoParameters.setPluginClass("somewhere.over.the.rainbow"); + daoParameters.setPersistenceUnit("Dorothy"); + try { + pfDao.init(daoParameters); + fail("Test should throw an exception here"); + } catch (final Exception e) { + assertEquals("Creation of Policy Framework persistence unit \"Dorothy\" failed", e.getMessage()); + } + try { + pfDao.create(new PfConceptKey()); + fail("Test should throw an exception here"); + } catch (final Exception e) { + assertEquals("Policy Framework DAO has not been initialized", e.getMessage()); + } + pfDao.close(); + } + + @Test + public void testEntityTestAllOpsJpa() throws PfModelException { + final DaoParameters daoParameters = new DaoParameters(); + daoParameters.setPluginClass(DefaultPfDao.class.getCanonicalName()); + daoParameters.setPersistenceUnit("DaoTest"); + + pfDao = new PfDaoFactory().createPfDao(daoParameters); + pfDao.init(daoParameters); + + testAllOps(); + pfDao.close(); + } + + @Test + public void testEntityTestBadVals() throws PfModelException { + final DaoParameters daoParameters = new DaoParameters(); + daoParameters.setPluginClass(DefaultPfDao.class.getCanonicalName()); + daoParameters.setPersistenceUnit("DaoTest"); + + pfDao = new PfDaoFactory().createPfDao(daoParameters); + pfDao.init(daoParameters); + + final PfConceptKey nullKey = null; + final PfReferenceKey nullRefKey = null; + final List<PfConceptKey> nullKeyList = null; + final List<PfConceptKey> emptyKeyList = new ArrayList<>(); + final List<PfReferenceKey> nullRKeyList = null; + final List<PfReferenceKey> emptyRKeyList = new ArrayList<>(); + + pfDao.create(nullKey); + pfDao.createCollection(nullKeyList); + pfDao.createCollection(emptyKeyList); + + pfDao.delete(nullKey); + pfDao.deleteCollection(nullKeyList); + pfDao.deleteCollection(emptyKeyList); + pfDao.delete(PfConceptKey.class, nullKey); + pfDao.delete(PfReferenceKey.class, nullRefKey); + pfDao.deleteByConceptKey(PfConceptKey.class, nullKeyList); + pfDao.deleteByConceptKey(PfConceptKey.class, emptyKeyList); + pfDao.deleteByReferenceKey(PfReferenceKey.class, nullRKeyList); + pfDao.deleteByReferenceKey(PfReferenceKey.class, emptyRKeyList); + + pfDao.get(null, nullKey); + pfDao.get(null, nullRefKey); + pfDao.getAll(null); + pfDao.getAll(null, nullKey); + pfDao.getConcept(null, nullKey); + pfDao.getConcept(PfConceptKey.class, nullKey); + pfDao.getConcept(null, nullRefKey); + pfDao.getConcept(PfReferenceKey.class, nullRefKey); + pfDao.size(null); + + pfDao.close(); + } + + private void testAllOps() { + final PfConceptKey aKey0 = new PfConceptKey("A-KEY0", "0.0.1"); + final PfConceptKey aKey1 = new PfConceptKey("A-KEY1", "0.0.1"); + final PfConceptKey aKey2 = new PfConceptKey("A-KEY2", "0.0.1"); + final DummyConceptEntity keyInfo0 = new DummyConceptEntity(aKey0, + UUID.fromString("00000000-0000-0000-0000-000000000000"), "key description 0"); + final DummyConceptEntity keyInfo1 = new DummyConceptEntity(aKey1, + UUID.fromString("00000000-0000-0000-0000-000000000001"), "key description 1"); + final DummyConceptEntity keyInfo2 = new DummyConceptEntity(aKey2, + UUID.fromString("00000000-0000-0000-0000-000000000002"), "key description 2"); + + pfDao.create(keyInfo0); + + final DummyConceptEntity keyInfoBack0 = pfDao.get(DummyConceptEntity.class, aKey0); + assertTrue(keyInfo0.equals(keyInfoBack0)); + + final DummyConceptEntity keyInfoBackNull = pfDao.get(DummyConceptEntity.class, PfConceptKey.getNullKey()); + assertNull(keyInfoBackNull); + + final DummyConceptEntity keyInfoBack1 = pfDao.getConcept(DummyConceptEntity.class, aKey0); + assertTrue(keyInfoBack0.equals(keyInfoBack1)); + + final DummyConceptEntity keyInfoBack2 = + pfDao.getConcept(DummyConceptEntity.class, new PfConceptKey("A-KEY3", "0.0.1")); + assertNull(keyInfoBack2); + + final Set<DummyConceptEntity> keyInfoSetIn = new TreeSet<DummyConceptEntity>(); + keyInfoSetIn.add(keyInfo1); + keyInfoSetIn.add(keyInfo2); + + pfDao.createCollection(keyInfoSetIn); + + Set<DummyConceptEntity> keyInfoSetOut = new TreeSet<DummyConceptEntity>(pfDao.getAll(DummyConceptEntity.class)); + + keyInfoSetIn.add(keyInfo0); + assertTrue(keyInfoSetIn.equals(keyInfoSetOut)); + + pfDao.delete(keyInfo1); + keyInfoSetIn.remove(keyInfo1); + keyInfoSetOut = new TreeSet<DummyConceptEntity>(pfDao.getAll(DummyConceptEntity.class)); + assertTrue(keyInfoSetIn.equals(keyInfoSetOut)); + + pfDao.deleteCollection(keyInfoSetIn); + keyInfoSetOut = new TreeSet<DummyConceptEntity>(pfDao.getAll(DummyConceptEntity.class)); + assertEquals(0, keyInfoSetOut.size()); + + keyInfoSetIn.add(keyInfo0); + keyInfoSetIn.add(keyInfo1); + keyInfoSetIn.add(keyInfo0); + pfDao.createCollection(keyInfoSetIn); + keyInfoSetOut = new TreeSet<DummyConceptEntity>(pfDao.getAll(DummyConceptEntity.class)); + assertTrue(keyInfoSetIn.equals(keyInfoSetOut)); + + pfDao.delete(DummyConceptEntity.class, aKey0); + keyInfoSetOut = new TreeSet<DummyConceptEntity>(pfDao.getAll(DummyConceptEntity.class)); + assertEquals(2, keyInfoSetOut.size()); + assertEquals(2, pfDao.size(DummyConceptEntity.class)); + + final Set<PfConceptKey> keySetIn = new TreeSet<PfConceptKey>(); + keySetIn.add(aKey1); + keySetIn.add(aKey2); + + final int deletedCount = pfDao.deleteByConceptKey(DummyConceptEntity.class, keySetIn); + assertEquals(2, deletedCount); + + keyInfoSetOut = new TreeSet<DummyConceptEntity>(pfDao.getAll(DummyConceptEntity.class)); + assertEquals(0, keyInfoSetOut.size()); + + keyInfoSetIn.add(keyInfo0); + keyInfoSetIn.add(keyInfo1); + keyInfoSetIn.add(keyInfo0); + pfDao.createCollection(keyInfoSetIn); + keyInfoSetOut = new TreeSet<DummyConceptEntity>(pfDao.getAll(DummyConceptEntity.class)); + assertTrue(keyInfoSetIn.equals(keyInfoSetOut)); + + pfDao.deleteAll(DummyConceptEntity.class); + assertEquals(0, pfDao.size(DummyConceptEntity.class)); + + final PfConceptKey owner0Key = new PfConceptKey("Owner0", "0.0.1"); + final PfConceptKey owner1Key = new PfConceptKey("Owner1", "0.0.1"); + final PfConceptKey owner2Key = new PfConceptKey("Owner2", "0.0.1"); + final PfConceptKey owner3Key = new PfConceptKey("Owner3", "0.0.1"); + final PfConceptKey owner4Key = new PfConceptKey("Owner4", "0.0.1"); + final PfConceptKey owner5Key = new PfConceptKey("Owner5", "0.0.1"); + + pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner0Key, "Entity0"), 100.0)); + pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner0Key, "Entity1"), 101.0)); + pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner0Key, "Entity2"), 102.0)); + pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner0Key, "Entity3"), 103.0)); + pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner0Key, "Entity4"), 104.0)); + pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner1Key, "Entity5"), 105.0)); + pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner1Key, "Entity6"), 106.0)); + pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner1Key, "Entity7"), 107.0)); + pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner2Key, "Entity8"), 108.0)); + pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner2Key, "Entity9"), 109.0)); + pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner3Key, "EntityA"), 110.0)); + pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner4Key, "EntityB"), 111.0)); + pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner5Key, "EntityC"), 112.0)); + pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner5Key, "EntityD"), 113.0)); + pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner5Key, "EntityE"), 114.0)); + pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner5Key, "EntityF"), 115.0)); + + TreeSet<DummyReferenceEntity> testEntitySetOut = + new TreeSet<DummyReferenceEntity>(pfDao.getAll(DummyReferenceEntity.class)); + assertEquals(16, testEntitySetOut.size()); + + testEntitySetOut = new TreeSet<DummyReferenceEntity>(pfDao.getAll(DummyReferenceEntity.class, owner0Key)); + assertEquals(5, testEntitySetOut.size()); + + testEntitySetOut = new TreeSet<DummyReferenceEntity>(pfDao.getAll(DummyReferenceEntity.class, owner1Key)); + assertEquals(3, testEntitySetOut.size()); + + testEntitySetOut = new TreeSet<DummyReferenceEntity>(pfDao.getAll(DummyReferenceEntity.class, owner2Key)); + assertEquals(2, testEntitySetOut.size()); + + testEntitySetOut = new TreeSet<DummyReferenceEntity>(pfDao.getAll(DummyReferenceEntity.class, owner3Key)); + assertEquals(1, testEntitySetOut.size()); + + testEntitySetOut = new TreeSet<DummyReferenceEntity>(pfDao.getAll(DummyReferenceEntity.class, owner4Key)); + assertEquals(1, testEntitySetOut.size()); + + testEntitySetOut = new TreeSet<DummyReferenceEntity>(pfDao.getAll(DummyReferenceEntity.class, owner5Key)); + assertEquals(4, testEntitySetOut.size()); + + assertNotNull(pfDao.get(DummyReferenceEntity.class, new PfReferenceKey(owner0Key, "Entity0"))); + assertNotNull(pfDao.getConcept(DummyReferenceEntity.class, new PfReferenceKey(owner0Key, "Entity0"))); + assertNull(pfDao.get(DummyReferenceEntity.class, new PfReferenceKey(owner0Key, "Entity1000"))); + assertNull(pfDao.getConcept(DummyReferenceEntity.class, new PfReferenceKey(owner0Key, "Entity1000"))); + pfDao.delete(DummyReferenceEntity.class, new PfReferenceKey(owner0Key, "Entity0")); + + final Set<PfReferenceKey> rKeySetIn = new TreeSet<PfReferenceKey>(); + rKeySetIn.add(new PfReferenceKey(owner4Key, "EntityB")); + rKeySetIn.add(new PfReferenceKey(owner5Key, "EntityD")); + + final int deletedRCount = pfDao.deleteByReferenceKey(DummyReferenceEntity.class, rKeySetIn); + assertEquals(2, deletedRCount); + + pfDao.update(new DummyReferenceEntity(new PfReferenceKey(owner5Key, "EntityF"), 120.0)); + } +} diff --git a/models-dao/src/test/resources/META-INF/persistence.xml b/models-dao/src/test/resources/META-INF/persistence.xml new file mode 100644 index 000000000..1f430bc8b --- /dev/null +++ b/models-dao/src/test/resources/META-INF/persistence.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============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========================================================= +--> + +<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0"> + <persistence-unit name="DaoTest" transaction-type="RESOURCE_LOCAL"> + <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> + + <class>org.onap.policy.models.dao.converters.CDataConditioner</class> + <class>org.onap.policy.models.dao.converters.Uuid2String</class> + <class>org.onap.policy.models.base.concepts.PfConcepttKey</class> + <class>org.onap.policy.models.dao.DummyConceptEntity</class> + <class>org.onap.policy.models.dao.DummyReferenceEntity</class> + + <properties> + <property name="javax.persistence.jdbc.driver" value="org.h2.Driver" /> + <property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:testdb" /> + <property name="javax.persistence.jdbc.user" value="sa" /> + <property name="javax.persistence.jdbc.password" value="" /> + <property name="eclipselink.ddl-generation" value="drop-and-create-tables" /> + <property name="eclipselink.ddl-generation.output-mode" value="database" /> + <property name="eclipselink.logging.level" value="INFO" /> + </properties> + </persistence-unit> +</persistence> diff --git a/models-dao/src/test/resources/logback-test.xml b/models-dao/src/test/resources/logback-test.xml new file mode 100644 index 000000000..f0c510c78 --- /dev/null +++ b/models-dao/src/test/resources/logback-test.xml @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============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========================================================= +--> + +<configuration> + + <contextName>PolicyModels</contextName> + <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" /> + <property name="LOG_DIR" value="${java.io.tmpdir}/onap_policy_logging/" /> + + <!-- USE FOR STD OUT ONLY --> + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + <encoder> + <Pattern>%d %contextName [%t] %level %logger{36} - %msg%n</Pattern> + </encoder> + </appender> + + <root level="INFO"> + <appender-ref ref="STDOUT" /> + </root> + + <logger name="org.infinispan" level="INFO" additivity="false"> + <appender-ref ref="STDOUT" /> + </logger> + + <logger name="org.apache.zookeeper.ClientCnxn" level="OFF" additivity="false"> + <appender-ref ref="STDOUT" /> + </logger> + + <appender name="FILE" class="ch.qos.logback.core.FileAppender"> + <file>${LOG_DIR}/models.log</file> + <encoder> + <pattern>%d %-5relative [procId=${processId}] [%thread] %-5level + %logger{26} - %msg %n %ex{full}</pattern> + </encoder> + </appender> + + <logger name="org.onap.policy.models.dao" level="INFO" additivity="false"> + <appender-ref ref="STDOUT" /> + </logger> +</configuration> diff --git a/models-tosca/pom.xml b/models-tosca/pom.xml new file mode 100644 index 000000000..839cc72c8 --- /dev/null +++ b/models-tosca/pom.xml @@ -0,0 +1,42 @@ +<!-- + ============LICENSE_START======================================================= + 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. + + 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-tosca</artifactId> + + <name>${project.artifactId}</name> + <description>The platform models that are shared across different policy components</description> + + <dependencies> + <dependency> + <groupId>org.onap.policy.models</groupId> + <artifactId>policy-models-base</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> +</project> diff --git a/platform/src/main/java/org/onap/policy/model/tosca/ToscaConstraint.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaConstraint.java index 21ae4c516..47a4d35a6 100644 --- a/platform/src/main/java/org/onap/policy/model/tosca/ToscaConstraint.java +++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaConstraint.java @@ -20,7 +20,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.policy.model.tosca; +package org.onap.policy.models.tosca; import com.google.gson.annotations.SerializedName; import lombok.Getter; @@ -28,7 +28,7 @@ import lombok.Setter; import lombok.ToString; /** - * Class to represent the Constraint of property in TOSCA definition + * Class to represent the Constraint of property in TOSCA definition. * * @author Chenfei Gao (cgao@research.att.com) * diff --git a/platform/src/main/java/org/onap/policy/model/tosca/ToscaDataType.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaDataType.java index 607c53c9d..0366ee467 100644 --- a/platform/src/main/java/org/onap/policy/model/tosca/ToscaDataType.java +++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaDataType.java @@ -20,24 +20,24 @@ * ============LICENSE_END========================================================= */ -package org.onap.policy.model.tosca; +package org.onap.policy.models.tosca; import com.google.gson.annotations.SerializedName; import java.util.List; import java.util.Map; + import lombok.Getter; import lombok.Setter; import lombok.ToString; /** - * Class to represent custom data type in TOSCA definition + * Class to represent custom data type in TOSCA definition. * * @author Chenfei Gao (cgao@research.att.com) * */ @ToString public class ToscaDataType { - @Getter @Setter @SerializedName("derived_from") diff --git a/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaEntityType.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaEntityType.java new file mode 100644 index 000000000..52a82cc53 --- /dev/null +++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaEntityType.java @@ -0,0 +1,168 @@ +/*- + * ============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.tosca; + +import com.google.gson.annotations.SerializedName; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NonNull; + +import org.onap.policy.common.utils.validation.Assertions; +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; + +/** + * Class to represent the EntrySchema of list/map property in TOSCA definition. + */ +@Entity +@Table(name = "ToscaEntityType") +@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) +@Data +@EqualsAndHashCode(callSuper = false) +public class ToscaEntityType extends PfConcept { + private static final long serialVersionUID = -1330661834220739393L; + + @EmbeddedId + @NonNull + private PfConceptKey key = PfConceptKey.getNullKey(); + + @SerializedName("derived_from") + @Column(name = "derivedFrom") + private PfConceptKey derivedFrom; + + @OneToMany(cascade = CascadeType.ALL) + private Map<String, String> metadata; + + @Column(name = "description") + private String description; + + /** + * The Default Constructor creates a {@link ToscaEntityType} object with a null key. + */ + public ToscaEntityType() { + this(new PfConceptKey()); + } + + /** + * The Key Constructor creates a {@link ToscaEntityType} object with the given concept key. + * + * @param key the key + */ + public ToscaEntityType(@NonNull final PfConceptKey key) { + this.key = key; + } + + /** + * Copy constructor. + * + * @param copyConcept the concept to copy from + */ + public ToscaEntityType(final ToscaEntityType copyConcept) { + super(copyConcept); + } + + @Override + public List<PfKey> getKeys() { + final List<PfKey> keyList = new ArrayList<>(); + keyList.add(getKey()); + return keyList; + } + + @Override + public void clean() { + description = description.trim(); + + for (Entry<String, String> metadataEntry : metadata.entrySet()) { + metadataEntry.setValue(metadataEntry.getValue().trim()); + } + } + + @Override + public PfValidationResult validate(PfValidationResult result) { + return null; + } + + @Override + public int compareTo(final PfConcept otherConcept) { + if (otherConcept == null) { + return -1; + } + if (this == otherConcept) { + return 0; + } + if (getClass() != otherConcept.getClass()) { + return this.hashCode() - otherConcept.hashCode(); + } + + final ToscaEntityType other = (ToscaEntityType) otherConcept; + if (!key.equals(other.key)) { + return key.compareTo(other.key); + } + + if (!derivedFrom.equals(other.derivedFrom)) { + return derivedFrom.compareTo(other.derivedFrom); + } + + if (!metadata.equals(other.metadata)) { + return (metadata.hashCode() - other.metadata.hashCode()); + } + + return description.compareTo(other.description); + } + + @Override + public PfConcept copyTo(@NonNull PfConcept target) { + final Object copyObject = target; + Assertions.instanceOf(copyObject, PfConcept.class); + + final ToscaEntityType copy = ((ToscaEntityType) copyObject); + copy.key = new PfConceptKey(key); + copy.derivedFrom = new PfConceptKey(derivedFrom); + + final Map<String, String> newMatadata = new TreeMap<>(); + for (final Entry<String, String> metadataEntry : metadata.entrySet()) { + newMatadata.put(metadataEntry.getKey(), metadataEntry.getValue()); + } + copy.metadata = newMatadata; + + copy.description = description; + + return copy; + } +} diff --git a/platform/src/main/java/org/onap/policy/model/tosca/ToscaEntrySchema.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaEntrySchema.java index b036dc60f..b3079afc0 100644 --- a/platform/src/main/java/org/onap/policy/model/tosca/ToscaEntrySchema.java +++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaEntrySchema.java @@ -20,16 +20,17 @@ * ============LICENSE_END========================================================= */ -package org.onap.policy.model.tosca; +package org.onap.policy.models.tosca; import com.google.gson.annotations.SerializedName; import java.util.List; + import lombok.Getter; import lombok.Setter; import lombok.ToString; /** - * Class to represent the EntrySchema of list/map property in TOSCA definition + * Class to represent the EntrySchema of list/map property in TOSCA definition. * * @author Chenfei Gao (cgao@research.att.com) * diff --git a/platform/src/main/java/org/onap/policy/model/tosca/ToscaEventFilter.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaEventFilter.java index 74277d3a7..34d791202 100644 --- a/platform/src/main/java/org/onap/policy/model/tosca/ToscaEventFilter.java +++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaEventFilter.java @@ -20,7 +20,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.policy.model.tosca; +package org.onap.policy.models.tosca; import com.google.gson.annotations.SerializedName; import lombok.Getter; @@ -28,7 +28,7 @@ import lombok.Setter; import lombok.ToString; /** - * Class to represent the EventFilter in TOSCA definition + * Class to represent the EventFilter in TOSCA definition. * * @author Chenfei Gao (cgao@research.att.com) * diff --git a/platform/src/main/java/org/onap/policy/model/tosca/ToscaPolicy.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaPolicy.java index 8f72dcb0b..4f9210c43 100644 --- a/platform/src/main/java/org/onap/policy/model/tosca/ToscaPolicy.java +++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaPolicy.java @@ -20,7 +20,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.policy.model.tosca; +package org.onap.policy.models.tosca; import com.google.gson.annotations.SerializedName; import java.util.List; @@ -30,7 +30,7 @@ import lombok.Setter; import lombok.ToString; /** - * Class to represent the policy in TOSCA definition + * Class to represent the policy in TOSCA definition. * * @author Chenfei Gao (cgao@research.att.com) * diff --git a/platform/src/main/java/org/onap/policy/model/tosca/ToscaPolicyList.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaPolicyList.java index ecc1251fb..ad8f1a498 100644 --- a/platform/src/main/java/org/onap/policy/model/tosca/ToscaPolicyList.java +++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaPolicyList.java @@ -20,7 +20,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.policy.model.tosca; +package org.onap.policy.models.tosca; import com.google.gson.annotations.SerializedName; import java.util.List; @@ -30,7 +30,7 @@ import lombok.Setter; import lombok.ToString; /** - * Class to represent the policy list in TOSCA definition + * Class to represent the policy list in TOSCA definition. * * @author Chenfei Gao (cgao@research.att.com) * diff --git a/platform/src/main/java/org/onap/policy/model/tosca/ToscaPolicyType.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaPolicyType.java index 8bb5200a7..241e178f5 100644 --- a/platform/src/main/java/org/onap/policy/model/tosca/ToscaPolicyType.java +++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaPolicyType.java @@ -20,7 +20,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.policy.model.tosca; +package org.onap.policy.models.tosca; import com.google.gson.annotations.SerializedName; import java.util.List; @@ -30,7 +30,7 @@ import lombok.Setter; import lombok.ToString; /** - * Class to represent the policy type in TOSCA definition + * Class to represent the policy type in TOSCA definition. * * @author Chenfei Gao (cgao@research.att.com) * diff --git a/platform/src/main/java/org/onap/policy/model/tosca/ToscaPolicyTypeList.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaPolicyTypeList.java index d5ca357c5..4a6a42dbd 100644 --- a/platform/src/main/java/org/onap/policy/model/tosca/ToscaPolicyTypeList.java +++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaPolicyTypeList.java @@ -20,7 +20,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.policy.model.tosca; +package org.onap.policy.models.tosca; import com.google.gson.annotations.SerializedName; import java.util.List; @@ -30,7 +30,7 @@ import lombok.Setter; import lombok.ToString; /** - * Class to represent the policy type list in TOSCA definition + * Class to represent the policy type list in TOSCA definition. * * @author Chenfei Gao (cgao@research.att.com) * diff --git a/platform/src/main/java/org/onap/policy/model/tosca/ToscaProperty.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaProperty.java index 6196637c1..4ee5c45ec 100644 --- a/platform/src/main/java/org/onap/policy/model/tosca/ToscaProperty.java +++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaProperty.java @@ -20,16 +20,21 @@ * ============LICENSE_END========================================================= */ -package org.onap.policy.model.tosca; +package org.onap.policy.models.tosca; import com.google.gson.annotations.SerializedName; import java.util.List; + +import javax.persistence.Column; + import lombok.Getter; import lombok.Setter; import lombok.ToString; +import org.onap.policy.models.base.PfConceptKey; + /** - * Class to represent the property in TOSCA definition + * Class to represent the property in TOSCA definition. * * @author Chenfei Gao (cgao@research.att.com) * @@ -40,7 +45,8 @@ public class ToscaProperty { @Getter @Setter @SerializedName("type") - private String type; + @Column(name = "derivedFrom") + private PfConceptKey type; @Getter @Setter diff --git a/platform/src/main/java/org/onap/policy/model/tosca/ToscaTimeInterval.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaTimeInterval.java index d63b4e039..86334ab7f 100644 --- a/platform/src/main/java/org/onap/policy/model/tosca/ToscaTimeInterval.java +++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaTimeInterval.java @@ -20,7 +20,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.policy.model.tosca; +package org.onap.policy.models.tosca; import com.google.gson.annotations.SerializedName; import lombok.Getter; @@ -28,14 +28,13 @@ import lombok.Setter; import lombok.ToString; /** - * Class to represent the TimeInterval in TOSCA definition + * Class to represent the TimeInterval in TOSCA definition. * * @author Chenfei Gao (cgao@research.att.com) * */ @ToString public class ToscaTimeInterval { - @Getter @Setter @SerializedName("start_time") @@ -45,4 +44,5 @@ public class ToscaTimeInterval { @Setter @SerializedName("end_time") private String endTime; + }
\ No newline at end of file diff --git a/platform/src/main/java/org/onap/policy/model/tosca/ToscaTrigger.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaTrigger.java index f5ca07cbb..2464c2e06 100644 --- a/platform/src/main/java/org/onap/policy/model/tosca/ToscaTrigger.java +++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaTrigger.java @@ -20,7 +20,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.policy.model.tosca; +package org.onap.policy.models.tosca; import com.google.gson.annotations.SerializedName; import lombok.Getter; @@ -28,7 +28,7 @@ import lombok.Setter; import lombok.ToString; /** - * Class to represent the trigger of policy type in TOSCA definition + * Class to represent the trigger of policy type in TOSCA definition. * * @author Chenfei Gao (cgao@research.att.com) * diff --git a/platform/src/test/java/org/onap/policy/tosca/TestPojos.java b/models-tosca/src/test/java/org/onap/policy/models/tosca/TestPojos.java index e86c75904..28cd4cc92 100644 --- a/platform/src/test/java/org/onap/policy/tosca/TestPojos.java +++ b/models-tosca/src/test/java/org/onap/policy/models/tosca/TestPojos.java @@ -20,7 +20,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.policy.tosca; +package org.onap.policy.models.tosca; import com.openpojo.reflection.filters.FilterPackageInfo; import com.openpojo.validation.Validator; @@ -34,14 +34,14 @@ import org.junit.Test; import org.onap.policy.common.utils.validation.ToStringTester; /** - * Class to perform unit tests of all pojos + * Class to perform unit tests of all pojos. * * @author Chenfei Gao (cgao@research.att.com) * */ public class TestPojos { - private static final String POJO_PACKAGE = "org.onap.policy.model.tosca"; + private static final String POJO_PACKAGE = "org.onap.policy.models.tosca"; @Test public void testPojos() { diff --git a/platform/pom.xml b/platform/pom.xml deleted file mode 100644 index 8e0434837..000000000 --- a/platform/pom.xml +++ /dev/null @@ -1,68 +0,0 @@ -<!-- - ============LICENSE_START======================================================= - 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. - - 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>platform</artifactId> - - <name>${project.artifactId}</name> - <description>The platform models that are shared across different policy components</description> - - <dependencies> - <dependency> - <groupId>org.projectlombok</groupId> - <artifactId>lombok</artifactId> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>com.google.code.gson</groupId> - <artifactId>gson</artifactId> - </dependency> - <dependency> - <groupId>org.onap.policy.common</groupId> - <artifactId>utils</artifactId> - </dependency> - </dependencies> - - <build> - <resources> - <!-- Output the version of the pap service --> - <resource> - <directory>src/main/resources</directory> - <filtering>true</filtering> - <includes> - <include>**/version.txt</include> - </includes> - </resource> - <resource> - <directory>src/main/resources</directory> - <filtering>false</filtering> - <excludes> - <exclude>**/version.txt</exclude> - </excludes> - </resource> - </resources> - </build> -</project>
\ No newline at end of file @@ -20,7 +20,8 @@ ============LICENSE_END========================================================= --> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +<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> @@ -38,35 +39,63 @@ <description>This repo holds model code agnostic to PDP engines</description> <properties> + <derby.version>10.13.1.1</derby.version> + <policy.common.version>1.4.0-SNAPSHOT</policy.common.version> + <!-- sonar/jacoco overrides --> <!-- Overriding oparent default sonar/jacoco settings Combine all our reports into one file shared across sub-modules --> <sonar.jacoco.reportPath>${project.basedir}/../target/code-coverage/jacoco-ut.exec</sonar.jacoco.reportPath> <sonar.jacoco.itReportPath>${project.basedir}/../target/code-coverage/jacoco-it.exec</sonar.jacoco.itReportPath> <sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis> - - <policy.common.version>1.4.0-SNAPSHOT</policy.common.version> </properties> <modules> - <module>platform</module> <module>models-base</module> <module>models-dao</module> + <module>models-tosca</module> </modules> + <distributionManagement> + <site> + <id>ecomp-site</id> + <url>dav:${nexusproxy}${sitePath}</url> + </site> + </distributionManagement> + <dependencies> <dependency> + <groupId>org.onap.policy.common</groupId> + <artifactId>utils</artifactId> + </dependency> + + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + + <dependency> + <groupId>org.projectlombok</groupId> + <artifactId>lombok</artifactId> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + </dependency> + + <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> - </dependencies> - <distributionManagement> - <site> - <id>ecomp-site</id> - <url>dav:${nexusproxy}${sitePath}</url> - </site> - </distributionManagement> + <dependency> + <groupId>org.eclipse.persistence</groupId> + <artifactId>eclipselink</artifactId> + </dependency> + + </dependencies> <dependencyManagement> <dependencies> |