Add Tosca model healer

create a Tosca model healer for future changes in Tosca structure

Change-Id: I3843e4727b6bbb383576ae6a4fb055c5b6fa001f
Issue-ID: SDC-973
Signed-off-by: talio <tali.orenbach@amdocs.com>
diff --git a/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-api/src/main/java/org/openecomp/sdc/healing/api/HealingManager.java b/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-api/src/main/java/org/openecomp/sdc/healing/api/HealingManager.java
index ca0a3c7..db9cafe 100644
--- a/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-api/src/main/java/org/openecomp/sdc/healing/api/HealingManager.java
+++ b/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-api/src/main/java/org/openecomp/sdc/healing/api/HealingManager.java
@@ -37,7 +37,4 @@
    */
   Optional<Version> healItemVersion(String itemId, Version version, ItemType itemType,
                                     boolean force);
-
-  Object heal(String itemId, Version version, HealerType healerType, HealCode code,
-              ItemType itemType);
 }
diff --git a/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-core/src/main/java/org/openecomp/sdc/healing/impl/HealingManagerImpl.java b/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-core/src/main/java/org/openecomp/sdc/healing/impl/HealingManagerImpl.java
index 07122f0..4a0bf13 100644
--- a/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-core/src/main/java/org/openecomp/sdc/healing/impl/HealingManagerImpl.java
+++ b/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-core/src/main/java/org/openecomp/sdc/healing/impl/HealingManagerImpl.java
@@ -158,21 +158,6 @@
     }
   }
 
-  @Override
-  public Object heal(String itemId, Version version, HealerType healerType, HealCode code,
-                     ItemType itemType) {
-    String healerClassName = getItemHealers(itemType).get(healerType.name()).get(code.name());
-    ArrayList<String> healingFailureMessages = new ArrayList<>();
-
-    Object result = executeHealer(itemId, version, healerClassName, healingFailureMessages);
-
-    if (!healingFailureMessages.isEmpty()) {
-      throw new CoreException(new ErrorCode.ErrorCodeBuilder().withMessage(CommonMethods
-          .listToSeparatedString(healingFailureMessages, '\n')).build());
-    }
-    return result;
-  }
-
   private Optional<String> executeHealers(String itemId, Version version,
                                           Map<String, Map<String, String>> itemHealers) {
     List<String> healers = itemHealers.values().stream()
diff --git a/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-core/src/main/resources/entityHealingConfiguration.json b/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-core/src/main/resources/entityHealingConfiguration.json
index ab8a1df..64f43a6 100644
--- a/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-core/src/main/resources/entityHealingConfiguration.json
+++ b/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-core/src/main/resources/entityHealingConfiguration.json
@@ -2,6 +2,9 @@
   "vsp": {
     "structure": {
       "ownerHealer": "org.openecomp.sdc.healing.healers.OwnerHealer"
+    },
+    "data": {
+      "toscaServiceModelHealer": "org.openecomp.sdc.healing.healers.ToscaServiceModelHealer"
     }
   },
   "vlm": {
diff --git a/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-impl/pom.xml b/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-impl/pom.xml
index 1359e69..5b0558c 100644
--- a/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-impl/pom.xml
+++ b/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-impl/pom.xml
@@ -44,6 +44,17 @@
             <artifactId>openecomp-item-permissions-impl</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.openecomp.sdc</groupId>
+            <artifactId>openecomp-tosca-converter-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.openecomp.sdc</groupId>
+            <artifactId>openecomp-tosca-converter-core</artifactId>
+            <version>${project.version}</version>
+            <scope>runtime</scope>
+        </dependency>
 
     </dependencies>
 
diff --git a/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-impl/src/main/java/org/openecomp/sdc/healing/healers/ToscaServiceModelHealer.java b/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-impl/src/main/java/org/openecomp/sdc/healing/healers/ToscaServiceModelHealer.java
new file mode 100644
index 0000000..e07faad
--- /dev/null
+++ b/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-impl/src/main/java/org/openecomp/sdc/healing/healers/ToscaServiceModelHealer.java
@@ -0,0 +1,116 @@
+package org.openecomp.sdc.healing.healers;
+
+import org.apache.commons.collections4.MapUtils;
+import org.openecomp.core.converter.ToscaConverter;
+import org.openecomp.core.converter.factory.ToscaConverterFactory;
+import org.openecomp.core.model.dao.ServiceModelDao;
+import org.openecomp.core.model.dao.ServiceModelDaoFactory;
+import org.openecomp.core.model.types.ServiceElement;
+import org.openecomp.core.translator.datatypes.TranslatorOutput;
+import org.openecomp.core.utilities.file.FileContentHandler;
+import org.openecomp.core.utilities.orchestration.OnboardingTypesEnum;
+import org.openecomp.core.validation.util.MessageContainerUtil;
+import org.openecomp.sdc.common.utils.CommonUtil;
+import org.openecomp.sdc.datatypes.error.ErrorLevel;
+import org.openecomp.sdc.healing.interfaces.Healer;
+import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
+import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil;
+import org.openecomp.sdc.vendorsoftwareproduct.dao.OrchestrationTemplateDao;
+import org.openecomp.sdc.vendorsoftwareproduct.dao.OrchestrationTemplateDaoFactory;
+import org.openecomp.sdc.vendorsoftwareproduct.dao.type.OrchestrationTemplateEntity;
+import org.openecomp.sdc.versioning.dao.types.Version;
+
+import java.io.IOException;
+import java.util.Objects;
+import java.util.Optional;
+
+public class ToscaServiceModelHealer implements Healer {
+  private ServiceModelDao<ToscaServiceModel, ServiceElement> serviceModelDao;
+  private OrchestrationTemplateDao orchestrationTemplateDao;
+  private static final String VALIDATION_FAILURE_MESSAGE = "Product was updated. Please " +
+      "update the uploaded Heat file according to these validation errors: \n";
+
+  public ToscaServiceModelHealer() {
+    this.serviceModelDao = ServiceModelDaoFactory.getInstance().createInterface();
+    this.orchestrationTemplateDao = OrchestrationTemplateDaoFactory.getInstance().createInterface();
+  }
+
+  public ToscaServiceModelHealer(
+      ServiceModelDao<ToscaServiceModel, ServiceElement> serviceModelDao,
+      OrchestrationTemplateDao orchestrationTemplateDao) {
+    this.serviceModelDao = serviceModelDao;
+    this.orchestrationTemplateDao = orchestrationTemplateDao;
+  }
+
+  @Override
+  public Object heal(String itemId, Version version) throws Exception {
+    OrchestrationTemplateEntity orchestrationTemplateEntity =
+        orchestrationTemplateDao.get(itemId, version);
+    OnboardingTypesEnum type =
+        OnboardingTypesEnum.getOnboardingTypesEnum(orchestrationTemplateEntity.getFileSuffix());
+
+    if (Objects.isNull(type)
+        || Objects.isNull(orchestrationTemplateEntity.getContentData())) {
+      return null;
+    }
+
+    Optional<ToscaServiceModel> healedServiceModel =
+        healServiceModel(orchestrationTemplateEntity, type);
+
+    healedServiceModel.ifPresent(serviceModel -> serviceModelDao
+        .overrideServiceModel(itemId, version, serviceModel));
+
+    return healedServiceModel;
+
+  }
+
+  private Optional<ToscaServiceModel> healServiceModel(
+      OrchestrationTemplateEntity orchestrationTemplateEntity,
+      OnboardingTypesEnum type) throws IOException {
+    switch (type) {
+      case ZIP:
+        return Optional.of(healServiceModelFromZip(
+            getFileContentHandlerForHealing(orchestrationTemplateEntity, type)));
+
+      case CSAR:
+        return Optional.of(healServiceModelFromCsar(
+            getFileContentHandlerForHealing(orchestrationTemplateEntity, type)));
+
+      default:
+        return Optional.empty();
+    }
+
+  }
+
+  private FileContentHandler getFileContentHandlerForHealing(
+      OrchestrationTemplateEntity orchestrationTemplateEntity, OnboardingTypesEnum type)
+      throws IOException {
+    byte[] uploadedFileContent = orchestrationTemplateEntity.getContentData().array();
+    return CommonUtil.validateAndUploadFileContent(type, uploadedFileContent);
+  }
+
+  private ToscaServiceModel healServiceModelFromZip(FileContentHandler contentMap) {
+    TranslatorOutput translatorOutput =
+        HeatToToscaUtil.loadAndTranslateTemplateData(contentMap);
+
+    if (areThereValidationErrors(translatorOutput)) {
+      String validationErrorsAsString = MessageContainerUtil.getErrorMessagesListAsString
+          (MessageContainerUtil
+              .getMessageByLevel(ErrorLevel.ERROR, translatorOutput.getErrorMessages()));
+      throw new RuntimeException(VALIDATION_FAILURE_MESSAGE + validationErrorsAsString);
+    }
+
+    return translatorOutput.getToscaServiceModel();
+  }
+
+  private boolean areThereValidationErrors(TranslatorOutput translatorOutput) {
+    return MapUtils.isNotEmpty(MessageContainerUtil.getMessageByLevel(ErrorLevel.ERROR,
+        translatorOutput.getErrorMessages()));
+  }
+
+  private ToscaServiceModel healServiceModelFromCsar(FileContentHandler contentMap)
+      throws IOException {
+    ToscaConverter toscaConverter = ToscaConverterFactory.getInstance().createInterface();
+    return toscaConverter.convert(contentMap);
+  }
+}
diff --git a/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-impl/src/test/resources/mock/healers/capability/capabilityAsList/in/MainServiceTemplate.yaml b/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-impl/src/test/resources/mock/healers/capability/capabilityAsList/in/MainServiceTemplate.yaml
new file mode 100644
index 0000000..faa15f3
--- /dev/null
+++ b/openecomp-be/lib/openecomp-healing-lib/openecomp-sdc-healing-impl/src/test/resources/mock/healers/capability/capabilityAsList/in/MainServiceTemplate.yaml
@@ -0,0 +1,76 @@
+tosca_definitions_version: tosca_simple_yaml_1_0_0
+metadata:
+  template_name: Main
+imports:
+- openecomp_heat_index:
+    file: openecomp-heat/_index.yml
+node_types:
+  org.openecomp.resource.vfc.nodes.heat.pcrf_psm:
+    derived_from: org.openecomp.resource.vfc.nodes.heat.nova.Server
+  org.openecomp.resource.vfc.nodes.heat.pcm:
+    derived_from: org.openecomp.resource.vfc.nodes.heat.nova.Server
+topology_template:
+  inputs:
+    Internal2_name:
+      label: Internal2_name
+      hidden: false
+      immutable: false
+      type: string
+      description: Internal2_name
+  node_templates:
+    pd_server:
+      type: org.openecomp.resource.vfc.nodes.heat.pd_server
+      properties:
+        availability_zone:
+          get_input:
+          - compute_pd_server_availability_zone
+          - index_value
+        flavor:
+          get_input: vm_flavor_name
+        image:
+          get_input: vm_image_name
+        name:
+          get_input:
+          - compute_pd_server_name
+          - index_value
+        user_data_format:
+          get_input:
+          - compute_pd_server_user_data_format
+          - index_value
+    pd_server_pd01_port:
+      type: org.openecomp.resource.cp.v2.extNeutronCP
+      properties:
+        ip_requirements:
+          get_input: port_pd01_port_ip_requirements
+      requirements:
+      - binding:
+          capability: tosca.capabilities.network.Bindable
+          node: pd_server
+          relationship: tosca.relationships.network.BindsTo
+      capabilities:
+      - port_mirroring:
+          properties:
+            connection_point:
+              nf_type: ''
+              nfc_type: pd_server
+              network_role:
+                get_input: port_pd01_port_network_role
+              pps_capacity: ''
+  groups:
+    ep-jsa_net:
+      type: org.openecomp.groups.heat.HeatStack
+      properties:
+        heat_file: ../Artifacts/ep-jsa_net.yaml
+        description: |
+          Version 2.0 02-09-2016 (Authors: John Doe, user PROD)
+      members:
+      - pcm_port_1
+      - FSB1_Internal2
+      - FSB1_Internal1
+      - FSB1_OAM
+      - psm01_port_0
+      - pcm_port_0
+      - server_pcm
+      - pcrf_server_psm
+      - FSB2
+      - FSB1
\ No newline at end of file
diff --git a/openecomp-be/lib/openecomp-sdc-model-lib/openecomp-sdc-model-api/src/main/java/org/openecomp/core/model/dao/ServiceModelDao.java b/openecomp-be/lib/openecomp-sdc-model-lib/openecomp-sdc-model-api/src/main/java/org/openecomp/core/model/dao/ServiceModelDao.java
index 2ef31d4..0fb80b1 100644
--- a/openecomp-be/lib/openecomp-sdc-model-lib/openecomp-sdc-model-api/src/main/java/org/openecomp/core/model/dao/ServiceModelDao.java
+++ b/openecomp-be/lib/openecomp-sdc-model-lib/openecomp-sdc-model-api/src/main/java/org/openecomp/core/model/dao/ServiceModelDao.java
@@ -32,4 +32,10 @@
   E getServiceModelInfo(String vspId, Version version, String name);
 
   void deleteAll(String vspId, Version version);
+
+  /**
+   * This method gets used in healing, in order to replace the healed service model with the
+   * existing one without creating any conflicts
+   **/
+  void overrideServiceModel(String vspId, Version version, M serviceModel);
 }
diff --git a/openecomp-be/lib/openecomp-sdc-model-lib/openecomp-sdc-model-impl/src/main/java/org/openecomp/sdc/model/impl/EnrichedServiceModelDaoImpl.java b/openecomp-be/lib/openecomp-sdc-model-lib/openecomp-sdc-model-impl/src/main/java/org/openecomp/sdc/model/impl/EnrichedServiceModelDaoImpl.java
index 348a8ad..3bf61e5 100644
--- a/openecomp-be/lib/openecomp-sdc-model-lib/openecomp-sdc-model-impl/src/main/java/org/openecomp/sdc/model/impl/EnrichedServiceModelDaoImpl.java
+++ b/openecomp-be/lib/openecomp-sdc-model-lib/openecomp-sdc-model-impl/src/main/java/org/openecomp/sdc/model/impl/EnrichedServiceModelDaoImpl.java
@@ -45,4 +45,11 @@
     templateDao.deleteAll(vspId, version);
     artifactDao.deleteAll(vspId, version);
   }
+
+  @Override
+  public void overrideServiceModel(String vspId, Version version, ToscaServiceModel serviceModel) {
+    storeServiceModel(vspId, version, serviceModel);
+  }
+
+
 }
diff --git a/openecomp-be/lib/openecomp-sdc-model-lib/openecomp-sdc-model-impl/src/main/java/org/openecomp/sdc/model/impl/ServiceModelDaoImpl.java b/openecomp-be/lib/openecomp-sdc-model-lib/openecomp-sdc-model-impl/src/main/java/org/openecomp/sdc/model/impl/ServiceModelDaoImpl.java
index 4ad8d7c..b9a703e 100644
--- a/openecomp-be/lib/openecomp-sdc-model-lib/openecomp-sdc-model-impl/src/main/java/org/openecomp/sdc/model/impl/ServiceModelDaoImpl.java
+++ b/openecomp-be/lib/openecomp-sdc-model-lib/openecomp-sdc-model-impl/src/main/java/org/openecomp/sdc/model/impl/ServiceModelDaoImpl.java
@@ -39,4 +39,10 @@
   public void deleteAll(String vspId, Version version) {
 
   }
+
+  @Override
+  public void overrideServiceModel(String vspId, Version version,
+                                   ToscaServiceModel serviceModel) {
+    storeServiceModel(vspId, version, serviceModel);
+  }
 }
diff --git a/openecomp-be/lib/openecomp-sdc-model-lib/openecomp-sdc-model-impl/src/main/java/org/openecomp/sdc/model/impl/zusammen/ServiceModelDaoZusammenImpl.java b/openecomp-be/lib/openecomp-sdc-model-lib/openecomp-sdc-model-impl/src/main/java/org/openecomp/sdc/model/impl/zusammen/ServiceModelDaoZusammenImpl.java
index 4ae9353..c73a304 100644
--- a/openecomp-be/lib/openecomp-sdc-model-lib/openecomp-sdc-model-impl/src/main/java/org/openecomp/sdc/model/impl/zusammen/ServiceModelDaoZusammenImpl.java
+++ b/openecomp-be/lib/openecomp-sdc-model-lib/openecomp-sdc-model-impl/src/main/java/org/openecomp/sdc/model/impl/zusammen/ServiceModelDaoZusammenImpl.java
@@ -162,6 +162,65 @@
         elementType.name(), vspId, version.getId());
   }
 
+  @Override
+  public void overrideServiceModel(String vspId,
+                                   Version version,
+                                   ToscaServiceModel serviceModel) {
+    SessionContext context = ZusammenUtil.createSessionContext();
+    ElementContext elementContext = new ElementContext(vspId, version.getId());
+
+    ZusammenElement serviceModelElement = buildStructuralElement(elementType, Action.UPDATE);
+
+    Optional<ElementInfo> origServiceModel = getServiceModelElementInfo(context, elementContext);
+    if (!origServiceModel.isPresent()) {
+      return;
+    }
+
+    Id serviceModelElementId = origServiceModel.get().getId();
+    overrideServiceTemplates(serviceModelElementId, serviceModel, context, elementContext,
+        serviceModelElement);
+    serviceModelElement.getInfo()
+        .addProperty(BASE_PROPERTY, serviceModel.getEntryDefinitionServiceTemplate());
+
+    zusammenAdaptor
+        .saveElement(context, elementContext, serviceModelElement, "Override service model");
+  }
+
+
+  private void overrideServiceTemplates(Id serviceModelElementId,
+                                        ToscaServiceModel serviceModel,
+                                        SessionContext context,
+                                        ElementContext elementContext,
+                                        ZusammenElement serviceModelElement) {
+    Optional<ElementInfo> elementInfo = zusammenAdaptor.getElementInfoByName(
+        context, elementContext, serviceModelElementId, ElementType.ServiceTemplate.name());
+    if (!elementInfo.isPresent()) {
+      return;
+    }
+    ZusammenElement zusammenElement =
+        buildStructuralElement(ElementType.ServiceTemplate, Action.UPDATE);
+    Collection<Element> elements = zusammenAdaptor.listElementData(context, elementContext,
+        elementInfo.get().getId());
+
+    elements
+        .forEach(element -> zusammenElement
+            .addSubElement(overrideServiceTemplateInElement(element, serviceModel)));
+
+    serviceModelElement.addSubElement(zusammenElement);
+  }
+
+  private ZusammenElement overrideServiceTemplateInElement(Element element,
+                                                           ToscaServiceModel serviceModel) {
+    ZusammenElement serviceTemplateElement = (ZusammenElement) element;
+    String templateName = element.getInfo().getName();
+    Optional<ServiceTemplate> serviceTemplate = serviceModel.getServiceTemplate(templateName);
+    serviceTemplate.ifPresent(serviceTemplateFile -> {
+      String yaml = new ToscaExtensionYamlUtil().objectToYaml(serviceTemplateFile);
+      serviceTemplateElement.setData(new ByteArrayInputStream(yaml.getBytes()));
+    });
+    return serviceTemplateElement;
+  }
+
   private Optional<ElementInfo> getServiceModelElementInfo(SessionContext context,
                                                            ElementContext elementContext) {
     Collection<ElementInfo> vspModelSubs = zusammenAdaptor
@@ -240,7 +299,7 @@
       String yamlContent = IOUtils.toString(element.getData());
       return new ToscaExtensionYamlUtil().
           yamlToObject(yamlContent, ServiceTemplate.class);
-    }catch (Exception e){
+    } catch (Exception e) {
       throw new CoreException(
           new RetrieveServiceTemplateFromDbErrorBuilder(
               element.getInfo().getName(), e.getMessage()).build());
diff --git a/openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/src/test/resources/mock/heat/nested/nestedwithoutNodeTemplates/expectedoutputfiles/GlobalSubstitutionTypesServiceTemplate.yaml b/openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/src/test/resources/mock/heat/nested/nestedwithoutNodeTemplates/expectedoutputfiles/GlobalSubstitutionTypesServiceTemplate.yaml
index 67df29f..dfd7204 100644
--- a/openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/src/test/resources/mock/heat/nested/nestedwithoutNodeTemplates/expectedoutputfiles/GlobalSubstitutionTypesServiceTemplate.yaml
+++ b/openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/src/test/resources/mock/heat/nested/nestedwithoutNodeTemplates/expectedoutputfiles/GlobalSubstitutionTypesServiceTemplate.yaml
@@ -237,6 +237,26 @@
         occurrences:
         - 1
         - 1
+    - dependency_perimeta_ssc_a_untrusted_0_vlan_ports:
+        capability: tosca.capabilities.Node
+        node: tosca.nodes.Root
+        relationship: tosca.relationships.DependsOn
+        occurrences:
+        - 0
+        - UNBOUNDED
+    - dependency_contrail_vmi_subinterface_perimeta_ssc_a_untrusted_0_vlan_ports:
+        capability: tosca.capabilities.Node
+        node: tosca.nodes.Root
+        relationship: tosca.relationships.DependsOn
+        occurrences:
+        - 0
+        - UNBOUNDED
+    - link_contrail_vmi_subinterface_perimeta_ssc_a_untrusted_0_vlan_ports:
+        capability: tosca.capabilities.network.Linkable
+        relationship: tosca.relationships.network.LinksTo
+        occurrences:
+        - 1
+        - 1
     - dependency_perimeta_ssc_a_trusted_0_port:
         capability: tosca.capabilities.Node
         node: tosca.nodes.Root
@@ -436,6 +456,11 @@
         occurrences:
         - 1
         - UNBOUNDED
+      feature_contrail_vmi_subinterface_perimeta_ssc_a_untrusted_0_vlan_ports:
+        type: tosca.capabilities.Node
+        occurrences:
+        - 1
+        - UNBOUNDED
       feature_perimeta_ssc_a_mgmt_1_port:
         type: tosca.capabilities.Node
         occurrences:
@@ -650,6 +675,11 @@
         occurrences:
         - 1
         - UNBOUNDED
+      feature_perimeta_ssc_a_untrusted_0_vlan_ports:
+        type: tosca.capabilities.Node
+        occurrences:
+        - 1
+        - UNBOUNDED
       disk.device.latency_perimeta_ssc_a_server_0:
         type: org.openecomp.capabilities.metric.Ceilometer
         description: A node type that includes the Metric capability indicates that it can be monitored using ceilometer.
@@ -1167,6 +1197,26 @@
         occurrences:
         - 1
         - 1
+    - dependency_perimeta_ssc_b_untrusted_0_vlan_ports:
+        capability: tosca.capabilities.Node
+        node: tosca.nodes.Root
+        relationship: tosca.relationships.DependsOn
+        occurrences:
+        - 0
+        - UNBOUNDED
+    - dependency_contrail_vmi_subinterface_perimeta_ssc_b_untrusted_0_vlan_ports:
+        capability: tosca.capabilities.Node
+        node: tosca.nodes.Root
+        relationship: tosca.relationships.DependsOn
+        occurrences:
+        - 0
+        - UNBOUNDED
+    - link_contrail_vmi_subinterface_perimeta_ssc_b_untrusted_0_vlan_ports:
+        capability: tosca.capabilities.network.Linkable
+        relationship: tosca.relationships.network.LinksTo
+        occurrences:
+        - 1
+        - 1
     - dependency_perimeta_ssc_b_mgmt_1_port:
         capability: tosca.capabilities.Node
         node: tosca.nodes.Root
@@ -1574,6 +1624,11 @@
         occurrences:
         - 1
         - UNBOUNDED
+      feature_perimeta_ssc_b_untrusted_0_vlan_ports:
+        type: tosca.capabilities.Node
+        occurrences:
+        - 1
+        - UNBOUNDED
       network.outgoing.bytes.rate_perimeta_ssc_b_mgmt_1_port:
         type: org.openecomp.capabilities.metric.Ceilometer
         description: A node type that includes the Metric capability indicates that it can be monitored using ceilometer.
@@ -1813,6 +1868,11 @@
         occurrences:
         - 1
         - UNBOUNDED
+      feature_contrail_vmi_subinterface_perimeta_ssc_b_untrusted_0_vlan_ports:
+        type: tosca.capabilities.Node
+        occurrences:
+        - 1
+        - UNBOUNDED
       network.outgoing.bytes.rate_perimeta_ssc_b_untrusted_parent_0_port:
         type: org.openecomp.capabilities.metric.Ceilometer
         description: A node type that includes the Metric capability indicates that it can be monitored using ceilometer.
@@ -2111,6 +2171,26 @@
         entry_schema:
           type: string
     requirements:
+    - dependency_perimeta_rtp_msc_a_untrusted_0_vlan_ports:
+        capability: tosca.capabilities.Node
+        node: tosca.nodes.Root
+        relationship: tosca.relationships.DependsOn
+        occurrences:
+        - 0
+        - UNBOUNDED
+    - dependency_contrail_vmi_subinterface_perimeta_rtp_msc_a_untrusted_0_vlan_ports:
+        capability: tosca.capabilities.Node
+        node: tosca.nodes.Root
+        relationship: tosca.relationships.DependsOn
+        occurrences:
+        - 0
+        - UNBOUNDED
+    - link_contrail_vmi_subinterface_perimeta_rtp_msc_a_untrusted_0_vlan_ports:
+        capability: tosca.capabilities.network.Linkable
+        relationship: tosca.relationships.network.LinksTo
+        occurrences:
+        - 1
+        - 1
     - dependency_perimeta_rtp_msc_a_trusted_0_port:
         capability: tosca.capabilities.Node
         node: tosca.nodes.Root
@@ -2189,6 +2269,11 @@
         occurrences:
         - 1
         - UNBOUNDED
+      feature_perimeta_rtp_msc_a_untrusted_0_vlan_ports:
+        type: tosca.capabilities.Node
+        occurrences:
+        - 1
+        - UNBOUNDED
       attachment_perimeta_rtp_msc_a_mgmt_0_port:
         type: tosca.capabilities.Attachment
         occurrences:
@@ -2390,6 +2475,11 @@
         occurrences:
         - 1
         - UNBOUNDED
+      feature_contrail_vmi_subinterface_perimeta_rtp_msc_a_untrusted_0_vlan_ports:
+        type: tosca.capabilities.Node
+        occurrences:
+        - 1
+        - UNBOUNDED
       disk.usage_perimeta_rtp_msc_a_server_0:
         type: org.openecomp.capabilities.metric.Ceilometer
         description: A node type that includes the Metric capability indicates that it can be monitored using ceilometer.
@@ -2761,6 +2851,33 @@
         description: IPv6 address associated with subinterfaces
         required: true
         status: SUPPORTED
+    requirements:
+    - dependency_contrail_vmi_subinterface:
+        capability: tosca.capabilities.Node
+        node: tosca.nodes.Root
+        relationship: tosca.relationships.DependsOn
+        occurrences:
+        - 0
+        - UNBOUNDED
+    - link_contrail_vmi_subinterface:
+        capability: tosca.capabilities.network.Linkable
+        relationship: tosca.relationships.network.LinksTo
+        occurrences:
+        - 1
+        - 1
+    - binding_contrail_vmi_subinterface:
+        capability: tosca.capabilities.network.Bindable
+        node: org.openecomp.resource.cp.nodes.network.Port
+        relationship: tosca.relationships.network.BindsTo
+        occurrences:
+        - 1
+        - 1
+    capabilities:
+      feature_contrail_vmi_subinterface:
+        type: tosca.capabilities.Node
+        occurrences:
+        - 1
+        - UNBOUNDED
   org.openecomp.resource.abstract.nodes.heat.module_2_perimeta_sw_b_child:
     derived_from: org.openecomp.resource.abstract.nodes.AbstractSubstitute
     properties:
@@ -2997,6 +3114,26 @@
         occurrences:
         - 1
         - 1
+    - dependency_perimeta_rtp_msc_b_untrusted_0_vlan_ports:
+        capability: tosca.capabilities.Node
+        node: tosca.nodes.Root
+        relationship: tosca.relationships.DependsOn
+        occurrences:
+        - 0
+        - UNBOUNDED
+    - dependency_contrail_vmi_subinterface_perimeta_rtp_msc_b_untrusted_0_vlan_ports:
+        capability: tosca.capabilities.Node
+        node: tosca.nodes.Root
+        relationship: tosca.relationships.DependsOn
+        occurrences:
+        - 0
+        - UNBOUNDED
+    - link_contrail_vmi_subinterface_perimeta_rtp_msc_b_untrusted_0_vlan_ports:
+        capability: tosca.capabilities.network.Linkable
+        relationship: tosca.relationships.network.LinksTo
+        occurrences:
+        - 1
+        - 1
     - dependency_perimeta_rtp_msc_b_server_0:
         capability: tosca.capabilities.Node
         node: tosca.nodes.Root
@@ -3154,6 +3291,11 @@
         occurrences:
         - 1
         - UNBOUNDED
+      feature_contrail_vmi_subinterface_perimeta_rtp_msc_b_untrusted_0_vlan_ports:
+        type: tosca.capabilities.Node
+        occurrences:
+        - 1
+        - UNBOUNDED
       attachment_perimeta_rtp_msc_b_ha_0_port:
         type: tosca.capabilities.Attachment
         occurrences:
@@ -3399,6 +3541,11 @@
         occurrences:
         - 1
         - UNBOUNDED
+      feature_perimeta_rtp_msc_b_untrusted_0_vlan_ports:
+        type: tosca.capabilities.Node
+        occurrences:
+        - 1
+        - UNBOUNDED
       network.incoming.packets.rate_perimeta_rtp_msc_b_mgmt_0_port:
         type: org.openecomp.capabilities.metric.Ceilometer
         description: A node type that includes the Metric capability indicates that it can be monitored using ceilometer.
@@ -3559,4 +3706,4 @@
         description: A node type that includes the Metric capability indicates that it can be monitored using ceilometer.
         occurrences:
         - 1
-        - UNBOUNDED
\ No newline at end of file
+        - UNBOUNDED
diff --git a/openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/src/test/resources/mock/heat/nested/nestedwithoutNodeTemplates/expectedoutputfiles/module_1_perimeta_swmu_a_childServiceTemplate.yaml b/openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/src/test/resources/mock/heat/nested/nestedwithoutNodeTemplates/expectedoutputfiles/module_1_perimeta_swmu_a_childServiceTemplate.yaml
index ed4dfdd..96d690f 100644
--- a/openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/src/test/resources/mock/heat/nested/nestedwithoutNodeTemplates/expectedoutputfiles/module_1_perimeta_swmu_a_childServiceTemplate.yaml
+++ b/openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/src/test/resources/mock/heat/nested/nestedwithoutNodeTemplates/expectedoutputfiles/module_1_perimeta_swmu_a_childServiceTemplate.yaml
@@ -306,6 +306,51 @@
           capability: tosca.capabilities.network.Bindable
           node: perimeta_ssc_a_server_0
           relationship: tosca.relationships.network.BindsTo
+    perimeta_ssc_a_untrusted_0_vlan_ports:
+      type: org.openecomp.resource.abstract.nodes.heat.vlan_subinterface_dual
+      directives:
+      - substitutable
+      properties:
+        perimeta_parent_interface: perimeta_ssc_a_untrusted_parent_0_port
+        perimeta_v6_vip_0:
+          get_input: ssc_untrusted_v6_vip_0
+        service_template_filter:
+          substitute_service_template: vlan_subinterface_dualServiceTemplate.yaml
+          count:
+            get_input: perimeta_untrusted_num_vlans
+          mandatory: false
+        perimeta_subinterface_name_prefix:
+          str_replace:
+            template: $VNF_NAME_$VM_untrusted_port_vlan
+            params:
+              $VM:
+                get_input: ssc_a_name_0
+              $VNF_NAME:
+                get_input: vnf_name
+        perimeta_vlan_networks:
+          get_input: perimeta_untrusted_vlan_networks
+        perimeta_subinterface_instance_index:
+          get_property:
+          - SELF
+          - service_template_filter
+          - index_value
+        perimeta_ip_0:
+          get_input: ssc_a_untrusted_ip_0
+        perimeta_vip_0:
+          get_input: ssc_untrusted_vip_0
+        perimeta_vlan_ids:
+          get_input: perimeta_untrusted_vlan_ids
+        perimeta_mac_address:
+          get_attribute:
+          - perimeta_ssc_a_untrusted_parent_0_port
+          - mac_address
+        perimeta_v6_ip_0:
+          get_input: ssc_a_untrusted_v6_ip_0
+      requirements:
+      - binding_contrail_vmi_subinterface:
+          capability: tosca.capabilities.network.Bindable
+          node: perimeta_ssc_a_untrusted_parent_0_port
+          relationship: tosca.relationships.network.BindsTo
     perimeta_ssc_a_trusted_0_port:
       type: org.openecomp.resource.cp.nodes.heat.network.neutron.Port
       properties:
@@ -458,6 +503,7 @@
       - perimeta_ssc_a_ha_0_port
       - perimeta_ssc_a_untrusted_parent_0_port
       - perimeta_ssc_a_mgmt_1_port
+      - perimeta_ssc_a_untrusted_0_vlan_ports
       - perimeta_ssc_a_trusted_0_port
       - perimeta_ssc_a_unused_0_port
       - perimeta_ssc_a_mgmt_0_port
@@ -540,6 +586,9 @@
       network.outgoing.packets.rate_perimeta_ssc_a_unused_0_port:
       - perimeta_ssc_a_unused_0_port
       - network.outgoing.packets.rate
+      feature_contrail_vmi_subinterface_perimeta_ssc_a_untrusted_0_vlan_ports:
+      - perimeta_ssc_a_untrusted_0_vlan_ports
+      - feature_contrail_vmi_subinterface
       feature_perimeta_ssc_a_mgmt_1_port:
       - perimeta_ssc_a_mgmt_1_port
       - feature
@@ -651,6 +700,9 @@
       network.incoming.packets_perimeta_ssc_a_mgmt_0_port:
       - perimeta_ssc_a_mgmt_0_port
       - network.incoming.packets
+      feature_perimeta_ssc_a_untrusted_0_vlan_ports:
+      - perimeta_ssc_a_untrusted_0_vlan_ports
+      - feature
       disk.device.latency_perimeta_ssc_a_server_0:
       - perimeta_ssc_a_server_0
       - disk.device.latency
@@ -811,6 +863,9 @@
       dependency_perimeta_ssc_a_mgmt_1_port:
       - perimeta_ssc_a_mgmt_1_port
       - dependency
+      dependency_contrail_vmi_subinterface_perimeta_ssc_a_untrusted_0_vlan_ports:
+      - perimeta_ssc_a_untrusted_0_vlan_ports
+      - dependency_contrail_vmi_subinterface
       dependency_perimeta_ssc_a_untrusted_parent_0_port:
       - perimeta_ssc_a_untrusted_parent_0_port
       - dependency
@@ -829,6 +884,9 @@
       dependency_perimeta_ssc_a_ha_0_port:
       - perimeta_ssc_a_ha_0_port
       - dependency
+      link_contrail_vmi_subinterface_perimeta_ssc_a_untrusted_0_vlan_ports:
+      - perimeta_ssc_a_untrusted_0_vlan_ports
+      - link_contrail_vmi_subinterface
       link_perimeta_ssc_a_mgmt_0_port:
       - perimeta_ssc_a_mgmt_0_port
       - link
@@ -844,6 +902,9 @@
       dependency_perimeta_ssc_a_mgmt_0_port:
       - perimeta_ssc_a_mgmt_0_port
       - dependency
+      dependency_perimeta_ssc_a_untrusted_0_vlan_ports:
+      - perimeta_ssc_a_untrusted_0_vlan_ports
+      - dependency
       dependency_perimeta_ssc_a_server_0:
       - perimeta_ssc_a_server_0
       - dependency
diff --git a/openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/src/test/resources/mock/heat/nested/nestedwithoutNodeTemplates/expectedoutputfiles/module_1_perimeta_swmu_b_childServiceTemplate.yaml b/openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/src/test/resources/mock/heat/nested/nestedwithoutNodeTemplates/expectedoutputfiles/module_1_perimeta_swmu_b_childServiceTemplate.yaml
index fffad89..74a843c 100644
--- a/openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/src/test/resources/mock/heat/nested/nestedwithoutNodeTemplates/expectedoutputfiles/module_1_perimeta_swmu_b_childServiceTemplate.yaml
+++ b/openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/src/test/resources/mock/heat/nested/nestedwithoutNodeTemplates/expectedoutputfiles/module_1_perimeta_swmu_b_childServiceTemplate.yaml
@@ -268,6 +268,51 @@
           capability: tosca.capabilities.network.Bindable
           node: perimeta_ssc_b_server_0
           relationship: tosca.relationships.network.BindsTo
+    perimeta_ssc_b_untrusted_0_vlan_ports:
+      type: org.openecomp.resource.abstract.nodes.heat.vlan_subinterface_dual
+      directives:
+      - substitutable
+      properties:
+        perimeta_parent_interface: perimeta_ssc_b_untrusted_parent_0_port
+        perimeta_v6_vip_0:
+          get_input: ssc_untrusted_v6_vip_0
+        service_template_filter:
+          substitute_service_template: vlan_subinterface_dualServiceTemplate.yaml
+          count:
+            get_input: perimeta_untrusted_num_vlans
+          mandatory: false
+        perimeta_subinterface_name_prefix:
+          str_replace:
+            template: $VNF_NAME_$VM_untrusted_port_vlan
+            params:
+              $VM:
+                get_input: ssc_b_name_0
+              $VNF_NAME:
+                get_input: vnf_name
+        perimeta_vlan_networks:
+          get_input: perimeta_untrusted_vlan_networks
+        perimeta_subinterface_instance_index:
+          get_property:
+          - SELF
+          - service_template_filter
+          - index_value
+        perimeta_ip_0:
+          get_input: ssc_b_untrusted_ip_0
+        perimeta_vip_0:
+          get_input: ssc_untrusted_vip_0
+        perimeta_vlan_ids:
+          get_input: perimeta_untrusted_vlan_ids
+        perimeta_mac_address:
+          get_attribute:
+          - perimeta_ssc_b_untrusted_parent_0_port
+          - mac_address
+        perimeta_v6_ip_0:
+          get_input: ssc_b_untrusted_v6_ip_0
+      requirements:
+      - binding_contrail_vmi_subinterface:
+          capability: tosca.capabilities.network.Bindable
+          node: perimeta_ssc_b_untrusted_parent_0_port
+          relationship: tosca.relationships.network.BindsTo
     perimeta_ssc_b_mgmt_1_port:
       type: org.openecomp.resource.cp.nodes.heat.network.neutron.Port
       properties:
@@ -443,6 +488,7 @@
       members:
       - perimeta_ssc_b_trusted_0_port
       - perimeta_ssc_b_untrusted_parent_0_port
+      - perimeta_ssc_b_untrusted_0_vlan_ports
       - perimeta_ssc_b_mgmt_1_port
       - perimeta_ssc_b_unused_0_port
       - perimeta_ssc_b_server_0
@@ -625,6 +671,9 @@
       forwarder_perimeta_ssc_b_ha_0_port:
       - perimeta_ssc_b_ha_0_port
       - forwarder
+      feature_perimeta_ssc_b_untrusted_0_vlan_ports:
+      - perimeta_ssc_b_untrusted_0_vlan_ports
+      - feature
       network.outgoing.bytes.rate_perimeta_ssc_b_mgmt_1_port:
       - perimeta_ssc_b_mgmt_1_port
       - network.outgoing.bytes.rate
@@ -748,6 +797,9 @@
       network.outgoing.bytes_perimeta_ssc_b_unused_0_port:
       - perimeta_ssc_b_unused_0_port
       - network.outgoing.bytes
+      feature_contrail_vmi_subinterface_perimeta_ssc_b_untrusted_0_vlan_ports:
+      - perimeta_ssc_b_untrusted_0_vlan_ports
+      - feature_contrail_vmi_subinterface
       network.outgoing.bytes.rate_perimeta_ssc_b_untrusted_parent_0_port:
       - perimeta_ssc_b_untrusted_parent_0_port
       - network.outgoing.bytes.rate
@@ -800,12 +852,18 @@
       dependency_perimeta_ssc_b_unused_0_port:
       - perimeta_ssc_b_unused_0_port
       - dependency
+      dependency_contrail_vmi_subinterface_perimeta_ssc_b_untrusted_0_vlan_ports:
+      - perimeta_ssc_b_untrusted_0_vlan_ports
+      - dependency_contrail_vmi_subinterface
       dependency_perimeta_ssc_b_ha_0_port:
       - perimeta_ssc_b_ha_0_port
       - dependency
       local_storage_perimeta_ssc_b_server_0:
       - perimeta_ssc_b_server_0
       - local_storage
+      link_contrail_vmi_subinterface_perimeta_ssc_b_untrusted_0_vlan_ports:
+      - perimeta_ssc_b_untrusted_0_vlan_ports
+      - link_contrail_vmi_subinterface
       link_perimeta_ssc_b_mgmt_0_port:
       - perimeta_ssc_b_mgmt_0_port
       - link
@@ -821,6 +879,9 @@
       link_perimeta_ssc_b_untrusted_parent_0_port:
       - perimeta_ssc_b_untrusted_parent_0_port
       - link
+      dependency_perimeta_ssc_b_untrusted_0_vlan_ports:
+      - perimeta_ssc_b_untrusted_0_vlan_ports
+      - dependency
       dependency_perimeta_ssc_b_server_0:
       - perimeta_ssc_b_server_0
       - dependency
diff --git a/openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/src/test/resources/mock/heat/nested/nestedwithoutNodeTemplates/expectedoutputfiles/module_2_perimeta_sw_a_childServiceTemplate.yaml b/openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/src/test/resources/mock/heat/nested/nestedwithoutNodeTemplates/expectedoutputfiles/module_2_perimeta_sw_a_childServiceTemplate.yaml
index 370cc8c..d5d91bb 100644
--- a/openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/src/test/resources/mock/heat/nested/nestedwithoutNodeTemplates/expectedoutputfiles/module_2_perimeta_sw_a_childServiceTemplate.yaml
+++ b/openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/src/test/resources/mock/heat/nested/nestedwithoutNodeTemplates/expectedoutputfiles/module_2_perimeta_sw_a_childServiceTemplate.yaml
@@ -223,6 +223,61 @@
       entry_schema:
         type: string
   node_templates:
+    perimeta_rtp_msc_a_untrusted_0_vlan_ports:
+      type: org.openecomp.resource.abstract.nodes.heat.vlan_subinterface_dual
+      directives:
+      - substitutable
+      properties:
+        perimeta_parent_interface: perimeta_rtp_msc_a_untrusted_parent_0_port
+        perimeta_v6_vip_0:
+          get_input:
+          - rtp_msc_untrusted_v6_vips
+          - get_input: perimeta_instance_index
+        service_template_filter:
+          substitute_service_template: vlan_subinterface_dualServiceTemplate.yaml
+          count:
+            get_input: perimeta_untrusted_num_vlans
+          mandatory: false
+        perimeta_subinterface_name_prefix:
+          str_replace:
+            template: $VNF_NAME_$VM_untrusted_port_vlan
+            params:
+              $VM:
+                get_input:
+                - rtp_msc_a_names
+                - get_input: perimeta_instance_index
+              $VNF_NAME:
+                get_input: vnf_name
+        perimeta_vlan_networks:
+          get_input: perimeta_untrusted_vlan_networks
+        perimeta_subinterface_instance_index:
+          get_property:
+          - SELF
+          - service_template_filter
+          - index_value
+        perimeta_ip_0:
+          get_input:
+          - rtp_msc_a_untrusted_ips
+          - get_input: perimeta_instance_index
+        perimeta_vip_0:
+          get_input:
+          - rtp_msc_untrusted_vips
+          - get_input: perimeta_instance_index
+        perimeta_vlan_ids:
+          get_input: perimeta_untrusted_vlan_ids
+        perimeta_mac_address:
+          get_attribute:
+          - perimeta_rtp_msc_a_untrusted_parent_0_port
+          - mac_address
+        perimeta_v6_ip_0:
+          get_input:
+          - rtp_msc_a_untrusted_v6_ips
+          - get_input: perimeta_instance_index
+      requirements:
+      - binding_contrail_vmi_subinterface:
+          capability: tosca.capabilities.network.Bindable
+          node: perimeta_rtp_msc_a_untrusted_parent_0_port
+          relationship: tosca.relationships.network.BindsTo
     perimeta_rtp_msc_a_trusted_0_port:
       type: org.openecomp.resource.cp.nodes.heat.network.neutron.Port
       properties:
@@ -439,6 +494,7 @@
         description: |
           HOT template to instantiate an A side Perimeta RTP MSC instance with 4 vNICs as part of a nested template
       members:
+      - perimeta_rtp_msc_a_untrusted_0_vlan_ports
       - perimeta_rtp_msc_a_trusted_0_port
       - perimeta_rtp_msc_a_ha_0_port
       - perimeta_rtp_msc_a_untrusted_parent_0_port
@@ -453,6 +509,9 @@
       disk.device.read.requests_perimeta_rtp_msc_a_server_0:
       - perimeta_rtp_msc_a_server_0
       - disk.device.read.requests
+      feature_perimeta_rtp_msc_a_untrusted_0_vlan_ports:
+      - perimeta_rtp_msc_a_untrusted_0_vlan_ports
+      - feature
       attachment_perimeta_rtp_msc_a_mgmt_0_port:
       - perimeta_rtp_msc_a_mgmt_0_port
       - attachment
@@ -558,6 +617,9 @@
       feature_perimeta_rtp_msc_a_untrusted_parent_0_port:
       - perimeta_rtp_msc_a_untrusted_parent_0_port
       - feature
+      feature_contrail_vmi_subinterface_perimeta_rtp_msc_a_untrusted_0_vlan_ports:
+      - perimeta_rtp_msc_a_untrusted_0_vlan_ports
+      - feature_contrail_vmi_subinterface
       disk.usage_perimeta_rtp_msc_a_server_0:
       - perimeta_rtp_msc_a_server_0
       - disk.usage
@@ -721,27 +783,36 @@
       local_storage_perimeta_rtp_msc_a_server_0:
       - perimeta_rtp_msc_a_server_0
       - local_storage
-      dependency_perimeta_rtp_msc_a_server_0:
-      - perimeta_rtp_msc_a_server_0
+      dependency_contrail_vmi_subinterface_perimeta_rtp_msc_a_untrusted_0_vlan_ports:
+      - perimeta_rtp_msc_a_untrusted_0_vlan_ports
+      - dependency_contrail_vmi_subinterface
+      dependency_perimeta_rtp_msc_a_untrusted_0_vlan_ports:
+      - perimeta_rtp_msc_a_untrusted_0_vlan_ports
       - dependency
       dependency_perimeta_rtp_msc_a_untrusted_parent_0_port:
       - perimeta_rtp_msc_a_untrusted_parent_0_port
       - dependency
-      dependency_perimeta_rtp_msc_a_trusted_0_port:
-      - perimeta_rtp_msc_a_trusted_0_port
-      - dependency
       dependency_perimeta_rtp_msc_a_ha_0_port:
       - perimeta_rtp_msc_a_ha_0_port
       - dependency
+      link_contrail_vmi_subinterface_perimeta_rtp_msc_a_untrusted_0_vlan_ports:
+      - perimeta_rtp_msc_a_untrusted_0_vlan_ports
+      - link_contrail_vmi_subinterface
+      link_perimeta_rtp_msc_a_untrusted_parent_0_port:
+      - perimeta_rtp_msc_a_untrusted_parent_0_port
+      - link
+      dependency_perimeta_rtp_msc_a_mgmt_0_port:
+      - perimeta_rtp_msc_a_mgmt_0_port
+      - dependency
+      dependency_perimeta_rtp_msc_a_server_0:
+      - perimeta_rtp_msc_a_server_0
+      - dependency
+      dependency_perimeta_rtp_msc_a_trusted_0_port:
+      - perimeta_rtp_msc_a_trusted_0_port
+      - dependency
       link_perimeta_rtp_msc_a_mgmt_0_port:
       - perimeta_rtp_msc_a_mgmt_0_port
       - link
       link_perimeta_rtp_msc_a_ha_0_port:
       - perimeta_rtp_msc_a_ha_0_port
       - link
-      link_perimeta_rtp_msc_a_untrusted_parent_0_port:
-      - perimeta_rtp_msc_a_untrusted_parent_0_port
-      - link
-      dependency_perimeta_rtp_msc_a_mgmt_0_port:
-      - perimeta_rtp_msc_a_mgmt_0_port
-      - dependency
diff --git a/openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/src/test/resources/mock/heat/nested/nestedwithoutNodeTemplates/expectedoutputfiles/module_2_perimeta_sw_b_childServiceTemplate.yaml b/openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/src/test/resources/mock/heat/nested/nestedwithoutNodeTemplates/expectedoutputfiles/module_2_perimeta_sw_b_childServiceTemplate.yaml
index 6b306a4..6aca484 100644
--- a/openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/src/test/resources/mock/heat/nested/nestedwithoutNodeTemplates/expectedoutputfiles/module_2_perimeta_sw_b_childServiceTemplate.yaml
+++ b/openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/src/test/resources/mock/heat/nested/nestedwithoutNodeTemplates/expectedoutputfiles/module_2_perimeta_sw_b_childServiceTemplate.yaml
@@ -302,6 +302,61 @@
           capability: tosca.capabilities.network.Bindable
           node: perimeta_rtp_msc_b_server_0
           relationship: tosca.relationships.network.BindsTo
+    perimeta_rtp_msc_b_untrusted_0_vlan_ports:
+      type: org.openecomp.resource.abstract.nodes.heat.vlan_subinterface_dual
+      directives:
+      - substitutable
+      properties:
+        perimeta_parent_interface: perimeta_rtp_msc_b_untrusted_parent_0_port
+        perimeta_v6_vip_0:
+          get_input:
+          - rtp_msc_untrusted_v6_vips
+          - get_input: perimeta_instance_index
+        service_template_filter:
+          substitute_service_template: vlan_subinterface_dualServiceTemplate.yaml
+          count:
+            get_input: perimeta_untrusted_num_vlans
+          mandatory: false
+        perimeta_subinterface_name_prefix:
+          str_replace:
+            template: $VNF_NAME_$VM_untrusted_port_vlan
+            params:
+              $VM:
+                get_input:
+                - rtp_msc_b_names
+                - get_input: perimeta_instance_index
+              $VNF_NAME:
+                get_input: vnf_name
+        perimeta_vlan_networks:
+          get_input: perimeta_untrusted_vlan_networks
+        perimeta_subinterface_instance_index:
+          get_property:
+          - SELF
+          - service_template_filter
+          - index_value
+        perimeta_ip_0:
+          get_input:
+          - rtp_msc_b_untrusted_ips
+          - get_input: perimeta_instance_index
+        perimeta_vip_0:
+          get_input:
+          - rtp_msc_untrusted_vips
+          - get_input: perimeta_instance_index
+        perimeta_vlan_ids:
+          get_input: perimeta_untrusted_vlan_ids
+        perimeta_mac_address:
+          get_attribute:
+          - perimeta_rtp_msc_b_untrusted_parent_0_port
+          - mac_address
+        perimeta_v6_ip_0:
+          get_input:
+          - rtp_msc_b_untrusted_v6_ips
+          - get_input: perimeta_instance_index
+      requirements:
+      - binding_contrail_vmi_subinterface:
+          capability: tosca.capabilities.network.Bindable
+          node: perimeta_rtp_msc_b_untrusted_parent_0_port
+          relationship: tosca.relationships.network.BindsTo
     perimeta_rtp_msc_b_server_0:
       type: org.openecomp.resource.vfc.nodes.heat.rtp_msc_b
       properties:
@@ -427,6 +482,7 @@
       members:
       - perimeta_rtp_msc_b_trusted_0_port
       - perimeta_rtp_msc_b_mgmt_0_port
+      - perimeta_rtp_msc_b_untrusted_0_vlan_ports
       - perimeta_rtp_msc_b_server_0
       - perimeta_rtp_msc_b_ha_0_port
       - perimeta_rtp_msc_b_untrusted_parent_0_port
@@ -493,6 +549,9 @@
       network.outgoing.bytes.rate_perimeta_rtp_msc_b_trusted_0_port:
       - perimeta_rtp_msc_b_trusted_0_port
       - network.outgoing.bytes.rate
+      feature_contrail_vmi_subinterface_perimeta_rtp_msc_b_untrusted_0_vlan_ports:
+      - perimeta_rtp_msc_b_untrusted_0_vlan_ports
+      - feature_contrail_vmi_subinterface
       attachment_perimeta_rtp_msc_b_ha_0_port:
       - perimeta_rtp_msc_b_ha_0_port
       - attachment
@@ -619,6 +678,9 @@
       disk.write.requests_perimeta_rtp_msc_b_server_0:
       - perimeta_rtp_msc_b_server_0
       - disk.write.requests
+      feature_perimeta_rtp_msc_b_untrusted_0_vlan_ports:
+      - perimeta_rtp_msc_b_untrusted_0_vlan_ports
+      - feature
       network.incoming.packets.rate_perimeta_rtp_msc_b_mgmt_0_port:
       - perimeta_rtp_msc_b_mgmt_0_port
       - network.incoming.packets.rate
@@ -701,18 +763,15 @@
       - perimeta_rtp_msc_b_server_0
       - disk.read.bytes.rate
     requirements:
-      link_perimeta_rtp_msc_b_trusted_0_port:
-      - perimeta_rtp_msc_b_trusted_0_port
-      - link
-      dependency_perimeta_rtp_msc_b_untrusted_parent_0_port:
-      - perimeta_rtp_msc_b_untrusted_parent_0_port
-      - dependency
-      link_perimeta_rtp_msc_b_ha_0_port:
-      - perimeta_rtp_msc_b_ha_0_port
-      - link
+      dependency_contrail_vmi_subinterface_perimeta_rtp_msc_b_untrusted_0_vlan_ports:
+      - perimeta_rtp_msc_b_untrusted_0_vlan_ports
+      - dependency_contrail_vmi_subinterface
       dependency_perimeta_rtp_msc_b_trusted_0_port:
       - perimeta_rtp_msc_b_trusted_0_port
       - dependency
+      dependency_perimeta_rtp_msc_b_untrusted_0_vlan_ports:
+      - perimeta_rtp_msc_b_untrusted_0_vlan_ports
+      - dependency
       dependency_perimeta_rtp_msc_b_ha_0_port:
       - perimeta_rtp_msc_b_ha_0_port
       - dependency
@@ -722,6 +781,18 @@
       dependency_perimeta_rtp_msc_b_mgmt_0_port:
       - perimeta_rtp_msc_b_mgmt_0_port
       - dependency
+      link_contrail_vmi_subinterface_perimeta_rtp_msc_b_untrusted_0_vlan_ports:
+      - perimeta_rtp_msc_b_untrusted_0_vlan_ports
+      - link_contrail_vmi_subinterface
+      link_perimeta_rtp_msc_b_trusted_0_port:
+      - perimeta_rtp_msc_b_trusted_0_port
+      - link
+      dependency_perimeta_rtp_msc_b_untrusted_parent_0_port:
+      - perimeta_rtp_msc_b_untrusted_parent_0_port
+      - dependency
+      link_perimeta_rtp_msc_b_ha_0_port:
+      - perimeta_rtp_msc_b_ha_0_port
+      - link
       local_storage_perimeta_rtp_msc_b_server_0:
       - perimeta_rtp_msc_b_server_0
       - local_storage
diff --git a/openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/src/test/resources/mock/heat/nested/nestedwithoutNodeTemplates/expectedoutputfiles/vlan_subinterface_dualServiceTemplate.yaml b/openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/src/test/resources/mock/heat/nested/nestedwithoutNodeTemplates/expectedoutputfiles/vlan_subinterface_dualServiceTemplate.yaml
new file mode 100644
index 0000000..d9cb24a
--- /dev/null
+++ b/openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/src/test/resources/mock/heat/nested/nestedwithoutNodeTemplates/expectedoutputfiles/vlan_subinterface_dualServiceTemplate.yaml
@@ -0,0 +1,137 @@
+tosca_definitions_version: tosca_simple_yaml_1_0_0
+metadata:
+  template_name: vlan_subinterface_dual
+imports:
+- openecomp_heat_index:
+    file: openecomp-heat/_index.yml
+- GlobalSubstitutionTypes:
+    file: GlobalSubstitutionTypesServiceTemplate.yaml
+topology_template:
+  inputs:
+    perimeta_parent_interface:
+      hidden: false
+      immutable: false
+      type: string
+      description: Parent Contrail interface
+    perimeta_v6_vip_0:
+      hidden: false
+      immutable: false
+      type: string
+      description: virtual IPv6 address associated with subinterfaces
+    perimeta_subinterface_name_prefix:
+      hidden: false
+      immutable: false
+      type: string
+      description: Combined with subinterface_instance_index, this is used as the name of the subinterface resource
+    perimeta_vlan_networks:
+      hidden: false
+      immutable: false
+      type: list
+      description: List of Contrail VLAN networks to use for the subinterfaces.   The order and number of these must match the VLAN ID list
+      entry_schema:
+        type: string
+    perimeta_subinterface_instance_index:
+      hidden: false
+      immutable: false
+      type: float
+      description: Index of instance among multiple instances.  Use to retrieve correct parameter for this instance when passed all parameters for all instances.
+      constraints:
+      - in_range:
+        - 1
+        - 1001
+    perimeta_ip_0:
+      hidden: false
+      immutable: false
+      type: string
+      description: IPv4 address associated with subinterfaces
+    perimeta_vip_0:
+      hidden: false
+      immutable: false
+      type: string
+      description: virtual IPv4 address associated with subinterfaces
+    perimeta_vlan_ids:
+      hidden: false
+      immutable: false
+      type: list
+      description: List of VLAN IDs to use for subinterfaces
+      entry_schema:
+        type: string
+    perimeta_mac_address:
+      hidden: false
+      immutable: false
+      type: string
+      description: MAC address to use for subinterface
+    perimeta_v6_ip_0:
+      hidden: false
+      immutable: false
+      type: string
+      description: IPv6 address associated with subinterfaces
+  node_templates:
+    contrail_vmi_subinterface:
+      type: org.openecomp.resource.cp.nodes.heat.network.contrailV2.VLANSubInterface
+      properties:
+        virtual_machine_interface_refs:
+        - get_input: perimeta_parent_interface
+        name:
+          str_replace:
+            template: $NAME_$VLAN
+            params:
+              $NAME:
+                get_input: perimeta_subinterface_name_prefix
+              $VLAN:
+                get_input:
+                - perimeta_vlan_ids
+                - get_input: perimeta_subinterface_instance_index
+        virtual_network_refs:
+        - get_input:
+          - perimeta_vlan_networks
+          - get_input: perimeta_subinterface_instance_index
+        virtual_machine_interface_properties:
+          sub_interface_vlan_tag:
+            get_input:
+            - perimeta_vlan_ids
+            - get_input: perimeta_subinterface_instance_index
+        virtual_machine_interface_allowed_address_pairs:
+          allowed_address_pair:
+          - address_mode: active-standby
+            ip:
+              ip_prefix:
+                get_input: perimeta_vip_0
+              ip_prefix_len: 32
+            mac:
+              get_input: perimeta_mac_address
+          - address_mode: active-standby
+            ip:
+              ip_prefix:
+                get_input: perimeta_v6_vip_0
+              ip_prefix_len: 128
+            mac:
+              get_input: perimeta_mac_address
+        virtual_machine_interface_mac_addresses:
+          mac_address:
+          - get_input: perimeta_mac_address
+  groups:
+    vlan_subinterface_dual_group:
+      type: org.openecomp.groups.heat.HeatStack
+      properties:
+        heat_file: ../Artifacts/vlan_subinterface_dual.yaml
+        description: |
+          HOT template to instantiate a single Contrail VLAN sub-interface with associated instance IP addresses and allowed address pairs
+      members:
+      - contrail_vmi_subinterface
+  substitution_mappings:
+    node_type: org.openecomp.resource.abstract.nodes.heat.vlan_subinterface_dual
+    capabilities:
+      feature_contrail_vmi_subinterface:
+      - contrail_vmi_subinterface
+      - feature
+    requirements:
+      binding_contrail_vmi_subinterface:
+      - contrail_vmi_subinterface
+      - binding
+      link_contrail_vmi_subinterface:
+      - contrail_vmi_subinterface
+      - link
+      dependency_contrail_vmi_subinterface:
+      - contrail_vmi_subinterface
+      - dependency
diff --git a/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-api/src/main/java/org/openecomp/core/validation/util/MessageContainerUtil.java b/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-api/src/main/java/org/openecomp/core/validation/util/MessageContainerUtil.java
index 8c78f49..aab8383 100644
--- a/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-api/src/main/java/org/openecomp/core/validation/util/MessageContainerUtil.java
+++ b/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-api/src/main/java/org/openecomp/core/validation/util/MessageContainerUtil.java
@@ -44,7 +44,7 @@
       return null;
     }
     Map<String, List<ErrorMessage>> filteredMessages = new HashMap<>();
-    messages.entrySet().stream().forEach(
+    messages.entrySet().forEach(
         entry -> entry.getValue().stream().filter(message -> message.getLevel().equals(level))
             .forEach(message -> addMessage(entry.getKey(), message, filteredMessages
             )));
@@ -53,11 +53,33 @@
 
   private static void addMessage(String fileName, ErrorMessage message,
                                  Map<String, List<ErrorMessage>> messages) {
-    List<ErrorMessage> messageList = messages.get(fileName);
-    if (messageList == null) {
-      messageList = new ArrayList<>();
-      messages.put(fileName, messageList);
-    }
+    List<ErrorMessage> messageList = messages.computeIfAbsent(fileName, k -> new ArrayList<>());
     messageList.add(message);
   }
+
+  public static String getErrorMessagesListAsString(Map<String, List<ErrorMessage>> messages) {
+    StringBuilder concatErrorMessage = new StringBuilder();
+
+    for (Map.Entry<String, List<ErrorMessage>> errorMessageEntry : messages.entrySet()) {
+      appendErrorMessageAsString(concatErrorMessage, errorMessageEntry.getKey(),
+          errorMessageEntry.getValue());
+    }
+    return concatErrorMessage.toString();
+  }
+
+  private static void appendErrorMessageAsString(StringBuilder concatErrorMessage,
+                                                 String fileName,
+                                                 List<ErrorMessage> errorMessageList) {
+    for (ErrorMessage errorMessage : errorMessageList) {
+      addErrorMessage(concatErrorMessage, fileName, errorMessage);
+    }
+  }
+
+  private static void addErrorMessage(StringBuilder concatErrorMessage,
+                                      String fileName,
+                                      ErrorMessage errorMessage) {
+    concatErrorMessage.append(fileName).append(" : ");
+    concatErrorMessage.append(errorMessage.getMessage());
+    concatErrorMessage.append("\n");
+  }
 }
diff --git a/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-api/src/resources/factoryConfiguration.json b/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-api/src/main/resources/factoryConfiguration.json
similarity index 100%
rename from openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-api/src/resources/factoryConfiguration.json
rename to openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-api/src/main/resources/factoryConfiguration.json
diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/datatypes/ToscaServiceModel.java b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/datatypes/ToscaServiceModel.java
index 4512fce..b1a0976 100644
--- a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/datatypes/ToscaServiceModel.java
+++ b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/datatypes/ToscaServiceModel.java
@@ -29,13 +29,13 @@
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Optional;
 
 /**
  * Tosca service model.
  */
 public class ToscaServiceModel implements AsdcModel {
   private FileContentHandler artifactFiles;
-  private FileContentHandler externalFiles;
   private Map<String, ServiceTemplate> serviceTemplates;
   private String entryDefinitionServiceTemplate;
 
@@ -57,16 +57,6 @@
     this.entryDefinitionServiceTemplate = entryDefinitionServiceTemplate;
   }
 
-  public ToscaServiceModel(FileContentHandler artifactFiles,
-                           FileContentHandler externalFiles,
-                           Map<String, ServiceTemplate> serviceTemplates,
-                           String entryDefinitionServiceTemplate) {
-    this.artifactFiles = artifactFiles;
-    this.externalFiles = externalFiles;
-    this.serviceTemplates = serviceTemplates;
-    this.entryDefinitionServiceTemplate = entryDefinitionServiceTemplate;
-  }
-
   /**
    * Gets artifact files.
    *
@@ -89,6 +79,11 @@
     return Collections.unmodifiableMap(serviceTemplates);
   }
 
+  public Optional<ServiceTemplate> getServiceTemplate(String serviceTemplateName) {
+    return MapUtils.isEmpty(this.serviceTemplates) ? Optional.empty()
+        : Optional.of(this.serviceTemplates.get(serviceTemplateName));
+  }
+
   public void addServiceTemplate(String serviceTemplateName,
                                  ServiceTemplate serviceTemplate) {
     if(MapUtils.isEmpty(serviceTemplates)){