Fix 'Unable to drag a VFC on to composition if an existing VFC instance has the same...
[sdc.git] / catalog-model / src / main / java / org / openecomp / sdc / be / model / jsonjanusgraph / operations / ToscaOperationFacade.java
index 06e23f0..d654f23 100644 (file)
  */
 package org.openecomp.sdc.be.model.jsonjanusgraph.operations;
 
-import static java.util.Objects.requireNonNull;
-import static org.apache.commons.collections.CollectionUtils.isEmpty;
-import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
-import static org.janusgraph.core.attribute.Text.REGEX;
-
 import com.vdurmont.semver4j.Semver;
 import com.vdurmont.semver4j.Semver.SemverType;
 import fj.data.Either;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumMap;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Optional;
-import java.util.Set;
-import java.util.function.BiPredicate;
-import java.util.stream.Collectors;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -52,9 +33,10 @@ import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.janusgraph.graphdb.query.JanusGraphPredicate;
 import org.openecomp.sdc.be.config.Configuration;
 import org.openecomp.sdc.be.config.ConfigurationManager;
+import org.openecomp.sdc.be.dao.api.exception.JanusGraphException;
+import org.openecomp.sdc.be.dao.janusgraph.HealingJanusGraphDao;
 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
-import org.openecomp.sdc.be.dao.jsongraph.HealingJanusGraphDao;
 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
@@ -64,6 +46,7 @@ import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.DataTypeDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.ListCapabilityDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.ListRequirementDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.MapArtifactDataDefinition;
@@ -78,6 +61,7 @@ import org.openecomp.sdc.be.datatypes.elements.RequirementDataDefinition;
 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
+import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.PromoteVersionEnum;
 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
@@ -98,6 +82,7 @@ import org.openecomp.sdc.be.model.DistributionStatusEnum;
 import org.openecomp.sdc.be.model.GroupDefinition;
 import org.openecomp.sdc.be.model.GroupInstance;
 import org.openecomp.sdc.be.model.InputDefinition;
+import org.openecomp.sdc.be.model.InterfaceDefinition;
 import org.openecomp.sdc.be.model.LifecycleStateEnum;
 import org.openecomp.sdc.be.model.OutputDefinition;
 import org.openecomp.sdc.be.model.PolicyDefinition;
@@ -112,8 +97,10 @@ import org.openecomp.sdc.be.model.catalog.CatalogComponent;
 import org.openecomp.sdc.be.model.jsonjanusgraph.config.ContainerInstanceTypesData;
 import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.TopologyTemplate;
 import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.ToscaElement;
+import org.openecomp.sdc.be.model.jsonjanusgraph.operations.exception.ToscaOperationExceptionSupplier;
 import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter;
 import org.openecomp.sdc.be.model.operations.StorageException;
+import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
@@ -121,10 +108,37 @@ import org.openecomp.sdc.be.model.utils.GroupUtils;
 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
+import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
 import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.openecomp.sdc.common.util.ValidationUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.function.BiPredicate;
+import java.util.stream.Collectors;
+
+import static java.util.Objects.requireNonNull;
+import static org.apache.commons.collections.CollectionUtils.isEmpty;
+import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
+import static org.janusgraph.core.attribute.Text.REGEX;
+import static org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum.TOPOLOGY_TEMPLATE;
+
 @org.springframework.stereotype.Component("tosca-operation-facade")
 public class ToscaOperationFacade {
 
@@ -136,11 +150,16 @@ public class ToscaOperationFacade {
     private static final String FAILED_TO_GET_UPDATED_RESOURCE_STATUS_IS = "Failed to get updated resource {}. Status is {}. ";
     private static final String FAILED_TO_ADD_THE_PROPERTY_TO_THE_RESOURCE_STATUS_IS = "Failed to add the property {} to the resource {}. Status is {}. ";
     private static final String SERVICE = "service";
+    private static final String VF = "VF";
     private static final String NOT_SUPPORTED_COMPONENT_TYPE = "Not supported component type {}";
     private static final String COMPONENT_CREATED_SUCCESSFULLY = "Component created successfully!!!";
+    private static final String INPUTS_ASSOCIATED_TO_COMPONENT_SUCCESSFULLY = "Inputs associated to component successfully!";
+    private static final String OUTPUTS_ASSOCIATED_TO_COMPONENT_SUCCESSFULLY = "Outputs associated to component successfully!";
     private static final String COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR = "Couldn't fetch component with and unique id {}, error: {}";
     private static final Logger log = Logger.getLogger(ToscaOperationFacade.class.getName());
     @Autowired
+    private IGraphLockOperation graphLockOperation;
+    @Autowired
     private NodeTypeOperation nodeTypeOperation;
     @Autowired
     private TopologyTemplateOperation topologyTemplateOperation;
@@ -347,19 +366,56 @@ public class ToscaOperationFacade {
         return ModelConverter.isAtomicComponent(component) ? nodeTypeOperation : topologyTemplateOperation;
     }
 
-    public <T extends Component> Either<T, StorageOperationStatus> getLatestByToscaResourceName(String toscaResourceName) {
-        return getLatestByName(GraphPropertyEnum.TOSCA_RESOURCE_NAME, toscaResourceName);
+    public <T extends Component> Either<T, StorageOperationStatus> getLatestByToscaResourceNameAndModel(final String toscaResourceName,
+                                                                                                        final String model) {
+        return getLatestByNameAndModel(toscaResourceName, JsonParseFlagEnum.ParseMetadata, new ComponentParametersView(), model);
+    }
+
+    private <T extends Component> Either<T, StorageOperationStatus> getLatestByNameAndModel(final String nodeName,
+                                                                                            final JsonParseFlagEnum parseFlag,
+                                                                                            final ComponentParametersView filter,
+                                                                                            final String model) {
+        Either<T, StorageOperationStatus> result;
+        final Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
+        final Map<GraphPropertyEnum, Object> propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
+        propertiesToMatch.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, nodeName);
+        propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
+        propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
+        final Either<List<GraphVertex>, JanusGraphOperationStatus> highestResources = janusGraphDao
+            .getByCriteria(null, propertiesToMatch, propertiesNotToMatch, parseFlag, model);
+        if (highestResources.isRight()) {
+            final JanusGraphOperationStatus status = highestResources.right().value();
+            log.debug("failed to find resource with name {}. status={} ", nodeName, status);
+            result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
+            return result;
+        }
+        final List<GraphVertex> resources = highestResources.left().value();
+        double version = 0.0;
+        GraphVertex highestResource = null;
+        for (final GraphVertex vertex : resources) {
+            final Object versionObj = vertex.getMetadataProperty(GraphPropertyEnum.VERSION);
+            double resourceVersion = Double.parseDouble((String) versionObj);
+            if (resourceVersion > version) {
+                version = resourceVersion;
+                highestResource = vertex;
+            }
+        }
+        return getToscaElementByOperation(highestResource, filter);
+    }
+
+    public <T extends Component> Either<T, StorageOperationStatus> getLatestByToscaResourceName(String toscaResourceName, String modelName) {
+        return getLatestByName(GraphPropertyEnum.TOSCA_RESOURCE_NAME, toscaResourceName, modelName);
     }
 
     public <T extends Component> Either<T, StorageOperationStatus> getFullLatestComponentByToscaResourceName(String toscaResourceName) {
         ComponentParametersView fetchAllFilter = new ComponentParametersView();
         fetchAllFilter.setIgnoreServicePath(true);
         fetchAllFilter.setIgnoreCapabiltyProperties(false);
-        return getLatestByName(GraphPropertyEnum.TOSCA_RESOURCE_NAME, toscaResourceName, JsonParseFlagEnum.ParseAll, fetchAllFilter);
+        return getLatestByName(GraphPropertyEnum.TOSCA_RESOURCE_NAME, toscaResourceName, JsonParseFlagEnum.ParseAll, fetchAllFilter, null);
     }
 
-    public <T extends Component> Either<T, StorageOperationStatus> getLatestByName(String resourceName) {
-        return getLatestByName(GraphPropertyEnum.NAME, resourceName);
+    public <T extends Component> Either<T, StorageOperationStatus> getLatestByName(String resourceName, String modelName) {
+        return getLatestByName(GraphPropertyEnum.NAME, resourceName, modelName);
     }
 
     public StorageOperationStatus validateCsarUuidUniqueness(String csarUUID) {
@@ -418,7 +474,7 @@ public class ToscaOperationFacade {
         props.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
         Map<String, Entry<JanusGraphPredicate, Object>> predicateCriteria = getVendorVersionPredicate(vendorRelease);
         Either<List<GraphVertex>, JanusGraphOperationStatus> getLatestRes = janusGraphDao
-            .getByCriteria(vertexType, props, null, predicateCriteria, parseFlag);
+            .getByCriteria(vertexType, props, null, predicateCriteria, parseFlag, null);
         if (getLatestRes.isRight() || CollectionUtils.isEmpty(getLatestRes.left().value())) {
             getLatestRes = janusGraphDao.getByCriteria(vertexType, props, parseFlag);
         }
@@ -445,7 +501,8 @@ public class ToscaOperationFacade {
         });
     }
 
-    public <T extends Component> Either<T, StorageOperationStatus> getByToscaResourceNameAndVersion(final String toscaResourceName, final String version) {
+    public <T extends Component> Either<T, StorageOperationStatus> getByToscaResourceNameAndVersion(final String toscaResourceName,
+                                                                                                    final String version, final String model) {
         Either<T, StorageOperationStatus> result;
 
         Map<GraphPropertyEnum, Object> hasProperties = new EnumMap<>(GraphPropertyEnum.class);
@@ -456,7 +513,7 @@ public class ToscaOperationFacade {
         hasNotProperties.put(GraphPropertyEnum.IS_DELETED, true);
 
         Either<List<GraphVertex>, JanusGraphOperationStatus> getResourceRes = janusGraphDao
-            .getByCriteria(VertexTypeEnum.NODE_TYPE, hasProperties, hasNotProperties, JsonParseFlagEnum.ParseAll);
+            .getByCriteria(VertexTypeEnum.NODE_TYPE, hasProperties, hasNotProperties, JsonParseFlagEnum.ParseAll, model);
         if (getResourceRes.isRight()) {
             JanusGraphOperationStatus status = getResourceRes.right().value();
             log.debug("failed to find resource with toscaResourceName {}, version {}. Status is {} ", toscaResourceName, version, status);
@@ -482,6 +539,28 @@ public class ToscaOperationFacade {
         return predicateCriteria;
     }
 
+    public boolean isNodeAssociatedToModel(final String model, final Resource resource) {
+        final List<GraphVertex> modelElementVertices = getResourceModelElementVertices(resource);
+        if (model == null) {
+            return modelElementVertices.isEmpty();
+        }
+        return modelElementVertices.stream().anyMatch(graphVertex -> graphVertex.getMetadataProperty(GraphPropertyEnum.NAME).equals(model));
+    }
+
+    public List<GraphVertex> getResourceModelElementVertices(final Resource resource) {
+        final Either<GraphVertex, JanusGraphOperationStatus> vertex =
+            janusGraphDao.getVertexById(resource.getUniqueId(), JsonParseFlagEnum.NoParse);
+        if (vertex.isRight() || Objects.isNull(vertex.left().value())) {
+            return Collections.emptyList();
+        }
+        final Either<List<GraphVertex>, JanusGraphOperationStatus> nodeModelVertices =
+            janusGraphDao.getParentVertices(vertex.left().value(), EdgeLabelEnum.MODEL_ELEMENT, JsonParseFlagEnum.NoParse);
+        if (nodeModelVertices.isRight() || nodeModelVertices.left().value() == null) {
+            return Collections.emptyList();
+        }
+        return nodeModelVertices.left().value();
+    }
+
     private boolean isValidForVendorRelease(final GraphVertex resource, final String vendorRelease) {
         if (!vendorRelease.equals("1.0")) {
             try {
@@ -528,7 +607,7 @@ public class ToscaOperationFacade {
 
     public Either<Resource, StorageOperationStatus> getLatestResourceByToscaResourceName(String toscaResourceName) {
         if (toscaResourceName != null && toscaResourceName.contains("org.openecomp.resource.vf")) {
-            return getLatestResourceByToscaResourceName(toscaResourceName, VertexTypeEnum.TOPOLOGY_TEMPLATE, JsonParseFlagEnum.ParseMetadata);
+            return getLatestResourceByToscaResourceName(toscaResourceName, TOPOLOGY_TEMPLATE, JsonParseFlagEnum.ParseMetadata);
         } else {
             return getLatestResourceByToscaResourceName(toscaResourceName, VertexTypeEnum.NODE_TYPE, JsonParseFlagEnum.ParseMetadata);
         }
@@ -605,7 +684,7 @@ public class ToscaOperationFacade {
     public Either<List<RequirementCapabilityRelDef>, StorageOperationStatus> associateResourceInstances(Component component, String componentId,
                                                                                                         List<RequirementCapabilityRelDef> relations) {
         Either<List<RequirementCapabilityRelDef>, StorageOperationStatus> reqAndCapListEither = nodeTemplateOperation
-            .associateResourceInstances(component, componentId, relations);
+            .associateResourceInstances(componentId, relations);
         if (component != null) {
             updateInstancesCapAndReqOnComponentFromDB(component);
         }
@@ -708,7 +787,7 @@ public class ToscaOperationFacade {
         return updateToscaElement(componentToUpdate, new ComponentParametersView());
     }
 
-    public <T extends Component> Either<T, StorageOperationStatus> updateToscaElement(T componentToUpdate, ComponentParametersView filterResult) {
+    private <T extends Component> Either<T, StorageOperationStatus> updateToscaElement(T componentToUpdate, ComponentParametersView filterResult) {
         String componentId = componentToUpdate.getUniqueId();
         Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
         if (getVertexEither.isRight()) {
@@ -732,13 +811,13 @@ public class ToscaOperationFacade {
     }
 
     private <T extends Component> Either<T, StorageOperationStatus> getLatestByName(GraphPropertyEnum property, String nodeName,
-                                                                                    JsonParseFlagEnum parseFlag) {
-        return getLatestByName(property, nodeName, parseFlag, new ComponentParametersView());
+                                                                                    JsonParseFlagEnum parseFlag, String modelName) {
+        return getLatestByName(property, nodeName, parseFlag, new ComponentParametersView(), modelName);
     }
-    // endregion
 
     private <T extends Component> Either<T, StorageOperationStatus> getLatestByName(GraphPropertyEnum property, String nodeName,
-                                                                                    JsonParseFlagEnum parseFlag, ComponentParametersView filter) {
+                                                                                    JsonParseFlagEnum parseFlag, ComponentParametersView filter,
+                                                                                    String model) {
         Either<T, StorageOperationStatus> result;
         Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
         Map<GraphPropertyEnum, Object> propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
@@ -746,7 +825,7 @@ public class ToscaOperationFacade {
         propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
         propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
         Either<List<GraphVertex>, JanusGraphOperationStatus> highestResources = janusGraphDao
-            .getByCriteria(null, propertiesToMatch, propertiesNotToMatch, parseFlag);
+            .getByCriteria(null, propertiesToMatch, propertiesNotToMatch, parseFlag, model);
         if (highestResources.isRight()) {
             JanusGraphOperationStatus status = highestResources.right().value();
             log.debug("failed to find resource with name {}. status={} ", nodeName, status);
@@ -768,48 +847,30 @@ public class ToscaOperationFacade {
     }
 
     // region - Component Get By ..
-    private <T extends Component> Either<T, StorageOperationStatus> getLatestByName(GraphPropertyEnum property, String nodeName) {
-        return getLatestByName(property, nodeName, JsonParseFlagEnum.ParseMetadata);
+    private <T extends Component> Either<T, StorageOperationStatus> getLatestByName(GraphPropertyEnum property, String nodeName, String modelName) {
+        return getLatestByName(property, nodeName, JsonParseFlagEnum.ParseMetadata, modelName);
     }
 
-    public <T extends Component> Either<List<T>, StorageOperationStatus> getBySystemName(ComponentTypeEnum componentType, String systemName) {
-        Either<List<T>, StorageOperationStatus> result = null;
-        Either<T, StorageOperationStatus> getComponentRes;
-        List<T> components = new ArrayList<>();
-        List<GraphVertex> componentVertices;
-        Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
-        Map<GraphPropertyEnum, Object> propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
+    public <T extends Component> Either<T, StorageOperationStatus> getBySystemNameAndVersion(final ComponentTypeEnum componentType,
+                                                                                             final String systemName,
+                                                                                             final String version) {
+        final Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
+        final Map<GraphPropertyEnum, Object> propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
         propertiesToMatch.put(GraphPropertyEnum.SYSTEM_NAME, systemName);
+        propertiesToMatch.put(GraphPropertyEnum.VERSION, version);
         if (componentType != null) {
             propertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
         }
         propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
-        Either<List<GraphVertex>, JanusGraphOperationStatus> getComponentsRes = janusGraphDao
-            .getByCriteria(null, propertiesToMatch, propertiesNotToMatch, JsonParseFlagEnum.ParseAll);
-        if (getComponentsRes.isRight()) {
-            JanusGraphOperationStatus status = getComponentsRes.right().value();
-            log.debug("Failed to fetch the component with system name {}. Status is {} ", systemName, status);
-            result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
-        }
-        if (result == null) {
-            componentVertices = getComponentsRes.left().value();
-            for (GraphVertex componentVertex : componentVertices) {
-                getComponentRes = getToscaElementByOperation(componentVertex);
-                if (getComponentRes.isRight()) {
-                    log.debug("Failed to get the component {}. Status is {} ", componentVertex.getJsonMetadataField(JsonPresentationFields.NAME),
-                        getComponentRes.right().value());
-                    result = Either.right(getComponentRes.right().value());
-                    break;
-                }
-                T componentBySystemName = getComponentRes.left().value();
-                log.debug("Found component, id: {}", componentBySystemName.getUniqueId());
-                components.add(componentBySystemName);
-            }
-        }
-        if (result == null) {
-            result = Either.left(components);
+
+        final Either<List<GraphVertex>, JanusGraphOperationStatus> getResourceResult
+            = janusGraphDao.getByCriteria(null, propertiesToMatch, propertiesNotToMatch, JsonParseFlagEnum.ParseAll);
+        if (getResourceResult.isRight()) {
+            final JanusGraphOperationStatus status = getResourceResult.right().value();
+            log.debug("Failed to find resource with systemName {}, version {}. Status is {} ", systemName, version, status);
+            return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
         }
-        return result;
+        return getToscaElementByOperation(getResourceResult.left().value().get(0));
     }
 
     public <T extends Component> Either<T, StorageOperationStatus> getComponentByNameAndVersion(ComponentTypeEnum componentType, String name,
@@ -819,7 +880,6 @@ public class ToscaOperationFacade {
 
     public <T extends Component> Either<T, StorageOperationStatus> getComponentByNameAndVersion(ComponentTypeEnum componentType, String name,
                                                                                                 String version, JsonParseFlagEnum parseFlag) {
-        Either<T, StorageOperationStatus> result;
         Map<GraphPropertyEnum, Object> hasProperties = new EnumMap<>(GraphPropertyEnum.class);
         Map<GraphPropertyEnum, Object> hasNotProperties = new EnumMap<>(GraphPropertyEnum.class);
         hasProperties.put(GraphPropertyEnum.NAME, name);
@@ -833,15 +893,15 @@ public class ToscaOperationFacade {
         if (getResourceRes.isRight()) {
             JanusGraphOperationStatus status = getResourceRes.right().value();
             log.debug("failed to find resource with name {}, version {}. Status is {} ", name, version, status);
-            result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
-            return result;
+            return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
         }
         return getToscaElementByOperation(getResourceRes.left().value().get(0));
     }
 
     public <T extends Component> Either<T, StorageOperationStatus> getComponentByNameAndVendorRelease(final ComponentTypeEnum componentType,
                                                                                                       final String name, final String vendorRelease,
-                                                                                                      final JsonParseFlagEnum parseFlag) {
+                                                                                                      final JsonParseFlagEnum parseFlag,
+                                                                                                      final String modelName) {
         Map<GraphPropertyEnum, Object> hasProperties = new EnumMap<>(GraphPropertyEnum.class);
         Map<GraphPropertyEnum, Object> hasNotProperties = new EnumMap<>(GraphPropertyEnum.class);
         hasProperties.put(GraphPropertyEnum.NAME, name);
@@ -850,8 +910,8 @@ public class ToscaOperationFacade {
             hasProperties.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
         }
         Map<String, Entry<JanusGraphPredicate, Object>> predicateCriteria = getVendorVersionPredicate(vendorRelease);
-        Either<List<GraphVertex>, JanusGraphOperationStatus> getResourceRes = janusGraphDao
-            .getByCriteria(null, hasProperties, hasNotProperties, predicateCriteria, parseFlag);
+        Either<List<GraphVertex>, JanusGraphOperationStatus> getResourceRes = janusGraphDao.getByCriteria(null, hasProperties, hasNotProperties,
+            predicateCriteria, parseFlag, modelName);
         if (getResourceRes.isRight()) {
             JanusGraphOperationStatus status = getResourceRes.right().value();
             log.debug("failed to find resource with name {}, version {}. Status is {} ", name, predicateCriteria, status);
@@ -928,21 +988,117 @@ public class ToscaOperationFacade {
         return Either.left(checkIfInUseAndDelete(allMarked));
     }
 
-    private List<String> checkIfInUseAndDelete(List<GraphVertex> allMarked) {
+    public List<String> deleteService(String invariantUUID, final boolean inTransaction) {
+        return deleteComponent(invariantUUID, NodeTypeEnum.Service, inTransaction);
+    }
+
+    public List<String> deleteComponent(String invariantUUID, NodeTypeEnum componentType, final boolean inTransaction) {
+        final List<GraphVertex> allServiceVerticesToDelete = findVertexListByInvariantUuid(invariantUUID);
+        List<String> affectedComponentIds = new ArrayList<>();
+        try {
+            checkNotUsed(allServiceVerticesToDelete);
+            lockAllVerticesByNodeType(allServiceVerticesToDelete, componentType);
+            for (GraphVertex elementV : allServiceVerticesToDelete) {
+                Either<ToscaElement, StorageOperationStatus> deleteToscaElement = deleteToscaElement(elementV);
+                if (deleteToscaElement.isRight()) {
+                    log.debug("Failed to delete element UniqueID {}, Name {}, error {}", elementV.getUniqueId(),
+                        elementV.getMetadataProperties().get(GraphPropertyEnum.NAME), deleteToscaElement.right().value());
+                    throwStorageException(deleteToscaElement.right().value());
+                }
+                affectedComponentIds.add(elementV.getUniqueId());
+            }
+            if (!inTransaction) {
+                janusGraphDao.commit();
+            }
+        } catch (Exception exception) {
+            if (!inTransaction) {
+                janusGraphDao.rollback();
+            }
+            throw exception;
+        } finally {
+            unlockAllVerticesByNodeType(allServiceVerticesToDelete, componentType);
+        }
+        return affectedComponentIds;
+    }
+
+    private void checkNotUsed(List<GraphVertex> vertices) {
+        boolean isInUse = isAnyComponentInUse(vertices);
+        if (isInUse) {
+            Set<GraphVertex> listOfVertices = getComponentsUsingComponents(vertices);
+            List<String> listOfStringComponents = new ArrayList<>();
+            for (GraphVertex componentVertex : listOfVertices) {
+                listOfStringComponents.add(
+                    componentVertex.getMetadataJson().get(GraphPropertyEnum.COMPONENT_TYPE.getProperty()) + " "
+                        + componentVertex.getMetadataJson().get(GraphPropertyEnum.NAME.getProperty())
+                );
+            }
+            String stringOfComponents = String.join(", ", listOfStringComponents);
+            throw ToscaOperationExceptionSupplier.componentInUse(stringOfComponents).get();
+        }
+    }
+
+    public List<GraphVertex> findVertexListByInvariantUuid(final String invariantUuid) {
+        try {
+            return janusGraphDao.findAllVertexByInvariantUuid(invariantUuid, Collections.emptyMap());
+        } catch (final JanusGraphException e) {
+            log.error(EcompLoggerErrorCode.DATA_ERROR, this.getClass().getName(), e.getMessage());
+            throw new StorageException(e.getStatus());
+        }
+    }
+
+    public void commitAndCheck(String componentId) {
+        JanusGraphOperationStatus status = janusGraphDao.commit();
+        if (!status.equals(JanusGraphOperationStatus.OK)) {
+            log.debug("error occurred when trying to DELETE {}. Return code is: {}", componentId, status);
+            throwStorageException(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
+        }
+    }
+
+    private Set<GraphVertex> getComponentsUsingComponents(List<GraphVertex> componentVertices) {
+        Set<GraphVertex> inUseBy = new TreeSet<>(Comparator.comparing(GraphVertex::getUniqueId));
+        for (final GraphVertex elementV : componentVertices) {
+            List<GraphVertex> inUseByVertex = isInUse(elementV);
+            if (!inUseByVertex.isEmpty()) {
+                inUseBy.addAll(inUseByVertex);
+            }
+        }
+        return inUseBy;
+    }
+
+    private boolean isAnyComponentInUse(List<GraphVertex> componentVertices) {
+        boolean isComponentInUse = false;
+        if (log.isDebugEnabled()) {
+            for (final GraphVertex graphVertex : componentVertices) {
+                if (!isInUse(graphVertex).isEmpty()) {
+                    isComponentInUse = true;
+                }
+            }
+        } else {
+            isComponentInUse = componentVertices.stream().anyMatch(vertex -> !isInUse(vertex).isEmpty());
+        }
+        return isComponentInUse;
+    }
+
+    private List<GraphVertex> isInUse(GraphVertex elementV) {
         final List<EdgeLabelEnum> forbiddenEdgeLabelEnums = Arrays
             .asList(EdgeLabelEnum.INSTANCE_OF, EdgeLabelEnum.PROXY_OF, EdgeLabelEnum.ALLOTTED_OF);
-        List<String> deleted = new ArrayList<>();
-        for (GraphVertex elementV : allMarked) {
-            boolean isAllowedToDelete = true;
-            for (EdgeLabelEnum edgeLabelEnum : forbiddenEdgeLabelEnums) {
-                Either<Edge, JanusGraphOperationStatus> belongingEdgeByCriteria = janusGraphDao
-                    .getBelongingEdgeByCriteria(elementV, edgeLabelEnum, null);
-                if (belongingEdgeByCriteria.isLeft()) {
-                    log.debug("Marked element {} in use. don't delete it", elementV.getUniqueId());
-                    isAllowedToDelete = false;
-                    break;
+        for (EdgeLabelEnum edgeLabelEnum : forbiddenEdgeLabelEnums) {
+            Either<List<GraphVertex>, JanusGraphOperationStatus> inUseBy =
+                janusGraphDao.getParentVertices(elementV, edgeLabelEnum, JsonParseFlagEnum.ParseAll);
+            if (inUseBy.isLeft()) {
+                if (log.isDebugEnabled()) {
+                    log.debug("Element {} in use.", elementV.getUniqueId());
                 }
+                return inUseBy.left().value();
             }
+        }
+        return Collections.emptyList();
+    }
+
+    private List<String> checkIfInUseAndDelete(List<GraphVertex> allMarked) {
+        List<String> deleted = new ArrayList<>();
+        for (GraphVertex elementV : allMarked) {
+            boolean isAllowedToDelete = !isInUse(elementV).isEmpty();
             if (isAllowedToDelete) {
                 Either<ToscaElement, StorageOperationStatus> deleteToscaElement = deleteToscaElement(elementV);
                 if (deleteToscaElement.isRight()) {
@@ -956,6 +1112,21 @@ public class ToscaOperationFacade {
         return deleted;
     }
 
+    private void lockAllVerticesByNodeType(List<GraphVertex> allVerticesToLock, NodeTypeEnum nodeType) {
+        for (GraphVertex graphVertex : allVerticesToLock) {
+            StorageOperationStatus storageOperationStatus = graphLockOperation.lockComponent(graphVertex.getUniqueId(), nodeType);
+            if (!storageOperationStatus.equals(StorageOperationStatus.OK)) {
+                throwStorageException(storageOperationStatus);
+            }
+        }
+    }
+
+    private void unlockAllVerticesByNodeType(List<GraphVertex> allVerticesToUnlock, NodeTypeEnum nodeType) {
+        for (GraphVertex graphVertex : allVerticesToUnlock) {
+            graphLockOperation.unlockComponent(graphVertex.getUniqueId(), nodeType);
+        }
+    }
+
     public Either<List<String>, StorageOperationStatus> getAllComponentsMarkedForDeletion(ComponentTypeEnum componentType) {
         Either<List<GraphVertex>, StorageOperationStatus> allComponentsMarkedForDeletion;
         switch (componentType) {
@@ -1134,14 +1305,22 @@ public class ToscaOperationFacade {
     /**
      * @return max counter of component instance Id's, null if not found
      */
-    private Integer getMaxCounterFromNamesAndIds(Component containerComponent, String normalizedName) {
-        List<String> countersInNames = containerComponent.getComponentInstances().stream()
+    private Integer getMaxCounterFromNamesAndIds(final Component containerComponent, final String normalizedName) {
+        final Pattern COUNTER_PATTERN = Pattern.compile(normalizedName + "[\\s_:-]?\\d+$");
+        final List<String> countersInNames = containerComponent.getComponentInstances().stream()
             .filter(ci -> ci.getNormalizedName() != null && ci.getNormalizedName().startsWith(normalizedName))
-            .map(ci -> ci.getNormalizedName().split(normalizedName)[1]).collect(Collectors.toList());
-        List<String> countersInIds = containerComponent.getComponentInstances().stream()
-            .filter(ci -> ci.getUniqueId() != null && ci.getUniqueId().contains(normalizedName)).map(ci -> ci.getUniqueId().split(normalizedName)[1])
+            .filter(ci -> !ci.getNormalizedName().equals(normalizedName))
+            .map(ComponentInstance::getNormalizedName)
+            .map(COUNTER_PATTERN::matcher).filter(Matcher::find).map(matcher -> matcher.group(0))
+            .map(nn -> nn.replaceAll("\\D", ""))
             .collect(Collectors.toList());
-        List<String> namesAndIdsList = new ArrayList<>(countersInNames);
+        final List<String> countersInIds = containerComponent.getComponentInstances().stream()
+            .filter(ci -> ci.getUniqueId() != null && ci.getUniqueId().contains(normalizedName))
+            .map(ComponentInstance::getUniqueId)
+            .map(COUNTER_PATTERN::matcher).filter(Matcher::find).map(matcher -> matcher.group(0))
+            .map(nn -> nn.replaceAll("\\D", ""))
+            .collect(Collectors.toList());
+        final List<String> namesAndIdsList = new ArrayList<>(countersInNames);
         namesAndIdsList.addAll(countersInIds);
         return getMaxInteger(namesAndIdsList);
     }
@@ -1156,7 +1335,6 @@ public class ToscaOperationFacade {
                     maxCounter = currCounter;
                 }
             } catch (NumberFormatException e) {
-                continue;
             }
         }
         return currCounter == null ? null : maxCounter;
@@ -1164,7 +1342,7 @@ public class ToscaOperationFacade {
 
     public Either<RequirementCapabilityRelDef, StorageOperationStatus> associateResourceInstances(Component component, String componentId,
                                                                                                   RequirementCapabilityRelDef requirementDef) {
-        return nodeTemplateOperation.associateResourceInstances(component, componentId, requirementDef);
+        return nodeTemplateOperation.associateResourceInstances(componentId, requirementDef);
     }
 
     public Either<List<InputDefinition>, StorageOperationStatus> createAndAssociateInputs(Map<String, InputDefinition> inputs, String componentId) {
@@ -1178,7 +1356,7 @@ public class ToscaOperationFacade {
             .collect(Collectors.toMap(Map.Entry::getKey, e -> new PropertyDataDefinition(e.getValue())));
         StorageOperationStatus status = topologyTemplateOperation.associateInputsToComponent(vertex, inputsMap, componentId);
         if (StorageOperationStatus.OK == status) {
-            log.debug(COMPONENT_CREATED_SUCCESSFULLY);
+            log.debug(INPUTS_ASSOCIATED_TO_COMPONENT_SUCCESSFULLY);
             List<InputDefinition> inputsResList = null;
             if (inputsMap != null && !inputsMap.isEmpty()) {
                 inputsResList = inputsMap.values().stream().map(InputDefinition::new).collect(Collectors.toList());
@@ -1188,6 +1366,28 @@ public class ToscaOperationFacade {
         return Either.right(status);
     }
 
+    public Either<List<OutputDefinition>, StorageOperationStatus> createAndAssociateOutputs(final Map<String, OutputDefinition> outputs,
+                                                                                            final String componentId) {
+        final Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
+        if (getVertexEither.isRight()) {
+            log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
+            return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value()));
+        }
+        final GraphVertex vertex = getVertexEither.left().value();
+        final Map<String, OutputDefinition> outputsMap = outputs.entrySet().stream()
+            .collect(Collectors.toMap(Map.Entry::getKey, e -> new OutputDefinition(e.getValue())));
+        final StorageOperationStatus status = topologyTemplateOperation.associateOutputsToComponent(vertex, outputsMap, componentId);
+        if (StorageOperationStatus.OK == status) {
+            log.debug(OUTPUTS_ASSOCIATED_TO_COMPONENT_SUCCESSFULLY);
+            List<OutputDefinition> outputsResList = null;
+            if (MapUtils.isNotEmpty(outputsMap)) {
+                outputsResList = outputsMap.values().stream().map(OutputDefinition::new).collect(Collectors.toList());
+            }
+            return Either.left(outputsResList);
+        }
+        return Either.right(status);
+    }
+
     public Either<List<InputDefinition>, StorageOperationStatus> addInputsToComponent(Map<String, InputDefinition> inputs, String componentId) {
         Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
         if (getVertexEither.isRight()) {
@@ -1325,7 +1525,7 @@ public class ToscaOperationFacade {
         if (StorageOperationStatus.OK == status) {
             log.debug(COMPONENT_CREATED_SUCCESSFULLY);
             List<InputDefinition> inputsResList = null;
-            if (inputsAsDataDef != null && !inputsAsDataDef.isEmpty()) {
+            if (CollectionUtils.isNotEmpty(inputsAsDataDef)) {
                 inputsResList = inputsAsDataDef.stream().map(InputDefinition::new).collect(Collectors.toList());
             }
             return Either.left(inputsResList);
@@ -1333,6 +1533,27 @@ public class ToscaOperationFacade {
         return Either.right(status);
     }
 
+    public Either<List<OutputDefinition>, StorageOperationStatus> updateOutputsToComponent(List<OutputDefinition> outputs, String componentId) {
+        Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
+        if (getVertexEither.isRight()) {
+            log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
+            return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value()));
+        }
+        GraphVertex vertex = getVertexEither.left().value();
+        List<AttributeDataDefinition> outputsAsDataDef = outputs.stream().map(AttributeDataDefinition::new).collect(Collectors.toList());
+        StorageOperationStatus status = topologyTemplateOperation
+            .updateToscaDataOfToscaElement(vertex, EdgeLabelEnum.OUTPUTS, VertexTypeEnum.OUTPUTS, outputsAsDataDef, JsonPresentationFields.NAME);
+        if (StorageOperationStatus.OK == status) {
+            log.debug(COMPONENT_CREATED_SUCCESSFULLY);
+            List<OutputDefinition> outputsResList = null;
+            if (!outputsAsDataDef.isEmpty()) {
+                outputsResList = outputsAsDataDef.stream().map(OutputDefinition::new).collect(Collectors.toList());
+            }
+            return Either.left(outputsResList);
+        }
+        return Either.right(status);
+    }
+
     // region - ComponentInstance
     public Either<Map<String, List<ComponentInstanceProperty>>, StorageOperationStatus> associateComponentInstancePropertiesToComponent(
         Map<String, List<ComponentInstanceProperty>> instProperties, String componentId) {
@@ -1436,6 +1657,49 @@ public class ToscaOperationFacade {
         return Either.right(status);
     }
 
+    public Either<Map<String, MapInterfaceDataDefinition>, StorageOperationStatus> associateComponentInstanceInterfacesToComponent(
+        Map<String, Map<String, InterfaceDefinition>> instInterfaces,
+        String componentId
+    ) {
+        Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao.getVertexById(
+            componentId,
+            JsonParseFlagEnum.NoParse
+        );
+        if (getVertexEither.isRight()) {
+            log.debug(
+                COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR,
+                componentId,
+                getVertexEither.right().value()
+            );
+            return Either.right(
+                DaoStatusConverter.convertJanusGraphStatusToStorageStatus(
+                    getVertexEither.right().value()
+                )
+            );
+        }
+        GraphVertex vertex = getVertexEither.left().value();
+        Map<String, MapInterfaceDataDefinition> instInterfacesMap = new HashMap<>();
+        if (instInterfaces != null) {
+
+            for (Map.Entry<String, Map<String, InterfaceDefinition>> entryInstances : instInterfaces.entrySet()) {
+                Map<String, InterfaceDataDefinition> incomingInterfacesMap = entryInstances.getValue().entrySet().stream()
+                    .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue()));
+                MapInterfaceDataDefinition interfacesMap = new MapInterfaceDataDefinition();
+                interfacesMap.setMapToscaDataDefinition(incomingInterfacesMap);
+                instInterfacesMap.put(entryInstances.getKey(), interfacesMap);
+            }
+        }
+        StorageOperationStatus status = topologyTemplateOperation.associateInstInterfacesToComponent(
+            vertex,
+            instInterfacesMap
+        );
+        if (StorageOperationStatus.OK == status) {
+            log.debug(COMPONENT_CREATED_SUCCESSFULLY);
+            return Either.left(instInterfacesMap);
+        }
+        return Either.right(status);
+    }
+
     public Either<Map<String, List<ComponentInstanceInput>>, StorageOperationStatus> addComponentInstanceInputsToComponent(
         Component containerComponent, Map<String, List<ComponentInstanceInput>> instProperties) {
         requireNonNull(instProperties);
@@ -1466,33 +1730,33 @@ public class ToscaOperationFacade {
     }
 
     public Either<Map<String, List<ComponentInstanceOutput>>, StorageOperationStatus> addComponentInstanceOutputsToComponent(
-        Component containerComponent, Map<String, List<ComponentInstanceOutput>> instProperties) {
-        requireNonNull(instProperties);
+        Component containerComponent, Map<String, List<ComponentInstanceOutput>> instOutputs) {
+        requireNonNull(instOutputs);
         StorageOperationStatus status;
-        for (final Entry<String, List<ComponentInstanceOutput>> entry : instProperties.entrySet()) {
-            final List<ComponentInstanceOutput> props = entry.getValue();
+        for (final Entry<String, List<ComponentInstanceOutput>> entry : instOutputs.entrySet()) {
+            final List<ComponentInstanceOutput> outputs = entry.getValue();
             final String componentInstanceId = entry.getKey();
-            if (!isEmpty(props)) {
-                for (final ComponentInstanceOutput property : props) {
-                    final List<ComponentInstanceOutput> componentInstancesInputs = containerComponent.getComponentInstancesOutputs()
+            if (!isEmpty(outputs)) {
+                for (final ComponentInstanceOutput output : outputs) {
+                    final List<ComponentInstanceOutput> componentInstanceOutputs = containerComponent.getComponentInstancesOutputs()
                         .get(componentInstanceId);
-                    final Optional<ComponentInstanceOutput> instanceProperty = componentInstancesInputs.stream()
-                        .filter(p -> p.getName().equals(property.getName())).findAny();
-                    if (instanceProperty.isPresent()) {
-                        status = updateComponentInstanceOutput(containerComponent, componentInstanceId, property);
+                    final Optional<ComponentInstanceOutput> componentInstanceOutput = componentInstanceOutputs.stream()
+                        .filter(p -> p.getName().equals(output.getName())).findAny();
+                    if (componentInstanceOutput.isPresent()) {
+                        status = updateComponentInstanceOutput(containerComponent, componentInstanceId, output);
                     } else {
-                        status = addComponentInstanceOutput(containerComponent, componentInstanceId, property);
+                        status = addComponentInstanceOutput(containerComponent, componentInstanceId, output);
                     }
                     if (status != StorageOperationStatus.OK) {
-                        log.debug("Failed to update instance input {} for instance {} error {} ", property, componentInstanceId, status);
+                        log.debug("Failed to update instance output {} for instance {} error {} ", output, componentInstanceId, status);
                         return Either.right(status);
                     } else {
-                        log.trace("instance input {} for instance {} updated", property, componentInstanceId);
+                        log.trace("instance output {} for instance {} updated", output, componentInstanceId);
                     }
                 }
             }
         }
-        return Either.left(instProperties);
+        return Either.left(instOutputs);
     }
 
     public Either<Map<String, List<ComponentInstanceProperty>>, StorageOperationStatus> addComponentInstancePropertiesToComponent(
@@ -1808,6 +2072,38 @@ public class ToscaOperationFacade {
         return storageOperationStatus;
     }
 
+    public StorageOperationStatus updateCalculatedCapabilitiesRequirements(
+        final Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> instCapabilties,
+        final Map<ComponentInstance, Map<String, List<RequirementDefinition>>> instReg,
+        final Component component) {
+        StorageOperationStatus storageOperationStatus = StorageOperationStatus.OK;
+        if (instCapabilties != null) {
+            for (Entry<ComponentInstance, Map<String, List<CapabilityDefinition>>> entry : instCapabilties.entrySet()) {
+                final Map<String, List<CapabilityDefinition>> cap = entry.getValue();
+                for (List<CapabilityDefinition> capabilityList : cap.values()) {
+                    for (CapabilityDefinition capability : capabilityList) {
+                        nodeTemplateOperation.updateComponentInstanceCapabilities(component.getUniqueId(), entry.getKey().getUniqueId(), capability);
+                    }
+                }
+            }
+        }
+        if (instReg != null) {
+            for (Entry<ComponentInstance, Map<String, List<RequirementDefinition>>> entry : instReg.entrySet()) {
+                final Map<String, List<RequirementDefinition>> req = entry.getValue();
+                for (List<RequirementDefinition> requirementList : req.values()) {
+                    for (RequirementDefinition requirement : requirementList) {
+                        storageOperationStatus = nodeTemplateOperation.updateComponentInstanceRequirement(component.getUniqueId(),
+                            entry.getKey().getUniqueId(), requirement);
+                        if (storageOperationStatus != StorageOperationStatus.OK) {
+                            return storageOperationStatus;
+                        }
+                    }
+                }
+            }
+        }
+        return storageOperationStatus;
+    }
+
     private void updateInstancesCapAndReqOnComponentFromDB(Component component) {
         ComponentParametersView componentParametersView = new ComponentParametersView(true);
         componentParametersView.setIgnoreCapabilities(false);
@@ -1821,45 +2117,48 @@ public class ToscaOperationFacade {
         Component updatedComponent = componentEither.left().value();
         component.setCapabilities(updatedComponent.getCapabilities());
         component.setRequirements(updatedComponent.getRequirements());
+        component.setComponentInstancesRelations(updatedComponent.getComponentInstancesRelations());
         component.setComponentInstances(updatedComponent.getComponentInstances());
     }
 
     private Either<List<Service>, StorageOperationStatus> getLatestVersionNonCheckoutServicesMetadataOnly(Map<GraphPropertyEnum, Object> hasProps,
-                                                                                                          Map<GraphPropertyEnum, Object> hasNotProps) {
+                                                                                                          Map<GraphPropertyEnum, Object> hasNotProps,
+                                                                                                          String modelName) {
         List<Service> services = new ArrayList<>();
         List<LifecycleStateEnum> states = new ArrayList<>();
         // include props
         hasProps.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.SERVICE.name());
         hasProps.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
+        if (modelName != null) {
+            hasProps.put(GraphPropertyEnum.MODEL, modelName);
+        }
         // exclude props
         states.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
         hasNotProps.put(GraphPropertyEnum.STATE, states);
         hasNotProps.put(GraphPropertyEnum.IS_DELETED, true);
         hasNotProps.put(GraphPropertyEnum.IS_ARCHIVED, true);
-        return fetchServicesByCriteria(services, hasProps, hasNotProps);
+        return fetchServicesByCriteria(services, hasProps, hasNotProps, modelName);
     }
 
-    private Either<List<Component>, StorageOperationStatus> getLatestVersionNotAbstractToscaElementsMetadataOnly(boolean isAbstract,
-                                                                                                                 ComponentTypeEnum componentTypeEnum,
-                                                                                                                 String internalComponentType,
-                                                                                                                 VertexTypeEnum vertexType) {
+    private Either<List<Component>, StorageOperationStatus> getLatestVersionNotAbstractToscaElementsMetadataOnly(final boolean isAbstract,
+                                                                                                                 final ComponentTypeEnum componentTypeEnum,
+                                                                                                                 final String internalComponentType,
+                                                                                                                 final VertexTypeEnum vertexType,
+                                                                                                                 final String modelName,
+                                                                                                                 final boolean includeNormativeExtensionModels) {
         List<Service> services = null;
         Map<GraphPropertyEnum, Object> hasProps = new EnumMap<>(GraphPropertyEnum.class);
         Map<GraphPropertyEnum, Object> hasNotProps = new EnumMap<>(GraphPropertyEnum.class);
-        fillPropsMap(hasProps, hasNotProps, internalComponentType, componentTypeEnum, isAbstract, vertexType);
+        fillPropsMap(hasProps, hasNotProps, internalComponentType, componentTypeEnum, isAbstract, vertexType, modelName);
         Either<List<GraphVertex>, JanusGraphOperationStatus> getRes = janusGraphDao
-            .getByCriteria(vertexType, hasProps, hasNotProps, JsonParseFlagEnum.ParseMetadata);
-        if (getRes.isRight()) {
-            if (getRes.right().value().equals(JanusGraphOperationStatus.NOT_FOUND)) {
-                return Either.left(new ArrayList<>());
-            } else {
-                return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getRes.right().value()));
-            }
+            .getByCriteria(vertexType, hasProps, hasNotProps, JsonParseFlagEnum.ParseMetadata, modelName, includeNormativeExtensionModels);
+        if (getRes.isRight() && !JanusGraphOperationStatus.NOT_FOUND.equals(getRes.right().value())) {
+            return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getRes.right().value()));
         }
         // region -> Fetch non checked-out services
         if (internalComponentType != null && internalComponentType.toLowerCase().trim().equals(SERVICE) && VertexTypeEnum.NODE_TYPE == vertexType) {
             Either<List<Service>, StorageOperationStatus> result = getLatestVersionNonCheckoutServicesMetadataOnly(
-                new EnumMap<>(GraphPropertyEnum.class), new EnumMap<>(GraphPropertyEnum.class));
+                new EnumMap<>(GraphPropertyEnum.class), new EnumMap<>(GraphPropertyEnum.class), modelName);
             if (result.isRight()) {
                 log.debug("Failed to fetch services for");
                 return Either.right(result.right().value());
@@ -1873,15 +2172,17 @@ public class ToscaOperationFacade {
         List<Component> nonAbstractLatestComponents = new ArrayList<>();
         ComponentParametersView params = new ComponentParametersView(true);
         params.setIgnoreAllVersions(false);
-        for (GraphVertex vertexComponent : getRes.left().value()) {
-            Either<ToscaElement, StorageOperationStatus> componentRes = topologyTemplateOperation
-                .getLightComponent(vertexComponent, componentTypeEnum, params);
-            if (componentRes.isRight()) {
-                log.debug("Failed to fetch light element for {} error {}", vertexComponent.getUniqueId(), componentRes.right().value());
-                return Either.right(componentRes.right().value());
-            } else {
-                Component component = ModelConverter.convertFromToscaElement(componentRes.left().value());
-                nonAbstractLatestComponents.add(component);
+        if (getRes.isLeft()) {
+            for (GraphVertex vertexComponent : getRes.left().value()) {
+                Either<ToscaElement, StorageOperationStatus> componentRes = topologyTemplateOperation
+                    .getLightComponent(vertexComponent, componentTypeEnum, params);
+                if (componentRes.isRight()) {
+                    log.debug("Failed to fetch light element for {} error {}", vertexComponent.getUniqueId(), componentRes.right().value());
+                    return Either.right(componentRes.right().value());
+                } else {
+                    Component component = ModelConverter.convertFromToscaElement(componentRes.left().value());
+                    nonAbstractLatestComponents.add(component);
+                }
             }
         }
         if (CollectionUtils.isNotEmpty(services)) {
@@ -1975,7 +2276,7 @@ public class ToscaOperationFacade {
     private Either<List<String>, StorageOperationStatus> getComponentUids(boolean isAbstract, ComponentTypeEnum componentTypeEnum,
                                                                           String internalComponentType) {
         Either<List<Component>, StorageOperationStatus> getToscaElementsRes = getLatestVersionNotAbstractMetadataOnly(isAbstract, componentTypeEnum,
-            internalComponentType);
+            internalComponentType, null, false);
         if (getToscaElementsRes.isRight()) {
             return Either.right(getToscaElementsRes.right().value());
         }
@@ -2008,13 +2309,9 @@ public class ToscaOperationFacade {
 
     public Either<Boolean, StorageOperationStatus> validateComponentNameUniqueness(String name, ResourceTypeEnum resourceType,
                                                                                    ComponentTypeEnum componentType) {
-        VertexTypeEnum vertexType = ModelConverter.isAtomicComponent(resourceType) ? VertexTypeEnum.NODE_TYPE : VertexTypeEnum.TOPOLOGY_TEMPLATE;
         String normalizedName = ValidationUtils.normaliseComponentName(name);
-        Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
-        properties.put(GraphPropertyEnum.NORMALIZED_NAME, normalizedName);
-        properties.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
         Either<List<GraphVertex>, JanusGraphOperationStatus> vertexEither = janusGraphDao
-            .getByCriteria(vertexType, properties, JsonParseFlagEnum.NoParse);
+            .getByCriteria(getVertexTypeEnum(resourceType), propertiesToMatch(normalizedName, componentType), JsonParseFlagEnum.NoParse);
         if (vertexEither.isRight() && vertexEither.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
             log.debug("failed to get vertex from graph with property normalizedName: {}", normalizedName);
             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(vertexEither.right().value()));
@@ -2022,12 +2319,48 @@ public class ToscaOperationFacade {
         return Either.left(CollectionUtils.isEmpty(vertexEither.isLeft() ? vertexEither.left().value() : null));
     }
 
+    public Either<Boolean, StorageOperationStatus> validateComponentNameAndModelExists(final String resourceName, final String model,
+                                                                                       final ResourceTypeEnum resourceType,
+                                                                                       final ComponentTypeEnum componentType) {
+        Either<Boolean, StorageOperationStatus> result = validateComponentNameAndModelUniqueness(resourceName, model, resourceType, componentType);
+        if (result.isLeft()) {
+            result = Either.left(!result.left().value());
+        }
+        return result;
+    }
+
+    private Either<Boolean, StorageOperationStatus> validateComponentNameAndModelUniqueness(final String resourceName, final String modelName,
+                                                                                            final ResourceTypeEnum resourceType,
+                                                                                            final ComponentTypeEnum componentType) {
+        final String normalizedName = ValidationUtils.normaliseComponentName(resourceName);
+        final Either<List<GraphVertex>, JanusGraphOperationStatus> vertexEither = janusGraphDao
+            .getByCriteria(getVertexTypeEnum(resourceType), propertiesToMatch(normalizedName, componentType), null, null, JsonParseFlagEnum.NoParse,
+                modelName);
+        if (vertexEither.isRight() && vertexEither.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
+            log.debug("failed to get vertex from graph with property normalizedName: {} and model: {}", normalizedName, modelName);
+            return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(vertexEither.right().value()));
+        }
+        return Either.left(CollectionUtils.isEmpty(vertexEither.isLeft() ? vertexEither.left().value().stream()
+            .collect(Collectors.toList()) : null));
+    }
+
+    private VertexTypeEnum getVertexTypeEnum(final ResourceTypeEnum resourceType) {
+        return ModelConverter.isAtomicComponent(resourceType) ? VertexTypeEnum.NODE_TYPE : TOPOLOGY_TEMPLATE;
+    }
+
+    private Map<GraphPropertyEnum, Object> propertiesToMatch(final String normalizedName, final ComponentTypeEnum componentType) {
+        final Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
+        properties.put(GraphPropertyEnum.NORMALIZED_NAME, normalizedName);
+        properties.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
+        return properties;
+    }
+
     private void fillNodeTypePropsMap(final Map<GraphPropertyEnum, Object> hasProps, final Map<GraphPropertyEnum, Object> hasNotProps,
-                                      final String internalComponentType) {
+                                      final String internalComponentType, String modelName) {
         final Configuration configuration = ConfigurationManager.getConfigurationManager().getConfiguration();
         final List<String> allowedTypes;
         if (ComponentTypeEnum.SERVICE.getValue().equalsIgnoreCase(internalComponentType)) {
-            allowedTypes = containerInstanceTypesData.getComponentAllowedList(ComponentTypeEnum.SERVICE, null);
+            allowedTypes = containerInstanceTypesData.getServiceAllowedList(modelName);
         } else {
             final ResourceTypeEnum resourceType = ResourceTypeEnum.getTypeIgnoreCase(internalComponentType);
             allowedTypes = containerInstanceTypesData.getComponentAllowedList(ComponentTypeEnum.RESOURCE, resourceType);
@@ -2061,15 +2394,16 @@ public class ToscaOperationFacade {
     }
 
     private void fillPropsMap(Map<GraphPropertyEnum, Object> hasProps, Map<GraphPropertyEnum, Object> hasNotProps, String internalComponentType,
-                              ComponentTypeEnum componentTypeEnum, boolean isAbstract, VertexTypeEnum internalVertexType) {
+                              ComponentTypeEnum componentTypeEnum, boolean isAbstract, VertexTypeEnum internalVertexType, String modelName) {
         hasNotProps.put(GraphPropertyEnum.STATE, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name());
         hasNotProps.put(GraphPropertyEnum.IS_DELETED, true);
         hasNotProps.put(GraphPropertyEnum.IS_ARCHIVED, true);
         hasProps.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
+
         if (VertexTypeEnum.NODE_TYPE == internalVertexType) {
             hasProps.put(GraphPropertyEnum.IS_ABSTRACT, isAbstract);
             if (internalComponentType != null) {
-                fillNodeTypePropsMap(hasProps, hasNotProps, internalComponentType);
+                fillNodeTypePropsMap(hasProps, hasNotProps, internalComponentType, modelName);
             }
         } else {
             fillTopologyTemplatePropsMap(hasProps, hasNotProps, componentTypeEnum);
@@ -2081,20 +2415,23 @@ public class ToscaOperationFacade {
         if (ComponentTypeEnum.RESOURCE == componentTypeEnum) {
             internalVertexTypes.add(VertexTypeEnum.NODE_TYPE);
         }
-        if (ComponentTypeEnum.SERVICE == componentTypeEnum || SERVICE.equalsIgnoreCase(internalComponentType)) {
-            internalVertexTypes.add(VertexTypeEnum.TOPOLOGY_TEMPLATE);
+        if (ComponentTypeEnum.SERVICE == componentTypeEnum || SERVICE.equalsIgnoreCase(internalComponentType) || VF.equalsIgnoreCase(
+            internalComponentType)) {
+            internalVertexTypes.add(TOPOLOGY_TEMPLATE);
         }
         return internalVertexTypes;
     }
 
     public Either<List<Component>, StorageOperationStatus> getLatestVersionNotAbstractMetadataOnly(boolean isAbstract,
-                                                                                                   ComponentTypeEnum componentTypeEnum,
-                                                                                                   String internalComponentType) {
+                                                                                                   final ComponentTypeEnum componentTypeEnum,
+                                                                                                   final String internalComponentType,
+                                                                                                   final String modelName,
+                                                                                                   final boolean includeNormativeExtensionModels) {
         List<VertexTypeEnum> internalVertexTypes = getInternalVertexTypes(componentTypeEnum, internalComponentType);
         List<Component> result = new ArrayList<>();
         for (VertexTypeEnum vertexType : internalVertexTypes) {
             Either<List<Component>, StorageOperationStatus> listByVertexType = getLatestVersionNotAbstractToscaElementsMetadataOnly(isAbstract,
-                componentTypeEnum, internalComponentType, vertexType);
+                componentTypeEnum, internalComponentType, vertexType, modelName, includeNormativeExtensionModels);
             if (listByVertexType.isRight()) {
                 return listByVertexType;
             }
@@ -2228,7 +2565,7 @@ public class ToscaOperationFacade {
     }
 
     public <T extends Component> Either<T, StorageOperationStatus> getLatestByNameAndVersion(String name, String version,
-                                                                                             JsonParseFlagEnum parseFlag) {
+                                                                                             JsonParseFlagEnum parseFlag, String model) {
         Either<T, StorageOperationStatus> result;
         Map<GraphPropertyEnum, Object> hasProperties = new EnumMap<>(GraphPropertyEnum.class);
         Map<GraphPropertyEnum, Object> hasNotProperties = new EnumMap<>(GraphPropertyEnum.class);
@@ -2237,7 +2574,7 @@ public class ToscaOperationFacade {
         hasProperties.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
         hasNotProperties.put(GraphPropertyEnum.IS_DELETED, true);
         Either<List<GraphVertex>, JanusGraphOperationStatus> getResourceRes = janusGraphDao
-            .getByCriteria(null, hasProperties, hasNotProperties, parseFlag);
+            .getByCriteria(null, hasProperties, hasNotProperties, parseFlag, model);
         if (getResourceRes.isRight()) {
             JanusGraphOperationStatus status = getResourceRes.right().value();
             log.debug("failed to find resource with name {}, version {}. Status is {} ", name, version, status);
@@ -2303,10 +2640,10 @@ public class ToscaOperationFacade {
                     log.debug("getLatestResourceByCsarOrName - getByCriteria(by system name) returned 2 latest CERTIFIED versions");
                     return Either.right(StorageOperationStatus.GENERAL_ERROR);
                 }
-                if (resourceMetadataData.getJsonMetadataField(JsonPresentationFields.CSAR_UUID) != null && !((String) resourceMetadataData
-                    .getJsonMetadataField(JsonPresentationFields.CSAR_UUID)).equals(csarUUID)) {
+                final Object csarUuid = resourceMetadataData.getJsonMetadataField(JsonPresentationFields.CSAR_UUID);
+                if (csarUuid != null && !csarUuid.equals(csarUUID)) {
                     log.debug("getLatestResourceByCsarOrName - same system name {} but different csarUUID. exist {} and new {} ", systemName,
-                        resourceMetadataData.getJsonMetadataField(JsonPresentationFields.CSAR_UUID), csarUUID);
+                        csarUuid, csarUUID);
                     // correct error will be returned from create flow. with all
 
                     // correct audit records!!!!!
@@ -2340,10 +2677,11 @@ public class ToscaOperationFacade {
         return null;
     }
 
-    public Either<Boolean, StorageOperationStatus> validateToscaResourceNameExtends(String templateNameCurrent, String templateNameExtends) {
+    public Either<Boolean, StorageOperationStatus> validateToscaResourceNameExtends(String templateNameCurrent, String templateNameExtends,
+                                                                                    String model) {
         String currentTemplateNameChecked = templateNameExtends;
         while (currentTemplateNameChecked != null && !currentTemplateNameChecked.equalsIgnoreCase(templateNameCurrent)) {
-            Either<Resource, StorageOperationStatus> latestByToscaResourceName = getLatestByToscaResourceName(currentTemplateNameChecked);
+            Either<Resource, StorageOperationStatus> latestByToscaResourceName = getLatestByToscaResourceName(currentTemplateNameChecked, model);
             if (latestByToscaResourceName.isRight()) {
                 return latestByToscaResourceName.right().value() == StorageOperationStatus.NOT_FOUND ? Either.left(false)
                     : Either.right(latestByToscaResourceName.right().value());
@@ -2440,11 +2778,11 @@ public class ToscaOperationFacade {
         }
         propertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.SERVICE.name());
         propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
-        if (distStatus != null && !distStatus.isEmpty()) {
+        if (CollectionUtils.isNotEmpty(distStatus)) {
             for (DistributionStatusEnum state : distStatus) {
                 propertiesToMatch.put(GraphPropertyEnum.DISTRIBUTION_STATUS, state.name());
                 Either<List<Service>, StorageOperationStatus> fetchServicesByCriteria = fetchServicesByCriteria(servicesAll, propertiesToMatch,
-                    propertiesNotToMatch);
+                    propertiesNotToMatch, null);
                 if (fetchServicesByCriteria.isRight()) {
                     return fetchServicesByCriteria;
                 } else {
@@ -2453,15 +2791,20 @@ public class ToscaOperationFacade {
             }
             return Either.left(servicesAll);
         } else {
-            return fetchServicesByCriteria(servicesAll, propertiesToMatch, propertiesNotToMatch);
+            return fetchServicesByCriteria(servicesAll, propertiesToMatch, propertiesNotToMatch, null);
         }
     }
 
     private Either<List<Service>, StorageOperationStatus> fetchServicesByCriteria(List<Service> servicesAll,
                                                                                   Map<GraphPropertyEnum, Object> propertiesToMatch,
-                                                                                  Map<GraphPropertyEnum, Object> propertiesNotToMatch) {
-        Either<List<GraphVertex>, JanusGraphOperationStatus> getRes = janusGraphDao
-            .getByCriteria(VertexTypeEnum.TOPOLOGY_TEMPLATE, propertiesToMatch, propertiesNotToMatch, JsonParseFlagEnum.ParseAll);
+                                                                                  Map<GraphPropertyEnum, Object> propertiesNotToMatch,
+                                                                                  String modelName) {
+        Either<List<GraphVertex>, JanusGraphOperationStatus> getRes;
+        if (StringUtils.isEmpty(modelName)) {
+            getRes = janusGraphDao.getByCriteria(TOPOLOGY_TEMPLATE, propertiesToMatch, propertiesNotToMatch, JsonParseFlagEnum.ParseAll);
+        } else {
+            getRes = janusGraphDao.getByCriteria(TOPOLOGY_TEMPLATE, propertiesToMatch, propertiesNotToMatch, JsonParseFlagEnum.ParseAll, modelName);
+        }
         if (getRes.isRight()) {
             if (getRes.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG,
@@ -2470,7 +2813,7 @@ public class ToscaOperationFacade {
                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getRes.right().value()));
             }
         } else {
-            for (GraphVertex vertex : getRes.left().value()) {
+            for (final GraphVertex vertex : getRes.left().value()) {
                 Either<ToscaElement, StorageOperationStatus> getServiceRes = topologyTemplateOperation
                     .getLightComponent(vertex, ComponentTypeEnum.SERVICE, new ComponentParametersView(true));
                 if (getServiceRes.isRight()) {
@@ -2515,9 +2858,9 @@ public class ToscaOperationFacade {
         return nodeTemplateOperation.generateCustomizationUUIDOnInstanceGroup(componentId, instanceId, groupInstances);
     }
 
-    public Either<PropertyDefinition, StorageOperationStatus> addPropertyToComponent(String propertyName, PropertyDefinition newPropertyDefinition,
+    public Either<PropertyDefinition, StorageOperationStatus> addPropertyToComponent(PropertyDefinition newPropertyDefinition,
                                                                                      Component component) {
-        newPropertyDefinition.setName(propertyName);
+        final String propertyName = newPropertyDefinition.getName();
         StorageOperationStatus status = getToscaElementOperation(component)
             .addToscaDataToToscaElement(component.getUniqueId(), EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, newPropertyDefinition,
                 JsonPresentationFields.NAME);
@@ -2821,7 +3164,7 @@ public class ToscaOperationFacade {
                                                                                                                String componentInstanceId) {
         String uniqueId = componentInstance.getUniqueId();
         StorageOperationStatus status = nodeTemplateOperation
-            .deleteToscaDataDeepElementsBlockOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS,
+            .deleteToscaDataDeepElementsBlockOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_GROUPS,
                 uniqueId);
         if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
             CommonUtility
@@ -2954,7 +3297,7 @@ public class ToscaOperationFacade {
 
     public StorageOperationStatus updateComponentInstanceCapabilityProperties(Component containerComponent, String componentInstanceUniqueId) {
         return convertComponentInstanceProperties(containerComponent, componentInstanceUniqueId).map(instanceCapProps -> topologyTemplateOperation
-            .updateComponentInstanceCapabilityProperties(containerComponent, componentInstanceUniqueId, instanceCapProps))
+                .updateComponentInstanceCapabilityProperties(containerComponent, componentInstanceUniqueId, instanceCapProps))
             .orElse(StorageOperationStatus.NOT_FOUND);
     }
 
@@ -2963,11 +3306,67 @@ public class ToscaOperationFacade {
         return nodeTemplateOperation.updateComponentInstanceRequirement(containerComponentId, componentInstanceUniqueId, requirementDataDefinition);
     }
 
+    public CapabilityDataDefinition updateComponentInstanceCapability(final String containerComponentId, final String componentInstanceUniqueId,
+                                                                      final CapabilityDataDefinition capabilityDataDefinition) {
+
+        return nodeTemplateOperation.updateComponentInstanceCapabilities(containerComponentId, componentInstanceUniqueId, capabilityDataDefinition);
+    }
+
     public StorageOperationStatus updateComponentInstanceInterfaces(Component containerComponent, String componentInstanceUniqueId) {
         MapInterfaceDataDefinition mapInterfaceDataDefinition = convertComponentInstanceInterfaces(containerComponent, componentInstanceUniqueId);
         return topologyTemplateOperation.updateComponentInstanceInterfaces(containerComponent, componentInstanceUniqueId, mapInterfaceDataDefinition);
     }
 
+    public StorageOperationStatus updateComponentInterfaces(final Component component, final String componentInterfaceUpdatedKey) {
+        MapInterfaceDataDefinition mapInterfaceDataDefinition = convertComponentInterfaces(component.getInterfaces());
+        return topologyTemplateOperation.updateComponentInterfaces(component.getUniqueId(), mapInterfaceDataDefinition, componentInterfaceUpdatedKey);
+    }
+
+    public Either<InterfaceDefinition, StorageOperationStatus> addInterfaceToComponent(final String interfaceName,
+                                                                                       final InterfaceDefinition interfaceDefinition,
+                                                                                       final Component component) {
+
+        final boolean match = component.getInterfaces().keySet().stream().anyMatch(s -> s.equals(interfaceName));
+        StorageOperationStatus status;
+        final ToscaElementOperation toscaElementOperation = getToscaElementOperation(component);
+        if (match) {
+            status = toscaElementOperation.updateToscaDataOfToscaElement(component.getUniqueId(), EdgeLabelEnum.INTERFACE_ARTIFACTS,
+                VertexTypeEnum.INTERFACE_ARTIFACTS, interfaceDefinition, JsonPresentationFields.TYPE);
+        } else {
+            status = toscaElementOperation.addToscaDataToToscaElement(component.getUniqueId(), EdgeLabelEnum.INTERFACE_ARTIFACTS,
+                VertexTypeEnum.INTERFACE_ARTIFACTS, interfaceDefinition, JsonPresentationFields.TYPE);
+        }
+
+        if (status != StorageOperationStatus.OK) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to add the interface {} to the component {}. Status is {}. ",
+                interfaceName, component.getName(), status);
+            return Either.right(status);
+        }
+        final ComponentParametersView filter = new ComponentParametersView(true);
+        filter.setIgnoreInterfaces(false);
+        filter.setIgnoreInterfaceInstances(false);
+        final Either<Component, StorageOperationStatus> getUpdatedComponentRes = getToscaElement(component.getUniqueId(), filter);
+        if (getUpdatedComponentRes.isRight()) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to get updated component {}. Status is {}. ",
+                component.getUniqueId(), getUpdatedComponentRes.right().value());
+            return Either.right(getUpdatedComponentRes.right().value());
+        }
+        InterfaceDefinition newInterfaceDefinition = null;
+        final Map<String, InterfaceDefinition> interfaces = (getUpdatedComponentRes.left().value()).getInterfaces();
+        if (MapUtils.isNotEmpty(interfaces)) {
+            final Optional<String> interfaceNameOptional = interfaces.keySet().stream().filter(key -> key.equals(interfaceName)).findAny();
+            if (interfaceNameOptional.isPresent()) {
+                newInterfaceDefinition = interfaces.get(interfaceNameOptional.get());
+            }
+        }
+        if (newInterfaceDefinition == null) {
+            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find recently added interface {} on the component {}. Status is {}. ",
+                interfaceName, component.getUniqueId(), StorageOperationStatus.NOT_FOUND);
+            return Either.right(StorageOperationStatus.NOT_FOUND);
+        }
+        return Either.left(newInterfaceDefinition);
+    }
+
     public StorageOperationStatus updateComponentCalculatedCapabilitiesProperties(Component containerComponent) {
         Map<String, MapCapabilityProperty> mapCapabiltyPropertyMap = convertComponentCapabilitiesProperties(containerComponent);
         return nodeTemplateOperation.overrideComponentCapabilitiesProperties(containerComponent, mapCapabiltyPropertyMap);
@@ -2975,14 +3374,14 @@ public class ToscaOperationFacade {
 
     public StorageOperationStatus deleteAllCalculatedCapabilitiesRequirements(String topologyTemplateId) {
         StorageOperationStatus status = topologyTemplateOperation
-            .removeToscaData(topologyTemplateId, EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES);
+            .removeToscaData(topologyTemplateId, EdgeLabelEnum.CALCULATED_CAPABILITIES);
         if (status == StorageOperationStatus.OK) {
             status = topologyTemplateOperation
-                .removeToscaData(topologyTemplateId, EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS);
+                .removeToscaData(topologyTemplateId, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
         }
         if (status == StorageOperationStatus.OK) {
             status = topologyTemplateOperation
-                .removeToscaData(topologyTemplateId, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES);
+                .removeToscaData(topologyTemplateId, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES);
         }
         return status;
     }
@@ -3029,6 +3428,14 @@ public class ToscaOperationFacade {
         return mapInterfaceDataDefinition;
     }
 
+    private MapInterfaceDataDefinition convertComponentInterfaces(final Map<String, InterfaceDefinition> interfaces) {
+        final MapInterfaceDataDefinition mapInterfaceDataDefinition = new MapInterfaceDataDefinition();
+        if (MapUtils.isNotEmpty(interfaces)) {
+            interfaces.values().stream().forEach(interfaceDef -> mapInterfaceDataDefinition.put(interfaceDef.getType(), interfaceDef));
+        }
+        return mapInterfaceDataDefinition;
+    }
+
     private Map<String, MapCapabilityProperty> convertComponentCapabilitiesProperties(Component currComponent) {
         Map<String, MapCapabilityProperty> map = ModelConverter.extractCapabilityPropertiesFromGroups(currComponent.getGroups(), true);
         map.putAll(ModelConverter.extractCapabilityProperteisFromInstances(currComponent.getComponentInstances(), true));
@@ -3049,7 +3456,7 @@ public class ToscaOperationFacade {
             log.error(COULDNT_FETCH_A_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value());
             result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value()));
         } else {
-            if (getVertexEither.left().value().getLabel() != VertexTypeEnum.TOPOLOGY_TEMPLATE) {
+            if (getVertexEither.left().value().getLabel() != TOPOLOGY_TEMPLATE) {
                 log.error("Policy association to component of Tosca type {} is not allowed. ", getVertexEither.left().value().getLabel());
                 result = Either.right(StorageOperationStatus.BAD_REQUEST);
             }
@@ -3235,6 +3642,6 @@ public class ToscaOperationFacade {
     }
 
     public <T extends Component> Either<T, StorageOperationStatus> getLatestByServiceName(String serviceName) {
-        return getLatestByName(GraphPropertyEnum.NAME, serviceName);
+        return getLatestByName(GraphPropertyEnum.NAME, serviceName, null);
     }
 }