Rename packages from openecomp to onap.
[sdc.git] / openecomp-be / lib / openecomp-sdc-translator-lib / openecomp-sdc-translator-core / src / main / java / org / openecomp / sdc / translator / services / heattotosca / ConsolidationService.java
index d3f2a72..7f3ab73 100644 (file)
@@ -1,14 +1,35 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package org.openecomp.sdc.translator.services.heattotosca;
 
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.ListMultimap;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.MapUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.openecomp.sdc.common.errors.CoreException;
-import org.openecomp.sdc.common.errors.ErrorCode;
-import org.openecomp.sdc.logging.context.impl.MdcDataDebugMessage;
-import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
-import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate;
+import org.openecomp.sdc.tosca.datatypes.ToscaNodeType;
+import org.onap.sdc.tosca.datatypes.model.NodeTemplate;
+import org.onap.sdc.tosca.datatypes.model.ServiceTemplate;
+import org.openecomp.sdc.tosca.services.DataModelUtil;
+import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
 import org.openecomp.sdc.tosca.services.ToscaConstants;
 import org.openecomp.sdc.tosca.services.ToscaUtil;
+import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl;
 import org.openecomp.sdc.translator.datatypes.heattotosca.TranslationContext;
 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.composition.UnifiedCompositionData;
 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.composition.UnifiedCompositionEntity;
@@ -20,9 +41,11 @@ import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolida
 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.FileNestedConsolidationData;
 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.FilePortConsolidationData;
 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.GetAttrFuncData;
+import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.NestedConsolidationData;
 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.NestedTemplateConsolidationData;
 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.PortTemplateConsolidationData;
 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.RequirementAssignmentData;
+import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.SubInterfaceTemplateConsolidationData;
 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.TypeComputeConsolidationData;
 import org.openecomp.sdc.translator.services.heattotosca.errors.DuplicateResourceIdsInDifferentFilesErrorBuilder;
 
@@ -31,14 +54,17 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
 
 public class ConsolidationService {
 
-  private MdcDataDebugMessage mdcDataDebugMessage = new MdcDataDebugMessage();
   private UnifiedCompositionService unifiedCompositionService;
 
   public ConsolidationService(UnifiedCompositionService unifiedCompositionService) {
@@ -74,7 +100,7 @@ public class ConsolidationService {
       if (preConditionResult) {
         boolean consolidationRuleCheckResult =
             checkConsolidationRules(serviceTemplate, typeComputeConsolidationData,
-                consolidationData, translationContext);
+                consolidationData);
 
         unifiedCompositionService.createUnifiedComposition(
             serviceTemplate, null, unifiedCompositionDataList,
@@ -91,8 +117,8 @@ public class ConsolidationService {
 
   }
 
-  public static Map<String, String> getConsolidationEntityIdToType(ServiceTemplate serviceTemplate,
-                                                             ConsolidationData consolidationData) {
+  static Map<String, String> getConsolidationEntityIdToType(ServiceTemplate serviceTemplate,
+                                                            ConsolidationData consolidationData) {
     Map<String, String> consolidationEntityIdToType = new HashMap<>();
 
     String serviceTemplateFileName = ToscaUtil.getServiceTemplateFileName(serviceTemplate);
@@ -102,11 +128,11 @@ public class ConsolidationService {
     FilePortConsolidationData filePortConsolidationData =
         consolidationData.getPortConsolidationData()
             .getFilePortConsolidationData(serviceTemplateFileName);
-    if(Objects.nonNull(fileComputeConsolidationData)) {
+    if (Objects.nonNull(fileComputeConsolidationData)) {
       for (String computeType : fileComputeConsolidationData.getAllComputeTypes()) {
         TypeComputeConsolidationData typeComputeConsolidationData =
             fileComputeConsolidationData.getTypeComputeConsolidationData(computeType);
-        Set<String> computeNodeTemplateIds =
+        Collection<String> computeNodeTemplateIds =
             typeComputeConsolidationData.getAllComputeNodeTemplateIds();
         for (String computeNodeTemplateId : computeNodeTemplateIds) {
           consolidationEntityIdToType.put(computeNodeTemplateId, computeType);
@@ -114,7 +140,7 @@ public class ConsolidationService {
       }
     }
 
-    if(Objects.nonNull(filePortConsolidationData)) {
+    if (Objects.nonNull(filePortConsolidationData)) {
       Set<String> portNodeTemplateIds = filePortConsolidationData.getAllPortNodeTemplateIds();
       for (String portNodeTemplateId : portNodeTemplateIds) {
         consolidationEntityIdToType
@@ -128,11 +154,10 @@ public class ConsolidationService {
 
   private boolean checkConsolidationRules(ServiceTemplate serviceTemplate,
                                           TypeComputeConsolidationData typeComputeConsolidationData,
-                                          ConsolidationData consolidationData,
-                                          TranslationContext context) {
+                                          ConsolidationData consolidationData) {
     return checkComputeConsolidation(serviceTemplate, typeComputeConsolidationData)
         && checkPortConsolidation(serviceTemplate, typeComputeConsolidationData,
-        consolidationData, context)
+        consolidationData)
         && !checkGetAttrBetweenEntityConsolidationOfTheSameType(serviceTemplate,
         typeComputeConsolidationData, consolidationData);
   }
@@ -141,13 +166,13 @@ public class ConsolidationService {
       ServiceTemplate serviceTemplate,
       TypeComputeConsolidationData typeComputeConsolidationData,
       ConsolidationData consolidationData) {
-    List<ComputeTemplateConsolidationData> computeTemplateConsolidationDataList =
-        new ArrayList(typeComputeConsolidationData.getAllComputeTemplateConsolidationData());
+    Collection<ComputeTemplateConsolidationData> computeTemplateConsolidationDataList =
+        typeComputeConsolidationData.getAllComputeTemplateConsolidationData();
 
-    Set<String> computeNodeTemplateIds =
+    Collection<String> computeNodeTemplateIds =
         typeComputeConsolidationData.getAllComputeNodeTemplateIds();
 
-    Map<String, Set<String>> portTypeToIds = UnifiedCompositionUtil
+    Map<String, List<String>> portTypeToIds = UnifiedCompositionUtil
         .collectAllPortsFromEachTypesFromComputes(computeTemplateConsolidationDataList);
 
     return
@@ -157,72 +182,18 @@ public class ConsolidationService {
 
   }
 
-  private boolean checkGetAttrInEntityConsolidationWithPortIsLegal(
-      List entityConsolidationDatas,
-      TypeComputeConsolidationData typeComputeConsolidationData) {
-    Map<String, Set<String>> portTypeToIds =
-        UnifiedCompositionUtil.collectAllPortsFromEachTypesFromComputes(
-            typeComputeConsolidationData.getAllComputeTemplateConsolidationData());
-
-    Set<String> startingPortTypesPointByGetAttr =
-        getPortTypesPointedByGetAttrFromEntity(
-            (EntityConsolidationData) entityConsolidationDatas.get(0), portTypeToIds);
-
-    for (int i = 1; i < entityConsolidationDatas.size(); i++) {
-      Set<String> currentPortTypesPointByGetAttr =
-          getPortTypesPointedByGetAttrFromEntity(
-              (EntityConsolidationData) entityConsolidationDatas.get(i), portTypeToIds);
-      if (!startingPortTypesPointByGetAttr.equals(currentPortTypesPointByGetAttr)) {
-        return false;
-      }
-    }
-
-    return true;
-  }
-
-  private Set<String> getPortTypesPointedByGetAttrFromEntity(
-      EntityConsolidationData entity,
-      Map<String, Set<String>> portTypeToIds) {
-    return getPortTypeToIdPointByGetAttrInOrOut(
-        entity.getNodesGetAttrIn(), portTypeToIds, entity).keySet();
-  }
-
-  private boolean checkGetAttrInToPortIsLegal(
-      ServiceTemplate serviceTemplate,
-      TypeComputeConsolidationData typeComputeConsolidationData,
-      ConsolidationData consolidationData) {
-
-    Map<String, Set<String>> portTypeToIds = UnifiedCompositionUtil
-        .collectAllPortsFromEachTypesFromComputes(
-            typeComputeConsolidationData.getAllComputeTemplateConsolidationData());
-
-    for (Set<String> portIdsFromSameType : portTypeToIds.values()) {
-      List<PortTemplateConsolidationData> portTemplateConsolidationDataList =
-          collectAllPortsTemplateConsolidationData(
-              portIdsFromSameType, ToscaUtil.getServiceTemplateFileName(serviceTemplate),
-              consolidationData);
-
-      if (!checkGetAttrInEntityConsolidationWithPortIsLegal(
-          portTemplateConsolidationDataList, typeComputeConsolidationData)) {
-        return false;
-      }
-    }
-
-    return true;
-  }
-
-
   private boolean checkGetAttrOutFromPortLegal(String serviceTemplateName,
-                                               Set<String> computeNodeTemplateIds,
-                                               Map<String, Set<String>> portTypeToIds,
+                                               Collection<String> computeNodeTemplateIds,
+                                               Map<String, List<String>> portTypeToIds,
                                                ConsolidationData consolidationData) {
-    for (Set<String> portIdsFromSameType : portTypeToIds.values()) {
+    for (List<String> portIdsFromSameType : portTypeToIds.values()) {
       List<PortTemplateConsolidationData> portTemplateConsolidationDataList =
           collectAllPortsTemplateConsolidationData(portIdsFromSameType, serviceTemplateName,
               consolidationData);
 
       if (!(checkGetAttrOutFromEntityToPortIsLegal(portTemplateConsolidationDataList, portTypeToIds)
-          && checkGetAttrOutFromPortToComputeIsLegal(portTemplateConsolidationDataList,
+          && checkGetAttrOutFromConsolidationEntityToEntityNotFromSameTypeIsLegal(
+          portTemplateConsolidationDataList,
           computeNodeTemplateIds))) {
         return false;
       }
@@ -231,18 +202,20 @@ public class ConsolidationService {
     return true;
   }
 
-  private boolean checkGetAttrOutFromEntityToPortIsLegal(List entityConsolidationDataList,
-                                                         Map<String, Set<String>> portTypeToIds) {
+  private boolean checkGetAttrOutFromEntityToPortIsLegal(Collection entities,
+                                                         Map<String, List<String>> portTypeToIds) {
 
     for (String portType : portTypeToIds.keySet()) {
+      if (CollectionUtils.isEmpty(entities)) {
+        continue;
+      }
       Set<GetAttrFuncData> startingGetAttrFunc =
           getEntityGetAttrFuncAsSet(portType,
-              (EntityConsolidationData) entityConsolidationDataList.get(0));
-      for (int i = 1; i < entityConsolidationDataList.size(); i++) {
-        Object entity = entityConsolidationDataList.get(i);
+              (EntityConsolidationData) entities.iterator().next());
+      for (Object entity : entities) {
+        EntityConsolidationData currentEntity = (EntityConsolidationData) entity;
         Set<GetAttrFuncData> currentGetAttrFuncData =
-            getEntityGetAttrFuncAsSet(portType,
-                (EntityConsolidationData) entity);
+            getEntityGetAttrFuncAsSet(portType, currentEntity);
         if (!(startingGetAttrFunc.equals(currentGetAttrFuncData))) {
           return false;
         }
@@ -252,24 +225,27 @@ public class ConsolidationService {
     return true;
   }
 
-  private boolean checkGetAttrOutFromPortToComputeIsLegal(
-      List<PortTemplateConsolidationData> portTemplateConsolidationDataList,
-      Set<String> computeNodeTemplateIds) {
-    PortTemplateConsolidationData startingPortTemplate =
-        portTemplateConsolidationDataList.get(0);
-    Map<String, Set<GetAttrFuncData>> startingComputeGetAttrOutFuncData =
-        getComputeGetAttrOutFuncData(startingPortTemplate.getNodesGetAttrOut(),
-            computeNodeTemplateIds);
-
-    for (int i = 1; i < portTemplateConsolidationDataList.size(); i++) {
-      PortTemplateConsolidationData currentPortTemplate =
-          portTemplateConsolidationDataList.get(i);
-      Map<String, Set<GetAttrFuncData>> currentComputeGetAttrOutFuncData =
-          getComputeGetAttrOutFuncData(currentPortTemplate.getNodesGetAttrOut(),
-              computeNodeTemplateIds);
-
-      if (!isGetAttrRelationToComputeSimilarBetweenEntities(startingComputeGetAttrOutFuncData,
-          currentComputeGetAttrOutFuncData)) {
+  private boolean checkGetAttrOutFromConsolidationEntityToEntityNotFromSameTypeIsLegal(
+      List entityConsolidationDataList,
+      Collection<String> consolidationEntityNodeTemplateIds) {
+    if (CollectionUtils.isEmpty(entityConsolidationDataList)) {
+      return true;
+    }
+    EntityConsolidationData startingEntityTemplate =
+        (EntityConsolidationData) entityConsolidationDataList.get(0);
+    Map<String, Set<GetAttrFuncData>> startingGetAttrOutFuncData =
+        getConsolidationEntityGetAttrOutFuncData(startingEntityTemplate.getNodesGetAttrOut(),
+            consolidationEntityNodeTemplateIds);
+
+    for (int i = 1; i < entityConsolidationDataList.size(); i++) {
+      EntityConsolidationData currentEntityTemplate =
+          (EntityConsolidationData) entityConsolidationDataList.get(i);
+      Map<String, Set<GetAttrFuncData>> currentGetAttrOutFuncData =
+          getConsolidationEntityGetAttrOutFuncData(currentEntityTemplate.getNodesGetAttrOut(),
+              consolidationEntityNodeTemplateIds);
+
+      if (!isGetAttrRelationToEntitySimilarBetweenEntities(startingGetAttrOutFuncData,
+          currentGetAttrOutFuncData)) {
         return false;
       }
     }
@@ -277,20 +253,102 @@ public class ConsolidationService {
     return true;
   }
 
-  private boolean isGetAttrRelationToComputeSimilarBetweenEntities(
+  private boolean isGetAttrRelationToEntitySimilarBetweenEntities(
       Map<String, Set<GetAttrFuncData>> firstMap,
       Map<String, Set<GetAttrFuncData>> secondMap) {
     if (MapUtils.isEmpty(firstMap) != MapUtils.isEmpty(secondMap)) {
       return false;
     }
 
-    if (MapUtils.isEmpty(firstMap) && MapUtils.isEmpty(secondMap)) {
+    return (MapUtils.isEmpty(firstMap) && MapUtils.isEmpty(secondMap)) ||
+        (new ArrayList<>(firstMap.values()).equals(new ArrayList<>(secondMap.values())));
+
+  }
+
+  private boolean checkSubInterfaceConsolidationPreCondition(ServiceTemplate serviceTemplate,
+                                                             ConsolidationData consolidationData,
+                                                             TypeComputeConsolidationData typeComputeConsolidationData) {
+    FilePortConsolidationData filePortConsolidationData =
+        consolidationData.getPortConsolidationData()
+            .getFilePortConsolidationData(ToscaUtil.getServiceTemplateFileName(serviceTemplate));
+
+    if (Objects.isNull(filePortConsolidationData)) {
       return true;
     }
 
-    return new ArrayList<>(firstMap.values()).equals(new ArrayList<>(secondMap.values()));
+    Map<String, List<String>> portTypeToPortIds = UnifiedCompositionUtil
+        .collectAllPortsFromEachTypesFromComputes(
+            typeComputeConsolidationData.getAllComputeTemplateConsolidationData());
+
+    Collection<String> computeNodeTemplateIds =
+        typeComputeConsolidationData.getAllComputeNodeTemplateIds();
+
+    for (List<String> portIdsFromSameType : portTypeToPortIds.values()) {
+      List<PortTemplateConsolidationData> portTemplateConsolidationDataList =
+          getAllPortTemplateConsolidationData(portIdsFromSameType, filePortConsolidationData);
+
+      if (!areSubInterfacePreConditionRulesValid(portTypeToPortIds, computeNodeTemplateIds,
+          portTemplateConsolidationDataList, portTemplateConsolidationDataList.get(0))) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  private boolean areSubInterfacePreConditionRulesValid(Map<String, List<String>> portTypeToPortIds,
+                                                        Collection<String> computeNodeTemplateIds,
+                                                        List<PortTemplateConsolidationData> portTemplateConsolidationDataList,
+                                                         PortTemplateConsolidationData subInterfaceConsolidationData) {
+    return areSubInterfaceTypesSimilarBetweenPorts(portTemplateConsolidationDataList,
+        subInterfaceConsolidationData)
+        && isNumberOfSubInterfacesPerTypeSimilar(portTemplateConsolidationDataList,
+        subInterfaceConsolidationData)
+        && isGetAttrFromSubInterfaceToOtherEntitiesLegal(computeNodeTemplateIds,
+        portTypeToPortIds, portTemplateConsolidationDataList);
+  }
+
+  private boolean isGetAttrFromSubInterfaceToOtherEntitiesLegal(
+      Collection<String> computeNodeTemplateIds,
+      Map<String, List<String>> portTypeToPortIds,
+      List<PortTemplateConsolidationData> portTemplateConsolidationDataList) {
+
+    ListMultimap<String, SubInterfaceTemplateConsolidationData> subInterfacesFromSameTypeFromPorts =
+        collectAllSubInterfacesFromSameTypeFromPorts(portTemplateConsolidationDataList);
+
+    List<SubInterfaceTemplateConsolidationData> subInterfaceList = new ArrayList<>(subInterfacesFromSameTypeFromPorts
+        .values());
+    return areGetAttrRelationshipsBetweenSubInterfaceToConsolidationEntitiesValid(
+        computeNodeTemplateIds, portTypeToPortIds, portTemplateConsolidationDataList, subInterfaceList);
+  }
+
+  private boolean areGetAttrRelationshipsBetweenSubInterfaceToConsolidationEntitiesValid(
+      Collection<String> computeNodeTemplateIds, Map<String, List<String>> portTypeToPortIds,
+      List<PortTemplateConsolidationData> portTemplateConsolidationDataList,
+      List<SubInterfaceTemplateConsolidationData> subInterfaceList) {
+    return checkGetAttrOutFromEntityToPortIsLegal(subInterfaceList, portTypeToPortIds)
+        && checkGetAttrOutFromConsolidationEntityToEntityNotFromSameTypeIsLegal(
+        portTemplateConsolidationDataList, getSubInterfaceIdsFromSameType(subInterfaceList))
+        && checkGetAttrOutFromConsolidationEntityToEntityNotFromSameTypeIsLegal(
+        subInterfaceList, computeNodeTemplateIds);
+  }
+
+  private boolean areSubInterfaceTypesSimilarBetweenPorts(
+      List<PortTemplateConsolidationData> portTemplateConsolidationDataList,
+      PortTemplateConsolidationData subInterfaceConsolidationData) {
+
+    return portTemplateConsolidationDataList.stream().allMatch(
+        element -> element.hasSameSubInterfaceTypes(subInterfaceConsolidationData));
   }
 
+  private boolean isNumberOfSubInterfacesPerTypeSimilar(
+      List<PortTemplateConsolidationData> portTemplateConsolidationDataList,
+      PortTemplateConsolidationData subInterfaceConsolidationData) {
+
+    return portTemplateConsolidationDataList.stream()
+        .allMatch(element -> element.isNumberOfSubInterfacesPerTypeSimilar(subInterfaceConsolidationData));
+  }
+
+
   private Set<GetAttrFuncData> getEntityGetAttrFuncAsSet(
       String portType,
       EntityConsolidationData entityConsolidationData) {
@@ -312,9 +370,9 @@ public class ConsolidationService {
     return getAttrFuncDataFromPortsWithSameType;
   }
 
-  private Map<String, Set<GetAttrFuncData>> getComputeGetAttrOutFuncData(
+  private Map<String, Set<GetAttrFuncData>> getConsolidationEntityGetAttrOutFuncData(
       Map<String, List<GetAttrFuncData>> nodesGetAttrOut,
-      Set<String> computeNodeTemplateIds) {
+      Collection<String> computeNodeTemplateIds) {
     Map<String, Set<GetAttrFuncData>> computeGetAttrFuncData = new HashMap<>();
 
     if (MapUtils.isEmpty(nodesGetAttrOut)) {
@@ -331,76 +389,48 @@ public class ConsolidationService {
     return computeGetAttrFuncData;
   }
 
-  private Map<String, List<String>> getPortTypeToIdPointByGetAttrInOrOut(
-      Map<String, List<GetAttrFuncData>> getAttr,
-      Map<String, Set<String>> portTypeToIds,
-      EntityConsolidationData entityConsolidationData) {
-    Map<String, List<String>> portIdToType = new HashMap<>();
-
-    if (MapUtils.isEmpty(getAttr)) {
-      return portIdToType;
-    }
-
-    for (String getAttrId : getAttr.keySet()) {
-      if (isNodeTemplateIdIsInComputeConsolidationData(getAttrId, portTypeToIds)) {
-        String portType = ConsolidationDataUtil.getPortType(getAttrId);
-        portIdToType.putIfAbsent(portType, new ArrayList<>());
-        portIdToType.get(portType).add(getAttrId);
-      }
-    }
-
-    return portIdToType;
-
-  }
-
-
-  private boolean isNodeTemplateIdIsInComputeConsolidationData(
-      String getAttrInId,
-      Map<String, Set<String>> portTypeToIds) {
-    return portTypeToIds.keySet().contains(ConsolidationDataUtil.getPortType(getAttrInId));
-  }
-
   private boolean checkGetAttrBetweenEntityConsolidationOfTheSameType(
       ServiceTemplate serviceTemplate,
       TypeComputeConsolidationData typeComputeConsolidationData,
       ConsolidationData consolidationData) {
-    return checkGetAttrRelationsBetweenComputesOfSameType(typeComputeConsolidationData)
-        || checkGetAttrRelationsBetweenPortsOfTheSameType(serviceTemplate,
+    return areThereGetAttrRelationsBetweenComputesOfSameType(typeComputeConsolidationData)
+        || areThereGetAttrRelationsBetweenPortsOfTheSameType(serviceTemplate,
         typeComputeConsolidationData, consolidationData);
 
   }
 
-  private boolean checkGetAttrRelationsBetweenComputesOfSameType(
+  private boolean areThereGetAttrRelationsBetweenComputesOfSameType(
       TypeComputeConsolidationData typeComputeConsolidationData) {
 
-    Collection<ComputeTemplateConsolidationData> computeTemplateConsolidationDatas =
+    Collection<ComputeTemplateConsolidationData> computeTemplateConsolidationEntities =
         typeComputeConsolidationData.getAllComputeTemplateConsolidationData();
-    Set<String> computeNodeTemplateIds =
+    Collection<String> computeNodeTemplateIds =
         typeComputeConsolidationData.getAllComputeNodeTemplateIds();
 
     return checkGetAttrRelationsForEntityConsolidationData(
-        computeTemplateConsolidationDatas, computeNodeTemplateIds);
+        computeTemplateConsolidationEntities, computeNodeTemplateIds,
+        EntityConsolidationData::getNodesGetAttrIn);
   }
 
-  private boolean checkGetAttrRelationsBetweenPortsOfTheSameType(
+  private boolean areThereGetAttrRelationsBetweenPortsOfTheSameType(
       ServiceTemplate serviceTemplate,
       TypeComputeConsolidationData typeComputeConsolidationData,
       ConsolidationData consolidationData) {
 
-    Collection<ComputeTemplateConsolidationData> computeTemplateConsolidationDatas =
+    Collection<ComputeTemplateConsolidationData> computeTemplateConsolidationEntities =
         typeComputeConsolidationData.getAllComputeTemplateConsolidationData();
-    Map<String, Set<String>> portTypeToPortIds = UnifiedCompositionUtil
-        .collectAllPortsFromEachTypesFromComputes(computeTemplateConsolidationDatas);
+    Map<String, List<String>> portTypeToPortIds = UnifiedCompositionUtil
+        .collectAllPortsFromEachTypesFromComputes(computeTemplateConsolidationEntities);
 
     FilePortConsolidationData filePortConsolidationData =
         consolidationData.getPortConsolidationData().getFilePortConsolidationData(ToscaUtil
             .getServiceTemplateFileName(serviceTemplate));
 
-    for (Set<String> portsOfTheSameTypeIds : portTypeToPortIds.values()) {
+    for (List<String> portsOfTheSameTypeIds : portTypeToPortIds.values()) {
       List<PortTemplateConsolidationData> portTemplateConsolidationDataOfSameType =
           getAllPortTemplateConsolidationData(portsOfTheSameTypeIds, filePortConsolidationData);
       if (!checkGetAttrRelationsForEntityConsolidationData(portTemplateConsolidationDataOfSameType,
-          portsOfTheSameTypeIds)) {
+          portsOfTheSameTypeIds, EntityConsolidationData::getNodesGetAttrIn)) {
         return false;
       }
     }
@@ -408,8 +438,19 @@ public class ConsolidationService {
     return true;
   }
 
+  private boolean areThereGetAttrRelationsBetweenSubInterfacesOfSameType(
+      List<String> subInterfacesIdsFromSameType,
+      List<SubInterfaceTemplateConsolidationData> subInterfaceList) {
+
+    return checkGetAttrRelationsForEntityConsolidationData(subInterfaceList,
+        subInterfacesIdsFromSameType, EntityConsolidationData::getNodesGetAttrIn)
+        || checkGetAttrRelationsForEntityConsolidationData(subInterfaceList,
+        subInterfacesIdsFromSameType, EntityConsolidationData::getNodesGetAttrOut);
+
+  }
+
   private List<PortTemplateConsolidationData> getAllPortTemplateConsolidationData(
-      Set<String> portsIds,
+      List<String> portsIds,
       FilePortConsolidationData filePortConsolidationData) {
     List<PortTemplateConsolidationData> portTemplateConsolidationDataOfSameType = new ArrayList<>();
 
@@ -424,24 +465,19 @@ public class ConsolidationService {
     return portTemplateConsolidationDataOfSameType;
   }
 
-  private boolean checkGetAttrRelationsForEntityConsolidationData(
-      Collection entities,
-      Set<String> nodeTemplateIdsOfTheSameType) {
-
-    List<EntityConsolidationData> entityConsolidationDataList =
-        new ArrayList(entities);
-
-    for (EntityConsolidationData entityConsolidationData : entityConsolidationDataList) {
-      Set<String> getAttrInNodeIds =
-          entityConsolidationData.getNodesGetAttrIn() == null ? new HashSet<>()
-              : entityConsolidationData.getNodesGetAttrIn().keySet();
-      for (String nodeId : getAttrInNodeIds) {
-        if (nodeTemplateIdsOfTheSameType.contains(nodeId)) {
-          return true;
-        }
+  private boolean checkGetAttrRelationsForEntityConsolidationData(Collection entities,
+                                                                  Collection<String> nodeTemplateIdsOfTheSameType,
+                                                                  Function<EntityConsolidationData, Map<String, List<GetAttrFuncData>>> getAttrValuesMethod) {
+    for (Object entity : entities) {
+      Map<String, List<GetAttrFuncData>> getAttrValue =
+          getAttrValuesMethod.apply((EntityConsolidationData) entity);
+      Set<String> getAttrNodeIds =
+          getAttrValue == null ? new HashSet<>()
+              : getAttrValue.keySet();
+      if (getAttrNodeIds.stream().anyMatch(nodeTemplateIdsOfTheSameType::contains)) {
+        return true;
       }
     }
-
     return false;
   }
 
@@ -449,31 +485,29 @@ public class ConsolidationService {
   private boolean checkComputeConsolidation(
       ServiceTemplate serviceTemplate,
       TypeComputeConsolidationData typeComputeConsolidationData) {
-    List<String> computeNodeTemplateIds =
-        new ArrayList(typeComputeConsolidationData.getAllComputeNodeTemplateIds());
+    Collection<String> computeNodeTemplateIds =
+        typeComputeConsolidationData.getAllComputeNodeTemplateIds();
     List<String> propertiesWithIdenticalVal = getComputePropertiesWithIdenticalVal();
 
-    return arePropertiesSimilarBetweenComputeNodeTemplates(
-        serviceTemplate, computeNodeTemplateIds, propertiesWithIdenticalVal)
+    return arePropertiesSimilarBetweenComputeNodeTemplates(serviceTemplate, computeNodeTemplateIds,
+        propertiesWithIdenticalVal)
         && checkComputeRelations(
         typeComputeConsolidationData.getAllComputeTemplateConsolidationData());
   }
 
 
   private boolean checkComputeRelations(
-      Collection<ComputeTemplateConsolidationData> computeTemplateConsolidationDatas) {
+      Collection<ComputeTemplateConsolidationData> computeTemplateConsolidationEntities) {
 
-    return checkEntityConsolidationDataRelations(computeTemplateConsolidationDatas)
-        && checkComputesRelationsToVolume(computeTemplateConsolidationDatas);
+    return checkEntityConsolidationDataRelations(computeTemplateConsolidationEntities)
+        && checkComputesRelationsToVolume(computeTemplateConsolidationEntities);
   }
 
   private boolean checkEntityConsolidationDataRelations(Collection entities) {
-    List<EntityConsolidationData> entityConsolidationDataList =
-        new ArrayList(entities);
-    EntityConsolidationData startingEntity = entityConsolidationDataList.get(0);
+    EntityConsolidationData startingEntity = (EntityConsolidationData) entities.iterator().next();
 
-    for (int i = 1; i < entityConsolidationDataList.size(); i++) {
-      EntityConsolidationData currentEntity = entityConsolidationDataList.get(i);
+    for (Object entity : entities) {
+      EntityConsolidationData currentEntity = (EntityConsolidationData) entity;
       if (!(checkNodesConnectedInRelations(startingEntity, currentEntity)
           && (checkNodesConnectedOutRelations(startingEntity, currentEntity))
           && (checkGroupIdsRelations(startingEntity, currentEntity)))) {
@@ -498,40 +532,34 @@ public class ConsolidationService {
   private boolean compareNodeConnectivity(
       Map<String, List<RequirementAssignmentData>> firstEntityMap,
       Map<String, List<RequirementAssignmentData>> secondEntityMap) {
+
     if (MapUtils.isEmpty(firstEntityMap)
         && MapUtils.isEmpty(secondEntityMap)) {
       return true;
     }
-    if (!MapUtils.isEmpty(firstEntityMap)
-        && !MapUtils.isEmpty(secondEntityMap)) {
-      return firstEntityMap.keySet().equals(secondEntityMap.keySet());
-    }
-    return false;
+    return !MapUtils.isEmpty(firstEntityMap) && !MapUtils.isEmpty(secondEntityMap)
+        && firstEntityMap.keySet().equals(secondEntityMap.keySet());
   }
 
   private boolean checkGroupIdsRelations(EntityConsolidationData startingEntity,
                                          EntityConsolidationData currentEntity) {
-    if (CollectionUtils.isEmpty(startingEntity.getGroupIds())
-        && CollectionUtils.isEmpty(currentEntity.getGroupIds())) {
-      return true;
-    }
+    return CollectionUtils.isEmpty(startingEntity.getGroupIds())
+        && CollectionUtils.isEmpty(currentEntity.getGroupIds())
+        || startingEntity.getGroupIds().equals(currentEntity.getGroupIds());
 
-    return startingEntity.getGroupIds().equals(currentEntity.getGroupIds());
   }
 
   private boolean checkComputesRelationsToVolume(
-      Collection<ComputeTemplateConsolidationData> computeTemplateConsolidationDatas) {
-
-    Set<String> volumeRelationsFromComputes = new HashSet<>();
-    List<ComputeTemplateConsolidationData> computeTemplateConsolidationDataList =
-        new ArrayList(computeTemplateConsolidationDatas);
+      Collection<ComputeTemplateConsolidationData> computeTemplateConsolidationEntities) {
+    Iterator<ComputeTemplateConsolidationData> iterator =
+        computeTemplateConsolidationEntities.iterator();
 
     Map<String, List<RequirementAssignmentData>> startingVolumes =
-        computeTemplateConsolidationDataList.get(0).getVolumes();
+        iterator.next().getVolumes();
 
-    for (int i = 1; i < computeTemplateConsolidationDataList.size(); i++) {
+    for (ComputeTemplateConsolidationData compute : computeTemplateConsolidationEntities) {
       Map<String, List<RequirementAssignmentData>> currentVolumes =
-          computeTemplateConsolidationDataList.get(i).getVolumes();
+          compute.getVolumes();
       if (!compareNodeConnectivity(startingVolumes, currentVolumes)) {
         return false;
       }
@@ -542,28 +570,28 @@ public class ConsolidationService {
 
   private boolean checkPortConsolidation(ServiceTemplate serviceTemplate,
                                          TypeComputeConsolidationData typeComputeConsolidationData,
-                                         ConsolidationData consolidationData,
-                                         TranslationContext context) {
-    return isWantedPortPropertiesUsageIsSimilarInAllPorts(serviceTemplate,
-        typeComputeConsolidationData, context)
+                                         ConsolidationData consolidationData) {
+    return validateWantedPortProperties(serviceTemplate,
+        typeComputeConsolidationData)
         && checkPortRelations(ToscaUtil.getServiceTemplateFileName(serviceTemplate),
         typeComputeConsolidationData, consolidationData);
   }
 
 
-  private boolean isWantedPortPropertiesUsageIsSimilarInAllPorts(ServiceTemplate serviceTemplate,
-                                                                 TypeComputeConsolidationData typeComputeConsolidationData,
-                                                                 TranslationContext context) {
+  private boolean validateWantedPortProperties(ServiceTemplate serviceTemplate,
+                                               TypeComputeConsolidationData typeComputeConsolidationData) {
 
     Collection<ComputeTemplateConsolidationData> computeTemplateConsolidationDataCollection =
         typeComputeConsolidationData.getAllComputeTemplateConsolidationData();
-    List<String> propertiesThatNeedHaveUsage = getPortPropertiesWithIdenticalVal(context);
-    Map<String, Set<String>> portTypeToIds = UnifiedCompositionUtil
+    Map<String, List<String>> portTypeToIds = UnifiedCompositionUtil
         .collectAllPortsFromEachTypesFromComputes(computeTemplateConsolidationDataCollection);
+    List<String> propertiesWithIdenticalVal = getPortPropertiesWithIdenticalVal();
+    List<String> propertiesThatNeedToHaveSameUsage =
+        getPortPropertiesThatNeedToHaveSameUsage();
 
-    for (Set<String> portsIds : portTypeToIds.values()) {
-      if (!areAllPortsFromSameTypeHaveIdenticalValForProperties(
-          serviceTemplate, portsIds, propertiesThatNeedHaveUsage)) {
+    for (List<String> portsIds : portTypeToIds.values()) {
+      if (!arePortPropertiesValid(serviceTemplate, propertiesWithIdenticalVal,
+          propertiesThatNeedToHaveSameUsage, portsIds)) {
         return false;
       }
     }
@@ -571,20 +599,42 @@ public class ConsolidationService {
     return true;
   }
 
+  private boolean arePortPropertiesValid(ServiceTemplate serviceTemplate,
+                                         List<String> propertiesWithIdenticalVal,
+                                         List<String> propertiesThatNeedToHaveSameUsage,
+                                         List<String> portsIds) {
+    Map<String, NodeTemplate> nodeTemplates =
+        serviceTemplate.getTopology_template().getNode_templates();
+
+    Predicate<String> similar = property ->
+        isPropertyValueSimilarBetweenNodeTemplates(property,
+            portsIds, nodeTemplates);
+
+    Predicate<String> exists = property ->
+        isPropertyUsageSimilarBetweenAllNodeTemplates(property,
+            portsIds, nodeTemplates);
+
+    return areWantedPortPropertiesValid(
+        propertiesWithIdenticalVal, similar)
+        && areWantedPortPropertiesValid(
+        propertiesThatNeedToHaveSameUsage, exists);
+  }
+
   private boolean checkPortRelations(String serviceTemplateName,
                                      TypeComputeConsolidationData typeComputeConsolidationData,
                                      ConsolidationData consolidationData) {
     Collection<ComputeTemplateConsolidationData> computeTemplateConsolidationDataCollection =
         typeComputeConsolidationData.getAllComputeTemplateConsolidationData();
-    Map<String, Set<String>> portTypeToIds = UnifiedCompositionUtil
+    Map<String, List<String>> portTypeToIds = UnifiedCompositionUtil
         .collectAllPortsFromEachTypesFromComputes(computeTemplateConsolidationDataCollection);
 
-    for (Set<String> portIds : portTypeToIds.values()) {
+    for (List<String> portIds : portTypeToIds.values()) {
       List<PortTemplateConsolidationData> portTemplateConsolidationDataList =
           collectAllPortsTemplateConsolidationData(
               portIds, serviceTemplateName, consolidationData);
 
-      if (!checkEntityConsolidationDataRelations(portTemplateConsolidationDataList)) {
+      if (!checkEntityConsolidationDataRelations(portTemplateConsolidationDataList)
+          || !checkSubInterfaceRules(portTemplateConsolidationDataList)) {
         return false;
       }
     }
@@ -592,36 +642,38 @@ public class ConsolidationService {
     return true;
   }
 
-  private List<PortTemplateConsolidationData>
-  collectAllPortsTemplateConsolidationData(Set<String> portIds,
-                                           String serviceTemplateName,
-                                           ConsolidationData consolidationData) {
-
-    FilePortConsolidationData filePortConsolidationData =
-        consolidationData.getPortConsolidationData()
-            .getFilePortConsolidationData(serviceTemplateName);
-    List<PortTemplateConsolidationData> portTemplateConsolidationDataList = new ArrayList<>();
+  private boolean checkSubInterfaceRules(List<PortTemplateConsolidationData>
+                                             portTemplateConsolidationDataList) {
+    ListMultimap<String, SubInterfaceTemplateConsolidationData> subInterfaceTypeToEntity =
+        collectAllSubInterfacesFromSameTypeFromPorts(portTemplateConsolidationDataList);
+    List<SubInterfaceTemplateConsolidationData> subInterfaceList = new ArrayList<>(subInterfaceTypeToEntity.values());
+    return areSubInterfacePropertiesAndRelationsValid(subInterfaceList);
+  }
 
-    for (String portId : portIds) {
-      PortTemplateConsolidationData portTemplateConsolidationData = filePortConsolidationData
-          .getPortTemplateConsolidationData(portId);
-      if (Objects.nonNull(portTemplateConsolidationData)) {
-        portTemplateConsolidationDataList.add(portTemplateConsolidationData);
-      }
-    }
+  private boolean areSubInterfacePropertiesAndRelationsValid(
+      List<SubInterfaceTemplateConsolidationData> subInterfaceList) {
+    return isResourceGroupPropertiesSimilarBetweenSubPorts(subInterfaceList)
+        && checkSubInterfaceRelations(subInterfaceList)
+        && !areThereGetAttrRelationsBetweenSubInterfacesOfSameType(
+        getSubInterfaceIdsFromSameType(subInterfaceList), subInterfaceList);
+  }
 
-    return portTemplateConsolidationDataList;
+  private boolean checkSubInterfaceRelations(List<SubInterfaceTemplateConsolidationData>
+                                                 subInterfaceList) {
+    return CollectionUtils.isEmpty(subInterfaceList)
+        || checkEntityConsolidationDataRelations(subInterfaceList);
   }
 
-  private boolean areAllPortsFromSameTypeHaveIdenticalValForProperties(
-      ServiceTemplate serviceTemplate,
-      Set<String> portNodeTemplateIds,
-      List<String> propertiesThatNeedToHaveUsage) {
-    Map<String, NodeTemplate> nodeTemplates =
-        serviceTemplate.getTopology_template().getNode_templates();
+  private boolean isResourceGroupPropertiesSimilarBetweenSubPorts(
+      List<SubInterfaceTemplateConsolidationData> subInterfaceList) {
+    if (CollectionUtils.isEmpty(subInterfaceList)) {
+      return true;
+    }
 
-    for (String property : propertiesThatNeedToHaveUsage) {
-      if (!areAllPortsHaveIdenticalValForProperties(property, portNodeTemplateIds, nodeTemplates)) {
+    SubInterfaceTemplateConsolidationData startingSubInterface = subInterfaceList.get(0);
+    for (SubInterfaceTemplateConsolidationData subInterface : subInterfaceList) {
+      if (!startingSubInterface.getResourceGroupCount().equals(subInterface.getResourceGroupCount())
+          || !StringUtils.equals(startingSubInterface.getNetworkRole(), subInterface.getNetworkRole())) {
         return false;
       }
     }
@@ -629,46 +681,63 @@ public class ConsolidationService {
     return true;
   }
 
-  private boolean areAllPortsHaveIdenticalValForProperties(
-      String propertyToCheck,
-      Set<String> portNodeTemplateIds,
-      Map<String, NodeTemplate> nodeTemplates) {
+  private List<String> getSubInterfaceIdsFromSameType(List<SubInterfaceTemplateConsolidationData>
+                                                          subInterfaceList) {
+    if (CollectionUtils.isEmpty(subInterfaceList)) {
+      return new ArrayList<>();
+    }
 
-    List<String> portNodeTemplateIdList = new ArrayList(portNodeTemplateIds);
-    NodeTemplate startingPortNodeTemplate = nodeTemplates.get(portNodeTemplateIdList.get(0));
+    return subInterfaceList.stream().map(SubInterfaceTemplateConsolidationData::getNodeTemplateId)
+        .collect(Collectors.toList());
+  }
 
-    if (Objects.isNull(startingPortNodeTemplate)) {
-      throw new CoreException(
-          new DuplicateResourceIdsInDifferentFilesErrorBuilder(portNodeTemplateIdList.get(0)).build());
+  private ListMultimap<String, SubInterfaceTemplateConsolidationData> collectAllSubInterfacesFromSameTypeFromPorts(
+      List<PortTemplateConsolidationData> portTemplateConsolidationDataList) {
+    ListMultimap<String, SubInterfaceTemplateConsolidationData>  subInterfaceTypeToEntity = ArrayListMultimap.create();
+    for (PortTemplateConsolidationData portTemplateConsolidationData : portTemplateConsolidationDataList) {
+      portTemplateConsolidationData.copyMappedInto(subInterfaceTypeToEntity);
     }
 
-    for (int i = 1; i < portNodeTemplateIdList.size(); i++) {
-      NodeTemplate portNodeTemplate = nodeTemplates.get(portNodeTemplateIdList.get(i));
+    return subInterfaceTypeToEntity;
+  }
 
-      if (Objects.isNull(portNodeTemplate)) {
-        throw new CoreException(
-            new DuplicateResourceIdsInDifferentFilesErrorBuilder(portNodeTemplateIdList.get(i)).build());
-      }
+  private List<PortTemplateConsolidationData> collectAllPortsTemplateConsolidationData(List<String> portIds,
+                                                                                       String serviceTemplateName,
+                                                                                       ConsolidationData consolidationData) {
 
-      if (!isPropertySimilarBetweenNodeTemplates(propertyToCheck, portNodeTemplateIdList, nodeTemplates)) {
-        return false;
+    FilePortConsolidationData filePortConsolidationData =
+        consolidationData.getPortConsolidationData()
+            .getFilePortConsolidationData(serviceTemplateName);
+    List<PortTemplateConsolidationData> portTemplateConsolidationDataList = new ArrayList<>();
+
+    for (String portId : portIds) {
+      PortTemplateConsolidationData portTemplateConsolidationData = filePortConsolidationData
+          .getPortTemplateConsolidationData(portId);
+      if (Objects.nonNull(portTemplateConsolidationData)) {
+        portTemplateConsolidationDataList.add(portTemplateConsolidationData);
       }
     }
 
-    return true;
+    return portTemplateConsolidationDataList;
+  }
+
+  private boolean areWantedPortPropertiesValid(List<String> propertiesToCheck,
+                                               Predicate<String> condition) {
+
+    return propertiesToCheck.stream().allMatch(condition);
   }
 
 
   private boolean arePropertiesSimilarBetweenComputeNodeTemplates(
       ServiceTemplate serviceTemplate,
-      List<String> computeNodeTemplateIds,
+      Collection<String> computeNodeTemplateIds,
       List<String> propertiesThatNeedToBeSimilar) {
 
     Map<String, NodeTemplate> idToNodeTemplate =
         serviceTemplate.getTopology_template().getNode_templates();
 
     for (String property : propertiesThatNeedToBeSimilar) {
-      if (!isPropertySimilarBetweenNodeTemplates(property, computeNodeTemplateIds,
+      if (!isPropertyValueSimilarBetweenNodeTemplates(property, computeNodeTemplateIds,
           idToNodeTemplate)) {
         return false;
       }
@@ -676,43 +745,81 @@ public class ConsolidationService {
     return true;
   }
 
-  private boolean isPropertySimilarBetweenNodeTemplates(
-      String propertyToCheck,
-      List<String> entityNodeTemplateIds,
-      Map<String, NodeTemplate> idToNodeTemplate) {
-
+  private boolean isPropertyUsageSimilarBetweenAllNodeTemplates(String propertyToCheck,
+                                                                List<String> entityNodeTemplateIds,
+                                                                Map<String, NodeTemplate> idToNodeTemplate) {
     NodeTemplate startingNodeTemplate = idToNodeTemplate.get(entityNodeTemplateIds.get(0));
+    if (Objects.isNull(startingNodeTemplate)) {
+      throw new CoreException(
+          new DuplicateResourceIdsInDifferentFilesErrorBuilder(entityNodeTemplateIds.get(0))
+              .build());
+    }
+
     boolean propertyExistCondition =
         isPropertyExistInNodeTemplate(propertyToCheck, startingNodeTemplate);
 
-    Set<Object> propertiesValues = new HashSet<>();
-    propertiesValues
-        .add(startingNodeTemplate.getProperties().get(propertyToCheck));
-
     for (int i = 1; i < entityNodeTemplateIds.size(); i++) {
       NodeTemplate currentNodeTemplate = idToNodeTemplate.get(entityNodeTemplateIds.get(i));
       if (Objects.isNull(currentNodeTemplate)) {
         throw new CoreException(
-            new DuplicateResourceIdsInDifferentFilesErrorBuilder(entityNodeTemplateIds.get(i)).build());
+            new DuplicateResourceIdsInDifferentFilesErrorBuilder(entityNodeTemplateIds.get(i))
+                .build());
       }
-      if(propertyExistCondition != isPropertyExistInNodeTemplate(propertyToCheck, currentNodeTemplate)){
+      if (propertyExistCondition != isPropertyExistInNodeTemplate(propertyToCheck, currentNodeTemplate)) {
         return false;
       }
-      propertiesValues
-          .add(currentNodeTemplate.getProperties().get(propertyToCheck));
+    }
+
+    return true;
+
+  }
+
+  private boolean isPropertyValueSimilarBetweenNodeTemplates(String propertyToCheck,
+                                                             Collection<String> entityNodeTemplateIds,
+                                                             Map<String, NodeTemplate> idToNodeTemplate) {
+
+    Set<Object> propertiesValues = new HashSet<>();
+    Iterator<String> iterator = entityNodeTemplateIds.iterator();
+
+    handlePropertyValue(propertyToCheck, idToNodeTemplate, propertiesValues, iterator.next());
+
+    while (iterator.hasNext()) {
+      handlePropertyValue(propertyToCheck, idToNodeTemplate, propertiesValues, iterator.next());
     }
 
     return propertiesValues.size() == 1;
   }
 
-  private boolean isPropertyExistInNodeTemplate(String propertyToCheck, NodeTemplate nodeTemplate){
-    return !(nodeTemplate.getProperties() == null || nodeTemplate.getProperties().get(propertyToCheck) == null);
+  private void handlePropertyValue(String propertyToCheck,
+                                   Map<String, NodeTemplate> idToNodeTemplate,
+                                   Set<Object> propertiesValues, String nodeId) {
+    NodeTemplate startingNodeTemplate = idToNodeTemplate.get(nodeId);
+    if (Objects.isNull(startingNodeTemplate)) {
+      throw new CoreException(
+          new DuplicateResourceIdsInDifferentFilesErrorBuilder(nodeId)
+              .build());
+    }
+
+    addPropertyValue(propertyToCheck, startingNodeTemplate, propertiesValues);
+  }
+
+  private void addPropertyValue(String property,
+                                NodeTemplate nodeTemplate,
+                                Set<Object> propertiesValues) {
+    propertiesValues.add(
+        isPropertyExistInNodeTemplate(property, nodeTemplate) ? nodeTemplate.getProperties()
+            .get(property) : "");
   }
 
-  public void substitutionServiceTemplateConsolidation(String substituteNodeTemplateId,
-                                                       ServiceTemplate serviceTemplate,
-                                                       ServiceTemplate substitutionServiceTemplate,
-                                                       TranslationContext translationContext) {
+  private boolean isPropertyExistInNodeTemplate(String propertyToCheck, NodeTemplate nodeTemplate) {
+    return !(nodeTemplate.getProperties() == null
+       || nodeTemplate.getProperties().get(propertyToCheck) == null);
+  }
+
+  void substitutionServiceTemplateConsolidation(String substituteNodeTemplateId,
+                                                ServiceTemplate serviceTemplate,
+                                                ServiceTemplate substitutionServiceTemplate,
+                                                TranslationContext translationContext) {
 
     ConsolidationData consolidationData = translationContext.getConsolidationData();
 
@@ -727,7 +834,7 @@ public class ConsolidationService {
     if (substitutionConsolidationRuleResult) {
       List<UnifiedCompositionData> unifiedCompositionDataList =
           createSubstitutionUnifiedCompositionDataList(substituteNodeTemplateId,
-              serviceTemplate, consolidationData);
+              serviceTemplate, substitutionServiceTemplate, consolidationData);
       unifiedCompositionService
           .createUnifiedComposition(serviceTemplate, substitutionServiceTemplate,
               unifiedCompositionDataList, UnifiedCompositionMode.NestedSingleCompute,
@@ -749,13 +856,12 @@ public class ConsolidationService {
       ServiceTemplate nestedServiceTemplate,
       FileComputeConsolidationData fileComputeConsolidationData,
       TranslationContext context) {
-    if (Objects.isNull(fileComputeConsolidationData)) {
-      return false;
-    }
-    return isNumberOfComputeTypesLegal(fileComputeConsolidationData)
+
+    return Objects.nonNull(fileComputeConsolidationData)
+        && isNumberOfComputeTypesLegal(fileComputeConsolidationData)
         && isNumberOfComputeConsolidationDataPerTypeLegal(
         fileComputeConsolidationData.getAllTypeComputeConsolidationData().iterator().next())
-        && !isThereMoreThanOneNestedLevel(nestedServiceTemplate, context.getConsolidationData());
+        && !isThereMoreThanOneNestedLevel(nestedServiceTemplate, context);
   }
 
   private boolean isNumberOfComputeTypesLegal(
@@ -769,24 +875,60 @@ public class ConsolidationService {
   }
 
   private boolean isThereMoreThanOneNestedLevel(ServiceTemplate nestedServiceTemplate,
-                                                ConsolidationData consolidationData) {
+                                                TranslationContext context) {
+    FileNestedConsolidationData fileNestedConsolidationData = null;
     String nestedServiceTemplateName = ToscaUtil.getServiceTemplateFileName(nestedServiceTemplate);
     if (Objects.isNull(nestedServiceTemplateName)) {
       return false;
     }
 
-    FileNestedConsolidationData fileNestedConsolidationData =
-        consolidationData.getNestedConsolidationData() == null ? new FileNestedConsolidationData()
-            : consolidationData.getNestedConsolidationData()
-                .getFileNestedConsolidationData(nestedServiceTemplateName);
+    NestedConsolidationData nestedConsolidationData = context.getConsolidationData()
+                                                                .getNestedConsolidationData();
+    if (Objects.nonNull(nestedConsolidationData)) {
+      fileNestedConsolidationData =
+          nestedConsolidationData.getFileNestedConsolidationData(nestedServiceTemplateName);
+    }
 
-    if (Objects.isNull(fileNestedConsolidationData)) {
-      return false;
+    //Condition to check if there is nested file and if file contains only sub interfaces then
+    // return false
+    return Objects.nonNull(fileNestedConsolidationData)
+        && !ifNestedFileContainsOnlySubInterface(nestedServiceTemplate, context);
+  }
+
+  private boolean ifNestedFileContainsOnlySubInterface(ServiceTemplate serviceTemplate,
+                                                       TranslationContext context) {
+    Map<String, NodeTemplate> nestedNodeTemplateMap =
+        DataModelUtil.getNodeTemplates(serviceTemplate);
+
+    ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
+    Set<Object> nestedHeatFileNames = nestedNodeTemplateMap.entrySet().stream()
+        .filter(entry -> toscaAnalyzerService.isSubstitutableNodeTemplate(entry.getValue())
+        && toscaAnalyzerService
+            .getSubstituteServiceTemplateName(entry.getKey(), entry.getValue()).isPresent())
+        .map(entry -> toscaAnalyzerService
+            .getSubstituteServiceTemplateName(entry.getKey(), entry.getValue()).get())
+        .collect(Collectors.toSet());
+
+    if (CollectionUtils.isNotEmpty(nestedHeatFileNames)) {
+      for (Object fileName : nestedHeatFileNames) {
+        String heatFileName = context.getNestedHeatFileName().get(String.valueOf(fileName));
+
+        if (Objects.nonNull(heatFileName)
+              && !ifAllResourceAreSubInterface(context.getTranslatedServiceTemplates()
+                    .get(heatFileName).getTopology_template().getNode_templates().values())) {
+          return false;
+        }
+      }
     }
 
-    return !CollectionUtils.isEmpty(fileNestedConsolidationData.getAllNestedNodeTemplateIds());
+    return true;
   }
 
+  // Method returns true if all of the resource are sub interface
+  private boolean ifAllResourceAreSubInterface(Collection<NodeTemplate> nodeTemplates) {
+    return nodeTemplates.stream().allMatch(nodeTemplate ->
+        ToscaNodeType.CONTRAILV2_VLAN_SUB_INTERFACE.equals(nodeTemplate.getType()));
+  }
 
   private List<UnifiedCompositionData> createUnifiedCompositionDataList(
       ServiceTemplate serviceTemplate,
@@ -797,35 +939,38 @@ public class ConsolidationService {
 
     for (ComputeTemplateConsolidationData computeTemplateConsolidationData : typeComputeConsolidationData
         .getAllComputeTemplateConsolidationData()) {
-
       UnifiedCompositionData unifiedCompositionData = new UnifiedCompositionData();
       unifiedCompositionData.setComputeTemplateConsolidationData(computeTemplateConsolidationData);
-
-      Collection<List<String>> portCollection =
-          computeTemplateConsolidationData.getPorts() == null ? Collections.emptyList()
-              : computeTemplateConsolidationData.getPorts().values();
-
       FilePortConsolidationData filePortConsolidationData =
           consolidationData.getPortConsolidationData().getFilePortConsolidationData(ToscaUtil
               .getServiceTemplateFileName(serviceTemplate));
-
-      for (List<String> portList : portCollection) {
-        for (String portId : portList) {
-          if (!Objects.isNull(filePortConsolidationData)) {
-            unifiedCompositionData.addPortTemplateConsolidationData(
-                (filePortConsolidationData.getPortTemplateConsolidationData(portId)));
-          }
-        }
-      }
+      setUnifiedCompositionDataWithPortTemplateData(computeTemplateConsolidationData, filePortConsolidationData,
+          unifiedCompositionData);
       unifiedCompositionDataList.add(unifiedCompositionData);
     }
-
     return unifiedCompositionDataList;
   }
 
+  private void setPortTemplateConsolidationData(FilePortConsolidationData filePortConsolidationData,
+                                                String portId,
+                                                UnifiedCompositionData unifiedCompositionData,
+                                                List<SubInterfaceTemplateConsolidationData>
+                                                                 subInterfaceTemplateConsolidationDataList) {
+    if (Objects.isNull(filePortConsolidationData)) {
+      return;
+    }
+    PortTemplateConsolidationData portTemplateConsolidationData =
+        filePortConsolidationData.getPortTemplateConsolidationData(portId);
+    unifiedCompositionData.addPortTemplateConsolidationData(portTemplateConsolidationData);
+    if (portTemplateConsolidationData != null) {
+      portTemplateConsolidationData.copyFlatInto(subInterfaceTemplateConsolidationDataList);
+    }
+  }
+
   private List<UnifiedCompositionData> createSubstitutionUnifiedCompositionDataList(
       String substituteNodeTemplateId,
       ServiceTemplate serviceTemplate,
+      ServiceTemplate substitutionServiceTemplate,
       ConsolidationData consolidationData) {
     List<UnifiedCompositionData> unifiedCompositionDataList = new ArrayList<>();
     FileNestedConsolidationData fileNestedConsolidationData =
@@ -838,12 +983,51 @@ public class ConsolidationService {
       UnifiedCompositionData unifiedCompositionData = new UnifiedCompositionData();
       unifiedCompositionData.setNestedTemplateConsolidationData(nestedTemplateConsolidationData);
       unifiedCompositionDataList.add(unifiedCompositionData);
-      return unifiedCompositionDataList;
+      addSubInterfaceDataToNestedCompositionData(substitutionServiceTemplate, consolidationData,
+          unifiedCompositionData);
     }
 
     return unifiedCompositionDataList;
   }
 
+  private void addSubInterfaceDataToNestedCompositionData(ServiceTemplate substitutionServiceTemplate,
+                                                          ConsolidationData consolidationData,
+                                                          UnifiedCompositionData unifiedCompositionData) {
+    FileComputeConsolidationData nestedFileComputeConsolidationData = consolidationData.getComputeConsolidationData()
+        .getFileComputeConsolidationData(ToscaUtil.getServiceTemplateFileName(substitutionServiceTemplate));
+    FilePortConsolidationData nestedFilePortConsolidationData = consolidationData.getPortConsolidationData()
+        .getFilePortConsolidationData(ToscaUtil.getServiceTemplateFileName(substitutionServiceTemplate));
+    if (Objects.isNull(nestedFileComputeConsolidationData)
+        || Objects.isNull(nestedFilePortConsolidationData)) {
+      return;
+    }
+    TypeComputeConsolidationData computeType =
+        nestedFileComputeConsolidationData.getAllTypeComputeConsolidationData().iterator().next();
+    if (Objects.isNull(computeType)) {
+      return;
+    }
+    ComputeTemplateConsolidationData computeTemplateConsolidationData =
+        computeType.getAllComputeTemplateConsolidationData().iterator().next();
+    setUnifiedCompositionDataWithPortTemplateData(computeTemplateConsolidationData, nestedFilePortConsolidationData,
+        unifiedCompositionData);
+  }
+
+  private void setUnifiedCompositionDataWithPortTemplateData(ComputeTemplateConsolidationData
+                                                                 computeTemplateConsolidationData,
+                                                             FilePortConsolidationData filePortConsolidationData,
+                                                             UnifiedCompositionData unifiedCompositionData) {
+    Collection<List<String>> portCollection =
+        computeTemplateConsolidationData.getPorts() == null ? Collections.emptyList()
+            : computeTemplateConsolidationData.getPorts().values();
+    List<SubInterfaceTemplateConsolidationData> subInterfaceTemplateConsolidationDataList = new ArrayList<>();
+    portCollection.stream()
+        .flatMap(Collection::stream)
+        .forEach(portId -> setPortTemplateConsolidationData(filePortConsolidationData, portId,
+            unifiedCompositionData, subInterfaceTemplateConsolidationDataList));
+    unifiedCompositionData.setSubInterfaceTemplateConsolidationDataList(
+        subInterfaceTemplateConsolidationDataList);
+  }
+
   private boolean consolidationPreCondition(
       ServiceTemplate serviceTemplate,
       ConsolidationData consolidationData,
@@ -854,7 +1038,9 @@ public class ConsolidationService {
         && isNumberOfPortFromEachTypeLegal(typeComputeConsolidationData)
         && isPortTypesEqualsBetweenComputeNodes(typeComputeConsolidationData)
         && checkGetAttrBetweenConsolidationDataEntitiesNotFromSameType(serviceTemplate,
-        typeComputeConsolidationData, consolidationData));
+        typeComputeConsolidationData, consolidationData)
+        && checkSubInterfaceConsolidationPreCondition(serviceTemplate, consolidationData,
+        typeComputeConsolidationData));
 
   }
 
@@ -865,17 +1051,13 @@ public class ConsolidationService {
 
   private boolean isNumberOfPortsEqualsBetweenComputeNodes(
       TypeComputeConsolidationData typeComputeConsolidationData) {
-
-    ArrayList<ComputeTemplateConsolidationData> computeTemplateConsolidationDataList =
-        new ArrayList(typeComputeConsolidationData.getAllComputeTemplateConsolidationData());
     int startingNumberOfPorts =
-        getNumberOfPortsPerCompute(computeTemplateConsolidationDataList.get(0));
+        getNumberOfPortsPerCompute(typeComputeConsolidationData
+            .getAllComputeTemplateConsolidationData().iterator().next());
 
-
-    for (int i = 1; i < computeTemplateConsolidationDataList.size(); i++) {
-      int currNumberOfPorts =
-          getNumberOfPortsPerCompute(computeTemplateConsolidationDataList.get(i));
-      if (currNumberOfPorts != startingNumberOfPorts) {
+    for (ComputeTemplateConsolidationData compute : typeComputeConsolidationData
+        .getAllComputeTemplateConsolidationData()) {
+      if (getNumberOfPortsPerCompute(compute) != startingNumberOfPorts) {
         return false;
       }
     }
@@ -887,8 +1069,8 @@ public class ConsolidationService {
   private boolean isNumberOfPortFromEachTypeLegal(
       TypeComputeConsolidationData typeComputeConsolidationData) {
 
-    ArrayList<ComputeTemplateConsolidationData> computeTemplateConsolidationDataList =
-        new ArrayList(typeComputeConsolidationData.getAllComputeTemplateConsolidationData());
+    Collection<ComputeTemplateConsolidationData> computeTemplateConsolidationDataList =
+        typeComputeConsolidationData.getAllComputeTemplateConsolidationData();
 
     for (ComputeTemplateConsolidationData computeTemplate : computeTemplateConsolidationDataList) {
       Map<String, List<String>> currPortsMap = computeTemplate.getPorts();
@@ -907,45 +1089,40 @@ public class ConsolidationService {
 
   private boolean isPortTypesEqualsBetweenComputeNodes(
       TypeComputeConsolidationData typeComputeConsolidationData) {
+    Set<String> staringPortIds = getPortsIds(
+        typeComputeConsolidationData.getAllComputeTemplateConsolidationData().iterator().next());
 
-    ArrayList<ComputeTemplateConsolidationData> computeTemplateConsolidationDataList =
-        new ArrayList(typeComputeConsolidationData.getAllComputeTemplateConsolidationData());
-    Set<String> staringPortIds = getPortsIds(computeTemplateConsolidationDataList.get(0));
-
-    for (int i = 1; i < computeTemplateConsolidationDataList.size(); i++) {
-      Set<String> currentPortIds = getPortsIds(computeTemplateConsolidationDataList.get(i));
+    for (ComputeTemplateConsolidationData compute : typeComputeConsolidationData
+        .getAllComputeTemplateConsolidationData()) {
+      Set<String> currentPortIds = getPortsIds(compute);
       if (!currentPortIds.equals(staringPortIds)) {
         return false;
       }
     }
-
     return true;
   }
 
   private int getNumberOfPortsPerCompute(
       ComputeTemplateConsolidationData computeTemplateConsolidationData) {
-    return getPortsIds(computeTemplateConsolidationData) == null ? 0 :
-        getPortsIds(computeTemplateConsolidationData).size();
+    return getPortsIds(computeTemplateConsolidationData).size();
   }
 
   private Set<String> getPortsIds(
       ComputeTemplateConsolidationData computeTemplateConsolidationData) {
-    return computeTemplateConsolidationData.getPorts() == null ? new HashSet<>()
-        : computeTemplateConsolidationData
-            .getPorts().keySet();
+    return MapUtils.isEmpty(computeTemplateConsolidationData.getPorts()) ? new HashSet<>()
+        : computeTemplateConsolidationData.getPorts().keySet();
   }
 
-  public List<String> getPropertiesWithIdenticalVal(UnifiedCompositionEntity entity,
-                                                    TranslationContext context){
-    switch (entity){
-      case Compute:
+  List<String> getPropertiesWithIdenticalVal(UnifiedCompositionEntity entity) {
+    switch (entity) {
+      case COMPUTE:
         return getComputePropertiesWithIdenticalVal();
 
-      case Other:
+      case OTHER:
         return getComputePropertiesWithIdenticalVal();
 
-      case Port:
-        return getPortPropertiesWithIdenticalVal(context);
+      case PORT:
+        return getPortPropertiesWithIdenticalVal();
 
       default:
         return new ArrayList<>();
@@ -959,15 +1136,27 @@ public class ConsolidationService {
     return propertyWithIdenticalValue;
   }
 
-  private List<String> getPortPropertiesWithIdenticalVal(TranslationContext context) {
-    List<String> propertiesThatNeedToHaveUsage = new ArrayList<>();
-    propertiesThatNeedToHaveUsage.add(ToscaConstants.PORT_FIXED_IPS);
-    propertiesThatNeedToHaveUsage.add(ToscaConstants.PORT_ALLOWED_ADDRESS_PAIRS);
-    propertiesThatNeedToHaveUsage.add(ToscaConstants.MAC_ADDRESS);
+  private List<String> getPortPropertiesWithIdenticalVal() {
+    List<String> propertiesThatNeedToHaveIdenticalVal = new ArrayList<>();
+    propertiesThatNeedToHaveIdenticalVal.add(ToscaConstants.PORT_ALLOWED_ADDRESS_PAIRS);
+    propertiesThatNeedToHaveIdenticalVal.add(ToscaConstants.MAC_ADDRESS);
+
+    propertiesThatNeedToHaveIdenticalVal
+        .addAll(TranslationContext.getEnrichPortResourceProperties());
+
+    return propertiesThatNeedToHaveIdenticalVal;
+  }
+
+  private List<String> getPortPropertiesThatNeedToHaveSameUsage() {
+    List<String> propertiesThatNeedToHaveSameUsage = new ArrayList<>();
+    propertiesThatNeedToHaveSameUsage.add(ToscaConstants.PORT_FIXED_IPS);
+    propertiesThatNeedToHaveSameUsage.add(ToscaConstants.PORT_ALLOWED_ADDRESS_PAIRS);
+    propertiesThatNeedToHaveSameUsage.add(ToscaConstants.MAC_ADDRESS);
 
-    propertiesThatNeedToHaveUsage.addAll(context.getEnrichPortResourceProperties());
+    propertiesThatNeedToHaveSameUsage.addAll(TranslationContext.getEnrichPortResourceProperties());
 
-    return propertiesThatNeedToHaveUsage;
+    return propertiesThatNeedToHaveSameUsage;
   }
+
 }