Implement 'Update Service by importing Tosca Template'-story
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / tosca / ToscaExportHandler.java
index 1f0270f..fa7d2a0 100644 (file)
  * limitations under the License.
  * ============LICENSE_END=========================================================
  */
  * limitations under the License.
  * ============LICENSE_END=========================================================
  */
-
 package org.openecomp.sdc.be.tosca;
 
 import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
 import static org.apache.commons.collections.MapUtils.isNotEmpty;
 import static org.openecomp.sdc.be.components.utils.PropertiesUtils.resolvePropertyValueFromInput;
 package org.openecomp.sdc.be.tosca;
 
 import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
 import static org.apache.commons.collections.MapUtils.isNotEmpty;
 import static org.openecomp.sdc.be.components.utils.PropertiesUtils.resolvePropertyValueFromInput;
-import static org.openecomp.sdc.be.tosca.InterfacesOperationsConverter.addInterfaceTypeElement;
 import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_ATTRIBUTE;
 import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_INPUT;
 import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_PROPERTY;
 
 import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_ATTRIBUTE;
 import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_INPUT;
 import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_PROPERTY;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.primitives.Ints;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.google.gson.stream.JsonReader;
 import fj.data.Either;
 import fj.data.Either;
+
+import java.io.StringReader;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
@@ -45,29 +53,36 @@ import java.util.Optional;
 import java.util.Set;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
 import java.util.Set;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
-import lombok.NoArgsConstructor;
+
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.commons.lang3.tuple.ImmutableTriple;
 import org.apache.commons.lang3.tuple.Triple;
 import org.onap.sdc.tosca.services.YamlUtil;
 import org.openecomp.sdc.be.components.impl.exceptions.SdcResourceNotFoundException;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.commons.lang3.tuple.ImmutableTriple;
 import org.apache.commons.lang3.tuple.Triple;
 import org.onap.sdc.tosca.services.YamlUtil;
 import org.openecomp.sdc.be.components.impl.exceptions.SdcResourceNotFoundException;
+import org.openecomp.sdc.be.config.CategoryBaseTypeConfig;
+import org.openecomp.sdc.be.config.Configuration;
 import org.openecomp.sdc.be.config.ConfigurationManager;
 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
 import org.openecomp.sdc.be.config.ConfigurationManager;
 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
+import org.openecomp.sdc.be.data.model.ToscaImportByModel;
 import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
 import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.PropertyFilterConstraintDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.PropertyFilterDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterPropertyDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterPropertyDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.ToscaArtifactDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.ToscaArtifactDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.ToscaFunction;
 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
+import org.openecomp.sdc.be.datatypes.enums.ConstraintType;
 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
@@ -78,6 +93,7 @@ import org.openecomp.sdc.be.model.CapabilityDefinition;
 import org.openecomp.sdc.be.model.CapabilityRequirementRelationship;
 import org.openecomp.sdc.be.model.Component;
 import org.openecomp.sdc.be.model.ComponentInstance;
 import org.openecomp.sdc.be.model.CapabilityRequirementRelationship;
 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.ComponentInstanceInterface;
 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
 import org.openecomp.sdc.be.model.ComponentInstanceInput;
 import org.openecomp.sdc.be.model.ComponentInstanceInterface;
 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
@@ -98,6 +114,9 @@ import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade
 import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
 import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
+import org.openecomp.sdc.be.model.operations.impl.ModelOperation;
+import org.openecomp.sdc.be.model.tosca.ToscaType;
+import org.openecomp.sdc.be.model.tosca.converters.ToscaMapValueConverter;
 import org.openecomp.sdc.be.tosca.PropertyConvertor.PropertyType;
 import org.openecomp.sdc.be.tosca.builder.ToscaRelationshipBuilder;
 import org.openecomp.sdc.be.tosca.exception.ToscaConversionException;
 import org.openecomp.sdc.be.tosca.PropertyConvertor.PropertyType;
 import org.openecomp.sdc.be.tosca.builder.ToscaRelationshipBuilder;
 import org.openecomp.sdc.be.tosca.exception.ToscaConversionException;
@@ -113,6 +132,7 @@ import org.openecomp.sdc.be.tosca.model.ToscaNodeType;
 import org.openecomp.sdc.be.tosca.model.ToscaPolicyTemplate;
 import org.openecomp.sdc.be.tosca.model.ToscaProperty;
 import org.openecomp.sdc.be.tosca.model.ToscaPropertyAssignment;
 import org.openecomp.sdc.be.tosca.model.ToscaPolicyTemplate;
 import org.openecomp.sdc.be.tosca.model.ToscaProperty;
 import org.openecomp.sdc.be.tosca.model.ToscaPropertyAssignment;
+import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraint;
 import org.openecomp.sdc.be.tosca.model.ToscaRelationshipTemplate;
 import org.openecomp.sdc.be.tosca.model.ToscaRequirement;
 import org.openecomp.sdc.be.tosca.model.ToscaTemplate;
 import org.openecomp.sdc.be.tosca.model.ToscaRelationshipTemplate;
 import org.openecomp.sdc.be.tosca.model.ToscaRequirement;
 import org.openecomp.sdc.be.tosca.model.ToscaTemplate;
@@ -124,6 +144,7 @@ import org.openecomp.sdc.be.tosca.utils.InputConverter;
 import org.openecomp.sdc.be.tosca.utils.OutputConverter;
 import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
 import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.openecomp.sdc.be.tosca.utils.OutputConverter;
 import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
 import org.openecomp.sdc.common.log.wrappers.Logger;
+import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.yaml.snakeyaml.DumperOptions;
 import org.yaml.snakeyaml.DumperOptions.FlowStyle;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.yaml.snakeyaml.DumperOptions;
 import org.yaml.snakeyaml.DumperOptions.FlowStyle;
@@ -138,114 +159,140 @@ import org.yaml.snakeyaml.nodes.Tag;
 import org.yaml.snakeyaml.representer.Represent;
 import org.yaml.snakeyaml.representer.Representer;
 
 import org.yaml.snakeyaml.representer.Represent;
 import org.yaml.snakeyaml.representer.Representer;
 
-@NoArgsConstructor
 @org.springframework.stereotype.Component("tosca-export-handler")
 public class ToscaExportHandler {
 
 @org.springframework.stereotype.Component("tosca-export-handler")
 public class ToscaExportHandler {
 
+    public static final String ASSET_TOSCA_TEMPLATE = "assettoscatemplate";
     private static final Logger log = Logger.getLogger(ToscaExportHandler.class);
     private static final Logger log = Logger.getLogger(ToscaExportHandler.class);
-
-    private ApplicationDataTypeCache dataTypeCache;
-    private ToscaOperationFacade toscaOperationFacade;
-    private CapabilityRequirementConverter capabilityRequirementConverter;
-    private PolicyExportParser policyExportParser;
-    private GroupExportParser groupExportParser;
-    private PropertyConvertor propertyConvertor;
-    private InputConverter inputConverter;
-    private OutputConverter outputConverter;
-    private InterfaceLifecycleOperation interfaceLifecycleOperation;
-    private InterfacesOperationsConverter interfacesOperationsConverter;
+    private static final String INVARIANT_UUID = "invariantUUID";
+    private static final String TOSCA_VERSION = "tosca_simple_yaml_1_3";
+    private static final String SERVICE_NODE_TYPE_PREFIX = "org.openecomp.service.";
+    private static final String IMPORTS_FILE_KEY = "file";
+    private static final String TOSCA_INTERFACE_NAME = "-interface.yml";
+    private static final String FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION = "convertToToscaTemplate - failed to get Default Imports section from configuration";
+    private static final String NOT_SUPPORTED_COMPONENT_TYPE = "Not supported component type {}";
+    private static final String NATIVE_ROOT = "tosca.nodes.Root";
+    private static final List<String> EXCLUDED_CATEGORY_SPECIFIC_METADATA = List
+            .of("Service Function", "Service Role", "Naming Policy", "Service Type");
+    private static final YamlUtil yamlUtil = new YamlUtil();
+    private final ApplicationDataTypeCache applicationDataTypeCache;
+    private final ToscaOperationFacade toscaOperationFacade;
+    private final CapabilityRequirementConverter capabilityRequirementConverter;
+    private final PolicyExportParser policyExportParser;
+    private final GroupExportParser groupExportParser;
+    private final PropertyConvertor propertyConvertor;
+    private final AttributeConverter attributeConverter;
+    private final InputConverter inputConverter;
+    private final OutputConverter outputConverter;
+    private final InterfaceLifecycleOperation interfaceLifecycleOperation;
+    private final InterfacesOperationsConverter interfacesOperationsConverter;
+    private final ModelOperation modelOperation;
 
     @Autowired
 
     @Autowired
-    public ToscaExportHandler(final ApplicationDataTypeCache dataTypeCache,
+    public ToscaExportHandler(final ApplicationDataTypeCache applicationDataTypeCache,
                               final ToscaOperationFacade toscaOperationFacade,
                               final CapabilityRequirementConverter capabilityRequirementConverter,
                               final PolicyExportParser policyExportParser,
                               final GroupExportParser groupExportParser,
                               final PropertyConvertor propertyConvertor,
                               final ToscaOperationFacade toscaOperationFacade,
                               final CapabilityRequirementConverter capabilityRequirementConverter,
                               final PolicyExportParser policyExportParser,
                               final GroupExportParser groupExportParser,
                               final PropertyConvertor propertyConvertor,
+                              final AttributeConverter attributeConverter,
                               final InputConverter inputConverter,
                               final OutputConverter outputConverter,
                               final InterfaceLifecycleOperation interfaceLifecycleOperation,
                               final InputConverter inputConverter,
                               final OutputConverter outputConverter,
                               final InterfaceLifecycleOperation interfaceLifecycleOperation,
-                              final InterfacesOperationsConverter interfacesOperationsConverter) {
-        this.dataTypeCache = dataTypeCache;
+                              final InterfacesOperationsConverter interfacesOperationsConverter,
+                              final ModelOperation modelOperation) {
+        this.applicationDataTypeCache = applicationDataTypeCache;
         this.toscaOperationFacade = toscaOperationFacade;
         this.capabilityRequirementConverter = capabilityRequirementConverter;
         this.policyExportParser = policyExportParser;
         this.groupExportParser = groupExportParser;
         this.propertyConvertor = propertyConvertor;
         this.toscaOperationFacade = toscaOperationFacade;
         this.capabilityRequirementConverter = capabilityRequirementConverter;
         this.policyExportParser = policyExportParser;
         this.groupExportParser = groupExportParser;
         this.propertyConvertor = propertyConvertor;
+        this.attributeConverter = attributeConverter;
         this.inputConverter = inputConverter;
         this.outputConverter = outputConverter;
         this.interfaceLifecycleOperation = interfaceLifecycleOperation;
         this.interfacesOperationsConverter = interfacesOperationsConverter;
         this.inputConverter = inputConverter;
         this.outputConverter = outputConverter;
         this.interfaceLifecycleOperation = interfaceLifecycleOperation;
         this.interfacesOperationsConverter = interfacesOperationsConverter;
+        this.modelOperation = modelOperation;
     }
 
     }
 
-    private static final String TOSCA_VERSION = "tosca_simple_yaml_1_3";
-    private static final String SERVICE_NODE_TYPE_PREFIX = "org.openecomp.service.";
-    private static final String IMPORTS_FILE_KEY = "file";
-    private static final String TOSCA_INTERFACE_NAME = "-interface.yml";
-    public static final String ASSET_TOSCA_TEMPLATE = "assettoscatemplate";
-    private static final String FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION = "convertToToscaTemplate - failed to get Default Imports section from configuration";
-    private static final String NOT_SUPPORTED_COMPONENT_TYPE = "Not supported component type {}";
-    private static final String NATIVE_ROOT = "tosca.nodes.Root";
-    private static final YamlUtil yamlUtil = new YamlUtil();
+    public static String getInterfaceFilename(String artifactName) {
+        return artifactName.substring(0, artifactName.lastIndexOf('.')) + TOSCA_INTERFACE_NAME;
+    }
+
+    private static void removeOperationImplementationForProxyNodeType(Map<String, InterfaceDefinition> proxyComponentInterfaces) {
+        if (MapUtils.isEmpty(proxyComponentInterfaces)) {
+            return;
+        }
+        proxyComponentInterfaces.values().stream().map(InterfaceDataDefinition::getOperations).filter(MapUtils::isNotEmpty)
+                .forEach(operations -> operations.values().forEach(operation -> operation.setImplementation(null)));
+    }
 
     public Either<ToscaRepresentation, ToscaError> exportComponent(Component component) {
         return convertToToscaTemplate(component).left().map(this::createToscaRepresentation);
     }
 
 
     public Either<ToscaRepresentation, ToscaError> exportComponent(Component component) {
         return convertToToscaTemplate(component).left().map(this::createToscaRepresentation);
     }
 
-    public Either<ToscaRepresentation, ToscaError> exportComponentInterface(final Component component,
-                                                                            final boolean isAssociatedComponent) {
-        final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImportConfig();
-        if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
+    public Either<ToscaRepresentation, ToscaError> exportDataType(DataTypeDefinition dataTypeDefinition) {
+        return convertDataTypeToToscaTemplate(dataTypeDefinition).left().map(this::createToscaRepresentation);
+    }
+
+    public Either<ToscaRepresentation, ToscaError> exportComponentInterface(final Component component, final boolean isAssociatedComponent) {
+        final List<Map<String, Map<String, String>>> imports = new ArrayList<>(getDefaultToscaImports(component.getModel()));
+        if (CollectionUtils.isEmpty(imports)) {
             log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
             return Either.right(ToscaError.GENERAL_ERROR);
         }
             log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
             return Either.right(ToscaError.GENERAL_ERROR);
         }
+        List<Triple<String, String, Component>> dependencies = new ArrayList<>();
+        if (component.getDerivedFromGenericType() != null && !component.getDerivedFromGenericType()
+                .startsWith("org.openecomp.resource.abstract.nodes.")) {
+            final Either<Component, StorageOperationStatus> baseType = toscaOperationFacade
+                    .getByToscaResourceNameAndVersion(component.getDerivedFromGenericType(), component.getDerivedFromGenericVersion(),
+                            component.getModel());
+            if (baseType.isLeft() && baseType.left().value() != null) {
+                addDependencies(imports, dependencies, baseType.left().value());
+            } else {
+                log.debug("Failed to fetch derived from type {}", component.getDerivedFromGenericType());
+            }
+        }
 
         String toscaVersion = null;
         if (component instanceof Resource) {
             toscaVersion = ((Resource) component).getToscaVersion();
         }
         ToscaTemplate toscaTemplate = new ToscaTemplate(toscaVersion != null ? toscaVersion : TOSCA_VERSION);
 
         String toscaVersion = null;
         if (component instanceof Resource) {
             toscaVersion = ((Resource) component).getToscaVersion();
         }
         ToscaTemplate toscaTemplate = new ToscaTemplate(toscaVersion != null ? toscaVersion : TOSCA_VERSION);
-        toscaTemplate.setImports(new ArrayList<>(defaultToscaImportConfig));
+        toscaTemplate.setImports(imports);
         final Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
         final Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
-        final Either<ToscaTemplate, ToscaError> toscaTemplateRes =
-            convertInterfaceNodeType(new HashMap<>(), component, toscaTemplate, nodeTypes, isAssociatedComponent);
+        final Either<ToscaTemplate, ToscaError> toscaTemplateRes = convertInterfaceNodeType(new HashMap<>(), component, toscaTemplate, nodeTypes,
+                isAssociatedComponent);
         if (toscaTemplateRes.isRight()) {
             return Either.right(toscaTemplateRes.right().value());
         }
         if (toscaTemplateRes.isRight()) {
             return Either.right(toscaTemplateRes.right().value());
         }
-
         toscaTemplate = toscaTemplateRes.left().value();
         toscaTemplate = toscaTemplateRes.left().value();
+        toscaTemplate.setDependencies(dependencies);
         ToscaRepresentation toscaRepresentation = this.createToscaRepresentation(toscaTemplate);
         return Either.left(toscaRepresentation);
     }
 
         ToscaRepresentation toscaRepresentation = this.createToscaRepresentation(toscaTemplate);
         return Either.left(toscaRepresentation);
     }
 
-    public ToscaRepresentation createToscaRepresentation(ToscaTemplate toscaTemplate) {
+    private ToscaRepresentation createToscaRepresentation(ToscaTemplate toscaTemplate) {
         CustomRepresenter representer = new CustomRepresenter();
         DumperOptions options = new DumperOptions();
         options.setAllowReadOnlyProperties(false);
         options.setPrettyFlow(true);
         CustomRepresenter representer = new CustomRepresenter();
         DumperOptions options = new DumperOptions();
         options.setAllowReadOnlyProperties(false);
         options.setPrettyFlow(true);
-
         options.setDefaultFlowStyle(FlowStyle.FLOW);
         options.setCanonical(false);
         options.setDefaultFlowStyle(FlowStyle.FLOW);
         options.setCanonical(false);
-
         representer.addClassTag(toscaTemplate.getClass(), Tag.MAP);
         representer.addClassTag(toscaTemplate.getClass(), Tag.MAP);
-
         representer.setPropertyUtils(new UnsortedPropertyUtils());
         representer.setPropertyUtils(new UnsortedPropertyUtils());
-        Yaml yaml = new Yaml(representer, options);
 
 
+        Yaml yaml = new Yaml(representer, options);
         String yamlAsString = yaml.dumpAsMap(toscaTemplate);
         String yamlAsString = yaml.dumpAsMap(toscaTemplate);
-
-        StringBuilder sb = new StringBuilder();
-        sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactHeader());
-        sb.append(yamlAsString);
-        sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactFooter());
-
-        return ToscaRepresentation.make(sb.toString().getBytes(), toscaTemplate);
+        String sb = getConfiguration().getHeatEnvArtifactHeader()
+                + yamlAsString
+                + getConfiguration().getHeatEnvArtifactFooter();
+        return ToscaRepresentation.make(sb.getBytes(), toscaTemplate);
     }
 
     public Either<ToscaTemplate, ToscaError> getDependencies(Component component) {
         ToscaTemplate toscaTemplate = new ToscaTemplate(null);
     }
 
     public Either<ToscaTemplate, ToscaError> getDependencies(Component component) {
         ToscaTemplate toscaTemplate = new ToscaTemplate(null);
-        Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports = fillImports(component,
-            toscaTemplate);
+        Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports = fillImports(component, toscaTemplate);
         if (fillImports.isRight()) {
             return Either.right(fillImports.right().value());
         }
         if (fillImports.isRight()) {
             return Either.right(fillImports.right().value());
         }
@@ -253,7 +300,7 @@ public class ToscaExportHandler {
     }
 
     public Either<ToscaTemplate, ToscaError> convertToToscaTemplate(final Component component) {
     }
 
     public Either<ToscaTemplate, ToscaError> convertToToscaTemplate(final Component component) {
-        final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImportConfig();
+        final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImports(component.getModel());
         if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
             log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
             return Either.right(ToscaError.GENERAL_ERROR);
         if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
             log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
             return Either.right(ToscaError.GENERAL_ERROR);
@@ -274,44 +321,89 @@ public class ToscaExportHandler {
             log.trace("convert component as topology template");
             return convertToscaTemplate(component, toscaTemplate);
         }
             log.trace("convert component as topology template");
             return convertToscaTemplate(component, toscaTemplate);
         }
+    }
 
 
+    private Either<ToscaTemplate, ToscaError> convertDataTypeToToscaTemplate(final DataTypeDefinition dataTypeDefinition) {
+        final ToscaTemplate toscaTemplate = new ToscaTemplate(TOSCA_VERSION);
+        return convertDataTypeTosca(dataTypeDefinition, toscaTemplate);
     }
 
     }
 
-    private Either<ToscaTemplate, ToscaError> convertToscaTemplate(Component component, ToscaTemplate toscaNode) {
+    private Either<ToscaTemplate, ToscaError> convertDataTypeTosca(final DataTypeDefinition dataTypeDefinition, final ToscaTemplate toscaTemplate) {
+        final var dataTypesEither = applicationDataTypeCache.getAll(dataTypeDefinition.getModel());
+        if (dataTypesEither.isRight()) {
+            log.debug("Failed to fetch all data types :", dataTypesEither.right().value());
+            return Either.right(ToscaError.GENERAL_ERROR);
+        }
+        Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
+        if (!dataTypeDefinition.isEmpty()) {
+            Map<String, ToscaDataType> toscaDataTypeMap = new HashMap<>();
+            ToscaDataType toscaDataType = new ToscaDataType();
+            toscaDataType.setDerived_from(dataTypeDefinition.getDerivedFromName());
+            toscaDataType.setDescription(dataTypeDefinition.getDescription());
+            toscaDataType.setVersion(dataTypeDefinition.getVersion());
+            if (CollectionUtils.isNotEmpty(dataTypeDefinition.getProperties())) {
+                toscaDataType.setProperties(dataTypeDefinition.getProperties().stream()
+                        .collect(Collectors.toMap(
+                                PropertyDataDefinition::getName,
+                                s -> propertyConvertor.convertProperty(dataTypes, s, PropertyType.PROPERTY),
+                                (toscaPropertyTobeValidated, toscaProperty) -> validateToscaProperty((List<DataTypeDefinition>) dataTypeDefinition,
+                                        toscaPropertyTobeValidated,
+                                        toscaProperty)
+                        )));
+            }
+            toscaDataTypeMap.put(dataTypeDefinition.getName(), toscaDataType);
+            toscaTemplate.setData_types(toscaDataTypeMap);
+        }
+        return Either.left(toscaTemplate);
+    }
+
+    private List<Map<String, Map<String, String>>> getDefaultToscaImports(final String modelId) {
+        if (modelId == null) {
+            return getDefaultToscaImportConfig();
+        }
+
+        final List<ToscaImportByModel> allModelImports = modelOperation.findAllModelImports(modelId, true);
+        final List<Map<String, Map<String, String>>> importList = new ArrayList<>();
+        final Set<Path> addedPathList = new HashSet<>();
+        for (final ToscaImportByModel toscaImportByModel : allModelImports) {
+            var importPath = Path.of(toscaImportByModel.getFullPath());
+            if (addedPathList.contains(importPath)) {
+                importPath = ToscaDefaultImportHelper.addModelAsFilePrefix(importPath, toscaImportByModel.getModelId());
+            }
+            final String fileName = FilenameUtils.getBaseName(importPath.toString());
+            importList.add(Map.of(fileName, Map.of("file", importPath.toString())));
+            addedPathList.add(importPath);
+        }
+        return importList;
+    }
 
 
-        Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> importsRes = fillImports(component,
-            toscaNode);
+    private Either<ToscaTemplate, ToscaError> convertToscaTemplate(Component component, ToscaTemplate toscaNode) {
+        Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> importsRes = fillImports(component, toscaNode);
         if (importsRes.isRight()) {
             return Either.right(importsRes.right().value());
         }
         toscaNode = importsRes.left().value().left;
         Map<String, Component> componentCache = importsRes.left().value().right;
         if (importsRes.isRight()) {
             return Either.right(importsRes.right().value());
         }
         toscaNode = importsRes.left().value().left;
         Map<String, Component> componentCache = importsRes.left().value().right;
-        Either<Map<String, ToscaNodeType>, ToscaError> nodeTypesMapEither = createProxyNodeTypes(componentCache,
-            component);
+        Either<Map<String, ToscaNodeType>, ToscaError> nodeTypesMapEither = createProxyNodeTypes(componentCache, component);
         if (nodeTypesMapEither.isRight()) {
         if (nodeTypesMapEither.isRight()) {
-            log.debug("Failed to fetch normative service proxy resource by tosca name, error {}",
-                nodeTypesMapEither.right().value());
+            log.debug("Failed to fetch normative service proxy resource by tosca name, error {}", nodeTypesMapEither.right().value());
             return Either.right(nodeTypesMapEither.right().value());
         }
         Map<String, ToscaNodeType> nodeTypesMap = nodeTypesMapEither.left().value();
         if (nodeTypesMap != null && !nodeTypesMap.isEmpty()) {
             toscaNode.setNode_types(nodeTypesMap);
         }
             return Either.right(nodeTypesMapEither.right().value());
         }
         Map<String, ToscaNodeType> nodeTypesMap = nodeTypesMapEither.left().value();
         if (nodeTypesMap != null && !nodeTypesMap.isEmpty()) {
             toscaNode.setNode_types(nodeTypesMap);
         }
-
         createServiceSubstitutionNodeTypes(componentCache, component, toscaNode);
         createServiceSubstitutionNodeTypes(componentCache, component, toscaNode);
-
         Either<Map<String, Object>, ToscaError> proxyInterfaceTypesEither = createProxyInterfaceTypes(component);
         if (proxyInterfaceTypesEither.isRight()) {
         Either<Map<String, Object>, ToscaError> proxyInterfaceTypesEither = createProxyInterfaceTypes(component);
         if (proxyInterfaceTypesEither.isRight()) {
-            log.debug("Failed to populate service proxy local interface types in tosca, error {}",
-                nodeTypesMapEither.right().value());
+            log.debug("Failed to populate service proxy local interface types in tosca, error {}", nodeTypesMapEither.right().value());
             return Either.right(proxyInterfaceTypesEither.right().value());
         }
         Map<String, Object> proxyInterfaceTypes = proxyInterfaceTypesEither.left().value();
         if (MapUtils.isNotEmpty(proxyInterfaceTypes)) {
             toscaNode.setInterface_types(proxyInterfaceTypes);
         }
             return Either.right(proxyInterfaceTypesEither.right().value());
         }
         Map<String, Object> proxyInterfaceTypes = proxyInterfaceTypesEither.left().value();
         if (MapUtils.isNotEmpty(proxyInterfaceTypes)) {
             toscaNode.setInterface_types(proxyInterfaceTypes);
         }
-
-        Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = dataTypeCache.getAll();
+        Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = applicationDataTypeCache.getAll(component.getModel());
         if (dataTypesEither.isRight()) {
             log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
             return Either.right(ToscaError.GENERAL_ERROR);
         if (dataTypesEither.isRight()) {
             log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
             return Either.right(ToscaError.GENERAL_ERROR);
@@ -320,106 +412,135 @@ public class ToscaExportHandler {
         ToscaTopolgyTemplate topologyTemplate = new ToscaTopolgyTemplate();
         List<InputDefinition> inputDef = component.getInputs();
         Map<String, ToscaProperty> inputs = inputConverter.convertInputs(inputDef, dataTypes);
         ToscaTopolgyTemplate topologyTemplate = new ToscaTopolgyTemplate();
         List<InputDefinition> inputDef = component.getInputs();
         Map<String, ToscaProperty> inputs = inputConverter.convertInputs(inputDef, dataTypes);
-
         if (!inputs.isEmpty()) {
             topologyTemplate.setInputs(inputs);
         }
         if (!inputs.isEmpty()) {
             topologyTemplate.setInputs(inputs);
         }
-
         final Map<String, ToscaProperty> outputs;
         try {
             outputs = outputConverter.convert(component.getOutputs(), dataTypes);
         } catch (final ToscaConversionException e) {
             log.error(EcompLoggerErrorCode.SCHEMA_ERROR, ToscaExportHandler.class.getName(),
         final Map<String, ToscaProperty> outputs;
         try {
             outputs = outputConverter.convert(component.getOutputs(), dataTypes);
         } catch (final ToscaConversionException e) {
             log.error(EcompLoggerErrorCode.SCHEMA_ERROR, ToscaExportHandler.class.getName(),
-                "Could not parse component '{}' outputs. Component unique id '{}'.",
-                new Object[]{component.getName(), component.getUniqueId(), e});
+                    "Could not parse component '{}' outputs. Component unique id '{}'.", component.getName(), component.getUniqueId(), e);
             return Either.right(ToscaError.GENERAL_ERROR);
         }
         if (!outputs.isEmpty()) {
             topologyTemplate.setOutputs(outputs);
         }
             return Either.right(ToscaError.GENERAL_ERROR);
         }
         if (!outputs.isEmpty()) {
             topologyTemplate.setOutputs(outputs);
         }
-
-        final List<ComponentInstance> componentInstances = component.getComponentInstances();
-        Map<String, List<ComponentInstanceProperty>> componentInstancesProperties = component.getComponentInstancesProperties();
-        Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces = component.getComponentInstancesInterfaces();
-        if (CollectionUtils.isNotEmpty(componentInstances)) {
-            final Either<Map<String, ToscaNodeTemplate>, ToscaError> nodeTemplates = convertNodeTemplates(component, componentInstances,
-                componentInstancesProperties, componentInstanceInterfaces, componentCache, dataTypes, topologyTemplate);
+        if (CollectionUtils.isNotEmpty(component.getComponentInstances())) {
+            final Either<Map<String, ToscaNodeTemplate>, ToscaError> nodeTemplates =
+                    convertNodeTemplates(component, componentCache, dataTypes, topologyTemplate);
             if (nodeTemplates.isRight()) {
                 return Either.right(nodeTemplates.right().value());
             }
             log.debug("node templates converted");
             topologyTemplate.setNode_templates(nodeTemplates.left().value());
         }
             if (nodeTemplates.isRight()) {
                 return Either.right(nodeTemplates.right().value());
             }
             log.debug("node templates converted");
             topologyTemplate.setNode_templates(nodeTemplates.left().value());
         }
-        final Map<String, ToscaRelationshipTemplate> relationshipTemplatesMap =
-            new ToscaExportRelationshipTemplatesHandler().createFrom(topologyTemplate.getNode_templates());
+        final Map<String, ToscaRelationshipTemplate> relationshipTemplatesMap = new ToscaExportRelationshipTemplatesHandler()
+                .createFrom(topologyTemplate.getNode_templates());
         if (!relationshipTemplatesMap.isEmpty()) {
             topologyTemplate.setRelationshipTemplates(relationshipTemplatesMap);
         }
         if (!relationshipTemplatesMap.isEmpty()) {
             topologyTemplate.setRelationshipTemplates(relationshipTemplatesMap);
         }
-
-        SubstitutionMapping substitutionMapping = new SubstitutionMapping();
-        convertSubstitutionMappingFilter(component, substitutionMapping);
-
         addGroupsToTopologyTemplate(component, topologyTemplate);
         addGroupsToTopologyTemplate(component, topologyTemplate);
-
         try {
             addPoliciesToTopologyTemplate(component, topologyTemplate);
         } catch (SdcResourceNotFoundException e) {
             log.debug("Fail to add policies to topology template:", e);
             return Either.right(ToscaError.GENERAL_ERROR);
         }
         try {
             addPoliciesToTopologyTemplate(component, topologyTemplate);
         } catch (SdcResourceNotFoundException e) {
             log.debug("Fail to add policies to topology template:", e);
             return Either.right(ToscaError.GENERAL_ERROR);
         }
+        try {
+            createSubstitutionMapping(component, componentCache).ifPresent(topologyTemplate::setSubstitution_mappings);
+        } catch (final ToscaExportException e) {
+            log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, ToscaExportHandler.class.getName(), e.getMessage());
+            return Either.right(e.getToscaError());
+        }
+        if (!topologyTemplate.isEmpty()) {
+            toscaNode.setTopology_template(topologyTemplate);
+        }
+        return Either.left(toscaNode);
+    }
 
 
-        String toscaResourceName;
+    private Either<String, ToscaError> createComponentToscaName(final Component component) {
         switch (component.getComponentType()) {
             case RESOURCE:
         switch (component.getComponentType()) {
             case RESOURCE:
-                toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition()
-                    .getMetadataDataDefinition()).getToscaResourceName();
-                break;
+                final ResourceMetadataDataDefinition resourceMetadata =
+                        (ResourceMetadataDataDefinition) component.getComponentMetadataDefinition().getMetadataDataDefinition();
+                return Either.left(resourceMetadata.getToscaResourceName());
             case SERVICE:
             case SERVICE:
-                toscaResourceName = SERVICE_NODE_TYPE_PREFIX
-                    + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName();
-                break;
+                return Either.left(SERVICE_NODE_TYPE_PREFIX + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName());
             default:
                 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
                 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
         }
             default:
                 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
                 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
         }
-        substitutionMapping.setNode_type(toscaResourceName);
-        Either<SubstitutionMapping, ToscaError> capabilities = convertCapabilities(component, substitutionMapping,
-            componentCache);
-        if (capabilities.isRight()) {
-            return Either.right(capabilities.right().value());
+    }
+
+    private Optional<SubstitutionMapping> createSubstitutionMapping(final Component component,
+                                                                    final Map<String, Component> componentCache) throws ToscaExportException {
+        if (component instanceof Service && !((Service) component).isSubstituteCandidate()) {
+            return Optional.empty();
+        }
+
+        final Either<String, ToscaError> toscaResourceNameEither = createComponentToscaName(component);
+        if (toscaResourceNameEither.isRight()) {
+            throw new ToscaExportException("Could not create component TOSCA name", toscaResourceNameEither.right().value());
+        }
+        final String toscaResourceName = toscaResourceNameEither.left().value();
+
+        final SubstitutionMapping substitutionMapping = new SubstitutionMapping();
+        if (doNotExtendBaseType(component)) {
+            substitutionMapping.setNode_type(component.getDerivedFromGenericType());
+        } else {
+            substitutionMapping.setNode_type(toscaResourceName);
         }
         }
-        substitutionMapping = capabilities.left().value();
+        convertSubstitutionMappingFilter(component).ifPresent(substitutionMapping::setSubstitution_filter);
 
 
-        Either<SubstitutionMapping, ToscaError> requirements = capabilityRequirementConverter
-            .convertSubstitutionMappingRequirements(componentCache, component, substitutionMapping);
+        final Either<Map<String, String[]>, ToscaError> capabilitiesEither = convertSubstitutionMappingCapabilities(component, componentCache);
+        if (capabilitiesEither.isRight()) {
+            throw new ToscaExportException("Could not convert substitution mapping capabilities", capabilitiesEither.right().value());
+        }
+        final Map<String, String[]> capabilityMap = capabilitiesEither.left().value();
+        if (!capabilityMap.isEmpty()) {
+            substitutionMapping.setCapabilities(capabilityMap);
+        }
+        final Either<Map<String, String[]>, ToscaError> requirements =
+                capabilityRequirementConverter.convertSubstitutionMappingRequirements(component, componentCache);
         if (requirements.isRight()) {
         if (requirements.isRight()) {
-            return Either.right(requirements.right().value());
+            throw new ToscaExportException("Could not convert substitution mapping requirements", requirements.right().value());
         }
         }
-        substitutionMapping = requirements.left().value();
+        final Map<String, String[]> requirementMap = requirements.left().value();
+        if (MapUtils.isNotEmpty(requirementMap)) {
+            substitutionMapping.setRequirements(requirementMap);
+        }
+
         final Map<String, String[]> propertyMappingMap = buildSubstitutionMappingPropertyMapping(component);
         final Map<String, String[]> propertyMappingMap = buildSubstitutionMappingPropertyMapping(component);
-        if (!propertyMappingMap.isEmpty()) {
+        if (MapUtils.isNotEmpty(propertyMappingMap)) {
             substitutionMapping.setProperties(propertyMappingMap);
         }
 
         final Map<String, String[]> attributesMappingMap = buildSubstitutionMappingAttributesMapping(component);
             substitutionMapping.setProperties(propertyMappingMap);
         }
 
         final Map<String, String[]> attributesMappingMap = buildSubstitutionMappingAttributesMapping(component);
-        if (!attributesMappingMap.isEmpty()) {
+        if (MapUtils.isNotEmpty(attributesMappingMap)) {
             substitutionMapping.setAttributes(attributesMappingMap);
         }
 
             substitutionMapping.setAttributes(attributesMappingMap);
         }
 
-        topologyTemplate.setSubstitution_mappings(substitutionMapping);
-
-        toscaNode.setTopology_template(topologyTemplate);
+        return Optional.of(substitutionMapping);
+    }
 
 
-        return Either.left(toscaNode);
+    private boolean doNotExtendBaseType(final Component component) {
+        final Map<String, CategoryBaseTypeConfig> serviceNodeTypesConfig = ConfigurationManager.getConfigurationManager().getConfiguration()
+                .getServiceBaseNodeTypes();
+        List<CategoryDefinition> categories = component.getCategories();
+        if (CollectionUtils.isNotEmpty(categories) && MapUtils.isNotEmpty(serviceNodeTypesConfig)
+                && serviceNodeTypesConfig.get(categories.get(0).getName()) != null) {
+            return serviceNodeTypesConfig.get(categories.get(0).getName()).isDoNotExtendBaseType();
+        }
+        return false;
     }
 
     }
 
-    private void convertSubstitutionMappingFilter(final Component component,
-                                                  final SubstitutionMapping substitutionMapping) {
-        if (component.getSubstitutionFilter() != null
-            && (component.getSubstitutionFilter().getProperties()).getListToscaDataDefinition() != null) {
-            substitutionMapping
-                .setSubstitution_filter(convertToSubstitutionFilterComponent(component.getSubstitutionFilter()));
+    private Optional<NodeFilter> convertSubstitutionMappingFilter(final Component component) {
+        if (component.getSubstitutionFilter() == null || (component.getSubstitutionFilter().getProperties()).getListToscaDataDefinition() == null) {
+            return Optional.empty();
         }
         }
+
+        return Optional.ofNullable(convertToSubstitutionFilterComponent(component.getSubstitutionFilter()));
     }
 
     private void addGroupsToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate) {
     }
 
     private void addGroupsToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate) {
@@ -429,66 +550,63 @@ public class ToscaExportHandler {
         }
     }
 
         }
     }
 
-    private void addPoliciesToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate)
-        throws SdcResourceNotFoundException {
+    private void addPoliciesToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate) throws SdcResourceNotFoundException {
         Map<String, ToscaPolicyTemplate> policies = policyExportParser.getPolicies(component);
         if (policies != null) {
             topologyTemplate.addPolicies(policies);
         }
     }
 
         Map<String, ToscaPolicyTemplate> policies = policyExportParser.getPolicies(component);
         if (policies != null) {
             topologyTemplate.addPolicies(policies);
         }
     }
 
-    private Map<String, String> convertMetadata(Component component) {
+    private Map<String, Object> convertMetadata(Component component) {
         return convertMetadata(component, false, null);
     }
 
         return convertMetadata(component, false, null);
     }
 
-    private Map<String, String> convertMetadata(Component component, boolean isInstance,
-                                                ComponentInstance componentInstance) {
-        Map<String, String> toscaMetadata = new LinkedHashMap<>();
-        toscaMetadata.put(JsonPresentationFields.INVARIANT_UUID.getPresentation(), component.getInvariantUUID());
+    private Map<String, Object> convertMetadata(Component component, boolean isInstance, ComponentInstance componentInstance) {
+        Map<String, Object> toscaMetadata = new LinkedHashMap<>();
+        toscaMetadata.put(convertMetadataKey(JsonPresentationFields.INVARIANT_UUID), component.getInvariantUUID());
         toscaMetadata.put(JsonPresentationFields.UUID.getPresentation(), component.getUUID());
         toscaMetadata
         toscaMetadata.put(JsonPresentationFields.UUID.getPresentation(), component.getUUID());
         toscaMetadata
-            .put(JsonPresentationFields.NAME.getPresentation(), component.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
+                .put(JsonPresentationFields.NAME.getPresentation(), component.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
         toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), component.getDescription());
         toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), component.getDescription());
-
         List<CategoryDefinition> categories = component.getCategories();
         CategoryDefinition categoryDefinition = categories.get(0);
         List<CategoryDefinition> categories = component.getCategories();
         CategoryDefinition categoryDefinition = categories.get(0);
+        toscaMetadata.put(JsonPresentationFields.MODEL.getPresentation(), component.getModel());
         toscaMetadata.put(JsonPresentationFields.CATEGORY.getPresentation(), categoryDefinition.getName());
         toscaMetadata.put(JsonPresentationFields.CATEGORY.getPresentation(), categoryDefinition.getName());
-
         if (isInstance) {
             toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), component.getVersion());
             toscaMetadata.put(JsonPresentationFields.CUSTOMIZATION_UUID.getPresentation(), componentInstance.getCustomizationUUID());
         if (isInstance) {
             toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), component.getVersion());
             toscaMetadata.put(JsonPresentationFields.CUSTOMIZATION_UUID.getPresentation(), componentInstance.getCustomizationUUID());
-            if (componentInstance.getSourceModelInvariant() != null
-                && !componentInstance.getSourceModelInvariant().isEmpty()) {
+            if (componentInstance.getSourceModelInvariant() != null && !componentInstance.getSourceModelInvariant().isEmpty()) {
                 toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), componentInstance.getComponentVersion());
                 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_INVARIANT.getPresentation(), componentInstance.getSourceModelInvariant());
                 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_UUID.getPresentation(), componentInstance.getSourceModelUuid());
                 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_NAME.getPresentation(), componentInstance.getSourceModelName());
                 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
                     toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(),
                 toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), componentInstance.getComponentVersion());
                 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_INVARIANT.getPresentation(), componentInstance.getSourceModelInvariant());
                 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_UUID.getPresentation(), componentInstance.getSourceModelUuid());
                 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_NAME.getPresentation(), componentInstance.getSourceModelName());
                 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
                     toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(),
-                        componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceProxy.getDisplayValue());
+                            componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceProxy.getDisplayValue());
                 } else if (componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
                     toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(),
                 } else if (componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
                     toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(),
-                        componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceSubstitution
-                            .getDisplayValue());
+                            componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceSubstitution.getDisplayValue());
                 }
                 toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), componentInstance.getDescription());
             }
                 }
                 toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), componentInstance.getDescription());
             }
-
         }
         switch (component.getComponentType()) {
             case RESOURCE:
                 Resource resource = (Resource) component;
         }
         switch (component.getComponentType()) {
             case RESOURCE:
                 Resource resource = (Resource) component;
-
                 if (isInstance && (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy
                 if (isInstance && (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy
-                    || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution)) {
+                        || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution)) {
                     toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), componentInstance.getOriginType().getDisplayValue());
                 } else {
                     toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), resource.getResourceType().name());
                 }
                 toscaMetadata.put(JsonPresentationFields.SUB_CATEGORY.getPresentation(), categoryDefinition.getSubcategories().get(0).getName());
                 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR.getPresentation(), resource.getVendorName());
                     toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), componentInstance.getOriginType().getDisplayValue());
                 } else {
                     toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), resource.getResourceType().name());
                 }
                 toscaMetadata.put(JsonPresentationFields.SUB_CATEGORY.getPresentation(), categoryDefinition.getSubcategories().get(0).getName());
                 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR.getPresentation(), resource.getVendorName());
+                if (resource.getTenant() != null) {
+                    toscaMetadata.put(JsonPresentationFields.TENANT.getPresentation(), resource.getTenant());
+                }
                 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_RELEASE.getPresentation(), resource.getVendorRelease());
                 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_MODEL_NUMBER.getPresentation(), resource.getResourceVendorModelNumber());
                 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_RELEASE.getPresentation(), resource.getVendorRelease());
                 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_MODEL_NUMBER.getPresentation(), resource.getResourceVendorModelNumber());
+                toscaMetadata.put(resource.isTopologyTemplate() ? JsonPresentationFields.TEMPLATE_VERSION.getPresentation() : JsonPresentationFields.VERSION.getPresentation(), resource.getVersion());
                 break;
             case SERVICE:
                 Service service = (Service) component;
                 break;
             case SERVICE:
                 Service service = (Service) component;
@@ -497,61 +615,53 @@ public class ToscaExportHandler {
                 toscaMetadata.put(JsonPresentationFields.SERVICE_ROLE.getPresentation(), service.getServiceRole());
                 toscaMetadata.put(JsonPresentationFields.SERVICE_FUNCTION.getPresentation(), service.getServiceFunction());
                 toscaMetadata.put(JsonPresentationFields.ENVIRONMENT_CONTEXT.getPresentation(), service.getEnvironmentContext());
                 toscaMetadata.put(JsonPresentationFields.SERVICE_ROLE.getPresentation(), service.getServiceRole());
                 toscaMetadata.put(JsonPresentationFields.SERVICE_FUNCTION.getPresentation(), service.getServiceFunction());
                 toscaMetadata.put(JsonPresentationFields.ENVIRONMENT_CONTEXT.getPresentation(), service.getEnvironmentContext());
+                toscaMetadata.put(JsonPresentationFields.TEMPLATE_VERSION.getPresentation(), service.getVersion());
                 toscaMetadata.put(JsonPresentationFields.INSTANTIATION_TYPE.getPresentation(),
                 toscaMetadata.put(JsonPresentationFields.INSTANTIATION_TYPE.getPresentation(),
-                    service.getEnvironmentContext() == null ? StringUtils.EMPTY : service.getInstantiationType());
+                        service.getEnvironmentContext() == null ? StringUtils.EMPTY : service.getInstantiationType());
                 if (!isInstance) {
                 if (!isInstance) {
-                    // DE268546
-                    toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming().toString());
-                    toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming().toString());
+                    toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming());
                     toscaMetadata.put(JsonPresentationFields.NAMING_POLICY.getPresentation(), service.getNamingPolicy());
                 }
                 break;
             default:
                 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
         }
                     toscaMetadata.put(JsonPresentationFields.NAMING_POLICY.getPresentation(), service.getNamingPolicy());
                 }
                 break;
             default:
                 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
         }
-
         for (final String key : component.getCategorySpecificMetadata().keySet()) {
         for (final String key : component.getCategorySpecificMetadata().keySet()) {
-            toscaMetadata.put(key, component.getCategorySpecificMetadata().get(key));
+            if (!EXCLUDED_CATEGORY_SPECIFIC_METADATA.contains(key)) {
+                toscaMetadata.put(key, component.getCategorySpecificMetadata().get(key));
+            }
         }
         return toscaMetadata;
     }
 
         }
         return toscaMetadata;
     }
 
-    private Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports(Component component,
-                                                                                                 ToscaTemplate toscaTemplate) {
+    private String convertMetadataKey(JsonPresentationFields jsonPresentationField) {
+        if (JsonPresentationFields.INVARIANT_UUID.equals(jsonPresentationField)) {
+            return INVARIANT_UUID;
+        }
+        return jsonPresentationField.getPresentation();
+    }
 
 
-        final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImportConfig();
+    private Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports(Component component, ToscaTemplate toscaTemplate) {
+        final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImports(component.getModel());
         if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
             log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
             return Either.right(ToscaError.GENERAL_ERROR);
         }
         Map<String, Component> componentCache = new HashMap<>();
         if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
             log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
             return Either.right(ToscaError.GENERAL_ERROR);
         }
         Map<String, Component> componentCache = new HashMap<>();
-
         if (!ModelConverter.isAtomicComponent(component)) {
             final List<Map<String, Map<String, String>>> additionalImports =
         if (!ModelConverter.isAtomicComponent(component)) {
             final List<Map<String, Map<String, String>>> additionalImports =
-                toscaTemplate.getImports() == null ? new ArrayList<>(defaultToscaImportConfig)
-                    : new ArrayList<>(toscaTemplate.getImports());
-
-            List<Triple<String, String, Component>> dependecies = new ArrayList<>();
-
+                    toscaTemplate.getImports() == null ? new ArrayList<>(defaultToscaImportConfig) : new ArrayList<>(toscaTemplate.getImports());
+            List<Triple<String, String, Component>> dependencies = new ArrayList<>();
             Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
             Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
-            if (isNotEmpty(toscaArtifacts)) {
-                ArtifactDefinition artifactDefinition = toscaArtifacts.get(ToscaExportHandler.ASSET_TOSCA_TEMPLATE);
-                if (artifactDefinition != null) {
-                    Map<String, Map<String, String>> importsListMember = new HashMap<>();
-                    Map<String, String> interfaceFiles = new HashMap<>();
-                    interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactDefinition.getArtifactName()));
-                    StringBuilder keyNameBuilder = new StringBuilder();
-                    keyNameBuilder.append(component.getComponentType().toString().toLowerCase()).append("-")
-                        .append(component.getName()).append("-interface");
-                    importsListMember.put(keyNameBuilder.toString(), interfaceFiles);
-                    additionalImports.add(importsListMember);
-                }
+            final Map<String, Map<String, String>> substituteTypeImportEntry = generateComponentSubstituteTypeImport(component, toscaArtifacts);
+            if (!substituteTypeImportEntry.isEmpty()) {
+                additionalImports.add(substituteTypeImportEntry);
             }
             List<ComponentInstance> componentInstances = component.getComponentInstances();
             if (componentInstances != null && !componentInstances.isEmpty()) {
             }
             List<ComponentInstance> componentInstances = component.getComponentInstances();
             if (componentInstances != null && !componentInstances.isEmpty()) {
-                componentInstances.forEach(ci -> createDependency(componentCache, additionalImports, dependecies, ci));
+                componentInstances.forEach(ci -> createDependency(componentCache, additionalImports, dependencies, ci));
             }
             }
-            toscaTemplate.setDependencies(dependecies);
+            toscaTemplate.setDependencies(dependencies);
             toscaTemplate.setImports(additionalImports);
         } else {
             log.debug("currently imports supported for VF and service only");
             toscaTemplate.setImports(additionalImports);
         } else {
             log.debug("currently imports supported for VF and service only");
@@ -559,23 +669,41 @@ public class ToscaExportHandler {
         return Either.left(new ImmutablePair<>(toscaTemplate, componentCache));
     }
 
         return Either.left(new ImmutablePair<>(toscaTemplate, componentCache));
     }
 
+    private Map<String, Map<String, String>> generateComponentSubstituteTypeImport(final Component component,
+                                                                                   final Map<String, ArtifactDefinition> toscaArtifacts) {
+        if (doNotExtendBaseType(component)) {
+            return Collections.emptyMap();
+        }
+        if (component instanceof Service && !((Service) component).isSubstituteCandidate()) {
+            return Collections.emptyMap();
+        }
+        if (MapUtils.isEmpty(toscaArtifacts)) {
+            return Collections.emptyMap();
+        }
+        final ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE);
+        if (artifactDefinition == null) {
+            return Collections.emptyMap();
+        }
+        final var importEntryName = component.getComponentType().toString().toLowerCase() + "-" + component.getName() + "-interface";
+        return Map.of(importEntryName,
+                Map.of(IMPORTS_FILE_KEY, getInterfaceFilename(artifactDefinition.getArtifactName()))
+        );
+    }
+
     private List<Map<String, Map<String, String>>> getDefaultToscaImportConfig() {
     private List<Map<String, Map<String, String>>> getDefaultToscaImportConfig() {
-        return ConfigurationManager.getConfigurationManager().getConfiguration().getDefaultImports();
+        return getConfiguration().getDefaultImports();
     }
 
     }
 
-    private void createDependency(final Map<String, Component> componentCache,
-                                  final List<Map<String, Map<String, String>>> imports,
-                                  final List<Triple<String, String, Component>> dependencies,
-                                  final ComponentInstance componentInstance) {
+    private void createDependency(final Map<String, Component> componentCache, final List<Map<String, Map<String, String>>> imports,
+                                  final List<Triple<String, String, Component>> dependencies, final ComponentInstance componentInstance) {
         log.debug("createDependency componentCache {}", componentCache);
         Component componentRI = componentCache.get(componentInstance.getComponentUid());
         if (componentRI == null || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
             // all resource must be only once!
         log.debug("createDependency componentCache {}", componentCache);
         Component componentRI = componentCache.get(componentInstance.getComponentUid());
         if (componentRI == null || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
             // all resource must be only once!
-            final Either<Component, StorageOperationStatus> resource = toscaOperationFacade
-                .getToscaFullElement(componentInstance.getComponentUid());
+            final Either<Component, StorageOperationStatus> resource = toscaOperationFacade.getToscaFullElement(componentInstance.getComponentUid());
             if ((resource.isRight()) && (log.isDebugEnabled())) {
                 log.debug("Failed to fetch resource with id {} for instance {}", componentInstance.getComponentUid(),
             if ((resource.isRight()) && (log.isDebugEnabled())) {
                 log.debug("Failed to fetch resource with id {} for instance {}", componentInstance.getComponentUid(),
-                    componentInstance.getUniqueId());
+                        componentInstance.getUniqueId());
                 return;
             }
             final Component fetchedComponent = resource.left().value();
                 return;
             }
             final Component fetchedComponent = resource.left().value();
@@ -587,17 +715,16 @@ public class ToscaExportHandler {
     /**
      * Sets a componentCache from the given component/resource.
      */
     /**
      * Sets a componentCache from the given component/resource.
      */
-    private Component setComponentCache(final Map<String, Component> componentCache,
-                                   final ComponentInstance componentInstance,
-                                   final Component fetchedComponent) {
+    private Component setComponentCache(final Map<String, Component> componentCache, final ComponentInstance componentInstance,
+                                        final Component fetchedComponent) {
         componentCache.put(fetchedComponent.getUniqueId(), fetchedComponent);
         if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy
         componentCache.put(fetchedComponent.getUniqueId(), fetchedComponent);
         if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy
-            || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
+                || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
             final Either<Component, StorageOperationStatus> sourceService = toscaOperationFacade
             final Either<Component, StorageOperationStatus> sourceService = toscaOperationFacade
-                .getToscaFullElement(componentInstance.getSourceModelUid());
+                    .getToscaFullElement(componentInstance.getSourceModelUid());
             if (sourceService.isRight() && (log.isDebugEnabled())) {
             if (sourceService.isRight() && (log.isDebugEnabled())) {
-                log.debug("Failed to fetch source service with id {} for proxy {}",
-                    componentInstance.getSourceModelUid(), componentInstance.getUniqueId());
+                log.debug("Failed to fetch source service with id {} for proxy {}", componentInstance.getSourceModelUid(),
+                        componentInstance.getUniqueId());
             }
             final Component fetchedSource = sourceService.left().value();
             componentCache.put(fetchedSource.getUniqueId(), fetchedSource);
             }
             final Component fetchedSource = sourceService.left().value();
             componentCache.put(fetchedSource.getUniqueId(), fetchedSource);
@@ -609,21 +736,17 @@ public class ToscaExportHandler {
     /**
      * Retrieves all derived_from nodes and stores it in a predictable order.
      */
     /**
      * Retrieves all derived_from nodes and stores it in a predictable order.
      */
-    private void addDependencies(final List<Map<String, Map<String, String>>> imports,
-                                 final List<Triple<String, String, Component>> dependencies,
+    private void addDependencies(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
                                  final Component fetchedComponent) {
         final Set<Component> componentsList = new LinkedHashSet<>();
         if (fetchedComponent instanceof Resource) {
             log.debug("fetchedComponent is a resource {}", fetchedComponent);
                                  final Component fetchedComponent) {
         final Set<Component> componentsList = new LinkedHashSet<>();
         if (fetchedComponent instanceof Resource) {
             log.debug("fetchedComponent is a resource {}", fetchedComponent);
-
-            final Optional<Map<String, String>> derivedFromMapOfIdToName = getDerivedFromMapOfIdToName(fetchedComponent,
-                componentsList);
+            final Optional<Map<String, String>> derivedFromMapOfIdToName = getDerivedFromMapOfIdToName(fetchedComponent, componentsList);
             if (derivedFromMapOfIdToName.isPresent() && !derivedFromMapOfIdToName.get().isEmpty()) {
                 derivedFromMapOfIdToName.get().entrySet().forEach(entry -> {
                     log.debug("Started entry.getValue() : {}", entry.getValue());
                     if (!NATIVE_ROOT.equals(entry.getValue())) {
             if (derivedFromMapOfIdToName.isPresent() && !derivedFromMapOfIdToName.get().isEmpty()) {
                 derivedFromMapOfIdToName.get().entrySet().forEach(entry -> {
                     log.debug("Started entry.getValue() : {}", entry.getValue());
                     if (!NATIVE_ROOT.equals(entry.getValue())) {
-                        Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade
-                            .getToscaElement(entry.getKey());
+                        Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade.getToscaElement(entry.getKey());
                         if (resourcefetched != null && resourcefetched.isLeft()) {
                             componentsList.add(resourcefetched.left().value());
                         }
                         if (resourcefetched != null && resourcefetched.isLeft()) {
                             componentsList.add(resourcefetched.left().value());
                         }
@@ -633,25 +756,22 @@ public class ToscaExportHandler {
             } else {
                 setImports(imports, dependencies, fetchedComponent);
             }
             } else {
                 setImports(imports, dependencies, fetchedComponent);
             }
-
         }
     }
 
     /**
      * Returns all derived_from nodes found.
      */
         }
     }
 
     /**
      * Returns all derived_from nodes found.
      */
-    private Optional<Map<String, String>> getDerivedFromMapOfIdToName(final Component fetchedComponent,
-                                                                      final Set<Component> componentsList) {
+    private Optional<Map<String, String>> getDerivedFromMapOfIdToName(final Component fetchedComponent, final Set<Component> componentsList) {
         final Resource parentResource = (Resource) fetchedComponent;
         Map<String, String> derivedFromMapOfIdToName = new HashMap<>();
         if (CollectionUtils.isNotEmpty(parentResource.getComponentInstances())) {
             componentsList.add(fetchedComponent);
             for (final ComponentInstance componentInstance : parentResource.getComponentInstances()) {
                 final Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade
         final Resource parentResource = (Resource) fetchedComponent;
         Map<String, String> derivedFromMapOfIdToName = new HashMap<>();
         if (CollectionUtils.isNotEmpty(parentResource.getComponentInstances())) {
             componentsList.add(fetchedComponent);
             for (final ComponentInstance componentInstance : parentResource.getComponentInstances()) {
                 final Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade
-                    .getToscaElement(componentInstance.getComponentUid());
+                        .getToscaElement(componentInstance.getComponentUid());
                 if (resourcefetched != null && resourcefetched.isLeft()) {
                 if (resourcefetched != null && resourcefetched.isLeft()) {
-                    final Map<String, String> derivedWithId = resourcefetched.left().value()
-                        .getDerivedFromMapOfIdToName();
+                    final Map<String, String> derivedWithId = resourcefetched.left().value().getDerivedFromMapOfIdToName();
                     if (MapUtils.isNotEmpty(derivedWithId)) {
                         derivedFromMapOfIdToName.putAll(derivedWithId);
                     }
                     if (MapUtils.isNotEmpty(derivedWithId)) {
                         derivedFromMapOfIdToName.putAll(derivedWithId);
                     }
@@ -667,14 +787,12 @@ public class ToscaExportHandler {
     /**
      * Creates a resource map and adds it to the import list.
      */
     /**
      * Creates a resource map and adds it to the import list.
      */
-    private void setImports(final List<Map<String, Map<String, String>>> imports,
-                            final List<Triple<String, String, Component>> dependencies,
+    private void setImports(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
                             final Set<Component> componentsList) {
         componentsList.forEach(component -> setImports(imports, dependencies, component));
     }
 
                             final Set<Component> componentsList) {
         componentsList.forEach(component -> setImports(imports, dependencies, component));
     }
 
-    private void setImports(final List<Map<String, Map<String, String>>> imports,
-                            final List<Triple<String, String, Component>> dependencies,
+    private void setImports(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
                             final Component component) {
         final Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
         final ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE);
                             final Component component) {
         final Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
         final ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE);
@@ -687,9 +805,7 @@ public class ToscaExportHandler {
             keyNameBuilder.append("-");
             keyNameBuilder.append(component.getName());
             addImports(imports, keyNameBuilder, files);
             keyNameBuilder.append("-");
             keyNameBuilder.append(component.getName());
             addImports(imports, keyNameBuilder, files);
-            dependencies
-                    .add(new ImmutableTriple<>(artifactName, artifactDefinition.getEsId(), component));
-
+            dependencies.add(new ImmutableTriple<>(artifactName, artifactDefinition.getEsId(), component));
             if (!ModelConverter.isAtomicComponent(component)) {
                 final Map<String, String> interfaceFiles = new HashMap<>();
                 interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactName));
             if (!ModelConverter.isAtomicComponent(component)) {
                 final Map<String, String> interfaceFiles = new HashMap<>();
                 interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactName));
@@ -702,8 +818,7 @@ public class ToscaExportHandler {
     /**
      * Adds the found resource to the import definition list.
      */
     /**
      * Adds the found resource to the import definition list.
      */
-    private void addImports(final List<Map<String, Map<String, String>>> imports,
-                            final StringBuilder keyNameBuilder,
+    private void addImports(final List<Map<String, Map<String, String>>> imports, final StringBuilder keyNameBuilder,
                             final Map<String, String> files) {
         final String mapKey = keyNameBuilder.toString();
         if (imports.stream().allMatch(stringMapMap -> stringMapMap.get(mapKey) == null)) {
                             final Map<String, String> files) {
         final String mapKey = keyNameBuilder.toString();
         if (imports.stream().allMatch(stringMapMap -> stringMapMap.get(mapKey) == null)) {
@@ -713,94 +828,68 @@ public class ToscaExportHandler {
         }
     }
 
         }
     }
 
-    public static String getInterfaceFilename(String artifactName) {
-        return artifactName.substring(0, artifactName.lastIndexOf('.')) + ToscaExportHandler.TOSCA_INTERFACE_NAME;
-    }
-
-    private Either<ToscaTemplate, ToscaError> convertNodeType(Map<String, Component> componentsCache,
-                                                              Component component, ToscaTemplate toscaNode,
+    private Either<ToscaTemplate, ToscaError> convertNodeType(Map<String, Component> componentsCache, Component component, ToscaTemplate toscaNode,
                                                               Map<String, ToscaNodeType> nodeTypes) {
         return convertInterfaceNodeType(componentsCache, component, toscaNode, nodeTypes, false);
     }
 
                                                               Map<String, ToscaNodeType> nodeTypes) {
         return convertInterfaceNodeType(componentsCache, component, toscaNode, nodeTypes, false);
     }
 
-    public Either<ToscaTemplate, ToscaError> convertInterfaceNodeType(Map<String, Component> componentsCache,
-                                                                      Component component, ToscaTemplate toscaNode,
-                                                                      Map<String, ToscaNodeType> nodeTypes,
+    public Either<ToscaTemplate, ToscaError> convertInterfaceNodeType(Map<String, Component> componentsCache, Component component,
+                                                                      ToscaTemplate toscaNode, Map<String, ToscaNodeType> nodeTypes,
                                                                       boolean isAssociatedComponent) {
         log.debug("start convert node type for {}", component.getUniqueId());
         ToscaNodeType toscaNodeType = createNodeType(component);
                                                                       boolean isAssociatedComponent) {
         log.debug("start convert node type for {}", component.getUniqueId());
         ToscaNodeType toscaNodeType = createNodeType(component);
-
-        Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither =
-            interfaceLifecycleOperation.getAllInterfaceLifecycleTypes();
-        if (lifecycleTypeEither.isRight()) {
+        Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither = interfaceLifecycleOperation
+                .getAllInterfaceLifecycleTypes(component.getModel());
+        if (lifecycleTypeEither.isRight() && !StorageOperationStatus.NOT_FOUND.equals(lifecycleTypeEither.right().value())) {
             log.debug("Failed to fetch all interface types :", lifecycleTypeEither.right().value());
             return Either.right(ToscaError.GENERAL_ERROR);
         }
             log.debug("Failed to fetch all interface types :", lifecycleTypeEither.right().value());
             return Either.right(ToscaError.GENERAL_ERROR);
         }
-        List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value()
-            .values()
-            .stream()
-            .map(InterfaceDataDefinition::getType)
-            .collect(Collectors.toList());
-        toscaNode.setInterface_types(addInterfaceTypeElement(component, allGlobalInterfaceTypes));
-
-        Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = dataTypeCache.getAll();
+        if (lifecycleTypeEither.isLeft()) {
+            List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value().values().stream().map(InterfaceDataDefinition::getType)
+                    .collect(Collectors.toList());
+            toscaNode.setInterface_types(interfacesOperationsConverter.addInterfaceTypeElement(component, allGlobalInterfaceTypes));
+        }
+        final var dataTypesEither = applicationDataTypeCache.getAll(component.getModel());
         if (dataTypesEither.isRight()) {
             log.debug("Failed to fetch all data types :", dataTypesEither.right().value());
             return Either.right(ToscaError.GENERAL_ERROR);
         }
         if (dataTypesEither.isRight()) {
             log.debug("Failed to fetch all data types :", dataTypesEither.right().value());
             return Either.right(ToscaError.GENERAL_ERROR);
         }
-
         Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
         Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
-
-        List<InputDefinition> inputDef = component.getInputs();
-        Map<String, ToscaProperty> mergedProperties = new HashMap<>();
-        interfacesOperationsConverter
-            .addInterfaceDefinitionElement(component, toscaNodeType, dataTypes, isAssociatedComponent);
-        addInputsToProperties(dataTypes, inputDef, mergedProperties);
-
-        final Map<String, ToscaAttribute> toscaAttributeMap;
-        try {
-            toscaAttributeMap = convertToToscaAttributes(component.getAttributes(), dataTypes);
-        } catch (final ToscaConversionException e) {
-            log.error(EcompLoggerErrorCode.SCHEMA_ERROR, ToscaExportHandler.class.getName(),
-                "Could not parse component '{}' attributes. Component unique id '{}'.",
-                new Object[]{component.getName(), component.getUniqueId(), e});
-            return Either.right(ToscaError.GENERAL_ERROR);
-        }
+        interfacesOperationsConverter.addInterfaceDefinitionElement(component, toscaNodeType, dataTypes, isAssociatedComponent);
+        final var toscaAttributeMap = convertToToscaAttributes(component.getAttributes(), dataTypes);
         if (!toscaAttributeMap.isEmpty()) {
             toscaNodeType.setAttributes(toscaAttributeMap);
         }
         if (!toscaAttributeMap.isEmpty()) {
             toscaNodeType.setAttributes(toscaAttributeMap);
         }
+        Map<String, ToscaProperty> convertedProperties = new HashMap();
         if (CollectionUtils.isNotEmpty(component.getProperties())) {
             List<PropertyDefinition> properties = component.getProperties();
         if (CollectionUtils.isNotEmpty(component.getProperties())) {
             List<PropertyDefinition> properties = component.getProperties();
-            Map<String, ToscaProperty> convertedProperties = properties.stream()
-                .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, component.getInputs()))
-                .collect(Collectors.toMap(PropertyDataDefinition::getName,
-                    property -> propertyConvertor.convertProperty(dataTypes, property,
-                        PropertyConvertor.PropertyType.PROPERTY)));
-            // merge component properties and inputs properties
-            mergedProperties.putAll(convertedProperties);
+            convertedProperties = properties.stream()
+                    .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, component.getInputs())).collect(Collectors
+                            .toMap(PropertyDataDefinition::getName,
+                                    property -> propertyConvertor.convertProperty(dataTypes, property, PropertyConvertor.PropertyType.PROPERTY)));
         }
         }
-        if (MapUtils.isNotEmpty(mergedProperties)) {
-            toscaNodeType.setProperties(mergedProperties);
+        if (MapUtils.isNotEmpty(convertedProperties)) {
+            toscaNodeType.setProperties(convertedProperties);
         }
         }
-
         /* convert private data_types */
         List<DataTypeDefinition> privateDataTypes = component.getDataTypes();
         if (CollectionUtils.isNotEmpty(privateDataTypes)) {
             Map<String, ToscaDataType> toscaDataTypeMap = new HashMap<>();
             for (DataTypeDefinition dataType : privateDataTypes) {
                 log.debug("Emitting private data type: component.name={} dataType.name={}",
         /* convert private data_types */
         List<DataTypeDefinition> privateDataTypes = component.getDataTypes();
         if (CollectionUtils.isNotEmpty(privateDataTypes)) {
             Map<String, ToscaDataType> toscaDataTypeMap = new HashMap<>();
             for (DataTypeDefinition dataType : privateDataTypes) {
                 log.debug("Emitting private data type: component.name={} dataType.name={}",
-                    component.getNormalizedName(), dataType.getName());
+                        component.getNormalizedName(), dataType.getName());
                 ToscaDataType toscaDataType = new ToscaDataType();
                 toscaDataType.setDerived_from(dataType.getDerivedFromName());
                 toscaDataType.setDescription(dataType.getDescription());
                 toscaDataType.setVersion(dataType.getVersion());
                 if (CollectionUtils.isNotEmpty(dataType.getProperties())) {
                     toscaDataType.setProperties(dataType.getProperties().stream()
                 ToscaDataType toscaDataType = new ToscaDataType();
                 toscaDataType.setDerived_from(dataType.getDerivedFromName());
                 toscaDataType.setDescription(dataType.getDescription());
                 toscaDataType.setVersion(dataType.getVersion());
                 if (CollectionUtils.isNotEmpty(dataType.getProperties())) {
                     toscaDataType.setProperties(dataType.getProperties().stream()
-                        .collect(Collectors.toMap(
-                            PropertyDataDefinition::getName,
-                            s -> propertyConvertor
-                                .convertProperty(dataTypes, s, PropertyType.PROPERTY)
-                        )));
+                            .collect(Collectors.toMap(
+                                    PropertyDataDefinition::getName,
+                                    s -> propertyConvertor.convertProperty(dataTypes, s, PropertyType.PROPERTY),
+                                    (toscaPropertyTobeValidated, toscaProperty) -> validateToscaProperty(privateDataTypes, toscaPropertyTobeValidated,
+                                            toscaProperty)
+                            )));
                 }
                 toscaDataTypeMap.put(dataType.getName(), toscaDataType);
             }
                 }
                 toscaDataTypeMap.put(dataType.getName(), toscaDataType);
             }
@@ -811,15 +900,22 @@ public class ToscaExportHandler {
         return convertReqCapAndTypeName(componentsCache, component, toscaNode, nodeTypes, toscaNodeType, dataTypes);
     }
 
         return convertReqCapAndTypeName(componentsCache, component, toscaNode, nodeTypes, toscaNodeType, dataTypes);
     }
 
+    private ToscaProperty validateToscaProperty(final List<DataTypeDefinition> privateDataTypes, final ToscaProperty toscaPropertyTobeValidated,
+                                                final ToscaProperty toscaProperty) {
+        final Optional<DataTypeDefinition> match = privateDataTypes.stream()
+                .filter(dataType -> dataType.getName().equals(toscaPropertyTobeValidated.getType())).findFirst();
+        return match.isPresent() ? toscaPropertyTobeValidated : toscaProperty;
+    }
+
     private Map<String, ToscaAttribute> convertToToscaAttributes(final List<AttributeDefinition> attributeList,
     private Map<String, ToscaAttribute> convertToToscaAttributes(final List<AttributeDefinition> attributeList,
-                                                                 final Map<String, DataTypeDefinition> dataTypes) throws ToscaConversionException {
+                                                                 final Map<String, DataTypeDefinition> dataTypes) {
         if (CollectionUtils.isEmpty(attributeList)) {
             return Collections.emptyMap();
         }
         if (CollectionUtils.isEmpty(attributeList)) {
             return Collections.emptyMap();
         }
-        final AttributeConverter attributeConverter = new AttributeConverter(dataTypes);
+        final AttributeConverter converter = new AttributeConverter(dataTypes);
         final Map<String, ToscaAttribute> toscaAttributeMap = new HashMap<>();
         for (final AttributeDefinition attributeDefinition : attributeList) {
         final Map<String, ToscaAttribute> toscaAttributeMap = new HashMap<>();
         for (final AttributeDefinition attributeDefinition : attributeList) {
-            toscaAttributeMap.put(attributeDefinition.getName(), attributeConverter.convert(attributeDefinition));
+            toscaAttributeMap.put(attributeDefinition.getName(), converter.convert(attributeDefinition));
         }
         return toscaAttributeMap;
     }
         }
         return toscaAttributeMap;
     }
@@ -830,7 +926,7 @@ public class ToscaExportHandler {
                                                                        ToscaNodeType toscaNodeType,
                                                                        Map<String, DataTypeDefinition> dataTypes) {
         Either<ToscaNodeType, ToscaError> capabilities = convertCapabilities(componentsCache, component, toscaNodeType,
                                                                        ToscaNodeType toscaNodeType,
                                                                        Map<String, DataTypeDefinition> dataTypes) {
         Either<ToscaNodeType, ToscaError> capabilities = convertCapabilities(componentsCache, component, toscaNodeType,
-            dataTypes);
+                dataTypes);
         if (capabilities.isRight()) {
             return Either.right(capabilities.right().value());
         }
         if (capabilities.isRight()) {
             return Either.right(capabilities.right().value());
         }
@@ -838,8 +934,7 @@ public class ToscaExportHandler {
         log.debug("Capabilities converted for {}", component.getUniqueId());
 
         Either<ToscaNodeType, ToscaError> requirements = capabilityRequirementConverter
         log.debug("Capabilities converted for {}", component.getUniqueId());
 
         Either<ToscaNodeType, ToscaError> requirements = capabilityRequirementConverter
-            .convertRequirements(componentsCache, component,
-                toscaNodeType);
+                .convertRequirements(componentsCache, component, toscaNodeType);
         if (requirements.isRight()) {
             return Either.right(requirements.right().value());
         }
         if (requirements.isRight()) {
             return Either.right(requirements.right().value());
         }
@@ -850,11 +945,11 @@ public class ToscaExportHandler {
         switch (component.getComponentType()) {
             case RESOURCE:
                 toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition()
         switch (component.getComponentType()) {
             case RESOURCE:
                 toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition()
-                    .getMetadataDataDefinition()).getToscaResourceName();
+                        .getMetadataDataDefinition()).getToscaResourceName();
                 break;
             case SERVICE:
                 toscaResourceName = SERVICE_NODE_TYPE_PREFIX
                 break;
             case SERVICE:
                 toscaResourceName = SERVICE_NODE_TYPE_PREFIX
-                    + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName();
+                        + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName();
                 break;
             default:
                 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
                 break;
             default:
                 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
@@ -867,59 +962,75 @@ public class ToscaExportHandler {
         return Either.left(toscaNode);
     }
 
         return Either.left(toscaNode);
     }
 
-    protected Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplates(
-        Component component,
-        List<ComponentInstance> componentInstances,
-        Map<String, List<ComponentInstanceProperty>> componentInstancesProperties,
-        Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces,
-        Map<String, Component> componentCache, Map<String, DataTypeDefinition> dataTypes,
-        ToscaTopolgyTemplate topologyTemplate) {
+    private Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplates(final Component component,
+                                                                                    final Map<String, Component> componentCache,
+                                                                                    final Map<String, DataTypeDefinition> dataTypes,
+                                                                                    final ToscaTopolgyTemplate topologyTemplate) {
+
+        final Map<String, List<ComponentInstanceProperty>> componentInstancesProperties = component.getComponentInstancesProperties();
+        final Map<String, List<ComponentInstanceAttribute>> componentInstancesAttributes = component.getComponentInstancesAttributes();
+        final Map<String, List<ComponentInstanceInput>> componentInstancesInputs = component.getComponentInstancesInputs();
+        final Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces = component.getComponentInstancesInterfaces();
+        final List<RequirementCapabilityRelDef> componentInstancesRelations = component.getComponentInstancesRelations();
 
         Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplatesRes = null;
 
         Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplatesRes = null;
-        log.debug("start convert topology template for {} for type {}", component.getUniqueId(),
-            component.getComponentType());
-        Map<String, ToscaNodeTemplate> nodeTemplates = new HashMap<>();
-        Map<String, List<ComponentInstanceInput>> componentInstancesInputs = component.getComponentInstancesInputs();
+        log.debug("start convert topology template for {} for type {}", component.getUniqueId(), component.getComponentType());
+        final Map<String, ToscaNodeTemplate> nodeTemplates = new HashMap<>();
 
         Map<String, ToscaGroupTemplate> groupsMap = null;
 
         Map<String, ToscaGroupTemplate> groupsMap = null;
-        for (ComponentInstance componentInstance : componentInstances) {
+        for (final ComponentInstance componentInstance : component.getComponentInstances()) {
             ToscaNodeTemplate nodeTemplate = new ToscaNodeTemplate();
             if (MapUtils.isNotEmpty(componentInstance.getToscaArtifacts())) {
                 nodeTemplate.setArtifacts(convertToNodeTemplateArtifacts(componentInstance.getToscaArtifacts()));
             }
             ToscaNodeTemplate nodeTemplate = new ToscaNodeTemplate();
             if (MapUtils.isNotEmpty(componentInstance.getToscaArtifacts())) {
                 nodeTemplate.setArtifacts(convertToNodeTemplateArtifacts(componentInstance.getToscaArtifacts()));
             }
+            if (componentInstance.getMinOccurrences() != null && componentInstance.getMaxOccurrences() != null) {
+                List<Object> occur = new ArrayList<>();
+                occur.add(parseToIntIfPossible(componentInstance.getMinOccurrences()));
+                occur.add(parseToIntIfPossible(componentInstance.getMaxOccurrences()));
+                nodeTemplate.setOccurrences(occur);
+            }
+            if (componentInstance.getInstanceCount() != null) {
+                ObjectMapper objectMapper = new ObjectMapper();
+                Object obj = convertToToscaObject(componentInstance.getInstanceCount());
+                if (obj != null) {
+                    Map<String, String> map = objectMapper.convertValue(obj, Map.class);
+                    nodeTemplate.setInstance_count(map);
+                }
+            }
             nodeTemplate.setType(componentInstance.getToscaComponentName());
             nodeTemplate.setDirectives(componentInstance.getDirectives());
             nodeTemplate.setType(componentInstance.getToscaComponentName());
             nodeTemplate.setDirectives(componentInstance.getDirectives());
-            nodeTemplate.setNode_filter(convertToNodeTemplateNodeFilterComponent(componentInstance.getNodeFilter()));
-
-            Either<Component, Boolean> originComponentRes = capabilityRequirementConverter
-                .getOriginComponent(componentCache, componentInstance);
+            NodeFilter nodeFilter = convertToNodeTemplateNodeFilterComponent(componentInstance.getNodeFilter());
+            if (nodeFilter != null && nodeFilter.hasData()) {
+                nodeTemplate.setNode_filter(nodeFilter);
+            }
+            final Either<Component, Boolean> originComponentRes = capabilityRequirementConverter
+                    .getOriginComponent(componentCache, componentInstance);
             if (originComponentRes.isRight()) {
                 convertNodeTemplatesRes = Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
                 break;
             }
             if (originComponentRes.isRight()) {
                 convertNodeTemplatesRes = Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
                 break;
             }
-            Either<ToscaNodeTemplate, ToscaError> requirements = convertComponentInstanceRequirements(component,
-                componentInstance, component.getComponentInstancesRelations(), nodeTemplate,
-                originComponentRes.left().value(), componentCache);
+            final Either<ToscaNodeTemplate, ToscaError> requirements = convertComponentInstanceRequirements(component, componentInstance,
+                    componentInstancesRelations, nodeTemplate, originComponentRes.left().value(), componentCache);
             if (requirements.isRight()) {
                 convertNodeTemplatesRes = Either.right(requirements.right().value());
                 break;
             }
             if (requirements.isRight()) {
                 convertNodeTemplatesRes = Either.right(requirements.right().value());
                 break;
             }
-            String instanceUniqueId = componentInstance.getUniqueId();
+            final String instanceUniqueId = componentInstance.getUniqueId();
             log.debug("Component instance Requirements converted for instance {}", instanceUniqueId);
 
             nodeTemplate = requirements.left().value();
 
             log.debug("Component instance Requirements converted for instance {}", instanceUniqueId);
 
             nodeTemplate = requirements.left().value();
 
-            Component originalComponent = componentCache.get(componentInstance.getActualComponentUid());
+            final Component originalComponent = componentCache.get(componentInstance.getActualComponentUid());
 
             if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
 
             if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
-                Component componentOfProxy = componentCache.get(componentInstance.getComponentUid());
+                final Component componentOfProxy = componentCache.get(componentInstance.getComponentUid());
                 nodeTemplate.setMetadata(convertMetadata(componentOfProxy, true, componentInstance));
             } else {
                 nodeTemplate.setMetadata(convertMetadata(originalComponent, true, componentInstance));
             }
 
                 nodeTemplate.setMetadata(convertMetadata(componentOfProxy, true, componentInstance));
             } else {
                 nodeTemplate.setMetadata(convertMetadata(originalComponent, true, componentInstance));
             }
 
-            Either<ToscaNodeTemplate, ToscaError> capabilities = capabilityRequirementConverter
-                .convertComponentInstanceCapabilities(componentInstance, dataTypes, nodeTemplate);
+            final Either<ToscaNodeTemplate, ToscaError> capabilities =
+                    capabilityRequirementConverter.convertComponentInstanceCapabilities(componentInstance, dataTypes, nodeTemplate);
             if (capabilities.isRight()) {
                 convertNodeTemplatesRes = Either.right(capabilities.right().value());
                 break;
             if (capabilities.isRight()) {
                 convertNodeTemplatesRes = Either.right(capabilities.right().value());
                 break;
@@ -927,49 +1038,47 @@ public class ToscaExportHandler {
             log.debug("Component instance Capabilities converted for instance {}", instanceUniqueId);
 
             nodeTemplate = capabilities.left().value();
             log.debug("Component instance Capabilities converted for instance {}", instanceUniqueId);
 
             nodeTemplate = capabilities.left().value();
-            Map<String, Object> props = new HashMap<>();
+            final Map<String, Object> props = new HashMap<>();
+            final Map<String, Object> attribs = new HashMap<>();
 
             if (originalComponent.getComponentType() == ComponentTypeEnum.RESOURCE) {
                 // Adds the properties of parent component to map
                 addPropertiesOfParentComponent(dataTypes, originalComponent, props);
 
             if (originalComponent.getComponentType() == ComponentTypeEnum.RESOURCE) {
                 // Adds the properties of parent component to map
                 addPropertiesOfParentComponent(dataTypes, originalComponent, props);
+                addAttributesOfParentComponent(originalComponent, attribs);
             }
 
             if (null != componentInstancesProperties && componentInstancesProperties.containsKey(instanceUniqueId)) {
             }
 
             if (null != componentInstancesProperties && componentInstancesProperties.containsKey(instanceUniqueId)) {
-                addPropertiesOfComponentInstance(componentInstancesProperties, dataTypes, instanceUniqueId,
-                    props);
+                addPropertiesOfComponentInstance(componentInstancesProperties, dataTypes, instanceUniqueId, props);
+            }
+            if (null != componentInstancesAttributes && componentInstancesAttributes.containsKey(instanceUniqueId)) {
+                addAttributesOfComponentInstance(componentInstancesAttributes, instanceUniqueId, attribs);
             }
 
             }
 
-            if (componentInstancesInputs != null && componentInstancesInputs.containsKey(instanceUniqueId)
-                && !isComponentOfTypeServiceProxy(componentInstance)) {
+            if (componentInstancesInputs != null
+                    && componentInstancesInputs.containsKey(instanceUniqueId)
+                    && !isComponentOfTypeServiceProxy(componentInstance)) {
                 //For service proxy the inputs are already handled under instance properties above
                 addComponentInstanceInputs(dataTypes, componentInstancesInputs, instanceUniqueId, props);
             }
 
             //M3[00001] - NODE TEMPLATE INTERFACES  - START
                 //For service proxy the inputs are already handled under instance properties above
                 addComponentInstanceInputs(dataTypes, componentInstancesInputs, instanceUniqueId, props);
             }
 
             //M3[00001] - NODE TEMPLATE INTERFACES  - START
-            handleInstanceInterfaces(componentInstanceInterfaces, componentInstance, dataTypes, nodeTemplate,
-                instanceUniqueId, component);
+            handleInstanceInterfaces(componentInstanceInterfaces, componentInstance, dataTypes, nodeTemplate, instanceUniqueId, component);
             //M3[00001] - NODE TEMPLATE INTERFACES  - END
             //M3[00001] - NODE TEMPLATE INTERFACES  - END
-            if (props != null && !props.isEmpty()) {
+            if (MapUtils.isNotEmpty(props)) {
                 nodeTemplate.setProperties(props);
             }
                 nodeTemplate.setProperties(props);
             }
+            if (MapUtils.isNotEmpty(attribs)) {
+                nodeTemplate.setAttributes(attribs);
+            }
 
 
-            List<GroupInstance> groupInstances = componentInstance.getGroupInstances();
-            if (groupInstances != null) {
+            final List<GroupInstance> groupInstances = componentInstance.getGroupInstances();
+            if (CollectionUtils.isNotEmpty(groupInstances)) {
                 if (groupsMap == null) {
                     groupsMap = new HashMap<>();
                 }
                 if (groupsMap == null) {
                     groupsMap = new HashMap<>();
                 }
-                for (GroupInstance groupInst : groupInstances) {
-                    boolean addToTosca = true;
-
-                    List<String> artifacts = groupInst.getArtifacts();
-                    if (artifacts == null || artifacts.isEmpty()) {
-                        addToTosca = false;
-                    }
-
-                    if (addToTosca) {
-                        ToscaGroupTemplate toscaGroup = groupExportParser
-                            .getToscaGroupTemplate(groupInst, componentInstance.getInvariantName());
-                        groupsMap.put(groupInst.getName(), toscaGroup);
+                for (final GroupInstance groupInst : groupInstances) {
+                    if (CollectionUtils.isNotEmpty(groupInst.getArtifacts())) {
+                        groupsMap.put(groupInst.getName(), groupExportParser.getToscaGroupTemplate(groupInst, componentInstance.getInvariantName()));
                     }
                 }
             }
                     }
                 }
             }
@@ -981,45 +1090,60 @@ public class ToscaExportHandler {
             topologyTemplate.addGroups(groupsMap);
         }
         if (component.getComponentType() == ComponentTypeEnum.SERVICE && isNotEmpty(
             topologyTemplate.addGroups(groupsMap);
         }
         if (component.getComponentType() == ComponentTypeEnum.SERVICE && isNotEmpty(
-            ((Service) component).getForwardingPaths())) {
-            log.debug("Starting converting paths for component {}, name {}", component.getUniqueId(),
-                component.getName());
+                ((Service) component).getForwardingPaths())) {
+            log.debug("Starting converting paths for component {}, name {}", component.getUniqueId(), component.getName());
             ForwardingPathToscaUtil
             ForwardingPathToscaUtil
-                .addForwardingPaths((Service) component, nodeTemplates, capabilityRequirementConverter, componentCache,
-                    toscaOperationFacade);
-            log.debug("Finished converting paths for component {}, name {}", component.getUniqueId(),
-                component.getName());
+                    .addForwardingPaths((Service) component, nodeTemplates, capabilityRequirementConverter, componentCache, toscaOperationFacade);
+            log.debug("Finished converting paths for component {}, name {}", component.getUniqueId(), component.getName());
         }
         if (convertNodeTemplatesRes == null) {
             convertNodeTemplatesRes = Either.left(nodeTemplates);
         }
         }
         if (convertNodeTemplatesRes == null) {
             convertNodeTemplatesRes = Either.left(nodeTemplates);
         }
-        log.debug("finish convert topology template for {} for type {}", component.getUniqueId(),
-            component.getComponentType());
+        log.debug("finish convert topology template for {} for type {}", component.getUniqueId(), component.getComponentType());
         return convertNodeTemplatesRes;
     }
 
         return convertNodeTemplatesRes;
     }
 
-    private void handleInstanceInterfaces(
-        Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces,
-        ComponentInstance componentInstance, Map<String, DataTypeDefinition> dataTypes, ToscaNodeTemplate nodeTemplate,
-        String instanceUniqueId,
-        Component parentComponent) {
+    private Object convertToToscaObject(String value) {
+        try {
+            ToscaMapValueConverter mapConverterInst = ToscaMapValueConverter.getInstance();
+            StringReader reader = new StringReader(value);
+            JsonReader jsonReader = new JsonReader(reader);
+            jsonReader.setLenient(true);
+            JsonElement jsonElement = JsonParser.parseReader(jsonReader);
+            if (jsonElement.isJsonObject()) {
+                JsonObject jsonObj = jsonElement.getAsJsonObject();
+                if (jsonObj.entrySet().size() == 1 && jsonObj.has(ToscaFunctions.GET_INPUT.getFunctionName())) {
+                    return mapConverterInst.handleComplexJsonValue(jsonElement);
+                }
+            }
+            return null;
+        } catch (Exception e) {
+            log.debug("convertToToscaValue failed to parse json value :", e);
+            return null;
+        }
+    }
 
 
-        if (MapUtils.isEmpty(componentInstanceInterfaces)
-            || !componentInstanceInterfaces.containsKey(instanceUniqueId)) {
+    private Object parseToIntIfPossible(final String value) {
+        final Integer intValue = Ints.tryParse(value);
+        return intValue == null ? value : intValue;
+    }
+
+    private void handleInstanceInterfaces(Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces,
+                                          ComponentInstance componentInstance, Map<String, DataTypeDefinition> dataTypes,
+                                          ToscaNodeTemplate nodeTemplate, String instanceUniqueId, Component parentComponent) {
+
+        if (MapUtils.isEmpty(componentInstanceInterfaces) || !componentInstanceInterfaces.containsKey(instanceUniqueId)) {
             nodeTemplate.setInterfaces(null);
             return;
         }
 
             nodeTemplate.setInterfaces(null);
             return;
         }
 
-        final List<ComponentInstanceInterface> currServiceInterfaces =
-            componentInstanceInterfaces.get(instanceUniqueId);
+        final List<ComponentInstanceInterface> currServiceInterfaces = componentInstanceInterfaces.get(instanceUniqueId);
 
         final Map<String, InterfaceDefinition> tmpInterfaces = new HashMap<>();
 
         final Map<String, InterfaceDefinition> tmpInterfaces = new HashMap<>();
-        currServiceInterfaces.forEach(instInterface -> tmpInterfaces.put(instInterface
-            .getUniqueId(), instInterface));
+        currServiceInterfaces.forEach(instInterface -> tmpInterfaces.put(instInterface.getUniqueId(), instInterface));
 
         final Map<String, Object> interfaceMap = interfacesOperationsConverter
 
         final Map<String, Object> interfaceMap = interfacesOperationsConverter
-            .getInterfacesMap(parentComponent, componentInstance, tmpInterfaces, dataTypes, isComponentOfTypeServiceProxy(componentInstance),
-                isComponentOfTypeServiceProxy(componentInstance));
+                .getInterfacesMap(parentComponent, componentInstance, tmpInterfaces, dataTypes, isComponentOfTypeServiceProxy(componentInstance));
 
         interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
         nodeTemplate.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap);
 
         interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
         nodeTemplate.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap);
@@ -1027,7 +1151,7 @@ public class ToscaExportHandler {
 
     private boolean isComponentOfTypeServiceProxy(ComponentInstance componentInstance) {
         return Objects.nonNull(componentInstance.getOriginType())
 
     private boolean isComponentOfTypeServiceProxy(ComponentInstance componentInstance) {
         return Objects.nonNull(componentInstance.getOriginType())
-            && componentInstance.getOriginType().getValue().equals("Service Proxy");
+                && componentInstance.getOriginType().getValue().equals("Service Proxy");
     }
 
     private void addComponentInstanceInputs(Map<String, DataTypeDefinition> dataTypes,
     }
 
     private void addComponentInstanceInputs(Map<String, DataTypeDefinition> dataTypes,
@@ -1037,24 +1161,32 @@ public class ToscaExportHandler {
         List<ComponentInstanceInput> instanceInputsList = componentInstancesInputs.get(instanceUniqueId);
         if (instanceInputsList != null) {
             instanceInputsList.forEach(input -> {
         List<ComponentInstanceInput> instanceInputsList = componentInstancesInputs.get(instanceUniqueId);
         if (instanceInputsList != null) {
             instanceInputsList.forEach(input -> {
-
-                Supplier<String> supplier = () -> input.getValue() != null && !Objects.isNull(input.getValue())
-                    ? input.getValue() : input.getDefaultValue();
+                Supplier<String> supplier = () -> input.getValue() != null && !Objects.isNull(input.getValue()) ? input.getValue()
+                        : input.getDefaultValue();
                 propertyConvertor.convertAndAddValue(dataTypes, props, input, supplier);
             });
         }
     }
 
                 propertyConvertor.convertAndAddValue(dataTypes, props, input, supplier);
             });
         }
     }
 
-    private void addPropertiesOfComponentInstance(
-        Map<String, List<ComponentInstanceProperty>> componentInstancesProperties,
-        Map<String, DataTypeDefinition> dataTypes, String instanceUniqueId,
-        Map<String, Object> props) {
+    private void addPropertiesOfComponentInstance(final Map<String, List<ComponentInstanceProperty>> componentInstancesProperties,
+                                                  final Map<String, DataTypeDefinition> dataTypes,
+                                                  final String instanceUniqueId,
+                                                  final Map<String, Object> props) {
 
         if (isNotEmpty(componentInstancesProperties)) {
             componentInstancesProperties.get(instanceUniqueId)
 
         if (isNotEmpty(componentInstancesProperties)) {
             componentInstancesProperties.get(instanceUniqueId)
-                // Converts and adds each value to property map
-                .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop,
-                    prop::getValue));
+                    // Converts and adds each value to property map
+                    .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop, prop::getValue));
+        }
+    }
+
+    private void addAttributesOfComponentInstance(final Map<String, List<ComponentInstanceAttribute>> componentInstancesAttributes,
+                                                  final String instanceUniqueId,
+                                                  final Map<String, Object> attribs) {
+
+        if (isNotEmpty(componentInstancesAttributes) && componentInstancesAttributes.containsKey(instanceUniqueId)) {
+            componentInstancesAttributes.get(instanceUniqueId)
+                    .forEach(attributeDefinition -> attributeConverter.convertAndAddValue(attribs, attributeDefinition));
         }
     }
 
         }
     }
 
@@ -1064,11 +1196,22 @@ public class ToscaExportHandler {
         List<PropertyDefinition> componentProperties = componentOfInstance.getProperties();
         if (isNotEmpty(componentProperties)) {
             componentProperties.stream()
         List<PropertyDefinition> componentProperties = componentOfInstance.getProperties();
         if (isNotEmpty(componentProperties)) {
             componentProperties.stream()
-                // Filters out properties with empty default values
-                .filter(prop -> StringUtils.isNotEmpty(prop.getDefaultValue()))
-                // Converts and adds each value to property map
-                .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop,
-                    prop::getDefaultValue));
+                    // Filters out properties with empty default values
+                    .filter(prop -> StringUtils.isNotEmpty(prop.getDefaultValue()))
+                    // Converts and adds each value to property map
+                    .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop, prop::getDefaultValue));
+        }
+    }
+
+    private void addAttributesOfParentComponent(final Component componentOfInstance, final Map<String, Object> attribs) {
+
+        final List<AttributeDefinition> componentAttributes = componentOfInstance.getAttributes();
+        if (isNotEmpty(componentAttributes)) {
+            componentAttributes.stream()
+                    // Filters out Attributes with empty default values
+                    .filter(attrib -> StringUtils.isNotEmpty(attrib.getDefaultValue()))
+                    // Converts and adds each value to attribute map
+                    .forEach(attributeDefinition -> attributeConverter.convertAndAddValue(attribs, attributeDefinition));
         }
     }
 
         }
     }
 
@@ -1081,7 +1224,7 @@ public class ToscaExportHandler {
             toscaNodeType.setDescription(component.getDescription());
         } else {
             String derivedFrom = null != component.getDerivedFromGenericType() ? component.getDerivedFromGenericType()
             toscaNodeType.setDescription(component.getDescription());
         } else {
             String derivedFrom = null != component.getDerivedFromGenericType() ? component.getDerivedFromGenericType()
-                : NATIVE_ROOT;
+                    : NATIVE_ROOT;
             toscaNodeType.setDerived_from(derivedFrom);
         }
         return toscaNodeType;
             toscaNodeType.setDerived_from(derivedFrom);
         }
         return toscaNodeType;
@@ -1097,8 +1240,8 @@ public class ToscaExportHandler {
         }
         Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
         componentInstances.stream()
         }
         Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
         componentInstances.stream()
-            .filter(this::isComponentOfTypeServiceProxy)
-            .forEach(inst -> serviceProxyInstanceList.put(inst.getToscaComponentName(), inst));
+                .filter(this::isComponentOfTypeServiceProxy)
+                .forEach(inst -> serviceProxyInstanceList.put(inst.getToscaComponentName(), inst));
         if (MapUtils.isEmpty(serviceProxyInstanceList)) {
             return res;
         }
         if (MapUtils.isEmpty(serviceProxyInstanceList)) {
             return res;
         }
@@ -1108,28 +1251,28 @@ public class ToscaExportHandler {
             componentParametersView.disableAll();
             componentParametersView.setIgnoreInterfaces(false);
             Either<Component, StorageOperationStatus> service = toscaOperationFacade
             componentParametersView.disableAll();
             componentParametersView.setIgnoreInterfaces(false);
             Either<Component, StorageOperationStatus> service = toscaOperationFacade
-                .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
+                    .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
             if (service.isRight()) {
                 log.debug("Failed to fetch original service component with id {} for instance {}",
             if (service.isRight()) {
                 log.debug("Failed to fetch original service component with id {} for instance {}",
-                    entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName());
+                        entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName());
                 return Either.right(ToscaError.GENERAL_ERROR);
             } else {
                 serviceComponent = service.left().value();
             }
 
             Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither =
                 return Either.right(ToscaError.GENERAL_ERROR);
             } else {
                 serviceComponent = service.left().value();
             }
 
             Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither =
-                interfaceLifecycleOperation.getAllInterfaceLifecycleTypes();
+                    interfaceLifecycleOperation.getAllInterfaceLifecycleTypes(serviceComponent.getModel());
             if (lifecycleTypeEither.isRight()) {
                 log.debug("Failed to retrieve global interface types :", lifecycleTypeEither.right().value());
                 return Either.right(ToscaError.GENERAL_ERROR);
             }
 
             List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value().values().stream()
             if (lifecycleTypeEither.isRight()) {
                 log.debug("Failed to retrieve global interface types :", lifecycleTypeEither.right().value());
                 return Either.right(ToscaError.GENERAL_ERROR);
             }
 
             List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value().values().stream()
-                .map(InterfaceDataDefinition::getType)
-                .collect(Collectors.toList());
+                    .map(InterfaceDataDefinition::getType)
+                    .collect(Collectors.toList());
             //Add interface types for local interfaces in the original service component for proxy
             //Add interface types for local interfaces in the original service component for proxy
-            Map<String, Object> localInterfaceTypes = addInterfaceTypeElement(serviceComponent,
-                allGlobalInterfaceTypes);
+            Map<String, Object> localInterfaceTypes = interfacesOperationsConverter.addInterfaceTypeElement(serviceComponent,
+                    allGlobalInterfaceTypes);
             if (MapUtils.isNotEmpty(localInterfaceTypes)) {
                 proxyInterfaceTypes.putAll(localInterfaceTypes);
             }
             if (MapUtils.isNotEmpty(localInterfaceTypes)) {
                 proxyInterfaceTypes.putAll(localInterfaceTypes);
             }
@@ -1151,8 +1294,8 @@ public class ToscaExportHandler {
         }
         Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
         List<ComponentInstance> proxyInst = componentInstances.stream()
         }
         Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
         List<ComponentInstance> proxyInst = componentInstances.stream()
-            .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceProxy.name()))
-            .collect(Collectors.toList());
+                .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceProxy.name()))
+                .collect(Collectors.toList());
         if (proxyInst != null && !proxyInst.isEmpty()) {
             for (ComponentInstance inst : proxyInst) {
                 serviceProxyInstanceList.put(inst.getToscaComponentName(), inst);
         if (proxyInst != null && !proxyInst.isEmpty()) {
             for (ComponentInstance inst : proxyInst) {
                 serviceProxyInstanceList.put(inst.getToscaComponentName(), inst);
@@ -1163,10 +1306,10 @@ public class ToscaExportHandler {
             return res;
         }
         Either<Resource, StorageOperationStatus> serviceProxyOrigin = toscaOperationFacade
             return res;
         }
         Either<Resource, StorageOperationStatus> serviceProxyOrigin = toscaOperationFacade
-            .getLatestByName("serviceProxy");
+                .getLatestByName("serviceProxy", null);
         if (serviceProxyOrigin.isRight()) {
             log.debug("Failed to fetch normative service proxy resource by tosca name, error {}",
         if (serviceProxyOrigin.isRight()) {
             log.debug("Failed to fetch normative service proxy resource by tosca name, error {}",
-                serviceProxyOrigin.right().value());
+                    serviceProxyOrigin.right().value());
             return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
         }
         Component origComponent = serviceProxyOrigin.left().value();
             return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
         }
         Component origComponent = serviceProxyOrigin.left().value();
@@ -1181,16 +1324,16 @@ public class ToscaExportHandler {
             componentParametersView.setIgnoreInterfaces(false);
             componentParametersView.setIgnoreRequirements(false);
             Either<Component, StorageOperationStatus> service = toscaOperationFacade
             componentParametersView.setIgnoreInterfaces(false);
             componentParametersView.setIgnoreRequirements(false);
             Either<Component, StorageOperationStatus> service = toscaOperationFacade
-                .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
+                    .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
             if (service.isRight()) {
                 log.debug("Failed to fetch resource with id {} for instance {}",
             if (service.isRight()) {
                 log.debug("Failed to fetch resource with id {} for instance {}",
-                    entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName());
+                        entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName());
             } else {
                 serviceComponent = service.left().value();
             }
 
             ToscaNodeType toscaNodeType = createProxyNodeType(componentCache, origComponent, serviceComponent,
             } else {
                 serviceComponent = service.left().value();
             }
 
             ToscaNodeType toscaNodeType = createProxyNodeType(componentCache, origComponent, serviceComponent,
-                entryProxy.getValue());
+                    entryProxy.getValue());
             nodeTypesMap.put(entryProxy.getKey(), toscaNodeType);
         }
 
             nodeTypesMap.put(entryProxy.getKey(), toscaNodeType);
         }
 
@@ -1205,14 +1348,14 @@ public class ToscaExportHandler {
             return;
         }
         final List<ComponentInstance> serviceSubstitutionInstanceList = componentInstances.stream()
             return;
         }
         final List<ComponentInstance> serviceSubstitutionInstanceList = componentInstances.stream()
-            .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceSubstitution.name()))
-            .collect(Collectors.toList());
+                .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceSubstitution.name()))
+                .collect(Collectors.toList());
         if (CollectionUtils.isNotEmpty(serviceSubstitutionInstanceList)) {
             for (ComponentInstance inst : serviceSubstitutionInstanceList) {
                 final Map<String, ToscaNodeType> nodeTypes =
         if (CollectionUtils.isNotEmpty(serviceSubstitutionInstanceList)) {
             for (ComponentInstance inst : serviceSubstitutionInstanceList) {
                 final Map<String, ToscaNodeType> nodeTypes =
-                    toscaNode.getNode_types() == null ? new HashMap<>() : toscaNode.getNode_types();
+                        toscaNode.getNode_types() == null ? new HashMap<>() : toscaNode.getNode_types();
                 convertInterfaceNodeType(new HashMap<>(), componentCache.get(inst.getSourceModelUid()), toscaNode,
                 convertInterfaceNodeType(new HashMap<>(), componentCache.get(inst.getSourceModelUid()), toscaNode,
-                    nodeTypes, true);
+                        nodeTypes, true);
             }
         }
     }
             }
         }
     }
@@ -1223,19 +1366,20 @@ public class ToscaExportHandler {
         String derivedFrom = ((Resource) origComponent).getToscaResourceName();
 
         toscaNodeType.setDerived_from(derivedFrom);
         String derivedFrom = ((Resource) origComponent).getToscaResourceName();
 
         toscaNodeType.setDerived_from(derivedFrom);
-        Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = dataTypeCache.getAll();
+        Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = applicationDataTypeCache.getAll(
+                origComponent.getModel());
         if (dataTypesEither.isRight()) {
             log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
         }
         Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
         Map<String, ToscaCapability> capabilities = this.capabilityRequirementConverter
         if (dataTypesEither.isRight()) {
             log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
         }
         Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
         Map<String, ToscaCapability> capabilities = this.capabilityRequirementConverter
-            .convertProxyCapabilities(componentCache, componentInstance, dataTypes);
+                .convertProxyCapabilities(componentCache, componentInstance, dataTypes);
 
         if (MapUtils.isNotEmpty(capabilities)) {
             toscaNodeType.setCapabilities(capabilities);
         }
         List<Map<String, ToscaRequirement>> proxyNodeTypeRequirements = this.capabilityRequirementConverter
 
         if (MapUtils.isNotEmpty(capabilities)) {
             toscaNodeType.setCapabilities(capabilities);
         }
         List<Map<String, ToscaRequirement>> proxyNodeTypeRequirements = this.capabilityRequirementConverter
-            .convertProxyRequirements(componentCache, componentInstance);
+                .convertProxyRequirements(componentCache, componentInstance);
         if (CollectionUtils.isNotEmpty(proxyNodeTypeRequirements)) {
             toscaNodeType.setRequirements(proxyNodeTypeRequirements);
         }
         if (CollectionUtils.isNotEmpty(proxyNodeTypeRequirements)) {
             toscaNodeType.setRequirements(proxyNodeTypeRequirements);
         }
@@ -1249,8 +1393,7 @@ public class ToscaExportHandler {
                 interfaceMap = proxyInterfaces.get();
             }
         } else {
                 interfaceMap = proxyInterfaces.get();
             }
         } else {
-            interfaceMap = interfacesOperationsConverter
-                .getInterfacesMapFromComponentInstance(proxyComponent, componentInstance, dataTypes, false, false);
+            interfaceMap = interfacesOperationsConverter.getInterfacesMapFromComponentInstance(proxyComponent, componentInstance, dataTypes, false);
 
         }
         interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
 
         }
         interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
@@ -1266,19 +1409,18 @@ public class ToscaExportHandler {
                                                                                        Component originComponent,
                                                                                        Map<String, Component> componentCache) {
 
                                                                                        Component originComponent,
                                                                                        Map<String, Component> componentCache) {
 
-        final List<Map<String, ToscaTemplateRequirement>> toscaRequirements;
         final List<RequirementCapabilityRelDef> requirementDefinitionList = filterRequirements(componentInstance,
         final List<RequirementCapabilityRelDef> requirementDefinitionList = filterRequirements(componentInstance,
-            relations);
+                relations);
         if (isNotEmpty(requirementDefinitionList)) {
             try {
         if (isNotEmpty(requirementDefinitionList)) {
             try {
-                toscaRequirements = buildRequirements(component, componentInstance,
-                    requirementDefinitionList, originComponent, componentCache);
-                if (!toscaRequirements.isEmpty()) {
+                final List<Map<String, ToscaTemplateRequirement>> toscaRequirements = buildRequirements(component, componentInstance,
+                        requirementDefinitionList, originComponent, componentCache);
+                if (CollectionUtils.isNotEmpty(toscaRequirements)) {
                     nodeTypeTemplate.setRequirements(toscaRequirements);
                 }
             } catch (final Exception e) {
                 log.debug("Failed to convert component instance requirements for the component instance {}. ",
                     nodeTypeTemplate.setRequirements(toscaRequirements);
                 }
             } catch (final Exception e) {
                 log.debug("Failed to convert component instance requirements for the component instance {}. ",
-                    componentInstance.getName(), e);
+                        componentInstance.getName(), e);
                 return Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
             }
         }
                 return Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
             }
         }
@@ -1291,14 +1433,15 @@ public class ToscaExportHandler {
                                                                           final List<RequirementCapabilityRelDef> filteredRelations,
                                                                           final Component originComponent,
                                                                           final Map<String, Component> componentCache)
                                                                           final List<RequirementCapabilityRelDef> filteredRelations,
                                                                           final Component originComponent,
                                                                           final Map<String, Component> componentCache)
-        throws ToscaExportException {
+            throws ToscaExportException {
 
         final List<Map<String, ToscaTemplateRequirement>> toscaRequirements = new ArrayList<>();
         for (RequirementCapabilityRelDef relationshipDefinition : filteredRelations) {
             final Map<String, ToscaTemplateRequirement> toscaTemplateRequirementMap =
 
         final List<Map<String, ToscaTemplateRequirement>> toscaRequirements = new ArrayList<>();
         for (RequirementCapabilityRelDef relationshipDefinition : filteredRelations) {
             final Map<String, ToscaTemplateRequirement> toscaTemplateRequirementMap =
-                buildRequirement(componentInstance, originComponent, component.getComponentInstances(),
-                    relationshipDefinition, componentCache);
-            toscaRequirements.add(toscaTemplateRequirementMap);
+                    buildRequirement(componentInstance, originComponent, component.getComponentInstances(), relationshipDefinition, componentCache);
+            if (MapUtils.isNotEmpty(toscaTemplateRequirementMap)) {
+                toscaRequirements.add(toscaTemplateRequirementMap);
+            }
         }
 
         return toscaRequirements;
         }
 
         return toscaRequirements;
@@ -1307,7 +1450,7 @@ public class ToscaExportHandler {
     private List<RequirementCapabilityRelDef> filterRequirements(ComponentInstance componentInstance,
                                                                  List<RequirementCapabilityRelDef> relations) {
         return relations.stream()
     private List<RequirementCapabilityRelDef> filterRequirements(ComponentInstance componentInstance,
                                                                  List<RequirementCapabilityRelDef> relations) {
         return relations.stream()
-            .filter(p -> componentInstance.getUniqueId().equals(p.getFromNode())).collect(Collectors.toList());
+                .filter(p -> componentInstance.getUniqueId().equals(p.getFromNode())).collect(Collectors.toList());
     }
 
     private Map<String, ToscaTemplateRequirement> buildRequirement(final ComponentInstance fromInstance,
     }
 
     private Map<String, ToscaTemplateRequirement> buildRequirement(final ComponentInstance fromInstance,
@@ -1315,28 +1458,27 @@ public class ToscaExportHandler {
                                                                    final List<ComponentInstance> instancesList,
                                                                    final RequirementCapabilityRelDef relationshipDefinition,
                                                                    final Map<String, Component> componentCache)
                                                                    final List<ComponentInstance> instancesList,
                                                                    final RequirementCapabilityRelDef relationshipDefinition,
                                                                    final Map<String, Component> componentCache)
-        throws ToscaExportException {
+            throws ToscaExportException {
 
         final Map<String, List<RequirementDefinition>> reqMap = fromOriginComponent.getRequirements();
 
         final Map<String, List<RequirementDefinition>> reqMap = fromOriginComponent.getRequirements();
-        final CapabilityRequirementRelationship capabilityRequirementRelationship = relationshipDefinition
-            .getRelationships().get(0);
+        if (MapUtils.isEmpty(reqMap)) {
+            return new HashMap<>();
+        }
+        final CapabilityRequirementRelationship capabilityRequirementRelationship = relationshipDefinition.getRelationships().get(0);
         final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation();
 
         final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation();
 
-        final ComponentInstance toInstance = instancesList.stream()
-            .filter(i -> relationshipDefinition.getToNode().equals(i.getUniqueId()))
-            .findFirst().orElse(null);
+        final ComponentInstance toInstance = instancesList.stream().filter(i -> relationshipDefinition.getToNode().equals(i.getUniqueId()))
+                .findFirst().orElse(null);
         if (toInstance == null) {
             final String errorMsg = String
         if (toInstance == null) {
             final String errorMsg = String
-                .format("Failed to find a relation from the node %s to the node %s", fromInstance.getName(),
-                    relationshipDefinition.getToNode());
+                    .format("Failed to find a relation from the node %s to the node %s", fromInstance.getName(),
+                            relationshipDefinition.getToNode());
             log.debug(errorMsg);
             throw new ToscaExportException(errorMsg);
         }
             log.debug(errorMsg);
             throw new ToscaExportException(errorMsg);
         }
-        final Optional<RequirementDefinition> reqOpt =
-            findRequirement(fromOriginComponent, reqMap, relationshipInfo, fromInstance.getUniqueId());
+        final Optional<RequirementDefinition> reqOpt = findRequirement(fromOriginComponent, reqMap, relationshipInfo, fromInstance.getUniqueId());
         if (reqOpt.isEmpty()) {
         if (reqOpt.isEmpty()) {
-            final String errorMsg = String
-                .format("Failed to find a requirement with uniqueId %s on a component with uniqueId %s",
+            final String errorMsg = String.format("Failed to find a requirement with uniqueId %s on a component with uniqueId %s",
                     relationshipInfo.getRequirementUid(), fromOriginComponent.getUniqueId());
             log.debug(errorMsg);
             throw new ToscaExportException(errorMsg);
                     relationshipInfo.getRequirementUid(), fromOriginComponent.getUniqueId());
             log.debug(errorMsg);
             throw new ToscaExportException(errorMsg);
@@ -1346,46 +1488,44 @@ public class ToscaExportHandler {
         filter.setIgnoreCapabilities(false);
         filter.setIgnoreGroups(false);
         final Either<Component, StorageOperationStatus> getOriginRes =
         filter.setIgnoreCapabilities(false);
         filter.setIgnoreGroups(false);
         final Either<Component, StorageOperationStatus> getOriginRes =
-            toscaOperationFacade.getToscaElement(toInstance.getActualComponentUid(), filter);
+                toscaOperationFacade.getToscaElement(toInstance.getActualComponentUid(), filter);
         if (getOriginRes.isRight()) {
             final String errorMsg = String.format(
         if (getOriginRes.isRight()) {
             final String errorMsg = String.format(
-                "Failed to build substituted name for the requirement %s. "
-                    + "Failed to get an origin component with uniqueId %s",
-                reqOpt.get().getName(), toInstance.getActualComponentUid());
+                    "Failed to build substituted name for the requirement %s. Failed to get an origin component with uniqueId %s",
+                    reqOpt.get().getName(), toInstance.getActualComponentUid());
             log.debug(errorMsg);
             throw new ToscaExportException(errorMsg);
         }
         final Component toOriginComponent = getOriginRes.left().value();
         Optional<CapabilityDefinition> capOpt = toOriginComponent.getCapabilities().get(reqOpt.get().getCapability()).stream()
             log.debug(errorMsg);
             throw new ToscaExportException(errorMsg);
         }
         final Component toOriginComponent = getOriginRes.left().value();
         Optional<CapabilityDefinition> capOpt = toOriginComponent.getCapabilities().get(reqOpt.get().getCapability()).stream()
-            .filter(c -> isCapabilityBelongToRelation(relationshipInfo, c)).findFirst();
+                .filter(c -> isCapabilityBelongToRelation(relationshipInfo, c)).findFirst();
         if (capOpt.isEmpty()) {
             capOpt = findCapability(relationshipInfo, toOriginComponent, fromOriginComponent, reqOpt.get());
             if (capOpt.isEmpty()) {
         if (capOpt.isEmpty()) {
             capOpt = findCapability(relationshipInfo, toOriginComponent, fromOriginComponent, reqOpt.get());
             if (capOpt.isEmpty()) {
-                final String errorMsg = String
-                    .format("Failed to find a capability with name %s on a component with uniqueId %s",
+                final String errorMsg = String.format("Failed to find a capability with name %s on a component with uniqueId %s",
                         relationshipInfo.getCapability(), fromOriginComponent.getUniqueId());
                 log.debug(errorMsg);
                 throw new ToscaExportException(errorMsg);
             }
         }
         return buildRequirement(fromOriginComponent, toOriginComponent, capOpt.get(), reqOpt.get(),
                         relationshipInfo.getCapability(), fromOriginComponent.getUniqueId());
                 log.debug(errorMsg);
                 throw new ToscaExportException(errorMsg);
             }
         }
         return buildRequirement(fromOriginComponent, toOriginComponent, capOpt.get(), reqOpt.get(),
-            capabilityRequirementRelationship, toInstance, componentCache);
+                capabilityRequirementRelationship, toInstance, componentCache);
     }
 
     private boolean isCapabilityBelongToRelation(RelationshipInfo reqAndRelationshipPair,
                                                  CapabilityDefinition capability) {
         return capability.getName().equals(reqAndRelationshipPair.getCapability()) && (capability.getOwnerId() != null
     }
 
     private boolean isCapabilityBelongToRelation(RelationshipInfo reqAndRelationshipPair,
                                                  CapabilityDefinition capability) {
         return capability.getName().equals(reqAndRelationshipPair.getCapability()) && (capability.getOwnerId() != null
-            && capability.getOwnerId().equals(reqAndRelationshipPair.getCapabilityOwnerId()));
+                && capability.getOwnerId().equals(reqAndRelationshipPair.getCapabilityOwnerId()));
     }
 
     private Optional<CapabilityDefinition> findCapability(RelationshipInfo reqAndRelationshipPair,
                                                           Component toOriginComponent, Component fromOriginComponent,
                                                           RequirementDefinition requirement) {
         Optional<CapabilityDefinition> cap = toOriginComponent.getCapabilities().get(requirement.getCapability())
     }
 
     private Optional<CapabilityDefinition> findCapability(RelationshipInfo reqAndRelationshipPair,
                                                           Component toOriginComponent, Component fromOriginComponent,
                                                           RequirementDefinition requirement) {
         Optional<CapabilityDefinition> cap = toOriginComponent.getCapabilities().get(requirement.getCapability())
-            .stream().filter(c -> c.getType().equals(requirement.getCapability())).findFirst();
-        if (!cap.isPresent()) {
+                .stream().filter(c -> c.getType().equals(requirement.getCapability())).findFirst();
+        if (cap.isEmpty()) {
             log.debug("Failed to find a capability with name {} on a component with uniqueId {}",
             log.debug("Failed to find a capability with name {} on a component with uniqueId {}",
-                reqAndRelationshipPair.getCapability(), fromOriginComponent.getUniqueId());
+                    reqAndRelationshipPair.getCapability(), fromOriginComponent.getUniqueId());
         }
         return cap;
     }
         }
         return cap;
     }
@@ -1397,31 +1537,31 @@ public class ToscaExportHandler {
                                                                    final CapabilityRequirementRelationship capabilityRequirementRelationship,
                                                                    final ComponentInstance toInstance,
                                                                    final Map<String, Component> componentCache)
                                                                    final CapabilityRequirementRelationship capabilityRequirementRelationship,
                                                                    final ComponentInstance toInstance,
                                                                    final Map<String, Component> componentCache)
-        throws ToscaExportException {
+            throws ToscaExportException {
 
         List<String> reducedPath = capability.getPath();
         if (capability.getOwnerId() != null) {
             reducedPath = capabilityRequirementConverter
 
         List<String> reducedPath = capability.getPath();
         if (capability.getOwnerId() != null) {
             reducedPath = capabilityRequirementConverter
-                .getReducedPathByOwner(capability.getPath(), capability.getOwnerId());
+                    .getReducedPathByOwner(capability.getPath(), capability.getOwnerId());
         }
         final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation();
         final Either<String, Boolean> capabilityNameEither = capabilityRequirementConverter.buildSubstitutedName(componentCache,
         }
         final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation();
         final Either<String, Boolean> capabilityNameEither = capabilityRequirementConverter.buildSubstitutedName(componentCache,
-            toOriginComponent, reducedPath, relationshipInfo.getCapability(), capability.getPreviousName());
+                toOriginComponent, reducedPath, relationshipInfo.getCapability(), capability.getPreviousName(), capability.getExternalName());
         if (capabilityNameEither.isRight()) {
             final String errorMsg = String.format(
         if (capabilityNameEither.isRight()) {
             final String errorMsg = String.format(
-                "Failed to build a substituted capability name for the capability with name %s on a component with uniqueId %s",
-                capabilityRequirementRelationship.getCapability(), toOriginComponent.getUniqueId());
+                    "Failed to build a substituted capability name for the capability with name %s on a component with uniqueId %s",
+                    capabilityRequirementRelationship.getCapability(), toOriginComponent.getUniqueId());
             log.debug(
             log.debug(
-                errorMsg);
+                    errorMsg);
             throw new ToscaExportException(errorMsg);
         }
         final Either<String, Boolean> requirementNameEither = capabilityRequirementConverter
             throw new ToscaExportException(errorMsg);
         }
         final Either<String, Boolean> requirementNameEither = capabilityRequirementConverter
-            .buildSubstitutedName(componentCache, fromOriginComponent,
-                requirement.getPath(), relationshipInfo.getRequirement(), requirement.getPreviousName());
+                .buildSubstitutedName(componentCache, fromOriginComponent,
+                        requirement.getPath(), relationshipInfo.getRequirement(), requirement.getPreviousName(), requirement.getExternalName());
         if (requirementNameEither.isRight()) {
             final String errorMsg = String.format("Failed to build a substituted requirement name for the requirement "
         if (requirementNameEither.isRight()) {
             final String errorMsg = String.format("Failed to build a substituted requirement name for the requirement "
-                    + "with name %s on a component with uniqueId %s",
-                capabilityRequirementRelationship.getRequirement(), fromOriginComponent.getUniqueId());
+                            + "with name %s on a component with uniqueId %s",
+                    capabilityRequirementRelationship.getRequirement(), fromOriginComponent.getUniqueId());
             log.debug(errorMsg);
             throw new ToscaExportException(errorMsg);
         }
             log.debug(errorMsg);
             throw new ToscaExportException(errorMsg);
         }
@@ -1440,10 +1580,9 @@ public class ToscaExportHandler {
                                                             Map<String, List<RequirementDefinition>> reqMap,
                                                             RelationshipInfo reqAndRelationshipPair,
                                                             String fromInstanceId) {
                                                             Map<String, List<RequirementDefinition>> reqMap,
                                                             RelationshipInfo reqAndRelationshipPair,
                                                             String fromInstanceId) {
-        for (List<RequirementDefinition> reqList : reqMap.values()) {
-            Optional<RequirementDefinition> reqOpt = reqList.stream().filter(
-                r -> isRequirementBelongToRelation(fromOriginComponent, reqAndRelationshipPair, r, fromInstanceId))
-                .findFirst();
+        for (final List<RequirementDefinition> reqList : reqMap.values()) {
+            final Optional<RequirementDefinition> reqOpt = reqList.stream()
+                    .filter(r -> isRequirementBelongToRelation(fromOriginComponent, reqAndRelationshipPair, r, fromInstanceId)).findFirst();
             if (reqOpt.isPresent()) {
                 return reqOpt;
             }
             if (reqOpt.isPresent()) {
                 return reqOpt;
             }
@@ -1458,63 +1597,57 @@ public class ToscaExportHandler {
      */
     private boolean isRequirementBelongToRelation(Component originComponent, RelationshipInfo reqAndRelationshipPair,
                                                   RequirementDefinition requirement, String fromInstanceId) {
      */
     private boolean isRequirementBelongToRelation(Component originComponent, RelationshipInfo reqAndRelationshipPair,
                                                   RequirementDefinition requirement, String fromInstanceId) {
+        if (originComponent.isService() && requirement.getUniqueId().equals(reqAndRelationshipPair.getRequirementUid())) {
+            return true;
+        }
         if (!StringUtils.equals(requirement.getName(), reqAndRelationshipPair.getRequirement())) {
         if (!StringUtils.equals(requirement.getName(), reqAndRelationshipPair.getRequirement())) {
-            log.debug("Failed to find a requirement with name {} and  reqAndRelationshipPair {}",
-                requirement.getName(), reqAndRelationshipPair.getRequirement());
+            log.debug("Failed to find a requirement with name {} and  reqAndRelationshipPair {}", requirement.getName(),
+                    reqAndRelationshipPair.getRequirement());
             return false;
         }
             return false;
         }
-        return ModelConverter.isAtomicComponent(originComponent) ||
-            isRequirementBelongToOwner(reqAndRelationshipPair, requirement, fromInstanceId, originComponent);
+        return ModelConverter.isAtomicComponent(originComponent) || isRequirementBelongToOwner(reqAndRelationshipPair, requirement, fromInstanceId,
+                originComponent);
     }
 
     }
 
-    private boolean isRequirementBelongToOwner(RelationshipInfo reqAndRelationshipPair,
-                                               RequirementDefinition requirement, String fromInstanceId,
+    private boolean isRequirementBelongToOwner(RelationshipInfo reqAndRelationshipPair, RequirementDefinition requirement, String fromInstanceId,
                                                Component originComponent) {
                                                Component originComponent) {
-        return StringUtils.equals(requirement.getOwnerId(), reqAndRelationshipPair.getRequirementOwnerId())
-            || (isCvfc(originComponent) && StringUtils
-            .equals(fromInstanceId, reqAndRelationshipPair.getRequirementOwnerId())
-            || StringUtils.equals(requirement.getOwnerId(), originComponent.getUniqueId()));
+        return StringUtils.equals(requirement.getOwnerId(), reqAndRelationshipPair.getRequirementOwnerId()) || (
+                isCvfc(originComponent) && StringUtils.equals(fromInstanceId, reqAndRelationshipPair.getRequirementOwnerId()) || StringUtils
+                        .equals(requirement.getOwnerId(), originComponent.getUniqueId()));
     }
 
     private boolean isCvfc(Component component) {
     }
 
     private boolean isCvfc(Component component) {
-        return component.getComponentType() == ComponentTypeEnum.RESOURCE &&
-            ((Resource) component).getResourceType() == ResourceTypeEnum.CVFC;
+        return component.getComponentType() == ComponentTypeEnum.RESOURCE && ((Resource) component).getResourceType() == ResourceTypeEnum.CVFC;
     }
 
     }
 
-    private Either<SubstitutionMapping, ToscaError> convertCapabilities(Component component,
-                                                                        SubstitutionMapping substitutionMappings,
-                                                                        Map<String, Component> componentCache) {
-
-        Either<SubstitutionMapping, ToscaError> result = Either.left(substitutionMappings);
-        Either<Map<String, String[]>, ToscaError> toscaCapabilitiesRes = capabilityRequirementConverter
-            .convertSubstitutionMappingCapabilities(componentCache, component);
+    private Either<Map<String, String[]>, ToscaError> convertSubstitutionMappingCapabilities(final Component component,
+                                                                                             final Map<String, Component> componentCache) {
+        Either<Map<String, String[]>, ToscaError> toscaCapabilitiesRes =
+                capabilityRequirementConverter.convertSubstitutionMappingCapabilities(componentCache, component);
         if (toscaCapabilitiesRes.isRight()) {
         if (toscaCapabilitiesRes.isRight()) {
-            result = Either.right(toscaCapabilitiesRes.right().value());
             log.debug("Failed convert capabilities for the component {}. ", component.getName());
             log.debug("Failed convert capabilities for the component {}. ", component.getName());
-        } else if (isNotEmpty(toscaCapabilitiesRes.left().value())) {
-            substitutionMappings.setCapabilities(toscaCapabilitiesRes.left().value());
+            return Either.right(toscaCapabilitiesRes.right().value());
+        }
+        if (isNotEmpty(toscaCapabilitiesRes.left().value())) {
             log.debug("Finish convert capabilities for the component {}. ", component.getName());
             log.debug("Finish convert capabilities for the component {}. ", component.getName());
+            return Either.left(toscaCapabilitiesRes.left().value());
         }
         log.debug("Finished to convert capabilities for the component {}. ", component.getName());
         }
         log.debug("Finished to convert capabilities for the component {}. ", component.getName());
-        return result;
+
+        return Either.left(Collections.emptyMap());
     }
 
     }
 
-    private Either<ToscaNodeType, ToscaError> convertCapabilities(Map<String, Component> componentsCache,
-                                                                  Component component, ToscaNodeType nodeType,
+    private Either<ToscaNodeType, ToscaError> convertCapabilities(Map<String, Component> componentsCache, Component component, ToscaNodeType nodeType,
                                                                   Map<String, DataTypeDefinition> dataTypes) {
                                                                   Map<String, DataTypeDefinition> dataTypes) {
-        Map<String, ToscaCapability> toscaCapabilities = capabilityRequirementConverter
-            .convertCapabilities(componentsCache, component,
-                dataTypes);
+        Map<String, ToscaCapability> toscaCapabilities = capabilityRequirementConverter.convertCapabilities(componentsCache, component, dataTypes);
         if (!toscaCapabilities.isEmpty()) {
             nodeType.setCapabilities(toscaCapabilities);
         }
         log.debug("Finish convert Capabilities for node type");
         if (!toscaCapabilities.isEmpty()) {
             nodeType.setCapabilities(toscaCapabilities);
         }
         log.debug("Finish convert Capabilities for node type");
-
         return Either.left(nodeType);
     }
 
         return Either.left(nodeType);
     }
 
-    private Map<String, ToscaTemplateArtifact> convertToNodeTemplateArtifacts(
-        Map<String, ToscaArtifactDataDefinition> artifacts) {
+    private Map<String, ToscaTemplateArtifact> convertToNodeTemplateArtifacts(Map<String, ToscaArtifactDataDefinition> artifacts) {
         if (artifacts == null) {
             return null;
         }
         if (artifacts == null) {
             return null;
         }
@@ -1523,68 +1656,48 @@ public class ToscaExportHandler {
             ToscaTemplateArtifact artifact = new ToscaTemplateArtifact();
             artifact.setFile(entry.getValue().getFile());
             artifact.setType(entry.getValue().getType());
             ToscaTemplateArtifact artifact = new ToscaTemplateArtifact();
             artifact.setFile(entry.getValue().getFile());
             artifact.setType(entry.getValue().getType());
+            artifact.setProperties(entry.getValue().getProperties());
             arts.put(entry.getKey(), artifact);
         }
         return arts;
     }
 
             arts.put(entry.getKey(), artifact);
         }
         return arts;
     }
 
-    protected NodeFilter convertToNodeTemplateNodeFilterComponent(CINodeFilterDataDefinition inNodeFilter) {
+    private NodeFilter convertToNodeTemplateNodeFilterComponent(CINodeFilterDataDefinition inNodeFilter) {
         if (inNodeFilter == null) {
             return null;
         }
         NodeFilter nodeFilter = new NodeFilter();
         if (inNodeFilter == null) {
             return null;
         }
         NodeFilter nodeFilter = new NodeFilter();
-
-        ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities =
-            inNodeFilter.getCapabilities();
-
-        ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> origProperties = inNodeFilter.getProperties();
-
+        ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities = inNodeFilter.getCapabilities();
+        ListDataDefinition<PropertyFilterDataDefinition> origProperties = inNodeFilter.getProperties();
         List<Map<String, CapabilityFilter>> capabilitiesCopy = new ArrayList<>();
         List<Map<String, CapabilityFilter>> capabilitiesCopy = new ArrayList<>();
-        List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
-
         copyNodeFilterCapabilitiesTemplate(origCapabilities, capabilitiesCopy);
         copyNodeFilterCapabilitiesTemplate(origCapabilities, capabilitiesCopy);
-        copyNodeFilterProperties(origProperties, propertiesCopy);
-
         if (CollectionUtils.isNotEmpty(capabilitiesCopy)) {
             nodeFilter.setCapabilities(capabilitiesCopy);
         }
         if (CollectionUtils.isNotEmpty(capabilitiesCopy)) {
             nodeFilter.setCapabilities(capabilitiesCopy);
         }
-
+        final List<Map<String, List<Object>>> propertiesCopy = copyNodeFilterProperties(origProperties);
         if (CollectionUtils.isNotEmpty(propertiesCopy)) {
             nodeFilter.setProperties(propertiesCopy);
         }
         if (CollectionUtils.isNotEmpty(propertiesCopy)) {
             nodeFilter.setProperties(propertiesCopy);
         }
-
         nodeFilter.setTosca_id(cloneToscaId(inNodeFilter.getTosca_id()));
         nodeFilter.setTosca_id(cloneToscaId(inNodeFilter.getTosca_id()));
-
         nodeFilter = (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
         nodeFilter = (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
-
         return nodeFilter;
     }
 
         return nodeFilter;
     }
 
-    private NodeFilter convertToSubstitutionFilterComponent(
-        final SubstitutionFilterDataDefinition substitutionFilterDataDefinition) {
-
+    private NodeFilter convertToSubstitutionFilterComponent(final SubstitutionFilterDataDefinition substitutionFilterDataDefinition) {
         if (substitutionFilterDataDefinition == null) {
             return null;
         }
         NodeFilter nodeFilter = new NodeFilter();
         if (substitutionFilterDataDefinition == null) {
             return null;
         }
         NodeFilter nodeFilter = new NodeFilter();
-
-        ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> origProperties =
-            substitutionFilterDataDefinition.getProperties();
-        List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
-
-        copySubstitutionFilterProperties(origProperties, propertiesCopy);
-
-        if (CollectionUtils.isNotEmpty(propertiesCopy)) {
+        final List<Map<String, List<Object>>> propertiesCopy = copySubstitutionPropertiesFilter(substitutionFilterDataDefinition.getProperties());
+        if (!propertiesCopy.isEmpty()) {
             nodeFilter.setProperties(propertiesCopy);
         }
         nodeFilter.setTosca_id(cloneToscaId(substitutionFilterDataDefinition.getTosca_id()));
             nodeFilter.setProperties(propertiesCopy);
         }
         nodeFilter.setTosca_id(cloneToscaId(substitutionFilterDataDefinition.getTosca_id()));
-
         return (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
     }
 
     private Object cloneToscaId(Object toscaId) {
         return (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
     }
 
     private Object cloneToscaId(Object toscaId) {
-        return Objects.isNull(toscaId) ? null
-            : cloneObjectFromYml(toscaId, toscaId.getClass());
+        return Objects.isNull(toscaId) ? null : cloneObjectFromYml(toscaId, toscaId.getClass());
     }
 
     private Object cloneObjectFromYml(Object objToClone, Class classOfObj) {
     }
 
     private Object cloneObjectFromYml(Object objToClone, Class classOfObj) {
@@ -1592,171 +1705,192 @@ public class ToscaExportHandler {
         return yamlUtil.yamlToObject(objectAsYml, classOfObj);
     }
 
         return yamlUtil.yamlToObject(objectAsYml, classOfObj);
     }
 
-    private void copyNodeFilterCapabilitiesTemplate(
-        ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities,
-        List<Map<String, CapabilityFilter>> capabilitiesCopy) {
-        if (origCapabilities == null || origCapabilities.getListToscaDataDefinition() == null ||
-            origCapabilities.getListToscaDataDefinition().isEmpty()) {
+    private void copyNodeFilterCapabilitiesTemplate(ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities,
+                                                    List<Map<String, CapabilityFilter>> capabilitiesCopy) {
+        if (origCapabilities == null || origCapabilities.getListToscaDataDefinition() == null || origCapabilities.getListToscaDataDefinition()
+                .isEmpty()) {
             return;
         }
         for (RequirementNodeFilterCapabilityDataDefinition capability : origCapabilities.getListToscaDataDefinition()) {
             Map<String, CapabilityFilter> capabilityFilterCopyMap = new HashMap<>();
             return;
         }
         for (RequirementNodeFilterCapabilityDataDefinition capability : origCapabilities.getListToscaDataDefinition()) {
             Map<String, CapabilityFilter> capabilityFilterCopyMap = new HashMap<>();
-            CapabilityFilter capabilityFilter = new CapabilityFilter();
-            List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
-            copyNodeFilterProperties(capability.getProperties(), propertiesCopy);
-            capabilityFilter.setProperties(propertiesCopy);
+            final var capabilityFilter = new CapabilityFilter();
+            capabilityFilter.setProperties(copyNodeFilterProperties(capability.getProperties()));
             capabilityFilterCopyMap.put(capability.getName(), capabilityFilter);
             capabilitiesCopy.add(capabilityFilterCopyMap);
         }
     }
 
             capabilityFilterCopyMap.put(capability.getName(), capabilityFilter);
             capabilitiesCopy.add(capabilityFilterCopyMap);
         }
     }
 
-    private void copyNodeFilterProperties(
-        ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> origProperties,
-        List<Map<String, List<Object>>> propertiesCopy) {
-        if (origProperties == null || origProperties.getListToscaDataDefinition() == null ||
-            origProperties.isEmpty()) {
-            return;
+    private List<Map<String, List<Object>>> copyNodeFilterProperties(final ListDataDefinition<PropertyFilterDataDefinition> origProperties) {
+        if (origProperties == null || origProperties.getListToscaDataDefinition() == null || origProperties.isEmpty()) {
+            return Collections.emptyList();
         }
         }
-        Map<String, List<Object>> propertyMapCopy = new HashMap<>();
-        for (RequirementNodeFilterPropertyDataDefinition propertyDataDefinition : origProperties
-            .getListToscaDataDefinition()) {
-            for (String propertyInfoEntry : propertyDataDefinition.getConstraints()) {
-                Map propertyValObj = new YamlUtil().yamlToObject(propertyInfoEntry, Map.class);
-                String propertyName = propertyDataDefinition.getName();
-                if (propertyMapCopy.containsKey(propertyName)) {
-                    addPropertyConstraintValueToList(propertyName, propertyValObj, propertyMapCopy.get(propertyName));
-                } else {
-                    if (propertyName != null) {
-                        List<Object> propsList = new ArrayList<>();
-                        addPropertyConstraintValueToList(propertyName, propertyValObj, propsList);
-                        propertyMapCopy.put(propertyName, propsList);
-                    } else {
-                        propertyMapCopy.putAll(propertyValObj);
+        List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
+        Map<String, List<Object>> propertyFilterDefinitionMap = new HashMap<>();
+        for (final PropertyFilterDataDefinition propertyFilter : origProperties.getListToscaDataDefinition()) {
+            final String propertyName = propertyFilter.getName();
+            for (final PropertyFilterConstraintDataDefinition filterConstraint : propertyFilter.getConstraints()) {
+                propertyFilterDefinitionMap.compute(propertyName, (propertyName1, constraints) -> {
+                    if (constraints == null) {
+                        constraints = new ArrayList<>();
                     }
                     }
-                }
+                    constraints.add(buildNodeFilterValue(filterConstraint));
+                    return constraints;
+                });
             }
         }
             }
         }
-        propertyMapCopy.entrySet().stream().forEach(entry ->
-            addCalculatedConstraintsIntoPropertiesList(propertiesCopy, entry));
+        propertyFilterDefinitionMap.entrySet().stream()
+                .map(entry -> Map.of(entry.getKey(), entry.getValue()))
+                .forEach(propertiesCopy::add);
+        return propertiesCopy;
     }
 
     }
 
-    private void copySubstitutionFilterProperties(
-        final ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> origProperties,
-        final List<Map<String, List<Object>>> propertiesCopy) {
-        if (origProperties == null || origProperties.getListToscaDataDefinition() == null ||
-            origProperties.isEmpty()) {
-            return;
+    private List<Map<String, List<Object>>> copySubstitutionPropertiesFilter(
+            final ListDataDefinition<SubstitutionFilterPropertyDataDefinition> origProperties) {
+
+        if (origProperties == null || origProperties.getListToscaDataDefinition() == null || origProperties.isEmpty()) {
+            return Collections.emptyList();
         }
         }
-        final Map<String, List<Object>> propertyMapCopy = new HashMap<>();
-        for (final RequirementSubstitutionFilterPropertyDataDefinition propertyDataDefinition : origProperties
-            .getListToscaDataDefinition()) {
-            for (final String propertyInfoEntry : propertyDataDefinition.getConstraints()) {
-                final Map<String, List<Object>> propertyValObj = new YamlUtil()
-                    .yamlToObject(propertyInfoEntry, Map.class);
-                final String propertyName = propertyDataDefinition.getName();
-                if (propertyMapCopy.containsKey(propertyName)) {
-                    addPropertyConstraintValueToList(propertyName, propertyValObj, propertyMapCopy.get(propertyName));
-                } else {
-                    if (propertyName != null) {
-                        final List<Object> propsList = new ArrayList<>();
-                        addPropertyConstraintValueToList(propertyName, propertyValObj, propsList);
-                        propertyMapCopy.put(propertyName, propsList);
-                    } else {
-                        propertyMapCopy.putAll(propertyValObj);
+        List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
+        Map<String, List<Object>> propertyFilterDefinitionMap = new HashMap<>();
+        for (final SubstitutionFilterPropertyDataDefinition propertyFilter : origProperties.getListToscaDataDefinition()) {
+            final String propertyName = propertyFilter.getName();
+            for (final PropertyFilterConstraintDataDefinition filterConstraint : propertyFilter.getConstraints()) {
+                propertyFilterDefinitionMap.compute(propertyName, (propertyName1, constraints) -> {
+                    if (constraints == null) {
+                        constraints = new ArrayList<>();
                     }
                     }
-                }
+                    constraints.add(buildNodeFilterValue(filterConstraint));
+                    return constraints;
+                });
             }
         }
             }
         }
-        propertyMapCopy.entrySet().forEach(entry ->
-            addCalculatedConstraintsIntoPropertiesList(propertiesCopy, entry));
+        propertyFilterDefinitionMap.entrySet().stream()
+                .map(entry -> Map.of(entry.getKey(), entry.getValue()))
+                .forEach(propertiesCopy::add);
+        return propertiesCopy;
     }
 
     }
 
-    private void addPropertyConstraintValueToList(String propertyName, Map<String, List<Object>> propertyValObj, List<Object> propsList) {
-        if (propertyValObj.containsKey(propertyName)) {
-            propsList.add(propertyValObj.get(propertyName));
-        } else {
-            propsList.add(propertyValObj);
+    private static Object buildNodeFilterValue(final PropertyFilterConstraintDataDefinition filterConstraint) {
+        if (filterConstraint.getValue() instanceof ToscaFunction) {
+            return Map.of(filterConstraint.getOperator().getType(), ((ToscaFunction) filterConstraint.getValue()).getJsonObjectValue());
+        }
+        if (filterConstraint.getValue() instanceof List) {
+            if (((List<?>) filterConstraint.getValue()).get(0) instanceof ToscaFunction) {
+                List<Object> toscaFunctionList = new ArrayList<>();
+                ((List<?>) filterConstraint.getValue()).forEach(toscaFunctionValue -> toscaFunctionList.add(
+                        ((ToscaFunction) toscaFunctionValue).getJsonObjectValue()));
+                return Map.of(filterConstraint.getOperator().getType(), toscaFunctionList);
+            }
         }
         }
+        if (doesTypeNeedConvertingToIntOrFloat(filterConstraint.getOriginalType(), filterConstraint.getValue())) {
+            ToscaType toscaType = ToscaType.getToscaType(
+                    filterConstraint.getValue() instanceof List ? ToscaType.LIST.getType() : filterConstraint.getOriginalType());
+            filterConstraint.setValue(toscaType.convert(String.valueOf(filterConstraint.getValue())));
+        } else if (ConstraintType.LENGTH.getType().equals(filterConstraint.getOperator().getType()) ||
+                ConstraintType.MIN_LENGTH.getType().equals(filterConstraint.getOperator().getType()) ||
+                ConstraintType.MAX_LENGTH.getType().equals(filterConstraint.getOperator().getType())) {
+            filterConstraint.setValue(Integer.valueOf(String.valueOf(filterConstraint.getValue())));
+        }
+        if (doesTypeNeedConvertingToBoolean(filterConstraint.getOriginalType())) {
+            filterConstraint.setValue(ToscaType.getToscaType(filterConstraint.getOriginalType()).convert(
+                String.valueOf(filterConstraint.getValue())));
+        }
+        return Map.of(filterConstraint.getOperator().getType(), filterConstraint.getValue());
     }
 
     }
 
-    private void addCalculatedConstraintsIntoPropertiesList(List<Map<String, List<Object>>> propertiesCopy,
-                                                            Entry<String, List<Object>> entry) {
-        Map<String, List<Object>> tempMap = new HashMap<>();
-        tempMap.put(entry.getKey(), entry.getValue());
-        propertiesCopy.add(tempMap);
+    private static boolean doesTypeNeedConvertingToIntOrFloat(String propertyType, Object value) {
+        if (value instanceof List && ((List<?>) value).get(0) instanceof LinkedHashMap
+                && ((LinkedHashMap) ((List<?>) value).get(0)).get("type") != null) {
+            return false;
+        }
+        return ToscaType.INTEGER.getType().equals(propertyType) || ToscaType.FLOAT.getType().equals(propertyType);
     }
 
     }
 
-    private static class CustomRepresenter extends Representer {
+    private static boolean doesTypeNeedConvertingToBoolean(String propertyType) {
+        return ToscaType.BOOLEAN.getType().equals(propertyType);
+    }
 
 
-        CustomRepresenter() {
-            super();
-            this.representers.put(ToscaPropertyAssignment.class, new RepresentToscaPropertyAssignment());
-            this.representers.put(ToscaAttribute.class, new RepresentToscaAttribute());
-            // null representer is exceptional and it is stored as an instance
-            // variable.
-            this.nullRepresenter = new RepresentNull();
+    private Map<String, String[]> buildSubstitutionMappingPropertyMapping(final Component component) {
+        if (component == null || CollectionUtils.isEmpty(component.getInputs())) {
+            return Collections.emptyMap();
+        }
+        Map<String, String[]> propertyMapping = new HashMap<>();
+        List<InputDefinition> propertyMappedInputList = component.getInputs().stream().filter(InputDefinition::isMappedToComponentProperty).collect(
+                Collectors.toList());
+
+        if (CollectionUtils.isNotEmpty(propertyMappedInputList)) {
+            propertyMappedInputList.forEach(inputDefinition -> {
+                if (StringUtils.isNotEmpty(inputDefinition.getPropertyId())) {
+                    Optional<PropertyDefinition> property = component.getProperties().stream()
+                            .filter(propertyDefinition -> propertyDefinition.getUniqueId().equals(inputDefinition.getPropertyId())).findFirst();
+                    if (property.isPresent()) {
+                        propertyMapping.put(property.get().getName(), new String[]{inputDefinition.getName()});
+                    }
+                } else {
+                    propertyMapping.put(inputDefinition.getName(), new String[]{inputDefinition.getName()});
+                }
+            });
+        }
+        return propertyMapping;
+    }
 
 
+    private Map<String, String[]> buildSubstitutionMappingAttributesMapping(final Component component) {
+        if (component == null || CollectionUtils.isEmpty(component.getOutputs())) {
+            return Collections.emptyMap();
         }
         }
+        return component.getOutputs().stream().map(AttributeDataDefinition::getName)
+                .collect(Collectors.toMap(outputName -> outputName, outputName -> new String[]{outputName}, (outputName1, outputName2) -> outputName1));
+    }
 
 
-        private class RepresentToscaAttribute implements Represent {
+    private Optional<Map<String, ToscaProperty>> getProxyNodeTypeProperties(Component proxyComponent, Map<String, DataTypeDefinition> dataTypes) {
+        if (Objects.isNull(proxyComponent)) {
+            return Optional.empty();
+        }
+        final var proxyProperties = convertInputsToProperties(dataTypes, proxyComponent.getInputs(), proxyComponent.getUniqueId());
+        if (CollectionUtils.isNotEmpty(proxyComponent.getProperties())) {
+            proxyProperties.putAll(proxyComponent.getProperties().stream()
+                    .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, proxyComponent.getInputs())).collect(Collectors
+                            .toMap(PropertyDataDefinition::getName,
+                                    property -> propertyConvertor.convertProperty(dataTypes, property, PropertyType.PROPERTY))));
+        }
+        return MapUtils.isNotEmpty(proxyProperties) ? Optional.of(proxyProperties) : Optional.empty();
+    }
 
 
-            @Override
-            public Node representData(Object data) {
-                final ToscaAttribute toscaAttribute = (ToscaAttribute) data;
-                return represent(toscaAttribute.asToscaMap());
-            }
+    private Map<String, ToscaProperty> convertInputsToProperties(Map<String, DataTypeDefinition> dataTypes, List<InputDefinition> componentInputs,
+                                                                 String componentUniqueId) {
+        if (CollectionUtils.isEmpty(componentInputs)) {
+            return new HashMap<>();
         }
         }
+        return componentInputs.stream().filter(input -> componentUniqueId.equals(input.getInstanceUniqueId()))
+                .collect(Collectors.toMap(InputDefinition::getName, i -> propertyConvertor.convertProperty(dataTypes, i, PropertyType.INPUT)));
+    }
 
 
-        private class RepresentToscaPropertyAssignment implements Represent {
+    private Optional<Map<String, Object>> getProxyNodeTypeInterfaces(Component proxyComponent, Map<String, DataTypeDefinition> dataTypes) {
+        if (Objects.isNull(proxyComponent) || MapUtils.isEmpty(proxyComponent.getInterfaces())) {
+            return Optional.empty();
+        }
+        Map<String, InterfaceDefinition> proxyComponentInterfaces = proxyComponent.getInterfaces();
+        //Unset artifact path for operation implementation for proxy node types as for operations with artifacts it is
 
 
-            public Node representData(Object data) {
-                final ToscaPropertyAssignment toscaOperationAssignment = (ToscaPropertyAssignment) data;
-                if (toscaOperationAssignment.getValue() instanceof String) {
-                    final String stringValue = (String) toscaOperationAssignment.getValue();
-                    if (isPropertyOrAttributeFunction(stringValue)) {
-                        return representGetAttribute(stringValue);
-                    }
+        // always available in the proxy node template
+        removeOperationImplementationForProxyNodeType(proxyComponentInterfaces);
+        return Optional.ofNullable(interfacesOperationsConverter.getInterfacesMap(proxyComponent, null, proxyComponentInterfaces, dataTypes, false));
+    }
 
 
-                    return representScalar(Tag.STR, stringValue);
-                }
-                return represent(null);
-            }
+    private Configuration getConfiguration() {
+        return ConfigurationManager.getConfigurationManager().getConfiguration();
+    }
 
 
-            public Node representGetAttribute(final String getAttributeFunction) {
-                return represent(new Yaml().load(getAttributeFunction));
-            }
+    private static class CustomRepresenter extends Representer {
 
 
-            public boolean isPropertyOrAttributeFunction(final String value) {
-                try {
-                    final Yaml yaml = new Yaml();
-                    final Object yamlObj = yaml.load(value);
-                    if (!(yamlObj instanceof Map)) {
-                        return false;
-                    }
-                    final Map<String, Object> getAttributeMap = (Map) yamlObj;
-                    if (getAttributeMap.size() != 1) {
-                        return false;
-                    }
-                    final List<String> functionList = Arrays
-                        .asList(GET_ATTRIBUTE.getFunctionName(), GET_INPUT.getFunctionName(),
-                            GET_PROPERTY.getFunctionName());
-                    final Optional<String> function = getAttributeMap.keySet().stream()
-                        .filter(key -> functionList.stream().anyMatch(function1 -> function1.equals(key))).findFirst();
+        CustomRepresenter() {
+            super();
+            this.representers.put(ToscaPropertyAssignment.class, new RepresentToscaPropertyAssignment());
+            this.representers.put(ToscaAttribute.class, new RepresentToscaAttribute());
+            // null representer is exceptional and it is stored as an instance
 
 
-                    if (function.isEmpty()) {
-                        return false;
-                    }
-                    final String functionName = function.get();
-                    final Object getAttributeValueObj = getAttributeMap.get(functionName);
-                    if (GET_INPUT.getFunctionName().equals(functionName)) {
-                        return validateGetInputValue(getAttributeValueObj);
-                    } else {
-                        return validateGetPropertyOrAttributeValue(getAttributeValueObj);
-                    }
-                } catch (final Exception ignored) {
-                    return false;
-                }
-            }
+            // variable.
+            this.nullRepresenter = new RepresentNull();
         }
 
         public boolean validateGetInputValue(final Object valueObj) {
         }
 
         public boolean validateGetInputValue(final Object valueObj) {
@@ -1766,7 +1900,6 @@ public class ToscaExportHandler {
             if (valueObj instanceof List) {
                 return ((List) valueObj).size() > 1;
             }
             if (valueObj instanceof List) {
                 return ((List) valueObj).size() > 1;
             }
-
             return true;
         }
 
             return true;
         }
 
@@ -1774,13 +1907,11 @@ public class ToscaExportHandler {
             if (valueObj instanceof List) {
                 return ((List) valueObj).size() > 1;
             }
             if (valueObj instanceof List) {
                 return ((List) valueObj).size() > 1;
             }
-
             return false;
         }
 
         @Override
             return false;
         }
 
         @Override
-        protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue,
-                                                      Tag customTag) {
+        protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue, Tag customTag) {
             if (propertyValue == null) {
                 return null;
             }
             if (propertyValue == null) {
                 return null;
             }
@@ -1791,27 +1922,31 @@ public class ToscaExportHandler {
             if (javaBean instanceof ToscaRelationshipTemplate && "name".equals(property.getName())) {
                 return null;
             }
             if (javaBean instanceof ToscaRelationshipTemplate && "name".equals(property.getName())) {
                 return null;
             }
-
+            if (javaBean instanceof ToscaPropertyConstraint) {
+                return handleToscaPropertyConstraint((ToscaPropertyConstraint) javaBean, property, propertyValue, customTag);
+            }
             removeDefaultP(propertyValue);
             NodeTuple defaultNode = super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
             removeDefaultP(propertyValue);
             NodeTuple defaultNode = super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
-
             if (javaBean instanceof ToscaTopolgyTemplate && "relationshipTemplates".equals(property.getName())) {
                 return new NodeTuple(representData("relationship_templates"), defaultNode.getValueNode());
             }
             if (javaBean instanceof ToscaTopolgyTemplate && "relationshipTemplates".equals(property.getName())) {
                 return new NodeTuple(representData("relationship_templates"), defaultNode.getValueNode());
             }
+            return "_defaultp_".equals(property.getName()) ? new NodeTuple(representData("default"), defaultNode.getValueNode()) : defaultNode;
+        }
 
 
-            return "_defaultp_".equals(property.getName())
-                ? new NodeTuple(representData("default"), defaultNode.getValueNode()) : defaultNode;
+        private NodeTuple handleToscaPropertyConstraint(final ToscaPropertyConstraint javaBean, final Property property, final Object propertyValue,
+                                                        final Tag customTag) {
+            final NodeTuple nodeTuple = super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
+            final String entryToscaName = javaBean.getEntryToscaName(property.getName());
+            return new NodeTuple(representData(entryToscaName), nodeTuple.getValueNode());
         }
 
         private void removeDefaultP(final Object propertyValue) {
             if (propertyValue instanceof Map) {
                 final Map mapPropertyValue = ((Map) propertyValue);
         }
 
         private void removeDefaultP(final Object propertyValue) {
             if (propertyValue instanceof Map) {
                 final Map mapPropertyValue = ((Map) propertyValue);
-
                 final Iterator<Entry> iter = mapPropertyValue.entrySet().iterator();
                 Object defaultValue = null;
                 while (iter.hasNext()) {
                     final Map.Entry entry = iter.next();
                 final Iterator<Entry> iter = mapPropertyValue.entrySet().iterator();
                 Object defaultValue = null;
                 while (iter.hasNext()) {
                     final Map.Entry entry = iter.next();
-
                     if ("_defaultp_".equals(entry.getKey())) {
                         defaultValue = entry.getValue();
                         iter.remove();
                     if ("_defaultp_".equals(entry.getKey())) {
                         defaultValue = entry.getValue();
                         iter.remove();
@@ -1831,10 +1966,67 @@ public class ToscaExportHandler {
             if (!classTags.containsKey(javaBean.getClass())) {
                 addClassTag(javaBean.getClass(), Tag.MAP);
             }
             if (!classTags.containsKey(javaBean.getClass())) {
                 addClassTag(javaBean.getClass(), Tag.MAP);
             }
-
             return super.representJavaBean(properties, javaBean);
         }
 
             return super.representJavaBean(properties, javaBean);
         }
 
+        private class RepresentToscaAttribute implements Represent {
+
+            @Override
+            public Node representData(Object data) {
+                final ToscaAttribute toscaAttribute = (ToscaAttribute) data;
+                return represent(toscaAttribute.asToscaMap());
+            }
+        }
+
+        private class RepresentToscaPropertyAssignment implements Represent {
+
+            public Node representData(Object data) {
+                final ToscaPropertyAssignment toscaOperationAssignment = (ToscaPropertyAssignment) data;
+                if (toscaOperationAssignment.getValue() instanceof String) {
+                    final String stringValue = (String) toscaOperationAssignment.getValue();
+                    if (isPropertyOrAttributeFunction(stringValue)) {
+                        return representGetAttribute(stringValue);
+                    }
+                    return representScalar(Tag.STR, stringValue);
+                }
+                return represent(null);
+            }
+
+            public Node representGetAttribute(final String getAttributeFunction) {
+                return represent(new Yaml().load(getAttributeFunction));
+            }
+
+            public boolean isPropertyOrAttributeFunction(final String value) {
+                try {
+                    final Yaml yaml = new Yaml();
+                    final Object yamlObj = yaml.load(value);
+                    if (!(yamlObj instanceof Map)) {
+                        return false;
+                    }
+                    final Map<String, Object> getAttributeMap = (Map) yamlObj;
+                    if (getAttributeMap.size() != 1) {
+                        return false;
+                    }
+                    final List<String> functionList = Arrays
+                            .asList(GET_ATTRIBUTE.getFunctionName(), GET_INPUT.getFunctionName(), GET_PROPERTY.getFunctionName());
+                    final Optional<String> function = getAttributeMap.keySet().stream()
+                            .filter(key -> functionList.stream().anyMatch(function1 -> function1.equals(key))).findFirst();
+                    if (function.isEmpty()) {
+                        return false;
+                    }
+                    final String functionName = function.get();
+                    final Object getAttributeValueObj = getAttributeMap.get(functionName);
+                    if (GET_INPUT.getFunctionName().equals(functionName)) {
+                        return validateGetInputValue(getAttributeValueObj);
+                    } else {
+                        return validateGetPropertyOrAttributeValue(getAttributeValueObj);
+                    }
+                } catch (final Exception ignored) {
+                    return false;
+                }
+            }
+        }
+
         private class RepresentNull implements Represent {
 
             @Override
         private class RepresentNull implements Represent {
 
             @Override
@@ -1854,87 +2046,4 @@ public class ToscaExportHandler {
         }
     }
 
         }
     }
 
-    private Map<String, String[]> buildSubstitutionMappingPropertyMapping(final Component component) {
-        if (component == null || CollectionUtils.isEmpty(component.getInputs())) {
-            return Collections.emptyMap();
-        }
-        return component.getInputs().stream()
-            .map(PropertyDataDefinition::getName)
-            .collect(
-                Collectors.toMap(
-                    inputName -> inputName,
-                    inputName -> new String[]{inputName},
-                    (inputName1, inputName2) -> inputName1)
-            );
-    }
-
-    private Map<String, String[]> buildSubstitutionMappingAttributesMapping(final Component component) {
-        if (component == null || CollectionUtils.isEmpty(component.getOutputs())) {
-            return Collections.emptyMap();
-        }
-        return component.getOutputs().stream()
-            .map(AttributeDataDefinition::getName)
-            .collect(
-                Collectors.toMap(
-                    outputName -> outputName,
-                    outputName -> new String[]{outputName},
-                    (outputName1, outputName2) -> outputName1)
-            );
-    }
-
-    Optional<Map<String, ToscaProperty>> getProxyNodeTypeProperties(Component proxyComponent,
-                                                                    Map<String, DataTypeDefinition>
-                                                                        dataTypes) {
-        if (Objects.isNull(proxyComponent)) {
-            return Optional.empty();
-        }
-        Map<String, ToscaProperty> proxyProperties = new HashMap<>();
-        addInputsToProperties(dataTypes, proxyComponent.getInputs(), proxyProperties);
-        if (CollectionUtils.isNotEmpty(proxyComponent.getProperties())) {
-            proxyProperties.putAll(proxyComponent.getProperties().stream()
-                .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition,
-                    proxyComponent.getInputs()))
-                .collect(Collectors.toMap(PropertyDataDefinition::getName,
-                    property -> propertyConvertor.convertProperty(dataTypes, property,
-                        PropertyConvertor.PropertyType.PROPERTY))));
-        }
-        return MapUtils.isNotEmpty(proxyProperties) ? Optional.of(proxyProperties) : Optional.empty();
-    }
-
-    void addInputsToProperties(Map<String, DataTypeDefinition> dataTypes,
-                               List<InputDefinition> componentInputs,
-                               Map<String, ToscaProperty> mergedProperties) {
-        if (CollectionUtils.isEmpty(componentInputs)) {
-            return;
-        }
-        for (InputDefinition input : componentInputs) {
-            ToscaProperty property = propertyConvertor.convertProperty(dataTypes, input,
-                PropertyConvertor.PropertyType.INPUT);
-            mergedProperties.put(input.getName(), property);
-        }
-    }
-
-    Optional<Map<String, Object>> getProxyNodeTypeInterfaces(Component proxyComponent,
-                                                             Map<String, DataTypeDefinition> dataTypes) {
-        if (Objects.isNull(proxyComponent) || MapUtils.isEmpty(proxyComponent.getInterfaces())) {
-            return Optional.empty();
-        }
-        Map<String, InterfaceDefinition> proxyComponentInterfaces = proxyComponent.getInterfaces();
-        //Unset artifact path for operation implementation for proxy node types as for operations with artifacts it is
-        // always available in the proxy node template
-        removeOperationImplementationForProxyNodeType(proxyComponentInterfaces);
-        return Optional.ofNullable(interfacesOperationsConverter
-            .getInterfacesMap(proxyComponent, null, proxyComponentInterfaces, dataTypes,
-                false, false));
-    }
-
-    private static void removeOperationImplementationForProxyNodeType(
-        Map<String, InterfaceDefinition> proxyComponentInterfaces) {
-        if (MapUtils.isEmpty(proxyComponentInterfaces)) {
-            return;
-        }
-        proxyComponentInterfaces.values().stream().map(InterfaceDataDefinition::getOperations)
-            .filter(MapUtils::isNotEmpty)
-            .forEach(operations -> operations.values().forEach(operation -> operation.setImplementation(null)));
-    }
 }
 }