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 fj.data.Either;
31 import java.nio.file.Path;
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.Collection;
35 import java.util.Collections;
36 import java.util.HashMap;
37 import java.util.HashSet;
38 import java.util.Iterator;
39 import java.util.LinkedHashMap;
40 import java.util.LinkedHashSet;
41 import java.util.List;
43 import java.util.Map.Entry;
44 import java.util.Objects;
45 import java.util.Optional;
47 import java.util.function.Supplier;
48 import java.util.stream.Collectors;
49 import com.google.common.primitives.Ints;
50 import org.apache.commons.collections.CollectionUtils;
51 import org.apache.commons.collections.MapUtils;
52 import org.apache.commons.io.FilenameUtils;
53 import org.apache.commons.lang3.StringUtils;
54 import org.apache.commons.lang3.tuple.ImmutablePair;
55 import org.apache.commons.lang3.tuple.ImmutableTriple;
56 import org.apache.commons.lang3.tuple.Triple;
57 import org.onap.sdc.tosca.services.YamlUtil;
58 import org.openecomp.sdc.be.components.impl.exceptions.SdcResourceNotFoundException;
59 import org.openecomp.sdc.be.config.Configuration;
60 import org.openecomp.sdc.be.config.ConfigurationManager;
61 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
62 import org.openecomp.sdc.be.data.model.ToscaImportByModel;
63 import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
64 import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition;
65 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
66 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
67 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
68 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
69 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition;
70 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition;
71 import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterPropertyDataDefinition;
72 import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition;
73 import org.openecomp.sdc.be.datatypes.elements.ToscaArtifactDataDefinition;
74 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
75 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
76 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
77 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
78 import org.openecomp.sdc.be.exception.ToscaExportException;
79 import org.openecomp.sdc.be.model.ArtifactDefinition;
80 import org.openecomp.sdc.be.model.AttributeDefinition;
81 import org.openecomp.sdc.be.model.CapabilityDefinition;
82 import org.openecomp.sdc.be.model.CapabilityRequirementRelationship;
83 import org.openecomp.sdc.be.model.Component;
84 import org.openecomp.sdc.be.model.ComponentInstance;
85 import org.openecomp.sdc.be.model.ComponentInstanceAttribute;
86 import org.openecomp.sdc.be.model.ComponentInstanceInput;
87 import org.openecomp.sdc.be.model.ComponentInstanceInterface;
88 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
89 import org.openecomp.sdc.be.model.ComponentParametersView;
90 import org.openecomp.sdc.be.model.DataTypeDefinition;
91 import org.openecomp.sdc.be.model.GroupInstance;
92 import org.openecomp.sdc.be.model.InputDefinition;
93 import org.openecomp.sdc.be.model.InterfaceDefinition;
94 import org.openecomp.sdc.be.model.PropertyDefinition;
95 import org.openecomp.sdc.be.model.RelationshipInfo;
96 import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
97 import org.openecomp.sdc.be.model.RequirementDefinition;
98 import org.openecomp.sdc.be.model.Resource;
99 import org.openecomp.sdc.be.model.Service;
100 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
101 import org.openecomp.sdc.be.model.category.CategoryDefinition;
102 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
103 import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter;
104 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
105 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
106 import org.openecomp.sdc.be.model.operations.impl.ModelOperation;
107 import org.openecomp.sdc.be.tosca.PropertyConvertor.PropertyType;
108 import org.openecomp.sdc.be.tosca.builder.ToscaRelationshipBuilder;
109 import org.openecomp.sdc.be.tosca.exception.ToscaConversionException;
110 import org.openecomp.sdc.be.tosca.model.CapabilityFilter;
111 import org.openecomp.sdc.be.tosca.model.NodeFilter;
112 import org.openecomp.sdc.be.tosca.model.SubstitutionMapping;
113 import org.openecomp.sdc.be.tosca.model.ToscaAttribute;
114 import org.openecomp.sdc.be.tosca.model.ToscaCapability;
115 import org.openecomp.sdc.be.tosca.model.ToscaDataType;
116 import org.openecomp.sdc.be.tosca.model.ToscaGroupTemplate;
117 import org.openecomp.sdc.be.tosca.model.ToscaNodeTemplate;
118 import org.openecomp.sdc.be.tosca.model.ToscaNodeType;
119 import org.openecomp.sdc.be.tosca.model.ToscaPolicyTemplate;
120 import org.openecomp.sdc.be.tosca.model.ToscaProperty;
121 import org.openecomp.sdc.be.tosca.model.ToscaPropertyAssignment;
122 import org.openecomp.sdc.be.tosca.model.ToscaRelationshipTemplate;
123 import org.openecomp.sdc.be.tosca.model.ToscaRequirement;
124 import org.openecomp.sdc.be.tosca.model.ToscaTemplate;
125 import org.openecomp.sdc.be.tosca.model.ToscaTemplateArtifact;
126 import org.openecomp.sdc.be.tosca.model.ToscaTemplateRequirement;
127 import org.openecomp.sdc.be.tosca.model.ToscaTopolgyTemplate;
128 import org.openecomp.sdc.be.tosca.utils.ForwardingPathToscaUtil;
129 import org.openecomp.sdc.be.tosca.utils.InputConverter;
130 import org.openecomp.sdc.be.tosca.utils.OutputConverter;
131 import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
132 import org.openecomp.sdc.common.log.wrappers.Logger;
133 import org.springframework.beans.factory.annotation.Autowired;
134 import org.yaml.snakeyaml.DumperOptions;
135 import org.yaml.snakeyaml.DumperOptions.FlowStyle;
136 import org.yaml.snakeyaml.Yaml;
137 import org.yaml.snakeyaml.introspector.BeanAccess;
138 import org.yaml.snakeyaml.introspector.Property;
139 import org.yaml.snakeyaml.introspector.PropertyUtils;
140 import org.yaml.snakeyaml.nodes.MappingNode;
141 import org.yaml.snakeyaml.nodes.Node;
142 import org.yaml.snakeyaml.nodes.NodeTuple;
143 import org.yaml.snakeyaml.nodes.Tag;
144 import org.yaml.snakeyaml.representer.Represent;
145 import org.yaml.snakeyaml.representer.Representer;
147 @org.springframework.stereotype.Component("tosca-export-handler")
148 public class ToscaExportHandler {
150 public static final String ASSET_TOSCA_TEMPLATE = "assettoscatemplate";
151 private static final Logger log = Logger.getLogger(ToscaExportHandler.class);
152 private static final String INVARIANT_UUID = "invariantUUID";
153 private static final String TOSCA_VERSION = "tosca_simple_yaml_1_3";
154 private static final String SERVICE_NODE_TYPE_PREFIX = "org.openecomp.service.";
155 private static final String IMPORTS_FILE_KEY = "file";
156 private static final String TOSCA_INTERFACE_NAME = "-interface.yml";
157 private static final String FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION = "convertToToscaTemplate - failed to get Default Imports section from configuration";
158 private static final String NOT_SUPPORTED_COMPONENT_TYPE = "Not supported component type {}";
159 private static final String NATIVE_ROOT = "tosca.nodes.Root";
160 private static final List<String> EXCLUDED_CATEGORY_SPECIFIC_METADATA = List
161 .of("Service Function", "Service Role", "Naming Policy", "Service Type");
162 private static final YamlUtil yamlUtil = new YamlUtil();
163 private final ApplicationDataTypeCache applicationDataTypeCache;
164 private final ToscaOperationFacade toscaOperationFacade;
165 private final CapabilityRequirementConverter capabilityRequirementConverter;
166 private final PolicyExportParser policyExportParser;
167 private final GroupExportParser groupExportParser;
168 private final PropertyConvertor propertyConvertor;
169 private final AttributeConverter attributeConverter;
170 private final InputConverter inputConverter;
171 private final OutputConverter outputConverter;
172 private final InterfaceLifecycleOperation interfaceLifecycleOperation;
173 private final InterfacesOperationsConverter interfacesOperationsConverter;
174 private final ModelOperation modelOperation;
177 public ToscaExportHandler(final ApplicationDataTypeCache applicationDataTypeCache,
178 final ToscaOperationFacade toscaOperationFacade,
179 final CapabilityRequirementConverter capabilityRequirementConverter,
180 final PolicyExportParser policyExportParser,
181 final GroupExportParser groupExportParser,
182 final PropertyConvertor propertyConvertor,
183 final AttributeConverter attributeConverter,
184 final InputConverter inputConverter,
185 final OutputConverter outputConverter,
186 final InterfaceLifecycleOperation interfaceLifecycleOperation,
187 final InterfacesOperationsConverter interfacesOperationsConverter,
188 final ModelOperation modelOperation) {
189 this.applicationDataTypeCache = applicationDataTypeCache;
190 this.toscaOperationFacade = toscaOperationFacade;
191 this.capabilityRequirementConverter = capabilityRequirementConverter;
192 this.policyExportParser = policyExportParser;
193 this.groupExportParser = groupExportParser;
194 this.propertyConvertor = propertyConvertor;
195 this.attributeConverter = attributeConverter;
196 this.inputConverter = inputConverter;
197 this.outputConverter = outputConverter;
198 this.interfaceLifecycleOperation = interfaceLifecycleOperation;
199 this.interfacesOperationsConverter = interfacesOperationsConverter;
200 this.modelOperation = modelOperation;
203 public static String getInterfaceFilename(String artifactName) {
204 return artifactName.substring(0, artifactName.lastIndexOf('.')) + TOSCA_INTERFACE_NAME;
207 private static void removeOperationImplementationForProxyNodeType(Map<String, InterfaceDefinition> proxyComponentInterfaces) {
208 if (MapUtils.isEmpty(proxyComponentInterfaces)) {
211 proxyComponentInterfaces.values().stream().map(InterfaceDataDefinition::getOperations).filter(MapUtils::isNotEmpty)
212 .forEach(operations -> operations.values().forEach(operation -> operation.setImplementation(null)));
215 public Either<ToscaRepresentation, ToscaError> exportComponent(Component component) {
216 return convertToToscaTemplate(component).left().map(this::createToscaRepresentation);
219 public Either<ToscaRepresentation, ToscaError> exportComponentInterface(final Component component, final boolean isAssociatedComponent) {
220 final List<Map<String, Map<String, String>>> imports = new ArrayList<>(getDefaultToscaImports(component.getModel()));
221 if (CollectionUtils.isEmpty(imports)) {
222 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
223 return Either.right(ToscaError.GENERAL_ERROR);
225 List<Triple<String, String, Component>> dependencies = new ArrayList<>();
226 if (component.getDerivedFromGenericType() != null && !component.getDerivedFromGenericType()
227 .startsWith("org.openecomp.resource.abstract.nodes.")) {
228 final Either<Component, StorageOperationStatus> baseType = toscaOperationFacade
229 .getByToscaResourceNameAndVersion(component.getDerivedFromGenericType(), component.getDerivedFromGenericVersion(), component.getModel());
230 if (baseType.isLeft() && baseType.left().value() != null) {
231 addDependencies(imports, dependencies, baseType.left().value());
233 log.debug("Failed to fetch derived from type {}", component.getDerivedFromGenericType());
237 String toscaVersion = null;
238 if (component instanceof Resource) {
239 toscaVersion = ((Resource) component).getToscaVersion();
241 ToscaTemplate toscaTemplate = new ToscaTemplate(toscaVersion != null ? toscaVersion : TOSCA_VERSION);
242 toscaTemplate.setImports(imports);
243 final Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
244 final Either<ToscaTemplate, ToscaError> toscaTemplateRes = convertInterfaceNodeType(new HashMap<>(), component, toscaTemplate, nodeTypes,
245 isAssociatedComponent);
246 if (toscaTemplateRes.isRight()) {
247 return Either.right(toscaTemplateRes.right().value());
249 toscaTemplate = toscaTemplateRes.left().value();
250 toscaTemplate.setDependencies(dependencies);
251 ToscaRepresentation toscaRepresentation = this.createToscaRepresentation(toscaTemplate);
252 return Either.left(toscaRepresentation);
255 public ToscaRepresentation createToscaRepresentation(ToscaTemplate toscaTemplate) {
256 CustomRepresenter representer = new CustomRepresenter();
257 DumperOptions options = new DumperOptions();
258 options.setAllowReadOnlyProperties(false);
259 options.setPrettyFlow(true);
260 options.setDefaultFlowStyle(FlowStyle.FLOW);
261 options.setCanonical(false);
262 representer.addClassTag(toscaTemplate.getClass(), Tag.MAP);
263 representer.setPropertyUtils(new UnsortedPropertyUtils());
264 Yaml yaml = new Yaml(representer, options);
265 String yamlAsString = yaml.dumpAsMap(toscaTemplate);
266 StringBuilder sb = new StringBuilder();
267 sb.append(getConfiguration().getHeatEnvArtifactHeader());
268 sb.append(yamlAsString);
269 sb.append(getConfiguration().getHeatEnvArtifactFooter());
270 return ToscaRepresentation.make(sb.toString().getBytes(), toscaTemplate);
273 public Either<ToscaTemplate, ToscaError> getDependencies(Component component) {
274 ToscaTemplate toscaTemplate = new ToscaTemplate(null);
275 Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports = fillImports(component, toscaTemplate);
276 if (fillImports.isRight()) {
277 return Either.right(fillImports.right().value());
279 return Either.left(fillImports.left().value().left);
282 public Either<ToscaTemplate, ToscaError> convertToToscaTemplate(final Component component) {
283 final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImports(component.getModel());
284 if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
285 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
286 return Either.right(ToscaError.GENERAL_ERROR);
288 log.trace("start tosca export for {}", component.getUniqueId());
289 String toscaVersion = null;
290 if (component instanceof Resource) {
291 toscaVersion = ((Resource) component).getToscaVersion();
293 final ToscaTemplate toscaTemplate = new ToscaTemplate(toscaVersion != null ? toscaVersion : TOSCA_VERSION);
294 toscaTemplate.setMetadata(convertMetadata(component));
295 toscaTemplate.setImports(new ArrayList<>(defaultToscaImportConfig));
296 final Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
297 if (ModelConverter.isAtomicComponent(component)) {
298 log.trace("convert component as node type");
299 return convertNodeType(new HashMap<>(), component, toscaTemplate, nodeTypes);
301 log.trace("convert component as topology template");
302 return convertToscaTemplate(component, toscaTemplate);
306 public List<Map<String, Map<String, String>>> getDefaultToscaImports(final String modelId) {
307 if (modelId == null) {
308 return getDefaultToscaImportConfig();
311 final List<ToscaImportByModel> allModelImports = modelOperation.findAllModelImports(modelId, true);
312 final List<Map<String, Map<String, String>>> importList = new ArrayList<>();
313 final Set<Path> addedPathList = new HashSet<>();
314 for (final ToscaImportByModel toscaImportByModel : allModelImports) {
315 var importPath = Path.of(toscaImportByModel.getFullPath());
316 if (addedPathList.contains(importPath)) {
317 importPath = ToscaDefaultImportHelper.addModelAsFilePrefix(importPath, toscaImportByModel.getModelId());
319 final String fileName = FilenameUtils.getBaseName(importPath.toString());
320 importList.add(Map.of(fileName, Map.of("file", importPath.toString())));
321 addedPathList.add(importPath);
326 private Either<ToscaTemplate, ToscaError> convertToscaTemplate(Component component, ToscaTemplate toscaNode) {
327 Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> importsRes = fillImports(component, toscaNode);
328 if (importsRes.isRight()) {
329 return Either.right(importsRes.right().value());
331 toscaNode = importsRes.left().value().left;
332 Map<String, Component> componentCache = importsRes.left().value().right;
333 Either<Map<String, ToscaNodeType>, ToscaError> nodeTypesMapEither = createProxyNodeTypes(componentCache, component);
334 if (nodeTypesMapEither.isRight()) {
335 log.debug("Failed to fetch normative service proxy resource by tosca name, error {}", nodeTypesMapEither.right().value());
336 return Either.right(nodeTypesMapEither.right().value());
338 Map<String, ToscaNodeType> nodeTypesMap = nodeTypesMapEither.left().value();
339 if (nodeTypesMap != null && !nodeTypesMap.isEmpty()) {
340 toscaNode.setNode_types(nodeTypesMap);
342 createServiceSubstitutionNodeTypes(componentCache, component, toscaNode);
343 Either<Map<String, Object>, ToscaError> proxyInterfaceTypesEither = createProxyInterfaceTypes(component);
344 if (proxyInterfaceTypesEither.isRight()) {
345 log.debug("Failed to populate service proxy local interface types in tosca, error {}", nodeTypesMapEither.right().value());
346 return Either.right(proxyInterfaceTypesEither.right().value());
348 Map<String, Object> proxyInterfaceTypes = proxyInterfaceTypesEither.left().value();
349 if (MapUtils.isNotEmpty(proxyInterfaceTypes)) {
350 toscaNode.setInterface_types(proxyInterfaceTypes);
352 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = applicationDataTypeCache.getAll(component.getModel());
353 if (dataTypesEither.isRight()) {
354 log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
355 return Either.right(ToscaError.GENERAL_ERROR);
357 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
358 ToscaTopolgyTemplate topologyTemplate = new ToscaTopolgyTemplate();
359 List<InputDefinition> inputDef = component.getInputs();
360 Map<String, ToscaProperty> inputs = inputConverter.convertInputs(inputDef, dataTypes);
361 if (!inputs.isEmpty()) {
362 topologyTemplate.setInputs(inputs);
364 final Map<String, ToscaProperty> outputs;
366 outputs = outputConverter.convert(component.getOutputs(), dataTypes);
367 } catch (final ToscaConversionException e) {
368 log.error(EcompLoggerErrorCode.SCHEMA_ERROR, ToscaExportHandler.class.getName(),
369 "Could not parse component '{}' outputs. Component unique id '{}'.", component.getName(), component.getUniqueId(), e);
370 return Either.right(ToscaError.GENERAL_ERROR);
372 if (!outputs.isEmpty()) {
373 topologyTemplate.setOutputs(outputs);
375 if (CollectionUtils.isNotEmpty(component.getComponentInstances())) {
376 final Either<Map<String, ToscaNodeTemplate>, ToscaError> nodeTemplates =
377 convertNodeTemplates(component, componentCache, dataTypes, topologyTemplate);
378 if (nodeTemplates.isRight()) {
379 return Either.right(nodeTemplates.right().value());
381 log.debug("node templates converted");
382 topologyTemplate.setNode_templates(nodeTemplates.left().value());
384 final Map<String, ToscaRelationshipTemplate> relationshipTemplatesMap = new ToscaExportRelationshipTemplatesHandler()
385 .createFrom(topologyTemplate.getNode_templates());
386 if (!relationshipTemplatesMap.isEmpty()) {
387 topologyTemplate.setRelationshipTemplates(relationshipTemplatesMap);
389 addGroupsToTopologyTemplate(component, topologyTemplate);
391 addPoliciesToTopologyTemplate(component, topologyTemplate);
392 } catch (SdcResourceNotFoundException e) {
393 log.debug("Fail to add policies to topology template:", e);
394 return Either.right(ToscaError.GENERAL_ERROR);
397 createSubstitutionMapping(component, componentCache).ifPresent(topologyTemplate::setSubstitution_mappings);
398 } catch (final ToscaExportException e) {
399 log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, ToscaExportHandler.class.getName(), e.getMessage());
400 return Either.right(e.getToscaError());
402 if (!topologyTemplate.isEmpty()) {
403 toscaNode.setTopology_template(topologyTemplate);
405 return Either.left(toscaNode);
408 private Either<String, ToscaError> createComponentToscaName(final Component component) {
409 switch (component.getComponentType()) {
411 final ResourceMetadataDataDefinition resourceMetadata =
412 (ResourceMetadataDataDefinition) component.getComponentMetadataDefinition().getMetadataDataDefinition();
413 return Either.left(resourceMetadata.getToscaResourceName());
415 return Either.left(SERVICE_NODE_TYPE_PREFIX + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName());
417 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
418 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
422 private Optional<SubstitutionMapping> createSubstitutionMapping(final Component component,
423 final Map<String, Component> componentCache) throws ToscaExportException {
424 if (component instanceof Service && !((Service) component).isSubstituteCandidate()) {
425 return Optional.empty();
428 final Either<String, ToscaError> toscaResourceNameEither = createComponentToscaName(component);
429 if (toscaResourceNameEither.isRight()) {
430 throw new ToscaExportException("Could not create component TOSCA name", toscaResourceNameEither.right().value());
432 final String toscaResourceName = toscaResourceNameEither.left().value();
434 final SubstitutionMapping substitutionMapping = new SubstitutionMapping();
435 substitutionMapping.setNode_type(toscaResourceName);
436 convertSubstitutionMappingFilter(component).ifPresent(substitutionMapping::setSubstitution_filter);
438 final Either<Map<String, String[]>, ToscaError> capabilitiesEither = convertSubstitutionMappingCapabilities(component, componentCache);
439 if (capabilitiesEither.isRight()) {
440 throw new ToscaExportException("Could not convert substitution mapping capabilities", capabilitiesEither.right().value());
442 final Map<String, String[]> capabilityMap = capabilitiesEither.left().value();
443 if (!capabilityMap.isEmpty()) {
444 substitutionMapping.setCapabilities(capabilityMap);
447 final Either<Map<String, String[]>, ToscaError> requirements =
448 capabilityRequirementConverter.convertSubstitutionMappingRequirements(component, componentCache);
449 if (requirements.isRight()) {
450 throw new ToscaExportException("Could not convert substitution mapping requirements", requirements.right().value());
452 final Map<String, String[]> requirementMap = requirements.left().value();
453 if (!requirementMap.isEmpty()) {
454 substitutionMapping.setRequirements(requirementMap);
457 final Map<String, String[]> propertyMappingMap = buildSubstitutionMappingPropertyMapping(component);
458 if (!propertyMappingMap.isEmpty()) {
459 substitutionMapping.setProperties(propertyMappingMap);
462 final Map<String, String[]> attributesMappingMap = buildSubstitutionMappingAttributesMapping(component);
463 if (!attributesMappingMap.isEmpty()) {
464 substitutionMapping.setAttributes(attributesMappingMap);
467 return Optional.of(substitutionMapping);
470 private Optional<NodeFilter> convertSubstitutionMappingFilter(final Component component) {
471 if (component.getSubstitutionFilter() == null || (component.getSubstitutionFilter().getProperties()).getListToscaDataDefinition() == null) {
472 return Optional.empty();
475 return Optional.ofNullable(convertToSubstitutionFilterComponent(component.getSubstitutionFilter()));
478 private void addGroupsToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate) {
479 Map<String, ToscaGroupTemplate> groups = groupExportParser.getGroups(component);
480 if (groups != null) {
481 topologyTemplate.addGroups(groups);
485 private void addPoliciesToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate) throws SdcResourceNotFoundException {
486 Map<String, ToscaPolicyTemplate> policies = policyExportParser.getPolicies(component);
487 if (policies != null) {
488 topologyTemplate.addPolicies(policies);
492 private Map<String, String> convertMetadata(Component component) {
493 return convertMetadata(component, false, null);
496 private Map<String, String> convertMetadata(Component component, boolean isInstance, ComponentInstance componentInstance) {
497 Map<String, String> toscaMetadata = new LinkedHashMap<>();
498 toscaMetadata.put(convertMetadataKey(JsonPresentationFields.INVARIANT_UUID), component.getInvariantUUID());
499 toscaMetadata.put(JsonPresentationFields.UUID.getPresentation(), component.getUUID());
501 .put(JsonPresentationFields.NAME.getPresentation(), component.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
502 toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), component.getDescription());
503 List<CategoryDefinition> categories = component.getCategories();
504 CategoryDefinition categoryDefinition = categories.get(0);
505 toscaMetadata.put(JsonPresentationFields.CATEGORY.getPresentation(), categoryDefinition.getName());
507 toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), component.getVersion());
508 toscaMetadata.put(JsonPresentationFields.CUSTOMIZATION_UUID.getPresentation(), componentInstance.getCustomizationUUID());
509 if (componentInstance.getSourceModelInvariant() != null && !componentInstance.getSourceModelInvariant().isEmpty()) {
510 toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), componentInstance.getComponentVersion());
511 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_INVARIANT.getPresentation(), componentInstance.getSourceModelInvariant());
512 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_UUID.getPresentation(), componentInstance.getSourceModelUuid());
513 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_NAME.getPresentation(), componentInstance.getSourceModelName());
514 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
515 toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(),
516 componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceProxy.getDisplayValue());
517 } else if (componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
518 toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(),
519 componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceSubstitution.getDisplayValue());
521 toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), componentInstance.getDescription());
524 switch (component.getComponentType()) {
526 Resource resource = (Resource) component;
527 if (isInstance && (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy
528 || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution)) {
529 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), componentInstance.getOriginType().getDisplayValue());
531 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), resource.getResourceType().name());
533 toscaMetadata.put(JsonPresentationFields.SUB_CATEGORY.getPresentation(), categoryDefinition.getSubcategories().get(0).getName());
534 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR.getPresentation(), resource.getVendorName());
535 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_RELEASE.getPresentation(), resource.getVendorRelease());
536 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_MODEL_NUMBER.getPresentation(), resource.getResourceVendorModelNumber());
539 Service service = (Service) component;
540 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), component.getComponentType().getValue());
541 toscaMetadata.put(JsonPresentationFields.SERVICE_TYPE.getPresentation(), service.getServiceType());
542 toscaMetadata.put(JsonPresentationFields.SERVICE_ROLE.getPresentation(), service.getServiceRole());
543 toscaMetadata.put(JsonPresentationFields.SERVICE_FUNCTION.getPresentation(), service.getServiceFunction());
544 toscaMetadata.put(JsonPresentationFields.ENVIRONMENT_CONTEXT.getPresentation(), service.getEnvironmentContext());
545 toscaMetadata.put(JsonPresentationFields.INSTANTIATION_TYPE.getPresentation(),
546 service.getEnvironmentContext() == null ? StringUtils.EMPTY : service.getInstantiationType());
549 toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming().toString());
550 toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming().toString());
551 toscaMetadata.put(JsonPresentationFields.NAMING_POLICY.getPresentation(), service.getNamingPolicy());
555 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
557 for (final String key : component.getCategorySpecificMetadata().keySet()) {
558 if (!EXCLUDED_CATEGORY_SPECIFIC_METADATA.contains(key)) {
559 toscaMetadata.put(key, component.getCategorySpecificMetadata().get(key));
562 return toscaMetadata;
565 private String convertMetadataKey(JsonPresentationFields jsonPresentationField) {
566 if (JsonPresentationFields.INVARIANT_UUID.equals(jsonPresentationField)) {
567 return INVARIANT_UUID;
569 return jsonPresentationField.getPresentation();
572 private Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports(Component component, ToscaTemplate toscaTemplate) {
573 final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImports(component.getModel());
574 if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
575 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
576 return Either.right(ToscaError.GENERAL_ERROR);
578 Map<String, Component> componentCache = new HashMap<>();
579 if (!ModelConverter.isAtomicComponent(component)) {
580 final List<Map<String, Map<String, String>>> additionalImports =
581 toscaTemplate.getImports() == null ? new ArrayList<>(defaultToscaImportConfig) : new ArrayList<>(toscaTemplate.getImports());
582 List<Triple<String, String, Component>> dependencies = new ArrayList<>();
583 Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
584 final Map<String, Map<String, String>> substituteTypeImportEntry = generateComponentSubstituteTypeImport(component, toscaArtifacts);
585 if (!substituteTypeImportEntry.isEmpty()) {
586 additionalImports.add(substituteTypeImportEntry);
588 List<ComponentInstance> componentInstances = component.getComponentInstances();
589 if (componentInstances != null && !componentInstances.isEmpty()) {
590 componentInstances.forEach(ci -> createDependency(componentCache, additionalImports, dependencies, ci));
592 toscaTemplate.setDependencies(dependencies);
593 toscaTemplate.setImports(additionalImports);
595 log.debug("currently imports supported for VF and service only");
597 return Either.left(new ImmutablePair<>(toscaTemplate, componentCache));
600 private Map<String, Map<String, String>> generateComponentSubstituteTypeImport(final Component component,
601 final Map<String, ArtifactDefinition> toscaArtifacts) {
603 if (component instanceof Service && !((Service) component).isSubstituteCandidate()) {
604 return Collections.emptyMap();
606 if (MapUtils.isEmpty(toscaArtifacts)) {
607 return Collections.emptyMap();
609 final ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE);
610 if (artifactDefinition == null) {
611 return Collections.emptyMap();
613 final var importEntryName = component.getComponentType().toString().toLowerCase() + "-" + component.getName() + "-interface";
614 return Map.of(importEntryName,
615 Map.of(IMPORTS_FILE_KEY, getInterfaceFilename(artifactDefinition.getArtifactName()))
619 private List<Map<String, Map<String, String>>> getDefaultToscaImportConfig() {
620 return getConfiguration().getDefaultImports();
623 private void createDependency(final Map<String, Component> componentCache, final List<Map<String, Map<String, String>>> imports,
624 final List<Triple<String, String, Component>> dependencies, final ComponentInstance componentInstance) {
625 log.debug("createDependency componentCache {}", componentCache);
626 Component componentRI = componentCache.get(componentInstance.getComponentUid());
627 if (componentRI == null || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
628 // all resource must be only once!
629 final Either<Component, StorageOperationStatus> resource = toscaOperationFacade.getToscaFullElement(componentInstance.getComponentUid());
630 if ((resource.isRight()) && (log.isDebugEnabled())) {
631 log.debug("Failed to fetch resource with id {} for instance {}", componentInstance.getComponentUid(),
632 componentInstance.getUniqueId());
635 final Component fetchedComponent = resource.left().value();
636 componentRI = setComponentCache(componentCache, componentInstance, fetchedComponent);
637 addDependencies(imports, dependencies, componentRI);
642 * Sets a componentCache from the given component/resource.
644 private Component setComponentCache(final Map<String, Component> componentCache, final ComponentInstance componentInstance,
645 final Component fetchedComponent) {
646 componentCache.put(fetchedComponent.getUniqueId(), fetchedComponent);
647 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy
648 || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
649 final Either<Component, StorageOperationStatus> sourceService = toscaOperationFacade
650 .getToscaFullElement(componentInstance.getSourceModelUid());
651 if (sourceService.isRight() && (log.isDebugEnabled())) {
652 log.debug("Failed to fetch source service with id {} for proxy {}", componentInstance.getSourceModelUid(),
653 componentInstance.getUniqueId());
655 final Component fetchedSource = sourceService.left().value();
656 componentCache.put(fetchedSource.getUniqueId(), fetchedSource);
657 return fetchedSource;
659 return fetchedComponent;
663 * Retrieves all derived_from nodes and stores it in a predictable order.
665 private void addDependencies(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
666 final Component fetchedComponent) {
667 final Set<Component> componentsList = new LinkedHashSet<>();
668 if (fetchedComponent instanceof Resource) {
669 log.debug("fetchedComponent is a resource {}", fetchedComponent);
670 final Optional<Map<String, String>> derivedFromMapOfIdToName = getDerivedFromMapOfIdToName(fetchedComponent, componentsList);
671 if (derivedFromMapOfIdToName.isPresent() && !derivedFromMapOfIdToName.get().isEmpty()) {
672 derivedFromMapOfIdToName.get().entrySet().forEach(entry -> {
673 log.debug("Started entry.getValue() : {}", entry.getValue());
674 if (!NATIVE_ROOT.equals(entry.getValue())) {
675 Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade.getToscaElement(entry.getKey());
676 if (resourcefetched != null && resourcefetched.isLeft()) {
677 componentsList.add(resourcefetched.left().value());
681 setImports(imports, dependencies, componentsList);
683 setImports(imports, dependencies, fetchedComponent);
689 * Returns all derived_from nodes found.
691 private Optional<Map<String, String>> getDerivedFromMapOfIdToName(final Component fetchedComponent, final Set<Component> componentsList) {
692 final Resource parentResource = (Resource) fetchedComponent;
693 Map<String, String> derivedFromMapOfIdToName = new HashMap<>();
694 if (CollectionUtils.isNotEmpty(parentResource.getComponentInstances())) {
695 componentsList.add(fetchedComponent);
696 for (final ComponentInstance componentInstance : parentResource.getComponentInstances()) {
697 final Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade
698 .getToscaElement(componentInstance.getComponentUid());
699 if (resourcefetched != null && resourcefetched.isLeft()) {
700 final Map<String, String> derivedWithId = resourcefetched.left().value().getDerivedFromMapOfIdToName();
701 if (MapUtils.isNotEmpty(derivedWithId)) {
702 derivedFromMapOfIdToName.putAll(derivedWithId);
707 derivedFromMapOfIdToName = parentResource.getDerivedFromMapOfIdToName();
709 log.debug("Started derivedFromMapOfIdToName: {}", derivedFromMapOfIdToName);
710 return Optional.ofNullable(derivedFromMapOfIdToName);
714 * Creates a resource map and adds it to the import list.
716 private void setImports(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
717 final Set<Component> componentsList) {
718 componentsList.forEach(component -> setImports(imports, dependencies, component));
721 private void setImports(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
722 final Component component) {
723 final Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
724 final ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE);
725 if (artifactDefinition != null) {
726 final Map<String, String> files = new HashMap<>();
727 final String artifactName = artifactDefinition.getArtifactName();
728 files.put(IMPORTS_FILE_KEY, artifactName);
729 final StringBuilder keyNameBuilder = new StringBuilder();
730 keyNameBuilder.append(component.getComponentType().toString().toLowerCase());
731 keyNameBuilder.append("-");
732 keyNameBuilder.append(component.getName());
733 addImports(imports, keyNameBuilder, files);
734 dependencies.add(new ImmutableTriple<>(artifactName, artifactDefinition.getEsId(), component));
735 if (!ModelConverter.isAtomicComponent(component)) {
736 final Map<String, String> interfaceFiles = new HashMap<>();
737 interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactName));
738 keyNameBuilder.append("-interface");
739 addImports(imports, keyNameBuilder, interfaceFiles);
745 * Adds the found resource to the import definition list.
747 private void addImports(final List<Map<String, Map<String, String>>> imports, final StringBuilder keyNameBuilder,
748 final Map<String, String> files) {
749 final String mapKey = keyNameBuilder.toString();
750 if (imports.stream().allMatch(stringMapMap -> stringMapMap.get(mapKey) == null)) {
751 final Map<String, Map<String, String>> importsListMember = new HashMap<>();
752 importsListMember.put(keyNameBuilder.toString(), files);
753 imports.add(importsListMember);
757 private Either<ToscaTemplate, ToscaError> convertNodeType(Map<String, Component> componentsCache, Component component, ToscaTemplate toscaNode,
758 Map<String, ToscaNodeType> nodeTypes) {
759 return convertInterfaceNodeType(componentsCache, component, toscaNode, nodeTypes, false);
762 public Either<ToscaTemplate, ToscaError> convertInterfaceNodeType(Map<String, Component> componentsCache, Component component,
763 ToscaTemplate toscaNode, Map<String, ToscaNodeType> nodeTypes,
764 boolean isAssociatedComponent) {
765 log.debug("start convert node type for {}", component.getUniqueId());
766 ToscaNodeType toscaNodeType = createNodeType(component);
767 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither = interfaceLifecycleOperation
768 .getAllInterfaceLifecycleTypes(component.getModel());
769 if (lifecycleTypeEither.isRight() && !StorageOperationStatus.NOT_FOUND.equals(lifecycleTypeEither.right().value())) {
770 log.debug("Failed to fetch all interface types :", lifecycleTypeEither.right().value());
771 return Either.right(ToscaError.GENERAL_ERROR);
773 if (lifecycleTypeEither.isLeft()) {
774 List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value().values().stream().map(InterfaceDataDefinition::getType)
775 .collect(Collectors.toList());
776 toscaNode.setInterface_types(addInterfaceTypeElement(component, allGlobalInterfaceTypes));
778 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = applicationDataTypeCache.getAll(component.getModel());
779 if (dataTypesEither.isRight()) {
780 log.debug("Failed to fetch all data types :", dataTypesEither.right().value());
781 return Either.right(ToscaError.GENERAL_ERROR);
783 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
784 List<InputDefinition> inputDef = component.getInputs();
785 Map<String, ToscaProperty> mergedProperties = new HashMap<>();
786 interfacesOperationsConverter.addInterfaceDefinitionElement(component, toscaNodeType, dataTypes, isAssociatedComponent);
787 addInputsToProperties(dataTypes, inputDef, mergedProperties);
788 final Map<String, ToscaAttribute> toscaAttributeMap;
789 toscaAttributeMap = convertToToscaAttributes(component.getAttributes(), dataTypes);
790 if (!toscaAttributeMap.isEmpty()) {
791 toscaNodeType.setAttributes(toscaAttributeMap);
793 if (CollectionUtils.isNotEmpty(component.getProperties())) {
794 List<PropertyDefinition> properties = component.getProperties();
795 Map<String, ToscaProperty> convertedProperties = properties.stream()
796 .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, component.getInputs())).collect(Collectors
797 .toMap(PropertyDataDefinition::getName,
798 property -> propertyConvertor.convertProperty(dataTypes, property, PropertyConvertor.PropertyType.PROPERTY)));
799 // merge component properties and inputs properties
800 mergedProperties.putAll(convertedProperties);
802 if (MapUtils.isNotEmpty(mergedProperties)) {
803 toscaNodeType.setProperties(mergedProperties);
805 /* convert private data_types */
806 List<DataTypeDefinition> privateDataTypes = component.getDataTypes();
807 if (CollectionUtils.isNotEmpty(privateDataTypes)) {
808 Map<String, ToscaDataType> toscaDataTypeMap = new HashMap<>();
809 for (DataTypeDefinition dataType : privateDataTypes) {
810 log.debug("Emitting private data type: component.name={} dataType.name={}",
811 component.getNormalizedName(), dataType.getName());
812 ToscaDataType toscaDataType = new ToscaDataType();
813 toscaDataType.setDerived_from(dataType.getDerivedFromName());
814 toscaDataType.setDescription(dataType.getDescription());
815 toscaDataType.setVersion(dataType.getVersion());
816 if (CollectionUtils.isNotEmpty(dataType.getProperties())) {
817 toscaDataType.setProperties(dataType.getProperties().stream()
818 .collect(Collectors.toMap(
819 PropertyDataDefinition::getName,
820 s -> propertyConvertor.convertProperty(dataTypes, s, PropertyType.PROPERTY),
821 (toscaPropertyTobeValidated, toscaProperty) -> validateToscaProperty(privateDataTypes, toscaPropertyTobeValidated, toscaProperty)
824 toscaDataTypeMap.put(dataType.getName(), toscaDataType);
826 toscaNode.setData_types(toscaDataTypeMap);
829 // Extracted to method for code reuse
830 return convertReqCapAndTypeName(componentsCache, component, toscaNode, nodeTypes, toscaNodeType, dataTypes);
833 private ToscaProperty validateToscaProperty(final List<DataTypeDefinition> privateDataTypes, final ToscaProperty toscaPropertyTobeValidated,
834 final ToscaProperty toscaProperty) {
835 final Optional<DataTypeDefinition> match = privateDataTypes.stream()
836 .filter(dataType -> dataType.getName().equals(toscaPropertyTobeValidated.getType())).findFirst();
837 return match.isPresent() ? toscaPropertyTobeValidated : toscaProperty;
840 private Map<String, ToscaAttribute> convertToToscaAttributes(final List<AttributeDefinition> attributeList,
841 final Map<String, DataTypeDefinition> dataTypes) {
842 if (CollectionUtils.isEmpty(attributeList)) {
843 return Collections.emptyMap();
845 final AttributeConverter converter = new AttributeConverter(dataTypes);
846 final Map<String, ToscaAttribute> toscaAttributeMap = new HashMap<>();
847 for (final AttributeDefinition attributeDefinition : attributeList) {
848 toscaAttributeMap.put(attributeDefinition.getName(), converter.convert(attributeDefinition));
850 return toscaAttributeMap;
853 private Either<ToscaTemplate, ToscaError> convertReqCapAndTypeName(Map<String, Component> componentsCache,
854 Component component, ToscaTemplate toscaNode,
855 Map<String, ToscaNodeType> nodeTypes,
856 ToscaNodeType toscaNodeType,
857 Map<String, DataTypeDefinition> dataTypes) {
858 Either<ToscaNodeType, ToscaError> capabilities = convertCapabilities(componentsCache, component, toscaNodeType,
860 if (capabilities.isRight()) {
861 return Either.right(capabilities.right().value());
863 toscaNodeType = capabilities.left().value();
864 log.debug("Capabilities converted for {}", component.getUniqueId());
866 Either<ToscaNodeType, ToscaError> requirements = capabilityRequirementConverter
867 .convertRequirements(componentsCache, component, toscaNodeType);
868 if (requirements.isRight()) {
869 return Either.right(requirements.right().value());
871 toscaNodeType = requirements.left().value();
872 log.debug("Requirements converted for {}", component.getUniqueId());
874 String toscaResourceName;
875 switch (component.getComponentType()) {
877 toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition()
878 .getMetadataDataDefinition()).getToscaResourceName();
881 toscaResourceName = SERVICE_NODE_TYPE_PREFIX
882 + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName();
885 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
886 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
889 nodeTypes.put(toscaResourceName, toscaNodeType);
890 toscaNode.setNode_types(nodeTypes);
891 log.debug("finish convert node type for {}", component.getUniqueId());
892 return Either.left(toscaNode);
895 private Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplates(final Component component,
896 final Map<String, Component> componentCache,
897 final Map<String, DataTypeDefinition> dataTypes,
898 final ToscaTopolgyTemplate topologyTemplate) {
900 final Map<String, List<ComponentInstanceProperty>> componentInstancesProperties = component.getComponentInstancesProperties();
901 final Map<String, List<ComponentInstanceAttribute>> componentInstancesAttributes = component.getComponentInstancesAttributes();
902 final Map<String, List<ComponentInstanceInput>> componentInstancesInputs = component.getComponentInstancesInputs();
903 final Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces = component.getComponentInstancesInterfaces();
904 final List<RequirementCapabilityRelDef> componentInstancesRelations = component.getComponentInstancesRelations();
906 Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplatesRes = null;
907 log.debug("start convert topology template for {} for type {}", component.getUniqueId(), component.getComponentType());
908 final Map<String, ToscaNodeTemplate> nodeTemplates = new HashMap<>();
910 Map<String, ToscaGroupTemplate> groupsMap = null;
911 for (final ComponentInstance componentInstance : component.getComponentInstances()) {
912 ToscaNodeTemplate nodeTemplate = new ToscaNodeTemplate();
913 if (MapUtils.isNotEmpty(componentInstance.getToscaArtifacts())) {
914 nodeTemplate.setArtifacts(convertToNodeTemplateArtifacts(componentInstance.getToscaArtifacts()));
916 if (componentInstance.getMinOccurrences() != null && componentInstance.getMaxOccurrences()!= null){
917 List<Object> occur = new ArrayList<Object>();
918 occur.add(parseToIntIfPossible(componentInstance.getMinOccurrences()));
919 occur.add(parseToIntIfPossible(componentInstance.getMaxOccurrences()));
920 nodeTemplate.setOccurrences(occur);
922 nodeTemplate.setType(componentInstance.getToscaComponentName());
923 nodeTemplate.setDirectives(componentInstance.getDirectives());
924 nodeTemplate.setNode_filter(convertToNodeTemplateNodeFilterComponent(componentInstance.getNodeFilter()));
926 final Either<Component, Boolean> originComponentRes = capabilityRequirementConverter
927 .getOriginComponent(componentCache, componentInstance);
928 if (originComponentRes.isRight()) {
929 convertNodeTemplatesRes = Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
932 final Either<ToscaNodeTemplate, ToscaError> requirements = convertComponentInstanceRequirements(component, componentInstance,
933 componentInstancesRelations, nodeTemplate, originComponentRes.left().value(), componentCache);
934 if (requirements.isRight()) {
935 convertNodeTemplatesRes = Either.right(requirements.right().value());
938 final String instanceUniqueId = componentInstance.getUniqueId();
939 log.debug("Component instance Requirements converted for instance {}", instanceUniqueId);
941 nodeTemplate = requirements.left().value();
943 final Component originalComponent = componentCache.get(componentInstance.getActualComponentUid());
945 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
946 final Component componentOfProxy = componentCache.get(componentInstance.getComponentUid());
947 nodeTemplate.setMetadata(convertMetadata(componentOfProxy, true, componentInstance));
949 nodeTemplate.setMetadata(convertMetadata(originalComponent, true, componentInstance));
952 final Either<ToscaNodeTemplate, ToscaError> capabilities =
953 capabilityRequirementConverter.convertComponentInstanceCapabilities(componentInstance, dataTypes, nodeTemplate);
954 if (capabilities.isRight()) {
955 convertNodeTemplatesRes = Either.right(capabilities.right().value());
958 log.debug("Component instance Capabilities converted for instance {}", instanceUniqueId);
960 nodeTemplate = capabilities.left().value();
961 final Map<String, Object> props = new HashMap<>();
962 final Map<String, Object> attribs = new HashMap<>();
964 if (originalComponent.getComponentType() == ComponentTypeEnum.RESOURCE) {
965 // Adds the properties of parent component to map
966 addPropertiesOfParentComponent(dataTypes, originalComponent, props);
967 addAttributesOfParentComponent(originalComponent, attribs);
970 if (null != componentInstancesProperties && componentInstancesProperties.containsKey(instanceUniqueId)) {
971 addPropertiesOfComponentInstance(componentInstancesProperties, dataTypes, instanceUniqueId, props);
973 if (null != componentInstancesAttributes && componentInstancesAttributes.containsKey(instanceUniqueId)) {
974 addAttributesOfComponentInstance(componentInstancesAttributes, instanceUniqueId, attribs);
977 if (componentInstancesInputs != null
978 && componentInstancesInputs.containsKey(instanceUniqueId)
979 && !isComponentOfTypeServiceProxy(componentInstance)) {
980 //For service proxy the inputs are already handled under instance properties above
981 addComponentInstanceInputs(dataTypes, componentInstancesInputs, instanceUniqueId, props);
984 //M3[00001] - NODE TEMPLATE INTERFACES - START
985 handleInstanceInterfaces(componentInstanceInterfaces, componentInstance, dataTypes, nodeTemplate, instanceUniqueId, component);
986 //M3[00001] - NODE TEMPLATE INTERFACES - END
987 if (MapUtils.isNotEmpty(props)) {
988 nodeTemplate.setProperties(props);
990 if (MapUtils.isNotEmpty(attribs)) {
991 nodeTemplate.setAttributes(attribs);
994 final List<GroupInstance> groupInstances = componentInstance.getGroupInstances();
995 if (CollectionUtils.isNotEmpty(groupInstances)) {
996 if (groupsMap == null) {
997 groupsMap = new HashMap<>();
999 for (final GroupInstance groupInst : groupInstances) {
1000 if (CollectionUtils.isNotEmpty(groupInst.getArtifacts())) {
1001 groupsMap.put(groupInst.getName(), groupExportParser.getToscaGroupTemplate(groupInst, componentInstance.getInvariantName()));
1006 nodeTemplates.put(componentInstance.getName(), nodeTemplate);
1008 if (groupsMap != null) {
1009 log.debug("instance groups added");
1010 topologyTemplate.addGroups(groupsMap);
1012 if (component.getComponentType() == ComponentTypeEnum.SERVICE && isNotEmpty(
1013 ((Service) component).getForwardingPaths())) {
1014 log.debug("Starting converting paths for component {}, name {}", component.getUniqueId(), component.getName());
1015 ForwardingPathToscaUtil
1016 .addForwardingPaths((Service) component, nodeTemplates, capabilityRequirementConverter, componentCache, toscaOperationFacade);
1017 log.debug("Finished converting paths for component {}, name {}", component.getUniqueId(), component.getName());
1019 if (convertNodeTemplatesRes == null) {
1020 convertNodeTemplatesRes = Either.left(nodeTemplates);
1022 log.debug("finish convert topology template for {} for type {}", component.getUniqueId(), component.getComponentType());
1023 return convertNodeTemplatesRes;
1026 private Object parseToIntIfPossible(final String value) {
1027 final Integer intValue = Ints.tryParse(value);
1028 return intValue == null ? value : intValue;
1031 private void handleInstanceInterfaces(
1032 Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces,
1033 ComponentInstance componentInstance, Map<String, DataTypeDefinition> dataTypes, ToscaNodeTemplate nodeTemplate,
1034 String instanceUniqueId,
1035 Component parentComponent) {
1037 if (MapUtils.isEmpty(componentInstanceInterfaces)
1038 || !componentInstanceInterfaces.containsKey(instanceUniqueId)) {
1039 nodeTemplate.setInterfaces(null);
1043 final List<ComponentInstanceInterface> currServiceInterfaces =
1044 componentInstanceInterfaces.get(instanceUniqueId);
1046 final Map<String, InterfaceDefinition> tmpInterfaces = new HashMap<>();
1047 currServiceInterfaces.forEach(instInterface -> tmpInterfaces.put(instInterface
1048 .getUniqueId(), instInterface));
1050 final Map<String, Object> interfaceMap = interfacesOperationsConverter
1051 .getInterfacesMap(parentComponent, componentInstance, tmpInterfaces, dataTypes, isComponentOfTypeServiceProxy(componentInstance),
1052 isComponentOfTypeServiceProxy(componentInstance));
1054 interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
1055 nodeTemplate.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap);
1058 private boolean isComponentOfTypeServiceProxy(ComponentInstance componentInstance) {
1059 return Objects.nonNull(componentInstance.getOriginType())
1060 && componentInstance.getOriginType().getValue().equals("Service Proxy");
1063 private void addComponentInstanceInputs(Map<String, DataTypeDefinition> dataTypes,
1064 Map<String, List<ComponentInstanceInput>> componentInstancesInputs,
1065 String instanceUniqueId, Map<String, Object> props) {
1067 List<ComponentInstanceInput> instanceInputsList = componentInstancesInputs.get(instanceUniqueId);
1068 if (instanceInputsList != null) {
1069 instanceInputsList.forEach(input -> {
1070 Supplier<String> supplier = () -> input.getValue() != null && !Objects.isNull(input.getValue()) ? input.getValue() : input.getDefaultValue();
1071 propertyConvertor.convertAndAddValue(dataTypes, props, input, supplier);
1076 private void addPropertiesOfComponentInstance(final Map<String, List<ComponentInstanceProperty>> componentInstancesProperties,
1077 final Map<String, DataTypeDefinition> dataTypes,
1078 final String instanceUniqueId,
1079 final Map<String, Object> props) {
1081 if (isNotEmpty(componentInstancesProperties)) {
1082 componentInstancesProperties.get(instanceUniqueId)
1083 // Converts and adds each value to property map
1084 .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop, prop::getValue));
1088 private void addAttributesOfComponentInstance(final Map<String, List<ComponentInstanceAttribute>> componentInstancesAttributes,
1089 final String instanceUniqueId,
1090 final Map<String, Object> attribs) {
1092 if (isNotEmpty(componentInstancesAttributes) && componentInstancesAttributes.containsKey(instanceUniqueId)) {
1093 componentInstancesAttributes.get(instanceUniqueId).stream()
1094 // Filters out Attributes with empty default values
1095 .filter(attributeDefinition -> StringUtils.isNotEmpty(attributeDefinition.getDefaultValue()))
1096 // Converts and adds each value to attribute map
1097 .forEach(attributeDefinition -> attributeConverter.convertAndAddValue(attribs, attributeDefinition));
1101 private void addPropertiesOfParentComponent(Map<String, DataTypeDefinition> dataTypes,
1102 Component componentOfInstance, Map<String, Object> props) {
1104 List<PropertyDefinition> componentProperties = componentOfInstance.getProperties();
1105 if (isNotEmpty(componentProperties)) {
1106 componentProperties.stream()
1107 // Filters out properties with empty default values
1108 .filter(prop -> StringUtils.isNotEmpty(prop.getDefaultValue()))
1109 // Converts and adds each value to property map
1110 .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop, prop::getDefaultValue));
1114 private void addAttributesOfParentComponent(final Component componentOfInstance, final Map<String, Object> attribs) {
1116 final List<AttributeDefinition> componentAttributes = componentOfInstance.getAttributes();
1117 if (isNotEmpty(componentAttributes)) {
1118 componentAttributes.stream()
1119 // Filters out Attributes with empty default values
1120 .filter(attrib -> StringUtils.isNotEmpty(attrib.getDefaultValue()))
1121 // Converts and adds each value to attribute map
1122 .forEach(attributeDefinition -> attributeConverter.convertAndAddValue(attribs, attributeDefinition));
1126 private ToscaNodeType createNodeType(Component component) {
1127 ToscaNodeType toscaNodeType = new ToscaNodeType();
1128 if (ModelConverter.isAtomicComponent(component)) {
1129 if (((Resource) component).getDerivedFrom() != null) {
1130 toscaNodeType.setDerived_from(((Resource) component).getDerivedFrom().get(0));
1132 toscaNodeType.setDescription(component.getDescription());
1134 String derivedFrom = null != component.getDerivedFromGenericType() ? component.getDerivedFromGenericType()
1136 toscaNodeType.setDerived_from(derivedFrom);
1138 return toscaNodeType;
1141 private Either<Map<String, Object>, ToscaError> createProxyInterfaceTypes(Component container) {
1143 Map<String, Object> proxyInterfaceTypes = new HashMap<>();
1144 Either<Map<String, Object>, ToscaError> res = Either.left(proxyInterfaceTypes);
1145 List<ComponentInstance> componentInstances = container.getComponentInstances();
1146 if (CollectionUtils.isEmpty(componentInstances)) {
1149 Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
1150 componentInstances.stream()
1151 .filter(this::isComponentOfTypeServiceProxy)
1152 .forEach(inst -> serviceProxyInstanceList.put(inst.getToscaComponentName(), inst));
1153 if (MapUtils.isEmpty(serviceProxyInstanceList)) {
1156 for (Entry<String, ComponentInstance> entryProxy : serviceProxyInstanceList.entrySet()) {
1157 Component serviceComponent;
1158 ComponentParametersView componentParametersView = new ComponentParametersView();
1159 componentParametersView.disableAll();
1160 componentParametersView.setIgnoreInterfaces(false);
1161 Either<Component, StorageOperationStatus> service = toscaOperationFacade
1162 .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
1163 if (service.isRight()) {
1164 log.debug("Failed to fetch original service component with id {} for instance {}",
1165 entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName());
1166 return Either.right(ToscaError.GENERAL_ERROR);
1168 serviceComponent = service.left().value();
1171 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither =
1172 interfaceLifecycleOperation.getAllInterfaceLifecycleTypes(serviceComponent.getModel());
1173 if (lifecycleTypeEither.isRight()) {
1174 log.debug("Failed to retrieve global interface types :", lifecycleTypeEither.right().value());
1175 return Either.right(ToscaError.GENERAL_ERROR);
1178 List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value().values().stream()
1179 .map(InterfaceDataDefinition::getType)
1180 .collect(Collectors.toList());
1181 //Add interface types for local interfaces in the original service component for proxy
1182 Map<String, Object> localInterfaceTypes = addInterfaceTypeElement(serviceComponent,
1183 allGlobalInterfaceTypes);
1184 if (MapUtils.isNotEmpty(localInterfaceTypes)) {
1185 proxyInterfaceTypes.putAll(localInterfaceTypes);
1189 return Either.left(proxyInterfaceTypes);
1192 private Either<Map<String, ToscaNodeType>, ToscaError> createProxyNodeTypes(Map<String, Component> componentCache,
1193 Component container) {
1195 Map<String, ToscaNodeType> nodeTypesMap = new HashMap<>();
1196 Either<Map<String, ToscaNodeType>, ToscaError> res = Either.left(nodeTypesMap);
1198 List<ComponentInstance> componentInstances = container.getComponentInstances();
1200 if (componentInstances == null || componentInstances.isEmpty()) {
1203 Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
1204 List<ComponentInstance> proxyInst = componentInstances.stream()
1205 .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceProxy.name()))
1206 .collect(Collectors.toList());
1207 if (proxyInst != null && !proxyInst.isEmpty()) {
1208 for (ComponentInstance inst : proxyInst) {
1209 serviceProxyInstanceList.put(inst.getToscaComponentName(), inst);
1213 if (serviceProxyInstanceList.isEmpty()) {
1216 Either<Resource, StorageOperationStatus> serviceProxyOrigin = toscaOperationFacade
1217 .getLatestByName("serviceProxy", null);
1218 if (serviceProxyOrigin.isRight()) {
1219 log.debug("Failed to fetch normative service proxy resource by tosca name, error {}",
1220 serviceProxyOrigin.right().value());
1221 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
1223 Component origComponent = serviceProxyOrigin.left().value();
1225 for (Entry<String, ComponentInstance> entryProxy : serviceProxyInstanceList.entrySet()) {
1226 Component serviceComponent = null;
1227 ComponentParametersView componentParametersView = new ComponentParametersView();
1228 componentParametersView.disableAll();
1229 componentParametersView.setIgnoreCategories(false);
1230 componentParametersView.setIgnoreProperties(false);
1231 componentParametersView.setIgnoreInputs(false);
1232 componentParametersView.setIgnoreInterfaces(false);
1233 componentParametersView.setIgnoreRequirements(false);
1234 Either<Component, StorageOperationStatus> service = toscaOperationFacade
1235 .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
1236 if (service.isRight()) {
1237 log.debug("Failed to fetch resource with id {} for instance {}",
1238 entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName());
1240 serviceComponent = service.left().value();
1243 ToscaNodeType toscaNodeType = createProxyNodeType(componentCache, origComponent, serviceComponent,
1244 entryProxy.getValue());
1245 nodeTypesMap.put(entryProxy.getKey(), toscaNodeType);
1248 return Either.left(nodeTypesMap);
1251 private void createServiceSubstitutionNodeTypes(final Map<String, Component> componentCache,
1252 final Component container, final ToscaTemplate toscaNode) {
1253 final List<ComponentInstance> componentInstances = container.getComponentInstances();
1255 if (CollectionUtils.isEmpty(componentInstances)) {
1258 final List<ComponentInstance> serviceSubstitutionInstanceList = componentInstances.stream()
1259 .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceSubstitution.name()))
1260 .collect(Collectors.toList());
1261 if (CollectionUtils.isNotEmpty(serviceSubstitutionInstanceList)) {
1262 for (ComponentInstance inst : serviceSubstitutionInstanceList) {
1263 final Map<String, ToscaNodeType> nodeTypes =
1264 toscaNode.getNode_types() == null ? new HashMap<>() : toscaNode.getNode_types();
1265 convertInterfaceNodeType(new HashMap<>(), componentCache.get(inst.getSourceModelUid()), toscaNode,
1271 private ToscaNodeType createProxyNodeType(Map<String, Component> componentCache, Component origComponent,
1272 Component proxyComponent, ComponentInstance componentInstance) {
1273 ToscaNodeType toscaNodeType = new ToscaNodeType();
1274 String derivedFrom = ((Resource) origComponent).getToscaResourceName();
1276 toscaNodeType.setDerived_from(derivedFrom);
1277 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = applicationDataTypeCache.getAll(origComponent.getModel());
1278 if (dataTypesEither.isRight()) {
1279 log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
1281 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
1282 Map<String, ToscaCapability> capabilities = this.capabilityRequirementConverter
1283 .convertProxyCapabilities(componentCache, componentInstance, dataTypes);
1285 if (MapUtils.isNotEmpty(capabilities)) {
1286 toscaNodeType.setCapabilities(capabilities);
1288 List<Map<String, ToscaRequirement>> proxyNodeTypeRequirements = this.capabilityRequirementConverter
1289 .convertProxyRequirements(componentCache, componentInstance);
1290 if (CollectionUtils.isNotEmpty(proxyNodeTypeRequirements)) {
1291 toscaNodeType.setRequirements(proxyNodeTypeRequirements);
1293 Optional<Map<String, ToscaProperty>> proxyProperties = getProxyNodeTypeProperties(proxyComponent, dataTypes);
1294 proxyProperties.ifPresent(toscaNodeType::setProperties);
1296 Map<String, Object> interfaceMap = new HashMap<>();
1297 if (MapUtils.isEmpty(componentInstance.getInterfaces())) {
1298 final Optional<Map<String, Object>> proxyInterfaces = getProxyNodeTypeInterfaces(proxyComponent, dataTypes);
1299 if (proxyInterfaces.isPresent()) {
1300 interfaceMap = proxyInterfaces.get();
1303 interfaceMap = interfacesOperationsConverter
1304 .getInterfacesMapFromComponentInstance(proxyComponent, componentInstance, dataTypes, false, false);
1307 interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
1308 toscaNodeType.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap);
1310 return toscaNodeType;
1313 private Either<ToscaNodeTemplate, ToscaError> convertComponentInstanceRequirements(Component component,
1314 ComponentInstance componentInstance,
1315 List<RequirementCapabilityRelDef> relations,
1316 ToscaNodeTemplate nodeTypeTemplate,
1317 Component originComponent,
1318 Map<String, Component> componentCache) {
1320 final List<RequirementCapabilityRelDef> requirementDefinitionList = filterRequirements(componentInstance,
1322 if (isNotEmpty(requirementDefinitionList)) {
1324 final List<Map<String, ToscaTemplateRequirement>> toscaRequirements = buildRequirements(component, componentInstance, requirementDefinitionList, originComponent, componentCache);
1325 if (!toscaRequirements.isEmpty()) {
1326 nodeTypeTemplate.setRequirements(toscaRequirements);
1328 } catch (final Exception e) {
1329 log.debug("Failed to convert component instance requirements for the component instance {}. ",
1330 componentInstance.getName(), e);
1331 return Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
1334 log.debug("Finished to convert requirements for the node type {} ", componentInstance.getName());
1335 return Either.left(nodeTypeTemplate);
1338 private List<Map<String, ToscaTemplateRequirement>> buildRequirements(final Component component,
1339 final ComponentInstance componentInstance,
1340 final List<RequirementCapabilityRelDef> filteredRelations,
1341 final Component originComponent,
1342 final Map<String, Component> componentCache)
1343 throws ToscaExportException {
1345 final List<Map<String, ToscaTemplateRequirement>> toscaRequirements = new ArrayList<>();
1346 for (RequirementCapabilityRelDef relationshipDefinition : filteredRelations) {
1347 final Map<String, ToscaTemplateRequirement> toscaTemplateRequirementMap =
1348 buildRequirement(componentInstance, originComponent, component.getComponentInstances(), relationshipDefinition, componentCache);
1349 toscaRequirements.add(toscaTemplateRequirementMap);
1352 return toscaRequirements;
1355 private List<RequirementCapabilityRelDef> filterRequirements(ComponentInstance componentInstance,
1356 List<RequirementCapabilityRelDef> relations) {
1357 return relations.stream()
1358 .filter(p -> componentInstance.getUniqueId().equals(p.getFromNode())).collect(Collectors.toList());
1361 private Map<String, ToscaTemplateRequirement> buildRequirement(final ComponentInstance fromInstance,
1362 final Component fromOriginComponent,
1363 final List<ComponentInstance> instancesList,
1364 final RequirementCapabilityRelDef relationshipDefinition,
1365 final Map<String, Component> componentCache)
1366 throws ToscaExportException {
1368 final Map<String, List<RequirementDefinition>> reqMap = fromOriginComponent.getRequirements();
1369 final CapabilityRequirementRelationship capabilityRequirementRelationship = relationshipDefinition
1370 .getRelationships().get(0);
1371 final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation();
1373 final ComponentInstance toInstance = instancesList.stream()
1374 .filter(i -> relationshipDefinition.getToNode().equals(i.getUniqueId()))
1375 .findFirst().orElse(null);
1376 if (toInstance == null) {
1377 final String errorMsg = String
1378 .format("Failed to find a relation from the node %s to the node %s", fromInstance.getName(),
1379 relationshipDefinition.getToNode());
1380 log.debug(errorMsg);
1381 throw new ToscaExportException(errorMsg);
1383 final Optional<RequirementDefinition> reqOpt =
1384 findRequirement(fromOriginComponent, reqMap, relationshipInfo, fromInstance.getUniqueId());
1385 if (reqOpt.isEmpty()) {
1386 final String errorMsg = String
1387 .format("Failed to find a requirement with uniqueId %s on a component with uniqueId %s",
1388 relationshipInfo.getRequirementUid(), fromOriginComponent.getUniqueId());
1389 log.debug(errorMsg);
1390 throw new ToscaExportException(errorMsg);
1392 final ComponentParametersView filter = new ComponentParametersView(true);
1393 filter.setIgnoreComponentInstances(false);
1394 filter.setIgnoreCapabilities(false);
1395 filter.setIgnoreGroups(false);
1396 final Either<Component, StorageOperationStatus> getOriginRes =
1397 toscaOperationFacade.getToscaElement(toInstance.getActualComponentUid(), filter);
1398 if (getOriginRes.isRight()) {
1399 final String errorMsg = String.format(
1400 "Failed to build substituted name for the requirement %s. "
1401 + "Failed to get an origin component with uniqueId %s",
1402 reqOpt.get().getName(), toInstance.getActualComponentUid());
1403 log.debug(errorMsg);
1404 throw new ToscaExportException(errorMsg);
1406 final Component toOriginComponent = getOriginRes.left().value();
1407 Optional<CapabilityDefinition> capOpt = toOriginComponent.getCapabilities().get(reqOpt.get().getCapability()).stream()
1408 .filter(c -> isCapabilityBelongToRelation(relationshipInfo, c)).findFirst();
1409 if (capOpt.isEmpty()) {
1410 capOpt = findCapability(relationshipInfo, toOriginComponent, fromOriginComponent, reqOpt.get());
1411 if (capOpt.isEmpty()) {
1412 final String errorMsg = String
1413 .format("Failed to find a capability with name %s on a component with uniqueId %s",
1414 relationshipInfo.getCapability(), fromOriginComponent.getUniqueId());
1415 log.debug(errorMsg);
1416 throw new ToscaExportException(errorMsg);
1419 return buildRequirement(fromOriginComponent, toOriginComponent, capOpt.get(), reqOpt.get(),
1420 capabilityRequirementRelationship, toInstance, componentCache);
1423 private boolean isCapabilityBelongToRelation(RelationshipInfo reqAndRelationshipPair,
1424 CapabilityDefinition capability) {
1425 return capability.getName().equals(reqAndRelationshipPair.getCapability()) && (capability.getOwnerId() != null
1426 && capability.getOwnerId().equals(reqAndRelationshipPair.getCapabilityOwnerId()));
1429 private Optional<CapabilityDefinition> findCapability(RelationshipInfo reqAndRelationshipPair,
1430 Component toOriginComponent, Component fromOriginComponent,
1431 RequirementDefinition requirement) {
1432 Optional<CapabilityDefinition> cap = toOriginComponent.getCapabilities().get(requirement.getCapability())
1433 .stream().filter(c -> c.getType().equals(requirement.getCapability())).findFirst();
1434 if (!cap.isPresent()) {
1435 log.debug("Failed to find a capability with name {} on a component with uniqueId {}",
1436 reqAndRelationshipPair.getCapability(), fromOriginComponent.getUniqueId());
1441 private Map<String, ToscaTemplateRequirement> buildRequirement(final Component fromOriginComponent,
1442 final Component toOriginComponent,
1443 final CapabilityDefinition capability,
1444 final RequirementDefinition requirement,
1445 final CapabilityRequirementRelationship capabilityRequirementRelationship,
1446 final ComponentInstance toInstance,
1447 final Map<String, Component> componentCache)
1448 throws ToscaExportException {
1450 List<String> reducedPath = capability.getPath();
1451 if (capability.getOwnerId() != null) {
1452 reducedPath = capabilityRequirementConverter
1453 .getReducedPathByOwner(capability.getPath(), capability.getOwnerId());
1455 final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation();
1456 final Either<String, Boolean> capabilityNameEither = capabilityRequirementConverter.buildSubstitutedName(componentCache,
1457 toOriginComponent, reducedPath, relationshipInfo.getCapability(), capability.getPreviousName(), capability.getExternalName());
1458 if (capabilityNameEither.isRight()) {
1459 final String errorMsg = String.format(
1460 "Failed to build a substituted capability name for the capability with name %s on a component with uniqueId %s",
1461 capabilityRequirementRelationship.getCapability(), toOriginComponent.getUniqueId());
1464 throw new ToscaExportException(errorMsg);
1466 final Either<String, Boolean> requirementNameEither = capabilityRequirementConverter
1467 .buildSubstitutedName(componentCache, fromOriginComponent,
1468 requirement.getPath(), relationshipInfo.getRequirement(), requirement.getPreviousName(), requirement.getExternalName());
1469 if (requirementNameEither.isRight()) {
1470 final String errorMsg = String.format("Failed to build a substituted requirement name for the requirement "
1471 + "with name %s on a component with uniqueId %s",
1472 capabilityRequirementRelationship.getRequirement(), fromOriginComponent.getUniqueId());
1473 log.debug(errorMsg);
1474 throw new ToscaExportException(errorMsg);
1476 final ToscaTemplateRequirement toscaRequirement = new ToscaTemplateRequirement();
1477 final Map<String, ToscaTemplateRequirement> toscaReqMap = new HashMap<>();
1478 toscaRequirement.setNode(toInstance.getName());
1479 toscaRequirement.setCapability(capabilityNameEither.left().value());
1480 if (isNotEmpty(capabilityRequirementRelationship.getOperations())) {
1481 toscaRequirement.setRelationship(new ToscaRelationshipBuilder().from(capabilityRequirementRelationship));
1483 toscaReqMap.put(requirementNameEither.left().value(), toscaRequirement);
1487 private Optional<RequirementDefinition> findRequirement(Component fromOriginComponent,
1488 Map<String, List<RequirementDefinition>> reqMap,
1489 RelationshipInfo reqAndRelationshipPair,
1490 String fromInstanceId) {
1491 for (List<RequirementDefinition> reqList : reqMap.values()) {
1492 Optional<RequirementDefinition> reqOpt = reqList.stream().filter(
1493 r -> isRequirementBelongToRelation(fromOriginComponent, reqAndRelationshipPair, r, fromInstanceId))
1495 if (reqOpt.isPresent()) {
1499 return Optional.empty();
1503 * Allows detecting the requirement belonging to the received relationship The detection logic is: A requirement belongs to a relationship IF
1504 * 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
1505 * requirement equals to requirementOwnerId of the relation OR uniqueId of toInstance equals to capabilityOwnerId of the relation
1507 private boolean isRequirementBelongToRelation(Component originComponent, RelationshipInfo reqAndRelationshipPair,
1508 RequirementDefinition requirement, String fromInstanceId) {
1509 if (!StringUtils.equals(requirement.getName(), reqAndRelationshipPair.getRequirement())) {
1510 log.debug("Failed to find a requirement with name {} and reqAndRelationshipPair {}", requirement.getName(),
1511 reqAndRelationshipPair.getRequirement());
1514 return ModelConverter.isAtomicComponent(originComponent) || isRequirementBelongToOwner(reqAndRelationshipPair, requirement, fromInstanceId,
1518 private boolean isRequirementBelongToOwner(RelationshipInfo reqAndRelationshipPair, RequirementDefinition requirement, String fromInstanceId,
1519 Component originComponent) {
1520 return StringUtils.equals(requirement.getOwnerId(), reqAndRelationshipPair.getRequirementOwnerId()) || (
1521 isCvfc(originComponent) && StringUtils.equals(fromInstanceId, reqAndRelationshipPair.getRequirementOwnerId()) || StringUtils
1522 .equals(requirement.getOwnerId(), originComponent.getUniqueId()));
1525 private boolean isCvfc(Component component) {
1526 return component.getComponentType() == ComponentTypeEnum.RESOURCE && ((Resource) component).getResourceType() == ResourceTypeEnum.CVFC;
1529 private Either<Map<String, String[]>, ToscaError> convertSubstitutionMappingCapabilities(final Component component,
1530 final Map<String, Component> componentCache) {
1531 Either<Map<String, String[]>, ToscaError> toscaCapabilitiesRes =
1532 capabilityRequirementConverter.convertSubstitutionMappingCapabilities(componentCache, component);
1533 if (toscaCapabilitiesRes.isRight()) {
1534 log.debug("Failed convert capabilities for the component {}. ", component.getName());
1535 return Either.right(toscaCapabilitiesRes.right().value());
1537 if (isNotEmpty(toscaCapabilitiesRes.left().value())) {
1538 log.debug("Finish convert capabilities for the component {}. ", component.getName());
1539 return Either.left(toscaCapabilitiesRes.left().value());
1541 log.debug("Finished to convert capabilities for the component {}. ", component.getName());
1543 return Either.left(Collections.emptyMap());
1546 private Either<ToscaNodeType, ToscaError> convertCapabilities(Map<String, Component> componentsCache, Component component, ToscaNodeType nodeType,
1547 Map<String, DataTypeDefinition> dataTypes) {
1548 Map<String, ToscaCapability> toscaCapabilities = capabilityRequirementConverter.convertCapabilities(componentsCache, component, dataTypes);
1549 if (!toscaCapabilities.isEmpty()) {
1550 nodeType.setCapabilities(toscaCapabilities);
1552 log.debug("Finish convert Capabilities for node type");
1553 return Either.left(nodeType);
1556 private Map<String, ToscaTemplateArtifact> convertToNodeTemplateArtifacts(Map<String, ToscaArtifactDataDefinition> artifacts) {
1557 if (artifacts == null) {
1560 Map<String, ToscaTemplateArtifact> arts = new HashMap<>();
1561 for (Map.Entry<String, ToscaArtifactDataDefinition> entry : artifacts.entrySet()) {
1562 ToscaTemplateArtifact artifact = new ToscaTemplateArtifact();
1563 artifact.setFile(entry.getValue().getFile());
1564 artifact.setType(entry.getValue().getType());
1565 artifact.setProperties(entry.getValue().getProperties());
1566 arts.put(entry.getKey(), artifact);
1571 private NodeFilter convertToNodeTemplateNodeFilterComponent(CINodeFilterDataDefinition inNodeFilter) {
1572 if (inNodeFilter == null) {
1575 NodeFilter nodeFilter = new NodeFilter();
1576 ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities = inNodeFilter.getCapabilities();
1577 ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> origProperties = inNodeFilter.getProperties();
1578 List<Map<String, CapabilityFilter>> capabilitiesCopy = new ArrayList<>();
1579 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1580 copyNodeFilterCapabilitiesTemplate(origCapabilities, capabilitiesCopy);
1581 copyNodeFilterProperties(origProperties, propertiesCopy);
1582 if (CollectionUtils.isNotEmpty(capabilitiesCopy)) {
1583 nodeFilter.setCapabilities(capabilitiesCopy);
1585 if (CollectionUtils.isNotEmpty(propertiesCopy)) {
1586 nodeFilter.setProperties(propertiesCopy);
1588 nodeFilter.setTosca_id(cloneToscaId(inNodeFilter.getTosca_id()));
1589 nodeFilter = (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
1593 private NodeFilter convertToSubstitutionFilterComponent(final SubstitutionFilterDataDefinition substitutionFilterDataDefinition) {
1594 if (substitutionFilterDataDefinition == null) {
1597 NodeFilter nodeFilter = new NodeFilter();
1598 ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> origProperties = substitutionFilterDataDefinition.getProperties();
1599 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1600 copySubstitutionFilterProperties(origProperties, propertiesCopy);
1601 if (CollectionUtils.isNotEmpty(propertiesCopy)) {
1602 nodeFilter.setProperties(propertiesCopy);
1604 nodeFilter.setTosca_id(cloneToscaId(substitutionFilterDataDefinition.getTosca_id()));
1605 return (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
1608 private Object cloneToscaId(Object toscaId) {
1609 return Objects.isNull(toscaId) ? null : cloneObjectFromYml(toscaId, toscaId.getClass());
1612 private Object cloneObjectFromYml(Object objToClone, Class classOfObj) {
1613 String objectAsYml = yamlUtil.objectToYaml(objToClone);
1614 return yamlUtil.yamlToObject(objectAsYml, classOfObj);
1617 private void copyNodeFilterCapabilitiesTemplate(ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities,
1618 List<Map<String, CapabilityFilter>> capabilitiesCopy) {
1619 if (origCapabilities == null || origCapabilities.getListToscaDataDefinition() == null || origCapabilities.getListToscaDataDefinition()
1623 for (RequirementNodeFilterCapabilityDataDefinition capability : origCapabilities.getListToscaDataDefinition()) {
1624 Map<String, CapabilityFilter> capabilityFilterCopyMap = new HashMap<>();
1625 CapabilityFilter capabilityFilter = new CapabilityFilter();
1626 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1627 copyNodeFilterProperties(capability.getProperties(), propertiesCopy);
1628 capabilityFilter.setProperties(propertiesCopy);
1629 capabilityFilterCopyMap.put(capability.getName(), capabilityFilter);
1630 capabilitiesCopy.add(capabilityFilterCopyMap);
1634 private void copyNodeFilterProperties(ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> origProperties,
1635 List<Map<String, List<Object>>> propertiesCopy) {
1636 if (origProperties == null || origProperties.getListToscaDataDefinition() == null || origProperties.isEmpty()) {
1639 Map<String, List<Object>> propertyMapCopy = new HashMap<>();
1640 for (RequirementNodeFilterPropertyDataDefinition propertyDataDefinition : origProperties.getListToscaDataDefinition()) {
1641 for (String propertyInfoEntry : propertyDataDefinition.getConstraints()) {
1642 Map<String, List<Object>> propertyValObj = new YamlUtil().yamlToObject(propertyInfoEntry, Map.class);
1643 String propertyName = propertyDataDefinition.getName();
1644 if (propertyMapCopy.containsKey(propertyName)) {
1645 addPropertyConstraintValueToList(propertyName, propertyValObj, propertyMapCopy.get(propertyName));
1647 if (propertyName != null) {
1648 List<Object> propsList = new ArrayList<>();
1649 addPropertyConstraintValueToList(propertyName, propertyValObj, propsList);
1650 propertyMapCopy.put(propertyName, propsList);
1652 propertyMapCopy.putAll(propertyValObj);
1657 propertyMapCopy.entrySet().stream().forEach(entry -> addCalculatedConstraintsIntoPropertiesList(propertiesCopy, entry));
1660 private void copySubstitutionFilterProperties(final ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> origProperties,
1661 final List<Map<String, List<Object>>> propertiesCopy) {
1662 if (origProperties == null || origProperties.getListToscaDataDefinition() == null || origProperties.isEmpty()) {
1665 final Map<String, List<Object>> propertyMapCopy = new HashMap<>();
1666 for (final RequirementSubstitutionFilterPropertyDataDefinition propertyDataDefinition : origProperties.getListToscaDataDefinition()) {
1667 for (final String propertyInfoEntry : propertyDataDefinition.getConstraints()) {
1668 final Map<String, List<Object>> propertyValObj = new YamlUtil().yamlToObject(propertyInfoEntry, Map.class);
1669 final String propertyName = propertyDataDefinition.getName();
1670 if (propertyMapCopy.containsKey(propertyName)) {
1671 addPropertyConstraintValueToList(propertyName, propertyValObj, propertyMapCopy.get(propertyName));
1673 if (propertyName != null) {
1674 final List<Object> propsList = new ArrayList<>();
1675 addPropertyConstraintValueToList(propertyName, propertyValObj, propsList);
1676 propertyMapCopy.put(propertyName, propsList);
1678 propertyMapCopy.putAll(propertyValObj);
1683 propertyMapCopy.entrySet().forEach(entry -> addCalculatedConstraintsIntoPropertiesList(propertiesCopy, entry));
1686 private void addPropertyConstraintValueToList(String propertyName, Map<String, List<Object>> propertyValObj, List<Object> propsList) {
1687 if (propertyValObj.containsKey(propertyName)) {
1688 propsList.add(propertyValObj.get(propertyName));
1690 propsList.add(propertyValObj);
1694 private void addCalculatedConstraintsIntoPropertiesList(List<Map<String, List<Object>>> propertiesCopy, Entry<String, List<Object>> entry) {
1695 Map<String, List<Object>> tempMap = new HashMap<>();
1696 tempMap.put(entry.getKey(), entry.getValue());
1697 propertiesCopy.add(tempMap);
1700 private Map<String, String[]> buildSubstitutionMappingPropertyMapping(final Component component) {
1701 if (component == null || CollectionUtils.isEmpty(component.getInputs())) {
1702 return Collections.emptyMap();
1704 return component.getInputs().stream().filter(InputDefinition::isMappedToComponentProperty).map(PropertyDataDefinition::getName)
1705 .collect(Collectors.toMap(inputName -> inputName, inputName -> new String[]{inputName}, (inputName1, inputName2) -> inputName1));
1708 private Map<String, String[]> buildSubstitutionMappingAttributesMapping(final Component component) {
1709 if (component == null || CollectionUtils.isEmpty(component.getOutputs())) {
1710 return Collections.emptyMap();
1712 return component.getOutputs().stream().map(AttributeDataDefinition::getName)
1713 .collect(Collectors.toMap(outputName -> outputName, outputName -> new String[]{outputName}, (outputName1, outputName2) -> outputName1));
1716 Optional<Map<String, ToscaProperty>> getProxyNodeTypeProperties(Component proxyComponent, Map<String, DataTypeDefinition> dataTypes) {
1717 if (Objects.isNull(proxyComponent)) {
1718 return Optional.empty();
1720 Map<String, ToscaProperty> proxyProperties = new HashMap<>();
1721 addInputsToProperties(dataTypes, proxyComponent.getInputs(), proxyProperties);
1722 if (CollectionUtils.isNotEmpty(proxyComponent.getProperties())) {
1723 proxyProperties.putAll(proxyComponent.getProperties().stream()
1724 .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, proxyComponent.getInputs())).collect(Collectors
1725 .toMap(PropertyDataDefinition::getName,
1726 property -> propertyConvertor.convertProperty(dataTypes, property, PropertyConvertor.PropertyType.PROPERTY))));
1728 return MapUtils.isNotEmpty(proxyProperties) ? Optional.of(proxyProperties) : Optional.empty();
1731 void addInputsToProperties(Map<String, DataTypeDefinition> dataTypes, List<InputDefinition> componentInputs,
1732 Map<String, ToscaProperty> mergedProperties) {
1733 if (CollectionUtils.isEmpty(componentInputs)) {
1736 for (InputDefinition input : componentInputs) {
1737 ToscaProperty property = propertyConvertor.convertProperty(dataTypes, input, PropertyConvertor.PropertyType.INPUT);
1738 mergedProperties.put(input.getName(), property);
1742 Optional<Map<String, Object>> getProxyNodeTypeInterfaces(Component proxyComponent, Map<String, DataTypeDefinition> dataTypes) {
1743 if (Objects.isNull(proxyComponent) || MapUtils.isEmpty(proxyComponent.getInterfaces())) {
1744 return Optional.empty();
1746 Map<String, InterfaceDefinition> proxyComponentInterfaces = proxyComponent.getInterfaces();
1747 //Unset artifact path for operation implementation for proxy node types as for operations with artifacts it is
1749 // always available in the proxy node template
1750 removeOperationImplementationForProxyNodeType(proxyComponentInterfaces);
1752 .ofNullable(interfacesOperationsConverter.getInterfacesMap(proxyComponent, null, proxyComponentInterfaces, dataTypes, false, false));
1755 private static class CustomRepresenter extends Representer {
1757 CustomRepresenter() {
1759 this.representers.put(ToscaPropertyAssignment.class, new RepresentToscaPropertyAssignment());
1760 this.representers.put(ToscaAttribute.class, new RepresentToscaAttribute());
1761 // null representer is exceptional and it is stored as an instance
1764 this.nullRepresenter = new RepresentNull();
1767 public boolean validateGetInputValue(final Object valueObj) {
1768 if (!(valueObj instanceof List) && !(valueObj instanceof String)) {
1771 if (valueObj instanceof List) {
1772 return ((List) valueObj).size() > 1;
1777 public boolean validateGetPropertyOrAttributeValue(final Object valueObj) {
1778 if (valueObj instanceof List) {
1779 return ((List) valueObj).size() > 1;
1785 protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue, Tag customTag) {
1786 if (propertyValue == null) {
1789 // skip not relevant for Tosca property
1790 if ("dependencies".equals(property.getName())) {
1793 if (javaBean instanceof ToscaRelationshipTemplate && "name".equals(property.getName())) {
1796 removeDefaultP(propertyValue);
1797 NodeTuple defaultNode = super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
1798 if (javaBean instanceof ToscaTopolgyTemplate && "relationshipTemplates".equals(property.getName())) {
1799 return new NodeTuple(representData("relationship_templates"), defaultNode.getValueNode());
1801 return "_defaultp_".equals(property.getName()) ? new NodeTuple(representData("default"), defaultNode.getValueNode()) : defaultNode;
1804 private void removeDefaultP(final Object propertyValue) {
1805 if (propertyValue instanceof Map) {
1806 final Map mapPropertyValue = ((Map) propertyValue);
1807 final Iterator<Entry> iter = mapPropertyValue.entrySet().iterator();
1808 Object defaultValue = null;
1809 while (iter.hasNext()) {
1810 final Map.Entry entry = iter.next();
1811 if ("_defaultp_".equals(entry.getKey())) {
1812 defaultValue = entry.getValue();
1814 } else if (entry.getValue() instanceof Map) {
1815 removeDefaultP(entry.getValue());
1818 if (defaultValue != null) {
1819 mapPropertyValue.putIfAbsent("default", defaultValue);
1825 protected MappingNode representJavaBean(Set<Property> properties, Object javaBean) {
1826 // remove the bean type from the output yaml (!! ...)
1827 if (!classTags.containsKey(javaBean.getClass())) {
1828 addClassTag(javaBean.getClass(), Tag.MAP);
1830 return super.representJavaBean(properties, javaBean);
1833 private class RepresentToscaAttribute implements Represent {
1836 public Node representData(Object data) {
1837 final ToscaAttribute toscaAttribute = (ToscaAttribute) data;
1838 return represent(toscaAttribute.asToscaMap());
1842 private class RepresentToscaPropertyAssignment implements Represent {
1844 public Node representData(Object data) {
1845 final ToscaPropertyAssignment toscaOperationAssignment = (ToscaPropertyAssignment) data;
1846 if (toscaOperationAssignment.getValue() instanceof String) {
1847 final String stringValue = (String) toscaOperationAssignment.getValue();
1848 if (isPropertyOrAttributeFunction(stringValue)) {
1849 return representGetAttribute(stringValue);
1851 return representScalar(Tag.STR, stringValue);
1853 return represent(null);
1856 public Node representGetAttribute(final String getAttributeFunction) {
1857 return represent(new Yaml().load(getAttributeFunction));
1860 public boolean isPropertyOrAttributeFunction(final String value) {
1862 final Yaml yaml = new Yaml();
1863 final Object yamlObj = yaml.load(value);
1864 if (!(yamlObj instanceof Map)) {
1867 final Map<String, Object> getAttributeMap = (Map) yamlObj;
1868 if (getAttributeMap.size() != 1) {
1871 final List<String> functionList = Arrays
1872 .asList(GET_ATTRIBUTE.getFunctionName(), GET_INPUT.getFunctionName(), GET_PROPERTY.getFunctionName());
1873 final Optional<String> function = getAttributeMap.keySet().stream()
1874 .filter(key -> functionList.stream().anyMatch(function1 -> function1.equals(key))).findFirst();
1875 if (function.isEmpty()) {
1878 final String functionName = function.get();
1879 final Object getAttributeValueObj = getAttributeMap.get(functionName);
1880 if (GET_INPUT.getFunctionName().equals(functionName)) {
1881 return validateGetInputValue(getAttributeValueObj);
1883 return validateGetPropertyOrAttributeValue(getAttributeValueObj);
1885 } catch (final Exception ignored) {
1891 private class RepresentNull implements Represent {
1894 public Node representData(Object data) {
1895 // possible values are here http://yaml.org/type/null.html
1896 return representScalar(Tag.NULL, "");
1901 private static class UnsortedPropertyUtils extends PropertyUtils {
1904 protected Set<Property> createPropertySet(Class type, BeanAccess bAccess) {
1905 Collection<Property> fields = getPropertiesMap(type, BeanAccess.FIELD).values();
1906 return new LinkedHashSet<>(fields);
1910 private Configuration getConfiguration() {
1911 return ConfigurationManager.getConfigurationManager().getConfiguration();