Fix 'Import use case fails when interfaces in template do not exist in system'-bug...
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / impl / ResourceBusinessLogic.java
index d692b4f..6e385b2 100644 (file)
  */
 package org.openecomp.sdc.be.components.impl;
 
-import static java.util.stream.Collectors.joining;
 import static java.util.stream.Collectors.toList;
 import static java.util.stream.Collectors.toMap;
-import static java.util.stream.Collectors.toSet;
 import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
 import static org.apache.commons.collections.MapUtils.isEmpty;
 import static org.apache.commons.collections.MapUtils.isNotEmpty;
@@ -44,6 +42,7 @@ import java.util.List;
 import java.util.ListIterator;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
 import java.util.function.Function;
@@ -59,6 +58,7 @@ import org.openecomp.sdc.be.catalog.enums.ChangeTypeEnum;
 import org.openecomp.sdc.be.components.csar.CsarArtifactsAndGroupsBusinessLogic;
 import org.openecomp.sdc.be.components.csar.CsarBusinessLogic;
 import org.openecomp.sdc.be.components.csar.CsarInfo;
+import org.openecomp.sdc.be.components.csar.OnboardedCsarInfo;
 import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperationEnum;
 import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum;
 import org.openecomp.sdc.be.components.impl.artifact.ArtifactOperationInfo;
@@ -73,7 +73,6 @@ import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction.L
 import org.openecomp.sdc.be.components.merge.TopologyComparator;
 import org.openecomp.sdc.be.components.merge.property.PropertyDataValueMergeBusinessLogic;
 import org.openecomp.sdc.be.components.merge.resource.ResourceDataMergeBusinessLogic;
-import org.openecomp.sdc.be.components.merge.utils.MergeInstanceUtils;
 import org.openecomp.sdc.be.components.property.PropertyConstraintsUtils;
 import org.openecomp.sdc.be.components.validation.component.ComponentContactIdValidator;
 import org.openecomp.sdc.be.components.validation.component.ComponentDescriptionValidator;
@@ -86,8 +85,7 @@ import org.openecomp.sdc.be.config.BeEcompErrorManager;
 import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
 import org.openecomp.sdc.be.config.ConfigurationManager;
 import org.openecomp.sdc.be.dao.api.ActionStatus;
-import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
-import org.openecomp.sdc.be.dao.jsongraph.JanusGraphDao;
+import org.openecomp.sdc.be.dao.janusgraph.JanusGraphDao;
 import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum;
 import org.openecomp.sdc.be.datamodel.utils.ArtifactUtils;
 import org.openecomp.sdc.be.datamodel.utils.UiComponentDataConverter;
@@ -102,6 +100,7 @@ import org.openecomp.sdc.be.datatypes.elements.ToscaArtifactDataDefinition;
 import org.openecomp.sdc.be.datatypes.enums.ComponentFieldsEnum;
 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.CreatedFrom;
+import org.openecomp.sdc.be.datatypes.enums.ModelTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
 import org.openecomp.sdc.be.impl.ComponentsUtils;
@@ -118,14 +117,17 @@ 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.GroupDefinition;
+import org.openecomp.sdc.be.model.GroupProperty;
 import org.openecomp.sdc.be.model.InputDefinition;
 import org.openecomp.sdc.be.model.InterfaceDefinition;
 import org.openecomp.sdc.be.model.LifeCycleTransitionEnum;
 import org.openecomp.sdc.be.model.LifecycleStateEnum;
+import org.openecomp.sdc.be.model.Model;
 import org.openecomp.sdc.be.model.NodeTypeInfo;
 import org.openecomp.sdc.be.model.Operation;
 import org.openecomp.sdc.be.model.ParsedToscaYamlInfo;
 import org.openecomp.sdc.be.model.PolicyDefinition;
+import org.openecomp.sdc.be.model.PolicyTypeDefinition;
 import org.openecomp.sdc.be.model.PropertyDefinition;
 import org.openecomp.sdc.be.model.RelationshipImpl;
 import org.openecomp.sdc.be.model.RelationshipInfo;
@@ -155,8 +157,8 @@ import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
 import org.openecomp.sdc.be.model.operations.api.IInterfaceLifecycleOperation;
 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.InterfaceLifecycleOperation;
+import org.openecomp.sdc.be.model.operations.impl.ModelOperation;
 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
 import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
@@ -168,6 +170,7 @@ import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
 import org.openecomp.sdc.be.user.UserBusinessLogic;
 import org.openecomp.sdc.be.utils.CommonBeUtils;
 import org.openecomp.sdc.be.utils.TypeUtils;
+import org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum;
 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
 import org.openecomp.sdc.common.api.Constants;
@@ -201,6 +204,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
     private static final String CREATE_RESOURCE_VALIDATE_CAPABILITY_TYPES = "Create Resource - validateCapabilityTypesCreate";
     private static final String COMPONENT_INSTANCE_WITH_NAME = "component instance with name ";
     private static final String COMPONENT_INSTANCE_WITH_NAME_IN_RESOURCE = "component instance with name {}  in resource {} ";
+    private static final String VALID_CHARACTERS_ARTIFACT_NAME = "'A-Z', 'a-z', '0-9', '.', '_', '-', '@' and space";
     private static final LoggerSupportability loggerSupportability = LoggerSupportability.getLogger(ResourceBusinessLogic.class.getName());
     private final ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
     private final ResourceImportManager resourceImportManager;
@@ -209,11 +213,14 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
     private final CompositionBusinessLogic compositionBusinessLogic;
     private final ResourceDataMergeBusinessLogic resourceDataMergeBusinessLogic;
     private final CsarArtifactsAndGroupsBusinessLogic csarArtifactsAndGroupsBusinessLogic;
-    private final MergeInstanceUtils mergeInstanceUtils;
     private final UiComponentDataConverter uiComponentDataConverter;
     private final CsarBusinessLogic csarBusinessLogic;
     private final PropertyBusinessLogic propertyBusinessLogic;
     private final PolicyBusinessLogic policyBusinessLogic;
+    private final ModelBusinessLogic modelBusinessLogic;
+    private final DataTypeBusinessLogic dataTypeBusinessLogic;
+    private final PolicyTypeBusinessLogic policyTypeBusinessLogic;
+    private final ModelOperation modelOperation;
     private IInterfaceLifecycleOperation interfaceTypeOperation;
     private LifecycleBusinessLogic lifecycleBusinessLogic;
     @Autowired
@@ -227,6 +234,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
     @Autowired
     private SoftwareInformationBusinessLogic softwareInformationBusinessLogic;
 
+
     @Autowired
     public ResourceBusinessLogic(final IElementOperation elementDao, final IGroupOperation groupOperation,
                                  final IGroupInstanceOperation groupInstanceOperation, final IGroupTypeOperation groupTypeOperation,
@@ -238,13 +246,15 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
                                  final OutputsBusinessLogic outputsBusinessLogic, final CompositionBusinessLogic compositionBusinessLogic,
                                  final ResourceDataMergeBusinessLogic resourceDataMergeBusinessLogic,
                                  final CsarArtifactsAndGroupsBusinessLogic csarArtifactsAndGroupsBusinessLogic,
-                                 final MergeInstanceUtils mergeInstanceUtils, final UiComponentDataConverter uiComponentDataConverter,
-                                 final CsarBusinessLogic csarBusinessLogic, final ArtifactsOperations artifactToscaOperation,
-                                 final PropertyBusinessLogic propertyBusinessLogic, final ComponentContactIdValidator componentContactIdValidator,
-                                 final ComponentNameValidator componentNameValidator, final ComponentTagsValidator componentTagsValidator,
-                                 final ComponentValidator componentValidator, final ComponentIconValidator componentIconValidator,
+                                 final UiComponentDataConverter uiComponentDataConverter, final CsarBusinessLogic csarBusinessLogic,
+                                 final ArtifactsOperations artifactToscaOperation, final PropertyBusinessLogic propertyBusinessLogic,
+                                 final ComponentContactIdValidator componentContactIdValidator, final ComponentNameValidator componentNameValidator,
+                                 final ComponentTagsValidator componentTagsValidator, final ComponentValidator componentValidator,
+                                 final ComponentIconValidator componentIconValidator,
                                  final ComponentProjectCodeValidator componentProjectCodeValidator,
-                                 final ComponentDescriptionValidator componentDescriptionValidator, final PolicyBusinessLogic policyBusinessLogic) {
+                                 final ComponentDescriptionValidator componentDescriptionValidator, final PolicyBusinessLogic policyBusinessLogic,
+                                 final ModelBusinessLogic modelBusinessLogic, final DataTypeBusinessLogic dataTypeBusinessLogic,
+                                 final PolicyTypeBusinessLogic policyTypeBusinessLogic, final ModelOperation modelOperation) {
         super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, groupBusinessLogic, interfaceOperation,
             interfaceLifecycleTypeOperation, artifactsBusinessLogic, artifactToscaOperation, componentContactIdValidator, componentNameValidator,
             componentTagsValidator, componentValidator, componentIconValidator, componentProjectCodeValidator, componentDescriptionValidator);
@@ -255,11 +265,14 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
         this.compositionBusinessLogic = compositionBusinessLogic;
         this.resourceDataMergeBusinessLogic = resourceDataMergeBusinessLogic;
         this.csarArtifactsAndGroupsBusinessLogic = csarArtifactsAndGroupsBusinessLogic;
-        this.mergeInstanceUtils = mergeInstanceUtils;
         this.uiComponentDataConverter = uiComponentDataConverter;
         this.csarBusinessLogic = csarBusinessLogic;
         this.propertyBusinessLogic = propertyBusinessLogic;
         this.policyBusinessLogic = policyBusinessLogic;
+        this.modelBusinessLogic = modelBusinessLogic;
+        this.dataTypeBusinessLogic = dataTypeBusinessLogic;
+        this.policyTypeBusinessLogic = policyTypeBusinessLogic;
+        this.modelOperation = modelOperation;
     }
 
     static <T> Either<T, RuntimeException> rollbackWithEither(final JanusGraphDao janusGraphDao, final ActionStatus actionStatus,
@@ -320,10 +333,6 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
         this.artifactsBusinessLogic = artifactsManager;
     }
 
-    public ApplicationDataTypeCache getApplicationDataTypeCache() {
-        return applicationDataTypeCache;
-    }
-
     @Autowired
     @Override
     public void setApplicationDataTypeCache(ApplicationDataTypeCache applicationDataTypeCache) {
@@ -508,9 +517,9 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
         validateLifecycleState(oldResource, user);
         String lockedResourceId = oldResource.getUniqueId();
         List<ArtifactDefinition> createdArtifacts = new ArrayList<>();
-        CsarInfo csarInfo = csarBusinessLogic.getCsarInfo(newResource, oldResource, user, csarUIPayload, csarUUID);
+        CsarInfo csarInfo = csarBusinessLogic.getCsarInfo(newResource, oldResource, user, csarUIPayload, csarUUID, null);
         lockComponent(lockedResourceId, oldResource, "update Resource From Csar");
-        Map<String, NodeTypeInfo> nodeTypesInfo = csarInfo.extractNodeTypesInfo();
+        Map<String, NodeTypeInfo> nodeTypesInfo = csarInfo.extractTypesInfo();
         Either<Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>>, ResponseFormat> findNodeTypesArtifactsToHandleRes = findNodeTypesArtifactsToHandle(
             nodeTypesInfo, csarInfo, oldResource);
         if (findNodeTypesArtifactsToHandleRes.isRight()) {
@@ -561,14 +570,18 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
             preparedResource = updateExistingResourceByImport(newResource, oldResource, csarInfo.getModifier(), inTransaction, shouldLock,
                 isNested).left;
             log.trace("YAML topology file found in CSAR, file name: {}, contents: {}", yamlFileName, yamlFileContent);
-            handleResourceGenericType(preparedResource);
+            handleResourceGenericType(preparedResource, yamlFileContent, uploadComponentInstanceInfoMap,
+                uploadComponentInstanceInfoMap.getSubstitutionMappingNodeType());
             handleNodeTypes(yamlFileName, preparedResource, yamlFileContent, shouldLock, nodeTypesArtifactsToHandle, createdArtifacts, nodeTypesInfo,
-                csarInfo, nodeName);
+                csarInfo, nodeName, newResource.getModel());
             preparedResource = createInputsOnResource(preparedResource, uploadComponentInstanceInfoMap.getInputs());
             Map<String, Resource> existingNodeTypesByResourceNames = new HashMap<>();
-            preparedResource = createResourceInstances(yamlFileName, preparedResource, oldResource, instances, csarInfo.getCreatedNodes(),
+            final Map<String, UploadComponentInstanceInfo> instancesToCreate = getInstancesToCreate(uploadComponentInstanceInfoMap,
+                newResource.getModel());
+            preparedResource = createResourceInstances(yamlFileName, preparedResource, oldResource, instancesToCreate, csarInfo.getCreatedNodes(),
                 existingNodeTypesByResourceNames);
-            preparedResource = createResourceInstancesRelations(csarInfo.getModifier(), yamlFileName, preparedResource, oldResource, instances,
+            preparedResource = createResourceInstancesRelations(csarInfo.getModifier(), yamlFileName, preparedResource, oldResource,
+                instancesToCreate,
                 existingNodeTypesByResourceNames);
         } catch (ComponentException e) {
             ResponseFormat responseFormat =
@@ -717,12 +730,32 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
 
     private Resource handleResourceGenericType(Resource resource) {
         Resource genericResource = fetchAndSetDerivedFromGenericType(resource);
+
         if (resource.shouldGenerateInputs()) {
             generateAndAddInputsFromGenericTypeProperties(resource, genericResource);
         }
         return genericResource;
     }
 
+    private Resource handleResourceGenericType(final Resource resource, final String topologyTemplateYaml,
+                                               final ParsedToscaYamlInfo parsedToscaYamlInfo, final String substitutionMappingNodeType) {
+        if (processSubstitutableAsNodeType(resource, parsedToscaYamlInfo)) {
+            final Map<String, Object> substitutableAsNodeType = getSubstitutableAsNodeTypeFromTemplate(
+                (Map<String, Object>) new Yaml().load(topologyTemplateYaml), substitutionMappingNodeType);
+            final Resource genericResource = fetchAndSetDerivedFromGenericType(resource,
+                (String) substitutableAsNodeType.get(TypeUtils.ToscaTagNamesEnum.DERIVED_FROM.getElementName()));
+
+            generatePropertiesFromGenericType(resource, genericResource);
+            generatePropertiesFromNodeType(resource, substitutableAsNodeType);
+            final String resourceId = resource.getUniqueId();
+            resource.getProperties().forEach(propertyDefinition -> propertyDefinition.setUniqueId(
+                UniqueIdBuilder.buildPropertyUniqueId(resourceId, propertyDefinition.getName())));
+            createResourcePropertiesOnGraph(resource);
+            return genericResource;
+        }
+        return handleResourceGenericType(resource);
+    }
+
     private Either<Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>>, ResponseFormat> findNodeTypesArtifactsToHandle(
         final Map<String, NodeTypeInfo> nodeTypesInfo, final CsarInfo csarInfo, final Resource oldResource) {
         final Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle = new HashMap<>();
@@ -788,7 +821,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
             componentsUtils.auditResource(responseFormat, csarInfo.getModifier(), resource, AuditingActionEnum.CREATE_RESOURCE);
             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status), csarInfo.getCsarUUID());
         } else if (StringUtils.isNotEmpty(currVfcToscaName)) {
-            return (Resource) toscaOperationFacade.getLatestByToscaResourceName(currVfcToscaName).left()
+            return (Resource) toscaOperationFacade.getLatestByToscaResourceName(currVfcToscaName, resource.getModel()).left()
                 .on(st -> findVfcResource(csarInfo, resource, previousVfcToscaName, null, st));
         }
         return null;
@@ -969,7 +1002,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
         if (!nodes.isEmpty()) {
             for (Entry<String, Object> nodeType : nodes.entrySet()) {
                 final ImmutablePair<String, String> toscaResourceName = buildNestedToscaResourceName(ResourceTypeEnum.VFC.name(), vfResourceName,
-                        nodeType.getKey());
+                    nodeType.getKey());
                 vfcToscaNames.put(nodeType.getKey(), toscaResourceName);
             }
         }
@@ -1001,8 +1034,23 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
         loggerSupportability
             .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, StatusCode.STARTED, "Starting to create Resource From Csar by user {}",
                 user.getUserId());
-        CsarInfo csarInfo = csarBusinessLogic.getCsarInfo(resource, null, user, csarUIPayload, csarUUID);
-        Map<String, NodeTypeInfo> nodeTypesInfo = csarInfo.extractNodeTypesInfo();
+        OnboardedCsarInfo csarInfo = csarBusinessLogic.getCsarInfo(resource, null, user, csarUIPayload, csarUUID, null);
+
+        Map<String, NodeTypeInfo> nodeTypesInfo = csarInfo.extractTypesInfo();
+        final String model = resource.getModel();
+        if (StringUtils.isNotEmpty(model)) {
+            final Map<String, Object> dataTypesToCreate = getDatatypesToCreate(model, csarInfo.getDataTypes());
+            final Map<String, Object> policyTypesToCreate = getPolicytypesToCreate(model, csarInfo.getPolicyTypes());
+            if (MapUtils.isNotEmpty(dataTypesToCreate) || MapUtils.isNotEmpty(policyTypesToCreate)) {
+                createModel(resource, csarInfo.getVfResourceName());
+            }
+            if (MapUtils.isNotEmpty(dataTypesToCreate)) {
+                dataTypeBusinessLogic.createDataTypeFromYaml(new Yaml().dump(dataTypesToCreate), model, true);
+            }
+            if (MapUtils.isNotEmpty(policyTypesToCreate)) {
+                policyTypeBusinessLogic.createPolicyTypeFromYaml(new Yaml().dump(policyTypesToCreate), model, true);
+            }
+        }
         Either<Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>>, ResponseFormat> findNodeTypesArtifactsToHandleRes = findNodeTypesArtifactsToHandle(
             nodeTypesInfo, csarInfo, resource);
         if (findNodeTypesArtifactsToHandleRes.isRight()) {
@@ -1072,23 +1120,69 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
                                                                       boolean needLock,
                                                                       Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle,
                                                                       List<ArtifactDefinition> nodeTypesNewCreatedArtifacts,
-                                                                      Map<String, NodeTypeInfo> nodeTypesInfo, CsarInfo csarInfo) {
+                                                                      Map<String, NodeTypeInfo> nodeTypesInfo, CsarInfo csarInfo,
+                                                                      final String substitutableAsNodeType) {
         Either<String, ResultStatusEnum> toscaVersion = findFirstToscaStringElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.TOSCA_VERSION);
         if (toscaVersion.isRight()) {
             throw new ByActionStatusComponentException(ActionStatus.INVALID_TOSCA_TEMPLATE);
         }
         Map<String, Object> mapToConvert = new HashMap<>();
         mapToConvert.put(TypeUtils.ToscaTagNamesEnum.TOSCA_VERSION.getElementName(), toscaVersion.left().value());
-        Map<String, Object> nodeTypes = getNodeTypesFromTemplate(mappedToscaTemplate);
+        final Map<String, Object> nodeTypes = getNodeTypesFromTemplate(mappedToscaTemplate, substitutableAsNodeType);
         createNodeTypes(yamlName, resource, needLock, nodeTypesArtifactsToHandle, nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo, mapToConvert,
             nodeTypes);
         return csarInfo.getCreatedNodes();
     }
 
-    private Map<String, Object> getNodeTypesFromTemplate(Map<String, Object> mappedToscaTemplate) {
+    private Map<String, Object> getNodeTypesFromTemplate(final Map<String, Object> mappedToscaTemplate, final String substitutableAsNodeType) {
+        final Map<String, Object> nodeTypes = getAllNodeTypesInTemplate(mappedToscaTemplate);
+        if (StringUtils.isNotEmpty(substitutableAsNodeType)) {
+            nodeTypes.remove(substitutableAsNodeType);
+        }
+        return nodeTypes;
+    }
+
+    @SuppressWarnings("unchecked")
+    private Map<String, Object> getSubstitutableAsNodeTypeFromTemplate(final Map<String, Object> mappedToscaTemplate,
+                                                                       final String substitutableAsNodeType) {
+        return (Map<String, Object>) getAllNodeTypesInTemplate(mappedToscaTemplate).get(substitutableAsNodeType);
+    }
+
+    private Map<String, Object> getAllNodeTypesInTemplate(final Map<String, Object> mappedToscaTemplate) {
         return ImportUtils.findFirstToscaMapElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES).left().orValue(HashMap::new);
     }
 
+    private void createModel(final Resource resource, final String vfResourcename) {
+        final String nameForGeneratedModel = resource.getModel() + "_" + vfResourcename + resource.getCsarVersion();
+        Model model = new Model(nameForGeneratedModel, resource.getModel(), ModelTypeEnum.NORMATIVE_EXTENSION);
+        modelBusinessLogic.createModel(model);
+        resource.setModel(nameForGeneratedModel);
+    }
+
+    private Map<String, Object> getDatatypesToCreate(final String model, final Map<String, Object> dataTypes) {
+        final Map<String, Object> dataTypesToCreate = new HashMap<>();
+        for (final String dataType : dataTypes.keySet()) {
+            final Either<DataTypeDefinition, StorageOperationStatus> result =
+                propertyOperation.getDataTypeByName(dataType, model);
+            if (result.isRight() && result.right().value().equals(StorageOperationStatus.NOT_FOUND)) {
+                dataTypesToCreate.put(dataType, dataTypes.get(dataType));
+            }
+        }
+        return dataTypesToCreate;
+    }
+
+    private Map<String, Object> getPolicytypesToCreate(final String model, final Map<String, Object> policyTypes) {
+        final Map<String, Object> policyTypesToCreate = new HashMap<>();
+        for (final String policyType : policyTypes.keySet()) {
+            final Either<PolicyTypeDefinition, StorageOperationStatus> result =
+                policyTypeOperation.getLatestPolicyTypeByType(policyType, model);
+            if (result.isRight() && result.right().value().equals(StorageOperationStatus.NOT_FOUND)) {
+                policyTypesToCreate.put(policyType, policyTypes.get(policyType));
+            }
+        }
+        return policyTypesToCreate;
+    }
+
     private void createNodeTypes(String yamlName, Resource resource, boolean needLock,
                                  Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle,
                                  List<ArtifactDefinition> nodeTypesNewCreatedArtifacts, Map<String, NodeTypeInfo> nodeTypesInfo, CsarInfo csarInfo,
@@ -1127,7 +1221,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
         Map<String, Object> nestedVfcJsonMap = nodesInfo.get(nodeName).getMappedToscaTemplate();
         log.debug("************* Going to create node types from yaml {}", yamlName);
         createResourcesFromYamlNodeTypesList(yamlName, resource, nestedVfcJsonMap, false, nodesArtifactsToHandle, createdArtifacts,
-            Collections.emptyMap(), csarInfo);
+            Collections.emptyMap(), csarInfo, resource.getModel());
         log.debug("************* Finished to create node types from yaml {}", yamlName);
         if (nestedVfcJsonMap.containsKey(TypeUtils.ToscaTagNamesEnum.TOPOLOGY_TEMPLATE.getElementName())) {
             log.debug("************* Going to handle complex VFC from yaml {}", yamlName);
@@ -1252,7 +1346,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
         Function<Resource, Boolean> validator = resource -> validateResourceCreationFromNodeType(resource, creator);
         return resourceImportManager
             .importCertifiedResource(nodeTypeYaml, resourceMetaData, creator, validator, lifecycleChangeInfo, isInTransaction, true, needLock,
-                nodeTypeArtifactsToHandle, nodeTypesNewCreatedArtifacts, forceCertificationAllowed, csarInfo, nodeName, isNested);
+                nodeTypeArtifactsToHandle, nodeTypesNewCreatedArtifacts, forceCertificationAllowed, csarInfo, nodeName, isNested, null);
     }
 
     /**
@@ -1313,7 +1407,9 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
         resourceMetaData.setIcon(ImportUtils.Constants.DEFAULT_ICON);
         resourceMetaData.setContactId(user.getUserId());
         resourceMetaData.setVendorName(resourceVf.getVendorName());
+        resourceMetaData.setTenant(resourceVf.getTenant());
         resourceMetaData.setVendorRelease(resourceVf.getVendorRelease());
+        resourceMetaData.setModel(resourceVf.getModel());
         // Setting tag
         final List<String> tags = new ArrayList<>();
         tags.add(resourceMetaData.getName());
@@ -1345,7 +1441,9 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
         cvfc.setContactId(csarInfo.getModifier().getUserId());
         cvfc.setCreatorUserId(csarInfo.getModifier().getUserId());
         cvfc.setVendorName(resourceVf.getVendorName());
+        cvfc.setTenant(resourceVf.getTenant());
         cvfc.setVendorRelease(resourceVf.getVendorRelease());
+        cvfc.setModel(resourceVf.getModel());
         cvfc.setResourceVendorModelNumber(resourceVf.getResourceVendorModelNumber());
         cvfc.setToscaResourceName(buildNestedToscaResourceName(ResourceTypeEnum.CVFC.name(), csarInfo.getVfResourceName(), nodeName).getLeft());
         cvfc.setInvariantUUID(UniqueIdBuilder.buildInvariantUUID());
@@ -1393,42 +1491,77 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
             log.trace("************* createResourceFromYaml before full create resource {}", yamlName);
             loggerSupportability.log(LoggerSupportabilityActions.CREATE_INPUTS, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,
                 "Starting to add inputs from yaml: {}", yamlName);
-            final Resource genericResource = fetchAndSetDerivedFromGenericType(resource);
-            resource = createResourceTransaction(resource, csarInfo.getModifier(), isNormative);
-            log.trace("************* createResourceFromYaml after full create resource {}", yamlName);
-            log.trace("************* Going to add inputs from yaml {}", yamlName);
-            if (resource.shouldGenerateInputs()) {
-                generateAndAddInputsFromGenericTypeProperties(resource, genericResource);
-            }
-            final Map<String, InputDefinition> inputs = parsedToscaYamlInfo.getInputs();
-            resource = createInputsOnResource(resource, inputs);
-            log.trace("************* Finish to add inputs from yaml {}", yamlName);
-            loggerSupportability.log(LoggerSupportabilityActions.CREATE_INPUTS, resource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE,
-                "Finish to add inputs from yaml: {}", yamlName);
-            if (resource.getResourceType() == ResourceTypeEnum.PNF) {
-                log.trace("************* Adding generic properties to PNF");
-                resource = (Resource) propertyBusinessLogic.copyPropertyToComponent(resource, genericResource.getProperties());
-                log.trace("************* Adding software information to PNF");
-                softwareInformationBusinessLogic.setSoftwareInformation(resource, csarInfo);
-                log.trace("************* Removing non-mano software information file from PNF");
-                if (csarInfo.getSoftwareInformationPath().isPresent() && !softwareInformationBusinessLogic.removeSoftwareInformationFile(csarInfo)) {
-                    log.warn(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, ResourceBusinessLogic.class.getName(), "catalog-be",
-                        "Could not remove the software information file.");
+            if (processSubstitutableAsNodeType(resource, parsedToscaYamlInfo)) {
+                final Map<String, Object> substitutableAsNodeType = getSubstitutableAsNodeTypeFromTemplate(
+                    (Map<String, Object>) new Yaml().load(topologyTemplateYaml), parsedToscaYamlInfo.getSubstitutionMappingNodeType());
+                resource.setToscaResourceName(parsedToscaYamlInfo.getSubstitutionMappingNodeType());
+                final Resource genericResource = fetchAndSetDerivedFromGenericType(resource,
+                    (String) substitutableAsNodeType.get(TypeUtils.ToscaTagNamesEnum.DERIVED_FROM.getElementName()));
+                resource = createResourceTransaction(resource, csarInfo.getModifier(), isNormative);
+                generatePropertiesFromGenericType(resource, genericResource);
+                generatePropertiesFromNodeType(resource, substitutableAsNodeType);
+                final String resourceId = resource.getUniqueId();
+                resource.getProperties().forEach(propertyDefinition -> propertyDefinition.setUniqueId(
+                    UniqueIdBuilder.buildPropertyUniqueId(resourceId, propertyDefinition.getName())));
+
+                createResourcePropertiesOnGraph(resource);
+                final Map<String, UploadComponentInstanceInfo> instancesToCreate = getInstancesToCreate(parsedToscaYamlInfo, resource.getModel());
+
+                if (MapUtils.isNotEmpty(instancesToCreate)) {
+                    log.trace("************* Going to create nodes, RI's and Relations  from yaml {}", yamlName);
+                    loggerSupportability
+                        .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,
+                            "Start create nodes, RI and Relations  from yaml: {}", yamlName);
+                    resource = createRIAndRelationsFromYaml(yamlName, resource, instancesToCreate, topologyTemplateYaml,
+                        nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo, nodeTypesArtifactsToCreate, nodeName,
+                        parsedToscaYamlInfo.getSubstitutionMappingNodeType());
                 }
+            } else {
+                final Resource genericResource = fetchAndSetDerivedFromGenericType(resource, null);
+                resource = createResourceTransaction(resource, csarInfo.getModifier(), isNormative);
+                log.trace("************* createResourceFromYaml after full create resource {}", yamlName);
+                log.trace("************* Going to add inputs from yaml {}", yamlName);
+                if (resource.shouldGenerateInputs()) {
+                    generateAndAddInputsFromGenericTypeProperties(resource, genericResource);
+                }
+                final Map<String, InputDefinition> inputs = parsedToscaYamlInfo.getInputs();
+                resource = createInputsOnResource(resource, inputs);
+
+                log.trace("************* Finish to add inputs from yaml {}", yamlName);
+                loggerSupportability.log(LoggerSupportabilityActions.CREATE_INPUTS, resource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE,
+                    "Finish to add inputs from yaml: {}", yamlName);
+                if (resource.getResourceType() == ResourceTypeEnum.PNF) {
+                    log.trace("************* Adding generic properties to PNF");
+                    resource = (Resource) propertyBusinessLogic.copyPropertyToComponent(resource, genericResource.getProperties());
+                    log.trace("************* Adding software information to PNF");
+                    softwareInformationBusinessLogic.setSoftwareInformation(resource, csarInfo);
+                    log.trace("************* Removing non-mano software information file from PNF");
+                    if (csarInfo.getSoftwareInformationPath().isPresent() && !softwareInformationBusinessLogic.removeSoftwareInformationFile(
+                        csarInfo)) {
+                        log.warn(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, ResourceBusinessLogic.class.getName(), "catalog-be",
+                            "Could not remove the software information file.");
+                    }
+                }
+                final Map<String, UploadComponentInstanceInfo> instancesToCreate = getInstancesToCreate(parsedToscaYamlInfo);
+
+                log.trace("************* Going to create nodes, RI's and Relations  from yaml {}", yamlName);
+                loggerSupportability
+                    .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,
+                        "Start create nodes, RI and Relations  from yaml: {}", yamlName);
+                resource = createRIAndRelationsFromYaml(yamlName, resource, instancesToCreate, topologyTemplateYaml,
+                    nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo, nodeTypesArtifactsToCreate, nodeName, null);
             }
-            final Map<String, UploadComponentInstanceInfo> uploadComponentInstanceInfoMap = parsedToscaYamlInfo.getInstances();
-            log.trace("************* Going to create nodes, RI's and Relations  from yaml {}", yamlName);
-            loggerSupportability
-                .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,
-                    "Start create nodes, RI and Relations  from yaml: {}", yamlName);
-            resource = createRIAndRelationsFromYaml(yamlName, resource, uploadComponentInstanceInfoMap, topologyTemplateYaml,
-                nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo, nodeTypesArtifactsToCreate, nodeName);
             log.trace("************* Finished to create nodes, RI and Relation  from yaml {}", yamlName);
             loggerSupportability.log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE,
                 "Finished to create nodes, RI and Relation  from yaml: {}", yamlName);
             // validate update vf module group names
+            Optional<Map<String, GroupDefinition>> asdGroups = checkAndCreateAsdTypeVfModules(parsedToscaYamlInfo.getInstances());
+            Map<String, GroupDefinition> parsedGroups = parsedToscaYamlInfo.getGroups();
+            if (asdGroups.isPresent()) {
+                parsedGroups.putAll(asdGroups.get());
+            }
             final Either<Map<String, GroupDefinition>, ResponseFormat> validateUpdateVfGroupNamesRes = groupBusinessLogic
-                .validateUpdateVfGroupNames(parsedToscaYamlInfo.getGroups(), resource.getSystemName());
+                .validateUpdateVfGroupNames(parsedGroups, resource.getSystemName());
             if (validateUpdateVfGroupNamesRes.isRight()) {
                 rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts);
                 throw new ByResponseFormatComponentException(validateUpdateVfGroupNamesRes.right().value());
@@ -1441,7 +1574,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
             if (!validateUpdateVfGroupNamesRes.left().value().isEmpty()) {
                 groups = validateUpdateVfGroupNamesRes.left().value();
             } else {
-                groups = parsedToscaYamlInfo.getGroups();
+                groups = parsedGroups;
             }
             final Either<Resource, ResponseFormat> createGroupsOnResource = createGroupsOnResource(resource, groups);
             if (createGroupsOnResource.isRight()) {
@@ -1485,11 +1618,11 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
             rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts);
             throw new ByResponseFormatComponentException(e.getResponseFormat());
         } catch (final ComponentException e) {
-                       log.error(EcompLoggerErrorCode.SCHEMA_ERROR, ResourceBusinessLogic.class.getName(),
-                               "An error has occurred during resource and resource instance creation", e);
-                       rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts);
-                       throw new ByResponseFormatComponentException(e.getResponseFormat());
-               } catch (final Exception e) {
+            log.error(EcompLoggerErrorCode.SCHEMA_ERROR, ResourceBusinessLogic.class.getName(),
+                "An error has occurred during resource and resource instance creation", e);
+            rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts);
+            throw new ByResponseFormatComponentException(e.getResponseFormat());
+        } catch (final Exception e) {
             log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, ResourceBusinessLogic.class.getName(),
                 "An error has occurred during resource and resource instance creation", e);
             rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts);
@@ -1504,6 +1637,85 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
         }
     }
 
+    private Optional<Map<String, GroupDefinition>> checkAndCreateAsdTypeVfModules(Map<String, UploadComponentInstanceInfo> instances) {
+        Map<String, GroupDefinition> addAsdGroups = new HashMap<>();
+        if (isNotEmpty(instances) || instances != null) {
+            for (Map.Entry<String, UploadComponentInstanceInfo> instance : instances.entrySet()) {
+                if (isNotEmpty(instance.getValue().getArtifacts()) || instance.getValue().getArtifacts() != null) {
+                    Map<String, UploadArtifactInfo> artifactsMap = instance.getValue().getArtifacts()
+                        .get(ToscaTagNamesEnum.ARTIFACTS.getElementName());
+                    if (isNotEmpty(artifactsMap) || artifactsMap != null) {
+                        for (Map.Entry<String, UploadArtifactInfo> artifact : artifactsMap.entrySet()) {
+                            if (artifact.getValue().getType().equals(Constants.ASD_DEPLOYMENT_ITEM)) {
+                                GroupDefinition groupDefinition = new GroupDefinition();
+                                groupDefinition.setName(artifact.getKey());
+                                groupDefinition.setType(Constants.DEFAULT_GROUP_VF_MODULE);
+                                addAsdTypeProperties(groupDefinition);
+                                addAsdGroups.put(groupDefinition.getName(), groupDefinition);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return Optional.of(addAsdGroups);
+    }
+
+    private void addAsdTypeProperties(GroupDefinition groupDefinition) {
+        List<GroupProperty> properties = new ArrayList<>();
+        GroupProperty propIsBase = new GroupProperty();
+        propIsBase.setName(Constants.IS_BASE);
+        propIsBase.setValue("true");
+        properties.add(propIsBase);
+        GroupProperty propVfModuleLabel = new GroupProperty();
+        propVfModuleLabel.setName(Constants.VF_MODULE_LABEL);
+        propVfModuleLabel.setValue(groupDefinition.getName());
+        properties.add(propVfModuleLabel);
+        GroupProperty propVfModuleDescription = new GroupProperty();
+        propVfModuleDescription.setName(Constants.VF_MODULE_DESCRIPTION);
+        propVfModuleDescription.setValue("VF Module representing deployment item " + groupDefinition.getName());
+        properties.add(propVfModuleDescription);
+        GroupProperty propMinVfModuleInstances = new GroupProperty();
+        propMinVfModuleInstances.setName(Constants.MIN_VF_MODULE_INSTANCES);
+        propMinVfModuleInstances.setValue("1");
+        properties.add(propMinVfModuleInstances);
+        GroupProperty propMaxVfModuleInstances = new GroupProperty();
+        propMaxVfModuleInstances.setName(Constants.MAX_VF_MODULE_INSTANCES);
+        propMaxVfModuleInstances.setValue("1");
+        properties.add(propMaxVfModuleInstances);
+        GroupProperty propInitialCount = new GroupProperty();
+        propInitialCount.setName(Constants.INITIAL_COUNT);
+        propInitialCount.setValue("1");
+        properties.add(propInitialCount);
+        GroupProperty propVfModuleType = new GroupProperty();
+        propVfModuleType.setName(Constants.VF_MODULE_TYPE);
+        propVfModuleType.setValue("Base");
+        properties.add(propVfModuleType);
+        GroupProperty propVolumeGroup = new GroupProperty();
+        propVolumeGroup.setName(Constants.VOLUME_GROUP);
+        propVolumeGroup.setValue("false");
+        properties.add(propVolumeGroup);
+        groupDefinition.convertFromGroupProperties(properties);
+    }
+
+    private boolean processSubstitutableAsNodeType(final Resource resource, final ParsedToscaYamlInfo parsedToscaYamlInfo) {
+        return !resource.getResourceType().isAtomicType() && StringUtils.isNotEmpty(resource.getModel())
+            && parsedToscaYamlInfo.getSubstitutionMappingNodeType() != null;
+    }
+
+    private Map<String, UploadComponentInstanceInfo> getInstancesToCreate(final ParsedToscaYamlInfo parsedToscaYamlInfo) {
+        return getInstancesToCreate(parsedToscaYamlInfo, null);
+    }
+
+    private Map<String, UploadComponentInstanceInfo> getInstancesToCreate(final ParsedToscaYamlInfo parsedToscaYamlInfo, final String model) {
+        if (StringUtils.isEmpty(model) || StringUtils.isEmpty(parsedToscaYamlInfo.getSubstitutionMappingNodeType())) {
+            return parsedToscaYamlInfo.getInstances();
+        }
+        return parsedToscaYamlInfo.getInstances().entrySet().stream()
+            .filter(entry -> !parsedToscaYamlInfo.getSubstitutionMappingNodeType().equals(entry.getValue().getType()))
+            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
+    }
+
     private void rollback(boolean inTransaction, Resource resource, List<ArtifactDefinition> createdArtifacts,
                           List<ArtifactDefinition> nodeTypesNewCreatedArtifacts) {
         if (!inTransaction) {
@@ -1547,7 +1759,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
     }
 
     private Resource createPoliciesOnResource(Resource resource, Map<String, PolicyDefinition> policies) {
-        policyBusinessLogic.createPoliciesFromParsedCsar(resource, policies);
+        policyBusinessLogic.createPolicies(resource, policies);
         return resource;
     }
 
@@ -1688,18 +1900,51 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
         return resource;
     }
 
+    private Resource generatePropertiesFromNodeType(final Resource resource, final Map<String, Object> nodeType) {
+        final Either<Map<String, PropertyDefinition>, ResultStatusEnum> properties = ImportUtils.getProperties(nodeType);
+        if (properties.isLeft()) {
+            final List<PropertyDefinition> propertiesList = new ArrayList<>();
+            final Map<String, PropertyDefinition> value = properties.left().value();
+            if (value != null) {
+                for (Entry<String, PropertyDefinition> entry : value.entrySet()) {
+                    final String name = entry.getKey();
+                    final PropertyDefinition propertyDefinition = entry.getValue();
+                    propertyDefinition.setName(name);
+                    propertiesList.add(propertyDefinition);
+                    resource.getProperties().removeIf(p -> p.getName().equals(name));
+                }
+            }
+            resource.getProperties().addAll(propertiesList);
+        }
+        return resource;
+    }
+
+    private Resource createResourcePropertiesOnGraph(final Resource resource) {
+        final List<PropertyDefinition> resourceProperties = resource.getProperties();
+        for (PropertyDefinition propertyDefinition : resourceProperties) {
+            final Either<PropertyDefinition, StorageOperationStatus> addPropertyEither = toscaOperationFacade
+                .addPropertyToComponent(propertyDefinition, resource);
+
+            if (addPropertyEither.isRight()) {
+                final String error = String.format("failed to add properties from yaml: %s", addPropertyEither.right().value());
+                loggerSupportability.log(LoggerSupportabilityActions.CREATE_PROPERTIES, resource.getComponentMetadataForSupportLog(),
+                    StatusCode.ERROR,
+                    error);
+                throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(addPropertyEither.right().value()), error);
+            }
+        }
+        return resource;
+    }
+
     private List<GroupDefinition> updateGroupsMembersUsingResource(Map<String, GroupDefinition> groups, Resource component) {
         List<GroupDefinition> result = new ArrayList<>();
         List<ComponentInstance> componentInstances = component.getComponentInstances();
         if (groups != null) {
-            Either<Boolean, ResponseFormat> validateCyclicGroupsDependencies = validateCyclicGroupsDependencies(groups);
-            if (validateCyclicGroupsDependencies.isRight()) {
-                throw new ByResponseFormatComponentException(validateCyclicGroupsDependencies.right().value());
-            }
             for (Entry<String, GroupDefinition> entry : groups.entrySet()) {
                 String groupName = entry.getKey();
                 GroupDefinition groupDefinition = entry.getValue();
                 GroupDefinition updatedGroupDefinition = new GroupDefinition(groupDefinition);
+
                 updatedGroupDefinition.setMembers(null);
                 Map<String, String> members = groupDefinition.getMembers();
                 if (members != null) {
@@ -1737,100 +1982,15 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
         updatedGroupDefinition.setMembers(relevantInstances);
     }
 
-    /**
-     * This Method validates that there is no cyclic group dependencies. meaning group A as member in group B which is member in group A
-     *
-     * @param allGroups
-     * @return
-     */
-    private Either<Boolean, ResponseFormat> validateCyclicGroupsDependencies(Map<String, GroupDefinition> allGroups) {
-        Either<Boolean, ResponseFormat> result = Either.left(true);
-        try {
-            Iterator<Entry<String, GroupDefinition>> allGroupsItr = allGroups.entrySet().iterator();
-            while (allGroupsItr.hasNext() && result.isLeft()) {
-                Entry<String, GroupDefinition> groupAEntry = allGroupsItr.next();
-                // Fetches a group member A
-                String groupAName = groupAEntry.getKey();
-                // Finds all group members in group A
-                Set<String> allGroupAMembersNames = new HashSet<>();
-                fillAllGroupMemebersRecursivly(groupAEntry.getKey(), allGroups, allGroupAMembersNames);
-                // If A is a group member of itself found cyclic dependency
-                if (allGroupAMembersNames.contains(groupAName)) {
-                    ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GROUP_HAS_CYCLIC_DEPENDENCY, groupAName);
-                    result = Either.right(responseFormat);
-                }
-            }
-        } catch (Exception e) {
-            ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
-            result = Either.right(responseFormat);
-            log.debug("Exception occurred when validateCyclicGroupsDependencies, error is:{}", e.getMessage(), e);
-        }
-        return result;
-    }
-
-    /**
-     * This Method fills recursively the set groupMembers with all the members of the given group which are also of type group.
-     *
-     * @param groupName
-     * @param allGroups
-     * @param allGroupMembers
-     * @return
-     */
-    private void fillAllGroupMemebersRecursivly(String groupName, Map<String, GroupDefinition> allGroups, Set<String> allGroupMembers) {
-        // Found Cyclic dependency
-        if (isfillGroupMemebersRecursivlyStopCondition(groupName, allGroups, allGroupMembers)) {
-            return;
-        }
-        GroupDefinition groupDefinition = allGroups.get(groupName);
-        // All Members Of Current Group Resource Instances & Other Groups
-        Set<String> currGroupMembers = groupDefinition.getMembers().keySet();
-        // Filtered Members Of Current Group containing only members which
-
-        // are groups
-        List<String> currGroupFilteredMembers = currGroupMembers.stream().
-            // Keep Only Elements of type group and not Resource Instances
-                filter(allGroups::containsKey).
-            // Add Filtered Elements to main Set
-                peek(allGroupMembers::add).
-            // Collect results
-                collect(toList());
-        // Recursively call the method for all the filtered group members
-        for (String innerGroupName : currGroupFilteredMembers) {
-            fillAllGroupMemebersRecursivly(innerGroupName, allGroups, allGroupMembers);
-        }
-    }
-
-    private boolean isfillGroupMemebersRecursivlyStopCondition(String groupName, Map<String, GroupDefinition> allGroups,
-                                                               Set<String> allGroupMembers) {
-        boolean stop = !allGroups.containsKey(groupName);
-        // In Case Not Group Stop
-        // In Case Group Has no members stop
-        if (!stop) {
-            GroupDefinition groupDefinition = allGroups.get(groupName);
-            stop = isEmpty(groupDefinition.getMembers());
-        }
-        // In Case all group members already contained stop
-        if (!stop) {
-            final Set<String> allMembers = allGroups.get(groupName).getMembers().keySet();
-            Set<String> membersOfTypeGroup = allMembers.stream().
-                // Filter In Only Group members
-                    filter(allGroups::containsKey).
-                // Collect
-                    collect(toSet());
-            stop = allGroupMembers.containsAll(membersOfTypeGroup);
-        }
-        return stop;
-    }
-
     private Resource createRIAndRelationsFromYaml(String yamlName, Resource resource,
                                                   Map<String, UploadComponentInstanceInfo> uploadComponentInstanceInfoMap,
                                                   String topologyTemplateYaml, List<ArtifactDefinition> nodeTypesNewCreatedArtifacts,
                                                   Map<String, NodeTypeInfo> nodeTypesInfo, CsarInfo csarInfo,
                                                   Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToCreate,
-                                                  String nodeName) {
+                                                  String nodeName, final String substitutableAsNodeType) {
         log.debug("************* Going to create all nodes {}", yamlName);
         handleNodeTypes(yamlName, resource, topologyTemplateYaml, false, nodeTypesArtifactsToCreate, nodeTypesNewCreatedArtifacts, nodeTypesInfo,
-            csarInfo, nodeName);
+            csarInfo, nodeName, substitutableAsNodeType);
         log.debug("************* Finished to create all nodes {}", yamlName);
         log.debug("************* Going to create all resource instances {}", yamlName);
         Map<String, Resource> existingNodeTypesByResourceNames = new HashMap<>();
@@ -1862,10 +2022,10 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
     private void handleNodeTypes(String yamlName, Resource resource, String topologyTemplateYaml, boolean needLock,
                                  Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle,
                                  List<ArtifactDefinition> nodeTypesNewCreatedArtifacts, Map<String, NodeTypeInfo> nodeTypesInfo, CsarInfo csarInfo,
-                                 String nodeName) {
+                                 String nodeName, String substitutableAsNodeType) {
         try {
             for (Entry<String, NodeTypeInfo> nodeTypeEntry : nodeTypesInfo.entrySet()) {
-                if (nodeTypeEntry.getValue().isNested() && !nodeTypeAlreadyExists(nodeTypeEntry.getKey())) {
+                if (nodeTypeEntry.getValue().isNested() && !nodeTypeAlreadyExists(nodeTypeEntry.getKey(), resource.getModel())) {
                     handleNestedVfc(resource, nodeTypesArtifactsToHandle, nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo,
                         nodeTypeEntry.getKey());
                     log.trace("************* finished to create node {}", nodeTypeEntry.getKey());
@@ -1879,7 +2039,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
                 mappedToscaTemplate = (Map<String, Object>) new Yaml().load(topologyTemplateYaml);
             }
             createResourcesFromYamlNodeTypesList(yamlName, resource, mappedToscaTemplate, needLock, nodeTypesArtifactsToHandle,
-                nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo);
+                nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo, substitutableAsNodeType);
         } catch (ComponentException e) {
             ResponseFormat responseFormat =
                 e.getResponseFormat() != null ? e.getResponseFormat() : componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
@@ -1892,9 +2052,9 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
             throw e;
         }
     }
-    
-    private boolean nodeTypeAlreadyExists(final String toscaResourceName) {
-        return toscaOperationFacade.getLatestByToscaResourceName(toscaResourceName).isLeft();
+
+    private boolean nodeTypeAlreadyExists(final String toscaResourceName, String modelName) {
+        return toscaOperationFacade.getLatestByToscaResourceName(toscaResourceName, modelName).isLeft();
     }
 
     private Either<Resource, ResponseFormat> handleVfCsarArtifacts(Resource resource, CsarInfo csarInfo, List<ArtifactDefinition> createdArtifacts,
@@ -1921,12 +2081,12 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
                 Constants.VENDOR_LICENSE_MODEL, ArtifactTypeEnum.VENDOR_LICENSE.getType(), ArtifactGroupTypeEnum.DEPLOYMENT,
                 Constants.VENDOR_LICENSE_LABEL, Constants.VENDOR_LICENSE_DISPLAY_NAME, Constants.VENDOR_LICENSE_DESCRIPTION, vendorLicenseModelId,
                 artifactOperation, null, true, shouldLock, inTransaction);
-            createOrUpdateSingleNonMetaArtifact(resource, csarInfo, CsarUtils.ARTIFACTS_PATH + Constants.VF_LICENSE_MODEL, Constants.VF_LICENSE_MODEL,
-                ArtifactTypeEnum.VF_LICENSE.getType(), ArtifactGroupTypeEnum.DEPLOYMENT, Constants.VF_LICENSE_LABEL,
-                Constants.VF_LICENSE_DISPLAY_NAME, Constants.VF_LICENSE_DESCRIPTION, vfLicenseModelId, artifactOperation, null, true, shouldLock,
-                inTransaction);
-            Either<Resource, ResponseFormat> eitherCreateResult = createOrUpdateNonMetaArtifacts(csarInfo, resource, createdArtifacts, shouldLock,
-                inTransaction, artifactOperation);
+            createOrUpdateSingleNonMetaArtifact(resource, csarInfo, CsarUtils.ARTIFACTS_PATH + Constants.VF_LICENSE_MODEL,
+                Constants.VF_LICENSE_MODEL, ArtifactTypeEnum.VF_LICENSE.getType(), ArtifactGroupTypeEnum.DEPLOYMENT,
+                Constants.VF_LICENSE_LABEL, Constants.VF_LICENSE_DISPLAY_NAME, Constants.VF_LICENSE_DESCRIPTION, vfLicenseModelId,
+                artifactOperation, null, true, shouldLock, inTransaction);
+            Either<Resource, ResponseFormat> eitherCreateResult
+                = createOrUpdateNonMetaArtifacts(csarInfo, resource, createdArtifacts, shouldLock, inTransaction, artifactOperation);
             if (eitherCreateResult.isRight()) {
                 return Either.right(eitherCreateResult.right().value());
             }
@@ -1955,8 +2115,6 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
                     return Either.right(createArtifactsFromCsar.right().value());
                 }
                 return Either.left(createArtifactsFromCsar.left().value());
-            } else {
-                return csarArtifactsAndGroupsBusinessLogic.deleteVFModules(resource, csarInfo, shouldLock, inTransaction);
             }
         }
         return Either.left(resource);
@@ -2044,7 +2202,8 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
             Either<List<NonMetaArtifactInfo>, String> artifactPathAndNameList = getValidArtifactNames(csarInfo, collectedWarningMessages);
             if (artifactPathAndNameList.isRight()) {
                 return Either.right(
-                    getComponentsUtils().getResponseFormatByArtifactId(ActionStatus.ARTIFACT_NAME_INVALID, artifactPathAndNameList.right().value()));
+                    getComponentsUtils().getResponseFormatByArtifactId(ActionStatus.ARTIFACT_NAME_INVALID, artifactPathAndNameList.right().value(),
+                        VALID_CHARACTERS_ARTIFACT_NAME));
             }
             EnumMap<ArtifactOperationEnum, List<NonMetaArtifactInfo>> vfCsarArtifactsToHandle = null;
             if (artifactOperation.isCreateOrLink()) {
@@ -2166,7 +2325,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
 
     private boolean isValidArtifactType(ArtifactDefinition artifact) {
         return artifact.getArtifactType() != null && ArtifactTypeEnum.parse(artifact.getArtifactType()) != ArtifactTypeEnum.VENDOR_LICENSE
-                && ArtifactTypeEnum.parse(artifact.getArtifactType()) != ArtifactTypeEnum.VF_LICENSE;
+            && ArtifactTypeEnum.parse(artifact.getArtifactType()) != ArtifactTypeEnum.VF_LICENSE;
     }
 
     private Resource createResourceInstancesRelations(User user, String yamlName, Resource resource, Resource oldResource,
@@ -2195,21 +2354,10 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
         Map<String, List<AttributeDefinition>> instAttributes = new HashMap<>();
         List<RequirementCapabilityRelDef> relations = new ArrayList<>();
         Map<String, List<ComponentInstanceInput>> instInputs = new HashMap<>();
-        log.debug("#createResourceInstancesRelations - Before get all datatypes. ");
-        Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> allDataTypes = dataTypeCache.getAll();
-        if (allDataTypes.isRight()) {
-            JanusGraphOperationStatus status = allDataTypes.right().value();
-            BeEcompErrorManager.getInstance()
-                .logInternalFlowError("UpdatePropertyValueOnComponentInstance", "Failed to update property value on instance. Status is " + status,
-                    ErrorSeverity.ERROR);
-            loggerSupportability.log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
-                "ERROR while update property value on instance. Status is: " + status);
-            throw new ByActionStatusComponentException(
-                componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status)), yamlName);
-        }
         Resource finalResource = resource;
         uploadResInstancesMap.values().forEach(
-            i -> processComponentInstance(yamlName, finalResource, componentInstancesList, allDataTypes, instProperties, instCapabilities,
+            i -> processComponentInstance(yamlName, finalResource, componentInstancesList,
+                componentsUtils.getAllDataTypes(applicationDataTypeCache, resource.getModel()), instProperties, instCapabilities,
                 instRequirements, instDeploymentArtifacts, instArtifacts, instAttributes, existingNodeTypesByResourceNames, instInputs, i));
         resource.getComponentInstances().stream().filter(i -> !i.isCreatedFromCsar()).forEach(
             i -> processUiComponentInstance(oldResource, i, instCapabilities, instRequirements, instDeploymentArtifacts, instArtifacts,
@@ -2382,14 +2530,18 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
     }
 
     private void handleSubstitutionMappings(Resource resource, Map<String, UploadComponentInstanceInfo> uploadResInstancesMap) {
+        Either<Resource, StorageOperationStatus> getResourceRes = null;
         if (resource.getResourceType() == ResourceTypeEnum.CVFC) {
-            Either<Resource, StorageOperationStatus> getResourceRes = updateCalculatedCapReqWithSubstitutionMappings(resource, uploadResInstancesMap);
-            if (getResourceRes.isRight()) {
-                ResponseFormat responseFormat = componentsUtils
-                    .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(getResourceRes.right().value()), resource);
-                throw new ByResponseFormatComponentException(responseFormat);
-            }
+            getResourceRes = updateCalculatedCapReqWithSubstitutionMappings(resource, uploadResInstancesMap);
+        } else if (StringUtils.isNotEmpty(resource.getModel()) && resource.getResourceType() == ResourceTypeEnum.VF) {
+            getResourceRes = updateCalculatedCapReqWithSubstitutionMappingsForVf(resource, uploadResInstancesMap);
+        }
+        if (getResourceRes != null && getResourceRes.isRight()) {
+            ResponseFormat responseFormat = componentsUtils
+                .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(getResourceRes.right().value()), resource);
+            throw new ByResponseFormatComponentException(responseFormat);
         }
+
     }
 
     private void addRelationsToRI(String yamlName, Resource resource, Map<String, UploadComponentInstanceInfo> uploadResInstancesMap,
@@ -2426,7 +2578,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
     }
 
     private void processComponentInstance(String yamlName, Resource resource, List<ComponentInstance> componentInstancesList,
-                                          Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> allDataTypes,
+                                          Map<String, DataTypeDefinition> allDataTypes,
                                           Map<String, List<ComponentInstanceProperty>> instProperties,
                                           Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> instCapabilties,
                                           Map<ComponentInstance, Map<String, List<RequirementDefinition>>> instRequirements,
@@ -2464,12 +2616,12 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
         }
         if (originResource.getResourceType() != ResourceTypeEnum.CVFC) {
             ResponseFormat addPropertiesValueToRiRes = addPropertyValuesToRi(uploadComponentInstanceInfo, resource, originResource,
-                currentCompInstance, instProperties, allDataTypes.left().value());
+                currentCompInstance, instProperties, allDataTypes);
             if (addPropertiesValueToRiRes.getStatus() != 200) {
                 throw new ByResponseFormatComponentException(addPropertiesValueToRiRes);
             }
         } else {
-            addInputsValuesToRi(uploadComponentInstanceInfo, resource, originResource, currentCompInstance, instInputs, allDataTypes.left().value());
+            addInputsValuesToRi(uploadComponentInstanceInfo, resource, originResource, currentCompInstance, instInputs, allDataTypes);
         }
     }
 
@@ -2492,7 +2644,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
         return originResource;
     }
 
-    private void processComponentInstanceCapabilities(Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> allDataTypes,
+    private void processComponentInstanceCapabilities(Map<String, DataTypeDefinition> allDataTypes,
                                                       Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> instCapabilties,
                                                       UploadComponentInstanceInfo uploadComponentInstanceInfo, ComponentInstance currentCompInstance,
                                                       Resource originResource) {
@@ -2502,18 +2654,18 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
             Map<String, Map<String, UploadPropInfo>> newPropertiesMap = new HashMap<>();
             originResource.getCapabilities().forEach((k, v) -> addCapabilities(originCapabilities, k, v));
             uploadComponentInstanceInfo.getCapabilities().values().forEach(l -> addCapabilitiesProperties(newPropertiesMap, l));
-            updateCapabilityPropertiesValues(allDataTypes, originCapabilities, newPropertiesMap);
+            updateCapabilityPropertiesValues(originCapabilities, newPropertiesMap, allDataTypes);
         } else {
             originCapabilities = originResource.getCapabilities();
         }
         instCapabilties.put(currentCompInstance, originCapabilities);
     }
 
-    private void updateCapabilityPropertiesValues(Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> allDataTypes,
-                                                  Map<String, List<CapabilityDefinition>> originCapabilities,
-                                                  Map<String, Map<String, UploadPropInfo>> newPropertiesMap) {
+    private void updateCapabilityPropertiesValues(Map<String, List<CapabilityDefinition>> originCapabilities,
+                                                  Map<String, Map<String, UploadPropInfo>> newPropertiesMap,
+                                                  Map<String, DataTypeDefinition> allDataTypes) {
         originCapabilities.values().stream().flatMap(Collection::stream).filter(c -> newPropertiesMap.containsKey(c.getName()))
-            .forEach(c -> updatePropertyValues(c.getProperties(), newPropertiesMap.get(c.getName()), allDataTypes.left().value()));
+            .forEach(c -> updatePropertyValues(c.getProperties(), newPropertiesMap.get(c.getName()), allDataTypes));
     }
 
     private void addCapabilitiesProperties(Map<String, Map<String, UploadPropInfo>> newPropertiesMap, List<UploadCapInfo> capabilities) {
@@ -2557,6 +2709,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
         Either<Resource, StorageOperationStatus> updateRes = null;
         Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> updatedInstCapabilities = new HashMap<>();
         Map<ComponentInstance, Map<String, List<RequirementDefinition>>> updatedInstRequirements = new HashMap<>();
+
         StorageOperationStatus status = toscaOperationFacade.deleteAllCalculatedCapabilitiesRequirements(resource.getUniqueId());
         if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
             log.debug("Failed to delete all calculated capabilities and requirements of resource {} upon update. Status is {}",
@@ -2580,6 +2733,32 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
         return updateRes;
     }
 
+    private Either<Resource, StorageOperationStatus> updateCalculatedCapReqWithSubstitutionMappingsForVf(final Resource resource,
+                                                                                                         final Map<String, UploadComponentInstanceInfo> uploadResInstancesMap) {
+        Either<Resource, StorageOperationStatus> updateRes = null;
+        final Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> updatedInstCapabilities = new HashMap<>();
+        final Map<ComponentInstance, Map<String, List<RequirementDefinition>>> updatedInstRequirements = new HashMap<>();
+
+        resource.getComponentInstances().forEach(i -> {
+            setExternalCapabilities(updatedInstCapabilities, i, uploadResInstancesMap.get(i.getName()).getCapabilitiesNamesToUpdate());
+            setExternalRequirements(updatedInstRequirements, i, uploadResInstancesMap.get(i.getName()).getRequirementsNamesToUpdate());
+        });
+
+        final StorageOperationStatus status = toscaOperationFacade.updateCalculatedCapabilitiesRequirements(updatedInstCapabilities,
+            updatedInstRequirements, resource);
+        if (status != StorageOperationStatus.OK) {
+            log.debug(
+                "Failed to update capabilities and requirements of resource {}. Status is {}",
+                resource.getUniqueId(), status);
+            updateRes = Either.right(status);
+        }
+
+        if (updateRes == null) {
+            updateRes = Either.left(resource);
+        }
+        return updateRes;
+    }
+
     private void fillUpdatedInstCapabilitiesRequirements(List<ComponentInstance> componentInstances,
                                                          Map<String, UploadComponentInstanceInfo> uploadResInstancesMap,
                                                          Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> updatedInstCapabilities,
@@ -2597,7 +2776,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
         if (isNotEmpty(requirementsNamesToUpdate)) {
             for (Map.Entry<String, List<RequirementDefinition>> requirements : instance.getRequirements().entrySet()) {
                 updatedRequirements.put(requirements.getKey(), requirements.getValue().stream().filter(
-                    r -> requirementsNamesToUpdate.containsKey(r.getName()) && !updatedReqNames.contains(requirementsNamesToUpdate.get(r.getName())))
+                        r -> requirementsNamesToUpdate.containsKey(r.getName()) && !updatedReqNames.contains(requirementsNamesToUpdate.get(r.getName())))
                     .map(r -> {
                         r.setParentName(r.getName());
                         r.setName(requirementsNamesToUpdate.get(r.getName()));
@@ -2611,6 +2790,54 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
         }
     }
 
+    private void setExternalRequirements(
+        final Map<ComponentInstance, Map<String, List<RequirementDefinition>>> updatedInstRequirements,
+        final ComponentInstance instance, final Map<String, String> requirementsNamesToUpdate) {
+        final Map<String, List<RequirementDefinition>> updatedRequirements = new HashMap<>();
+        final Set<String> updatedReqNames = new HashSet<>();
+        if (isNotEmpty(requirementsNamesToUpdate)) {
+            for (Map.Entry<String, List<RequirementDefinition>> requirements : instance.getRequirements().entrySet()) {
+                updatedRequirements.put(requirements.getKey(),
+                    requirements.getValue().stream()
+                        .filter(r -> requirementsNamesToUpdate.containsKey(r.getName())
+                            && !updatedReqNames.contains(requirementsNamesToUpdate.get(r.getName())))
+                        .map(r -> {
+                            r.setExternal(true);
+                            r.setExternalName(requirementsNamesToUpdate.get(r.getName()));
+                            updatedReqNames.add(r.getName());
+                            return r;
+                        }).collect(toList()));
+            }
+        }
+        if (isNotEmpty(updatedRequirements)) {
+            updatedInstRequirements.put(instance, updatedRequirements);
+        }
+    }
+
+    private void setExternalCapabilities(
+        final Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> updatedInstCapabilties,
+        final ComponentInstance instance, Map<String, String> capabilitiesNamesToUpdate) {
+        final Map<String, List<CapabilityDefinition>> updatedCapabilities = new HashMap<>();
+        final Set<String> updatedCapNames = new HashSet<>();
+        if (isNotEmpty(capabilitiesNamesToUpdate)) {
+            for (Map.Entry<String, List<CapabilityDefinition>> requirements : instance.getCapabilities().entrySet()) {
+                updatedCapabilities.put(requirements.getKey(),
+                    requirements.getValue().stream()
+                        .filter(c -> capabilitiesNamesToUpdate.containsKey(c.getName())
+                            && !updatedCapNames.contains(capabilitiesNamesToUpdate.get(c.getName())))
+                        .map(c -> {
+                            c.setExternal(true);
+                            c.setExternalName(capabilitiesNamesToUpdate.get(c.getName()));
+                            updatedCapNames.add(c.getName());
+                            return c;
+                        }).collect(toList()));
+            }
+        }
+        if (isNotEmpty(updatedCapabilities)) {
+            updatedInstCapabilties.put(instance, updatedCapabilities);
+        }
+    }
+
     private void fillUpdatedInstCapabilities(Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> updatedInstCapabilties,
                                              ComponentInstance instance, Map<String, String> capabilitiesNamesToUpdate) {
         Map<String, List<CapabilityDefinition>> updatedCapabilities = new HashMap<>();
@@ -2618,7 +2845,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
         if (isNotEmpty(capabilitiesNamesToUpdate)) {
             for (Map.Entry<String, List<CapabilityDefinition>> requirements : instance.getCapabilities().entrySet()) {
                 updatedCapabilities.put(requirements.getKey(), requirements.getValue().stream().filter(
-                    c -> capabilitiesNamesToUpdate.containsKey(c.getName()) && !updatedCapNames.contains(capabilitiesNamesToUpdate.get(c.getName())))
+                        c -> capabilitiesNamesToUpdate.containsKey(c.getName()) && !updatedCapNames.contains(capabilitiesNamesToUpdate.get(c.getName())))
                     .map(c -> {
                         c.setParentName(c.getName());
                         c.setName(capabilitiesNamesToUpdate.get(c.getName()));
@@ -2657,19 +2884,19 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
                 for (UploadReqInfo uploadRegInfo : uploadRegInfoList) {
                     log.debug("Going to create  relation {}", uploadRegInfo.getName());
                     loggerSupportability
-                            .log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,
-                                    "Started to create relations on instance: {}", uploadRegInfo.getName());
+                        .log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,
+                            "Started to create relations on instance: {}", uploadRegInfo.getName());
                     String regName = uploadRegInfo.getName();
                     RequirementCapabilityRelDef regCapRelDef = new RequirementCapabilityRelDef();
                     regCapRelDef.setFromNode(resourceInstanceId);
                     log.debug("try to find available requirement {} ", regName);
                     Either<RequirementDefinition, ResponseFormat> eitherReqStatus = findAviableRequiremen(regName, yamlName, nodesInfoValue,
-                            currentCompInstance, uploadRegInfo.getCapabilityName());
+                        currentCompInstance, uploadRegInfo.getCapabilityName());
                     if (eitherReqStatus.isRight()) {
                         log.debug("failed to find available requirement {} status is {}", regName, eitherReqStatus.right().value());
                         loggerSupportability
-                                .log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
-                                        "ERROR while search available requirement {} status is: {}", regName, eitherReqStatus.right().value());
+                            .log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
+                                "ERROR while search available requirement {} status is: {}", regName, eitherReqStatus.right().value());
                         return eitherReqStatus.right().value();
                     }
                     RequirementDefinition validReq = eitherReqStatus.left().value();
@@ -2694,11 +2921,11 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
                     if (currentCapCompInstance == null) {
                         log.debug("The component instance  with name {} not found on resource {} ", uploadRegInfo.getNode(), resource.getUniqueId());
                         loggerSupportability
-                                .log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
-                                        "ERROR component instance  with name: {} not found on resource: {}", uploadRegInfo.getNode(), resource.getUniqueId());
+                            .log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
+                                "ERROR component instance  with name: {} not found on resource: {}", uploadRegInfo.getNode(), resource.getUniqueId());
                         BeEcompErrorManager.getInstance()
-                                .logInternalDataError(COMPONENT_INSTANCE_WITH_NAME + uploadRegInfo.getNode() + IN_RESOURCE, resource.getUniqueId(),
-                                        ErrorSeverity.ERROR);
+                            .logInternalDataError(COMPONENT_INSTANCE_WITH_NAME + uploadRegInfo.getNode() + IN_RESOURCE, resource.getUniqueId(),
+                                ErrorSeverity.ERROR);
                         return componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName);
                     }
                     regCapRelDef.setToNode(currentCapCompInstance.getUniqueId());
@@ -2706,14 +2933,14 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
                     CapabilityDefinition aviableCapForRel = findAvailableCapabilityByTypeOrName(validReq, currentCapCompInstance, uploadRegInfo);
                     if (aviableCapForRel == null) {
                         log.debug("aviable capability was not found. req name is {} component instance is {}", validReq.getName(),
-                                currentCapCompInstance.getUniqueId());
+                            currentCapCompInstance.getUniqueId());
                         loggerSupportability
-                                .log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
-                                        "ERROR available capability was not found. req name is: {} component instance is: {}", validReq.getName(),
-                                        currentCapCompInstance.getUniqueId());
+                            .log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
+                                "ERROR available capability was not found. req name is: {} component instance is: {}", validReq.getName(),
+                                currentCapCompInstance.getUniqueId());
                         BeEcompErrorManager.getInstance().logInternalDataError(
-                                "aviable capability was not found. req name is " + validReq.getName() + " component instance is " + currentCapCompInstance
-                                        .getUniqueId(), resource.getUniqueId(), ErrorSeverity.ERROR);
+                            "aviable capability was not found. req name is " + validReq.getName() + " component instance is " + currentCapCompInstance
+                                .getUniqueId(), resource.getUniqueId(), ErrorSeverity.ERROR);
                         return componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName);
                     }
                     reqAndRelationshipPair.setCapability(aviableCapForRel.getName());
@@ -3155,6 +3382,14 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
                 ToscaArtifactDataDefinition to = new ToscaArtifactDataDefinition();
                 to.setFile(entry.getValue().getFile());
                 to.setType(entry.getValue().getType());
+                if (isNotEmpty(entry.getValue().getProperties())) {
+                    Map<String, Object> newPropertiesMap = new HashMap<>();
+                    List<UploadPropInfo> artifactPropsInfo = entry.getValue().getProperties();
+                    for (UploadPropInfo propInfo : artifactPropsInfo) {
+                        newPropertiesMap.put(propInfo.getName(), propInfo.getValue());
+                    }
+                    to.setProperties(newPropertiesMap);
+                }
                 toscaArtifacts.put(entry.getKey(), to);
             }
             componentInstance.setToscaArtifacts(toscaArtifacts);
@@ -3199,9 +3434,10 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
         if (nodeNamespaceMap.containsKey(uploadComponentInstanceInfo.getType())) {
             refResource = nodeNamespaceMap.get(uploadComponentInstanceInfo.getType());
         } else {
-            Either<Resource, StorageOperationStatus> findResourceEither = toscaOperationFacade
-                .getByToscaResourceNameMatchingVendorRelease(uploadComponentInstanceInfo.getType(),
-                    ((ResourceMetadataDataDefinition) resource.getComponentMetadataDefinition().getMetadataDataDefinition()).getVendorRelease());
+            Either<Resource, StorageOperationStatus> findResourceEither = StringUtils.isEmpty(resource.getModel()) ?
+                toscaOperationFacade.getByToscaResourceNameMatchingVendorRelease(uploadComponentInstanceInfo.getType(),
+                    ((ResourceMetadataDataDefinition) resource.getComponentMetadataDefinition().getMetadataDataDefinition()).getVendorRelease()) :
+                toscaOperationFacade.getLatestByToscaResourceNameAndModel(uploadComponentInstanceInfo.getType(), resource.getModel());
             if (findResourceEither.isRight()) {
                 log.debug("validateResourceInstanceBeforeCreate - not found latest version for resource instance with name {} and type {}",
                     uploadComponentInstanceInfo.getName(), uploadComponentInstanceInfo.getType());
@@ -3235,7 +3471,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
                 nodeForceCertification(resource, user, lifecycleChangeInfo, inTransaction, needLock);
             }
             if (resource.getLifecycleState() == LifecycleStateEnum.CERTIFIED) {
-                Either<ArtifactDefinition, Operation> eitherPopulated = populateToscaArtifacts(resource, user, false, inTransaction, needLock, false);
+                populateToscaArtifacts(resource, user, false, inTransaction, needLock, false);
                 return resource;
             }
             return nodeFullCertification(resource.getUniqueId(), user, lifecycleChangeInfo, inTransaction, needLock);
@@ -3277,10 +3513,11 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
         ImmutablePair<Resource, ActionStatus> result = null;
         // check if resource already exists (search by tosca name = type)
         final boolean isNestedResource = isNestedResourceUpdate(csarInfo, nodeName);
+        final String resourceName = resource.getToscaResourceName();
         final Either<Resource, StorageOperationStatus> latestByToscaName = toscaOperationFacade
-            .getLatestByToscaResourceName(resource.getToscaResourceName());
-        if (latestByToscaName.isLeft()) {
-            Resource foundResource = latestByToscaName.left().value();
+            .getLatestByToscaResourceNameAndModel(resourceName, resource.getModel());
+        if (latestByToscaName.isLeft() && Objects.nonNull(latestByToscaName.left().value())) {
+            final Resource foundResource = latestByToscaName.left().value();
             // we don't allow updating names of top level types
             if (!isNestedResource && !StringUtils.equals(resource.getName(), foundResource.getName())) {
                 BeEcompErrorManager.getInstance()
@@ -3318,7 +3555,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
                                                                                final CsarInfo csarInfo, final boolean isNested,
                                                                                final String nodeName) {
         final Either<Component, StorageOperationStatus> latestByToscaName = toscaOperationFacade.getLatestByToscaResourceName(
-            buildNestedToscaResourceName(resource.getResourceType().name(), csarInfo.getVfResourceName(), nodeName).getRight());
+            buildNestedToscaResourceName(resource.getResourceType().name(), csarInfo.getVfResourceName(), nodeName).getRight(), resource.getModel());
         if (latestByToscaName.isLeft()) {
             final Resource nestedResource = (Resource) latestByToscaName.left().value();
             log.debug(VALIDATE_DERIVED_BEFORE_UPDATE);
@@ -3349,7 +3586,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
     }
 
     public boolean isResourceExist(String resourceName) {
-        Either<Resource, StorageOperationStatus> latestByName = toscaOperationFacade.getLatestByName(resourceName);
+        Either<Resource, StorageOperationStatus> latestByName = toscaOperationFacade.getLatestByName(resourceName, null);
         return latestByName.isLeft();
     }
 
@@ -3380,6 +3617,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
             newResource.setUUID(oldResource.getUUID());
             newResource.setNormalizedName(oldResource.getNormalizedName());
             newResource.setSystemName(oldResource.getSystemName());
+            newResource.setModel(oldResource.getModel());
             if (oldResource.getCsarUUID() != null) {
                 newResource.setCsarUUID(oldResource.getCsarUUID());
             }
@@ -3405,9 +3643,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
             if (MapUtils.isEmpty(newResource.getToscaArtifacts())) {
                 setToscaArtifactsPlaceHolders(newResource, user);
             }
-            if (MapUtils.isEmpty(newResource.getInterfaces())) {
-                newResource.setInterfaces(oldResource.getInterfaces());
-            }
+
             if (CollectionUtils.isEmpty(newResource.getAttributes())) {
                 newResource.setAttributes(oldResource.getAttributes());
             }
@@ -3464,9 +3700,13 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
         if (newResource.getResourceVendorModelNumber() == null) {
             newResource.setResourceVendorModelNumber(oldResource.getResourceVendorModelNumber());
         }
+        if (newResource.getModel() == null) {
+            newResource.setModel(oldResource.getModel());
+        }
         if (newResource.getContactId() == null) {
             newResource.setContactId(oldResource.getContactId());
         }
+        newResource.setIcon(oldResource.getIcon());
         newResource.setCategories(oldResource.getCategories());
         if (newResource.getVendorName() == null) {
             newResource.setVendorName(oldResource.getVendorName());
@@ -3480,9 +3720,9 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
         if (newResource.getResourceType().isAtomicType() && !newResource.getName().equals("Root")
             && newResource.getResourceType() != ResourceTypeEnum.CVFC) {
             ResourceTypeEnum updatedResourceType = newResource.getResourceType();
-            Component derivedFromResource = getParentComponent(newResource);
-            if (derivedFromResource.getComponentType() == ComponentTypeEnum.RESOURCE) {
-                Resource parentResource = (Resource) derivedFromResource;
+            Optional<Component> derivedFromResourceOptional = getParentComponent(newResource);
+            if (derivedFromResourceOptional.isPresent() && derivedFromResourceOptional.get().getComponentType() == ComponentTypeEnum.RESOURCE) {
+                Resource parentResource = (Resource) derivedFromResourceOptional.get();
                 if (!(parentResource.isAbstract() && (ResourceTypeEnum.VFC == parentResource.getResourceType()
                     || ResourceTypeEnum.ABSTRACT == parentResource.getResourceType())) && parentResource.getResourceType() != updatedResourceType
                     && oldResource.getResourceType() != updatedResourceType) {
@@ -3497,17 +3737,20 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
         }
     }
 
-    private Component getParentComponent(Resource newResource) {
+    private Optional<Component> getParentComponent(Resource newResource) {
+        if (newResource.getDerivedFrom() == null) {
+            return Optional.empty();
+        }
         String toscaResourceNameDerivedFrom = newResource.getDerivedFrom().get(0);
         Either<Component, StorageOperationStatus> latestByToscaResourceName = toscaOperationFacade
-            .getLatestByToscaResourceName(toscaResourceNameDerivedFrom);
+            .getLatestByToscaResourceName(toscaResourceNameDerivedFrom, newResource.getModel());
         if (latestByToscaResourceName.isRight()) {
             BeEcompErrorManager.getInstance()
                 .logInternalDataError("mergeOldResourceMetadataWithNew", "derived from resource not found", ErrorSeverity.ERROR);
             log.debug("#mergeOldResourceMetadataWithNew - derived from resource {} not found", toscaResourceNameDerivedFrom);
             throw new ByActionStatusComponentException(ActionStatus.RESOURCE_NOT_FOUND, toscaResourceNameDerivedFrom);
         }
-        return latestByToscaResourceName.left().value();
+        return Optional.of(latestByToscaResourceName.left().value());
     }
 
     private Resource prepareResourceForUpdate(Resource oldResource, Resource newResource, User user, boolean inTransaction, boolean needLock) {
@@ -3575,7 +3818,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
             while (intItr.hasNext() && eitherResult.isLeft()) {
                 InterfaceDefinition interfaceDefinition = intItr.next();
                 String intType = interfaceDefinition.getUniqueId();
-                Either<InterfaceDefinition, StorageOperationStatus> eitherCapTypeFound = interfaceTypeOperation.getInterface(intType);
+                Either<InterfaceDefinition, StorageOperationStatus> eitherCapTypeFound = interfaceTypeOperation.getInterface(UniqueIdBuilder.buildInterfaceTypeUid(resource.getModel(), intType));
                 if (eitherCapTypeFound.isRight()) {
                     if (eitherCapTypeFound.right().value() == StorageOperationStatus.NOT_FOUND) {
                         BeEcompErrorManager.getInstance()
@@ -3624,7 +3867,8 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
                                                                          Resource resource, List<?> validationObjects, AuditingActionEnum actionEnum,
                                                                          Either<Boolean, ResponseFormat> eitherResult, String type,
                                                                          boolean inTransaction) {
-        Either<CapabilityTypeDefinition, StorageOperationStatus> eitherCapTypeFound = capabilityTypeOperation.getCapabilityType(type, inTransaction);
+        Either<CapabilityTypeDefinition, StorageOperationStatus> eitherCapTypeFound = capabilityTypeOperation.getCapabilityType(
+            UniqueIdBuilder.buildCapabilityTypeUid(resource.getModel(), type), inTransaction);
         if (eitherCapTypeFound.isRight()) {
             if (eitherCapTypeFound.right().value() == StorageOperationStatus.NOT_FOUND) {
                 BeEcompErrorManager.getInstance().logBeGraphObjectMissingError(CREATE_RESOURCE_VALIDATE_CAPABILITY_TYPES, "Capability Type", type);
@@ -3649,7 +3893,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
                                                                          Either<Boolean, ResponseFormat> eitherResult,
                                                                          Entry<String, List<CapabilityDefinition>> typeEntry, boolean inTransaction) {
         Either<CapabilityTypeDefinition, StorageOperationStatus> eitherCapTypeFound = capabilityTypeOperation
-            .getCapabilityType(typeEntry.getKey(), inTransaction);
+            .getCapabilityType(UniqueIdBuilder.buildCapabilityTypeUid(resource.getModel(), typeEntry.getKey()), inTransaction);
         if (eitherCapTypeFound.isRight()) {
             if (eitherCapTypeFound.right().value() == StorageOperationStatus.NOT_FOUND) {
                 BeEcompErrorManager.getInstance()
@@ -3731,11 +3975,13 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
             componentsUtils.auditResource(componentsUtils.getResponseFormat(ActionStatus.CREATED), user, createdResource, actionEnum);
             ASDCKpiApi.countCreatedResourcesKPI();
         } catch (ComponentException e) {
+            janusGraphDao.rollback();
             ResponseFormat responseFormat =
                 e.getResponseFormat() == null ? componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams()) : e.getResponseFormat();
             componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
             throw e;
         } catch (StorageException e) {
+            janusGraphDao.rollback();
             ResponseFormat responseFormat = componentsUtils
                 .getResponseFormat(componentsUtils.convertFromStorageResponse(e.getStorageOperationStatus()));
             componentsUtils.auditResource(responseFormat, user, resource, actionEnum);
@@ -3749,10 +3995,12 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
     }
 
     private Resource createResourceTransaction(Resource resource, User user, boolean isNormative) {
-        // validate resource name uniqueness
-        log.debug("validate resource name");
-        Either<Boolean, StorageOperationStatus> eitherValidation = toscaOperationFacade
-            .validateComponentNameExists(resource.getName(), resource.getResourceType(), resource.getComponentType());
+        final String resourceName = resource.getName();
+        final String modelName = resource.getModel();
+        final ResourceTypeEnum resourceType = resource.getResourceType();
+        final ComponentTypeEnum componentType = resource.getComponentType();
+        final Either<Boolean, StorageOperationStatus> eitherValidation = toscaOperationFacade
+            .validateComponentNameAndModelExists(resourceName, modelName, resourceType, componentType);
         if (eitherValidation.isRight()) {
             loggerSupportability.log(LoggerSupportabilityActions.VALIDATE_NAME, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,
                 "ERROR while validate component name {} Status is: {}", resource.getName(), eitherValidation.right().value());
@@ -3906,6 +4154,53 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
         }
     }
 
+    private boolean isComponentSystemDeployed(Resource resource) {
+        return resource.getComponentMetadataDefinition().getMetadataDataDefinition().isNormative();
+    }
+
+    /**
+     * Deletes every version of the provided resource
+     *
+     * @param resourceId the resource identifier
+     * @param user       the user that performs the deletion
+     * @return
+     * @throws ComponentException if there is any error in the deletion of the resource operation
+     */
+    public void deleteResourceAllVersions(String resourceId, User user) {
+        validateUserExists(user);
+        Either<Resource, StorageOperationStatus> resourceStatus = toscaOperationFacade.getToscaElement(resourceId);
+        if (resourceStatus.isRight()) {
+            log.debug("Failed to get resource {}", resourceId);
+            componentException(resourceStatus.right().value());
+        }
+        Resource resource = resourceStatus.left().value();
+        if (isComponentSystemDeployed(resource)) {
+            throw new ByActionStatusComponentException(ActionStatus.CANNOT_DELETE_SYSTEM_DEPLOYED_RESOURCES, ComponentTypeEnum.RESOURCE.getValue(),
+                resource.getName());
+        }
+        if (Boolean.FALSE.equals(resource.isArchived())) {
+            log.debug("The resource, {}, requested for delete has not been archived.", resourceId);
+            throw new ComponentException(ActionStatus.COMPONENT_NOT_ARCHIVED, resourceId);
+        }
+        try {
+            String model = resource.getModel();
+            final Optional<Model> modelOptional = modelOperation.findModelByName(model);
+            List<String> deletedResourceList = toscaOperationFacade.deleteComponent(resource.getInvariantUUID(), NodeTypeEnum.Resource, true);
+            if (log.isDebugEnabled()) {
+                deletedResourceList.forEach(deletedR -> log.debug("Component {} was deleted.", deletedR));
+            }
+            if (modelOptional.isPresent() && modelOptional.get().getModelType() == ModelTypeEnum.NORMATIVE_EXTENSION) {
+                modelOperation.deleteModel(modelOptional.get(), true);
+            }
+            toscaOperationFacade.commitAndCheck(resource.getUniqueId());
+            updateCatalog(resource, ChangeTypeEnum.DELETE);
+        } catch (ComponentException exception) {
+            log.debug("Failed to delete resource, {} ", resourceId);
+            janusGraphDao.rollback();
+            throw exception;
+        }
+    }
+
     public ResponseFormat deleteResourceByNameAndVersion(String resourceName, String version, User user) {
         ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
         validateUserExists(user);
@@ -4033,7 +4328,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
             } else {
                 newResource.setDerivedFrom(null);
             }
-            Either<Resource, ResponseFormat> dataModelResponse = updateResourceMetadata(resourceIdToUpdate, newResource, user, currentResource, false,
+            Either<Resource, ResponseFormat> dataModelResponse = updateResourceMetadata(resourceIdToUpdate, newResource, user, currentResource,
                 true);
             if (dataModelResponse.isRight()) {
                 log.debug("failed to update resource metadata!!!");
@@ -4055,7 +4350,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
     }
 
     private Either<Resource, ResponseFormat> updateResourceMetadata(String resourceIdToUpdate, Resource newResource, User user,
-                                                                    Resource currentResource, boolean shouldLock, boolean inTransaction) {
+                                                                    Resource currentResource, boolean inTransaction) {
         updateVfModuleGroupsNames(currentResource, newResource);
         validateResourceFieldsBeforeUpdate(currentResource, newResource, inTransaction, false);
         // Setting last updater and uniqueId
@@ -4423,7 +4718,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
         String currentTemplateName = currentResource.getDerivedFrom().get(0);
         String updatedTemplateName = updateInfoResource.getDerivedFrom().get(0);
         Either<Boolean, StorageOperationStatus> dataModelResponse = toscaOperationFacade
-            .validateToscaResourceNameExtends(currentTemplateName, updatedTemplateName);
+            .validateToscaResourceNameExtends(currentTemplateName, updatedTemplateName, currentResource.getModel());
         if (dataModelResponse.isRight()) {
             StorageOperationStatus storageStatus = dataModelResponse.right().value();
             BeEcompErrorManager.getInstance().logBeDaoSystemError("Create/Update Resource - validateDerivingFromExtendingType");
@@ -4727,50 +5022,47 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
         log.debug("validate resource properties default values");
         List<PropertyDefinition> properties = resource.getProperties();
         if (properties != null) {
-            iterateOverProperties(properties);
+            iterateOverProperties(properties, resource.getModel());
         }
         return true;
     }
 
-    public void iterateOverProperties(List<PropertyDefinition> properties) {
-        String type = null;
-        String innerType = null;
+    public void iterateOverProperties(List<PropertyDefinition> properties, String model) {
         for (PropertyDefinition property : properties) {
-            if (!propertyOperation.isPropertyTypeValid(property)) {
+            if (!propertyOperation.isPropertyTypeValid(property, model)) {
                 log.info("Invalid type for property {}", property);
                 throw new ByActionStatusComponentException(ActionStatus.INVALID_PROPERTY_TYPE, property.getType(), property.getName());
             }
-            Map<String, DataTypeDefinition> allDataTypes = getAllDataTypes(applicationDataTypeCache);
-            type = property.getType();
+            Map<String, DataTypeDefinition> allDataTypes = componentsUtils.getAllDataTypes(applicationDataTypeCache, model);
+            String type = property.getType();
             if (type.equals(ToscaPropertyType.LIST.getType()) || type.equals(ToscaPropertyType.MAP.getType())) {
-                ResponseFormat responseFormat = validateMapOrListPropertyType(property, innerType, allDataTypes);
+                ResponseFormat responseFormat = validateMapOrListPropertyType(property, allDataTypes);
                 if (responseFormat != null) {
                     break;
                 }
             }
-            validateDefaultPropertyValue(property, allDataTypes, type, innerType);
+            validateDefaultPropertyValue(property, allDataTypes, type);
         }
     }
 
-    private void validateDefaultPropertyValue(PropertyDefinition property, Map<String, DataTypeDefinition> allDataTypes, String type,
-                                              String innerType) {
+    private void validateDefaultPropertyValue(PropertyDefinition property, Map<String, DataTypeDefinition> allDataTypes, String type) {
         if (!propertyOperation.isPropertyDefaultValueValid(property, allDataTypes)) {
             log.info("Invalid default value for property {}", property);
             ResponseFormat responseFormat;
             if (type.equals(ToscaPropertyType.LIST.getType()) || type.equals(ToscaPropertyType.MAP.getType())) {
-                throw new ByActionStatusComponentException(ActionStatus.INVALID_COMPLEX_DEFAULT_VALUE, property.getName(), type, innerType,
+                throw new ByActionStatusComponentException(ActionStatus.INVALID_COMPLEX_DEFAULT_VALUE, property.getName(), type,
                     property.getDefaultValue());
             }
             throw new ByActionStatusComponentException(ActionStatus.INVALID_DEFAULT_VALUE, property.getName(), type, property.getDefaultValue());
         }
     }
 
-    private ResponseFormat validateMapOrListPropertyType(PropertyDefinition property, String innerType,
+    private ResponseFormat validateMapOrListPropertyType(PropertyDefinition property,
                                                          Map<String, DataTypeDefinition> allDataTypes) {
         ResponseFormat responseFormat = null;
         ImmutablePair<String, Boolean> propertyInnerTypeValid = propertyOperation.isPropertyInnerTypeValid(property, allDataTypes);
-        innerType = propertyInnerTypeValid.getLeft();
-        if (!propertyInnerTypeValid.getRight()) {
+        String innerType = propertyInnerTypeValid.getLeft();
+        if (Boolean.FALSE.equals(propertyInnerTypeValid.getRight())) {
             log.info("Invalid inner type for property {}", property);
             responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_INNER_TYPE, innerType, property.getName());
         }