* ============LICENSE_START=======================================================
* ONAP Policy Model
* ================================================================================
- * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
- * Modifications Copyright (C) 2019 Nordix Foundation.
+ * Copyright (C) 2019-2021 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2019-2021, 2023 Nordix Foundation.
+ * Modifications Copyright (C) 2022 Bell Canada. 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.
package org.onap.policy.models.tosca.simple.concepts;
-import java.util.ArrayList;
+import jakarta.persistence.CollectionTable;
+import jakarta.persistence.ElementCollection;
+import jakarta.persistence.Entity;
+import jakarta.persistence.Inheritance;
+import jakarta.persistence.InheritanceType;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.Table;
+import jakarta.ws.rs.core.Response;
+import java.io.Serial;
import java.util.LinkedHashMap;
import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import javax.persistence.AttributeOverride;
-import javax.persistence.AttributeOverrides;
-import javax.persistence.Column;
-import javax.persistence.ElementCollection;
-import javax.persistence.Entity;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.Lob;
-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.common.utils.validation.ParameterValidationUtils;
-import org.onap.policy.models.base.PfAuthorative;
+import org.onap.policy.common.parameters.BeanValidationResult;
+import org.onap.policy.common.parameters.annotations.NotNull;
+import org.onap.policy.common.parameters.annotations.Valid;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.common.utils.coder.StandardCoder;
import org.onap.policy.models.base.PfConcept;
import org.onap.policy.models.base.PfConceptKey;
import org.onap.policy.models.base.PfKey;
+import org.onap.policy.models.base.PfModelRuntimeException;
import org.onap.policy.models.base.PfUtils;
-import org.onap.policy.models.base.PfValidationMessage;
-import org.onap.policy.models.base.PfValidationResult;
-import org.onap.policy.models.base.PfValidationResult.ValidationResult;
import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
/**
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Data
@EqualsAndHashCode(callSuper = true)
-public class JpaToscaPolicy extends JpaToscaEntityType<ToscaPolicy> implements PfAuthorative<ToscaPolicy> {
+public class JpaToscaPolicy extends JpaToscaWithTypeAndStringProperties<ToscaPolicy> {
+ @Serial
private static final long serialVersionUID = 3265174757061982805L;
+ private static final String METADATA_METADATA_SET_NAME_TAG = "metadataSetName";
+ private static final String METADATA_METADATA_SET_VERSION_TAG = "metadataSetVersion";
// Tags for metadata
private static final String METADATA_POLICY_ID_TAG = "policy-id";
private static final String METADATA_POLICY_VERSION_TAG = "policy-version";
- // @formatter:off
- @Column
- @AttributeOverrides({
- @AttributeOverride(name = "name",
- column = @Column(name = "type_name")),
- @AttributeOverride(name = "version",
- column = @Column(name = "type_version"))
- })
- private PfConceptKey type;
+ private static final StandardCoder STANDARD_CODER = new StandardCoder();
@ElementCollection
- @Lob
- private Map<String, String> properties;
-
- @ElementCollection
- private List<PfConceptKey> targets;
- // @formatter:on
+ @CollectionTable(joinColumns = {
+ @JoinColumn(name = "toscaPolicyName", referencedColumnName = "name"),
+ @JoinColumn(name = "toscaPolicyVersion", referencedColumnName = "version")
+ })
+ private List<@NotNull @Valid PfConceptKey> targets;
/**
* The Default Constructor creates a {@link JpaToscaPolicy} object with a null key.
*/
public JpaToscaPolicy() {
- this(new PfConceptKey());
+ super();
}
/**
* @param key the key
*/
public JpaToscaPolicy(@NonNull final PfConceptKey key) {
- this(key, new PfConceptKey());
+ super(key, new PfConceptKey());
}
/**
* @param type the type of the policy
*/
public JpaToscaPolicy(@NonNull final PfConceptKey key, @NonNull final PfConceptKey type) {
- super(key);
- this.type = type;
+ super(key, type);
}
/**
*/
public JpaToscaPolicy(@NonNull final JpaToscaPolicy copyConcept) {
super(copyConcept);
+ this.targets = PfUtils.mapList(copyConcept.targets, PfConceptKey::new);
}
/**
*/
public JpaToscaPolicy(final ToscaPolicy authorativeConcept) {
super(new PfConceptKey());
- type = new PfConceptKey();
this.fromAuthorative(authorativeConcept);
}
@Override
public ToscaPolicy toAuthorative() {
- ToscaPolicy toscaPolicy = new ToscaPolicy();
+ var toscaPolicy = new ToscaPolicy();
super.setToscaEntity(toscaPolicy);
super.toAuthorative();
- toscaPolicy.setType(type.getName());
-
- if (!PfKey.NULL_KEY_VERSION.equals(type.getVersion())) {
- toscaPolicy.setTypeVersion(type.getVersion());
- }
- else {
- toscaPolicy.setTypeVersion(null);
- }
-
- if (properties != null) {
- Map<String, Object> propertyMap = new LinkedHashMap<>();
-
- for (Entry<String, String> entry : properties.entrySet()) {
- propertyMap.put(entry.getKey(), entry.getValue());
- }
-
- toscaPolicy.setProperties(propertyMap);
- }
-
return toscaPolicy;
}
public void fromAuthorative(@NonNull final ToscaPolicy toscaPolicy) {
super.fromAuthorative(toscaPolicy);
- type.setName(toscaPolicy.getType());
- type.setVersion(toscaPolicy.getTypeVersion());
- if (type.getVersion() == null) {
- type.setVersion(PfKey.NULL_KEY_VERSION);
- }
-
- if (toscaPolicy.getProperties() != null) {
- properties = new LinkedHashMap<>();
-
- for (Entry<String, Object> propertyEntry : toscaPolicy.getProperties().entrySet()) {
- // TODO: This is a HACK, we need to validate the properties against their
- // TODO: their data type in their policy type definition in TOSCA, which means reading
- // TODO: the policy type from the database and parsing the property value object correctly
- // TODO: Here we are simply serializing the property value into a string and storing it
- // TODO: unvalidated into the database
- properties.put(propertyEntry.getKey(), propertyEntry.getValue().toString());
- }
- }
-
// Add the property metadata if it doesn't exist already
if (toscaPolicy.getMetadata() == null) {
setMetadata(new LinkedHashMap<>());
// Add the policy name and version fields to the metadata
getMetadata().put(METADATA_POLICY_ID_TAG, getKey().getName());
- getMetadata().put(METADATA_POLICY_VERSION_TAG, Integer.toString(getKey().getMajorVersion()));
+ getMetadata().put(METADATA_POLICY_VERSION_TAG, getKey().getVersion());
+
+ // Add metadataSet name and version to the metadata
+ if (getMetadata().containsKey(METADATA_METADATA_SET_NAME_TAG)
+ && getMetadata().containsKey(METADATA_METADATA_SET_VERSION_TAG)) {
+ getMetadata().put(METADATA_METADATA_SET_NAME_TAG, getMetadata().get(METADATA_METADATA_SET_NAME_TAG)
+ .replaceAll("^\"|\"$", ""));
+
+ getMetadata().put(METADATA_METADATA_SET_VERSION_TAG, getMetadata().get(METADATA_METADATA_SET_VERSION_TAG)
+ .replaceAll("^\"|\"$", ""));
+ }
+ }
+
+ @Override
+ protected Object deserializePropertyValue(String propValue) {
+ try {
+ return STANDARD_CODER.decode(propValue, Object.class);
+ } catch (CoderException ce) {
+ String errorMessage = "error decoding property JSON value read from database: " + propValue;
+ throw new PfModelRuntimeException(Response.Status.INTERNAL_SERVER_ERROR, errorMessage, ce);
+ }
+ }
+
+ @Override
+ protected String serializePropertyValue(Object propValue) {
+ try {
+ return STANDARD_CODER.encode(propValue);
+ } catch (CoderException ce) {
+ String errorMessage = "error encoding property JSON value for database: " + propValue;
+ throw new PfModelRuntimeException(Response.Status.INTERNAL_SERVER_ERROR, errorMessage, ce);
+ }
}
@Override
public List<PfKey> getKeys() {
final List<PfKey> keyList = super.getKeys();
- keyList.addAll(type.getKeys());
-
if (targets != null) {
keyList.addAll(targets);
}
public void clean() {
super.clean();
- type.clean();
-
if (targets != null) {
for (PfConceptKey target : targets) {
target.clean();
}
@Override
- public PfValidationResult validate(@NonNull final PfValidationResult resultIn) {
- PfValidationResult result = super.validate(resultIn);
-
- if (type == null || type.isNullKey()) {
- result.addValidationMessage(new PfValidationMessage(getKey(), this.getClass(), ValidationResult.INVALID,
- "type is null or a null key"));
- } else {
- result = type.validate(result);
- }
+ public BeanValidationResult validate(@NonNull String fieldName) {
+ BeanValidationResult result = super.validate(fieldName);
- if (properties != null) {
- result = validateProperties(result);
- }
+ validateKeyVersionNotNull(result, "key", getKey());
- if (targets != null) {
- result = validateTargets(result);
- }
-
- return result;
- }
-
- /**
- * Validate the policy properties.
- *
- * @param result The result of validations up to now
- * @return the validation result
- */
- private PfValidationResult validateProperties(final PfValidationResult resultIn) {
- PfValidationResult result = resultIn;
-
- for (Entry<String, String> propertyEntry : properties.entrySet()) {
- if (!ParameterValidationUtils.validateStringParameter(propertyEntry.getKey())) {
- result.addValidationMessage(new PfValidationMessage(getKey(), this.getClass(), ValidationResult.INVALID,
- "policy property key may not be null "));
- } else if (propertyEntry.getValue() == null) {
- result.addValidationMessage(new PfValidationMessage(getKey(), this.getClass(), ValidationResult.INVALID,
- "policy property value may not be null "));
- }
- }
- return result;
- }
-
- /**
- * Validate the policy targets.
- *
- * @param result The result of validations up to now
- * @return the validation result
- */
- private PfValidationResult validateTargets(final PfValidationResult resultIn) {
- PfValidationResult result = resultIn;
-
- for (PfConceptKey target : targets) {
- if (target == null) {
- result.addValidationMessage(new PfValidationMessage(getKey(), this.getClass(), ValidationResult.INVALID,
- "policy target may not be null "));
- } else {
- result = target.validate(result);
- }
- }
return result;
}
@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();
+ int result = super.compareTo(otherConcept);
+ if (result != 0) {
+ return result;
}
final JpaToscaPolicy other = (JpaToscaPolicy) otherConcept;
- if (!super.equals(other)) {
- return super.compareTo(other);
- }
-
- if (!type.equals(other.type)) {
- return type.compareTo(other.type);
- }
-
- int retVal = PfUtils.compareObjects(properties, other.properties);
- if (retVal != 0) {
- return retVal;
- }
-
- return PfUtils.compareObjects(targets, other.targets);
- }
-
- @Override
- public PfConcept copyTo(@NonNull PfConcept target) {
- final Object copyObject = target;
- Assertions.instanceOf(copyObject, PfConcept.class);
-
- final JpaToscaPolicy copy = ((JpaToscaPolicy) copyObject);
- super.copyTo(target);
-
- copy.setType(new PfConceptKey(type));
-
- if (properties == null) {
- copy.setProperties(null);
- } else {
- copy.setProperties(properties);
- }
-
- if (targets == null) {
- copy.setTargets(null);
- } else {
- final List<PfConceptKey> newTargets = new ArrayList<>();
- for (final PfConceptKey oldTarget : targets) {
- newTargets.add(new PfConceptKey(oldTarget));
- }
- copy.setTargets(newTargets);
- }
- return copy;
+ return PfUtils.compareCollections(targets, other.targets);
}
}