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.be.tosca.InterfacesOperationsConverter.addInterfaceTypeElement;
26 import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_ATTRIBUTE;
27 import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_INPUT;
28 import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_PROPERTY;
30 import com.fasterxml.jackson.databind.ObjectMapper;
31 import com.google.gson.JsonParser;
32 import com.google.gson.JsonElement;
33 import com.google.gson.JsonObject;
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 com.google.common.primitives.Ints;
56 import org.apache.commons.collections.CollectionUtils;
57 import org.apache.commons.collections.MapUtils;
58 import org.apache.commons.io.FilenameUtils;
59 import org.apache.commons.lang3.StringUtils;
60 import org.apache.commons.lang3.tuple.ImmutablePair;
61 import org.apache.commons.lang3.tuple.ImmutableTriple;
62 import org.apache.commons.lang3.tuple.Triple;
63 import org.onap.sdc.tosca.services.YamlUtil;
64 import org.openecomp.sdc.be.components.impl.exceptions.SdcResourceNotFoundException;
65 import org.openecomp.sdc.be.config.Configuration;
66 import org.openecomp.sdc.be.config.ConfigurationManager;
67 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
68 import org.openecomp.sdc.be.data.model.ToscaImportByModel;
69 import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
70 import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition;
71 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
72 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
73 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
74 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
75 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition;
76 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition;
77 import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterPropertyDataDefinition;
78 import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition;
79 import org.openecomp.sdc.be.datatypes.elements.ToscaArtifactDataDefinition;
80 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
81 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
82 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
83 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
84 import org.openecomp.sdc.be.exception.ToscaExportException;
85 import org.openecomp.sdc.be.model.ArtifactDefinition;
86 import org.openecomp.sdc.be.model.AttributeDefinition;
87 import org.openecomp.sdc.be.model.CapabilityDefinition;
88 import org.openecomp.sdc.be.model.CapabilityRequirementRelationship;
89 import org.openecomp.sdc.be.model.Component;
90 import org.openecomp.sdc.be.model.ComponentInstance;
91 import org.openecomp.sdc.be.model.ComponentInstanceAttribute;
92 import org.openecomp.sdc.be.model.ComponentInstanceInput;
93 import org.openecomp.sdc.be.model.ComponentInstanceInterface;
94 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
95 import org.openecomp.sdc.be.model.ComponentParametersView;
96 import org.openecomp.sdc.be.model.DataTypeDefinition;
97 import org.openecomp.sdc.be.model.GroupInstance;
98 import org.openecomp.sdc.be.model.InputDefinition;
99 import org.openecomp.sdc.be.model.InterfaceDefinition;
100 import org.openecomp.sdc.be.model.PropertyDefinition;
101 import org.openecomp.sdc.be.model.RelationshipInfo;
102 import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
103 import org.openecomp.sdc.be.model.RequirementDefinition;
104 import org.openecomp.sdc.be.model.Resource;
105 import org.openecomp.sdc.be.model.Service;
106 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
107 import org.openecomp.sdc.be.model.category.CategoryDefinition;
108 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
109 import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter;
110 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
111 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
112 import org.openecomp.sdc.be.model.operations.impl.ModelOperation;
113 import org.openecomp.sdc.be.model.tosca.converters.ToscaMapValueConverter;
114 import org.openecomp.sdc.be.tosca.PropertyConvertor.PropertyType;
115 import org.openecomp.sdc.be.tosca.builder.ToscaRelationshipBuilder;
116 import org.openecomp.sdc.be.tosca.exception.ToscaConversionException;
117 import org.openecomp.sdc.be.tosca.model.CapabilityFilter;
118 import org.openecomp.sdc.be.tosca.model.NodeFilter;
119 import org.openecomp.sdc.be.tosca.model.SubstitutionMapping;
120 import org.openecomp.sdc.be.tosca.model.ToscaAttribute;
121 import org.openecomp.sdc.be.tosca.model.ToscaCapability;
122 import org.openecomp.sdc.be.tosca.model.ToscaDataType;
123 import org.openecomp.sdc.be.tosca.model.ToscaGroupTemplate;
124 import org.openecomp.sdc.be.tosca.model.ToscaNodeTemplate;
125 import org.openecomp.sdc.be.tosca.model.ToscaNodeType;
126 import org.openecomp.sdc.be.tosca.model.ToscaPolicyTemplate;
127 import org.openecomp.sdc.be.tosca.model.ToscaProperty;
128 import org.openecomp.sdc.be.tosca.model.ToscaPropertyAssignment;
129 import org.openecomp.sdc.be.tosca.model.ToscaRelationshipTemplate;
130 import org.openecomp.sdc.be.tosca.model.ToscaRequirement;
131 import org.openecomp.sdc.be.tosca.model.ToscaTemplate;
132 import org.openecomp.sdc.be.tosca.model.ToscaTemplateArtifact;
133 import org.openecomp.sdc.be.tosca.model.ToscaTemplateRequirement;
134 import org.openecomp.sdc.be.tosca.model.ToscaTopolgyTemplate;
135 import org.openecomp.sdc.be.tosca.utils.ForwardingPathToscaUtil;
136 import org.openecomp.sdc.be.tosca.utils.InputConverter;
137 import org.openecomp.sdc.be.tosca.utils.OutputConverter;
138 import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
139 import org.openecomp.sdc.common.log.wrappers.Logger;
140 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
141 import org.springframework.beans.factory.annotation.Autowired;
142 import org.yaml.snakeyaml.DumperOptions;
143 import org.yaml.snakeyaml.DumperOptions.FlowStyle;
144 import org.yaml.snakeyaml.Yaml;
145 import org.yaml.snakeyaml.introspector.BeanAccess;
146 import org.yaml.snakeyaml.introspector.Property;
147 import org.yaml.snakeyaml.introspector.PropertyUtils;
148 import org.yaml.snakeyaml.nodes.MappingNode;
149 import org.yaml.snakeyaml.nodes.Node;
150 import org.yaml.snakeyaml.nodes.NodeTuple;
151 import org.yaml.snakeyaml.nodes.Tag;
152 import org.yaml.snakeyaml.representer.Represent;
153 import org.yaml.snakeyaml.representer.Representer;
155 @org.springframework.stereotype.Component("tosca-export-handler")
156 public class ToscaExportHandler {
158 public static final String ASSET_TOSCA_TEMPLATE = "assettoscatemplate";
159 private static final Logger log = Logger.getLogger(ToscaExportHandler.class);
160 private static final String INVARIANT_UUID = "invariantUUID";
161 private static final String TOSCA_VERSION = "tosca_simple_yaml_1_3";
162 private static final String SERVICE_NODE_TYPE_PREFIX = "org.openecomp.service.";
163 private static final String IMPORTS_FILE_KEY = "file";
164 private static final String TOSCA_INTERFACE_NAME = "-interface.yml";
165 private static final String FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION = "convertToToscaTemplate - failed to get Default Imports section from configuration";
166 private static final String NOT_SUPPORTED_COMPONENT_TYPE = "Not supported component type {}";
167 private static final String NATIVE_ROOT = "tosca.nodes.Root";
168 private static final List<String> EXCLUDED_CATEGORY_SPECIFIC_METADATA = List
169 .of("Service Function", "Service Role", "Naming Policy", "Service Type");
170 private static final YamlUtil yamlUtil = new YamlUtil();
171 private final ApplicationDataTypeCache applicationDataTypeCache;
172 private final ToscaOperationFacade toscaOperationFacade;
173 private final CapabilityRequirementConverter capabilityRequirementConverter;
174 private final PolicyExportParser policyExportParser;
175 private final GroupExportParser groupExportParser;
176 private final PropertyConvertor propertyConvertor;
177 private final AttributeConverter attributeConverter;
178 private final InputConverter inputConverter;
179 private final OutputConverter outputConverter;
180 private final InterfaceLifecycleOperation interfaceLifecycleOperation;
181 private final InterfacesOperationsConverter interfacesOperationsConverter;
182 private final ModelOperation modelOperation;
185 public ToscaExportHandler(final ApplicationDataTypeCache applicationDataTypeCache,
186 final ToscaOperationFacade toscaOperationFacade,
187 final CapabilityRequirementConverter capabilityRequirementConverter,
188 final PolicyExportParser policyExportParser,
189 final GroupExportParser groupExportParser,
190 final PropertyConvertor propertyConvertor,
191 final AttributeConverter attributeConverter,
192 final InputConverter inputConverter,
193 final OutputConverter outputConverter,
194 final InterfaceLifecycleOperation interfaceLifecycleOperation,
195 final InterfacesOperationsConverter interfacesOperationsConverter,
196 final ModelOperation modelOperation) {
197 this.applicationDataTypeCache = applicationDataTypeCache;
198 this.toscaOperationFacade = toscaOperationFacade;
199 this.capabilityRequirementConverter = capabilityRequirementConverter;
200 this.policyExportParser = policyExportParser;
201 this.groupExportParser = groupExportParser;
202 this.propertyConvertor = propertyConvertor;
203 this.attributeConverter = attributeConverter;
204 this.inputConverter = inputConverter;
205 this.outputConverter = outputConverter;
206 this.interfaceLifecycleOperation = interfaceLifecycleOperation;
207 this.interfacesOperationsConverter = interfacesOperationsConverter;
208 this.modelOperation = modelOperation;
211 public static String getInterfaceFilename(String artifactName) {
212 return artifactName.substring(0, artifactName.lastIndexOf('.')) + TOSCA_INTERFACE_NAME;
215 private static void removeOperationImplementationForProxyNodeType(Map<String, InterfaceDefinition> proxyComponentInterfaces) {
216 if (MapUtils.isEmpty(proxyComponentInterfaces)) {
219 proxyComponentInterfaces.values().stream().map(InterfaceDataDefinition::getOperations).filter(MapUtils::isNotEmpty)
220 .forEach(operations -> operations.values().forEach(operation -> operation.setImplementation(null)));
223 public Either<ToscaRepresentation, ToscaError> exportComponent(Component component) {
224 return convertToToscaTemplate(component).left().map(this::createToscaRepresentation);
227 public Either<ToscaRepresentation, ToscaError> exportComponentInterface(final Component component, final boolean isAssociatedComponent) {
228 final List<Map<String, Map<String, String>>> imports = new ArrayList<>(getDefaultToscaImports(component.getModel()));
229 if (CollectionUtils.isEmpty(imports)) {
230 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
231 return Either.right(ToscaError.GENERAL_ERROR);
233 List<Triple<String, String, Component>> dependencies = new ArrayList<>();
234 if (component.getDerivedFromGenericType() != null && !component.getDerivedFromGenericType()
235 .startsWith("org.openecomp.resource.abstract.nodes.")) {
236 final Either<Component, StorageOperationStatus> baseType = toscaOperationFacade
237 .getByToscaResourceNameAndVersion(component.getDerivedFromGenericType(), component.getDerivedFromGenericVersion(), 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 public 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 public 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 (!requirementMap.isEmpty()) {
462 substitutionMapping.setRequirements(requirementMap);
465 final Map<String, String[]> propertyMappingMap = buildSubstitutionMappingPropertyMapping(component);
466 if (!propertyMappingMap.isEmpty()) {
467 substitutionMapping.setProperties(propertyMappingMap);
470 final Map<String, String[]> attributesMappingMap = buildSubstitutionMappingAttributesMapping(component);
471 if (!attributesMappingMap.isEmpty()) {
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(addInterfaceTypeElement(component, allGlobalInterfaceTypes));
787 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> 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 Map<String, ToscaProperty> mergedProperties = new HashMap<>();
795 interfacesOperationsConverter.addInterfaceDefinitionElement(component, toscaNodeType, dataTypes, isAssociatedComponent);
796 addInputsToProperties(dataTypes, inputDef, mergedProperties);
797 final Map<String, ToscaAttribute> toscaAttributeMap;
798 toscaAttributeMap = convertToToscaAttributes(component.getAttributes(), dataTypes);
799 if (!toscaAttributeMap.isEmpty()) {
800 toscaNodeType.setAttributes(toscaAttributeMap);
802 if (CollectionUtils.isNotEmpty(component.getProperties())) {
803 List<PropertyDefinition> properties = component.getProperties();
804 Map<String, ToscaProperty> convertedProperties = properties.stream()
805 .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, component.getInputs())).collect(Collectors
806 .toMap(PropertyDataDefinition::getName,
807 property -> propertyConvertor.convertProperty(dataTypes, property, PropertyConvertor.PropertyType.PROPERTY)));
808 // merge component properties and inputs properties
809 mergedProperties.putAll(convertedProperties);
811 if (MapUtils.isNotEmpty(mergedProperties)) {
812 toscaNodeType.setProperties(mergedProperties);
814 /* convert private data_types */
815 List<DataTypeDefinition> privateDataTypes = component.getDataTypes();
816 if (CollectionUtils.isNotEmpty(privateDataTypes)) {
817 Map<String, ToscaDataType> toscaDataTypeMap = new HashMap<>();
818 for (DataTypeDefinition dataType : privateDataTypes) {
819 log.debug("Emitting private data type: component.name={} dataType.name={}",
820 component.getNormalizedName(), dataType.getName());
821 ToscaDataType toscaDataType = new ToscaDataType();
822 toscaDataType.setDerived_from(dataType.getDerivedFromName());
823 toscaDataType.setDescription(dataType.getDescription());
824 toscaDataType.setVersion(dataType.getVersion());
825 if (CollectionUtils.isNotEmpty(dataType.getProperties())) {
826 toscaDataType.setProperties(dataType.getProperties().stream()
827 .collect(Collectors.toMap(
828 PropertyDataDefinition::getName,
829 s -> propertyConvertor.convertProperty(dataTypes, s, PropertyType.PROPERTY),
830 (toscaPropertyTobeValidated, toscaProperty) -> validateToscaProperty(privateDataTypes, toscaPropertyTobeValidated, toscaProperty)
833 toscaDataTypeMap.put(dataType.getName(), toscaDataType);
835 toscaNode.setData_types(toscaDataTypeMap);
838 // Extracted to method for code reuse
839 return convertReqCapAndTypeName(componentsCache, component, toscaNode, nodeTypes, toscaNodeType, dataTypes);
842 private ToscaProperty validateToscaProperty(final List<DataTypeDefinition> privateDataTypes, final ToscaProperty toscaPropertyTobeValidated,
843 final ToscaProperty toscaProperty) {
844 final Optional<DataTypeDefinition> match = privateDataTypes.stream()
845 .filter(dataType -> dataType.getName().equals(toscaPropertyTobeValidated.getType())).findFirst();
846 return match.isPresent() ? toscaPropertyTobeValidated : toscaProperty;
849 private Map<String, ToscaAttribute> convertToToscaAttributes(final List<AttributeDefinition> attributeList,
850 final Map<String, DataTypeDefinition> dataTypes) {
851 if (CollectionUtils.isEmpty(attributeList)) {
852 return Collections.emptyMap();
854 final AttributeConverter converter = new AttributeConverter(dataTypes);
855 final Map<String, ToscaAttribute> toscaAttributeMap = new HashMap<>();
856 for (final AttributeDefinition attributeDefinition : attributeList) {
857 toscaAttributeMap.put(attributeDefinition.getName(), converter.convert(attributeDefinition));
859 return toscaAttributeMap;
862 private Either<ToscaTemplate, ToscaError> convertReqCapAndTypeName(Map<String, Component> componentsCache,
863 Component component, ToscaTemplate toscaNode,
864 Map<String, ToscaNodeType> nodeTypes,
865 ToscaNodeType toscaNodeType,
866 Map<String, DataTypeDefinition> dataTypes) {
867 Either<ToscaNodeType, ToscaError> capabilities = convertCapabilities(componentsCache, component, toscaNodeType,
869 if (capabilities.isRight()) {
870 return Either.right(capabilities.right().value());
872 toscaNodeType = capabilities.left().value();
873 log.debug("Capabilities converted for {}", component.getUniqueId());
875 Either<ToscaNodeType, ToscaError> requirements = capabilityRequirementConverter
876 .convertRequirements(componentsCache, component, toscaNodeType);
877 if (requirements.isRight()) {
878 return Either.right(requirements.right().value());
880 toscaNodeType = requirements.left().value();
881 log.debug("Requirements converted for {}", component.getUniqueId());
883 String toscaResourceName;
884 switch (component.getComponentType()) {
886 toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition()
887 .getMetadataDataDefinition()).getToscaResourceName();
890 toscaResourceName = SERVICE_NODE_TYPE_PREFIX
891 + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName();
894 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
895 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
898 nodeTypes.put(toscaResourceName, toscaNodeType);
899 toscaNode.setNode_types(nodeTypes);
900 log.debug("finish convert node type for {}", component.getUniqueId());
901 return Either.left(toscaNode);
904 private Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplates(final Component component,
905 final Map<String, Component> componentCache,
906 final Map<String, DataTypeDefinition> dataTypes,
907 final ToscaTopolgyTemplate topologyTemplate) {
909 final Map<String, List<ComponentInstanceProperty>> componentInstancesProperties = component.getComponentInstancesProperties();
910 final Map<String, List<ComponentInstanceAttribute>> componentInstancesAttributes = component.getComponentInstancesAttributes();
911 final Map<String, List<ComponentInstanceInput>> componentInstancesInputs = component.getComponentInstancesInputs();
912 final Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces = component.getComponentInstancesInterfaces();
913 final List<RequirementCapabilityRelDef> componentInstancesRelations = component.getComponentInstancesRelations();
915 Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplatesRes = null;
916 log.debug("start convert topology template for {} for type {}", component.getUniqueId(), component.getComponentType());
917 final Map<String, ToscaNodeTemplate> nodeTemplates = new HashMap<>();
919 Map<String, ToscaGroupTemplate> groupsMap = null;
920 for (final ComponentInstance componentInstance : component.getComponentInstances()) {
921 ToscaNodeTemplate nodeTemplate = new ToscaNodeTemplate();
922 if (MapUtils.isNotEmpty(componentInstance.getToscaArtifacts())) {
923 nodeTemplate.setArtifacts(convertToNodeTemplateArtifacts(componentInstance.getToscaArtifacts()));
925 if (componentInstance.getMinOccurrences() != null && componentInstance.getMaxOccurrences()!= null){
926 List<Object> occur = new ArrayList<>();
927 occur.add(parseToIntIfPossible(componentInstance.getMinOccurrences()));
928 occur.add(parseToIntIfPossible(componentInstance.getMaxOccurrences()));
929 nodeTemplate.setOccurrences(occur);
931 if (componentInstance.getInstanceCount() != null){
932 ObjectMapper objectMapper = new ObjectMapper();
933 Object obj = convertToToscaObject(componentInstance.getInstanceCount());
935 Map<String, String> map = objectMapper.convertValue(obj, Map.class);
936 nodeTemplate.setInstance_count(map);
939 nodeTemplate.setType(componentInstance.getToscaComponentName());
940 nodeTemplate.setDirectives(componentInstance.getDirectives());
941 nodeTemplate.setNode_filter(convertToNodeTemplateNodeFilterComponent(componentInstance.getNodeFilter()));
943 final Either<Component, Boolean> originComponentRes = capabilityRequirementConverter
944 .getOriginComponent(componentCache, componentInstance);
945 if (originComponentRes.isRight()) {
946 convertNodeTemplatesRes = Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
949 final Either<ToscaNodeTemplate, ToscaError> requirements = convertComponentInstanceRequirements(component, componentInstance,
950 componentInstancesRelations, nodeTemplate, originComponentRes.left().value(), componentCache);
951 if (requirements.isRight()) {
952 convertNodeTemplatesRes = Either.right(requirements.right().value());
955 final String instanceUniqueId = componentInstance.getUniqueId();
956 log.debug("Component instance Requirements converted for instance {}", instanceUniqueId);
958 nodeTemplate = requirements.left().value();
960 final Component originalComponent = componentCache.get(componentInstance.getActualComponentUid());
962 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
963 final Component componentOfProxy = componentCache.get(componentInstance.getComponentUid());
964 nodeTemplate.setMetadata(convertMetadata(componentOfProxy, true, componentInstance));
966 nodeTemplate.setMetadata(convertMetadata(originalComponent, true, componentInstance));
969 final Either<ToscaNodeTemplate, ToscaError> capabilities =
970 capabilityRequirementConverter.convertComponentInstanceCapabilities(componentInstance, dataTypes, nodeTemplate);
971 if (capabilities.isRight()) {
972 convertNodeTemplatesRes = Either.right(capabilities.right().value());
975 log.debug("Component instance Capabilities converted for instance {}", instanceUniqueId);
977 nodeTemplate = capabilities.left().value();
978 final Map<String, Object> props = new HashMap<>();
979 final Map<String, Object> attribs = new HashMap<>();
981 if (originalComponent.getComponentType() == ComponentTypeEnum.RESOURCE) {
982 // Adds the properties of parent component to map
983 addPropertiesOfParentComponent(dataTypes, originalComponent, props);
984 addAttributesOfParentComponent(originalComponent, attribs);
987 if (null != componentInstancesProperties && componentInstancesProperties.containsKey(instanceUniqueId)) {
988 addPropertiesOfComponentInstance(componentInstancesProperties, dataTypes, instanceUniqueId, props);
990 if (null != componentInstancesAttributes && componentInstancesAttributes.containsKey(instanceUniqueId)) {
991 addAttributesOfComponentInstance(componentInstancesAttributes, instanceUniqueId, attribs);
994 if (componentInstancesInputs != null
995 && componentInstancesInputs.containsKey(instanceUniqueId)
996 && !isComponentOfTypeServiceProxy(componentInstance)) {
997 //For service proxy the inputs are already handled under instance properties above
998 addComponentInstanceInputs(dataTypes, componentInstancesInputs, instanceUniqueId, props);
1001 //M3[00001] - NODE TEMPLATE INTERFACES - START
1002 handleInstanceInterfaces(componentInstanceInterfaces, componentInstance, dataTypes, nodeTemplate, instanceUniqueId, component);
1003 //M3[00001] - NODE TEMPLATE INTERFACES - END
1004 if (MapUtils.isNotEmpty(props)) {
1005 nodeTemplate.setProperties(props);
1007 if (MapUtils.isNotEmpty(attribs)) {
1008 nodeTemplate.setAttributes(attribs);
1011 final List<GroupInstance> groupInstances = componentInstance.getGroupInstances();
1012 if (CollectionUtils.isNotEmpty(groupInstances)) {
1013 if (groupsMap == null) {
1014 groupsMap = new HashMap<>();
1016 for (final GroupInstance groupInst : groupInstances) {
1017 if (CollectionUtils.isNotEmpty(groupInst.getArtifacts())) {
1018 groupsMap.put(groupInst.getName(), groupExportParser.getToscaGroupTemplate(groupInst, componentInstance.getInvariantName()));
1023 nodeTemplates.put(componentInstance.getName(), nodeTemplate);
1025 if (groupsMap != null) {
1026 log.debug("instance groups added");
1027 topologyTemplate.addGroups(groupsMap);
1029 if (component.getComponentType() == ComponentTypeEnum.SERVICE && isNotEmpty(
1030 ((Service) component).getForwardingPaths())) {
1031 log.debug("Starting converting paths for component {}, name {}", component.getUniqueId(), component.getName());
1032 ForwardingPathToscaUtil
1033 .addForwardingPaths((Service) component, nodeTemplates, capabilityRequirementConverter, componentCache, toscaOperationFacade);
1034 log.debug("Finished converting paths for component {}, name {}", component.getUniqueId(), component.getName());
1036 if (convertNodeTemplatesRes == null) {
1037 convertNodeTemplatesRes = Either.left(nodeTemplates);
1039 log.debug("finish convert topology template for {} for type {}", component.getUniqueId(), component.getComponentType());
1040 return convertNodeTemplatesRes;
1043 public Object convertToToscaObject(String value) {
1045 ToscaMapValueConverter mapConverterInst = ToscaMapValueConverter.getInstance();
1046 JsonParser jsonParser = new JsonParser();
1047 StringReader reader = new StringReader(value);
1048 JsonReader jsonReader = new JsonReader(reader);
1049 jsonReader.setLenient(true);
1050 JsonElement jsonElement = jsonParser.parse(jsonReader);
1051 if (jsonElement.isJsonObject()) {
1052 JsonObject jsonObj = jsonElement.getAsJsonObject();
1053 if (jsonObj.entrySet().size() == 1 && jsonObj.has(ToscaFunctions.GET_INPUT.getFunctionName())) {
1054 return mapConverterInst.handleComplexJsonValue(jsonElement);
1058 } catch (Exception e) {
1059 log.debug("convertToToscaValue failed to parse json value :", e);
1064 private Object parseToIntIfPossible(final String value) {
1065 final Integer intValue = Ints.tryParse(value);
1066 return intValue == null ? value : intValue;
1069 private void handleInstanceInterfaces(
1070 Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces,
1071 ComponentInstance componentInstance, Map<String, DataTypeDefinition> dataTypes, ToscaNodeTemplate nodeTemplate,
1072 String instanceUniqueId,
1073 Component parentComponent) {
1075 if (MapUtils.isEmpty(componentInstanceInterfaces)
1076 || !componentInstanceInterfaces.containsKey(instanceUniqueId)) {
1077 nodeTemplate.setInterfaces(null);
1081 final List<ComponentInstanceInterface> currServiceInterfaces =
1082 componentInstanceInterfaces.get(instanceUniqueId);
1084 final Map<String, InterfaceDefinition> tmpInterfaces = new HashMap<>();
1085 currServiceInterfaces.forEach(instInterface -> tmpInterfaces.put(instInterface
1086 .getUniqueId(), instInterface));
1088 final Map<String, Object> interfaceMap = interfacesOperationsConverter
1089 .getInterfacesMap(parentComponent, componentInstance, tmpInterfaces, dataTypes, isComponentOfTypeServiceProxy(componentInstance),
1090 isComponentOfTypeServiceProxy(componentInstance));
1092 interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
1093 nodeTemplate.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap);
1096 private boolean isComponentOfTypeServiceProxy(ComponentInstance componentInstance) {
1097 return Objects.nonNull(componentInstance.getOriginType())
1098 && componentInstance.getOriginType().getValue().equals("Service Proxy");
1101 private void addComponentInstanceInputs(Map<String, DataTypeDefinition> dataTypes,
1102 Map<String, List<ComponentInstanceInput>> componentInstancesInputs,
1103 String instanceUniqueId, Map<String, Object> props) {
1105 List<ComponentInstanceInput> instanceInputsList = componentInstancesInputs.get(instanceUniqueId);
1106 if (instanceInputsList != null) {
1107 instanceInputsList.forEach(input -> {
1108 Supplier<String> supplier = () -> input.getValue() != null && !Objects.isNull(input.getValue()) ? input.getValue() : 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 = 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(origComponent.getModel());
1316 if (dataTypesEither.isRight()) {
1317 log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
1319 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
1320 Map<String, ToscaCapability> capabilities = this.capabilityRequirementConverter
1321 .convertProxyCapabilities(componentCache, componentInstance, dataTypes);
1323 if (MapUtils.isNotEmpty(capabilities)) {
1324 toscaNodeType.setCapabilities(capabilities);
1326 List<Map<String, ToscaRequirement>> proxyNodeTypeRequirements = this.capabilityRequirementConverter
1327 .convertProxyRequirements(componentCache, componentInstance);
1328 if (CollectionUtils.isNotEmpty(proxyNodeTypeRequirements)) {
1329 toscaNodeType.setRequirements(proxyNodeTypeRequirements);
1331 Optional<Map<String, ToscaProperty>> proxyProperties = getProxyNodeTypeProperties(proxyComponent, dataTypes);
1332 proxyProperties.ifPresent(toscaNodeType::setProperties);
1334 Map<String, Object> interfaceMap = new HashMap<>();
1335 if (MapUtils.isEmpty(componentInstance.getInterfaces())) {
1336 final Optional<Map<String, Object>> proxyInterfaces = getProxyNodeTypeInterfaces(proxyComponent, dataTypes);
1337 if (proxyInterfaces.isPresent()) {
1338 interfaceMap = proxyInterfaces.get();
1341 interfaceMap = interfacesOperationsConverter
1342 .getInterfacesMapFromComponentInstance(proxyComponent, componentInstance, dataTypes, false, false);
1345 interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
1346 toscaNodeType.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap);
1348 return toscaNodeType;
1351 private Either<ToscaNodeTemplate, ToscaError> convertComponentInstanceRequirements(Component component,
1352 ComponentInstance componentInstance,
1353 List<RequirementCapabilityRelDef> relations,
1354 ToscaNodeTemplate nodeTypeTemplate,
1355 Component originComponent,
1356 Map<String, Component> componentCache) {
1358 final List<RequirementCapabilityRelDef> requirementDefinitionList = filterRequirements(componentInstance,
1360 if (isNotEmpty(requirementDefinitionList)) {
1362 final List<Map<String, ToscaTemplateRequirement>> toscaRequirements = buildRequirements(component, componentInstance, requirementDefinitionList, originComponent, componentCache);
1363 if (!toscaRequirements.isEmpty()) {
1364 nodeTypeTemplate.setRequirements(toscaRequirements);
1366 } catch (final Exception e) {
1367 log.debug("Failed to convert component instance requirements for the component instance {}. ",
1368 componentInstance.getName(), e);
1369 return Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
1372 log.debug("Finished to convert requirements for the node type {} ", componentInstance.getName());
1373 return Either.left(nodeTypeTemplate);
1376 private List<Map<String, ToscaTemplateRequirement>> buildRequirements(final Component component,
1377 final ComponentInstance componentInstance,
1378 final List<RequirementCapabilityRelDef> filteredRelations,
1379 final Component originComponent,
1380 final Map<String, Component> componentCache)
1381 throws ToscaExportException {
1383 final List<Map<String, ToscaTemplateRequirement>> toscaRequirements = new ArrayList<>();
1384 for (RequirementCapabilityRelDef relationshipDefinition : filteredRelations) {
1385 final Map<String, ToscaTemplateRequirement> toscaTemplateRequirementMap =
1386 buildRequirement(componentInstance, originComponent, component.getComponentInstances(), relationshipDefinition, componentCache);
1387 toscaRequirements.add(toscaTemplateRequirementMap);
1390 return toscaRequirements;
1393 private List<RequirementCapabilityRelDef> filterRequirements(ComponentInstance componentInstance,
1394 List<RequirementCapabilityRelDef> relations) {
1395 return relations.stream()
1396 .filter(p -> componentInstance.getUniqueId().equals(p.getFromNode())).collect(Collectors.toList());
1399 private Map<String, ToscaTemplateRequirement> buildRequirement(final ComponentInstance fromInstance,
1400 final Component fromOriginComponent,
1401 final List<ComponentInstance> instancesList,
1402 final RequirementCapabilityRelDef relationshipDefinition,
1403 final Map<String, Component> componentCache)
1404 throws ToscaExportException {
1406 final Map<String, List<RequirementDefinition>> reqMap = fromOriginComponent.getRequirements();
1407 final CapabilityRequirementRelationship capabilityRequirementRelationship = relationshipDefinition
1408 .getRelationships().get(0);
1409 final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation();
1411 final ComponentInstance toInstance = instancesList.stream()
1412 .filter(i -> relationshipDefinition.getToNode().equals(i.getUniqueId()))
1413 .findFirst().orElse(null);
1414 if (toInstance == null) {
1415 final String errorMsg = String
1416 .format("Failed to find a relation from the node %s to the node %s", fromInstance.getName(),
1417 relationshipDefinition.getToNode());
1418 log.debug(errorMsg);
1419 throw new ToscaExportException(errorMsg);
1421 final Optional<RequirementDefinition> reqOpt =
1422 findRequirement(fromOriginComponent, reqMap, relationshipInfo, fromInstance.getUniqueId());
1423 if (reqOpt.isEmpty()) {
1424 final String errorMsg = String
1425 .format("Failed to find a requirement with uniqueId %s on a component with uniqueId %s",
1426 relationshipInfo.getRequirementUid(), fromOriginComponent.getUniqueId());
1427 log.debug(errorMsg);
1428 throw new ToscaExportException(errorMsg);
1430 final ComponentParametersView filter = new ComponentParametersView(true);
1431 filter.setIgnoreComponentInstances(false);
1432 filter.setIgnoreCapabilities(false);
1433 filter.setIgnoreGroups(false);
1434 final Either<Component, StorageOperationStatus> getOriginRes =
1435 toscaOperationFacade.getToscaElement(toInstance.getActualComponentUid(), filter);
1436 if (getOriginRes.isRight()) {
1437 final String errorMsg = String.format(
1438 "Failed to build substituted name for the requirement %s. "
1439 + "Failed to get an origin component with uniqueId %s",
1440 reqOpt.get().getName(), toInstance.getActualComponentUid());
1441 log.debug(errorMsg);
1442 throw new ToscaExportException(errorMsg);
1444 final Component toOriginComponent = getOriginRes.left().value();
1445 Optional<CapabilityDefinition> capOpt = toOriginComponent.getCapabilities().get(reqOpt.get().getCapability()).stream()
1446 .filter(c -> isCapabilityBelongToRelation(relationshipInfo, c)).findFirst();
1447 if (capOpt.isEmpty()) {
1448 capOpt = findCapability(relationshipInfo, toOriginComponent, fromOriginComponent, reqOpt.get());
1449 if (capOpt.isEmpty()) {
1450 final String errorMsg = String
1451 .format("Failed to find a capability with name %s on a component with uniqueId %s",
1452 relationshipInfo.getCapability(), fromOriginComponent.getUniqueId());
1453 log.debug(errorMsg);
1454 throw new ToscaExportException(errorMsg);
1457 return buildRequirement(fromOriginComponent, toOriginComponent, capOpt.get(), reqOpt.get(),
1458 capabilityRequirementRelationship, toInstance, componentCache);
1461 private boolean isCapabilityBelongToRelation(RelationshipInfo reqAndRelationshipPair,
1462 CapabilityDefinition capability) {
1463 return capability.getName().equals(reqAndRelationshipPair.getCapability()) && (capability.getOwnerId() != null
1464 && capability.getOwnerId().equals(reqAndRelationshipPair.getCapabilityOwnerId()));
1467 private Optional<CapabilityDefinition> findCapability(RelationshipInfo reqAndRelationshipPair,
1468 Component toOriginComponent, Component fromOriginComponent,
1469 RequirementDefinition requirement) {
1470 Optional<CapabilityDefinition> cap = toOriginComponent.getCapabilities().get(requirement.getCapability())
1471 .stream().filter(c -> c.getType().equals(requirement.getCapability())).findFirst();
1472 if (!cap.isPresent()) {
1473 log.debug("Failed to find a capability with name {} on a component with uniqueId {}",
1474 reqAndRelationshipPair.getCapability(), fromOriginComponent.getUniqueId());
1479 private Map<String, ToscaTemplateRequirement> buildRequirement(final Component fromOriginComponent,
1480 final Component toOriginComponent,
1481 final CapabilityDefinition capability,
1482 final RequirementDefinition requirement,
1483 final CapabilityRequirementRelationship capabilityRequirementRelationship,
1484 final ComponentInstance toInstance,
1485 final Map<String, Component> componentCache)
1486 throws ToscaExportException {
1488 List<String> reducedPath = capability.getPath();
1489 if (capability.getOwnerId() != null) {
1490 reducedPath = capabilityRequirementConverter
1491 .getReducedPathByOwner(capability.getPath(), capability.getOwnerId());
1493 final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation();
1494 final Either<String, Boolean> capabilityNameEither = capabilityRequirementConverter.buildSubstitutedName(componentCache,
1495 toOriginComponent, reducedPath, relationshipInfo.getCapability(), capability.getPreviousName(), capability.getExternalName());
1496 if (capabilityNameEither.isRight()) {
1497 final String errorMsg = String.format(
1498 "Failed to build a substituted capability name for the capability with name %s on a component with uniqueId %s",
1499 capabilityRequirementRelationship.getCapability(), toOriginComponent.getUniqueId());
1502 throw new ToscaExportException(errorMsg);
1504 final Either<String, Boolean> requirementNameEither = capabilityRequirementConverter
1505 .buildSubstitutedName(componentCache, fromOriginComponent,
1506 requirement.getPath(), relationshipInfo.getRequirement(), requirement.getPreviousName(), requirement.getExternalName());
1507 if (requirementNameEither.isRight()) {
1508 final String errorMsg = String.format("Failed to build a substituted requirement name for the requirement "
1509 + "with name %s on a component with uniqueId %s",
1510 capabilityRequirementRelationship.getRequirement(), fromOriginComponent.getUniqueId());
1511 log.debug(errorMsg);
1512 throw new ToscaExportException(errorMsg);
1514 final ToscaTemplateRequirement toscaRequirement = new ToscaTemplateRequirement();
1515 final Map<String, ToscaTemplateRequirement> toscaReqMap = new HashMap<>();
1516 toscaRequirement.setNode(toInstance.getName());
1517 toscaRequirement.setCapability(capabilityNameEither.left().value());
1518 if (isNotEmpty(capabilityRequirementRelationship.getOperations())) {
1519 toscaRequirement.setRelationship(new ToscaRelationshipBuilder().from(capabilityRequirementRelationship));
1521 toscaReqMap.put(requirementNameEither.left().value(), toscaRequirement);
1525 private Optional<RequirementDefinition> findRequirement(Component fromOriginComponent,
1526 Map<String, List<RequirementDefinition>> reqMap,
1527 RelationshipInfo reqAndRelationshipPair,
1528 String fromInstanceId) {
1529 for (List<RequirementDefinition> reqList : reqMap.values()) {
1530 Optional<RequirementDefinition> reqOpt = reqList.stream().filter(
1531 r -> isRequirementBelongToRelation(fromOriginComponent, reqAndRelationshipPair, r, fromInstanceId))
1533 if (reqOpt.isPresent()) {
1537 return Optional.empty();
1541 * Allows detecting the requirement belonging to the received relationship The detection logic is: A requirement belongs to a relationship IF
1542 * 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
1543 * requirement equals to requirementOwnerId of the relation OR uniqueId of toInstance equals to capabilityOwnerId of the relation
1545 private boolean isRequirementBelongToRelation(Component originComponent, RelationshipInfo reqAndRelationshipPair,
1546 RequirementDefinition requirement, String fromInstanceId) {
1547 if (!StringUtils.equals(requirement.getName(), reqAndRelationshipPair.getRequirement())) {
1548 log.debug("Failed to find a requirement with name {} and reqAndRelationshipPair {}", requirement.getName(),
1549 reqAndRelationshipPair.getRequirement());
1552 return ModelConverter.isAtomicComponent(originComponent) || isRequirementBelongToOwner(reqAndRelationshipPair, requirement, fromInstanceId,
1556 private boolean isRequirementBelongToOwner(RelationshipInfo reqAndRelationshipPair, RequirementDefinition requirement, String fromInstanceId,
1557 Component originComponent) {
1558 return StringUtils.equals(requirement.getOwnerId(), reqAndRelationshipPair.getRequirementOwnerId()) || (
1559 isCvfc(originComponent) && StringUtils.equals(fromInstanceId, reqAndRelationshipPair.getRequirementOwnerId()) || StringUtils
1560 .equals(requirement.getOwnerId(), originComponent.getUniqueId()));
1563 private boolean isCvfc(Component component) {
1564 return component.getComponentType() == ComponentTypeEnum.RESOURCE && ((Resource) component).getResourceType() == ResourceTypeEnum.CVFC;
1567 private Either<Map<String, String[]>, ToscaError> convertSubstitutionMappingCapabilities(final Component component,
1568 final Map<String, Component> componentCache) {
1569 Either<Map<String, String[]>, ToscaError> toscaCapabilitiesRes =
1570 capabilityRequirementConverter.convertSubstitutionMappingCapabilities(componentCache, component);
1571 if (toscaCapabilitiesRes.isRight()) {
1572 log.debug("Failed convert capabilities for the component {}. ", component.getName());
1573 return Either.right(toscaCapabilitiesRes.right().value());
1575 if (isNotEmpty(toscaCapabilitiesRes.left().value())) {
1576 log.debug("Finish convert capabilities for the component {}. ", component.getName());
1577 return Either.left(toscaCapabilitiesRes.left().value());
1579 log.debug("Finished to convert capabilities for the component {}. ", component.getName());
1581 return Either.left(Collections.emptyMap());
1584 private Either<ToscaNodeType, ToscaError> convertCapabilities(Map<String, Component> componentsCache, Component component, ToscaNodeType nodeType,
1585 Map<String, DataTypeDefinition> dataTypes) {
1586 Map<String, ToscaCapability> toscaCapabilities = capabilityRequirementConverter.convertCapabilities(componentsCache, component, dataTypes);
1587 if (!toscaCapabilities.isEmpty()) {
1588 nodeType.setCapabilities(toscaCapabilities);
1590 log.debug("Finish convert Capabilities for node type");
1591 return Either.left(nodeType);
1594 private Map<String, ToscaTemplateArtifact> convertToNodeTemplateArtifacts(Map<String, ToscaArtifactDataDefinition> artifacts) {
1595 if (artifacts == null) {
1598 Map<String, ToscaTemplateArtifact> arts = new HashMap<>();
1599 for (Map.Entry<String, ToscaArtifactDataDefinition> entry : artifacts.entrySet()) {
1600 ToscaTemplateArtifact artifact = new ToscaTemplateArtifact();
1601 artifact.setFile(entry.getValue().getFile());
1602 artifact.setType(entry.getValue().getType());
1603 artifact.setProperties(entry.getValue().getProperties());
1604 arts.put(entry.getKey(), artifact);
1609 private NodeFilter convertToNodeTemplateNodeFilterComponent(CINodeFilterDataDefinition inNodeFilter) {
1610 if (inNodeFilter == null) {
1613 NodeFilter nodeFilter = new NodeFilter();
1614 ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities = inNodeFilter.getCapabilities();
1615 ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> origProperties = inNodeFilter.getProperties();
1616 List<Map<String, CapabilityFilter>> capabilitiesCopy = new ArrayList<>();
1617 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1618 copyNodeFilterCapabilitiesTemplate(origCapabilities, capabilitiesCopy);
1619 copyNodeFilterProperties(origProperties, propertiesCopy);
1620 if (CollectionUtils.isNotEmpty(capabilitiesCopy)) {
1621 nodeFilter.setCapabilities(capabilitiesCopy);
1623 if (CollectionUtils.isNotEmpty(propertiesCopy)) {
1624 nodeFilter.setProperties(propertiesCopy);
1626 nodeFilter.setTosca_id(cloneToscaId(inNodeFilter.getTosca_id()));
1627 nodeFilter = (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
1631 private NodeFilter convertToSubstitutionFilterComponent(final SubstitutionFilterDataDefinition substitutionFilterDataDefinition) {
1632 if (substitutionFilterDataDefinition == null) {
1635 NodeFilter nodeFilter = new NodeFilter();
1636 ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> origProperties = substitutionFilterDataDefinition.getProperties();
1637 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1638 copySubstitutionFilterProperties(origProperties, propertiesCopy);
1639 if (CollectionUtils.isNotEmpty(propertiesCopy)) {
1640 nodeFilter.setProperties(propertiesCopy);
1642 nodeFilter.setTosca_id(cloneToscaId(substitutionFilterDataDefinition.getTosca_id()));
1643 return (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
1646 private Object cloneToscaId(Object toscaId) {
1647 return Objects.isNull(toscaId) ? null : cloneObjectFromYml(toscaId, toscaId.getClass());
1650 private Object cloneObjectFromYml(Object objToClone, Class classOfObj) {
1651 String objectAsYml = yamlUtil.objectToYaml(objToClone);
1652 return yamlUtil.yamlToObject(objectAsYml, classOfObj);
1655 private void copyNodeFilterCapabilitiesTemplate(ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities,
1656 List<Map<String, CapabilityFilter>> capabilitiesCopy) {
1657 if (origCapabilities == null || origCapabilities.getListToscaDataDefinition() == null || origCapabilities.getListToscaDataDefinition()
1661 for (RequirementNodeFilterCapabilityDataDefinition capability : origCapabilities.getListToscaDataDefinition()) {
1662 Map<String, CapabilityFilter> capabilityFilterCopyMap = new HashMap<>();
1663 CapabilityFilter capabilityFilter = new CapabilityFilter();
1664 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1665 copyNodeFilterProperties(capability.getProperties(), propertiesCopy);
1666 capabilityFilter.setProperties(propertiesCopy);
1667 capabilityFilterCopyMap.put(capability.getName(), capabilityFilter);
1668 capabilitiesCopy.add(capabilityFilterCopyMap);
1672 private void copyNodeFilterProperties(ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> origProperties,
1673 List<Map<String, List<Object>>> propertiesCopy) {
1674 if (origProperties == null || origProperties.getListToscaDataDefinition() == null || origProperties.isEmpty()) {
1677 Map<String, List<Object>> propertyMapCopy = new HashMap<>();
1678 for (RequirementNodeFilterPropertyDataDefinition propertyDataDefinition : origProperties.getListToscaDataDefinition()) {
1679 for (String propertyInfoEntry : propertyDataDefinition.getConstraints()) {
1680 Map<String, List<Object>> propertyValObj = new YamlUtil().yamlToObject(propertyInfoEntry, Map.class);
1681 String propertyName = propertyDataDefinition.getName();
1682 if (propertyMapCopy.containsKey(propertyName)) {
1683 addPropertyConstraintValueToList(propertyName, propertyValObj, propertyMapCopy.get(propertyName));
1685 if (propertyName != null) {
1686 List<Object> propsList = new ArrayList<>();
1687 addPropertyConstraintValueToList(propertyName, propertyValObj, propsList);
1688 propertyMapCopy.put(propertyName, propsList);
1690 propertyMapCopy.putAll(propertyValObj);
1695 propertyMapCopy.entrySet().stream().forEach(entry -> addCalculatedConstraintsIntoPropertiesList(propertiesCopy, entry));
1698 private void copySubstitutionFilterProperties(final ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> origProperties,
1699 final List<Map<String, List<Object>>> propertiesCopy) {
1700 if (origProperties == null || origProperties.getListToscaDataDefinition() == null || origProperties.isEmpty()) {
1703 final Map<String, List<Object>> propertyMapCopy = new HashMap<>();
1704 for (final RequirementSubstitutionFilterPropertyDataDefinition propertyDataDefinition : origProperties.getListToscaDataDefinition()) {
1705 for (final String propertyInfoEntry : propertyDataDefinition.getConstraints()) {
1706 final Map<String, List<Object>> propertyValObj = new YamlUtil().yamlToObject(propertyInfoEntry, Map.class);
1707 final String propertyName = propertyDataDefinition.getName();
1708 if (propertyMapCopy.containsKey(propertyName)) {
1709 addPropertyConstraintValueToList(propertyName, propertyValObj, propertyMapCopy.get(propertyName));
1711 if (propertyName != null) {
1712 final List<Object> propsList = new ArrayList<>();
1713 addPropertyConstraintValueToList(propertyName, propertyValObj, propsList);
1714 propertyMapCopy.put(propertyName, propsList);
1716 propertyMapCopy.putAll(propertyValObj);
1721 propertyMapCopy.entrySet().forEach(entry -> addCalculatedConstraintsIntoPropertiesList(propertiesCopy, entry));
1724 private void addPropertyConstraintValueToList(String propertyName, Map<String, List<Object>> propertyValObj, List<Object> propsList) {
1725 if (propertyValObj.containsKey(propertyName)) {
1726 propsList.add(propertyValObj.get(propertyName));
1728 propsList.add(propertyValObj);
1732 private void addCalculatedConstraintsIntoPropertiesList(List<Map<String, List<Object>>> propertiesCopy, Entry<String, List<Object>> entry) {
1733 Map<String, List<Object>> tempMap = new HashMap<>();
1734 tempMap.put(entry.getKey(), entry.getValue());
1735 propertiesCopy.add(tempMap);
1738 private Map<String, String[]> buildSubstitutionMappingPropertyMapping(final Component component) {
1739 if (component == null || CollectionUtils.isEmpty(component.getInputs())) {
1740 return Collections.emptyMap();
1742 return component.getInputs().stream().filter(InputDefinition::isMappedToComponentProperty).map(PropertyDataDefinition::getName)
1743 .collect(Collectors.toMap(inputName -> inputName, inputName -> new String[]{inputName}, (inputName1, inputName2) -> inputName1));
1746 private Map<String, String[]> buildSubstitutionMappingAttributesMapping(final Component component) {
1747 if (component == null || CollectionUtils.isEmpty(component.getOutputs())) {
1748 return Collections.emptyMap();
1750 return component.getOutputs().stream().map(AttributeDataDefinition::getName)
1751 .collect(Collectors.toMap(outputName -> outputName, outputName -> new String[]{outputName}, (outputName1, outputName2) -> outputName1));
1754 Optional<Map<String, ToscaProperty>> getProxyNodeTypeProperties(Component proxyComponent, Map<String, DataTypeDefinition> dataTypes) {
1755 if (Objects.isNull(proxyComponent)) {
1756 return Optional.empty();
1758 Map<String, ToscaProperty> proxyProperties = new HashMap<>();
1759 addInputsToProperties(dataTypes, proxyComponent.getInputs(), proxyProperties);
1760 if (CollectionUtils.isNotEmpty(proxyComponent.getProperties())) {
1761 proxyProperties.putAll(proxyComponent.getProperties().stream()
1762 .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, proxyComponent.getInputs())).collect(Collectors
1763 .toMap(PropertyDataDefinition::getName,
1764 property -> propertyConvertor.convertProperty(dataTypes, property, PropertyConvertor.PropertyType.PROPERTY))));
1766 return MapUtils.isNotEmpty(proxyProperties) ? Optional.of(proxyProperties) : Optional.empty();
1769 void addInputsToProperties(Map<String, DataTypeDefinition> dataTypes, List<InputDefinition> componentInputs,
1770 Map<String, ToscaProperty> mergedProperties) {
1771 if (CollectionUtils.isEmpty(componentInputs)) {
1774 for (InputDefinition input : componentInputs) {
1775 ToscaProperty property = propertyConvertor.convertProperty(dataTypes, input, PropertyConvertor.PropertyType.INPUT);
1776 mergedProperties.put(input.getName(), property);
1780 Optional<Map<String, Object>> getProxyNodeTypeInterfaces(Component proxyComponent, Map<String, DataTypeDefinition> dataTypes) {
1781 if (Objects.isNull(proxyComponent) || MapUtils.isEmpty(proxyComponent.getInterfaces())) {
1782 return Optional.empty();
1784 Map<String, InterfaceDefinition> proxyComponentInterfaces = proxyComponent.getInterfaces();
1785 //Unset artifact path for operation implementation for proxy node types as for operations with artifacts it is
1787 // always available in the proxy node template
1788 removeOperationImplementationForProxyNodeType(proxyComponentInterfaces);
1790 .ofNullable(interfacesOperationsConverter.getInterfacesMap(proxyComponent, null, proxyComponentInterfaces, dataTypes, false, false));
1793 private static class CustomRepresenter extends Representer {
1795 CustomRepresenter() {
1797 this.representers.put(ToscaPropertyAssignment.class, new RepresentToscaPropertyAssignment());
1798 this.representers.put(ToscaAttribute.class, new RepresentToscaAttribute());
1799 // null representer is exceptional and it is stored as an instance
1802 this.nullRepresenter = new RepresentNull();
1805 public boolean validateGetInputValue(final Object valueObj) {
1806 if (!(valueObj instanceof List) && !(valueObj instanceof String)) {
1809 if (valueObj instanceof List) {
1810 return ((List) valueObj).size() > 1;
1815 public boolean validateGetPropertyOrAttributeValue(final Object valueObj) {
1816 if (valueObj instanceof List) {
1817 return ((List) valueObj).size() > 1;
1823 protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue, Tag customTag) {
1824 if (propertyValue == null) {
1827 // skip not relevant for Tosca property
1828 if ("dependencies".equals(property.getName())) {
1831 if (javaBean instanceof ToscaRelationshipTemplate && "name".equals(property.getName())) {
1834 removeDefaultP(propertyValue);
1835 NodeTuple defaultNode = super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
1836 if (javaBean instanceof ToscaTopolgyTemplate && "relationshipTemplates".equals(property.getName())) {
1837 return new NodeTuple(representData("relationship_templates"), defaultNode.getValueNode());
1839 return "_defaultp_".equals(property.getName()) ? new NodeTuple(representData("default"), defaultNode.getValueNode()) : defaultNode;
1842 private void removeDefaultP(final Object propertyValue) {
1843 if (propertyValue instanceof Map) {
1844 final Map mapPropertyValue = ((Map) propertyValue);
1845 final Iterator<Entry> iter = mapPropertyValue.entrySet().iterator();
1846 Object defaultValue = null;
1847 while (iter.hasNext()) {
1848 final Map.Entry entry = iter.next();
1849 if ("_defaultp_".equals(entry.getKey())) {
1850 defaultValue = entry.getValue();
1852 } else if (entry.getValue() instanceof Map) {
1853 removeDefaultP(entry.getValue());
1856 if (defaultValue != null) {
1857 mapPropertyValue.putIfAbsent("default", defaultValue);
1863 protected MappingNode representJavaBean(Set<Property> properties, Object javaBean) {
1864 // remove the bean type from the output yaml (!! ...)
1865 if (!classTags.containsKey(javaBean.getClass())) {
1866 addClassTag(javaBean.getClass(), Tag.MAP);
1868 return super.representJavaBean(properties, javaBean);
1871 private class RepresentToscaAttribute implements Represent {
1874 public Node representData(Object data) {
1875 final ToscaAttribute toscaAttribute = (ToscaAttribute) data;
1876 return represent(toscaAttribute.asToscaMap());
1880 private class RepresentToscaPropertyAssignment implements Represent {
1882 public Node representData(Object data) {
1883 final ToscaPropertyAssignment toscaOperationAssignment = (ToscaPropertyAssignment) data;
1884 if (toscaOperationAssignment.getValue() instanceof String) {
1885 final String stringValue = (String) toscaOperationAssignment.getValue();
1886 if (isPropertyOrAttributeFunction(stringValue)) {
1887 return representGetAttribute(stringValue);
1889 return representScalar(Tag.STR, stringValue);
1891 return represent(null);
1894 public Node representGetAttribute(final String getAttributeFunction) {
1895 return represent(new Yaml().load(getAttributeFunction));
1898 public boolean isPropertyOrAttributeFunction(final String value) {
1900 final Yaml yaml = new Yaml();
1901 final Object yamlObj = yaml.load(value);
1902 if (!(yamlObj instanceof Map)) {
1905 final Map<String, Object> getAttributeMap = (Map) yamlObj;
1906 if (getAttributeMap.size() != 1) {
1909 final List<String> functionList = Arrays
1910 .asList(GET_ATTRIBUTE.getFunctionName(), GET_INPUT.getFunctionName(), GET_PROPERTY.getFunctionName());
1911 final Optional<String> function = getAttributeMap.keySet().stream()
1912 .filter(key -> functionList.stream().anyMatch(function1 -> function1.equals(key))).findFirst();
1913 if (function.isEmpty()) {
1916 final String functionName = function.get();
1917 final Object getAttributeValueObj = getAttributeMap.get(functionName);
1918 if (GET_INPUT.getFunctionName().equals(functionName)) {
1919 return validateGetInputValue(getAttributeValueObj);
1921 return validateGetPropertyOrAttributeValue(getAttributeValueObj);
1923 } catch (final Exception ignored) {
1929 private class RepresentNull implements Represent {
1932 public Node representData(Object data) {
1933 // possible values are here http://yaml.org/type/null.html
1934 return representScalar(Tag.NULL, "");
1939 private static class UnsortedPropertyUtils extends PropertyUtils {
1942 protected Set<Property> createPropertySet(Class type, BeanAccess bAccess) {
1943 Collection<Property> fields = getPropertiesMap(type, BeanAccess.FIELD).values();
1944 return new LinkedHashSet<>(fields);
1948 private Configuration getConfiguration() {
1949 return ConfigurationManager.getConfigurationManager().getConfiguration();