Implement Attributes/Outputs BE (part 2)
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / tosca / ToscaExportHandler.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.sdc.be.tosca;
22
23 import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
24 import static org.apache.commons.collections.MapUtils.isNotEmpty;
25 import static org.openecomp.sdc.be.components.utils.PropertiesUtils.resolvePropertyValueFromInput;
26 import static org.openecomp.sdc.be.tosca.InterfacesOperationsConverter.addInterfaceTypeElement;
27 import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_ATTRIBUTE;
28 import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_INPUT;
29 import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_PROPERTY;
30
31 import com.fasterxml.jackson.databind.ObjectMapper;
32 import fj.data.Either;
33 import java.beans.IntrospectionException;
34 import java.util.ArrayList;
35 import java.util.Arrays;
36 import java.util.Collection;
37 import java.util.Collections;
38 import java.util.HashMap;
39 import java.util.Iterator;
40 import java.util.LinkedHashMap;
41 import java.util.LinkedHashSet;
42 import java.util.List;
43 import java.util.Map;
44 import java.util.Map.Entry;
45 import java.util.Objects;
46 import java.util.Optional;
47 import java.util.Set;
48 import java.util.function.Supplier;
49 import java.util.stream.Collectors;
50 import lombok.NoArgsConstructor;
51 import org.apache.commons.collections.CollectionUtils;
52 import org.apache.commons.collections.MapUtils;
53 import org.apache.commons.lang.StringUtils;
54 import org.apache.commons.lang3.tuple.ImmutablePair;
55 import org.apache.commons.lang3.tuple.ImmutableTriple;
56 import org.apache.commons.lang3.tuple.Triple;
57 import org.onap.sdc.tosca.services.YamlUtil;
58 import org.openecomp.sdc.be.components.impl.exceptions.SdcResourceNotFoundException;
59 import org.openecomp.sdc.be.config.ConfigurationManager;
60 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
61 import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
62 import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition;
63 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
64 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
65 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
66 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
67 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition;
68 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition;
69 import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterPropertyDataDefinition;
70 import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition;
71 import org.openecomp.sdc.be.datatypes.elements.ToscaArtifactDataDefinition;
72 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
73 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
74 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
75 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
76 import org.openecomp.sdc.be.exception.ToscaExportException;
77 import org.openecomp.sdc.be.model.ArtifactDefinition;
78 import org.openecomp.sdc.be.model.AttributeDefinition;
79 import org.openecomp.sdc.be.model.CapabilityDefinition;
80 import org.openecomp.sdc.be.model.CapabilityRequirementRelationship;
81 import org.openecomp.sdc.be.model.Component;
82 import org.openecomp.sdc.be.model.ComponentInstance;
83 import org.openecomp.sdc.be.model.ComponentInstanceInput;
84 import org.openecomp.sdc.be.model.ComponentInstanceInterface;
85 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
86 import org.openecomp.sdc.be.model.ComponentParametersView;
87 import org.openecomp.sdc.be.model.DataTypeDefinition;
88 import org.openecomp.sdc.be.model.GroupInstance;
89 import org.openecomp.sdc.be.model.InputDefinition;
90 import org.openecomp.sdc.be.model.InterfaceDefinition;
91 import org.openecomp.sdc.be.model.PropertyDefinition;
92 import org.openecomp.sdc.be.model.RelationshipInfo;
93 import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
94 import org.openecomp.sdc.be.model.RequirementDefinition;
95 import org.openecomp.sdc.be.model.Resource;
96 import org.openecomp.sdc.be.model.Service;
97 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
98 import org.openecomp.sdc.be.model.category.CategoryDefinition;
99 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
100 import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter;
101 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
102 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
103 import org.openecomp.sdc.be.tosca.PropertyConvertor.PropertyType;
104 import org.openecomp.sdc.be.tosca.builder.ToscaRelationshipBuilder;
105 import org.openecomp.sdc.be.tosca.model.CapabilityFilter;
106 import org.openecomp.sdc.be.tosca.model.NodeFilter;
107 import org.openecomp.sdc.be.tosca.model.SubstitutionMapping;
108 import org.openecomp.sdc.be.tosca.model.ToscaCapability;
109 import org.openecomp.sdc.be.tosca.model.ToscaDataType;
110 import org.openecomp.sdc.be.tosca.model.ToscaGroupTemplate;
111 import org.openecomp.sdc.be.tosca.model.ToscaNodeTemplate;
112 import org.openecomp.sdc.be.tosca.model.ToscaNodeType;
113 import org.openecomp.sdc.be.tosca.model.ToscaPolicyTemplate;
114 import org.openecomp.sdc.be.tosca.model.ToscaProperty;
115 import org.openecomp.sdc.be.tosca.model.ToscaPropertyAssignment;
116 import org.openecomp.sdc.be.tosca.model.ToscaRelationshipTemplate;
117 import org.openecomp.sdc.be.tosca.model.ToscaRequirement;
118 import org.openecomp.sdc.be.tosca.model.ToscaTemplate;
119 import org.openecomp.sdc.be.tosca.model.ToscaTemplateArtifact;
120 import org.openecomp.sdc.be.tosca.model.ToscaTemplateRequirement;
121 import org.openecomp.sdc.be.tosca.model.ToscaTopolgyTemplate;
122 import org.openecomp.sdc.be.tosca.utils.ForwardingPathToscaUtil;
123 import org.openecomp.sdc.be.tosca.utils.InputConverter;
124 import org.openecomp.sdc.be.tosca.utils.OutputConverter;
125 import org.openecomp.sdc.common.log.wrappers.Logger;
126 import org.springframework.beans.factory.annotation.Autowired;
127 import org.yaml.snakeyaml.DumperOptions;
128 import org.yaml.snakeyaml.DumperOptions.FlowStyle;
129 import org.yaml.snakeyaml.Yaml;
130 import org.yaml.snakeyaml.introspector.BeanAccess;
131 import org.yaml.snakeyaml.introspector.Property;
132 import org.yaml.snakeyaml.introspector.PropertyUtils;
133 import org.yaml.snakeyaml.nodes.MappingNode;
134 import org.yaml.snakeyaml.nodes.Node;
135 import org.yaml.snakeyaml.nodes.NodeTuple;
136 import org.yaml.snakeyaml.nodes.Tag;
137 import org.yaml.snakeyaml.representer.Represent;
138 import org.yaml.snakeyaml.representer.Representer;
139
140 @NoArgsConstructor
141 @org.springframework.stereotype.Component("tosca-export-handler")
142 public class ToscaExportHandler {
143
144     private static final Logger log = Logger.getLogger(ToscaExportHandler.class);
145
146     private ApplicationDataTypeCache dataTypeCache;
147     private ToscaOperationFacade toscaOperationFacade;
148     private CapabilityRequirementConverter capabilityRequirementConverter;
149     private PolicyExportParser policyExportParser;
150     private GroupExportParser groupExportParser;
151     private PropertyConvertor propertyConvertor;
152     private InputConverter inputConverter;
153     private OutputConverter outputConverter;
154     private InterfaceLifecycleOperation interfaceLifecycleOperation;
155     private InterfacesOperationsConverter interfacesOperationsConverter;
156
157     @Autowired
158     public ToscaExportHandler(final ApplicationDataTypeCache dataTypeCache,
159                               final ToscaOperationFacade toscaOperationFacade,
160                               final CapabilityRequirementConverter capabilityRequirementConverter,
161                               final PolicyExportParser policyExportParser,
162                               final GroupExportParser groupExportParser,
163                               final PropertyConvertor propertyConvertor,
164                               final InputConverter inputConverter,
165                               final OutputConverter outputConverter,
166                               final InterfaceLifecycleOperation interfaceLifecycleOperation,
167                               final InterfacesOperationsConverter interfacesOperationsConverter) {
168         this.dataTypeCache = dataTypeCache;
169         this.toscaOperationFacade = toscaOperationFacade;
170         this.capabilityRequirementConverter = capabilityRequirementConverter;
171         this.policyExportParser = policyExportParser;
172         this.groupExportParser = groupExportParser;
173         this.propertyConvertor = propertyConvertor;
174         this.inputConverter = inputConverter;
175         this.outputConverter = outputConverter;
176         this.interfaceLifecycleOperation = interfaceLifecycleOperation;
177         this.interfacesOperationsConverter = interfacesOperationsConverter;
178     }
179
180     private static final String TOSCA_VERSION = "tosca_simple_yaml_1_3";
181     private static final String SERVICE_NODE_TYPE_PREFIX = "org.openecomp.service.";
182     private static final String IMPORTS_FILE_KEY = "file";
183     private static final String TOSCA_INTERFACE_NAME = "-interface.yml";
184     public static final String ASSET_TOSCA_TEMPLATE = "assettoscatemplate";
185     private static final String FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION = "convertToToscaTemplate - failed to get Default Imports section from configuration";
186     private static final String NOT_SUPPORTED_COMPONENT_TYPE = "Not supported component type {}";
187     private static final String NATIVE_ROOT = "tosca.nodes.Root";
188     private static final YamlUtil yamlUtil = new YamlUtil();
189
190     public Either<ToscaRepresentation, ToscaError> exportComponent(Component component) {
191         return convertToToscaTemplate(component).left().map(this::createToscaRepresentation);
192     }
193
194     public Either<ToscaRepresentation, ToscaError> exportComponentInterface(final Component component,
195                                                                             final boolean isAssociatedComponent) {
196         final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImportConfig();
197         if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
198             log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
199             return Either.right(ToscaError.GENERAL_ERROR);
200         }
201
202         String toscaVersion = null;
203         if (component instanceof Resource) {
204             toscaVersion = ((Resource) component).getToscaVersion();
205         }
206         ToscaTemplate toscaTemplate = new ToscaTemplate(toscaVersion != null ? toscaVersion : TOSCA_VERSION);
207         toscaTemplate.setImports(new ArrayList<>(defaultToscaImportConfig));
208         final Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
209         final Either<ToscaTemplate, ToscaError> toscaTemplateRes =
210             convertInterfaceNodeType(new HashMap<>(), component, toscaTemplate, nodeTypes, isAssociatedComponent);
211         if (toscaTemplateRes.isRight()) {
212             return Either.right(toscaTemplateRes.right().value());
213         }
214
215         toscaTemplate = toscaTemplateRes.left().value();
216         ToscaRepresentation toscaRepresentation = this.createToscaRepresentation(toscaTemplate);
217         return Either.left(toscaRepresentation);
218     }
219
220     public ToscaRepresentation createToscaRepresentation(ToscaTemplate toscaTemplate) {
221         CustomRepresenter representer = new CustomRepresenter();
222         DumperOptions options = new DumperOptions();
223         options.setAllowReadOnlyProperties(false);
224         options.setPrettyFlow(true);
225
226         options.setDefaultFlowStyle(FlowStyle.FLOW);
227         options.setCanonical(false);
228
229         representer.addClassTag(toscaTemplate.getClass(), Tag.MAP);
230
231         representer.setPropertyUtils(new UnsortedPropertyUtils());
232         Yaml yaml = new Yaml(representer, options);
233
234         String yamlAsString = yaml.dumpAsMap(toscaTemplate);
235
236         StringBuilder sb = new StringBuilder();
237         sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactHeader());
238         sb.append(yamlAsString);
239         sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactFooter());
240
241         return ToscaRepresentation.make(sb.toString().getBytes(), toscaTemplate);
242     }
243
244     public Either<ToscaTemplate, ToscaError> getDependencies(Component component) {
245         ToscaTemplate toscaTemplate = new ToscaTemplate(null);
246         Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports = fillImports(component,
247             toscaTemplate);
248         if (fillImports.isRight()) {
249             return Either.right(fillImports.right().value());
250         }
251         return Either.left(fillImports.left().value().left);
252     }
253
254     public Either<ToscaTemplate, ToscaError> convertToToscaTemplate(final Component component) {
255         final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImportConfig();
256         if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
257             log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
258             return Either.right(ToscaError.GENERAL_ERROR);
259         }
260         log.trace("start tosca export for {}", component.getUniqueId());
261         String toscaVersion = null;
262         if (component instanceof Resource) {
263             toscaVersion = ((Resource) component).getToscaVersion();
264         }
265         final ToscaTemplate toscaTemplate = new ToscaTemplate(toscaVersion != null ? toscaVersion : TOSCA_VERSION);
266         toscaTemplate.setMetadata(convertMetadata(component));
267         toscaTemplate.setImports(new ArrayList<>(defaultToscaImportConfig));
268         final Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
269         if (ModelConverter.isAtomicComponent(component)) {
270             log.trace("convert component as node type");
271             return convertNodeType(new HashMap<>(), component, toscaTemplate, nodeTypes);
272         } else {
273             log.trace("convert component as topology template");
274             return convertToscaTemplate(component, toscaTemplate);
275         }
276
277     }
278
279     private Either<ToscaTemplate, ToscaError> convertToscaTemplate(Component component, ToscaTemplate toscaNode) {
280
281         Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> importsRes = fillImports(component,
282             toscaNode);
283         if (importsRes.isRight()) {
284             return Either.right(importsRes.right().value());
285         }
286         toscaNode = importsRes.left().value().left;
287         Map<String, Component> componentCache = importsRes.left().value().right;
288         Either<Map<String, ToscaNodeType>, ToscaError> nodeTypesMapEither = createProxyNodeTypes(componentCache,
289             component);
290         if (nodeTypesMapEither.isRight()) {
291             log.debug("Failed to fetch normative service proxy resource by tosca name, error {}",
292                 nodeTypesMapEither.right().value());
293             return Either.right(nodeTypesMapEither.right().value());
294         }
295         Map<String, ToscaNodeType> nodeTypesMap = nodeTypesMapEither.left().value();
296         if (nodeTypesMap != null && !nodeTypesMap.isEmpty()) {
297             toscaNode.setNode_types(nodeTypesMap);
298         }
299
300         createServiceSubstitutionNodeTypes(componentCache, component, toscaNode);
301
302         Either<Map<String, Object>, ToscaError> proxyInterfaceTypesEither = createProxyInterfaceTypes(component);
303         if (proxyInterfaceTypesEither.isRight()) {
304             log.debug("Failed to populate service proxy local interface types in tosca, error {}",
305                 nodeTypesMapEither.right().value());
306             return Either.right(proxyInterfaceTypesEither.right().value());
307         }
308         Map<String, Object> proxyInterfaceTypes = proxyInterfaceTypesEither.left().value();
309         if (MapUtils.isNotEmpty(proxyInterfaceTypes)) {
310             toscaNode.setInterface_types(proxyInterfaceTypes);
311         }
312
313         Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = dataTypeCache.getAll();
314         if (dataTypesEither.isRight()) {
315             log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
316             return Either.right(ToscaError.GENERAL_ERROR);
317         }
318         Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
319         ToscaTopolgyTemplate topologyTemplate = new ToscaTopolgyTemplate();
320         List<InputDefinition> inputDef = component.getInputs();
321         Map<String, ToscaProperty> inputs = inputConverter.convertInputs(inputDef, dataTypes);
322
323         if (!inputs.isEmpty()) {
324             topologyTemplate.setInputs(inputs);
325         }
326
327         final Map<String, ToscaProperty> outputs = outputConverter.convert(component.getOutputs(), dataTypes);
328         if (!outputs.isEmpty()) {
329             topologyTemplate.setOutputs(outputs);
330         }
331
332         final List<ComponentInstance> componentInstances = component.getComponentInstances();
333         Map<String, List<ComponentInstanceProperty>> componentInstancesProperties = component.getComponentInstancesProperties();
334         Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces = component.getComponentInstancesInterfaces();
335         if (CollectionUtils.isNotEmpty(componentInstances)) {
336             final Either<Map<String, ToscaNodeTemplate>, ToscaError> nodeTemplates = convertNodeTemplates(component, componentInstances,
337                 componentInstancesProperties, componentInstanceInterfaces, componentCache, dataTypes, topologyTemplate);
338             if (nodeTemplates.isRight()) {
339                 return Either.right(nodeTemplates.right().value());
340             }
341             log.debug("node templates converted");
342             topologyTemplate.setNode_templates(nodeTemplates.left().value());
343         }
344         final Map<String, ToscaRelationshipTemplate> relationshipTemplatesMap =
345             new ToscaExportRelationshipTemplatesHandler().createFrom(topologyTemplate.getNode_templates());
346         if (!relationshipTemplatesMap.isEmpty()) {
347             topologyTemplate.setRelationshipTemplates(relationshipTemplatesMap);
348         }
349
350         SubstitutionMapping substitutionMapping = new SubstitutionMapping();
351         convertSubstitutionMappingFilter(component, substitutionMapping);
352
353         addGroupsToTopologyTemplate(component, topologyTemplate);
354
355         try {
356             addPoliciesToTopologyTemplate(component, topologyTemplate);
357         } catch (SdcResourceNotFoundException e) {
358             log.debug("Fail to add policies to topology template:", e);
359             return Either.right(ToscaError.GENERAL_ERROR);
360         }
361
362         String toscaResourceName;
363         switch (component.getComponentType()) {
364             case RESOURCE:
365                 toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition()
366                     .getMetadataDataDefinition()).getToscaResourceName();
367                 break;
368             case SERVICE:
369                 toscaResourceName = SERVICE_NODE_TYPE_PREFIX
370                     + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName();
371                 break;
372             default:
373                 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
374                 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
375         }
376         substitutionMapping.setNode_type(toscaResourceName);
377         Either<SubstitutionMapping, ToscaError> capabilities = convertCapabilities(component, substitutionMapping,
378             componentCache);
379         if (capabilities.isRight()) {
380             return Either.right(capabilities.right().value());
381         }
382         substitutionMapping = capabilities.left().value();
383
384         Either<SubstitutionMapping, ToscaError> requirements = capabilityRequirementConverter
385             .convertSubstitutionMappingRequirements(componentCache, component, substitutionMapping);
386         if (requirements.isRight()) {
387             return Either.right(requirements.right().value());
388         }
389         substitutionMapping = requirements.left().value();
390         final Map<String, String[]> propertyMappingMap = buildSubstitutionMappingPropertyMapping(component);
391         if (!propertyMappingMap.isEmpty()) {
392             substitutionMapping.setProperties(propertyMappingMap);
393         }
394
395         final Map<String, String[]> attributesMappingMap = buildSubstitutionMappingAttributesMapping(component);
396         if (!attributesMappingMap.isEmpty()) {
397             substitutionMapping.setAttributes(attributesMappingMap);
398         }
399
400         topologyTemplate.setSubstitution_mappings(substitutionMapping);
401
402         toscaNode.setTopology_template(topologyTemplate);
403
404         return Either.left(toscaNode);
405     }
406
407     private void convertSubstitutionMappingFilter(final Component component,
408                                                   final SubstitutionMapping substitutionMapping) {
409         if (component.getSubstitutionFilter() != null
410             && (component.getSubstitutionFilter().getProperties()).getListToscaDataDefinition() != null) {
411             substitutionMapping
412                 .setSubstitution_filter(convertToSubstitutionFilterComponent(component.getSubstitutionFilter()));
413         }
414     }
415
416     private void addGroupsToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate) {
417         Map<String, ToscaGroupTemplate> groups = groupExportParser.getGroups(component);
418         if (groups != null) {
419             topologyTemplate.addGroups(groups);
420         }
421     }
422
423     private void addPoliciesToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate)
424         throws SdcResourceNotFoundException {
425         Map<String, ToscaPolicyTemplate> policies = policyExportParser.getPolicies(component);
426         if (policies != null) {
427             topologyTemplate.addPolicies(policies);
428         }
429     }
430
431     private Map<String, String> convertMetadata(Component component) {
432         return convertMetadata(component, false, null);
433     }
434
435     private Map<String, String> convertMetadata(Component component, boolean isInstance,
436                                                 ComponentInstance componentInstance) {
437         Map<String, String> toscaMetadata = new LinkedHashMap<>();
438         toscaMetadata.put(JsonPresentationFields.INVARIANT_UUID.getPresentation(), component.getInvariantUUID());
439         toscaMetadata.put(JsonPresentationFields.UUID.getPresentation(), component.getUUID());
440         toscaMetadata
441             .put(JsonPresentationFields.NAME.getPresentation(), component.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
442         toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), component.getDescription());
443
444         List<CategoryDefinition> categories = component.getCategories();
445         CategoryDefinition categoryDefinition = categories.get(0);
446         toscaMetadata.put(JsonPresentationFields.CATEGORY.getPresentation(), categoryDefinition.getName());
447
448         if (isInstance) {
449             toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), component.getVersion());
450             toscaMetadata.put(JsonPresentationFields.CUSTOMIZATION_UUID.getPresentation(), componentInstance.getCustomizationUUID());
451             if (componentInstance.getSourceModelInvariant() != null
452                 && !componentInstance.getSourceModelInvariant().isEmpty()) {
453                 toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), componentInstance.getComponentVersion());
454                 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_INVARIANT.getPresentation(), componentInstance.getSourceModelInvariant());
455                 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_UUID.getPresentation(), componentInstance.getSourceModelUuid());
456                 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_NAME.getPresentation(), componentInstance.getSourceModelName());
457                 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
458                     toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(),
459                         componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceProxy.getDisplayValue());
460                 } else if (componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
461                     toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(),
462                         componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceSubstitution
463                             .getDisplayValue());
464                 }
465                 toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), componentInstance.getDescription());
466             }
467
468         }
469         switch (component.getComponentType()) {
470             case RESOURCE:
471                 Resource resource = (Resource) component;
472
473                 if (isInstance && (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy
474                     || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution)) {
475                     toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), componentInstance.getOriginType().getDisplayValue());
476                 } else {
477                     toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), resource.getResourceType().name());
478                 }
479                 toscaMetadata.put(JsonPresentationFields.SUB_CATEGORY.getPresentation(), categoryDefinition.getSubcategories().get(0).getName());
480                 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR.getPresentation(), resource.getVendorName());
481                 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_RELEASE.getPresentation(), resource.getVendorRelease());
482                 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_MODEL_NUMBER.getPresentation(), resource.getResourceVendorModelNumber());
483                 break;
484             case SERVICE:
485                 Service service = (Service) component;
486                 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), component.getComponentType().getValue());
487                 toscaMetadata.put(JsonPresentationFields.SERVICE_TYPE.getPresentation(), service.getServiceType());
488                 toscaMetadata.put(JsonPresentationFields.SERVICE_ROLE.getPresentation(), service.getServiceRole());
489                 toscaMetadata.put(JsonPresentationFields.SERVICE_FUNCTION.getPresentation(), service.getServiceFunction());
490                 toscaMetadata.put(JsonPresentationFields.ENVIRONMENT_CONTEXT.getPresentation(), service.getEnvironmentContext());
491                 toscaMetadata.put(JsonPresentationFields.INSTANTIATION_TYPE.getPresentation(),
492                     service.getEnvironmentContext() == null ? StringUtils.EMPTY : service.getInstantiationType());
493                 if (!isInstance) {
494                     // DE268546
495                     toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming().toString());
496                     toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming().toString());
497                     toscaMetadata.put(JsonPresentationFields.NAMING_POLICY.getPresentation(), service.getNamingPolicy());
498                 }
499                 break;
500             default:
501                 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
502         }
503
504         for (final String key : component.getCategorySpecificMetadata().keySet()) {
505             toscaMetadata.put(key, component.getCategorySpecificMetadata().get(key));
506         }
507         return toscaMetadata;
508     }
509
510     private Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports(Component component,
511                                                                                                  ToscaTemplate toscaTemplate) {
512
513         final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImportConfig();
514         if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
515             log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
516             return Either.right(ToscaError.GENERAL_ERROR);
517         }
518         Map<String, Component> componentCache = new HashMap<>();
519
520         if (!ModelConverter.isAtomicComponent(component)) {
521             final List<Map<String, Map<String, String>>> additionalImports =
522                 toscaTemplate.getImports() == null ? new ArrayList<>(defaultToscaImportConfig)
523                     : new ArrayList<>(toscaTemplate.getImports());
524
525             List<Triple<String, String, Component>> dependecies = new ArrayList<>();
526
527             Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
528             if (isNotEmpty(toscaArtifacts)) {
529                 ArtifactDefinition artifactDefinition = toscaArtifacts.get(ToscaExportHandler.ASSET_TOSCA_TEMPLATE);
530                 if (artifactDefinition != null) {
531                     Map<String, Map<String, String>> importsListMember = new HashMap<>();
532                     Map<String, String> interfaceFiles = new HashMap<>();
533                     interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactDefinition.getArtifactName()));
534                     StringBuilder keyNameBuilder = new StringBuilder();
535                     keyNameBuilder.append(component.getComponentType().toString().toLowerCase()).append("-")
536                         .append(component.getName()).append("-interface");
537                     importsListMember.put(keyNameBuilder.toString(), interfaceFiles);
538                     additionalImports.add(importsListMember);
539                 }
540             }
541             List<ComponentInstance> componentInstances = component.getComponentInstances();
542             if (componentInstances != null && !componentInstances.isEmpty()) {
543                 componentInstances.forEach(ci -> createDependency(componentCache, additionalImports, dependecies, ci));
544             }
545             toscaTemplate.setDependencies(dependecies);
546             toscaTemplate.setImports(additionalImports);
547         } else {
548             log.debug("currently imports supported for VF and service only");
549         }
550         return Either.left(new ImmutablePair<>(toscaTemplate, componentCache));
551     }
552
553     private List<Map<String, Map<String, String>>> getDefaultToscaImportConfig() {
554         return ConfigurationManager.getConfigurationManager().getConfiguration().getDefaultImports();
555     }
556
557     private void createDependency(final Map<String, Component> componentCache,
558                                   final List<Map<String, Map<String, String>>> imports,
559                                   final List<Triple<String, String, Component>> dependencies,
560                                   final ComponentInstance componentInstance) {
561         log.debug("createDependency componentCache {}", componentCache);
562         Component componentRI = componentCache.get(componentInstance.getComponentUid());
563         if (componentRI == null || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
564             // all resource must be only once!
565             final Either<Component, StorageOperationStatus> resource = toscaOperationFacade
566                 .getToscaFullElement(componentInstance.getComponentUid());
567             if ((resource.isRight()) && (log.isDebugEnabled())) {
568                 log.debug("Failed to fetch resource with id {} for instance {}", componentInstance.getComponentUid(),
569                     componentInstance.getUniqueId());
570                 return;
571             }
572             final Component fetchedComponent = resource.left().value();
573             componentRI = setComponentCache(componentCache, componentInstance, fetchedComponent);
574             addDependencies(imports, dependencies, componentRI);
575         }
576     }
577
578     /**
579      * Sets a componentCache from the given component/resource.
580      */
581     private Component setComponentCache(final Map<String, Component> componentCache,
582                                    final ComponentInstance componentInstance,
583                                    final Component fetchedComponent) {
584         componentCache.put(fetchedComponent.getUniqueId(), fetchedComponent);
585         if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy
586             || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
587             final Either<Component, StorageOperationStatus> sourceService = toscaOperationFacade
588                 .getToscaFullElement(componentInstance.getSourceModelUid());
589             if (sourceService.isRight() && (log.isDebugEnabled())) {
590                 log.debug("Failed to fetch source service with id {} for proxy {}",
591                     componentInstance.getSourceModelUid(), componentInstance.getUniqueId());
592             }
593             final Component fetchedSource = sourceService.left().value();
594             componentCache.put(fetchedSource.getUniqueId(), fetchedSource);
595             return fetchedSource;
596         }
597         return fetchedComponent;
598     }
599
600     /**
601      * Retrieves all derived_from nodes and stores it in a predictable order.
602      */
603     private void addDependencies(final List<Map<String, Map<String, String>>> imports,
604                                  final List<Triple<String, String, Component>> dependencies,
605                                  final Component fetchedComponent) {
606         final Set<Component> componentsList = new LinkedHashSet<>();
607         if (fetchedComponent instanceof Resource) {
608             log.debug("fetchedComponent is a resource {}", fetchedComponent);
609
610             final Optional<Map<String, String>> derivedFromMapOfIdToName = getDerivedFromMapOfIdToName(fetchedComponent,
611                 componentsList);
612             if (derivedFromMapOfIdToName.isPresent() && !derivedFromMapOfIdToName.get().isEmpty()) {
613                 derivedFromMapOfIdToName.get().entrySet().forEach(entry -> {
614                     log.debug("Started entry.getValue() : {}", entry.getValue());
615                     if (!NATIVE_ROOT.equals(entry.getValue())) {
616                         Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade
617                             .getToscaElement(entry.getKey());
618                         if (resourcefetched != null && resourcefetched.isLeft()) {
619                             componentsList.add(resourcefetched.left().value());
620                         }
621                     }
622                 });
623                 setImports(imports, dependencies, componentsList);
624             } else {
625                 setImports(imports, dependencies, fetchedComponent);
626             }
627
628         }
629     }
630
631     /**
632      * Returns all derived_from nodes found.
633      */
634     private Optional<Map<String, String>> getDerivedFromMapOfIdToName(final Component fetchedComponent,
635                                                                       final Set<Component> componentsList) {
636         final Resource parentResource = (Resource) fetchedComponent;
637         Map<String, String> derivedFromMapOfIdToName = new HashMap<>();
638         if (CollectionUtils.isNotEmpty(parentResource.getComponentInstances())) {
639             componentsList.add(fetchedComponent);
640             for (final ComponentInstance componentInstance : parentResource.getComponentInstances()) {
641                 final Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade
642                     .getToscaElement(componentInstance.getComponentUid());
643                 if (resourcefetched != null && resourcefetched.isLeft()) {
644                     final Map<String, String> derivedWithId = resourcefetched.left().value()
645                         .getDerivedFromMapOfIdToName();
646                     if (MapUtils.isNotEmpty(derivedWithId)) {
647                         derivedFromMapOfIdToName.putAll(derivedWithId);
648                     }
649                 }
650             }
651         } else {
652             derivedFromMapOfIdToName = parentResource.getDerivedFromMapOfIdToName();
653         }
654         log.debug("Started derivedFromMapOfIdToName: {}", derivedFromMapOfIdToName);
655         return Optional.ofNullable(derivedFromMapOfIdToName);
656     }
657
658     /**
659      * Creates a resource map and adds it to the import list.
660      */
661     private void setImports(final List<Map<String, Map<String, String>>> imports,
662                             final List<Triple<String, String, Component>> dependencies,
663                             final Set<Component> componentsList) {
664         componentsList.forEach(component -> setImports(imports, dependencies, component));
665     }
666
667     private void setImports(final List<Map<String, Map<String, String>>> imports,
668                             final List<Triple<String, String, Component>> dependencies,
669                             final Component component) {
670         final Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
671         final ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE);
672         if (artifactDefinition != null) {
673             final Map<String, String> files = new HashMap<>();
674             final String artifactName = artifactDefinition.getArtifactName();
675             files.put(IMPORTS_FILE_KEY, artifactName);
676             final StringBuilder keyNameBuilder = new StringBuilder();
677             keyNameBuilder.append(component.getComponentType().toString().toLowerCase());
678             keyNameBuilder.append("-");
679             keyNameBuilder.append(component.getName());
680             addImports(imports, keyNameBuilder, files);
681             dependencies
682                     .add(new ImmutableTriple<>(artifactName, artifactDefinition.getEsId(), component));
683
684             if (!ModelConverter.isAtomicComponent(component)) {
685                 final Map<String, String> interfaceFiles = new HashMap<>();
686                 interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactName));
687                 keyNameBuilder.append("-interface");
688                 addImports(imports, keyNameBuilder, interfaceFiles);
689             }
690         }
691     }
692
693     /**
694      * Adds the found resource to the import definition list.
695      */
696     private void addImports(final List<Map<String, Map<String, String>>> imports,
697                             final StringBuilder keyNameBuilder,
698                             final Map<String, String> files) {
699         final String mapKey = keyNameBuilder.toString();
700         if (imports.stream().allMatch(stringMapMap -> stringMapMap.get(mapKey) == null)) {
701             final Map<String, Map<String, String>> importsListMember = new HashMap<>();
702             importsListMember.put(keyNameBuilder.toString(), files);
703             imports.add(importsListMember);
704         }
705     }
706
707     public static String getInterfaceFilename(String artifactName) {
708         return artifactName.substring(0, artifactName.lastIndexOf('.')) + ToscaExportHandler.TOSCA_INTERFACE_NAME;
709     }
710
711     private Either<ToscaTemplate, ToscaError> convertNodeType(Map<String, Component> componentsCache,
712                                                               Component component, ToscaTemplate toscaNode,
713                                                               Map<String, ToscaNodeType> nodeTypes) {
714         return convertInterfaceNodeType(componentsCache, component, toscaNode, nodeTypes, false);
715     }
716
717     public Either<ToscaTemplate, ToscaError> convertInterfaceNodeType(Map<String, Component> componentsCache,
718                                                                       Component component, ToscaTemplate toscaNode,
719                                                                       Map<String, ToscaNodeType> nodeTypes,
720                                                                       boolean isAssociatedComponent) {
721         log.debug("start convert node type for {}", component.getUniqueId());
722         ToscaNodeType toscaNodeType = createNodeType(component);
723
724         Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither =
725             interfaceLifecycleOperation.getAllInterfaceLifecycleTypes();
726         if (lifecycleTypeEither.isRight()) {
727             log.debug("Failed to fetch all interface types :", lifecycleTypeEither.right().value());
728             return Either.right(ToscaError.GENERAL_ERROR);
729         }
730         List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value()
731             .values()
732             .stream()
733             .map(InterfaceDataDefinition::getType)
734             .collect(Collectors.toList());
735         toscaNode.setInterface_types(addInterfaceTypeElement(component, allGlobalInterfaceTypes));
736
737         Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = dataTypeCache.getAll();
738         if (dataTypesEither.isRight()) {
739             log.debug("Failed to fetch all data types :", dataTypesEither.right().value());
740             return Either.right(ToscaError.GENERAL_ERROR);
741         }
742
743         Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
744
745         List<InputDefinition> inputDef = component.getInputs();
746         Map<String, ToscaProperty> mergedProperties = new HashMap<>();
747         interfacesOperationsConverter
748             .addInterfaceDefinitionElement(component, toscaNodeType, dataTypes, isAssociatedComponent);
749         addInputsToProperties(dataTypes, inputDef, mergedProperties);
750
751         if (CollectionUtils.isNotEmpty(component.getProperties())) {
752             List<PropertyDefinition> properties = component.getProperties();
753             Map<String, ToscaProperty> convertedProperties = properties.stream()
754                 .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, component.getInputs()))
755                 .collect(Collectors.toMap(PropertyDataDefinition::getName,
756                     property -> propertyConvertor.convertProperty(dataTypes, property,
757                         PropertyConvertor.PropertyType.PROPERTY)));
758             // merge component properties and inputs properties
759             mergedProperties.putAll(convertedProperties);
760         }
761         if (MapUtils.isNotEmpty(mergedProperties)) {
762             toscaNodeType.setProperties(mergedProperties);
763         }
764
765         /* convert private data_types */
766         List<DataTypeDefinition> privateDataTypes = component.getDataTypes();
767         if (CollectionUtils.isNotEmpty(privateDataTypes)) {
768             Map<String, ToscaDataType> toscaDataTypeMap = new HashMap<>();
769             for (DataTypeDefinition dataType : privateDataTypes) {
770                 log.debug("Emitting private data type: component.name={} dataType.name={}",
771                     component.getNormalizedName(), dataType.getName());
772                 ToscaDataType toscaDataType = new ToscaDataType();
773                 toscaDataType.setDerived_from(dataType.getDerivedFromName());
774                 toscaDataType.setDescription(dataType.getDescription());
775                 toscaDataType.setVersion(dataType.getVersion());
776                 if (CollectionUtils.isNotEmpty(dataType.getProperties())) {
777                     toscaDataType.setProperties(dataType.getProperties().stream()
778                         .collect(Collectors.toMap(
779                             PropertyDataDefinition::getName,
780                             s -> propertyConvertor
781                                 .convertProperty(dataTypes, s, PropertyType.PROPERTY)
782                         )));
783                 }
784                 toscaDataTypeMap.put(dataType.getName(), toscaDataType);
785             }
786             toscaNode.setData_types(toscaDataTypeMap);
787         }
788
789         // Extracted to method for code reuse
790         return convertReqCapAndTypeName(componentsCache, component, toscaNode, nodeTypes, toscaNodeType, dataTypes);
791     }
792
793     private Either<ToscaTemplate, ToscaError> convertReqCapAndTypeName(Map<String, Component> componentsCache,
794                                                                        Component component, ToscaTemplate toscaNode,
795                                                                        Map<String, ToscaNodeType> nodeTypes,
796                                                                        ToscaNodeType toscaNodeType,
797                                                                        Map<String, DataTypeDefinition> dataTypes) {
798         Either<ToscaNodeType, ToscaError> capabilities = convertCapabilities(componentsCache, component, toscaNodeType,
799             dataTypes);
800         if (capabilities.isRight()) {
801             return Either.right(capabilities.right().value());
802         }
803         toscaNodeType = capabilities.left().value();
804         log.debug("Capabilities converted for {}", component.getUniqueId());
805
806         Either<ToscaNodeType, ToscaError> requirements = capabilityRequirementConverter
807             .convertRequirements(componentsCache, component,
808                 toscaNodeType);
809         if (requirements.isRight()) {
810             return Either.right(requirements.right().value());
811         }
812         toscaNodeType = requirements.left().value();
813         log.debug("Requirements converted for {}", component.getUniqueId());
814
815         String toscaResourceName;
816         switch (component.getComponentType()) {
817             case RESOURCE:
818                 toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition()
819                     .getMetadataDataDefinition()).getToscaResourceName();
820                 break;
821             case SERVICE:
822                 toscaResourceName = SERVICE_NODE_TYPE_PREFIX
823                     + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName();
824                 break;
825             default:
826                 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
827                 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
828         }
829
830         nodeTypes.put(toscaResourceName, toscaNodeType);
831         toscaNode.setNode_types(nodeTypes);
832         log.debug("finish convert node type for {}", component.getUniqueId());
833         return Either.left(toscaNode);
834     }
835
836     protected Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplates(
837         Component component,
838         List<ComponentInstance> componentInstances,
839         Map<String, List<ComponentInstanceProperty>> componentInstancesProperties,
840         Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces,
841         Map<String, Component> componentCache, Map<String, DataTypeDefinition> dataTypes,
842         ToscaTopolgyTemplate topologyTemplate) {
843
844         Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplatesRes = null;
845         log.debug("start convert topology template for {} for type {}", component.getUniqueId(),
846             component.getComponentType());
847         Map<String, ToscaNodeTemplate> nodeTemplates = new HashMap<>();
848         Map<String, List<ComponentInstanceInput>> componentInstancesInputs = component.getComponentInstancesInputs();
849
850         Map<String, ToscaGroupTemplate> groupsMap = null;
851         for (ComponentInstance componentInstance : componentInstances) {
852             ToscaNodeTemplate nodeTemplate = new ToscaNodeTemplate();
853             if (MapUtils.isNotEmpty(componentInstance.getToscaArtifacts())) {
854                 nodeTemplate.setArtifacts(convertToNodeTemplateArtifacts(componentInstance.getToscaArtifacts()));
855             }
856             nodeTemplate.setType(componentInstance.getToscaComponentName());
857             nodeTemplate.setDirectives(componentInstance.getDirectives());
858             nodeTemplate.setNode_filter(convertToNodeTemplateNodeFilterComponent(componentInstance.getNodeFilter()));
859
860             Either<Component, Boolean> originComponentRes = capabilityRequirementConverter
861                 .getOriginComponent(componentCache, componentInstance);
862             if (originComponentRes.isRight()) {
863                 convertNodeTemplatesRes = Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
864                 break;
865             }
866             Either<ToscaNodeTemplate, ToscaError> requirements = convertComponentInstanceRequirements(component,
867                 componentInstance, component.getComponentInstancesRelations(), nodeTemplate,
868                 originComponentRes.left().value(), componentCache);
869             if (requirements.isRight()) {
870                 convertNodeTemplatesRes = Either.right(requirements.right().value());
871                 break;
872             }
873             String instanceUniqueId = componentInstance.getUniqueId();
874             log.debug("Component instance Requirements converted for instance {}", instanceUniqueId);
875
876             nodeTemplate = requirements.left().value();
877
878             Component originalComponent = componentCache.get(componentInstance.getActualComponentUid());
879
880             if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
881                 Component componentOfProxy = componentCache.get(componentInstance.getComponentUid());
882                 nodeTemplate.setMetadata(convertMetadata(componentOfProxy, true, componentInstance));
883             } else {
884                 nodeTemplate.setMetadata(convertMetadata(originalComponent, true, componentInstance));
885             }
886
887             Either<ToscaNodeTemplate, ToscaError> capabilities = capabilityRequirementConverter
888                 .convertComponentInstanceCapabilities(componentInstance, dataTypes, nodeTemplate);
889             if (capabilities.isRight()) {
890                 convertNodeTemplatesRes = Either.right(capabilities.right().value());
891                 break;
892             }
893             log.debug("Component instance Capabilities converted for instance {}", instanceUniqueId);
894
895             nodeTemplate = capabilities.left().value();
896             Map<String, Object> props = new HashMap<>();
897
898             if (originalComponent.getComponentType() == ComponentTypeEnum.RESOURCE) {
899                 // Adds the properties of parent component to map
900                 addPropertiesOfParentComponent(dataTypes, originalComponent, props);
901             }
902
903             if (null != componentInstancesProperties && componentInstancesProperties.containsKey(instanceUniqueId)) {
904                 addPropertiesOfComponentInstance(componentInstancesProperties, dataTypes, instanceUniqueId,
905                     props);
906             }
907
908             if (componentInstancesInputs != null && componentInstancesInputs.containsKey(instanceUniqueId)
909                 && !isComponentOfTypeServiceProxy(componentInstance)) {
910                 //For service proxy the inputs are already handled under instance properties above
911                 addComponentInstanceInputs(dataTypes, componentInstancesInputs, instanceUniqueId, props);
912             }
913
914             //M3[00001] - NODE TEMPLATE INTERFACES  - START
915             handleInstanceInterfaces(componentInstanceInterfaces, componentInstance, dataTypes, nodeTemplate,
916                 instanceUniqueId, component);
917             //M3[00001] - NODE TEMPLATE INTERFACES  - END
918             if (props != null && !props.isEmpty()) {
919                 nodeTemplate.setProperties(props);
920             }
921
922             List<GroupInstance> groupInstances = componentInstance.getGroupInstances();
923             if (groupInstances != null) {
924                 if (groupsMap == null) {
925                     groupsMap = new HashMap<>();
926                 }
927                 for (GroupInstance groupInst : groupInstances) {
928                     boolean addToTosca = true;
929
930                     List<String> artifacts = groupInst.getArtifacts();
931                     if (artifacts == null || artifacts.isEmpty()) {
932                         addToTosca = false;
933                     }
934
935                     if (addToTosca) {
936                         ToscaGroupTemplate toscaGroup = groupExportParser
937                             .getToscaGroupTemplate(groupInst, componentInstance.getInvariantName());
938                         groupsMap.put(groupInst.getName(), toscaGroup);
939                     }
940                 }
941             }
942
943             nodeTemplates.put(componentInstance.getName(), nodeTemplate);
944         }
945         if (groupsMap != null) {
946             log.debug("instance groups added");
947             topologyTemplate.addGroups(groupsMap);
948         }
949         if (component.getComponentType() == ComponentTypeEnum.SERVICE && isNotEmpty(
950             ((Service) component).getForwardingPaths())) {
951             log.debug("Starting converting paths for component {}, name {}", component.getUniqueId(),
952                 component.getName());
953             ForwardingPathToscaUtil
954                 .addForwardingPaths((Service) component, nodeTemplates, capabilityRequirementConverter, componentCache,
955                     toscaOperationFacade);
956             log.debug("Finished converting paths for component {}, name {}", component.getUniqueId(),
957                 component.getName());
958         }
959         if (convertNodeTemplatesRes == null) {
960             convertNodeTemplatesRes = Either.left(nodeTemplates);
961         }
962         log.debug("finish convert topology template for {} for type {}", component.getUniqueId(),
963             component.getComponentType());
964         return convertNodeTemplatesRes;
965     }
966
967     private void handleInstanceInterfaces(
968         Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces,
969         ComponentInstance componentInstance, Map<String, DataTypeDefinition> dataTypes, ToscaNodeTemplate nodeTemplate,
970         String instanceUniqueId,
971         Component parentComponent) {
972
973         if (MapUtils.isEmpty(componentInstanceInterfaces)
974             || !componentInstanceInterfaces.containsKey(instanceUniqueId)) {
975             nodeTemplate.setInterfaces(null);
976             return;
977         }
978
979         final List<ComponentInstanceInterface> currServiceInterfaces =
980             componentInstanceInterfaces.get(instanceUniqueId);
981
982         final Map<String, InterfaceDefinition> tmpInterfaces = new HashMap<>();
983         currServiceInterfaces.forEach(instInterface -> tmpInterfaces.put(instInterface
984             .getUniqueId(), instInterface));
985
986         final Map<String, Object> interfaceMap = interfacesOperationsConverter
987             .getInterfacesMap(parentComponent, componentInstance, tmpInterfaces, dataTypes, isComponentOfTypeServiceProxy(componentInstance),
988                 isComponentOfTypeServiceProxy(componentInstance));
989
990         interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
991         nodeTemplate.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap);
992     }
993
994     private boolean isComponentOfTypeServiceProxy(ComponentInstance componentInstance) {
995         return Objects.nonNull(componentInstance.getOriginType())
996             && componentInstance.getOriginType().getValue().equals("Service Proxy");
997     }
998
999     private void addComponentInstanceInputs(Map<String, DataTypeDefinition> dataTypes,
1000                                             Map<String, List<ComponentInstanceInput>> componentInstancesInputs,
1001                                             String instanceUniqueId, Map<String, Object> props) {
1002
1003         List<ComponentInstanceInput> instanceInputsList = componentInstancesInputs.get(instanceUniqueId);
1004         if (instanceInputsList != null) {
1005             instanceInputsList.forEach(input -> {
1006
1007                 Supplier<String> supplier = () -> input.getValue() != null && !Objects.isNull(input.getValue())
1008                     ? input.getValue() : input.getDefaultValue();
1009                 propertyConvertor.convertAndAddValue(dataTypes, props, input, supplier);
1010             });
1011         }
1012     }
1013
1014     private void addPropertiesOfComponentInstance(
1015         Map<String, List<ComponentInstanceProperty>> componentInstancesProperties,
1016         Map<String, DataTypeDefinition> dataTypes, String instanceUniqueId,
1017         Map<String, Object> props) {
1018
1019         if (isNotEmpty(componentInstancesProperties)) {
1020             componentInstancesProperties.get(instanceUniqueId)
1021                 // Converts and adds each value to property map
1022                 .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop,
1023                     prop::getValue));
1024         }
1025     }
1026
1027     private void addPropertiesOfParentComponent(Map<String, DataTypeDefinition> dataTypes,
1028                                                 Component componentOfInstance, Map<String, Object> props) {
1029
1030         List<PropertyDefinition> componentProperties = componentOfInstance.getProperties();
1031         if (isNotEmpty(componentProperties)) {
1032             componentProperties.stream()
1033                 // Filters out properties with empty default values
1034                 .filter(prop -> StringUtils.isNotEmpty(prop.getDefaultValue()))
1035                 // Converts and adds each value to property map
1036                 .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop,
1037                     prop::getDefaultValue));
1038         }
1039     }
1040
1041     private ToscaNodeType createNodeType(Component component) {
1042         ToscaNodeType toscaNodeType = new ToscaNodeType();
1043         if (ModelConverter.isAtomicComponent(component)) {
1044             if (((Resource) component).getDerivedFrom() != null) {
1045                 toscaNodeType.setDerived_from(((Resource) component).getDerivedFrom().get(0));
1046             }
1047             toscaNodeType.setDescription(component.getDescription());
1048         } else {
1049             String derivedFrom = null != component.getDerivedFromGenericType() ? component.getDerivedFromGenericType()
1050                 : NATIVE_ROOT;
1051             toscaNodeType.setDerived_from(derivedFrom);
1052         }
1053         if (component instanceof Resource) {
1054             final List<AttributeDefinition> attributes = ((Resource) component).getAttributes();
1055             if (CollectionUtils.isNotEmpty(attributes)) {
1056                 final Map<String, Object> attributeDataDefinitionMap = new HashMap<>();
1057                 attributes.forEach(attributeDataDefinition ->
1058                     buildAttributeData(attributeDataDefinition, attributeDataDefinitionMap));
1059
1060                 toscaNodeType.setAttributes(attributeDataDefinitionMap);
1061             }
1062         }
1063         return toscaNodeType;
1064     }
1065
1066     private void buildAttributeData(final AttributeDefinition originalAttributeDefinition,
1067                                     final Map<String, Object> attributeDataDefinitionMap) {
1068
1069         attributeDataDefinitionMap.put(originalAttributeDefinition.getName(),
1070             new ObjectMapper().convertValue(new org.onap.sdc.tosca.datatypes.model.AttributeDefinition(
1071                 originalAttributeDefinition.getType(),
1072                 originalAttributeDefinition.getDescription(),
1073                 originalAttributeDefinition.get_default(),
1074                 originalAttributeDefinition.getStatus(),
1075                 originalAttributeDefinition.getEntry_schema()), Object.class));
1076     }
1077
1078     private Either<Map<String, Object>, ToscaError> createProxyInterfaceTypes(Component container) {
1079
1080         Map<String, Object> proxyInterfaceTypes = new HashMap<>();
1081         Either<Map<String, Object>, ToscaError> res = Either.left(proxyInterfaceTypes);
1082         List<ComponentInstance> componentInstances = container.getComponentInstances();
1083         if (CollectionUtils.isEmpty(componentInstances)) {
1084             return res;
1085         }
1086         Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
1087         componentInstances.stream()
1088             .filter(this::isComponentOfTypeServiceProxy)
1089             .forEach(inst -> serviceProxyInstanceList.put(inst.getToscaComponentName(), inst));
1090         if (MapUtils.isEmpty(serviceProxyInstanceList)) {
1091             return res;
1092         }
1093         for (Entry<String, ComponentInstance> entryProxy : serviceProxyInstanceList.entrySet()) {
1094             Component serviceComponent;
1095             ComponentParametersView componentParametersView = new ComponentParametersView();
1096             componentParametersView.disableAll();
1097             componentParametersView.setIgnoreInterfaces(false);
1098             Either<Component, StorageOperationStatus> service = toscaOperationFacade
1099                 .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
1100             if (service.isRight()) {
1101                 log.debug("Failed to fetch original service component with id {} for instance {}",
1102                     entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName());
1103                 return Either.right(ToscaError.GENERAL_ERROR);
1104             } else {
1105                 serviceComponent = service.left().value();
1106             }
1107
1108             Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither =
1109                 interfaceLifecycleOperation.getAllInterfaceLifecycleTypes();
1110             if (lifecycleTypeEither.isRight()) {
1111                 log.debug("Failed to retrieve global interface types :", lifecycleTypeEither.right().value());
1112                 return Either.right(ToscaError.GENERAL_ERROR);
1113             }
1114
1115             List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value().values().stream()
1116                 .map(InterfaceDataDefinition::getType)
1117                 .collect(Collectors.toList());
1118             //Add interface types for local interfaces in the original service component for proxy
1119             Map<String, Object> localInterfaceTypes = addInterfaceTypeElement(serviceComponent,
1120                 allGlobalInterfaceTypes);
1121             if (MapUtils.isNotEmpty(localInterfaceTypes)) {
1122                 proxyInterfaceTypes.putAll(localInterfaceTypes);
1123             }
1124
1125         }
1126         return Either.left(proxyInterfaceTypes);
1127     }
1128
1129     private Either<Map<String, ToscaNodeType>, ToscaError> createProxyNodeTypes(Map<String, Component> componentCache,
1130                                                                                 Component container) {
1131
1132         Map<String, ToscaNodeType> nodeTypesMap = new HashMap<>();
1133         Either<Map<String, ToscaNodeType>, ToscaError> res = Either.left(nodeTypesMap);
1134
1135         List<ComponentInstance> componentInstances = container.getComponentInstances();
1136
1137         if (componentInstances == null || componentInstances.isEmpty()) {
1138             return res;
1139         }
1140         Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
1141         List<ComponentInstance> proxyInst = componentInstances.stream()
1142             .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceProxy.name()))
1143             .collect(Collectors.toList());
1144         if (proxyInst != null && !proxyInst.isEmpty()) {
1145             for (ComponentInstance inst : proxyInst) {
1146                 serviceProxyInstanceList.put(inst.getToscaComponentName(), inst);
1147             }
1148         }
1149
1150         if (serviceProxyInstanceList.isEmpty()) {
1151             return res;
1152         }
1153         Either<Resource, StorageOperationStatus> serviceProxyOrigin = toscaOperationFacade
1154             .getLatestByName("serviceProxy");
1155         if (serviceProxyOrigin.isRight()) {
1156             log.debug("Failed to fetch normative service proxy resource by tosca name, error {}",
1157                 serviceProxyOrigin.right().value());
1158             return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
1159         }
1160         Component origComponent = serviceProxyOrigin.left().value();
1161
1162         for (Entry<String, ComponentInstance> entryProxy : serviceProxyInstanceList.entrySet()) {
1163             Component serviceComponent = null;
1164             ComponentParametersView componentParametersView = new ComponentParametersView();
1165             componentParametersView.disableAll();
1166             componentParametersView.setIgnoreCategories(false);
1167             componentParametersView.setIgnoreProperties(false);
1168             componentParametersView.setIgnoreInputs(false);
1169             componentParametersView.setIgnoreInterfaces(false);
1170             componentParametersView.setIgnoreRequirements(false);
1171             Either<Component, StorageOperationStatus> service = toscaOperationFacade
1172                 .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
1173             if (service.isRight()) {
1174                 log.debug("Failed to fetch resource with id {} for instance {}",
1175                     entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName());
1176             } else {
1177                 serviceComponent = service.left().value();
1178             }
1179
1180             ToscaNodeType toscaNodeType = createProxyNodeType(componentCache, origComponent, serviceComponent,
1181                 entryProxy.getValue());
1182             nodeTypesMap.put(entryProxy.getKey(), toscaNodeType);
1183         }
1184
1185         return Either.left(nodeTypesMap);
1186     }
1187
1188     private void createServiceSubstitutionNodeTypes(final Map<String, Component> componentCache,
1189                                                     final Component container, final ToscaTemplate toscaNode) {
1190         final List<ComponentInstance> componentInstances = container.getComponentInstances();
1191
1192         if (CollectionUtils.isEmpty(componentInstances)) {
1193             return;
1194         }
1195         final List<ComponentInstance> serviceSubstitutionInstanceList = componentInstances.stream()
1196             .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceSubstitution.name()))
1197             .collect(Collectors.toList());
1198         if (CollectionUtils.isNotEmpty(serviceSubstitutionInstanceList)) {
1199             for (ComponentInstance inst : serviceSubstitutionInstanceList) {
1200                 final Map<String, ToscaNodeType> nodeTypes =
1201                     toscaNode.getNode_types() == null ? new HashMap<>() : toscaNode.getNode_types();
1202                 convertInterfaceNodeType(new HashMap<>(), componentCache.get(inst.getSourceModelUid()), toscaNode,
1203                     nodeTypes, true);
1204             }
1205         }
1206     }
1207
1208     private ToscaNodeType createProxyNodeType(Map<String, Component> componentCache, Component origComponent,
1209                                               Component proxyComponent, ComponentInstance componentInstance) {
1210         ToscaNodeType toscaNodeType = new ToscaNodeType();
1211         String derivedFrom = ((Resource) origComponent).getToscaResourceName();
1212
1213         toscaNodeType.setDerived_from(derivedFrom);
1214         Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = dataTypeCache.getAll();
1215         if (dataTypesEither.isRight()) {
1216             log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
1217         }
1218         Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
1219         Map<String, ToscaCapability> capabilities = this.capabilityRequirementConverter
1220             .convertProxyCapabilities(componentCache, componentInstance, dataTypes);
1221
1222         if (MapUtils.isNotEmpty(capabilities)) {
1223             toscaNodeType.setCapabilities(capabilities);
1224         }
1225         List<Map<String, ToscaRequirement>> proxyNodeTypeRequirements = this.capabilityRequirementConverter
1226             .convertProxyRequirements(componentCache, componentInstance);
1227         if (CollectionUtils.isNotEmpty(proxyNodeTypeRequirements)) {
1228             toscaNodeType.setRequirements(proxyNodeTypeRequirements);
1229         }
1230         Optional<Map<String, ToscaProperty>> proxyProperties = getProxyNodeTypeProperties(proxyComponent, dataTypes);
1231         proxyProperties.ifPresent(toscaNodeType::setProperties);
1232
1233         Map<String, Object> interfaceMap = new HashMap<>();
1234         if (MapUtils.isEmpty(componentInstance.getInterfaces())) {
1235             final Optional<Map<String, Object>> proxyInterfaces = getProxyNodeTypeInterfaces(proxyComponent, dataTypes);
1236             if (proxyInterfaces.isPresent()) {
1237                 interfaceMap = proxyInterfaces.get();
1238             }
1239         } else {
1240             interfaceMap = interfacesOperationsConverter
1241                 .getInterfacesMapFromComponentInstance(proxyComponent, componentInstance, dataTypes, false, false);
1242
1243         }
1244         interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
1245         toscaNodeType.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap);
1246
1247         return toscaNodeType;
1248     }
1249
1250     private Either<ToscaNodeTemplate, ToscaError> convertComponentInstanceRequirements(Component component,
1251                                                                                        ComponentInstance componentInstance,
1252                                                                                        List<RequirementCapabilityRelDef> relations,
1253                                                                                        ToscaNodeTemplate nodeTypeTemplate,
1254                                                                                        Component originComponent,
1255                                                                                        Map<String, Component> componentCache) {
1256
1257         final List<Map<String, ToscaTemplateRequirement>> toscaRequirements;
1258         final List<RequirementCapabilityRelDef> requirementDefinitionList = filterRequirements(componentInstance,
1259             relations);
1260         if (isNotEmpty(requirementDefinitionList)) {
1261             try {
1262                 toscaRequirements = buildRequirements(component, componentInstance,
1263                     requirementDefinitionList, originComponent, componentCache);
1264                 if (!toscaRequirements.isEmpty()) {
1265                     nodeTypeTemplate.setRequirements(toscaRequirements);
1266                 }
1267             } catch (final Exception e) {
1268                 log.debug("Failed to convert component instance requirements for the component instance {}. ",
1269                     componentInstance.getName(), e);
1270                 return Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
1271             }
1272         }
1273         log.debug("Finished to convert requirements for the node type {} ", componentInstance.getName());
1274         return Either.left(nodeTypeTemplate);
1275     }
1276
1277     private List<Map<String, ToscaTemplateRequirement>> buildRequirements(final Component component,
1278                                                                           final ComponentInstance componentInstance,
1279                                                                           final List<RequirementCapabilityRelDef> filteredRelations,
1280                                                                           final Component originComponent,
1281                                                                           final Map<String, Component> componentCache)
1282         throws ToscaExportException {
1283
1284         final List<Map<String, ToscaTemplateRequirement>> toscaRequirements = new ArrayList<>();
1285         for (RequirementCapabilityRelDef relationshipDefinition : filteredRelations) {
1286             final Map<String, ToscaTemplateRequirement> toscaTemplateRequirementMap =
1287                 buildRequirement(componentInstance, originComponent, component.getComponentInstances(),
1288                     relationshipDefinition, componentCache);
1289             toscaRequirements.add(toscaTemplateRequirementMap);
1290         }
1291
1292         return toscaRequirements;
1293     }
1294
1295     private List<RequirementCapabilityRelDef> filterRequirements(ComponentInstance componentInstance,
1296                                                                  List<RequirementCapabilityRelDef> relations) {
1297         return relations.stream()
1298             .filter(p -> componentInstance.getUniqueId().equals(p.getFromNode())).collect(Collectors.toList());
1299     }
1300
1301     private Map<String, ToscaTemplateRequirement> buildRequirement(final ComponentInstance fromInstance,
1302                                                                    final Component fromOriginComponent,
1303                                                                    final List<ComponentInstance> instancesList,
1304                                                                    final RequirementCapabilityRelDef relationshipDefinition,
1305                                                                    final Map<String, Component> componentCache)
1306         throws ToscaExportException {
1307
1308         final Map<String, List<RequirementDefinition>> reqMap = fromOriginComponent.getRequirements();
1309         final CapabilityRequirementRelationship capabilityRequirementRelationship = relationshipDefinition
1310             .getRelationships().get(0);
1311         final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation();
1312
1313         final ComponentInstance toInstance = instancesList.stream()
1314             .filter(i -> relationshipDefinition.getToNode().equals(i.getUniqueId()))
1315             .findFirst().orElse(null);
1316         if (toInstance == null) {
1317             final String errorMsg = String
1318                 .format("Failed to find a relation from the node %s to the node %s", fromInstance.getName(),
1319                     relationshipDefinition.getToNode());
1320             log.debug(errorMsg);
1321             throw new ToscaExportException(errorMsg);
1322         }
1323         final Optional<RequirementDefinition> reqOpt =
1324             findRequirement(fromOriginComponent, reqMap, relationshipInfo, fromInstance.getUniqueId());
1325         if (reqOpt.isEmpty()) {
1326             final String errorMsg = String
1327                 .format("Failed to find a requirement with uniqueId %s on a component with uniqueId %s",
1328                     relationshipInfo.getRequirementUid(), fromOriginComponent.getUniqueId());
1329             log.debug(errorMsg);
1330             throw new ToscaExportException(errorMsg);
1331         }
1332         final ComponentParametersView filter = new ComponentParametersView(true);
1333         filter.setIgnoreComponentInstances(false);
1334         filter.setIgnoreCapabilities(false);
1335         filter.setIgnoreGroups(false);
1336         final Either<Component, StorageOperationStatus> getOriginRes =
1337             toscaOperationFacade.getToscaElement(toInstance.getActualComponentUid(), filter);
1338         if (getOriginRes.isRight()) {
1339             final String errorMsg = String.format(
1340                 "Failed to build substituted name for the requirement %s. "
1341                     + "Failed to get an origin component with uniqueId %s",
1342                 reqOpt.get().getName(), toInstance.getActualComponentUid());
1343             log.debug(errorMsg);
1344             throw new ToscaExportException(errorMsg);
1345         }
1346         final Component toOriginComponent = getOriginRes.left().value();
1347         Optional<CapabilityDefinition> capOpt = toOriginComponent.getCapabilities().get(reqOpt.get().getCapability()).stream()
1348             .filter(c -> isCapabilityBelongToRelation(relationshipInfo, c)).findFirst();
1349         if (capOpt.isEmpty()) {
1350             capOpt = findCapability(relationshipInfo, toOriginComponent, fromOriginComponent, reqOpt.get());
1351             if (capOpt.isEmpty()) {
1352                 final String errorMsg = String
1353                     .format("Failed to find a capability with name %s on a component with uniqueId %s",
1354                         relationshipInfo.getCapability(), fromOriginComponent.getUniqueId());
1355                 log.debug(errorMsg);
1356                 throw new ToscaExportException(errorMsg);
1357             }
1358         }
1359         return buildRequirement(fromOriginComponent, toOriginComponent, capOpt.get(), reqOpt.get(),
1360             capabilityRequirementRelationship, toInstance, componentCache);
1361     }
1362
1363     private boolean isCapabilityBelongToRelation(RelationshipInfo reqAndRelationshipPair,
1364                                                  CapabilityDefinition capability) {
1365         return capability.getName().equals(reqAndRelationshipPair.getCapability()) && (capability.getOwnerId() != null
1366             && capability.getOwnerId().equals(reqAndRelationshipPair.getCapabilityOwnerId()));
1367     }
1368
1369     private Optional<CapabilityDefinition> findCapability(RelationshipInfo reqAndRelationshipPair,
1370                                                           Component toOriginComponent, Component fromOriginComponent,
1371                                                           RequirementDefinition requirement) {
1372         Optional<CapabilityDefinition> cap = toOriginComponent.getCapabilities().get(requirement.getCapability())
1373             .stream().filter(c -> c.getType().equals(requirement.getCapability())).findFirst();
1374         if (!cap.isPresent()) {
1375             log.debug("Failed to find a capability with name {} on a component with uniqueId {}",
1376                 reqAndRelationshipPair.getCapability(), fromOriginComponent.getUniqueId());
1377         }
1378         return cap;
1379     }
1380
1381     private Map<String, ToscaTemplateRequirement> buildRequirement(final Component fromOriginComponent,
1382                                                                    final Component toOriginComponent,
1383                                                                    final CapabilityDefinition capability,
1384                                                                    final RequirementDefinition requirement,
1385                                                                    final CapabilityRequirementRelationship capabilityRequirementRelationship,
1386                                                                    final ComponentInstance toInstance,
1387                                                                    final Map<String, Component> componentCache)
1388         throws ToscaExportException {
1389
1390         List<String> reducedPath = capability.getPath();
1391         if (capability.getOwnerId() != null) {
1392             reducedPath = capabilityRequirementConverter
1393                 .getReducedPathByOwner(capability.getPath(), capability.getOwnerId());
1394         }
1395         final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation();
1396         final Either<String, Boolean> capabilityNameEither = capabilityRequirementConverter.buildSubstitutedName(componentCache,
1397             toOriginComponent, reducedPath, relationshipInfo.getCapability(), capability.getPreviousName());
1398         if (capabilityNameEither.isRight()) {
1399             final String errorMsg = String.format(
1400                 "Failed to build a substituted capability name for the capability with name %s on a component with uniqueId %s",
1401                 capabilityRequirementRelationship.getCapability(), toOriginComponent.getUniqueId());
1402             log.debug(
1403                 errorMsg);
1404             throw new ToscaExportException(errorMsg);
1405         }
1406         final Either<String, Boolean> requirementNameEither = capabilityRequirementConverter
1407             .buildSubstitutedName(componentCache, fromOriginComponent,
1408                 requirement.getPath(), relationshipInfo.getRequirement(), requirement.getPreviousName());
1409         if (requirementNameEither.isRight()) {
1410             final String errorMsg = String.format("Failed to build a substituted requirement name for the requirement "
1411                     + "with name %s on a component with uniqueId %s",
1412                 capabilityRequirementRelationship.getRequirement(), fromOriginComponent.getUniqueId());
1413             log.debug(errorMsg);
1414             throw new ToscaExportException(errorMsg);
1415         }
1416         final ToscaTemplateRequirement toscaRequirement = new ToscaTemplateRequirement();
1417         final Map<String, ToscaTemplateRequirement> toscaReqMap = new HashMap<>();
1418         toscaRequirement.setNode(toInstance.getName());
1419         toscaRequirement.setCapability(capabilityNameEither.left().value());
1420         if (isNotEmpty(capabilityRequirementRelationship.getOperations())) {
1421             toscaRequirement.setRelationship(new ToscaRelationshipBuilder().from(capabilityRequirementRelationship));
1422         }
1423         toscaReqMap.put(requirementNameEither.left().value(), toscaRequirement);
1424         return toscaReqMap;
1425     }
1426
1427     private Optional<RequirementDefinition> findRequirement(Component fromOriginComponent,
1428                                                             Map<String, List<RequirementDefinition>> reqMap,
1429                                                             RelationshipInfo reqAndRelationshipPair,
1430                                                             String fromInstanceId) {
1431         for (List<RequirementDefinition> reqList : reqMap.values()) {
1432             Optional<RequirementDefinition> reqOpt = reqList.stream().filter(
1433                 r -> isRequirementBelongToRelation(fromOriginComponent, reqAndRelationshipPair, r, fromInstanceId))
1434                 .findFirst();
1435             if (reqOpt.isPresent()) {
1436                 return reqOpt;
1437             }
1438         }
1439         return Optional.empty();
1440     }
1441
1442     /**
1443      * Allows detecting the requirement belonging to the received relationship The detection logic is: A requirement belongs to a relationship IF
1444      * 1.The name of the requirement equals to the "requirement" field of the relation; AND 2. In case of a non-atomic resource, OwnerId of the
1445      * requirement equals to requirementOwnerId of the relation OR uniqueId of toInstance equals to capabilityOwnerId of the relation
1446      */
1447     private boolean isRequirementBelongToRelation(Component originComponent, RelationshipInfo reqAndRelationshipPair,
1448                                                   RequirementDefinition requirement, String fromInstanceId) {
1449         if (!StringUtils.equals(requirement.getName(), reqAndRelationshipPair.getRequirement())) {
1450             log.debug("Failed to find a requirement with name {} and  reqAndRelationshipPair {}",
1451                 requirement.getName(), reqAndRelationshipPair.getRequirement());
1452             return false;
1453         }
1454         return ModelConverter.isAtomicComponent(originComponent) ||
1455             isRequirementBelongToOwner(reqAndRelationshipPair, requirement, fromInstanceId, originComponent);
1456     }
1457
1458     private boolean isRequirementBelongToOwner(RelationshipInfo reqAndRelationshipPair,
1459                                                RequirementDefinition requirement, String fromInstanceId,
1460                                                Component originComponent) {
1461         return StringUtils.equals(requirement.getOwnerId(), reqAndRelationshipPair.getRequirementOwnerId())
1462             || (isCvfc(originComponent) && StringUtils
1463             .equals(fromInstanceId, reqAndRelationshipPair.getRequirementOwnerId())
1464             || StringUtils.equals(requirement.getOwnerId(), originComponent.getUniqueId()));
1465     }
1466
1467     private boolean isCvfc(Component component) {
1468         return component.getComponentType() == ComponentTypeEnum.RESOURCE &&
1469             ((Resource) component).getResourceType() == ResourceTypeEnum.CVFC;
1470     }
1471
1472     private Either<SubstitutionMapping, ToscaError> convertCapabilities(Component component,
1473                                                                         SubstitutionMapping substitutionMappings,
1474                                                                         Map<String, Component> componentCache) {
1475
1476         Either<SubstitutionMapping, ToscaError> result = Either.left(substitutionMappings);
1477         Either<Map<String, String[]>, ToscaError> toscaCapabilitiesRes = capabilityRequirementConverter
1478             .convertSubstitutionMappingCapabilities(componentCache, component);
1479         if (toscaCapabilitiesRes.isRight()) {
1480             result = Either.right(toscaCapabilitiesRes.right().value());
1481             log.debug("Failed convert capabilities for the component {}. ", component.getName());
1482         } else if (isNotEmpty(toscaCapabilitiesRes.left().value())) {
1483             substitutionMappings.setCapabilities(toscaCapabilitiesRes.left().value());
1484             log.debug("Finish convert capabilities for the component {}. ", component.getName());
1485         }
1486         log.debug("Finished to convert capabilities for the component {}. ", component.getName());
1487         return result;
1488     }
1489
1490     private Either<ToscaNodeType, ToscaError> convertCapabilities(Map<String, Component> componentsCache,
1491                                                                   Component component, ToscaNodeType nodeType,
1492                                                                   Map<String, DataTypeDefinition> dataTypes) {
1493         Map<String, ToscaCapability> toscaCapabilities = capabilityRequirementConverter
1494             .convertCapabilities(componentsCache, component,
1495                 dataTypes);
1496         if (!toscaCapabilities.isEmpty()) {
1497             nodeType.setCapabilities(toscaCapabilities);
1498         }
1499         log.debug("Finish convert Capabilities for node type");
1500
1501         return Either.left(nodeType);
1502     }
1503
1504     private Map<String, ToscaTemplateArtifact> convertToNodeTemplateArtifacts(
1505         Map<String, ToscaArtifactDataDefinition> artifacts) {
1506         if (artifacts == null) {
1507             return null;
1508         }
1509         Map<String, ToscaTemplateArtifact> arts = new HashMap<>();
1510         for (Map.Entry<String, ToscaArtifactDataDefinition> entry : artifacts.entrySet()) {
1511             ToscaTemplateArtifact artifact = new ToscaTemplateArtifact();
1512             artifact.setFile(entry.getValue().getFile());
1513             artifact.setType(entry.getValue().getType());
1514             arts.put(entry.getKey(), artifact);
1515         }
1516         return arts;
1517     }
1518
1519     protected NodeFilter convertToNodeTemplateNodeFilterComponent(CINodeFilterDataDefinition inNodeFilter) {
1520         if (inNodeFilter == null) {
1521             return null;
1522         }
1523         NodeFilter nodeFilter = new NodeFilter();
1524
1525         ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities =
1526             inNodeFilter.getCapabilities();
1527
1528         ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> origProperties = inNodeFilter.getProperties();
1529
1530         List<Map<String, CapabilityFilter>> capabilitiesCopy = new ArrayList<>();
1531         List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1532
1533         copyNodeFilterCapabilitiesTemplate(origCapabilities, capabilitiesCopy);
1534         copyNodeFilterProperties(origProperties, propertiesCopy);
1535
1536         if (CollectionUtils.isNotEmpty(capabilitiesCopy)) {
1537             nodeFilter.setCapabilities(capabilitiesCopy);
1538         }
1539
1540         if (CollectionUtils.isNotEmpty(propertiesCopy)) {
1541             nodeFilter.setProperties(propertiesCopy);
1542         }
1543
1544         nodeFilter.setTosca_id(cloneToscaId(inNodeFilter.getTosca_id()));
1545
1546         nodeFilter = (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
1547
1548         return nodeFilter;
1549     }
1550
1551     private NodeFilter convertToSubstitutionFilterComponent(
1552         final SubstitutionFilterDataDefinition substitutionFilterDataDefinition) {
1553
1554         if (substitutionFilterDataDefinition == null) {
1555             return null;
1556         }
1557         NodeFilter nodeFilter = new NodeFilter();
1558
1559         ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> origProperties =
1560             substitutionFilterDataDefinition.getProperties();
1561         List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1562
1563         copySubstitutionFilterProperties(origProperties, propertiesCopy);
1564
1565         if (CollectionUtils.isNotEmpty(propertiesCopy)) {
1566             nodeFilter.setProperties(propertiesCopy);
1567         }
1568         nodeFilter.setTosca_id(cloneToscaId(substitutionFilterDataDefinition.getTosca_id()));
1569
1570         return (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
1571     }
1572
1573     private Object cloneToscaId(Object toscaId) {
1574         return Objects.isNull(toscaId) ? null
1575             : cloneObjectFromYml(toscaId, toscaId.getClass());
1576     }
1577
1578     private Object cloneObjectFromYml(Object objToClone, Class classOfObj) {
1579         String objectAsYml = yamlUtil.objectToYaml(objToClone);
1580         return yamlUtil.yamlToObject(objectAsYml, classOfObj);
1581     }
1582
1583     private void copyNodeFilterCapabilitiesTemplate(
1584         ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities,
1585         List<Map<String, CapabilityFilter>> capabilitiesCopy) {
1586         if (origCapabilities == null || origCapabilities.getListToscaDataDefinition() == null ||
1587             origCapabilities.getListToscaDataDefinition().isEmpty()) {
1588             return;
1589         }
1590         for (RequirementNodeFilterCapabilityDataDefinition capability : origCapabilities.getListToscaDataDefinition()) {
1591             Map<String, CapabilityFilter> capabilityFilterCopyMap = new HashMap<>();
1592             CapabilityFilter capabilityFilter = new CapabilityFilter();
1593             List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1594             copyNodeFilterProperties(capability.getProperties(), propertiesCopy);
1595             capabilityFilter.setProperties(propertiesCopy);
1596             capabilityFilterCopyMap.put(capability.getName(), capabilityFilter);
1597             capabilitiesCopy.add(capabilityFilterCopyMap);
1598         }
1599     }
1600
1601     private void copyNodeFilterProperties(
1602         ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> origProperties,
1603         List<Map<String, List<Object>>> propertiesCopy) {
1604         if (origProperties == null || origProperties.getListToscaDataDefinition() == null ||
1605             origProperties.isEmpty()) {
1606             return;
1607         }
1608         Map<String, List<Object>> propertyMapCopy = new HashMap<>();
1609         for (RequirementNodeFilterPropertyDataDefinition propertyDataDefinition : origProperties
1610             .getListToscaDataDefinition()) {
1611             for (String propertyInfoEntry : propertyDataDefinition.getConstraints()) {
1612                 Map propertyValObj = new YamlUtil().yamlToObject(propertyInfoEntry, Map.class);
1613                 String propertyName = propertyDataDefinition.getName();
1614                 if (propertyMapCopy.containsKey(propertyName)) {
1615                     addPropertyConstraintValueToList(propertyName, propertyValObj, propertyMapCopy.get(propertyName));
1616                 } else {
1617                     if (propertyName != null) {
1618                         List<Object> propsList = new ArrayList<>();
1619                         addPropertyConstraintValueToList(propertyName, propertyValObj, propsList);
1620                         propertyMapCopy.put(propertyName, propsList);
1621                     } else {
1622                         propertyMapCopy.putAll(propertyValObj);
1623                     }
1624                 }
1625             }
1626         }
1627         propertyMapCopy.entrySet().stream().forEach(entry ->
1628             addCalculatedConstraintsIntoPropertiesList(propertiesCopy, entry));
1629     }
1630
1631     private void copySubstitutionFilterProperties(
1632         final ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> origProperties,
1633         final List<Map<String, List<Object>>> propertiesCopy) {
1634         if (origProperties == null || origProperties.getListToscaDataDefinition() == null ||
1635             origProperties.isEmpty()) {
1636             return;
1637         }
1638         final Map<String, List<Object>> propertyMapCopy = new HashMap<>();
1639         for (final RequirementSubstitutionFilterPropertyDataDefinition propertyDataDefinition : origProperties
1640             .getListToscaDataDefinition()) {
1641             for (final String propertyInfoEntry : propertyDataDefinition.getConstraints()) {
1642                 final Map<String, List<Object>> propertyValObj = new YamlUtil()
1643                     .yamlToObject(propertyInfoEntry, Map.class);
1644                 final String propertyName = propertyDataDefinition.getName();
1645                 if (propertyMapCopy.containsKey(propertyName)) {
1646                     addPropertyConstraintValueToList(propertyName, propertyValObj, propertyMapCopy.get(propertyName));
1647                 } else {
1648                     if (propertyName != null) {
1649                         final List<Object> propsList = new ArrayList<>();
1650                         addPropertyConstraintValueToList(propertyName, propertyValObj, propsList);
1651                         propertyMapCopy.put(propertyName, propsList);
1652                     } else {
1653                         propertyMapCopy.putAll(propertyValObj);
1654                     }
1655                 }
1656             }
1657         }
1658         propertyMapCopy.entrySet().forEach(entry ->
1659             addCalculatedConstraintsIntoPropertiesList(propertiesCopy, entry));
1660     }
1661
1662     private void addPropertyConstraintValueToList(String propertyName, Map<String, List<Object>> propertyValObj, List<Object> propsList) {
1663         if (propertyValObj.containsKey(propertyName)) {
1664             propsList.add(propertyValObj.get(propertyName));
1665         } else {
1666             propsList.add(propertyValObj);
1667         }
1668     }
1669
1670     private void addCalculatedConstraintsIntoPropertiesList(List<Map<String, List<Object>>> propertiesCopy,
1671                                                             Entry<String, List<Object>> entry) {
1672         Map<String, List<Object>> tempMap = new HashMap<>();
1673         tempMap.put(entry.getKey(), entry.getValue());
1674         propertiesCopy.add(tempMap);
1675     }
1676
1677     private static class CustomRepresenter extends Representer {
1678
1679         CustomRepresenter() {
1680             super();
1681             this.representers.put(ToscaPropertyAssignment.class, new RepresentToscaPropertyAssignment());
1682             // null representer is exceptional and it is stored as an instance
1683             // variable.
1684             this.nullRepresenter = new RepresentNull();
1685
1686         }
1687
1688         private class RepresentToscaPropertyAssignment implements Represent {
1689
1690             public Node representData(Object data) {
1691                 final ToscaPropertyAssignment toscaOperationAssignment = (ToscaPropertyAssignment) data;
1692                 if (toscaOperationAssignment.getValue() instanceof String) {
1693                     final String stringValue = (String) toscaOperationAssignment.getValue();
1694                     if (isPropertyOrAttributeFunction(stringValue)) {
1695                         return representGetAttribute(stringValue);
1696                     }
1697
1698                     return representScalar(Tag.STR, stringValue);
1699                 }
1700                 return represent(null);
1701             }
1702
1703             public Node representGetAttribute(final String getAttributeFunction) {
1704                 return represent(new Yaml().load(getAttributeFunction));
1705             }
1706
1707             public boolean isPropertyOrAttributeFunction(final String value) {
1708                 try {
1709                     final Yaml yaml = new Yaml();
1710                     final Object yamlObj = yaml.load(value);
1711                     if (!(yamlObj instanceof Map)) {
1712                         return false;
1713                     }
1714                     final Map<String, Object> getAttributeMap = (Map) yamlObj;
1715                     if (getAttributeMap.size() != 1) {
1716                         return false;
1717                     }
1718                     final List<String> functionList = Arrays
1719                         .asList(GET_ATTRIBUTE.getFunctionName(), GET_INPUT.getFunctionName(),
1720                             GET_PROPERTY.getFunctionName());
1721                     final Optional<String> function = getAttributeMap.keySet().stream()
1722                         .filter(key -> functionList.stream().anyMatch(function1 -> function1.equals(key))).findFirst();
1723
1724                     if (function.isEmpty()) {
1725                         return false;
1726                     }
1727                     final String functionName = function.get();
1728                     final Object getAttributeValueObj = getAttributeMap.get(functionName);
1729                     if (GET_INPUT.getFunctionName().equals(functionName)) {
1730                         return validateGetInputValue(getAttributeValueObj);
1731                     } else {
1732                         return validateGetPropertyOrAttributeValue(getAttributeValueObj);
1733                     }
1734                 } catch (final Exception ignored) {
1735                     return false;
1736                 }
1737             }
1738         }
1739
1740         public boolean validateGetInputValue(final Object valueObj) {
1741             if (!(valueObj instanceof List) && !(valueObj instanceof String)) {
1742                 return false;
1743             }
1744             if (valueObj instanceof List) {
1745                 return ((List) valueObj).size() > 1;
1746             }
1747
1748             return true;
1749         }
1750
1751         public boolean validateGetPropertyOrAttributeValue(final Object valueObj) {
1752             if (valueObj instanceof List) {
1753                 return ((List) valueObj).size() > 1;
1754             }
1755
1756             return false;
1757         }
1758
1759         @Override
1760         protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue,
1761                                                       Tag customTag) {
1762             if (propertyValue == null) {
1763                 return null;
1764             }
1765             // skip not relevant for Tosca property
1766             if ("dependencies".equals(property.getName())) {
1767                 return null;
1768             }
1769             if (javaBean instanceof ToscaRelationshipTemplate && "name".equals(property.getName())) {
1770                 return null;
1771             }
1772
1773             removeDefaultP(propertyValue);
1774             NodeTuple defaultNode = super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
1775
1776             if (javaBean instanceof ToscaTopolgyTemplate && "relationshipTemplates".equals(property.getName())) {
1777                 return new NodeTuple(representData("relationship_templates"), defaultNode.getValueNode());
1778             }
1779
1780             return "_defaultp_".equals(property.getName())
1781                 ? new NodeTuple(representData("default"), defaultNode.getValueNode()) : defaultNode;
1782         }
1783
1784         private void removeDefaultP(final Object propertyValue) {
1785             if (propertyValue instanceof Map) {
1786                 final Map mapPropertyValue = ((Map) propertyValue);
1787
1788                 final Iterator<Entry> iter = mapPropertyValue.entrySet().iterator();
1789                 Object defaultValue = null;
1790                 while (iter.hasNext()) {
1791                     final Map.Entry entry = iter.next();
1792
1793                     if ("_defaultp_".equals(entry.getKey())) {
1794                         defaultValue = entry.getValue();
1795                         iter.remove();
1796                     } else if (entry.getValue() instanceof Map) {
1797                         removeDefaultP(entry.getValue());
1798                     }
1799                 }
1800                 if (defaultValue != null) {
1801                     mapPropertyValue.putIfAbsent("default", defaultValue);
1802                 }
1803             }
1804         }
1805
1806         @Override
1807         protected MappingNode representJavaBean(Set<Property> properties, Object javaBean) {
1808             // remove the bean type from the output yaml (!! ...)
1809             if (!classTags.containsKey(javaBean.getClass())) {
1810                 addClassTag(javaBean.getClass(), Tag.MAP);
1811             }
1812
1813             return super.representJavaBean(properties, javaBean);
1814         }
1815
1816         private class RepresentNull implements Represent {
1817
1818             @Override
1819             public Node representData(Object data) {
1820                 // possible values are here http://yaml.org/type/null.html
1821                 return representScalar(Tag.NULL, "");
1822             }
1823         }
1824     }
1825
1826     private static class UnsortedPropertyUtils extends PropertyUtils {
1827
1828         @Override
1829         protected Set<Property> createPropertySet(Class type, BeanAccess bAccess) {
1830             Collection<Property> fields = getPropertiesMap(type, BeanAccess.FIELD).values();
1831             return new LinkedHashSet<>(fields);
1832         }
1833     }
1834
1835     private Map<String, String[]> buildSubstitutionMappingPropertyMapping(final Component component) {
1836         if (component == null || CollectionUtils.isEmpty(component.getInputs())) {
1837             return Collections.emptyMap();
1838         }
1839         return component.getInputs().stream()
1840             .map(PropertyDataDefinition::getName)
1841             .collect(
1842                 Collectors.toMap(
1843                     inputName -> inputName,
1844                     inputName -> new String[]{inputName},
1845                     (inputName1, inputName2) -> inputName1)
1846             );
1847     }
1848
1849     private Map<String, String[]> buildSubstitutionMappingAttributesMapping(final Component component) {
1850         if (component == null || CollectionUtils.isEmpty(component.getOutputs())) {
1851             return Collections.emptyMap();
1852         }
1853         return component.getOutputs().stream()
1854             .map(AttributeDataDefinition::getName)
1855             .collect(
1856                 Collectors.toMap(
1857                     outputName -> outputName,
1858                     outputName -> new String[]{outputName},
1859                     (outputName1, outputName2) -> outputName1)
1860             );
1861     }
1862
1863     Optional<Map<String, ToscaProperty>> getProxyNodeTypeProperties(Component proxyComponent,
1864                                                                     Map<String, DataTypeDefinition>
1865                                                                         dataTypes) {
1866         if (Objects.isNull(proxyComponent)) {
1867             return Optional.empty();
1868         }
1869         Map<String, ToscaProperty> proxyProperties = new HashMap<>();
1870         addInputsToProperties(dataTypes, proxyComponent.getInputs(), proxyProperties);
1871         if (CollectionUtils.isNotEmpty(proxyComponent.getProperties())) {
1872             proxyProperties.putAll(proxyComponent.getProperties().stream()
1873                 .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition,
1874                     proxyComponent.getInputs()))
1875                 .collect(Collectors.toMap(PropertyDataDefinition::getName,
1876                     property -> propertyConvertor.convertProperty(dataTypes, property,
1877                         PropertyConvertor.PropertyType.PROPERTY))));
1878         }
1879         return MapUtils.isNotEmpty(proxyProperties) ? Optional.of(proxyProperties) : Optional.empty();
1880     }
1881
1882     void addInputsToProperties(Map<String, DataTypeDefinition> dataTypes,
1883                                List<InputDefinition> componentInputs,
1884                                Map<String, ToscaProperty> mergedProperties) {
1885         if (CollectionUtils.isEmpty(componentInputs)) {
1886             return;
1887         }
1888         for (InputDefinition input : componentInputs) {
1889             ToscaProperty property = propertyConvertor.convertProperty(dataTypes, input,
1890                 PropertyConvertor.PropertyType.INPUT);
1891             mergedProperties.put(input.getName(), property);
1892         }
1893     }
1894
1895     Optional<Map<String, Object>> getProxyNodeTypeInterfaces(Component proxyComponent,
1896                                                              Map<String, DataTypeDefinition> dataTypes) {
1897         if (Objects.isNull(proxyComponent) || MapUtils.isEmpty(proxyComponent.getInterfaces())) {
1898             return Optional.empty();
1899         }
1900         Map<String, InterfaceDefinition> proxyComponentInterfaces = proxyComponent.getInterfaces();
1901         //Unset artifact path for operation implementation for proxy node types as for operations with artifacts it is
1902         // always available in the proxy node template
1903         removeOperationImplementationForProxyNodeType(proxyComponentInterfaces);
1904         return Optional.ofNullable(interfacesOperationsConverter
1905             .getInterfacesMap(proxyComponent, null, proxyComponentInterfaces, dataTypes,
1906                 false, false));
1907     }
1908
1909     private static void removeOperationImplementationForProxyNodeType(
1910         Map<String, InterfaceDefinition> proxyComponentInterfaces) {
1911         if (MapUtils.isEmpty(proxyComponentInterfaces)) {
1912             return;
1913         }
1914         proxyComponentInterfaces.values().stream().map(InterfaceDataDefinition::getOperations)
1915             .filter(MapUtils::isNotEmpty)
1916             .forEach(operations -> operations.values().forEach(operation -> operation.setImplementation(null)));
1917     }
1918 }