eb601d836d9f741b7c73c46cba11dc905f0c297b
[sdc.git] / catalog-be-plugins / etsi-nfv-nsd-csar-plugin / src / main / java / org / openecomp / sdc / be / plugins / etsi / nfv / nsd / generator / NsDescriptorGeneratorImpl.java
1  
2 /*
3  * ============LICENSE_START=======================================================
4  *  Copyright (C) 2020 Nordix Foundation
5  *  ================================================================================
6  *  Licensed under the Apache License, Version 2.0 (the "License");
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at
9  *
10  *        http://www.apache.org/licenses/LICENSE-2.0
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  *  SPDX-License-Identifier: Apache-2.0
18  *  ============LICENSE_END=========================================================
19  */
20 package org.openecomp.sdc.be.plugins.etsi.nfv.nsd.generator;
21
22 import com.google.common.collect.ImmutableMap;
23 import fj.data.Either;
24 import groovy.util.MapEntry;
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.Collection;
28 import java.util.Collections;
29 import java.util.HashMap;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Map.Entry;
33 import java.util.Optional;
34 import java.util.stream.Collectors;
35 import org.apache.commons.collections4.CollectionUtils;
36 import org.apache.commons.collections4.MapUtils;
37 import org.openecomp.sdc.be.config.ConfigurationManager;
38 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
39 import org.openecomp.sdc.be.model.Component;
40 import org.openecomp.sdc.be.datatypes.enums.ConstraintType;
41 import org.openecomp.sdc.be.plugins.etsi.nfv.nsd.exception.NsdException;
42 import org.openecomp.sdc.be.plugins.etsi.nfv.nsd.model.Nsd;
43 import org.openecomp.sdc.be.plugins.etsi.nfv.nsd.model.VnfDescriptor;
44 import org.openecomp.sdc.be.plugins.etsi.nfv.nsd.tosca.yaml.ToscaTemplateYamlGenerator;
45 import org.openecomp.sdc.be.tosca.ToscaError;
46 import org.openecomp.sdc.be.tosca.ToscaExportHandler;
47 import org.openecomp.sdc.be.tosca.model.SubstitutionMapping;
48 import org.openecomp.sdc.be.tosca.model.ToscaNodeTemplate;
49 import org.openecomp.sdc.be.tosca.model.ToscaNodeType;
50 import org.openecomp.sdc.be.tosca.model.ToscaProperty;
51 import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraint;
52 import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraintValidValues;
53 import org.openecomp.sdc.be.tosca.model.ToscaRequirement;
54 import org.openecomp.sdc.be.tosca.model.ToscaTemplate;
55 import org.openecomp.sdc.be.tosca.model.ToscaTemplateRequirement;
56 import org.openecomp.sdc.be.tosca.model.ToscaTopolgyTemplate;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
59 import org.springframework.beans.factory.ObjectProvider;
60 import org.springframework.beans.factory.config.BeanDefinition;
61 import org.springframework.context.annotation.Scope;
62
63 @org.springframework.stereotype.Component("nsDescriptorGenerator")
64 @Scope(BeanDefinition.SCOPE_PROTOTYPE)
65 public class NsDescriptorGeneratorImpl implements NsDescriptorGenerator {
66
67     private static final Logger LOGGER = LoggerFactory.getLogger(NsDescriptorGeneratorImpl.class);
68     private static final String TOSCA_VERSION = "tosca_simple_yaml_1_1";
69     private static final String NS_TOSCA_TYPE = "tosca.nodes.nfv.NS";
70     private static final List<Map<String, Map<String, String>>> DEFAULT_IMPORTS = ConfigurationManager.getConfigurationManager().getConfiguration()
71         .getDefaultImports();
72     private static final List<String> PROPERTIES_TO_EXCLUDE_FROM_ETSI_SOL_NSD_NS_NODE_TYPE = Arrays
73         .asList("cds_model_name", "cds_model_version", "skip_post_instantiation_configuration", "controller_actor");
74     private static final List<String> ETSI_SOL_NSD_NS_NODE_TYPE_PROPERTIES = Arrays
75             .asList("descriptor_id", "designer", "version", "name", "invariant_id", "flavour_id", "ns_profile", "service_availability_level");
76     private static final List<String> PROPERTIES_TO_EXCLUDE_FROM_ETSI_SOL_NSD_NS_NODE_TEMPLATE = Arrays
77         .asList("nf_function", "nf_role", "nf_naming_code", "nf_type", "nf_naming", "availability_zone_max_count", "min_instances", "max_instances",
78             "multi_stage_design", "sdnc_model_name", "sdnc_model_version", "sdnc_artifact_name", "skip_post_instantiation_configuration",
79             "controller_actor");
80     private final ToscaExportHandler toscaExportHandler;
81     private final ObjectProvider<ToscaTemplateYamlGenerator> toscaTemplateYamlGeneratorProvider;
82
83     public NsDescriptorGeneratorImpl(final ToscaExportHandler toscaExportHandler,
84                                      final ObjectProvider<ToscaTemplateYamlGenerator> toscaTemplateYamlGeneratorProvider) {
85         this.toscaExportHandler = toscaExportHandler;
86         this.toscaTemplateYamlGeneratorProvider = toscaTemplateYamlGeneratorProvider;
87     }
88
89     public Optional<Nsd> generate(final Component component, final List<VnfDescriptor> vnfDescriptorList) throws NsdException {
90         if (!ComponentTypeEnum.SERVICE.equals(component.getComponentType())) {
91             return Optional.empty();
92         }
93         final ToscaTemplate toscaTemplate = createNetworkServiceDescriptor(component, vnfDescriptorList);
94         final ToscaNodeType nsNodeType = toscaTemplate.getNode_types().values().stream()
95             .filter(toscaNodeType -> NS_TOSCA_TYPE.equals(toscaNodeType.getDerived_from())).findFirst().orElse(null);
96         if (nsNodeType == null) {
97             return Optional.empty();
98         }
99         return Optional.of(buildNsd(toscaTemplate, nsNodeType));
100     }
101
102     private Nsd buildNsd(final ToscaTemplate toscaTemplate, final ToscaNodeType nsNodeType) {
103         final Nsd nsd = new Nsd();
104         nsd.setDesigner(getProperty(nsNodeType, Nsd.DESIGNER_PROPERTY));
105         nsd.setVersion(getProperty(nsNodeType, Nsd.VERSION_PROPERTY));
106         nsd.setName(getProperty(nsNodeType, Nsd.NAME_PROPERTY));
107         nsd.setInvariantId(getProperty(nsNodeType, Nsd.INVARIANT_ID_PROPERTY));
108         final ToscaTemplateYamlGenerator yamlParserProvider = toscaTemplateYamlGeneratorProvider.getObject(toscaTemplate);
109         final byte[] contents = yamlParserProvider.parseToYamlString().getBytes();
110         nsd.setContents(contents);
111         final List<String> interfaceImplementations = getInterfaceImplementations(toscaTemplate);
112         nsd.setArtifactReferences(interfaceImplementations);
113         return nsd;
114     }
115
116     private List<String> getInterfaceImplementations(final ToscaTemplate template) {
117         if (template.getTopology_template().getNode_templates() == null) {
118             return Collections.emptyList();
119         }
120         final List<String> interfaceImplementations = new ArrayList<>();
121         final Collection<ToscaNodeTemplate> nodeTemplates = template.getTopology_template().getNode_templates().values();
122         nodeTemplates.stream().filter(toscaNodeTemplate -> toscaNodeTemplate.getInterfaces() != null).forEach(
123             toscaNodeTemplate -> toscaNodeTemplate.getInterfaces().values()
124                 .forEach(interfaceInstance -> interfaceImplementations.addAll(getInterfaceImplementations(interfaceInstance))));
125         return interfaceImplementations;
126     }
127
128     private Collection<String> getInterfaceImplementations(final Object interfaceInstance) {
129         final Collection<String> interfaceImplementations = new ArrayList<>();
130         if (interfaceInstance instanceof Map) {
131             for (final Object value : ((Map<?, ?>) interfaceInstance).values()) {
132                 if (value instanceof Map && ((Map<?, ?>) value).get("implementation") != null) {
133                     interfaceImplementations.add(((Map<?, ?>) value).get("implementation").toString());
134                 }
135             }
136         }
137         return interfaceImplementations;
138     }
139
140     private String getProperty(final ToscaNodeType nodeType, final String propertyName) {
141         final ToscaProperty toscaProperty = nodeType.getProperties().get(propertyName);
142         final String errorMsg = String.format("Property '%s' must be defined and must have a valid values constraint", propertyName);
143         final String returnValueOnError = "unknown";
144         if (toscaProperty == null || CollectionUtils.isEmpty(toscaProperty.getConstraints())) {
145             LOGGER.error(errorMsg);
146             return returnValueOnError;
147         }
148         final ToscaPropertyConstraint toscaPropertyConstraint = toscaProperty.getConstraints().get(0);
149         if (ConstraintType.VALID_VALUES != toscaPropertyConstraint.getConstraintType()) {
150             LOGGER.error(errorMsg);
151             return returnValueOnError;
152         }
153         final ToscaPropertyConstraintValidValues validValuesConstraint = (ToscaPropertyConstraintValidValues) toscaPropertyConstraint;
154         final List<Object> validValues = validValuesConstraint.getValidValues();
155         if (CollectionUtils.isEmpty(validValues)) {
156             LOGGER.error(errorMsg);
157             return returnValueOnError;
158         }
159         return String.valueOf(validValues.get(0));
160     }
161
162     private ToscaTemplate createNetworkServiceDescriptor(final Component component, final List<VnfDescriptor> vnfDescriptorList) throws NsdException {
163         final ToscaTemplate componentToscaTemplate = parseToToscaTemplate(component);
164         final ToscaTemplate componentToscaTemplateInterface = exportComponentInterfaceAsToscaTemplate(component);
165         final Entry<String, ToscaNodeType> firstNodeTypeEntry = componentToscaTemplateInterface.getNode_types().entrySet().stream().findFirst()
166             .orElse(null);
167         if (firstNodeTypeEntry == null) {
168             throw new NsdException("Could not find abstract Service type");
169         }
170         final String nsNodeTypeName = firstNodeTypeEntry.getKey();
171         final ToscaNodeType nsNodeType = firstNodeTypeEntry.getValue();
172         final Map<String, ToscaNodeType> nodeTypeMap = new HashMap<>();
173         nodeTypeMap.put(nsNodeTypeName, createEtsiSolNsNodeType(nsNodeType, componentToscaTemplate));
174         if (componentToscaTemplate.getNode_types() == null) {
175             componentToscaTemplate.setNode_types(nodeTypeMap);
176         } else {
177             componentToscaTemplate.getNode_types().putAll(nodeTypeMap);
178         }
179         handleNodeTemplates(componentToscaTemplate);
180         removeOnapAndEtsiNsdPropertiesFromInputs(componentToscaTemplate);
181         handleSubstitutionMappings(componentToscaTemplate, nsNodeTypeName);
182         final Map<String, ToscaNodeTemplate> nodeTemplates = new HashMap<>();
183         nodeTemplates.put(nsNodeTypeName,
184             createNodeTemplateForNsNodeType(nsNodeTypeName, componentToscaTemplateInterface.getNode_types().get(nsNodeTypeName)));
185         if (componentToscaTemplate.getTopology_template().getNode_templates() == null) {
186             componentToscaTemplate.getTopology_template().setNode_templates(nodeTemplates);
187         } else {
188             setNodeTemplateTypesForVnfs(componentToscaTemplate, vnfDescriptorList);
189             componentToscaTemplate.getTopology_template().getNode_templates().putAll(nodeTemplates);
190         }
191         removeOnapMetaData(componentToscaTemplate);
192         setDefaultImportsForEtsiSolNsNsd(componentToscaTemplate, vnfDescriptorList);
193         return componentToscaTemplate;
194     }
195
196     private void handleSubstitutionMappings(final ToscaTemplate componentToscaTemplate, final String nsNodeTypeName) {
197         final SubstitutionMapping substitutionMapping = new SubstitutionMapping();
198         substitutionMapping.setNode_type(nsNodeTypeName);
199         final SubstitutionMapping onapSubstitutionMapping = componentToscaTemplate.getTopology_template().getSubstitution_mappings();
200         if (onapSubstitutionMapping != null && onapSubstitutionMapping.getRequirements() != null) {
201             substitutionMapping.setRequirements(adjustRequirementNamesToMatchVnfd(onapSubstitutionMapping.getRequirements()));
202         }
203         componentToscaTemplate.getTopology_template().setSubstitution_mappings(substitutionMapping);
204     }
205     
206     private Map<String, String[]> adjustRequirementNamesToMatchVnfd(final Map<String, String[]> requirements) {
207         for (final Map.Entry<String, String[]> entry : requirements.entrySet()) {
208             try {
209                 final String[] adjustedValue = {entry.getValue()[0], entry.getValue()[1].substring(entry.getValue()[1].lastIndexOf('.') + 1)};
210                 entry.setValue(adjustedValue);
211             } catch (final ArrayIndexOutOfBoundsException exception) {
212                 LOGGER.error("Malformed requirement: {}", entry);
213             }
214         }
215         return requirements;
216     }
217
218     private void setNodeTemplateTypesForVnfs(final ToscaTemplate template, final List<VnfDescriptor> vnfDescriptorList) {
219         if (CollectionUtils.isEmpty(vnfDescriptorList)) {
220             return;
221         }
222         final Map<String, ToscaNodeTemplate> nodeTemplateMap = template.getTopology_template().getNode_templates();
223         if (MapUtils.isEmpty(nodeTemplateMap)) {
224             return;
225         }
226         nodeTemplateMap.forEach(
227             (key, toscaNodeTemplate) -> vnfDescriptorList.stream().filter(vnfDescriptor -> key.equals(vnfDescriptor.getName())).findFirst()
228                 .ifPresent(vnfDescriptor -> toscaNodeTemplate.setType(vnfDescriptor.getNodeType())));
229     }
230
231     private void handleNodeTemplates(final ToscaTemplate template) {
232         final Map<String, ToscaNodeTemplate> nodeTemplateMap = template.getTopology_template().getNode_templates();
233         if (MapUtils.isEmpty(nodeTemplateMap)) {
234             return;
235         }
236         for (final Entry<String, ToscaNodeTemplate> nodeTemplate : nodeTemplateMap.entrySet()) {
237             setPropertiesForNodeTemplate(nodeTemplate);
238             setRequirementsForNodeTemplate(nodeTemplate);
239             removeCapabilitiesFromNodeTemplate(nodeTemplate);
240         }
241     }
242     
243     private void setPropertiesForNodeTemplate(final Entry<String, ToscaNodeTemplate> nodeTemplate) {
244         final Map<String, Object> propertyMap = nodeTemplate.getValue().getProperties();
245         if (MapUtils.isEmpty(propertyMap)) {
246             nodeTemplate.getValue().setProperties(null);
247             return;
248         }
249         final Map<String, Object> editedPropertyMap = new HashMap<>();
250         for (final Entry<String, Object> property : propertyMap.entrySet()) {
251             if (!PROPERTIES_TO_EXCLUDE_FROM_ETSI_SOL_NSD_NS_NODE_TEMPLATE.contains(property.getKey()) && propertyIsDefinedInNodeType(
252                 property.getKey())) {
253                 editedPropertyMap.put(property.getKey(), property.getValue());
254             }
255         }
256         if (editedPropertyMap.isEmpty()) {
257             nodeTemplate.getValue().setProperties(null);
258         } else {
259             nodeTemplate.getValue().setProperties(editedPropertyMap);
260         }
261     }
262
263     private void setRequirementsForNodeTemplate(final Entry<String, ToscaNodeTemplate> nodeTemplateMap) {
264         final List<Map<String,ToscaTemplateRequirement>> requirementAssignments = nodeTemplateMap.getValue().getRequirements();
265         if (requirementAssignments != null) {  
266             final List<Map<String,ToscaTemplateRequirement>> requirementAssignmentsMatchingVnfdRequirements = new ArrayList<>();
267             for (final Map<String, ToscaTemplateRequirement> requirementAssignment: requirementAssignments) {
268                 final Map<String, ToscaTemplateRequirement> requirementAssignmentMatchingVnfd = 
269                         requirementAssignment.entrySet().stream().collect(Collectors.toMap(entry -> entry.getKey().substring(entry.getKey().lastIndexOf('.') + 1), Map.Entry::getValue));
270                 requirementAssignmentsMatchingVnfdRequirements.add(requirementAssignmentMatchingVnfd);
271             }
272             nodeTemplateMap.getValue().setRequirements(requirementAssignmentsMatchingVnfdRequirements);
273         }
274     }
275
276
277     private void removeCapabilitiesFromNodeTemplate(final Entry<String, ToscaNodeTemplate> nodeTemplate) {
278         nodeTemplate.getValue().setCapabilities(null);
279     }
280
281     private void removeOnapAndEtsiNsdPropertiesFromInputs(final ToscaTemplate template) {
282         final ToscaTopolgyTemplate topologyTemplate = template.getTopology_template();
283         final Map<String, ToscaProperty> inputMap = topologyTemplate.getInputs();
284         
285         
286         if (MapUtils.isNotEmpty(inputMap)) {
287             inputMap.entrySet().removeIf(entry -> PROPERTIES_TO_EXCLUDE_FROM_ETSI_SOL_NSD_NS_NODE_TYPE.contains(entry.getKey()) || ETSI_SOL_NSD_NS_NODE_TYPE_PROPERTIES.contains(entry.getKey()));
288         }
289         if (MapUtils.isEmpty(inputMap)) {
290             topologyTemplate.setInputs(null);
291         }
292     }
293
294     private void removeOnapMetaData(final ToscaTemplate template) {
295         template.setMetadata(null);
296         final Map<String, ToscaNodeTemplate> nodeTemplateMap = template.getTopology_template().getNode_templates();
297         if (MapUtils.isEmpty(nodeTemplateMap)) {
298             return;
299         }
300         nodeTemplateMap.values().forEach(toscaNodeTemplate -> toscaNodeTemplate.setMetadata(null));
301     }
302
303     private void setDefaultImportsForEtsiSolNsNsd(final ToscaTemplate template, final List<VnfDescriptor> vnfDescriptorList) {
304         final List<Map<String, Map<String, String>>> importEntryMap = new ArrayList<>();
305         final Map<String, Map<String, String>> defaultImportEntryMap = generateDefaultImportEntry();
306         if (MapUtils.isNotEmpty(defaultImportEntryMap)) {
307             importEntryMap.add(defaultImportEntryMap);
308         }
309         if (CollectionUtils.isNotEmpty(vnfDescriptorList)) {
310             for (final VnfDescriptor vnfDescriptor : vnfDescriptorList) {
311                 final Map<String, String> vnfImportChildEntry = new HashMap<>();
312                 vnfImportChildEntry.put("file", vnfDescriptor.getVnfdFileName());
313                 final Map<String, Map<String, String>> vnfdImportVnfdEntry = new HashMap<>();
314                 vnfdImportVnfdEntry.put(vnfDescriptor.getName(), vnfImportChildEntry);
315                 importEntryMap.add(vnfdImportVnfdEntry);
316             }
317         }
318         template.setImports(importEntryMap);
319     }
320
321     private Map<String, Map<String, String>> generateDefaultImportEntry() {
322         return ImmutableMap.of("etsi_nfv_sol001_nsd_types", ImmutableMap.of("file", "etsi_nfv_sol001_nsd_types.yaml"));
323     }
324
325     private ToscaNodeType createEtsiSolNsNodeType(final ToscaNodeType nsNodeType, final ToscaTemplate componentToscaTemplate) {
326         final ToscaNodeType toscaNodeType = new ToscaNodeType();
327         toscaNodeType.setDerived_from(NS_TOSCA_TYPE);
328         final Map<String, ToscaProperty> propertiesInNsNodeType = nsNodeType.getProperties();
329         for (final Entry<String, ToscaProperty> property : propertiesInNsNodeType.entrySet()) {
330             final ToscaProperty toscaProperty = property.getValue();
331             if (toscaProperty.getDefaultp() != null && ETSI_SOL_NSD_NS_NODE_TYPE_PROPERTIES.contains(property.getKey())) {
332                 final ToscaPropertyConstraintValidValues constraint = new ToscaPropertyConstraintValidValues(
333                     Collections.singletonList(toscaProperty.getDefaultp().toString()));
334                 toscaProperty.setConstraints(Collections.singletonList(constraint));
335             }
336         }
337         propertiesInNsNodeType.entrySet().removeIf(entry -> PROPERTIES_TO_EXCLUDE_FROM_ETSI_SOL_NSD_NS_NODE_TYPE.contains(entry.getKey()));
338         toscaNodeType.setProperties(propertiesInNsNodeType);
339         
340         final List<Map<String, ToscaRequirement>> requirementsInNsNodeType = getRequirementsForNsNodeType(nsNodeType.getRequirements(), componentToscaTemplate);
341         if (!requirementsInNsNodeType.isEmpty()) {
342             toscaNodeType.setRequirements(requirementsInNsNodeType);  
343         }
344
345         return toscaNodeType;
346     }
347     
348     private List<Map<String,ToscaRequirement>> getRequirementsForNsNodeType(final List<Map<String,ToscaRequirement>> requirements, final ToscaTemplate componentToscaTemplate) {
349         final Map<String, String[]> requirementsInSubstitutionMapping = componentToscaTemplate.getTopology_template().getSubstitution_mappings().getRequirements();
350         if (requirements == null || MapUtils.isEmpty(requirementsInSubstitutionMapping)) {
351             return Collections.emptyList();
352         }
353         final List<Map<String,ToscaRequirement>> requirementsToAdd = new ArrayList<>();
354         for (final Map<String,ToscaRequirement> requirementMap : requirements) {
355             final Map<String,ToscaRequirement> neededRequirements = requirementMap.entrySet().stream().filter(entry -> requirementsInSubstitutionMapping.containsKey(entry.getKey())).collect(Collectors.toMap(Entry::getKey, Entry::getValue));
356             if (!neededRequirements.isEmpty()) {
357                 requirementsToAdd.add(neededRequirements);
358             }
359         }
360         return requirementsToAdd;
361        
362     }
363
364     private boolean propertyIsDefinedInNodeType(final String propertyName) {
365         // This will achieve what we want for now, but will look into a more generic solution which would involve
366
367         // checking the node_type definition in the VNFD
368         return !propertyName.equals("additional_parameters");
369     }
370
371     private ToscaNodeTemplate createNodeTemplateForNsNodeType(final String nodeType, final ToscaNodeType toscaNodeType) {
372         final ToscaNodeTemplate nodeTemplate = new ToscaNodeTemplate();
373         nodeTemplate.setType(nodeType);
374         final Map<String, ToscaProperty> properties = toscaNodeType.getProperties();
375         final Map<String, Object> nodeTemplateProperties = new HashMap<>();
376         for (final Entry<String, ToscaProperty> property : properties.entrySet()) {
377             if (property.getValue().getDefaultp() != null) {
378                 nodeTemplateProperties.put(property.getKey(), property.getValue().getDefaultp());
379             }
380         }
381         if (!nodeTemplateProperties.isEmpty()) {
382             nodeTemplate.setProperties(nodeTemplateProperties);
383         }
384         final Map<String, Object> interfaces = toscaNodeType.getInterfaces();
385         if (interfaces != null) {
386             for (final Entry<String, Object> nodeInterface : interfaces.entrySet()) {
387                 if ("Nslcm".equals(nodeInterface.getKey()) && nodeInterface.getValue() instanceof Map) {
388                     ((Map<?, ?>) nodeInterface.getValue()).remove("type");
389                 }
390             }
391             nodeTemplate.setInterfaces(interfaces);
392         }
393         return nodeTemplate;
394     }
395
396     private ToscaTemplate parseToToscaTemplate(final Component component) throws NsdException {
397         final Either<ToscaTemplate, ToscaError> toscaTemplateRes = toscaExportHandler.convertToToscaTemplate(component);
398         if (toscaTemplateRes.isRight()) {
399             String errorMsg = String
400                 .format("Could not parse component '%s' to tosca template. Error '%s'", component.getName(), toscaTemplateRes.right().value().name());
401             throw new NsdException(errorMsg);
402         }
403         return toscaTemplateRes.left().value();
404     }
405
406     private ToscaTemplate exportComponentInterfaceAsToscaTemplate(final Component component) throws NsdException {
407         if (null == DEFAULT_IMPORTS) {
408             throw new NsdException("Could not load default CSAR imports from configuration");
409         }
410         final ToscaTemplate toscaTemplate = new ToscaTemplate(TOSCA_VERSION);
411         toscaTemplate.setImports(new ArrayList<>(DEFAULT_IMPORTS));
412         final Either<ToscaTemplate, ToscaError> toscaTemplateRes = toscaExportHandler
413             .convertInterfaceNodeType(new HashMap<>(), component, toscaTemplate, new HashMap<>(), false);
414         if (toscaTemplateRes.isRight()) {
415             throw new NsdException(String.format("Could not create abstract service from component '%s'", component.getName()));
416         }
417         return toscaTemplateRes.left().value();
418     }
419 }