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