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.RESOURCE_VENDOR_RELEASE.getPresentation(), resource.getVendorRelease());
550 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_MODEL_NUMBER.getPresentation(), resource.getResourceVendorModelNumber());
553 Service service = (Service) component;
554 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), component.getComponentType().getValue());
555 toscaMetadata.put(JsonPresentationFields.SERVICE_TYPE.getPresentation(), service.getServiceType());
556 toscaMetadata.put(JsonPresentationFields.SERVICE_ROLE.getPresentation(), service.getServiceRole());
557 toscaMetadata.put(JsonPresentationFields.SERVICE_FUNCTION.getPresentation(), service.getServiceFunction());
558 toscaMetadata.put(JsonPresentationFields.ENVIRONMENT_CONTEXT.getPresentation(), service.getEnvironmentContext());
559 toscaMetadata.put(JsonPresentationFields.INSTANTIATION_TYPE.getPresentation(),
560 service.getEnvironmentContext() == null ? StringUtils.EMPTY : service.getInstantiationType());
563 toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming().toString());
564 toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming().toString());
565 toscaMetadata.put(JsonPresentationFields.NAMING_POLICY.getPresentation(), service.getNamingPolicy());
569 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
571 for (final String key : component.getCategorySpecificMetadata().keySet()) {
572 if (!EXCLUDED_CATEGORY_SPECIFIC_METADATA.contains(key)) {
573 toscaMetadata.put(key, component.getCategorySpecificMetadata().get(key));
576 return toscaMetadata;
579 private String convertMetadataKey(JsonPresentationFields jsonPresentationField) {
580 if (JsonPresentationFields.INVARIANT_UUID.equals(jsonPresentationField)) {
581 return INVARIANT_UUID;
583 return jsonPresentationField.getPresentation();
586 private Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports(Component component, ToscaTemplate toscaTemplate) {
587 final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImports(component.getModel());
588 if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
589 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
590 return Either.right(ToscaError.GENERAL_ERROR);
592 Map<String, Component> componentCache = new HashMap<>();
593 if (!ModelConverter.isAtomicComponent(component)) {
594 final List<Map<String, Map<String, String>>> additionalImports =
595 toscaTemplate.getImports() == null ? new ArrayList<>(defaultToscaImportConfig) : new ArrayList<>(toscaTemplate.getImports());
596 List<Triple<String, String, Component>> dependencies = new ArrayList<>();
597 Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
598 final Map<String, Map<String, String>> substituteTypeImportEntry = generateComponentSubstituteTypeImport(component, toscaArtifacts);
599 if (!substituteTypeImportEntry.isEmpty()) {
600 additionalImports.add(substituteTypeImportEntry);
602 List<ComponentInstance> componentInstances = component.getComponentInstances();
603 if (componentInstances != null && !componentInstances.isEmpty()) {
604 componentInstances.forEach(ci -> createDependency(componentCache, additionalImports, dependencies, ci));
606 toscaTemplate.setDependencies(dependencies);
607 toscaTemplate.setImports(additionalImports);
609 log.debug("currently imports supported for VF and service only");
611 return Either.left(new ImmutablePair<>(toscaTemplate, componentCache));
614 private Map<String, Map<String, String>> generateComponentSubstituteTypeImport(final Component component,
615 final Map<String, ArtifactDefinition> toscaArtifacts) {
617 if (component instanceof Service && !((Service) component).isSubstituteCandidate()) {
618 return Collections.emptyMap();
620 if (MapUtils.isEmpty(toscaArtifacts)) {
621 return Collections.emptyMap();
623 final ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE);
624 if (artifactDefinition == null) {
625 return Collections.emptyMap();
627 final var importEntryName = component.getComponentType().toString().toLowerCase() + "-" + component.getName() + "-interface";
628 return Map.of(importEntryName,
629 Map.of(IMPORTS_FILE_KEY, getInterfaceFilename(artifactDefinition.getArtifactName()))
633 private List<Map<String, Map<String, String>>> getDefaultToscaImportConfig() {
634 return getConfiguration().getDefaultImports();
637 private void createDependency(final Map<String, Component> componentCache, final List<Map<String, Map<String, String>>> imports,
638 final List<Triple<String, String, Component>> dependencies, final ComponentInstance componentInstance) {
639 log.debug("createDependency componentCache {}", componentCache);
640 Component componentRI = componentCache.get(componentInstance.getComponentUid());
641 if (componentRI == null || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
642 // all resource must be only once!
643 final Either<Component, StorageOperationStatus> resource = toscaOperationFacade.getToscaFullElement(componentInstance.getComponentUid());
644 if ((resource.isRight()) && (log.isDebugEnabled())) {
645 log.debug("Failed to fetch resource with id {} for instance {}", componentInstance.getComponentUid(),
646 componentInstance.getUniqueId());
649 final Component fetchedComponent = resource.left().value();
650 componentRI = setComponentCache(componentCache, componentInstance, fetchedComponent);
651 addDependencies(imports, dependencies, componentRI);
656 * Sets a componentCache from the given component/resource.
658 private Component setComponentCache(final Map<String, Component> componentCache, final ComponentInstance componentInstance,
659 final Component fetchedComponent) {
660 componentCache.put(fetchedComponent.getUniqueId(), fetchedComponent);
661 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy
662 || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
663 final Either<Component, StorageOperationStatus> sourceService = toscaOperationFacade
664 .getToscaFullElement(componentInstance.getSourceModelUid());
665 if (sourceService.isRight() && (log.isDebugEnabled())) {
666 log.debug("Failed to fetch source service with id {} for proxy {}", componentInstance.getSourceModelUid(),
667 componentInstance.getUniqueId());
669 final Component fetchedSource = sourceService.left().value();
670 componentCache.put(fetchedSource.getUniqueId(), fetchedSource);
671 return fetchedSource;
673 return fetchedComponent;
677 * Retrieves all derived_from nodes and stores it in a predictable order.
679 private void addDependencies(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
680 final Component fetchedComponent) {
681 final Set<Component> componentsList = new LinkedHashSet<>();
682 if (fetchedComponent instanceof Resource) {
683 log.debug("fetchedComponent is a resource {}", fetchedComponent);
684 final Optional<Map<String, String>> derivedFromMapOfIdToName = getDerivedFromMapOfIdToName(fetchedComponent, componentsList);
685 if (derivedFromMapOfIdToName.isPresent() && !derivedFromMapOfIdToName.get().isEmpty()) {
686 derivedFromMapOfIdToName.get().entrySet().forEach(entry -> {
687 log.debug("Started entry.getValue() : {}", entry.getValue());
688 if (!NATIVE_ROOT.equals(entry.getValue())) {
689 Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade.getToscaElement(entry.getKey());
690 if (resourcefetched != null && resourcefetched.isLeft()) {
691 componentsList.add(resourcefetched.left().value());
695 setImports(imports, dependencies, componentsList);
697 setImports(imports, dependencies, fetchedComponent);
703 * Returns all derived_from nodes found.
705 private Optional<Map<String, String>> getDerivedFromMapOfIdToName(final Component fetchedComponent, final Set<Component> componentsList) {
706 final Resource parentResource = (Resource) fetchedComponent;
707 Map<String, String> derivedFromMapOfIdToName = new HashMap<>();
708 if (CollectionUtils.isNotEmpty(parentResource.getComponentInstances())) {
709 componentsList.add(fetchedComponent);
710 for (final ComponentInstance componentInstance : parentResource.getComponentInstances()) {
711 final Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade
712 .getToscaElement(componentInstance.getComponentUid());
713 if (resourcefetched != null && resourcefetched.isLeft()) {
714 final Map<String, String> derivedWithId = resourcefetched.left().value().getDerivedFromMapOfIdToName();
715 if (MapUtils.isNotEmpty(derivedWithId)) {
716 derivedFromMapOfIdToName.putAll(derivedWithId);
721 derivedFromMapOfIdToName = parentResource.getDerivedFromMapOfIdToName();
723 log.debug("Started derivedFromMapOfIdToName: {}", derivedFromMapOfIdToName);
724 return Optional.ofNullable(derivedFromMapOfIdToName);
728 * Creates a resource map and adds it to the import list.
730 private void setImports(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
731 final Set<Component> componentsList) {
732 componentsList.forEach(component -> setImports(imports, dependencies, component));
735 private void setImports(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
736 final Component component) {
737 final Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
738 final ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE);
739 if (artifactDefinition != null) {
740 final Map<String, String> files = new HashMap<>();
741 final String artifactName = artifactDefinition.getArtifactName();
742 files.put(IMPORTS_FILE_KEY, artifactName);
743 final StringBuilder keyNameBuilder = new StringBuilder();
744 keyNameBuilder.append(component.getComponentType().toString().toLowerCase());
745 keyNameBuilder.append("-");
746 keyNameBuilder.append(component.getName());
747 addImports(imports, keyNameBuilder, files);
748 dependencies.add(new ImmutableTriple<>(artifactName, artifactDefinition.getEsId(), component));
749 if (!ModelConverter.isAtomicComponent(component)) {
750 final Map<String, String> interfaceFiles = new HashMap<>();
751 interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactName));
752 keyNameBuilder.append("-interface");
753 addImports(imports, keyNameBuilder, interfaceFiles);
759 * Adds the found resource to the import definition list.
761 private void addImports(final List<Map<String, Map<String, String>>> imports, final StringBuilder keyNameBuilder,
762 final Map<String, String> files) {
763 final String mapKey = keyNameBuilder.toString();
764 if (imports.stream().allMatch(stringMapMap -> stringMapMap.get(mapKey) == null)) {
765 final Map<String, Map<String, String>> importsListMember = new HashMap<>();
766 importsListMember.put(keyNameBuilder.toString(), files);
767 imports.add(importsListMember);
771 private Either<ToscaTemplate, ToscaError> convertNodeType(Map<String, Component> componentsCache, Component component, ToscaTemplate toscaNode,
772 Map<String, ToscaNodeType> nodeTypes) {
773 return convertInterfaceNodeType(componentsCache, component, toscaNode, nodeTypes, false);
776 public Either<ToscaTemplate, ToscaError> convertInterfaceNodeType(Map<String, Component> componentsCache, Component component,
777 ToscaTemplate toscaNode, Map<String, ToscaNodeType> nodeTypes,
778 boolean isAssociatedComponent) {
779 log.debug("start convert node type for {}", component.getUniqueId());
780 ToscaNodeType toscaNodeType = createNodeType(component);
781 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither = interfaceLifecycleOperation
782 .getAllInterfaceLifecycleTypes(component.getModel());
783 if (lifecycleTypeEither.isRight() && !StorageOperationStatus.NOT_FOUND.equals(lifecycleTypeEither.right().value())) {
784 log.debug("Failed to fetch all interface types :", lifecycleTypeEither.right().value());
785 return Either.right(ToscaError.GENERAL_ERROR);
787 if (lifecycleTypeEither.isLeft()) {
788 List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value().values().stream().map(InterfaceDataDefinition::getType)
789 .collect(Collectors.toList());
790 toscaNode.setInterface_types(interfacesOperationsConverter.addInterfaceTypeElement(component, allGlobalInterfaceTypes));
792 final var dataTypesEither = applicationDataTypeCache.getAll(component.getModel());
793 if (dataTypesEither.isRight()) {
794 log.debug("Failed to fetch all data types :", dataTypesEither.right().value());
795 return Either.right(ToscaError.GENERAL_ERROR);
797 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
798 List<InputDefinition> inputDef = component.getInputs();
799 interfacesOperationsConverter.addInterfaceDefinitionElement(component, toscaNodeType, dataTypes, isAssociatedComponent);
800 final var toscaAttributeMap = convertToToscaAttributes(component.getAttributes(), dataTypes);
801 if (!toscaAttributeMap.isEmpty()) {
802 toscaNodeType.setAttributes(toscaAttributeMap);
804 final var mergedProperties = convertInputsToProperties(dataTypes, inputDef, component.getUniqueId());
805 if (CollectionUtils.isNotEmpty(component.getProperties())) {
806 List<PropertyDefinition> properties = component.getProperties();
807 Map<String, ToscaProperty> convertedProperties = properties.stream()
808 .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, component.getInputs())).collect(Collectors
809 .toMap(PropertyDataDefinition::getName,
810 property -> propertyConvertor.convertProperty(dataTypes, property, PropertyConvertor.PropertyType.PROPERTY)));
811 // merge component properties and inputs properties
812 mergedProperties.putAll(convertedProperties);
814 if (MapUtils.isNotEmpty(mergedProperties)) {
815 toscaNodeType.setProperties(mergedProperties);
817 /* convert private data_types */
818 List<DataTypeDefinition> privateDataTypes = component.getDataTypes();
819 if (CollectionUtils.isNotEmpty(privateDataTypes)) {
820 Map<String, ToscaDataType> toscaDataTypeMap = new HashMap<>();
821 for (DataTypeDefinition dataType : privateDataTypes) {
822 log.debug("Emitting private data type: component.name={} dataType.name={}",
823 component.getNormalizedName(), dataType.getName());
824 ToscaDataType toscaDataType = new ToscaDataType();
825 toscaDataType.setDerived_from(dataType.getDerivedFromName());
826 toscaDataType.setDescription(dataType.getDescription());
827 toscaDataType.setVersion(dataType.getVersion());
828 if (CollectionUtils.isNotEmpty(dataType.getProperties())) {
829 toscaDataType.setProperties(dataType.getProperties().stream()
830 .collect(Collectors.toMap(
831 PropertyDataDefinition::getName,
832 s -> propertyConvertor.convertProperty(dataTypes, s, PropertyType.PROPERTY),
833 (toscaPropertyTobeValidated, toscaProperty) -> validateToscaProperty(privateDataTypes, toscaPropertyTobeValidated,
837 toscaDataTypeMap.put(dataType.getName(), toscaDataType);
839 toscaNode.setData_types(toscaDataTypeMap);
842 // Extracted to method for code reuse
843 return convertReqCapAndTypeName(componentsCache, component, toscaNode, nodeTypes, toscaNodeType, dataTypes);
846 private ToscaProperty validateToscaProperty(final List<DataTypeDefinition> privateDataTypes, final ToscaProperty toscaPropertyTobeValidated,
847 final ToscaProperty toscaProperty) {
848 final Optional<DataTypeDefinition> match = privateDataTypes.stream()
849 .filter(dataType -> dataType.getName().equals(toscaPropertyTobeValidated.getType())).findFirst();
850 return match.isPresent() ? toscaPropertyTobeValidated : toscaProperty;
853 private Map<String, ToscaAttribute> convertToToscaAttributes(final List<AttributeDefinition> attributeList,
854 final Map<String, DataTypeDefinition> dataTypes) {
855 if (CollectionUtils.isEmpty(attributeList)) {
856 return Collections.emptyMap();
858 final AttributeConverter converter = new AttributeConverter(dataTypes);
859 final Map<String, ToscaAttribute> toscaAttributeMap = new HashMap<>();
860 for (final AttributeDefinition attributeDefinition : attributeList) {
861 toscaAttributeMap.put(attributeDefinition.getName(), converter.convert(attributeDefinition));
863 return toscaAttributeMap;
866 private Either<ToscaTemplate, ToscaError> convertReqCapAndTypeName(Map<String, Component> componentsCache,
867 Component component, ToscaTemplate toscaNode,
868 Map<String, ToscaNodeType> nodeTypes,
869 ToscaNodeType toscaNodeType,
870 Map<String, DataTypeDefinition> dataTypes) {
871 Either<ToscaNodeType, ToscaError> capabilities = convertCapabilities(componentsCache, component, toscaNodeType,
873 if (capabilities.isRight()) {
874 return Either.right(capabilities.right().value());
876 toscaNodeType = capabilities.left().value();
877 log.debug("Capabilities converted for {}", component.getUniqueId());
879 Either<ToscaNodeType, ToscaError> requirements = capabilityRequirementConverter
880 .convertRequirements(componentsCache, component, toscaNodeType);
881 if (requirements.isRight()) {
882 return Either.right(requirements.right().value());
884 toscaNodeType = requirements.left().value();
885 log.debug("Requirements converted for {}", component.getUniqueId());
887 String toscaResourceName;
888 switch (component.getComponentType()) {
890 toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition()
891 .getMetadataDataDefinition()).getToscaResourceName();
894 toscaResourceName = SERVICE_NODE_TYPE_PREFIX
895 + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName();
898 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
899 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
902 nodeTypes.put(toscaResourceName, toscaNodeType);
903 toscaNode.setNode_types(nodeTypes);
904 log.debug("finish convert node type for {}", component.getUniqueId());
905 return Either.left(toscaNode);
908 private Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplates(final Component component,
909 final Map<String, Component> componentCache,
910 final Map<String, DataTypeDefinition> dataTypes,
911 final ToscaTopolgyTemplate topologyTemplate) {
913 final Map<String, List<ComponentInstanceProperty>> componentInstancesProperties = component.getComponentInstancesProperties();
914 final Map<String, List<ComponentInstanceAttribute>> componentInstancesAttributes = component.getComponentInstancesAttributes();
915 final Map<String, List<ComponentInstanceInput>> componentInstancesInputs = component.getComponentInstancesInputs();
916 final Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces = component.getComponentInstancesInterfaces();
917 final List<RequirementCapabilityRelDef> componentInstancesRelations = component.getComponentInstancesRelations();
919 Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplatesRes = null;
920 log.debug("start convert topology template for {} for type {}", component.getUniqueId(), component.getComponentType());
921 final Map<String, ToscaNodeTemplate> nodeTemplates = new HashMap<>();
923 Map<String, ToscaGroupTemplate> groupsMap = null;
924 for (final ComponentInstance componentInstance : component.getComponentInstances()) {
925 ToscaNodeTemplate nodeTemplate = new ToscaNodeTemplate();
926 if (MapUtils.isNotEmpty(componentInstance.getToscaArtifacts())) {
927 nodeTemplate.setArtifacts(convertToNodeTemplateArtifacts(componentInstance.getToscaArtifacts()));
929 if (componentInstance.getMinOccurrences() != null && componentInstance.getMaxOccurrences() != null) {
930 List<Object> occur = new ArrayList<>();
931 occur.add(parseToIntIfPossible(componentInstance.getMinOccurrences()));
932 occur.add(parseToIntIfPossible(componentInstance.getMaxOccurrences()));
933 nodeTemplate.setOccurrences(occur);
935 if (componentInstance.getInstanceCount() != null) {
936 ObjectMapper objectMapper = new ObjectMapper();
937 Object obj = convertToToscaObject(componentInstance.getInstanceCount());
939 Map<String, String> map = objectMapper.convertValue(obj, Map.class);
940 nodeTemplate.setInstance_count(map);
943 nodeTemplate.setType(componentInstance.getToscaComponentName());
944 nodeTemplate.setDirectives(componentInstance.getDirectives());
945 NodeFilter nodeFilter = convertToNodeTemplateNodeFilterComponent(componentInstance.getNodeFilter());
946 if(nodeFilter != null && nodeFilter.hasData()){
947 nodeTemplate.setNode_filter(nodeFilter);
949 final Either<Component, Boolean> originComponentRes = capabilityRequirementConverter
950 .getOriginComponent(componentCache, componentInstance);
951 if (originComponentRes.isRight()) {
952 convertNodeTemplatesRes = Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
955 final Either<ToscaNodeTemplate, ToscaError> requirements = convertComponentInstanceRequirements(component, componentInstance,
956 componentInstancesRelations, nodeTemplate, originComponentRes.left().value(), componentCache);
957 if (requirements.isRight()) {
958 convertNodeTemplatesRes = Either.right(requirements.right().value());
961 final String instanceUniqueId = componentInstance.getUniqueId();
962 log.debug("Component instance Requirements converted for instance {}", instanceUniqueId);
964 nodeTemplate = requirements.left().value();
966 final Component originalComponent = componentCache.get(componentInstance.getActualComponentUid());
968 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
969 final Component componentOfProxy = componentCache.get(componentInstance.getComponentUid());
970 nodeTemplate.setMetadata(convertMetadata(componentOfProxy, true, componentInstance));
972 nodeTemplate.setMetadata(convertMetadata(originalComponent, true, componentInstance));
975 final Either<ToscaNodeTemplate, ToscaError> capabilities =
976 capabilityRequirementConverter.convertComponentInstanceCapabilities(componentInstance, dataTypes, nodeTemplate);
977 if (capabilities.isRight()) {
978 convertNodeTemplatesRes = Either.right(capabilities.right().value());
981 log.debug("Component instance Capabilities converted for instance {}", instanceUniqueId);
983 nodeTemplate = capabilities.left().value();
984 final Map<String, Object> props = new HashMap<>();
985 final Map<String, Object> attribs = new HashMap<>();
987 if (originalComponent.getComponentType() == ComponentTypeEnum.RESOURCE) {
988 // Adds the properties of parent component to map
989 addPropertiesOfParentComponent(dataTypes, originalComponent, props);
990 addAttributesOfParentComponent(originalComponent, attribs);
993 if (null != componentInstancesProperties && componentInstancesProperties.containsKey(instanceUniqueId)) {
994 addPropertiesOfComponentInstance(componentInstancesProperties, dataTypes, instanceUniqueId, props);
996 if (null != componentInstancesAttributes && componentInstancesAttributes.containsKey(instanceUniqueId)) {
997 addAttributesOfComponentInstance(componentInstancesAttributes, instanceUniqueId, attribs);
1000 if (componentInstancesInputs != null
1001 && componentInstancesInputs.containsKey(instanceUniqueId)
1002 && !isComponentOfTypeServiceProxy(componentInstance)) {
1003 //For service proxy the inputs are already handled under instance properties above
1004 addComponentInstanceInputs(dataTypes, componentInstancesInputs, instanceUniqueId, props);
1007 //M3[00001] - NODE TEMPLATE INTERFACES - START
1008 handleInstanceInterfaces(componentInstanceInterfaces, componentInstance, dataTypes, nodeTemplate, instanceUniqueId, component);
1009 //M3[00001] - NODE TEMPLATE INTERFACES - END
1010 if (MapUtils.isNotEmpty(props)) {
1011 nodeTemplate.setProperties(props);
1013 if (MapUtils.isNotEmpty(attribs)) {
1014 nodeTemplate.setAttributes(attribs);
1017 final List<GroupInstance> groupInstances = componentInstance.getGroupInstances();
1018 if (CollectionUtils.isNotEmpty(groupInstances)) {
1019 if (groupsMap == null) {
1020 groupsMap = new HashMap<>();
1022 for (final GroupInstance groupInst : groupInstances) {
1023 if (CollectionUtils.isNotEmpty(groupInst.getArtifacts())) {
1024 groupsMap.put(groupInst.getName(), groupExportParser.getToscaGroupTemplate(groupInst, componentInstance.getInvariantName()));
1029 nodeTemplates.put(componentInstance.getName(), nodeTemplate);
1031 if (groupsMap != null) {
1032 log.debug("instance groups added");
1033 topologyTemplate.addGroups(groupsMap);
1035 if (component.getComponentType() == ComponentTypeEnum.SERVICE && isNotEmpty(
1036 ((Service) component).getForwardingPaths())) {
1037 log.debug("Starting converting paths for component {}, name {}", component.getUniqueId(), component.getName());
1038 ForwardingPathToscaUtil
1039 .addForwardingPaths((Service) component, nodeTemplates, capabilityRequirementConverter, componentCache, toscaOperationFacade);
1040 log.debug("Finished converting paths for component {}, name {}", component.getUniqueId(), component.getName());
1042 if (convertNodeTemplatesRes == null) {
1043 convertNodeTemplatesRes = Either.left(nodeTemplates);
1045 log.debug("finish convert topology template for {} for type {}", component.getUniqueId(), component.getComponentType());
1046 return convertNodeTemplatesRes;
1049 private Object convertToToscaObject(String value) {
1051 ToscaMapValueConverter mapConverterInst = ToscaMapValueConverter.getInstance();
1052 StringReader reader = new StringReader(value);
1053 JsonReader jsonReader = new JsonReader(reader);
1054 jsonReader.setLenient(true);
1055 JsonElement jsonElement = JsonParser.parseReader(jsonReader);
1056 if (jsonElement.isJsonObject()) {
1057 JsonObject jsonObj = jsonElement.getAsJsonObject();
1058 if (jsonObj.entrySet().size() == 1 && jsonObj.has(ToscaFunctions.GET_INPUT.getFunctionName())) {
1059 return mapConverterInst.handleComplexJsonValue(jsonElement);
1063 } catch (Exception e) {
1064 log.debug("convertToToscaValue failed to parse json value :", e);
1069 private Object parseToIntIfPossible(final String value) {
1070 final Integer intValue = Ints.tryParse(value);
1071 return intValue == null ? value : intValue;
1074 private void handleInstanceInterfaces(
1075 Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces,
1076 ComponentInstance componentInstance, Map<String, DataTypeDefinition> dataTypes, ToscaNodeTemplate nodeTemplate,
1077 String instanceUniqueId,
1078 Component parentComponent) {
1080 if (MapUtils.isEmpty(componentInstanceInterfaces)
1081 || !componentInstanceInterfaces.containsKey(instanceUniqueId)) {
1082 nodeTemplate.setInterfaces(null);
1086 final List<ComponentInstanceInterface> currServiceInterfaces =
1087 componentInstanceInterfaces.get(instanceUniqueId);
1089 final Map<String, InterfaceDefinition> tmpInterfaces = new HashMap<>();
1090 currServiceInterfaces.forEach(instInterface -> tmpInterfaces.put(instInterface
1091 .getUniqueId(), instInterface));
1093 final Map<String, Object> interfaceMap = interfacesOperationsConverter
1094 .getInterfacesMap(parentComponent, componentInstance, tmpInterfaces, dataTypes, isComponentOfTypeServiceProxy(componentInstance),
1095 isComponentOfTypeServiceProxy(componentInstance));
1097 interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
1098 nodeTemplate.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap);
1101 private boolean isComponentOfTypeServiceProxy(ComponentInstance componentInstance) {
1102 return Objects.nonNull(componentInstance.getOriginType())
1103 && componentInstance.getOriginType().getValue().equals("Service Proxy");
1106 private void addComponentInstanceInputs(Map<String, DataTypeDefinition> dataTypes,
1107 Map<String, List<ComponentInstanceInput>> componentInstancesInputs,
1108 String instanceUniqueId, Map<String, Object> props) {
1110 List<ComponentInstanceInput> instanceInputsList = componentInstancesInputs.get(instanceUniqueId);
1111 if (instanceInputsList != null) {
1112 instanceInputsList.forEach(input -> {
1113 Supplier<String> supplier = () -> input.getValue() != null && !Objects.isNull(input.getValue()) ? input.getValue()
1114 : input.getDefaultValue();
1115 propertyConvertor.convertAndAddValue(dataTypes, props, input, supplier);
1120 private void addPropertiesOfComponentInstance(final Map<String, List<ComponentInstanceProperty>> componentInstancesProperties,
1121 final Map<String, DataTypeDefinition> dataTypes,
1122 final String instanceUniqueId,
1123 final Map<String, Object> props) {
1125 if (isNotEmpty(componentInstancesProperties)) {
1126 componentInstancesProperties.get(instanceUniqueId)
1127 // Converts and adds each value to property map
1128 .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop, prop::getValue));
1132 private void addAttributesOfComponentInstance(final Map<String, List<ComponentInstanceAttribute>> componentInstancesAttributes,
1133 final String instanceUniqueId,
1134 final Map<String, Object> attribs) {
1136 if (isNotEmpty(componentInstancesAttributes) && componentInstancesAttributes.containsKey(instanceUniqueId)) {
1137 componentInstancesAttributes.get(instanceUniqueId)
1138 .forEach(attributeDefinition -> attributeConverter.convertAndAddValue(attribs, attributeDefinition));
1142 private void addPropertiesOfParentComponent(Map<String, DataTypeDefinition> dataTypes,
1143 Component componentOfInstance, Map<String, Object> props) {
1145 List<PropertyDefinition> componentProperties = componentOfInstance.getProperties();
1146 if (isNotEmpty(componentProperties)) {
1147 componentProperties.stream()
1148 // Filters out properties with empty default values
1149 .filter(prop -> StringUtils.isNotEmpty(prop.getDefaultValue()))
1150 // Converts and adds each value to property map
1151 .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop, prop::getDefaultValue));
1155 private void addAttributesOfParentComponent(final Component componentOfInstance, final Map<String, Object> attribs) {
1157 final List<AttributeDefinition> componentAttributes = componentOfInstance.getAttributes();
1158 if (isNotEmpty(componentAttributes)) {
1159 componentAttributes.stream()
1160 // Filters out Attributes with empty default values
1161 .filter(attrib -> StringUtils.isNotEmpty(attrib.getDefaultValue()))
1162 // Converts and adds each value to attribute map
1163 .forEach(attributeDefinition -> attributeConverter.convertAndAddValue(attribs, attributeDefinition));
1167 private ToscaNodeType createNodeType(Component component) {
1168 ToscaNodeType toscaNodeType = new ToscaNodeType();
1169 if (ModelConverter.isAtomicComponent(component)) {
1170 if (((Resource) component).getDerivedFrom() != null) {
1171 toscaNodeType.setDerived_from(((Resource) component).getDerivedFrom().get(0));
1173 toscaNodeType.setDescription(component.getDescription());
1175 String derivedFrom = null != component.getDerivedFromGenericType() ? component.getDerivedFromGenericType()
1177 toscaNodeType.setDerived_from(derivedFrom);
1179 return toscaNodeType;
1182 private Either<Map<String, Object>, ToscaError> createProxyInterfaceTypes(Component container) {
1184 Map<String, Object> proxyInterfaceTypes = new HashMap<>();
1185 Either<Map<String, Object>, ToscaError> res = Either.left(proxyInterfaceTypes);
1186 List<ComponentInstance> componentInstances = container.getComponentInstances();
1187 if (CollectionUtils.isEmpty(componentInstances)) {
1190 Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
1191 componentInstances.stream()
1192 .filter(this::isComponentOfTypeServiceProxy)
1193 .forEach(inst -> serviceProxyInstanceList.put(inst.getToscaComponentName(), inst));
1194 if (MapUtils.isEmpty(serviceProxyInstanceList)) {
1197 for (Entry<String, ComponentInstance> entryProxy : serviceProxyInstanceList.entrySet()) {
1198 Component serviceComponent;
1199 ComponentParametersView componentParametersView = new ComponentParametersView();
1200 componentParametersView.disableAll();
1201 componentParametersView.setIgnoreInterfaces(false);
1202 Either<Component, StorageOperationStatus> service = toscaOperationFacade
1203 .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
1204 if (service.isRight()) {
1205 log.debug("Failed to fetch original service component with id {} for instance {}",
1206 entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName());
1207 return Either.right(ToscaError.GENERAL_ERROR);
1209 serviceComponent = service.left().value();
1212 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither =
1213 interfaceLifecycleOperation.getAllInterfaceLifecycleTypes(serviceComponent.getModel());
1214 if (lifecycleTypeEither.isRight()) {
1215 log.debug("Failed to retrieve global interface types :", lifecycleTypeEither.right().value());
1216 return Either.right(ToscaError.GENERAL_ERROR);
1219 List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value().values().stream()
1220 .map(InterfaceDataDefinition::getType)
1221 .collect(Collectors.toList());
1222 //Add interface types for local interfaces in the original service component for proxy
1223 Map<String, Object> localInterfaceTypes = interfacesOperationsConverter.addInterfaceTypeElement(serviceComponent,
1224 allGlobalInterfaceTypes);
1225 if (MapUtils.isNotEmpty(localInterfaceTypes)) {
1226 proxyInterfaceTypes.putAll(localInterfaceTypes);
1230 return Either.left(proxyInterfaceTypes);
1233 private Either<Map<String, ToscaNodeType>, ToscaError> createProxyNodeTypes(Map<String, Component> componentCache,
1234 Component container) {
1236 Map<String, ToscaNodeType> nodeTypesMap = new HashMap<>();
1237 Either<Map<String, ToscaNodeType>, ToscaError> res = Either.left(nodeTypesMap);
1239 List<ComponentInstance> componentInstances = container.getComponentInstances();
1241 if (componentInstances == null || componentInstances.isEmpty()) {
1244 Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
1245 List<ComponentInstance> proxyInst = componentInstances.stream()
1246 .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceProxy.name()))
1247 .collect(Collectors.toList());
1248 if (proxyInst != null && !proxyInst.isEmpty()) {
1249 for (ComponentInstance inst : proxyInst) {
1250 serviceProxyInstanceList.put(inst.getToscaComponentName(), inst);
1254 if (serviceProxyInstanceList.isEmpty()) {
1257 Either<Resource, StorageOperationStatus> serviceProxyOrigin = toscaOperationFacade
1258 .getLatestByName("serviceProxy", null);
1259 if (serviceProxyOrigin.isRight()) {
1260 log.debug("Failed to fetch normative service proxy resource by tosca name, error {}",
1261 serviceProxyOrigin.right().value());
1262 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
1264 Component origComponent = serviceProxyOrigin.left().value();
1266 for (Entry<String, ComponentInstance> entryProxy : serviceProxyInstanceList.entrySet()) {
1267 Component serviceComponent = null;
1268 ComponentParametersView componentParametersView = new ComponentParametersView();
1269 componentParametersView.disableAll();
1270 componentParametersView.setIgnoreCategories(false);
1271 componentParametersView.setIgnoreProperties(false);
1272 componentParametersView.setIgnoreInputs(false);
1273 componentParametersView.setIgnoreInterfaces(false);
1274 componentParametersView.setIgnoreRequirements(false);
1275 Either<Component, StorageOperationStatus> service = toscaOperationFacade
1276 .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
1277 if (service.isRight()) {
1278 log.debug("Failed to fetch resource with id {} for instance {}",
1279 entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName());
1281 serviceComponent = service.left().value();
1284 ToscaNodeType toscaNodeType = createProxyNodeType(componentCache, origComponent, serviceComponent,
1285 entryProxy.getValue());
1286 nodeTypesMap.put(entryProxy.getKey(), toscaNodeType);
1289 return Either.left(nodeTypesMap);
1292 private void createServiceSubstitutionNodeTypes(final Map<String, Component> componentCache,
1293 final Component container, final ToscaTemplate toscaNode) {
1294 final List<ComponentInstance> componentInstances = container.getComponentInstances();
1296 if (CollectionUtils.isEmpty(componentInstances)) {
1299 final List<ComponentInstance> serviceSubstitutionInstanceList = componentInstances.stream()
1300 .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceSubstitution.name()))
1301 .collect(Collectors.toList());
1302 if (CollectionUtils.isNotEmpty(serviceSubstitutionInstanceList)) {
1303 for (ComponentInstance inst : serviceSubstitutionInstanceList) {
1304 final Map<String, ToscaNodeType> nodeTypes =
1305 toscaNode.getNode_types() == null ? new HashMap<>() : toscaNode.getNode_types();
1306 convertInterfaceNodeType(new HashMap<>(), componentCache.get(inst.getSourceModelUid()), toscaNode,
1312 private ToscaNodeType createProxyNodeType(Map<String, Component> componentCache, Component origComponent,
1313 Component proxyComponent, ComponentInstance componentInstance) {
1314 ToscaNodeType toscaNodeType = new ToscaNodeType();
1315 String derivedFrom = ((Resource) origComponent).getToscaResourceName();
1317 toscaNodeType.setDerived_from(derivedFrom);
1318 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = applicationDataTypeCache.getAll(
1319 origComponent.getModel());
1320 if (dataTypesEither.isRight()) {
1321 log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
1323 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
1324 Map<String, ToscaCapability> capabilities = this.capabilityRequirementConverter
1325 .convertProxyCapabilities(componentCache, componentInstance, dataTypes);
1327 if (MapUtils.isNotEmpty(capabilities)) {
1328 toscaNodeType.setCapabilities(capabilities);
1330 List<Map<String, ToscaRequirement>> proxyNodeTypeRequirements = this.capabilityRequirementConverter
1331 .convertProxyRequirements(componentCache, componentInstance);
1332 if (CollectionUtils.isNotEmpty(proxyNodeTypeRequirements)) {
1333 toscaNodeType.setRequirements(proxyNodeTypeRequirements);
1335 Optional<Map<String, ToscaProperty>> proxyProperties = getProxyNodeTypeProperties(proxyComponent, dataTypes);
1336 proxyProperties.ifPresent(toscaNodeType::setProperties);
1338 Map<String, Object> interfaceMap = new HashMap<>();
1339 if (MapUtils.isEmpty(componentInstance.getInterfaces())) {
1340 final Optional<Map<String, Object>> proxyInterfaces = getProxyNodeTypeInterfaces(proxyComponent, dataTypes);
1341 if (proxyInterfaces.isPresent()) {
1342 interfaceMap = proxyInterfaces.get();
1345 interfaceMap = interfacesOperationsConverter
1346 .getInterfacesMapFromComponentInstance(proxyComponent, componentInstance, dataTypes, false, false);
1349 interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
1350 toscaNodeType.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap);
1352 return toscaNodeType;
1355 private Either<ToscaNodeTemplate, ToscaError> convertComponentInstanceRequirements(Component component,
1356 ComponentInstance componentInstance,
1357 List<RequirementCapabilityRelDef> relations,
1358 ToscaNodeTemplate nodeTypeTemplate,
1359 Component originComponent,
1360 Map<String, Component> componentCache) {
1362 final List<RequirementCapabilityRelDef> requirementDefinitionList = filterRequirements(componentInstance,
1364 if (isNotEmpty(requirementDefinitionList)) {
1366 final List<Map<String, ToscaTemplateRequirement>> toscaRequirements = buildRequirements(component, componentInstance,
1367 requirementDefinitionList, originComponent, componentCache);
1368 if (!toscaRequirements.isEmpty()) {
1369 nodeTypeTemplate.setRequirements(toscaRequirements);
1371 } catch (final Exception e) {
1372 log.debug("Failed to convert component instance requirements for the component instance {}. ",
1373 componentInstance.getName(), e);
1374 return Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
1377 log.debug("Finished to convert requirements for the node type {} ", componentInstance.getName());
1378 return Either.left(nodeTypeTemplate);
1381 private List<Map<String, ToscaTemplateRequirement>> buildRequirements(final Component component,
1382 final ComponentInstance componentInstance,
1383 final List<RequirementCapabilityRelDef> filteredRelations,
1384 final Component originComponent,
1385 final Map<String, Component> componentCache)
1386 throws ToscaExportException {
1388 final List<Map<String, ToscaTemplateRequirement>> toscaRequirements = new ArrayList<>();
1389 for (RequirementCapabilityRelDef relationshipDefinition : filteredRelations) {
1390 final Map<String, ToscaTemplateRequirement> toscaTemplateRequirementMap =
1391 buildRequirement(componentInstance, originComponent, component.getComponentInstances(), relationshipDefinition, componentCache);
1392 toscaRequirements.add(toscaTemplateRequirementMap);
1395 return toscaRequirements;
1398 private List<RequirementCapabilityRelDef> filterRequirements(ComponentInstance componentInstance,
1399 List<RequirementCapabilityRelDef> relations) {
1400 return relations.stream()
1401 .filter(p -> componentInstance.getUniqueId().equals(p.getFromNode())).collect(Collectors.toList());
1404 private Map<String, ToscaTemplateRequirement> buildRequirement(final ComponentInstance fromInstance,
1405 final Component fromOriginComponent,
1406 final List<ComponentInstance> instancesList,
1407 final RequirementCapabilityRelDef relationshipDefinition,
1408 final Map<String, Component> componentCache)
1409 throws ToscaExportException {
1411 final Map<String, List<RequirementDefinition>> reqMap = fromOriginComponent.getRequirements();
1412 final CapabilityRequirementRelationship capabilityRequirementRelationship = relationshipDefinition
1413 .getRelationships().get(0);
1414 final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation();
1416 final ComponentInstance toInstance = instancesList.stream()
1417 .filter(i -> relationshipDefinition.getToNode().equals(i.getUniqueId()))
1418 .findFirst().orElse(null);
1419 if (toInstance == null) {
1420 final String errorMsg = String
1421 .format("Failed to find a relation from the node %s to the node %s", fromInstance.getName(),
1422 relationshipDefinition.getToNode());
1423 log.debug(errorMsg);
1424 throw new ToscaExportException(errorMsg);
1426 final Optional<RequirementDefinition> reqOpt =
1427 findRequirement(fromOriginComponent, reqMap, relationshipInfo, fromInstance.getUniqueId());
1428 if (reqOpt.isEmpty()) {
1429 final String errorMsg = String
1430 .format("Failed to find a requirement with uniqueId %s on a component with uniqueId %s",
1431 relationshipInfo.getRequirementUid(), fromOriginComponent.getUniqueId());
1432 log.debug(errorMsg);
1433 throw new ToscaExportException(errorMsg);
1435 final ComponentParametersView filter = new ComponentParametersView(true);
1436 filter.setIgnoreComponentInstances(false);
1437 filter.setIgnoreCapabilities(false);
1438 filter.setIgnoreGroups(false);
1439 final Either<Component, StorageOperationStatus> getOriginRes =
1440 toscaOperationFacade.getToscaElement(toInstance.getActualComponentUid(), filter);
1441 if (getOriginRes.isRight()) {
1442 final String errorMsg = String.format(
1443 "Failed to build substituted name for the requirement %s. "
1444 + "Failed to get an origin component with uniqueId %s",
1445 reqOpt.get().getName(), toInstance.getActualComponentUid());
1446 log.debug(errorMsg);
1447 throw new ToscaExportException(errorMsg);
1449 final Component toOriginComponent = getOriginRes.left().value();
1450 Optional<CapabilityDefinition> capOpt = toOriginComponent.getCapabilities().get(reqOpt.get().getCapability()).stream()
1451 .filter(c -> isCapabilityBelongToRelation(relationshipInfo, c)).findFirst();
1452 if (capOpt.isEmpty()) {
1453 capOpt = findCapability(relationshipInfo, toOriginComponent, fromOriginComponent, reqOpt.get());
1454 if (capOpt.isEmpty()) {
1455 final String errorMsg = String
1456 .format("Failed to find a capability with name %s on a component with uniqueId %s",
1457 relationshipInfo.getCapability(), fromOriginComponent.getUniqueId());
1458 log.debug(errorMsg);
1459 throw new ToscaExportException(errorMsg);
1462 return buildRequirement(fromOriginComponent, toOriginComponent, capOpt.get(), reqOpt.get(),
1463 capabilityRequirementRelationship, toInstance, componentCache);
1466 private boolean isCapabilityBelongToRelation(RelationshipInfo reqAndRelationshipPair,
1467 CapabilityDefinition capability) {
1468 return capability.getName().equals(reqAndRelationshipPair.getCapability()) && (capability.getOwnerId() != null
1469 && capability.getOwnerId().equals(reqAndRelationshipPair.getCapabilityOwnerId()));
1472 private Optional<CapabilityDefinition> findCapability(RelationshipInfo reqAndRelationshipPair,
1473 Component toOriginComponent, Component fromOriginComponent,
1474 RequirementDefinition requirement) {
1475 Optional<CapabilityDefinition> cap = toOriginComponent.getCapabilities().get(requirement.getCapability())
1476 .stream().filter(c -> c.getType().equals(requirement.getCapability())).findFirst();
1477 if (!cap.isPresent()) {
1478 log.debug("Failed to find a capability with name {} on a component with uniqueId {}",
1479 reqAndRelationshipPair.getCapability(), fromOriginComponent.getUniqueId());
1484 private Map<String, ToscaTemplateRequirement> buildRequirement(final Component fromOriginComponent,
1485 final Component toOriginComponent,
1486 final CapabilityDefinition capability,
1487 final RequirementDefinition requirement,
1488 final CapabilityRequirementRelationship capabilityRequirementRelationship,
1489 final ComponentInstance toInstance,
1490 final Map<String, Component> componentCache)
1491 throws ToscaExportException {
1493 List<String> reducedPath = capability.getPath();
1494 if (capability.getOwnerId() != null) {
1495 reducedPath = capabilityRequirementConverter
1496 .getReducedPathByOwner(capability.getPath(), capability.getOwnerId());
1498 final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation();
1499 final Either<String, Boolean> capabilityNameEither = capabilityRequirementConverter.buildSubstitutedName(componentCache,
1500 toOriginComponent, reducedPath, relationshipInfo.getCapability(), capability.getPreviousName(), capability.getExternalName());
1501 if (capabilityNameEither.isRight()) {
1502 final String errorMsg = String.format(
1503 "Failed to build a substituted capability name for the capability with name %s on a component with uniqueId %s",
1504 capabilityRequirementRelationship.getCapability(), toOriginComponent.getUniqueId());
1507 throw new ToscaExportException(errorMsg);
1509 final Either<String, Boolean> requirementNameEither = capabilityRequirementConverter
1510 .buildSubstitutedName(componentCache, fromOriginComponent,
1511 requirement.getPath(), relationshipInfo.getRequirement(), requirement.getPreviousName(), requirement.getExternalName());
1512 if (requirementNameEither.isRight()) {
1513 final String errorMsg = String.format("Failed to build a substituted requirement name for the requirement "
1514 + "with name %s on a component with uniqueId %s",
1515 capabilityRequirementRelationship.getRequirement(), fromOriginComponent.getUniqueId());
1516 log.debug(errorMsg);
1517 throw new ToscaExportException(errorMsg);
1519 final ToscaTemplateRequirement toscaRequirement = new ToscaTemplateRequirement();
1520 final Map<String, ToscaTemplateRequirement> toscaReqMap = new HashMap<>();
1521 toscaRequirement.setNode(toInstance.getName());
1522 toscaRequirement.setCapability(capabilityNameEither.left().value());
1523 if (isNotEmpty(capabilityRequirementRelationship.getOperations())) {
1524 toscaRequirement.setRelationship(new ToscaRelationshipBuilder().from(capabilityRequirementRelationship));
1526 toscaReqMap.put(requirementNameEither.left().value(), toscaRequirement);
1530 private Optional<RequirementDefinition> findRequirement(Component fromOriginComponent,
1531 Map<String, List<RequirementDefinition>> reqMap,
1532 RelationshipInfo reqAndRelationshipPair,
1533 String fromInstanceId) {
1534 for (List<RequirementDefinition> reqList : reqMap.values()) {
1535 Optional<RequirementDefinition> reqOpt = reqList.stream().filter(
1536 r -> isRequirementBelongToRelation(fromOriginComponent, reqAndRelationshipPair, r, fromInstanceId))
1538 if (reqOpt.isPresent()) {
1542 return Optional.empty();
1546 * Allows detecting the requirement belonging to the received relationship The detection logic is: A requirement belongs to a relationship IF
1547 * 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
1548 * requirement equals to requirementOwnerId of the relation OR uniqueId of toInstance equals to capabilityOwnerId of the relation
1550 private boolean isRequirementBelongToRelation(Component originComponent, RelationshipInfo reqAndRelationshipPair,
1551 RequirementDefinition requirement, String fromInstanceId) {
1552 if (!StringUtils.equals(requirement.getName(), reqAndRelationshipPair.getRequirement())) {
1553 log.debug("Failed to find a requirement with name {} and reqAndRelationshipPair {}", requirement.getName(),
1554 reqAndRelationshipPair.getRequirement());
1557 return ModelConverter.isAtomicComponent(originComponent) || isRequirementBelongToOwner(reqAndRelationshipPair, requirement, fromInstanceId,
1561 private boolean isRequirementBelongToOwner(RelationshipInfo reqAndRelationshipPair, RequirementDefinition requirement, String fromInstanceId,
1562 Component originComponent) {
1563 return StringUtils.equals(requirement.getOwnerId(), reqAndRelationshipPair.getRequirementOwnerId()) || (
1564 isCvfc(originComponent) && StringUtils.equals(fromInstanceId, reqAndRelationshipPair.getRequirementOwnerId()) || StringUtils
1565 .equals(requirement.getOwnerId(), originComponent.getUniqueId()));
1568 private boolean isCvfc(Component component) {
1569 return component.getComponentType() == ComponentTypeEnum.RESOURCE && ((Resource) component).getResourceType() == ResourceTypeEnum.CVFC;
1572 private Either<Map<String, String[]>, ToscaError> convertSubstitutionMappingCapabilities(final Component component,
1573 final Map<String, Component> componentCache) {
1574 Either<Map<String, String[]>, ToscaError> toscaCapabilitiesRes =
1575 capabilityRequirementConverter.convertSubstitutionMappingCapabilities(componentCache, component);
1576 if (toscaCapabilitiesRes.isRight()) {
1577 log.debug("Failed convert capabilities for the component {}. ", component.getName());
1578 return Either.right(toscaCapabilitiesRes.right().value());
1580 if (isNotEmpty(toscaCapabilitiesRes.left().value())) {
1581 log.debug("Finish convert capabilities for the component {}. ", component.getName());
1582 return Either.left(toscaCapabilitiesRes.left().value());
1584 log.debug("Finished to convert capabilities for the component {}. ", component.getName());
1586 return Either.left(Collections.emptyMap());
1589 private Either<ToscaNodeType, ToscaError> convertCapabilities(Map<String, Component> componentsCache, Component component, ToscaNodeType nodeType,
1590 Map<String, DataTypeDefinition> dataTypes) {
1591 Map<String, ToscaCapability> toscaCapabilities = capabilityRequirementConverter.convertCapabilities(componentsCache, component, dataTypes);
1592 if (!toscaCapabilities.isEmpty()) {
1593 nodeType.setCapabilities(toscaCapabilities);
1595 log.debug("Finish convert Capabilities for node type");
1596 return Either.left(nodeType);
1599 private Map<String, ToscaTemplateArtifact> convertToNodeTemplateArtifacts(Map<String, ToscaArtifactDataDefinition> artifacts) {
1600 if (artifacts == null) {
1603 Map<String, ToscaTemplateArtifact> arts = new HashMap<>();
1604 for (Map.Entry<String, ToscaArtifactDataDefinition> entry : artifacts.entrySet()) {
1605 ToscaTemplateArtifact artifact = new ToscaTemplateArtifact();
1606 artifact.setFile(entry.getValue().getFile());
1607 artifact.setType(entry.getValue().getType());
1608 artifact.setProperties(entry.getValue().getProperties());
1609 arts.put(entry.getKey(), artifact);
1614 private NodeFilter convertToNodeTemplateNodeFilterComponent(CINodeFilterDataDefinition inNodeFilter) {
1615 if (inNodeFilter == null) {
1618 NodeFilter nodeFilter = new NodeFilter();
1619 ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities = inNodeFilter.getCapabilities();
1620 ListDataDefinition<PropertyFilterDataDefinition> origProperties = inNodeFilter.getProperties();
1621 List<Map<String, CapabilityFilter>> capabilitiesCopy = new ArrayList<>();
1622 copyNodeFilterCapabilitiesTemplate(origCapabilities, capabilitiesCopy);
1623 if (CollectionUtils.isNotEmpty(capabilitiesCopy)) {
1624 nodeFilter.setCapabilities(capabilitiesCopy);
1626 final List<Map<String, List<Object>>> propertiesCopy = copyNodeFilterProperties(origProperties);
1627 if (CollectionUtils.isNotEmpty(propertiesCopy)) {
1628 nodeFilter.setProperties(propertiesCopy);
1630 nodeFilter.setTosca_id(cloneToscaId(inNodeFilter.getTosca_id()));
1631 nodeFilter = (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
1635 private NodeFilter convertToSubstitutionFilterComponent(final SubstitutionFilterDataDefinition substitutionFilterDataDefinition) {
1636 if (substitutionFilterDataDefinition == null) {
1639 NodeFilter nodeFilter = new NodeFilter();
1640 final List<Map<String, List<Object>>> propertiesCopy = copySubstitutionPropertiesFilter(substitutionFilterDataDefinition.getProperties());
1641 if (!propertiesCopy.isEmpty()) {
1642 nodeFilter.setProperties(propertiesCopy);
1644 nodeFilter.setTosca_id(cloneToscaId(substitutionFilterDataDefinition.getTosca_id()));
1645 return (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
1648 private Object cloneToscaId(Object toscaId) {
1649 return Objects.isNull(toscaId) ? null : cloneObjectFromYml(toscaId, toscaId.getClass());
1652 private Object cloneObjectFromYml(Object objToClone, Class classOfObj) {
1653 String objectAsYml = yamlUtil.objectToYaml(objToClone);
1654 return yamlUtil.yamlToObject(objectAsYml, classOfObj);
1657 private void copyNodeFilterCapabilitiesTemplate(ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities,
1658 List<Map<String, CapabilityFilter>> capabilitiesCopy) {
1659 if (origCapabilities == null || origCapabilities.getListToscaDataDefinition() == null || origCapabilities.getListToscaDataDefinition()
1663 for (RequirementNodeFilterCapabilityDataDefinition capability : origCapabilities.getListToscaDataDefinition()) {
1664 Map<String, CapabilityFilter> capabilityFilterCopyMap = new HashMap<>();
1665 final var capabilityFilter = new CapabilityFilter();
1666 capabilityFilter.setProperties(copyNodeFilterProperties(capability.getProperties()));
1667 capabilityFilterCopyMap.put(capability.getName(), capabilityFilter);
1668 capabilitiesCopy.add(capabilityFilterCopyMap);
1672 private List<Map<String, List<Object>>> copyNodeFilterProperties(final ListDataDefinition<PropertyFilterDataDefinition> origProperties) {
1673 if (origProperties == null || origProperties.getListToscaDataDefinition() == null || origProperties.isEmpty()) {
1674 return Collections.emptyList();
1676 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1677 Map<String, List<Object>> propertyFilterDefinitionMap = new HashMap<>();
1678 for (final PropertyFilterDataDefinition propertyFilter : origProperties.getListToscaDataDefinition()) {
1679 final String propertyName = propertyFilter.getName();
1680 for (final PropertyFilterConstraintDataDefinition filterConstraint : propertyFilter.getConstraints()) {
1681 propertyFilterDefinitionMap.compute(propertyName, (propertyName1, constraints) -> {
1682 if (constraints == null) {
1683 constraints = new ArrayList<>();
1685 constraints.add(buildNodeFilterValue(filterConstraint));
1690 propertyFilterDefinitionMap.entrySet().stream()
1691 .map(entry -> Map.of(entry.getKey(), entry.getValue()))
1692 .forEach(propertiesCopy::add);
1693 return propertiesCopy;
1696 private List<Map<String, List<Object>>> copySubstitutionPropertiesFilter(
1697 final ListDataDefinition<SubstitutionFilterPropertyDataDefinition> origProperties) {
1699 if (origProperties == null || origProperties.getListToscaDataDefinition() == null || origProperties.isEmpty()) {
1700 return Collections.emptyList();
1702 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1703 Map<String, List<Object>> propertyFilterDefinitionMap = new HashMap<>();
1704 for (final SubstitutionFilterPropertyDataDefinition propertyFilter : origProperties.getListToscaDataDefinition()) {
1705 final String propertyName = propertyFilter.getName();
1706 for (final PropertyFilterConstraintDataDefinition filterConstraint : propertyFilter.getConstraints()) {
1707 propertyFilterDefinitionMap.compute(propertyName, (propertyName1, constraints) -> {
1708 if (constraints == null) {
1709 constraints = new ArrayList<>();
1711 constraints.add(buildNodeFilterValue(filterConstraint));
1716 propertyFilterDefinitionMap.entrySet().stream()
1717 .map(entry -> Map.of(entry.getKey(), entry.getValue()))
1718 .forEach(propertiesCopy::add);
1719 return propertiesCopy;
1722 private static Object buildNodeFilterValue(final PropertyFilterConstraintDataDefinition filterConstraint) {
1723 if (filterConstraint.getValue() instanceof ToscaFunction) {
1724 return Map.of(filterConstraint.getOperator().getType(), ((ToscaFunction) filterConstraint.getValue()).getJsonObjectValue());
1726 return Map.of(filterConstraint.getOperator().getType(), filterConstraint.getValue());
1730 private Map<String, String[]> buildSubstitutionMappingPropertyMapping(final Component component) {
1731 if (component == null || CollectionUtils.isEmpty(component.getInputs())) {
1732 return Collections.emptyMap();
1734 return component.getInputs().stream().filter(InputDefinition::isMappedToComponentProperty).map(PropertyDataDefinition::getName)
1735 .collect(Collectors.toMap(inputName -> inputName, inputName -> new String[]{inputName}, (inputName1, inputName2) -> inputName1));
1738 private Map<String, String[]> buildSubstitutionMappingAttributesMapping(final Component component) {
1739 if (component == null || CollectionUtils.isEmpty(component.getOutputs())) {
1740 return Collections.emptyMap();
1742 return component.getOutputs().stream().map(AttributeDataDefinition::getName)
1743 .collect(Collectors.toMap(outputName -> outputName, outputName -> new String[]{outputName}, (outputName1, outputName2) -> outputName1));
1746 private Optional<Map<String, ToscaProperty>> getProxyNodeTypeProperties(Component proxyComponent, Map<String, DataTypeDefinition> dataTypes) {
1747 if (Objects.isNull(proxyComponent)) {
1748 return Optional.empty();
1750 final var proxyProperties = convertInputsToProperties(dataTypes, proxyComponent.getInputs(), proxyComponent.getUniqueId());
1751 if (CollectionUtils.isNotEmpty(proxyComponent.getProperties())) {
1752 proxyProperties.putAll(proxyComponent.getProperties().stream()
1753 .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, proxyComponent.getInputs())).collect(Collectors
1754 .toMap(PropertyDataDefinition::getName,
1755 property -> propertyConvertor.convertProperty(dataTypes, property, PropertyType.PROPERTY))));
1757 return MapUtils.isNotEmpty(proxyProperties) ? Optional.of(proxyProperties) : Optional.empty();
1760 private Map<String, ToscaProperty> convertInputsToProperties(Map<String, DataTypeDefinition> dataTypes, List<InputDefinition> componentInputs,
1761 String componentUniqueId) {
1762 if (CollectionUtils.isEmpty(componentInputs)) {
1763 return new HashMap<>();
1765 return componentInputs.stream().filter(input -> componentUniqueId.equals(input.getInstanceUniqueId()))
1766 .collect(Collectors.toMap(InputDefinition::getName, i -> propertyConvertor.convertProperty(dataTypes, i, PropertyType.INPUT)));
1769 private Optional<Map<String, Object>> getProxyNodeTypeInterfaces(Component proxyComponent, Map<String, DataTypeDefinition> dataTypes) {
1770 if (Objects.isNull(proxyComponent) || MapUtils.isEmpty(proxyComponent.getInterfaces())) {
1771 return Optional.empty();
1773 Map<String, InterfaceDefinition> proxyComponentInterfaces = proxyComponent.getInterfaces();
1774 //Unset artifact path for operation implementation for proxy node types as for operations with artifacts it is
1776 // always available in the proxy node template
1777 removeOperationImplementationForProxyNodeType(proxyComponentInterfaces);
1779 .ofNullable(interfacesOperationsConverter.getInterfacesMap(proxyComponent, null, proxyComponentInterfaces, dataTypes, false, false));
1782 private static class CustomRepresenter extends Representer {
1784 CustomRepresenter() {
1786 this.representers.put(ToscaPropertyAssignment.class, new RepresentToscaPropertyAssignment());
1787 this.representers.put(ToscaAttribute.class, new RepresentToscaAttribute());
1788 // null representer is exceptional and it is stored as an instance
1791 this.nullRepresenter = new RepresentNull();
1794 public boolean validateGetInputValue(final Object valueObj) {
1795 if (!(valueObj instanceof List) && !(valueObj instanceof String)) {
1798 if (valueObj instanceof List) {
1799 return ((List) valueObj).size() > 1;
1804 public boolean validateGetPropertyOrAttributeValue(final Object valueObj) {
1805 if (valueObj instanceof List) {
1806 return ((List) valueObj).size() > 1;
1812 protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue, Tag customTag) {
1813 if (propertyValue == null) {
1816 // skip not relevant for Tosca property
1817 if ("dependencies".equals(property.getName())) {
1820 if (javaBean instanceof ToscaRelationshipTemplate && "name".equals(property.getName())) {
1823 if (javaBean instanceof ToscaPropertyConstraint) {
1824 return handleToscaPropertyConstraint((ToscaPropertyConstraint)javaBean, property, propertyValue, customTag);
1826 removeDefaultP(propertyValue);
1827 NodeTuple defaultNode = super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
1828 if (javaBean instanceof ToscaTopolgyTemplate && "relationshipTemplates".equals(property.getName())) {
1829 return new NodeTuple(representData("relationship_templates"), defaultNode.getValueNode());
1831 return "_defaultp_".equals(property.getName()) ? new NodeTuple(representData("default"), defaultNode.getValueNode()) : defaultNode;
1834 private NodeTuple handleToscaPropertyConstraint(final ToscaPropertyConstraint javaBean, final Property property, final Object propertyValue,
1835 final Tag customTag) {
1836 final NodeTuple nodeTuple = super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
1837 final String entryToscaName = javaBean.getEntryToscaName(property.getName());
1838 return new NodeTuple(representData(entryToscaName), nodeTuple.getValueNode());
1841 private void removeDefaultP(final Object propertyValue) {
1842 if (propertyValue instanceof Map) {
1843 final Map mapPropertyValue = ((Map) propertyValue);
1844 final Iterator<Entry> iter = mapPropertyValue.entrySet().iterator();
1845 Object defaultValue = null;
1846 while (iter.hasNext()) {
1847 final Map.Entry entry = iter.next();
1848 if ("_defaultp_".equals(entry.getKey())) {
1849 defaultValue = entry.getValue();
1851 } else if (entry.getValue() instanceof Map) {
1852 removeDefaultP(entry.getValue());
1855 if (defaultValue != null) {
1856 mapPropertyValue.putIfAbsent("default", defaultValue);
1862 protected MappingNode representJavaBean(Set<Property> properties, Object javaBean) {
1863 // remove the bean type from the output yaml (!! ...)
1864 if (!classTags.containsKey(javaBean.getClass())) {
1865 addClassTag(javaBean.getClass(), Tag.MAP);
1867 return super.representJavaBean(properties, javaBean);
1870 private class RepresentToscaAttribute implements Represent {
1873 public Node representData(Object data) {
1874 final ToscaAttribute toscaAttribute = (ToscaAttribute) data;
1875 return represent(toscaAttribute.asToscaMap());
1879 private class RepresentToscaPropertyAssignment implements Represent {
1881 public Node representData(Object data) {
1882 final ToscaPropertyAssignment toscaOperationAssignment = (ToscaPropertyAssignment) data;
1883 if (toscaOperationAssignment.getValue() instanceof String) {
1884 final String stringValue = (String) toscaOperationAssignment.getValue();
1885 if (isPropertyOrAttributeFunction(stringValue)) {
1886 return representGetAttribute(stringValue);
1888 return representScalar(Tag.STR, stringValue);
1890 return represent(null);
1893 public Node representGetAttribute(final String getAttributeFunction) {
1894 return represent(new Yaml().load(getAttributeFunction));
1897 public boolean isPropertyOrAttributeFunction(final String value) {
1899 final Yaml yaml = new Yaml();
1900 final Object yamlObj = yaml.load(value);
1901 if (!(yamlObj instanceof Map)) {
1904 final Map<String, Object> getAttributeMap = (Map) yamlObj;
1905 if (getAttributeMap.size() != 1) {
1908 final List<String> functionList = Arrays
1909 .asList(GET_ATTRIBUTE.getFunctionName(), GET_INPUT.getFunctionName(), GET_PROPERTY.getFunctionName());
1910 final Optional<String> function = getAttributeMap.keySet().stream()
1911 .filter(key -> functionList.stream().anyMatch(function1 -> function1.equals(key))).findFirst();
1912 if (function.isEmpty()) {
1915 final String functionName = function.get();
1916 final Object getAttributeValueObj = getAttributeMap.get(functionName);
1917 if (GET_INPUT.getFunctionName().equals(functionName)) {
1918 return validateGetInputValue(getAttributeValueObj);
1920 return validateGetPropertyOrAttributeValue(getAttributeValueObj);
1922 } catch (final Exception ignored) {
1928 private class RepresentNull implements Represent {
1931 public Node representData(Object data) {
1932 // possible values are here http://yaml.org/type/null.html
1933 return representScalar(Tag.NULL, "");
1938 private static class UnsortedPropertyUtils extends PropertyUtils {
1941 protected Set<Property> createPropertySet(Class type, BeanAccess bAccess) {
1942 Collection<Property> fields = getPropertiesMap(type, BeanAccess.FIELD).values();
1943 return new LinkedHashSet<>(fields);
1947 private Configuration getConfiguration() {
1948 return ConfigurationManager.getConfigurationManager().getConfiguration();