diff options
Diffstat (limited to 'models/src/main/java')
31 files changed, 2952 insertions, 153 deletions
diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationComposition.java b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationComposition.java index 4736d3190..c3245d27c 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationComposition.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationComposition.java @@ -27,9 +27,7 @@ import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.NonNull; import org.apache.commons.collections4.MapUtils; -import org.onap.policy.models.base.PfConceptKey; import org.onap.policy.models.base.PfUtils; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; import org.onap.policy.models.tosca.authorative.concepts.ToscaEntity; /** @@ -40,7 +38,7 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaEntity; @EqualsAndHashCode(callSuper = true) public class AutomationComposition extends ToscaEntity implements Comparable<AutomationComposition> { @NonNull - private ToscaConceptIdentifier definition = new ToscaConceptIdentifier(PfConceptKey.getNullKey()); + private UUID compositionId; @NonNull private AutomationCompositionState state = AutomationCompositionState.UNINITIALISED; @@ -53,16 +51,6 @@ public class AutomationComposition extends ToscaEntity implements Comparable<Aut @NonNull private Boolean primed = false; - @Override - public String getType() { - return definition.getName(); - } - - @Override - public String getTypeVersion() { - return definition.getVersion(); - } - /** * Copy contructor, does a deep copy. * @@ -70,7 +58,7 @@ public class AutomationComposition extends ToscaEntity implements Comparable<Aut */ public AutomationComposition(final AutomationComposition otherAutomationComposition) { super(otherAutomationComposition); - this.definition = new ToscaConceptIdentifier(otherAutomationComposition.definition); + this.compositionId = otherAutomationComposition.compositionId; this.state = otherAutomationComposition.state; this.orderedState = otherAutomationComposition.orderedState; this.elements = PfUtils.mapMap(otherAutomationComposition.elements, AutomationCompositionElement::new); diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/document/base/DocConceptKey.java b/models/src/main/java/org/onap/policy/clamp/models/acm/document/base/DocConceptKey.java new file mode 100644 index 000000000..56413d888 --- /dev/null +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/document/base/DocConceptKey.java @@ -0,0 +1,94 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.clamp.models.acm.document.base; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NonNull; +import lombok.ToString; +import org.onap.policy.common.parameters.annotations.Pattern; +import org.onap.policy.common.utils.validation.Assertions; +import org.onap.policy.models.base.PfConceptKey; +import org.onap.policy.models.base.PfKeyImpl; + +@Data +@EqualsAndHashCode(callSuper = false) +@ToString +public class DocConceptKey extends PfKeyImpl { + + private static final long serialVersionUID = 1L; + + @Pattern(regexp = NAME_REGEXP) + private String name; + + @Pattern(regexp = VERSION_REGEXP) + private String version; + + /** + * Constructor. + */ + public DocConceptKey() { + this(NULL_KEY_NAME, NULL_KEY_VERSION); + } + + @Override + public String getId() { + return name + ":" + version; + } + + /** + * Copy constructor. + * + * @param copyConcept the concept to copy from + */ + public DocConceptKey(final PfConceptKey copyConcept) { + super(copyConcept); + } + + /** + * Copy constructor. + * + * @param copyConcept the concept to copy from + */ + public DocConceptKey(final DocConceptKey copyConcept) { + this(copyConcept.getName(), copyConcept.getVersion()); + } + + /** + * Temporary Constructor to create a key with the specified name and version. + * + * @param name the key name + * @param version the key version + */ + public DocConceptKey(final String name, final String version) { + super(name, version); + } + + @Override + public void setName(@NonNull final String name) { + this.name = Assertions.validateStringParameter(NAME_TOKEN, name, getNameRegEx()); + } + + @Override + public void setVersion(@NonNull final String version) { + this.version = Assertions.validateStringParameter(VERSION_TOKEN, version, getVersionRegEx()); + } +} diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/document/base/DocUtil.java b/models/src/main/java/org/onap/policy/clamp/models/acm/document/base/DocUtil.java new file mode 100644 index 000000000..5e31ad239 --- /dev/null +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/document/base/DocUtil.java @@ -0,0 +1,320 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.clamp.models.acm.document.base; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.function.Function; +import javax.ws.rs.core.Response; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; +import org.onap.policy.clamp.models.acm.document.concepts.DocToscaEntity; +import org.onap.policy.clamp.models.acm.document.concepts.DocToscaServiceTemplate; +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.PfNameVersion; +import org.onap.policy.models.tosca.authorative.concepts.ToscaEntity; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class DocUtil { + + public static final String REF_DATA_TYPES = "dataTypes"; + public static final String REF_POLICY_TYPES = "policyTypes"; + public static final String REF_NODE_TYPES = "nodeTypes"; + public static final String REF_CAPABILITY_TYPES = "capabilityTypes"; + public static final String REF_RELATIONSHIP_TYPES = "relationshipTypes"; + public static final String REF_NODE_TEMPLATES = "nodeTemplates"; + public static final String REF_POLICIES = "policies"; + public static final String REF_REQUIREMENTS = "requirements"; + public static final String REF_CAPABILITIES = "capabilities"; + + /** + * Convenience method to apply a mapping function to all of the values of a map, generating a new map. + * + * @param source map whose values are to be mapped, or {@code null} + * @param mapFunc mapping function + * @return a new map, containing mappings of all of the items in the original map + */ + public static <A extends PfNameVersion, R> Map<String, R> docMapToMap(Map<String, A> source, + Function<A, R> mapFunc) { + return docMapToMap(source, mapFunc, null); + } + + /** + * Convenience method to apply a mapping function to all of the values of a map, generating a new map. + * + * @param source map whose values are to be mapped, or {@code null} + * @param mapFunc mapping function + * @param defaultValue if source is null + * @return a new map, containing mappings of all of the items in the original map + */ + public static <A extends PfNameVersion, R> Map<String, R> docMapToMap(Map<String, A> source, Function<A, R> mapFunc, + Map<String, R> defaultValue) { + if (source == null) { + return defaultValue; + } + Map<String, R> map = new LinkedHashMap<>(); + for (Entry<String, A> ent : source.entrySet()) { + map.put(ent.getValue().getName(), mapFunc.apply(ent.getValue())); + } + + return map; + } + + /** + * Convenience method to apply a mapping function to all of the values of a map, generating a new map. + * + * @param source map whose values are to be mapped, or {@code null} + * @param mapFunc mapping function + * @return a new map, containing mappings of all of the items in the original map, or {@code null} if the source is + * {@code null} + */ + public static <A extends ToscaEntity, R> Map<String, R> mapToDocMap(Map<String, A> source, Function<A, R> mapFunc) { + return mapToDocMap(source, mapFunc, null); + } + + /** + * Convenience method to apply a mapping function to all of the values of a map, generating a new map. + * + * @param source map whose values are to be mapped, or {@code null} + * @param mapFunc mapping function + * @param defaultValue if source is null + * @return a new map, containing mappings of all of the items in the original map, or defaultValue if the source is + * {@code null} + */ + public static <A extends ToscaEntity, R> Map<String, R> mapToDocMap(Map<String, A> source, Function<A, R> mapFunc, + Map<String, R> defaultValue) { + if (source == null) { + return defaultValue; + } + Map<String, R> conceptMap = new LinkedHashMap<>(); + + for (var incomingConceptEntry : source.entrySet()) { + + var conceptKey = new PfConceptKey(); + conceptKey.setName(incomingConceptEntry.getKey()); + if (incomingConceptEntry.getValue().getVersion() != null) { + conceptKey.setVersion(incomingConceptEntry.getValue().getVersion()); + } + + incomingConceptEntry.getValue().setName(findConceptField(conceptKey, conceptKey.getName(), + incomingConceptEntry.getValue(), PfNameVersion::getDefinedName)); + incomingConceptEntry.getValue().setVersion(findConceptField(conceptKey, conceptKey.getVersion(), + incomingConceptEntry.getValue(), PfNameVersion::getDefinedVersion)); + + var authoritiveImpl = mapFunc.apply(incomingConceptEntry.getValue()); + + // After all that, save the map entry + conceptMap.put(conceptKey.getId(), authoritiveImpl); + } + + return conceptMap; + } + + private static String findConceptField(final PfConceptKey conceptKey, final String keyFieldValue, + final PfNameVersion concept, final Function<PfNameVersion, String> fieldGetterFunction) { + + String conceptField = fieldGetterFunction.apply(concept); + + if (StringUtils.isBlank(conceptField) || keyFieldValue.equals(conceptField)) { + return keyFieldValue; + } else { + throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, "Key " + conceptKey.getId() + " field " + + keyFieldValue + " does not match the value " + conceptField + " in the concept field"); + } + } + + /** + * Convenience method to apply a mapping function to all of the values of a list of maps, generating a new map. + * + * @param source list of maps whose values are to be mapped, or {@code null} + * @param mapFunc mapping function + * @return a new map, containing mappings of all of the items in the original map, or {@code null} if the source is + * {@code null} + */ + public static <A extends ToscaEntity, R> Map<String, R> listToDocMap(List<Map<String, A>> source, + Function<A, R> mapFunc) { + + return listToDocMap(source, mapFunc, null); + } + + /** + * Convenience method to apply a mapping function to all of the values of a list of maps, generating a new map. + * + * @param source list of maps whose values are to be mapped, or {@code null} + * @param mapFunc mapping function + * @param defaultValue if source is null + * @return a new map, containing mappings of all of the items in the original map, or defaultValue if the source is + * {@code null} + */ + public static <A extends ToscaEntity, R> Map<String, R> listToDocMap(List<Map<String, A>> source, + Function<A, R> mapFunc, Map<String, R> defaultValue) { + if (source == null) { + return defaultValue; + } + Map<String, R> conceptMap = new LinkedHashMap<>(); + + for (var map : source) { + conceptMap.putAll(mapToDocMap(map, mapFunc)); + } + + return conceptMap; + } + + /** + * Convenience method to apply a mapping function to all of the values of a map, generating a new list of maps. + * + * @param source map whose values are to be mapped, or {@code null} + * @param mapFunc mapping function + * @return a new list of maps, containing mappings of all of the items in the original map, or {@code null} if the + * source is {@code null} + */ + public static <A extends PfNameVersion, R> List<Map<String, R>> docMapToList(Map<String, A> source, + Function<A, R> mapFunc) { + return docMapToList(source, mapFunc, null); + } + + /** + * Convenience method to apply a mapping function to all of the values of a map, generating a new list of maps. + * + * @param source map whose values are to be mapped, or {@code null} + * @param mapFunc mapping function + * @param defaultValue if source is null + * @return a new list of maps, containing mappings of all of the items in the original map, or defaultValue if the + * source is {@code null} + */ + public static <A extends PfNameVersion, R> List<Map<String, R>> docMapToList(Map<String, A> source, + Function<A, R> mapFunc, List<Map<String, R>> defaultValue) { + if (source == null) { + return defaultValue; + } + + List<Map<String, R>> result = new ArrayList<>(); + for (Entry<String, A> ent : source.entrySet()) { + Map<String, R> map = new LinkedHashMap<>(); + map.put(ent.getValue().getName(), mapFunc.apply(ent.getValue())); + result.add(map); + + } + + return result; + } + + /** + * Create DocConceptKey. + * + * @param name the name + * @param version the version + * @return DocConceptKey + */ + public static DocConceptKey createDocConceptKey(String name, String version) { + var key = new DocConceptKey(); + if (version != null && !version.isBlank()) { + key.setName(name); + key.setVersion(version); + } else { + var list = name.split(":"); + switch (list.length) { + case 0: + case 1: + key.setName(name); + key.setVersion(PfKey.NULL_KEY_VERSION); + break; + case 2: + key.setName(list[0]); + key.setVersion(list[1]); + break; + default: + } + } + return key; + } + + /** + * Get DocToscaReferences. + * + * @return ToscaReferenceType + */ + public static Map<String, Set<String>> getToscaReferences(DocToscaServiceTemplate serviceTemplate) { + var referenceType = new HashMap<String, Set<String>>(); + fillReferenceType(referenceType, REF_DATA_TYPES, serviceTemplate.getDataTypes()); + fillReferenceType(referenceType, REF_POLICY_TYPES, serviceTemplate.getPolicyTypes()); + fillReferenceType(referenceType, REF_NODE_TYPES, serviceTemplate.getNodeTypes()); + fillReferenceType(referenceType, REF_CAPABILITY_TYPES, serviceTemplate.getCapabilityTypes()); + fillReferenceType(referenceType, REF_RELATIONSHIP_TYPES, serviceTemplate.getRelationshipTypes()); + + if (serviceTemplate.getNodeTypes() != null) { + + serviceTemplate.getNodeTypes().values().forEach( + nodeType -> fillReferenceType(referenceType, REF_REQUIREMENTS, nodeType.getRequirements())); + } + if (serviceTemplate.getToscaTopologyTemplate() != null) { + + fillReferenceType(referenceType, REF_NODE_TEMPLATES, + serviceTemplate.getToscaTopologyTemplate().getNodeTemplates()); + + fillReferenceType(referenceType, REF_POLICIES, serviceTemplate.getToscaTopologyTemplate().getPolicies()); + + if (serviceTemplate.getToscaTopologyTemplate().getNodeTemplates() != null) { + for (var nodeTemplate : serviceTemplate.getToscaTopologyTemplate().getNodeTemplates().values()) { + fillReferenceType(referenceType, REF_REQUIREMENTS, nodeTemplate.getRequirements()); + fillReferenceType(referenceType, REF_CAPABILITIES, nodeTemplate.getCapabilities()); + } + } + + } + return referenceType; + } + + private static <A extends DocToscaEntity<?>> void fillReferenceType(Map<String, Set<String>> referenceType, + String type, Map<String, A> map) { + referenceType.putIfAbsent(type, new HashSet<>()); + if (map != null) { + referenceType.get(type).addAll(toSetToscaReferences(map)); + } + + } + + private static <A extends DocToscaEntity<?>> void fillReferenceType(Map<String, Set<String>> referenceType, + String type, List<Map<String, A>> list) { + referenceType.putIfAbsent(type, new HashSet<>()); + if (list != null) { + list.forEach(map -> referenceType.get(type).addAll(toSetToscaReferences(map))); + } + } + + private static <A extends DocToscaEntity<?>> Set<String> toSetToscaReferences(Map<String, A> map) { + Set<String> result = new HashSet<>(); + for (var entity : map.values()) { + result.add(entity.getDocConceptKey().getId()); // ref for type + result.add(entity.getDocConceptKey().getName()); // ref for derived from + } + return result; + } +} diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/document/base/ToscaServiceTemplateValidation.java b/models/src/main/java/org/onap/policy/clamp/models/acm/document/base/ToscaServiceTemplateValidation.java new file mode 100644 index 000000000..76496780d --- /dev/null +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/document/base/ToscaServiceTemplateValidation.java @@ -0,0 +1,233 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.clamp.models.acm.document.base; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import org.onap.policy.clamp.models.acm.document.concepts.DocToscaEntity; +import org.onap.policy.clamp.models.acm.document.concepts.DocToscaServiceTemplate; +import org.onap.policy.common.parameters.BeanValidationResult; +import org.onap.policy.common.parameters.ValidationStatus; +import org.onap.policy.models.base.Validated; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class ToscaServiceTemplateValidation { + + private static final String ROOT_KEY_NAME_SUFFIX = ".Root"; + + /** + * validate a serviceTemplate. + * + * @param result the result + * @param serviceTemplate the serviceTemplate to validate + */ + public static void validate(final BeanValidationResult result, DocToscaServiceTemplate serviceTemplate) { + + var references = DocUtil.getToscaReferences(serviceTemplate); + + validEntityTypeAncestors(serviceTemplate.getDataTypes(), references.get(DocUtil.REF_DATA_TYPES), result); + validEntityTypeAncestors(serviceTemplate.getCapabilityTypes(), references.get(DocUtil.REF_CAPABILITY_TYPES), + result); + validEntityTypeAncestors(serviceTemplate.getNodeTypes(), references.get(DocUtil.REF_NODE_TYPES), result); + validEntityTypeAncestors(serviceTemplate.getRelationshipTypes(), references.get(DocUtil.REF_RELATIONSHIP_TYPES), + result); + validEntityTypeAncestors(serviceTemplate.getPolicyTypes(), references.get(DocUtil.REF_POLICY_TYPES), result); + + if (serviceTemplate.getNodeTypes() != null) { + for (var nodeType : serviceTemplate.getNodeTypes().values()) { + validEntityTypeAncestors(nodeType.getRequirements(), references.get(DocUtil.REF_REQUIREMENTS), result); + } + } + + if (serviceTemplate.getToscaTopologyTemplate() != null) { + validEntityTypeAncestors(serviceTemplate.getToscaTopologyTemplate().getNodeTemplates(), + references.get(DocUtil.REF_NODE_TEMPLATES), result); + validEntityTypeAncestors(serviceTemplate.getToscaTopologyTemplate().getPolicies(), + references.get(DocUtil.REF_POLICIES), result); + + if (serviceTemplate.getToscaTopologyTemplate().getNodeTemplates() != null) { + for (var nodeTemplate : serviceTemplate.getToscaTopologyTemplate().getNodeTemplates().values()) { + validEntityTypeAncestors(nodeTemplate.getCapabilities(), references.get(DocUtil.REF_CAPABILITIES), + result); + validEntityTypeAncestors(nodeTemplate.getRequirements(), references.get(DocUtil.REF_REQUIREMENTS), + result); + } + } + } + + validateReferencedDataTypes(result, serviceTemplate, references); + + validatePolicyTypesInPolicies(result, serviceTemplate, references); + + } + + /** + * Validate that all data types referenced in policy types exist. + * + * @param result where the results are added + */ + private static void validateReferencedDataTypes(final BeanValidationResult result, + DocToscaServiceTemplate serviceTemplate, Map<String, Set<String>> references) { + if (serviceTemplate.getDataTypes() != null) { + for (var dataType : serviceTemplate.getDataTypes().values()) { + validateReferencedDataTypesExists(result, dataType.getReferencedDataTypes(), references); + } + } + + if (serviceTemplate.getPolicyTypes() != null) { + for (var policyType : serviceTemplate.getPolicyTypes().values()) { + validateReferencedDataTypesExists(result, policyType.getReferencedDataTypes(), references); + } + } + if (serviceTemplate.getNodeTypes() != null) { + for (var nodeType : serviceTemplate.getNodeTypes().values()) { + validateReferencedDataTypesExists(result, nodeType.getReferencedDataTypes(), references); + } + } + } + + /** + * Validate that the referenced data types exist for a collection of data type keys. + * + * @param dataTypeKeyCollection the data type key collection + * @param result where the results are added + */ + private static void validateReferencedDataTypesExists(final BeanValidationResult result, + final Collection<DocConceptKey> dataTypeKeyCollection, Map<String, Set<String>> references) { + for (DocConceptKey dataTypeKey : dataTypeKeyCollection) { + if (!isTypePresent(dataTypeKey, references.get(DocUtil.REF_DATA_TYPES))) { + result.addResult("data type", dataTypeKey.getId(), ValidationStatus.INVALID, Validated.NOT_FOUND); + } + } + } + + /** + * Validate that all policy types referenced in policies exist. + * + * @param result where the results are added + */ + private static void validatePolicyTypesInPolicies(final BeanValidationResult result, + DocToscaServiceTemplate serviceTemplate, Map<String, Set<String>> references) { + if (serviceTemplate.getToscaTopologyTemplate() == null) { + return; + } + + if (serviceTemplate.getToscaTopologyTemplate().getPolicies() != null) { + for (var policy : serviceTemplate.getToscaTopologyTemplate().getPolicies().values()) { + var key = policy.getTypeDocConceptKey(); + if (!isTypePresent(key, references.get(DocUtil.REF_POLICY_TYPES))) { + result.addResult("policy type", key, ValidationStatus.INVALID, Validated.NOT_FOUND); + } + } + } + if (serviceTemplate.getToscaTopologyTemplate().getNodeTemplates() != null) { + for (var nodeTemplate : serviceTemplate.getToscaTopologyTemplate().getNodeTemplates().values()) { + var key = nodeTemplate.getTypeDocConceptKey(); + if (!isTypePresent(key, references.get(DocUtil.REF_NODE_TYPES))) { + result.addResult("node Template", key, ValidationStatus.INVALID, Validated.NOT_FOUND); + } + } + } + } + + private static boolean isTypePresent(String key, Set<String> reference) { + if (reference == null || reference.isEmpty()) { + return false; + } + return reference.contains(key); + } + + private static boolean isTypePresent(DocConceptKey key, Set<String> reference) { + if (reference == null || reference.isEmpty()) { + return false; + } + return reference.contains(key.getId()); + } + + private static String extractDerivedFrom(DocToscaEntity<?> entityType, final BeanValidationResult result) { + if (entityType.getDerivedFrom() == null) { + return null; + } + var parentEntityTypeKey = entityType.getDerivedFrom(); + + if (parentEntityTypeKey.endsWith(ROOT_KEY_NAME_SUFFIX)) { + return null; + } + if (entityType.getName().equals(parentEntityTypeKey)) { + result.addResult("entity type", entityType.getDocConceptKey().getId(), ValidationStatus.INVALID, + "ancestor of itself"); + return null; + } + return parentEntityTypeKey; + } + + /** + * validate all the ancestors of an entity type. + * + * @param entityTypes the set of entity types that exist + * @param result the result of the ancestor search with any warnings or errors + */ + private static void validEntityTypeAncestors(Map<String, ? extends DocToscaEntity<?>> entityTypes, + Set<String> reference, @NonNull final BeanValidationResult result) { + if (entityTypes != null) { + for (var entityType : entityTypes.values()) { + var parentEntityTypeKey = extractDerivedFrom(entityType, result); + if (parentEntityTypeKey == null) { + continue; + } + if (!isTypePresent(parentEntityTypeKey, reference)) { + result.addResult("parent", parentEntityTypeKey, ValidationStatus.INVALID, + Validated.NOT_FOUND); + } + } + } + } + + /** + * validate all the ancestors of an entity type. + * + * @param entityTypesList the set of entity types that exist + * @param result the result of the ancestor search with any warnings or errors + */ + private static <T extends DocToscaEntity<?>> void validEntityTypeAncestors(List<Map<String, T>> entityTypesList, + Set<String> reference, @NonNull final BeanValidationResult result) { + if (entityTypesList != null) { + for (var entityTypes : entityTypesList) { + for (var entityType : entityTypes.values()) { + var parentEntityTypeKey = extractDerivedFrom(entityType, result); + if (parentEntityTypeKey == null) { + continue; + } + if (!isTypePresent(parentEntityTypeKey, reference)) { + result.addResult("parent", parentEntityTypeKey, ValidationStatus.INVALID, + Validated.NOT_FOUND); + } + } + } + } + } + +} diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaCapabilityAssignment.java b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaCapabilityAssignment.java new file mode 100644 index 000000000..9caefe238 --- /dev/null +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaCapabilityAssignment.java @@ -0,0 +1,106 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.clamp.models.acm.document.concepts; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.ToString; +import org.onap.policy.common.parameters.annotations.NotNull; +import org.onap.policy.models.base.PfUtils; +import org.onap.policy.models.tosca.authorative.concepts.ToscaCapabilityAssignment; + +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor +@ToString(callSuper = true) +public class DocToscaCapabilityAssignment extends DocToscaWithTypeAndStringProperties<ToscaCapabilityAssignment> { + + private static final long serialVersionUID = 1L; + + private Map<@NotNull String, @NotNull Object> attributes; + private List<@NotNull Object> occurrences; + + /** + * Authorative constructor. + * + * @param authorativeConcept the authorative concept to copy from + */ + public DocToscaCapabilityAssignment(final ToscaCapabilityAssignment authorativeConcept) { + fromAuthorative(authorativeConcept); + } + + /** + * Copy constructor. + * + * @param copyConcept the concept to copy from + */ + public DocToscaCapabilityAssignment(final DocToscaCapabilityAssignment copyConcept) { + super(copyConcept); + this.attributes = copyConcept.attributes == null ? null : new LinkedHashMap<>(copyConcept.attributes); + this.occurrences = copyConcept.occurrences == null ? null : new ArrayList<>(copyConcept.occurrences); + } + + @Override + public ToscaCapabilityAssignment toAuthorative() { + var toscaCapabilityAssignment = new ToscaCapabilityAssignment(); + super.setToscaEntity(toscaCapabilityAssignment); + super.toAuthorative(); + + toscaCapabilityAssignment.setAttributes(PfUtils.mapMap(attributes, attribute -> attribute)); + toscaCapabilityAssignment.setOccurrences(PfUtils.mapList(occurrences, occurrence -> occurrence)); + + return toscaCapabilityAssignment; + } + + @Override + public void fromAuthorative(ToscaCapabilityAssignment toscaCapabilityAssignment) { + super.fromAuthorative(toscaCapabilityAssignment); + + attributes = PfUtils.mapMap(toscaCapabilityAssignment.getAttributes(), attribute -> attribute); + occurrences = PfUtils.mapList(toscaCapabilityAssignment.getOccurrences(), occurrence -> occurrence); + } + + @Override + public int compareTo(DocToscaEntity<ToscaCapabilityAssignment> otherConcept) { + if (this == otherConcept) { + return 0; + } + + int result = super.compareTo(otherConcept); + if (result != 0) { + return result; + } + + final var other = (DocToscaCapabilityAssignment) otherConcept; + + result = PfUtils.compareMaps(attributes, other.attributes); + if (result != 0) { + return result; + } + + return PfUtils.compareCollections(occurrences, other.occurrences); + } +} diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaCapabilityType.java b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaCapabilityType.java new file mode 100644 index 000000000..38e790ed7 --- /dev/null +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaCapabilityType.java @@ -0,0 +1,65 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.clamp.models.acm.document.concepts; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import org.onap.policy.common.parameters.BeanValidationResult; +import org.onap.policy.models.tosca.authorative.concepts.ToscaCapabilityType; + +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor +public class DocToscaCapabilityType extends DocToscaWithToscaProperties<ToscaCapabilityType> { + + private static final long serialVersionUID = 1L; + + /** + * Authorative constructor. + * + * @param authorativeConcept the authorative concept to copy from + */ + public DocToscaCapabilityType(final ToscaCapabilityType authorativeConcept) { + fromAuthorative(authorativeConcept); + } + + /** + * Copy constructor. + * + * @param copyConcept the concept to copy from + */ + public DocToscaCapabilityType(DocToscaCapabilityType copyConcept) { + super(copyConcept); + } + + @Override + public ToscaCapabilityType toAuthorative() { + super.setToscaEntity(new ToscaCapabilityType()); + return super.toAuthorative(); + } + + @Override + public BeanValidationResult validate(@NonNull String fieldName) { + return validateWithKey(fieldName); + } +} diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaConstraint.java b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaConstraint.java new file mode 100644 index 000000000..f5b60a1c3 --- /dev/null +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaConstraint.java @@ -0,0 +1,107 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.clamp.models.acm.document.concepts; + +import com.google.gson.annotations.SerializedName; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.onap.policy.models.base.PfAuthorative; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConstraint; + +@Data +@NoArgsConstructor +public class DocToscaConstraint implements PfAuthorative<ToscaConstraint>, Serializable { + + private static final long serialVersionUID = 1L; + + @SerializedName("valid_values") + private List<String> validValues; + + private String equal; + + @SerializedName("greater_than") + private String greaterThan; + + @SerializedName("greater_or_equal") + private String greaterOrEqual; + + @SerializedName("less_than") + private String lessThan; + + @SerializedName("less_or_equal") + private String lessOrEqual; + + @SerializedName("in_range") + private List<String> rangeValues; + + public DocToscaConstraint(ToscaConstraint toscaConstraint) { + fromAuthorative(toscaConstraint); + } + + /** + * Copy constructor. + * + * @param copyConcept the concept to copy from + */ + public DocToscaConstraint(final DocToscaConstraint copyConcept) { + this.validValues = copyConcept.validValues == null ? null : new ArrayList<>(copyConcept.validValues); + this.equal = copyConcept.equal; + this.greaterThan = copyConcept.greaterThan; + this.greaterOrEqual = copyConcept.greaterOrEqual; + this.lessThan = copyConcept.lessThan; + this.lessOrEqual = copyConcept.lessOrEqual; + this.rangeValues = copyConcept.rangeValues == null ? null : new ArrayList<>(copyConcept.rangeValues); + } + + @Override + public ToscaConstraint toAuthorative() { + var toscaConstraint = new ToscaConstraint(); + if (validValues != null) { + toscaConstraint.setValidValues(new ArrayList<>(validValues)); + } + toscaConstraint.setEqual(equal); + toscaConstraint.setGreaterThan(greaterThan); + toscaConstraint.setGreaterOrEqual(greaterOrEqual); + toscaConstraint.setLessOrEqual(lessOrEqual); + if (rangeValues != null) { + toscaConstraint.setRangeValues(new ArrayList<>(rangeValues)); + } + return toscaConstraint; + } + + @Override + public void fromAuthorative(ToscaConstraint toscaConstraint) { + if (toscaConstraint.getValidValues() != null) { + validValues = new ArrayList<>(toscaConstraint.getValidValues()); + } + equal = toscaConstraint.getEqual(); + greaterThan = toscaConstraint.getGreaterThan(); + greaterOrEqual = toscaConstraint.getGreaterOrEqual(); + lessThan = toscaConstraint.getLessThan(); + lessOrEqual = toscaConstraint.getLessOrEqual(); + if (toscaConstraint.getRangeValues() != null) { + rangeValues = new ArrayList<>(toscaConstraint.getRangeValues()); + } + } +} diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaDataType.java b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaDataType.java new file mode 100644 index 000000000..73ffe1758 --- /dev/null +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaDataType.java @@ -0,0 +1,87 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.clamp.models.acm.document.concepts; + +import java.util.List; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import org.onap.policy.common.parameters.annotations.NotNull; +import org.onap.policy.common.parameters.annotations.Valid; +import org.onap.policy.models.base.PfUtils; +import org.onap.policy.models.tosca.authorative.concepts.ToscaDataType; + +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor +public class DocToscaDataType extends DocToscaWithToscaProperties<ToscaDataType> { + + private static final long serialVersionUID = 1L; + + private List<@NotNull @Valid DocToscaConstraint> constraints; + + public DocToscaDataType(final ToscaDataType toscaDataType) { + fromAuthorative(toscaDataType); + } + + /** + * Copy constructor. + * + * @param copyConcept the concept to copy from + */ + public DocToscaDataType(final DocToscaDataType copyConcept) { + super(copyConcept); + this.constraints = PfUtils.mapList(copyConcept.constraints, DocToscaConstraint::new); + } + + @Override + public ToscaDataType toAuthorative() { + var toscaDataType = new ToscaDataType(); + super.setToscaEntity(toscaDataType); + super.toAuthorative(); + toscaDataType.setConstraints(PfUtils.mapList(constraints, DocToscaConstraint::toAuthorative)); + + return toscaDataType; + } + + @Override + public void fromAuthorative(final ToscaDataType toscaDataType) { + super.fromAuthorative(toscaDataType); + + constraints = PfUtils.mapList(toscaDataType.getConstraints(), DocToscaConstraint::new); + } + + @Override + public int compareTo(DocToscaEntity<ToscaDataType> otherConcept) { + if (this == otherConcept) { + return 0; + } + + int result = super.compareTo(otherConcept); + if (result != 0) { + return result; + } + + final var other = (DocToscaDataType) otherConcept; + + return PfUtils.compareCollections(constraints, other.constraints); + } +} diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaEntity.java b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaEntity.java new file mode 100644 index 000000000..5d173aff4 --- /dev/null +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaEntity.java @@ -0,0 +1,196 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.clamp.models.acm.document.concepts; + +import com.google.gson.annotations.SerializedName; +import java.io.Serializable; +import java.util.LinkedHashMap; +import java.util.Map; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.ObjectUtils; +import org.onap.policy.clamp.models.acm.document.base.DocConceptKey; +import org.onap.policy.common.parameters.annotations.NotBlank; +import org.onap.policy.common.parameters.annotations.NotNull; +import org.onap.policy.models.base.PfAuthorative; +import org.onap.policy.models.base.PfConceptKey; +import org.onap.policy.models.base.PfKey; +import org.onap.policy.models.base.PfNameVersion; +import org.onap.policy.models.base.PfUtils; +import org.onap.policy.models.base.Validated; +import org.onap.policy.models.tosca.authorative.concepts.ToscaEntity; +import org.onap.policy.models.tosca.authorative.concepts.ToscaEntityKey; + +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor +public class DocToscaEntity<T extends ToscaEntity> extends Validated + implements PfNameVersion, PfAuthorative<T>, Serializable, Comparable<DocToscaEntity<T>> { + + private static final long serialVersionUID = 1L; + + @NotNull + private String name = PfKey.NULL_KEY_NAME; + + @NotNull + private String version = PfKey.NULL_KEY_VERSION; + + @SerializedName("derived_from") + private String derivedFrom; + + private Map<@NotNull @NotBlank String, @NotNull @NotBlank Object> metadata = new LinkedHashMap<>(); + + @NotBlank + private String description; + + private transient T toscaEntity; + + /** + * Get a key for this entity. + * + * @return a ToscaEntityKey for this entry + */ + public ToscaEntityKey getKey() { + return new ToscaEntityKey(name, version); + } + + /** + * Get a key for this entity. + * + * @return a PfConceptKey for this entry + */ + public PfConceptKey getConceptKey() { + return new PfConceptKey(name, version); + } + + public DocConceptKey getDocConceptKey() { + return new DocConceptKey(name, version); + } + + @Override + public String getDefinedName() { + return (PfKey.NULL_KEY_NAME.equals(name) ? null : name); + } + + @Override + public String getDefinedVersion() { + return (PfKey.NULL_KEY_VERSION.equals(version) ? null : version); + } + + /** + * Method that should be specialised to return the type of the entity if the entity has a type. + * + * @return the type of the entity or null if it has no type + */ + public String getType() { + return null; + } + + /** + * Method that should be specialised to return the type version of the entity if the entity has a type. + * + * @return the type of the entity or null if it has no type + */ + public String getTypeVersion() { + return null; + } + + /** + * Copy constructor. + * + * @param copyConcept the concept to copy from + */ + public DocToscaEntity(final DocToscaEntity<T> copyConcept) { + this.name = copyConcept.name; + this.version = copyConcept.version; + this.derivedFrom = copyConcept.derivedFrom; + this.metadata = (copyConcept.metadata != null ? new LinkedHashMap<>(copyConcept.metadata) : null); + this.description = copyConcept.description; + } + + @Override + public T toAuthorative() { + toscaEntity.setName(getName()); + toscaEntity.setVersion(getVersion()); + + if (derivedFrom != null) { + toscaEntity.setDerivedFrom(derivedFrom); + } + + if (description != null) { + toscaEntity.setDescription(description); + } + + toscaEntity.setMetadata(metadata); + + return toscaEntity; + } + + @Override + public void fromAuthorative(T toscaEntity) { + if (toscaEntity.getName() != null) { + name = toscaEntity.getName(); + } + if (toscaEntity.getVersion() != null) { + version = toscaEntity.getVersion(); + } + if (toscaEntity.getDerivedFrom() != null) { + derivedFrom = toscaEntity.getDerivedFrom(); + } + + if (toscaEntity.getDescription() != null) { + description = toscaEntity.getDescription(); + } + + metadata = toscaEntity.getMetadata(); + } + + @Override + public int compareTo(final DocToscaEntity<T> otherConcept) { + if (otherConcept == null) { + return -1; + } + if (this == otherConcept) { + return 0; + } + if (getClass() != otherConcept.getClass()) { + return getClass().getName().compareTo(otherConcept.getClass().getName()); + } + + int result = getKey().asIdentifier().compareTo(otherConcept.getKey().asIdentifier()); + if (result != 0) { + return result; + } + + result = ObjectUtils.compare(derivedFrom, otherConcept.derivedFrom); + if (result != 0) { + return result; + } + + result = PfUtils.compareMaps(metadata, otherConcept.metadata); + if (result != 0) { + return result; + } + + return ObjectUtils.compare(description, otherConcept.description); + } +} diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaNodeTemplate.java b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaNodeTemplate.java new file mode 100644 index 000000000..acd42baa0 --- /dev/null +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaNodeTemplate.java @@ -0,0 +1,112 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.clamp.models.acm.document.concepts; + +import java.util.List; +import java.util.Map; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.ToString; +import org.onap.policy.clamp.models.acm.document.base.DocUtil; +import org.onap.policy.common.parameters.annotations.Valid; +import org.onap.policy.models.base.PfUtils; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; + +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor +@ToString(callSuper = true) +public class DocToscaNodeTemplate extends DocToscaWithTypeAndStringProperties<ToscaNodeTemplate> { + + private static final long serialVersionUID = 1L; + + private List<Map<String, @Valid DocToscaRequirement>> requirements; + + private Map<String, @Valid DocToscaCapabilityAssignment> capabilities; + + /** + * Authorative constructor. + * + * @param authorativeConcept the authorative concept to copy from + */ + public DocToscaNodeTemplate(final ToscaNodeTemplate authorativeConcept) { + this.fromAuthorative(authorativeConcept); + } + + /** + * Copy constructor. + * + * @param copyConcept the concept to copy from + */ + public DocToscaNodeTemplate(final DocToscaNodeTemplate copyConcept) { + super(copyConcept); + this.requirements = + PfUtils.mapList(copyConcept.requirements, map -> DocUtil.docMapToMap(map, DocToscaRequirement::new)); + this.capabilities = DocUtil.docMapToMap(copyConcept.capabilities, DocToscaCapabilityAssignment::new); + } + + @Override + public ToscaNodeTemplate toAuthorative() { + var toscaNodeTemplate = new ToscaNodeTemplate(); + super.setToscaEntity(toscaNodeTemplate); + super.toAuthorative(); + + toscaNodeTemplate.setRequirements( + PfUtils.mapList(requirements, map -> DocUtil.docMapToMap(map, DocToscaRequirement::toAuthorative))); + + toscaNodeTemplate + .setCapabilities(DocUtil.docMapToMap(capabilities, DocToscaCapabilityAssignment::toAuthorative)); + + return toscaNodeTemplate; + } + + @Override + public void fromAuthorative(ToscaNodeTemplate toscaNodeTemplate) { + super.fromAuthorative(toscaNodeTemplate); + + requirements = PfUtils.mapList(toscaNodeTemplate.getRequirements(), + map -> DocUtil.mapToDocMap(map, DocToscaRequirement::new)); + + capabilities = DocUtil.mapToDocMap(toscaNodeTemplate.getCapabilities(), DocToscaCapabilityAssignment::new); + } + + @Override + public int compareTo(DocToscaEntity<ToscaNodeTemplate> otherConcept) { + if (this == otherConcept) { + return 0; + } + + int result = super.compareTo(otherConcept); + if (result != 0) { + return result; + } + + final var other = (DocToscaNodeTemplate) otherConcept; + + result = PfUtils.compareCollections(requirements, other.requirements); + if (result != 0) { + return result; + } + + return PfUtils.compareMaps(capabilities, other.capabilities); + } +} diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaNodeType.java b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaNodeType.java new file mode 100644 index 000000000..9f79b20f6 --- /dev/null +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaNodeType.java @@ -0,0 +1,90 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.clamp.models.acm.document.concepts; + +import java.util.List; +import java.util.Map; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import org.onap.policy.clamp.models.acm.document.base.DocUtil; +import org.onap.policy.common.parameters.annotations.Valid; +import org.onap.policy.models.base.PfUtils; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeType; + +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor +public class DocToscaNodeType extends DocToscaWithToscaProperties<ToscaNodeType> { + + private static final long serialVersionUID = 1L; + + private List<Map<String, @Valid DocToscaRequirement>> requirements; + + public DocToscaNodeType(ToscaNodeType toscaNodeType) { + fromAuthorative(toscaNodeType); + } + + /** + * Copy constructor. + * + * @param copyConcept the concept to copy from + */ + public DocToscaNodeType(final DocToscaNodeType copyConcept) { + super(copyConcept); + this.requirements = + PfUtils.mapList(copyConcept.requirements, map -> DocUtil.docMapToMap(map, DocToscaRequirement::new)); + } + + @Override + public ToscaNodeType toAuthorative() { + var toscaNodeType = new ToscaNodeType(); + super.setToscaEntity(toscaNodeType); + super.toAuthorative(); + toscaNodeType.setRequirements( + PfUtils.mapList(requirements, map -> DocUtil.docMapToMap(map, DocToscaRequirement::toAuthorative))); + + return toscaNodeType; + } + + @Override + public void fromAuthorative(ToscaNodeType toscaNodeType) { + super.fromAuthorative(toscaNodeType); + requirements = PfUtils.mapList(toscaNodeType.getRequirements(), + map -> DocUtil.mapToDocMap(map, DocToscaRequirement::new)); + } + + @Override + public int compareTo(DocToscaEntity<ToscaNodeType> otherConcept) { + if (this == otherConcept) { + return 0; + } + + int result = super.compareTo(otherConcept); + if (result != 0) { + return result; + } + + final var other = (DocToscaNodeType) otherConcept; + + return PfUtils.compareCollections(requirements, other.requirements); + } +} diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaParameter.java b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaParameter.java new file mode 100644 index 000000000..ab7894a1e --- /dev/null +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaParameter.java @@ -0,0 +1,114 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.clamp.models.acm.document.concepts; + +import com.google.gson.annotations.SerializedName; +import java.io.Serializable; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.onap.policy.common.parameters.annotations.NotNull; +import org.onap.policy.models.base.PfAuthorative; +import org.onap.policy.models.base.PfKey; +import org.onap.policy.models.base.PfUtils; +import org.onap.policy.models.tosca.authorative.concepts.ToscaParameter; + +@Data +@NoArgsConstructor +public class DocToscaParameter implements PfAuthorative<ToscaParameter>, Serializable, Comparable<DocToscaParameter> { + + private static final long serialVersionUID = 1L; + + @NotNull + private String name; + + @NotNull + private String type; + + @NotNull + @SerializedName("type_version") + private String typeVersion; + + private Object value; + + /** + * Authorative constructor. + * + * @param authorativeConcept the authorative concept to copy from + */ + public DocToscaParameter(final ToscaParameter authorativeConcept) { + this.fromAuthorative(authorativeConcept); + } + + /** + * Copy constructor. + * + * @param copyConcept the concept to copy from + */ + public DocToscaParameter(final DocToscaParameter copyConcept) { + this.name = copyConcept.name; + this.type = copyConcept.type; + this.typeVersion = copyConcept.typeVersion; + this.value = copyConcept.value; + } + + @Override + public ToscaParameter toAuthorative() { + var toscaParameter = new ToscaParameter(); + + toscaParameter.setName(name); + toscaParameter.setType(type); + toscaParameter.setTypeVersion(typeVersion); + toscaParameter.setValue(value); + + return toscaParameter; + } + + @Override + public void fromAuthorative(ToscaParameter toscaParameter) { + name = toscaParameter.getName(); + type = toscaParameter.getType(); + + if (toscaParameter.getTypeVersion() != null) { + typeVersion = toscaParameter.getTypeVersion(); + } else { + typeVersion = PfKey.NULL_KEY_VERSION; + } + + value = toscaParameter.getValue(); + } + + @Override + public int compareTo(DocToscaParameter otherConcept) { + if (otherConcept == null) { + return -1; + } + if (this == otherConcept) { + return 0; + } + + int result = name.compareTo(otherConcept.name); + if (result != 0) { + return result; + } + + return PfUtils.compareObjects(value, otherConcept.value); + } +} diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaPolicy.java b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaPolicy.java new file mode 100644 index 000000000..7b2291bfd --- /dev/null +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaPolicy.java @@ -0,0 +1,93 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.clamp.models.acm.document.concepts; + +import java.util.LinkedHashMap; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import lombok.ToString; +import org.onap.policy.common.parameters.BeanValidationResult; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; + +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor +@ToString(callSuper = true) +public class DocToscaPolicy extends DocToscaWithTypeAndStringProperties<ToscaPolicy> { + + private static final long serialVersionUID = 1L; + + // Tags for metadata + private static final String METADATA_POLICY_ID_TAG = "policy-id"; + private static final String METADATA_POLICY_VERSION_TAG = "policy-version"; + + /** + * Copy constructor. + * + * @param copyObject object to copy + */ + public DocToscaPolicy(@NonNull ToscaPolicy copyObject) { + this.fromAuthorative(copyObject); + } + + /** + * Copy constructor. + * + * @param copyConcept the concept to copy from + */ + public DocToscaPolicy(final DocToscaPolicy copyConcept) { + super(copyConcept); + } + + @Override + public ToscaPolicy toAuthorative() { + var toscaPolicy = new ToscaPolicy(); + super.setToscaEntity(toscaPolicy); + super.toAuthorative(); + + return toscaPolicy; + } + + @Override + public void fromAuthorative(ToscaPolicy toscaPolicy) { + super.fromAuthorative(toscaPolicy); + + // 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, getKey().getVersion()); + } + + @Override + public BeanValidationResult validate(String fieldName) { + var result = super.validate(fieldName); + + validateKeyVersionNotNull(result, "key", getConceptKey()); + + return result; + } +} diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaPolicyType.java b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaPolicyType.java new file mode 100644 index 000000000..a57014425 --- /dev/null +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaPolicyType.java @@ -0,0 +1,60 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.clamp.models.acm.document.concepts; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyType; + +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor +public class DocToscaPolicyType extends DocToscaWithToscaProperties<ToscaPolicyType> { + + private static final long serialVersionUID = 1L; + + /** + * Authorative constructor. + * + * @param authorativeConcept the authorative concept to copy from + */ + public DocToscaPolicyType(final ToscaPolicyType authorativeConcept) { + fromAuthorative(authorativeConcept); + } + + /** + * Copy constructor. + * + * @param copyConcept the concept to copy from + */ + public DocToscaPolicyType(final DocToscaPolicyType copyConcept) { + super(copyConcept); + } + + @Override + public ToscaPolicyType toAuthorative() { + var toscaPolicyType = new ToscaPolicyType(); + super.setToscaEntity(toscaPolicyType); + super.toAuthorative(); + return toscaPolicyType; + } +} diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaProperty.java b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaProperty.java new file mode 100644 index 000000000..1bcbd6b0a --- /dev/null +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaProperty.java @@ -0,0 +1,215 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.clamp.models.acm.document.concepts; + +import com.google.gson.annotations.SerializedName; +import java.io.Serializable; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.ObjectUtils; +import org.onap.policy.clamp.models.acm.document.base.DocConceptKey; +import org.onap.policy.clamp.models.acm.document.base.DocUtil; +import org.onap.policy.common.parameters.annotations.NotBlank; +import org.onap.policy.common.parameters.annotations.NotNull; +import org.onap.policy.common.parameters.annotations.Valid; +import org.onap.policy.models.base.PfAuthorative; +import org.onap.policy.models.base.PfUtils; +import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty; + +@Data +@NoArgsConstructor +public class DocToscaProperty implements PfAuthorative<ToscaProperty>, Serializable, Comparable<DocToscaProperty> { + + private static final long serialVersionUID = 1L; + + @NotNull + private String name; + + @NotNull + private String type; + + @SerializedName("type_version") + @NotNull + private String typeVersion; + + @NotBlank + private String description; + + @SerializedName("default") + @NotBlank + private Object defaultValue; + + private boolean required = false; + private ToscaProperty.Status status; + private List<@NotNull @Valid DocToscaConstraint> constraints; + + @SerializedName("key_schema") + @Valid + private DocToscaSchemaDefinition keySchema; + + @SerializedName("entry_schema") + @Valid + private DocToscaSchemaDefinition entrySchema; + + private Map<String, String> metadata; + + public DocToscaProperty(ToscaProperty toscaProperty) { + fromAuthorative(toscaProperty); + } + + /** + * Copy constructor. + * + * @param copyConcept the concept to copy from + */ + public DocToscaProperty(final DocToscaProperty copyConcept) { + this.name = copyConcept.name; + this.type = copyConcept.type; + this.typeVersion = copyConcept.typeVersion; + this.description = copyConcept.description; + this.defaultValue = copyConcept.defaultValue; + this.required = copyConcept.required; + this.status = copyConcept.status; + this.constraints = PfUtils.mapList(copyConcept.constraints, DocToscaConstraint::new); + if (copyConcept.keySchema != null) { + this.keySchema = new DocToscaSchemaDefinition(copyConcept.keySchema); + } + if (copyConcept.entrySchema != null) { + this.entrySchema = new DocToscaSchemaDefinition(copyConcept.entrySchema); + } + this.metadata = (copyConcept.metadata != null ? new LinkedHashMap<>(copyConcept.metadata) : null); + } + + @Override + public ToscaProperty toAuthorative() { + var toscaProperty = new ToscaProperty(); + + toscaProperty.setName(name); + toscaProperty.setType(getTypeDocConceptKey().getId()); + toscaProperty.setDescription(description); + toscaProperty.setRequired(required); + toscaProperty.setStatus(status); + toscaProperty.setDefaultValue(defaultValue); + toscaProperty.setConstraints(PfUtils.mapList(constraints, DocToscaConstraint::toAuthorative)); + + if (entrySchema != null) { + toscaProperty.setEntrySchema(entrySchema.toAuthorative()); + } + if (keySchema != null) { + toscaProperty.setEntrySchema(keySchema.toAuthorative()); + } + + toscaProperty.setMetadata(PfUtils.mapMap(metadata, metadataItem -> metadataItem)); + + return toscaProperty; + } + + @Override + public void fromAuthorative(ToscaProperty toscaProperty) { + name = toscaProperty.getName(); + + var key = DocUtil.createDocConceptKey(toscaProperty.getType(), toscaProperty.getTypeVersion()); + type = key.getName(); + typeVersion = key.getVersion(); + + description = toscaProperty.getDescription(); + required = toscaProperty.isRequired(); + status = toscaProperty.getStatus(); + defaultValue = toscaProperty.getDefaultValue(); + constraints = PfUtils.mapList(toscaProperty.getConstraints(), DocToscaConstraint::new); + + if (toscaProperty.getEntrySchema() != null) { + entrySchema = new DocToscaSchemaDefinition(toscaProperty.getEntrySchema()); + } + if (toscaProperty.getKeySchema() != null) { + keySchema = new DocToscaSchemaDefinition(toscaProperty.getKeySchema()); + } + + metadata = PfUtils.mapMap(toscaProperty.getMetadata(), metadataItem -> metadataItem); + } + + public DocConceptKey getTypeDocConceptKey() { + return new DocConceptKey(type, typeVersion); + } + + @Override + public int compareTo(DocToscaProperty otherConcept) { + if (otherConcept == null) { + return -1; + } + if (this == otherConcept) { + return 0; + } + + int result = name.compareTo(otherConcept.name); + if (result != 0) { + return result; + } + + return compareFields(otherConcept); + } + + /** + * Compare the fields of this ToscaProperty object with the fields of the other ToscaProperty object. + * + * @param other the other ToscaProperty object + */ + private int compareFields(final DocToscaProperty other) { + if (!type.equals(other.type)) { + return type.compareTo(other.type); + } + + int result = ObjectUtils.compare(description, other.description); + if (result != 0) { + return result; + } + + result = ObjectUtils.compare(required, other.required); + if (result != 0) { + return result; + } + + result = PfUtils.compareObjects(defaultValue, other.defaultValue); + if (result != 0) { + return result; + } + + result = ObjectUtils.compare(status, other.status); + if (result != 0) { + return result; + } + + result = PfUtils.compareCollections(constraints, other.constraints); + if (result != 0) { + return result; + } + + result = entrySchema.compareTo(other.entrySchema); + if (result != 0) { + return result; + } + + return PfUtils.compareMaps(metadata, other.metadata); + } +} diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaRelationshipType.java b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaRelationshipType.java new file mode 100644 index 000000000..5a650f1df --- /dev/null +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaRelationshipType.java @@ -0,0 +1,58 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.clamp.models.acm.document.concepts; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import org.onap.policy.models.tosca.authorative.concepts.ToscaRelationshipType; + +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor +public class DocToscaRelationshipType extends DocToscaWithToscaProperties<ToscaRelationshipType> { + + private static final long serialVersionUID = 1L; + + /** + * Authorative constructor. + * + * @param authorativeConcept the authorative concept to copy from + */ + public DocToscaRelationshipType(final ToscaRelationshipType authorativeConcept) { + fromAuthorative(authorativeConcept); + } + + /** + * Copy constructor. + * + * @param copyConcept the concept to copy from + */ + public DocToscaRelationshipType(final DocToscaRelationshipType copyConcept) { + super(copyConcept); + } + + @Override + public ToscaRelationshipType toAuthorative() { + super.setToscaEntity(new ToscaRelationshipType()); + return super.toAuthorative(); + } +} diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaRequirement.java b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaRequirement.java new file mode 100644 index 000000000..5bef710d2 --- /dev/null +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaRequirement.java @@ -0,0 +1,122 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.clamp.models.acm.document.concepts; + +import java.util.ArrayList; +import java.util.List; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.ToString; +import org.onap.policy.models.base.PfUtils; +import org.onap.policy.models.tosca.authorative.concepts.ToscaRequirement; + +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor +@ToString(callSuper = true) +public class DocToscaRequirement extends DocToscaWithTypeAndStringProperties<ToscaRequirement> { + + private static final long serialVersionUID = 1L; + + private String capability; + private String node; + private String relationship; + private List<Object> occurrences; + + public DocToscaRequirement(ToscaRequirement toscaRequirement) { + fromAuthorative(toscaRequirement); + } + + /** + * Copy constructor. + * + * @param copyConcept the concept to copy from + */ + public DocToscaRequirement(final DocToscaRequirement copyConcept) { + super(copyConcept); + this.capability = copyConcept.capability; + this.node = copyConcept.node; + this.relationship = copyConcept.relationship; + this.occurrences = new ArrayList<>(copyConcept.occurrences); + } + + @Override + public ToscaRequirement toAuthorative() { + var toscaRequirement = new ToscaRequirement(); + super.setToscaEntity(toscaRequirement); + super.toAuthorative(); + + toscaRequirement.setCapability(capability); + toscaRequirement.setNode(node); + toscaRequirement.setRelationship(relationship); + + if (occurrences != null) { + toscaRequirement.setOccurrences(new ArrayList<>(occurrences)); + } + + return toscaRequirement; + } + + @Override + public void fromAuthorative(ToscaRequirement toscaRequirement) { + super.fromAuthorative(toscaRequirement); + + capability = toscaRequirement.getCapability(); + node = toscaRequirement.getNode(); + relationship = toscaRequirement.getRelationship(); + + if (toscaRequirement.getOccurrences() != null) { + occurrences = new ArrayList<>(toscaRequirement.getOccurrences()); + } + } + + @Override + public int compareTo(DocToscaEntity<ToscaRequirement> otherConcept) { + if (this == otherConcept) { + return 0; + } + + int result = super.compareTo(otherConcept); + if (result != 0) { + return result; + } + + final var other = (DocToscaRequirement) otherConcept; + + result = capability.compareTo(other.capability); + if (result != 0) { + return result; + } + + result = node.compareTo(other.node); + if (result != 0) { + return result; + } + + result = relationship.compareTo(other.relationship); + if (result != 0) { + return result; + } + + return PfUtils.compareCollections(occurrences, other.occurrences); + } +} diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaSchemaDefinition.java b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaSchemaDefinition.java new file mode 100644 index 000000000..89b3c42cd --- /dev/null +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaSchemaDefinition.java @@ -0,0 +1,119 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.clamp.models.acm.document.concepts; + +import com.google.gson.annotations.SerializedName; +import java.io.Serializable; +import java.util.List; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.ObjectUtils; +import org.onap.policy.clamp.models.acm.document.base.DocConceptKey; +import org.onap.policy.clamp.models.acm.document.base.DocUtil; +import org.onap.policy.models.base.PfAuthorative; +import org.onap.policy.models.base.PfUtils; +import org.onap.policy.models.tosca.authorative.concepts.ToscaSchemaDefinition; + +@Data +@NoArgsConstructor +public class DocToscaSchemaDefinition + implements PfAuthorative<ToscaSchemaDefinition>, Serializable, Comparable<DocToscaSchemaDefinition> { + + private static final long serialVersionUID = 1L; + + private String name; + private String type; + + @SerializedName("type_version") + private String typeVersion; + + private String description; + private List<DocToscaConstraint> constraints; + + public DocToscaSchemaDefinition(ToscaSchemaDefinition toscaEntrySchema) { + fromAuthorative(toscaEntrySchema); + } + + /** + * Copy constructor. + * + * @param copyConcept the concept to copy from + */ + public DocToscaSchemaDefinition(final DocToscaSchemaDefinition copyConcept) { + this.name = copyConcept.name; + this.type = copyConcept.type; + this.typeVersion = copyConcept.typeVersion; + this.description = copyConcept.description; + this.constraints = PfUtils.mapList(copyConcept.constraints, DocToscaConstraint::new); + } + + @Override + public ToscaSchemaDefinition toAuthorative() { + var toscaEntrySchema = new ToscaSchemaDefinition(); + + toscaEntrySchema.setName(name); + toscaEntrySchema.setType(getTypeDocConceptKey().getId()); + toscaEntrySchema.setDescription(description); + + if (constraints != null) { + toscaEntrySchema.setConstraints(PfUtils.mapList(constraints, DocToscaConstraint::toAuthorative)); + } + + return toscaEntrySchema; + } + + @Override + public void fromAuthorative(ToscaSchemaDefinition toscaEntrySchema) { + name = toscaEntrySchema.getName(); + + var key = DocUtil.createDocConceptKey(toscaEntrySchema.getType(), toscaEntrySchema.getTypeVersion()); + type = key.getName(); + typeVersion = key.getVersion(); + + description = toscaEntrySchema.getDescription(); + + if (toscaEntrySchema.getConstraints() != null) { + constraints = PfUtils.mapList(toscaEntrySchema.getConstraints(), DocToscaConstraint::new); + + } + } + + public DocConceptKey getTypeDocConceptKey() { + return new DocConceptKey(type, typeVersion); + } + + @Override + public int compareTo(DocToscaSchemaDefinition other) { + if (other == null) { + return -1; + } + if (this == other) { + return 0; + } + + int result = ObjectUtils.compare(description, other.description); + if (result != 0) { + return result; + } + + return PfUtils.compareCollections(constraints, other.constraints); + } +} diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaServiceTemplate.java b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaServiceTemplate.java new file mode 100644 index 000000000..bd47452e4 --- /dev/null +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaServiceTemplate.java @@ -0,0 +1,215 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.clamp.models.acm.document.concepts; + +import com.google.gson.annotations.SerializedName; +import java.util.LinkedHashMap; +import java.util.Map; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.ObjectUtils; +import org.onap.policy.clamp.models.acm.document.base.DocUtil; +import org.onap.policy.common.parameters.annotations.NotBlank; +import org.onap.policy.common.parameters.annotations.NotNull; +import org.onap.policy.common.parameters.annotations.Valid; +import org.onap.policy.models.base.PfKey; +import org.onap.policy.models.base.PfUtils; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; + +@Data +@EqualsAndHashCode(callSuper = true) +public class DocToscaServiceTemplate extends DocToscaEntity<ToscaServiceTemplate> { + + private static final long serialVersionUID = 1L; + + public static final String DEFAULT_TOSCA_DEFINTIONS_VERISON = "tosca_simple_yaml_1_1_0"; + public static final String DEFAULT_NAME = "tosca"; + public static final String DEFAULT_VERSION = "1.0.0"; + + @SerializedName("tosca_definitions_version") + @NotNull + @NotBlank + private String toscaDefinitionsVersion; + + @SerializedName("data_types") + private Map<String, @Valid DocToscaDataType> dataTypes; + + @SerializedName("capability_types") + private Map<String, @Valid DocToscaCapabilityType> capabilityTypes; + + @SerializedName("node_types") + private Map<String, @Valid DocToscaNodeType> nodeTypes; + + @SerializedName("relationship_types") + private Map<String, @Valid DocToscaRelationshipType> relationshipTypes; + + @SerializedName("policy_types") + private Map<String, @Valid DocToscaPolicyType> policyTypes; + + @SerializedName("topology_template") + @Valid + private DocToscaTopologyTemplate toscaTopologyTemplate; + + public DocToscaServiceTemplate(ToscaServiceTemplate authorativeConcept) { + this.fromAuthorative(authorativeConcept); + } + + /** + * The Default Constructor creates a {@link DocToscaServiceTemplate} object with a null key. + */ + public DocToscaServiceTemplate() { + super(); + setName(DEFAULT_NAME); + setVersion(DEFAULT_VERSION); + setToscaDefinitionsVersion(DEFAULT_TOSCA_DEFINTIONS_VERISON); + } + + /** + * Copy constructor. + * + * @param copyConcept the concept to copy from + */ + public DocToscaServiceTemplate(final DocToscaServiceTemplate copyConcept) { + super(copyConcept); + this.toscaDefinitionsVersion = copyConcept.toscaDefinitionsVersion; + this.dataTypes = DocUtil.docMapToMap(copyConcept.dataTypes, DocToscaDataType::new, new LinkedHashMap<>()); + this.capabilityTypes = + DocUtil.docMapToMap(copyConcept.capabilityTypes, DocToscaCapabilityType::new, new LinkedHashMap<>()); + this.nodeTypes = DocUtil.docMapToMap(copyConcept.nodeTypes, DocToscaNodeType::new, new LinkedHashMap<>()); + this.relationshipTypes = DocUtil.docMapToMap(copyConcept.relationshipTypes, DocToscaRelationshipType::new, + new LinkedHashMap<>()); + this.policyTypes = DocUtil.docMapToMap(copyConcept.policyTypes, DocToscaPolicyType::new, new LinkedHashMap<>()); + if (copyConcept.toscaTopologyTemplate != null) { + this.toscaTopologyTemplate = new DocToscaTopologyTemplate(copyConcept.toscaTopologyTemplate); + } + } + + @Override + public ToscaServiceTemplate toAuthorative() { + final var toscaServiceTemplate = new ToscaServiceTemplate(); + super.setToscaEntity(toscaServiceTemplate); + super.toAuthorative(); + + toscaServiceTemplate.setToscaDefinitionsVersion(toscaDefinitionsVersion); + toscaServiceTemplate.setDataTypes(DocUtil.docMapToMap(dataTypes, DocToscaDataType::toAuthorative)); + toscaServiceTemplate + .setCapabilityTypes(DocUtil.docMapToMap(capabilityTypes, DocToscaCapabilityType::toAuthorative)); + toscaServiceTemplate + .setRelationshipTypes(DocUtil.docMapToMap(relationshipTypes, DocToscaRelationshipType::toAuthorative)); + toscaServiceTemplate.setNodeTypes(DocUtil.docMapToMap(nodeTypes, DocToscaNodeType::toAuthorative)); + toscaServiceTemplate.setPolicyTypes(DocUtil.docMapToMap(policyTypes, DocToscaPolicyType::toAuthorative)); + toscaServiceTemplate.setToscaTopologyTemplate(toscaTopologyTemplate.toAuthorative()); + + return toscaServiceTemplate; + } + + @Override + public void fromAuthorative(ToscaServiceTemplate toscaServiceTemplate) { + super.fromAuthorative(toscaServiceTemplate); + if (getVersion() == null || PfKey.NULL_KEY_VERSION.equals(getVersion())) { + setVersion(DEFAULT_VERSION); + } + if (getName() == null || PfKey.NULL_KEY_NAME.equals(getName())) { + setName(DEFAULT_NAME); + } + + toscaDefinitionsVersion = toscaServiceTemplate.getToscaDefinitionsVersion(); + + dataTypes = DocUtil.mapToDocMap(toscaServiceTemplate.getDataTypes(), DocToscaDataType::new); + + capabilityTypes = DocUtil.mapToDocMap(toscaServiceTemplate.getCapabilityTypes(), DocToscaCapabilityType::new); + + relationshipTypes = + DocUtil.mapToDocMap(toscaServiceTemplate.getRelationshipTypes(), DocToscaRelationshipType::new); + + nodeTypes = DocUtil.mapToDocMap(toscaServiceTemplate.getNodeTypes(), DocToscaNodeType::new); + + if (toscaServiceTemplate.getPolicyTypes() != null) { + policyTypes = DocUtil.mapToDocMap(toscaServiceTemplate.getPolicyTypes(), DocToscaPolicyType::new); + } + + if (toscaServiceTemplate.getToscaTopologyTemplate() != null) { + toscaTopologyTemplate = new DocToscaTopologyTemplate(toscaServiceTemplate.getToscaTopologyTemplate()); + } + } + + @Override + public int compareTo(DocToscaEntity<ToscaServiceTemplate> otherConcept) { + int result = compareToWithoutEntities(otherConcept); + if (result != 0) { + return result; + } + + final DocToscaServiceTemplate other = (DocToscaServiceTemplate) otherConcept; + + result = PfUtils.compareMaps(dataTypes, other.dataTypes); + if (result != 0) { + return result; + } + + result = PfUtils.compareMaps(capabilityTypes, other.capabilityTypes); + if (result != 0) { + return result; + } + + result = PfUtils.compareMaps(relationshipTypes, other.relationshipTypes); + if (result != 0) { + return result; + } + + result = PfUtils.compareMaps(nodeTypes, other.nodeTypes); + if (result != 0) { + return result; + } + + result = PfUtils.compareMaps(policyTypes, other.policyTypes); + if (result != 0) { + return result; + } + + return ObjectUtils.compare(toscaTopologyTemplate, other.toscaTopologyTemplate); + } + + /** + * Compare this service template to another service template, ignoring contained entitites. + * + * @param otherConcept the other topology template + * @return the result of the comparison + */ + public int compareToWithoutEntities(final DocToscaEntity<ToscaServiceTemplate> otherConcept) { + if (otherConcept == null) { + return -1; + } + if (this == otherConcept) { + return 0; + } + if (getClass() != otherConcept.getClass()) { + return getClass().getName().compareTo(otherConcept.getClass().getName()); + } + + final var other = (DocToscaServiceTemplate) otherConcept; + if (!super.equals(other)) { + return super.compareTo(other); + } + + return ObjectUtils.compare(toscaDefinitionsVersion, other.toscaDefinitionsVersion); + } +} diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaTopologyTemplate.java b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaTopologyTemplate.java new file mode 100644 index 000000000..79a68e244 --- /dev/null +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaTopologyTemplate.java @@ -0,0 +1,143 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.clamp.models.acm.document.concepts; + +import com.google.gson.annotations.SerializedName; +import java.io.Serializable; +import java.util.LinkedHashMap; +import java.util.Map; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.ObjectUtils; +import org.onap.policy.clamp.models.acm.document.base.DocUtil; +import org.onap.policy.common.parameters.annotations.Valid; +import org.onap.policy.models.base.PfAuthorative; +import org.onap.policy.models.base.PfUtils; +import org.onap.policy.models.base.Validated; +import org.onap.policy.models.tosca.authorative.concepts.ToscaTopologyTemplate; + +@Data +@NoArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class DocToscaTopologyTemplate extends Validated + implements PfAuthorative<ToscaTopologyTemplate>, Serializable, Comparable<DocToscaTopologyTemplate> { + + private static final long serialVersionUID = 1L; + + private String description; + + private Map<String, @Valid DocToscaParameter> inputs; + + @SerializedName("node_templates") + private Map<String, @Valid DocToscaNodeTemplate> nodeTemplates; + + private Map<String, @Valid DocToscaPolicy> policies; + + /** + * Authorative constructor. + * + * @param authorativeConcept the authorative concept to copy from + */ + public DocToscaTopologyTemplate(final ToscaTopologyTemplate authorativeConcept) { + this.fromAuthorative(authorativeConcept); + } + + /** + * Copy constructor. + * + * @param copyConcept the concept to copy from + */ + public DocToscaTopologyTemplate(final DocToscaTopologyTemplate copyConcept) { + this.description = copyConcept.description; + this.inputs = PfUtils.mapMap(copyConcept.inputs, DocToscaParameter::new); + this.nodeTemplates = + DocUtil.docMapToMap(copyConcept.nodeTemplates, DocToscaNodeTemplate::new, new LinkedHashMap<>()); + this.policies = DocUtil.docMapToMap(copyConcept.policies, DocToscaPolicy::new, new LinkedHashMap<>()); + } + + @Override + public ToscaTopologyTemplate toAuthorative() { + final var toscaTopologyTemplate = new ToscaTopologyTemplate(); + + toscaTopologyTemplate.setDescription(description); + toscaTopologyTemplate.setInputs(PfUtils.mapMap(inputs, DocToscaParameter::toAuthorative)); + toscaTopologyTemplate.setNodeTemplates(DocUtil.docMapToMap(nodeTemplates, DocToscaNodeTemplate::toAuthorative)); + + toscaTopologyTemplate.setPolicies(DocUtil.docMapToList(policies, DocToscaPolicy::toAuthorative)); + + return toscaTopologyTemplate; + } + + @Override + public void fromAuthorative(ToscaTopologyTemplate toscaTopologyTemplate) { + description = toscaTopologyTemplate.getDescription(); + + if (toscaTopologyTemplate.getInputs() != null) { + inputs = PfUtils.mapMap(toscaTopologyTemplate.getInputs(), DocToscaParameter::new); + for (var entry : inputs.entrySet()) { + if (entry.getValue().getName() == null) { + entry.getValue().setName(entry.getKey()); + } + } + } + + nodeTemplates = DocUtil.mapToDocMap(toscaTopologyTemplate.getNodeTemplates(), DocToscaNodeTemplate::new); + + policies = DocUtil.listToDocMap(toscaTopologyTemplate.getPolicies(), DocToscaPolicy::new); + } + + @Override + public int compareTo(DocToscaTopologyTemplate otherConcept) { + int result = compareToWithoutEntities(otherConcept); + if (result != 0) { + return result; + } + + result = PfUtils.compareMaps(inputs, otherConcept.inputs); + if (result != 0) { + return result; + } + + result = PfUtils.compareMaps(nodeTemplates, otherConcept.nodeTemplates); + if (result != 0) { + return result; + } + return PfUtils.compareMaps(policies, otherConcept.policies); + } + + /** + * Compare this topology template to another topology template, ignoring contained entities. + * + * @param otherConcept the other topology template + * @return the result of the comparison + */ + public int compareToWithoutEntities(final DocToscaTopologyTemplate otherConcept) { + if (otherConcept == null) { + return -1; + } + if (this == otherConcept) { + return 0; + } + + return ObjectUtils.compare(description, otherConcept.description); + } +} diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaWithToscaProperties.java b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaWithToscaProperties.java new file mode 100644 index 000000000..3b53e1bc8 --- /dev/null +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaWithToscaProperties.java @@ -0,0 +1,122 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.clamp.models.acm.document.concepts; + +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import org.apache.commons.collections4.CollectionUtils; +import org.onap.policy.clamp.models.acm.document.base.DocConceptKey; +import org.onap.policy.common.parameters.BeanValidationResult; +import org.onap.policy.common.parameters.annotations.NotBlank; +import org.onap.policy.common.parameters.annotations.NotNull; +import org.onap.policy.common.parameters.annotations.Valid; +import org.onap.policy.models.base.PfUtils; +import org.onap.policy.models.tosca.authorative.concepts.ToscaWithToscaProperties; +import org.onap.policy.models.tosca.utils.ToscaUtils; + +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor +public class DocToscaWithToscaProperties<T extends ToscaWithToscaProperties> extends DocToscaEntity<T> { + + private static final long serialVersionUID = 1L; + + private Map<@NotNull @NotBlank String, @NotNull @Valid DocToscaProperty> properties; + + /** + * Copy constructor. + * + * @param copyConcept the concept to copy from + */ + public DocToscaWithToscaProperties(DocToscaWithToscaProperties<T> copyConcept) { + super(copyConcept); + this.properties = PfUtils.mapMap(copyConcept.properties, DocToscaProperty::new); + } + + @Override + public T toAuthorative() { + var tosca = super.toAuthorative(); + tosca.setProperties(PfUtils.mapMap(properties, DocToscaProperty::toAuthorative)); + return tosca; + } + + /** + * Validates the fields of the object, including its key. + * + * @param fieldName name of the field containing this + * @return the result, or {@code null} + */ + protected BeanValidationResult validateWithKey(@NonNull String fieldName) { + var result = super.validate(fieldName); + + validateKeyVersionNotNull(result, "key", getConceptKey()); + + return result; + } + + @Override + public void fromAuthorative(T authorativeConcept) { + super.fromAuthorative(authorativeConcept); + + // Set properties + if (authorativeConcept.getProperties() != null) { + properties = new LinkedHashMap<>(); + for (var toscaPropertyEntry : authorativeConcept.getProperties().entrySet()) { + var jpaProperty = new DocToscaProperty(toscaPropertyEntry.getValue()); + jpaProperty.setName(toscaPropertyEntry.getKey()); + properties.put(toscaPropertyEntry.getKey(), jpaProperty); + } + } + } + + /** + * Get the referenced data types. + * + * @return the referenced data types + */ + public Collection<DocConceptKey> getReferencedDataTypes() { + if (properties == null) { + return CollectionUtils.emptyCollection(); + } + + Set<DocConceptKey> referencedDataTypes = new LinkedHashSet<>(); + + for (var property : properties.values()) { + referencedDataTypes.add(property.getTypeDocConceptKey()); + + if (property.getEntrySchema() != null) { + referencedDataTypes.add(property.getEntrySchema().getTypeDocConceptKey()); + } + } + + var set = ToscaUtils.getPredefinedDataTypes().stream().map(DocConceptKey::new).collect(Collectors.toSet()); + referencedDataTypes.removeAll(set); + return referencedDataTypes; + } +} diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaWithTypeAndStringProperties.java b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaWithTypeAndStringProperties.java new file mode 100644 index 000000000..377cecb28 --- /dev/null +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/document/concepts/DocToscaWithTypeAndStringProperties.java @@ -0,0 +1,100 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.clamp.models.acm.document.concepts; + +import com.google.gson.annotations.SerializedName; +import java.util.LinkedHashMap; +import java.util.Map; +import javax.ws.rs.core.Response; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.ToString; +import org.onap.policy.clamp.models.acm.document.base.DocConceptKey; +import org.onap.policy.clamp.models.acm.document.base.DocUtil; +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.tosca.authorative.concepts.ToscaWithTypeAndObjectProperties; + +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor +@ToString +public class DocToscaWithTypeAndStringProperties<T extends ToscaWithTypeAndObjectProperties> extends DocToscaEntity<T> { + + private static final long serialVersionUID = 1L; + + private String type; + + @SerializedName("type_version") + private String typeVersion; + + private Map<String, Object> properties; + + /** + * Copy constructor. + * + * @param copyConcept the concept to copy from + */ + public DocToscaWithTypeAndStringProperties(final DocToscaWithTypeAndStringProperties<T> copyConcept) { + super(copyConcept); + this.type = copyConcept.type; + this.typeVersion = copyConcept.typeVersion; + this.properties = (copyConcept.properties != null ? new LinkedHashMap<>(copyConcept.properties) : null); + } + + @Override + public T toAuthorative() { + var tosca = super.toAuthorative(); + + tosca.setType(getTypeDocConceptKey().getId()); + tosca.setTypeVersion(""); + + tosca.setProperties(PfUtils.mapMap(properties, x -> x)); + + return tosca; + } + + @Override + public void fromAuthorative(T authorativeConcept) { + super.fromAuthorative(authorativeConcept); + if (authorativeConcept.getType() == null) { + throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, + "Type not specified, the type of this TOSCA entity must be specified in the type field"); + } + var key = DocUtil.createDocConceptKey(authorativeConcept.getType(), authorativeConcept.getTypeVersion()); + type = key.getName(); + typeVersion = key.getVersion(); + + if (PfKey.NULL_KEY_VERSION.equals(typeVersion)) { + throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, + "Version not specified, the version of this TOSCA entity must be specified" + + " in the type_version field"); + } + + properties = PfUtils.mapMap(authorativeConcept.getProperties(), x -> x); + } + + public DocConceptKey getTypeDocConceptKey() { + return new DocConceptKey(type, typeVersion); + } +} diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationComposition.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationComposition.java index e5c44d0a2..8268e9066 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationComposition.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationComposition.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. + * Copyright (C) 2021-2022 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,12 +25,12 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.UUID; -import javax.persistence.AttributeOverride; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.EmbeddedId; import javax.persistence.Entity; import javax.persistence.FetchType; +import javax.persistence.Index; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; import javax.persistence.ManyToMany; @@ -52,7 +52,6 @@ import org.onap.policy.models.base.PfKey; import org.onap.policy.models.base.PfReferenceKey; import org.onap.policy.models.base.PfUtils; import org.onap.policy.models.base.validation.annotations.VerifyKey; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; /** * Class to represent a automation composition in the database. @@ -60,7 +59,7 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; * @author Liam Fallon (liam.fallon@est.tech) */ @Entity -@Table(name = "AutomationComposition") +@Table(name = "AutomationComposition", indexes = {@Index(name = "ac_compositionId", columnList = "compositionId")}) @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) @Data @EqualsAndHashCode(callSuper = false) @@ -72,13 +71,8 @@ public class JpaAutomationComposition extends PfConcept implements PfAuthorative @NotNull private PfConceptKey key; - // @formatter:off - @VerifyKey @NotNull - @AttributeOverride(name = "name", column = @Column(name = "definition_name")) - @AttributeOverride(name = "version", column = @Column(name = "definition_version")) - private PfConceptKey definition; - // @formatter:on + private String compositionId; @Column @NotNull @@ -112,22 +106,22 @@ public class JpaAutomationComposition extends PfConcept implements PfAuthorative * @param key the key */ public JpaAutomationComposition(@NonNull final PfConceptKey key) { - this(key, new PfConceptKey(), AutomationCompositionState.UNINITIALISED, new LinkedHashMap<>()); + this(key, UUID.randomUUID().toString(), AutomationCompositionState.UNINITIALISED, new LinkedHashMap<>()); } /** * The Key Constructor creates a {@link JpaAutomationComposition} object with all mandatory fields. * * @param key the key - * @param definition the TOSCA definition of the automation composition + * @param compositionId the TOSCA compositionId of the automation composition definition * @param state the state of the automation composition * @param elements the elements of the automation composition in participants */ - public JpaAutomationComposition(@NonNull final PfConceptKey key, @NonNull final PfConceptKey definition, - @NonNull final AutomationCompositionState state, - @NonNull final Map<UUID, JpaAutomationCompositionElement> elements) { + public JpaAutomationComposition(@NonNull final PfConceptKey key, @NonNull final String compositionId, + @NonNull final AutomationCompositionState state, + @NonNull final Map<UUID, JpaAutomationCompositionElement> elements) { this.key = key; - this.definition = definition; + this.compositionId = compositionId; this.state = state; this.elements = elements; } @@ -140,12 +134,12 @@ public class JpaAutomationComposition extends PfConcept implements PfAuthorative public JpaAutomationComposition(@NonNull final JpaAutomationComposition copyConcept) { super(copyConcept); this.key = new PfConceptKey(copyConcept.key); - this.definition = new PfConceptKey(copyConcept.definition); + this.compositionId = copyConcept.compositionId; this.state = copyConcept.state; this.orderedState = copyConcept.orderedState; this.description = copyConcept.description; this.elements = - PfUtils.mapMap(copyConcept.elements, JpaAutomationCompositionElement::new, new LinkedHashMap<>(0)); + PfUtils.mapMap(copyConcept.elements, JpaAutomationCompositionElement::new, new LinkedHashMap<>(0)); this.primed = copyConcept.primed; } @@ -164,12 +158,12 @@ public class JpaAutomationComposition extends PfConcept implements PfAuthorative automationComposition.setName(getKey().getName()); automationComposition.setVersion(getKey().getVersion()); - automationComposition.setDefinition(new ToscaConceptIdentifier(definition)); + automationComposition.setCompositionId(UUID.fromString(compositionId)); automationComposition.setState(state); automationComposition.setOrderedState(orderedState != null ? orderedState : state.asOrderedState()); automationComposition.setDescription(description); automationComposition.setElements( - PfUtils.mapMap(elements, JpaAutomationCompositionElement::toAuthorative, new LinkedHashMap<>(0))); + PfUtils.mapMap(elements, JpaAutomationCompositionElement::toAuthorative, new LinkedHashMap<>(0))); automationComposition.setPrimed(primed); return automationComposition; @@ -181,7 +175,7 @@ public class JpaAutomationComposition extends PfConcept implements PfAuthorative this.setKey(new PfConceptKey(automationComposition.getName(), automationComposition.getVersion())); } - this.definition = automationComposition.getDefinition().asConceptKey(); + this.compositionId = automationComposition.getCompositionId().toString(); this.state = automationComposition.getState(); this.orderedState = automationComposition.getOrderedState(); this.description = automationComposition.getDescription(); @@ -191,7 +185,7 @@ public class JpaAutomationComposition extends PfConcept implements PfAuthorative for (Entry<UUID, AutomationCompositionElement> elementEntry : automationComposition.getElements().entrySet()) { var jpaAutomationCompositionElement = new JpaAutomationCompositionElement(); jpaAutomationCompositionElement - .setKey(new PfReferenceKey(getKey(), elementEntry.getValue().getId().toString())); + .setKey(new PfReferenceKey(getKey(), elementEntry.getValue().getId().toString())); jpaAutomationCompositionElement.fromAuthorative(elementEntry.getValue()); this.elements.put(elementEntry.getKey(), jpaAutomationCompositionElement); } @@ -201,8 +195,6 @@ public class JpaAutomationComposition extends PfConcept implements PfAuthorative public List<PfKey> getKeys() { List<PfKey> keyList = getKey().getKeys(); - keyList.add(definition); - for (JpaAutomationCompositionElement element : elements.values()) { keyList.addAll(element.getKeys()); } @@ -213,7 +205,6 @@ public class JpaAutomationComposition extends PfConcept implements PfAuthorative @Override public void clean() { key.clean(); - definition.clean(); description = (description == null ? null : description.trim()); for (JpaAutomationCompositionElement element : elements.values()) { @@ -239,7 +230,7 @@ public class JpaAutomationComposition extends PfConcept implements PfAuthorative return result; } - result = definition.compareTo(other.definition); + result = ObjectUtils.compare(compositionId, other.compositionId); if (result != 0) { return result; } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionDefinition.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionDefinition.java index 46c09d388..247d8f28c 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionDefinition.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionDefinition.java @@ -32,11 +32,14 @@ import javax.persistence.OneToOne; import javax.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.NonNull; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition; -import org.onap.policy.clamp.models.acm.persistence.provider.ProviderUtils; +import org.onap.policy.clamp.models.acm.utils.AcmUtils; +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.models.base.PfAuthorative; +import org.onap.policy.models.base.Validated; import org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate; /** @@ -47,7 +50,8 @@ import org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate; @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) @Data @EqualsAndHashCode(callSuper = false) -public class JpaAutomationCompositionDefinition implements PfAuthorative<AutomationCompositionDefinition> { +public class JpaAutomationCompositionDefinition extends Validated + implements PfAuthorative<AutomationCompositionDefinition> { @Id @NotNull @@ -69,9 +73,7 @@ public class JpaAutomationCompositionDefinition implements PfAuthorative<Automat @Override public void fromAuthorative(final AutomationCompositionDefinition copyConcept) { compositionId = copyConcept.getCompositionId().toString(); - serviceTemplate = ProviderUtils.getJpaAndValidate(copyConcept.getServiceTemplate(), - JpaToscaServiceTemplate::new, "toscaServiceTemplate"); - + serviceTemplate = new JpaToscaServiceTemplate(copyConcept.getServiceTemplate()); } public JpaAutomationCompositionDefinition(final AutomationCompositionDefinition acmDefinition) { @@ -82,4 +84,16 @@ public class JpaAutomationCompositionDefinition implements PfAuthorative<Automat super(); } + @Override + public BeanValidationResult validate(@NonNull String fieldName) { + var result = super.validate(fieldName); + + AcmUtils.validateToscaTopologyTemplate(result, serviceTemplate); + + if (!result.isValid()) { + return result; + } + + return result; + } } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/StringToServiceTemplateConverter.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/StringToServiceTemplateConverter.java new file mode 100644 index 000000000..79e69128b --- /dev/null +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/StringToServiceTemplateConverter.java @@ -0,0 +1,57 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.clamp.models.acm.persistence.concepts; + +import javax.persistence.AttributeConverter; +import javax.persistence.Converter; +import javax.ws.rs.core.Response; +import org.onap.policy.clamp.models.acm.document.concepts.DocToscaServiceTemplate; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.models.base.PfModelRuntimeException; + +@Converter(autoApply = true) +public class StringToServiceTemplateConverter implements AttributeConverter<DocToscaServiceTemplate, String> { + + private static final Coder coder = new StandardCoder(); + + @Override + public String convertToDatabaseColumn(DocToscaServiceTemplate serviceTemplate) { + try { + return serviceTemplate == null ? null : coder.encode(serviceTemplate); + } catch (CoderException e) { + throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, e.getMessage(), e); + } + } + + @Override + public DocToscaServiceTemplate convertToEntityAttribute(String dbData) { + if (dbData == null) { + return new DocToscaServiceTemplate(); + } + try { + return coder.decode(dbData, DocToscaServiceTemplate.class); + } catch (CoderException e) { + throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, e.getMessage(), e); + } + } +} diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProvider.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProvider.java index 5740207c7..dc1785e52 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProvider.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProvider.java @@ -21,6 +21,7 @@ package org.onap.policy.clamp.models.acm.persistence.provider; import java.util.List; +import java.util.Optional; import java.util.UUID; import javax.ws.rs.core.Response; import lombok.RequiredArgsConstructor; @@ -53,7 +54,10 @@ public class AcDefinitionProvider { var acmDefinition = new AutomationCompositionDefinition(); acmDefinition.setCompositionId(UUID.randomUUID()); acmDefinition.setServiceTemplate(serviceTemplate); - var result = acmDefinitionRepository.save(new JpaAutomationCompositionDefinition(acmDefinition)); + var jpaAcmDefinition = ProviderUtils.getJpaAndValidate(acmDefinition, JpaAutomationCompositionDefinition::new, + "AutomationCompositionDefinition"); + var result = acmDefinitionRepository.save(jpaAcmDefinition); + return result.toAuthorative(); } @@ -107,13 +111,26 @@ public class AcDefinitionProvider { } /** - * Get service templates. + * Get the requested automation composition definition. * - * @return the topology templates found + * @param compositionId The UUID of the automation composition definition to delete + * @return the automation composition definition + */ + @Transactional(readOnly = true) + public Optional<ToscaServiceTemplate> findAcDefinition(UUID compositionId) { + var jpaGet = acmDefinitionRepository.findById(compositionId.toString()); + return jpaGet.stream().map(JpaAutomationCompositionDefinition::getServiceTemplate) + .map(JpaToscaServiceTemplate::toAuthorative).findFirst(); + } + + /** + * Get Automation Composition Definitions. + * + * @return the Automation Composition Definitions found */ @Transactional(readOnly = true) - public List<ToscaServiceTemplate> getAllServiceTemplates() { - var jpaList = serviceTemplateRepository.findAll(); + public List<AutomationCompositionDefinition> getAllAcDefinitions() { + var jpaList = acmDefinitionRepository.findAll(); return ProviderUtils.asEntityList(jpaList); } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java index c4f8b91e7..272ea422b 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java @@ -24,6 +24,7 @@ package org.onap.policy.clamp.models.acm.persistence.provider; import java.util.List; import java.util.Optional; +import java.util.UUID; import javax.persistence.EntityNotFoundException; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; @@ -32,13 +33,9 @@ import lombok.NonNull; import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; import org.onap.policy.clamp.models.acm.persistence.concepts.JpaAutomationComposition; import org.onap.policy.clamp.models.acm.persistence.repository.AutomationCompositionRepository; -import org.onap.policy.clamp.models.acm.persistence.repository.ToscaNodeTemplateRepository; import org.onap.policy.models.base.PfConceptKey; import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; -import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; -import org.onap.policy.models.tosca.authorative.concepts.ToscaTypedEntityFilter; -import org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -51,7 +48,6 @@ import org.springframework.transaction.annotation.Transactional; public class AutomationCompositionProvider { private final AutomationCompositionRepository automationCompositionRepository; - private final ToscaNodeTemplateRepository toscaNodeTemplateRepository; /** * Get automation composition. @@ -62,7 +58,7 @@ public class AutomationCompositionProvider { */ @Transactional(readOnly = true) public AutomationComposition getAutomationComposition(final ToscaConceptIdentifier automationCompositionId) - throws PfModelException { + throws PfModelException { try { return automationCompositionRepository.getById(automationCompositionId.asConceptKey()).toAuthorative(); } catch (EntityNotFoundException e) { @@ -80,7 +76,7 @@ public class AutomationCompositionProvider { */ @Transactional(readOnly = true) public Optional<AutomationComposition> findAutomationComposition(@NonNull final String name, - @NonNull final String version) throws PfModelException { + @NonNull final String version) throws PfModelException { return findAutomationComposition(new PfConceptKey(name, version)); } @@ -93,12 +89,12 @@ public class AutomationCompositionProvider { */ @Transactional(readOnly = true) public Optional<AutomationComposition> findAutomationComposition( - final ToscaConceptIdentifier automationCompositionId) throws PfModelException { + final ToscaConceptIdentifier automationCompositionId) throws PfModelException { return findAutomationComposition(automationCompositionId.asConceptKey()); } private Optional<AutomationComposition> findAutomationComposition(@NonNull final PfConceptKey key) - throws PfModelException { + throws PfModelException { try { return automationCompositionRepository.findById(key).map(JpaAutomationComposition::toAuthorative); } catch (IllegalArgumentException e) { @@ -114,10 +110,10 @@ public class AutomationCompositionProvider { * @throws PfModelException on errors updating the automation composition */ public AutomationComposition saveAutomationComposition(final AutomationComposition automationComposition) - throws PfModelException { + throws PfModelException { try { var result = automationCompositionRepository.save(ProviderUtils.getJpaAndValidate(automationComposition, - JpaAutomationComposition::new, "automation composition")); + JpaAutomationComposition::new, "automation composition")); // Return the saved participant return result.toAuthorative(); @@ -127,14 +123,15 @@ public class AutomationCompositionProvider { } /** - * Get all automation compositions. + * Get all automation compositions by compositionId. * + * @param compositionId the compositionId of the automation composition definition * @return all automation compositions found */ @Transactional(readOnly = true) - public List<AutomationComposition> getAutomationCompositions() { - - return ProviderUtils.asEntityList(automationCompositionRepository.findAll()); + public List<AutomationComposition> getAcInstancesByCompositionId(UUID compositionId) { + return ProviderUtils + .asEntityList(automationCompositionRepository.findByCompositionId(compositionId.toString())); } /** @@ -147,8 +144,8 @@ public class AutomationCompositionProvider { @Transactional(readOnly = true) public List<AutomationComposition> getAutomationCompositions(final String name, final String version) { - return ProviderUtils - .asEntityList(automationCompositionRepository.getFiltered(JpaAutomationComposition.class, name, version)); + return ProviderUtils.asEntityList( + automationCompositionRepository.getFiltered(JpaAutomationComposition.class, name, version)); } /** @@ -159,11 +156,11 @@ public class AutomationCompositionProvider { * @throws PfModelException on errors creating automation compositions */ public List<AutomationComposition> saveAutomationCompositions( - @NonNull final List<AutomationComposition> automationCompositions) throws PfModelException { + @NonNull final List<AutomationComposition> automationCompositions) throws PfModelException { try { var result = - automationCompositionRepository.saveAll(ProviderUtils.getJpaAndValidateList(automationCompositions, - JpaAutomationComposition::new, "automation compositions")); + automationCompositionRepository.saveAll(ProviderUtils.getJpaAndValidateList(automationCompositions, + JpaAutomationComposition::new, "automation compositions")); // Return the saved participant return ProviderUtils.asEntityList(result); @@ -181,14 +178,14 @@ public class AutomationCompositionProvider { * @throws PfModelException on errors deleting the automation composition */ public AutomationComposition deleteAutomationComposition(@NonNull final String name, @NonNull final String version) - throws PfModelException { + throws PfModelException { var automationCompositionKey = new PfConceptKey(name, version); var jpaDeleteAutomationComposition = automationCompositionRepository.findById(automationCompositionKey); if (jpaDeleteAutomationComposition.isEmpty()) { String errorMessage = "delete of automation composition \"" + automationCompositionKey.getId() - + "\" failed, automation composition does not exist"; + + "\" failed, automation composition does not exist"; throw new PfModelException(Response.Status.NOT_FOUND, errorMessage); } @@ -196,43 +193,4 @@ public class AutomationCompositionProvider { return jpaDeleteAutomationComposition.get().toAuthorative(); } - - /** - * Get All Node Templates. - * - * @return the list of node templates found - */ - @Transactional(readOnly = true) - public List<ToscaNodeTemplate> getAllNodeTemplates() { - return ProviderUtils.asEntityList(toscaNodeTemplateRepository.findAll()); - } - - /** - * Get Node Templates. - * - * @param name the name of the node template to get, null to get all node templates - * @param version the version of the node template to get, null to get all node templates - * @return the node templates found - * @throws PfModelException on errors getting node templates - */ - @Transactional(readOnly = true) - public List<ToscaNodeTemplate> getNodeTemplates(final String name, final String version) { - return ProviderUtils - .asEntityList(toscaNodeTemplateRepository.getFiltered(JpaToscaNodeTemplate.class, name, version)); - } - - /** - * Get filtered node templates. - * - * @param filter the filter for the node templates to get - * @return the node templates found - * @throws PfModelException on errors getting node templates - */ - @Transactional(readOnly = true) - public List<ToscaNodeTemplate> getFilteredNodeTemplates( - @NonNull final ToscaTypedEntityFilter<ToscaNodeTemplate> filter) { - - return filter.filter(ProviderUtils.asEntityList(toscaNodeTemplateRepository - .getFiltered(JpaToscaNodeTemplate.class, filter.getName(), filter.getVersion()))); - } } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/ProviderUtils.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/ProviderUtils.java index 7d751fa36..9dc07ae72 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/ProviderUtils.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/ProviderUtils.java @@ -31,7 +31,7 @@ import org.onap.policy.common.parameters.BeanValidationResult; import org.onap.policy.models.base.PfAuthorative; import org.onap.policy.models.base.PfConcept; import org.onap.policy.models.base.PfModelRuntimeException; -import org.onap.policy.models.tosca.authorative.concepts.ToscaEntity; +import org.onap.policy.models.base.Validated; @NoArgsConstructor(access = AccessLevel.PRIVATE) public final class ProviderUtils { @@ -72,7 +72,7 @@ public final class ProviderUtils { * @param conceptDescription the description used for validation result * @return the Jpa object */ - public static <A, J extends PfConcept & PfAuthorative<A>> J getJpaAndValidate(A authorativeConcept, + public static <A, J extends Validated & PfAuthorative<A>> J getJpaAndValidate(A authorativeConcept, Supplier<J> jpaSupplier, String conceptDescription) { var validationResult = new BeanValidationResult(conceptDescription, authorativeConcept); @@ -95,7 +95,7 @@ public final class ProviderUtils { * @param jpaEntityList the list to convert * @return the authorative list */ - public static <T extends ToscaEntity, J extends PfAuthorative<T>> List<T> asEntityList(List<J> jpaEntityList) { + public static <T, J extends PfAuthorative<T>> List<T> asEntityList(List<J> jpaEntityList) { return jpaEntityList.stream().map(J::toAuthorative).collect(Collectors.toList()); } } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionRepository.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionRepository.java index 8eeb77e0d..273b99a63 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionRepository.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionRepository.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. + * Copyright (C) 2021-2022 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ package org.onap.policy.clamp.models.acm.persistence.repository; +import java.util.List; import org.onap.policy.clamp.models.acm.persistence.concepts.JpaAutomationComposition; import org.onap.policy.models.base.PfConceptKey; import org.springframework.data.jpa.repository.JpaRepository; @@ -28,4 +29,6 @@ import org.springframework.stereotype.Repository; @Repository public interface AutomationCompositionRepository extends JpaRepository<JpaAutomationComposition, PfConceptKey>, FilterRepository { + + List<JpaAutomationComposition> findByCompositionId(String compositionId); } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/ToscaNodeTemplateRepository.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/ToscaNodeTemplateRepository.java deleted file mode 100644 index 20d0f0f7e..000000000 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/ToscaNodeTemplateRepository.java +++ /dev/null @@ -1,30 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.clamp.models.acm.persistence.repository; - -import org.onap.policy.models.base.PfConceptKey; -import org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeTemplate; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface ToscaNodeTemplateRepository - extends JpaRepository<JpaToscaNodeTemplate, PfConceptKey>, FilterRepository { - -} diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmUtils.java b/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmUtils.java index 283edd49e..a8203484a 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmUtils.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmUtils.java @@ -48,6 +48,7 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeType; import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; import org.onap.policy.models.tosca.authorative.concepts.ToscaTopologyTemplate; +import org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate; /** * Utility functions used in acm-runtime and participants. @@ -57,6 +58,8 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaTopologyTemplate; public final class AcmUtils { private static final String AUTOMATION_COMPOSITION_NODE_TYPE = "org.onap.policy.clamp.acm.AutomationComposition"; + private static final String AC_NODE_TYPE_NOT_PRESENT = + "NodeTemplate with type " + AUTOMATION_COMPOSITION_NODE_TYPE + " must exist!"; public static final String ENTRY = "entry "; /** @@ -175,20 +178,19 @@ public final class AcmUtils { */ public static BeanValidationResult validateAutomationComposition(AutomationComposition automationComposition, ToscaServiceTemplate serviceTemplate) { - var result = new BeanValidationResult(ENTRY + automationComposition.getDefinition().getName(), - automationComposition); + var result = new BeanValidationResult(ENTRY + automationComposition.getName(), automationComposition); var map = getMapToscaNodeTemplates(serviceTemplate); - var toscaNodeTemplate = map.get(new ToscaConceptIdentifier(automationComposition.getDefinition().getName(), - automationComposition.getDefinition().getVersion())); + var nodeTemplateGet = map.values().stream() + .filter(nodeTemplate -> AUTOMATION_COMPOSITION_NODE_TYPE.equals(nodeTemplate.getType())).findFirst(); - if (toscaNodeTemplate == null || !AUTOMATION_COMPOSITION_NODE_TYPE.equals(toscaNodeTemplate.getType())) { - result.addResult( - new ObjectValidationResult("AutomationComposition", automationComposition.getDefinition().getName(), - ValidationStatus.INVALID, "Commissioned automation composition definition not found")); + if (nodeTemplateGet.isEmpty()) { + result.addResult(new ObjectValidationResult("ToscaServiceTemplate", serviceTemplate.getName(), + ValidationStatus.INVALID, "Commissioned automation composition definition not consistent")); } else { + var toscaNodeTemplate = nodeTemplateGet.get(); var acElementDefinitions = getAutomationCompositionElementDefinitions(map, toscaNodeTemplate); // @formatter:off @@ -354,4 +356,32 @@ public final class AcmUtils { return getFinalNodeTypesMap(serviceTemplate.getNodeTypes(), tempNodeTypesMap); } + + /** + * Validate ToscaTopologyTemplate. + * + * @param result + * + * @param serviceTemplate the ToscaServiceTemplate + */ + public static void validateToscaTopologyTemplate(BeanValidationResult result, + JpaToscaServiceTemplate serviceTemplate) { + if (serviceTemplate.getTopologyTemplate() != null + && serviceTemplate.getTopologyTemplate().getNodeTemplates() != null) { + var nodeTemplates = serviceTemplate.getTopologyTemplate().getNodeTemplates(); + var acNumber = nodeTemplates.getConceptMap().values().stream() + .filter(nodeTemplate -> AUTOMATION_COMPOSITION_NODE_TYPE.equals(nodeTemplate.getType().getName())) + .count(); + if (acNumber == 0) { + result.addResult("TopologyTemplate", nodeTemplates, ValidationStatus.INVALID, AC_NODE_TYPE_NOT_PRESENT); + } + if (acNumber > 1) { + result.addResult("TopologyTemplate", nodeTemplates, ValidationStatus.INVALID, "NodeTemplate with type " + + AUTOMATION_COMPOSITION_NODE_TYPE + " not allowed to be more than one!"); + } + } else { + result.addResult("ServiceTemplate", serviceTemplate, ValidationStatus.INVALID, AC_NODE_TYPE_NOT_PRESENT); + } + } + } |