2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
20 package org.openecomp.sdc.be.tosca;
22 import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
23 import static org.apache.commons.collections.MapUtils.isNotEmpty;
24 import static org.openecomp.sdc.be.components.utils.PropertiesUtils.resolvePropertyValueFromInput;
25 import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_ATTRIBUTE;
26 import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_INPUT;
27 import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_PROPERTY;
29 import com.fasterxml.jackson.databind.ObjectMapper;
30 import com.google.common.primitives.Ints;
31 import com.google.gson.JsonElement;
32 import com.google.gson.JsonObject;
33 import com.google.gson.JsonParser;
34 import com.google.gson.stream.JsonReader;
35 import fj.data.Either;
36 import java.io.StringReader;
37 import java.nio.file.Path;
38 import java.util.ArrayList;
39 import java.util.Arrays;
40 import java.util.Collection;
41 import java.util.Collections;
42 import java.util.HashMap;
43 import java.util.HashSet;
44 import java.util.Iterator;
45 import java.util.LinkedHashMap;
46 import java.util.LinkedHashSet;
47 import java.util.List;
49 import java.util.Map.Entry;
50 import java.util.Objects;
51 import java.util.Optional;
53 import java.util.function.Supplier;
54 import java.util.stream.Collectors;
55 import org.apache.commons.collections.CollectionUtils;
56 import org.apache.commons.collections.MapUtils;
57 import org.apache.commons.io.FilenameUtils;
58 import org.apache.commons.lang3.StringUtils;
59 import org.apache.commons.lang3.tuple.ImmutablePair;
60 import org.apache.commons.lang3.tuple.ImmutableTriple;
61 import org.apache.commons.lang3.tuple.Triple;
62 import org.onap.sdc.tosca.services.YamlUtil;
63 import org.openecomp.sdc.be.components.impl.exceptions.SdcResourceNotFoundException;
64 import org.openecomp.sdc.be.config.Configuration;
65 import org.openecomp.sdc.be.config.ConfigurationManager;
66 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
67 import org.openecomp.sdc.be.data.model.ToscaImportByModel;
68 import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
69 import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition;
70 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
71 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
72 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
73 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
74 import org.openecomp.sdc.be.datatypes.elements.PropertyFilterConstraintDataDefinition;
75 import org.openecomp.sdc.be.datatypes.elements.PropertyFilterDataDefinition;
76 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition;
77 import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition;
78 import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterPropertyDataDefinition;
79 import org.openecomp.sdc.be.datatypes.elements.ToscaArtifactDataDefinition;
80 import org.openecomp.sdc.be.datatypes.elements.ToscaFunction;
81 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
82 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
83 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
84 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
85 import org.openecomp.sdc.be.exception.ToscaExportException;
86 import org.openecomp.sdc.be.model.ArtifactDefinition;
87 import org.openecomp.sdc.be.model.AttributeDefinition;
88 import org.openecomp.sdc.be.model.CapabilityDefinition;
89 import org.openecomp.sdc.be.model.CapabilityRequirementRelationship;
90 import org.openecomp.sdc.be.model.Component;
91 import org.openecomp.sdc.be.model.ComponentInstance;
92 import org.openecomp.sdc.be.model.ComponentInstanceAttribute;
93 import org.openecomp.sdc.be.model.ComponentInstanceInput;
94 import org.openecomp.sdc.be.model.ComponentInstanceInterface;
95 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
96 import org.openecomp.sdc.be.model.ComponentParametersView;
97 import org.openecomp.sdc.be.model.DataTypeDefinition;
98 import org.openecomp.sdc.be.model.GroupInstance;
99 import org.openecomp.sdc.be.model.InputDefinition;
100 import org.openecomp.sdc.be.model.InterfaceDefinition;
101 import org.openecomp.sdc.be.model.PropertyDefinition;
102 import org.openecomp.sdc.be.model.RelationshipInfo;
103 import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
104 import org.openecomp.sdc.be.model.RequirementDefinition;
105 import org.openecomp.sdc.be.model.Resource;
106 import org.openecomp.sdc.be.model.Service;
107 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
108 import org.openecomp.sdc.be.model.category.CategoryDefinition;
109 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
110 import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter;
111 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
112 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
113 import org.openecomp.sdc.be.model.operations.impl.ModelOperation;
114 import org.openecomp.sdc.be.model.tosca.converters.ToscaMapValueConverter;
115 import org.openecomp.sdc.be.tosca.PropertyConvertor.PropertyType;
116 import org.openecomp.sdc.be.tosca.builder.ToscaRelationshipBuilder;
117 import org.openecomp.sdc.be.tosca.exception.ToscaConversionException;
118 import org.openecomp.sdc.be.tosca.model.CapabilityFilter;
119 import org.openecomp.sdc.be.tosca.model.NodeFilter;
120 import org.openecomp.sdc.be.tosca.model.SubstitutionMapping;
121 import org.openecomp.sdc.be.tosca.model.ToscaAttribute;
122 import org.openecomp.sdc.be.tosca.model.ToscaCapability;
123 import org.openecomp.sdc.be.tosca.model.ToscaDataType;
124 import org.openecomp.sdc.be.tosca.model.ToscaGroupTemplate;
125 import org.openecomp.sdc.be.tosca.model.ToscaNodeTemplate;
126 import org.openecomp.sdc.be.tosca.model.ToscaNodeType;
127 import org.openecomp.sdc.be.tosca.model.ToscaPolicyTemplate;
128 import org.openecomp.sdc.be.tosca.model.ToscaProperty;
129 import org.openecomp.sdc.be.tosca.model.ToscaPropertyAssignment;
130 import org.openecomp.sdc.be.tosca.model.ToscaRelationshipTemplate;
131 import org.openecomp.sdc.be.tosca.model.ToscaRequirement;
132 import org.openecomp.sdc.be.tosca.model.ToscaTemplate;
133 import org.openecomp.sdc.be.tosca.model.ToscaTemplateArtifact;
134 import org.openecomp.sdc.be.tosca.model.ToscaTemplateRequirement;
135 import org.openecomp.sdc.be.tosca.model.ToscaTopolgyTemplate;
136 import org.openecomp.sdc.be.tosca.utils.ForwardingPathToscaUtil;
137 import org.openecomp.sdc.be.tosca.utils.InputConverter;
138 import org.openecomp.sdc.be.tosca.utils.OutputConverter;
139 import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
140 import org.openecomp.sdc.common.log.wrappers.Logger;
141 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
142 import org.springframework.beans.factory.annotation.Autowired;
143 import org.yaml.snakeyaml.DumperOptions;
144 import org.yaml.snakeyaml.DumperOptions.FlowStyle;
145 import org.yaml.snakeyaml.Yaml;
146 import org.yaml.snakeyaml.introspector.BeanAccess;
147 import org.yaml.snakeyaml.introspector.Property;
148 import org.yaml.snakeyaml.introspector.PropertyUtils;
149 import org.yaml.snakeyaml.nodes.MappingNode;
150 import org.yaml.snakeyaml.nodes.Node;
151 import org.yaml.snakeyaml.nodes.NodeTuple;
152 import org.yaml.snakeyaml.nodes.Tag;
153 import org.yaml.snakeyaml.representer.Represent;
154 import org.yaml.snakeyaml.representer.Representer;
156 @org.springframework.stereotype.Component("tosca-export-handler")
157 public class ToscaExportHandler {
159 public static final String ASSET_TOSCA_TEMPLATE = "assettoscatemplate";
160 private static final Logger log = Logger.getLogger(ToscaExportHandler.class);
161 private static final String INVARIANT_UUID = "invariantUUID";
162 private static final String TOSCA_VERSION = "tosca_simple_yaml_1_3";
163 private static final String SERVICE_NODE_TYPE_PREFIX = "org.openecomp.service.";
164 private static final String IMPORTS_FILE_KEY = "file";
165 private static final String TOSCA_INTERFACE_NAME = "-interface.yml";
166 private static final String FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION = "convertToToscaTemplate - failed to get Default Imports section from configuration";
167 private static final String NOT_SUPPORTED_COMPONENT_TYPE = "Not supported component type {}";
168 private static final String NATIVE_ROOT = "tosca.nodes.Root";
169 private static final List<String> EXCLUDED_CATEGORY_SPECIFIC_METADATA = List
170 .of("Service Function", "Service Role", "Naming Policy", "Service Type");
171 private static final YamlUtil yamlUtil = new YamlUtil();
172 private final ApplicationDataTypeCache applicationDataTypeCache;
173 private final ToscaOperationFacade toscaOperationFacade;
174 private final CapabilityRequirementConverter capabilityRequirementConverter;
175 private final PolicyExportParser policyExportParser;
176 private final GroupExportParser groupExportParser;
177 private final PropertyConvertor propertyConvertor;
178 private final AttributeConverter attributeConverter;
179 private final InputConverter inputConverter;
180 private final OutputConverter outputConverter;
181 private final InterfaceLifecycleOperation interfaceLifecycleOperation;
182 private final InterfacesOperationsConverter interfacesOperationsConverter;
183 private final ModelOperation modelOperation;
186 public ToscaExportHandler(final ApplicationDataTypeCache applicationDataTypeCache,
187 final ToscaOperationFacade toscaOperationFacade,
188 final CapabilityRequirementConverter capabilityRequirementConverter,
189 final PolicyExportParser policyExportParser,
190 final GroupExportParser groupExportParser,
191 final PropertyConvertor propertyConvertor,
192 final AttributeConverter attributeConverter,
193 final InputConverter inputConverter,
194 final OutputConverter outputConverter,
195 final InterfaceLifecycleOperation interfaceLifecycleOperation,
196 final InterfacesOperationsConverter interfacesOperationsConverter,
197 final ModelOperation modelOperation) {
198 this.applicationDataTypeCache = applicationDataTypeCache;
199 this.toscaOperationFacade = toscaOperationFacade;
200 this.capabilityRequirementConverter = capabilityRequirementConverter;
201 this.policyExportParser = policyExportParser;
202 this.groupExportParser = groupExportParser;
203 this.propertyConvertor = propertyConvertor;
204 this.attributeConverter = attributeConverter;
205 this.inputConverter = inputConverter;
206 this.outputConverter = outputConverter;
207 this.interfaceLifecycleOperation = interfaceLifecycleOperation;
208 this.interfacesOperationsConverter = interfacesOperationsConverter;
209 this.modelOperation = modelOperation;
212 public static String getInterfaceFilename(String artifactName) {
213 return artifactName.substring(0, artifactName.lastIndexOf('.')) + TOSCA_INTERFACE_NAME;
216 private static void removeOperationImplementationForProxyNodeType(Map<String, InterfaceDefinition> proxyComponentInterfaces) {
217 if (MapUtils.isEmpty(proxyComponentInterfaces)) {
220 proxyComponentInterfaces.values().stream().map(InterfaceDataDefinition::getOperations).filter(MapUtils::isNotEmpty)
221 .forEach(operations -> operations.values().forEach(operation -> operation.setImplementation(null)));
224 public Either<ToscaRepresentation, ToscaError> exportComponent(Component component) {
225 return convertToToscaTemplate(component).left().map(this::createToscaRepresentation);
228 public Either<ToscaRepresentation, ToscaError> exportComponentInterface(final Component component, final boolean isAssociatedComponent) {
229 final List<Map<String, Map<String, String>>> imports = new ArrayList<>(getDefaultToscaImports(component.getModel()));
230 if (CollectionUtils.isEmpty(imports)) {
231 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
232 return Either.right(ToscaError.GENERAL_ERROR);
234 List<Triple<String, String, Component>> dependencies = new ArrayList<>();
235 if (component.getDerivedFromGenericType() != null && !component.getDerivedFromGenericType()
236 .startsWith("org.openecomp.resource.abstract.nodes.")) {
237 final Either<Component, StorageOperationStatus> baseType = toscaOperationFacade
238 .getByToscaResourceNameAndVersion(component.getDerivedFromGenericType(), component.getDerivedFromGenericVersion(),
239 component.getModel());
240 if (baseType.isLeft() && baseType.left().value() != null) {
241 addDependencies(imports, dependencies, baseType.left().value());
243 log.debug("Failed to fetch derived from type {}", component.getDerivedFromGenericType());
247 String toscaVersion = null;
248 if (component instanceof Resource) {
249 toscaVersion = ((Resource) component).getToscaVersion();
251 ToscaTemplate toscaTemplate = new ToscaTemplate(toscaVersion != null ? toscaVersion : TOSCA_VERSION);
252 toscaTemplate.setImports(imports);
253 final Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
254 final Either<ToscaTemplate, ToscaError> toscaTemplateRes = convertInterfaceNodeType(new HashMap<>(), component, toscaTemplate, nodeTypes,
255 isAssociatedComponent);
256 if (toscaTemplateRes.isRight()) {
257 return Either.right(toscaTemplateRes.right().value());
259 toscaTemplate = toscaTemplateRes.left().value();
260 toscaTemplate.setDependencies(dependencies);
261 ToscaRepresentation toscaRepresentation = this.createToscaRepresentation(toscaTemplate);
262 return Either.left(toscaRepresentation);
265 private ToscaRepresentation createToscaRepresentation(ToscaTemplate toscaTemplate) {
266 CustomRepresenter representer = new CustomRepresenter();
267 DumperOptions options = new DumperOptions();
268 options.setAllowReadOnlyProperties(false);
269 options.setPrettyFlow(true);
270 options.setDefaultFlowStyle(FlowStyle.FLOW);
271 options.setCanonical(false);
272 representer.addClassTag(toscaTemplate.getClass(), Tag.MAP);
273 representer.setPropertyUtils(new UnsortedPropertyUtils());
274 Yaml yaml = new Yaml(representer, options);
275 String yamlAsString = yaml.dumpAsMap(toscaTemplate);
276 StringBuilder sb = new StringBuilder();
277 sb.append(getConfiguration().getHeatEnvArtifactHeader());
278 sb.append(yamlAsString);
279 sb.append(getConfiguration().getHeatEnvArtifactFooter());
280 return ToscaRepresentation.make(sb.toString().getBytes(), toscaTemplate);
283 public Either<ToscaTemplate, ToscaError> getDependencies(Component component) {
284 ToscaTemplate toscaTemplate = new ToscaTemplate(null);
285 Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports = fillImports(component, toscaTemplate);
286 if (fillImports.isRight()) {
287 return Either.right(fillImports.right().value());
289 return Either.left(fillImports.left().value().left);
292 public Either<ToscaTemplate, ToscaError> convertToToscaTemplate(final Component component) {
293 final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImports(component.getModel());
294 if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
295 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
296 return Either.right(ToscaError.GENERAL_ERROR);
298 log.trace("start tosca export for {}", component.getUniqueId());
299 String toscaVersion = null;
300 if (component instanceof Resource) {
301 toscaVersion = ((Resource) component).getToscaVersion();
303 final ToscaTemplate toscaTemplate = new ToscaTemplate(toscaVersion != null ? toscaVersion : TOSCA_VERSION);
304 toscaTemplate.setMetadata(convertMetadata(component));
305 toscaTemplate.setImports(new ArrayList<>(defaultToscaImportConfig));
306 final Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
307 if (ModelConverter.isAtomicComponent(component)) {
308 log.trace("convert component as node type");
309 return convertNodeType(new HashMap<>(), component, toscaTemplate, nodeTypes);
311 log.trace("convert component as topology template");
312 return convertToscaTemplate(component, toscaTemplate);
316 private List<Map<String, Map<String, String>>> getDefaultToscaImports(final String modelId) {
317 if (modelId == null) {
318 return getDefaultToscaImportConfig();
321 final List<ToscaImportByModel> allModelImports = modelOperation.findAllModelImports(modelId, true);
322 final List<Map<String, Map<String, String>>> importList = new ArrayList<>();
323 final Set<Path> addedPathList = new HashSet<>();
324 for (final ToscaImportByModel toscaImportByModel : allModelImports) {
325 var importPath = Path.of(toscaImportByModel.getFullPath());
326 if (addedPathList.contains(importPath)) {
327 importPath = ToscaDefaultImportHelper.addModelAsFilePrefix(importPath, toscaImportByModel.getModelId());
329 final String fileName = FilenameUtils.getBaseName(importPath.toString());
330 importList.add(Map.of(fileName, Map.of("file", importPath.toString())));
331 addedPathList.add(importPath);
336 private Either<ToscaTemplate, ToscaError> convertToscaTemplate(Component component, ToscaTemplate toscaNode) {
337 Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> importsRes = fillImports(component, toscaNode);
338 if (importsRes.isRight()) {
339 return Either.right(importsRes.right().value());
341 toscaNode = importsRes.left().value().left;
342 Map<String, Component> componentCache = importsRes.left().value().right;
343 Either<Map<String, ToscaNodeType>, ToscaError> nodeTypesMapEither = createProxyNodeTypes(componentCache, component);
344 if (nodeTypesMapEither.isRight()) {
345 log.debug("Failed to fetch normative service proxy resource by tosca name, error {}", nodeTypesMapEither.right().value());
346 return Either.right(nodeTypesMapEither.right().value());
348 Map<String, ToscaNodeType> nodeTypesMap = nodeTypesMapEither.left().value();
349 if (nodeTypesMap != null && !nodeTypesMap.isEmpty()) {
350 toscaNode.setNode_types(nodeTypesMap);
352 createServiceSubstitutionNodeTypes(componentCache, component, toscaNode);
353 Either<Map<String, Object>, ToscaError> proxyInterfaceTypesEither = createProxyInterfaceTypes(component);
354 if (proxyInterfaceTypesEither.isRight()) {
355 log.debug("Failed to populate service proxy local interface types in tosca, error {}", nodeTypesMapEither.right().value());
356 return Either.right(proxyInterfaceTypesEither.right().value());
358 Map<String, Object> proxyInterfaceTypes = proxyInterfaceTypesEither.left().value();
359 if (MapUtils.isNotEmpty(proxyInterfaceTypes)) {
360 toscaNode.setInterface_types(proxyInterfaceTypes);
362 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = applicationDataTypeCache.getAll(component.getModel());
363 if (dataTypesEither.isRight()) {
364 log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
365 return Either.right(ToscaError.GENERAL_ERROR);
367 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
368 ToscaTopolgyTemplate topologyTemplate = new ToscaTopolgyTemplate();
369 List<InputDefinition> inputDef = component.getInputs();
370 Map<String, ToscaProperty> inputs = inputConverter.convertInputs(inputDef, dataTypes);
371 if (!inputs.isEmpty()) {
372 topologyTemplate.setInputs(inputs);
374 final Map<String, ToscaProperty> outputs;
376 outputs = outputConverter.convert(component.getOutputs(), dataTypes);
377 } catch (final ToscaConversionException e) {
378 log.error(EcompLoggerErrorCode.SCHEMA_ERROR, ToscaExportHandler.class.getName(),
379 "Could not parse component '{}' outputs. Component unique id '{}'.", component.getName(), component.getUniqueId(), e);
380 return Either.right(ToscaError.GENERAL_ERROR);
382 if (!outputs.isEmpty()) {
383 topologyTemplate.setOutputs(outputs);
385 if (CollectionUtils.isNotEmpty(component.getComponentInstances())) {
386 final Either<Map<String, ToscaNodeTemplate>, ToscaError> nodeTemplates =
387 convertNodeTemplates(component, componentCache, dataTypes, topologyTemplate);
388 if (nodeTemplates.isRight()) {
389 return Either.right(nodeTemplates.right().value());
391 log.debug("node templates converted");
392 topologyTemplate.setNode_templates(nodeTemplates.left().value());
394 final Map<String, ToscaRelationshipTemplate> relationshipTemplatesMap = new ToscaExportRelationshipTemplatesHandler()
395 .createFrom(topologyTemplate.getNode_templates());
396 if (!relationshipTemplatesMap.isEmpty()) {
397 topologyTemplate.setRelationshipTemplates(relationshipTemplatesMap);
399 addGroupsToTopologyTemplate(component, topologyTemplate);
401 addPoliciesToTopologyTemplate(component, topologyTemplate);
402 } catch (SdcResourceNotFoundException e) {
403 log.debug("Fail to add policies to topology template:", e);
404 return Either.right(ToscaError.GENERAL_ERROR);
407 createSubstitutionMapping(component, componentCache).ifPresent(topologyTemplate::setSubstitution_mappings);
408 } catch (final ToscaExportException e) {
409 log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, ToscaExportHandler.class.getName(), e.getMessage());
410 return Either.right(e.getToscaError());
412 if (!topologyTemplate.isEmpty()) {
413 toscaNode.setTopology_template(topologyTemplate);
415 return Either.left(toscaNode);
418 private Either<String, ToscaError> createComponentToscaName(final Component component) {
419 switch (component.getComponentType()) {
421 final ResourceMetadataDataDefinition resourceMetadata =
422 (ResourceMetadataDataDefinition) component.getComponentMetadataDefinition().getMetadataDataDefinition();
423 return Either.left(resourceMetadata.getToscaResourceName());
425 return Either.left(SERVICE_NODE_TYPE_PREFIX + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName());
427 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
428 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
432 private Optional<SubstitutionMapping> createSubstitutionMapping(final Component component,
433 final Map<String, Component> componentCache) throws ToscaExportException {
434 if (component instanceof Service && !((Service) component).isSubstituteCandidate()) {
435 return Optional.empty();
438 final Either<String, ToscaError> toscaResourceNameEither = createComponentToscaName(component);
439 if (toscaResourceNameEither.isRight()) {
440 throw new ToscaExportException("Could not create component TOSCA name", toscaResourceNameEither.right().value());
442 final String toscaResourceName = toscaResourceNameEither.left().value();
444 final SubstitutionMapping substitutionMapping = new SubstitutionMapping();
445 substitutionMapping.setNode_type(toscaResourceName);
446 convertSubstitutionMappingFilter(component).ifPresent(substitutionMapping::setSubstitution_filter);
448 final Either<Map<String, String[]>, ToscaError> capabilitiesEither = convertSubstitutionMappingCapabilities(component, componentCache);
449 if (capabilitiesEither.isRight()) {
450 throw new ToscaExportException("Could not convert substitution mapping capabilities", capabilitiesEither.right().value());
452 final Map<String, String[]> capabilityMap = capabilitiesEither.left().value();
453 if (!capabilityMap.isEmpty()) {
454 substitutionMapping.setCapabilities(capabilityMap);
457 final Either<Map<String, String[]>, ToscaError> requirements =
458 capabilityRequirementConverter.convertSubstitutionMappingRequirements(component, componentCache);
459 if (requirements.isRight()) {
460 throw new ToscaExportException("Could not convert substitution mapping requirements", requirements.right().value());
462 final Map<String, String[]> requirementMap = requirements.left().value();
463 if (MapUtils.isNotEmpty(requirementMap)) {
464 substitutionMapping.setRequirements(requirementMap);
467 final Map<String, String[]> propertyMappingMap = buildSubstitutionMappingPropertyMapping(component);
468 if (MapUtils.isNotEmpty(propertyMappingMap)) {
469 substitutionMapping.setProperties(propertyMappingMap);
472 final Map<String, String[]> attributesMappingMap = buildSubstitutionMappingAttributesMapping(component);
473 if (MapUtils.isNotEmpty(attributesMappingMap)) {
474 substitutionMapping.setAttributes(attributesMappingMap);
477 return Optional.of(substitutionMapping);
480 private Optional<NodeFilter> convertSubstitutionMappingFilter(final Component component) {
481 if (component.getSubstitutionFilter() == null || (component.getSubstitutionFilter().getProperties()).getListToscaDataDefinition() == null) {
482 return Optional.empty();
485 return Optional.ofNullable(convertToSubstitutionFilterComponent(component.getSubstitutionFilter()));
488 private void addGroupsToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate) {
489 Map<String, ToscaGroupTemplate> groups = groupExportParser.getGroups(component);
490 if (groups != null) {
491 topologyTemplate.addGroups(groups);
495 private void addPoliciesToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate) throws SdcResourceNotFoundException {
496 Map<String, ToscaPolicyTemplate> policies = policyExportParser.getPolicies(component);
497 if (policies != null) {
498 topologyTemplate.addPolicies(policies);
502 private Map<String, String> convertMetadata(Component component) {
503 return convertMetadata(component, false, null);
506 private Map<String, String> convertMetadata(Component component, boolean isInstance, ComponentInstance componentInstance) {
507 Map<String, String> toscaMetadata = new LinkedHashMap<>();
508 toscaMetadata.put(convertMetadataKey(JsonPresentationFields.INVARIANT_UUID), component.getInvariantUUID());
509 toscaMetadata.put(JsonPresentationFields.UUID.getPresentation(), component.getUUID());
511 .put(JsonPresentationFields.NAME.getPresentation(), component.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
512 toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), component.getDescription());
513 List<CategoryDefinition> categories = component.getCategories();
514 CategoryDefinition categoryDefinition = categories.get(0);
515 toscaMetadata.put(JsonPresentationFields.MODEL.getPresentation(), component.getModel());
516 toscaMetadata.put(JsonPresentationFields.CATEGORY.getPresentation(), categoryDefinition.getName());
518 toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), component.getVersion());
519 toscaMetadata.put(JsonPresentationFields.CUSTOMIZATION_UUID.getPresentation(), componentInstance.getCustomizationUUID());
520 if (componentInstance.getSourceModelInvariant() != null && !componentInstance.getSourceModelInvariant().isEmpty()) {
521 toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), componentInstance.getComponentVersion());
522 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_INVARIANT.getPresentation(), componentInstance.getSourceModelInvariant());
523 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_UUID.getPresentation(), componentInstance.getSourceModelUuid());
524 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_NAME.getPresentation(), componentInstance.getSourceModelName());
525 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
526 toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(),
527 componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceProxy.getDisplayValue());
528 } else if (componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
529 toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(),
530 componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceSubstitution.getDisplayValue());
532 toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), componentInstance.getDescription());
535 switch (component.getComponentType()) {
537 Resource resource = (Resource) component;
538 if (isInstance && (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy
539 || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution)) {
540 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), componentInstance.getOriginType().getDisplayValue());
542 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), resource.getResourceType().name());
544 toscaMetadata.put(JsonPresentationFields.SUB_CATEGORY.getPresentation(), categoryDefinition.getSubcategories().get(0).getName());
545 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR.getPresentation(), resource.getVendorName());
546 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_RELEASE.getPresentation(), resource.getVendorRelease());
547 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_MODEL_NUMBER.getPresentation(), resource.getResourceVendorModelNumber());
550 Service service = (Service) component;
551 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), component.getComponentType().getValue());
552 toscaMetadata.put(JsonPresentationFields.SERVICE_TYPE.getPresentation(), service.getServiceType());
553 toscaMetadata.put(JsonPresentationFields.SERVICE_ROLE.getPresentation(), service.getServiceRole());
554 toscaMetadata.put(JsonPresentationFields.SERVICE_FUNCTION.getPresentation(), service.getServiceFunction());
555 toscaMetadata.put(JsonPresentationFields.ENVIRONMENT_CONTEXT.getPresentation(), service.getEnvironmentContext());
556 toscaMetadata.put(JsonPresentationFields.INSTANTIATION_TYPE.getPresentation(),
557 service.getEnvironmentContext() == null ? StringUtils.EMPTY : service.getInstantiationType());
560 toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming().toString());
561 toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming().toString());
562 toscaMetadata.put(JsonPresentationFields.NAMING_POLICY.getPresentation(), service.getNamingPolicy());
566 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
568 for (final String key : component.getCategorySpecificMetadata().keySet()) {
569 if (!EXCLUDED_CATEGORY_SPECIFIC_METADATA.contains(key)) {
570 toscaMetadata.put(key, component.getCategorySpecificMetadata().get(key));
573 return toscaMetadata;
576 private String convertMetadataKey(JsonPresentationFields jsonPresentationField) {
577 if (JsonPresentationFields.INVARIANT_UUID.equals(jsonPresentationField)) {
578 return INVARIANT_UUID;
580 return jsonPresentationField.getPresentation();
583 private Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports(Component component, ToscaTemplate toscaTemplate) {
584 final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImports(component.getModel());
585 if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
586 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
587 return Either.right(ToscaError.GENERAL_ERROR);
589 Map<String, Component> componentCache = new HashMap<>();
590 if (!ModelConverter.isAtomicComponent(component)) {
591 final List<Map<String, Map<String, String>>> additionalImports =
592 toscaTemplate.getImports() == null ? new ArrayList<>(defaultToscaImportConfig) : new ArrayList<>(toscaTemplate.getImports());
593 List<Triple<String, String, Component>> dependencies = new ArrayList<>();
594 Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
595 final Map<String, Map<String, String>> substituteTypeImportEntry = generateComponentSubstituteTypeImport(component, toscaArtifacts);
596 if (!substituteTypeImportEntry.isEmpty()) {
597 additionalImports.add(substituteTypeImportEntry);
599 List<ComponentInstance> componentInstances = component.getComponentInstances();
600 if (componentInstances != null && !componentInstances.isEmpty()) {
601 componentInstances.forEach(ci -> createDependency(componentCache, additionalImports, dependencies, ci));
603 toscaTemplate.setDependencies(dependencies);
604 toscaTemplate.setImports(additionalImports);
606 log.debug("currently imports supported for VF and service only");
608 return Either.left(new ImmutablePair<>(toscaTemplate, componentCache));
611 private Map<String, Map<String, String>> generateComponentSubstituteTypeImport(final Component component,
612 final Map<String, ArtifactDefinition> toscaArtifacts) {
614 if (component instanceof Service && !((Service) component).isSubstituteCandidate()) {
615 return Collections.emptyMap();
617 if (MapUtils.isEmpty(toscaArtifacts)) {
618 return Collections.emptyMap();
620 final ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE);
621 if (artifactDefinition == null) {
622 return Collections.emptyMap();
624 final var importEntryName = component.getComponentType().toString().toLowerCase() + "-" + component.getName() + "-interface";
625 return Map.of(importEntryName,
626 Map.of(IMPORTS_FILE_KEY, getInterfaceFilename(artifactDefinition.getArtifactName()))
630 private List<Map<String, Map<String, String>>> getDefaultToscaImportConfig() {
631 return getConfiguration().getDefaultImports();
634 private void createDependency(final Map<String, Component> componentCache, final List<Map<String, Map<String, String>>> imports,
635 final List<Triple<String, String, Component>> dependencies, final ComponentInstance componentInstance) {
636 log.debug("createDependency componentCache {}", componentCache);
637 Component componentRI = componentCache.get(componentInstance.getComponentUid());
638 if (componentRI == null || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
639 // all resource must be only once!
640 final Either<Component, StorageOperationStatus> resource = toscaOperationFacade.getToscaFullElement(componentInstance.getComponentUid());
641 if ((resource.isRight()) && (log.isDebugEnabled())) {
642 log.debug("Failed to fetch resource with id {} for instance {}", componentInstance.getComponentUid(),
643 componentInstance.getUniqueId());
646 final Component fetchedComponent = resource.left().value();
647 componentRI = setComponentCache(componentCache, componentInstance, fetchedComponent);
648 addDependencies(imports, dependencies, componentRI);
653 * Sets a componentCache from the given component/resource.
655 private Component setComponentCache(final Map<String, Component> componentCache, final ComponentInstance componentInstance,
656 final Component fetchedComponent) {
657 componentCache.put(fetchedComponent.getUniqueId(), fetchedComponent);
658 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy
659 || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
660 final Either<Component, StorageOperationStatus> sourceService = toscaOperationFacade
661 .getToscaFullElement(componentInstance.getSourceModelUid());
662 if (sourceService.isRight() && (log.isDebugEnabled())) {
663 log.debug("Failed to fetch source service with id {} for proxy {}", componentInstance.getSourceModelUid(),
664 componentInstance.getUniqueId());
666 final Component fetchedSource = sourceService.left().value();
667 componentCache.put(fetchedSource.getUniqueId(), fetchedSource);
668 return fetchedSource;
670 return fetchedComponent;
674 * Retrieves all derived_from nodes and stores it in a predictable order.
676 private void addDependencies(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
677 final Component fetchedComponent) {
678 final Set<Component> componentsList = new LinkedHashSet<>();
679 if (fetchedComponent instanceof Resource) {
680 log.debug("fetchedComponent is a resource {}", fetchedComponent);
681 final Optional<Map<String, String>> derivedFromMapOfIdToName = getDerivedFromMapOfIdToName(fetchedComponent, componentsList);
682 if (derivedFromMapOfIdToName.isPresent() && !derivedFromMapOfIdToName.get().isEmpty()) {
683 derivedFromMapOfIdToName.get().entrySet().forEach(entry -> {
684 log.debug("Started entry.getValue() : {}", entry.getValue());
685 if (!NATIVE_ROOT.equals(entry.getValue())) {
686 Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade.getToscaElement(entry.getKey());
687 if (resourcefetched != null && resourcefetched.isLeft()) {
688 componentsList.add(resourcefetched.left().value());
692 setImports(imports, dependencies, componentsList);
694 setImports(imports, dependencies, fetchedComponent);
700 * Returns all derived_from nodes found.
702 private Optional<Map<String, String>> getDerivedFromMapOfIdToName(final Component fetchedComponent, final Set<Component> componentsList) {
703 final Resource parentResource = (Resource) fetchedComponent;
704 Map<String, String> derivedFromMapOfIdToName = new HashMap<>();
705 if (CollectionUtils.isNotEmpty(parentResource.getComponentInstances())) {
706 componentsList.add(fetchedComponent);
707 for (final ComponentInstance componentInstance : parentResource.getComponentInstances()) {
708 final Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade
709 .getToscaElement(componentInstance.getComponentUid());
710 if (resourcefetched != null && resourcefetched.isLeft()) {
711 final Map<String, String> derivedWithId = resourcefetched.left().value().getDerivedFromMapOfIdToName();
712 if (MapUtils.isNotEmpty(derivedWithId)) {
713 derivedFromMapOfIdToName.putAll(derivedWithId);
718 derivedFromMapOfIdToName = parentResource.getDerivedFromMapOfIdToName();
720 log.debug("Started derivedFromMapOfIdToName: {}", derivedFromMapOfIdToName);
721 return Optional.ofNullable(derivedFromMapOfIdToName);
725 * Creates a resource map and adds it to the import list.
727 private void setImports(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
728 final Set<Component> componentsList) {
729 componentsList.forEach(component -> setImports(imports, dependencies, component));
732 private void setImports(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
733 final Component component) {
734 final Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
735 final ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE);
736 if (artifactDefinition != null) {
737 final Map<String, String> files = new HashMap<>();
738 final String artifactName = artifactDefinition.getArtifactName();
739 files.put(IMPORTS_FILE_KEY, artifactName);
740 final StringBuilder keyNameBuilder = new StringBuilder();
741 keyNameBuilder.append(component.getComponentType().toString().toLowerCase());
742 keyNameBuilder.append("-");
743 keyNameBuilder.append(component.getName());
744 addImports(imports, keyNameBuilder, files);
745 dependencies.add(new ImmutableTriple<>(artifactName, artifactDefinition.getEsId(), component));
746 if (!ModelConverter.isAtomicComponent(component)) {
747 final Map<String, String> interfaceFiles = new HashMap<>();
748 interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactName));
749 keyNameBuilder.append("-interface");
750 addImports(imports, keyNameBuilder, interfaceFiles);
756 * Adds the found resource to the import definition list.
758 private void addImports(final List<Map<String, Map<String, String>>> imports, final StringBuilder keyNameBuilder,
759 final Map<String, String> files) {
760 final String mapKey = keyNameBuilder.toString();
761 if (imports.stream().allMatch(stringMapMap -> stringMapMap.get(mapKey) == null)) {
762 final Map<String, Map<String, String>> importsListMember = new HashMap<>();
763 importsListMember.put(keyNameBuilder.toString(), files);
764 imports.add(importsListMember);
768 private Either<ToscaTemplate, ToscaError> convertNodeType(Map<String, Component> componentsCache, Component component, ToscaTemplate toscaNode,
769 Map<String, ToscaNodeType> nodeTypes) {
770 return convertInterfaceNodeType(componentsCache, component, toscaNode, nodeTypes, false);
773 public Either<ToscaTemplate, ToscaError> convertInterfaceNodeType(Map<String, Component> componentsCache, Component component,
774 ToscaTemplate toscaNode, Map<String, ToscaNodeType> nodeTypes,
775 boolean isAssociatedComponent) {
776 log.debug("start convert node type for {}", component.getUniqueId());
777 ToscaNodeType toscaNodeType = createNodeType(component);
778 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither = interfaceLifecycleOperation
779 .getAllInterfaceLifecycleTypes(component.getModel());
780 if (lifecycleTypeEither.isRight() && !StorageOperationStatus.NOT_FOUND.equals(lifecycleTypeEither.right().value())) {
781 log.debug("Failed to fetch all interface types :", lifecycleTypeEither.right().value());
782 return Either.right(ToscaError.GENERAL_ERROR);
784 if (lifecycleTypeEither.isLeft()) {
785 List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value().values().stream().map(InterfaceDataDefinition::getType)
786 .collect(Collectors.toList());
787 toscaNode.setInterface_types(interfacesOperationsConverter.addInterfaceTypeElement(component, allGlobalInterfaceTypes));
789 final var dataTypesEither = applicationDataTypeCache.getAll(component.getModel());
790 if (dataTypesEither.isRight()) {
791 log.debug("Failed to fetch all data types :", dataTypesEither.right().value());
792 return Either.right(ToscaError.GENERAL_ERROR);
794 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
795 List<InputDefinition> inputDef = component.getInputs();
796 interfacesOperationsConverter.addInterfaceDefinitionElement(component, toscaNodeType, dataTypes, isAssociatedComponent);
797 final var toscaAttributeMap = convertToToscaAttributes(component.getAttributes(), dataTypes);
798 if (!toscaAttributeMap.isEmpty()) {
799 toscaNodeType.setAttributes(toscaAttributeMap);
801 final var mergedProperties = convertInputsToProperties(dataTypes, inputDef, component.getUniqueId());
802 if (CollectionUtils.isNotEmpty(component.getProperties())) {
803 List<PropertyDefinition> properties = component.getProperties();
804 Map<String, ToscaProperty> convertedProperties = properties.stream()
805 .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, component.getInputs())).collect(Collectors
806 .toMap(PropertyDataDefinition::getName,
807 property -> propertyConvertor.convertProperty(dataTypes, property, PropertyConvertor.PropertyType.PROPERTY)));
808 // merge component properties and inputs properties
809 mergedProperties.putAll(convertedProperties);
811 if (MapUtils.isNotEmpty(mergedProperties)) {
812 toscaNodeType.setProperties(mergedProperties);
814 /* convert private data_types */
815 List<DataTypeDefinition> privateDataTypes = component.getDataTypes();
816 if (CollectionUtils.isNotEmpty(privateDataTypes)) {
817 Map<String, ToscaDataType> toscaDataTypeMap = new HashMap<>();
818 for (DataTypeDefinition dataType : privateDataTypes) {
819 log.debug("Emitting private data type: component.name={} dataType.name={}",
820 component.getNormalizedName(), dataType.getName());
821 ToscaDataType toscaDataType = new ToscaDataType();
822 toscaDataType.setDerived_from(dataType.getDerivedFromName());
823 toscaDataType.setDescription(dataType.getDescription());
824 toscaDataType.setVersion(dataType.getVersion());
825 if (CollectionUtils.isNotEmpty(dataType.getProperties())) {
826 toscaDataType.setProperties(dataType.getProperties().stream()
827 .collect(Collectors.toMap(
828 PropertyDataDefinition::getName,
829 s -> propertyConvertor.convertProperty(dataTypes, s, PropertyType.PROPERTY),
830 (toscaPropertyTobeValidated, toscaProperty) -> validateToscaProperty(privateDataTypes, toscaPropertyTobeValidated,
834 toscaDataTypeMap.put(dataType.getName(), toscaDataType);
836 toscaNode.setData_types(toscaDataTypeMap);
839 // Extracted to method for code reuse
840 return convertReqCapAndTypeName(componentsCache, component, toscaNode, nodeTypes, toscaNodeType, dataTypes);
843 private ToscaProperty validateToscaProperty(final List<DataTypeDefinition> privateDataTypes, final ToscaProperty toscaPropertyTobeValidated,
844 final ToscaProperty toscaProperty) {
845 final Optional<DataTypeDefinition> match = privateDataTypes.stream()
846 .filter(dataType -> dataType.getName().equals(toscaPropertyTobeValidated.getType())).findFirst();
847 return match.isPresent() ? toscaPropertyTobeValidated : toscaProperty;
850 private Map<String, ToscaAttribute> convertToToscaAttributes(final List<AttributeDefinition> attributeList,
851 final Map<String, DataTypeDefinition> dataTypes) {
852 if (CollectionUtils.isEmpty(attributeList)) {
853 return Collections.emptyMap();
855 final AttributeConverter converter = new AttributeConverter(dataTypes);
856 final Map<String, ToscaAttribute> toscaAttributeMap = new HashMap<>();
857 for (final AttributeDefinition attributeDefinition : attributeList) {
858 toscaAttributeMap.put(attributeDefinition.getName(), converter.convert(attributeDefinition));
860 return toscaAttributeMap;
863 private Either<ToscaTemplate, ToscaError> convertReqCapAndTypeName(Map<String, Component> componentsCache,
864 Component component, ToscaTemplate toscaNode,
865 Map<String, ToscaNodeType> nodeTypes,
866 ToscaNodeType toscaNodeType,
867 Map<String, DataTypeDefinition> dataTypes) {
868 Either<ToscaNodeType, ToscaError> capabilities = convertCapabilities(componentsCache, component, toscaNodeType,
870 if (capabilities.isRight()) {
871 return Either.right(capabilities.right().value());
873 toscaNodeType = capabilities.left().value();
874 log.debug("Capabilities converted for {}", component.getUniqueId());
876 Either<ToscaNodeType, ToscaError> requirements = capabilityRequirementConverter
877 .convertRequirements(componentsCache, component, toscaNodeType);
878 if (requirements.isRight()) {
879 return Either.right(requirements.right().value());
881 toscaNodeType = requirements.left().value();
882 log.debug("Requirements converted for {}", component.getUniqueId());
884 String toscaResourceName;
885 switch (component.getComponentType()) {
887 toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition()
888 .getMetadataDataDefinition()).getToscaResourceName();
891 toscaResourceName = SERVICE_NODE_TYPE_PREFIX
892 + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName();
895 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
896 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
899 nodeTypes.put(toscaResourceName, toscaNodeType);
900 toscaNode.setNode_types(nodeTypes);
901 log.debug("finish convert node type for {}", component.getUniqueId());
902 return Either.left(toscaNode);
905 private Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplates(final Component component,
906 final Map<String, Component> componentCache,
907 final Map<String, DataTypeDefinition> dataTypes,
908 final ToscaTopolgyTemplate topologyTemplate) {
910 final Map<String, List<ComponentInstanceProperty>> componentInstancesProperties = component.getComponentInstancesProperties();
911 final Map<String, List<ComponentInstanceAttribute>> componentInstancesAttributes = component.getComponentInstancesAttributes();
912 final Map<String, List<ComponentInstanceInput>> componentInstancesInputs = component.getComponentInstancesInputs();
913 final Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces = component.getComponentInstancesInterfaces();
914 final List<RequirementCapabilityRelDef> componentInstancesRelations = component.getComponentInstancesRelations();
916 Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplatesRes = null;
917 log.debug("start convert topology template for {} for type {}", component.getUniqueId(), component.getComponentType());
918 final Map<String, ToscaNodeTemplate> nodeTemplates = new HashMap<>();
920 Map<String, ToscaGroupTemplate> groupsMap = null;
921 for (final ComponentInstance componentInstance : component.getComponentInstances()) {
922 ToscaNodeTemplate nodeTemplate = new ToscaNodeTemplate();
923 if (MapUtils.isNotEmpty(componentInstance.getToscaArtifacts())) {
924 nodeTemplate.setArtifacts(convertToNodeTemplateArtifacts(componentInstance.getToscaArtifacts()));
926 if (componentInstance.getMinOccurrences() != null && componentInstance.getMaxOccurrences() != null) {
927 List<Object> occur = new ArrayList<>();
928 occur.add(parseToIntIfPossible(componentInstance.getMinOccurrences()));
929 occur.add(parseToIntIfPossible(componentInstance.getMaxOccurrences()));
930 nodeTemplate.setOccurrences(occur);
932 if (componentInstance.getInstanceCount() != null) {
933 ObjectMapper objectMapper = new ObjectMapper();
934 Object obj = convertToToscaObject(componentInstance.getInstanceCount());
936 Map<String, String> map = objectMapper.convertValue(obj, Map.class);
937 nodeTemplate.setInstance_count(map);
940 nodeTemplate.setType(componentInstance.getToscaComponentName());
941 nodeTemplate.setDirectives(componentInstance.getDirectives());
942 NodeFilter nodeFilter = convertToNodeTemplateNodeFilterComponent(componentInstance.getNodeFilter());
943 if(nodeFilter != null && nodeFilter.hasData()){
944 nodeTemplate.setNode_filter(nodeFilter);
946 final Either<Component, Boolean> originComponentRes = capabilityRequirementConverter
947 .getOriginComponent(componentCache, componentInstance);
948 if (originComponentRes.isRight()) {
949 convertNodeTemplatesRes = Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
952 final Either<ToscaNodeTemplate, ToscaError> requirements = convertComponentInstanceRequirements(component, componentInstance,
953 componentInstancesRelations, nodeTemplate, originComponentRes.left().value(), componentCache);
954 if (requirements.isRight()) {
955 convertNodeTemplatesRes = Either.right(requirements.right().value());
958 final String instanceUniqueId = componentInstance.getUniqueId();
959 log.debug("Component instance Requirements converted for instance {}", instanceUniqueId);
961 nodeTemplate = requirements.left().value();
963 final Component originalComponent = componentCache.get(componentInstance.getActualComponentUid());
965 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
966 final Component componentOfProxy = componentCache.get(componentInstance.getComponentUid());
967 nodeTemplate.setMetadata(convertMetadata(componentOfProxy, true, componentInstance));
969 nodeTemplate.setMetadata(convertMetadata(originalComponent, true, componentInstance));
972 final Either<ToscaNodeTemplate, ToscaError> capabilities =
973 capabilityRequirementConverter.convertComponentInstanceCapabilities(componentInstance, dataTypes, nodeTemplate);
974 if (capabilities.isRight()) {
975 convertNodeTemplatesRes = Either.right(capabilities.right().value());
978 log.debug("Component instance Capabilities converted for instance {}", instanceUniqueId);
980 nodeTemplate = capabilities.left().value();
981 final Map<String, Object> props = new HashMap<>();
982 final Map<String, Object> attribs = new HashMap<>();
984 if (originalComponent.getComponentType() == ComponentTypeEnum.RESOURCE) {
985 // Adds the properties of parent component to map
986 addPropertiesOfParentComponent(dataTypes, originalComponent, props);
987 addAttributesOfParentComponent(originalComponent, attribs);
990 if (null != componentInstancesProperties && componentInstancesProperties.containsKey(instanceUniqueId)) {
991 addPropertiesOfComponentInstance(componentInstancesProperties, dataTypes, instanceUniqueId, props);
993 if (null != componentInstancesAttributes && componentInstancesAttributes.containsKey(instanceUniqueId)) {
994 addAttributesOfComponentInstance(componentInstancesAttributes, instanceUniqueId, attribs);
997 if (componentInstancesInputs != null
998 && componentInstancesInputs.containsKey(instanceUniqueId)
999 && !isComponentOfTypeServiceProxy(componentInstance)) {
1000 //For service proxy the inputs are already handled under instance properties above
1001 addComponentInstanceInputs(dataTypes, componentInstancesInputs, instanceUniqueId, props);
1004 //M3[00001] - NODE TEMPLATE INTERFACES - START
1005 handleInstanceInterfaces(componentInstanceInterfaces, componentInstance, dataTypes, nodeTemplate, instanceUniqueId, component);
1006 //M3[00001] - NODE TEMPLATE INTERFACES - END
1007 if (MapUtils.isNotEmpty(props)) {
1008 nodeTemplate.setProperties(props);
1010 if (MapUtils.isNotEmpty(attribs)) {
1011 nodeTemplate.setAttributes(attribs);
1014 final List<GroupInstance> groupInstances = componentInstance.getGroupInstances();
1015 if (CollectionUtils.isNotEmpty(groupInstances)) {
1016 if (groupsMap == null) {
1017 groupsMap = new HashMap<>();
1019 for (final GroupInstance groupInst : groupInstances) {
1020 if (CollectionUtils.isNotEmpty(groupInst.getArtifacts())) {
1021 groupsMap.put(groupInst.getName(), groupExportParser.getToscaGroupTemplate(groupInst, componentInstance.getInvariantName()));
1026 nodeTemplates.put(componentInstance.getName(), nodeTemplate);
1028 if (groupsMap != null) {
1029 log.debug("instance groups added");
1030 topologyTemplate.addGroups(groupsMap);
1032 if (component.getComponentType() == ComponentTypeEnum.SERVICE && isNotEmpty(
1033 ((Service) component).getForwardingPaths())) {
1034 log.debug("Starting converting paths for component {}, name {}", component.getUniqueId(), component.getName());
1035 ForwardingPathToscaUtil
1036 .addForwardingPaths((Service) component, nodeTemplates, capabilityRequirementConverter, componentCache, toscaOperationFacade);
1037 log.debug("Finished converting paths for component {}, name {}", component.getUniqueId(), component.getName());
1039 if (convertNodeTemplatesRes == null) {
1040 convertNodeTemplatesRes = Either.left(nodeTemplates);
1042 log.debug("finish convert topology template for {} for type {}", component.getUniqueId(), component.getComponentType());
1043 return convertNodeTemplatesRes;
1046 private Object convertToToscaObject(String value) {
1048 ToscaMapValueConverter mapConverterInst = ToscaMapValueConverter.getInstance();
1049 StringReader reader = new StringReader(value);
1050 JsonReader jsonReader = new JsonReader(reader);
1051 jsonReader.setLenient(true);
1052 JsonElement jsonElement = JsonParser.parseReader(jsonReader);
1053 if (jsonElement.isJsonObject()) {
1054 JsonObject jsonObj = jsonElement.getAsJsonObject();
1055 if (jsonObj.entrySet().size() == 1 && jsonObj.has(ToscaFunctions.GET_INPUT.getFunctionName())) {
1056 return mapConverterInst.handleComplexJsonValue(jsonElement);
1060 } catch (Exception e) {
1061 log.debug("convertToToscaValue failed to parse json value :", e);
1066 private Object parseToIntIfPossible(final String value) {
1067 final Integer intValue = Ints.tryParse(value);
1068 return intValue == null ? value : intValue;
1071 private void handleInstanceInterfaces(
1072 Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces,
1073 ComponentInstance componentInstance, Map<String, DataTypeDefinition> dataTypes, ToscaNodeTemplate nodeTemplate,
1074 String instanceUniqueId,
1075 Component parentComponent) {
1077 if (MapUtils.isEmpty(componentInstanceInterfaces)
1078 || !componentInstanceInterfaces.containsKey(instanceUniqueId)) {
1079 nodeTemplate.setInterfaces(null);
1083 final List<ComponentInstanceInterface> currServiceInterfaces =
1084 componentInstanceInterfaces.get(instanceUniqueId);
1086 final Map<String, InterfaceDefinition> tmpInterfaces = new HashMap<>();
1087 currServiceInterfaces.forEach(instInterface -> tmpInterfaces.put(instInterface
1088 .getUniqueId(), instInterface));
1090 final Map<String, Object> interfaceMap = interfacesOperationsConverter
1091 .getInterfacesMap(parentComponent, componentInstance, tmpInterfaces, dataTypes, isComponentOfTypeServiceProxy(componentInstance),
1092 isComponentOfTypeServiceProxy(componentInstance));
1094 interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
1095 nodeTemplate.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap);
1098 private boolean isComponentOfTypeServiceProxy(ComponentInstance componentInstance) {
1099 return Objects.nonNull(componentInstance.getOriginType())
1100 && componentInstance.getOriginType().getValue().equals("Service Proxy");
1103 private void addComponentInstanceInputs(Map<String, DataTypeDefinition> dataTypes,
1104 Map<String, List<ComponentInstanceInput>> componentInstancesInputs,
1105 String instanceUniqueId, Map<String, Object> props) {
1107 List<ComponentInstanceInput> instanceInputsList = componentInstancesInputs.get(instanceUniqueId);
1108 if (instanceInputsList != null) {
1109 instanceInputsList.forEach(input -> {
1110 Supplier<String> supplier = () -> input.getValue() != null && !Objects.isNull(input.getValue()) ? input.getValue()
1111 : input.getDefaultValue();
1112 propertyConvertor.convertAndAddValue(dataTypes, props, input, supplier);
1117 private void addPropertiesOfComponentInstance(final Map<String, List<ComponentInstanceProperty>> componentInstancesProperties,
1118 final Map<String, DataTypeDefinition> dataTypes,
1119 final String instanceUniqueId,
1120 final Map<String, Object> props) {
1122 if (isNotEmpty(componentInstancesProperties)) {
1123 componentInstancesProperties.get(instanceUniqueId)
1124 // Converts and adds each value to property map
1125 .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop, prop::getValue));
1129 private void addAttributesOfComponentInstance(final Map<String, List<ComponentInstanceAttribute>> componentInstancesAttributes,
1130 final String instanceUniqueId,
1131 final Map<String, Object> attribs) {
1133 if (isNotEmpty(componentInstancesAttributes) && componentInstancesAttributes.containsKey(instanceUniqueId)) {
1134 componentInstancesAttributes.get(instanceUniqueId)
1135 .forEach(attributeDefinition -> attributeConverter.convertAndAddValue(attribs, attributeDefinition));
1139 private void addPropertiesOfParentComponent(Map<String, DataTypeDefinition> dataTypes,
1140 Component componentOfInstance, Map<String, Object> props) {
1142 List<PropertyDefinition> componentProperties = componentOfInstance.getProperties();
1143 if (isNotEmpty(componentProperties)) {
1144 componentProperties.stream()
1145 // Filters out properties with empty default values
1146 .filter(prop -> StringUtils.isNotEmpty(prop.getDefaultValue()))
1147 // Converts and adds each value to property map
1148 .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop, prop::getDefaultValue));
1152 private void addAttributesOfParentComponent(final Component componentOfInstance, final Map<String, Object> attribs) {
1154 final List<AttributeDefinition> componentAttributes = componentOfInstance.getAttributes();
1155 if (isNotEmpty(componentAttributes)) {
1156 componentAttributes.stream()
1157 // Filters out Attributes with empty default values
1158 .filter(attrib -> StringUtils.isNotEmpty(attrib.getDefaultValue()))
1159 // Converts and adds each value to attribute map
1160 .forEach(attributeDefinition -> attributeConverter.convertAndAddValue(attribs, attributeDefinition));
1164 private ToscaNodeType createNodeType(Component component) {
1165 ToscaNodeType toscaNodeType = new ToscaNodeType();
1166 if (ModelConverter.isAtomicComponent(component)) {
1167 if (((Resource) component).getDerivedFrom() != null) {
1168 toscaNodeType.setDerived_from(((Resource) component).getDerivedFrom().get(0));
1170 toscaNodeType.setDescription(component.getDescription());
1172 String derivedFrom = null != component.getDerivedFromGenericType() ? component.getDerivedFromGenericType()
1174 toscaNodeType.setDerived_from(derivedFrom);
1176 return toscaNodeType;
1179 private Either<Map<String, Object>, ToscaError> createProxyInterfaceTypes(Component container) {
1181 Map<String, Object> proxyInterfaceTypes = new HashMap<>();
1182 Either<Map<String, Object>, ToscaError> res = Either.left(proxyInterfaceTypes);
1183 List<ComponentInstance> componentInstances = container.getComponentInstances();
1184 if (CollectionUtils.isEmpty(componentInstances)) {
1187 Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
1188 componentInstances.stream()
1189 .filter(this::isComponentOfTypeServiceProxy)
1190 .forEach(inst -> serviceProxyInstanceList.put(inst.getToscaComponentName(), inst));
1191 if (MapUtils.isEmpty(serviceProxyInstanceList)) {
1194 for (Entry<String, ComponentInstance> entryProxy : serviceProxyInstanceList.entrySet()) {
1195 Component serviceComponent;
1196 ComponentParametersView componentParametersView = new ComponentParametersView();
1197 componentParametersView.disableAll();
1198 componentParametersView.setIgnoreInterfaces(false);
1199 Either<Component, StorageOperationStatus> service = toscaOperationFacade
1200 .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
1201 if (service.isRight()) {
1202 log.debug("Failed to fetch original service component with id {} for instance {}",
1203 entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName());
1204 return Either.right(ToscaError.GENERAL_ERROR);
1206 serviceComponent = service.left().value();
1209 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither =
1210 interfaceLifecycleOperation.getAllInterfaceLifecycleTypes(serviceComponent.getModel());
1211 if (lifecycleTypeEither.isRight()) {
1212 log.debug("Failed to retrieve global interface types :", lifecycleTypeEither.right().value());
1213 return Either.right(ToscaError.GENERAL_ERROR);
1216 List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value().values().stream()
1217 .map(InterfaceDataDefinition::getType)
1218 .collect(Collectors.toList());
1219 //Add interface types for local interfaces in the original service component for proxy
1220 Map<String, Object> localInterfaceTypes = interfacesOperationsConverter.addInterfaceTypeElement(serviceComponent,
1221 allGlobalInterfaceTypes);
1222 if (MapUtils.isNotEmpty(localInterfaceTypes)) {
1223 proxyInterfaceTypes.putAll(localInterfaceTypes);
1227 return Either.left(proxyInterfaceTypes);
1230 private Either<Map<String, ToscaNodeType>, ToscaError> createProxyNodeTypes(Map<String, Component> componentCache,
1231 Component container) {
1233 Map<String, ToscaNodeType> nodeTypesMap = new HashMap<>();
1234 Either<Map<String, ToscaNodeType>, ToscaError> res = Either.left(nodeTypesMap);
1236 List<ComponentInstance> componentInstances = container.getComponentInstances();
1238 if (componentInstances == null || componentInstances.isEmpty()) {
1241 Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
1242 List<ComponentInstance> proxyInst = componentInstances.stream()
1243 .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceProxy.name()))
1244 .collect(Collectors.toList());
1245 if (proxyInst != null && !proxyInst.isEmpty()) {
1246 for (ComponentInstance inst : proxyInst) {
1247 serviceProxyInstanceList.put(inst.getToscaComponentName(), inst);
1251 if (serviceProxyInstanceList.isEmpty()) {
1254 Either<Resource, StorageOperationStatus> serviceProxyOrigin = toscaOperationFacade
1255 .getLatestByName("serviceProxy", null);
1256 if (serviceProxyOrigin.isRight()) {
1257 log.debug("Failed to fetch normative service proxy resource by tosca name, error {}",
1258 serviceProxyOrigin.right().value());
1259 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
1261 Component origComponent = serviceProxyOrigin.left().value();
1263 for (Entry<String, ComponentInstance> entryProxy : serviceProxyInstanceList.entrySet()) {
1264 Component serviceComponent = null;
1265 ComponentParametersView componentParametersView = new ComponentParametersView();
1266 componentParametersView.disableAll();
1267 componentParametersView.setIgnoreCategories(false);
1268 componentParametersView.setIgnoreProperties(false);
1269 componentParametersView.setIgnoreInputs(false);
1270 componentParametersView.setIgnoreInterfaces(false);
1271 componentParametersView.setIgnoreRequirements(false);
1272 Either<Component, StorageOperationStatus> service = toscaOperationFacade
1273 .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
1274 if (service.isRight()) {
1275 log.debug("Failed to fetch resource with id {} for instance {}",
1276 entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName());
1278 serviceComponent = service.left().value();
1281 ToscaNodeType toscaNodeType = createProxyNodeType(componentCache, origComponent, serviceComponent,
1282 entryProxy.getValue());
1283 nodeTypesMap.put(entryProxy.getKey(), toscaNodeType);
1286 return Either.left(nodeTypesMap);
1289 private void createServiceSubstitutionNodeTypes(final Map<String, Component> componentCache,
1290 final Component container, final ToscaTemplate toscaNode) {
1291 final List<ComponentInstance> componentInstances = container.getComponentInstances();
1293 if (CollectionUtils.isEmpty(componentInstances)) {
1296 final List<ComponentInstance> serviceSubstitutionInstanceList = componentInstances.stream()
1297 .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceSubstitution.name()))
1298 .collect(Collectors.toList());
1299 if (CollectionUtils.isNotEmpty(serviceSubstitutionInstanceList)) {
1300 for (ComponentInstance inst : serviceSubstitutionInstanceList) {
1301 final Map<String, ToscaNodeType> nodeTypes =
1302 toscaNode.getNode_types() == null ? new HashMap<>() : toscaNode.getNode_types();
1303 convertInterfaceNodeType(new HashMap<>(), componentCache.get(inst.getSourceModelUid()), toscaNode,
1309 private ToscaNodeType createProxyNodeType(Map<String, Component> componentCache, Component origComponent,
1310 Component proxyComponent, ComponentInstance componentInstance) {
1311 ToscaNodeType toscaNodeType = new ToscaNodeType();
1312 String derivedFrom = ((Resource) origComponent).getToscaResourceName();
1314 toscaNodeType.setDerived_from(derivedFrom);
1315 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = applicationDataTypeCache.getAll(
1316 origComponent.getModel());
1317 if (dataTypesEither.isRight()) {
1318 log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
1320 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
1321 Map<String, ToscaCapability> capabilities = this.capabilityRequirementConverter
1322 .convertProxyCapabilities(componentCache, componentInstance, dataTypes);
1324 if (MapUtils.isNotEmpty(capabilities)) {
1325 toscaNodeType.setCapabilities(capabilities);
1327 List<Map<String, ToscaRequirement>> proxyNodeTypeRequirements = this.capabilityRequirementConverter
1328 .convertProxyRequirements(componentCache, componentInstance);
1329 if (CollectionUtils.isNotEmpty(proxyNodeTypeRequirements)) {
1330 toscaNodeType.setRequirements(proxyNodeTypeRequirements);
1332 Optional<Map<String, ToscaProperty>> proxyProperties = getProxyNodeTypeProperties(proxyComponent, dataTypes);
1333 proxyProperties.ifPresent(toscaNodeType::setProperties);
1335 Map<String, Object> interfaceMap = new HashMap<>();
1336 if (MapUtils.isEmpty(componentInstance.getInterfaces())) {
1337 final Optional<Map<String, Object>> proxyInterfaces = getProxyNodeTypeInterfaces(proxyComponent, dataTypes);
1338 if (proxyInterfaces.isPresent()) {
1339 interfaceMap = proxyInterfaces.get();
1342 interfaceMap = interfacesOperationsConverter
1343 .getInterfacesMapFromComponentInstance(proxyComponent, componentInstance, dataTypes, false, false);
1346 interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
1347 toscaNodeType.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap);
1349 return toscaNodeType;
1352 private Either<ToscaNodeTemplate, ToscaError> convertComponentInstanceRequirements(Component component,
1353 ComponentInstance componentInstance,
1354 List<RequirementCapabilityRelDef> relations,
1355 ToscaNodeTemplate nodeTypeTemplate,
1356 Component originComponent,
1357 Map<String, Component> componentCache) {
1359 final List<RequirementCapabilityRelDef> requirementDefinitionList = filterRequirements(componentInstance,
1361 if (isNotEmpty(requirementDefinitionList)) {
1363 final List<Map<String, ToscaTemplateRequirement>> toscaRequirements = buildRequirements(component, componentInstance,
1364 requirementDefinitionList, originComponent, componentCache);
1365 if (!toscaRequirements.isEmpty()) {
1366 nodeTypeTemplate.setRequirements(toscaRequirements);
1368 } catch (final Exception e) {
1369 log.debug("Failed to convert component instance requirements for the component instance {}. ",
1370 componentInstance.getName(), e);
1371 return Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
1374 log.debug("Finished to convert requirements for the node type {} ", componentInstance.getName());
1375 return Either.left(nodeTypeTemplate);
1378 private List<Map<String, ToscaTemplateRequirement>> buildRequirements(final Component component,
1379 final ComponentInstance componentInstance,
1380 final List<RequirementCapabilityRelDef> filteredRelations,
1381 final Component originComponent,
1382 final Map<String, Component> componentCache)
1383 throws ToscaExportException {
1385 final List<Map<String, ToscaTemplateRequirement>> toscaRequirements = new ArrayList<>();
1386 for (RequirementCapabilityRelDef relationshipDefinition : filteredRelations) {
1387 final Map<String, ToscaTemplateRequirement> toscaTemplateRequirementMap =
1388 buildRequirement(componentInstance, originComponent, component.getComponentInstances(), relationshipDefinition, componentCache);
1389 toscaRequirements.add(toscaTemplateRequirementMap);
1392 return toscaRequirements;
1395 private List<RequirementCapabilityRelDef> filterRequirements(ComponentInstance componentInstance,
1396 List<RequirementCapabilityRelDef> relations) {
1397 return relations.stream()
1398 .filter(p -> componentInstance.getUniqueId().equals(p.getFromNode())).collect(Collectors.toList());
1401 private Map<String, ToscaTemplateRequirement> buildRequirement(final ComponentInstance fromInstance,
1402 final Component fromOriginComponent,
1403 final List<ComponentInstance> instancesList,
1404 final RequirementCapabilityRelDef relationshipDefinition,
1405 final Map<String, Component> componentCache)
1406 throws ToscaExportException {
1408 final Map<String, List<RequirementDefinition>> reqMap = fromOriginComponent.getRequirements();
1409 final CapabilityRequirementRelationship capabilityRequirementRelationship = relationshipDefinition
1410 .getRelationships().get(0);
1411 final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation();
1413 final ComponentInstance toInstance = instancesList.stream()
1414 .filter(i -> relationshipDefinition.getToNode().equals(i.getUniqueId()))
1415 .findFirst().orElse(null);
1416 if (toInstance == null) {
1417 final String errorMsg = String
1418 .format("Failed to find a relation from the node %s to the node %s", fromInstance.getName(),
1419 relationshipDefinition.getToNode());
1420 log.debug(errorMsg);
1421 throw new ToscaExportException(errorMsg);
1423 final Optional<RequirementDefinition> reqOpt =
1424 findRequirement(fromOriginComponent, reqMap, relationshipInfo, fromInstance.getUniqueId());
1425 if (reqOpt.isEmpty()) {
1426 final String errorMsg = String
1427 .format("Failed to find a requirement with uniqueId %s on a component with uniqueId %s",
1428 relationshipInfo.getRequirementUid(), fromOriginComponent.getUniqueId());
1429 log.debug(errorMsg);
1430 throw new ToscaExportException(errorMsg);
1432 final ComponentParametersView filter = new ComponentParametersView(true);
1433 filter.setIgnoreComponentInstances(false);
1434 filter.setIgnoreCapabilities(false);
1435 filter.setIgnoreGroups(false);
1436 final Either<Component, StorageOperationStatus> getOriginRes =
1437 toscaOperationFacade.getToscaElement(toInstance.getActualComponentUid(), filter);
1438 if (getOriginRes.isRight()) {
1439 final String errorMsg = String.format(
1440 "Failed to build substituted name for the requirement %s. "
1441 + "Failed to get an origin component with uniqueId %s",
1442 reqOpt.get().getName(), toInstance.getActualComponentUid());
1443 log.debug(errorMsg);
1444 throw new ToscaExportException(errorMsg);
1446 final Component toOriginComponent = getOriginRes.left().value();
1447 Optional<CapabilityDefinition> capOpt = toOriginComponent.getCapabilities().get(reqOpt.get().getCapability()).stream()
1448 .filter(c -> isCapabilityBelongToRelation(relationshipInfo, c)).findFirst();
1449 if (capOpt.isEmpty()) {
1450 capOpt = findCapability(relationshipInfo, toOriginComponent, fromOriginComponent, reqOpt.get());
1451 if (capOpt.isEmpty()) {
1452 final String errorMsg = String
1453 .format("Failed to find a capability with name %s on a component with uniqueId %s",
1454 relationshipInfo.getCapability(), fromOriginComponent.getUniqueId());
1455 log.debug(errorMsg);
1456 throw new ToscaExportException(errorMsg);
1459 return buildRequirement(fromOriginComponent, toOriginComponent, capOpt.get(), reqOpt.get(),
1460 capabilityRequirementRelationship, toInstance, componentCache);
1463 private boolean isCapabilityBelongToRelation(RelationshipInfo reqAndRelationshipPair,
1464 CapabilityDefinition capability) {
1465 return capability.getName().equals(reqAndRelationshipPair.getCapability()) && (capability.getOwnerId() != null
1466 && capability.getOwnerId().equals(reqAndRelationshipPair.getCapabilityOwnerId()));
1469 private Optional<CapabilityDefinition> findCapability(RelationshipInfo reqAndRelationshipPair,
1470 Component toOriginComponent, Component fromOriginComponent,
1471 RequirementDefinition requirement) {
1472 Optional<CapabilityDefinition> cap = toOriginComponent.getCapabilities().get(requirement.getCapability())
1473 .stream().filter(c -> c.getType().equals(requirement.getCapability())).findFirst();
1474 if (!cap.isPresent()) {
1475 log.debug("Failed to find a capability with name {} on a component with uniqueId {}",
1476 reqAndRelationshipPair.getCapability(), fromOriginComponent.getUniqueId());
1481 private Map<String, ToscaTemplateRequirement> buildRequirement(final Component fromOriginComponent,
1482 final Component toOriginComponent,
1483 final CapabilityDefinition capability,
1484 final RequirementDefinition requirement,
1485 final CapabilityRequirementRelationship capabilityRequirementRelationship,
1486 final ComponentInstance toInstance,
1487 final Map<String, Component> componentCache)
1488 throws ToscaExportException {
1490 List<String> reducedPath = capability.getPath();
1491 if (capability.getOwnerId() != null) {
1492 reducedPath = capabilityRequirementConverter
1493 .getReducedPathByOwner(capability.getPath(), capability.getOwnerId());
1495 final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation();
1496 final Either<String, Boolean> capabilityNameEither = capabilityRequirementConverter.buildSubstitutedName(componentCache,
1497 toOriginComponent, reducedPath, relationshipInfo.getCapability(), capability.getPreviousName(), capability.getExternalName());
1498 if (capabilityNameEither.isRight()) {
1499 final String errorMsg = String.format(
1500 "Failed to build a substituted capability name for the capability with name %s on a component with uniqueId %s",
1501 capabilityRequirementRelationship.getCapability(), toOriginComponent.getUniqueId());
1504 throw new ToscaExportException(errorMsg);
1506 final Either<String, Boolean> requirementNameEither = capabilityRequirementConverter
1507 .buildSubstitutedName(componentCache, fromOriginComponent,
1508 requirement.getPath(), relationshipInfo.getRequirement(), requirement.getPreviousName(), requirement.getExternalName());
1509 if (requirementNameEither.isRight()) {
1510 final String errorMsg = String.format("Failed to build a substituted requirement name for the requirement "
1511 + "with name %s on a component with uniqueId %s",
1512 capabilityRequirementRelationship.getRequirement(), fromOriginComponent.getUniqueId());
1513 log.debug(errorMsg);
1514 throw new ToscaExportException(errorMsg);
1516 final ToscaTemplateRequirement toscaRequirement = new ToscaTemplateRequirement();
1517 final Map<String, ToscaTemplateRequirement> toscaReqMap = new HashMap<>();
1518 toscaRequirement.setNode(toInstance.getName());
1519 toscaRequirement.setCapability(capabilityNameEither.left().value());
1520 if (isNotEmpty(capabilityRequirementRelationship.getOperations())) {
1521 toscaRequirement.setRelationship(new ToscaRelationshipBuilder().from(capabilityRequirementRelationship));
1523 toscaReqMap.put(requirementNameEither.left().value(), toscaRequirement);
1527 private Optional<RequirementDefinition> findRequirement(Component fromOriginComponent,
1528 Map<String, List<RequirementDefinition>> reqMap,
1529 RelationshipInfo reqAndRelationshipPair,
1530 String fromInstanceId) {
1531 for (List<RequirementDefinition> reqList : reqMap.values()) {
1532 Optional<RequirementDefinition> reqOpt = reqList.stream().filter(
1533 r -> isRequirementBelongToRelation(fromOriginComponent, reqAndRelationshipPair, r, fromInstanceId))
1535 if (reqOpt.isPresent()) {
1539 return Optional.empty();
1543 * Allows detecting the requirement belonging to the received relationship The detection logic is: A requirement belongs to a relationship IF
1544 * 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
1545 * requirement equals to requirementOwnerId of the relation OR uniqueId of toInstance equals to capabilityOwnerId of the relation
1547 private boolean isRequirementBelongToRelation(Component originComponent, RelationshipInfo reqAndRelationshipPair,
1548 RequirementDefinition requirement, String fromInstanceId) {
1549 if (!StringUtils.equals(requirement.getName(), reqAndRelationshipPair.getRequirement())) {
1550 log.debug("Failed to find a requirement with name {} and reqAndRelationshipPair {}", requirement.getName(),
1551 reqAndRelationshipPair.getRequirement());
1554 return ModelConverter.isAtomicComponent(originComponent) || isRequirementBelongToOwner(reqAndRelationshipPair, requirement, fromInstanceId,
1558 private boolean isRequirementBelongToOwner(RelationshipInfo reqAndRelationshipPair, RequirementDefinition requirement, String fromInstanceId,
1559 Component originComponent) {
1560 return StringUtils.equals(requirement.getOwnerId(), reqAndRelationshipPair.getRequirementOwnerId()) || (
1561 isCvfc(originComponent) && StringUtils.equals(fromInstanceId, reqAndRelationshipPair.getRequirementOwnerId()) || StringUtils
1562 .equals(requirement.getOwnerId(), originComponent.getUniqueId()));
1565 private boolean isCvfc(Component component) {
1566 return component.getComponentType() == ComponentTypeEnum.RESOURCE && ((Resource) component).getResourceType() == ResourceTypeEnum.CVFC;
1569 private Either<Map<String, String[]>, ToscaError> convertSubstitutionMappingCapabilities(final Component component,
1570 final Map<String, Component> componentCache) {
1571 Either<Map<String, String[]>, ToscaError> toscaCapabilitiesRes =
1572 capabilityRequirementConverter.convertSubstitutionMappingCapabilities(componentCache, component);
1573 if (toscaCapabilitiesRes.isRight()) {
1574 log.debug("Failed convert capabilities for the component {}. ", component.getName());
1575 return Either.right(toscaCapabilitiesRes.right().value());
1577 if (isNotEmpty(toscaCapabilitiesRes.left().value())) {
1578 log.debug("Finish convert capabilities for the component {}. ", component.getName());
1579 return Either.left(toscaCapabilitiesRes.left().value());
1581 log.debug("Finished to convert capabilities for the component {}. ", component.getName());
1583 return Either.left(Collections.emptyMap());
1586 private Either<ToscaNodeType, ToscaError> convertCapabilities(Map<String, Component> componentsCache, Component component, ToscaNodeType nodeType,
1587 Map<String, DataTypeDefinition> dataTypes) {
1588 Map<String, ToscaCapability> toscaCapabilities = capabilityRequirementConverter.convertCapabilities(componentsCache, component, dataTypes);
1589 if (!toscaCapabilities.isEmpty()) {
1590 nodeType.setCapabilities(toscaCapabilities);
1592 log.debug("Finish convert Capabilities for node type");
1593 return Either.left(nodeType);
1596 private Map<String, ToscaTemplateArtifact> convertToNodeTemplateArtifacts(Map<String, ToscaArtifactDataDefinition> artifacts) {
1597 if (artifacts == null) {
1600 Map<String, ToscaTemplateArtifact> arts = new HashMap<>();
1601 for (Map.Entry<String, ToscaArtifactDataDefinition> entry : artifacts.entrySet()) {
1602 ToscaTemplateArtifact artifact = new ToscaTemplateArtifact();
1603 artifact.setFile(entry.getValue().getFile());
1604 artifact.setType(entry.getValue().getType());
1605 artifact.setProperties(entry.getValue().getProperties());
1606 arts.put(entry.getKey(), artifact);
1611 private NodeFilter convertToNodeTemplateNodeFilterComponent(CINodeFilterDataDefinition inNodeFilter) {
1612 if (inNodeFilter == null) {
1615 NodeFilter nodeFilter = new NodeFilter();
1616 ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities = inNodeFilter.getCapabilities();
1617 ListDataDefinition<PropertyFilterDataDefinition> origProperties = inNodeFilter.getProperties();
1618 List<Map<String, CapabilityFilter>> capabilitiesCopy = new ArrayList<>();
1619 copyNodeFilterCapabilitiesTemplate(origCapabilities, capabilitiesCopy);
1620 if (CollectionUtils.isNotEmpty(capabilitiesCopy)) {
1621 nodeFilter.setCapabilities(capabilitiesCopy);
1623 final List<Map<String, List<Object>>> propertiesCopy = copyNodeFilterProperties(origProperties);
1624 if (CollectionUtils.isNotEmpty(propertiesCopy)) {
1625 nodeFilter.setProperties(propertiesCopy);
1627 nodeFilter.setTosca_id(cloneToscaId(inNodeFilter.getTosca_id()));
1628 nodeFilter = (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
1632 private NodeFilter convertToSubstitutionFilterComponent(final SubstitutionFilterDataDefinition substitutionFilterDataDefinition) {
1633 if (substitutionFilterDataDefinition == null) {
1636 NodeFilter nodeFilter = new NodeFilter();
1637 final List<Map<String, List<Object>>> propertiesCopy = copySubstitutionPropertiesFilter(substitutionFilterDataDefinition.getProperties());
1638 if (!propertiesCopy.isEmpty()) {
1639 nodeFilter.setProperties(propertiesCopy);
1641 nodeFilter.setTosca_id(cloneToscaId(substitutionFilterDataDefinition.getTosca_id()));
1642 return (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
1645 private Object cloneToscaId(Object toscaId) {
1646 return Objects.isNull(toscaId) ? null : cloneObjectFromYml(toscaId, toscaId.getClass());
1649 private Object cloneObjectFromYml(Object objToClone, Class classOfObj) {
1650 String objectAsYml = yamlUtil.objectToYaml(objToClone);
1651 return yamlUtil.yamlToObject(objectAsYml, classOfObj);
1654 private void copyNodeFilterCapabilitiesTemplate(ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities,
1655 List<Map<String, CapabilityFilter>> capabilitiesCopy) {
1656 if (origCapabilities == null || origCapabilities.getListToscaDataDefinition() == null || origCapabilities.getListToscaDataDefinition()
1660 for (RequirementNodeFilterCapabilityDataDefinition capability : origCapabilities.getListToscaDataDefinition()) {
1661 Map<String, CapabilityFilter> capabilityFilterCopyMap = new HashMap<>();
1662 final var capabilityFilter = new CapabilityFilter();
1663 capabilityFilter.setProperties(copyNodeFilterProperties(capability.getProperties()));
1664 capabilityFilterCopyMap.put(capability.getName(), capabilityFilter);
1665 capabilitiesCopy.add(capabilityFilterCopyMap);
1669 private List<Map<String, List<Object>>> copyNodeFilterProperties(final ListDataDefinition<PropertyFilterDataDefinition> origProperties) {
1670 if (origProperties == null || origProperties.getListToscaDataDefinition() == null || origProperties.isEmpty()) {
1671 return Collections.emptyList();
1673 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1674 Map<String, List<Object>> propertyFilterDefinitionMap = new HashMap<>();
1675 for (final PropertyFilterDataDefinition propertyFilter : origProperties.getListToscaDataDefinition()) {
1676 final String propertyName = propertyFilter.getName();
1677 for (final PropertyFilterConstraintDataDefinition filterConstraint : propertyFilter.getConstraints()) {
1678 propertyFilterDefinitionMap.compute(propertyName, (propertyName1, constraints) -> {
1679 if (constraints == null) {
1680 constraints = new ArrayList<>();
1682 constraints.add(buildNodeFilterValue(filterConstraint));
1687 propertyFilterDefinitionMap.entrySet().stream()
1688 .map(entry -> Map.of(entry.getKey(), entry.getValue()))
1689 .forEach(propertiesCopy::add);
1690 return propertiesCopy;
1693 private List<Map<String, List<Object>>> copySubstitutionPropertiesFilter(
1694 final ListDataDefinition<SubstitutionFilterPropertyDataDefinition> origProperties) {
1696 if (origProperties == null || origProperties.getListToscaDataDefinition() == null || origProperties.isEmpty()) {
1697 return Collections.emptyList();
1699 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1700 Map<String, List<Object>> propertyFilterDefinitionMap = new HashMap<>();
1701 for (final SubstitutionFilterPropertyDataDefinition propertyFilter : origProperties.getListToscaDataDefinition()) {
1702 final String propertyName = propertyFilter.getName();
1703 for (final PropertyFilterConstraintDataDefinition filterConstraint : propertyFilter.getConstraints()) {
1704 propertyFilterDefinitionMap.compute(propertyName, (propertyName1, constraints) -> {
1705 if (constraints == null) {
1706 constraints = new ArrayList<>();
1708 constraints.add(buildNodeFilterValue(filterConstraint));
1713 propertyFilterDefinitionMap.entrySet().stream()
1714 .map(entry -> Map.of(entry.getKey(), entry.getValue()))
1715 .forEach(propertiesCopy::add);
1716 return propertiesCopy;
1719 private static Object buildNodeFilterValue(final PropertyFilterConstraintDataDefinition filterConstraint) {
1720 if (filterConstraint.getValue() instanceof ToscaFunction) {
1721 return Map.of(filterConstraint.getOperator().getType(), ((ToscaFunction) filterConstraint.getValue()).getJsonObjectValue());
1723 return Map.of(filterConstraint.getOperator().getType(), filterConstraint.getValue());
1727 private Map<String, String[]> buildSubstitutionMappingPropertyMapping(final Component component) {
1728 if (component == null || CollectionUtils.isEmpty(component.getInputs())) {
1729 return Collections.emptyMap();
1731 return component.getInputs().stream().filter(InputDefinition::isMappedToComponentProperty).map(PropertyDataDefinition::getName)
1732 .collect(Collectors.toMap(inputName -> inputName, inputName -> new String[]{inputName}, (inputName1, inputName2) -> inputName1));
1735 private Map<String, String[]> buildSubstitutionMappingAttributesMapping(final Component component) {
1736 if (component == null || CollectionUtils.isEmpty(component.getOutputs())) {
1737 return Collections.emptyMap();
1739 return component.getOutputs().stream().map(AttributeDataDefinition::getName)
1740 .collect(Collectors.toMap(outputName -> outputName, outputName -> new String[]{outputName}, (outputName1, outputName2) -> outputName1));
1743 private Optional<Map<String, ToscaProperty>> getProxyNodeTypeProperties(Component proxyComponent, Map<String, DataTypeDefinition> dataTypes) {
1744 if (Objects.isNull(proxyComponent)) {
1745 return Optional.empty();
1747 final var proxyProperties = convertInputsToProperties(dataTypes, proxyComponent.getInputs(), proxyComponent.getUniqueId());
1748 if (CollectionUtils.isNotEmpty(proxyComponent.getProperties())) {
1749 proxyProperties.putAll(proxyComponent.getProperties().stream()
1750 .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, proxyComponent.getInputs())).collect(Collectors
1751 .toMap(PropertyDataDefinition::getName,
1752 property -> propertyConvertor.convertProperty(dataTypes, property, PropertyType.PROPERTY))));
1754 return MapUtils.isNotEmpty(proxyProperties) ? Optional.of(proxyProperties) : Optional.empty();
1757 private Map<String, ToscaProperty> convertInputsToProperties(Map<String, DataTypeDefinition> dataTypes, List<InputDefinition> componentInputs,
1758 String componentUniqueId) {
1759 if (CollectionUtils.isEmpty(componentInputs)) {
1760 return new HashMap<>();
1762 return componentInputs.stream().filter(input -> componentUniqueId.equals(input.getInstanceUniqueId()))
1763 .collect(Collectors.toMap(InputDefinition::getName, i -> propertyConvertor.convertProperty(dataTypes, i, PropertyType.INPUT)));
1766 private Optional<Map<String, Object>> getProxyNodeTypeInterfaces(Component proxyComponent, Map<String, DataTypeDefinition> dataTypes) {
1767 if (Objects.isNull(proxyComponent) || MapUtils.isEmpty(proxyComponent.getInterfaces())) {
1768 return Optional.empty();
1770 Map<String, InterfaceDefinition> proxyComponentInterfaces = proxyComponent.getInterfaces();
1771 //Unset artifact path for operation implementation for proxy node types as for operations with artifacts it is
1773 // always available in the proxy node template
1774 removeOperationImplementationForProxyNodeType(proxyComponentInterfaces);
1776 .ofNullable(interfacesOperationsConverter.getInterfacesMap(proxyComponent, null, proxyComponentInterfaces, dataTypes, false, false));
1779 private static class CustomRepresenter extends Representer {
1781 CustomRepresenter() {
1783 this.representers.put(ToscaPropertyAssignment.class, new RepresentToscaPropertyAssignment());
1784 this.representers.put(ToscaAttribute.class, new RepresentToscaAttribute());
1785 // null representer is exceptional and it is stored as an instance
1788 this.nullRepresenter = new RepresentNull();
1791 public boolean validateGetInputValue(final Object valueObj) {
1792 if (!(valueObj instanceof List) && !(valueObj instanceof String)) {
1795 if (valueObj instanceof List) {
1796 return ((List) valueObj).size() > 1;
1801 public boolean validateGetPropertyOrAttributeValue(final Object valueObj) {
1802 if (valueObj instanceof List) {
1803 return ((List) valueObj).size() > 1;
1809 protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue, Tag customTag) {
1810 if (propertyValue == null) {
1813 // skip not relevant for Tosca property
1814 if ("dependencies".equals(property.getName())) {
1817 if (javaBean instanceof ToscaRelationshipTemplate && "name".equals(property.getName())) {
1820 removeDefaultP(propertyValue);
1821 NodeTuple defaultNode = super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
1822 if (javaBean instanceof ToscaTopolgyTemplate && "relationshipTemplates".equals(property.getName())) {
1823 return new NodeTuple(representData("relationship_templates"), defaultNode.getValueNode());
1825 return "_defaultp_".equals(property.getName()) ? new NodeTuple(representData("default"), defaultNode.getValueNode()) : defaultNode;
1828 private void removeDefaultP(final Object propertyValue) {
1829 if (propertyValue instanceof Map) {
1830 final Map mapPropertyValue = ((Map) propertyValue);
1831 final Iterator<Entry> iter = mapPropertyValue.entrySet().iterator();
1832 Object defaultValue = null;
1833 while (iter.hasNext()) {
1834 final Map.Entry entry = iter.next();
1835 if ("_defaultp_".equals(entry.getKey())) {
1836 defaultValue = entry.getValue();
1838 } else if (entry.getValue() instanceof Map) {
1839 removeDefaultP(entry.getValue());
1842 if (defaultValue != null) {
1843 mapPropertyValue.putIfAbsent("default", defaultValue);
1849 protected MappingNode representJavaBean(Set<Property> properties, Object javaBean) {
1850 // remove the bean type from the output yaml (!! ...)
1851 if (!classTags.containsKey(javaBean.getClass())) {
1852 addClassTag(javaBean.getClass(), Tag.MAP);
1854 return super.representJavaBean(properties, javaBean);
1857 private class RepresentToscaAttribute implements Represent {
1860 public Node representData(Object data) {
1861 final ToscaAttribute toscaAttribute = (ToscaAttribute) data;
1862 return represent(toscaAttribute.asToscaMap());
1866 private class RepresentToscaPropertyAssignment implements Represent {
1868 public Node representData(Object data) {
1869 final ToscaPropertyAssignment toscaOperationAssignment = (ToscaPropertyAssignment) data;
1870 if (toscaOperationAssignment.getValue() instanceof String) {
1871 final String stringValue = (String) toscaOperationAssignment.getValue();
1872 if (isPropertyOrAttributeFunction(stringValue)) {
1873 return representGetAttribute(stringValue);
1875 return representScalar(Tag.STR, stringValue);
1877 return represent(null);
1880 public Node representGetAttribute(final String getAttributeFunction) {
1881 return represent(new Yaml().load(getAttributeFunction));
1884 public boolean isPropertyOrAttributeFunction(final String value) {
1886 final Yaml yaml = new Yaml();
1887 final Object yamlObj = yaml.load(value);
1888 if (!(yamlObj instanceof Map)) {
1891 final Map<String, Object> getAttributeMap = (Map) yamlObj;
1892 if (getAttributeMap.size() != 1) {
1895 final List<String> functionList = Arrays
1896 .asList(GET_ATTRIBUTE.getFunctionName(), GET_INPUT.getFunctionName(), GET_PROPERTY.getFunctionName());
1897 final Optional<String> function = getAttributeMap.keySet().stream()
1898 .filter(key -> functionList.stream().anyMatch(function1 -> function1.equals(key))).findFirst();
1899 if (function.isEmpty()) {
1902 final String functionName = function.get();
1903 final Object getAttributeValueObj = getAttributeMap.get(functionName);
1904 if (GET_INPUT.getFunctionName().equals(functionName)) {
1905 return validateGetInputValue(getAttributeValueObj);
1907 return validateGetPropertyOrAttributeValue(getAttributeValueObj);
1909 } catch (final Exception ignored) {
1915 private class RepresentNull implements Represent {
1918 public Node representData(Object data) {
1919 // possible values are here http://yaml.org/type/null.html
1920 return representScalar(Tag.NULL, "");
1925 private static class UnsortedPropertyUtils extends PropertyUtils {
1928 protected Set<Property> createPropertySet(Class type, BeanAccess bAccess) {
1929 Collection<Property> fields = getPropertiesMap(type, BeanAccess.FIELD).values();
1930 return new LinkedHashSet<>(fields);
1934 private Configuration getConfiguration() {
1935 return ConfigurationManager.getConfigurationManager().getConfiguration();