Fix 'Wrong Inputs creation on (Add Service)'
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / tosca / ToscaExportHandler.java
index 6a1ba4e..25d0287 100644 (file)
@@ -22,17 +22,25 @@ 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 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 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.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
@@ -101,6 +109,7 @@ 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.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;
@@ -127,6 +136,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.tosca.datatypes.ToscaFunctions;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.yaml.snakeyaml.DumperOptions;
 import org.yaml.snakeyaml.DumperOptions.FlowStyle;
@@ -223,7 +233,8 @@ public class ToscaExportHandler {
         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());
+                .getByToscaResourceNameAndVersion(component.getDerivedFromGenericType(), component.getDerivedFromGenericVersion(),
+                    component.getModel());
             if (baseType.isLeft() && baseType.left().value() != null) {
                 addDependencies(imports, dependencies, baseType.left().value());
             } else {
@@ -249,7 +260,7 @@ public class ToscaExportHandler {
         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);
@@ -300,16 +311,22 @@ public class ToscaExportHandler {
         }
     }
 
-    public List<Map<String, Map<String, String>>> getDefaultToscaImports(final String modelId) {
+    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<>();
-        for(final ToscaImportByModel toscaImportByModel: allModelImports) {
-            final String fileName = FilenameUtils.getBaseName(toscaImportByModel.getFullPath());
-            importList.add(Map.of(fileName, Map.of("file", toscaImportByModel.getFullPath())));
+        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;
     }
@@ -377,8 +394,6 @@ public class ToscaExportHandler {
         if (!relationshipTemplatesMap.isEmpty()) {
             topologyTemplate.setRelationshipTemplates(relationshipTemplatesMap);
         }
-        SubstitutionMapping substitutionMapping = new SubstitutionMapping();
-        convertSubstitutionMappingFilter(component, substitutionMapping);
         addGroupsToTopologyTemplate(component, topologyTemplate);
         try {
             addPoliciesToTopologyTemplate(component, topologyTemplate);
@@ -386,48 +401,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 (MapUtils.isNotEmpty(requirementMap)) {
+            substitutionMapping.setRequirements(requirementMap);
         }
-        substitutionMapping = requirements.left().value();
+
         final Map<String, String[]> propertyMappingMap = buildSubstitutionMappingPropertyMapping(component);
-        if (!propertyMappingMap.isEmpty()) {
+        if (MapUtils.isNotEmpty(propertyMappingMap)) {
             substitutionMapping.setProperties(propertyMappingMap);
         }
+
         final Map<String, String[]> attributesMappingMap = buildSubstitutionMappingAttributesMapping(component);
-        if (!attributesMappingMap.isEmpty()) {
+        if (MapUtils.isNotEmpty(attributesMappingMap)) {
             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) {
@@ -457,6 +510,7 @@ public class ToscaExportHandler {
         toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), component.getDescription());
         List<CategoryDefinition> categories = component.getCategories();
         CategoryDefinition categoryDefinition = categories.get(0);
+        toscaMetadata.put(JsonPresentationFields.MODEL.getPresentation(), component.getModel());
         toscaMetadata.put(JsonPresentationFields.CATEGORY.getPresentation(), categoryDefinition.getName());
         if (isInstance) {
             toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), component.getVersion());
@@ -536,18 +590,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(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()) {
@@ -561,6 +606,25 @@ 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 getConfiguration().getDefaultImports();
     }
@@ -711,36 +775,36 @@ public class ToscaExportHandler {
         ToscaNodeType toscaNodeType = createNodeType(component);
         Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither = interfaceLifecycleOperation
             .getAllInterfaceLifecycleTypes(component.getModel());
-        if (lifecycleTypeEither.isRight()) {
+        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 = applicationDataTypeCache.getAll(component.getModel());
+        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);
         }
         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;
-        toscaAttributeMap = convertToToscaAttributes(component.getAttributes(), dataTypes);
+        final var toscaAttributeMap = convertToToscaAttributes(component.getAttributes(), dataTypes);
         if (!toscaAttributeMap.isEmpty()) {
             toscaNodeType.setAttributes(toscaAttributeMap);
         }
+        final var mergedProperties = convertInputsToProperties(dataTypes, inputDef, component.getUniqueId());
         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)));
+                .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.forEach((k, v) -> mergedProperties.putIfAbsent(k, v));
         }
         if (MapUtils.isNotEmpty(mergedProperties)) {
             toscaNodeType.setProperties(mergedProperties);
@@ -760,8 +824,9 @@ 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);
@@ -773,6 +838,13 @@ 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) {
         if (CollectionUtils.isEmpty(attributeList)) {
@@ -849,10 +921,26 @@ public class ToscaExportHandler {
             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.setNode_filter(convertToNodeTemplateNodeFilterComponent(componentInstance.getNodeFilter()));
-
+            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()) {
@@ -953,6 +1041,32 @@ public class ToscaExportHandler {
         return convertNodeTemplatesRes;
     }
 
+    private Object convertToToscaObject(String value) {
+        try {
+            ToscaMapValueConverter mapConverterInst = ToscaMapValueConverter.getInstance();
+            JsonParser jsonParser = new JsonParser();
+            StringReader reader = new StringReader(value);
+            JsonReader jsonReader = new JsonReader(reader);
+            jsonReader.setLenient(true);
+            JsonElement jsonElement = jsonParser.parse(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;
+        }
+    }
+
+    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,
@@ -992,7 +1106,8 @@ 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);
             });
         }
@@ -1015,10 +1130,7 @@ public class ToscaExportHandler {
                                                   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
+            componentInstancesAttributes.get(instanceUniqueId)
                 .forEach(attributeDefinition -> attributeConverter.convertAndAddValue(attribs, attributeDefinition));
         }
     }
@@ -1104,7 +1216,7 @@ public class ToscaExportHandler {
                 .map(InterfaceDataDefinition::getType)
                 .collect(Collectors.toList());
             //Add interface types for local interfaces in the original service component for proxy
-            Map<String, Object> localInterfaceTypes = addInterfaceTypeElement(serviceComponent,
+            Map<String, Object> localInterfaceTypes = interfacesOperationsConverter.addInterfaceTypeElement(serviceComponent,
                 allGlobalInterfaceTypes);
             if (MapUtils.isNotEmpty(localInterfaceTypes)) {
                 proxyInterfaceTypes.putAll(localInterfaceTypes);
@@ -1199,7 +1311,8 @@ public class ToscaExportHandler {
         String derivedFrom = ((Resource) origComponent).getToscaResourceName();
 
         toscaNodeType.setDerived_from(derivedFrom);
-        Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = applicationDataTypeCache.getAll(origComponent.getModel());
+        Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = applicationDataTypeCache.getAll(
+            origComponent.getModel());
         if (dataTypesEither.isRight()) {
             log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
         }
@@ -1246,7 +1359,8 @@ public class ToscaExportHandler {
             relations);
         if (isNotEmpty(requirementDefinitionList)) {
             try {
-                final List<Map<String, ToscaTemplateRequirement>> 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);
                 }
@@ -1415,7 +1529,7 @@ public class ToscaExportHandler {
                                                             String fromInstanceId) {
         for (List<RequirementDefinition> reqList : reqMap.values()) {
             Optional<RequirementDefinition> reqOpt = reqList.stream().filter(
-                r -> isRequirementBelongToRelation(fromOriginComponent, reqAndRelationshipPair, r, fromInstanceId))
+                    r -> isRequirementBelongToRelation(fromOriginComponent, reqAndRelationshipPair, r, fromInstanceId))
                 .findFirst();
             if (reqOpt.isPresent()) {
                 return reqOpt;
@@ -1451,20 +1565,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,
@@ -1486,6 +1601,7 @@ 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;
@@ -1636,33 +1752,30 @@ public class ToscaExportHandler {
             .collect(Collectors.toMap(outputName -> outputName, outputName -> new String[]{outputName}, (outputName1, outputName2) -> outputName1));
     }
 
-    Optional<Map<String, ToscaProperty>> getProxyNodeTypeProperties(Component proxyComponent, Map<String, DataTypeDefinition> dataTypes) {
+    private 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);
+        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, PropertyConvertor.PropertyType.PROPERTY))));
+                        property -> propertyConvertor.convertProperty(dataTypes, property, PropertyType.PROPERTY))));
         }
         return MapUtils.isNotEmpty(proxyProperties) ? Optional.of(proxyProperties) : Optional.empty();
     }
 
-    void addInputsToProperties(Map<String, DataTypeDefinition> dataTypes, List<InputDefinition> componentInputs,
-                               Map<String, ToscaProperty> mergedProperties) {
+    private Map<String, ToscaProperty> convertInputsToProperties(Map<String, DataTypeDefinition> dataTypes, List<InputDefinition> componentInputs,
+                                                                 String componentUniqueId) {
         if (CollectionUtils.isEmpty(componentInputs)) {
-            return;
-        }
-        for (InputDefinition input : componentInputs) {
-            ToscaProperty property = propertyConvertor.convertProperty(dataTypes, input, PropertyConvertor.PropertyType.INPUT);
-            mergedProperties.put(input.getName(), property);
+            return new HashMap<>();
         }
+        return componentInputs.stream().filter(input -> componentUniqueId.equals(input.getInstanceUniqueId()))
+            .collect(Collectors.toMap(InputDefinition::getName, i -> propertyConvertor.convertProperty(dataTypes, i, PropertyType.INPUT)));
     }
 
-    Optional<Map<String, Object>> getProxyNodeTypeInterfaces(Component proxyComponent, Map<String, DataTypeDefinition> dataTypes) {
+    private Optional<Map<String, Object>> getProxyNodeTypeInterfaces(Component proxyComponent, Map<String, DataTypeDefinition> dataTypes) {
         if (Objects.isNull(proxyComponent) || MapUtils.isEmpty(proxyComponent.getInterfaces())) {
             return Optional.empty();
         }
@@ -1675,6 +1788,10 @@ public class ToscaExportHandler {
             .ofNullable(interfacesOperationsConverter.getInterfacesMap(proxyComponent, null, proxyComponentInterfaces, dataTypes, false, false));
     }
 
+    private Configuration getConfiguration() {
+        return ConfigurationManager.getConfigurationManager().getConfiguration();
+    }
+
     private static class CustomRepresenter extends Representer {
 
         CustomRepresenter() {
@@ -1830,8 +1947,4 @@ public class ToscaExportHandler {
         }
     }
 
-    private Configuration getConfiguration() {
-        return ConfigurationManager.getConfigurationManager().getConfiguration();
-    }
-
 }