From 902ef574e39ea5d0c8341e8d5e3b84eae766ecae Mon Sep 17 00:00:00 2001 From: talio Date: Tue, 19 Sep 2017 17:29:25 +0300 Subject: Port mirroring create port mirroring enricher and added corresponding global types Issue - ID : SDC-351 Change-Id: Iaffda0187a3529823cb1857b1272dc22b8005ab8 Signed-off-by: talio --- .../impl/tosca/PortMirroringEnricher.java | 330 +++++++++++++++++++++ .../sdc/enrichment/impl/tosca/ToscaEnricher.java | 11 + .../PortMirroringConnectionPointDescription.java | 60 ++++ 3 files changed, 401 insertions(+) create mode 100644 openecomp-be/lib/openecomp-sdc-enrichment-lib/openecomp-sdc-enrichment-impl/src/main/java/org/openecomp/sdc/enrichment/impl/tosca/PortMirroringEnricher.java create mode 100644 openecomp-be/lib/openecomp-sdc-enrichment-lib/openecomp-sdc-enrichment-impl/src/main/java/org/openecomp/sdc/enrichment/impl/tosca/model/PortMirroringConnectionPointDescription.java (limited to 'openecomp-be/lib/openecomp-sdc-enrichment-lib') diff --git a/openecomp-be/lib/openecomp-sdc-enrichment-lib/openecomp-sdc-enrichment-impl/src/main/java/org/openecomp/sdc/enrichment/impl/tosca/PortMirroringEnricher.java b/openecomp-be/lib/openecomp-sdc-enrichment-lib/openecomp-sdc-enrichment-impl/src/main/java/org/openecomp/sdc/enrichment/impl/tosca/PortMirroringEnricher.java new file mode 100644 index 0000000000..130590cbb3 --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-enrichment-lib/openecomp-sdc-enrichment-impl/src/main/java/org/openecomp/sdc/enrichment/impl/tosca/PortMirroringEnricher.java @@ -0,0 +1,330 @@ +package org.openecomp.sdc.enrichment.impl.tosca; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.MapUtils; +import org.openecomp.sdc.datatypes.error.ErrorMessage; +import org.openecomp.sdc.enrichment.impl.tosca.model.PortMirroringConnectionPointDescription; +import org.openecomp.sdc.logging.context.impl.MdcDataDebugMessage; +import org.openecomp.sdc.tosca.datatypes.ToscaNodeType; +import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel; +import org.openecomp.sdc.tosca.datatypes.model.CapabilityAssignment; +import org.openecomp.sdc.tosca.datatypes.model.Import; +import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate; +import org.openecomp.sdc.tosca.datatypes.model.PropertyDefinition; +import org.openecomp.sdc.tosca.datatypes.model.RequirementAssignment; +import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate; +import org.openecomp.sdc.tosca.services.DataModelUtil; +import org.openecomp.sdc.tosca.services.ToscaConstants; +import org.openecomp.sdc.tosca.services.ToscaUtil; +import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil; +import org.openecomp.sdc.translator.services.heattotosca.globaltypes.GlobalTypesGenerator; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +import static org.openecomp.sdc.tosca.services.DataModelUtil.getClonedObject; +import static org.openecomp.sdc.tosca.services.ToscaConstants.PORT_MIRRORING_CAPABILITY_CP_PROPERTY_NAME; +import static org.openecomp.sdc.tosca.services.ToscaConstants.PORT_MIRRORING_CAPABILITY_ID; + +public class PortMirroringEnricher { + //Map of service template file name and map of all port node template ids, node template + private Map> portNodeTemplates = new HashMap<>(); + //Map of service template file name and map of external port node template ids, node template + private Map> externalPortNodeTemplates = new HashMap<>(); + //Map of substitution service template name and the list of ports with link requirement from + // the abstract + private Map> portNodeTemplateIdsFromAbstract = new HashMap<>(); + private static MdcDataDebugMessage mdcDataDebugMessage = new MdcDataDebugMessage(); + private Map globalTypesServiceTemplate = + GlobalTypesGenerator.getGlobalTypesServiceTemplate(); + + /** + * Enrich tosca for port mirroring. + * + * @param toscaServiceModel the tosca service model + * @return the map Error descriptor map + */ + public Map> enrich(ToscaServiceModel toscaServiceModel) { + mdcDataDebugMessage.debugEntryMessage(null); + Map> errors = new HashMap<>(); + Map serviceTemplates = toscaServiceModel.getServiceTemplates(); + serviceTemplates.entrySet().stream() + //Skipping the service templates which do not contain topology template + .filter(serviceTemplateEntry -> serviceTemplateEntry.getValue() + .getTopology_template() != null) + .forEach(serviceTemplateEntry -> + //Collect all the ports across all the service templates + collectPorts(serviceTemplateEntry.getValue())); + //Collect External ports from the list of all ports collected above + filterExternalPorts(toscaServiceModel); + //Handle external port changes + handleExternalPorts(toscaServiceModel); + mdcDataDebugMessage.debugExitMessage(null); + return errors; + } + + private void collectPorts(ServiceTemplate serviceTemplate) { + Map nodeTemplates = + serviceTemplate.getTopology_template().getNode_templates(); + if (Objects.nonNull(nodeTemplates)) { + //Get all concrete port node templates from the service template + Map serviceTemplatePortNodeTemplates = nodeTemplates.entrySet().stream() + .filter(nodeTemplateEntry -> isPortNodeTemplate(nodeTemplateEntry.getValue())) + .collect(Collectors.toMap(nodeTemplateEntry -> nodeTemplateEntry.getKey(), + nodeTemplateEntry -> nodeTemplateEntry.getValue())); + + portNodeTemplates.put(ToscaUtil.getServiceTemplateFileName(serviceTemplate), + serviceTemplatePortNodeTemplates); + + //Get all linked internal ports from abstract node template link requirements + List abstractLinkedPortNodeTemplates = new ArrayList<>(); + for (Map.Entry nodeTemplateEntry : nodeTemplates.entrySet()) { + NodeTemplate nodeTemplate = nodeTemplateEntry.getValue(); + if (isSubstitutableNodeTemplate(nodeTemplate)) { + List> requirements = nodeTemplate.getRequirements(); + if (Objects.nonNull(requirements)) { + for (Map requirement : requirements) { + String requirementId = requirement.keySet().iterator().next(); + String abstractLinkRequirementIdPrefix = ToscaConstants.LINK_REQUIREMENT_ID + "_"; + if (requirementId.startsWith(abstractLinkRequirementIdPrefix)) { + //Collect port node template ids from the link requirement ids in the abstract + // node template + abstractLinkedPortNodeTemplates.add(requirementId.substring(requirementId + .indexOf("_") + 1)); + } + } + } + if (CollectionUtils.isNotEmpty(abstractLinkedPortNodeTemplates)) { + //Populate a map of the substitution service templates and list of internal ports + addCollectedPortsToAbstractServiceTemplatePortMap(nodeTemplate, + abstractLinkedPortNodeTemplates); + } + } + } + } + } + + private void addCollectedPortsToAbstractServiceTemplatePortMap(NodeTemplate nodeTemplate, + List + abstractLinkedPortNodeTemplates) { + String substitutionServiceTemplateName = null; + if (nodeTemplate.getProperties() != null) { + Map serviceTemplateFilter = (Map) nodeTemplate.getProperties() + .get(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME); + substitutionServiceTemplateName = (String) + serviceTemplateFilter.get(ToscaConstants.SUBSTITUTE_SERVICE_TEMPLATE_PROPERTY_NAME); + if (Objects.nonNull(substitutionServiceTemplateName)) { + if (portNodeTemplateIdsFromAbstract.containsKey(substitutionServiceTemplateName)) { + List portList = + portNodeTemplateIdsFromAbstract.get(substitutionServiceTemplateName); + portList.addAll(abstractLinkedPortNodeTemplates); + portNodeTemplateIdsFromAbstract.put(substitutionServiceTemplateName, portList); + } else { + portNodeTemplateIdsFromAbstract.put(substitutionServiceTemplateName, + abstractLinkedPortNodeTemplates); + } + } + } + } + + private void filterExternalPorts(ToscaServiceModel toscaServiceModel) { + for (Map.Entry> portNodeTemplateEntry : portNodeTemplates + .entrySet()) { + Map externalPorts = new HashMap<>(); + String serviceTemplateFileName = portNodeTemplateEntry.getKey(); + Map portNodeTemplateMap = portNodeTemplateEntry.getValue(); + for (Map.Entry portNodeTemplate : portNodeTemplateMap.entrySet()) { + String nodeTemplateId = portNodeTemplate.getKey(); + NodeTemplate nodeTemplate = portNodeTemplate.getValue(); + String newPortNodeType = nodeTemplate.getType(); + if (!isInternalPort(serviceTemplateFileName, nodeTemplateId, nodeTemplate)) { + //External Port + externalPorts.putIfAbsent(nodeTemplateId, nodeTemplate); + } + } + externalPortNodeTemplates.putIfAbsent(serviceTemplateFileName, externalPorts); + } + } + + private void updateExternalPortNodeTemplate(NodeTemplate externalPortNodeTemplate, + ToscaServiceModel toscaServiceModel) { + String currentPortNodeType = externalPortNodeTemplate.getType(); + if (currentPortNodeType.equals(ToscaNodeType.CONTRAIL_PORT) + || currentPortNodeType.equals(ToscaNodeType.CONTRAILV2_VIRTUAL_MACHINE_INTERFACE)) { + //Set external contrail port node type + externalPortNodeTemplate.setType(ToscaNodeType.EXTERNAL_CONTRAIL_PORT); + addPortMirroringCapability(externalPortNodeTemplate); + } else if (currentPortNodeType.equals(ToscaNodeType.NEUTRON_PORT)) { + //Set external neutron port node type + externalPortNodeTemplate.setType(ToscaNodeType.EXTERNAL_NEUTRON_PORT); + addPortMirroringCapability(externalPortNodeTemplate); + } + } + + private void handleExternalPorts(ToscaServiceModel toscaServiceModel) { + + for (Map.Entry> entry : externalPortNodeTemplates + .entrySet()) { + String serviceTemplateName = entry.getKey(); + ServiceTemplate serviceTemplate = + toscaServiceModel.getServiceTemplates().get(serviceTemplateName); + Map externalNodeTemplates = entry.getValue(); + if (MapUtils.isNotEmpty(externalNodeTemplates)) { + for (Map.Entry externalNodeTemplate : externalNodeTemplates + .entrySet()) { + String externalPortNodeTemplateId = externalNodeTemplate.getKey(); + updateExternalPortNodeTemplate(externalNodeTemplate.getValue(), toscaServiceModel); + if (serviceTemplate.getTopology_template().getSubstitution_mappings() != null) { + //Add port mirroring capability to substitution mapping for external ports + addPortMirroringSubstitutionMappingCapability(serviceTemplate, + externalPortNodeTemplateId); + } + handleExternalPortProperties(externalNodeTemplate.getValue()); + } + addGlobalTypeImport(serviceTemplate); + } + } + } + + private void handleExternalPortProperties(NodeTemplate portNodeTemplate){ + + ServiceTemplate serviceTemplate = globalTypesServiceTemplate.get("openecomp/nodes.yml"); + String externalPortType = portNodeTemplate.getType(); + Map globalTypesportProperties = new HashMap<>(); + globalTypesportProperties.putAll(serviceTemplate.getNode_types().get("org.openecomp.resource.cp.nodes.network.Port").getProperties()); + globalTypesportProperties.putAll(serviceTemplate.getNode_types().get(externalPortType).getProperties()); + + Map properties = portNodeTemplate.getProperties(); + Map filteredProperties = new HashMap<>(); + + if(MapUtils.isEmpty(properties)){ + return; + } + + for(Map.Entry propertyEntry: properties.entrySet()){ + if(globalTypesportProperties.containsKey(propertyEntry.getKey())){ + filteredProperties.put(propertyEntry.getKey(), propertyEntry.getValue()); + } + } + + if(!MapUtils.isEmpty(filteredProperties)) { + portNodeTemplate.setProperties(filteredProperties); + }else{ + portNodeTemplate.setProperties(null); + } + + } + + private void addPortMirroringSubstitutionMappingCapability(ServiceTemplate serviceTemplate, + String externalPortNodeTemplateId) { + List portMirroringCapability = new LinkedList<>(); + portMirroringCapability.add(externalPortNodeTemplateId); + portMirroringCapability.add(PORT_MIRRORING_CAPABILITY_ID); + String substitutionMappingCapabilityId = PORT_MIRRORING_CAPABILITY_ID + "_" + + externalPortNodeTemplateId; + DataModelUtil.addSubstitutionMappingCapability(serviceTemplate, + substitutionMappingCapabilityId, portMirroringCapability); + } + + private void addPortMirroringCapability(NodeTemplate portNodeTemplate) { + List> capabilities = portNodeTemplate.getCapabilities(); + if (Objects.isNull(capabilities)) { + capabilities = new ArrayList<>(); + } + Map portMirroringCapabilityProperties = new HashMap<>(); + PortMirroringConnectionPointDescription connectionPoint = new + PortMirroringConnectionPointDescription(); + //Get Network role property + if (Objects.nonNull(portNodeTemplate.getProperties())) { + Object networkRolePropertyValue = + portNodeTemplate.getProperties().get(ToscaConstants.PORT_NETWORK_ROLE_PROPERTY_NAME); + if (Objects.nonNull(networkRolePropertyValue)) { + Object portMirroringNetworkRolePropertyVal = getClonedObject(networkRolePropertyValue); + connectionPoint.setNetwork_role(portMirroringNetworkRolePropertyVal); + } + } + //Get NFC_Type from the binding requirement node + if (Objects.nonNull(portNodeTemplate.getRequirements())) { + Optional> requirementAssignment = + DataModelUtil.getRequirementAssignment(portNodeTemplate.getRequirements(), ToscaConstants + .BINDING_REQUIREMENT_ID); + if (requirementAssignment.isPresent()) { + RequirementAssignment bindingRequirementAssignment = requirementAssignment.get().get(0); + String node = bindingRequirementAssignment.getNode(); + connectionPoint.setNfc_type(node); + } + } + + if (!connectionPoint.isEmpty()) { + portMirroringCapabilityProperties.put(PORT_MIRRORING_CAPABILITY_CP_PROPERTY_NAME, + connectionPoint); + DataModelUtil.addNodeTemplateCapability(portNodeTemplate, + PORT_MIRRORING_CAPABILITY_ID, portMirroringCapabilityProperties, null); + } + } + + private void addGlobalTypeImport(ServiceTemplate serviceTemplate) { + List> imports = serviceTemplate.getImports(); + Map openecompIndexImport = new HashMap<>(); + openecompIndexImport.put("openecomp_index", + HeatToToscaUtil.createServiceTemplateImport(globalTypesServiceTemplate + .get("openecomp/_index.yml"))); + imports.add(openecompIndexImport); + } + + private boolean isPortNodeTemplate(NodeTemplate nodeTemplate) { + String nodeType = nodeTemplate.getType(); + //Check if node corresponds to a concrete port node + if (nodeType.equals(ToscaNodeType.NEUTRON_PORT) + || nodeType.equals(ToscaNodeType.CONTRAILV2_VIRTUAL_MACHINE_INTERFACE) + || nodeType.equals(ToscaNodeType.CONTRAIL_PORT) + || nodeType.equals(ToscaNodeType.NETWORK_PORT) + || nodeType.equals(ToscaNodeType.NATIVE_NETWORK_PORT)) { + return true; + } + return false; + } + + private boolean isSubstitutableNodeTemplate(NodeTemplate nodeTemplate) { + if (Objects.nonNull(nodeTemplate.getDirectives())) { + return nodeTemplate.getDirectives().contains(ToscaConstants + .NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE); + } + return false; + } + + private boolean isInternalPort(String serviceTemplateFileName, String nodeTemplateId, + NodeTemplate nodeTemplate) { + return isAbstractInternalPort(serviceTemplateFileName, nodeTemplateId) + || isConcreteInternalPort(nodeTemplate); + } + + private boolean isAbstractInternalPort(String serviceTemplateFileName, String nodeTemplateId) { + //Check if port corresponds to an abstract internal port + if (portNodeTemplateIdsFromAbstract.containsKey(serviceTemplateFileName)) { + return portNodeTemplateIdsFromAbstract.get(serviceTemplateFileName).contains(nodeTemplateId); + } + return false; + } + + + private boolean isConcreteInternalPort(NodeTemplate nodeTemplate) { + //Check if node template contains a link requirement + List> requirements = nodeTemplate.getRequirements(); + if (Objects.nonNull(requirements)) { + for (Map requirement : requirements) { + String requirementId = requirement.keySet().iterator().next(); + if (requirementId.equals(ToscaConstants.LINK_REQUIREMENT_ID)) { + return true; + } + } + } + return false; + } +} diff --git a/openecomp-be/lib/openecomp-sdc-enrichment-lib/openecomp-sdc-enrichment-impl/src/main/java/org/openecomp/sdc/enrichment/impl/tosca/ToscaEnricher.java b/openecomp-be/lib/openecomp-sdc-enrichment-lib/openecomp-sdc-enrichment-impl/src/main/java/org/openecomp/sdc/enrichment/impl/tosca/ToscaEnricher.java index f1804c8f62..090c3ae101 100644 --- a/openecomp-be/lib/openecomp-sdc-enrichment-lib/openecomp-sdc-enrichment-impl/src/main/java/org/openecomp/sdc/enrichment/impl/tosca/ToscaEnricher.java +++ b/openecomp-be/lib/openecomp-sdc-enrichment-lib/openecomp-sdc-enrichment-impl/src/main/java/org/openecomp/sdc/enrichment/impl/tosca/ToscaEnricher.java @@ -37,6 +37,7 @@ public class ToscaEnricher extends Enricher { public Map> enrich() { Map> errors = new HashMap<>(); errors.putAll(enrichAbstractSubstitute()); + errors.putAll(enrichPortMirroring()); return errors; } @@ -55,4 +56,14 @@ public class ToscaEnricher extends Enricher { mdcDataDebugMessage.debugExitMessage(null, null); return enrichErrors; } + + private Map> enrichPortMirroring() { + mdcDataDebugMessage.debugEntryMessage(null, null); + Map> enrichErrors; + ToscaServiceModel toscaModel = (ToscaServiceModel) model; + PortMirroringEnricher portMirroringEnricher = new PortMirroringEnricher(); + enrichErrors = portMirroringEnricher.enrich(toscaModel); + mdcDataDebugMessage.debugExitMessage(null, null); + return enrichErrors; + } } diff --git a/openecomp-be/lib/openecomp-sdc-enrichment-lib/openecomp-sdc-enrichment-impl/src/main/java/org/openecomp/sdc/enrichment/impl/tosca/model/PortMirroringConnectionPointDescription.java b/openecomp-be/lib/openecomp-sdc-enrichment-lib/openecomp-sdc-enrichment-impl/src/main/java/org/openecomp/sdc/enrichment/impl/tosca/model/PortMirroringConnectionPointDescription.java new file mode 100644 index 0000000000..c166938d2d --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-enrichment-lib/openecomp-sdc-enrichment-impl/src/main/java/org/openecomp/sdc/enrichment/impl/tosca/model/PortMirroringConnectionPointDescription.java @@ -0,0 +1,60 @@ +package org.openecomp.sdc.enrichment.impl.tosca.model; + +import java.util.Objects; + +@SuppressWarnings("CheckStyle") +public class PortMirroringConnectionPointDescription { + private String nf_type; + private String nfc_type; + //Keeping below attributes as objects to accomodate for tosca functions for property + // values like get_input, get_attribute + private Object network_role; + private Object pps_capacity; + + public PortMirroringConnectionPointDescription() { + //Populating empty strings as default values to be populated in tosca + nf_type = ""; + nfc_type = ""; + network_role = ""; + pps_capacity = ""; + } + + public String getNf_type() { + return nf_type; + } + + public void setNf_type(String nf_type) { + this.nf_type = nf_type; + } + + public String getNfc_type() { + return nfc_type; + } + + public void setNfc_type(String nfc_type) { + this.nfc_type = nfc_type; + } + + public Object getNetwork_role() { + return network_role; + } + + public void setNetwork_role(Object network_role) { + this.network_role = network_role; + } + + public Object getPps_capacity() { + return pps_capacity; + } + + public void setPps_capacity(String pps_capacity) { + this.pps_capacity = pps_capacity; + } + + public boolean isEmpty() { + return Objects.isNull(nf_type) + && Objects.isNull(nfc_type) + && Objects.isNull(network_role) + && Objects.isNull(pps_capacity); + } +} -- cgit 1.2.3-korg