From fe7a82b3a8f416fd87519caa07124261d9f117f3 Mon Sep 17 00:00:00 2001 From: Natalia Sheshukov Date: Thu, 22 Feb 2018 16:50:05 +0200 Subject: [PATCH] [367741] vLAN Tagging. Support Tosca Policies. Change-Id: I4d47ee603883e4d6a2b54776d7d570ba074cc25a Issue-ID: SDC-1056 Signed-off-by: Natalia Sheshukov --- pom.xml | 4 +- .../sdc/tosca/parser/api/ISdcCsarHelper.java | 93 +++++ .../sdc/tosca/parser/impl/SdcCsarHelperImpl.java | 376 +++++++++++++++++---- .../sdc/tosca/parser/impl/SdcPropertyNames.java | 8 + .../sdc/impl/SdcToscaParserBasicTest.java | 9 +- .../sdc/impl/ToscaParserMetadataTest.java | 5 +- .../sdc/impl/ToscaParserNodeTemplateTest.java | 84 ++++- src/test/resources/csars/resource-Policy-csar.csar | Bin 0 -> 27747 bytes .../resources/csars/service-AlService-csar.csar | Bin 0 -> 37565 bytes version.properties | 2 +- 10 files changed, 492 insertions(+), 89 deletions(-) create mode 100644 src/test/resources/csars/resource-Policy-csar.csar create mode 100644 src/test/resources/csars/service-AlService-csar.csar diff --git a/pom.xml b/pom.xml index 2b8f08d..4c982e3 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ sdc-tosca sdc-sdc-tosca SDC Tosca Parser JAR file for use by consumers - 1.2.2-SNAPSHOT + 1.2.3-SNAPSHOT jar @@ -112,7 +112,7 @@ org.openecomp.sdc.jtosca jtosca - 1.2.1 + 1.2.2-SNAPSHOT diff --git a/src/main/java/org/openecomp/sdc/tosca/parser/api/ISdcCsarHelper.java b/src/main/java/org/openecomp/sdc/tosca/parser/api/ISdcCsarHelper.java index df9e47d..cd5b018 100644 --- a/src/main/java/org/openecomp/sdc/tosca/parser/api/ISdcCsarHelper.java +++ b/src/main/java/org/openecomp/sdc/tosca/parser/api/ISdcCsarHelper.java @@ -450,5 +450,98 @@ public interface ISdcCsarHelper { * @return the leaf value as String, or null if there's no such property, or it's not a leaf. */ public String getCapabilityPropertyLeafValue(CapabilityAssignment capability, String pathToPropertyLeafValue); + + /** + * Get all the policies of the main topology template (either VF or service) + * @return the list of the policies + */ + public List>> getPoliciesOfTopologyTemplate(); + + /** + * Get all the policies of the main topology template (either VF or service) specified by policy type + * @param policyTypeName the name of the policy type + * @return the list of the policies + */ + public List>> getPoliciesOfTopologyTemplateByToscaPolicyType(String policyTypeName); + + /** + * Get all the policies of the origin component (nested topology template) of the node template + * @param nodeTemplate the node template + * @return the list of the policies + */ + public List> getPoliciesOfOriginOfNodeTemplate(NodeTemplate nodeTemplate); + + /** + * Get all the policies of the origin component (nested topology template) of the node template specified by policy type + * @param nodeTemplate the node template + * @param policyTypeName the name of the policy type + * @return the list of the policies + */ + public List> getPoliciesOfOriginOfNodeTemplateByToscaPolicyType(NodeTemplate nodeTemplate, String policyTypeName); + + /** + * Get all the node templates of the topology template, which are the targets of the policy specified by name + * @param policyName the name of the policy + * @return the list of the node templates + */ + public List getPolicyTargetsFromTopologyTemplate(String policyName); + + /** + * Get all the node templates of the origin component (nested topology template) of node template, which are the targets of the policy specified by name + * @param nodeTemplate the node template + * @param policyName the name of the policy + * @return the list of the node templates + */ + public List> getPolicyTargetsFromOrigin(NodeTemplate nodeTemplate, String policyName); + + /** + * Get the node template of the topology template specified by name + * @param nodeTemplateName the name of the node template + * @return the node template + */ + public NodeTemplate getNodeTemplateByName(String nodeTemplateName); + + /** + * Get all the policies, which contain the specified node template as a target + * @param targetNode the node template + * @return the list of the policies + */ + public List>> getPoliciesOfTarget(NodeTemplate targetNode); + + /** + * Get all the policies of the specified type, which contain the specified node template as a target + * @param nodeTemplate the node template + * @param policyTypeName the name of the policy type + * @return the list of the policies + */ + public List>> getPoliciesOfTargetByToscaPolicyType(NodeTemplate nodeTemplate, String policyTypeName); + + /** + * Get all groups of this of the main topology template (either VF or service) + * @return the list of the groups + */ + public List>> getGroupsOfTopologyTemplate(); + + /** + * Get all groups of this of the main topology template (either VF or service) by specified tosca group type + * @param groupType the group type + * @return the list of the groups + */ + public List>> getGroupsOfTopologyTemplateByToscaGroupType(String groupType); + + + /** + * Get all the groups of the origin component (nested topology template) of the node template + * @param nodeTemplate the node template + * @return the list of the groups + */ + public List> getGroupsOfOriginOfNodeTemplate(NodeTemplate nodeTemplate); + + /** + * Get group members of the group belongs to the main topology template (either VF or service) by group name + * @param groupName the name of the group + * @return + */ + public List getGroupMembersFromTopologyTemplate(String groupName); } \ No newline at end of file diff --git a/src/main/java/org/openecomp/sdc/tosca/parser/impl/SdcCsarHelperImpl.java b/src/main/java/org/openecomp/sdc/tosca/parser/impl/SdcCsarHelperImpl.java index 901b315..a963189 100644 --- a/src/main/java/org/openecomp/sdc/tosca/parser/impl/SdcCsarHelperImpl.java +++ b/src/main/java/org/openecomp/sdc/tosca/parser/impl/SdcCsarHelperImpl.java @@ -22,15 +22,12 @@ package org.openecomp.sdc.tosca.parser.impl; import java.util.*; import java.util.Map.Entry; -import java.util.stream.Collectors; - +import static java.util.stream.Collectors.toList; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; import org.openecomp.sdc.tosca.parser.api.ISdcCsarHelper; import org.openecomp.sdc.tosca.parser.config.ConfigurationManager; -import org.openecomp.sdc.toscaparser.api.CapabilityAssignments; import org.openecomp.sdc.tosca.parser.utils.GeneralUtility; -import org.openecomp.sdc.toscaparser.api.RequirementAssignments; import org.openecomp.sdc.tosca.parser.utils.SdcToscaUtility; import org.openecomp.sdc.toscaparser.api.*; import org.openecomp.sdc.toscaparser.api.elements.Metadata; @@ -58,7 +55,232 @@ public class SdcCsarHelperImpl implements ISdcCsarHelper { this.toscaTemplate = toscaTemplate; this.configurationManager = configurationManager; } + + @Override + public List>> getPoliciesOfTarget(NodeTemplate nodeTemplate) { + return getPoliciesOfNodeTemplate(nodeTemplate.getName()) + .stream() + .sorted(Policy::compareTo) + .map(this::convertPolicyToMap) + .collect(toList()); + } + + @Override + public List> getPoliciesOfOriginOfNodeTemplate(NodeTemplate nodeTemplate) { + List> policies = new ArrayList<>(); + if(toscaTemplate.getNestedTopologyTemplates() != null && !toscaTemplate.getNestedTopologyTemplates().isEmpty()){ + String invariantUUID = nodeTemplate.getMetaData().getValue(SdcPropertyNames.PROPERTY_NAME_INVARIANTUUID); + Optional nestedTopTmpl = toscaTemplate.getNestedTopologyTemplates() + .values() + .stream() + .filter(nt->invariantUuidEqualsTo(invariantUUID, nt)) + .findFirst(); + if(nestedTopTmpl.isPresent()){ + policies = getPoliciesSection(nestedTopTmpl.get()); + } + } + return policies; + } + + @Override + public List>> getPoliciesOfTargetByToscaPolicyType(NodeTemplate nodeTemplate, String policyTypeName) { + return getPoliciesOfNodeTemplate(nodeTemplate.getName()) + .stream() + .filter(p->p.getType().equals(policyTypeName)) + .sorted(Policy::compareTo) + .map(this::convertPolicyToMap) + .collect(toList()); + } + + @Override + public List> getPoliciesOfOriginOfNodeTemplateByToscaPolicyType(NodeTemplate nodeTemplate, String policyTypeName) { + return getPoliciesOfOriginOfNodeTemplate(nodeTemplate) + .stream() + .filter(p->typeEqualsTo(p, policyTypeName)) + .sorted(this::comparePolicyMapObjects) + .collect(toList()); + } + + @Override + public List getPolicyTargetsFromTopologyTemplate(String policyName) { + if(toscaTemplate.getNodeTemplates() == null){ + return new ArrayList<>(); + } + List targetNames = getPolicyTargets(policyName); + return toscaTemplate.getNodeTemplates().stream() + .filter(nt->targetNames.contains(nt.getName())) + .collect(toList()); + } + + @Override + public List> getPolicyTargetsFromOrigin(NodeTemplate nodeTemplate, String policyName) { + List targets = getTargetsOfPolicyOfNestedTopologyTemplate(nodeTemplate, policyName); + if(targets.isEmpty()){ + return new ArrayList<>(); + } + return toscaTemplate.getNestedTopologyTemplates() + .values() + .stream() + .map(this::getNodeTemplatesSection) + .filter(nt->targets.contains(nt.keySet().iterator().next())) + .collect(toList()); + } + + @Override + public List>> getPoliciesOfTopologyTemplate(){ + if(toscaTemplate.getPolicies() == null) + return new ArrayList<>(); + return toscaTemplate.getPolicies() + .stream() + .sorted(Policy::compareTo) + .map(this::convertPolicyToMap) + .collect(toList()); + } + + @Override + public List>> getPoliciesOfTopologyTemplateByToscaPolicyType(String policyTypeName){ + if(toscaTemplate.getPolicies() == null) + return new ArrayList<>(); + return toscaTemplate.getPolicies() + .stream() + .filter(p->p.getType().equals(policyTypeName)) + .sorted(Policy::compareTo) + .map(this::convertPolicyToMap) + .collect(toList()); + } + + + private List getTargetsOfPolicyOfNestedTopologyTemplate(NodeTemplate nodeTemplate, String policyName) { + if(toscaTemplate.getNodeTemplates() == null){ + return new ArrayList<>(); + } + Optional> policy = getPolicyOfNestedTopologyTemplateByName(nodeTemplate, policyName); + if(!policy.isPresent()){ + return new ArrayList<>(); + } + return getTargetsSection(policy.get()); + } + + private Optional> getPolicyOfNestedTopologyTemplateByName(NodeTemplate nodeTemplate, String policyName) { + return getPoliciesOfOriginOfNodeTemplate(nodeTemplate).stream() + .filter(p->policyNameEqualsTo(p, policyName)) + .findFirst(); + } + + private boolean policyNameEqualsTo(Map policy, String policyName) { + return policy != null && !policy.isEmpty() && policy.keySet().iterator().next().equals(policyName); + } + + public NodeTemplate getNodeTemplateByName(String nodeTemplateName) { + if(toscaTemplate.getNodeTemplates() == null) + return null; + return toscaTemplate.getNodeTemplates() + .stream() + .filter(nt -> nt.getName().equals(nodeTemplateName)) + .findFirst().orElse(null); + } + + + private int comparePolicyMapObjects(Map policy, Map otherPolicy){ + if(policy.equals(otherPolicy)) + return 0; + return getTypeSection(policy).compareTo(getTypeSection(otherPolicy)) == 0 ? getNameSection(policy).compareTo(getNameSection(otherPolicy)) : getTypeSection(policy).compareTo(getTypeSection(otherPolicy)); + } + + @SuppressWarnings("unchecked") + private List getTargetsSection(Map policy) { + if(policy == null || policy.isEmpty()){ + return new ArrayList<>(); + } + List targets = (List) ((Map)policy.values().iterator().next()).get(SdcPropertyNames.PROPERTY_NAME_TARGETS); + if(targets == null){ + return new ArrayList<>(); + } + return targets; + } + @SuppressWarnings("unchecked") + private boolean typeEqualsTo(Map policy, String policyTypeName) { + if(policy.values().iterator().hasNext()){ + return ((Map)policy.values().iterator().next()).get(SdcPropertyNames.PROPERTY_NAME_TYPE).equals(policyTypeName); + } + return false; + } + + private String getNameSection(Map policy) { + Object name = policy.get(SdcPropertyNames.PROPERTY_NAME_NAME); + if(name == null) + return ""; + return (String)name; + } + + private String getTypeSection(Map policy) { + Object type = policy.get(SdcPropertyNames.PROPERTY_NAME_TYPE); + if(type == null) + return ""; + return (String)type; + } + + @SuppressWarnings("unchecked") + private List> getPoliciesSection(Object nestedTopTmpl) { + List> policies = (List>)getTopologyTemplateSection(nestedTopTmpl).get(SdcPropertyNames.PROPERTY_NAME_POLICIES); + if(policies == null || policies.isEmpty()) + return new ArrayList<>(); + return policies; + } + + @SuppressWarnings("unchecked") + private Map getNodeTemplatesSection(Object topologyTemplate) { + Map nodeTemplates = (Map)getTopologyTemplateSection(topologyTemplate).get(SdcPropertyNames.PROPERTY_NAME_NODE_TEMPLATES); + if(nodeTemplates == null || nodeTemplates.isEmpty()) + return new HashMap<>(); + return nodeTemplates; + } + + @SuppressWarnings("unchecked") + private Map getTopologyTemplateSection(Object topologyTemplate) { + Map topologyTemplateSection = (Map)((Map)topologyTemplate).get(SdcPropertyNames.PROPERTY_NAME_TOPOLOGY_TEMPLATE); + if(topologyTemplateSection == null || topologyTemplateSection.isEmpty()) + return new HashMap<>(); + return topologyTemplateSection; + } + @SuppressWarnings("unchecked") + private boolean invariantUuidEqualsTo(String invariantUUID, Object nt) { + return ((Map)((Map)nt).get(SdcPropertyNames.PROPERTY_NAME_METADATA)).get(SdcPropertyNames.PROPERTY_NAME_INVARIANTUUID).equals(invariantUUID); + } + + private Map> convertPolicyToMap(Policy policy){ + Map> policyMap = new HashMap<>(); + Map policyValue = new HashMap<>(); + policyMap.put(policy.getName(), policyValue); + policyValue.put(SdcPropertyNames.PROPERTY_NAME_TYPE, policy.getType()); + policyValue.put(SdcPropertyNames.PROPERTY_NAME_METADATA, policy.getmetadata()); + policyValue.put(SdcPropertyNames.PROPERTY_NAME_TARGETS, policy.getTargets()); + policyValue.put(SdcPropertyNames.PROPERTY_NAME_PROPERTIES, policy.getPolicyProperties()); + return policyMap; + } + + private List getPoliciesOfNodeTemplate(String nodeTemplateName) { + if(toscaTemplate.getPolicies() == null) + return new ArrayList<>(); + return toscaTemplate.getPolicies() + .stream() + .filter(p -> p.getTargets().contains(nodeTemplateName)) + .collect(toList()); + } + + private List getPolicyTargets(String policyName) { + return getPolicyByName(policyName).map(Policy::getTargets).orElse(new ArrayList<>()); + } + + private Optional getPolicyByName(String policyName) { + if(toscaTemplate.getPolicies() == null) + return Optional.empty(); + return toscaTemplate.getPolicies() + .stream() + .filter(p -> p.getName().equals(policyName)).findFirst(); + } + @Override //Sunny flow - covered with UT, flat and nested public String getNodeTemplatePropertyLeafValue(NodeTemplate nodeTemplate, String leafValuePath) { @@ -110,24 +332,27 @@ public class SdcCsarHelperImpl implements ISdcCsarHelper { } } - if (cps.size() > 0) { - // ports found - find all their properties - for (String portName : cps.keySet()) { - for (Map.Entry property: props.entrySet()) { - if (property.getKey().startsWith(portName)) { - String portProperty = property.getKey().replaceFirst(portName + "_", ""); - if (property.getValue() != null) { - cps.get(portName).put(portProperty, property.getValue().getValue()); - } - } - } - } - } + findPutAllPortsProperties(cps, props); } return cps; } + private void findPutAllPortsProperties(Map> cps, Map props) { + if (!cps.isEmpty()) { + for (Entry> port : cps.entrySet()) { + for (Map.Entry property: props.entrySet()) { + if (property.getKey().startsWith(port.getKey())) { + String portProperty = property.getKey().replaceFirst(port.getKey() + "_", ""); + if (property.getValue() != null) { + cps.get(port.getKey()).put(portProperty, property.getValue().getValue()); + } + } + } + } + } + } + public Map> getCpPropertiesFromVfc(NodeTemplate vfc) { if (vfc == null) { @@ -147,26 +372,27 @@ public class SdcCsarHelperImpl implements ISdcCsarHelper { cps.put(portName, new HashMap<>()); } } - - if (cps.size() > 0) { - // ports found - find all their properties - for (String portName : cps.keySet()) { - for (Map.Entry property: props.entrySet()) { - if (property.getKey().startsWith(portName)) { - Map portPaths = new HashMap<>(); - String portProperty = property.getKey().replaceFirst(portName + "_", ""); - buildPathMappedToValue(portProperty, property.getValue().getValue(), portPaths); - - cps.get(portName).putAll(portPaths); - } - } - } - } + findBuildPutAllPortsProperties(cps, props); } return cps; } + private void findBuildPutAllPortsProperties(Map> cps, Map props) { + if (!cps.isEmpty()) { + for (Entry> port : cps.entrySet()) { + for (Map.Entry property: props.entrySet()) { + if (property.getKey().startsWith(port.getKey())) { + Map portPaths = new HashMap<>(); + String portProperty = property.getKey().replaceFirst(port.getKey() + "_", ""); + buildPathMappedToValue(portProperty, property.getValue().getValue(), portPaths); + cps.get(port.getKey()).putAll(portPaths); + } + } + } + } + } + @SuppressWarnings("unchecked") private void buildPathMappedToValue(String path, Object property, Map pathsMap) { if (property instanceof Map) { @@ -190,15 +416,13 @@ public class SdcCsarHelperImpl implements ISdcCsarHelper { @Override //Sunny flow - covered with UT public List getServiceVlList() { - List serviceVlList = getNodeTemplateBySdcType(toscaTemplate.getTopologyTemplate(), SdcTypes.VL); - return serviceVlList; + return getNodeTemplateBySdcType(toscaTemplate.getTopologyTemplate(), SdcTypes.VL); } @Override //Sunny flow - covered with UT public List getServiceVfList() { - List serviceVfList = getNodeTemplateBySdcType(toscaTemplate.getTopologyTemplate(), SdcTypes.VF); - return serviceVfList; + return getNodeTemplateBySdcType(toscaTemplate.getTopologyTemplate(), SdcTypes.VF); } @Override @@ -212,8 +436,7 @@ public class SdcCsarHelperImpl implements ISdcCsarHelper { log.error("getMetadataPropertyValue - the metadata is null"); return null; } - String metadataPropertyValue = metadata.getValue(metadataPropertyName); - return metadataPropertyValue; + return metadata.getValue(metadataPropertyName); } @@ -239,8 +462,7 @@ public class SdcCsarHelperImpl implements ISdcCsarHelper { @Override public List getServiceNodeTemplates() { - List nodeTemplates = toscaTemplate.getNodeTemplates(); - return nodeTemplates; + return toscaTemplate.getNodeTemplates(); } @Override @@ -265,25 +487,15 @@ public class SdcCsarHelperImpl implements ISdcCsarHelper { List serviceVfList = getServiceVfList(); NodeTemplate nodeTemplateByCustomizationUuid = getNodeTemplateByCustomizationUuid(serviceVfList, vfCustomizationUuid); if (nodeTemplateByCustomizationUuid != null) { - /*SubstitutionMappings substitutionMappings = nodeTemplateByCustomizationUuid.getSubstitutionMappings(); - if (substitutionMappings != null){ - List groups = substitutionMappings.getGroups(); - if (groups != null){ - List collect = groups.stream().filter(x -> "org.openecomp.groups.VfModule".equals(x.getTypeDefinition().getType())).collect(Collectors.toList()); - log.debug("getVfModulesByVf - VfModules are {}", collect); - return collect; - } - }*/ String name = nodeTemplateByCustomizationUuid.getName(); String normaliseComponentInstanceName = SdcToscaUtility.normaliseComponentInstanceName(name); List serviceLevelGroups = toscaTemplate.getTopologyTemplate().getGroups(); log.debug("getVfModulesByVf - VF node template name {}, normalized name {}. Searching groups on service level starting with VF normalized name...", name, normaliseComponentInstanceName); if (serviceLevelGroups != null) { - List collect = serviceLevelGroups + return serviceLevelGroups .stream() .filter(x -> "org.openecomp.groups.VfModule".equals(x.getTypeDefinition().getType()) && x.getName().startsWith(normaliseComponentInstanceName)) - .collect(Collectors.toList()); - return collect; + .collect(toList()); } } return new ArrayList<>(); @@ -468,7 +680,7 @@ public class SdcCsarHelperImpl implements ISdcCsarHelper { } List serviceVfList = getServiceVfList(); - if (serviceVfList == null || serviceVfList.size() == 0) { + if (serviceVfList == null || serviceVfList.isEmpty()) { log.error("getCpListByVf Vfs not exist for vfCustomizationId {}", vfCustomizationId); return cpList; } @@ -478,7 +690,7 @@ public class SdcCsarHelperImpl implements ISdcCsarHelper { return cpList; } cpList = getNodeTemplateBySdcType(vfInstance, SdcTypes.CP); - if (cpList == null || cpList.size() == 0) + if (cpList == null || cpList.isEmpty()) log.debug("getCpListByVf cps not exist for vfCustomizationId {}", vfCustomizationId); return cpList; } @@ -507,8 +719,7 @@ public class SdcCsarHelperImpl implements ISdcCsarHelper { if (findFirst.isPresent()) { List members = findFirst.get().getMembers(); if (members != null) { - List collect = substitutionMappings.getNodeTemplates().stream().filter(x -> members.contains(x.getName())).collect(Collectors.toList()); - return collect; + return substitutionMappings.getNodeTemplates().stream().filter(x -> members.contains(x.getName())).collect(toList()); } } } @@ -517,8 +728,6 @@ public class SdcCsarHelperImpl implements ISdcCsarHelper { } @Override - //Sunny flow - covered with UT - @SuppressWarnings("unchecked") public List> getNodeTemplatePairsByReqName( List listOfReqNodeTemplates, List listOfCapNodeTemplates, String reqName) { @@ -557,7 +766,6 @@ public class SdcCsarHelperImpl implements ISdcCsarHelper { @Override //Sunny flow - covered with UT - //TODO constant strings public List getAllottedResources() { List nodeTemplates = null; nodeTemplates = toscaTemplate.getTopologyTemplate().getNodeTemplates(); @@ -566,12 +774,10 @@ public class SdcCsarHelperImpl implements ISdcCsarHelper { } nodeTemplates = nodeTemplates.stream().filter( x -> x.getMetaData() != null && x.getMetaData().getValue("category").equals("Allotted Resource")) - .collect(Collectors.toList()); + .collect(toList()); if (nodeTemplates.isEmpty()) { log.debug("getAllottedResources - allotted resources not exist"); - } else { } - return nodeTemplates; } @@ -653,18 +859,18 @@ public class SdcCsarHelperImpl implements ISdcCsarHelper { if (substitutionMappings != null) { List nodeTemplates = substitutionMappings.getNodeTemplates(); - if (nodeTemplates != null && nodeTemplates.size() > 0) { + if (nodeTemplates != null && !nodeTemplates.isEmpty()) { if (sdcType.equals(SdcTypes.VFC) && isVNF) { return nodeTemplates.stream() .filter(x -> (x.getMetaData() != null && sdcType.getValue().equals(x.getMetaData().getValue(SdcPropertyNames.PROPERTY_NAME_TYPE))) && isVNFType(x)) - .collect(Collectors.toList()); + .collect(toList()); } else { return nodeTemplates.stream() .filter(x -> (x.getMetaData() != null && sdcType.getValue().equals(x.getMetaData().getValue(SdcPropertyNames.PROPERTY_NAME_TYPE))) && !isVNFType(x)) - .collect(Collectors.toList()); + .collect(toList()); } } else { @@ -717,8 +923,7 @@ public class SdcCsarHelperImpl implements ISdcCsarHelper { List serviceVfList = getServiceVfList(); NodeTemplate vfInstance = getNodeTemplateByCustomizationUuid(serviceVfList, vfCustomizationUuid); - NodeTemplate vnfConfig = getNodeTemplateBySdcType(vfInstance, SdcTypes.VFC, true).stream().findAny().orElse(null); - return vnfConfig; + return getNodeTemplateBySdcType(vfInstance, SdcTypes.VFC, true).stream().findAny().orElse(null); } @Override @@ -747,11 +952,11 @@ public class SdcCsarHelperImpl implements ISdcCsarHelper { SubstitutionMappings substitutionMappings = nodeTemplate.getSubMappingToscaTemplate(); if (substitutionMappings != null) { List nodeTemplates = substitutionMappings.getNodeTemplates(); - if (nodeTemplates != null && nodeTemplates.size() > 0) { + if (nodeTemplates != null && !nodeTemplates.isEmpty()) { return nodeTemplates.stream() .filter(x -> !isVNFType(x)) - .collect(Collectors.toList()); + .collect(toList()); } else { log.debug("getNodeTemplateChildren - SubstitutionMappings' node Templates not exist"); @@ -822,6 +1027,31 @@ public class SdcCsarHelperImpl implements ISdcCsarHelper { Object property = processProperties(split, properties); return property == null || property instanceof Function ? null : String.valueOf(property); } + + @Override + public List>> getGroupsOfTopologyTemplate() { + // TODO Auto-generated method stub + return null; + } + + @Override + public List>> getGroupsOfTopologyTemplateByToscaGroupType(String groupType) { + // TODO Auto-generated method stub + return null; + } + + @Override + public List getGroupMembersFromTopologyTemplate(String groupName) { + // TODO Auto-generated method stub + return null; + } + + @Override + public List> getGroupsOfOriginOfNodeTemplate(NodeTemplate nodeTemplate) { + // TODO Auto-generated method stub + return null; + } + /************************************* helper functions ***********************************/ private boolean isVNFType(NodeTemplate nt) { @@ -874,8 +1104,8 @@ public class SdcCsarHelperImpl implements ISdcCsarHelper { List nodeTemplates = topologyTemplate.getNodeTemplates(); - if (nodeTemplates != null && nodeTemplates.size() > 0) - return nodeTemplates.stream().filter(x -> (x.getMetaData() != null && sdcType.getValue().equals(x.getMetaData().getValue(SdcPropertyNames.PROPERTY_NAME_TYPE)))).collect(Collectors.toList()); + if (nodeTemplates != null && !nodeTemplates.isEmpty()) + return nodeTemplates.stream().filter(x -> (x.getMetaData() != null && sdcType.getValue().equals(x.getMetaData().getValue(SdcPropertyNames.PROPERTY_NAME_TYPE)))).collect(toList()); log.debug("getNodeTemplateBySdcType - topologyTemplate's nodeTemplates not exist"); return new ArrayList<>(); @@ -905,8 +1135,4 @@ public class SdcCsarHelperImpl implements ISdcCsarHelper { return null; } - - - - } diff --git a/src/main/java/org/openecomp/sdc/tosca/parser/impl/SdcPropertyNames.java b/src/main/java/org/openecomp/sdc/tosca/parser/impl/SdcPropertyNames.java index 7d34c6f..367aa7f 100644 --- a/src/main/java/org/openecomp/sdc/tosca/parser/impl/SdcPropertyNames.java +++ b/src/main/java/org/openecomp/sdc/tosca/parser/impl/SdcPropertyNames.java @@ -106,4 +106,12 @@ public class SdcPropertyNames { public static String PROPERTY_NAME_NETWORKFLOWS_ISBOUNDTOVPN="network_flows#is_bound_to_vpn"; public static String PROPERTY_NAME_NETWORKFLOWS_VPNBINDING="network_flows#vpn_binding"; + + //Policy + public static String PROPERTY_NAME_TOPOLOGY_TEMPLATE = "topology_template"; + public static String PROPERTY_NAME_NODE_TEMPLATES = "node_templates"; + public static String PROPERTY_NAME_POLICIES = "policies"; + public static String PROPERTY_NAME_METADATA = "metadata"; + public static String PROPERTY_NAME_PROPERTIES = "properties"; + public static String PROPERTY_NAME_TARGETS = "targets"; } diff --git a/src/test/java/org/openecomp/sdc/impl/SdcToscaParserBasicTest.java b/src/test/java/org/openecomp/sdc/impl/SdcToscaParserBasicTest.java index 1695671..b65d70b 100644 --- a/src/test/java/org/openecomp/sdc/impl/SdcToscaParserBasicTest.java +++ b/src/test/java/org/openecomp/sdc/impl/SdcToscaParserBasicTest.java @@ -36,7 +36,8 @@ public abstract class SdcToscaParserBasicTest { static ISdcCsarHelper resolveReqsCapsCsarQA; static ISdcCsarHelper portMirroring; static ISdcCsarHelper csarHelperServiceWithCrs; - + static ISdcCsarHelper csarHelperServicePolicy; + static ISdcCsarHelper csarHelperVfPolicy; static Map>> fdntCsarHelper_Data; @@ -59,8 +60,10 @@ public abstract class SdcToscaParserBasicTest { resolveReqsCapsCsarQA = getCsarHelper("csars/service-sunny-flow2.csar"); portMirroring = getCsarHelper("csars/service-PortMirroring.csar"); csarHelperServiceWithCrs = getCsarHelper("csars/service-CrTestService-csar.csar"); - - fdntCsarHelper_Data = new HashMap>>(){ + csarHelperVfPolicy = getCsarHelper("csars/resource-Policy-csar.csar"); + csarHelperServicePolicy = getCsarHelper("csars/service-AlService-csar.csar"); + + fdntCsarHelper_Data = new HashMap>>(){ { HashMap> FDNT ; diff --git a/src/test/java/org/openecomp/sdc/impl/ToscaParserMetadataTest.java b/src/test/java/org/openecomp/sdc/impl/ToscaParserMetadataTest.java index 4a17b66..0725cb9 100644 --- a/src/test/java/org/openecomp/sdc/impl/ToscaParserMetadataTest.java +++ b/src/test/java/org/openecomp/sdc/impl/ToscaParserMetadataTest.java @@ -3,6 +3,7 @@ package org.openecomp.sdc.impl; import org.openecomp.sdc.tosca.parser.api.ISdcCsarHelper; import org.openecomp.sdc.tosca.parser.config.ConfigurationManager; import org.openecomp.sdc.tosca.parser.exceptions.SdcToscaParserException; +import org.openecomp.sdc.tosca.parser.impl.SdcToscaParserFactory; import org.openecomp.sdc.toscaparser.api.NodeTemplate; import org.openecomp.sdc.toscaparser.api.elements.Metadata; import org.testng.annotations.Test; @@ -207,7 +208,7 @@ public class ToscaParserMetadataTest extends SdcToscaParserBasicTest { SdcToscaParserException { ConfigurationManager configurationManager = ConfigurationManager.getInstance(); configurationManager.setErrorConfiguration("error-configuration-test.yaml"); - factory.setConfigurationManager(configurationManager); + SdcToscaParserFactory.setConfigurationManager(configurationManager); ISdcCsarHelper missingCSARMetaCsarCustomConfig = getCsarHelper ("csars/service-missing-csar-meta-file.csar"); @@ -217,7 +218,7 @@ public class ToscaParserMetadataTest extends SdcToscaParserBasicTest { .getMaxVersion()); configurationManager.setErrorConfiguration("error-configuration.yaml"); - factory.setConfigurationManager(configurationManager); + SdcToscaParserFactory.setConfigurationManager(configurationManager); } @Test(expectedExceptions = SdcToscaParserException.class) diff --git a/src/test/java/org/openecomp/sdc/impl/ToscaParserNodeTemplateTest.java b/src/test/java/org/openecomp/sdc/impl/ToscaParserNodeTemplateTest.java index 04675b4..32336af 100644 --- a/src/test/java/org/openecomp/sdc/impl/ToscaParserNodeTemplateTest.java +++ b/src/test/java/org/openecomp/sdc/impl/ToscaParserNodeTemplateTest.java @@ -5,8 +5,6 @@ import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNull; import static org.testng.Assert.assertTrue; import java.util.*; -import static org.hamcrest.CoreMatchers.is; - import com.google.common.collect.ImmutableMap; import org.apache.commons.lang3.tuple.Pair; import org.openecomp.sdc.tosca.parser.exceptions.SdcToscaParserException; @@ -14,11 +12,8 @@ import org.openecomp.sdc.tosca.parser.impl.FilterType; import org.openecomp.sdc.tosca.parser.impl.SdcTypes; import org.openecomp.sdc.toscaparser.api.Group; import org.openecomp.sdc.toscaparser.api.NodeTemplate; -import org.openecomp.sdc.toscaparser.api.Property; import org.testng.annotations.Test; -import fj.data.fingertrees.Node; - public class ToscaParserNodeTemplateTest extends SdcToscaParserBasicTest { //region getServiceVfList @@ -965,7 +960,84 @@ public class ToscaParserNodeTemplateTest extends SdcToscaParserBasicTest { assertEquals(crTemplate.getPropertyValue("nf_naming").toString(), ImmutableMap.of("ecomp_generated_naming", "true").toString()); assertEquals(crTemplate.getPropertyValue("contrailport0_virtual_network"), "chaya"); } - + + @Test + public void testGetPoliciesOfOriginOfNodeTemplate() { + NodeTemplate nt0 = csarHelperServicePolicy.getNodeTemplateByName("al_vf 0"); + NodeTemplate nt1 = csarHelperServicePolicy.getNodeTemplateByName("al_vf 1"); + List> policies = csarHelperServicePolicy.getPoliciesOfOriginOfNodeTemplate(nt0); + assertNotNull(policies); + assertEquals(policies.size(), 3); + policies = csarHelperServicePolicy.getPoliciesOfOriginOfNodeTemplate(nt1); + assertNotNull(policies); + assertEquals(policies.size(), 3); + } + + @Test + public void testGetPoliciesOfOriginOfNodeTemplateByToscaPolicyType() { + NodeTemplate nt0 = csarHelperServicePolicy.getNodeTemplateByName("al_vf 0"); + NodeTemplate nt1 = csarHelperServicePolicy.getNodeTemplateByName("al_vf 1"); + List> policies = csarHelperServicePolicy.getPoliciesOfOriginOfNodeTemplateByToscaPolicyType(nt0, "org.openecomp.policies.placement.Colocate"); + assertNotNull(policies); + assertEquals(policies.size(), 1); + + policies = csarHelperServicePolicy.getPoliciesOfOriginOfNodeTemplateByToscaPolicyType(nt0, "org.openecomp.policies.placement.Antilocate"); + assertNotNull(policies); + assertEquals(policies.size(), 1); + + policies = csarHelperServicePolicy.getPoliciesOfOriginOfNodeTemplateByToscaPolicyType(nt0, "org.openecomp.policies.placement.valet.Diversity"); + assertNotNull(policies); + assertEquals(policies.size(), 1); + + policies = csarHelperServicePolicy.getPoliciesOfOriginOfNodeTemplateByToscaPolicyType(nt1, "org.openecomp.policies.placement.Colocate"); + assertNotNull(policies); + assertEquals(policies.size(), 1); + + policies = csarHelperServicePolicy.getPoliciesOfOriginOfNodeTemplateByToscaPolicyType(nt1, "org.openecomp.policies.placement.Antilocate"); + assertNotNull(policies); + assertEquals(policies.size(), 1); + + policies = csarHelperServicePolicy.getPoliciesOfOriginOfNodeTemplateByToscaPolicyType(nt1, "org.openecomp.policies.placement.valet.Diversity"); + assertNotNull(policies); + assertEquals(policies.size(), 1); + } + + @Test + public void testGetPolicyTargetNodeTemplatesFromOrigin() { + List> nodeTemplates = csarHelperServicePolicy.getPolicyTargetsFromOrigin(csarHelperServicePolicy.getNodeTemplateByName("al_vf 1"),"policy..Colocate..0"); + assertNotNull(nodeTemplates); + assertEquals(nodeTemplates.size(), 2); + } + + @Test + public void testGetPoliciesOfNodeTemplate() { + NodeTemplate nt0 = csarHelperVfPolicy.getNodeTemplateByName("al_vfc 1"); + List>> policies = csarHelperVfPolicy.getPoliciesOfTarget(nt0); + assertNotNull(policies); + assertEquals(policies.size(), 1); + } + + @Test + public void testGetPoliciesOfNodeTemplateByToscaPolicyType() { + NodeTemplate nt0 = csarHelperVfPolicy.getNodeTemplateByName("al_vfc 1"); + List>> policies = csarHelperVfPolicy.getPoliciesOfTargetByToscaPolicyType(nt0, "org.openecomp.policies.placement.Colocate"); + assertNotNull(policies); + assertEquals(policies.size(), 1); + } + + @Test + public void testGetPoliciesOfTopologyTemplate() { + List>> policies = csarHelperVfPolicy.getPoliciesOfTopologyTemplate(); + assertNotNull(policies); + assertEquals(policies.size(), 1); + } + + @Test + public void testGetPolicyTargetNodeTemplates() { + List nodeTemplates = csarHelperVfPolicy.getPolicyTargetsFromTopologyTemplate("policy..Colocate..0"); + assertNotNull(nodeTemplates); + assertEquals(nodeTemplates.size(), 2); + } } diff --git a/src/test/resources/csars/resource-Policy-csar.csar b/src/test/resources/csars/resource-Policy-csar.csar new file mode 100644 index 0000000000000000000000000000000000000000..d6d7b424c70c9ba17e5fd006053778ae13628c94 GIT binary patch literal 27747 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 literal 0 HcmV?d00001 diff --git a/src/test/resources/csars/service-AlService-csar.csar b/src/test/resources/csars/service-AlService-csar.csar new file mode 100644 index 0000000000000000000000000000000000000000..253268319545fb418ebb0cc43244a590d6fd8025 GIT binary patch literal 37565 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%0DJI>I8Yv^*9FO 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