re base code
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / tosca / CapabilityRequirementConverter.java
 
 package org.openecomp.sdc.be.tosca;
 
-import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
-import static org.apache.commons.lang3.StringUtils.isBlank;
-import static org.apache.commons.lang3.StringUtils.isNoneBlank;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Maps;
+import fj.data.Either;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.RequirementDataDefinition;
-import org.openecomp.sdc.be.model.CapabilityDefinition;
-import org.openecomp.sdc.be.model.Component;
-import org.openecomp.sdc.be.model.ComponentInstance;
-import org.openecomp.sdc.be.model.ComponentInstanceProperty;
-import org.openecomp.sdc.be.model.ComponentParametersView;
-import org.openecomp.sdc.be.model.DataTypeDefinition;
-import org.openecomp.sdc.be.model.PropertyDefinition;
-import org.openecomp.sdc.be.model.RequirementDefinition;
+import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
+import org.openecomp.sdc.be.model.*;
 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
 import org.openecomp.sdc.be.model.jsontitan.utils.ModelConverter;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
-import org.openecomp.sdc.be.tosca.ToscaUtils.SubstituitionEntry;
-import org.openecomp.sdc.be.tosca.model.SubstitutionMapping;
-import org.openecomp.sdc.be.tosca.model.ToscaCapability;
-import org.openecomp.sdc.be.tosca.model.ToscaNodeTemplate;
-import org.openecomp.sdc.be.tosca.model.ToscaNodeType;
-import org.openecomp.sdc.be.tosca.model.ToscaProperty;
-import org.openecomp.sdc.be.tosca.model.ToscaRequirement;
-import org.openecomp.sdc.be.tosca.model.ToscaTemplateCapability;
-import org.openecomp.sdc.common.util.ValidationUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.openecomp.sdc.be.model.utils.ComponentUtilities;
+import org.openecomp.sdc.be.tosca.ToscaUtils.SubstitutionEntry;
+import org.openecomp.sdc.be.tosca.model.*;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Scope;
 
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
-import fj.data.Either;
+import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
+import static org.apache.commons.lang3.StringUtils.isBlank;
+import static org.apache.commons.lang3.StringUtils.isNoneBlank;
 
 /**
  * Allows to convert requirements\capabilities of a component to requirements\capabilities of a substitution mappings section of a tosca template
@@ -76,32 +55,38 @@ import fj.data.Either;
  */
 @org.springframework.stereotype.Component("capabilty-requirement-convertor")
 @Scope(value = "singleton")
-public class CapabiltyRequirementConvertor {
+public class CapabilityRequirementConverter {
 
     private static final String NO_CAPABILITIES = "No Capabilities for node type";
-    private static CapabiltyRequirementConvertor instance;
-    private static final Logger logger = LoggerFactory.getLogger(CapabiltyRequirementConvertor.class);
-    public static final String PATH_DELIMITER = ".";
+    private static CapabilityRequirementConverter instance;
+    private static final Logger logger = Logger.getLogger(CapabilityRequirementConverter.class);
+    private static final String PATH_DELIMITER = ".";
 
     @Autowired
     private ToscaOperationFacade toscaOperationFacade;
 
-    protected CapabiltyRequirementConvertor() {}
+    public CapabilityRequirementConverter() {}
 
-    public static synchronized CapabiltyRequirementConvertor getInstance() {
+    public static synchronized CapabilityRequirementConverter getInstance() {
         if (instance == null) {
-            instance = new CapabiltyRequirementConvertor();
+            instance = new CapabilityRequirementConverter();
         }
         return instance;
     }
 
     public String buildCapabilityNameForComponentInstance( Map<String,Component> componentCache , ComponentInstance componentInstance, CapabilityDefinition c) {
-
-        Either eitherName = buildSubstitutedName(componentCache, c.getName(), c.getPath(), c.getOwnerId(), componentInstance);
-
-        return eitherName.isLeft() ? (String) eitherName.left().value() : c.getName() ;
+        String prefix = buildCapReqNamePrefix(componentInstance.getNormalizedName());
+        if(ComponentUtilities.isNotUpdatedCapReqName(prefix, c.getName(), c.getPreviousName())){
+            return buildSubstitutedName(componentCache, c.getName(), c.getPreviousName(), c.getPath(), c.getOwnerId(), componentInstance)
+                    .left()
+                    .orValue(c.getName());
+        }
+        return c.getPreviousName();
     }
 
+    private String buildCapReqNamePrefix(String normalizedName) {
+        return normalizedName + PATH_DELIMITER;
+    }
 
     /**
      * Allows to convert capabilities of a component to capabilities of a substitution mappings section of a tosca template
@@ -110,7 +95,7 @@ public class CapabiltyRequirementConvertor {
      * @param nodeTemplate
      * @return
      */
-    public Either<ToscaNodeTemplate, ToscaError> convertComponentInstanceCapabilties(ComponentInstance componentInstance, Map<String, DataTypeDefinition> dataTypes, ToscaNodeTemplate nodeTemplate) {
+    public Either<ToscaNodeTemplate, ToscaError> convertComponentInstanceCapabilities(ComponentInstance componentInstance, Map<String, DataTypeDefinition> dataTypes, ToscaNodeTemplate nodeTemplate) {
 
         Map<String, List<CapabilityDefinition>> capabilitiesInst = componentInstance.getCapabilities();
         Map<String,Component> componentCache = new HashMap<>();
@@ -119,10 +104,9 @@ public class CapabiltyRequirementConvertor {
             capabilitiesInst.entrySet().forEach( e -> {
                 List<CapabilityDefinition> capList = e.getValue();
                 if ( capList != null && !capList.isEmpty() ) {
-                    capList.forEach( c -> {
-                        String capName = buildCapabilityNameForComponentInstance( componentCache , componentInstance , c ) ;
-                        convertOverridenProperties( componentInstance, dataTypes, capabilities, c , capName );
-                    } );
+                    capList.stream()
+                            .forEach( c -> convertOverridenProperties( componentInstance, dataTypes, capabilities, c ,
+                                buildCapabilityNameForComponentInstance( componentCache , componentInstance , c )));
                 }
             });
             if (MapUtils.isNotEmpty(capabilities)) {
@@ -137,13 +121,13 @@ public class CapabiltyRequirementConvertor {
             c.getProperties()
             .stream()
             .filter(p -> p.getValue() != null || p.getDefaultValue() != null)
-            .forEach(p -> convertOverridenProperty(componentInstance, dataTypes, capabilties , p ,capabilityName));
+            .forEach(p -> convertOverriddenProperty(componentInstance, dataTypes, capabilties , p ,capabilityName));
         }
     }
 
-    private void convertOverridenProperty(ComponentInstance componentInstance, Map<String, DataTypeDefinition> dataTypes, Map<String, ToscaTemplateCapability> capabilties, ComponentInstanceProperty p ,String capabilityName) {
+    private void convertOverriddenProperty(ComponentInstance componentInstance, Map<String, DataTypeDefinition> dataTypes, Map<String, ToscaTemplateCapability> capabilties, ComponentInstanceProperty p , String capabilityName) {
         if (logger.isDebugEnabled()) {
-            logger.debug("Exist overriden property {} for capabity {} with value {}", p.getName(), capabilityName, p.getValue());
+            logger.debug("Exist d property {} for capability {} with value {}", p.getName(), capabilityName, p.getValue());
         }
         ToscaTemplateCapability toscaTemplateCapability = capabilties.computeIfAbsent( capabilityName , key -> new ToscaTemplateCapability() );
 
@@ -164,7 +148,7 @@ public class CapabiltyRequirementConvertor {
             innerType = prop.getSchema().getProperty().getType();
         }
         String propValue = prop.getValue() == null ? prop.getDefaultValue() : prop.getValue();
-        return PropertyConvertor.getInstance().convertToToscaObject(propertyType, propValue, innerType, dataTypes);
+        return PropertyConvertor.getInstance().convertToToscaObject(propertyType, propValue, innerType, dataTypes, false);
     }
     /**
      * Allows to convert requirements of a node type to tosca template requirements representation
@@ -172,8 +156,8 @@ public class CapabiltyRequirementConvertor {
      * @param nodeType
      * @return
      */
-    public Either<ToscaNodeType, ToscaError> convertRequirements(Component component, ToscaNodeType nodeType) {
-        List<Map<String, ToscaRequirement>> toscaRequirements = convertRequirementsAsList(component);
+    public Either<ToscaNodeType, ToscaError> convertRequirements(Map<String, Component> componentsCache, Component component, ToscaNodeType nodeType) {
+        List<Map<String, ToscaRequirement>> toscaRequirements = convertRequirementsAsList(componentsCache, component);
         if (!toscaRequirements.isEmpty()) {
             nodeType.setRequirements(toscaRequirements);
         }
@@ -194,7 +178,7 @@ public class CapabiltyRequirementConvertor {
         Either<Map<String, String[]>, ToscaError> toscaRequirementsRes = convertSubstitutionMappingRequirementsAsMap(componentsCache, component);
         if(toscaRequirementsRes.isRight()){
             result = Either.right(toscaRequirementsRes.right().value());
-            logger.error("Failed convert requirements for the component {}. ", component.getName());
+            logger.debug("Failed convert requirements for the component {}. ", component.getName());
         } else if (MapUtils.isNotEmpty(toscaRequirementsRes.left().value())) {
             substitutionMappings.setRequirements(toscaRequirementsRes.left().value());
             result = Either.left(substitutionMappings);
@@ -203,13 +187,13 @@ public class CapabiltyRequirementConvertor {
         return result;
     }
 
-    private List<Map<String, ToscaRequirement>> convertRequirementsAsList(Component component) {
+    private List<Map<String, ToscaRequirement>> convertRequirementsAsList(Map<String, Component> componentsCache, Component component) {
         Map<String, List<RequirementDefinition>> requirements = component.getRequirements();
         List<Map<String, ToscaRequirement>> toscaRequirements = new ArrayList<>();
         if (requirements != null) {
             for (Map.Entry<String, List<RequirementDefinition>> entry : requirements.entrySet()) {
                 entry.getValue().stream().filter(r -> filter(component, r.getOwnerId())).forEach(r -> {
-                    ImmutablePair<String, ToscaRequirement> pair = convertRequirement(component, ModelConverter.isAtomicComponent(component), r);
+                    ImmutablePair<String, ToscaRequirement> pair = convertRequirement(componentsCache, component, ModelConverter.isAtomicComponent(component), r);
                     Map<String, ToscaRequirement> requirement = new HashMap<>();
 
                     requirement.put(pair.left, pair.right);
@@ -231,10 +215,6 @@ public class CapabiltyRequirementConvertor {
         return ModelConverter.isAtomicComponent(component) && component.getUniqueId().equals(ownerId);
     }
 
-    private String getSubPathByLastDelimiterAppearance(String path) {
-        return path.substring(path.lastIndexOf(PATH_DELIMITER) + 1);
-    }
-
     private String dropLast( String path, String delimiter ) {
         if (isBlank(path) || isBlank(delimiter)){
             return path;
@@ -261,10 +241,10 @@ public class CapabiltyRequirementConvertor {
         for (Map.Entry<String, List<RequirementDefinition>> entry : requirements.entrySet()) {
             Optional<RequirementDefinition> failedToAddRequirement = entry.getValue()
                     .stream()
-                    .filter(r->!addEntry(componentsCache, toscaRequirements, component, r.getName(), r.getParentName(), r.getOwnerId(), r.getPath()))
+                    .filter(r->!addEntry(componentsCache, toscaRequirements, component, new SubstitutionEntry(r.getName(), r.getParentName(), ""), r.getPreviousName(), r.getOwnerId(), r.getPath()))
                     .findAny();
             if(failedToAddRequirement.isPresent()){
-                logger.error("Failed to convert requirement {} for substitution mappings section of a tosca template of the component {}. ",
+                logger.debug("Failed to convert requirement {} for substitution mappings section of a tosca template of the component {}. ",
                         failedToAddRequirement.get().getName(), component.getName());
                 result = Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
             }
@@ -283,10 +263,10 @@ public class CapabiltyRequirementConvertor {
         for (Map.Entry<String, List<CapabilityDefinition>> entry : capabilities.entrySet()) {
             Optional<CapabilityDefinition> failedToAddRequirement = entry.getValue()
                     .stream()
-                    .filter(c->!addEntry(componentsCache, toscaRequirements, component, c.getName(), c.getParentName(), c.getOwnerId(), c.getPath()))
+                    .filter(c->!addEntry(componentsCache, toscaRequirements, component, new SubstitutionEntry(c.getName(), c.getParentName(), ""), c.getPreviousName(), c.getOwnerId(), c.getPath()))
                     .findAny();
             if(failedToAddRequirement.isPresent()){
-                logger.error("Failed to convert capalility {} for substitution mappings section of a tosca template of the component {}. ",
+                logger.debug("Failed to convert capalility {} for substitution mappings section of a tosca template of the component {}. ",
                         failedToAddRequirement.get().getName(), component.getName());
                 result = Either.right(ToscaError.NODE_TYPE_CAPABILITY_ERROR);
             }
@@ -298,11 +278,9 @@ public class CapabiltyRequirementConvertor {
         return result;
     }
 
-    private boolean addEntry(Map<String,Component> componentsCache, Map<String, String[]> capReqMap, Component component, String name, String parentName, String ownerId, List<String> path){
-
-        SubstituitionEntry entry = new SubstituitionEntry(name, parentName, "");
-
-        if(shouldBuildSubstitutionName(component, path) && !buildSubstitutedNamePerInstance(componentsCache, component, name, path, ownerId, entry)){
+    private boolean addEntry(Map<String, Component> componentsCache, Map<String, String[]> capReqMap, Component component, SubstitutionEntry entry, String previousName, String ownerId, List<String> path){
+    
+        if(shouldBuildSubstitutionName(component, path) && !buildSubstitutedNamePerInstance(componentsCache, component, entry.getFullName(), previousName, path, ownerId, entry)){
             return false;
         }
         logger.debug("The requirement/capability {} belongs to the component {} ", entry.getFullName(), component.getUniqueId());
@@ -315,96 +293,106 @@ public class CapabiltyRequirementConvertor {
     }
 
     private boolean shouldBuildSubstitutionName(Component component, List<String> path) {
-        return !ToscaUtils.isComplexVfc(component) && isNotEmpty(path) && path.iterator().hasNext();
-    }
+        return ToscaUtils.isNotComplexVfc(component) && isNotEmpty(path) && path.iterator().hasNext();
+    }
+
+    private boolean buildSubstitutedNamePerInstance(Map<String, Component> componentsCache, Component component, String name, String previousName, List<String> path, String ownerId, SubstitutionEntry entry) {
+        String fullName;
+        String sourceName;
+        String prefix;
+        if(CollectionUtils.isNotEmpty(component.getGroups())) {
+            Optional<GroupDefinition> groupOpt = component.getGroups().stream().filter(g -> g.getUniqueId().equals(ownerId)).findFirst();
+            if (groupOpt.isPresent()) {
+                prefix = buildCapReqNamePrefix(groupOpt.get().getNormalizedName());
+                if(ComponentUtilities.isNotUpdatedCapReqName(prefix, name, previousName)){
+                    sourceName = name;
+                    fullName = prefix + sourceName;
+                } else {
+                    sourceName = previousName;
+                    fullName = name;
+                }
+                entry.setFullName(fullName);
+                entry.setSourceName(sourceName);
+                entry.setOwner(groupOpt.get().getNormalizedName());
+                return true;
+            }
+        }
 
-    private boolean buildSubstitutedNamePerInstance(Map<String, Component> componentsCache, Component component, String name, List<String> path, String ownerId, SubstituitionEntry entry) {
         Optional<ComponentInstance> ci = component.getComponentInstances().stream().filter(c->c.getUniqueId().equals(Iterables.getLast(path))).findFirst();
         if(!ci.isPresent()){
-            logger.error("Failed to find ci in the path is {} component {}", path, component.getUniqueId());
+            logger.debug("Failed to find ci in the path is {} component {}", path, component.getUniqueId());
 
             Collections.reverse(path);
 
-            logger.error("try to reverse path {} component {}", path, component.getUniqueId());
+            logger.debug("try to reverse path {} component {}", path, component.getUniqueId());
             ci = component.getComponentInstances().stream().filter(c->c.getUniqueId().equals(Iterables.getLast(path))).findFirst();
         }
         if(ci.isPresent()){
-            Either<String, Boolean> buildSubstitutedName = buildSubstitutedName(componentsCache, name, path, ownerId, ci.get());
-            if(buildSubstitutedName.isRight()){
-                logger.error("Failed buildSubstitutedName name {}  path {} component {}", name, path, component.getUniqueId());
-                return false;
+            prefix = buildCapReqNamePrefix(ci.get().getNormalizedName());
+            if(ComponentUtilities.isNotUpdatedCapReqName(prefix, name, previousName)){
+                Either<String, Boolean> buildSubstitutedName = buildSubstitutedName(componentsCache, name, previousName, path, ownerId, ci.get());
+                if(buildSubstitutedName.isRight()){
+                    logger.debug("Failed buildSubstitutedName name {}  path {} component {}", name, path, component.getUniqueId());
+                    return false;
+                }
+                sourceName = buildSubstitutedName.left().value();
+                fullName = prefix + sourceName;
+            } else {
+                sourceName = previousName;
+                fullName = name;
             }
-            entry.setFullName(ci.get().getNormalizedName() + '.' + buildSubstitutedName.left().value());
-            entry.setSourceName(buildSubstitutedName.left().value());
+            entry.setFullName(fullName);
+            entry.setSourceName(sourceName);
         } else {
-            logger.error("Failed to find ci in the path is {} component {}", path, component.getUniqueId());
+            logger.debug("Failed to find ci in the path is {} component {}", path, component.getUniqueId());
             return false;
         }
         return true;
     }
 
-    private void addEntry(Map<String, String[]> toscaRequirements, Component component, List<String> capPath, SubstituitionEntry entry) {
-        Optional<ComponentInstance> findFirst = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(Iterables.getLast(capPath))).findFirst();
+    private void addEntry(Map<String, String[]> toscaRequirements, Component component, List<String> capPath, SubstitutionEntry entry) {
+        Optional<ComponentInstance> findFirst = component.safeGetComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(Iterables.getLast(capPath))).findFirst();
         if (findFirst.isPresent()) {
             entry.setOwner(findFirst.get().getNormalizedName());
         }
         toscaRequirements.put(entry.getFullName(), new String[] { entry.getOwner(), entry.getSourceName() });
     }
 
-    public Either<String, Boolean> buildSubstitutedName(Map<String, Component> componentsCache, String name, List<String> path, String ownerId, ComponentInstance instance) {
-
-        Either<String, Boolean> result = null;
+    public Either<String, Boolean> buildSubstitutedName(Map<String, Component> componentsCache, String name, String previousName, List<String> path, String ownerId, ComponentInstance instance) {
+        if(StringUtils.isNotEmpty(previousName)){
+            return Either.left(name);
+        }
         Either<Component, Boolean> getOriginRes = getOriginComponent(componentsCache, instance);
         if(getOriginRes.isRight()){
-            logger.error("Failed to build substituted name for the capability/requirement {}. Failed to get an origin component with uniqueId {}", name, instance.getComponentUid());
-            result = Either.right(false);
-        }
-        if(result == null){
-            List<String> reducedPath = ownerId !=null ? getReducedPathByOwner(path , ownerId ) : getReducedPath(path) ;
-            logger.debug("reducedPath for ownerId {}, reducedPath {} ", ownerId, reducedPath);
-            reducedPath.remove(reducedPath.size()-1);
-            result = buildSubstitutedName(componentsCache, getOriginRes.left().value(), reducedPath, name);
+            logger.debug("Failed to build substituted name for the capability/requirement {}. Failed to get an origin component with uniqueId {}", name, instance.getComponentUid());
+            return Either.right(false);
         }
-        return result;
+        List<String> reducedPath = ownerId !=null ? getReducedPathByOwner(path , ownerId ) : getReducedPath(path) ;
+        logger.debug("reducedPath for ownerId {}, reducedPath {} ", ownerId, reducedPath);
+        reducedPath.remove(reducedPath.size() - 1);
+        return buildSubstitutedName(componentsCache, getOriginRes.left().value(), reducedPath, name, previousName);
     }
 
-    private String getRequirementPath(Component component, RequirementDefinition r) {
-
-        // Evg : for the last in path take real instance name and not "decrypt" unique id. ( instance name can be change and not equal to id..)
-        // dirty quick fix. must be changed as capability redesign
-        List<String> capPath = r.getPath();
-        String lastInPath = capPath.get(capPath.size() - 1);
-        Optional<ComponentInstance> findFirst = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(lastInPath)).findFirst();
-        if (findFirst.isPresent()) {
-            String lastInPathName = findFirst.get().getNormalizedName();
-
-            if (capPath.size() > 1) {
-                List<String> pathArray = Lists.reverse(capPath.stream().map(path -> ValidationUtils.normalizeComponentInstanceName(getSubPathByLastDelimiterAppearance(path))).collect(Collectors.toList()));
-
-                return new StringBuilder().append(lastInPathName).append(PATH_DELIMITER).append(String.join(PATH_DELIMITER, pathArray.subList(1, pathArray.size() ))).append(PATH_DELIMITER).append(r.getName()).toString();
-            }else{
-                return new StringBuilder().append(lastInPathName).append(PATH_DELIMITER).append(r.getName()).toString();
-            }
-        }
-        return "";
+    private String buildReqNamePerOwnerByPath(Map<String, Component> componentsCache, Component component, RequirementDefinition r) {
+        return buildCapReqNamePerOwnerByPath(componentsCache, component, r.getName(), r.getPreviousName(), r.getPath());
     }
 
-    private ImmutablePair<String, ToscaRequirement> convertRequirement(Component component, boolean isNodeType, RequirementDefinition r) {
+    private ImmutablePair<String, ToscaRequirement> convertRequirement(Map<String, Component> componentsCache, Component component, boolean isNodeType, RequirementDefinition r) {
         String name = r.getName();
-        if (!isNodeType) {
-            name = getRequirementPath(component, r);
+        if (!isNodeType && ToscaUtils.isNotComplexVfc(component)) {
+            name = buildReqNamePerOwnerByPath(componentsCache, component, r);
         }
         logger.debug("the requirement {} belongs to resource {} ", name, component.getUniqueId());
         ToscaRequirement toscaRequirement = new ToscaRequirement();
 
-        List<Object> occurences = new ArrayList<>();
-        occurences.add(Integer.valueOf(r.getMinOccurrences()));
+        List<Object> occurrences = new ArrayList<>();
+        occurrences.add(Integer.valueOf(r.getMinOccurrences()));
         if (r.getMaxOccurrences().equals(RequirementDataDefinition.MAX_OCCURRENCES)) {
-            occurences.add(r.getMaxOccurrences());
+            occurrences.add(r.getMaxOccurrences());
         } else {
-            occurences.add(Integer.valueOf(r.getMaxOccurrences()));
+            occurrences.add(Integer.valueOf(r.getMaxOccurrences()));
         }
-        toscaRequirement.setOccurrences(occurences);
+        toscaRequirement.setOccurrences(occurrences);
         toscaRequirement.setNode(r.getNode());
         toscaRequirement.setCapability(r.getCapability());
         toscaRequirement.setRelationship(r.getRelationship());
@@ -418,13 +406,13 @@ public class CapabiltyRequirementConvertor {
      * @param dataTypes
      * @return
      */
-    public Map<String, ToscaCapability> convertCapabilities(Component component, Map<String, DataTypeDefinition> dataTypes) {
+    public Map<String, ToscaCapability> convertCapabilities(Map<String, Component> componentsCache, Component component, Map<String, DataTypeDefinition> dataTypes) {
         Map<String, List<CapabilityDefinition>> capabilities = component.getCapabilities();
         Map<String, ToscaCapability> toscaCapabilities = new HashMap<>();
         if (capabilities != null) {
             boolean isNodeType = ModelConverter.isAtomicComponent(component);
             for (Map.Entry<String, List<CapabilityDefinition>> entry : capabilities.entrySet()) {
-                entry.getValue().stream().filter(c -> filter(component, c.getOwnerId())).forEach(c -> convertCapabilty(component, toscaCapabilities, isNodeType, c, dataTypes , c.getName()));
+                entry.getValue().stream().filter(c -> filter(component, c.getOwnerId())).forEach(c -> convertCapability(componentsCache, component, toscaCapabilities, isNodeType, c, dataTypes , c.getName()));
             }
         } else {
             logger.debug(NO_CAPABILITIES);
@@ -447,7 +435,10 @@ public class CapabiltyRequirementConvertor {
         if (capabilities != null) {
             boolean isNodeType = ModelConverter.isAtomicComponent(component);
             for (Map.Entry<String, List<CapabilityDefinition>> entry : capabilities.entrySet()) {
-                entry.getValue().stream().forEach(c -> convertCapabilty(proxyComponent, toscaCapabilities, isNodeType, c, dataTypes , buildCapabilityNameForComponentInstance( componentCache , instanceProxy , c )));
+                entry.getValue()
+                        .stream()
+                        .forEach(c -> convertProxyCapability(toscaCapabilities, c, dataTypes ,
+                                buildCapabilityNameForComponentInstance( componentCache , instanceProxy , c )));
             }
         } else {
             logger.debug(NO_CAPABILITIES);
@@ -474,44 +465,55 @@ public class CapabiltyRequirementConvertor {
         return res;
     }
 
-    private String getCapabilityPath(CapabilityDefinition c, Component component) {
-        // Evg : for the last in path take real instance name and not "decrypt" unique id. ( instance name can be change and not equal to id..)
-        // dirty quick fix. must be changed as capability redesign
-        List<String> capPath = c.getPath();
-        String lastInPath = capPath.get(capPath.size() - 1);
-        Optional<ComponentInstance> findFirst = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(lastInPath)).findFirst();
-        if (findFirst.isPresent()) {
-            String lastInPathName = findFirst.get().getNormalizedName();
+    private String buildCapNamePerOwnerByPath(Map<String, Component> componentsCache, CapabilityDefinition c, Component component) {
+        return buildCapReqNamePerOwnerByPath(componentsCache, component, c.getName(), c.getPreviousName(), c.getPath());
+    }
 
-            if (capPath.size() > 1) {
-                List<String> pathArray = Lists.reverse(capPath.stream().map(path -> ValidationUtils.normalizeComponentInstanceName(getSubPathByLastDelimiterAppearance(path))).collect(Collectors.toList()));
+    private void convertProxyCapability(Map<String, ToscaCapability> toscaCapabilities, CapabilityDefinition c, Map<String, DataTypeDefinition> dataTypes, String capabilityName) {
+        ToscaCapability toscaCapability = new ToscaCapability();
+        toscaCapability.setDescription(c.getDescription());
+        toscaCapability.setType(c.getType());
 
-                return new StringBuilder().append(lastInPathName).append(PATH_DELIMITER).append(String.join(PATH_DELIMITER, pathArray.subList(1, pathArray.size() ))).append(PATH_DELIMITER).append(c.getName()).toString();
-            }else{
-                return new StringBuilder().append(lastInPathName).append(PATH_DELIMITER).append(c.getName()).toString();
+        List<Object> occurrences = new ArrayList<>();
+        occurrences.add(Integer.valueOf(c.getMinOccurrences()));
+        if (c.getMaxOccurrences().equals(CapabilityDataDefinition.MAX_OCCURRENCES)) {
+            occurrences.add(c.getMaxOccurrences());
+        } else {
+            occurrences.add(Integer.valueOf(c.getMaxOccurrences()));
+        }
+        toscaCapability.setOccurrences(occurrences);
+
+        toscaCapability.setValid_source_types(c.getValidSourceTypes());
+        List<ComponentInstanceProperty> properties = c.getProperties();
+        if (isNotEmpty(properties)) {
+            Map<String, ToscaProperty> toscaProperties = new HashMap<>();
+            for (PropertyDefinition property : properties) {
+                ToscaProperty toscaProperty = PropertyConvertor.getInstance().convertProperty(dataTypes, property, true);
+                toscaProperties.put(property.getName(), toscaProperty);
             }
+            toscaCapability.setProperties(toscaProperties);
         }
-        return "";
+        toscaCapabilities.put(capabilityName, toscaCapability);
     }
 
-    private void convertCapabilty(Component component, Map<String, ToscaCapability> toscaCapabilities, boolean isNodeType, CapabilityDefinition c, Map<String, DataTypeDefinition> dataTypes , String capabilityName) {
+    private void convertCapability(Map<String, Component> componentsCache, Component component, Map<String, ToscaCapability> toscaCapabilities, boolean isNodeType, CapabilityDefinition c, Map<String, DataTypeDefinition> dataTypes , String capabilityName) {
         String name = isNoneBlank(capabilityName) ? capabilityName : c.getName();
-        if (!isNodeType) {
-            name = getCapabilityPath(c, component);
+        if (!isNodeType && ToscaUtils.isNotComplexVfc(component)) {
+            name = buildCapNamePerOwnerByPath(componentsCache, c, component);
         }
-        logger.debug("the capabilty {} belongs to resource {} ", name, component.getUniqueId());
+        logger.debug("The capability {} belongs to resource {} ", name, component.getUniqueId());
         ToscaCapability toscaCapability = new ToscaCapability();
         toscaCapability.setDescription(c.getDescription());
         toscaCapability.setType(c.getType());
 
-        List<Object> occurences = new ArrayList<>();
-        occurences.add(Integer.valueOf(c.getMinOccurrences()));
+        List<Object> occurrences = new ArrayList<>();
+        occurrences.add(Integer.valueOf(c.getMinOccurrences()));
         if (c.getMaxOccurrences().equals(CapabilityDataDefinition.MAX_OCCURRENCES)) {
-            occurences.add(c.getMaxOccurrences());
+            occurrences.add(c.getMaxOccurrences());
         } else {
-            occurences.add(Integer.valueOf(c.getMaxOccurrences()));
+            occurrences.add(Integer.valueOf(c.getMaxOccurrences()));
         }
-        toscaCapability.setOccurrences(occurences);
+        toscaCapability.setOccurrences(occurrences);
 
         toscaCapability.setValid_source_types(c.getValidSourceTypes());
         List<ComponentInstanceProperty> properties = c.getProperties();
@@ -525,29 +527,63 @@ public class CapabiltyRequirementConvertor {
         }
         toscaCapabilities.put(name, toscaCapability);
     }
+
+    private String buildCapReqNamePerOwnerByPath(Map<String, Component> componentsCache, Component component, String name, String previousName, List<String> path) {
+        String ownerId = path.get(path.size() - 1);
+        String prefix;
+        if(CollectionUtils.isNotEmpty(component.getGroups())) {
+            Optional<GroupDefinition> groupOpt = component.getGroups().stream().filter(g -> g.getUniqueId().equals(ownerId)).findFirst();
+            if (groupOpt.isPresent()) {
+                prefix = buildCapReqNamePrefix(groupOpt.get().getNormalizedName());
+                if(ComponentUtilities.isNotUpdatedCapReqName(prefix, name, previousName)){
+                    return prefix + name;
+                }
+                return name;
+            }
+        }
+        Optional<ComponentInstance> ci = component.getComponentInstances().stream().filter(c->c.getUniqueId().equals(Iterables.getLast(path))).findFirst();
+        if(!ci.isPresent()){
+            logger.debug("Failed to find ci in the path is {} component {}", path, component.getUniqueId());
+
+            Collections.reverse(path);
+
+            logger.debug("try to reverse path {} component {}", path, component.getUniqueId());
+            ci = component.getComponentInstances().stream().filter(c->c.getUniqueId().equals(Iterables.getLast(path))).findFirst();
+        }
+        if(ci.isPresent()){
+            prefix = buildCapReqNamePrefix(ci.get().getNormalizedName());
+            if(ComponentUtilities.isNotUpdatedCapReqName(prefix, name, previousName)){
+                Either<String, Boolean> buildSubstitutedName = buildSubstitutedName(componentsCache, name, previousName, path, ownerId, ci.get());
+                if(buildSubstitutedName.isRight()){
+                    logger.debug("Failed buildSubstitutedName name {}  path {} component {}", name, path, component.getUniqueId());
+                }
+                return prefix + buildSubstitutedName.left().value();
+            }
+            return name;
+        }
+        return StringUtils.EMPTY;
+    }
     /**
      * Allows to build substituted name of capability\requirement of the origin component instance according to the path
      * @param componentsCache
      * @param originComponent
      * @param path
      * @param name
+     * @param previousName
      * @return
      */
-    public Either<String, Boolean> buildSubstitutedName(Map<String, Component> componentsCache, Component originComponent, List<String> path, String name) {
+    public Either<String, Boolean> buildSubstitutedName(Map<String, Component> componentsCache, Component originComponent, List<String> path, String name, String previousName) {
+        if(StringUtils.isNotEmpty(previousName)){
+            return Either.left(name);
+        }
         StringBuilder substitutedName = new StringBuilder();
         boolean nameBuiltSuccessfully = true;
-        Either<String, Boolean> result;
-        if(isNotEmpty(path) && !ToscaUtils.isComplexVfc(originComponent)){
+        if(isNotEmpty(path) && ToscaUtils.isNotComplexVfc(originComponent)){
             List<String> reducedPath = getReducedPath(path);
             Collections.reverse(reducedPath);
             nameBuiltSuccessfully = appendNameRecursively(componentsCache, originComponent, reducedPath.iterator(), substitutedName);
         }
-        if(nameBuiltSuccessfully){
-            result = Either.left(substitutedName.append(name).toString());
-        } else {
-            result = Either.right(nameBuiltSuccessfully);
-        }
-        return result;
+        return nameBuiltSuccessfully ? Either.left(substitutedName.append(name).toString()) : Either.right(nameBuiltSuccessfully);
     }
 
     protected List<String> getReducedPathByOwner(List<String> path , String ownerId) {
@@ -571,19 +607,27 @@ public class CapabiltyRequirementConvertor {
     }
 
     private boolean appendNameRecursively(Map<String, Component> componentsCache, Component originComponent, Iterator<String> instanceIdIter, StringBuilder substitutedName) {
-        if(isNotEmpty(originComponent.getComponentInstances()) && instanceIdIter.hasNext() && !ToscaUtils.isComplexVfc(originComponent)){
-            String instanceId = instanceIdIter.next();
-            Optional<ComponentInstance> instanceOpt = originComponent.getComponentInstances().stream().filter(i -> i.getUniqueId().equals(instanceId)).findFirst();
-            if(!instanceOpt.isPresent()){
-                logger.error("Failed to find an instance with uniqueId {} on a component with uniqueId {}", instanceId, originComponent.getUniqueId());
-                return false;
-            }
-            substitutedName.append(instanceOpt.get().getNormalizedName()).append('.');
-            Either<Component, Boolean> getOriginRes = getOriginComponent(componentsCache, instanceOpt.get());
-            if(getOriginRes.isRight()){
+        if(isNotEmpty(originComponent.getComponentInstances()) && instanceIdIter.hasNext() && ToscaUtils.isNotComplexVfc(originComponent)){
+            String ownerId = instanceIdIter.next();
+            Optional<ComponentInstance> instanceOpt = originComponent.getComponentInstances().stream().filter(i -> i.getUniqueId().equals(ownerId)).findFirst();
+            if(instanceOpt.isPresent()){
+                substitutedName.append(instanceOpt.get().getNormalizedName()).append(PATH_DELIMITER);
+                Either<Component, Boolean> getOriginRes = getOriginComponent(componentsCache, instanceOpt.get());
+                if(getOriginRes.isRight()){
+                    return false;
+                }
+                appendNameRecursively(componentsCache, getOriginRes.left().value(), instanceIdIter, substitutedName);
+            } else if(CollectionUtils.isNotEmpty(originComponent.getGroups())){
+                Optional<GroupDefinition> groupOpt = originComponent.getGroups().stream().filter(g -> g.getUniqueId().equals(ownerId)).findFirst();
+                if(!groupOpt.isPresent()){
+                    logger.debug("Failed to find an capability owner with uniqueId {} on a component with uniqueId {}", ownerId, originComponent.getUniqueId());
+                    return false;
+                }
+                substitutedName.append(groupOpt.get().getNormalizedName()).append(PATH_DELIMITER);
+            } else {
+                logger.debug("Failed to find an capability owner with uniqueId {} on a component with uniqueId {}", ownerId, originComponent.getUniqueId());
                 return false;
             }
-            appendNameRecursively(componentsCache, getOriginRes.left().value(), instanceIdIter, substitutedName);
         }
         return true;
     }
@@ -597,7 +641,7 @@ public class CapabiltyRequirementConvertor {
             ComponentParametersView filter = getFilter(instance);
             getOriginRes = toscaOperationFacade.getToscaElement(instance.getActualComponentUid(), filter);
             if(getOriginRes.isRight()){
-                logger.error("Failed to get an origin component with uniqueId {}", instance.getActualComponentUid());
+                logger.debug("Failed to get an origin component with uniqueId {}", instance.getActualComponentUid());
                 result = Either.right(false);
             } else {
                 result = Either.left(getOriginRes.left().value());
@@ -615,6 +659,9 @@ public class CapabiltyRequirementConvertor {
             filter.setIgnoreRequirements(false);
             filter.setIgnoreCategories(false);
         }
+        if(instance.getOriginType() == OriginTypeEnum.VF){
+            filter.setIgnoreGroups(false);
+        }
         return filter;
     }