Merge "Port mirroring"
diff --git a/common/openecomp-tosca-datatype/src/main/resources/globalTypes/openecomp/capabilities.yml b/common/openecomp-tosca-datatype/src/main/resources/globalTypes/openecomp/capabilities.yml
index e395e3f..285d6b2 100644
--- a/common/openecomp-tosca-datatype/src/main/resources/globalTypes/openecomp/capabilities.yml
+++ b/common/openecomp-tosca-datatype/src/main/resources/globalTypes/openecomp/capabilities.yml
@@ -147,4 +147,11 @@
derived_from: tosca.capabilities.Root
tosca.capabilities.nfv.ext.LocalAttachment:
- derived_from: tosca.capabilities.Root
\ No newline at end of file
+ derived_from: tosca.capabilities.Root
+ # New capability types for Port Mirroring
+ org.openecomp.capabilities.PortMirroring:
+ derived_from: tosca.capabilities.Root
+ properties:
+ connection_point:
+ type: org.openecomp.datatypes.PortMirroringConnectionPointDescription
+ required: true
\ No newline at end of file
diff --git a/common/openecomp-tosca-datatype/src/main/resources/globalTypes/openecomp/data.yml b/common/openecomp-tosca-datatype/src/main/resources/globalTypes/openecomp/data.yml
index 85ff50c..c395675 100644
--- a/common/openecomp-tosca-datatype/src/main/resources/globalTypes/openecomp/data.yml
+++ b/common/openecomp-tosca-datatype/src/main/resources/globalTypes/openecomp/data.yml
@@ -92,7 +92,7 @@
type: string
status: SUPPORTED
required: true
-
+
org.openecomp.datatypes.EcompHoming:
derived_from: org.openecomp.datatypes.Root
properties:
@@ -468,7 +468,7 @@
description: Referenc to naming policy that OPENECOMP will use when the name is auto-generated
type: string
required: false
-
+
org.openecomp.datatypes.Naming:
derived_from: org.openecomp.datatypes.Root
properties:
@@ -478,7 +478,7 @@
type: boolean
default: true
required: true
-
+
org.openecomp.datatypes.EcompGeneratedNaming:
derived_from: org.openecomp.datatypes.Naming
properties:
@@ -486,7 +486,7 @@
description: Referenc to naming policy that OPENECOMP will use when the name is auto-generated
type: string
required: false
-
+
org.openecomp.datatypes.UserDefinedNaming:
derived_from: org.openecomp.datatypes.Naming
properties:
@@ -555,6 +555,18 @@
required: false
default: md5
+ # New data types for Port Mirroring
+ org.openecomp.datatypes.PortMirroringConnectionPointDescription:
+ properties:
+ nf_type:
+ type: string
+ nfc_type:
+ type: string
+ network_role:
+ type: string
+ pps_capacity:
+ type: string
+
tosca.datatypes.nfv.RequestedAdditionalCapability:
derived_from: tosca.datatypes.Root
properties:
diff --git a/common/openecomp-tosca-datatype/src/main/resources/globalTypes/openecomp/nodes.yml b/common/openecomp-tosca-datatype/src/main/resources/globalTypes/openecomp/nodes.yml
index da41c93..810bf30 100644
--- a/common/openecomp-tosca-datatype/src/main/resources/globalTypes/openecomp/nodes.yml
+++ b/common/openecomp-tosca-datatype/src/main/resources/globalTypes/openecomp/nodes.yml
@@ -570,6 +570,222 @@
entry_schema:
type: org.openecomp.datatypes.ImageInfo
required: false
+
+ ## New node types for Port Mirroring
+ org.openecomp.nodes.ServiceProxy:
+ derived_from: tosca.nodes.Root
+
+ org.openecomp.nodes.PortMirroringConfiguration:
+ derived_from: tosca.nodes.Root
+ requirements:
+ - source:
+ capability: org.openecomp.capabilities.PortMirroring
+ occurrences:
+ - 1
+ - UNBOUNDED
+ - collector:
+ capability: org.openecomp.capabilities.PortMirroring
+ occurrences:
+ - 1
+ - 1
+
+ org.openecomp.resource.cp.v2.extCP:
+ derived_from: org.openecomp.resource.cp.nodes.network.Port
+ description: The SDC External Connection Point base type
+ capabilities:
+ port_mirroring:
+ type: org.openecomp.capabilities.PortMirroring
+
+ org.openecomp.resource.cp.v2.extNeutronCP:
+ derived_from: org.openecomp.resource.cp.v2.extCP
+ properties:
+ port_security_enabled:
+ type: boolean
+ description: Flag to enable/disable port security on the network
+ required: false
+ status: SUPPORTED
+ device_id:
+ type: string
+ description: Device ID of this port
+ required: false
+ status: SUPPORTED
+ qos_policy:
+ type: string
+ description: The name or ID of QoS policy to attach to this network
+ required: false
+ status: SUPPORTED
+ allowed_address_pairs:
+ type: list
+ description: Additional MAC/IP address pairs allowed to pass through the port
+ required: false
+ status: SUPPORTED
+ entry_schema:
+ type: org.openecomp.datatypes.heat.network.AddressPair
+ binding:vnic_type:
+ type: string
+ description: The vnic type to be bound on the neutron port
+ required: false
+ status: SUPPORTED
+ constraints:
+ - valid_values:
+ - macvtap
+ - direct
+ - normal
+ value_specs:
+ type: map
+ description: Extra parameters to include in the request
+ required: false
+ default: {
+ }
+ status: SUPPORTED
+ entry_schema:
+ type: string
+ device_owner:
+ type: string
+ description: Name of the network owning the port
+ required: false
+ status: SUPPORTED
+ network:
+ type: string
+ description: Network this port belongs to
+ required: false
+ status: SUPPORTED
+ replacement_policy:
+ type: string
+ description: Policy on how to respond to a stack-update for this resource
+ required: false
+ default: AUTO
+ status: SUPPORTED
+ constraints:
+ - valid_values:
+ - REPLACE_ALWAYS
+ - AUTO
+ security_groups:
+ type: list
+ description: List of security group names or IDs
+ required: false
+ status: SUPPORTED
+ entry_schema:
+ type: string
+ fixed_ips:
+ type: list
+ description: Desired IPs for this port
+ required: false
+ status: SUPPORTED
+ entry_schema:
+ type: org.openecomp.datatypes.heat.neutron.port.FixedIps
+ mac_address:
+ type: string
+ description: MAC address to give to this port
+ required: false
+ status: SUPPORTED
+ admin_state_up:
+ type: boolean
+ description: A boolean value specifying the administrative status of the network
+ required: false
+ default: true
+ status: SUPPORTED
+ name:
+ type: string
+ description: A symbolic name for this port
+ required: false
+ status: SUPPORTED
+ attributes:
+ tenant_id:
+ type: string
+ description: Tenant owning the port
+ status: SUPPORTED
+ network_id:
+ type: string
+ description: Unique identifier for the network owning the port
+ status: SUPPORTED
+ qos_policy_id:
+ type: string
+ description: The QoS policy ID attached to this network
+ status: SUPPORTED
+ show:
+ type: string
+ description: Detailed information about resource
+ status: SUPPORTED
+ subnets:
+ type: list
+ description: Subnets of this network
+ status: SUPPORTED
+ entry_schema:
+ type: string
+ status:
+ type: string
+ description: The status of the network
+ status: SUPPORTED
+ capabilities:
+ attachment:
+ type: tosca.capabilities.Attachment
+ occurrences:
+ - 1
+ - UNBOUNDED
+ binding:
+ type: tosca.capabilities.network.Bindable
+ valid_source_types:
+ - org.openecomp.resource.cp.nodes.heat.network.contrailV2.VLANSubInterface
+ occurrences:
+ - 0
+ - UNBOUNDED
+
+ org.openecomp.resource.cp.v2.extContrailCP:
+ derived_from: org.openecomp.resource.cp.v2.extCP
+ properties:
+ static_routes:
+ type: list
+ description: An ordered list of static routes to be added to this interface
+ required: false
+ status: SUPPORTED
+ entry_schema:
+ type: org.openecomp.datatypes.heat.network.contrail.port.StaticRoute
+ virtual_network:
+ type: string
+ description: Virtual Network for this interface
+ required: true
+ status: SUPPORTED
+ static_route:
+ type: boolean
+ description: Static route enabled
+ required: false
+ default: false
+ status: SUPPORTED
+ allowed_address_pairs:
+ type: list
+ description: List of allowed address pair for this interface
+ required: false
+ status: SUPPORTED
+ entry_schema:
+ type: org.openecomp.datatypes.heat.network.contrail.AddressPair
+ shared_ip:
+ type: boolean
+ description: Shared ip enabled
+ required: false
+ default: false
+ status: SUPPORTED
+ ip_address:
+ type: string
+ description: IP for this interface
+ required: false
+ status: SUPPORTED
+ interface_type:
+ type: string
+ description: Interface type
+ required: true
+ status: SUPPORTED
+ constraints:
+ - valid_values:
+ - management
+ - left
+ - right
+ - other
+ attributes:
+ fq_name:
+ type: string
+ description: fq_name
+ status: SUPPORTED
tosca.nodes.nfv.NS.vEPC_NS:
derived_from: tosca.nodes.nfv.NS
properties:
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 0000000..130590c
--- /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<String, Map<String, NodeTemplate>> portNodeTemplates = new HashMap<>();
+ //Map of service template file name and map of external port node template ids, node template
+ private Map<String, Map<String, NodeTemplate>> externalPortNodeTemplates = new HashMap<>();
+ //Map of substitution service template name and the list of ports with link requirement from
+ // the abstract
+ private Map<String, List<String>> portNodeTemplateIdsFromAbstract = new HashMap<>();
+ private static MdcDataDebugMessage mdcDataDebugMessage = new MdcDataDebugMessage();
+ private Map<String, ServiceTemplate> globalTypesServiceTemplate =
+ GlobalTypesGenerator.getGlobalTypesServiceTemplate();
+
+ /**
+ * Enrich tosca for port mirroring.
+ *
+ * @param toscaServiceModel the tosca service model
+ * @return the map Error descriptor map
+ */
+ public Map<String,List<ErrorMessage>> enrich(ToscaServiceModel toscaServiceModel) {
+ mdcDataDebugMessage.debugEntryMessage(null);
+ Map<String, List<ErrorMessage>> errors = new HashMap<>();
+ Map<String, ServiceTemplate> 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<String, NodeTemplate> nodeTemplates =
+ serviceTemplate.getTopology_template().getNode_templates();
+ if (Objects.nonNull(nodeTemplates)) {
+ //Get all concrete port node templates from the service template
+ Map<String, NodeTemplate> 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<String> abstractLinkedPortNodeTemplates = new ArrayList<>();
+ for (Map.Entry<String, NodeTemplate> nodeTemplateEntry : nodeTemplates.entrySet()) {
+ NodeTemplate nodeTemplate = nodeTemplateEntry.getValue();
+ if (isSubstitutableNodeTemplate(nodeTemplate)) {
+ List<Map<String, RequirementAssignment>> requirements = nodeTemplate.getRequirements();
+ if (Objects.nonNull(requirements)) {
+ for (Map<String, RequirementAssignment> 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<String>
+ abstractLinkedPortNodeTemplates) {
+ String substitutionServiceTemplateName = null;
+ if (nodeTemplate.getProperties() != null) {
+ Map serviceTemplateFilter = (Map<String, Object>) 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<String> portList =
+ portNodeTemplateIdsFromAbstract.get(substitutionServiceTemplateName);
+ portList.addAll(abstractLinkedPortNodeTemplates);
+ portNodeTemplateIdsFromAbstract.put(substitutionServiceTemplateName, portList);
+ } else {
+ portNodeTemplateIdsFromAbstract.put(substitutionServiceTemplateName,
+ abstractLinkedPortNodeTemplates);
+ }
+ }
+ }
+ }
+
+ private void filterExternalPorts(ToscaServiceModel toscaServiceModel) {
+ for (Map.Entry<String, Map<String, NodeTemplate>> portNodeTemplateEntry : portNodeTemplates
+ .entrySet()) {
+ Map<String, NodeTemplate> externalPorts = new HashMap<>();
+ String serviceTemplateFileName = portNodeTemplateEntry.getKey();
+ Map<String, NodeTemplate> portNodeTemplateMap = portNodeTemplateEntry.getValue();
+ for (Map.Entry<String, NodeTemplate> 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<String, Map<String, NodeTemplate>> entry : externalPortNodeTemplates
+ .entrySet()) {
+ String serviceTemplateName = entry.getKey();
+ ServiceTemplate serviceTemplate =
+ toscaServiceModel.getServiceTemplates().get(serviceTemplateName);
+ Map<String, NodeTemplate> externalNodeTemplates = entry.getValue();
+ if (MapUtils.isNotEmpty(externalNodeTemplates)) {
+ for (Map.Entry<String, NodeTemplate> 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<String, PropertyDefinition> 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<String, Object> properties = portNodeTemplate.getProperties();
+ Map<String, Object> filteredProperties = new HashMap<>();
+
+ if(MapUtils.isEmpty(properties)){
+ return;
+ }
+
+ for(Map.Entry<String, Object> 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<String> 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<Map<String, CapabilityAssignment>> capabilities = portNodeTemplate.getCapabilities();
+ if (Objects.isNull(capabilities)) {
+ capabilities = new ArrayList<>();
+ }
+ Map<String, Object> 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<List<RequirementAssignment>> 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<Map<String, Import>> imports = serviceTemplate.getImports();
+ Map<String, Import> 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<Map<String, RequirementAssignment>> requirements = nodeTemplate.getRequirements();
+ if (Objects.nonNull(requirements)) {
+ for (Map<String, RequirementAssignment> 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 f1804c8..090c3ae 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 Map<String, List<ErrorMessage>> enrich() {
Map<String, List<ErrorMessage>> errors = new HashMap<>();
errors.putAll(enrichAbstractSubstitute());
+ errors.putAll(enrichPortMirroring());
return errors;
}
@@ -55,4 +56,14 @@
mdcDataDebugMessage.debugExitMessage(null, null);
return enrichErrors;
}
+
+ private Map<String, List<ErrorMessage>> enrichPortMirroring() {
+ mdcDataDebugMessage.debugEntryMessage(null, null);
+ Map<String, List<ErrorMessage>> 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 0000000..c166938
--- /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);
+ }
+}
diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/datatypes/ToscaNodeType.java b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/datatypes/ToscaNodeType.java
index d8e0902..952a9cf 100644
--- a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/datatypes/ToscaNodeType.java
+++ b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/datatypes/ToscaNodeType.java
@@ -33,7 +33,9 @@
config.getAsString(ConfigConstants.NAMESPACE, ConfigConstants.PREFIX_NODE_TYPE_VFC);
public static final String CP_NODE_TYPE_PREFIX =
config.getAsString(ConfigConstants.NAMESPACE, ConfigConstants.PREFIX_NODE_TYPE_CP);
- public static final String NETWORK_NODE_TYPE_PREFIX =
+ public static String EXTERNAL_CP_NODE_TYPE_PREFIX =
+ config.getAsString(ConfigConstants.NAMESPACE, ConfigConstants.PREFIX_NODE_TYPE_EXTERNAL_CP);
+ public static String NETWORK_NODE_TYPE_PREFIX =
config.getAsString(ConfigConstants.NAMESPACE, ConfigConstants.PREFIX_NODE_TYPE_NETWORK);
public static final String ABSTRACT_NODE_TYPE_PREFIX =
config.getAsString(ConfigConstants.NAMESPACE, ConfigConstants.PREFIX_NODE_TYPE_ABSTARCT);
@@ -77,6 +79,10 @@
public static final String NETWORK_SUB_INTERFACE = CP_NODE_TYPE_PREFIX + "network.SubInterface";
public static final String CONTRAILV2_VLAN_SUB_INTERFACE = CP_NODE_TYPE_PREFIX
+ "heat.network.contrailV2.VLANSubInterface";
+ //Port Mirroring external node types
+ public static String EXTERNAL_CP = EXTERNAL_CP_NODE_TYPE_PREFIX + "extCP";
+ public static String EXTERNAL_CONTRAIL_PORT = EXTERNAL_CP_NODE_TYPE_PREFIX + "extContrailCP";
+ public static String EXTERNAL_NEUTRON_PORT = EXTERNAL_CP_NODE_TYPE_PREFIX + "extNeutronCP";
public static final String ABSTRACT_SUBSTITUTE = ABSTRACT_NODE_TYPE_PREFIX + "AbstractSubstitute";
public static final String VFC_ABSTRACT_SUBSTITUTE = ABSTRACT_NODE_TYPE_PREFIX + "VFC";
diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/ConfigConstants.java b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/ConfigConstants.java
index 0e4bc22..91103c5 100644
--- a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/ConfigConstants.java
+++ b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/ConfigConstants.java
@@ -36,6 +36,8 @@
public static final String PREFIX_NODE_TYPE_VFC = PREFIX + ".nodeType.vfc";
public static final String PREFIX_NODE_TYPE_NETWORK = PREFIX + ".nodeType.network";
public static final String PREFIX_NODE_TYPE_CP = PREFIX + ".nodeType.connectionPoint";
+ public static final String PREFIX_NODE_TYPE_EXTERNAL_CP = PREFIX + ".nodeType"
+ + ".external.connectionPoint";
public static final String PREFIX_NODE_TYPE_ABSTARCT = PREFIX + ".nodeType.abstract";
public static final String PREFIX_NODE_TYPE_RULE = PREFIX + ".nodeType.rule";
diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/DataModelUtil.java b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/DataModelUtil.java
index 0effd40..d223b5f 100644
--- a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/DataModelUtil.java
+++ b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/DataModelUtil.java
@@ -37,6 +37,7 @@
import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
import org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType;
import org.openecomp.sdc.tosca.datatypes.model.AttributeDefinition;
+import org.openecomp.sdc.tosca.datatypes.model.CapabilityAssignment;
import org.openecomp.sdc.tosca.datatypes.model.CapabilityDefinition;
import org.openecomp.sdc.tosca.datatypes.model.CapabilityType;
import org.openecomp.sdc.tosca.datatypes.model.Constraint;
@@ -157,6 +158,47 @@
}
/**
+ * Add substitution mapping capability.
+ *
+ * @param serviceTemplate the service template
+ * @param substitutionMappingCapabilityId the substitution mapping capability id
+ * @param substitutionMappingCapabilityList the substitution mapping capability list
+ */
+ public static void addSubstitutionMappingCapability(ServiceTemplate serviceTemplate,
+ String substitutionMappingCapabilityId,
+ List<String> substitutionMappingCapabilityList) {
+
+
+ mdcDataDebugMessage.debugEntryMessage(null, null);
+
+ if (serviceTemplate == null) {
+ MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
+ LoggerTragetServiceName.ADD_ENTITIES_TO_TOSCA, ErrorLevel.ERROR.name(),
+ LoggerErrorCode.DATA_ERROR.getErrorCode(), LoggerErrorDescription.INVALID_ADD_ACTION);
+ throw new CoreException(
+ new InvalidAddActionNullEntityErrorBuilder("Substitution Mapping Capabilities",
+ "Service Template").build());
+ }
+
+ if (serviceTemplate.getTopology_template() == null) {
+ serviceTemplate.setTopology_template(new TopologyTemplate());
+ }
+ if (serviceTemplate.getTopology_template().getSubstitution_mappings() == null) {
+ serviceTemplate.getTopology_template().setSubstitution_mappings(new SubstitutionMapping());
+ }
+ if (serviceTemplate.getTopology_template().getSubstitution_mappings().getCapabilities()
+ == null) {
+ serviceTemplate.getTopology_template().getSubstitution_mappings()
+ .setCapabilities(new HashMap<>());
+ }
+
+ serviceTemplate.getTopology_template().getSubstitution_mappings().getCapabilities()
+ .putIfAbsent(substitutionMappingCapabilityId, substitutionMappingCapabilityList);
+
+ mdcDataDebugMessage.debugExitMessage(null, null);
+ }
+
+ /**
* Add node template.
*
* @param serviceTemplate the service template
@@ -1445,11 +1487,11 @@
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
clonedObjectValue = objectInputStream.readObject();
} catch (NotSerializableException ex) {
- logger.debug(ex.getMessage(), ex);
- return getClonedObject(obj, obj.getClass());
+ logger.debug(ex.getMessage(), ex);
+ return getClonedObject(obj, obj.getClass());
} catch (IOException | ClassNotFoundException ex) {
- logger.debug(ex.getMessage(), ex);
- return null;
+ logger.debug(ex.getMessage(), ex);
+ return null;
}
return clonedObjectValue;
}
@@ -1510,6 +1552,30 @@
return substitutionMapping;
}
+ /**
+ * Add node template capability.
+ *
+ * @param nodeTemplate the node template
+ * @param capabilityId the capability id
+ * @param capabilityProperties the capability properties
+ * @param capabilityAttributes the capability attributes
+ */
+ public static void addNodeTemplateCapability(NodeTemplate nodeTemplate, String capabilityId,
+ Map<String, Object> capabilityProperties,
+ Map<String, Object> capabilityAttributes) {
+ List<Map<String, CapabilityAssignment>> capabilities = nodeTemplate.getCapabilities();
+ if (Objects.isNull(capabilities)) {
+ capabilities = new ArrayList<>();
+ }
+ CapabilityAssignment capabilityAssignment = new CapabilityAssignment();
+ capabilityAssignment.setProperties(capabilityProperties);
+ capabilityAssignment.setAttributes(capabilityAttributes);
+ Map<String, CapabilityAssignment> nodeTemplateCapability = new HashMap<>();
+ nodeTemplateCapability.put(capabilityId, capabilityAssignment);
+ capabilities.add(nodeTemplateCapability);
+ nodeTemplate.setCapabilities(capabilities);
+ }
+
private static Map<String, List<String>> manageRequirementMapping(
List<Map<String, RequirementDefinition>> requirementList,
Map<String, List<String>> requirementSubstitutionMapping) {
diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/ToscaConstants.java b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/ToscaConstants.java
index cf0c763..4d45e8f 100644
--- a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/ToscaConstants.java
+++ b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/ToscaConstants.java
@@ -40,6 +40,7 @@
public static final String SCALABLE_CAPABILITY_ID = "scalable";
public static final String ATTACHMENT_CAPABILITY_ID = "attachment";
public static final String FEATURE_CAPABILITY_ID = "feature";
+ public static final String PORT_MIRRORING_CAPABILITY_ID = "port_mirroring";
//General
public static final String TOSCA_DEFINITIONS_VERSION = "tosca_simple_yaml_1_0_0";
@@ -62,6 +63,8 @@
public static final String PORT_FIXED_IPS = "fixed_ips";
public static final String PORT_ALLOWED_ADDRESS_PAIRS = "allowed_address_pairs";
+ public static final String PORT_NETWORK_ROLE_PROPERTY_NAME = "network_role";
+ public static final String PORT_MIRRORING_CAPABILITY_CP_PROPERTY_NAME = "connection_point";
public static final String MAC_ADDRESS = "mac_address";
public static final String COMPUTE_IMAGE = "image";