2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
20 package org.openecomp.sdc.be.tosca;
22 import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
23 import static org.apache.commons.collections.MapUtils.isNotEmpty;
24 import static org.openecomp.sdc.be.components.utils.PropertiesUtils.resolvePropertyValueFromInput;
25 import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_ATTRIBUTE;
26 import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_INPUT;
27 import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_PROPERTY;
29 import com.fasterxml.jackson.databind.ObjectMapper;
30 import com.google.common.primitives.Ints;
31 import com.google.gson.JsonElement;
32 import com.google.gson.JsonObject;
33 import com.google.gson.JsonParser;
34 import com.google.gson.stream.JsonReader;
35 import fj.data.Either;
36 import java.io.StringReader;
37 import java.nio.file.Path;
38 import java.util.ArrayList;
39 import java.util.Arrays;
40 import java.util.Collection;
41 import java.util.Collections;
42 import java.util.HashMap;
43 import java.util.HashSet;
44 import java.util.Iterator;
45 import java.util.LinkedHashMap;
46 import java.util.LinkedHashSet;
47 import java.util.List;
49 import java.util.Map.Entry;
50 import java.util.Objects;
51 import java.util.Optional;
53 import java.util.function.Supplier;
54 import java.util.stream.Collectors;
55 import org.apache.commons.collections.CollectionUtils;
56 import org.apache.commons.collections.MapUtils;
57 import org.apache.commons.io.FilenameUtils;
58 import org.apache.commons.lang3.StringUtils;
59 import org.apache.commons.lang3.tuple.ImmutablePair;
60 import org.apache.commons.lang3.tuple.ImmutableTriple;
61 import org.apache.commons.lang3.tuple.Triple;
62 import org.onap.sdc.tosca.services.YamlUtil;
63 import org.openecomp.sdc.be.components.impl.exceptions.SdcResourceNotFoundException;
64 import org.openecomp.sdc.be.config.Configuration;
65 import org.openecomp.sdc.be.config.ConfigurationManager;
66 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
67 import org.openecomp.sdc.be.data.model.ToscaImportByModel;
68 import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
69 import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition;
70 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
71 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
72 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
73 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
74 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition;
75 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition;
76 import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterPropertyDataDefinition;
77 import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition;
78 import org.openecomp.sdc.be.datatypes.elements.ToscaArtifactDataDefinition;
79 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
80 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
81 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
82 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
83 import org.openecomp.sdc.be.exception.ToscaExportException;
84 import org.openecomp.sdc.be.model.ArtifactDefinition;
85 import org.openecomp.sdc.be.model.AttributeDefinition;
86 import org.openecomp.sdc.be.model.CapabilityDefinition;
87 import org.openecomp.sdc.be.model.CapabilityRequirementRelationship;
88 import org.openecomp.sdc.be.model.Component;
89 import org.openecomp.sdc.be.model.ComponentInstance;
90 import org.openecomp.sdc.be.model.ComponentInstanceAttribute;
91 import org.openecomp.sdc.be.model.ComponentInstanceInput;
92 import org.openecomp.sdc.be.model.ComponentInstanceInterface;
93 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
94 import org.openecomp.sdc.be.model.ComponentParametersView;
95 import org.openecomp.sdc.be.model.DataTypeDefinition;
96 import org.openecomp.sdc.be.model.GroupInstance;
97 import org.openecomp.sdc.be.model.InputDefinition;
98 import org.openecomp.sdc.be.model.InterfaceDefinition;
99 import org.openecomp.sdc.be.model.PropertyDefinition;
100 import org.openecomp.sdc.be.model.RelationshipInfo;
101 import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
102 import org.openecomp.sdc.be.model.RequirementDefinition;
103 import org.openecomp.sdc.be.model.Resource;
104 import org.openecomp.sdc.be.model.Service;
105 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
106 import org.openecomp.sdc.be.model.category.CategoryDefinition;
107 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
108 import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter;
109 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
110 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
111 import org.openecomp.sdc.be.model.operations.impl.ModelOperation;
112 import org.openecomp.sdc.be.model.tosca.converters.ToscaMapValueConverter;
113 import org.openecomp.sdc.be.tosca.PropertyConvertor.PropertyType;
114 import org.openecomp.sdc.be.tosca.builder.ToscaRelationshipBuilder;
115 import org.openecomp.sdc.be.tosca.exception.ToscaConversionException;
116 import org.openecomp.sdc.be.tosca.model.CapabilityFilter;
117 import org.openecomp.sdc.be.tosca.model.NodeFilter;
118 import org.openecomp.sdc.be.tosca.model.SubstitutionMapping;
119 import org.openecomp.sdc.be.tosca.model.ToscaAttribute;
120 import org.openecomp.sdc.be.tosca.model.ToscaCapability;
121 import org.openecomp.sdc.be.tosca.model.ToscaDataType;
122 import org.openecomp.sdc.be.tosca.model.ToscaGroupTemplate;
123 import org.openecomp.sdc.be.tosca.model.ToscaNodeTemplate;
124 import org.openecomp.sdc.be.tosca.model.ToscaNodeType;
125 import org.openecomp.sdc.be.tosca.model.ToscaPolicyTemplate;
126 import org.openecomp.sdc.be.tosca.model.ToscaProperty;
127 import org.openecomp.sdc.be.tosca.model.ToscaPropertyAssignment;
128 import org.openecomp.sdc.be.tosca.model.ToscaRelationshipTemplate;
129 import org.openecomp.sdc.be.tosca.model.ToscaRequirement;
130 import org.openecomp.sdc.be.tosca.model.ToscaTemplate;
131 import org.openecomp.sdc.be.tosca.model.ToscaTemplateArtifact;
132 import org.openecomp.sdc.be.tosca.model.ToscaTemplateRequirement;
133 import org.openecomp.sdc.be.tosca.model.ToscaTopolgyTemplate;
134 import org.openecomp.sdc.be.tosca.utils.ForwardingPathToscaUtil;
135 import org.openecomp.sdc.be.tosca.utils.InputConverter;
136 import org.openecomp.sdc.be.tosca.utils.OutputConverter;
137 import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
138 import org.openecomp.sdc.common.log.wrappers.Logger;
139 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
140 import org.springframework.beans.factory.annotation.Autowired;
141 import org.yaml.snakeyaml.DumperOptions;
142 import org.yaml.snakeyaml.DumperOptions.FlowStyle;
143 import org.yaml.snakeyaml.Yaml;
144 import org.yaml.snakeyaml.introspector.BeanAccess;
145 import org.yaml.snakeyaml.introspector.Property;
146 import org.yaml.snakeyaml.introspector.PropertyUtils;
147 import org.yaml.snakeyaml.nodes.MappingNode;
148 import org.yaml.snakeyaml.nodes.Node;
149 import org.yaml.snakeyaml.nodes.NodeTuple;
150 import org.yaml.snakeyaml.nodes.Tag;
151 import org.yaml.snakeyaml.representer.Represent;
152 import org.yaml.snakeyaml.representer.Representer;
154 @org.springframework.stereotype.Component("tosca-export-handler")
155 public class ToscaExportHandler {
157 public static final String ASSET_TOSCA_TEMPLATE = "assettoscatemplate";
158 private static final Logger log = Logger.getLogger(ToscaExportHandler.class);
159 private static final String INVARIANT_UUID = "invariantUUID";
160 private static final String TOSCA_VERSION = "tosca_simple_yaml_1_3";
161 private static final String SERVICE_NODE_TYPE_PREFIX = "org.openecomp.service.";
162 private static final String IMPORTS_FILE_KEY = "file";
163 private static final String TOSCA_INTERFACE_NAME = "-interface.yml";
164 private static final String FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION = "convertToToscaTemplate - failed to get Default Imports section from configuration";
165 private static final String NOT_SUPPORTED_COMPONENT_TYPE = "Not supported component type {}";
166 private static final String NATIVE_ROOT = "tosca.nodes.Root";
167 private static final List<String> EXCLUDED_CATEGORY_SPECIFIC_METADATA = List
168 .of("Service Function", "Service Role", "Naming Policy", "Service Type");
169 private static final YamlUtil yamlUtil = new YamlUtil();
170 private final ApplicationDataTypeCache applicationDataTypeCache;
171 private final ToscaOperationFacade toscaOperationFacade;
172 private final CapabilityRequirementConverter capabilityRequirementConverter;
173 private final PolicyExportParser policyExportParser;
174 private final GroupExportParser groupExportParser;
175 private final PropertyConvertor propertyConvertor;
176 private final AttributeConverter attributeConverter;
177 private final InputConverter inputConverter;
178 private final OutputConverter outputConverter;
179 private final InterfaceLifecycleOperation interfaceLifecycleOperation;
180 private final InterfacesOperationsConverter interfacesOperationsConverter;
181 private final ModelOperation modelOperation;
184 public ToscaExportHandler(final ApplicationDataTypeCache applicationDataTypeCache,
185 final ToscaOperationFacade toscaOperationFacade,
186 final CapabilityRequirementConverter capabilityRequirementConverter,
187 final PolicyExportParser policyExportParser,
188 final GroupExportParser groupExportParser,
189 final PropertyConvertor propertyConvertor,
190 final AttributeConverter attributeConverter,
191 final InputConverter inputConverter,
192 final OutputConverter outputConverter,
193 final InterfaceLifecycleOperation interfaceLifecycleOperation,
194 final InterfacesOperationsConverter interfacesOperationsConverter,
195 final ModelOperation modelOperation) {
196 this.applicationDataTypeCache = applicationDataTypeCache;
197 this.toscaOperationFacade = toscaOperationFacade;
198 this.capabilityRequirementConverter = capabilityRequirementConverter;
199 this.policyExportParser = policyExportParser;
200 this.groupExportParser = groupExportParser;
201 this.propertyConvertor = propertyConvertor;
202 this.attributeConverter = attributeConverter;
203 this.inputConverter = inputConverter;
204 this.outputConverter = outputConverter;
205 this.interfaceLifecycleOperation = interfaceLifecycleOperation;
206 this.interfacesOperationsConverter = interfacesOperationsConverter;
207 this.modelOperation = modelOperation;
210 public static String getInterfaceFilename(String artifactName) {
211 return artifactName.substring(0, artifactName.lastIndexOf('.')) + TOSCA_INTERFACE_NAME;
214 private static void removeOperationImplementationForProxyNodeType(Map<String, InterfaceDefinition> proxyComponentInterfaces) {
215 if (MapUtils.isEmpty(proxyComponentInterfaces)) {
218 proxyComponentInterfaces.values().stream().map(InterfaceDataDefinition::getOperations).filter(MapUtils::isNotEmpty)
219 .forEach(operations -> operations.values().forEach(operation -> operation.setImplementation(null)));
222 public Either<ToscaRepresentation, ToscaError> exportComponent(Component component) {
223 return convertToToscaTemplate(component).left().map(this::createToscaRepresentation);
226 public Either<ToscaRepresentation, ToscaError> exportComponentInterface(final Component component, final boolean isAssociatedComponent) {
227 final List<Map<String, Map<String, String>>> imports = new ArrayList<>(getDefaultToscaImports(component.getModel()));
228 if (CollectionUtils.isEmpty(imports)) {
229 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
230 return Either.right(ToscaError.GENERAL_ERROR);
232 List<Triple<String, String, Component>> dependencies = new ArrayList<>();
233 if (component.getDerivedFromGenericType() != null && !component.getDerivedFromGenericType()
234 .startsWith("org.openecomp.resource.abstract.nodes.")) {
235 final Either<Component, StorageOperationStatus> baseType = toscaOperationFacade
236 .getByToscaResourceNameAndVersion(component.getDerivedFromGenericType(), component.getDerivedFromGenericVersion(),
237 component.getModel());
238 if (baseType.isLeft() && baseType.left().value() != null) {
239 addDependencies(imports, dependencies, baseType.left().value());
241 log.debug("Failed to fetch derived from type {}", component.getDerivedFromGenericType());
245 String toscaVersion = null;
246 if (component instanceof Resource) {
247 toscaVersion = ((Resource) component).getToscaVersion();
249 ToscaTemplate toscaTemplate = new ToscaTemplate(toscaVersion != null ? toscaVersion : TOSCA_VERSION);
250 toscaTemplate.setImports(imports);
251 final Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
252 final Either<ToscaTemplate, ToscaError> toscaTemplateRes = convertInterfaceNodeType(new HashMap<>(), component, toscaTemplate, nodeTypes,
253 isAssociatedComponent);
254 if (toscaTemplateRes.isRight()) {
255 return Either.right(toscaTemplateRes.right().value());
257 toscaTemplate = toscaTemplateRes.left().value();
258 toscaTemplate.setDependencies(dependencies);
259 ToscaRepresentation toscaRepresentation = this.createToscaRepresentation(toscaTemplate);
260 return Either.left(toscaRepresentation);
263 private ToscaRepresentation createToscaRepresentation(ToscaTemplate toscaTemplate) {
264 CustomRepresenter representer = new CustomRepresenter();
265 DumperOptions options = new DumperOptions();
266 options.setAllowReadOnlyProperties(false);
267 options.setPrettyFlow(true);
268 options.setDefaultFlowStyle(FlowStyle.FLOW);
269 options.setCanonical(false);
270 representer.addClassTag(toscaTemplate.getClass(), Tag.MAP);
271 representer.setPropertyUtils(new UnsortedPropertyUtils());
272 Yaml yaml = new Yaml(representer, options);
273 String yamlAsString = yaml.dumpAsMap(toscaTemplate);
274 StringBuilder sb = new StringBuilder();
275 sb.append(getConfiguration().getHeatEnvArtifactHeader());
276 sb.append(yamlAsString);
277 sb.append(getConfiguration().getHeatEnvArtifactFooter());
278 return ToscaRepresentation.make(sb.toString().getBytes(), toscaTemplate);
281 public Either<ToscaTemplate, ToscaError> getDependencies(Component component) {
282 ToscaTemplate toscaTemplate = new ToscaTemplate(null);
283 Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports = fillImports(component, toscaTemplate);
284 if (fillImports.isRight()) {
285 return Either.right(fillImports.right().value());
287 return Either.left(fillImports.left().value().left);
290 public Either<ToscaTemplate, ToscaError> convertToToscaTemplate(final Component component) {
291 final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImports(component.getModel());
292 if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
293 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
294 return Either.right(ToscaError.GENERAL_ERROR);
296 log.trace("start tosca export for {}", component.getUniqueId());
297 String toscaVersion = null;
298 if (component instanceof Resource) {
299 toscaVersion = ((Resource) component).getToscaVersion();
301 final ToscaTemplate toscaTemplate = new ToscaTemplate(toscaVersion != null ? toscaVersion : TOSCA_VERSION);
302 toscaTemplate.setMetadata(convertMetadata(component));
303 toscaTemplate.setImports(new ArrayList<>(defaultToscaImportConfig));
304 final Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
305 if (ModelConverter.isAtomicComponent(component)) {
306 log.trace("convert component as node type");
307 return convertNodeType(new HashMap<>(), component, toscaTemplate, nodeTypes);
309 log.trace("convert component as topology template");
310 return convertToscaTemplate(component, toscaTemplate);
314 private List<Map<String, Map<String, String>>> getDefaultToscaImports(final String modelId) {
315 if (modelId == null) {
316 return getDefaultToscaImportConfig();
319 final List<ToscaImportByModel> allModelImports = modelOperation.findAllModelImports(modelId, true);
320 final List<Map<String, Map<String, String>>> importList = new ArrayList<>();
321 final Set<Path> addedPathList = new HashSet<>();
322 for (final ToscaImportByModel toscaImportByModel : allModelImports) {
323 var importPath = Path.of(toscaImportByModel.getFullPath());
324 if (addedPathList.contains(importPath)) {
325 importPath = ToscaDefaultImportHelper.addModelAsFilePrefix(importPath, toscaImportByModel.getModelId());
327 final String fileName = FilenameUtils.getBaseName(importPath.toString());
328 importList.add(Map.of(fileName, Map.of("file", importPath.toString())));
329 addedPathList.add(importPath);
334 private Either<ToscaTemplate, ToscaError> convertToscaTemplate(Component component, ToscaTemplate toscaNode) {
335 Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> importsRes = fillImports(component, toscaNode);
336 if (importsRes.isRight()) {
337 return Either.right(importsRes.right().value());
339 toscaNode = importsRes.left().value().left;
340 Map<String, Component> componentCache = importsRes.left().value().right;
341 Either<Map<String, ToscaNodeType>, ToscaError> nodeTypesMapEither = createProxyNodeTypes(componentCache, component);
342 if (nodeTypesMapEither.isRight()) {
343 log.debug("Failed to fetch normative service proxy resource by tosca name, error {}", nodeTypesMapEither.right().value());
344 return Either.right(nodeTypesMapEither.right().value());
346 Map<String, ToscaNodeType> nodeTypesMap = nodeTypesMapEither.left().value();
347 if (nodeTypesMap != null && !nodeTypesMap.isEmpty()) {
348 toscaNode.setNode_types(nodeTypesMap);
350 createServiceSubstitutionNodeTypes(componentCache, component, toscaNode);
351 Either<Map<String, Object>, ToscaError> proxyInterfaceTypesEither = createProxyInterfaceTypes(component);
352 if (proxyInterfaceTypesEither.isRight()) {
353 log.debug("Failed to populate service proxy local interface types in tosca, error {}", nodeTypesMapEither.right().value());
354 return Either.right(proxyInterfaceTypesEither.right().value());
356 Map<String, Object> proxyInterfaceTypes = proxyInterfaceTypesEither.left().value();
357 if (MapUtils.isNotEmpty(proxyInterfaceTypes)) {
358 toscaNode.setInterface_types(proxyInterfaceTypes);
360 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = applicationDataTypeCache.getAll(component.getModel());
361 if (dataTypesEither.isRight()) {
362 log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
363 return Either.right(ToscaError.GENERAL_ERROR);
365 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
366 ToscaTopolgyTemplate topologyTemplate = new ToscaTopolgyTemplate();
367 List<InputDefinition> inputDef = component.getInputs();
368 Map<String, ToscaProperty> inputs = inputConverter.convertInputs(inputDef, dataTypes);
369 if (!inputs.isEmpty()) {
370 topologyTemplate.setInputs(inputs);
372 final Map<String, ToscaProperty> outputs;
374 outputs = outputConverter.convert(component.getOutputs(), dataTypes);
375 } catch (final ToscaConversionException e) {
376 log.error(EcompLoggerErrorCode.SCHEMA_ERROR, ToscaExportHandler.class.getName(),
377 "Could not parse component '{}' outputs. Component unique id '{}'.", component.getName(), component.getUniqueId(), e);
378 return Either.right(ToscaError.GENERAL_ERROR);
380 if (!outputs.isEmpty()) {
381 topologyTemplate.setOutputs(outputs);
383 if (CollectionUtils.isNotEmpty(component.getComponentInstances())) {
384 final Either<Map<String, ToscaNodeTemplate>, ToscaError> nodeTemplates =
385 convertNodeTemplates(component, componentCache, dataTypes, topologyTemplate);
386 if (nodeTemplates.isRight()) {
387 return Either.right(nodeTemplates.right().value());
389 log.debug("node templates converted");
390 topologyTemplate.setNode_templates(nodeTemplates.left().value());
392 final Map<String, ToscaRelationshipTemplate> relationshipTemplatesMap = new ToscaExportRelationshipTemplatesHandler()
393 .createFrom(topologyTemplate.getNode_templates());
394 if (!relationshipTemplatesMap.isEmpty()) {
395 topologyTemplate.setRelationshipTemplates(relationshipTemplatesMap);
397 addGroupsToTopologyTemplate(component, topologyTemplate);
399 addPoliciesToTopologyTemplate(component, topologyTemplate);
400 } catch (SdcResourceNotFoundException e) {
401 log.debug("Fail to add policies to topology template:", e);
402 return Either.right(ToscaError.GENERAL_ERROR);
405 createSubstitutionMapping(component, componentCache).ifPresent(topologyTemplate::setSubstitution_mappings);
406 } catch (final ToscaExportException e) {
407 log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, ToscaExportHandler.class.getName(), e.getMessage());
408 return Either.right(e.getToscaError());
410 if (!topologyTemplate.isEmpty()) {
411 toscaNode.setTopology_template(topologyTemplate);
413 return Either.left(toscaNode);
416 private Either<String, ToscaError> createComponentToscaName(final Component component) {
417 switch (component.getComponentType()) {
419 final ResourceMetadataDataDefinition resourceMetadata =
420 (ResourceMetadataDataDefinition) component.getComponentMetadataDefinition().getMetadataDataDefinition();
421 return Either.left(resourceMetadata.getToscaResourceName());
423 return Either.left(SERVICE_NODE_TYPE_PREFIX + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName());
425 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
426 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
430 private Optional<SubstitutionMapping> createSubstitutionMapping(final Component component,
431 final Map<String, Component> componentCache) throws ToscaExportException {
432 if (component instanceof Service && !((Service) component).isSubstituteCandidate()) {
433 return Optional.empty();
436 final Either<String, ToscaError> toscaResourceNameEither = createComponentToscaName(component);
437 if (toscaResourceNameEither.isRight()) {
438 throw new ToscaExportException("Could not create component TOSCA name", toscaResourceNameEither.right().value());
440 final String toscaResourceName = toscaResourceNameEither.left().value();
442 final SubstitutionMapping substitutionMapping = new SubstitutionMapping();
443 substitutionMapping.setNode_type(toscaResourceName);
444 convertSubstitutionMappingFilter(component).ifPresent(substitutionMapping::setSubstitution_filter);
446 final Either<Map<String, String[]>, ToscaError> capabilitiesEither = convertSubstitutionMappingCapabilities(component, componentCache);
447 if (capabilitiesEither.isRight()) {
448 throw new ToscaExportException("Could not convert substitution mapping capabilities", capabilitiesEither.right().value());
450 final Map<String, String[]> capabilityMap = capabilitiesEither.left().value();
451 if (!capabilityMap.isEmpty()) {
452 substitutionMapping.setCapabilities(capabilityMap);
455 final Either<Map<String, String[]>, ToscaError> requirements =
456 capabilityRequirementConverter.convertSubstitutionMappingRequirements(component, componentCache);
457 if (requirements.isRight()) {
458 throw new ToscaExportException("Could not convert substitution mapping requirements", requirements.right().value());
460 final Map<String, String[]> requirementMap = requirements.left().value();
461 if (MapUtils.isNotEmpty(requirementMap)) {
462 substitutionMapping.setRequirements(requirementMap);
465 final Map<String, String[]> propertyMappingMap = buildSubstitutionMappingPropertyMapping(component);
466 if (MapUtils.isNotEmpty(propertyMappingMap)) {
467 substitutionMapping.setProperties(propertyMappingMap);
470 final Map<String, String[]> attributesMappingMap = buildSubstitutionMappingAttributesMapping(component);
471 if (MapUtils.isNotEmpty(attributesMappingMap)) {
472 substitutionMapping.setAttributes(attributesMappingMap);
475 return Optional.of(substitutionMapping);
478 private Optional<NodeFilter> convertSubstitutionMappingFilter(final Component component) {
479 if (component.getSubstitutionFilter() == null || (component.getSubstitutionFilter().getProperties()).getListToscaDataDefinition() == null) {
480 return Optional.empty();
483 return Optional.ofNullable(convertToSubstitutionFilterComponent(component.getSubstitutionFilter()));
486 private void addGroupsToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate) {
487 Map<String, ToscaGroupTemplate> groups = groupExportParser.getGroups(component);
488 if (groups != null) {
489 topologyTemplate.addGroups(groups);
493 private void addPoliciesToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate) throws SdcResourceNotFoundException {
494 Map<String, ToscaPolicyTemplate> policies = policyExportParser.getPolicies(component);
495 if (policies != null) {
496 topologyTemplate.addPolicies(policies);
500 private Map<String, String> convertMetadata(Component component) {
501 return convertMetadata(component, false, null);
504 private Map<String, String> convertMetadata(Component component, boolean isInstance, ComponentInstance componentInstance) {
505 Map<String, String> toscaMetadata = new LinkedHashMap<>();
506 toscaMetadata.put(convertMetadataKey(JsonPresentationFields.INVARIANT_UUID), component.getInvariantUUID());
507 toscaMetadata.put(JsonPresentationFields.UUID.getPresentation(), component.getUUID());
509 .put(JsonPresentationFields.NAME.getPresentation(), component.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
510 toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), component.getDescription());
511 List<CategoryDefinition> categories = component.getCategories();
512 CategoryDefinition categoryDefinition = categories.get(0);
513 toscaMetadata.put(JsonPresentationFields.MODEL.getPresentation(), component.getModel());
514 toscaMetadata.put(JsonPresentationFields.CATEGORY.getPresentation(), categoryDefinition.getName());
516 toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), component.getVersion());
517 toscaMetadata.put(JsonPresentationFields.CUSTOMIZATION_UUID.getPresentation(), componentInstance.getCustomizationUUID());
518 if (componentInstance.getSourceModelInvariant() != null && !componentInstance.getSourceModelInvariant().isEmpty()) {
519 toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), componentInstance.getComponentVersion());
520 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_INVARIANT.getPresentation(), componentInstance.getSourceModelInvariant());
521 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_UUID.getPresentation(), componentInstance.getSourceModelUuid());
522 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_NAME.getPresentation(), componentInstance.getSourceModelName());
523 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
524 toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(),
525 componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceProxy.getDisplayValue());
526 } else if (componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
527 toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(),
528 componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceSubstitution.getDisplayValue());
530 toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), componentInstance.getDescription());
533 switch (component.getComponentType()) {
535 Resource resource = (Resource) component;
536 if (isInstance && (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy
537 || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution)) {
538 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), componentInstance.getOriginType().getDisplayValue());
540 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), resource.getResourceType().name());
542 toscaMetadata.put(JsonPresentationFields.SUB_CATEGORY.getPresentation(), categoryDefinition.getSubcategories().get(0).getName());
543 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR.getPresentation(), resource.getVendorName());
544 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_RELEASE.getPresentation(), resource.getVendorRelease());
545 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_MODEL_NUMBER.getPresentation(), resource.getResourceVendorModelNumber());
548 Service service = (Service) component;
549 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), component.getComponentType().getValue());
550 toscaMetadata.put(JsonPresentationFields.SERVICE_TYPE.getPresentation(), service.getServiceType());
551 toscaMetadata.put(JsonPresentationFields.SERVICE_ROLE.getPresentation(), service.getServiceRole());
552 toscaMetadata.put(JsonPresentationFields.SERVICE_FUNCTION.getPresentation(), service.getServiceFunction());
553 toscaMetadata.put(JsonPresentationFields.ENVIRONMENT_CONTEXT.getPresentation(), service.getEnvironmentContext());
554 toscaMetadata.put(JsonPresentationFields.INSTANTIATION_TYPE.getPresentation(),
555 service.getEnvironmentContext() == null ? StringUtils.EMPTY : service.getInstantiationType());
558 toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming().toString());
559 toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming().toString());
560 toscaMetadata.put(JsonPresentationFields.NAMING_POLICY.getPresentation(), service.getNamingPolicy());
564 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
566 for (final String key : component.getCategorySpecificMetadata().keySet()) {
567 if (!EXCLUDED_CATEGORY_SPECIFIC_METADATA.contains(key)) {
568 toscaMetadata.put(key, component.getCategorySpecificMetadata().get(key));
571 return toscaMetadata;
574 private String convertMetadataKey(JsonPresentationFields jsonPresentationField) {
575 if (JsonPresentationFields.INVARIANT_UUID.equals(jsonPresentationField)) {
576 return INVARIANT_UUID;
578 return jsonPresentationField.getPresentation();
581 private Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports(Component component, ToscaTemplate toscaTemplate) {
582 final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImports(component.getModel());
583 if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
584 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
585 return Either.right(ToscaError.GENERAL_ERROR);
587 Map<String, Component> componentCache = new HashMap<>();
588 if (!ModelConverter.isAtomicComponent(component)) {
589 final List<Map<String, Map<String, String>>> additionalImports =
590 toscaTemplate.getImports() == null ? new ArrayList<>(defaultToscaImportConfig) : new ArrayList<>(toscaTemplate.getImports());
591 List<Triple<String, String, Component>> dependencies = new ArrayList<>();
592 Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
593 final Map<String, Map<String, String>> substituteTypeImportEntry = generateComponentSubstituteTypeImport(component, toscaArtifacts);
594 if (!substituteTypeImportEntry.isEmpty()) {
595 additionalImports.add(substituteTypeImportEntry);
597 List<ComponentInstance> componentInstances = component.getComponentInstances();
598 if (componentInstances != null && !componentInstances.isEmpty()) {
599 componentInstances.forEach(ci -> createDependency(componentCache, additionalImports, dependencies, ci));
601 toscaTemplate.setDependencies(dependencies);
602 toscaTemplate.setImports(additionalImports);
604 log.debug("currently imports supported for VF and service only");
606 return Either.left(new ImmutablePair<>(toscaTemplate, componentCache));
609 private Map<String, Map<String, String>> generateComponentSubstituteTypeImport(final Component component,
610 final Map<String, ArtifactDefinition> toscaArtifacts) {
612 if (component instanceof Service && !((Service) component).isSubstituteCandidate()) {
613 return Collections.emptyMap();
615 if (MapUtils.isEmpty(toscaArtifacts)) {
616 return Collections.emptyMap();
618 final ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE);
619 if (artifactDefinition == null) {
620 return Collections.emptyMap();
622 final var importEntryName = component.getComponentType().toString().toLowerCase() + "-" + component.getName() + "-interface";
623 return Map.of(importEntryName,
624 Map.of(IMPORTS_FILE_KEY, getInterfaceFilename(artifactDefinition.getArtifactName()))
628 private List<Map<String, Map<String, String>>> getDefaultToscaImportConfig() {
629 return getConfiguration().getDefaultImports();
632 private void createDependency(final Map<String, Component> componentCache, final List<Map<String, Map<String, String>>> imports,
633 final List<Triple<String, String, Component>> dependencies, final ComponentInstance componentInstance) {
634 log.debug("createDependency componentCache {}", componentCache);
635 Component componentRI = componentCache.get(componentInstance.getComponentUid());
636 if (componentRI == null || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
637 // all resource must be only once!
638 final Either<Component, StorageOperationStatus> resource = toscaOperationFacade.getToscaFullElement(componentInstance.getComponentUid());
639 if ((resource.isRight()) && (log.isDebugEnabled())) {
640 log.debug("Failed to fetch resource with id {} for instance {}", componentInstance.getComponentUid(),
641 componentInstance.getUniqueId());
644 final Component fetchedComponent = resource.left().value();
645 componentRI = setComponentCache(componentCache, componentInstance, fetchedComponent);
646 addDependencies(imports, dependencies, componentRI);
651 * Sets a componentCache from the given component/resource.
653 private Component setComponentCache(final Map<String, Component> componentCache, final ComponentInstance componentInstance,
654 final Component fetchedComponent) {
655 componentCache.put(fetchedComponent.getUniqueId(), fetchedComponent);
656 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy
657 || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
658 final Either<Component, StorageOperationStatus> sourceService = toscaOperationFacade
659 .getToscaFullElement(componentInstance.getSourceModelUid());
660 if (sourceService.isRight() && (log.isDebugEnabled())) {
661 log.debug("Failed to fetch source service with id {} for proxy {}", componentInstance.getSourceModelUid(),
662 componentInstance.getUniqueId());
664 final Component fetchedSource = sourceService.left().value();
665 componentCache.put(fetchedSource.getUniqueId(), fetchedSource);
666 return fetchedSource;
668 return fetchedComponent;
672 * Retrieves all derived_from nodes and stores it in a predictable order.
674 private void addDependencies(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
675 final Component fetchedComponent) {
676 final Set<Component> componentsList = new LinkedHashSet<>();
677 if (fetchedComponent instanceof Resource) {
678 log.debug("fetchedComponent is a resource {}", fetchedComponent);
679 final Optional<Map<String, String>> derivedFromMapOfIdToName = getDerivedFromMapOfIdToName(fetchedComponent, componentsList);
680 if (derivedFromMapOfIdToName.isPresent() && !derivedFromMapOfIdToName.get().isEmpty()) {
681 derivedFromMapOfIdToName.get().entrySet().forEach(entry -> {
682 log.debug("Started entry.getValue() : {}", entry.getValue());
683 if (!NATIVE_ROOT.equals(entry.getValue())) {
684 Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade.getToscaElement(entry.getKey());
685 if (resourcefetched != null && resourcefetched.isLeft()) {
686 componentsList.add(resourcefetched.left().value());
690 setImports(imports, dependencies, componentsList);
692 setImports(imports, dependencies, fetchedComponent);
698 * Returns all derived_from nodes found.
700 private Optional<Map<String, String>> getDerivedFromMapOfIdToName(final Component fetchedComponent, final Set<Component> componentsList) {
701 final Resource parentResource = (Resource) fetchedComponent;
702 Map<String, String> derivedFromMapOfIdToName = new HashMap<>();
703 if (CollectionUtils.isNotEmpty(parentResource.getComponentInstances())) {
704 componentsList.add(fetchedComponent);
705 for (final ComponentInstance componentInstance : parentResource.getComponentInstances()) {
706 final Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade
707 .getToscaElement(componentInstance.getComponentUid());
708 if (resourcefetched != null && resourcefetched.isLeft()) {
709 final Map<String, String> derivedWithId = resourcefetched.left().value().getDerivedFromMapOfIdToName();
710 if (MapUtils.isNotEmpty(derivedWithId)) {
711 derivedFromMapOfIdToName.putAll(derivedWithId);
716 derivedFromMapOfIdToName = parentResource.getDerivedFromMapOfIdToName();
718 log.debug("Started derivedFromMapOfIdToName: {}", derivedFromMapOfIdToName);
719 return Optional.ofNullable(derivedFromMapOfIdToName);
723 * Creates a resource map and adds it to the import list.
725 private void setImports(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
726 final Set<Component> componentsList) {
727 componentsList.forEach(component -> setImports(imports, dependencies, component));
730 private void setImports(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
731 final Component component) {
732 final Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
733 final ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE);
734 if (artifactDefinition != null) {
735 final Map<String, String> files = new HashMap<>();
736 final String artifactName = artifactDefinition.getArtifactName();
737 files.put(IMPORTS_FILE_KEY, artifactName);
738 final StringBuilder keyNameBuilder = new StringBuilder();
739 keyNameBuilder.append(component.getComponentType().toString().toLowerCase());
740 keyNameBuilder.append("-");
741 keyNameBuilder.append(component.getName());
742 addImports(imports, keyNameBuilder, files);
743 dependencies.add(new ImmutableTriple<>(artifactName, artifactDefinition.getEsId(), component));
744 if (!ModelConverter.isAtomicComponent(component)) {
745 final Map<String, String> interfaceFiles = new HashMap<>();
746 interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactName));
747 keyNameBuilder.append("-interface");
748 addImports(imports, keyNameBuilder, interfaceFiles);
754 * Adds the found resource to the import definition list.
756 private void addImports(final List<Map<String, Map<String, String>>> imports, final StringBuilder keyNameBuilder,
757 final Map<String, String> files) {
758 final String mapKey = keyNameBuilder.toString();
759 if (imports.stream().allMatch(stringMapMap -> stringMapMap.get(mapKey) == null)) {
760 final Map<String, Map<String, String>> importsListMember = new HashMap<>();
761 importsListMember.put(keyNameBuilder.toString(), files);
762 imports.add(importsListMember);
766 private Either<ToscaTemplate, ToscaError> convertNodeType(Map<String, Component> componentsCache, Component component, ToscaTemplate toscaNode,
767 Map<String, ToscaNodeType> nodeTypes) {
768 return convertInterfaceNodeType(componentsCache, component, toscaNode, nodeTypes, false);
771 public Either<ToscaTemplate, ToscaError> convertInterfaceNodeType(Map<String, Component> componentsCache, Component component,
772 ToscaTemplate toscaNode, Map<String, ToscaNodeType> nodeTypes,
773 boolean isAssociatedComponent) {
774 log.debug("start convert node type for {}", component.getUniqueId());
775 ToscaNodeType toscaNodeType = createNodeType(component);
776 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither = interfaceLifecycleOperation
777 .getAllInterfaceLifecycleTypes(component.getModel());
778 if (lifecycleTypeEither.isRight() && !StorageOperationStatus.NOT_FOUND.equals(lifecycleTypeEither.right().value())) {
779 log.debug("Failed to fetch all interface types :", lifecycleTypeEither.right().value());
780 return Either.right(ToscaError.GENERAL_ERROR);
782 if (lifecycleTypeEither.isLeft()) {
783 List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value().values().stream().map(InterfaceDataDefinition::getType)
784 .collect(Collectors.toList());
785 toscaNode.setInterface_types(interfacesOperationsConverter.addInterfaceTypeElement(component, allGlobalInterfaceTypes));
787 final var dataTypesEither = applicationDataTypeCache.getAll(component.getModel());
788 if (dataTypesEither.isRight()) {
789 log.debug("Failed to fetch all data types :", dataTypesEither.right().value());
790 return Either.right(ToscaError.GENERAL_ERROR);
792 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
793 List<InputDefinition> inputDef = component.getInputs();
794 interfacesOperationsConverter.addInterfaceDefinitionElement(component, toscaNodeType, dataTypes, isAssociatedComponent);
795 final var toscaAttributeMap = convertToToscaAttributes(component.getAttributes(), dataTypes);
796 if (!toscaAttributeMap.isEmpty()) {
797 toscaNodeType.setAttributes(toscaAttributeMap);
799 final var mergedProperties = convertInputsToProperties(dataTypes, inputDef, component.getUniqueId());
800 if (CollectionUtils.isNotEmpty(component.getProperties())) {
801 List<PropertyDefinition> properties = component.getProperties();
802 Map<String, ToscaProperty> convertedProperties = properties.stream()
803 .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, component.getInputs()))
804 .collect(Collectors.toMap(PropertyDataDefinition::getName,
805 property -> propertyConvertor.convertProperty(dataTypes, property, PropertyConvertor.PropertyType.PROPERTY)));
806 // merge component properties and inputs properties
807 convertedProperties.forEach((k, v) -> mergedProperties.putIfAbsent(k, v));
809 if (MapUtils.isNotEmpty(mergedProperties)) {
810 toscaNodeType.setProperties(mergedProperties);
812 /* convert private data_types */
813 List<DataTypeDefinition> privateDataTypes = component.getDataTypes();
814 if (CollectionUtils.isNotEmpty(privateDataTypes)) {
815 Map<String, ToscaDataType> toscaDataTypeMap = new HashMap<>();
816 for (DataTypeDefinition dataType : privateDataTypes) {
817 log.debug("Emitting private data type: component.name={} dataType.name={}",
818 component.getNormalizedName(), dataType.getName());
819 ToscaDataType toscaDataType = new ToscaDataType();
820 toscaDataType.setDerived_from(dataType.getDerivedFromName());
821 toscaDataType.setDescription(dataType.getDescription());
822 toscaDataType.setVersion(dataType.getVersion());
823 if (CollectionUtils.isNotEmpty(dataType.getProperties())) {
824 toscaDataType.setProperties(dataType.getProperties().stream()
825 .collect(Collectors.toMap(
826 PropertyDataDefinition::getName,
827 s -> propertyConvertor.convertProperty(dataTypes, s, PropertyType.PROPERTY),
828 (toscaPropertyTobeValidated, toscaProperty) -> validateToscaProperty(privateDataTypes, toscaPropertyTobeValidated,
832 toscaDataTypeMap.put(dataType.getName(), toscaDataType);
834 toscaNode.setData_types(toscaDataTypeMap);
837 // Extracted to method for code reuse
838 return convertReqCapAndTypeName(componentsCache, component, toscaNode, nodeTypes, toscaNodeType, dataTypes);
841 private ToscaProperty validateToscaProperty(final List<DataTypeDefinition> privateDataTypes, final ToscaProperty toscaPropertyTobeValidated,
842 final ToscaProperty toscaProperty) {
843 final Optional<DataTypeDefinition> match = privateDataTypes.stream()
844 .filter(dataType -> dataType.getName().equals(toscaPropertyTobeValidated.getType())).findFirst();
845 return match.isPresent() ? toscaPropertyTobeValidated : toscaProperty;
848 private Map<String, ToscaAttribute> convertToToscaAttributes(final List<AttributeDefinition> attributeList,
849 final Map<String, DataTypeDefinition> dataTypes) {
850 if (CollectionUtils.isEmpty(attributeList)) {
851 return Collections.emptyMap();
853 final AttributeConverter converter = new AttributeConverter(dataTypes);
854 final Map<String, ToscaAttribute> toscaAttributeMap = new HashMap<>();
855 for (final AttributeDefinition attributeDefinition : attributeList) {
856 toscaAttributeMap.put(attributeDefinition.getName(), converter.convert(attributeDefinition));
858 return toscaAttributeMap;
861 private Either<ToscaTemplate, ToscaError> convertReqCapAndTypeName(Map<String, Component> componentsCache,
862 Component component, ToscaTemplate toscaNode,
863 Map<String, ToscaNodeType> nodeTypes,
864 ToscaNodeType toscaNodeType,
865 Map<String, DataTypeDefinition> dataTypes) {
866 Either<ToscaNodeType, ToscaError> capabilities = convertCapabilities(componentsCache, component, toscaNodeType,
868 if (capabilities.isRight()) {
869 return Either.right(capabilities.right().value());
871 toscaNodeType = capabilities.left().value();
872 log.debug("Capabilities converted for {}", component.getUniqueId());
874 Either<ToscaNodeType, ToscaError> requirements = capabilityRequirementConverter
875 .convertRequirements(componentsCache, component, toscaNodeType);
876 if (requirements.isRight()) {
877 return Either.right(requirements.right().value());
879 toscaNodeType = requirements.left().value();
880 log.debug("Requirements converted for {}", component.getUniqueId());
882 String toscaResourceName;
883 switch (component.getComponentType()) {
885 toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition()
886 .getMetadataDataDefinition()).getToscaResourceName();
889 toscaResourceName = SERVICE_NODE_TYPE_PREFIX
890 + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName();
893 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
894 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
897 nodeTypes.put(toscaResourceName, toscaNodeType);
898 toscaNode.setNode_types(nodeTypes);
899 log.debug("finish convert node type for {}", component.getUniqueId());
900 return Either.left(toscaNode);
903 private Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplates(final Component component,
904 final Map<String, Component> componentCache,
905 final Map<String, DataTypeDefinition> dataTypes,
906 final ToscaTopolgyTemplate topologyTemplate) {
908 final Map<String, List<ComponentInstanceProperty>> componentInstancesProperties = component.getComponentInstancesProperties();
909 final Map<String, List<ComponentInstanceAttribute>> componentInstancesAttributes = component.getComponentInstancesAttributes();
910 final Map<String, List<ComponentInstanceInput>> componentInstancesInputs = component.getComponentInstancesInputs();
911 final Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces = component.getComponentInstancesInterfaces();
912 final List<RequirementCapabilityRelDef> componentInstancesRelations = component.getComponentInstancesRelations();
914 Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplatesRes = null;
915 log.debug("start convert topology template for {} for type {}", component.getUniqueId(), component.getComponentType());
916 final Map<String, ToscaNodeTemplate> nodeTemplates = new HashMap<>();
918 Map<String, ToscaGroupTemplate> groupsMap = null;
919 for (final ComponentInstance componentInstance : component.getComponentInstances()) {
920 ToscaNodeTemplate nodeTemplate = new ToscaNodeTemplate();
921 if (MapUtils.isNotEmpty(componentInstance.getToscaArtifacts())) {
922 nodeTemplate.setArtifacts(convertToNodeTemplateArtifacts(componentInstance.getToscaArtifacts()));
924 if (componentInstance.getMinOccurrences() != null && componentInstance.getMaxOccurrences() != null) {
925 List<Object> occur = new ArrayList<>();
926 occur.add(parseToIntIfPossible(componentInstance.getMinOccurrences()));
927 occur.add(parseToIntIfPossible(componentInstance.getMaxOccurrences()));
928 nodeTemplate.setOccurrences(occur);
930 if (componentInstance.getInstanceCount() != null) {
931 ObjectMapper objectMapper = new ObjectMapper();
932 Object obj = convertToToscaObject(componentInstance.getInstanceCount());
934 Map<String, String> map = objectMapper.convertValue(obj, Map.class);
935 nodeTemplate.setInstance_count(map);
938 nodeTemplate.setType(componentInstance.getToscaComponentName());
939 nodeTemplate.setDirectives(componentInstance.getDirectives());
940 NodeFilter nodeFilter = convertToNodeTemplateNodeFilterComponent(componentInstance.getNodeFilter());
941 if (nodeFilter != null && nodeFilter.hasData()) {
942 nodeTemplate.setNode_filter(nodeFilter);
944 final Either<Component, Boolean> originComponentRes = capabilityRequirementConverter
945 .getOriginComponent(componentCache, componentInstance);
946 if (originComponentRes.isRight()) {
947 convertNodeTemplatesRes = Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
950 final Either<ToscaNodeTemplate, ToscaError> requirements = convertComponentInstanceRequirements(component, componentInstance,
951 componentInstancesRelations, nodeTemplate, originComponentRes.left().value(), componentCache);
952 if (requirements.isRight()) {
953 convertNodeTemplatesRes = Either.right(requirements.right().value());
956 final String instanceUniqueId = componentInstance.getUniqueId();
957 log.debug("Component instance Requirements converted for instance {}", instanceUniqueId);
959 nodeTemplate = requirements.left().value();
961 final Component originalComponent = componentCache.get(componentInstance.getActualComponentUid());
963 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
964 final Component componentOfProxy = componentCache.get(componentInstance.getComponentUid());
965 nodeTemplate.setMetadata(convertMetadata(componentOfProxy, true, componentInstance));
967 nodeTemplate.setMetadata(convertMetadata(originalComponent, true, componentInstance));
970 final Either<ToscaNodeTemplate, ToscaError> capabilities =
971 capabilityRequirementConverter.convertComponentInstanceCapabilities(componentInstance, dataTypes, nodeTemplate);
972 if (capabilities.isRight()) {
973 convertNodeTemplatesRes = Either.right(capabilities.right().value());
976 log.debug("Component instance Capabilities converted for instance {}", instanceUniqueId);
978 nodeTemplate = capabilities.left().value();
979 final Map<String, Object> props = new HashMap<>();
980 final Map<String, Object> attribs = new HashMap<>();
982 if (originalComponent.getComponentType() == ComponentTypeEnum.RESOURCE) {
983 // Adds the properties of parent component to map
984 addPropertiesOfParentComponent(dataTypes, originalComponent, props);
985 addAttributesOfParentComponent(originalComponent, attribs);
988 if (null != componentInstancesProperties && componentInstancesProperties.containsKey(instanceUniqueId)) {
989 addPropertiesOfComponentInstance(componentInstancesProperties, dataTypes, instanceUniqueId, props);
991 if (null != componentInstancesAttributes && componentInstancesAttributes.containsKey(instanceUniqueId)) {
992 addAttributesOfComponentInstance(componentInstancesAttributes, instanceUniqueId, attribs);
995 if (componentInstancesInputs != null
996 && componentInstancesInputs.containsKey(instanceUniqueId)
997 && !isComponentOfTypeServiceProxy(componentInstance)) {
998 //For service proxy the inputs are already handled under instance properties above
999 addComponentInstanceInputs(dataTypes, componentInstancesInputs, instanceUniqueId, props);
1002 //M3[00001] - NODE TEMPLATE INTERFACES - START
1003 handleInstanceInterfaces(componentInstanceInterfaces, componentInstance, dataTypes, nodeTemplate, instanceUniqueId, component);
1004 //M3[00001] - NODE TEMPLATE INTERFACES - END
1005 if (MapUtils.isNotEmpty(props)) {
1006 nodeTemplate.setProperties(props);
1008 if (MapUtils.isNotEmpty(attribs)) {
1009 nodeTemplate.setAttributes(attribs);
1012 final List<GroupInstance> groupInstances = componentInstance.getGroupInstances();
1013 if (CollectionUtils.isNotEmpty(groupInstances)) {
1014 if (groupsMap == null) {
1015 groupsMap = new HashMap<>();
1017 for (final GroupInstance groupInst : groupInstances) {
1018 if (CollectionUtils.isNotEmpty(groupInst.getArtifacts())) {
1019 groupsMap.put(groupInst.getName(), groupExportParser.getToscaGroupTemplate(groupInst, componentInstance.getInvariantName()));
1024 nodeTemplates.put(componentInstance.getName(), nodeTemplate);
1026 if (groupsMap != null) {
1027 log.debug("instance groups added");
1028 topologyTemplate.addGroups(groupsMap);
1030 if (component.getComponentType() == ComponentTypeEnum.SERVICE && isNotEmpty(
1031 ((Service) component).getForwardingPaths())) {
1032 log.debug("Starting converting paths for component {}, name {}", component.getUniqueId(), component.getName());
1033 ForwardingPathToscaUtil
1034 .addForwardingPaths((Service) component, nodeTemplates, capabilityRequirementConverter, componentCache, toscaOperationFacade);
1035 log.debug("Finished converting paths for component {}, name {}", component.getUniqueId(), component.getName());
1037 if (convertNodeTemplatesRes == null) {
1038 convertNodeTemplatesRes = Either.left(nodeTemplates);
1040 log.debug("finish convert topology template for {} for type {}", component.getUniqueId(), component.getComponentType());
1041 return convertNodeTemplatesRes;
1044 private Object convertToToscaObject(String value) {
1046 ToscaMapValueConverter mapConverterInst = ToscaMapValueConverter.getInstance();
1047 JsonParser jsonParser = new JsonParser();
1048 StringReader reader = new StringReader(value);
1049 JsonReader jsonReader = new JsonReader(reader);
1050 jsonReader.setLenient(true);
1051 JsonElement jsonElement = jsonParser.parse(jsonReader);
1052 if (jsonElement.isJsonObject()) {
1053 JsonObject jsonObj = jsonElement.getAsJsonObject();
1054 if (jsonObj.entrySet().size() == 1 && jsonObj.has(ToscaFunctions.GET_INPUT.getFunctionName())) {
1055 return mapConverterInst.handleComplexJsonValue(jsonElement);
1059 } catch (Exception e) {
1060 log.debug("convertToToscaValue failed to parse json value :", e);
1065 private Object parseToIntIfPossible(final String value) {
1066 final Integer intValue = Ints.tryParse(value);
1067 return intValue == null ? value : intValue;
1070 private void handleInstanceInterfaces(
1071 Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces,
1072 ComponentInstance componentInstance, Map<String, DataTypeDefinition> dataTypes, ToscaNodeTemplate nodeTemplate,
1073 String instanceUniqueId,
1074 Component parentComponent) {
1076 if (MapUtils.isEmpty(componentInstanceInterfaces)
1077 || !componentInstanceInterfaces.containsKey(instanceUniqueId)) {
1078 nodeTemplate.setInterfaces(null);
1082 final List<ComponentInstanceInterface> currServiceInterfaces =
1083 componentInstanceInterfaces.get(instanceUniqueId);
1085 final Map<String, InterfaceDefinition> tmpInterfaces = new HashMap<>();
1086 currServiceInterfaces.forEach(instInterface -> tmpInterfaces.put(instInterface
1087 .getUniqueId(), instInterface));
1089 final Map<String, Object> interfaceMap = interfacesOperationsConverter
1090 .getInterfacesMap(parentComponent, componentInstance, tmpInterfaces, dataTypes, isComponentOfTypeServiceProxy(componentInstance),
1091 isComponentOfTypeServiceProxy(componentInstance));
1093 interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
1094 nodeTemplate.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap);
1097 private boolean isComponentOfTypeServiceProxy(ComponentInstance componentInstance) {
1098 return Objects.nonNull(componentInstance.getOriginType())
1099 && componentInstance.getOriginType().getValue().equals("Service Proxy");
1102 private void addComponentInstanceInputs(Map<String, DataTypeDefinition> dataTypes,
1103 Map<String, List<ComponentInstanceInput>> componentInstancesInputs,
1104 String instanceUniqueId, Map<String, Object> props) {
1106 List<ComponentInstanceInput> instanceInputsList = componentInstancesInputs.get(instanceUniqueId);
1107 if (instanceInputsList != null) {
1108 instanceInputsList.forEach(input -> {
1109 Supplier<String> supplier = () -> input.getValue() != null && !Objects.isNull(input.getValue()) ? input.getValue()
1110 : input.getDefaultValue();
1111 propertyConvertor.convertAndAddValue(dataTypes, props, input, supplier);
1116 private void addPropertiesOfComponentInstance(final Map<String, List<ComponentInstanceProperty>> componentInstancesProperties,
1117 final Map<String, DataTypeDefinition> dataTypes,
1118 final String instanceUniqueId,
1119 final Map<String, Object> props) {
1121 if (isNotEmpty(componentInstancesProperties)) {
1122 componentInstancesProperties.get(instanceUniqueId)
1123 // Converts and adds each value to property map
1124 .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop, prop::getValue));
1128 private void addAttributesOfComponentInstance(final Map<String, List<ComponentInstanceAttribute>> componentInstancesAttributes,
1129 final String instanceUniqueId,
1130 final Map<String, Object> attribs) {
1132 if (isNotEmpty(componentInstancesAttributes) && componentInstancesAttributes.containsKey(instanceUniqueId)) {
1133 componentInstancesAttributes.get(instanceUniqueId)
1134 .forEach(attributeDefinition -> attributeConverter.convertAndAddValue(attribs, attributeDefinition));
1138 private void addPropertiesOfParentComponent(Map<String, DataTypeDefinition> dataTypes,
1139 Component componentOfInstance, Map<String, Object> props) {
1141 List<PropertyDefinition> componentProperties = componentOfInstance.getProperties();
1142 if (isNotEmpty(componentProperties)) {
1143 componentProperties.stream()
1144 // Filters out properties with empty default values
1145 .filter(prop -> StringUtils.isNotEmpty(prop.getDefaultValue()))
1146 // Converts and adds each value to property map
1147 .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop, prop::getDefaultValue));
1151 private void addAttributesOfParentComponent(final Component componentOfInstance, final Map<String, Object> attribs) {
1153 final List<AttributeDefinition> componentAttributes = componentOfInstance.getAttributes();
1154 if (isNotEmpty(componentAttributes)) {
1155 componentAttributes.stream()
1156 // Filters out Attributes with empty default values
1157 .filter(attrib -> StringUtils.isNotEmpty(attrib.getDefaultValue()))
1158 // Converts and adds each value to attribute map
1159 .forEach(attributeDefinition -> attributeConverter.convertAndAddValue(attribs, attributeDefinition));
1163 private ToscaNodeType createNodeType(Component component) {
1164 ToscaNodeType toscaNodeType = new ToscaNodeType();
1165 if (ModelConverter.isAtomicComponent(component)) {
1166 if (((Resource) component).getDerivedFrom() != null) {
1167 toscaNodeType.setDerived_from(((Resource) component).getDerivedFrom().get(0));
1169 toscaNodeType.setDescription(component.getDescription());
1171 String derivedFrom = null != component.getDerivedFromGenericType() ? component.getDerivedFromGenericType()
1173 toscaNodeType.setDerived_from(derivedFrom);
1175 return toscaNodeType;
1178 private Either<Map<String, Object>, ToscaError> createProxyInterfaceTypes(Component container) {
1180 Map<String, Object> proxyInterfaceTypes = new HashMap<>();
1181 Either<Map<String, Object>, ToscaError> res = Either.left(proxyInterfaceTypes);
1182 List<ComponentInstance> componentInstances = container.getComponentInstances();
1183 if (CollectionUtils.isEmpty(componentInstances)) {
1186 Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
1187 componentInstances.stream()
1188 .filter(this::isComponentOfTypeServiceProxy)
1189 .forEach(inst -> serviceProxyInstanceList.put(inst.getToscaComponentName(), inst));
1190 if (MapUtils.isEmpty(serviceProxyInstanceList)) {
1193 for (Entry<String, ComponentInstance> entryProxy : serviceProxyInstanceList.entrySet()) {
1194 Component serviceComponent;
1195 ComponentParametersView componentParametersView = new ComponentParametersView();
1196 componentParametersView.disableAll();
1197 componentParametersView.setIgnoreInterfaces(false);
1198 Either<Component, StorageOperationStatus> service = toscaOperationFacade
1199 .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
1200 if (service.isRight()) {
1201 log.debug("Failed to fetch original service component with id {} for instance {}",
1202 entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName());
1203 return Either.right(ToscaError.GENERAL_ERROR);
1205 serviceComponent = service.left().value();
1208 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither =
1209 interfaceLifecycleOperation.getAllInterfaceLifecycleTypes(serviceComponent.getModel());
1210 if (lifecycleTypeEither.isRight()) {
1211 log.debug("Failed to retrieve global interface types :", lifecycleTypeEither.right().value());
1212 return Either.right(ToscaError.GENERAL_ERROR);
1215 List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value().values().stream()
1216 .map(InterfaceDataDefinition::getType)
1217 .collect(Collectors.toList());
1218 //Add interface types for local interfaces in the original service component for proxy
1219 Map<String, Object> localInterfaceTypes = interfacesOperationsConverter.addInterfaceTypeElement(serviceComponent,
1220 allGlobalInterfaceTypes);
1221 if (MapUtils.isNotEmpty(localInterfaceTypes)) {
1222 proxyInterfaceTypes.putAll(localInterfaceTypes);
1226 return Either.left(proxyInterfaceTypes);
1229 private Either<Map<String, ToscaNodeType>, ToscaError> createProxyNodeTypes(Map<String, Component> componentCache,
1230 Component container) {
1232 Map<String, ToscaNodeType> nodeTypesMap = new HashMap<>();
1233 Either<Map<String, ToscaNodeType>, ToscaError> res = Either.left(nodeTypesMap);
1235 List<ComponentInstance> componentInstances = container.getComponentInstances();
1237 if (componentInstances == null || componentInstances.isEmpty()) {
1240 Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
1241 List<ComponentInstance> proxyInst = componentInstances.stream()
1242 .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceProxy.name()))
1243 .collect(Collectors.toList());
1244 if (proxyInst != null && !proxyInst.isEmpty()) {
1245 for (ComponentInstance inst : proxyInst) {
1246 serviceProxyInstanceList.put(inst.getToscaComponentName(), inst);
1250 if (serviceProxyInstanceList.isEmpty()) {
1253 Either<Resource, StorageOperationStatus> serviceProxyOrigin = toscaOperationFacade
1254 .getLatestByName("serviceProxy", null);
1255 if (serviceProxyOrigin.isRight()) {
1256 log.debug("Failed to fetch normative service proxy resource by tosca name, error {}",
1257 serviceProxyOrigin.right().value());
1258 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
1260 Component origComponent = serviceProxyOrigin.left().value();
1262 for (Entry<String, ComponentInstance> entryProxy : serviceProxyInstanceList.entrySet()) {
1263 Component serviceComponent = null;
1264 ComponentParametersView componentParametersView = new ComponentParametersView();
1265 componentParametersView.disableAll();
1266 componentParametersView.setIgnoreCategories(false);
1267 componentParametersView.setIgnoreProperties(false);
1268 componentParametersView.setIgnoreInputs(false);
1269 componentParametersView.setIgnoreInterfaces(false);
1270 componentParametersView.setIgnoreRequirements(false);
1271 Either<Component, StorageOperationStatus> service = toscaOperationFacade
1272 .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
1273 if (service.isRight()) {
1274 log.debug("Failed to fetch resource with id {} for instance {}",
1275 entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName());
1277 serviceComponent = service.left().value();
1280 ToscaNodeType toscaNodeType = createProxyNodeType(componentCache, origComponent, serviceComponent,
1281 entryProxy.getValue());
1282 nodeTypesMap.put(entryProxy.getKey(), toscaNodeType);
1285 return Either.left(nodeTypesMap);
1288 private void createServiceSubstitutionNodeTypes(final Map<String, Component> componentCache,
1289 final Component container, final ToscaTemplate toscaNode) {
1290 final List<ComponentInstance> componentInstances = container.getComponentInstances();
1292 if (CollectionUtils.isEmpty(componentInstances)) {
1295 final List<ComponentInstance> serviceSubstitutionInstanceList = componentInstances.stream()
1296 .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceSubstitution.name()))
1297 .collect(Collectors.toList());
1298 if (CollectionUtils.isNotEmpty(serviceSubstitutionInstanceList)) {
1299 for (ComponentInstance inst : serviceSubstitutionInstanceList) {
1300 final Map<String, ToscaNodeType> nodeTypes =
1301 toscaNode.getNode_types() == null ? new HashMap<>() : toscaNode.getNode_types();
1302 convertInterfaceNodeType(new HashMap<>(), componentCache.get(inst.getSourceModelUid()), toscaNode,
1308 private ToscaNodeType createProxyNodeType(Map<String, Component> componentCache, Component origComponent,
1309 Component proxyComponent, ComponentInstance componentInstance) {
1310 ToscaNodeType toscaNodeType = new ToscaNodeType();
1311 String derivedFrom = ((Resource) origComponent).getToscaResourceName();
1313 toscaNodeType.setDerived_from(derivedFrom);
1314 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = applicationDataTypeCache.getAll(
1315 origComponent.getModel());
1316 if (dataTypesEither.isRight()) {
1317 log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
1319 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
1320 Map<String, ToscaCapability> capabilities = this.capabilityRequirementConverter
1321 .convertProxyCapabilities(componentCache, componentInstance, dataTypes);
1323 if (MapUtils.isNotEmpty(capabilities)) {
1324 toscaNodeType.setCapabilities(capabilities);
1326 List<Map<String, ToscaRequirement>> proxyNodeTypeRequirements = this.capabilityRequirementConverter
1327 .convertProxyRequirements(componentCache, componentInstance);
1328 if (CollectionUtils.isNotEmpty(proxyNodeTypeRequirements)) {
1329 toscaNodeType.setRequirements(proxyNodeTypeRequirements);
1331 Optional<Map<String, ToscaProperty>> proxyProperties = getProxyNodeTypeProperties(proxyComponent, dataTypes);
1332 proxyProperties.ifPresent(toscaNodeType::setProperties);
1334 Map<String, Object> interfaceMap = new HashMap<>();
1335 if (MapUtils.isEmpty(componentInstance.getInterfaces())) {
1336 final Optional<Map<String, Object>> proxyInterfaces = getProxyNodeTypeInterfaces(proxyComponent, dataTypes);
1337 if (proxyInterfaces.isPresent()) {
1338 interfaceMap = proxyInterfaces.get();
1341 interfaceMap = interfacesOperationsConverter
1342 .getInterfacesMapFromComponentInstance(proxyComponent, componentInstance, dataTypes, false, false);
1345 interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
1346 toscaNodeType.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap);
1348 return toscaNodeType;
1351 private Either<ToscaNodeTemplate, ToscaError> convertComponentInstanceRequirements(Component component,
1352 ComponentInstance componentInstance,
1353 List<RequirementCapabilityRelDef> relations,
1354 ToscaNodeTemplate nodeTypeTemplate,
1355 Component originComponent,
1356 Map<String, Component> componentCache) {
1358 final List<RequirementCapabilityRelDef> requirementDefinitionList = filterRequirements(componentInstance,
1360 if (isNotEmpty(requirementDefinitionList)) {
1362 final List<Map<String, ToscaTemplateRequirement>> toscaRequirements = buildRequirements(component, componentInstance,
1363 requirementDefinitionList, originComponent, componentCache);
1364 if (!toscaRequirements.isEmpty()) {
1365 nodeTypeTemplate.setRequirements(toscaRequirements);
1367 } catch (final Exception e) {
1368 log.debug("Failed to convert component instance requirements for the component instance {}. ",
1369 componentInstance.getName(), e);
1370 return Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
1373 log.debug("Finished to convert requirements for the node type {} ", componentInstance.getName());
1374 return Either.left(nodeTypeTemplate);
1377 private List<Map<String, ToscaTemplateRequirement>> buildRequirements(final Component component,
1378 final ComponentInstance componentInstance,
1379 final List<RequirementCapabilityRelDef> filteredRelations,
1380 final Component originComponent,
1381 final Map<String, Component> componentCache)
1382 throws ToscaExportException {
1384 final List<Map<String, ToscaTemplateRequirement>> toscaRequirements = new ArrayList<>();
1385 for (RequirementCapabilityRelDef relationshipDefinition : filteredRelations) {
1386 final Map<String, ToscaTemplateRequirement> toscaTemplateRequirementMap =
1387 buildRequirement(componentInstance, originComponent, component.getComponentInstances(), relationshipDefinition, componentCache);
1388 toscaRequirements.add(toscaTemplateRequirementMap);
1391 return toscaRequirements;
1394 private List<RequirementCapabilityRelDef> filterRequirements(ComponentInstance componentInstance,
1395 List<RequirementCapabilityRelDef> relations) {
1396 return relations.stream()
1397 .filter(p -> componentInstance.getUniqueId().equals(p.getFromNode())).collect(Collectors.toList());
1400 private Map<String, ToscaTemplateRequirement> buildRequirement(final ComponentInstance fromInstance,
1401 final Component fromOriginComponent,
1402 final List<ComponentInstance> instancesList,
1403 final RequirementCapabilityRelDef relationshipDefinition,
1404 final Map<String, Component> componentCache)
1405 throws ToscaExportException {
1407 final Map<String, List<RequirementDefinition>> reqMap = fromOriginComponent.getRequirements();
1408 final CapabilityRequirementRelationship capabilityRequirementRelationship = relationshipDefinition
1409 .getRelationships().get(0);
1410 final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation();
1412 final ComponentInstance toInstance = instancesList.stream()
1413 .filter(i -> relationshipDefinition.getToNode().equals(i.getUniqueId()))
1414 .findFirst().orElse(null);
1415 if (toInstance == null) {
1416 final String errorMsg = String
1417 .format("Failed to find a relation from the node %s to the node %s", fromInstance.getName(),
1418 relationshipDefinition.getToNode());
1419 log.debug(errorMsg);
1420 throw new ToscaExportException(errorMsg);
1422 final Optional<RequirementDefinition> reqOpt =
1423 findRequirement(fromOriginComponent, reqMap, relationshipInfo, fromInstance.getUniqueId());
1424 if (reqOpt.isEmpty()) {
1425 final String errorMsg = String
1426 .format("Failed to find a requirement with uniqueId %s on a component with uniqueId %s",
1427 relationshipInfo.getRequirementUid(), fromOriginComponent.getUniqueId());
1428 log.debug(errorMsg);
1429 throw new ToscaExportException(errorMsg);
1431 final ComponentParametersView filter = new ComponentParametersView(true);
1432 filter.setIgnoreComponentInstances(false);
1433 filter.setIgnoreCapabilities(false);
1434 filter.setIgnoreGroups(false);
1435 final Either<Component, StorageOperationStatus> getOriginRes =
1436 toscaOperationFacade.getToscaElement(toInstance.getActualComponentUid(), filter);
1437 if (getOriginRes.isRight()) {
1438 final String errorMsg = String.format(
1439 "Failed to build substituted name for the requirement %s. "
1440 + "Failed to get an origin component with uniqueId %s",
1441 reqOpt.get().getName(), toInstance.getActualComponentUid());
1442 log.debug(errorMsg);
1443 throw new ToscaExportException(errorMsg);
1445 final Component toOriginComponent = getOriginRes.left().value();
1446 Optional<CapabilityDefinition> capOpt = toOriginComponent.getCapabilities().get(reqOpt.get().getCapability()).stream()
1447 .filter(c -> isCapabilityBelongToRelation(relationshipInfo, c)).findFirst();
1448 if (capOpt.isEmpty()) {
1449 capOpt = findCapability(relationshipInfo, toOriginComponent, fromOriginComponent, reqOpt.get());
1450 if (capOpt.isEmpty()) {
1451 final String errorMsg = String
1452 .format("Failed to find a capability with name %s on a component with uniqueId %s",
1453 relationshipInfo.getCapability(), fromOriginComponent.getUniqueId());
1454 log.debug(errorMsg);
1455 throw new ToscaExportException(errorMsg);
1458 return buildRequirement(fromOriginComponent, toOriginComponent, capOpt.get(), reqOpt.get(),
1459 capabilityRequirementRelationship, toInstance, componentCache);
1462 private boolean isCapabilityBelongToRelation(RelationshipInfo reqAndRelationshipPair,
1463 CapabilityDefinition capability) {
1464 return capability.getName().equals(reqAndRelationshipPair.getCapability()) && (capability.getOwnerId() != null
1465 && capability.getOwnerId().equals(reqAndRelationshipPair.getCapabilityOwnerId()));
1468 private Optional<CapabilityDefinition> findCapability(RelationshipInfo reqAndRelationshipPair,
1469 Component toOriginComponent, Component fromOriginComponent,
1470 RequirementDefinition requirement) {
1471 Optional<CapabilityDefinition> cap = toOriginComponent.getCapabilities().get(requirement.getCapability())
1472 .stream().filter(c -> c.getType().equals(requirement.getCapability())).findFirst();
1473 if (!cap.isPresent()) {
1474 log.debug("Failed to find a capability with name {} on a component with uniqueId {}",
1475 reqAndRelationshipPair.getCapability(), fromOriginComponent.getUniqueId());
1480 private Map<String, ToscaTemplateRequirement> buildRequirement(final Component fromOriginComponent,
1481 final Component toOriginComponent,
1482 final CapabilityDefinition capability,
1483 final RequirementDefinition requirement,
1484 final CapabilityRequirementRelationship capabilityRequirementRelationship,
1485 final ComponentInstance toInstance,
1486 final Map<String, Component> componentCache)
1487 throws ToscaExportException {
1489 List<String> reducedPath = capability.getPath();
1490 if (capability.getOwnerId() != null) {
1491 reducedPath = capabilityRequirementConverter
1492 .getReducedPathByOwner(capability.getPath(), capability.getOwnerId());
1494 final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation();
1495 final Either<String, Boolean> capabilityNameEither = capabilityRequirementConverter.buildSubstitutedName(componentCache,
1496 toOriginComponent, reducedPath, relationshipInfo.getCapability(), capability.getPreviousName(), capability.getExternalName());
1497 if (capabilityNameEither.isRight()) {
1498 final String errorMsg = String.format(
1499 "Failed to build a substituted capability name for the capability with name %s on a component with uniqueId %s",
1500 capabilityRequirementRelationship.getCapability(), toOriginComponent.getUniqueId());
1503 throw new ToscaExportException(errorMsg);
1505 final Either<String, Boolean> requirementNameEither = capabilityRequirementConverter
1506 .buildSubstitutedName(componentCache, fromOriginComponent,
1507 requirement.getPath(), relationshipInfo.getRequirement(), requirement.getPreviousName(), requirement.getExternalName());
1508 if (requirementNameEither.isRight()) {
1509 final String errorMsg = String.format("Failed to build a substituted requirement name for the requirement "
1510 + "with name %s on a component with uniqueId %s",
1511 capabilityRequirementRelationship.getRequirement(), fromOriginComponent.getUniqueId());
1512 log.debug(errorMsg);
1513 throw new ToscaExportException(errorMsg);
1515 final ToscaTemplateRequirement toscaRequirement = new ToscaTemplateRequirement();
1516 final Map<String, ToscaTemplateRequirement> toscaReqMap = new HashMap<>();
1517 toscaRequirement.setNode(toInstance.getName());
1518 toscaRequirement.setCapability(capabilityNameEither.left().value());
1519 if (isNotEmpty(capabilityRequirementRelationship.getOperations())) {
1520 toscaRequirement.setRelationship(new ToscaRelationshipBuilder().from(capabilityRequirementRelationship));
1522 toscaReqMap.put(requirementNameEither.left().value(), toscaRequirement);
1526 private Optional<RequirementDefinition> findRequirement(Component fromOriginComponent,
1527 Map<String, List<RequirementDefinition>> reqMap,
1528 RelationshipInfo reqAndRelationshipPair,
1529 String fromInstanceId) {
1530 for (List<RequirementDefinition> reqList : reqMap.values()) {
1531 Optional<RequirementDefinition> reqOpt = reqList.stream().filter(
1532 r -> isRequirementBelongToRelation(fromOriginComponent, reqAndRelationshipPair, r, fromInstanceId))
1534 if (reqOpt.isPresent()) {
1538 return Optional.empty();
1542 * Allows detecting the requirement belonging to the received relationship The detection logic is: A requirement belongs to a relationship IF
1543 * 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
1544 * requirement equals to requirementOwnerId of the relation OR uniqueId of toInstance equals to capabilityOwnerId of the relation
1546 private boolean isRequirementBelongToRelation(Component originComponent, RelationshipInfo reqAndRelationshipPair,
1547 RequirementDefinition requirement, String fromInstanceId) {
1548 if (!StringUtils.equals(requirement.getName(), reqAndRelationshipPair.getRequirement())) {
1549 log.debug("Failed to find a requirement with name {} and reqAndRelationshipPair {}", requirement.getName(),
1550 reqAndRelationshipPair.getRequirement());
1553 return ModelConverter.isAtomicComponent(originComponent) || isRequirementBelongToOwner(reqAndRelationshipPair, requirement, fromInstanceId,
1557 private boolean isRequirementBelongToOwner(RelationshipInfo reqAndRelationshipPair, RequirementDefinition requirement, String fromInstanceId,
1558 Component originComponent) {
1559 return StringUtils.equals(requirement.getOwnerId(), reqAndRelationshipPair.getRequirementOwnerId()) || (
1560 isCvfc(originComponent) && StringUtils.equals(fromInstanceId, reqAndRelationshipPair.getRequirementOwnerId()) || StringUtils
1561 .equals(requirement.getOwnerId(), originComponent.getUniqueId()));
1564 private boolean isCvfc(Component component) {
1565 return component.getComponentType() == ComponentTypeEnum.RESOURCE && ((Resource) component).getResourceType() == ResourceTypeEnum.CVFC;
1568 private Either<Map<String, String[]>, ToscaError> convertSubstitutionMappingCapabilities(final Component component,
1569 final Map<String, Component> componentCache) {
1570 Either<Map<String, String[]>, ToscaError> toscaCapabilitiesRes =
1571 capabilityRequirementConverter.convertSubstitutionMappingCapabilities(componentCache, component);
1572 if (toscaCapabilitiesRes.isRight()) {
1573 log.debug("Failed convert capabilities for the component {}. ", component.getName());
1574 return Either.right(toscaCapabilitiesRes.right().value());
1576 if (isNotEmpty(toscaCapabilitiesRes.left().value())) {
1577 log.debug("Finish convert capabilities for the component {}. ", component.getName());
1578 return Either.left(toscaCapabilitiesRes.left().value());
1580 log.debug("Finished to convert capabilities for the component {}. ", component.getName());
1582 return Either.left(Collections.emptyMap());
1585 private Either<ToscaNodeType, ToscaError> convertCapabilities(Map<String, Component> componentsCache, Component component, ToscaNodeType nodeType,
1586 Map<String, DataTypeDefinition> dataTypes) {
1587 Map<String, ToscaCapability> toscaCapabilities = capabilityRequirementConverter.convertCapabilities(componentsCache, component, dataTypes);
1588 if (!toscaCapabilities.isEmpty()) {
1589 nodeType.setCapabilities(toscaCapabilities);
1591 log.debug("Finish convert Capabilities for node type");
1592 return Either.left(nodeType);
1595 private Map<String, ToscaTemplateArtifact> convertToNodeTemplateArtifacts(Map<String, ToscaArtifactDataDefinition> artifacts) {
1596 if (artifacts == null) {
1599 Map<String, ToscaTemplateArtifact> arts = new HashMap<>();
1600 for (Map.Entry<String, ToscaArtifactDataDefinition> entry : artifacts.entrySet()) {
1601 ToscaTemplateArtifact artifact = new ToscaTemplateArtifact();
1602 artifact.setFile(entry.getValue().getFile());
1603 artifact.setType(entry.getValue().getType());
1604 artifact.setProperties(entry.getValue().getProperties());
1605 arts.put(entry.getKey(), artifact);
1610 private NodeFilter convertToNodeTemplateNodeFilterComponent(CINodeFilterDataDefinition inNodeFilter) {
1611 if (inNodeFilter == null) {
1614 NodeFilter nodeFilter = new NodeFilter();
1615 ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities = inNodeFilter.getCapabilities();
1616 ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> origProperties = inNodeFilter.getProperties();
1617 List<Map<String, CapabilityFilter>> capabilitiesCopy = new ArrayList<>();
1618 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1619 copyNodeFilterCapabilitiesTemplate(origCapabilities, capabilitiesCopy);
1620 copyNodeFilterProperties(origProperties, propertiesCopy);
1621 if (CollectionUtils.isNotEmpty(capabilitiesCopy)) {
1622 nodeFilter.setCapabilities(capabilitiesCopy);
1624 if (CollectionUtils.isNotEmpty(propertiesCopy)) {
1625 nodeFilter.setProperties(propertiesCopy);
1627 nodeFilter.setTosca_id(cloneToscaId(inNodeFilter.getTosca_id()));
1628 nodeFilter = (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
1632 private NodeFilter convertToSubstitutionFilterComponent(final SubstitutionFilterDataDefinition substitutionFilterDataDefinition) {
1633 if (substitutionFilterDataDefinition == null) {
1636 NodeFilter nodeFilter = new NodeFilter();
1637 ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> origProperties = substitutionFilterDataDefinition.getProperties();
1638 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1639 copySubstitutionFilterProperties(origProperties, propertiesCopy);
1640 if (CollectionUtils.isNotEmpty(propertiesCopy)) {
1641 nodeFilter.setProperties(propertiesCopy);
1643 nodeFilter.setTosca_id(cloneToscaId(substitutionFilterDataDefinition.getTosca_id()));
1644 return (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
1647 private Object cloneToscaId(Object toscaId) {
1648 return Objects.isNull(toscaId) ? null : cloneObjectFromYml(toscaId, toscaId.getClass());
1651 private Object cloneObjectFromYml(Object objToClone, Class classOfObj) {
1652 String objectAsYml = yamlUtil.objectToYaml(objToClone);
1653 return yamlUtil.yamlToObject(objectAsYml, classOfObj);
1656 private void copyNodeFilterCapabilitiesTemplate(ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities,
1657 List<Map<String, CapabilityFilter>> capabilitiesCopy) {
1658 if (origCapabilities == null || origCapabilities.getListToscaDataDefinition() == null || origCapabilities.getListToscaDataDefinition()
1662 for (RequirementNodeFilterCapabilityDataDefinition capability : origCapabilities.getListToscaDataDefinition()) {
1663 Map<String, CapabilityFilter> capabilityFilterCopyMap = new HashMap<>();
1664 CapabilityFilter capabilityFilter = new CapabilityFilter();
1665 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1666 copyNodeFilterProperties(capability.getProperties(), propertiesCopy);
1667 capabilityFilter.setProperties(propertiesCopy);
1668 capabilityFilterCopyMap.put(capability.getName(), capabilityFilter);
1669 capabilitiesCopy.add(capabilityFilterCopyMap);
1673 private void copyNodeFilterProperties(ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> origProperties,
1674 List<Map<String, List<Object>>> propertiesCopy) {
1675 if (origProperties == null || origProperties.getListToscaDataDefinition() == null || origProperties.isEmpty()) {
1678 Map<String, List<Object>> propertyMapCopy = new HashMap<>();
1679 for (RequirementNodeFilterPropertyDataDefinition propertyDataDefinition : origProperties.getListToscaDataDefinition()) {
1680 for (String propertyInfoEntry : propertyDataDefinition.getConstraints()) {
1681 Map<String, List<Object>> propertyValObj = new YamlUtil().yamlToObject(propertyInfoEntry, Map.class);
1682 String propertyName = propertyDataDefinition.getName();
1683 if (propertyMapCopy.containsKey(propertyName)) {
1684 addPropertyConstraintValueToList(propertyName, propertyValObj, propertyMapCopy.get(propertyName));
1686 if (propertyName != null) {
1687 List<Object> propsList = new ArrayList<>();
1688 addPropertyConstraintValueToList(propertyName, propertyValObj, propsList);
1689 propertyMapCopy.put(propertyName, propsList);
1691 propertyMapCopy.putAll(propertyValObj);
1696 propertyMapCopy.entrySet().stream().forEach(entry -> addCalculatedConstraintsIntoPropertiesList(propertiesCopy, entry));
1699 private void copySubstitutionFilterProperties(final ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> origProperties,
1700 final List<Map<String, List<Object>>> propertiesCopy) {
1701 if (origProperties == null || origProperties.getListToscaDataDefinition() == null || origProperties.isEmpty()) {
1704 final Map<String, List<Object>> propertyMapCopy = new HashMap<>();
1705 for (final RequirementSubstitutionFilterPropertyDataDefinition propertyDataDefinition : origProperties.getListToscaDataDefinition()) {
1706 for (final String propertyInfoEntry : propertyDataDefinition.getConstraints()) {
1707 final Map<String, List<Object>> propertyValObj = new YamlUtil().yamlToObject(propertyInfoEntry, Map.class);
1708 final String propertyName = propertyDataDefinition.getName();
1709 if (propertyMapCopy.containsKey(propertyName)) {
1710 addPropertyConstraintValueToList(propertyName, propertyValObj, propertyMapCopy.get(propertyName));
1712 if (propertyName != null) {
1713 final List<Object> propsList = new ArrayList<>();
1714 addPropertyConstraintValueToList(propertyName, propertyValObj, propsList);
1715 propertyMapCopy.put(propertyName, propsList);
1717 propertyMapCopy.putAll(propertyValObj);
1722 propertyMapCopy.entrySet().forEach(entry -> addCalculatedConstraintsIntoPropertiesList(propertiesCopy, entry));
1725 private void addPropertyConstraintValueToList(String propertyName, Map<String, List<Object>> propertyValObj, List<Object> propsList) {
1726 if (propertyValObj.containsKey(propertyName)) {
1727 propsList.add(propertyValObj.get(propertyName));
1729 propsList.add(propertyValObj);
1733 private void addCalculatedConstraintsIntoPropertiesList(List<Map<String, List<Object>>> propertiesCopy, Entry<String, List<Object>> entry) {
1734 Map<String, List<Object>> tempMap = new HashMap<>();
1735 tempMap.put(entry.getKey(), entry.getValue());
1736 propertiesCopy.add(tempMap);
1739 private Map<String, String[]> buildSubstitutionMappingPropertyMapping(final Component component) {
1740 if (component == null || CollectionUtils.isEmpty(component.getInputs())) {
1741 return Collections.emptyMap();
1743 return component.getInputs().stream().filter(InputDefinition::isMappedToComponentProperty).map(PropertyDataDefinition::getName)
1744 .collect(Collectors.toMap(inputName -> inputName, inputName -> new String[]{inputName}, (inputName1, inputName2) -> inputName1));
1747 private Map<String, String[]> buildSubstitutionMappingAttributesMapping(final Component component) {
1748 if (component == null || CollectionUtils.isEmpty(component.getOutputs())) {
1749 return Collections.emptyMap();
1751 return component.getOutputs().stream().map(AttributeDataDefinition::getName)
1752 .collect(Collectors.toMap(outputName -> outputName, outputName -> new String[]{outputName}, (outputName1, outputName2) -> outputName1));
1755 private Optional<Map<String, ToscaProperty>> getProxyNodeTypeProperties(Component proxyComponent, Map<String, DataTypeDefinition> dataTypes) {
1756 if (Objects.isNull(proxyComponent)) {
1757 return Optional.empty();
1759 final var proxyProperties = convertInputsToProperties(dataTypes, proxyComponent.getInputs(), proxyComponent.getUniqueId());
1760 if (CollectionUtils.isNotEmpty(proxyComponent.getProperties())) {
1761 proxyProperties.putAll(proxyComponent.getProperties().stream()
1762 .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, proxyComponent.getInputs())).collect(Collectors
1763 .toMap(PropertyDataDefinition::getName,
1764 property -> propertyConvertor.convertProperty(dataTypes, property, PropertyType.PROPERTY))));
1766 return MapUtils.isNotEmpty(proxyProperties) ? Optional.of(proxyProperties) : Optional.empty();
1769 private Map<String, ToscaProperty> convertInputsToProperties(Map<String, DataTypeDefinition> dataTypes, List<InputDefinition> componentInputs,
1770 String componentUniqueId) {
1771 if (CollectionUtils.isEmpty(componentInputs)) {
1772 return new HashMap<>();
1774 return componentInputs.stream().filter(input -> componentUniqueId.equals(input.getInstanceUniqueId()))
1775 .collect(Collectors.toMap(InputDefinition::getName, i -> propertyConvertor.convertProperty(dataTypes, i, PropertyType.INPUT)));
1778 private Optional<Map<String, Object>> getProxyNodeTypeInterfaces(Component proxyComponent, Map<String, DataTypeDefinition> dataTypes) {
1779 if (Objects.isNull(proxyComponent) || MapUtils.isEmpty(proxyComponent.getInterfaces())) {
1780 return Optional.empty();
1782 Map<String, InterfaceDefinition> proxyComponentInterfaces = proxyComponent.getInterfaces();
1783 //Unset artifact path for operation implementation for proxy node types as for operations with artifacts it is
1785 // always available in the proxy node template
1786 removeOperationImplementationForProxyNodeType(proxyComponentInterfaces);
1788 .ofNullable(interfacesOperationsConverter.getInterfacesMap(proxyComponent, null, proxyComponentInterfaces, dataTypes, false, false));
1791 private Configuration getConfiguration() {
1792 return ConfigurationManager.getConfigurationManager().getConfiguration();
1795 private static class CustomRepresenter extends Representer {
1797 CustomRepresenter() {
1799 this.representers.put(ToscaPropertyAssignment.class, new RepresentToscaPropertyAssignment());
1800 this.representers.put(ToscaAttribute.class, new RepresentToscaAttribute());
1801 // null representer is exceptional and it is stored as an instance
1804 this.nullRepresenter = new RepresentNull();
1807 public boolean validateGetInputValue(final Object valueObj) {
1808 if (!(valueObj instanceof List) && !(valueObj instanceof String)) {
1811 if (valueObj instanceof List) {
1812 return ((List) valueObj).size() > 1;
1817 public boolean validateGetPropertyOrAttributeValue(final Object valueObj) {
1818 if (valueObj instanceof List) {
1819 return ((List) valueObj).size() > 1;
1825 protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue, Tag customTag) {
1826 if (propertyValue == null) {
1829 // skip not relevant for Tosca property
1830 if ("dependencies".equals(property.getName())) {
1833 if (javaBean instanceof ToscaRelationshipTemplate && "name".equals(property.getName())) {
1836 removeDefaultP(propertyValue);
1837 NodeTuple defaultNode = super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
1838 if (javaBean instanceof ToscaTopolgyTemplate && "relationshipTemplates".equals(property.getName())) {
1839 return new NodeTuple(representData("relationship_templates"), defaultNode.getValueNode());
1841 return "_defaultp_".equals(property.getName()) ? new NodeTuple(representData("default"), defaultNode.getValueNode()) : defaultNode;
1844 private void removeDefaultP(final Object propertyValue) {
1845 if (propertyValue instanceof Map) {
1846 final Map mapPropertyValue = ((Map) propertyValue);
1847 final Iterator<Entry> iter = mapPropertyValue.entrySet().iterator();
1848 Object defaultValue = null;
1849 while (iter.hasNext()) {
1850 final Map.Entry entry = iter.next();
1851 if ("_defaultp_".equals(entry.getKey())) {
1852 defaultValue = entry.getValue();
1854 } else if (entry.getValue() instanceof Map) {
1855 removeDefaultP(entry.getValue());
1858 if (defaultValue != null) {
1859 mapPropertyValue.putIfAbsent("default", defaultValue);
1865 protected MappingNode representJavaBean(Set<Property> properties, Object javaBean) {
1866 // remove the bean type from the output yaml (!! ...)
1867 if (!classTags.containsKey(javaBean.getClass())) {
1868 addClassTag(javaBean.getClass(), Tag.MAP);
1870 return super.representJavaBean(properties, javaBean);
1873 private class RepresentToscaAttribute implements Represent {
1876 public Node representData(Object data) {
1877 final ToscaAttribute toscaAttribute = (ToscaAttribute) data;
1878 return represent(toscaAttribute.asToscaMap());
1882 private class RepresentToscaPropertyAssignment implements Represent {
1884 public Node representData(Object data) {
1885 final ToscaPropertyAssignment toscaOperationAssignment = (ToscaPropertyAssignment) data;
1886 if (toscaOperationAssignment.getValue() instanceof String) {
1887 final String stringValue = (String) toscaOperationAssignment.getValue();
1888 if (isPropertyOrAttributeFunction(stringValue)) {
1889 return representGetAttribute(stringValue);
1891 return representScalar(Tag.STR, stringValue);
1893 return represent(null);
1896 public Node representGetAttribute(final String getAttributeFunction) {
1897 return represent(new Yaml().load(getAttributeFunction));
1900 public boolean isPropertyOrAttributeFunction(final String value) {
1902 final Yaml yaml = new Yaml();
1903 final Object yamlObj = yaml.load(value);
1904 if (!(yamlObj instanceof Map)) {
1907 final Map<String, Object> getAttributeMap = (Map) yamlObj;
1908 if (getAttributeMap.size() != 1) {
1911 final List<String> functionList = Arrays
1912 .asList(GET_ATTRIBUTE.getFunctionName(), GET_INPUT.getFunctionName(), GET_PROPERTY.getFunctionName());
1913 final Optional<String> function = getAttributeMap.keySet().stream()
1914 .filter(key -> functionList.stream().anyMatch(function1 -> function1.equals(key))).findFirst();
1915 if (function.isEmpty()) {
1918 final String functionName = function.get();
1919 final Object getAttributeValueObj = getAttributeMap.get(functionName);
1920 if (GET_INPUT.getFunctionName().equals(functionName)) {
1921 return validateGetInputValue(getAttributeValueObj);
1923 return validateGetPropertyOrAttributeValue(getAttributeValueObj);
1925 } catch (final Exception ignored) {
1931 private class RepresentNull implements Represent {
1934 public Node representData(Object data) {
1935 // possible values are here http://yaml.org/type/null.html
1936 return representScalar(Tag.NULL, "");
1941 private static class UnsortedPropertyUtils extends PropertyUtils {
1944 protected Set<Property> createPropertySet(Class type, BeanAccess bAccess) {
1945 Collection<Property> fields = getPropertiesMap(type, BeanAccess.FIELD).values();
1946 return new LinkedHashSet<>(fields);