Unable to import service template with interface
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / impl / ServiceImportBusinessLogic.java
index 0a7ce20..8671d9e 100644 (file)
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 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 org.apache.commons.collections.CollectionUtils.isNotEmpty;
+import static org.openecomp.sdc.be.components.impl.CsarValidationUtils.TOSCA_METADATA_PATH_PATTERN;
+import static org.openecomp.sdc.be.components.impl.CsarValidationUtils.TOSCA_META_ENTRY_DEFINITIONS;
 import static org.openecomp.sdc.be.components.impl.ImportUtils.findFirstToscaMapElement;
 import static org.openecomp.sdc.be.components.impl.ImportUtils.findFirstToscaStringElement;
 import static org.openecomp.sdc.be.components.impl.ImportUtils.getPropertyJsonStringValue;
 import static org.openecomp.sdc.be.tosca.CsarUtils.VF_NODE_TYPE_ARTIFACTS_PATH_PATTERN;
 
 import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
 import fj.data.Either;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.lang.reflect.Method;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.EnumMap;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Optional;
+import java.util.Properties;
 import java.util.Set;
+import java.util.TreeSet;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import javax.validation.constraints.NotNull;
 import lombok.Getter;
 import lombok.Setter;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang3.StringEscapeUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.json.simple.JSONObject;
@@ -54,8 +71,10 @@ import org.openecomp.sdc.be.components.csar.ServiceCsarInfo;
 import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperationEnum;
 import org.openecomp.sdc.be.components.impl.artifact.ArtifactOperationInfo;
 import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException;
+import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
+import org.openecomp.sdc.be.components.impl.model.ToscaTypeImportData;
 import org.openecomp.sdc.be.components.impl.utils.CINodeFilterUtils;
 import org.openecomp.sdc.be.components.impl.utils.CreateServiceFromYamlParameter;
 import org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic;
@@ -67,7 +86,7 @@ import org.openecomp.sdc.be.dao.api.ActionStatus;
 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphDao;
 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
 import org.openecomp.sdc.be.datamodel.utils.ArtifactUtils;
-import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.CustomYamlFunction;
 import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.ListCapabilityDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
@@ -76,7 +95,9 @@ import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
 import org.openecomp.sdc.be.datatypes.elements.PolicyDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterPropertyDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.SubPropertyToscaFunction;
+import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterPropertyDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition;
 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
@@ -84,17 +105,21 @@ import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType;
 import org.openecomp.sdc.be.impl.ComponentsUtils;
 import org.openecomp.sdc.be.info.NodeTypeInfoToUpdateArtifacts;
 import org.openecomp.sdc.be.model.ArtifactDefinition;
+import org.openecomp.sdc.be.model.ArtifactTypeDefinition;
 import org.openecomp.sdc.be.model.AttributeDefinition;
 import org.openecomp.sdc.be.model.CapabilityDefinition;
 import org.openecomp.sdc.be.model.CapabilityRequirementRelationship;
+import org.openecomp.sdc.be.model.CapabilityTypeDefinition;
 import org.openecomp.sdc.be.model.Component;
 import org.openecomp.sdc.be.model.ComponentInstance;
+import org.openecomp.sdc.be.model.ComponentInstanceAttribute;
 import org.openecomp.sdc.be.model.ComponentInstanceInput;
 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.DistributionStatusEnum;
 import org.openecomp.sdc.be.model.GroupDefinition;
+import org.openecomp.sdc.be.model.GroupTypeDefinition;
 import org.openecomp.sdc.be.model.InputDefinition;
 import org.openecomp.sdc.be.model.InterfaceDefinition;
 import org.openecomp.sdc.be.model.LifeCycleTransitionEnum;
@@ -126,15 +151,23 @@ import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
 import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.ToscaElement;
 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
 import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter;
+import org.openecomp.sdc.be.model.normatives.ToscaTypeMetadata;
 import org.openecomp.sdc.be.model.operations.StorageException;
 import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.openecomp.sdc.be.model.operations.impl.ArtifactTypeOperation;
+import org.openecomp.sdc.be.model.operations.impl.CapabilityTypeOperation;
+import org.openecomp.sdc.be.model.operations.impl.GroupTypeOperation;
+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.tosca.ToscaPropertyType;
 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
 import org.openecomp.sdc.be.tosca.CsarUtils;
 import org.openecomp.sdc.be.tosca.ToscaExportHandler;
 import org.openecomp.sdc.be.ui.model.OperationUi;
 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;
@@ -142,6 +175,8 @@ import org.openecomp.sdc.common.datastructure.Wrapper;
 import org.openecomp.sdc.common.kpi.api.ASDCKpiApi;
 import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.openecomp.sdc.common.util.ValidationUtils;
+import org.openecomp.sdc.common.zip.ZipUtils;
+import org.openecomp.sdc.common.zip.exception.ZipException;
 import org.openecomp.sdc.exception.ResponseFormat;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.yaml.snakeyaml.Yaml;
@@ -177,9 +212,18 @@ public class ServiceImportBusinessLogic {
     private final ResourceImportManager resourceImportManager;
     private final JanusGraphDao janusGraphDao;
     private final ArtifactsBusinessLogic artifactsBusinessLogic;
+    private final ArtifactTypeImportManager artifactTypeImportManager;
     private final IGraphLockOperation graphLockOperation;
     private final ToscaFunctionService toscaFunctionService;
     private final DataTypeBusinessLogic dataTypeBusinessLogic;
+    private final ArtifactTypeOperation artifactTypeOperation;
+    private final GroupTypeImportManager groupTypeImportManager;
+    private final GroupTypeOperation groupTypeOperation;
+    private final CapabilityTypeImportManager capabilityTypeImportManager;
+    private final CapabilityTypeOperation capabilityTypeOperation;
+    private final InterfaceLifecycleOperation interfaceLifecycleTypeOperation;
+    private final InterfaceLifecycleTypeImportManager interfaceLifecycleTypeImportManager;
+    private final ModelOperation modelOperation;
     private ApplicationDataTypeCache applicationDataTypeCache;
 
     public ServiceImportBusinessLogic(final GroupBusinessLogic groupBusinessLogic, final ArtifactsBusinessLogic artifactsBusinessLogic,
@@ -191,7 +235,14 @@ public class ServiceImportBusinessLogic {
                                       final ServiceImportParseLogic serviceImportParseLogic, final PolicyBusinessLogic policyBusinessLogic,
                                       final ResourceImportManager resourceImportManager, final JanusGraphDao janusGraphDao,
                                       final IGraphLockOperation graphLockOperation, final ToscaFunctionService toscaFunctionService,
-                                      final DataTypeBusinessLogic dataTypeBusinessLogic) {
+                                      final DataTypeBusinessLogic dataTypeBusinessLogic, final ArtifactTypeOperation artifactTypeOperation,
+                                      final ArtifactTypeImportManager artifactTypeImportManager, final GroupTypeImportManager groupTypeImportManager,
+                                      final GroupTypeOperation groupTypeOperation,
+                                      final InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
+                                      final InterfaceLifecycleTypeImportManager interfaceLifecycleTypeImportManager,
+                                      final CapabilityTypeImportManager capabilityTypeImportManager,
+                                      final CapabilityTypeOperation capabilityTypeOperation,
+                                      final ModelOperation modelOperation) {
         this.componentsUtils = componentsUtils;
         this.toscaOperationFacade = toscaOperationFacade;
         this.serviceBusinessLogic = serviceBusinessLogic;
@@ -209,6 +260,15 @@ public class ServiceImportBusinessLogic {
         this.graphLockOperation = graphLockOperation;
         this.toscaFunctionService = toscaFunctionService;
         this.dataTypeBusinessLogic = dataTypeBusinessLogic;
+        this.artifactTypeOperation = artifactTypeOperation;
+        this.artifactTypeImportManager = artifactTypeImportManager;
+        this.groupTypeImportManager = groupTypeImportManager;
+        this.groupTypeOperation = groupTypeOperation;
+        this.interfaceLifecycleTypeOperation = interfaceLifecycleTypeOperation;
+        this.interfaceLifecycleTypeImportManager = interfaceLifecycleTypeImportManager;
+        this.capabilityTypeImportManager = capabilityTypeImportManager;
+        this.capabilityTypeOperation = capabilityTypeOperation;
+        this.modelOperation = modelOperation;
     }
 
     @Autowired
@@ -216,14 +276,108 @@ public class ServiceImportBusinessLogic {
         this.applicationDataTypeCache = applicationDataTypeCache;
     }
 
+    public Service updateServiceFromToscaTemplate(final String serviceId, final User modifier, final String data) {
+        final Either<Service, ResponseFormat> serviceResponseFormatEither = serviceBusinessLogic.getService(serviceId, modifier);
+        if (serviceResponseFormatEither.isRight()) {
+            throw new ByActionStatusComponentException(ActionStatus.SERVICE_NOT_FOUND, serviceId);
+        }
+        final Service serviceOriginal = serviceResponseFormatEither.left().value();
+        final Map<String, String> metadata = (Map<String, String>) new Yaml().loadAs(data, Map.class).get("metadata");
+        validateServiceMetadataBeforeCreate(serviceOriginal, metadata);
+
+        final Service newService = cloneServiceIdentifications(serviceOriginal);
+        final Map<String, byte[]> payload = new HashMap<>();
+        payload.put("Definitions/service-" + metadata.get("name") + "-template.yml", data.getBytes());
+        updateServiceMetadata(newService, metadata);
+        return createService(newService, AuditingActionEnum.UPDATE_SERVICE_TOSCA_TEMPLATE, modifier, payload, null);
+    }
+
+    public Service updateServiceFromToscaModel(final String serviceId, final User modifier, final @NotNull InputStream fileToUpload) {
+        final Either<Service, ResponseFormat> serviceResponseFormatEither = serviceBusinessLogic.getService(serviceId, modifier);
+        if (serviceResponseFormatEither.isRight()) {
+            throw new ByActionStatusComponentException(ActionStatus.SERVICE_NOT_FOUND, serviceId);
+        }
+        final Service serviceOriginal = serviceResponseFormatEither.left().value();
+        Map<String, byte[]> csar = null;
+        try {
+            csar = ZipUtils.readZip(fileToUpload.readAllBytes(), false);
+        } catch (final ZipException | IOException e) {
+            log.info("Failed to unzip received csar {}", serviceId, e);
+        }
+        if (csar == null) {
+            throw new ByActionStatusComponentException(ActionStatus.CSAR_NOT_FOUND);
+        }
+        final byte[] mainYamlBytes = readMainYamlFile(csar);
+        final Map<String, String> metadata = (Map<String, String>) new Yaml().loadAs(new String(mainYamlBytes), Map.class).get("metadata");
+        validateServiceMetadataBeforeCreate(serviceOriginal, metadata);
+        final Service newService = cloneServiceIdentifications(serviceOriginal);
+        updateServiceMetadata(newService, metadata);
+        return createService(newService, AuditingActionEnum.UPDATE_SERVICE_TOSCA_MODEL, modifier, csar, null);
+    }
+
+    private byte[] readMainYamlFile(final Map<String, byte[]> csar) {
+        final Pattern pattern = Pattern.compile(TOSCA_METADATA_PATH_PATTERN);
+        final Optional<String> keyOp = csar.keySet().stream().filter(k -> pattern.matcher(k).matches()).findAny();
+        if (keyOp.isEmpty()) {
+            throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND_IN_CSAR, TOSCA_METADATA_PATH_PATTERN, "");
+        }
+        final Properties props = new Properties();
+        try {
+            final String propStr = new String(csar.get(keyOp.get()));
+            props.load(new StringReader(propStr.replace("\\", "\\\\")));
+        } catch (IOException e) {
+            throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND_IN_CSAR, TOSCA_META_ENTRY_DEFINITIONS, "");
+        }
+        final String mainYamlFileName = props.getProperty(TOSCA_META_ENTRY_DEFINITIONS);
+        final byte[] mainYamlBytes = csar.get(mainYamlFileName);
+        if (mainYamlBytes == null) {
+            throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND_IN_CSAR, mainYamlFileName, "");
+        }
+        return mainYamlBytes;
+    }
+
+    private Service cloneServiceIdentifications(final Service serviceOriginal) {
+        final Service newService = new Service(serviceOriginal.getComponentMetadataDefinition());
+        newService.setCategories(serviceOriginal.getCategories());
+        newService.setInvariantUUID(serviceOriginal.getInvariantUUID());
+        newService.setUniqueId(serviceOriginal.getUniqueId());
+        newService.setName(serviceOriginal.getName());
+        newService.setUUID(serviceOriginal.getUUID());
+        return newService;
+    }
+
+    private void validateServiceMetadataBeforeCreate(final Service service, final Map<String, String> metadata) {
+        if (MapUtils.isEmpty(metadata)) {
+            throw new ByActionStatusComponentException(ActionStatus.MISSING_SERVICE_METADATA);
+        }
+        final String uuid = metadata.get("UUID");
+        if (!service.getUUID().equals(uuid)) {
+            throw new ByActionStatusComponentException(ActionStatus.UNCHANGEABLE_PROPERTY_ERROR, "UUID");
+        }
+        final String invariantUUID = metadata.get("invariantUUID");
+        if (!service.getInvariantUUID().equals(invariantUUID)) {
+            throw new ByActionStatusComponentException(ActionStatus.UNCHANGEABLE_PROPERTY_ERROR, "invariantUUID");
+        }
+        final String name = metadata.get("name");
+        if (!service.getName().equals(name)) {
+            throw new ByActionStatusComponentException(ActionStatus.UNCHANGEABLE_PROPERTY_ERROR, "name");
+        }
+        final String version = metadata.get("template_version");
+        if (!service.getVersion().equals(version)) {
+            throw new ByActionStatusComponentException(ActionStatus.UNCHANGEABLE_PROPERTY_ERROR, "template_version");
+        }
+    }
+
     public Service createService(Service service, AuditingActionEnum auditingAction, User user, Map<String, byte[]> csarUIPayload,
                                  String payloadName) {
         log.debug("enter createService");
-        service.setCreatorUserId(user.getUserId());
-        service.setState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
-        service.setVersion(INITIAL_VERSION);
-        service.setConformanceLevel(ConfigurationManager.getConfigurationManager().getConfiguration().getToscaConformanceLevel());
-        service.setDistributionStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED);
+        if (AuditingActionEnum.CREATE_SERVICE.equals(auditingAction)) {
+            service.setCreatorUserId(user.getUserId());
+            service.setState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
+            service.setVersion(INITIAL_VERSION);
+            service.setConformanceLevel(ConfigurationManager.getConfigurationManager().getConfiguration().getToscaConformanceLevel());
+            service.setDistributionStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED);
+        }
         try {
             final var serviceBeforeCreate = serviceBusinessLogic.validateServiceBeforeCreate(service, user, auditingAction);
             if (serviceBeforeCreate.isRight()) {
@@ -231,10 +385,12 @@ public class ServiceImportBusinessLogic {
             }
             log.debug("enter createService,validateServiceBeforeCreate success");
             String csarUUID = payloadName == null ? service.getCsarUUID() : payloadName;
-            log.debug("enter createService,get csarUUID:{}", csarUUID);
-            csarBusinessLogic.validateCsarBeforeCreate(service, csarUUID);
+            if (AuditingActionEnum.CREATE_SERVICE.equals(auditingAction)) {
+                log.debug("enter createService,get csarUUID:{}", csarUUID);
+                csarBusinessLogic.validateCsarBeforeCreate(service, csarUUID);
+            }
             log.debug("CsarUUID is {} - going to create resource from CSAR", csarUUID);
-            return createServiceFromCsar(service, user, csarUIPayload, csarUUID);
+            return createServiceFromCsar(service, user, csarUIPayload, csarUUID, auditingAction);
         } catch (final ComponentException e) {
             log.debug("Exception occurred when createService: {}", e.getMessage(), e);
             throw e;
@@ -244,31 +400,77 @@ public class ServiceImportBusinessLogic {
         }
     }
 
-    protected Service createServiceFromCsar(Service service, User user, Map<String, byte[]> csarUIPayload, String csarUUID) {
+    private void updateServiceMetadata(final Service service, final Map<String, String> metadata) {
+        metadata.entrySet().forEach(s -> {
+            final Optional<Method> find =
+                Arrays.stream(service.getClass().getMethods()).filter(method -> method.getName().equalsIgnoreCase("set" + s.getKey())).findAny();
+            if (find.isPresent()) {
+                try {
+                    find.get().invoke(service, s.getValue());
+                } catch (final Exception e) {
+                    log.warn("Unable to set '{}' with value '{}'", s.getKey(), s.getValue());
+                }
+            }
+        });
+    }
+
+    protected Service createServiceFromCsar(Service service, User user, Map<String, byte[]> csarUIPayload, String csarUUID,
+                                            AuditingActionEnum auditingAction) {
         log.trace("************* created successfully from YAML, resource TOSCA ");
         try {
-            ServiceCsarInfo csarInfo = csarBusinessLogic.getCsarInfo(service, null, user, csarUIPayload, csarUUID);
-
-            final Map<String, Object> dataTypesToCreate = getDatatypesToCreate(service.getModel(), csarInfo);
+            final ServiceCsarInfo csarInfo;
+            if (AuditingActionEnum.UPDATE_SERVICE_TOSCA_TEMPLATE.equals(auditingAction)) {
+                csarInfo = new ServiceCsarInfo(user, csarUUID, csarUIPayload, service.getName(), service.getModel(),
+                    csarUIPayload.keySet().iterator().next(), new String(csarUIPayload.values().iterator().next()), true, modelOperation);
+            } else {
+                csarInfo = csarBusinessLogic.getCsarInfo(service, null, user, csarUIPayload, csarUUID, auditingAction);
+            }
+            final String serviceModel = service.getModel();
+            final Map<String, Object> dataTypesToCreate = getDatatypesToCreate(serviceModel, csarInfo);
             if (MapUtils.isNotEmpty(dataTypesToCreate)) {
-                dataTypeBusinessLogic.createDataTypeFromYaml(new Yaml().dump(dataTypesToCreate), service.getModel(), true);
-                dataTypesToCreate.entrySet().stream().forEach(createdOrUpdatedDataType -> {
-                    applicationDataTypeCache.reload(service.getModel(), UniqueIdBuilder.buildDataTypeUid(service.getModel(), createdOrUpdatedDataType.getKey()));
-                });
+                dataTypeBusinessLogic.createDataTypeFromYaml(new Yaml().dump(dataTypesToCreate), serviceModel, true);
+                dataTypesToCreate.keySet().forEach(key ->
+                    applicationDataTypeCache.reload(serviceModel, UniqueIdBuilder.buildDataTypeUid(serviceModel, key))
+                );
             }
-            final List<NodeTypeDefinition> nodeTypesToCreate = getNodeTypesToCreate(service.getModel(), csarInfo);
+
+            final Map<String, Object> artifactTypesToCreate = getArtifactTypesToCreate(serviceModel, csarInfo);
+            if (MapUtils.isNotEmpty(artifactTypesToCreate)) {
+                artifactTypeImportManager.createArtifactTypes(new Yaml().dump(artifactTypesToCreate), serviceModel, true);
+            }
+
+            final List<NodeTypeDefinition> nodeTypesToCreate = getNodeTypesToCreate(serviceModel, csarInfo);
             if (CollectionUtils.isNotEmpty(nodeTypesToCreate)) {
-                createNodeTypes(nodeTypesToCreate, service.getModel(), csarInfo.getModifier());
+                ParsedToscaYamlInfo parsedToscaYamlInfo = csarBusinessLogic.getParsedToscaYamlInfo(csarInfo, service);
+                createNodeTypes(nodeTypesToCreate, parsedToscaYamlInfo.getInstances(), serviceModel, csarInfo.getModifier());
+            }
+
+            final Map<String, Object> groupTypesToCreate = getGroupTypesToCreate(serviceModel, csarInfo);
+            if (MapUtils.isNotEmpty(groupTypesToCreate)) {
+                final Map<String, ToscaTypeMetadata> toscaTypeMetadata = fillToscaTypeMetadata(groupTypesToCreate);
+                final ToscaTypeImportData toscaTypeImportData = new ToscaTypeImportData(new Yaml().dump(groupTypesToCreate), toscaTypeMetadata);
+                groupTypeImportManager.createGroupTypes(toscaTypeImportData, serviceModel, true);
+            }
+
+            final Map<String, Object> interfaceTypesToCreate = getInterfaceTypesToCreate(serviceModel, csarInfo);
+            if (MapUtils.isNotEmpty(interfaceTypesToCreate)) {
+                interfaceLifecycleTypeImportManager.createLifecycleTypes(new Yaml().dump(interfaceTypesToCreate), serviceModel, true);
+            }
+
+            final Map<String, Object> capabilityTypesToCreate = getCapabilityTypesToCreate(serviceModel, csarInfo);
+            if (MapUtils.isNotEmpty(capabilityTypesToCreate)) {
+                capabilityTypeImportManager.createCapabilityTypes(new Yaml().dump(capabilityTypesToCreate), serviceModel, true);
             }
+
             Map<String, NodeTypeInfo> nodeTypesInfo = csarInfo.extractTypesInfo();
-            Either<Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>>, ResponseFormat> findNodeTypesArtifactsToHandleRes = serviceImportParseLogic
-                .findNodeTypesArtifactsToHandle(nodeTypesInfo, csarInfo, service);
+            Either<Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>>, ResponseFormat> findNodeTypesArtifactsToHandleRes
+                = serviceImportParseLogic.findNodeTypesArtifactsToHandle(nodeTypesInfo, csarInfo, service);
             if (findNodeTypesArtifactsToHandleRes.isRight()) {
                 log.debug("failed to find node types for update with artifacts during import csar {}. ", csarInfo.getCsarUUID());
                 throw new ComponentException(findNodeTypesArtifactsToHandleRes.right().value());
             }
             return createServiceFromYaml(service, csarInfo.getMainTemplateContent(), csarInfo.getMainTemplateName(), nodeTypesInfo, csarInfo,
-                findNodeTypesArtifactsToHandleRes.left().value(), true, false, null, user.getUserId());
+                findNodeTypesArtifactsToHandleRes.left().value(), true, false, null, user.getUserId(), auditingAction);
         } catch (final ComponentException e) {
             log.debug("Exception occurred when createServiceFromCsar,error is:{}", e.getMessage(), e);
             throw e;
@@ -278,6 +480,63 @@ public class ServiceImportBusinessLogic {
         }
     }
 
+    private Map<String, ToscaTypeMetadata> fillToscaTypeMetadata(final Map<String, Object> groupTypesToCreate) {
+        final Map<String, ToscaTypeMetadata> toscaTypeMetadata = new HashMap<>();
+        groupTypesToCreate.entrySet().forEach(entry -> {
+            final ToscaTypeMetadata metadata = new ToscaTypeMetadata();
+            metadata.setIcon(getIconFromGroupType(entry.getValue()));
+            metadata.setDisplayName(extractDisplayName(entry.getKey()));
+            toscaTypeMetadata.put(entry.getKey(), metadata);
+        });
+        return toscaTypeMetadata;
+    }
+
+    private String extractDisplayName(final String key) {
+        final String[] split = key.split("\\.");
+        return split[split.length - 1];
+    }
+
+    private String getIconFromGroupType(final Object value) {
+        final Either<GroupTypeDefinition, StorageOperationStatus> groupType = groupTypeOperation.getLatestGroupTypeByType(
+            (String) ((LinkedHashMap) value).get(ToscaTagNamesEnum.DERIVED_FROM.getElementName()), null);
+        if (groupType.isLeft()) {
+            return groupType.left().value().getIcon();
+        }
+        return null;
+    }
+
+    private Map<String, Object> getGroupTypesToCreate(final String model, final CsarInfo csarInfo) {
+        final Map<String, Object> groupTypesToCreate = new HashMap<>();
+        final Map<String, Object> groupTypes = csarInfo.getGroupTypes();
+        if (MapUtils.isNotEmpty(groupTypes)) {
+            for (final Entry<String, Object> entry : groupTypes.entrySet()) {
+                final Either<GroupTypeDefinition, StorageOperationStatus> result
+                    = groupTypeOperation.getGroupTypeByUid(UniqueIdBuilder.buildGroupTypeUid(model, entry.getKey(), "1.0"));
+                if (result.isRight() && result.right().value().equals(StorageOperationStatus.NOT_FOUND)) {
+                    groupTypesToCreate.put(entry.getKey(), entry.getValue());
+                    log.info("Deploying new group type {} to model {} from package {}", entry.getKey(), model, csarInfo.getCsarUUID());
+                }
+            }
+        }
+        return groupTypesToCreate;
+    }
+
+    private Map<String, Object> getCapabilityTypesToCreate(final String model, final CsarInfo csarInfo) {
+        final Map<String, Object> capabilityTypesToCreate = new HashMap<>();
+        final Map<String, Object> capabilityTypes = csarInfo.getCapabilityTypes();
+        if (MapUtils.isNotEmpty(capabilityTypes)) {
+            for (final Entry<String, Object> entry : capabilityTypes.entrySet()) {
+                final Either<CapabilityTypeDefinition, StorageOperationStatus> result
+                    = capabilityTypeOperation.getCapabilityType(UniqueIdBuilder.buildCapabilityTypeUid(model, entry.getKey()));
+                if (result.isRight() && result.right().value().equals(StorageOperationStatus.NOT_FOUND)) {
+                    capabilityTypesToCreate.put(entry.getKey(), entry.getValue());
+                    log.info("Deploying new capability type {} to model {} from package {}", entry.getKey(), model, csarInfo.getCsarUUID());
+                }
+            }
+        }
+        return capabilityTypesToCreate;
+    }
+
     private Map<String, Object> getDatatypesToCreate(final String model, final CsarInfo csarInfo) {
         final Map<String, Object> dataTypesToCreate = new HashMap<>();
 
@@ -286,31 +545,64 @@ public class ServiceImportBusinessLogic {
                 UniqueIdBuilder.buildDataTypeUid(model, dataTypeEntry.getKey()));
             if (result.isRight() && result.right().value().equals(JanusGraphOperationStatus.NOT_FOUND)) {
                 dataTypesToCreate.put(dataTypeEntry.getKey(), dataTypeEntry.getValue());
-                log.info("Deploying unknown type " + dataTypeEntry.getKey() + " to model " + model + " from package " + csarInfo.getCsarUUID());
+                log.info("Deploying unknown type {} to model {} from package {}", dataTypeEntry.getKey(), model, csarInfo.getCsarUUID());
             }
             if (hasNewProperties(result, (Map<String, Map<String, Object>>) dataTypeEntry.getValue())) {
                 dataTypesToCreate.put(dataTypeEntry.getKey(), dataTypeEntry.getValue());
-                log.info("Deploying new version of type " + dataTypeEntry.getKey() + " to model " + model + " from package " + csarInfo.getCsarUUID());
+                log.info("Deploying new version of type {} to model {} from package {}", dataTypeEntry.getKey(), model, csarInfo.getCsarUUID());
             }
         }
         return dataTypesToCreate;
     }
-    
-    private boolean hasNewProperties(final Either<DataTypeDefinition, JanusGraphOperationStatus> result, final Map<String, Map<String, Object>> dataType) {
+
+    private Map<String, Object> getArtifactTypesToCreate(final String model, final CsarInfo csarInfo) {
+        final Map<String, Object> artifactTypesToCreate = new HashMap<>();
+        final Map<String, Object> artifactTypesMap = csarInfo.getArtifactTypes();
+        if (MapUtils.isNotEmpty(artifactTypesMap)) {
+            for (final Entry<String, Object> artifactTypeEntry : artifactTypesMap.entrySet()) {
+                final Either<ArtifactTypeDefinition, StorageOperationStatus> result =
+                    artifactTypeOperation.getArtifactTypeByUid(UniqueIdBuilder.buildArtifactTypeUid(model, artifactTypeEntry.getKey()));
+                if (result.isRight() && StorageOperationStatus.NOT_FOUND.equals(result.right().value())) {
+                    artifactTypesToCreate.put(artifactTypeEntry.getKey(), artifactTypeEntry.getValue());
+                    log.info("Deploying new artifact type={}, to model={}, from package={}",
+                        artifactTypeEntry.getKey(), model, csarInfo.getCsarUUID());
+                }
+            }
+        }
+        return artifactTypesToCreate;
+    }
+
+    private Map<String, Object> getInterfaceTypesToCreate(final String model, final CsarInfo csarInfo) {
+        final Map<String, Object> interfaceTypesToCreate = new HashMap<>();
+        Map<String, Object> interfacetypeMap = csarInfo.getInterfaceTypes();
+
+        interfacetypeMap.entrySet().forEach(interfacetypeDef -> {
+            Either<InterfaceDefinition, StorageOperationStatus> interfaceDefinition =
+                interfaceLifecycleTypeOperation.getInterface(UniqueIdBuilder.buildInterfaceTypeUid(model, interfacetypeDef.getKey()));
+            if (interfaceDefinition.isRight() && interfaceDefinition.right().value().equals(StorageOperationStatus.NOT_FOUND)) {
+                interfaceTypesToCreate.put(interfacetypeDef.getKey(), interfacetypeDef.getValue());
+            }
+        });
+        return interfaceTypesToCreate;
+    }
+
+    private boolean hasNewProperties(final Either<DataTypeDefinition, JanusGraphOperationStatus> result,
+                                     final Map<String, Map<String, Object>> dataType) {
         return result.isLeft() && dataType.containsKey("properties") && result.left().value().getProperties() != null
-                && result.left().value().getProperties().size() != dataType.get("properties").size();
+            && result.left().value().getProperties().size() != dataType.get("properties").size();
     }
 
-    private void createNodeTypes(List<NodeTypeDefinition> nodeTypesToCreate, String model, User user) {
+    private void createNodeTypes(List<NodeTypeDefinition> nodeTypesToCreate, Map<String, UploadComponentInstanceInfo> instancesFromCsar, String model,
+                                 User user) {
         NodeTypesMetadataList nodeTypesMetadataList = new NodeTypesMetadataList();
         List<NodeTypeMetadata> nodeTypeMetadataList = new ArrayList<>();
         final Map<String, Object> allTypesToCreate = new HashMap<>();
-        nodeTypesToCreate.stream().forEach(nodeType -> {
+        nodeTypesToCreate.forEach(nodeType -> {
             allTypesToCreate.put(nodeType.getMappedNodeType().getKey(), nodeType.getMappedNodeType().getValue());
             nodeTypeMetadataList.add(nodeType.getNodeTypeMetadata());
         });
         nodeTypesMetadataList.setNodeMetadataList(nodeTypeMetadataList);
-        resourceImportManager.importAllNormativeResource(allTypesToCreate, nodeTypesMetadataList, user, model,true, false);
+        resourceImportManager.importAllNormativeResource(allTypesToCreate, nodeTypesMetadataList, instancesFromCsar, user, model, true, false);
     }
 
     private List<NodeTypeDefinition> getNodeTypesToCreate(final String model, final ServiceCsarInfo csarInfo) {
@@ -323,14 +615,17 @@ public class ServiceImportBusinessLogic {
                 namesOfNodeTypesToCreate.add(nodeTypeDefinition);
             } else if (result.isLeft()) {
                 Resource latestResource = (Resource) result.left().value();
-                Entry<String, Object> latestMappedToscaTemplate = getResourceToscaTemplate(latestResource.getUniqueId(),
-                        latestResource.getToscaArtifacts().get(ToscaExportHandler.ASSET_TOSCA_TEMPLATE), csarInfo.getModifier().getUserId());
-                Map<String, Object> mappedToscaTemplate = (Map<String, Object>) nodeTypeDefinition.getMappedNodeType().getValue();
-                Map<String, Object> newMappedToscaTemplate =
-                        getNewChangesToToscaTemplate(mappedToscaTemplate, (Map<String, Object>) latestMappedToscaTemplate.getValue());
-                if (!newMappedToscaTemplate.equals(latestMappedToscaTemplate.getValue())) {
-                    latestMappedToscaTemplate.setValue(newMappedToscaTemplate);
-                    nodeTypeDefinition.setMappedNodeType(latestMappedToscaTemplate);
+                Entry<String, Object> existingMappedToscaTemplate = getResourceToscaTemplate(latestResource.getUniqueId(),
+                    latestResource.getToscaArtifacts().get(ToscaExportHandler.ASSET_TOSCA_TEMPLATE), csarInfo.getModifier().getUserId());
+                Map<String, Object> newMappedToscaTemplate = (Map<String, Object>) nodeTypeDefinition.getMappedNodeType().getValue();
+                Map<String, Object> combinedMappedToscaTemplate =
+                    getNewChangesToToscaTemplate(newMappedToscaTemplate, (Map<String, Object>) existingMappedToscaTemplate.getValue());
+                if (!combinedMappedToscaTemplate.equals(existingMappedToscaTemplate.getValue())) {
+                    if (latestResource.getComponentMetadataDefinition().getMetadataDataDefinition().isNormative()) {
+                        nodeTypeDefinition.getNodeTypeMetadata().setNormative(true);
+                    }
+                    existingMappedToscaTemplate.setValue(combinedMappedToscaTemplate);
+                    nodeTypeDefinition.setMappedNodeType(existingMappedToscaTemplate);
                     namesOfNodeTypesToCreate.add(nodeTypeDefinition);
                 }
             }
@@ -341,46 +636,139 @@ public class ServiceImportBusinessLogic {
     private Entry<String, Object> getResourceToscaTemplate(String uniqueId, ArtifactDefinition assetToscaTemplate, String userId) {
         String assetToToscaTemplate = assetToscaTemplate.getUniqueId();
         ImmutablePair<String, byte[]> toscaTemplate = artifactsBusinessLogic.
-                handleDownloadRequestById(uniqueId, assetToToscaTemplate, userId, ComponentTypeEnum.RESOURCE, null, null);
+            handleDownloadRequestById(uniqueId, assetToToscaTemplate, userId, ComponentTypeEnum.RESOURCE, null, null);
         Map<String, Object> mappedToscaTemplate = new Yaml().load(new String(toscaTemplate.right));
         Either<Map<String, Object>, ImportUtils.ResultStatusEnum> eitherNodeTypes =
-                findFirstToscaMapElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES);
+            findFirstToscaMapElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES);
         if (eitherNodeTypes.isRight()) {
             throw new ComponentException(ActionStatus.INVALID_TOSCA_TEMPLATE);
         }
-        Entry<String, Object> entry = eitherNodeTypes.left().value().entrySet().iterator().next();
-        return entry;
+        return eitherNodeTypes.left().value().entrySet().iterator().next();
     }
 
-    private Map<String, Object> getNewChangesToToscaTemplate(Map<String, Object> mappedToscaTemplate, Map<String, Object> latestMappedToscaTemplate) {
-        Map<String, Object> newMappedToscaTemplate = new HashMap<>(latestMappedToscaTemplate);
+    private Map<String, Object> getNewChangesToToscaTemplate(Map<String, Object> newMappedToscaTemplate,
+                                                             Map<String, Object> existingMappedToscaTemplate) {
+        Map<String, Object> combinedMappedToscaTemplate = new HashMap<>(existingMappedToscaTemplate);
+        combinePropertiesIntoToscaTemplate((Map<String, Object>) newMappedToscaTemplate.get("properties"),
+            (Map<String, Object>) existingMappedToscaTemplate.get("properties"), combinedMappedToscaTemplate);
+        combineAttributesIntoToscaTemplate((Map<String, Object>) newMappedToscaTemplate.get("attributes"),
+            (Map<String, Object>) existingMappedToscaTemplate.get("attributes"), combinedMappedToscaTemplate);
+        combineRequirementsIntoToscaTemplate((List<Map<String, Object>>) newMappedToscaTemplate.get("requirements"),
+            (List<Map<String, Object>>) existingMappedToscaTemplate.get("requirements"), combinedMappedToscaTemplate);
+        combineCapabilitiesIntoToscaTemplate((Map<String, Object>) newMappedToscaTemplate.get("capabilities"),
+            (Map<String, Object>) existingMappedToscaTemplate.get("capabilities"), combinedMappedToscaTemplate);
+        combineInterfacesIntoToscaTemplate((Map<String, Map<String, Object>>) newMappedToscaTemplate.get("interfaces"),
+            (Map<String, Map<String, Object>>) existingMappedToscaTemplate.get("interfaces"), combinedMappedToscaTemplate);
+        return combinedMappedToscaTemplate;
+    }
+
+    private void combineInterfacesIntoToscaTemplate(Map<String, Map<String, Object>> newInterfaces,
+                                                    Map<String, Map<String, Object>> existingInterfaces,
+                                                    Map<String, Object> combinedMappedToscaTemplate) {
+        Map<String, Map<String, Object>> combinedInterfaces = combineAdditionalInterfaces(newInterfaces, existingInterfaces);
+        if ((MapUtils.isEmpty(existingInterfaces) && MapUtils.isNotEmpty(combinedInterfaces))
+            || (MapUtils.isNotEmpty(existingInterfaces) && !existingInterfaces.equals(combinedInterfaces))) {
+            combinedMappedToscaTemplate.put("interfaces", combinedInterfaces);
+        }
+    }
+
+    private void combineCapabilitiesIntoToscaTemplate(Map<String, Object> newCapabilities, Map<String, Object> existingCapabilities,
+                                                      Map<String, Object> combinedMappedToscaTemplate) {
+        Map<String, Object> combinedCapabilities = combineEntries(newCapabilities, existingCapabilities);
+        if ((MapUtils.isEmpty(existingCapabilities) && MapUtils.isNotEmpty(combinedCapabilities)) ||
+            (MapUtils.isNotEmpty(existingCapabilities) && !combinedCapabilities.equals(existingCapabilities))) {
+            combinedMappedToscaTemplate.put("capabilities", combinedCapabilities);
+        }
+    }
+
+    private void combineRequirementsIntoToscaTemplate(List<Map<String, Object>> newRequirements, List<Map<String, Object>> existingRequirements,
+                                                      Map<String, Object> combinedMappedToscaTemplate) {
+        List<Map<String, Object>> combinedRequirements = combineAdditionalRequirements(newRequirements, existingRequirements);
+        if ((CollectionUtils.isEmpty(existingRequirements) && CollectionUtils.isNotEmpty(combinedRequirements))
+            || (CollectionUtils.isNotEmpty(existingRequirements) && !combinedRequirements.equals(existingRequirements))) {
+            combinedMappedToscaTemplate.put("requirements", combinedRequirements);
+        }
+    }
 
-        Map<String, Object> properties = (Map<String, Object>) mappedToscaTemplate.get("properties");
-        Map<String, Object> latestProperties = (Map<String, Object>) latestMappedToscaTemplate.get("properties");
-        Map<String, Object> allProperties = combinedEntries(properties, latestProperties);
-        if ((MapUtils.isEmpty(latestProperties) && MapUtils.isNotEmpty(allProperties)) ||
-            (MapUtils.isNotEmpty(latestProperties) && !allProperties.equals(latestProperties))) {
-            newMappedToscaTemplate.put("properties", allProperties);
+    private void combineAttributesIntoToscaTemplate(Map<String, Object> newAttributes, Map<String, Object> existingAttributes,
+                                                    Map<String, Object> combinedMappedToscaTemplate) {
+        Map<String, Object> combinedAttributes = combineEntries(newAttributes, existingAttributes);
+        if ((MapUtils.isEmpty(existingAttributes) && MapUtils.isNotEmpty(combinedAttributes)) ||
+            (MapUtils.isNotEmpty(existingAttributes) && !combinedAttributes.equals(existingAttributes))) {
+            combinedMappedToscaTemplate.put("attributes", combinedAttributes);
         }
-        return newMappedToscaTemplate;
     }
 
-    private Map<String, Object> combinedEntries(Map<String, Object> firstMap, Map<String, Object> secondMap) {
-        if (MapUtils.isEmpty(firstMap)) {
-            firstMap = new HashMap<>();
+    private void combinePropertiesIntoToscaTemplate(Map<String, Object> newProperties, Map<String, Object> existingProperties,
+                                                    Map<String, Object> combinedMappedToscaTemplate) {
+        Map<String, Object> combinedProperties = combineEntries(newProperties, existingProperties);
+        if ((MapUtils.isEmpty(existingProperties) && MapUtils.isNotEmpty(combinedProperties)) ||
+            (MapUtils.isNotEmpty(existingProperties) && !combinedProperties.equals(existingProperties))) {
+            combinedMappedToscaTemplate.put("properties", combinedProperties);
         }
-        Map<String, Object> combinedEntries = new HashMap<>(firstMap);
-        if (MapUtils.isEmpty(secondMap)) {
+    }
+
+    private Map<String, Map<String, Object>> combineAdditionalInterfaces(Map<String, Map<String, Object>> newInterfaces,
+                                                                         Map<String, Map<String, Object>> existingInterfaces) {
+        if (MapUtils.isNotEmpty(newInterfaces) && MapUtils.isNotEmpty(existingInterfaces) && newInterfaces.equals(existingInterfaces)) {
+            return new HashMap<>(existingInterfaces);
+        }
+        if (MapUtils.isEmpty(newInterfaces)) {
+            newInterfaces = new HashMap<>();
+        }
+        Map<String, Map<String, Object>> combinedEntries = new HashMap<>(newInterfaces);
+        if (MapUtils.isEmpty(existingInterfaces)) {
             return combinedEntries;
         }
-        combinedEntries.putAll(secondMap);
+        existingInterfaces.entrySet().forEach(interfaceDef -> {
+            combinedEntries.entrySet().stream().filter((interFace) -> interFace.getValue().get("type").equals((interfaceDef.getValue()).get("type")))
+                .findFirst().ifPresentOrElse((interFace) -> {
+                    interFace.getValue().putAll(interfaceDef.getValue());
+                }, () -> {
+                    combinedEntries.put(interfaceDef.getKey(), interfaceDef.getValue());
+                });
+        });
+        return combinedEntries;
+    }
+
+    private List<Map<String, Object>> combineAdditionalRequirements(List<Map<String, Object>> newReqs,
+                                                                    List<Map<String, Object>> existingResourceReqs) {
+        if (CollectionUtils.isNotEmpty(newReqs) && CollectionUtils.isNotEmpty(existingResourceReqs) && newReqs.equals(existingResourceReqs)) {
+            return new ArrayList<>(existingResourceReqs);
+        }
+        if (CollectionUtils.isEmpty(existingResourceReqs)) {
+            existingResourceReqs = new ArrayList<>();
+        }
+        Set<Map<String, Object>> combinedReqs = new TreeSet<>((map1, map2) ->
+            map1.keySet().equals(map2.keySet()) ? 0 : map1.keySet().iterator().next().compareTo(map2.keySet().iterator().next()));
+        combinedReqs.addAll(existingResourceReqs);
+        if (CollectionUtils.isEmpty(newReqs)) {
+            return new ArrayList<>(combinedReqs);
+        }
+        combinedReqs.addAll(newReqs);
+        return new ArrayList<>(combinedReqs);
+    }
+
+    private Map<String, Object> combineEntries(Map<String, Object> newMap, Map<String, Object> existingMap) {
+        if (MapUtils.isNotEmpty(newMap) && MapUtils.isNotEmpty(existingMap) && newMap.equals(existingMap)) {
+            return new HashMap<>(existingMap);
+        }
+        if (MapUtils.isEmpty(newMap)) {
+            newMap = new HashMap<>();
+        }
+        Map<String, Object> combinedEntries = new HashMap<>(newMap);
+        if (MapUtils.isEmpty(existingMap)) {
+            return combinedEntries;
+        }
+        combinedEntries.putAll(existingMap);
         return combinedEntries;
     }
 
     protected Service createServiceFromYaml(Service service, String topologyTemplateYaml, String yamlName, Map<String, NodeTypeInfo> nodeTypesInfo,
                                             CsarInfo csarInfo,
-                                            Map<String, EnumMap<ArtifactsBusinessLogic.ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToCreate,
-                                            boolean shouldLock, boolean inTransaction, String nodeName, final String userId)
+                                            Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToCreate,
+                                            boolean shouldLock, boolean inTransaction, String nodeName, final String userId,
+                                            AuditingActionEnum auditingAction)
         throws BusinessLogicException {
         List<ArtifactDefinition> createdArtifacts = new ArrayList<>();
         Service createdService;
@@ -396,7 +784,8 @@ public class ServiceImportBusinessLogic {
             csfyp.setNodeTypesInfo(nodeTypesInfo);
             csfyp.setCsarInfo(csarInfo);
             csfyp.setNodeName(nodeName);
-            createdService = createServiceAndRIsFromYaml(service, false, nodeTypesArtifactsToCreate, shouldLock, inTransaction, csfyp, userId);
+            createdService = createServiceAndRIsFromYaml(service, false, nodeTypesArtifactsToCreate, shouldLock, inTransaction, csfyp, userId,
+                auditingAction);
             log.debug("#createResourceFromYaml - The resource {} has been created ", service.getName());
         } catch (ComponentException | BusinessLogicException e) {
             log.debug("Create Service from yaml failed", e);
@@ -409,10 +798,11 @@ public class ServiceImportBusinessLogic {
     }
 
     protected Service createServiceAndRIsFromYaml(Service service, boolean isNormative,
-                                                  Map<String, EnumMap<ArtifactsBusinessLogic.ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToCreate,
+                                                  Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToCreate,
                                                   boolean shouldLock, boolean inTransaction, CreateServiceFromYamlParameter csfyp,
-                                                  final String userId)
+                                                  final String userId, AuditingActionEnum auditingAction)
         throws BusinessLogicException {
+
         List<ArtifactDefinition> nodeTypesNewCreatedArtifacts = new ArrayList<>();
         String yamlName = csfyp.getYamlName();
         ParsedToscaYamlInfo parsedToscaYamlInfo = csfyp.getParsedToscaYamlInfo();
@@ -424,7 +814,6 @@ public class ServiceImportBusinessLogic {
         if (shouldLock) {
             Either<Boolean, ResponseFormat> lockResult = serviceBusinessLogic.lockComponentByName(service.getSystemName(), service, CREATE_RESOURCE);
             if (lockResult.isRight()) {
-                serviceImportParseLogic.rollback(inTransaction, service, createdArtifacts, nodeTypesNewCreatedArtifacts);
                 throw new ComponentException(lockResult.right().value());
             }
             log.debug("name is locked {} status = {}", service.getSystemName(), lockResult);
@@ -442,12 +831,13 @@ public class ServiceImportBusinessLogic {
                 service.setProperties(propertiesList);
             }
             log.trace("************* createResourceFromYaml before full create resource {}", yamlName);
-            service = serviceImportParseLogic.createServiceTransaction(service, csarInfo.getModifier(), isNormative);
+            service = serviceImportParseLogic.createServiceTransaction(service, csarInfo.getModifier(), isNormative, auditingAction);
             log.trace("************* Going to add inputs from yaml {}", yamlName);
             Map<String, InputDefinition> inputs = parsedToscaYamlInfo.getInputs();
             service = serviceImportParseLogic.createInputsOnService(service, inputs);
             log.trace("************* Finished to add inputs from yaml {}", yamlName);
-            ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> substitutionFilterProperties = parsedToscaYamlInfo.getSubstitutionFilterProperties();
+            ListDataDefinition<SubstitutionFilterPropertyDataDefinition> substitutionFilterProperties =
+                parsedToscaYamlInfo.getSubstitutionFilterProperties();
             service = serviceImportParseLogic.createSubstitutionFilterOnService(service, substitutionFilterProperties);
             log.trace("************* Added Substitution filter from interface yaml {}", yamlName);
             Map<String, UploadComponentInstanceInfo> uploadComponentInstanceInfoMap = parsedToscaYamlInfo.getInstances();
@@ -463,7 +853,6 @@ public class ServiceImportBusinessLogic {
             Either<Map<String, GroupDefinition>, ResponseFormat> validateUpdateVfGroupNamesRes
                 = groupBusinessLogic.validateUpdateVfGroupNames(parsedToscaYamlInfo.getGroups(), service.getSystemName());
             if (validateUpdateVfGroupNamesRes.isRight()) {
-                serviceImportParseLogic.rollback(inTransaction, service, createdArtifacts, nodeTypesNewCreatedArtifacts);
                 throw new ComponentException(validateUpdateVfGroupNamesRes.right().value());
             }
             Map<String, GroupDefinition> groups;
@@ -475,31 +864,27 @@ public class ServiceImportBusinessLogic {
             }
             Either<Service, ResponseFormat> createGroupsOnResource = createGroupsOnResource(service, groups);
             if (createGroupsOnResource.isRight()) {
-                serviceImportParseLogic.rollback(inTransaction, service, createdArtifacts, nodeTypesNewCreatedArtifacts);
                 throw new ComponentException(createGroupsOnResource.right().value());
             }
             service = createGroupsOnResource.left().value();
 
             Either<Service, ResponseFormat> createPoliciesOnResource = createPoliciesOnResource(service, parsedToscaYamlInfo.getPolicies());
             if (createPoliciesOnResource.isRight()) {
-                serviceImportParseLogic.rollback(inTransaction, service, createdArtifacts, nodeTypesNewCreatedArtifacts);
                 throw new ComponentException(createPoliciesOnResource.right().value());
             }
             service = createPoliciesOnResource.left().value();
             log.trace("************* Going to add artifacts from yaml {}", yamlName);
-            NodeTypeInfoToUpdateArtifacts nodeTypeInfoToUpdateArtifacts = new NodeTypeInfoToUpdateArtifacts(nodeName, nodeTypesArtifactsToCreate);
             Either<Service, ResponseFormat> createArtifactsEither = createOrUpdateArtifacts(ArtifactsBusinessLogic.ArtifactOperationEnum.CREATE,
-                createdArtifacts, yamlName, csarInfo, service, nodeTypeInfoToUpdateArtifacts, inTransaction, shouldLock);
+                createdArtifacts, yamlName, csarInfo, service, inTransaction, shouldLock);
             if (createArtifactsEither.isRight()) {
-                serviceImportParseLogic.rollback(inTransaction, service, createdArtifacts, nodeTypesNewCreatedArtifacts);
                 throw new ComponentException(createArtifactsEither.right().value());
             }
             service = serviceImportParseLogic.getServiceWithGroups(createArtifactsEither.left().value().getUniqueId());
-            service = updateInputs(service, userId);
+            service = updateInputs(service, userId, parsedToscaYamlInfo.getSubstitutionMappingProperties());
 
             ASDCKpiApi.countCreatedResourcesKPI();
             return service;
-        } catch (ComponentException | StorageException | BusinessLogicException e) {
+        } catch (Exception e) {
             rollback = true;
             serviceImportParseLogic.rollback(inTransaction, service, createdArtifacts, nodeTypesNewCreatedArtifacts);
             throw e;
@@ -512,52 +897,57 @@ public class ServiceImportBusinessLogic {
                 }
             }
             if (shouldLock) {
-                graphLockOperation.unlockComponentByName(service.getSystemName(), service.getUniqueId(), NodeTypeEnum.Resource);
+                graphLockOperation.unlockComponentByName(service.getSystemName(), service.getUniqueId(), NodeTypeEnum.Service);
             }
         }
     }
 
-    private Service updateInputs(final Service component, final String userId) {
+    private Service updateInputs(final Service component, final String userId, final Map<String, List<String>> substitutionMappingProperties) {
         final List<InputDefinition> inputs = component.getInputs();
-        final List<ComponentInstance> componentInstances = component.getComponentInstances();
-        final String componentUniqueId = component.getUniqueId();
-        final Map<String, List<ComponentInstanceProperty>> componentInstancesProperties = component.getComponentInstancesProperties();
-        for (final InputDefinition input : inputs) {
-            if (isInputFromComponentInstanceProperty(input.getName(), componentInstances, componentInstancesProperties)) {
-                associateInputToComponentInstanceProperty(userId, input, componentInstances, componentInstancesProperties,
-                    componentUniqueId);
-            } else {
-                associateInputToServiceProperty(userId, input, component);
+        if (CollectionUtils.isNotEmpty(inputs)) {
+            final List<ComponentInstance> componentInstances = component.getComponentInstances();
+            final String componentUniqueId = component.getUniqueId();
+            List<String> propertyMissingNames = new ArrayList<>();
+            for (final InputDefinition input : inputs) {
+                boolean isSubMapProp = false;
+                if (substitutionMappingProperties != null && !substitutionMappingProperties.isEmpty()) {
+                    isSubMapProp = substitutionMappingProperties.entrySet().stream()
+                        .anyMatch(stringEntry -> stringEntry.getValue().get(0).equals(input.getName()));
+                }
+                if (!isSubMapProp && isInputFromComponentInstanceProperty(input.getName(), componentInstances)) {
+                    associateInputToComponentInstanceProperty(userId, input, componentInstances, componentUniqueId);
+                } else {
+                    String propertyName = associateInputToServiceProperty(userId, input, component, substitutionMappingProperties);
+                    if (StringUtils.isNotBlank(propertyName)) {
+                        propertyMissingNames.add(propertyName);
+                    }
+                }
+            }
+            if (CollectionUtils.isNotEmpty(propertyMissingNames)) {
+                throw new ComponentException(
+                    componentsUtils.getResponseFormat(ActionStatus.MISSING_PROPERTIES_ERROR, propertyMissingNames.toString()));
+            }
+            Either<List<InputDefinition>, StorageOperationStatus> either = toscaOperationFacade.updateInputsToComponent(inputs, componentUniqueId);
+            if (either.isRight()) {
+                throw new ComponentException(ActionStatus.GENERAL_ERROR);
             }
-
-        }
-
-        final Either<List<InputDefinition>, StorageOperationStatus> either
-            = toscaOperationFacade.updateInputsToComponent(inputs, componentUniqueId);
-        if (either.isRight()) {
-            throw new ComponentException(ActionStatus.GENERAL_ERROR);
         }
 
         return component;
     }
 
-    private boolean isInputFromComponentInstanceProperty(final String inputName, final List<ComponentInstance> componentInstances,
-                                                         final Map<String, List<ComponentInstanceProperty>> componentInstancesProperties) {
+    private boolean isInputFromComponentInstanceProperty(final String inputName, final List<ComponentInstance> componentInstances) {
+
         if (CollectionUtils.isNotEmpty(componentInstances)) {
-            // get instance's names
-            final List<String> componentInstancesNames = componentInstances.stream().map(ComponentInstanceDataDefinition::getNormalizedName)
-                .collect(toList());
-            final Optional<String> componentInstancesNameOptional = componentInstancesNames.stream()
-                .filter(cin -> inputName.startsWith(cin + "_")).findFirst();
-            if (componentInstancesNameOptional.isPresent() && MapUtils.isNotEmpty(componentInstancesProperties)) {
-                final Optional<String> componentInstanceIdOptional = componentInstancesProperties.keySet().stream()
-                    .filter(key -> key.endsWith("." + componentInstancesNameOptional.get())).findFirst();
-                if (componentInstanceIdOptional.isPresent()) {
-                    // get property's name
-                    final String propertyNameFromInput = extractPropertyNameFromInputName(inputName, componentInstancesNames);
-                    return componentInstancesProperties.get(componentInstanceIdOptional.get()).stream()
-                        .anyMatch(prop -> prop.getName().equals(propertyNameFromInput) && prop.getValue() != null
-                            && prop.getValue().contains(ToscaGetFunctionType.GET_INPUT.getFunctionName()));
+            for (ComponentInstance instance : componentInstances) {
+                for (PropertyDefinition instanceProperty : instance.getProperties()) {
+                    if (CollectionUtils.isNotEmpty(instanceProperty.getGetInputValues())) {
+                        for (GetInputValueDataDefinition getInputValueDataDefinition : instanceProperty.getGetInputValues()) {
+                            if (inputName.equals(getInputValueDataDefinition.getInputName())) {
+                                return true;
+                            }
+                        }
+                    }
                 }
             }
         }
@@ -566,25 +956,28 @@ public class ServiceImportBusinessLogic {
 
     private void associateInputToComponentInstanceProperty(final String userId, final InputDefinition input,
                                                            final List<ComponentInstance> componentInstances,
-                                                           final Map<String, List<ComponentInstanceProperty>> componentInstancesProperties,
                                                            String componentUniqueId) {
-        // From Instance
-        final List<String> componentInstancesNames = componentInstances.stream().map(ComponentInstanceDataDefinition::getNormalizedName)
-            .collect(toList());
-        final String propertyNameFromInput = extractPropertyNameFromInputName(input.getName(), componentInstancesNames);
-
-        final Optional<String> componentInstancesNameOptional = componentInstancesNames.stream()
-            .filter(cin -> input.getName().startsWith(cin + "_")).findFirst();
 
-        final Optional<String> componentInstanceIdOptional = componentInstancesProperties.keySet().stream()
-            .filter(key -> key.endsWith("." + componentInstancesNameOptional.get())).findFirst();
-
-        final String componentInstanceId = componentInstanceIdOptional.get();
-        final List<ComponentInstanceProperty> componentInstanceProperties = componentInstancesProperties.get(componentInstanceId);
+        String componentInstanceId = null;
+        ComponentInstanceProperty componentInstanceProperty = new ComponentInstanceProperty();
+
+        outer:
+        for (ComponentInstance instance : componentInstances) {
+            for (PropertyDefinition instanceProperty : instance.getProperties()) {
+                if (CollectionUtils.isNotEmpty(instanceProperty.getGetInputValues())) {
+                    for (GetInputValueDataDefinition getInputValueDataDefinition : instanceProperty.getGetInputValues()) {
+                        if (input.getName().equals(getInputValueDataDefinition.getInputName())) {
+                            componentInstanceId = instance.getUniqueId();
+                            componentInstanceProperty = new ComponentInstanceProperty(instanceProperty);
+                            break outer;
+                        }
+                    }
+                }
+            }
+        }
 
-        final ComponentInstanceProperty componentInstanceProperty = componentInstanceProperties.stream()
-            .filter(prop -> prop.getName().equals(propertyNameFromInput) && prop.getValue() != null
-                && prop.getValue().contains(ToscaGetFunctionType.GET_INPUT.getFunctionName())).findFirst().get();
+        //unmapping instance property declared inputs from substitution mapping
+        input.setMappedToComponentProperty(false);
 
         // From Instance
         updateInput(input, componentInstanceProperty, userId, componentInstanceId);
@@ -597,13 +990,21 @@ public class ServiceImportBusinessLogic {
         }
     }
 
-    private void associateInputToServiceProperty(final String userId,
-                                                 final InputDefinition input, final Service component) {
+    private String associateInputToServiceProperty(final String userId,
+                                                   final InputDefinition input, final Service component,
+                                                   final Map<String, List<String>> substitutionMappingProperties) {
         final List<PropertyDefinition> properties = component.getProperties();
-        if (CollectionUtils.isNotEmpty(properties)) {
-            final String propertyNameFromInput = input.getName();
-            final Optional<PropertyDefinition> propDefOptional = properties.stream().filter(prop -> prop.getName().equals(propertyNameFromInput))
-                .findFirst();
+        if (CollectionUtils.isNotEmpty(properties) && MapUtils.isNotEmpty(substitutionMappingProperties)) {
+            AtomicReference<String> propertyNameFromInput = new AtomicReference<>(" ");
+            substitutionMappingProperties.entrySet().forEach(stringEntry -> {
+                if (stringEntry.getValue().get(0).equals(input.getName())) {
+                    propertyNameFromInput.set(stringEntry.getKey());
+                }
+            });
+
+            final Optional<PropertyDefinition> propDefOptional =
+                properties.stream().filter(prop -> prop.getName().equals(propertyNameFromInput.get()))
+                    .findFirst();
             if (propDefOptional.isPresent()) {
                 // From SELF
                 final String componentUniqueId = component.getUniqueId();
@@ -619,8 +1020,12 @@ public class ServiceImportBusinessLogic {
                 if (either.isRight()) {
                     throw new ComponentException(ActionStatus.GENERAL_ERROR);
                 }
+            } else {
+                input.setMappedToComponentProperty(false);
+                return propertyNameFromInput.get();
             }
         }
+        return "";
     }
 
     private void updateProperty(final PropertyDefinition propertyDefinition, final InputDefinition input, final String componentUniqueId) {
@@ -641,12 +1046,6 @@ public class ServiceImportBusinessLogic {
         input.setParentPropertyType(propertyDefinition.getType());
     }
 
-    private String extractPropertyNameFromInputName(final String inputName, final List<String> componentInstancesNames) {
-        final AtomicReference<String> result = new AtomicReference<>(inputName);
-        componentInstancesNames.forEach(cin -> result.set(result.get().replace(cin + "_", "")));
-        return result.get();
-    }
-
     protected Either<Resource, ResponseFormat> createOrUpdateArtifacts(ArtifactsBusinessLogic.ArtifactOperationEnum operation,
                                                                        List<ArtifactDefinition> createdArtifacts, String yamlFileName,
                                                                        CsarInfo csarInfo, Resource preparedResource,
@@ -654,8 +1053,9 @@ public class ServiceImportBusinessLogic {
                                                                        boolean inTransaction, boolean shouldLock) {
         String nodeName = nodeTypeInfoToUpdateArtifacts.getNodeName();
         Resource resource = preparedResource;
-        Map<String, EnumMap<ArtifactsBusinessLogic.ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle = nodeTypeInfoToUpdateArtifacts
-            .getNodeTypesArtifactsToHandle();
+        Map<String, EnumMap<ArtifactsBusinessLogic.ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle =
+            nodeTypeInfoToUpdateArtifacts
+                .getNodeTypesArtifactsToHandle();
         if (preparedResource.getResourceType() == ResourceTypeEnum.VF) {
             if (nodeName != null && nodeTypesArtifactsToHandle.get(nodeName) != null && !nodeTypesArtifactsToHandle.get(nodeName).isEmpty()) {
                 Either<List<ArtifactDefinition>, ResponseFormat> handleNodeTypeArtifactsRes = handleNodeTypeArtifacts(preparedResource,
@@ -782,7 +1182,8 @@ public class ServiceImportBusinessLogic {
                 vfCsarArtifactsToHandle = new EnumMap<>(ArtifactsBusinessLogic.ArtifactOperationEnum.class);
                 vfCsarArtifactsToHandle.put(artifactOperation.getArtifactOperationEnum(), artifactPathAndNameList.left().value());
             } else {
-                Either<EnumMap<ArtifactsBusinessLogic.ArtifactOperationEnum, List<CsarUtils.NonMetaArtifactInfo>>, ResponseFormat> findVfCsarArtifactsToHandleRes = findVfCsarArtifactsToHandle(
+                Either<EnumMap<ArtifactsBusinessLogic.ArtifactOperationEnum, List<CsarUtils.NonMetaArtifactInfo>>, ResponseFormat>
+                    findVfCsarArtifactsToHandleRes = findVfCsarArtifactsToHandle(
                     component, artifactPathAndNameList.left().value(), csarInfo.getModifier());
                 if (findVfCsarArtifactsToHandleRes.isRight()) {
                     resStatus = Either.right(findVfCsarArtifactsToHandleRes.right().value());
@@ -941,7 +1342,6 @@ public class ServiceImportBusinessLogic {
 
     protected Either<Service, ResponseFormat> createOrUpdateArtifacts(ArtifactOperationEnum operation, List<ArtifactDefinition> createdArtifacts,
                                                                       String yamlFileName, CsarInfo csarInfo, Service preparedService,
-                                                                      NodeTypeInfoToUpdateArtifacts nodeTypeInfoToUpdateArtifacts,
                                                                       boolean inTransaction, boolean shouldLock) {
         Either<Service, ResponseFormat> createdCsarArtifactsEither = handleVfCsarArtifacts(preparedService, csarInfo, createdArtifacts,
             new ArtifactOperationInfo(false, false, operation), shouldLock, inTransaction);
@@ -1073,7 +1473,8 @@ public class ServiceImportBusinessLogic {
         EnumMap<ArtifactsBusinessLogic.ArtifactOperationEnum, List<CsarUtils.NonMetaArtifactInfo>> nodeTypeArtifactsToHandle = new EnumMap<>(
             ArtifactsBusinessLogic.ArtifactOperationEnum.class);
         Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
-        Either<EnumMap<ArtifactsBusinessLogic.ArtifactOperationEnum, List<CsarUtils.NonMetaArtifactInfo>>, ResponseFormat> nodeTypeArtifactsToHandleRes = Either
+        Either<EnumMap<ArtifactsBusinessLogic.ArtifactOperationEnum, List<CsarUtils.NonMetaArtifactInfo>>, ResponseFormat>
+            nodeTypeArtifactsToHandleRes = Either
             .left(nodeTypeArtifactsToHandle);
         try {
             List<CsarUtils.NonMetaArtifactInfo> artifactsToUpload = new ArrayList<>(artifactPathAndNameList);
@@ -1179,21 +1580,20 @@ public class ServiceImportBusinessLogic {
         if (MapUtils.isEmpty(policies)) {
             return Either.left(service);
         }
-        final Map<String, List<AttributeDefinition>> instanceAttributeMap =
-            service.getComponentInstancesAttributes()
+        Map<String, List<ComponentInstanceAttribute>> componentInstancesAttributes = service.getComponentInstancesAttributes();
+        final Map<String, List<AttributeDefinition>> instanceAttributeMap = new HashMap<>();
+        if (MapUtils.isNotEmpty(componentInstancesAttributes)) {
+            instanceAttributeMap.putAll(componentInstancesAttributes
                 .entrySet().stream()
-                .collect(
-                    toMap(Entry::getKey,
-                        entry -> entry.getValue().stream().map(AttributeDefinition.class::cast).collect(toList()))
-                );
+                .collect(toMap(Entry::getKey, entry -> entry.getValue().stream().map(AttributeDefinition.class::cast).collect(toList()))));
+        }
         policies.values().stream()
             .map(PolicyDataDefinition::getProperties)
             .flatMap(Collection::stream)
             .filter(PropertyDataDefinition::isToscaFunction)
-            .forEach(policyDefinition ->
-                toscaFunctionService
-                    .updateFunctionWithDataFromSelfComponent(policyDefinition.getToscaFunction(), service, service.getComponentInstancesProperties(),
-                        instanceAttributeMap)
+            .forEach(policyDefinition -> toscaFunctionService
+                .updateFunctionWithDataFromSelfComponent(policyDefinition.getToscaFunction(), service, service.getComponentInstancesProperties(),
+                    instanceAttributeMap)
             );
         policyBusinessLogic.createPolicies(service, policies);
         return getServiceResponseFormatEither(service);
@@ -1609,11 +2009,12 @@ public class ServiceImportBusinessLogic {
         log.debug("************* Going to create all nodes {}", yamlName);
         handleServiceNodeTypes(yamlName, service, topologyTemplateYaml, false, nodeTypesArtifactsToCreate, nodeTypesNewCreatedArtifacts,
             nodeTypesInfo, csarInfo, nodeName);
+        List<PropertyDefinition> serviceProperties = null != service ? service.getProperties() : Collections.emptyList();
         if (MapUtils.isNotEmpty(uploadComponentInstanceInfoMap)) {
             log.debug("************* Going to create all resource instances {}", yamlName);
             service = createServiceInstances(yamlName, service, uploadComponentInstanceInfoMap, csarInfo.getCreatedNodes());
             log.debug("************* Going to create all relations {}", yamlName);
-            service = createServiceInstancesRelations(csarInfo.getModifier(), yamlName, service, uploadComponentInstanceInfoMap);
+            service = createServiceInstancesRelations(csarInfo.getModifier(), yamlName, service, uploadComponentInstanceInfoMap, serviceProperties);
             log.debug("************* Going to create positions {}", yamlName);
             compositionBusinessLogic.setPositionsForComponentInstances(service, csarInfo.getModifier().getUserId());
             log.debug("************* Finished to set positions {}", yamlName);
@@ -1622,7 +2023,8 @@ public class ServiceImportBusinessLogic {
     }
 
     protected Service createServiceInstancesRelations(User user, String yamlName, Service service,
-                                                      Map<String, UploadComponentInstanceInfo> uploadResInstancesMap) {
+                                                      Map<String, UploadComponentInstanceInfo> uploadResInstancesMap,
+                                                      List<PropertyDefinition> serviceProperties) {
         log.debug("#createResourceInstancesRelations - Going to create relations ");
         List<ComponentInstance> componentInstancesList = service.getComponentInstances();
         if (MapUtils.isEmpty(uploadResInstancesMap) || CollectionUtils.isEmpty(componentInstancesList)) { // PNF can have no resource instances
@@ -1650,6 +2052,7 @@ public class ServiceImportBusinessLogic {
             final Map<String, DataTypeDefinition> allDataTypesMap =
                 componentsUtils.getAllDataTypes(applicationDataTypeCache, service.getModel());
             final Service service1 = service;
+            service1.setProperties(serviceProperties);
             uploadResInstancesMap.values().forEach(
                 i -> processComponentInstance(yamlName, service1, componentInstancesList,
                     allDataTypesMap, instProperties,
@@ -1708,7 +2111,7 @@ public class ServiceImportBusinessLogic {
                 .forEach(instanceProperty -> {
                     toscaFunctionService.updateFunctionWithDataFromSelfComponent(instanceProperty.getToscaFunction(),
                         updatedService, instancePropertyMap, instanceAttributeMap);
-                    instanceProperty.setValue(instanceProperty.getToscaFunction().getValue());
+                    instanceProperty.setValue(StringEscapeUtils.unescapeJava(instanceProperty.getToscaFunction().getValue()));
                 })
         );
     }
@@ -1754,8 +2157,11 @@ public class ServiceImportBusinessLogic {
         if (originResource.getAttributes() != null && !originResource.getAttributes().isEmpty()) {
             instAttributes.put(resourceInstanceId, originResource.getAttributes());
             addAttributeValueToResourceInstance(instAttributes, uploadComponentInstanceInfo.getAttributes());
+            instAttributes.get(resourceInstanceId).addAll(addImplicitAttributeValues(originResource, uploadComponentInstanceInfo));
         }
-        if (uploadComponentInstanceInfo.getUploadNodeFilterInfo() != null) {
+        if (uploadComponentInstanceInfo.getUploadNodeFilterInfo() == null) {
+            instNodeFilter.put(resourceInstanceId, new UploadNodeFilterInfo());
+        } else {
             instNodeFilter.put(resourceInstanceId, uploadComponentInstanceInfo.getUploadNodeFilterInfo());
         }
         if (MapUtils.isNotEmpty(uploadComponentInstanceInfo.getInterfaces())) {
@@ -1782,6 +2188,44 @@ public class ServiceImportBusinessLogic {
         }
     }
 
+    private List<AttributeDefinition> addImplicitAttributeValues(Resource originResource, UploadComponentInstanceInfo uploadComponentInstanceInfo) {
+        if (uploadComponentInstanceInfo.getAttributes() == null) {
+            return Collections.emptyList();
+        }
+        List<String> origAttributes = originResource.getAttributes().stream().map(AttributeDefinition::getName).collect(toList());
+        Map<String, UploadAttributeInfo> uploadAttributes = uploadComponentInstanceInfo.getAttributes();
+        List<String> newAttributesToAdd =
+            uploadAttributes.keySet().stream().filter(newAttribute -> !origAttributes.contains(newAttribute))
+                .collect(toList());
+        List<PropertyDefinition> propsToAddAsAttributes =
+            originResource.getProperties().stream().filter(prop -> newAttributesToAdd.contains(prop.getName())).collect(toList());
+        propsToAddAsAttributes.stream().forEach(prop -> {
+            Object value = uploadAttributes.get(prop.getName()).getValue();
+            if (value instanceof Collection<?> || value instanceof Map<?, ?>) {
+                Gson gson = new Gson();
+                String json = gson.toJson(value);
+                prop.setValue(json);
+            } else {
+                prop.setValue(String.valueOf(value));
+            }
+        });
+        List<AttributeDefinition> attributesToAdd = new ArrayList<>();
+        for (PropertyDefinition prop : propsToAddAsAttributes) {
+            attributesToAdd.add(getPropertyAsAttribute(prop));
+        }
+        return attributesToAdd;
+    }
+
+    private AttributeDefinition getPropertyAsAttribute(PropertyDefinition property) {
+        AttributeDefinition attribute = new AttributeDefinition();
+        attribute.setName(property.getName());
+        attribute.setType(property.getType());
+        attribute.setSchema(property.getSchema());
+        attribute.setValue(property.getValue());
+        attribute.setDefaultValue(property.getDefaultValue());
+        return attribute;
+    }
+
     protected void addInputsValuesToRi(UploadComponentInstanceInfo uploadComponentInstanceInfo, Component component, Resource originResource,
                                        ComponentInstance currentCompInstance, Map<String, List<ComponentInstanceInput>> instInputs,
                                        Map<String, DataTypeDefinition> allDataTypes) {
@@ -1891,10 +2335,30 @@ public class ServiceImportBusinessLogic {
                     }
                 }
                 final var property = new ComponentInstanceProperty(curPropertyDef, value, null);
-                String validatePropValue = serviceBusinessLogic.validatePropValueBeforeCreate(property, value, isValidate, allDataTypes);
-                property.setValue(validatePropValue);
-                property.setToscaFunction(propertyInfo.getToscaFunction());
-                if (!getInputs.isEmpty()) {
+                String validatedPropValue = serviceBusinessLogic.validatePropValueBeforeCreate(property, value, true, allDataTypes);
+
+                addSubPropertyYamlToscaFunctions(validatedPropValue, value, property.getType(), propertyInfo, allDataTypes);
+
+                if (CollectionUtils.isNotEmpty(propertyInfo.getSubPropertyToscaFunctions())) {
+                    validatedPropValue = value;
+                }
+
+                property.setValue(validatedPropValue);
+
+                if (tryHandlingAsYamlToscaFunction(validatedPropValue, value, propertyInfo)) {
+                    try {
+                        final Object yamlValue = new Yaml().loadAs(value, Object.class);
+                        CustomYamlFunction toscaFunction = new CustomYamlFunction();
+                        toscaFunction.setYamlValue(yamlValue);
+                        property.setToscaFunction(toscaFunction);
+                    } catch (Exception exception) {
+                        log.info("Cannot create YAML value for {}", propName);
+                    }
+                } else {
+                    property.setToscaFunction(propertyInfo.getToscaFunction());
+                }
+                property.setSubPropertyToscaFunctions(propertyInfo.getSubPropertyToscaFunctions());
+                if (!getInputs.isEmpty() && CollectionUtils.isEmpty(property.getSubPropertyToscaFunctions())) {
                     final List<GetInputValueDataDefinition> getInputValues = new ArrayList<>();
                     for (final GetInputValueDataDefinition getInput : getInputs) {
                         final List<InputDefinition> inputs = component.getInputs();
@@ -1928,6 +2392,68 @@ public class ServiceImportBusinessLogic {
         return componentsUtils.getResponseFormat(ActionStatus.OK);
     }
 
+    private boolean tryHandlingAsYamlToscaFunction(String validatedPropValue, String value, UploadPropInfo propertyInfo) {
+        return StringUtils.isEmpty(validatedPropValue) && StringUtils.isNotEmpty(value) && propertyInfo.getToscaFunction() == null
+            && CollectionUtils.isEmpty(propertyInfo.getSubPropertyToscaFunctions());
+    }
+
+    private void addSubPropertyYamlToscaFunctions(final String validatedPropValue, final String value, final String propertyType,
+                                                  final UploadPropInfo propertyInfo, final Map<String, DataTypeDefinition> allDataTypes) {
+        if (StringUtils.isNotEmpty(validatedPropValue) || StringUtils.isEmpty(value) || ToscaPropertyType.isValidType(propertyType) != null) {
+            return;
+        }
+        try {
+            final JsonObject jsonObject = JsonParser.parseString(value).getAsJsonObject();
+
+            final DataTypeDefinition dataTypeDefinition = allDataTypes.get(propertyType);
+            final List<String> propertyNames =
+                dataTypeDefinition.getProperties().stream().map(PropertyDataDefinition::getName).collect(Collectors.toList());
+
+            boolean hasSubPropertyValues = jsonObject.entrySet().stream().allMatch(entry -> propertyNames.contains(entry.getKey()));
+
+            if (hasSubPropertyValues) {
+                for (final PropertyDefinition prop : dataTypeDefinition.getProperties()) {
+                    if (propertyInfo.getSubPropertyToscaFunctions().stream()
+                        .anyMatch(subPropertyToscaFunction -> subPropertyToscaFunction.getSubPropertyPath().get(0).equals(prop.getName()))) {
+                        continue;
+                    }
+                    Optional<SubPropertyToscaFunction> subPropertyToscaFunction = createSubPropertyYamlToscaFunction(jsonObject, prop, allDataTypes);
+                    if (subPropertyToscaFunction.isPresent()) {
+                        propertyInfo.getSubPropertyToscaFunctions().add(subPropertyToscaFunction.get());
+                    }
+                }
+            }
+        } catch (Exception exception) {
+            log.info("Cannot create YAML value for {}", value);
+        }
+    }
+
+    private Optional<SubPropertyToscaFunction> createSubPropertyYamlToscaFunction(final JsonObject jsonObject, final PropertyDefinition prop,
+                                                                                  final Map<String, DataTypeDefinition> allDataTypes) {
+        JsonElement propJsonElement = jsonObject.get(prop.getName());
+        if (propJsonElement != null) {
+            final String subPropValue = propJsonElement.toString();
+            final ComponentInstanceProperty subProperty = new ComponentInstanceProperty(prop, subPropValue, null);
+            final String validateSubPropValue =
+                serviceBusinessLogic.validatePropValueBeforeCreate(subProperty, subPropValue, true, allDataTypes);
+
+            if (StringUtils.isEmpty(validateSubPropValue) && StringUtils.isNotEmpty(subPropValue)) {
+                try {
+                    Object yamlValue = new Yaml().loadAs(subPropValue, Object.class);
+                    SubPropertyToscaFunction subPropertyToscaFunction = new SubPropertyToscaFunction();
+                    CustomYamlFunction toscaFunction = new CustomYamlFunction();
+                    toscaFunction.setYamlValue(yamlValue);
+                    subPropertyToscaFunction.setToscaFunction(toscaFunction);
+                    subPropertyToscaFunction.setSubPropertyPath(Collections.singletonList(prop.getName()));
+                    return Optional.of(subPropertyToscaFunction);
+                } catch (Exception exception) {
+                    log.info("Cannot create YAML value for {}", subPropValue);
+                }
+            }
+        }
+        return Optional.empty();
+    }
+
     protected ResponseFormat addInterfaceValuesToRi(
         UploadComponentInstanceInfo uploadComponentInstanceInfo,
         Component component,
@@ -1937,13 +2463,13 @@ public class ServiceImportBusinessLogic {
         Map<String, UploadInterfaceInfo> instanceInterfacesMap = uploadComponentInstanceInfo.getInterfaces();
         Map<String, InterfaceDefinition> currInterfacesMap = new HashMap<>();
         Map<String, InterfaceDefinition> interfacesFromNodeType = originResource.getInterfaces();
-        if ((MapUtils.isNotEmpty(instanceInterfacesMap)) && (MapUtils.isEmpty(interfacesFromNodeType))) {
+        if (interfacesFromNodeType == null) {
+            interfacesFromNodeType = new HashMap<>();
+        }
+        if (MapUtils.isEmpty(instanceInterfacesMap) && MapUtils.isEmpty(instanceInterfacesMap)) {
             log.debug("failed to find interfaces ");
             return componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT);
         }
-        if (interfacesFromNodeType == null || interfacesFromNodeType.isEmpty()) {
-            return componentsUtils.getResponseFormat(ActionStatus.OK);
-        }
         for (Map.Entry<String, InterfaceDefinition> entryInstances : interfacesFromNodeType.entrySet()) {
             String interfaceName = entryInstances.getKey().substring(entryInstances.getKey().lastIndexOf(".") + 1);
             if (!currInterfacesMap.containsKey(interfaceName)) {
@@ -1955,25 +2481,42 @@ public class ServiceImportBusinessLogic {
         if (MapUtils.isNotEmpty(instanceInterfacesMap)) {
             for (UploadInterfaceInfo uploadInterfaceInfo : instanceInterfacesMap.values()) {
                 String interfaceName = uploadInterfaceInfo.getName();
+                InterfaceDefinition currentInterfaceDef;
                 if (!currInterfacesMap.containsKey(interfaceName)) {
-                    log.debug("failed to find interface {} ", interfaceName);
-                    return componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT, interfaceName);
+                    currentInterfaceDef = getInterfaceDef(interfaceName, component.getModel());
+                    if (currentInterfaceDef == null) {
+                        log.debug("failed to find interface {} ", interfaceName);
+                        return componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT, interfaceName);
+                    }
+                } else {
+                    currentInterfaceDef = currInterfacesMap.get(interfaceName);
                 }
-                InterfaceDefinition currentInterfaceDef = currInterfacesMap.get(interfaceName);
                 Map<String, OperationDataDefinition> operationsToAdd = new HashMap<>();
 
                 Map<String, OperationDataDefinition> operations = uploadInterfaceInfo.getOperations();
                 for (Map.Entry<String, OperationDataDefinition> operation : operations.entrySet()) {
-                    OperationDataDefinition templateOperation = currentInterfaceDef.getOperationsMap().get(operation.getKey());
                     OperationDataDefinition instanceOperation = operation.getValue();
+                    OperationDataDefinition templateOperation = currentInterfaceDef.getOperationsMap()
+                        .getOrDefault(operation.getKey(), new Operation(instanceOperation));
                     //Inputs
                     ListDataDefinition<OperationInputDefinition> instanceInputs = instanceOperation.getInputs();
-                    mergeOperationInputDefinitions(templateOperation.getInputs(), instanceInputs);
-                    templateOperation.setInputs(instanceInputs);
+                    if (null != instanceInputs) {
+                        mergeOperationInputDefinitions(templateOperation.getInputs(), instanceInputs);
+                        component.getProperties()
+                            .forEach(property -> instanceInputs.getListToscaDataDefinition().stream()
+                                .filter(instanceInput ->
+                                    instanceInput.getToscaFunction() instanceof ToscaGetFunctionDataDefinition &&
+                                        property.getName().equals(instanceInput.getToscaFunction() != null ?
+                                            ((ToscaGetFunctionDataDefinition) instanceInput.getToscaFunction()).getPropertyName() : null))
+                                .forEach(oldInput -> oldInput.setType(property.getType()))
+                            );
+                        templateOperation.setInputs(instanceInputs);
+                    }
                     //Implementation
                     templateOperation.setImplementation(instanceOperation.getImplementation());
                     //Description
                     templateOperation.setDescription(instanceOperation.getDescription());
+                    templateOperation.setMilestones(instanceOperation.getMilestones());
                     operationsToAdd.put(operation.getKey(), templateOperation);
                 }
                 InterfaceDefinition interfaceDef = new InterfaceDefinition();
@@ -1982,7 +2525,7 @@ public class ServiceImportBusinessLogic {
                 interfaceDef.setUniqueId(currentInterfaceDef.getType());
                 interfaceDef.setDescription(uploadInterfaceInfo.getDescription());
                 interfaceDef.setOperations(operationsToAdd);
-                instInterfacesMap.put(interfaceName, interfaceDef);
+                instInterfacesMap.put(currentInterfaceDef.getType(), interfaceDef);
                 currInterfacesMap.remove(interfaceName);
             }
         }
@@ -1995,8 +2538,27 @@ public class ServiceImportBusinessLogic {
         return componentsUtils.getResponseFormat(ActionStatus.OK);
     }
 
+    private InterfaceDefinition getInterfaceDef(String interfaceName, String model) {
+        Either<Map<String, InterfaceDefinition>, StorageOperationStatus> interfaceLifecycleTypesEither =
+            interfaceLifecycleTypeOperation.getAllInterfaceLifecycleTypes(model);
+        if (interfaceLifecycleTypesEither.isRight()) {
+            return null;
+        }
+        Map<String, InterfaceDefinition> interfaceLifecycleTypes = interfaceLifecycleTypesEither.left().value();
+        Optional<InterfaceDefinition> interfaceType =
+            interfaceLifecycleTypes.values().stream().filter(interfaceDef -> interfaceDef.getUniqueId().contains(interfaceName)).findFirst();
+        if (interfaceType.isEmpty()) {
+            return null;
+        }
+        return interfaceType.get();
+    }
+
     private void mergeOperationInputDefinitions(ListDataDefinition<OperationInputDefinition> inputsFromNodeType,
                                                 ListDataDefinition<OperationInputDefinition> instanceInputs) {
+        if (inputsFromNodeType == null || CollectionUtils.isEmpty(inputsFromNodeType.getListToscaDataDefinition()) || instanceInputs == null
+            || CollectionUtils.isEmpty(instanceInputs.getListToscaDataDefinition())) {
+            return;
+        }
         instanceInputs.getListToscaDataDefinition().forEach(
             instanceInput -> inputsFromNodeType.getListToscaDataDefinition().stream().filter(
                 templateInput -> templateInput.getName().equals(instanceInput.getName())
@@ -2347,7 +2909,8 @@ public class ServiceImportBusinessLogic {
             if (nodeNamespaceMap.containsKey(uploadComponentInstanceInfo.getType())) {
                 uploadComponentInstanceInfo.setType(nodeNamespaceMap.get(uploadComponentInstanceInfo.getType()).getToscaResourceName());
             }
-            Resource refResource = validateResourceInstanceBeforeCreate(yamlName, uploadComponentInstanceInfo, existingnodeTypeMap);
+            Resource refResource =
+                validateResourceInstanceBeforeCreate(yamlName, component.getModel(), uploadComponentInstanceInfo, existingnodeTypeMap);
             ComponentInstance componentInstance = new ComponentInstance();
             componentInstance.setComponentUid(refResource.getUniqueId());
             Collection<String> directives = uploadComponentInstanceInfo.getDirectives();
@@ -2378,27 +2941,32 @@ public class ServiceImportBusinessLogic {
             Resource origResource = existingnodeTypeMap.get(uploadComponentInstanceInfo.getType());
             componentInstance.setName(uploadComponentInstanceInfo.getName());
             componentInstance.setIcon(origResource.getIcon());
+            componentInstance.setMinOccurrences(uploadComponentInstanceInfo.getMinOccurrences());
+            componentInstance.setMaxOccurrences(uploadComponentInstanceInfo.getMaxOccurrences());
+            componentInstance.setInstanceCount(uploadComponentInstanceInfo.getInstanceCount());
             resourcesInstancesMap.put(componentInstance, origResource);
-        } catch (Exception e) {
+        } catch (final ComponentException e) {
+            throw e;
+        } catch (final Exception e) {
             throw new ComponentException(ActionStatus.GENERAL_ERROR, e.getMessage());
         }
     }
 
-    protected Resource validateResourceInstanceBeforeCreate(String yamlName, UploadComponentInstanceInfo uploadComponentInstanceInfo,
+    protected Resource validateResourceInstanceBeforeCreate(String yamlName, String model, UploadComponentInstanceInfo uploadComponentInstanceInfo,
                                                             Map<String, Resource> nodeNamespaceMap) {
         Resource refResource;
         try {
             if (nodeNamespaceMap.containsKey(uploadComponentInstanceInfo.getType())) {
                 refResource = nodeNamespaceMap.get(uploadComponentInstanceInfo.getType());
             } else {
-                Either<Resource, StorageOperationStatus> findResourceEither = toscaOperationFacade
-                    .getLatestResourceByToscaResourceName(uploadComponentInstanceInfo.getType());
-                if (findResourceEither.isRight()) {
+                final Either<Component, StorageOperationStatus> resourceEither =
+                    toscaOperationFacade.getLatestByToscaResourceName(uploadComponentInstanceInfo.getType(), model);
+                if (resourceEither.isRight()) {
                     ResponseFormat responseFormat = componentsUtils
-                        .getResponseFormat(componentsUtils.convertFromStorageResponse(findResourceEither.right().value()));
+                        .getResponseFormat(componentsUtils.convertFromStorageResponse(resourceEither.right().value()));
                     throw new ComponentException(responseFormat);
                 }
-                refResource = findResourceEither.left().value();
+                refResource = (Resource) resourceEither.left().value();
                 nodeNamespaceMap.put(refResource.getToscaResourceName(), refResource);
             }
             String componentState = refResource.getComponentMetadataDefinition().getMetadataDataDefinition().getState();
@@ -2416,7 +2984,9 @@ public class ServiceImportBusinessLogic {
                 throw new ComponentException(responseFormat);
             }
             return refResource;
-        } catch (Exception e) {
+        } catch (final ComponentException e) {
+            throw e;
+        } catch (final Exception e) {
             throw new ComponentException(ActionStatus.GENERAL_ERROR, e.getMessage());
         }
     }