2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
20 package org.openecomp.sdc.be.tosca;
22 import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
23 import static org.apache.commons.collections.MapUtils.isNotEmpty;
24 import static org.openecomp.sdc.be.components.utils.PropertiesUtils.resolvePropertyValueFromInput;
25 import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_ATTRIBUTE;
26 import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_INPUT;
27 import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_PROPERTY;
29 import com.fasterxml.jackson.databind.ObjectMapper;
30 import com.google.common.primitives.Ints;
31 import com.google.gson.JsonElement;
32 import com.google.gson.JsonObject;
33 import com.google.gson.JsonParser;
34 import com.google.gson.stream.JsonReader;
35 import fj.data.Either;
36 import java.io.StringReader;
37 import java.nio.file.Path;
38 import java.util.ArrayList;
39 import java.util.Arrays;
40 import java.util.Collection;
41 import java.util.Collections;
42 import java.util.HashMap;
43 import java.util.HashSet;
44 import java.util.Iterator;
45 import java.util.LinkedHashMap;
46 import java.util.LinkedHashSet;
47 import java.util.List;
49 import java.util.Map.Entry;
50 import java.util.Objects;
51 import java.util.Optional;
53 import java.util.function.Supplier;
54 import java.util.stream.Collectors;
55 import org.apache.commons.collections.CollectionUtils;
56 import org.apache.commons.collections.MapUtils;
57 import org.apache.commons.io.FilenameUtils;
58 import org.apache.commons.lang3.StringUtils;
59 import org.apache.commons.lang3.tuple.ImmutablePair;
60 import org.apache.commons.lang3.tuple.ImmutableTriple;
61 import org.apache.commons.lang3.tuple.Triple;
62 import org.onap.sdc.tosca.services.YamlUtil;
63 import org.openecomp.sdc.be.components.impl.exceptions.SdcResourceNotFoundException;
64 import org.openecomp.sdc.be.config.Configuration;
65 import org.openecomp.sdc.be.config.ConfigurationManager;
66 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
67 import org.openecomp.sdc.be.data.model.ToscaImportByModel;
68 import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
69 import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition;
70 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
71 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
72 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
73 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
74 import org.openecomp.sdc.be.datatypes.elements.PropertyFilterConstraintDataDefinition;
75 import org.openecomp.sdc.be.datatypes.elements.PropertyFilterDataDefinition;
76 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition;
77 import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition;
78 import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterPropertyDataDefinition;
79 import org.openecomp.sdc.be.datatypes.elements.ToscaArtifactDataDefinition;
80 import org.openecomp.sdc.be.datatypes.elements.ToscaFunction;
81 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
82 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
83 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
84 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
85 import org.openecomp.sdc.be.exception.ToscaExportException;
86 import org.openecomp.sdc.be.model.ArtifactDefinition;
87 import org.openecomp.sdc.be.model.AttributeDefinition;
88 import org.openecomp.sdc.be.model.CapabilityDefinition;
89 import org.openecomp.sdc.be.model.CapabilityRequirementRelationship;
90 import org.openecomp.sdc.be.model.Component;
91 import org.openecomp.sdc.be.model.ComponentInstance;
92 import org.openecomp.sdc.be.model.ComponentInstanceAttribute;
93 import org.openecomp.sdc.be.model.ComponentInstanceInput;
94 import org.openecomp.sdc.be.model.ComponentInstanceInterface;
95 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
96 import org.openecomp.sdc.be.model.ComponentParametersView;
97 import org.openecomp.sdc.be.model.DataTypeDefinition;
98 import org.openecomp.sdc.be.model.GroupInstance;
99 import org.openecomp.sdc.be.model.InputDefinition;
100 import org.openecomp.sdc.be.model.InterfaceDefinition;
101 import org.openecomp.sdc.be.model.PropertyDefinition;
102 import org.openecomp.sdc.be.model.RelationshipInfo;
103 import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
104 import org.openecomp.sdc.be.model.RequirementDefinition;
105 import org.openecomp.sdc.be.model.Resource;
106 import org.openecomp.sdc.be.model.Service;
107 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
108 import org.openecomp.sdc.be.model.category.CategoryDefinition;
109 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
110 import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter;
111 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
112 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
113 import org.openecomp.sdc.be.model.operations.impl.ModelOperation;
114 import org.openecomp.sdc.be.model.tosca.converters.ToscaMapValueConverter;
115 import org.openecomp.sdc.be.tosca.PropertyConvertor.PropertyType;
116 import org.openecomp.sdc.be.tosca.builder.ToscaRelationshipBuilder;
117 import org.openecomp.sdc.be.tosca.exception.ToscaConversionException;
118 import org.openecomp.sdc.be.tosca.model.CapabilityFilter;
119 import org.openecomp.sdc.be.tosca.model.NodeFilter;
120 import org.openecomp.sdc.be.tosca.model.SubstitutionMapping;
121 import org.openecomp.sdc.be.tosca.model.ToscaAttribute;
122 import org.openecomp.sdc.be.tosca.model.ToscaCapability;
123 import org.openecomp.sdc.be.tosca.model.ToscaDataType;
124 import org.openecomp.sdc.be.tosca.model.ToscaGroupTemplate;
125 import org.openecomp.sdc.be.tosca.model.ToscaNodeTemplate;
126 import org.openecomp.sdc.be.tosca.model.ToscaNodeType;
127 import org.openecomp.sdc.be.tosca.model.ToscaPolicyTemplate;
128 import org.openecomp.sdc.be.tosca.model.ToscaProperty;
129 import org.openecomp.sdc.be.tosca.model.ToscaPropertyAssignment;
130 import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraint;
131 import org.openecomp.sdc.be.tosca.model.ToscaRelationshipTemplate;
132 import org.openecomp.sdc.be.tosca.model.ToscaRequirement;
133 import org.openecomp.sdc.be.tosca.model.ToscaTemplate;
134 import org.openecomp.sdc.be.tosca.model.ToscaTemplateArtifact;
135 import org.openecomp.sdc.be.tosca.model.ToscaTemplateRequirement;
136 import org.openecomp.sdc.be.tosca.model.ToscaTopolgyTemplate;
137 import org.openecomp.sdc.be.tosca.utils.ForwardingPathToscaUtil;
138 import org.openecomp.sdc.be.tosca.utils.InputConverter;
139 import org.openecomp.sdc.be.tosca.utils.OutputConverter;
140 import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
141 import org.openecomp.sdc.common.log.wrappers.Logger;
142 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
143 import org.springframework.beans.factory.annotation.Autowired;
144 import org.yaml.snakeyaml.DumperOptions;
145 import org.yaml.snakeyaml.DumperOptions.FlowStyle;
146 import org.yaml.snakeyaml.Yaml;
147 import org.yaml.snakeyaml.introspector.BeanAccess;
148 import org.yaml.snakeyaml.introspector.Property;
149 import org.yaml.snakeyaml.introspector.PropertyUtils;
150 import org.yaml.snakeyaml.nodes.MappingNode;
151 import org.yaml.snakeyaml.nodes.Node;
152 import org.yaml.snakeyaml.nodes.NodeTuple;
153 import org.yaml.snakeyaml.nodes.Tag;
154 import org.yaml.snakeyaml.representer.Represent;
155 import org.yaml.snakeyaml.representer.Representer;
157 @org.springframework.stereotype.Component("tosca-export-handler")
158 public class ToscaExportHandler {
160 public static final String ASSET_TOSCA_TEMPLATE = "assettoscatemplate";
161 private static final Logger log = Logger.getLogger(ToscaExportHandler.class);
162 private static final String INVARIANT_UUID = "invariantUUID";
163 private static final String TOSCA_VERSION = "tosca_simple_yaml_1_3";
164 private static final String SERVICE_NODE_TYPE_PREFIX = "org.openecomp.service.";
165 private static final String IMPORTS_FILE_KEY = "file";
166 private static final String TOSCA_INTERFACE_NAME = "-interface.yml";
167 private static final String FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION = "convertToToscaTemplate - failed to get Default Imports section from configuration";
168 private static final String NOT_SUPPORTED_COMPONENT_TYPE = "Not supported component type {}";
169 private static final String NATIVE_ROOT = "tosca.nodes.Root";
170 private static final List<String> EXCLUDED_CATEGORY_SPECIFIC_METADATA = List
171 .of("Service Function", "Service Role", "Naming Policy", "Service Type");
172 private static final YamlUtil yamlUtil = new YamlUtil();
173 private final ApplicationDataTypeCache applicationDataTypeCache;
174 private final ToscaOperationFacade toscaOperationFacade;
175 private final CapabilityRequirementConverter capabilityRequirementConverter;
176 private final PolicyExportParser policyExportParser;
177 private final GroupExportParser groupExportParser;
178 private final PropertyConvertor propertyConvertor;
179 private final AttributeConverter attributeConverter;
180 private final InputConverter inputConverter;
181 private final OutputConverter outputConverter;
182 private final InterfaceLifecycleOperation interfaceLifecycleOperation;
183 private final InterfacesOperationsConverter interfacesOperationsConverter;
184 private final ModelOperation modelOperation;
187 public ToscaExportHandler(final ApplicationDataTypeCache applicationDataTypeCache,
188 final ToscaOperationFacade toscaOperationFacade,
189 final CapabilityRequirementConverter capabilityRequirementConverter,
190 final PolicyExportParser policyExportParser,
191 final GroupExportParser groupExportParser,
192 final PropertyConvertor propertyConvertor,
193 final AttributeConverter attributeConverter,
194 final InputConverter inputConverter,
195 final OutputConverter outputConverter,
196 final InterfaceLifecycleOperation interfaceLifecycleOperation,
197 final InterfacesOperationsConverter interfacesOperationsConverter,
198 final ModelOperation modelOperation) {
199 this.applicationDataTypeCache = applicationDataTypeCache;
200 this.toscaOperationFacade = toscaOperationFacade;
201 this.capabilityRequirementConverter = capabilityRequirementConverter;
202 this.policyExportParser = policyExportParser;
203 this.groupExportParser = groupExportParser;
204 this.propertyConvertor = propertyConvertor;
205 this.attributeConverter = attributeConverter;
206 this.inputConverter = inputConverter;
207 this.outputConverter = outputConverter;
208 this.interfaceLifecycleOperation = interfaceLifecycleOperation;
209 this.interfacesOperationsConverter = interfacesOperationsConverter;
210 this.modelOperation = modelOperation;
213 public static String getInterfaceFilename(String artifactName) {
214 return artifactName.substring(0, artifactName.lastIndexOf('.')) + TOSCA_INTERFACE_NAME;
217 private static void removeOperationImplementationForProxyNodeType(Map<String, InterfaceDefinition> proxyComponentInterfaces) {
218 if (MapUtils.isEmpty(proxyComponentInterfaces)) {
221 proxyComponentInterfaces.values().stream().map(InterfaceDataDefinition::getOperations).filter(MapUtils::isNotEmpty)
222 .forEach(operations -> operations.values().forEach(operation -> operation.setImplementation(null)));
225 public Either<ToscaRepresentation, ToscaError> exportComponent(Component component) {
226 return convertToToscaTemplate(component).left().map(this::createToscaRepresentation);
229 public Either<ToscaRepresentation, ToscaError> exportComponentInterface(final Component component, final boolean isAssociatedComponent) {
230 final List<Map<String, Map<String, String>>> imports = new ArrayList<>(getDefaultToscaImports(component.getModel()));
231 if (CollectionUtils.isEmpty(imports)) {
232 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
233 return Either.right(ToscaError.GENERAL_ERROR);
235 List<Triple<String, String, Component>> dependencies = new ArrayList<>();
236 if (component.getDerivedFromGenericType() != null && !component.getDerivedFromGenericType()
237 .startsWith("org.openecomp.resource.abstract.nodes.")) {
238 final Either<Component, StorageOperationStatus> baseType = toscaOperationFacade
239 .getByToscaResourceNameAndVersion(component.getDerivedFromGenericType(), component.getDerivedFromGenericVersion(),
240 component.getModel());
241 if (baseType.isLeft() && baseType.left().value() != null) {
242 addDependencies(imports, dependencies, baseType.left().value());
244 log.debug("Failed to fetch derived from type {}", component.getDerivedFromGenericType());
248 String toscaVersion = null;
249 if (component instanceof Resource) {
250 toscaVersion = ((Resource) component).getToscaVersion();
252 ToscaTemplate toscaTemplate = new ToscaTemplate(toscaVersion != null ? toscaVersion : TOSCA_VERSION);
253 toscaTemplate.setImports(imports);
254 final Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
255 final Either<ToscaTemplate, ToscaError> toscaTemplateRes = convertInterfaceNodeType(new HashMap<>(), component, toscaTemplate, nodeTypes,
256 isAssociatedComponent);
257 if (toscaTemplateRes.isRight()) {
258 return Either.right(toscaTemplateRes.right().value());
260 toscaTemplate = toscaTemplateRes.left().value();
261 toscaTemplate.setDependencies(dependencies);
262 ToscaRepresentation toscaRepresentation = this.createToscaRepresentation(toscaTemplate);
263 return Either.left(toscaRepresentation);
266 private ToscaRepresentation createToscaRepresentation(ToscaTemplate toscaTemplate) {
267 CustomRepresenter representer = new CustomRepresenter();
268 DumperOptions options = new DumperOptions();
269 options.setAllowReadOnlyProperties(false);
270 options.setPrettyFlow(true);
271 options.setDefaultFlowStyle(FlowStyle.FLOW);
272 options.setCanonical(false);
273 representer.addClassTag(toscaTemplate.getClass(), Tag.MAP);
274 representer.setPropertyUtils(new UnsortedPropertyUtils());
277 Yaml yaml = new Yaml(representer, options);
278 String yamlAsString = yaml.dumpAsMap(toscaTemplate);
279 StringBuilder sb = new StringBuilder();
280 sb.append(getConfiguration().getHeatEnvArtifactHeader());
281 sb.append(yamlAsString);
282 sb.append(getConfiguration().getHeatEnvArtifactFooter());
283 return ToscaRepresentation.make(sb.toString().getBytes(), toscaTemplate);
286 public Either<ToscaTemplate, ToscaError> getDependencies(Component component) {
287 ToscaTemplate toscaTemplate = new ToscaTemplate(null);
288 Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports = fillImports(component, toscaTemplate);
289 if (fillImports.isRight()) {
290 return Either.right(fillImports.right().value());
292 return Either.left(fillImports.left().value().left);
295 public Either<ToscaTemplate, ToscaError> convertToToscaTemplate(final Component component) {
296 final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImports(component.getModel());
297 if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
298 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
299 return Either.right(ToscaError.GENERAL_ERROR);
301 log.trace("start tosca export for {}", component.getUniqueId());
302 String toscaVersion = null;
303 if (component instanceof Resource) {
304 toscaVersion = ((Resource) component).getToscaVersion();
306 final ToscaTemplate toscaTemplate = new ToscaTemplate(toscaVersion != null ? toscaVersion : TOSCA_VERSION);
307 toscaTemplate.setMetadata(convertMetadata(component));
308 toscaTemplate.setImports(new ArrayList<>(defaultToscaImportConfig));
309 final Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
310 if (ModelConverter.isAtomicComponent(component)) {
311 log.trace("convert component as node type");
312 return convertNodeType(new HashMap<>(), component, toscaTemplate, nodeTypes);
314 log.trace("convert component as topology template");
315 return convertToscaTemplate(component, toscaTemplate);
319 private List<Map<String, Map<String, String>>> getDefaultToscaImports(final String modelId) {
320 if (modelId == null) {
321 return getDefaultToscaImportConfig();
324 final List<ToscaImportByModel> allModelImports = modelOperation.findAllModelImports(modelId, true);
325 final List<Map<String, Map<String, String>>> importList = new ArrayList<>();
326 final Set<Path> addedPathList = new HashSet<>();
327 for (final ToscaImportByModel toscaImportByModel : allModelImports) {
328 var importPath = Path.of(toscaImportByModel.getFullPath());
329 if (addedPathList.contains(importPath)) {
330 importPath = ToscaDefaultImportHelper.addModelAsFilePrefix(importPath, toscaImportByModel.getModelId());
332 final String fileName = FilenameUtils.getBaseName(importPath.toString());
333 importList.add(Map.of(fileName, Map.of("file", importPath.toString())));
334 addedPathList.add(importPath);
339 private Either<ToscaTemplate, ToscaError> convertToscaTemplate(Component component, ToscaTemplate toscaNode) {
340 Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> importsRes = fillImports(component, toscaNode);
341 if (importsRes.isRight()) {
342 return Either.right(importsRes.right().value());
344 toscaNode = importsRes.left().value().left;
345 Map<String, Component> componentCache = importsRes.left().value().right;
346 Either<Map<String, ToscaNodeType>, ToscaError> nodeTypesMapEither = createProxyNodeTypes(componentCache, component);
347 if (nodeTypesMapEither.isRight()) {
348 log.debug("Failed to fetch normative service proxy resource by tosca name, error {}", nodeTypesMapEither.right().value());
349 return Either.right(nodeTypesMapEither.right().value());
351 Map<String, ToscaNodeType> nodeTypesMap = nodeTypesMapEither.left().value();
352 if (nodeTypesMap != null && !nodeTypesMap.isEmpty()) {
353 toscaNode.setNode_types(nodeTypesMap);
355 createServiceSubstitutionNodeTypes(componentCache, component, toscaNode);
356 Either<Map<String, Object>, ToscaError> proxyInterfaceTypesEither = createProxyInterfaceTypes(component);
357 if (proxyInterfaceTypesEither.isRight()) {
358 log.debug("Failed to populate service proxy local interface types in tosca, error {}", nodeTypesMapEither.right().value());
359 return Either.right(proxyInterfaceTypesEither.right().value());
361 Map<String, Object> proxyInterfaceTypes = proxyInterfaceTypesEither.left().value();
362 if (MapUtils.isNotEmpty(proxyInterfaceTypes)) {
363 toscaNode.setInterface_types(proxyInterfaceTypes);
365 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = applicationDataTypeCache.getAll(component.getModel());
366 if (dataTypesEither.isRight()) {
367 log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
368 return Either.right(ToscaError.GENERAL_ERROR);
370 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
371 ToscaTopolgyTemplate topologyTemplate = new ToscaTopolgyTemplate();
372 List<InputDefinition> inputDef = component.getInputs();
373 Map<String, ToscaProperty> inputs = inputConverter.convertInputs(inputDef, dataTypes);
374 if (!inputs.isEmpty()) {
375 topologyTemplate.setInputs(inputs);
377 final Map<String, ToscaProperty> outputs;
379 outputs = outputConverter.convert(component.getOutputs(), dataTypes);
380 } catch (final ToscaConversionException e) {
381 log.error(EcompLoggerErrorCode.SCHEMA_ERROR, ToscaExportHandler.class.getName(),
382 "Could not parse component '{}' outputs. Component unique id '{}'.", component.getName(), component.getUniqueId(), e);
383 return Either.right(ToscaError.GENERAL_ERROR);
385 if (!outputs.isEmpty()) {
386 topologyTemplate.setOutputs(outputs);
388 if (CollectionUtils.isNotEmpty(component.getComponentInstances())) {
389 final Either<Map<String, ToscaNodeTemplate>, ToscaError> nodeTemplates =
390 convertNodeTemplates(component, componentCache, dataTypes, topologyTemplate);
391 if (nodeTemplates.isRight()) {
392 return Either.right(nodeTemplates.right().value());
394 log.debug("node templates converted");
395 topologyTemplate.setNode_templates(nodeTemplates.left().value());
397 final Map<String, ToscaRelationshipTemplate> relationshipTemplatesMap = new ToscaExportRelationshipTemplatesHandler()
398 .createFrom(topologyTemplate.getNode_templates());
399 if (!relationshipTemplatesMap.isEmpty()) {
400 topologyTemplate.setRelationshipTemplates(relationshipTemplatesMap);
402 addGroupsToTopologyTemplate(component, topologyTemplate);
404 addPoliciesToTopologyTemplate(component, topologyTemplate);
405 } catch (SdcResourceNotFoundException e) {
406 log.debug("Fail to add policies to topology template:", e);
407 return Either.right(ToscaError.GENERAL_ERROR);
410 createSubstitutionMapping(component, componentCache).ifPresent(topologyTemplate::setSubstitution_mappings);
411 } catch (final ToscaExportException e) {
412 log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, ToscaExportHandler.class.getName(), e.getMessage());
413 return Either.right(e.getToscaError());
415 if (!topologyTemplate.isEmpty()) {
416 toscaNode.setTopology_template(topologyTemplate);
418 return Either.left(toscaNode);
421 private Either<String, ToscaError> createComponentToscaName(final Component component) {
422 switch (component.getComponentType()) {
424 final ResourceMetadataDataDefinition resourceMetadata =
425 (ResourceMetadataDataDefinition) component.getComponentMetadataDefinition().getMetadataDataDefinition();
426 return Either.left(resourceMetadata.getToscaResourceName());
428 return Either.left(SERVICE_NODE_TYPE_PREFIX + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName());
430 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
431 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
435 private Optional<SubstitutionMapping> createSubstitutionMapping(final Component component,
436 final Map<String, Component> componentCache) throws ToscaExportException {
437 if (component instanceof Service && !((Service) component).isSubstituteCandidate()) {
438 return Optional.empty();
441 final Either<String, ToscaError> toscaResourceNameEither = createComponentToscaName(component);
442 if (toscaResourceNameEither.isRight()) {
443 throw new ToscaExportException("Could not create component TOSCA name", toscaResourceNameEither.right().value());
445 final String toscaResourceName = toscaResourceNameEither.left().value();
447 final SubstitutionMapping substitutionMapping = new SubstitutionMapping();
448 substitutionMapping.setNode_type(toscaResourceName);
449 convertSubstitutionMappingFilter(component).ifPresent(substitutionMapping::setSubstitution_filter);
451 final Either<Map<String, String[]>, ToscaError> capabilitiesEither = convertSubstitutionMappingCapabilities(component, componentCache);
452 if (capabilitiesEither.isRight()) {
453 throw new ToscaExportException("Could not convert substitution mapping capabilities", capabilitiesEither.right().value());
455 final Map<String, String[]> capabilityMap = capabilitiesEither.left().value();
456 if (!capabilityMap.isEmpty()) {
457 substitutionMapping.setCapabilities(capabilityMap);
460 final Either<Map<String, String[]>, ToscaError> requirements =
461 capabilityRequirementConverter.convertSubstitutionMappingRequirements(component, componentCache);
462 if (requirements.isRight()) {
463 throw new ToscaExportException("Could not convert substitution mapping requirements", requirements.right().value());
465 final Map<String, String[]> requirementMap = requirements.left().value();
466 if (MapUtils.isNotEmpty(requirementMap)) {
467 substitutionMapping.setRequirements(requirementMap);
470 final Map<String, String[]> propertyMappingMap = buildSubstitutionMappingPropertyMapping(component);
471 if (MapUtils.isNotEmpty(propertyMappingMap)) {
472 substitutionMapping.setProperties(propertyMappingMap);
475 final Map<String, String[]> attributesMappingMap = buildSubstitutionMappingAttributesMapping(component);
476 if (MapUtils.isNotEmpty(attributesMappingMap)) {
477 substitutionMapping.setAttributes(attributesMappingMap);
480 return Optional.of(substitutionMapping);
483 private Optional<NodeFilter> convertSubstitutionMappingFilter(final Component component) {
484 if (component.getSubstitutionFilter() == null || (component.getSubstitutionFilter().getProperties()).getListToscaDataDefinition() == null) {
485 return Optional.empty();
488 return Optional.ofNullable(convertToSubstitutionFilterComponent(component.getSubstitutionFilter()));
491 private void addGroupsToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate) {
492 Map<String, ToscaGroupTemplate> groups = groupExportParser.getGroups(component);
493 if (groups != null) {
494 topologyTemplate.addGroups(groups);
498 private void addPoliciesToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate) throws SdcResourceNotFoundException {
499 Map<String, ToscaPolicyTemplate> policies = policyExportParser.getPolicies(component);
500 if (policies != null) {
501 topologyTemplate.addPolicies(policies);
505 private Map<String, String> convertMetadata(Component component) {
506 return convertMetadata(component, false, null);
509 private Map<String, String> convertMetadata(Component component, boolean isInstance, ComponentInstance componentInstance) {
510 Map<String, String> toscaMetadata = new LinkedHashMap<>();
511 toscaMetadata.put(convertMetadataKey(JsonPresentationFields.INVARIANT_UUID), component.getInvariantUUID());
512 toscaMetadata.put(JsonPresentationFields.UUID.getPresentation(), component.getUUID());
514 .put(JsonPresentationFields.NAME.getPresentation(), component.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
515 toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), component.getDescription());
516 List<CategoryDefinition> categories = component.getCategories();
517 CategoryDefinition categoryDefinition = categories.get(0);
518 toscaMetadata.put(JsonPresentationFields.MODEL.getPresentation(), component.getModel());
519 toscaMetadata.put(JsonPresentationFields.CATEGORY.getPresentation(), categoryDefinition.getName());
521 toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), component.getVersion());
522 toscaMetadata.put(JsonPresentationFields.CUSTOMIZATION_UUID.getPresentation(), componentInstance.getCustomizationUUID());
523 if (componentInstance.getSourceModelInvariant() != null && !componentInstance.getSourceModelInvariant().isEmpty()) {
524 toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), componentInstance.getComponentVersion());
525 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_INVARIANT.getPresentation(), componentInstance.getSourceModelInvariant());
526 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_UUID.getPresentation(), componentInstance.getSourceModelUuid());
527 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_NAME.getPresentation(), componentInstance.getSourceModelName());
528 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
529 toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(),
530 componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceProxy.getDisplayValue());
531 } else if (componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
532 toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(),
533 componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceSubstitution.getDisplayValue());
535 toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), componentInstance.getDescription());
538 switch (component.getComponentType()) {
540 Resource resource = (Resource) component;
541 if (isInstance && (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy
542 || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution)) {
543 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), componentInstance.getOriginType().getDisplayValue());
545 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), resource.getResourceType().name());
547 toscaMetadata.put(JsonPresentationFields.SUB_CATEGORY.getPresentation(), categoryDefinition.getSubcategories().get(0).getName());
548 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR.getPresentation(), resource.getVendorName());
549 toscaMetadata.put(JsonPresentationFields.TENANT.getPresentation(), resource.getTenant());
550 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_RELEASE.getPresentation(), resource.getVendorRelease());
551 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_MODEL_NUMBER.getPresentation(), resource.getResourceVendorModelNumber());
554 Service service = (Service) component;
555 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), component.getComponentType().getValue());
556 toscaMetadata.put(JsonPresentationFields.SERVICE_TYPE.getPresentation(), service.getServiceType());
557 toscaMetadata.put(JsonPresentationFields.SERVICE_ROLE.getPresentation(), service.getServiceRole());
558 toscaMetadata.put(JsonPresentationFields.SERVICE_FUNCTION.getPresentation(), service.getServiceFunction());
559 toscaMetadata.put(JsonPresentationFields.ENVIRONMENT_CONTEXT.getPresentation(), service.getEnvironmentContext());
560 toscaMetadata.put(JsonPresentationFields.INSTANTIATION_TYPE.getPresentation(),
561 service.getEnvironmentContext() == null ? StringUtils.EMPTY : service.getInstantiationType());
564 toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming().toString());
565 toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming().toString());
566 toscaMetadata.put(JsonPresentationFields.NAMING_POLICY.getPresentation(), service.getNamingPolicy());
570 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
572 for (final String key : component.getCategorySpecificMetadata().keySet()) {
573 if (!EXCLUDED_CATEGORY_SPECIFIC_METADATA.contains(key)) {
574 toscaMetadata.put(key, component.getCategorySpecificMetadata().get(key));
577 return toscaMetadata;
580 private String convertMetadataKey(JsonPresentationFields jsonPresentationField) {
581 if (JsonPresentationFields.INVARIANT_UUID.equals(jsonPresentationField)) {
582 return INVARIANT_UUID;
584 return jsonPresentationField.getPresentation();
587 private Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports(Component component, ToscaTemplate toscaTemplate) {
588 final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImports(component.getModel());
589 if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
590 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
591 return Either.right(ToscaError.GENERAL_ERROR);
593 Map<String, Component> componentCache = new HashMap<>();
594 if (!ModelConverter.isAtomicComponent(component)) {
595 final List<Map<String, Map<String, String>>> additionalImports =
596 toscaTemplate.getImports() == null ? new ArrayList<>(defaultToscaImportConfig) : new ArrayList<>(toscaTemplate.getImports());
597 List<Triple<String, String, Component>> dependencies = new ArrayList<>();
598 Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
599 final Map<String, Map<String, String>> substituteTypeImportEntry = generateComponentSubstituteTypeImport(component, toscaArtifacts);
600 if (!substituteTypeImportEntry.isEmpty()) {
601 additionalImports.add(substituteTypeImportEntry);
603 List<ComponentInstance> componentInstances = component.getComponentInstances();
604 if (componentInstances != null && !componentInstances.isEmpty()) {
605 componentInstances.forEach(ci -> createDependency(componentCache, additionalImports, dependencies, ci));
607 toscaTemplate.setDependencies(dependencies);
608 toscaTemplate.setImports(additionalImports);
610 log.debug("currently imports supported for VF and service only");
612 return Either.left(new ImmutablePair<>(toscaTemplate, componentCache));
615 private Map<String, Map<String, String>> generateComponentSubstituteTypeImport(final Component component,
616 final Map<String, ArtifactDefinition> toscaArtifacts) {
618 if (component instanceof Service && !((Service) component).isSubstituteCandidate()) {
619 return Collections.emptyMap();
621 if (MapUtils.isEmpty(toscaArtifacts)) {
622 return Collections.emptyMap();
624 final ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE);
625 if (artifactDefinition == null) {
626 return Collections.emptyMap();
628 final var importEntryName = component.getComponentType().toString().toLowerCase() + "-" + component.getName() + "-interface";
629 return Map.of(importEntryName,
630 Map.of(IMPORTS_FILE_KEY, getInterfaceFilename(artifactDefinition.getArtifactName()))
634 private List<Map<String, Map<String, String>>> getDefaultToscaImportConfig() {
635 return getConfiguration().getDefaultImports();
638 private void createDependency(final Map<String, Component> componentCache, final List<Map<String, Map<String, String>>> imports,
639 final List<Triple<String, String, Component>> dependencies, final ComponentInstance componentInstance) {
640 log.debug("createDependency componentCache {}", componentCache);
641 Component componentRI = componentCache.get(componentInstance.getComponentUid());
642 if (componentRI == null || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
643 // all resource must be only once!
644 final Either<Component, StorageOperationStatus> resource = toscaOperationFacade.getToscaFullElement(componentInstance.getComponentUid());
645 if ((resource.isRight()) && (log.isDebugEnabled())) {
646 log.debug("Failed to fetch resource with id {} for instance {}", componentInstance.getComponentUid(),
647 componentInstance.getUniqueId());
650 final Component fetchedComponent = resource.left().value();
651 componentRI = setComponentCache(componentCache, componentInstance, fetchedComponent);
652 addDependencies(imports, dependencies, componentRI);
657 * Sets a componentCache from the given component/resource.
659 private Component setComponentCache(final Map<String, Component> componentCache, final ComponentInstance componentInstance,
660 final Component fetchedComponent) {
661 componentCache.put(fetchedComponent.getUniqueId(), fetchedComponent);
662 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy
663 || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
664 final Either<Component, StorageOperationStatus> sourceService = toscaOperationFacade
665 .getToscaFullElement(componentInstance.getSourceModelUid());
666 if (sourceService.isRight() && (log.isDebugEnabled())) {
667 log.debug("Failed to fetch source service with id {} for proxy {}", componentInstance.getSourceModelUid(),
668 componentInstance.getUniqueId());
670 final Component fetchedSource = sourceService.left().value();
671 componentCache.put(fetchedSource.getUniqueId(), fetchedSource);
672 return fetchedSource;
674 return fetchedComponent;
678 * Retrieves all derived_from nodes and stores it in a predictable order.
680 private void addDependencies(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
681 final Component fetchedComponent) {
682 final Set<Component> componentsList = new LinkedHashSet<>();
683 if (fetchedComponent instanceof Resource) {
684 log.debug("fetchedComponent is a resource {}", fetchedComponent);
685 final Optional<Map<String, String>> derivedFromMapOfIdToName = getDerivedFromMapOfIdToName(fetchedComponent, componentsList);
686 if (derivedFromMapOfIdToName.isPresent() && !derivedFromMapOfIdToName.get().isEmpty()) {
687 derivedFromMapOfIdToName.get().entrySet().forEach(entry -> {
688 log.debug("Started entry.getValue() : {}", entry.getValue());
689 if (!NATIVE_ROOT.equals(entry.getValue())) {
690 Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade.getToscaElement(entry.getKey());
691 if (resourcefetched != null && resourcefetched.isLeft()) {
692 componentsList.add(resourcefetched.left().value());
696 setImports(imports, dependencies, componentsList);
698 setImports(imports, dependencies, fetchedComponent);
704 * Returns all derived_from nodes found.
706 private Optional<Map<String, String>> getDerivedFromMapOfIdToName(final Component fetchedComponent, final Set<Component> componentsList) {
707 final Resource parentResource = (Resource) fetchedComponent;
708 Map<String, String> derivedFromMapOfIdToName = new HashMap<>();
709 if (CollectionUtils.isNotEmpty(parentResource.getComponentInstances())) {
710 componentsList.add(fetchedComponent);
711 for (final ComponentInstance componentInstance : parentResource.getComponentInstances()) {
712 final Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade
713 .getToscaElement(componentInstance.getComponentUid());
714 if (resourcefetched != null && resourcefetched.isLeft()) {
715 final Map<String, String> derivedWithId = resourcefetched.left().value().getDerivedFromMapOfIdToName();
716 if (MapUtils.isNotEmpty(derivedWithId)) {
717 derivedFromMapOfIdToName.putAll(derivedWithId);
722 derivedFromMapOfIdToName = parentResource.getDerivedFromMapOfIdToName();
724 log.debug("Started derivedFromMapOfIdToName: {}", derivedFromMapOfIdToName);
725 return Optional.ofNullable(derivedFromMapOfIdToName);
729 * Creates a resource map and adds it to the import list.
731 private void setImports(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
732 final Set<Component> componentsList) {
733 componentsList.forEach(component -> setImports(imports, dependencies, component));
736 private void setImports(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
737 final Component component) {
738 final Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
739 final ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE);
740 if (artifactDefinition != null) {
741 final Map<String, String> files = new HashMap<>();
742 final String artifactName = artifactDefinition.getArtifactName();
743 files.put(IMPORTS_FILE_KEY, artifactName);
744 final StringBuilder keyNameBuilder = new StringBuilder();
745 keyNameBuilder.append(component.getComponentType().toString().toLowerCase());
746 keyNameBuilder.append("-");
747 keyNameBuilder.append(component.getName());
748 addImports(imports, keyNameBuilder, files);
749 dependencies.add(new ImmutableTriple<>(artifactName, artifactDefinition.getEsId(), component));
750 if (!ModelConverter.isAtomicComponent(component)) {
751 final Map<String, String> interfaceFiles = new HashMap<>();
752 interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactName));
753 keyNameBuilder.append("-interface");
754 addImports(imports, keyNameBuilder, interfaceFiles);
760 * Adds the found resource to the import definition list.
762 private void addImports(final List<Map<String, Map<String, String>>> imports, final StringBuilder keyNameBuilder,
763 final Map<String, String> files) {
764 final String mapKey = keyNameBuilder.toString();
765 if (imports.stream().allMatch(stringMapMap -> stringMapMap.get(mapKey) == null)) {
766 final Map<String, Map<String, String>> importsListMember = new HashMap<>();
767 importsListMember.put(keyNameBuilder.toString(), files);
768 imports.add(importsListMember);
772 private Either<ToscaTemplate, ToscaError> convertNodeType(Map<String, Component> componentsCache, Component component, ToscaTemplate toscaNode,
773 Map<String, ToscaNodeType> nodeTypes) {
774 return convertInterfaceNodeType(componentsCache, component, toscaNode, nodeTypes, false);
777 public Either<ToscaTemplate, ToscaError> convertInterfaceNodeType(Map<String, Component> componentsCache, Component component,
778 ToscaTemplate toscaNode, Map<String, ToscaNodeType> nodeTypes,
779 boolean isAssociatedComponent) {
780 log.debug("start convert node type for {}", component.getUniqueId());
781 ToscaNodeType toscaNodeType = createNodeType(component);
782 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither = interfaceLifecycleOperation
783 .getAllInterfaceLifecycleTypes(component.getModel());
784 if (lifecycleTypeEither.isRight() && !StorageOperationStatus.NOT_FOUND.equals(lifecycleTypeEither.right().value())) {
785 log.debug("Failed to fetch all interface types :", lifecycleTypeEither.right().value());
786 return Either.right(ToscaError.GENERAL_ERROR);
788 if (lifecycleTypeEither.isLeft()) {
789 List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value().values().stream().map(InterfaceDataDefinition::getType)
790 .collect(Collectors.toList());
791 toscaNode.setInterface_types(interfacesOperationsConverter.addInterfaceTypeElement(component, allGlobalInterfaceTypes));
793 final var dataTypesEither = applicationDataTypeCache.getAll(component.getModel());
794 if (dataTypesEither.isRight()) {
795 log.debug("Failed to fetch all data types :", dataTypesEither.right().value());
796 return Either.right(ToscaError.GENERAL_ERROR);
798 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
799 List<InputDefinition> inputDef = component.getInputs();
800 interfacesOperationsConverter.addInterfaceDefinitionElement(component, toscaNodeType, dataTypes, isAssociatedComponent);
801 final var toscaAttributeMap = convertToToscaAttributes(component.getAttributes(), dataTypes);
802 if (!toscaAttributeMap.isEmpty()) {
803 toscaNodeType.setAttributes(toscaAttributeMap);
805 final var mergedProperties = convertInputsToProperties(dataTypes, inputDef, component.getUniqueId());
806 if (CollectionUtils.isNotEmpty(component.getProperties())) {
807 List<PropertyDefinition> properties = component.getProperties();
808 Map<String, ToscaProperty> convertedProperties = properties.stream()
809 .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, component.getInputs())).collect(Collectors
810 .toMap(PropertyDataDefinition::getName,
811 property -> propertyConvertor.convertProperty(dataTypes, property, PropertyConvertor.PropertyType.PROPERTY)));
812 // merge component properties and inputs properties
813 mergedProperties.putAll(convertedProperties);
815 if (MapUtils.isNotEmpty(mergedProperties)) {
816 toscaNodeType.setProperties(mergedProperties);
818 /* convert private data_types */
819 List<DataTypeDefinition> privateDataTypes = component.getDataTypes();
820 if (CollectionUtils.isNotEmpty(privateDataTypes)) {
821 Map<String, ToscaDataType> toscaDataTypeMap = new HashMap<>();
822 for (DataTypeDefinition dataType : privateDataTypes) {
823 log.debug("Emitting private data type: component.name={} dataType.name={}",
824 component.getNormalizedName(), dataType.getName());
825 ToscaDataType toscaDataType = new ToscaDataType();
826 toscaDataType.setDerived_from(dataType.getDerivedFromName());
827 toscaDataType.setDescription(dataType.getDescription());
828 toscaDataType.setVersion(dataType.getVersion());
829 if (CollectionUtils.isNotEmpty(dataType.getProperties())) {
830 toscaDataType.setProperties(dataType.getProperties().stream()
831 .collect(Collectors.toMap(
832 PropertyDataDefinition::getName,
833 s -> propertyConvertor.convertProperty(dataTypes, s, PropertyType.PROPERTY),
834 (toscaPropertyTobeValidated, toscaProperty) -> validateToscaProperty(privateDataTypes, toscaPropertyTobeValidated,
838 toscaDataTypeMap.put(dataType.getName(), toscaDataType);
840 toscaNode.setData_types(toscaDataTypeMap);
843 // Extracted to method for code reuse
844 return convertReqCapAndTypeName(componentsCache, component, toscaNode, nodeTypes, toscaNodeType, dataTypes);
847 private ToscaProperty validateToscaProperty(final List<DataTypeDefinition> privateDataTypes, final ToscaProperty toscaPropertyTobeValidated,
848 final ToscaProperty toscaProperty) {
849 final Optional<DataTypeDefinition> match = privateDataTypes.stream()
850 .filter(dataType -> dataType.getName().equals(toscaPropertyTobeValidated.getType())).findFirst();
851 return match.isPresent() ? toscaPropertyTobeValidated : toscaProperty;
854 private Map<String, ToscaAttribute> convertToToscaAttributes(final List<AttributeDefinition> attributeList,
855 final Map<String, DataTypeDefinition> dataTypes) {
856 if (CollectionUtils.isEmpty(attributeList)) {
857 return Collections.emptyMap();
859 final AttributeConverter converter = new AttributeConverter(dataTypes);
860 final Map<String, ToscaAttribute> toscaAttributeMap = new HashMap<>();
861 for (final AttributeDefinition attributeDefinition : attributeList) {
862 toscaAttributeMap.put(attributeDefinition.getName(), converter.convert(attributeDefinition));
864 return toscaAttributeMap;
867 private Either<ToscaTemplate, ToscaError> convertReqCapAndTypeName(Map<String, Component> componentsCache,
868 Component component, ToscaTemplate toscaNode,
869 Map<String, ToscaNodeType> nodeTypes,
870 ToscaNodeType toscaNodeType,
871 Map<String, DataTypeDefinition> dataTypes) {
872 Either<ToscaNodeType, ToscaError> capabilities = convertCapabilities(componentsCache, component, toscaNodeType,
874 if (capabilities.isRight()) {
875 return Either.right(capabilities.right().value());
877 toscaNodeType = capabilities.left().value();
878 log.debug("Capabilities converted for {}", component.getUniqueId());
880 Either<ToscaNodeType, ToscaError> requirements = capabilityRequirementConverter
881 .convertRequirements(componentsCache, component, toscaNodeType);
882 if (requirements.isRight()) {
883 return Either.right(requirements.right().value());
885 toscaNodeType = requirements.left().value();
886 log.debug("Requirements converted for {}", component.getUniqueId());
888 String toscaResourceName;
889 switch (component.getComponentType()) {
891 toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition()
892 .getMetadataDataDefinition()).getToscaResourceName();
895 toscaResourceName = SERVICE_NODE_TYPE_PREFIX
896 + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName();
899 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
900 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
903 nodeTypes.put(toscaResourceName, toscaNodeType);
904 toscaNode.setNode_types(nodeTypes);
905 log.debug("finish convert node type for {}", component.getUniqueId());
906 return Either.left(toscaNode);
909 private Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplates(final Component component,
910 final Map<String, Component> componentCache,
911 final Map<String, DataTypeDefinition> dataTypes,
912 final ToscaTopolgyTemplate topologyTemplate) {
914 final Map<String, List<ComponentInstanceProperty>> componentInstancesProperties = component.getComponentInstancesProperties();
915 final Map<String, List<ComponentInstanceAttribute>> componentInstancesAttributes = component.getComponentInstancesAttributes();
916 final Map<String, List<ComponentInstanceInput>> componentInstancesInputs = component.getComponentInstancesInputs();
917 final Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces = component.getComponentInstancesInterfaces();
918 final List<RequirementCapabilityRelDef> componentInstancesRelations = component.getComponentInstancesRelations();
920 Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplatesRes = null;
921 log.debug("start convert topology template for {} for type {}", component.getUniqueId(), component.getComponentType());
922 final Map<String, ToscaNodeTemplate> nodeTemplates = new HashMap<>();
924 Map<String, ToscaGroupTemplate> groupsMap = null;
925 for (final ComponentInstance componentInstance : component.getComponentInstances()) {
926 ToscaNodeTemplate nodeTemplate = new ToscaNodeTemplate();
927 if (MapUtils.isNotEmpty(componentInstance.getToscaArtifacts())) {
928 nodeTemplate.setArtifacts(convertToNodeTemplateArtifacts(componentInstance.getToscaArtifacts()));
930 if (componentInstance.getMinOccurrences() != null && componentInstance.getMaxOccurrences() != null) {
931 List<Object> occur = new ArrayList<>();
932 occur.add(parseToIntIfPossible(componentInstance.getMinOccurrences()));
933 occur.add(parseToIntIfPossible(componentInstance.getMaxOccurrences()));
934 nodeTemplate.setOccurrences(occur);
936 if (componentInstance.getInstanceCount() != null) {
937 ObjectMapper objectMapper = new ObjectMapper();
938 Object obj = convertToToscaObject(componentInstance.getInstanceCount());
940 Map<String, String> map = objectMapper.convertValue(obj, Map.class);
941 nodeTemplate.setInstance_count(map);
944 nodeTemplate.setType(componentInstance.getToscaComponentName());
945 nodeTemplate.setDirectives(componentInstance.getDirectives());
946 NodeFilter nodeFilter = convertToNodeTemplateNodeFilterComponent(componentInstance.getNodeFilter());
947 if(nodeFilter != null && nodeFilter.hasData()){
948 nodeTemplate.setNode_filter(nodeFilter);
950 final Either<Component, Boolean> originComponentRes = capabilityRequirementConverter
951 .getOriginComponent(componentCache, componentInstance);
952 if (originComponentRes.isRight()) {
953 convertNodeTemplatesRes = Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
956 final Either<ToscaNodeTemplate, ToscaError> requirements = convertComponentInstanceRequirements(component, componentInstance,
957 componentInstancesRelations, nodeTemplate, originComponentRes.left().value(), componentCache);
958 if (requirements.isRight()) {
959 convertNodeTemplatesRes = Either.right(requirements.right().value());
962 final String instanceUniqueId = componentInstance.getUniqueId();
963 log.debug("Component instance Requirements converted for instance {}", instanceUniqueId);
965 nodeTemplate = requirements.left().value();
967 final Component originalComponent = componentCache.get(componentInstance.getActualComponentUid());
969 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
970 final Component componentOfProxy = componentCache.get(componentInstance.getComponentUid());
971 nodeTemplate.setMetadata(convertMetadata(componentOfProxy, true, componentInstance));
973 nodeTemplate.setMetadata(convertMetadata(originalComponent, true, componentInstance));
976 final Either<ToscaNodeTemplate, ToscaError> capabilities =
977 capabilityRequirementConverter.convertComponentInstanceCapabilities(componentInstance, dataTypes, nodeTemplate);
978 if (capabilities.isRight()) {
979 convertNodeTemplatesRes = Either.right(capabilities.right().value());
982 log.debug("Component instance Capabilities converted for instance {}", instanceUniqueId);
984 nodeTemplate = capabilities.left().value();
985 final Map<String, Object> props = new HashMap<>();
986 final Map<String, Object> attribs = new HashMap<>();
988 if (originalComponent.getComponentType() == ComponentTypeEnum.RESOURCE) {
989 // Adds the properties of parent component to map
990 addPropertiesOfParentComponent(dataTypes, originalComponent, props);
991 addAttributesOfParentComponent(originalComponent, attribs);
994 if (null != componentInstancesProperties && componentInstancesProperties.containsKey(instanceUniqueId)) {
995 addPropertiesOfComponentInstance(componentInstancesProperties, dataTypes, instanceUniqueId, props);
997 if (null != componentInstancesAttributes && componentInstancesAttributes.containsKey(instanceUniqueId)) {
998 addAttributesOfComponentInstance(componentInstancesAttributes, instanceUniqueId, attribs);
1001 if (componentInstancesInputs != null
1002 && componentInstancesInputs.containsKey(instanceUniqueId)
1003 && !isComponentOfTypeServiceProxy(componentInstance)) {
1004 //For service proxy the inputs are already handled under instance properties above
1005 addComponentInstanceInputs(dataTypes, componentInstancesInputs, instanceUniqueId, props);
1008 //M3[00001] - NODE TEMPLATE INTERFACES - START
1009 handleInstanceInterfaces(componentInstanceInterfaces, componentInstance, dataTypes, nodeTemplate, instanceUniqueId, component);
1010 //M3[00001] - NODE TEMPLATE INTERFACES - END
1011 if (MapUtils.isNotEmpty(props)) {
1012 nodeTemplate.setProperties(props);
1014 if (MapUtils.isNotEmpty(attribs)) {
1015 nodeTemplate.setAttributes(attribs);
1018 final List<GroupInstance> groupInstances = componentInstance.getGroupInstances();
1019 if (CollectionUtils.isNotEmpty(groupInstances)) {
1020 if (groupsMap == null) {
1021 groupsMap = new HashMap<>();
1023 for (final GroupInstance groupInst : groupInstances) {
1024 if (CollectionUtils.isNotEmpty(groupInst.getArtifacts())) {
1025 groupsMap.put(groupInst.getName(), groupExportParser.getToscaGroupTemplate(groupInst, componentInstance.getInvariantName()));
1030 nodeTemplates.put(componentInstance.getName(), nodeTemplate);
1032 if (groupsMap != null) {
1033 log.debug("instance groups added");
1034 topologyTemplate.addGroups(groupsMap);
1036 if (component.getComponentType() == ComponentTypeEnum.SERVICE && isNotEmpty(
1037 ((Service) component).getForwardingPaths())) {
1038 log.debug("Starting converting paths for component {}, name {}", component.getUniqueId(), component.getName());
1039 ForwardingPathToscaUtil
1040 .addForwardingPaths((Service) component, nodeTemplates, capabilityRequirementConverter, componentCache, toscaOperationFacade);
1041 log.debug("Finished converting paths for component {}, name {}", component.getUniqueId(), component.getName());
1043 if (convertNodeTemplatesRes == null) {
1044 convertNodeTemplatesRes = Either.left(nodeTemplates);
1046 log.debug("finish convert topology template for {} for type {}", component.getUniqueId(), component.getComponentType());
1047 return convertNodeTemplatesRes;
1050 private Object convertToToscaObject(String value) {
1052 ToscaMapValueConverter mapConverterInst = ToscaMapValueConverter.getInstance();
1053 StringReader reader = new StringReader(value);
1054 JsonReader jsonReader = new JsonReader(reader);
1055 jsonReader.setLenient(true);
1056 JsonElement jsonElement = JsonParser.parseReader(jsonReader);
1057 if (jsonElement.isJsonObject()) {
1058 JsonObject jsonObj = jsonElement.getAsJsonObject();
1059 if (jsonObj.entrySet().size() == 1 && jsonObj.has(ToscaFunctions.GET_INPUT.getFunctionName())) {
1060 return mapConverterInst.handleComplexJsonValue(jsonElement);
1064 } catch (Exception e) {
1065 log.debug("convertToToscaValue failed to parse json value :", e);
1070 private Object parseToIntIfPossible(final String value) {
1071 final Integer intValue = Ints.tryParse(value);
1072 return intValue == null ? value : intValue;
1075 private void handleInstanceInterfaces(Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces,
1076 ComponentInstance componentInstance, Map<String, DataTypeDefinition> dataTypes,
1077 ToscaNodeTemplate nodeTemplate, String instanceUniqueId, Component parentComponent) {
1079 if (MapUtils.isEmpty(componentInstanceInterfaces) || !componentInstanceInterfaces.containsKey(instanceUniqueId)) {
1080 nodeTemplate.setInterfaces(null);
1084 final List<ComponentInstanceInterface> currServiceInterfaces = componentInstanceInterfaces.get(instanceUniqueId);
1086 final Map<String, InterfaceDefinition> tmpInterfaces = new HashMap<>();
1087 currServiceInterfaces.forEach(instInterface -> tmpInterfaces.put(instInterface.getUniqueId(), instInterface));
1089 final Map<String, Object> interfaceMap = interfacesOperationsConverter
1090 .getInterfacesMap(parentComponent, componentInstance, tmpInterfaces, dataTypes, isComponentOfTypeServiceProxy(componentInstance));
1092 interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
1093 nodeTemplate.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap);
1096 private boolean isComponentOfTypeServiceProxy(ComponentInstance componentInstance) {
1097 return Objects.nonNull(componentInstance.getOriginType())
1098 && componentInstance.getOriginType().getValue().equals("Service Proxy");
1101 private void addComponentInstanceInputs(Map<String, DataTypeDefinition> dataTypes,
1102 Map<String, List<ComponentInstanceInput>> componentInstancesInputs,
1103 String instanceUniqueId, Map<String, Object> props) {
1105 List<ComponentInstanceInput> instanceInputsList = componentInstancesInputs.get(instanceUniqueId);
1106 if (instanceInputsList != null) {
1107 instanceInputsList.forEach(input -> {
1108 Supplier<String> supplier = () -> input.getValue() != null && !Objects.isNull(input.getValue()) ? input.getValue()
1109 : input.getDefaultValue();
1110 propertyConvertor.convertAndAddValue(dataTypes, props, input, supplier);
1115 private void addPropertiesOfComponentInstance(final Map<String, List<ComponentInstanceProperty>> componentInstancesProperties,
1116 final Map<String, DataTypeDefinition> dataTypes,
1117 final String instanceUniqueId,
1118 final Map<String, Object> props) {
1120 if (isNotEmpty(componentInstancesProperties)) {
1121 componentInstancesProperties.get(instanceUniqueId)
1122 // Converts and adds each value to property map
1123 .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop, prop::getValue));
1127 private void addAttributesOfComponentInstance(final Map<String, List<ComponentInstanceAttribute>> componentInstancesAttributes,
1128 final String instanceUniqueId,
1129 final Map<String, Object> attribs) {
1131 if (isNotEmpty(componentInstancesAttributes) && componentInstancesAttributes.containsKey(instanceUniqueId)) {
1132 componentInstancesAttributes.get(instanceUniqueId)
1133 .forEach(attributeDefinition -> attributeConverter.convertAndAddValue(attribs, attributeDefinition));
1137 private void addPropertiesOfParentComponent(Map<String, DataTypeDefinition> dataTypes,
1138 Component componentOfInstance, Map<String, Object> props) {
1140 List<PropertyDefinition> componentProperties = componentOfInstance.getProperties();
1141 if (isNotEmpty(componentProperties)) {
1142 componentProperties.stream()
1143 // Filters out properties with empty default values
1144 .filter(prop -> StringUtils.isNotEmpty(prop.getDefaultValue()))
1145 // Converts and adds each value to property map
1146 .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop, prop::getDefaultValue));
1150 private void addAttributesOfParentComponent(final Component componentOfInstance, final Map<String, Object> attribs) {
1152 final List<AttributeDefinition> componentAttributes = componentOfInstance.getAttributes();
1153 if (isNotEmpty(componentAttributes)) {
1154 componentAttributes.stream()
1155 // Filters out Attributes with empty default values
1156 .filter(attrib -> StringUtils.isNotEmpty(attrib.getDefaultValue()))
1157 // Converts and adds each value to attribute map
1158 .forEach(attributeDefinition -> attributeConverter.convertAndAddValue(attribs, attributeDefinition));
1162 private ToscaNodeType createNodeType(Component component) {
1163 ToscaNodeType toscaNodeType = new ToscaNodeType();
1164 if (ModelConverter.isAtomicComponent(component)) {
1165 if (((Resource) component).getDerivedFrom() != null) {
1166 toscaNodeType.setDerived_from(((Resource) component).getDerivedFrom().get(0));
1168 toscaNodeType.setDescription(component.getDescription());
1170 String derivedFrom = null != component.getDerivedFromGenericType() ? component.getDerivedFromGenericType()
1172 toscaNodeType.setDerived_from(derivedFrom);
1174 return toscaNodeType;
1177 private Either<Map<String, Object>, ToscaError> createProxyInterfaceTypes(Component container) {
1179 Map<String, Object> proxyInterfaceTypes = new HashMap<>();
1180 Either<Map<String, Object>, ToscaError> res = Either.left(proxyInterfaceTypes);
1181 List<ComponentInstance> componentInstances = container.getComponentInstances();
1182 if (CollectionUtils.isEmpty(componentInstances)) {
1185 Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
1186 componentInstances.stream()
1187 .filter(this::isComponentOfTypeServiceProxy)
1188 .forEach(inst -> serviceProxyInstanceList.put(inst.getToscaComponentName(), inst));
1189 if (MapUtils.isEmpty(serviceProxyInstanceList)) {
1192 for (Entry<String, ComponentInstance> entryProxy : serviceProxyInstanceList.entrySet()) {
1193 Component serviceComponent;
1194 ComponentParametersView componentParametersView = new ComponentParametersView();
1195 componentParametersView.disableAll();
1196 componentParametersView.setIgnoreInterfaces(false);
1197 Either<Component, StorageOperationStatus> service = toscaOperationFacade
1198 .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
1199 if (service.isRight()) {
1200 log.debug("Failed to fetch original service component with id {} for instance {}",
1201 entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName());
1202 return Either.right(ToscaError.GENERAL_ERROR);
1204 serviceComponent = service.left().value();
1207 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither =
1208 interfaceLifecycleOperation.getAllInterfaceLifecycleTypes(serviceComponent.getModel());
1209 if (lifecycleTypeEither.isRight()) {
1210 log.debug("Failed to retrieve global interface types :", lifecycleTypeEither.right().value());
1211 return Either.right(ToscaError.GENERAL_ERROR);
1214 List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value().values().stream()
1215 .map(InterfaceDataDefinition::getType)
1216 .collect(Collectors.toList());
1217 //Add interface types for local interfaces in the original service component for proxy
1218 Map<String, Object> localInterfaceTypes = interfacesOperationsConverter.addInterfaceTypeElement(serviceComponent,
1219 allGlobalInterfaceTypes);
1220 if (MapUtils.isNotEmpty(localInterfaceTypes)) {
1221 proxyInterfaceTypes.putAll(localInterfaceTypes);
1225 return Either.left(proxyInterfaceTypes);
1228 private Either<Map<String, ToscaNodeType>, ToscaError> createProxyNodeTypes(Map<String, Component> componentCache,
1229 Component container) {
1231 Map<String, ToscaNodeType> nodeTypesMap = new HashMap<>();
1232 Either<Map<String, ToscaNodeType>, ToscaError> res = Either.left(nodeTypesMap);
1234 List<ComponentInstance> componentInstances = container.getComponentInstances();
1236 if (componentInstances == null || componentInstances.isEmpty()) {
1239 Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
1240 List<ComponentInstance> proxyInst = componentInstances.stream()
1241 .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceProxy.name()))
1242 .collect(Collectors.toList());
1243 if (proxyInst != null && !proxyInst.isEmpty()) {
1244 for (ComponentInstance inst : proxyInst) {
1245 serviceProxyInstanceList.put(inst.getToscaComponentName(), inst);
1249 if (serviceProxyInstanceList.isEmpty()) {
1252 Either<Resource, StorageOperationStatus> serviceProxyOrigin = toscaOperationFacade
1253 .getLatestByName("serviceProxy", null);
1254 if (serviceProxyOrigin.isRight()) {
1255 log.debug("Failed to fetch normative service proxy resource by tosca name, error {}",
1256 serviceProxyOrigin.right().value());
1257 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
1259 Component origComponent = serviceProxyOrigin.left().value();
1261 for (Entry<String, ComponentInstance> entryProxy : serviceProxyInstanceList.entrySet()) {
1262 Component serviceComponent = null;
1263 ComponentParametersView componentParametersView = new ComponentParametersView();
1264 componentParametersView.disableAll();
1265 componentParametersView.setIgnoreCategories(false);
1266 componentParametersView.setIgnoreProperties(false);
1267 componentParametersView.setIgnoreInputs(false);
1268 componentParametersView.setIgnoreInterfaces(false);
1269 componentParametersView.setIgnoreRequirements(false);
1270 Either<Component, StorageOperationStatus> service = toscaOperationFacade
1271 .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
1272 if (service.isRight()) {
1273 log.debug("Failed to fetch resource with id {} for instance {}",
1274 entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName());
1276 serviceComponent = service.left().value();
1279 ToscaNodeType toscaNodeType = createProxyNodeType(componentCache, origComponent, serviceComponent,
1280 entryProxy.getValue());
1281 nodeTypesMap.put(entryProxy.getKey(), toscaNodeType);
1284 return Either.left(nodeTypesMap);
1287 private void createServiceSubstitutionNodeTypes(final Map<String, Component> componentCache,
1288 final Component container, final ToscaTemplate toscaNode) {
1289 final List<ComponentInstance> componentInstances = container.getComponentInstances();
1291 if (CollectionUtils.isEmpty(componentInstances)) {
1294 final List<ComponentInstance> serviceSubstitutionInstanceList = componentInstances.stream()
1295 .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceSubstitution.name()))
1296 .collect(Collectors.toList());
1297 if (CollectionUtils.isNotEmpty(serviceSubstitutionInstanceList)) {
1298 for (ComponentInstance inst : serviceSubstitutionInstanceList) {
1299 final Map<String, ToscaNodeType> nodeTypes =
1300 toscaNode.getNode_types() == null ? new HashMap<>() : toscaNode.getNode_types();
1301 convertInterfaceNodeType(new HashMap<>(), componentCache.get(inst.getSourceModelUid()), toscaNode,
1307 private ToscaNodeType createProxyNodeType(Map<String, Component> componentCache, Component origComponent,
1308 Component proxyComponent, ComponentInstance componentInstance) {
1309 ToscaNodeType toscaNodeType = new ToscaNodeType();
1310 String derivedFrom = ((Resource) origComponent).getToscaResourceName();
1312 toscaNodeType.setDerived_from(derivedFrom);
1313 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = applicationDataTypeCache.getAll(
1314 origComponent.getModel());
1315 if (dataTypesEither.isRight()) {
1316 log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
1318 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
1319 Map<String, ToscaCapability> capabilities = this.capabilityRequirementConverter
1320 .convertProxyCapabilities(componentCache, componentInstance, dataTypes);
1322 if (MapUtils.isNotEmpty(capabilities)) {
1323 toscaNodeType.setCapabilities(capabilities);
1325 List<Map<String, ToscaRequirement>> proxyNodeTypeRequirements = this.capabilityRequirementConverter
1326 .convertProxyRequirements(componentCache, componentInstance);
1327 if (CollectionUtils.isNotEmpty(proxyNodeTypeRequirements)) {
1328 toscaNodeType.setRequirements(proxyNodeTypeRequirements);
1330 Optional<Map<String, ToscaProperty>> proxyProperties = getProxyNodeTypeProperties(proxyComponent, dataTypes);
1331 proxyProperties.ifPresent(toscaNodeType::setProperties);
1333 Map<String, Object> interfaceMap = new HashMap<>();
1334 if (MapUtils.isEmpty(componentInstance.getInterfaces())) {
1335 final Optional<Map<String, Object>> proxyInterfaces = getProxyNodeTypeInterfaces(proxyComponent, dataTypes);
1336 if (proxyInterfaces.isPresent()) {
1337 interfaceMap = proxyInterfaces.get();
1340 interfaceMap = interfacesOperationsConverter.getInterfacesMapFromComponentInstance(proxyComponent, componentInstance, dataTypes, 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<PropertyFilterDataDefinition> origProperties = inNodeFilter.getProperties();
1615 List<Map<String, CapabilityFilter>> capabilitiesCopy = new ArrayList<>();
1616 copyNodeFilterCapabilitiesTemplate(origCapabilities, capabilitiesCopy);
1617 if (CollectionUtils.isNotEmpty(capabilitiesCopy)) {
1618 nodeFilter.setCapabilities(capabilitiesCopy);
1620 final List<Map<String, List<Object>>> propertiesCopy = copyNodeFilterProperties(origProperties);
1621 if (CollectionUtils.isNotEmpty(propertiesCopy)) {
1622 nodeFilter.setProperties(propertiesCopy);
1624 nodeFilter.setTosca_id(cloneToscaId(inNodeFilter.getTosca_id()));
1625 nodeFilter = (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
1629 private NodeFilter convertToSubstitutionFilterComponent(final SubstitutionFilterDataDefinition substitutionFilterDataDefinition) {
1630 if (substitutionFilterDataDefinition == null) {
1633 NodeFilter nodeFilter = new NodeFilter();
1634 final List<Map<String, List<Object>>> propertiesCopy = copySubstitutionPropertiesFilter(substitutionFilterDataDefinition.getProperties());
1635 if (!propertiesCopy.isEmpty()) {
1636 nodeFilter.setProperties(propertiesCopy);
1638 nodeFilter.setTosca_id(cloneToscaId(substitutionFilterDataDefinition.getTosca_id()));
1639 return (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
1642 private Object cloneToscaId(Object toscaId) {
1643 return Objects.isNull(toscaId) ? null : cloneObjectFromYml(toscaId, toscaId.getClass());
1646 private Object cloneObjectFromYml(Object objToClone, Class classOfObj) {
1647 String objectAsYml = yamlUtil.objectToYaml(objToClone);
1648 return yamlUtil.yamlToObject(objectAsYml, classOfObj);
1651 private void copyNodeFilterCapabilitiesTemplate(ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities,
1652 List<Map<String, CapabilityFilter>> capabilitiesCopy) {
1653 if (origCapabilities == null || origCapabilities.getListToscaDataDefinition() == null || origCapabilities.getListToscaDataDefinition()
1657 for (RequirementNodeFilterCapabilityDataDefinition capability : origCapabilities.getListToscaDataDefinition()) {
1658 Map<String, CapabilityFilter> capabilityFilterCopyMap = new HashMap<>();
1659 final var capabilityFilter = new CapabilityFilter();
1660 capabilityFilter.setProperties(copyNodeFilterProperties(capability.getProperties()));
1661 capabilityFilterCopyMap.put(capability.getName(), capabilityFilter);
1662 capabilitiesCopy.add(capabilityFilterCopyMap);
1666 private List<Map<String, List<Object>>> copyNodeFilterProperties(final ListDataDefinition<PropertyFilterDataDefinition> origProperties) {
1667 if (origProperties == null || origProperties.getListToscaDataDefinition() == null || origProperties.isEmpty()) {
1668 return Collections.emptyList();
1670 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1671 Map<String, List<Object>> propertyFilterDefinitionMap = new HashMap<>();
1672 for (final PropertyFilterDataDefinition propertyFilter : origProperties.getListToscaDataDefinition()) {
1673 final String propertyName = propertyFilter.getName();
1674 for (final PropertyFilterConstraintDataDefinition filterConstraint : propertyFilter.getConstraints()) {
1675 propertyFilterDefinitionMap.compute(propertyName, (propertyName1, constraints) -> {
1676 if (constraints == null) {
1677 constraints = new ArrayList<>();
1679 constraints.add(buildNodeFilterValue(filterConstraint));
1684 propertyFilterDefinitionMap.entrySet().stream()
1685 .map(entry -> Map.of(entry.getKey(), entry.getValue()))
1686 .forEach(propertiesCopy::add);
1687 return propertiesCopy;
1690 private List<Map<String, List<Object>>> copySubstitutionPropertiesFilter(
1691 final ListDataDefinition<SubstitutionFilterPropertyDataDefinition> origProperties) {
1693 if (origProperties == null || origProperties.getListToscaDataDefinition() == null || origProperties.isEmpty()) {
1694 return Collections.emptyList();
1696 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1697 Map<String, List<Object>> propertyFilterDefinitionMap = new HashMap<>();
1698 for (final SubstitutionFilterPropertyDataDefinition propertyFilter : origProperties.getListToscaDataDefinition()) {
1699 final String propertyName = propertyFilter.getName();
1700 for (final PropertyFilterConstraintDataDefinition filterConstraint : propertyFilter.getConstraints()) {
1701 propertyFilterDefinitionMap.compute(propertyName, (propertyName1, constraints) -> {
1702 if (constraints == null) {
1703 constraints = new ArrayList<>();
1705 constraints.add(buildNodeFilterValue(filterConstraint));
1710 propertyFilterDefinitionMap.entrySet().stream()
1711 .map(entry -> Map.of(entry.getKey(), entry.getValue()))
1712 .forEach(propertiesCopy::add);
1713 return propertiesCopy;
1716 private static Object buildNodeFilterValue(final PropertyFilterConstraintDataDefinition filterConstraint) {
1717 if (filterConstraint.getValue() instanceof ToscaFunction) {
1718 return Map.of(filterConstraint.getOperator().getType(), ((ToscaFunction) filterConstraint.getValue()).getJsonObjectValue());
1720 return Map.of(filterConstraint.getOperator().getType(), filterConstraint.getValue());
1724 private Map<String, String[]> buildSubstitutionMappingPropertyMapping(final Component component) {
1725 if (component == null || CollectionUtils.isEmpty(component.getInputs())) {
1726 return Collections.emptyMap();
1728 return component.getInputs().stream().filter(InputDefinition::isMappedToComponentProperty).map(PropertyDataDefinition::getName)
1729 .collect(Collectors.toMap(inputName -> inputName, inputName -> new String[]{inputName}, (inputName1, inputName2) -> inputName1));
1732 private Map<String, String[]> buildSubstitutionMappingAttributesMapping(final Component component) {
1733 if (component == null || CollectionUtils.isEmpty(component.getOutputs())) {
1734 return Collections.emptyMap();
1736 return component.getOutputs().stream().map(AttributeDataDefinition::getName)
1737 .collect(Collectors.toMap(outputName -> outputName, outputName -> new String[]{outputName}, (outputName1, outputName2) -> outputName1));
1740 private Optional<Map<String, ToscaProperty>> getProxyNodeTypeProperties(Component proxyComponent, Map<String, DataTypeDefinition> dataTypes) {
1741 if (Objects.isNull(proxyComponent)) {
1742 return Optional.empty();
1744 final var proxyProperties = convertInputsToProperties(dataTypes, proxyComponent.getInputs(), proxyComponent.getUniqueId());
1745 if (CollectionUtils.isNotEmpty(proxyComponent.getProperties())) {
1746 proxyProperties.putAll(proxyComponent.getProperties().stream()
1747 .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, proxyComponent.getInputs())).collect(Collectors
1748 .toMap(PropertyDataDefinition::getName,
1749 property -> propertyConvertor.convertProperty(dataTypes, property, PropertyType.PROPERTY))));
1751 return MapUtils.isNotEmpty(proxyProperties) ? Optional.of(proxyProperties) : Optional.empty();
1754 private Map<String, ToscaProperty> convertInputsToProperties(Map<String, DataTypeDefinition> dataTypes, List<InputDefinition> componentInputs,
1755 String componentUniqueId) {
1756 if (CollectionUtils.isEmpty(componentInputs)) {
1757 return new HashMap<>();
1759 return componentInputs.stream().filter(input -> componentUniqueId.equals(input.getInstanceUniqueId()))
1760 .collect(Collectors.toMap(InputDefinition::getName, i -> propertyConvertor.convertProperty(dataTypes, i, PropertyType.INPUT)));
1763 private Optional<Map<String, Object>> getProxyNodeTypeInterfaces(Component proxyComponent, Map<String, DataTypeDefinition> dataTypes) {
1764 if (Objects.isNull(proxyComponent) || MapUtils.isEmpty(proxyComponent.getInterfaces())) {
1765 return Optional.empty();
1767 Map<String, InterfaceDefinition> proxyComponentInterfaces = proxyComponent.getInterfaces();
1768 //Unset artifact path for operation implementation for proxy node types as for operations with artifacts it is
1770 // always available in the proxy node template
1771 removeOperationImplementationForProxyNodeType(proxyComponentInterfaces);
1772 return Optional.ofNullable(interfacesOperationsConverter.getInterfacesMap(proxyComponent, null, proxyComponentInterfaces, dataTypes, false));
1775 private static class CustomRepresenter extends Representer {
1777 CustomRepresenter() {
1779 this.representers.put(ToscaPropertyAssignment.class, new RepresentToscaPropertyAssignment());
1780 this.representers.put(ToscaAttribute.class, new RepresentToscaAttribute());
1781 // null representer is exceptional and it is stored as an instance
1784 this.nullRepresenter = new RepresentNull();
1787 public boolean validateGetInputValue(final Object valueObj) {
1788 if (!(valueObj instanceof List) && !(valueObj instanceof String)) {
1791 if (valueObj instanceof List) {
1792 return ((List) valueObj).size() > 1;
1797 public boolean validateGetPropertyOrAttributeValue(final Object valueObj) {
1798 if (valueObj instanceof List) {
1799 return ((List) valueObj).size() > 1;
1805 protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue, Tag customTag) {
1806 if (propertyValue == null) {
1809 // skip not relevant for Tosca property
1810 if ("dependencies".equals(property.getName())) {
1813 if (javaBean instanceof ToscaRelationshipTemplate && "name".equals(property.getName())) {
1816 if (javaBean instanceof ToscaPropertyConstraint) {
1817 return handleToscaPropertyConstraint((ToscaPropertyConstraint)javaBean, property, propertyValue, customTag);
1819 removeDefaultP(propertyValue);
1820 NodeTuple defaultNode = super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
1821 if (javaBean instanceof ToscaTopolgyTemplate && "relationshipTemplates".equals(property.getName())) {
1822 return new NodeTuple(representData("relationship_templates"), defaultNode.getValueNode());
1824 return "_defaultp_".equals(property.getName()) ? new NodeTuple(representData("default"), defaultNode.getValueNode()) : defaultNode;
1827 private NodeTuple handleToscaPropertyConstraint(final ToscaPropertyConstraint javaBean, final Property property, final Object propertyValue,
1828 final Tag customTag) {
1829 final NodeTuple nodeTuple = super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
1830 final String entryToscaName = javaBean.getEntryToscaName(property.getName());
1831 return new NodeTuple(representData(entryToscaName), nodeTuple.getValueNode());
1834 private void removeDefaultP(final Object propertyValue) {
1835 if (propertyValue instanceof Map) {
1836 final Map mapPropertyValue = ((Map) propertyValue);
1837 final Iterator<Entry> iter = mapPropertyValue.entrySet().iterator();
1838 Object defaultValue = null;
1839 while (iter.hasNext()) {
1840 final Map.Entry entry = iter.next();
1841 if ("_defaultp_".equals(entry.getKey())) {
1842 defaultValue = entry.getValue();
1844 } else if (entry.getValue() instanceof Map) {
1845 removeDefaultP(entry.getValue());
1848 if (defaultValue != null) {
1849 mapPropertyValue.putIfAbsent("default", defaultValue);
1855 protected MappingNode representJavaBean(Set<Property> properties, Object javaBean) {
1856 // remove the bean type from the output yaml (!! ...)
1857 if (!classTags.containsKey(javaBean.getClass())) {
1858 addClassTag(javaBean.getClass(), Tag.MAP);
1860 return super.representJavaBean(properties, javaBean);
1863 private class RepresentToscaAttribute implements Represent {
1866 public Node representData(Object data) {
1867 final ToscaAttribute toscaAttribute = (ToscaAttribute) data;
1868 return represent(toscaAttribute.asToscaMap());
1872 private class RepresentToscaPropertyAssignment implements Represent {
1874 public Node representData(Object data) {
1875 final ToscaPropertyAssignment toscaOperationAssignment = (ToscaPropertyAssignment) data;
1876 if (toscaOperationAssignment.getValue() instanceof String) {
1877 final String stringValue = (String) toscaOperationAssignment.getValue();
1878 if (isPropertyOrAttributeFunction(stringValue)) {
1879 return representGetAttribute(stringValue);
1881 return representScalar(Tag.STR, stringValue);
1883 return represent(null);
1886 public Node representGetAttribute(final String getAttributeFunction) {
1887 return represent(new Yaml().load(getAttributeFunction));
1890 public boolean isPropertyOrAttributeFunction(final String value) {
1892 final Yaml yaml = new Yaml();
1893 final Object yamlObj = yaml.load(value);
1894 if (!(yamlObj instanceof Map)) {
1897 final Map<String, Object> getAttributeMap = (Map) yamlObj;
1898 if (getAttributeMap.size() != 1) {
1901 final List<String> functionList = Arrays
1902 .asList(GET_ATTRIBUTE.getFunctionName(), GET_INPUT.getFunctionName(), GET_PROPERTY.getFunctionName());
1903 final Optional<String> function = getAttributeMap.keySet().stream()
1904 .filter(key -> functionList.stream().anyMatch(function1 -> function1.equals(key))).findFirst();
1905 if (function.isEmpty()) {
1908 final String functionName = function.get();
1909 final Object getAttributeValueObj = getAttributeMap.get(functionName);
1910 if (GET_INPUT.getFunctionName().equals(functionName)) {
1911 return validateGetInputValue(getAttributeValueObj);
1913 return validateGetPropertyOrAttributeValue(getAttributeValueObj);
1915 } catch (final Exception ignored) {
1921 private class RepresentNull implements Represent {
1924 public Node representData(Object data) {
1925 // possible values are here http://yaml.org/type/null.html
1926 return representScalar(Tag.NULL, "");
1931 private static class UnsortedPropertyUtils extends PropertyUtils {
1934 protected Set<Property> createPropertySet(Class type, BeanAccess bAccess) {
1935 Collection<Property> fields = getPropertiesMap(type, BeanAccess.FIELD).values();
1936 return new LinkedHashSet<>(fields);
1940 private Configuration getConfiguration() {
1941 return ConfigurationManager.getConfigurationManager().getConfiguration();