Fix issues creating control loop model
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / tosca / ToscaExportHandler.java
index 10d2130..ef63a86 100644 (file)
@@ -28,11 +28,13 @@ import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_INPUT;
 import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_PROPERTY;
 
 import fj.data.Either;
+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.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
@@ -44,17 +46,19 @@ import java.util.Optional;
 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.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.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.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;
@@ -77,6 +81,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.ComponentInstanceAttribute;
 import org.openecomp.sdc.be.model.ComponentInstanceInput;
 import org.openecomp.sdc.be.model.ComponentInstanceInterface;
 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
@@ -97,6 +102,7 @@ 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.operations.impl.ModelOperation;
 import org.openecomp.sdc.be.tosca.PropertyConvertor.PropertyType;
 import org.openecomp.sdc.be.tosca.builder.ToscaRelationshipBuilder;
 import org.openecomp.sdc.be.tosca.exception.ToscaConversionException;
@@ -137,7 +143,6 @@ import org.yaml.snakeyaml.nodes.Tag;
 import org.yaml.snakeyaml.representer.Represent;
 import org.yaml.snakeyaml.representer.Representer;
 
-@NoArgsConstructor
 @org.springframework.stereotype.Component("tosca-export-handler")
 public class ToscaExportHandler {
 
@@ -151,40 +156,51 @@ public class ToscaExportHandler {
     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 List<String> EXCLUDED_CATEGORY_SPECIFIC_METADATA = List
+        .of("Service Function", "Service Role", "Naming Policy", "Service Type");
     private static final YamlUtil yamlUtil = new YamlUtil();
-    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 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
-    public ToscaExportHandler(final ApplicationDataTypeCache dataTypeCache, final ToscaOperationFacade toscaOperationFacade,
-                              final CapabilityRequirementConverter capabilityRequirementConverter, final PolicyExportParser policyExportParser,
-                              final GroupExportParser groupExportParser, final PropertyConvertor propertyConvertor,
-                              final InputConverter inputConverter, final OutputConverter outputConverter,
+    public ToscaExportHandler(final ApplicationDataTypeCache applicationDataTypeCache,
+                              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 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.attributeConverter = attributeConverter;
         this.inputConverter = inputConverter;
         this.outputConverter = outputConverter;
         this.interfaceLifecycleOperation = interfaceLifecycleOperation;
         this.interfacesOperationsConverter = interfacesOperationsConverter;
+        this.modelOperation = modelOperation;
     }
 
     public static String getInterfaceFilename(String artifactName) {
-        return artifactName.substring(0, artifactName.lastIndexOf('.')) + ToscaExportHandler.TOSCA_INTERFACE_NAME;
+        return artifactName.substring(0, artifactName.lastIndexOf('.')) + TOSCA_INTERFACE_NAME;
     }
 
     private static void removeOperationImplementationForProxyNodeType(Map<String, InterfaceDefinition> proxyComponentInterfaces) {
@@ -200,16 +216,18 @@ public class ToscaExportHandler {
     }
 
     public Either<ToscaRepresentation, ToscaError> exportComponentInterface(final Component component, final boolean isAssociatedComponent) {
-        final List<Map<String, Map<String, String>>> imports = getDefaultToscaImportConfig();
+        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);
         }
         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());
+        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());
+                addDependencies(imports, dependencies, baseType.left().value());
             } else {
                 log.debug("Failed to fetch derived from type {}", component.getDerivedFromGenericType());
             }
@@ -220,7 +238,7 @@ public class ToscaExportHandler {
             toscaVersion = ((Resource) component).getToscaVersion();
         }
         ToscaTemplate toscaTemplate = new ToscaTemplate(toscaVersion != null ? toscaVersion : TOSCA_VERSION);
-        toscaTemplate.setImports(new ArrayList<>(imports));
+        toscaTemplate.setImports(imports);
         final Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
         final Either<ToscaTemplate, ToscaError> toscaTemplateRes = convertInterfaceNodeType(new HashMap<>(), component, toscaTemplate, nodeTypes,
             isAssociatedComponent);
@@ -245,9 +263,9 @@ public class ToscaExportHandler {
         Yaml yaml = new Yaml(representer, options);
         String yamlAsString = yaml.dumpAsMap(toscaTemplate);
         StringBuilder sb = new StringBuilder();
-        sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactHeader());
+        sb.append(getConfiguration().getHeatEnvArtifactHeader());
         sb.append(yamlAsString);
-        sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactFooter());
+        sb.append(getConfiguration().getHeatEnvArtifactFooter());
         return ToscaRepresentation.make(sb.toString().getBytes(), toscaTemplate);
     }
 
@@ -261,7 +279,7 @@ public class ToscaExportHandler {
     }
 
     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);
@@ -284,6 +302,26 @@ public class ToscaExportHandler {
         }
     }
 
+    public 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;
+    }
+
     private Either<ToscaTemplate, ToscaError> convertToscaTemplate(Component component, ToscaTemplate toscaNode) {
         Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> importsRes = fillImports(component, toscaNode);
         if (importsRes.isRight()) {
@@ -310,7 +348,7 @@ public class ToscaExportHandler {
         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);
@@ -327,18 +365,15 @@ public class ToscaExportHandler {
             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);
         }
-        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());
             }
@@ -350,8 +385,6 @@ public class ToscaExportHandler {
         if (!relationshipTemplatesMap.isEmpty()) {
             topologyTemplate.setRelationshipTemplates(relationshipTemplatesMap);
         }
-        SubstitutionMapping substitutionMapping = new SubstitutionMapping();
-        convertSubstitutionMappingFilter(component, substitutionMapping);
         addGroupsToTopologyTemplate(component, topologyTemplate);
         try {
             addPoliciesToTopologyTemplate(component, topologyTemplate);
@@ -359,48 +392,86 @@ public class ToscaExportHandler {
             log.debug("Fail to add policies to topology template:", e);
             return Either.right(ToscaError.GENERAL_ERROR);
         }
-        String toscaResourceName;
+        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);
+    }
+
+    private Either<String, ToscaError> createComponentToscaName(final Component component) {
         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:
-                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);
         }
+    }
+
+    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();
         substitutionMapping.setNode_type(toscaResourceName);
-        Either<SubstitutionMapping, ToscaError> capabilities = convertCapabilities(component, substitutionMapping, componentCache);
-        if (capabilities.isRight()) {
-            return Either.right(capabilities.right().value());
+        convertSubstitutionMappingFilter(component).ifPresent(substitutionMapping::setSubstitution_filter);
+
+        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);
         }
-        substitutionMapping = capabilities.left().value();
-        Either<SubstitutionMapping, ToscaError> requirements = capabilityRequirementConverter
-            .convertSubstitutionMappingRequirements(componentCache, component, substitutionMapping);
+
+        final Either<Map<String, String[]>, ToscaError> requirements =
+            capabilityRequirementConverter.convertSubstitutionMappingRequirements(component, componentCache);
         if (requirements.isRight()) {
-            return Either.right(requirements.right().value());
+            throw new ToscaExportException("Could not convert substitution mapping requirements", requirements.right().value());
+        }
+        final Map<String, String[]> requirementMap = requirements.left().value();
+        if (!requirementMap.isEmpty()) {
+            substitutionMapping.setRequirements(requirementMap);
         }
-        substitutionMapping = requirements.left().value();
+
         final Map<String, String[]> propertyMappingMap = buildSubstitutionMappingPropertyMapping(component);
         if (!propertyMappingMap.isEmpty()) {
             substitutionMapping.setProperties(propertyMappingMap);
         }
+
         final Map<String, String[]> attributesMappingMap = buildSubstitutionMappingAttributesMapping(component);
         if (!attributesMappingMap.isEmpty()) {
             substitutionMapping.setAttributes(attributesMappingMap);
         }
-        topologyTemplate.setSubstitution_mappings(substitutionMapping);
-        toscaNode.setTopology_template(topologyTemplate);
-        return Either.left(toscaNode);
+
+        return Optional.of(substitutionMapping);
     }
 
-    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) {
@@ -483,8 +554,9 @@ public class ToscaExportHandler {
                 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
         }
         for (final String key : component.getCategorySpecificMetadata().keySet()) {
-            if (!EXCLUDED_CATEGORY_SPECIFIC_METADATA.contains(key))
+            if (!EXCLUDED_CATEGORY_SPECIFIC_METADATA.contains(key)) {
                 toscaMetadata.put(key, component.getCategorySpecificMetadata().get(key));
+            }
         }
         return toscaMetadata;
     }
@@ -497,7 +569,7 @@ public class ToscaExportHandler {
     }
 
     private Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports(Component component, ToscaTemplate toscaTemplate) {
-        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);
@@ -508,18 +580,9 @@ public class ToscaExportHandler {
                 toscaTemplate.getImports() == null ? new ArrayList<>(defaultToscaImportConfig) : new ArrayList<>(toscaTemplate.getImports());
             List<Triple<String, String, Component>> dependencies = new ArrayList<>();
             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()) {
@@ -533,8 +596,27 @@ public class ToscaExportHandler {
         return Either.left(new ImmutablePair<>(toscaTemplate, componentCache));
     }
 
+    private Map<String, Map<String, String>> generateComponentSubstituteTypeImport(final Component component,
+                                                                                   final Map<String, ArtifactDefinition> toscaArtifacts) {
+
+        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() {
-        return ConfigurationManager.getConfigurationManager().getConfiguration().getDefaultImports();
+        return getConfiguration().getDefaultImports();
     }
 
     private void createDependency(final Map<String, Component> componentCache, final List<Map<String, Map<String, String>>> imports,
@@ -682,15 +764,17 @@ public class ToscaExportHandler {
         log.debug("start convert node type for {}", component.getUniqueId());
         ToscaNodeType toscaNodeType = createNodeType(component);
         Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither = interfaceLifecycleOperation
-            .getAllInterfaceLifecycleTypes();
-        if (lifecycleTypeEither.isRight()) {
+            .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);
         }
-        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(addInterfaceTypeElement(component, allGlobalInterfaceTypes));
+        }
+        Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> 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);
@@ -701,14 +785,7 @@ public class ToscaExportHandler {
         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);
-        }
+        toscaAttributeMap = convertToToscaAttributes(component.getAttributes(), dataTypes);
         if (!toscaAttributeMap.isEmpty()) {
             toscaNodeType.setAttributes(toscaAttributeMap);
         }
@@ -739,8 +816,8 @@ public class ToscaExportHandler {
                     toscaDataType.setProperties(dataType.getProperties().stream()
                         .collect(Collectors.toMap(
                             PropertyDataDefinition::getName,
-                            s -> propertyConvertor
-                                .convertProperty(dataTypes, s, PropertyType.PROPERTY)
+                            s -> propertyConvertor.convertProperty(dataTypes, s, PropertyType.PROPERTY),
+                            (toscaPropertyTobeValidated, toscaProperty) -> validateToscaProperty(privateDataTypes, toscaPropertyTobeValidated, toscaProperty)
                         )));
                 }
                 toscaDataTypeMap.put(dataType.getName(), toscaDataType);
@@ -752,15 +829,22 @@ public class ToscaExportHandler {
         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,
-                                                                 final Map<String, DataTypeDefinition> dataTypes) throws ToscaConversionException {
+                                                                 final Map<String, DataTypeDefinition> dataTypes) {
         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) {
-            toscaAttributeMap.put(attributeDefinition.getName(), attributeConverter.convert(attributeDefinition));
+            toscaAttributeMap.put(attributeDefinition.getName(), converter.convert(attributeDefinition));
         }
         return toscaAttributeMap;
     }
@@ -779,8 +863,7 @@ public class ToscaExportHandler {
         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());
         }
@@ -808,22 +891,23 @@ public class ToscaExportHandler {
         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;
-        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;
-        for (ComponentInstance componentInstance : componentInstances) {
+        for (final ComponentInstance componentInstance : component.getComponentInstances()) {
             ToscaNodeTemplate nodeTemplate = new ToscaNodeTemplate();
             if (MapUtils.isNotEmpty(componentInstance.getToscaArtifacts())) {
                 nodeTemplate.setArtifacts(convertToNodeTemplateArtifacts(componentInstance.getToscaArtifacts()));
@@ -832,35 +916,34 @@ public class ToscaExportHandler {
             nodeTemplate.setDirectives(componentInstance.getDirectives());
             nodeTemplate.setNode_filter(convertToNodeTemplateNodeFilterComponent(componentInstance.getNodeFilter()));
 
-            Either<Component, Boolean> originComponentRes = capabilityRequirementConverter
+            final Either<Component, Boolean> originComponentRes = capabilityRequirementConverter
                 .getOriginComponent(componentCache, componentInstance);
             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;
             }
-            String instanceUniqueId = componentInstance.getUniqueId();
+            final String instanceUniqueId = componentInstance.getUniqueId();
             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) {
-                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));
             }
 
-            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;
@@ -868,49 +951,47 @@ public class ToscaExportHandler {
             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);
+                addAttributesOfParentComponent(originalComponent, attribs);
             }
 
             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)
+            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
-            handleInstanceInterfaces(componentInstanceInterfaces, componentInstance, dataTypes, nodeTemplate,
-                instanceUniqueId, component);
+            handleInstanceInterfaces(componentInstanceInterfaces, componentInstance, dataTypes, nodeTemplate, instanceUniqueId, component);
             //M3[00001] - NODE TEMPLATE INTERFACES  - END
-            if (props != null && !props.isEmpty()) {
+            if (MapUtils.isNotEmpty(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<>();
                 }
-                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()));
                     }
                 }
             }
@@ -923,19 +1004,15 @@ public class ToscaExportHandler {
         }
         if (component.getComponentType() == ComponentTypeEnum.SERVICE && isNotEmpty(
             ((Service) component).getForwardingPaths())) {
-            log.debug("Starting converting paths for component {}, name {}", component.getUniqueId(),
-                component.getName());
+            log.debug("Starting converting paths for component {}, name {}", component.getUniqueId(), component.getName());
             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);
         }
-        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;
     }
 
@@ -978,24 +1055,34 @@ public class ToscaExportHandler {
         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);
             });
         }
     }
 
-    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)
                 // Converts and adds each value to property map
-                .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop,
-                    prop::getValue));
+                .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).stream()
+                // Filters out Attributes with empty default values
+                .filter(attributeDefinition -> StringUtils.isNotEmpty(attributeDefinition.getDefaultValue()))
+                // Converts and adds each value to attribute map
+                .forEach(attributeDefinition -> attributeConverter.convertAndAddValue(attribs, attributeDefinition));
         }
     }
 
@@ -1008,8 +1095,19 @@ public class ToscaExportHandler {
                 // 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));
+                .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));
         }
     }
 
@@ -1059,7 +1157,7 @@ public class ToscaExportHandler {
             }
 
             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);
@@ -1104,7 +1202,7 @@ public class ToscaExportHandler {
             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 {}",
                 serviceProxyOrigin.right().value());
@@ -1164,7 +1262,7 @@ public class ToscaExportHandler {
         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());
         }
@@ -1207,13 +1305,11 @@ public class ToscaExportHandler {
                                                                                        Component originComponent,
                                                                                        Map<String, Component> componentCache) {
 
-        final List<Map<String, ToscaTemplateRequirement>> toscaRequirements;
         final List<RequirementCapabilityRelDef> requirementDefinitionList = filterRequirements(componentInstance,
             relations);
         if (isNotEmpty(requirementDefinitionList)) {
             try {
-                toscaRequirements = buildRequirements(component, componentInstance,
-                    requirementDefinitionList, originComponent, componentCache);
+                final List<Map<String, ToscaTemplateRequirement>> toscaRequirements = buildRequirements(component, componentInstance, requirementDefinitionList, originComponent, componentCache);
                 if (!toscaRequirements.isEmpty()) {
                     nodeTypeTemplate.setRequirements(toscaRequirements);
                 }
@@ -1237,8 +1333,7 @@ public class ToscaExportHandler {
         final List<Map<String, ToscaTemplateRequirement>> toscaRequirements = new ArrayList<>();
         for (RequirementCapabilityRelDef relationshipDefinition : filteredRelations) {
             final Map<String, ToscaTemplateRequirement> toscaTemplateRequirementMap =
-                buildRequirement(componentInstance, originComponent, component.getComponentInstances(),
-                    relationshipDefinition, componentCache);
+                buildRequirement(componentInstance, originComponent, component.getComponentInstances(), relationshipDefinition, componentCache);
             toscaRequirements.add(toscaTemplateRequirementMap);
         }
 
@@ -1347,7 +1442,7 @@ public class ToscaExportHandler {
         }
         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(
                 "Failed to build a substituted capability name for the capability with name %s on a component with uniqueId %s",
@@ -1358,7 +1453,7 @@ public class ToscaExportHandler {
         }
         final Either<String, Boolean> requirementNameEither = capabilityRequirementConverter
             .buildSubstitutedName(componentCache, fromOriginComponent,
-                requirement.getPath(), relationshipInfo.getRequirement(), requirement.getPreviousName());
+                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 "
                     + "with name %s on a component with uniqueId %s",
@@ -1419,20 +1514,21 @@ public class ToscaExportHandler {
         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()) {
-            result = Either.right(toscaCapabilitiesRes.right().value());
             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());
+            return Either.left(toscaCapabilitiesRes.left().value());
         }
         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,
@@ -1454,12 +1550,13 @@ public class ToscaExportHandler {
             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;
     }
 
-    protected NodeFilter convertToNodeTemplateNodeFilterComponent(CINodeFilterDataDefinition inNodeFilter) {
+    private NodeFilter convertToNodeTemplateNodeFilterComponent(CINodeFilterDataDefinition inNodeFilter) {
         if (inNodeFilter == null) {
             return null;
         }
@@ -1530,7 +1627,7 @@ public class ToscaExportHandler {
         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);
+                Map<String, List<Object>> propertyValObj = new YamlUtil().yamlToObject(propertyInfoEntry, Map.class);
                 String propertyName = propertyDataDefinition.getName();
                 if (propertyMapCopy.containsKey(propertyName)) {
                     addPropertyConstraintValueToList(propertyName, propertyValObj, propertyMapCopy.get(propertyName));
@@ -1592,7 +1689,7 @@ public class ToscaExportHandler {
         if (component == null || CollectionUtils.isEmpty(component.getInputs())) {
             return Collections.emptyMap();
         }
-        return component.getInputs().stream().filter(input -> input.isMappedToComponentProperty()).map(PropertyDataDefinition::getName)
+        return component.getInputs().stream().filter(InputDefinition::isMappedToComponentProperty).map(PropertyDataDefinition::getName)
             .collect(Collectors.toMap(inputName -> inputName, inputName -> new String[]{inputName}, (inputName1, inputName2) -> inputName1));
     }
 
@@ -1797,4 +1894,9 @@ public class ToscaExportHandler {
             return new LinkedHashSet<>(fields);
         }
     }
+
+    private Configuration getConfiguration() {
+        return ConfigurationManager.getConfigurationManager().getConfiguration();
+    }
+
 }