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.RequirementNodeFilterCapabilityDataDefinition;
75 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition;
76 import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterPropertyDataDefinition;
77 import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition;
78 import org.openecomp.sdc.be.datatypes.elements.ToscaArtifactDataDefinition;
79 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
80 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
81 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
82 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
83 import org.openecomp.sdc.be.exception.ToscaExportException;
84 import org.openecomp.sdc.be.model.ArtifactDefinition;
85 import org.openecomp.sdc.be.model.AttributeDefinition;
86 import org.openecomp.sdc.be.model.CapabilityDefinition;
87 import org.openecomp.sdc.be.model.CapabilityRequirementRelationship;
88 import org.openecomp.sdc.be.model.Component;
89 import org.openecomp.sdc.be.model.ComponentInstance;
90 import org.openecomp.sdc.be.model.ComponentInstanceAttribute;
91 import org.openecomp.sdc.be.model.ComponentInstanceInput;
92 import org.openecomp.sdc.be.model.ComponentInstanceInterface;
93 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
94 import org.openecomp.sdc.be.model.ComponentParametersView;
95 import org.openecomp.sdc.be.model.DataTypeDefinition;
96 import org.openecomp.sdc.be.model.GroupInstance;
97 import org.openecomp.sdc.be.model.InputDefinition;
98 import org.openecomp.sdc.be.model.InterfaceDefinition;
99 import org.openecomp.sdc.be.model.PropertyDefinition;
100 import org.openecomp.sdc.be.model.RelationshipInfo;
101 import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
102 import org.openecomp.sdc.be.model.RequirementDefinition;
103 import org.openecomp.sdc.be.model.Resource;
104 import org.openecomp.sdc.be.model.Service;
105 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
106 import org.openecomp.sdc.be.model.category.CategoryDefinition;
107 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
108 import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter;
109 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
110 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
111 import org.openecomp.sdc.be.model.operations.impl.ModelOperation;
112 import org.openecomp.sdc.be.model.tosca.converters.ToscaMapValueConverter;
113 import org.openecomp.sdc.be.tosca.PropertyConvertor.PropertyType;
114 import org.openecomp.sdc.be.tosca.builder.ToscaRelationshipBuilder;
115 import org.openecomp.sdc.be.tosca.exception.ToscaConversionException;
116 import org.openecomp.sdc.be.tosca.model.CapabilityFilter;
117 import org.openecomp.sdc.be.tosca.model.NodeFilter;
118 import org.openecomp.sdc.be.tosca.model.SubstitutionMapping;
119 import org.openecomp.sdc.be.tosca.model.ToscaAttribute;
120 import org.openecomp.sdc.be.tosca.model.ToscaCapability;
121 import org.openecomp.sdc.be.tosca.model.ToscaDataType;
122 import org.openecomp.sdc.be.tosca.model.ToscaGroupTemplate;
123 import org.openecomp.sdc.be.tosca.model.ToscaNodeTemplate;
124 import org.openecomp.sdc.be.tosca.model.ToscaNodeType;
125 import org.openecomp.sdc.be.tosca.model.ToscaPolicyTemplate;
126 import org.openecomp.sdc.be.tosca.model.ToscaProperty;
127 import org.openecomp.sdc.be.tosca.model.ToscaPropertyAssignment;
128 import org.openecomp.sdc.be.tosca.model.ToscaRelationshipTemplate;
129 import org.openecomp.sdc.be.tosca.model.ToscaRequirement;
130 import org.openecomp.sdc.be.tosca.model.ToscaTemplate;
131 import org.openecomp.sdc.be.tosca.model.ToscaTemplateArtifact;
132 import org.openecomp.sdc.be.tosca.model.ToscaTemplateRequirement;
133 import org.openecomp.sdc.be.tosca.model.ToscaTopolgyTemplate;
134 import org.openecomp.sdc.be.tosca.utils.ForwardingPathToscaUtil;
135 import org.openecomp.sdc.be.tosca.utils.InputConverter;
136 import org.openecomp.sdc.be.tosca.utils.OutputConverter;
137 import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
138 import org.openecomp.sdc.common.log.wrappers.Logger;
139 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
140 import org.springframework.beans.factory.annotation.Autowired;
141 import org.yaml.snakeyaml.DumperOptions;
142 import org.yaml.snakeyaml.DumperOptions.FlowStyle;
143 import org.yaml.snakeyaml.Yaml;
144 import org.yaml.snakeyaml.introspector.BeanAccess;
145 import org.yaml.snakeyaml.introspector.Property;
146 import org.yaml.snakeyaml.introspector.PropertyUtils;
147 import org.yaml.snakeyaml.nodes.MappingNode;
148 import org.yaml.snakeyaml.nodes.Node;
149 import org.yaml.snakeyaml.nodes.NodeTuple;
150 import org.yaml.snakeyaml.nodes.Tag;
151 import org.yaml.snakeyaml.representer.Represent;
152 import org.yaml.snakeyaml.representer.Representer;
154 @org.springframework.stereotype.Component("tosca-export-handler")
155 public class ToscaExportHandler {
157 public static final String ASSET_TOSCA_TEMPLATE = "assettoscatemplate";
158 private static final Logger log = Logger.getLogger(ToscaExportHandler.class);
159 private static final String INVARIANT_UUID = "invariantUUID";
160 private static final String TOSCA_VERSION = "tosca_simple_yaml_1_3";
161 private static final String SERVICE_NODE_TYPE_PREFIX = "org.openecomp.service.";
162 private static final String IMPORTS_FILE_KEY = "file";
163 private static final String TOSCA_INTERFACE_NAME = "-interface.yml";
164 private static final String FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION = "convertToToscaTemplate - failed to get Default Imports section from configuration";
165 private static final String NOT_SUPPORTED_COMPONENT_TYPE = "Not supported component type {}";
166 private static final String NATIVE_ROOT = "tosca.nodes.Root";
167 private static final List<String> EXCLUDED_CATEGORY_SPECIFIC_METADATA = List
168 .of("Service Function", "Service Role", "Naming Policy", "Service Type");
169 private static final YamlUtil yamlUtil = new YamlUtil();
170 private final ApplicationDataTypeCache applicationDataTypeCache;
171 private final ToscaOperationFacade toscaOperationFacade;
172 private final CapabilityRequirementConverter capabilityRequirementConverter;
173 private final PolicyExportParser policyExportParser;
174 private final GroupExportParser groupExportParser;
175 private final PropertyConvertor propertyConvertor;
176 private final AttributeConverter attributeConverter;
177 private final InputConverter inputConverter;
178 private final OutputConverter outputConverter;
179 private final InterfaceLifecycleOperation interfaceLifecycleOperation;
180 private final InterfacesOperationsConverter interfacesOperationsConverter;
181 private final ModelOperation modelOperation;
184 public ToscaExportHandler(final ApplicationDataTypeCache applicationDataTypeCache,
185 final ToscaOperationFacade toscaOperationFacade,
186 final CapabilityRequirementConverter capabilityRequirementConverter,
187 final PolicyExportParser policyExportParser,
188 final GroupExportParser groupExportParser,
189 final PropertyConvertor propertyConvertor,
190 final AttributeConverter attributeConverter,
191 final InputConverter inputConverter,
192 final OutputConverter outputConverter,
193 final InterfaceLifecycleOperation interfaceLifecycleOperation,
194 final InterfacesOperationsConverter interfacesOperationsConverter,
195 final ModelOperation modelOperation) {
196 this.applicationDataTypeCache = applicationDataTypeCache;
197 this.toscaOperationFacade = toscaOperationFacade;
198 this.capabilityRequirementConverter = capabilityRequirementConverter;
199 this.policyExportParser = policyExportParser;
200 this.groupExportParser = groupExportParser;
201 this.propertyConvertor = propertyConvertor;
202 this.attributeConverter = attributeConverter;
203 this.inputConverter = inputConverter;
204 this.outputConverter = outputConverter;
205 this.interfaceLifecycleOperation = interfaceLifecycleOperation;
206 this.interfacesOperationsConverter = interfacesOperationsConverter;
207 this.modelOperation = modelOperation;
210 public static String getInterfaceFilename(String artifactName) {
211 return artifactName.substring(0, artifactName.lastIndexOf('.')) + TOSCA_INTERFACE_NAME;
214 private static void removeOperationImplementationForProxyNodeType(Map<String, InterfaceDefinition> proxyComponentInterfaces) {
215 if (MapUtils.isEmpty(proxyComponentInterfaces)) {
218 proxyComponentInterfaces.values().stream().map(InterfaceDataDefinition::getOperations).filter(MapUtils::isNotEmpty)
219 .forEach(operations -> operations.values().forEach(operation -> operation.setImplementation(null)));
222 public Either<ToscaRepresentation, ToscaError> exportComponent(Component component) {
223 return convertToToscaTemplate(component).left().map(this::createToscaRepresentation);
226 public Either<ToscaRepresentation, ToscaError> exportComponentInterface(final Component component, final boolean isAssociatedComponent) {
227 final List<Map<String, Map<String, String>>> imports = new ArrayList<>(getDefaultToscaImports(component.getModel()));
228 if (CollectionUtils.isEmpty(imports)) {
229 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
230 return Either.right(ToscaError.GENERAL_ERROR);
232 List<Triple<String, String, Component>> dependencies = new ArrayList<>();
233 if (component.getDerivedFromGenericType() != null && !component.getDerivedFromGenericType()
234 .startsWith("org.openecomp.resource.abstract.nodes.")) {
235 final Either<Component, StorageOperationStatus> baseType = toscaOperationFacade
236 .getByToscaResourceNameAndVersion(component.getDerivedFromGenericType(), component.getDerivedFromGenericVersion(),
237 component.getModel());
238 if (baseType.isLeft() && baseType.left().value() != null) {
239 addDependencies(imports, dependencies, baseType.left().value());
241 log.debug("Failed to fetch derived from type {}", component.getDerivedFromGenericType());
245 String toscaVersion = null;
246 if (component instanceof Resource) {
247 toscaVersion = ((Resource) component).getToscaVersion();
249 ToscaTemplate toscaTemplate = new ToscaTemplate(toscaVersion != null ? toscaVersion : TOSCA_VERSION);
250 toscaTemplate.setImports(imports);
251 final Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
252 final Either<ToscaTemplate, ToscaError> toscaTemplateRes = convertInterfaceNodeType(new HashMap<>(), component, toscaTemplate, nodeTypes,
253 isAssociatedComponent);
254 if (toscaTemplateRes.isRight()) {
255 return Either.right(toscaTemplateRes.right().value());
257 toscaTemplate = toscaTemplateRes.left().value();
258 toscaTemplate.setDependencies(dependencies);
259 ToscaRepresentation toscaRepresentation = this.createToscaRepresentation(toscaTemplate);
260 return Either.left(toscaRepresentation);
263 private ToscaRepresentation createToscaRepresentation(ToscaTemplate toscaTemplate) {
264 CustomRepresenter representer = new CustomRepresenter();
265 DumperOptions options = new DumperOptions();
266 options.setAllowReadOnlyProperties(false);
267 options.setPrettyFlow(true);
268 options.setDefaultFlowStyle(FlowStyle.FLOW);
269 options.setCanonical(false);
270 representer.addClassTag(toscaTemplate.getClass(), Tag.MAP);
271 representer.setPropertyUtils(new UnsortedPropertyUtils());
272 Yaml yaml = new Yaml(representer, options);
273 String yamlAsString = yaml.dumpAsMap(toscaTemplate);
274 StringBuilder sb = new StringBuilder();
275 sb.append(getConfiguration().getHeatEnvArtifactHeader());
276 sb.append(yamlAsString);
277 sb.append(getConfiguration().getHeatEnvArtifactFooter());
278 return ToscaRepresentation.make(sb.toString().getBytes(), toscaTemplate);
281 public Either<ToscaTemplate, ToscaError> getDependencies(Component component) {
282 ToscaTemplate toscaTemplate = new ToscaTemplate(null);
283 Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports = fillImports(component, toscaTemplate);
284 if (fillImports.isRight()) {
285 return Either.right(fillImports.right().value());
287 return Either.left(fillImports.left().value().left);
290 public Either<ToscaTemplate, ToscaError> convertToToscaTemplate(final Component component) {
291 final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImports(component.getModel());
292 if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
293 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
294 return Either.right(ToscaError.GENERAL_ERROR);
296 log.trace("start tosca export for {}", component.getUniqueId());
297 String toscaVersion = null;
298 if (component instanceof Resource) {
299 toscaVersion = ((Resource) component).getToscaVersion();
301 final ToscaTemplate toscaTemplate = new ToscaTemplate(toscaVersion != null ? toscaVersion : TOSCA_VERSION);
302 toscaTemplate.setMetadata(convertMetadata(component));
303 toscaTemplate.setImports(new ArrayList<>(defaultToscaImportConfig));
304 final Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
305 if (ModelConverter.isAtomicComponent(component)) {
306 log.trace("convert component as node type");
307 return convertNodeType(new HashMap<>(), component, toscaTemplate, nodeTypes);
309 log.trace("convert component as topology template");
310 return convertToscaTemplate(component, toscaTemplate);
314 private List<Map<String, Map<String, String>>> getDefaultToscaImports(final String modelId) {
315 if (modelId == null) {
316 return getDefaultToscaImportConfig();
319 final List<ToscaImportByModel> allModelImports = modelOperation.findAllModelImports(modelId, true);
320 final List<Map<String, Map<String, String>>> importList = new ArrayList<>();
321 final Set<Path> addedPathList = new HashSet<>();
322 for (final ToscaImportByModel toscaImportByModel : allModelImports) {
323 var importPath = Path.of(toscaImportByModel.getFullPath());
324 if (addedPathList.contains(importPath)) {
325 importPath = ToscaDefaultImportHelper.addModelAsFilePrefix(importPath, toscaImportByModel.getModelId());
327 final String fileName = FilenameUtils.getBaseName(importPath.toString());
328 importList.add(Map.of(fileName, Map.of("file", importPath.toString())));
329 addedPathList.add(importPath);
334 private Either<ToscaTemplate, ToscaError> convertToscaTemplate(Component component, ToscaTemplate toscaNode) {
335 Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> importsRes = fillImports(component, toscaNode);
336 if (importsRes.isRight()) {
337 return Either.right(importsRes.right().value());
339 toscaNode = importsRes.left().value().left;
340 Map<String, Component> componentCache = importsRes.left().value().right;
341 Either<Map<String, ToscaNodeType>, ToscaError> nodeTypesMapEither = createProxyNodeTypes(componentCache, component);
342 if (nodeTypesMapEither.isRight()) {
343 log.debug("Failed to fetch normative service proxy resource by tosca name, error {}", nodeTypesMapEither.right().value());
344 return Either.right(nodeTypesMapEither.right().value());
346 Map<String, ToscaNodeType> nodeTypesMap = nodeTypesMapEither.left().value();
347 if (nodeTypesMap != null && !nodeTypesMap.isEmpty()) {
348 toscaNode.setNode_types(nodeTypesMap);
350 createServiceSubstitutionNodeTypes(componentCache, component, toscaNode);
351 Either<Map<String, Object>, ToscaError> proxyInterfaceTypesEither = createProxyInterfaceTypes(component);
352 if (proxyInterfaceTypesEither.isRight()) {
353 log.debug("Failed to populate service proxy local interface types in tosca, error {}", nodeTypesMapEither.right().value());
354 return Either.right(proxyInterfaceTypesEither.right().value());
356 Map<String, Object> proxyInterfaceTypes = proxyInterfaceTypesEither.left().value();
357 if (MapUtils.isNotEmpty(proxyInterfaceTypes)) {
358 toscaNode.setInterface_types(proxyInterfaceTypes);
360 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = applicationDataTypeCache.getAll(component.getModel());
361 if (dataTypesEither.isRight()) {
362 log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
363 return Either.right(ToscaError.GENERAL_ERROR);
365 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
366 ToscaTopolgyTemplate topologyTemplate = new ToscaTopolgyTemplate();
367 List<InputDefinition> inputDef = component.getInputs();
368 Map<String, ToscaProperty> inputs = inputConverter.convertInputs(inputDef, dataTypes);
369 if (!inputs.isEmpty()) {
370 topologyTemplate.setInputs(inputs);
372 final Map<String, ToscaProperty> outputs;
374 outputs = outputConverter.convert(component.getOutputs(), dataTypes);
375 } catch (final ToscaConversionException e) {
376 log.error(EcompLoggerErrorCode.SCHEMA_ERROR, ToscaExportHandler.class.getName(),
377 "Could not parse component '{}' outputs. Component unique id '{}'.", component.getName(), component.getUniqueId(), e);
378 return Either.right(ToscaError.GENERAL_ERROR);
380 if (!outputs.isEmpty()) {
381 topologyTemplate.setOutputs(outputs);
383 if (CollectionUtils.isNotEmpty(component.getComponentInstances())) {
384 final Either<Map<String, ToscaNodeTemplate>, ToscaError> nodeTemplates =
385 convertNodeTemplates(component, componentCache, dataTypes, topologyTemplate);
386 if (nodeTemplates.isRight()) {
387 return Either.right(nodeTemplates.right().value());
389 log.debug("node templates converted");
390 topologyTemplate.setNode_templates(nodeTemplates.left().value());
392 final Map<String, ToscaRelationshipTemplate> relationshipTemplatesMap = new ToscaExportRelationshipTemplatesHandler()
393 .createFrom(topologyTemplate.getNode_templates());
394 if (!relationshipTemplatesMap.isEmpty()) {
395 topologyTemplate.setRelationshipTemplates(relationshipTemplatesMap);
397 addGroupsToTopologyTemplate(component, topologyTemplate);
399 addPoliciesToTopologyTemplate(component, topologyTemplate);
400 } catch (SdcResourceNotFoundException e) {
401 log.debug("Fail to add policies to topology template:", e);
402 return Either.right(ToscaError.GENERAL_ERROR);
405 createSubstitutionMapping(component, componentCache).ifPresent(topologyTemplate::setSubstitution_mappings);
406 } catch (final ToscaExportException e) {
407 log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, ToscaExportHandler.class.getName(), e.getMessage());
408 return Either.right(e.getToscaError());
410 if (!topologyTemplate.isEmpty()) {
411 toscaNode.setTopology_template(topologyTemplate);
413 return Either.left(toscaNode);
416 private Either<String, ToscaError> createComponentToscaName(final Component component) {
417 switch (component.getComponentType()) {
419 final ResourceMetadataDataDefinition resourceMetadata =
420 (ResourceMetadataDataDefinition) component.getComponentMetadataDefinition().getMetadataDataDefinition();
421 return Either.left(resourceMetadata.getToscaResourceName());
423 return Either.left(SERVICE_NODE_TYPE_PREFIX + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName());
425 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
426 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
430 private Optional<SubstitutionMapping> createSubstitutionMapping(final Component component,
431 final Map<String, Component> componentCache) throws ToscaExportException {
432 if (component instanceof Service && !((Service) component).isSubstituteCandidate()) {
433 return Optional.empty();
436 final Either<String, ToscaError> toscaResourceNameEither = createComponentToscaName(component);
437 if (toscaResourceNameEither.isRight()) {
438 throw new ToscaExportException("Could not create component TOSCA name", toscaResourceNameEither.right().value());
440 final String toscaResourceName = toscaResourceNameEither.left().value();
442 final SubstitutionMapping substitutionMapping = new SubstitutionMapping();
443 substitutionMapping.setNode_type(toscaResourceName);
444 convertSubstitutionMappingFilter(component).ifPresent(substitutionMapping::setSubstitution_filter);
446 final Either<Map<String, String[]>, ToscaError> capabilitiesEither = convertSubstitutionMappingCapabilities(component, componentCache);
447 if (capabilitiesEither.isRight()) {
448 throw new ToscaExportException("Could not convert substitution mapping capabilities", capabilitiesEither.right().value());
450 final Map<String, String[]> capabilityMap = capabilitiesEither.left().value();
451 if (!capabilityMap.isEmpty()) {
452 substitutionMapping.setCapabilities(capabilityMap);
455 final Either<Map<String, String[]>, ToscaError> requirements =
456 capabilityRequirementConverter.convertSubstitutionMappingRequirements(component, componentCache);
457 if (requirements.isRight()) {
458 throw new ToscaExportException("Could not convert substitution mapping requirements", requirements.right().value());
460 final Map<String, String[]> requirementMap = requirements.left().value();
461 if (MapUtils.isNotEmpty(requirementMap)) {
462 substitutionMapping.setRequirements(requirementMap);
465 final Map<String, String[]> propertyMappingMap = buildSubstitutionMappingPropertyMapping(component);
466 if (MapUtils.isNotEmpty(propertyMappingMap)) {
467 substitutionMapping.setProperties(propertyMappingMap);
470 final Map<String, String[]> attributesMappingMap = buildSubstitutionMappingAttributesMapping(component);
471 if (MapUtils.isNotEmpty(attributesMappingMap)) {
472 substitutionMapping.setAttributes(attributesMappingMap);
475 return Optional.of(substitutionMapping);
478 private Optional<NodeFilter> convertSubstitutionMappingFilter(final Component component) {
479 if (component.getSubstitutionFilter() == null || (component.getSubstitutionFilter().getProperties()).getListToscaDataDefinition() == null) {
480 return Optional.empty();
483 return Optional.ofNullable(convertToSubstitutionFilterComponent(component.getSubstitutionFilter()));
486 private void addGroupsToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate) {
487 Map<String, ToscaGroupTemplate> groups = groupExportParser.getGroups(component);
488 if (groups != null) {
489 topologyTemplate.addGroups(groups);
493 private void addPoliciesToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate) throws SdcResourceNotFoundException {
494 Map<String, ToscaPolicyTemplate> policies = policyExportParser.getPolicies(component);
495 if (policies != null) {
496 topologyTemplate.addPolicies(policies);
500 private Map<String, String> convertMetadata(Component component) {
501 return convertMetadata(component, false, null);
504 private Map<String, String> convertMetadata(Component component, boolean isInstance, ComponentInstance componentInstance) {
505 Map<String, String> toscaMetadata = new LinkedHashMap<>();
506 toscaMetadata.put(convertMetadataKey(JsonPresentationFields.INVARIANT_UUID), component.getInvariantUUID());
507 toscaMetadata.put(JsonPresentationFields.UUID.getPresentation(), component.getUUID());
509 .put(JsonPresentationFields.NAME.getPresentation(), component.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
510 toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), component.getDescription());
511 List<CategoryDefinition> categories = component.getCategories();
512 CategoryDefinition categoryDefinition = categories.get(0);
513 toscaMetadata.put(JsonPresentationFields.MODEL.getPresentation(), component.getModel());
514 toscaMetadata.put(JsonPresentationFields.CATEGORY.getPresentation(), categoryDefinition.getName());
516 toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), component.getVersion());
517 toscaMetadata.put(JsonPresentationFields.CUSTOMIZATION_UUID.getPresentation(), componentInstance.getCustomizationUUID());
518 if (componentInstance.getSourceModelInvariant() != null && !componentInstance.getSourceModelInvariant().isEmpty()) {
519 toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), componentInstance.getComponentVersion());
520 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_INVARIANT.getPresentation(), componentInstance.getSourceModelInvariant());
521 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_UUID.getPresentation(), componentInstance.getSourceModelUuid());
522 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_NAME.getPresentation(), componentInstance.getSourceModelName());
523 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
524 toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(),
525 componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceProxy.getDisplayValue());
526 } else if (componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
527 toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(),
528 componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceSubstitution.getDisplayValue());
530 toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), componentInstance.getDescription());
533 switch (component.getComponentType()) {
535 Resource resource = (Resource) component;
536 if (isInstance && (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy
537 || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution)) {
538 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), componentInstance.getOriginType().getDisplayValue());
540 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), resource.getResourceType().name());
542 toscaMetadata.put(JsonPresentationFields.SUB_CATEGORY.getPresentation(), categoryDefinition.getSubcategories().get(0).getName());
543 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR.getPresentation(), resource.getVendorName());
544 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_RELEASE.getPresentation(), resource.getVendorRelease());
545 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_MODEL_NUMBER.getPresentation(), resource.getResourceVendorModelNumber());
548 Service service = (Service) component;
549 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), component.getComponentType().getValue());
550 toscaMetadata.put(JsonPresentationFields.SERVICE_TYPE.getPresentation(), service.getServiceType());
551 toscaMetadata.put(JsonPresentationFields.SERVICE_ROLE.getPresentation(), service.getServiceRole());
552 toscaMetadata.put(JsonPresentationFields.SERVICE_FUNCTION.getPresentation(), service.getServiceFunction());
553 toscaMetadata.put(JsonPresentationFields.ENVIRONMENT_CONTEXT.getPresentation(), service.getEnvironmentContext());
554 toscaMetadata.put(JsonPresentationFields.INSTANTIATION_TYPE.getPresentation(),
555 service.getEnvironmentContext() == null ? StringUtils.EMPTY : service.getInstantiationType());
558 toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming().toString());
559 toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming().toString());
560 toscaMetadata.put(JsonPresentationFields.NAMING_POLICY.getPresentation(), service.getNamingPolicy());
564 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
566 for (final String key : component.getCategorySpecificMetadata().keySet()) {
567 if (!EXCLUDED_CATEGORY_SPECIFIC_METADATA.contains(key)) {
568 toscaMetadata.put(key, component.getCategorySpecificMetadata().get(key));
571 return toscaMetadata;
574 private String convertMetadataKey(JsonPresentationFields jsonPresentationField) {
575 if (JsonPresentationFields.INVARIANT_UUID.equals(jsonPresentationField)) {
576 return INVARIANT_UUID;
578 return jsonPresentationField.getPresentation();
581 private Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports(Component component, ToscaTemplate toscaTemplate) {
582 final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImports(component.getModel());
583 if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
584 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
585 return Either.right(ToscaError.GENERAL_ERROR);
587 Map<String, Component> componentCache = new HashMap<>();
588 if (!ModelConverter.isAtomicComponent(component)) {
589 final List<Map<String, Map<String, String>>> additionalImports =
590 toscaTemplate.getImports() == null ? new ArrayList<>(defaultToscaImportConfig) : new ArrayList<>(toscaTemplate.getImports());
591 List<Triple<String, String, Component>> dependencies = new ArrayList<>();
592 Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
593 final Map<String, Map<String, String>> substituteTypeImportEntry = generateComponentSubstituteTypeImport(component, toscaArtifacts);
594 if (!substituteTypeImportEntry.isEmpty()) {
595 additionalImports.add(substituteTypeImportEntry);
597 List<ComponentInstance> componentInstances = component.getComponentInstances();
598 if (componentInstances != null && !componentInstances.isEmpty()) {
599 componentInstances.forEach(ci -> createDependency(componentCache, additionalImports, dependencies, ci));
601 toscaTemplate.setDependencies(dependencies);
602 toscaTemplate.setImports(additionalImports);
604 log.debug("currently imports supported for VF and service only");
606 return Either.left(new ImmutablePair<>(toscaTemplate, componentCache));
609 private Map<String, Map<String, String>> generateComponentSubstituteTypeImport(final Component component,
610 final Map<String, ArtifactDefinition> toscaArtifacts) {
612 if (component instanceof Service && !((Service) component).isSubstituteCandidate()) {
613 return Collections.emptyMap();
615 if (MapUtils.isEmpty(toscaArtifacts)) {
616 return Collections.emptyMap();
618 final ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE);
619 if (artifactDefinition == null) {
620 return Collections.emptyMap();
622 final var importEntryName = component.getComponentType().toString().toLowerCase() + "-" + component.getName() + "-interface";
623 return Map.of(importEntryName,
624 Map.of(IMPORTS_FILE_KEY, getInterfaceFilename(artifactDefinition.getArtifactName()))
628 private List<Map<String, Map<String, String>>> getDefaultToscaImportConfig() {
629 return getConfiguration().getDefaultImports();
632 private void createDependency(final Map<String, Component> componentCache, final List<Map<String, Map<String, String>>> imports,
633 final List<Triple<String, String, Component>> dependencies, final ComponentInstance componentInstance) {
634 log.debug("createDependency componentCache {}", componentCache);
635 Component componentRI = componentCache.get(componentInstance.getComponentUid());
636 if (componentRI == null || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
637 // all resource must be only once!
638 final Either<Component, StorageOperationStatus> resource = toscaOperationFacade.getToscaFullElement(componentInstance.getComponentUid());
639 if ((resource.isRight()) && (log.isDebugEnabled())) {
640 log.debug("Failed to fetch resource with id {} for instance {}", componentInstance.getComponentUid(),
641 componentInstance.getUniqueId());
644 final Component fetchedComponent = resource.left().value();
645 componentRI = setComponentCache(componentCache, componentInstance, fetchedComponent);
646 addDependencies(imports, dependencies, componentRI);
651 * Sets a componentCache from the given component/resource.
653 private Component setComponentCache(final Map<String, Component> componentCache, final ComponentInstance componentInstance,
654 final Component fetchedComponent) {
655 componentCache.put(fetchedComponent.getUniqueId(), fetchedComponent);
656 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy
657 || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
658 final Either<Component, StorageOperationStatus> sourceService = toscaOperationFacade
659 .getToscaFullElement(componentInstance.getSourceModelUid());
660 if (sourceService.isRight() && (log.isDebugEnabled())) {
661 log.debug("Failed to fetch source service with id {} for proxy {}", componentInstance.getSourceModelUid(),
662 componentInstance.getUniqueId());
664 final Component fetchedSource = sourceService.left().value();
665 componentCache.put(fetchedSource.getUniqueId(), fetchedSource);
666 return fetchedSource;
668 return fetchedComponent;
672 * Retrieves all derived_from nodes and stores it in a predictable order.
674 private void addDependencies(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
675 final Component fetchedComponent) {
676 final Set<Component> componentsList = new LinkedHashSet<>();
677 if (fetchedComponent instanceof Resource) {
678 log.debug("fetchedComponent is a resource {}", fetchedComponent);
679 final Optional<Map<String, String>> derivedFromMapOfIdToName = getDerivedFromMapOfIdToName(fetchedComponent, componentsList);
680 if (derivedFromMapOfIdToName.isPresent() && !derivedFromMapOfIdToName.get().isEmpty()) {
681 derivedFromMapOfIdToName.get().entrySet().forEach(entry -> {
682 log.debug("Started entry.getValue() : {}", entry.getValue());
683 if (!NATIVE_ROOT.equals(entry.getValue())) {
684 Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade.getToscaElement(entry.getKey());
685 if (resourcefetched != null && resourcefetched.isLeft()) {
686 componentsList.add(resourcefetched.left().value());
690 setImports(imports, dependencies, componentsList);
692 setImports(imports, dependencies, fetchedComponent);
698 * Returns all derived_from nodes found.
700 private Optional<Map<String, String>> getDerivedFromMapOfIdToName(final Component fetchedComponent, final Set<Component> componentsList) {
701 final Resource parentResource = (Resource) fetchedComponent;
702 Map<String, String> derivedFromMapOfIdToName = new HashMap<>();
703 if (CollectionUtils.isNotEmpty(parentResource.getComponentInstances())) {
704 componentsList.add(fetchedComponent);
705 for (final ComponentInstance componentInstance : parentResource.getComponentInstances()) {
706 final Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade
707 .getToscaElement(componentInstance.getComponentUid());
708 if (resourcefetched != null && resourcefetched.isLeft()) {
709 final Map<String, String> derivedWithId = resourcefetched.left().value().getDerivedFromMapOfIdToName();
710 if (MapUtils.isNotEmpty(derivedWithId)) {
711 derivedFromMapOfIdToName.putAll(derivedWithId);
716 derivedFromMapOfIdToName = parentResource.getDerivedFromMapOfIdToName();
718 log.debug("Started derivedFromMapOfIdToName: {}", derivedFromMapOfIdToName);
719 return Optional.ofNullable(derivedFromMapOfIdToName);
723 * Creates a resource map and adds it to the import list.
725 private void setImports(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
726 final Set<Component> componentsList) {
727 componentsList.forEach(component -> setImports(imports, dependencies, component));
730 private void setImports(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
731 final Component component) {
732 final Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
733 final ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE);
734 if (artifactDefinition != null) {
735 final Map<String, String> files = new HashMap<>();
736 final String artifactName = artifactDefinition.getArtifactName();
737 files.put(IMPORTS_FILE_KEY, artifactName);
738 final StringBuilder keyNameBuilder = new StringBuilder();
739 keyNameBuilder.append(component.getComponentType().toString().toLowerCase());
740 keyNameBuilder.append("-");
741 keyNameBuilder.append(component.getName());
742 addImports(imports, keyNameBuilder, files);
743 dependencies.add(new ImmutableTriple<>(artifactName, artifactDefinition.getEsId(), component));
744 if (!ModelConverter.isAtomicComponent(component)) {
745 final Map<String, String> interfaceFiles = new HashMap<>();
746 interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactName));
747 keyNameBuilder.append("-interface");
748 addImports(imports, keyNameBuilder, interfaceFiles);
754 * Adds the found resource to the import definition list.
756 private void addImports(final List<Map<String, Map<String, String>>> imports, final StringBuilder keyNameBuilder,
757 final Map<String, String> files) {
758 final String mapKey = keyNameBuilder.toString();
759 if (imports.stream().allMatch(stringMapMap -> stringMapMap.get(mapKey) == null)) {
760 final Map<String, Map<String, String>> importsListMember = new HashMap<>();
761 importsListMember.put(keyNameBuilder.toString(), files);
762 imports.add(importsListMember);
766 private Either<ToscaTemplate, ToscaError> convertNodeType(Map<String, Component> componentsCache, Component component, ToscaTemplate toscaNode,
767 Map<String, ToscaNodeType> nodeTypes) {
768 return convertInterfaceNodeType(componentsCache, component, toscaNode, nodeTypes, false);
771 public Either<ToscaTemplate, ToscaError> convertInterfaceNodeType(Map<String, Component> componentsCache, Component component,
772 ToscaTemplate toscaNode, Map<String, ToscaNodeType> nodeTypes,
773 boolean isAssociatedComponent) {
774 log.debug("start convert node type for {}", component.getUniqueId());
775 ToscaNodeType toscaNodeType = createNodeType(component);
776 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither = interfaceLifecycleOperation
777 .getAllInterfaceLifecycleTypes(component.getModel());
778 if (lifecycleTypeEither.isRight() && !StorageOperationStatus.NOT_FOUND.equals(lifecycleTypeEither.right().value())) {
779 log.debug("Failed to fetch all interface types :", lifecycleTypeEither.right().value());
780 return Either.right(ToscaError.GENERAL_ERROR);
782 if (lifecycleTypeEither.isLeft()) {
783 List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value().values().stream().map(InterfaceDataDefinition::getType)
784 .collect(Collectors.toList());
785 toscaNode.setInterface_types(interfacesOperationsConverter.addInterfaceTypeElement(component, allGlobalInterfaceTypes));
787 final var dataTypesEither = applicationDataTypeCache.getAll(component.getModel());
788 if (dataTypesEither.isRight()) {
789 log.debug("Failed to fetch all data types :", dataTypesEither.right().value());
790 return Either.right(ToscaError.GENERAL_ERROR);
792 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
793 List<InputDefinition> inputDef = component.getInputs();
794 interfacesOperationsConverter.addInterfaceDefinitionElement(component, toscaNodeType, dataTypes, isAssociatedComponent);
795 final var toscaAttributeMap = convertToToscaAttributes(component.getAttributes(), dataTypes);
796 if (!toscaAttributeMap.isEmpty()) {
797 toscaNodeType.setAttributes(toscaAttributeMap);
799 final var mergedProperties = convertInputsToProperties(dataTypes, inputDef, component.getUniqueId());
800 if (CollectionUtils.isNotEmpty(component.getProperties())) {
801 List<PropertyDefinition> properties = component.getProperties();
802 Map<String, ToscaProperty> convertedProperties = properties.stream()
803 .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, component.getInputs())).collect(Collectors
804 .toMap(PropertyDataDefinition::getName,
805 property -> propertyConvertor.convertProperty(dataTypes, property, PropertyConvertor.PropertyType.PROPERTY)));
806 // merge component properties and inputs properties
807 mergedProperties.putAll(convertedProperties);
809 if (MapUtils.isNotEmpty(mergedProperties)) {
810 toscaNodeType.setProperties(mergedProperties);
812 /* convert private data_types */
813 List<DataTypeDefinition> privateDataTypes = component.getDataTypes();
814 if (CollectionUtils.isNotEmpty(privateDataTypes)) {
815 Map<String, ToscaDataType> toscaDataTypeMap = new HashMap<>();
816 for (DataTypeDefinition dataType : privateDataTypes) {
817 log.debug("Emitting private data type: component.name={} dataType.name={}",
818 component.getNormalizedName(), dataType.getName());
819 ToscaDataType toscaDataType = new ToscaDataType();
820 toscaDataType.setDerived_from(dataType.getDerivedFromName());
821 toscaDataType.setDescription(dataType.getDescription());
822 toscaDataType.setVersion(dataType.getVersion());
823 if (CollectionUtils.isNotEmpty(dataType.getProperties())) {
824 toscaDataType.setProperties(dataType.getProperties().stream()
825 .collect(Collectors.toMap(
826 PropertyDataDefinition::getName,
827 s -> propertyConvertor.convertProperty(dataTypes, s, PropertyType.PROPERTY),
828 (toscaPropertyTobeValidated, toscaProperty) -> validateToscaProperty(privateDataTypes, toscaPropertyTobeValidated,
832 toscaDataTypeMap.put(dataType.getName(), toscaDataType);
834 toscaNode.setData_types(toscaDataTypeMap);
837 // Extracted to method for code reuse
838 return convertReqCapAndTypeName(componentsCache, component, toscaNode, nodeTypes, toscaNodeType, dataTypes);
841 private ToscaProperty validateToscaProperty(final List<DataTypeDefinition> privateDataTypes, final ToscaProperty toscaPropertyTobeValidated,
842 final ToscaProperty toscaProperty) {
843 final Optional<DataTypeDefinition> match = privateDataTypes.stream()
844 .filter(dataType -> dataType.getName().equals(toscaPropertyTobeValidated.getType())).findFirst();
845 return match.isPresent() ? toscaPropertyTobeValidated : toscaProperty;
848 private Map<String, ToscaAttribute> convertToToscaAttributes(final List<AttributeDefinition> attributeList,
849 final Map<String, DataTypeDefinition> dataTypes) {
850 if (CollectionUtils.isEmpty(attributeList)) {
851 return Collections.emptyMap();
853 final AttributeConverter converter = new AttributeConverter(dataTypes);
854 final Map<String, ToscaAttribute> toscaAttributeMap = new HashMap<>();
855 for (final AttributeDefinition attributeDefinition : attributeList) {
856 toscaAttributeMap.put(attributeDefinition.getName(), converter.convert(attributeDefinition));
858 return toscaAttributeMap;
861 private Either<ToscaTemplate, ToscaError> convertReqCapAndTypeName(Map<String, Component> componentsCache,
862 Component component, ToscaTemplate toscaNode,
863 Map<String, ToscaNodeType> nodeTypes,
864 ToscaNodeType toscaNodeType,
865 Map<String, DataTypeDefinition> dataTypes) {
866 Either<ToscaNodeType, ToscaError> capabilities = convertCapabilities(componentsCache, component, toscaNodeType,
868 if (capabilities.isRight()) {
869 return Either.right(capabilities.right().value());
871 toscaNodeType = capabilities.left().value();
872 log.debug("Capabilities converted for {}", component.getUniqueId());
874 Either<ToscaNodeType, ToscaError> requirements = capabilityRequirementConverter
875 .convertRequirements(componentsCache, component, toscaNodeType);
876 if (requirements.isRight()) {
877 return Either.right(requirements.right().value());
879 toscaNodeType = requirements.left().value();
880 log.debug("Requirements converted for {}", component.getUniqueId());
882 String toscaResourceName;
883 switch (component.getComponentType()) {
885 toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition()
886 .getMetadataDataDefinition()).getToscaResourceName();
889 toscaResourceName = SERVICE_NODE_TYPE_PREFIX
890 + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName();
893 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
894 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
897 nodeTypes.put(toscaResourceName, toscaNodeType);
898 toscaNode.setNode_types(nodeTypes);
899 log.debug("finish convert node type for {}", component.getUniqueId());
900 return Either.left(toscaNode);
903 private Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplates(final Component component,
904 final Map<String, Component> componentCache,
905 final Map<String, DataTypeDefinition> dataTypes,
906 final ToscaTopolgyTemplate topologyTemplate) {
908 final Map<String, List<ComponentInstanceProperty>> componentInstancesProperties = component.getComponentInstancesProperties();
909 final Map<String, List<ComponentInstanceAttribute>> componentInstancesAttributes = component.getComponentInstancesAttributes();
910 final Map<String, List<ComponentInstanceInput>> componentInstancesInputs = component.getComponentInstancesInputs();
911 final Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces = component.getComponentInstancesInterfaces();
912 final List<RequirementCapabilityRelDef> componentInstancesRelations = component.getComponentInstancesRelations();
914 Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplatesRes = null;
915 log.debug("start convert topology template for {} for type {}", component.getUniqueId(), component.getComponentType());
916 final Map<String, ToscaNodeTemplate> nodeTemplates = new HashMap<>();
918 Map<String, ToscaGroupTemplate> groupsMap = null;
919 for (final ComponentInstance componentInstance : component.getComponentInstances()) {
920 ToscaNodeTemplate nodeTemplate = new ToscaNodeTemplate();
921 if (MapUtils.isNotEmpty(componentInstance.getToscaArtifacts())) {
922 nodeTemplate.setArtifacts(convertToNodeTemplateArtifacts(componentInstance.getToscaArtifacts()));
924 if (componentInstance.getMinOccurrences() != null && componentInstance.getMaxOccurrences() != null) {
925 List<Object> occur = new ArrayList<>();
926 occur.add(parseToIntIfPossible(componentInstance.getMinOccurrences()));
927 occur.add(parseToIntIfPossible(componentInstance.getMaxOccurrences()));
928 nodeTemplate.setOccurrences(occur);
930 if (componentInstance.getInstanceCount() != null) {
931 ObjectMapper objectMapper = new ObjectMapper();
932 Object obj = convertToToscaObject(componentInstance.getInstanceCount());
934 Map<String, String> map = objectMapper.convertValue(obj, Map.class);
935 nodeTemplate.setInstance_count(map);
938 nodeTemplate.setType(componentInstance.getToscaComponentName());
939 nodeTemplate.setDirectives(componentInstance.getDirectives());
940 nodeTemplate.setNode_filter(convertToNodeTemplateNodeFilterComponent(componentInstance.getNodeFilter()));
942 final Either<Component, Boolean> originComponentRes = capabilityRequirementConverter
943 .getOriginComponent(componentCache, componentInstance);
944 if (originComponentRes.isRight()) {
945 convertNodeTemplatesRes = Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
948 final Either<ToscaNodeTemplate, ToscaError> requirements = convertComponentInstanceRequirements(component, componentInstance,
949 componentInstancesRelations, nodeTemplate, originComponentRes.left().value(), componentCache);
950 if (requirements.isRight()) {
951 convertNodeTemplatesRes = Either.right(requirements.right().value());
954 final String instanceUniqueId = componentInstance.getUniqueId();
955 log.debug("Component instance Requirements converted for instance {}", instanceUniqueId);
957 nodeTemplate = requirements.left().value();
959 final Component originalComponent = componentCache.get(componentInstance.getActualComponentUid());
961 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
962 final Component componentOfProxy = componentCache.get(componentInstance.getComponentUid());
963 nodeTemplate.setMetadata(convertMetadata(componentOfProxy, true, componentInstance));
965 nodeTemplate.setMetadata(convertMetadata(originalComponent, true, componentInstance));
968 final Either<ToscaNodeTemplate, ToscaError> capabilities =
969 capabilityRequirementConverter.convertComponentInstanceCapabilities(componentInstance, dataTypes, nodeTemplate);
970 if (capabilities.isRight()) {
971 convertNodeTemplatesRes = Either.right(capabilities.right().value());
974 log.debug("Component instance Capabilities converted for instance {}", instanceUniqueId);
976 nodeTemplate = capabilities.left().value();
977 final Map<String, Object> props = new HashMap<>();
978 final Map<String, Object> attribs = new HashMap<>();
980 if (originalComponent.getComponentType() == ComponentTypeEnum.RESOURCE) {
981 // Adds the properties of parent component to map
982 addPropertiesOfParentComponent(dataTypes, originalComponent, props);
983 addAttributesOfParentComponent(originalComponent, attribs);
986 if (null != componentInstancesProperties && componentInstancesProperties.containsKey(instanceUniqueId)) {
987 addPropertiesOfComponentInstance(componentInstancesProperties, dataTypes, instanceUniqueId, props);
989 if (null != componentInstancesAttributes && componentInstancesAttributes.containsKey(instanceUniqueId)) {
990 addAttributesOfComponentInstance(componentInstancesAttributes, instanceUniqueId, attribs);
993 if (componentInstancesInputs != null
994 && componentInstancesInputs.containsKey(instanceUniqueId)
995 && !isComponentOfTypeServiceProxy(componentInstance)) {
996 //For service proxy the inputs are already handled under instance properties above
997 addComponentInstanceInputs(dataTypes, componentInstancesInputs, instanceUniqueId, props);
1000 //M3[00001] - NODE TEMPLATE INTERFACES - START
1001 handleInstanceInterfaces(componentInstanceInterfaces, componentInstance, dataTypes, nodeTemplate, instanceUniqueId, component);
1002 //M3[00001] - NODE TEMPLATE INTERFACES - END
1003 if (MapUtils.isNotEmpty(props)) {
1004 nodeTemplate.setProperties(props);
1006 if (MapUtils.isNotEmpty(attribs)) {
1007 nodeTemplate.setAttributes(attribs);
1010 final List<GroupInstance> groupInstances = componentInstance.getGroupInstances();
1011 if (CollectionUtils.isNotEmpty(groupInstances)) {
1012 if (groupsMap == null) {
1013 groupsMap = new HashMap<>();
1015 for (final GroupInstance groupInst : groupInstances) {
1016 if (CollectionUtils.isNotEmpty(groupInst.getArtifacts())) {
1017 groupsMap.put(groupInst.getName(), groupExportParser.getToscaGroupTemplate(groupInst, componentInstance.getInvariantName()));
1022 nodeTemplates.put(componentInstance.getName(), nodeTemplate);
1024 if (groupsMap != null) {
1025 log.debug("instance groups added");
1026 topologyTemplate.addGroups(groupsMap);
1028 if (component.getComponentType() == ComponentTypeEnum.SERVICE && isNotEmpty(
1029 ((Service) component).getForwardingPaths())) {
1030 log.debug("Starting converting paths for component {}, name {}", component.getUniqueId(), component.getName());
1031 ForwardingPathToscaUtil
1032 .addForwardingPaths((Service) component, nodeTemplates, capabilityRequirementConverter, componentCache, toscaOperationFacade);
1033 log.debug("Finished converting paths for component {}, name {}", component.getUniqueId(), component.getName());
1035 if (convertNodeTemplatesRes == null) {
1036 convertNodeTemplatesRes = Either.left(nodeTemplates);
1038 log.debug("finish convert topology template for {} for type {}", component.getUniqueId(), component.getComponentType());
1039 return convertNodeTemplatesRes;
1042 private Object convertToToscaObject(String value) {
1044 ToscaMapValueConverter mapConverterInst = ToscaMapValueConverter.getInstance();
1045 JsonParser jsonParser = new JsonParser();
1046 StringReader reader = new StringReader(value);
1047 JsonReader jsonReader = new JsonReader(reader);
1048 jsonReader.setLenient(true);
1049 JsonElement jsonElement = jsonParser.parse(jsonReader);
1050 if (jsonElement.isJsonObject()) {
1051 JsonObject jsonObj = jsonElement.getAsJsonObject();
1052 if (jsonObj.entrySet().size() == 1 && jsonObj.has(ToscaFunctions.GET_INPUT.getFunctionName())) {
1053 return mapConverterInst.handleComplexJsonValue(jsonElement);
1057 } catch (Exception e) {
1058 log.debug("convertToToscaValue failed to parse json value :", e);
1063 private Object parseToIntIfPossible(final String value) {
1064 final Integer intValue = Ints.tryParse(value);
1065 return intValue == null ? value : intValue;
1068 private void handleInstanceInterfaces(
1069 Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces,
1070 ComponentInstance componentInstance, Map<String, DataTypeDefinition> dataTypes, ToscaNodeTemplate nodeTemplate,
1071 String instanceUniqueId,
1072 Component parentComponent) {
1074 if (MapUtils.isEmpty(componentInstanceInterfaces)
1075 || !componentInstanceInterfaces.containsKey(instanceUniqueId)) {
1076 nodeTemplate.setInterfaces(null);
1080 final List<ComponentInstanceInterface> currServiceInterfaces =
1081 componentInstanceInterfaces.get(instanceUniqueId);
1083 final Map<String, InterfaceDefinition> tmpInterfaces = new HashMap<>();
1084 currServiceInterfaces.forEach(instInterface -> tmpInterfaces.put(instInterface
1085 .getUniqueId(), instInterface));
1087 final Map<String, Object> interfaceMap = interfacesOperationsConverter
1088 .getInterfacesMap(parentComponent, componentInstance, tmpInterfaces, dataTypes, isComponentOfTypeServiceProxy(componentInstance),
1089 isComponentOfTypeServiceProxy(componentInstance));
1091 interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
1092 nodeTemplate.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap);
1095 private boolean isComponentOfTypeServiceProxy(ComponentInstance componentInstance) {
1096 return Objects.nonNull(componentInstance.getOriginType())
1097 && componentInstance.getOriginType().getValue().equals("Service Proxy");
1100 private void addComponentInstanceInputs(Map<String, DataTypeDefinition> dataTypes,
1101 Map<String, List<ComponentInstanceInput>> componentInstancesInputs,
1102 String instanceUniqueId, Map<String, Object> props) {
1104 List<ComponentInstanceInput> instanceInputsList = componentInstancesInputs.get(instanceUniqueId);
1105 if (instanceInputsList != null) {
1106 instanceInputsList.forEach(input -> {
1107 Supplier<String> supplier = () -> input.getValue() != null && !Objects.isNull(input.getValue()) ? input.getValue()
1108 : input.getDefaultValue();
1109 propertyConvertor.convertAndAddValue(dataTypes, props, input, supplier);
1114 private void addPropertiesOfComponentInstance(final Map<String, List<ComponentInstanceProperty>> componentInstancesProperties,
1115 final Map<String, DataTypeDefinition> dataTypes,
1116 final String instanceUniqueId,
1117 final Map<String, Object> props) {
1119 if (isNotEmpty(componentInstancesProperties)) {
1120 componentInstancesProperties.get(instanceUniqueId)
1121 // Converts and adds each value to property map
1122 .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop, prop::getValue));
1126 private void addAttributesOfComponentInstance(final Map<String, List<ComponentInstanceAttribute>> componentInstancesAttributes,
1127 final String instanceUniqueId,
1128 final Map<String, Object> attribs) {
1130 if (isNotEmpty(componentInstancesAttributes) && componentInstancesAttributes.containsKey(instanceUniqueId)) {
1131 componentInstancesAttributes.get(instanceUniqueId)
1132 .forEach(attributeDefinition -> attributeConverter.convertAndAddValue(attribs, attributeDefinition));
1136 private void addPropertiesOfParentComponent(Map<String, DataTypeDefinition> dataTypes,
1137 Component componentOfInstance, Map<String, Object> props) {
1139 List<PropertyDefinition> componentProperties = componentOfInstance.getProperties();
1140 if (isNotEmpty(componentProperties)) {
1141 componentProperties.stream()
1142 // Filters out properties with empty default values
1143 .filter(prop -> StringUtils.isNotEmpty(prop.getDefaultValue()))
1144 // Converts and adds each value to property map
1145 .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop, prop::getDefaultValue));
1149 private void addAttributesOfParentComponent(final Component componentOfInstance, final Map<String, Object> attribs) {
1151 final List<AttributeDefinition> componentAttributes = componentOfInstance.getAttributes();
1152 if (isNotEmpty(componentAttributes)) {
1153 componentAttributes.stream()
1154 // Filters out Attributes with empty default values
1155 .filter(attrib -> StringUtils.isNotEmpty(attrib.getDefaultValue()))
1156 // Converts and adds each value to attribute map
1157 .forEach(attributeDefinition -> attributeConverter.convertAndAddValue(attribs, attributeDefinition));
1161 private ToscaNodeType createNodeType(Component component) {
1162 ToscaNodeType toscaNodeType = new ToscaNodeType();
1163 if (ModelConverter.isAtomicComponent(component)) {
1164 if (((Resource) component).getDerivedFrom() != null) {
1165 toscaNodeType.setDerived_from(((Resource) component).getDerivedFrom().get(0));
1167 toscaNodeType.setDescription(component.getDescription());
1169 String derivedFrom = null != component.getDerivedFromGenericType() ? component.getDerivedFromGenericType()
1171 toscaNodeType.setDerived_from(derivedFrom);
1173 return toscaNodeType;
1176 private Either<Map<String, Object>, ToscaError> createProxyInterfaceTypes(Component container) {
1178 Map<String, Object> proxyInterfaceTypes = new HashMap<>();
1179 Either<Map<String, Object>, ToscaError> res = Either.left(proxyInterfaceTypes);
1180 List<ComponentInstance> componentInstances = container.getComponentInstances();
1181 if (CollectionUtils.isEmpty(componentInstances)) {
1184 Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
1185 componentInstances.stream()
1186 .filter(this::isComponentOfTypeServiceProxy)
1187 .forEach(inst -> serviceProxyInstanceList.put(inst.getToscaComponentName(), inst));
1188 if (MapUtils.isEmpty(serviceProxyInstanceList)) {
1191 for (Entry<String, ComponentInstance> entryProxy : serviceProxyInstanceList.entrySet()) {
1192 Component serviceComponent;
1193 ComponentParametersView componentParametersView = new ComponentParametersView();
1194 componentParametersView.disableAll();
1195 componentParametersView.setIgnoreInterfaces(false);
1196 Either<Component, StorageOperationStatus> service = toscaOperationFacade
1197 .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
1198 if (service.isRight()) {
1199 log.debug("Failed to fetch original service component with id {} for instance {}",
1200 entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName());
1201 return Either.right(ToscaError.GENERAL_ERROR);
1203 serviceComponent = service.left().value();
1206 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither =
1207 interfaceLifecycleOperation.getAllInterfaceLifecycleTypes(serviceComponent.getModel());
1208 if (lifecycleTypeEither.isRight()) {
1209 log.debug("Failed to retrieve global interface types :", lifecycleTypeEither.right().value());
1210 return Either.right(ToscaError.GENERAL_ERROR);
1213 List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value().values().stream()
1214 .map(InterfaceDataDefinition::getType)
1215 .collect(Collectors.toList());
1216 //Add interface types for local interfaces in the original service component for proxy
1217 Map<String, Object> localInterfaceTypes = interfacesOperationsConverter.addInterfaceTypeElement(serviceComponent,
1218 allGlobalInterfaceTypes);
1219 if (MapUtils.isNotEmpty(localInterfaceTypes)) {
1220 proxyInterfaceTypes.putAll(localInterfaceTypes);
1224 return Either.left(proxyInterfaceTypes);
1227 private Either<Map<String, ToscaNodeType>, ToscaError> createProxyNodeTypes(Map<String, Component> componentCache,
1228 Component container) {
1230 Map<String, ToscaNodeType> nodeTypesMap = new HashMap<>();
1231 Either<Map<String, ToscaNodeType>, ToscaError> res = Either.left(nodeTypesMap);
1233 List<ComponentInstance> componentInstances = container.getComponentInstances();
1235 if (componentInstances == null || componentInstances.isEmpty()) {
1238 Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
1239 List<ComponentInstance> proxyInst = componentInstances.stream()
1240 .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceProxy.name()))
1241 .collect(Collectors.toList());
1242 if (proxyInst != null && !proxyInst.isEmpty()) {
1243 for (ComponentInstance inst : proxyInst) {
1244 serviceProxyInstanceList.put(inst.getToscaComponentName(), inst);
1248 if (serviceProxyInstanceList.isEmpty()) {
1251 Either<Resource, StorageOperationStatus> serviceProxyOrigin = toscaOperationFacade
1252 .getLatestByName("serviceProxy", null);
1253 if (serviceProxyOrigin.isRight()) {
1254 log.debug("Failed to fetch normative service proxy resource by tosca name, error {}",
1255 serviceProxyOrigin.right().value());
1256 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
1258 Component origComponent = serviceProxyOrigin.left().value();
1260 for (Entry<String, ComponentInstance> entryProxy : serviceProxyInstanceList.entrySet()) {
1261 Component serviceComponent = null;
1262 ComponentParametersView componentParametersView = new ComponentParametersView();
1263 componentParametersView.disableAll();
1264 componentParametersView.setIgnoreCategories(false);
1265 componentParametersView.setIgnoreProperties(false);
1266 componentParametersView.setIgnoreInputs(false);
1267 componentParametersView.setIgnoreInterfaces(false);
1268 componentParametersView.setIgnoreRequirements(false);
1269 Either<Component, StorageOperationStatus> service = toscaOperationFacade
1270 .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
1271 if (service.isRight()) {
1272 log.debug("Failed to fetch resource with id {} for instance {}",
1273 entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName());
1275 serviceComponent = service.left().value();
1278 ToscaNodeType toscaNodeType = createProxyNodeType(componentCache, origComponent, serviceComponent,
1279 entryProxy.getValue());
1280 nodeTypesMap.put(entryProxy.getKey(), toscaNodeType);
1283 return Either.left(nodeTypesMap);
1286 private void createServiceSubstitutionNodeTypes(final Map<String, Component> componentCache,
1287 final Component container, final ToscaTemplate toscaNode) {
1288 final List<ComponentInstance> componentInstances = container.getComponentInstances();
1290 if (CollectionUtils.isEmpty(componentInstances)) {
1293 final List<ComponentInstance> serviceSubstitutionInstanceList = componentInstances.stream()
1294 .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceSubstitution.name()))
1295 .collect(Collectors.toList());
1296 if (CollectionUtils.isNotEmpty(serviceSubstitutionInstanceList)) {
1297 for (ComponentInstance inst : serviceSubstitutionInstanceList) {
1298 final Map<String, ToscaNodeType> nodeTypes =
1299 toscaNode.getNode_types() == null ? new HashMap<>() : toscaNode.getNode_types();
1300 convertInterfaceNodeType(new HashMap<>(), componentCache.get(inst.getSourceModelUid()), toscaNode,
1306 private ToscaNodeType createProxyNodeType(Map<String, Component> componentCache, Component origComponent,
1307 Component proxyComponent, ComponentInstance componentInstance) {
1308 ToscaNodeType toscaNodeType = new ToscaNodeType();
1309 String derivedFrom = ((Resource) origComponent).getToscaResourceName();
1311 toscaNodeType.setDerived_from(derivedFrom);
1312 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = applicationDataTypeCache.getAll(
1313 origComponent.getModel());
1314 if (dataTypesEither.isRight()) {
1315 log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
1317 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
1318 Map<String, ToscaCapability> capabilities = this.capabilityRequirementConverter
1319 .convertProxyCapabilities(componentCache, componentInstance, dataTypes);
1321 if (MapUtils.isNotEmpty(capabilities)) {
1322 toscaNodeType.setCapabilities(capabilities);
1324 List<Map<String, ToscaRequirement>> proxyNodeTypeRequirements = this.capabilityRequirementConverter
1325 .convertProxyRequirements(componentCache, componentInstance);
1326 if (CollectionUtils.isNotEmpty(proxyNodeTypeRequirements)) {
1327 toscaNodeType.setRequirements(proxyNodeTypeRequirements);
1329 Optional<Map<String, ToscaProperty>> proxyProperties = getProxyNodeTypeProperties(proxyComponent, dataTypes);
1330 proxyProperties.ifPresent(toscaNodeType::setProperties);
1332 Map<String, Object> interfaceMap = new HashMap<>();
1333 if (MapUtils.isEmpty(componentInstance.getInterfaces())) {
1334 final Optional<Map<String, Object>> proxyInterfaces = getProxyNodeTypeInterfaces(proxyComponent, dataTypes);
1335 if (proxyInterfaces.isPresent()) {
1336 interfaceMap = proxyInterfaces.get();
1339 interfaceMap = interfacesOperationsConverter
1340 .getInterfacesMapFromComponentInstance(proxyComponent, componentInstance, dataTypes, false, false);
1343 interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
1344 toscaNodeType.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap);
1346 return toscaNodeType;
1349 private Either<ToscaNodeTemplate, ToscaError> convertComponentInstanceRequirements(Component component,
1350 ComponentInstance componentInstance,
1351 List<RequirementCapabilityRelDef> relations,
1352 ToscaNodeTemplate nodeTypeTemplate,
1353 Component originComponent,
1354 Map<String, Component> componentCache) {
1356 final List<RequirementCapabilityRelDef> requirementDefinitionList = filterRequirements(componentInstance,
1358 if (isNotEmpty(requirementDefinitionList)) {
1360 final List<Map<String, ToscaTemplateRequirement>> toscaRequirements = buildRequirements(component, componentInstance,
1361 requirementDefinitionList, originComponent, componentCache);
1362 if (!toscaRequirements.isEmpty()) {
1363 nodeTypeTemplate.setRequirements(toscaRequirements);
1365 } catch (final Exception e) {
1366 log.debug("Failed to convert component instance requirements for the component instance {}. ",
1367 componentInstance.getName(), e);
1368 return Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
1371 log.debug("Finished to convert requirements for the node type {} ", componentInstance.getName());
1372 return Either.left(nodeTypeTemplate);
1375 private List<Map<String, ToscaTemplateRequirement>> buildRequirements(final Component component,
1376 final ComponentInstance componentInstance,
1377 final List<RequirementCapabilityRelDef> filteredRelations,
1378 final Component originComponent,
1379 final Map<String, Component> componentCache)
1380 throws ToscaExportException {
1382 final List<Map<String, ToscaTemplateRequirement>> toscaRequirements = new ArrayList<>();
1383 for (RequirementCapabilityRelDef relationshipDefinition : filteredRelations) {
1384 final Map<String, ToscaTemplateRequirement> toscaTemplateRequirementMap =
1385 buildRequirement(componentInstance, originComponent, component.getComponentInstances(), relationshipDefinition, componentCache);
1386 toscaRequirements.add(toscaTemplateRequirementMap);
1389 return toscaRequirements;
1392 private List<RequirementCapabilityRelDef> filterRequirements(ComponentInstance componentInstance,
1393 List<RequirementCapabilityRelDef> relations) {
1394 return relations.stream()
1395 .filter(p -> componentInstance.getUniqueId().equals(p.getFromNode())).collect(Collectors.toList());
1398 private Map<String, ToscaTemplateRequirement> buildRequirement(final ComponentInstance fromInstance,
1399 final Component fromOriginComponent,
1400 final List<ComponentInstance> instancesList,
1401 final RequirementCapabilityRelDef relationshipDefinition,
1402 final Map<String, Component> componentCache)
1403 throws ToscaExportException {
1405 final Map<String, List<RequirementDefinition>> reqMap = fromOriginComponent.getRequirements();
1406 final CapabilityRequirementRelationship capabilityRequirementRelationship = relationshipDefinition
1407 .getRelationships().get(0);
1408 final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation();
1410 final ComponentInstance toInstance = instancesList.stream()
1411 .filter(i -> relationshipDefinition.getToNode().equals(i.getUniqueId()))
1412 .findFirst().orElse(null);
1413 if (toInstance == null) {
1414 final String errorMsg = String
1415 .format("Failed to find a relation from the node %s to the node %s", fromInstance.getName(),
1416 relationshipDefinition.getToNode());
1417 log.debug(errorMsg);
1418 throw new ToscaExportException(errorMsg);
1420 final Optional<RequirementDefinition> reqOpt =
1421 findRequirement(fromOriginComponent, reqMap, relationshipInfo, fromInstance.getUniqueId());
1422 if (reqOpt.isEmpty()) {
1423 final String errorMsg = String
1424 .format("Failed to find a requirement with uniqueId %s on a component with uniqueId %s",
1425 relationshipInfo.getRequirementUid(), fromOriginComponent.getUniqueId());
1426 log.debug(errorMsg);
1427 throw new ToscaExportException(errorMsg);
1429 final ComponentParametersView filter = new ComponentParametersView(true);
1430 filter.setIgnoreComponentInstances(false);
1431 filter.setIgnoreCapabilities(false);
1432 filter.setIgnoreGroups(false);
1433 final Either<Component, StorageOperationStatus> getOriginRes =
1434 toscaOperationFacade.getToscaElement(toInstance.getActualComponentUid(), filter);
1435 if (getOriginRes.isRight()) {
1436 final String errorMsg = String.format(
1437 "Failed to build substituted name for the requirement %s. "
1438 + "Failed to get an origin component with uniqueId %s",
1439 reqOpt.get().getName(), toInstance.getActualComponentUid());
1440 log.debug(errorMsg);
1441 throw new ToscaExportException(errorMsg);
1443 final Component toOriginComponent = getOriginRes.left().value();
1444 Optional<CapabilityDefinition> capOpt = toOriginComponent.getCapabilities().get(reqOpt.get().getCapability()).stream()
1445 .filter(c -> isCapabilityBelongToRelation(relationshipInfo, c)).findFirst();
1446 if (capOpt.isEmpty()) {
1447 capOpt = findCapability(relationshipInfo, toOriginComponent, fromOriginComponent, reqOpt.get());
1448 if (capOpt.isEmpty()) {
1449 final String errorMsg = String
1450 .format("Failed to find a capability with name %s on a component with uniqueId %s",
1451 relationshipInfo.getCapability(), fromOriginComponent.getUniqueId());
1452 log.debug(errorMsg);
1453 throw new ToscaExportException(errorMsg);
1456 return buildRequirement(fromOriginComponent, toOriginComponent, capOpt.get(), reqOpt.get(),
1457 capabilityRequirementRelationship, toInstance, componentCache);
1460 private boolean isCapabilityBelongToRelation(RelationshipInfo reqAndRelationshipPair,
1461 CapabilityDefinition capability) {
1462 return capability.getName().equals(reqAndRelationshipPair.getCapability()) && (capability.getOwnerId() != null
1463 && capability.getOwnerId().equals(reqAndRelationshipPair.getCapabilityOwnerId()));
1466 private Optional<CapabilityDefinition> findCapability(RelationshipInfo reqAndRelationshipPair,
1467 Component toOriginComponent, Component fromOriginComponent,
1468 RequirementDefinition requirement) {
1469 Optional<CapabilityDefinition> cap = toOriginComponent.getCapabilities().get(requirement.getCapability())
1470 .stream().filter(c -> c.getType().equals(requirement.getCapability())).findFirst();
1471 if (!cap.isPresent()) {
1472 log.debug("Failed to find a capability with name {} on a component with uniqueId {}",
1473 reqAndRelationshipPair.getCapability(), fromOriginComponent.getUniqueId());
1478 private Map<String, ToscaTemplateRequirement> buildRequirement(final Component fromOriginComponent,
1479 final Component toOriginComponent,
1480 final CapabilityDefinition capability,
1481 final RequirementDefinition requirement,
1482 final CapabilityRequirementRelationship capabilityRequirementRelationship,
1483 final ComponentInstance toInstance,
1484 final Map<String, Component> componentCache)
1485 throws ToscaExportException {
1487 List<String> reducedPath = capability.getPath();
1488 if (capability.getOwnerId() != null) {
1489 reducedPath = capabilityRequirementConverter
1490 .getReducedPathByOwner(capability.getPath(), capability.getOwnerId());
1492 final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation();
1493 final Either<String, Boolean> capabilityNameEither = capabilityRequirementConverter.buildSubstitutedName(componentCache,
1494 toOriginComponent, reducedPath, relationshipInfo.getCapability(), capability.getPreviousName(), capability.getExternalName());
1495 if (capabilityNameEither.isRight()) {
1496 final String errorMsg = String.format(
1497 "Failed to build a substituted capability name for the capability with name %s on a component with uniqueId %s",
1498 capabilityRequirementRelationship.getCapability(), toOriginComponent.getUniqueId());
1501 throw new ToscaExportException(errorMsg);
1503 final Either<String, Boolean> requirementNameEither = capabilityRequirementConverter
1504 .buildSubstitutedName(componentCache, fromOriginComponent,
1505 requirement.getPath(), relationshipInfo.getRequirement(), requirement.getPreviousName(), requirement.getExternalName());
1506 if (requirementNameEither.isRight()) {
1507 final String errorMsg = String.format("Failed to build a substituted requirement name for the requirement "
1508 + "with name %s on a component with uniqueId %s",
1509 capabilityRequirementRelationship.getRequirement(), fromOriginComponent.getUniqueId());
1510 log.debug(errorMsg);
1511 throw new ToscaExportException(errorMsg);
1513 final ToscaTemplateRequirement toscaRequirement = new ToscaTemplateRequirement();
1514 final Map<String, ToscaTemplateRequirement> toscaReqMap = new HashMap<>();
1515 toscaRequirement.setNode(toInstance.getName());
1516 toscaRequirement.setCapability(capabilityNameEither.left().value());
1517 if (isNotEmpty(capabilityRequirementRelationship.getOperations())) {
1518 toscaRequirement.setRelationship(new ToscaRelationshipBuilder().from(capabilityRequirementRelationship));
1520 toscaReqMap.put(requirementNameEither.left().value(), toscaRequirement);
1524 private Optional<RequirementDefinition> findRequirement(Component fromOriginComponent,
1525 Map<String, List<RequirementDefinition>> reqMap,
1526 RelationshipInfo reqAndRelationshipPair,
1527 String fromInstanceId) {
1528 for (List<RequirementDefinition> reqList : reqMap.values()) {
1529 Optional<RequirementDefinition> reqOpt = reqList.stream().filter(
1530 r -> isRequirementBelongToRelation(fromOriginComponent, reqAndRelationshipPair, r, fromInstanceId))
1532 if (reqOpt.isPresent()) {
1536 return Optional.empty();
1540 * Allows detecting the requirement belonging to the received relationship The detection logic is: A requirement belongs to a relationship IF
1541 * 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
1542 * requirement equals to requirementOwnerId of the relation OR uniqueId of toInstance equals to capabilityOwnerId of the relation
1544 private boolean isRequirementBelongToRelation(Component originComponent, RelationshipInfo reqAndRelationshipPair,
1545 RequirementDefinition requirement, String fromInstanceId) {
1546 if (!StringUtils.equals(requirement.getName(), reqAndRelationshipPair.getRequirement())) {
1547 log.debug("Failed to find a requirement with name {} and reqAndRelationshipPair {}", requirement.getName(),
1548 reqAndRelationshipPair.getRequirement());
1551 return ModelConverter.isAtomicComponent(originComponent) || isRequirementBelongToOwner(reqAndRelationshipPair, requirement, fromInstanceId,
1555 private boolean isRequirementBelongToOwner(RelationshipInfo reqAndRelationshipPair, RequirementDefinition requirement, String fromInstanceId,
1556 Component originComponent) {
1557 return StringUtils.equals(requirement.getOwnerId(), reqAndRelationshipPair.getRequirementOwnerId()) || (
1558 isCvfc(originComponent) && StringUtils.equals(fromInstanceId, reqAndRelationshipPair.getRequirementOwnerId()) || StringUtils
1559 .equals(requirement.getOwnerId(), originComponent.getUniqueId()));
1562 private boolean isCvfc(Component component) {
1563 return component.getComponentType() == ComponentTypeEnum.RESOURCE && ((Resource) component).getResourceType() == ResourceTypeEnum.CVFC;
1566 private Either<Map<String, String[]>, ToscaError> convertSubstitutionMappingCapabilities(final Component component,
1567 final Map<String, Component> componentCache) {
1568 Either<Map<String, String[]>, ToscaError> toscaCapabilitiesRes =
1569 capabilityRequirementConverter.convertSubstitutionMappingCapabilities(componentCache, component);
1570 if (toscaCapabilitiesRes.isRight()) {
1571 log.debug("Failed convert capabilities for the component {}. ", component.getName());
1572 return Either.right(toscaCapabilitiesRes.right().value());
1574 if (isNotEmpty(toscaCapabilitiesRes.left().value())) {
1575 log.debug("Finish convert capabilities for the component {}. ", component.getName());
1576 return Either.left(toscaCapabilitiesRes.left().value());
1578 log.debug("Finished to convert capabilities for the component {}. ", component.getName());
1580 return Either.left(Collections.emptyMap());
1583 private Either<ToscaNodeType, ToscaError> convertCapabilities(Map<String, Component> componentsCache, Component component, ToscaNodeType nodeType,
1584 Map<String, DataTypeDefinition> dataTypes) {
1585 Map<String, ToscaCapability> toscaCapabilities = capabilityRequirementConverter.convertCapabilities(componentsCache, component, dataTypes);
1586 if (!toscaCapabilities.isEmpty()) {
1587 nodeType.setCapabilities(toscaCapabilities);
1589 log.debug("Finish convert Capabilities for node type");
1590 return Either.left(nodeType);
1593 private Map<String, ToscaTemplateArtifact> convertToNodeTemplateArtifacts(Map<String, ToscaArtifactDataDefinition> artifacts) {
1594 if (artifacts == null) {
1597 Map<String, ToscaTemplateArtifact> arts = new HashMap<>();
1598 for (Map.Entry<String, ToscaArtifactDataDefinition> entry : artifacts.entrySet()) {
1599 ToscaTemplateArtifact artifact = new ToscaTemplateArtifact();
1600 artifact.setFile(entry.getValue().getFile());
1601 artifact.setType(entry.getValue().getType());
1602 artifact.setProperties(entry.getValue().getProperties());
1603 arts.put(entry.getKey(), artifact);
1608 private NodeFilter convertToNodeTemplateNodeFilterComponent(CINodeFilterDataDefinition inNodeFilter) {
1609 if (inNodeFilter == null) {
1612 NodeFilter nodeFilter = new NodeFilter();
1613 ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities = inNodeFilter.getCapabilities();
1614 ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> origProperties = inNodeFilter.getProperties();
1615 List<Map<String, CapabilityFilter>> capabilitiesCopy = new ArrayList<>();
1616 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1617 copyNodeFilterCapabilitiesTemplate(origCapabilities, capabilitiesCopy);
1618 copyNodeFilterProperties(origProperties, propertiesCopy);
1619 if (CollectionUtils.isNotEmpty(capabilitiesCopy)) {
1620 nodeFilter.setCapabilities(capabilitiesCopy);
1622 if (CollectionUtils.isNotEmpty(propertiesCopy)) {
1623 nodeFilter.setProperties(propertiesCopy);
1625 nodeFilter.setTosca_id(cloneToscaId(inNodeFilter.getTosca_id()));
1626 nodeFilter = (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
1630 private NodeFilter convertToSubstitutionFilterComponent(final SubstitutionFilterDataDefinition substitutionFilterDataDefinition) {
1631 if (substitutionFilterDataDefinition == null) {
1634 NodeFilter nodeFilter = new NodeFilter();
1635 ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> origProperties = substitutionFilterDataDefinition.getProperties();
1636 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1637 copySubstitutionFilterProperties(origProperties, propertiesCopy);
1638 if (CollectionUtils.isNotEmpty(propertiesCopy)) {
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 CapabilityFilter capabilityFilter = new CapabilityFilter();
1663 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1664 copyNodeFilterProperties(capability.getProperties(), propertiesCopy);
1665 capabilityFilter.setProperties(propertiesCopy);
1666 capabilityFilterCopyMap.put(capability.getName(), capabilityFilter);
1667 capabilitiesCopy.add(capabilityFilterCopyMap);
1671 private void copyNodeFilterProperties(ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> origProperties,
1672 List<Map<String, List<Object>>> propertiesCopy) {
1673 if (origProperties == null || origProperties.getListToscaDataDefinition() == null || origProperties.isEmpty()) {
1676 Map<String, List<Object>> propertyMapCopy = new HashMap<>();
1677 for (RequirementNodeFilterPropertyDataDefinition propertyDataDefinition : origProperties.getListToscaDataDefinition()) {
1678 for (String propertyInfoEntry : propertyDataDefinition.getConstraints()) {
1679 Map<String, List<Object>> propertyValObj = new YamlUtil().yamlToObject(propertyInfoEntry, Map.class);
1680 String propertyName = propertyDataDefinition.getName();
1681 if (propertyMapCopy.containsKey(propertyName)) {
1682 addPropertyConstraintValueToList(propertyName, propertyValObj, propertyMapCopy.get(propertyName));
1684 if (propertyName != null) {
1685 List<Object> propsList = new ArrayList<>();
1686 addPropertyConstraintValueToList(propertyName, propertyValObj, propsList);
1687 propertyMapCopy.put(propertyName, propsList);
1689 propertyMapCopy.putAll(propertyValObj);
1694 propertyMapCopy.entrySet().stream().forEach(entry -> addCalculatedConstraintsIntoPropertiesList(propertiesCopy, entry));
1697 private void copySubstitutionFilterProperties(final ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> origProperties,
1698 final List<Map<String, List<Object>>> propertiesCopy) {
1699 if (origProperties == null || origProperties.getListToscaDataDefinition() == null || origProperties.isEmpty()) {
1702 final Map<String, List<Object>> propertyMapCopy = new HashMap<>();
1703 for (final RequirementSubstitutionFilterPropertyDataDefinition propertyDataDefinition : origProperties.getListToscaDataDefinition()) {
1704 for (final String propertyInfoEntry : propertyDataDefinition.getConstraints()) {
1705 final Map<String, List<Object>> propertyValObj = new YamlUtil().yamlToObject(propertyInfoEntry, Map.class);
1706 final String propertyName = propertyDataDefinition.getName();
1707 if (propertyMapCopy.containsKey(propertyName)) {
1708 addPropertyConstraintValueToList(propertyName, propertyValObj, propertyMapCopy.get(propertyName));
1710 if (propertyName != null) {
1711 final List<Object> propsList = new ArrayList<>();
1712 addPropertyConstraintValueToList(propertyName, propertyValObj, propsList);
1713 propertyMapCopy.put(propertyName, propsList);
1715 propertyMapCopy.putAll(propertyValObj);
1720 propertyMapCopy.entrySet().forEach(entry -> addCalculatedConstraintsIntoPropertiesList(propertiesCopy, entry));
1723 private void addPropertyConstraintValueToList(String propertyName, Map<String, List<Object>> propertyValObj, List<Object> propsList) {
1724 if (propertyValObj.containsKey(propertyName)) {
1725 propsList.add(propertyValObj.get(propertyName));
1727 propsList.add(propertyValObj);
1731 private void addCalculatedConstraintsIntoPropertiesList(List<Map<String, List<Object>>> propertiesCopy, Entry<String, List<Object>> entry) {
1732 Map<String, List<Object>> tempMap = new HashMap<>();
1733 tempMap.put(entry.getKey(), entry.getValue());
1734 propertiesCopy.add(tempMap);
1737 private Map<String, String[]> buildSubstitutionMappingPropertyMapping(final Component component) {
1738 if (component == null || CollectionUtils.isEmpty(component.getInputs())) {
1739 return Collections.emptyMap();
1741 return component.getInputs().stream().filter(InputDefinition::isMappedToComponentProperty).map(PropertyDataDefinition::getName)
1742 .collect(Collectors.toMap(inputName -> inputName, inputName -> new String[]{inputName}, (inputName1, inputName2) -> inputName1));
1745 private Map<String, String[]> buildSubstitutionMappingAttributesMapping(final Component component) {
1746 if (component == null || CollectionUtils.isEmpty(component.getOutputs())) {
1747 return Collections.emptyMap();
1749 return component.getOutputs().stream().map(AttributeDataDefinition::getName)
1750 .collect(Collectors.toMap(outputName -> outputName, outputName -> new String[]{outputName}, (outputName1, outputName2) -> outputName1));
1753 private Optional<Map<String, ToscaProperty>> getProxyNodeTypeProperties(Component proxyComponent, Map<String, DataTypeDefinition> dataTypes) {
1754 if (Objects.isNull(proxyComponent)) {
1755 return Optional.empty();
1757 final var proxyProperties = convertInputsToProperties(dataTypes, proxyComponent.getInputs(), proxyComponent.getUniqueId());
1758 if (CollectionUtils.isNotEmpty(proxyComponent.getProperties())) {
1759 proxyProperties.putAll(proxyComponent.getProperties().stream()
1760 .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, proxyComponent.getInputs())).collect(Collectors
1761 .toMap(PropertyDataDefinition::getName,
1762 property -> propertyConvertor.convertProperty(dataTypes, property, PropertyType.PROPERTY))));
1764 return MapUtils.isNotEmpty(proxyProperties) ? Optional.of(proxyProperties) : Optional.empty();
1767 private Map<String, ToscaProperty> convertInputsToProperties(Map<String, DataTypeDefinition> dataTypes, List<InputDefinition> componentInputs,
1768 String componentUniqueId) {
1769 if (CollectionUtils.isEmpty(componentInputs)) {
1770 return new HashMap<>();
1772 return componentInputs.stream().filter(input -> componentUniqueId.equals(input.getInstanceUniqueId()))
1773 .collect(Collectors.toMap(InputDefinition::getName, i -> propertyConvertor.convertProperty(dataTypes, i, PropertyType.INPUT)));
1776 private Optional<Map<String, Object>> getProxyNodeTypeInterfaces(Component proxyComponent, Map<String, DataTypeDefinition> dataTypes) {
1777 if (Objects.isNull(proxyComponent) || MapUtils.isEmpty(proxyComponent.getInterfaces())) {
1778 return Optional.empty();
1780 Map<String, InterfaceDefinition> proxyComponentInterfaces = proxyComponent.getInterfaces();
1781 //Unset artifact path for operation implementation for proxy node types as for operations with artifacts it is
1783 // always available in the proxy node template
1784 removeOperationImplementationForProxyNodeType(proxyComponentInterfaces);
1786 .ofNullable(interfacesOperationsConverter.getInterfacesMap(proxyComponent, null, proxyComponentInterfaces, dataTypes, false, false));
1789 private static class CustomRepresenter extends Representer {
1791 CustomRepresenter() {
1793 this.representers.put(ToscaPropertyAssignment.class, new RepresentToscaPropertyAssignment());
1794 this.representers.put(ToscaAttribute.class, new RepresentToscaAttribute());
1795 // null representer is exceptional and it is stored as an instance
1798 this.nullRepresenter = new RepresentNull();
1801 public boolean validateGetInputValue(final Object valueObj) {
1802 if (!(valueObj instanceof List) && !(valueObj instanceof String)) {
1805 if (valueObj instanceof List) {
1806 return ((List) valueObj).size() > 1;
1811 public boolean validateGetPropertyOrAttributeValue(final Object valueObj) {
1812 if (valueObj instanceof List) {
1813 return ((List) valueObj).size() > 1;
1819 protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue, Tag customTag) {
1820 if (propertyValue == null) {
1823 // skip not relevant for Tosca property
1824 if ("dependencies".equals(property.getName())) {
1827 if (javaBean instanceof ToscaRelationshipTemplate && "name".equals(property.getName())) {
1830 removeDefaultP(propertyValue);
1831 NodeTuple defaultNode = super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
1832 if (javaBean instanceof ToscaTopolgyTemplate && "relationshipTemplates".equals(property.getName())) {
1833 return new NodeTuple(representData("relationship_templates"), defaultNode.getValueNode());
1835 return "_defaultp_".equals(property.getName()) ? new NodeTuple(representData("default"), defaultNode.getValueNode()) : defaultNode;
1838 private void removeDefaultP(final Object propertyValue) {
1839 if (propertyValue instanceof Map) {
1840 final Map mapPropertyValue = ((Map) propertyValue);
1841 final Iterator<Entry> iter = mapPropertyValue.entrySet().iterator();
1842 Object defaultValue = null;
1843 while (iter.hasNext()) {
1844 final Map.Entry entry = iter.next();
1845 if ("_defaultp_".equals(entry.getKey())) {
1846 defaultValue = entry.getValue();
1848 } else if (entry.getValue() instanceof Map) {
1849 removeDefaultP(entry.getValue());
1852 if (defaultValue != null) {
1853 mapPropertyValue.putIfAbsent("default", defaultValue);
1859 protected MappingNode representJavaBean(Set<Property> properties, Object javaBean) {
1860 // remove the bean type from the output yaml (!! ...)
1861 if (!classTags.containsKey(javaBean.getClass())) {
1862 addClassTag(javaBean.getClass(), Tag.MAP);
1864 return super.representJavaBean(properties, javaBean);
1867 private class RepresentToscaAttribute implements Represent {
1870 public Node representData(Object data) {
1871 final ToscaAttribute toscaAttribute = (ToscaAttribute) data;
1872 return represent(toscaAttribute.asToscaMap());
1876 private class RepresentToscaPropertyAssignment implements Represent {
1878 public Node representData(Object data) {
1879 final ToscaPropertyAssignment toscaOperationAssignment = (ToscaPropertyAssignment) data;
1880 if (toscaOperationAssignment.getValue() instanceof String) {
1881 final String stringValue = (String) toscaOperationAssignment.getValue();
1882 if (isPropertyOrAttributeFunction(stringValue)) {
1883 return representGetAttribute(stringValue);
1885 return representScalar(Tag.STR, stringValue);
1887 return represent(null);
1890 public Node representGetAttribute(final String getAttributeFunction) {
1891 return represent(new Yaml().load(getAttributeFunction));
1894 public boolean isPropertyOrAttributeFunction(final String value) {
1896 final Yaml yaml = new Yaml();
1897 final Object yamlObj = yaml.load(value);
1898 if (!(yamlObj instanceof Map)) {
1901 final Map<String, Object> getAttributeMap = (Map) yamlObj;
1902 if (getAttributeMap.size() != 1) {
1905 final List<String> functionList = Arrays
1906 .asList(GET_ATTRIBUTE.getFunctionName(), GET_INPUT.getFunctionName(), GET_PROPERTY.getFunctionName());
1907 final Optional<String> function = getAttributeMap.keySet().stream()
1908 .filter(key -> functionList.stream().anyMatch(function1 -> function1.equals(key))).findFirst();
1909 if (function.isEmpty()) {
1912 final String functionName = function.get();
1913 final Object getAttributeValueObj = getAttributeMap.get(functionName);
1914 if (GET_INPUT.getFunctionName().equals(functionName)) {
1915 return validateGetInputValue(getAttributeValueObj);
1917 return validateGetPropertyOrAttributeValue(getAttributeValueObj);
1919 } catch (final Exception ignored) {
1925 private class RepresentNull implements Represent {
1928 public Node representData(Object data) {
1929 // possible values are here http://yaml.org/type/null.html
1930 return representScalar(Tag.NULL, "");
1935 private static class UnsortedPropertyUtils extends PropertyUtils {
1938 protected Set<Property> createPropertySet(Class type, BeanAccess bAccess) {
1939 Collection<Property> fields = getPropertiesMap(type, BeanAccess.FIELD).values();
1940 return new LinkedHashSet<>(fields);
1944 private Configuration getConfiguration() {
1945 return ConfigurationManager.getConfigurationManager().getConfiguration();