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 org.apache.commons.collections.CollectionUtils;
50 import org.apache.commons.collections.MapUtils;
51 import org.apache.commons.io.FilenameUtils;
52 import org.apache.commons.lang3.StringUtils;
53 import org.apache.commons.lang3.tuple.ImmutablePair;
54 import org.apache.commons.lang3.tuple.ImmutableTriple;
55 import org.apache.commons.lang3.tuple.Triple;
56 import org.onap.sdc.tosca.services.YamlUtil;
57 import org.openecomp.sdc.be.components.impl.exceptions.SdcResourceNotFoundException;
58 import org.openecomp.sdc.be.config.Configuration;
59 import org.openecomp.sdc.be.config.ConfigurationManager;
60 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
61 import org.openecomp.sdc.be.data.model.ToscaImportByModel;
62 import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
63 import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition;
64 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
65 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
66 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
67 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
68 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition;
69 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition;
70 import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterPropertyDataDefinition;
71 import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition;
72 import org.openecomp.sdc.be.datatypes.elements.ToscaArtifactDataDefinition;
73 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
74 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
75 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
76 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
77 import org.openecomp.sdc.be.exception.ToscaExportException;
78 import org.openecomp.sdc.be.model.ArtifactDefinition;
79 import org.openecomp.sdc.be.model.AttributeDefinition;
80 import org.openecomp.sdc.be.model.CapabilityDefinition;
81 import org.openecomp.sdc.be.model.CapabilityRequirementRelationship;
82 import org.openecomp.sdc.be.model.Component;
83 import org.openecomp.sdc.be.model.ComponentInstance;
84 import org.openecomp.sdc.be.model.ComponentInstanceAttribute;
85 import org.openecomp.sdc.be.model.ComponentInstanceInput;
86 import org.openecomp.sdc.be.model.ComponentInstanceInterface;
87 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
88 import org.openecomp.sdc.be.model.ComponentParametersView;
89 import org.openecomp.sdc.be.model.DataTypeDefinition;
90 import org.openecomp.sdc.be.model.GroupInstance;
91 import org.openecomp.sdc.be.model.InputDefinition;
92 import org.openecomp.sdc.be.model.InterfaceDefinition;
93 import org.openecomp.sdc.be.model.PropertyDefinition;
94 import org.openecomp.sdc.be.model.RelationshipInfo;
95 import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
96 import org.openecomp.sdc.be.model.RequirementDefinition;
97 import org.openecomp.sdc.be.model.Resource;
98 import org.openecomp.sdc.be.model.Service;
99 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
100 import org.openecomp.sdc.be.model.category.CategoryDefinition;
101 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
102 import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter;
103 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
104 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
105 import org.openecomp.sdc.be.model.operations.impl.ModelOperation;
106 import org.openecomp.sdc.be.tosca.PropertyConvertor.PropertyType;
107 import org.openecomp.sdc.be.tosca.builder.ToscaRelationshipBuilder;
108 import org.openecomp.sdc.be.tosca.exception.ToscaConversionException;
109 import org.openecomp.sdc.be.tosca.model.CapabilityFilter;
110 import org.openecomp.sdc.be.tosca.model.NodeFilter;
111 import org.openecomp.sdc.be.tosca.model.SubstitutionMapping;
112 import org.openecomp.sdc.be.tosca.model.ToscaAttribute;
113 import org.openecomp.sdc.be.tosca.model.ToscaCapability;
114 import org.openecomp.sdc.be.tosca.model.ToscaDataType;
115 import org.openecomp.sdc.be.tosca.model.ToscaGroupTemplate;
116 import org.openecomp.sdc.be.tosca.model.ToscaNodeTemplate;
117 import org.openecomp.sdc.be.tosca.model.ToscaNodeType;
118 import org.openecomp.sdc.be.tosca.model.ToscaPolicyTemplate;
119 import org.openecomp.sdc.be.tosca.model.ToscaProperty;
120 import org.openecomp.sdc.be.tosca.model.ToscaPropertyAssignment;
121 import org.openecomp.sdc.be.tosca.model.ToscaRelationshipTemplate;
122 import org.openecomp.sdc.be.tosca.model.ToscaRequirement;
123 import org.openecomp.sdc.be.tosca.model.ToscaTemplate;
124 import org.openecomp.sdc.be.tosca.model.ToscaTemplateArtifact;
125 import org.openecomp.sdc.be.tosca.model.ToscaTemplateRequirement;
126 import org.openecomp.sdc.be.tosca.model.ToscaTopolgyTemplate;
127 import org.openecomp.sdc.be.tosca.utils.ForwardingPathToscaUtil;
128 import org.openecomp.sdc.be.tosca.utils.InputConverter;
129 import org.openecomp.sdc.be.tosca.utils.OutputConverter;
130 import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
131 import org.openecomp.sdc.common.log.wrappers.Logger;
132 import org.springframework.beans.factory.annotation.Autowired;
133 import org.yaml.snakeyaml.DumperOptions;
134 import org.yaml.snakeyaml.DumperOptions.FlowStyle;
135 import org.yaml.snakeyaml.Yaml;
136 import org.yaml.snakeyaml.introspector.BeanAccess;
137 import org.yaml.snakeyaml.introspector.Property;
138 import org.yaml.snakeyaml.introspector.PropertyUtils;
139 import org.yaml.snakeyaml.nodes.MappingNode;
140 import org.yaml.snakeyaml.nodes.Node;
141 import org.yaml.snakeyaml.nodes.NodeTuple;
142 import org.yaml.snakeyaml.nodes.Tag;
143 import org.yaml.snakeyaml.representer.Represent;
144 import org.yaml.snakeyaml.representer.Representer;
146 @org.springframework.stereotype.Component("tosca-export-handler")
147 public class ToscaExportHandler {
149 public static final String ASSET_TOSCA_TEMPLATE = "assettoscatemplate";
150 private static final Logger log = Logger.getLogger(ToscaExportHandler.class);
151 private static final String INVARIANT_UUID = "invariantUUID";
152 private static final String TOSCA_VERSION = "tosca_simple_yaml_1_3";
153 private static final String SERVICE_NODE_TYPE_PREFIX = "org.openecomp.service.";
154 private static final String IMPORTS_FILE_KEY = "file";
155 private static final String TOSCA_INTERFACE_NAME = "-interface.yml";
156 private static final String FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION = "convertToToscaTemplate - failed to get Default Imports section from configuration";
157 private static final String NOT_SUPPORTED_COMPONENT_TYPE = "Not supported component type {}";
158 private static final String NATIVE_ROOT = "tosca.nodes.Root";
159 private static final List<String> EXCLUDED_CATEGORY_SPECIFIC_METADATA = List
160 .of("Service Function", "Service Role", "Naming Policy", "Service Type");
161 private static final YamlUtil yamlUtil = new YamlUtil();
162 private final ApplicationDataTypeCache applicationDataTypeCache;
163 private final ToscaOperationFacade toscaOperationFacade;
164 private final CapabilityRequirementConverter capabilityRequirementConverter;
165 private final PolicyExportParser policyExportParser;
166 private final GroupExportParser groupExportParser;
167 private final PropertyConvertor propertyConvertor;
168 private final AttributeConverter attributeConverter;
169 private final InputConverter inputConverter;
170 private final OutputConverter outputConverter;
171 private final InterfaceLifecycleOperation interfaceLifecycleOperation;
172 private final InterfacesOperationsConverter interfacesOperationsConverter;
173 private final ModelOperation modelOperation;
176 public ToscaExportHandler(final ApplicationDataTypeCache applicationDataTypeCache,
177 final ToscaOperationFacade toscaOperationFacade,
178 final CapabilityRequirementConverter capabilityRequirementConverter,
179 final PolicyExportParser policyExportParser,
180 final GroupExportParser groupExportParser,
181 final PropertyConvertor propertyConvertor,
182 final AttributeConverter attributeConverter,
183 final InputConverter inputConverter,
184 final OutputConverter outputConverter,
185 final InterfaceLifecycleOperation interfaceLifecycleOperation,
186 final InterfacesOperationsConverter interfacesOperationsConverter,
187 final ModelOperation modelOperation) {
188 this.applicationDataTypeCache = applicationDataTypeCache;
189 this.toscaOperationFacade = toscaOperationFacade;
190 this.capabilityRequirementConverter = capabilityRequirementConverter;
191 this.policyExportParser = policyExportParser;
192 this.groupExportParser = groupExportParser;
193 this.propertyConvertor = propertyConvertor;
194 this.attributeConverter = attributeConverter;
195 this.inputConverter = inputConverter;
196 this.outputConverter = outputConverter;
197 this.interfaceLifecycleOperation = interfaceLifecycleOperation;
198 this.interfacesOperationsConverter = interfacesOperationsConverter;
199 this.modelOperation = modelOperation;
202 public static String getInterfaceFilename(String artifactName) {
203 return artifactName.substring(0, artifactName.lastIndexOf('.')) + TOSCA_INTERFACE_NAME;
206 private static void removeOperationImplementationForProxyNodeType(Map<String, InterfaceDefinition> proxyComponentInterfaces) {
207 if (MapUtils.isEmpty(proxyComponentInterfaces)) {
210 proxyComponentInterfaces.values().stream().map(InterfaceDataDefinition::getOperations).filter(MapUtils::isNotEmpty)
211 .forEach(operations -> operations.values().forEach(operation -> operation.setImplementation(null)));
214 public Either<ToscaRepresentation, ToscaError> exportComponent(Component component) {
215 return convertToToscaTemplate(component).left().map(this::createToscaRepresentation);
218 public Either<ToscaRepresentation, ToscaError> exportComponentInterface(final Component component, final boolean isAssociatedComponent) {
219 final List<Map<String, Map<String, String>>> imports = new ArrayList<>(getDefaultToscaImports(component.getModel()));
220 if (CollectionUtils.isEmpty(imports)) {
221 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
222 return Either.right(ToscaError.GENERAL_ERROR);
224 List<Triple<String, String, Component>> dependencies = new ArrayList<>();
225 if (component.getDerivedFromGenericType() != null && !component.getDerivedFromGenericType()
226 .startsWith("org.openecomp.resource.abstract.nodes.")) {
227 final Either<Component, StorageOperationStatus> baseType = toscaOperationFacade
228 .getByToscaResourceNameAndVersion(component.getDerivedFromGenericType(), component.getDerivedFromGenericVersion(), component.getModel());
229 if (baseType.isLeft() && baseType.left().value() != null) {
230 addDependencies(imports, dependencies, baseType.left().value());
232 log.debug("Failed to fetch derived from type {}", component.getDerivedFromGenericType());
236 String toscaVersion = null;
237 if (component instanceof Resource) {
238 toscaVersion = ((Resource) component).getToscaVersion();
240 ToscaTemplate toscaTemplate = new ToscaTemplate(toscaVersion != null ? toscaVersion : TOSCA_VERSION);
241 toscaTemplate.setImports(imports);
242 final Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
243 final Either<ToscaTemplate, ToscaError> toscaTemplateRes = convertInterfaceNodeType(new HashMap<>(), component, toscaTemplate, nodeTypes,
244 isAssociatedComponent);
245 if (toscaTemplateRes.isRight()) {
246 return Either.right(toscaTemplateRes.right().value());
248 toscaTemplate = toscaTemplateRes.left().value();
249 toscaTemplate.setDependencies(dependencies);
250 ToscaRepresentation toscaRepresentation = this.createToscaRepresentation(toscaTemplate);
251 return Either.left(toscaRepresentation);
254 public ToscaRepresentation createToscaRepresentation(ToscaTemplate toscaTemplate) {
255 CustomRepresenter representer = new CustomRepresenter();
256 DumperOptions options = new DumperOptions();
257 options.setAllowReadOnlyProperties(false);
258 options.setPrettyFlow(true);
259 options.setDefaultFlowStyle(FlowStyle.FLOW);
260 options.setCanonical(false);
261 representer.addClassTag(toscaTemplate.getClass(), Tag.MAP);
262 representer.setPropertyUtils(new UnsortedPropertyUtils());
263 Yaml yaml = new Yaml(representer, options);
264 String yamlAsString = yaml.dumpAsMap(toscaTemplate);
265 StringBuilder sb = new StringBuilder();
266 sb.append(getConfiguration().getHeatEnvArtifactHeader());
267 sb.append(yamlAsString);
268 sb.append(getConfiguration().getHeatEnvArtifactFooter());
269 return ToscaRepresentation.make(sb.toString().getBytes(), toscaTemplate);
272 public Either<ToscaTemplate, ToscaError> getDependencies(Component component) {
273 ToscaTemplate toscaTemplate = new ToscaTemplate(null);
274 Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports = fillImports(component, toscaTemplate);
275 if (fillImports.isRight()) {
276 return Either.right(fillImports.right().value());
278 return Either.left(fillImports.left().value().left);
281 public Either<ToscaTemplate, ToscaError> convertToToscaTemplate(final Component component) {
282 final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImports(component.getModel());
283 if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
284 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
285 return Either.right(ToscaError.GENERAL_ERROR);
287 log.trace("start tosca export for {}", component.getUniqueId());
288 String toscaVersion = null;
289 if (component instanceof Resource) {
290 toscaVersion = ((Resource) component).getToscaVersion();
292 final ToscaTemplate toscaTemplate = new ToscaTemplate(toscaVersion != null ? toscaVersion : TOSCA_VERSION);
293 toscaTemplate.setMetadata(convertMetadata(component));
294 toscaTemplate.setImports(new ArrayList<>(defaultToscaImportConfig));
295 final Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
296 if (ModelConverter.isAtomicComponent(component)) {
297 log.trace("convert component as node type");
298 return convertNodeType(new HashMap<>(), component, toscaTemplate, nodeTypes);
300 log.trace("convert component as topology template");
301 return convertToscaTemplate(component, toscaTemplate);
305 public List<Map<String, Map<String, String>>> getDefaultToscaImports(final String modelId) {
306 if (modelId == null) {
307 return getDefaultToscaImportConfig();
310 final List<ToscaImportByModel> allModelImports = modelOperation.findAllModelImports(modelId, true);
311 final List<Map<String, Map<String, String>>> importList = new ArrayList<>();
312 final Set<Path> addedPathList = new HashSet<>();
313 for (final ToscaImportByModel toscaImportByModel : allModelImports) {
314 var importPath = Path.of(toscaImportByModel.getFullPath());
315 if (addedPathList.contains(importPath)) {
316 importPath = ToscaDefaultImportHelper.addModelAsFilePrefix(importPath, toscaImportByModel.getModelId());
318 final String fileName = FilenameUtils.getBaseName(importPath.toString());
319 importList.add(Map.of(fileName, Map.of("file", importPath.toString())));
320 addedPathList.add(importPath);
325 private Either<ToscaTemplate, ToscaError> convertToscaTemplate(Component component, ToscaTemplate toscaNode) {
326 Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> importsRes = fillImports(component, toscaNode);
327 if (importsRes.isRight()) {
328 return Either.right(importsRes.right().value());
330 toscaNode = importsRes.left().value().left;
331 Map<String, Component> componentCache = importsRes.left().value().right;
332 Either<Map<String, ToscaNodeType>, ToscaError> nodeTypesMapEither = createProxyNodeTypes(componentCache, component);
333 if (nodeTypesMapEither.isRight()) {
334 log.debug("Failed to fetch normative service proxy resource by tosca name, error {}", nodeTypesMapEither.right().value());
335 return Either.right(nodeTypesMapEither.right().value());
337 Map<String, ToscaNodeType> nodeTypesMap = nodeTypesMapEither.left().value();
338 if (nodeTypesMap != null && !nodeTypesMap.isEmpty()) {
339 toscaNode.setNode_types(nodeTypesMap);
341 createServiceSubstitutionNodeTypes(componentCache, component, toscaNode);
342 Either<Map<String, Object>, ToscaError> proxyInterfaceTypesEither = createProxyInterfaceTypes(component);
343 if (proxyInterfaceTypesEither.isRight()) {
344 log.debug("Failed to populate service proxy local interface types in tosca, error {}", nodeTypesMapEither.right().value());
345 return Either.right(proxyInterfaceTypesEither.right().value());
347 Map<String, Object> proxyInterfaceTypes = proxyInterfaceTypesEither.left().value();
348 if (MapUtils.isNotEmpty(proxyInterfaceTypes)) {
349 toscaNode.setInterface_types(proxyInterfaceTypes);
351 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = applicationDataTypeCache.getAll(component.getModel());
352 if (dataTypesEither.isRight()) {
353 log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
354 return Either.right(ToscaError.GENERAL_ERROR);
356 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
357 ToscaTopolgyTemplate topologyTemplate = new ToscaTopolgyTemplate();
358 List<InputDefinition> inputDef = component.getInputs();
359 Map<String, ToscaProperty> inputs = inputConverter.convertInputs(inputDef, dataTypes);
360 if (!inputs.isEmpty()) {
361 topologyTemplate.setInputs(inputs);
363 final Map<String, ToscaProperty> outputs;
365 outputs = outputConverter.convert(component.getOutputs(), dataTypes);
366 } catch (final ToscaConversionException e) {
367 log.error(EcompLoggerErrorCode.SCHEMA_ERROR, ToscaExportHandler.class.getName(),
368 "Could not parse component '{}' outputs. Component unique id '{}'.", component.getName(), component.getUniqueId(), e);
369 return Either.right(ToscaError.GENERAL_ERROR);
371 if (!outputs.isEmpty()) {
372 topologyTemplate.setOutputs(outputs);
374 if (CollectionUtils.isNotEmpty(component.getComponentInstances())) {
375 final Either<Map<String, ToscaNodeTemplate>, ToscaError> nodeTemplates =
376 convertNodeTemplates(component, componentCache, dataTypes, topologyTemplate);
377 if (nodeTemplates.isRight()) {
378 return Either.right(nodeTemplates.right().value());
380 log.debug("node templates converted");
381 topologyTemplate.setNode_templates(nodeTemplates.left().value());
383 final Map<String, ToscaRelationshipTemplate> relationshipTemplatesMap = new ToscaExportRelationshipTemplatesHandler()
384 .createFrom(topologyTemplate.getNode_templates());
385 if (!relationshipTemplatesMap.isEmpty()) {
386 topologyTemplate.setRelationshipTemplates(relationshipTemplatesMap);
388 addGroupsToTopologyTemplate(component, topologyTemplate);
390 addPoliciesToTopologyTemplate(component, topologyTemplate);
391 } catch (SdcResourceNotFoundException e) {
392 log.debug("Fail to add policies to topology template:", e);
393 return Either.right(ToscaError.GENERAL_ERROR);
396 createSubstitutionMapping(component, componentCache).ifPresent(topologyTemplate::setSubstitution_mappings);
397 } catch (final ToscaExportException e) {
398 log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, ToscaExportHandler.class.getName(), e.getMessage());
399 return Either.right(e.getToscaError());
401 if (!topologyTemplate.isEmpty()) {
402 toscaNode.setTopology_template(topologyTemplate);
404 return Either.left(toscaNode);
407 private Either<String, ToscaError> createComponentToscaName(final Component component) {
408 switch (component.getComponentType()) {
410 final ResourceMetadataDataDefinition resourceMetadata =
411 (ResourceMetadataDataDefinition) component.getComponentMetadataDefinition().getMetadataDataDefinition();
412 return Either.left(resourceMetadata.getToscaResourceName());
414 return Either.left(SERVICE_NODE_TYPE_PREFIX + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName());
416 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
417 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
421 private Optional<SubstitutionMapping> createSubstitutionMapping(final Component component,
422 final Map<String, Component> componentCache) throws ToscaExportException {
423 if (component instanceof Service && !((Service) component).isSubstituteCandidate()) {
424 return Optional.empty();
427 final Either<String, ToscaError> toscaResourceNameEither = createComponentToscaName(component);
428 if (toscaResourceNameEither.isRight()) {
429 throw new ToscaExportException("Could not create component TOSCA name", toscaResourceNameEither.right().value());
431 final String toscaResourceName = toscaResourceNameEither.left().value();
433 final SubstitutionMapping substitutionMapping = new SubstitutionMapping();
434 substitutionMapping.setNode_type(toscaResourceName);
435 convertSubstitutionMappingFilter(component).ifPresent(substitutionMapping::setSubstitution_filter);
437 final Either<Map<String, String[]>, ToscaError> capabilitiesEither = convertSubstitutionMappingCapabilities(component, componentCache);
438 if (capabilitiesEither.isRight()) {
439 throw new ToscaExportException("Could not convert substitution mapping capabilities", capabilitiesEither.right().value());
441 final Map<String, String[]> capabilityMap = capabilitiesEither.left().value();
442 if (!capabilityMap.isEmpty()) {
443 substitutionMapping.setCapabilities(capabilityMap);
446 final Either<Map<String, String[]>, ToscaError> requirements =
447 capabilityRequirementConverter.convertSubstitutionMappingRequirements(component, componentCache);
448 if (requirements.isRight()) {
449 throw new ToscaExportException("Could not convert substitution mapping requirements", requirements.right().value());
451 final Map<String, String[]> requirementMap = requirements.left().value();
452 if (!requirementMap.isEmpty()) {
453 substitutionMapping.setRequirements(requirementMap);
456 final Map<String, String[]> propertyMappingMap = buildSubstitutionMappingPropertyMapping(component);
457 if (!propertyMappingMap.isEmpty()) {
458 substitutionMapping.setProperties(propertyMappingMap);
461 final Map<String, String[]> attributesMappingMap = buildSubstitutionMappingAttributesMapping(component);
462 if (!attributesMappingMap.isEmpty()) {
463 substitutionMapping.setAttributes(attributesMappingMap);
466 return Optional.of(substitutionMapping);
469 private Optional<NodeFilter> convertSubstitutionMappingFilter(final Component component) {
470 if (component.getSubstitutionFilter() == null || (component.getSubstitutionFilter().getProperties()).getListToscaDataDefinition() == null) {
471 return Optional.empty();
474 return Optional.ofNullable(convertToSubstitutionFilterComponent(component.getSubstitutionFilter()));
477 private void addGroupsToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate) {
478 Map<String, ToscaGroupTemplate> groups = groupExportParser.getGroups(component);
479 if (groups != null) {
480 topologyTemplate.addGroups(groups);
484 private void addPoliciesToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate) throws SdcResourceNotFoundException {
485 Map<String, ToscaPolicyTemplate> policies = policyExportParser.getPolicies(component);
486 if (policies != null) {
487 topologyTemplate.addPolicies(policies);
491 private Map<String, String> convertMetadata(Component component) {
492 return convertMetadata(component, false, null);
495 private Map<String, String> convertMetadata(Component component, boolean isInstance, ComponentInstance componentInstance) {
496 Map<String, String> toscaMetadata = new LinkedHashMap<>();
497 toscaMetadata.put(convertMetadataKey(JsonPresentationFields.INVARIANT_UUID), component.getInvariantUUID());
498 toscaMetadata.put(JsonPresentationFields.UUID.getPresentation(), component.getUUID());
500 .put(JsonPresentationFields.NAME.getPresentation(), component.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
501 toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), component.getDescription());
502 List<CategoryDefinition> categories = component.getCategories();
503 CategoryDefinition categoryDefinition = categories.get(0);
504 toscaMetadata.put(JsonPresentationFields.CATEGORY.getPresentation(), categoryDefinition.getName());
506 toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), component.getVersion());
507 toscaMetadata.put(JsonPresentationFields.CUSTOMIZATION_UUID.getPresentation(), componentInstance.getCustomizationUUID());
508 if (componentInstance.getSourceModelInvariant() != null && !componentInstance.getSourceModelInvariant().isEmpty()) {
509 toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), componentInstance.getComponentVersion());
510 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_INVARIANT.getPresentation(), componentInstance.getSourceModelInvariant());
511 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_UUID.getPresentation(), componentInstance.getSourceModelUuid());
512 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_NAME.getPresentation(), componentInstance.getSourceModelName());
513 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
514 toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(),
515 componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceProxy.getDisplayValue());
516 } else if (componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
517 toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(),
518 componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceSubstitution.getDisplayValue());
520 toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), componentInstance.getDescription());
523 switch (component.getComponentType()) {
525 Resource resource = (Resource) component;
526 if (isInstance && (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy
527 || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution)) {
528 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), componentInstance.getOriginType().getDisplayValue());
530 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), resource.getResourceType().name());
532 toscaMetadata.put(JsonPresentationFields.SUB_CATEGORY.getPresentation(), categoryDefinition.getSubcategories().get(0).getName());
533 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR.getPresentation(), resource.getVendorName());
534 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_RELEASE.getPresentation(), resource.getVendorRelease());
535 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_MODEL_NUMBER.getPresentation(), resource.getResourceVendorModelNumber());
538 Service service = (Service) component;
539 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), component.getComponentType().getValue());
540 toscaMetadata.put(JsonPresentationFields.SERVICE_TYPE.getPresentation(), service.getServiceType());
541 toscaMetadata.put(JsonPresentationFields.SERVICE_ROLE.getPresentation(), service.getServiceRole());
542 toscaMetadata.put(JsonPresentationFields.SERVICE_FUNCTION.getPresentation(), service.getServiceFunction());
543 toscaMetadata.put(JsonPresentationFields.ENVIRONMENT_CONTEXT.getPresentation(), service.getEnvironmentContext());
544 toscaMetadata.put(JsonPresentationFields.INSTANTIATION_TYPE.getPresentation(),
545 service.getEnvironmentContext() == null ? StringUtils.EMPTY : service.getInstantiationType());
548 toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming().toString());
549 toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming().toString());
550 toscaMetadata.put(JsonPresentationFields.NAMING_POLICY.getPresentation(), service.getNamingPolicy());
554 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
556 for (final String key : component.getCategorySpecificMetadata().keySet()) {
557 if (!EXCLUDED_CATEGORY_SPECIFIC_METADATA.contains(key)) {
558 toscaMetadata.put(key, component.getCategorySpecificMetadata().get(key));
561 return toscaMetadata;
564 private String convertMetadataKey(JsonPresentationFields jsonPresentationField) {
565 if (JsonPresentationFields.INVARIANT_UUID.equals(jsonPresentationField)) {
566 return INVARIANT_UUID;
568 return jsonPresentationField.getPresentation();
571 private Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports(Component component, ToscaTemplate toscaTemplate) {
572 final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImports(component.getModel());
573 if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
574 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
575 return Either.right(ToscaError.GENERAL_ERROR);
577 Map<String, Component> componentCache = new HashMap<>();
578 if (!ModelConverter.isAtomicComponent(component)) {
579 final List<Map<String, Map<String, String>>> additionalImports =
580 toscaTemplate.getImports() == null ? new ArrayList<>(defaultToscaImportConfig) : new ArrayList<>(toscaTemplate.getImports());
581 List<Triple<String, String, Component>> dependencies = new ArrayList<>();
582 Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
583 final Map<String, Map<String, String>> substituteTypeImportEntry = generateComponentSubstituteTypeImport(component, toscaArtifacts);
584 if (!substituteTypeImportEntry.isEmpty()) {
585 additionalImports.add(substituteTypeImportEntry);
587 List<ComponentInstance> componentInstances = component.getComponentInstances();
588 if (componentInstances != null && !componentInstances.isEmpty()) {
589 componentInstances.forEach(ci -> createDependency(componentCache, additionalImports, dependencies, ci));
591 toscaTemplate.setDependencies(dependencies);
592 toscaTemplate.setImports(additionalImports);
594 log.debug("currently imports supported for VF and service only");
596 return Either.left(new ImmutablePair<>(toscaTemplate, componentCache));
599 private Map<String, Map<String, String>> generateComponentSubstituteTypeImport(final Component component,
600 final Map<String, ArtifactDefinition> toscaArtifacts) {
602 if (component instanceof Service && !((Service) component).isSubstituteCandidate()) {
603 return Collections.emptyMap();
605 if (MapUtils.isEmpty(toscaArtifacts)) {
606 return Collections.emptyMap();
608 final ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE);
609 if (artifactDefinition == null) {
610 return Collections.emptyMap();
612 final var importEntryName = component.getComponentType().toString().toLowerCase() + "-" + component.getName() + "-interface";
613 return Map.of(importEntryName,
614 Map.of(IMPORTS_FILE_KEY, getInterfaceFilename(artifactDefinition.getArtifactName()))
618 private List<Map<String, Map<String, String>>> getDefaultToscaImportConfig() {
619 return getConfiguration().getDefaultImports();
622 private void createDependency(final Map<String, Component> componentCache, final List<Map<String, Map<String, String>>> imports,
623 final List<Triple<String, String, Component>> dependencies, final ComponentInstance componentInstance) {
624 log.debug("createDependency componentCache {}", componentCache);
625 Component componentRI = componentCache.get(componentInstance.getComponentUid());
626 if (componentRI == null || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
627 // all resource must be only once!
628 final Either<Component, StorageOperationStatus> resource = toscaOperationFacade.getToscaFullElement(componentInstance.getComponentUid());
629 if ((resource.isRight()) && (log.isDebugEnabled())) {
630 log.debug("Failed to fetch resource with id {} for instance {}", componentInstance.getComponentUid(),
631 componentInstance.getUniqueId());
634 final Component fetchedComponent = resource.left().value();
635 componentRI = setComponentCache(componentCache, componentInstance, fetchedComponent);
636 addDependencies(imports, dependencies, componentRI);
641 * Sets a componentCache from the given component/resource.
643 private Component setComponentCache(final Map<String, Component> componentCache, final ComponentInstance componentInstance,
644 final Component fetchedComponent) {
645 componentCache.put(fetchedComponent.getUniqueId(), fetchedComponent);
646 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy
647 || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
648 final Either<Component, StorageOperationStatus> sourceService = toscaOperationFacade
649 .getToscaFullElement(componentInstance.getSourceModelUid());
650 if (sourceService.isRight() && (log.isDebugEnabled())) {
651 log.debug("Failed to fetch source service with id {} for proxy {}", componentInstance.getSourceModelUid(),
652 componentInstance.getUniqueId());
654 final Component fetchedSource = sourceService.left().value();
655 componentCache.put(fetchedSource.getUniqueId(), fetchedSource);
656 return fetchedSource;
658 return fetchedComponent;
662 * Retrieves all derived_from nodes and stores it in a predictable order.
664 private void addDependencies(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
665 final Component fetchedComponent) {
666 final Set<Component> componentsList = new LinkedHashSet<>();
667 if (fetchedComponent instanceof Resource) {
668 log.debug("fetchedComponent is a resource {}", fetchedComponent);
669 final Optional<Map<String, String>> derivedFromMapOfIdToName = getDerivedFromMapOfIdToName(fetchedComponent, componentsList);
670 if (derivedFromMapOfIdToName.isPresent() && !derivedFromMapOfIdToName.get().isEmpty()) {
671 derivedFromMapOfIdToName.get().entrySet().forEach(entry -> {
672 log.debug("Started entry.getValue() : {}", entry.getValue());
673 if (!NATIVE_ROOT.equals(entry.getValue())) {
674 Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade.getToscaElement(entry.getKey());
675 if (resourcefetched != null && resourcefetched.isLeft()) {
676 componentsList.add(resourcefetched.left().value());
680 setImports(imports, dependencies, componentsList);
682 setImports(imports, dependencies, fetchedComponent);
688 * Returns all derived_from nodes found.
690 private Optional<Map<String, String>> getDerivedFromMapOfIdToName(final Component fetchedComponent, final Set<Component> componentsList) {
691 final Resource parentResource = (Resource) fetchedComponent;
692 Map<String, String> derivedFromMapOfIdToName = new HashMap<>();
693 if (CollectionUtils.isNotEmpty(parentResource.getComponentInstances())) {
694 componentsList.add(fetchedComponent);
695 for (final ComponentInstance componentInstance : parentResource.getComponentInstances()) {
696 final Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade
697 .getToscaElement(componentInstance.getComponentUid());
698 if (resourcefetched != null && resourcefetched.isLeft()) {
699 final Map<String, String> derivedWithId = resourcefetched.left().value().getDerivedFromMapOfIdToName();
700 if (MapUtils.isNotEmpty(derivedWithId)) {
701 derivedFromMapOfIdToName.putAll(derivedWithId);
706 derivedFromMapOfIdToName = parentResource.getDerivedFromMapOfIdToName();
708 log.debug("Started derivedFromMapOfIdToName: {}", derivedFromMapOfIdToName);
709 return Optional.ofNullable(derivedFromMapOfIdToName);
713 * Creates a resource map and adds it to the import list.
715 private void setImports(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
716 final Set<Component> componentsList) {
717 componentsList.forEach(component -> setImports(imports, dependencies, component));
720 private void setImports(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
721 final Component component) {
722 final Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
723 final ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE);
724 if (artifactDefinition != null) {
725 final Map<String, String> files = new HashMap<>();
726 final String artifactName = artifactDefinition.getArtifactName();
727 files.put(IMPORTS_FILE_KEY, artifactName);
728 final StringBuilder keyNameBuilder = new StringBuilder();
729 keyNameBuilder.append(component.getComponentType().toString().toLowerCase());
730 keyNameBuilder.append("-");
731 keyNameBuilder.append(component.getName());
732 addImports(imports, keyNameBuilder, files);
733 dependencies.add(new ImmutableTriple<>(artifactName, artifactDefinition.getEsId(), component));
734 if (!ModelConverter.isAtomicComponent(component)) {
735 final Map<String, String> interfaceFiles = new HashMap<>();
736 interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactName));
737 keyNameBuilder.append("-interface");
738 addImports(imports, keyNameBuilder, interfaceFiles);
744 * Adds the found resource to the import definition list.
746 private void addImports(final List<Map<String, Map<String, String>>> imports, final StringBuilder keyNameBuilder,
747 final Map<String, String> files) {
748 final String mapKey = keyNameBuilder.toString();
749 if (imports.stream().allMatch(stringMapMap -> stringMapMap.get(mapKey) == null)) {
750 final Map<String, Map<String, String>> importsListMember = new HashMap<>();
751 importsListMember.put(keyNameBuilder.toString(), files);
752 imports.add(importsListMember);
756 private Either<ToscaTemplate, ToscaError> convertNodeType(Map<String, Component> componentsCache, Component component, ToscaTemplate toscaNode,
757 Map<String, ToscaNodeType> nodeTypes) {
758 return convertInterfaceNodeType(componentsCache, component, toscaNode, nodeTypes, false);
761 public Either<ToscaTemplate, ToscaError> convertInterfaceNodeType(Map<String, Component> componentsCache, Component component,
762 ToscaTemplate toscaNode, Map<String, ToscaNodeType> nodeTypes,
763 boolean isAssociatedComponent) {
764 log.debug("start convert node type for {}", component.getUniqueId());
765 ToscaNodeType toscaNodeType = createNodeType(component);
766 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither = interfaceLifecycleOperation
767 .getAllInterfaceLifecycleTypes(component.getModel());
768 if (lifecycleTypeEither.isRight() && !StorageOperationStatus.NOT_FOUND.equals(lifecycleTypeEither.right().value())) {
769 log.debug("Failed to fetch all interface types :", lifecycleTypeEither.right().value());
770 return Either.right(ToscaError.GENERAL_ERROR);
772 if (lifecycleTypeEither.isLeft()) {
773 List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value().values().stream().map(InterfaceDataDefinition::getType)
774 .collect(Collectors.toList());
775 toscaNode.setInterface_types(addInterfaceTypeElement(component, allGlobalInterfaceTypes));
777 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = applicationDataTypeCache.getAll(component.getModel());
778 if (dataTypesEither.isRight()) {
779 log.debug("Failed to fetch all data types :", dataTypesEither.right().value());
780 return Either.right(ToscaError.GENERAL_ERROR);
782 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
783 List<InputDefinition> inputDef = component.getInputs();
784 Map<String, ToscaProperty> mergedProperties = new HashMap<>();
785 interfacesOperationsConverter.addInterfaceDefinitionElement(component, toscaNodeType, dataTypes, isAssociatedComponent);
786 addInputsToProperties(dataTypes, inputDef, mergedProperties);
787 final Map<String, ToscaAttribute> toscaAttributeMap;
788 toscaAttributeMap = convertToToscaAttributes(component.getAttributes(), dataTypes);
789 if (!toscaAttributeMap.isEmpty()) {
790 toscaNodeType.setAttributes(toscaAttributeMap);
792 if (CollectionUtils.isNotEmpty(component.getProperties())) {
793 List<PropertyDefinition> properties = component.getProperties();
794 Map<String, ToscaProperty> convertedProperties = properties.stream()
795 .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, component.getInputs())).collect(Collectors
796 .toMap(PropertyDataDefinition::getName,
797 property -> propertyConvertor.convertProperty(dataTypes, property, PropertyConvertor.PropertyType.PROPERTY)));
798 // merge component properties and inputs properties
799 mergedProperties.putAll(convertedProperties);
801 if (MapUtils.isNotEmpty(mergedProperties)) {
802 toscaNodeType.setProperties(mergedProperties);
804 /* convert private data_types */
805 List<DataTypeDefinition> privateDataTypes = component.getDataTypes();
806 if (CollectionUtils.isNotEmpty(privateDataTypes)) {
807 Map<String, ToscaDataType> toscaDataTypeMap = new HashMap<>();
808 for (DataTypeDefinition dataType : privateDataTypes) {
809 log.debug("Emitting private data type: component.name={} dataType.name={}",
810 component.getNormalizedName(), dataType.getName());
811 ToscaDataType toscaDataType = new ToscaDataType();
812 toscaDataType.setDerived_from(dataType.getDerivedFromName());
813 toscaDataType.setDescription(dataType.getDescription());
814 toscaDataType.setVersion(dataType.getVersion());
815 if (CollectionUtils.isNotEmpty(dataType.getProperties())) {
816 toscaDataType.setProperties(dataType.getProperties().stream()
817 .collect(Collectors.toMap(
818 PropertyDataDefinition::getName,
819 s -> propertyConvertor.convertProperty(dataTypes, s, PropertyType.PROPERTY),
820 (toscaPropertyTobeValidated, toscaProperty) -> validateToscaProperty(privateDataTypes, toscaPropertyTobeValidated, toscaProperty)
823 toscaDataTypeMap.put(dataType.getName(), toscaDataType);
825 toscaNode.setData_types(toscaDataTypeMap);
828 // Extracted to method for code reuse
829 return convertReqCapAndTypeName(componentsCache, component, toscaNode, nodeTypes, toscaNodeType, dataTypes);
832 private ToscaProperty validateToscaProperty(final List<DataTypeDefinition> privateDataTypes, final ToscaProperty toscaPropertyTobeValidated,
833 final ToscaProperty toscaProperty) {
834 final Optional<DataTypeDefinition> match = privateDataTypes.stream()
835 .filter(dataType -> dataType.getName().equals(toscaPropertyTobeValidated.getType())).findFirst();
836 return match.isPresent() ? toscaPropertyTobeValidated : toscaProperty;
839 private Map<String, ToscaAttribute> convertToToscaAttributes(final List<AttributeDefinition> attributeList,
840 final Map<String, DataTypeDefinition> dataTypes) {
841 if (CollectionUtils.isEmpty(attributeList)) {
842 return Collections.emptyMap();
844 final AttributeConverter converter = new AttributeConverter(dataTypes);
845 final Map<String, ToscaAttribute> toscaAttributeMap = new HashMap<>();
846 for (final AttributeDefinition attributeDefinition : attributeList) {
847 toscaAttributeMap.put(attributeDefinition.getName(), converter.convert(attributeDefinition));
849 return toscaAttributeMap;
852 private Either<ToscaTemplate, ToscaError> convertReqCapAndTypeName(Map<String, Component> componentsCache,
853 Component component, ToscaTemplate toscaNode,
854 Map<String, ToscaNodeType> nodeTypes,
855 ToscaNodeType toscaNodeType,
856 Map<String, DataTypeDefinition> dataTypes) {
857 Either<ToscaNodeType, ToscaError> capabilities = convertCapabilities(componentsCache, component, toscaNodeType,
859 if (capabilities.isRight()) {
860 return Either.right(capabilities.right().value());
862 toscaNodeType = capabilities.left().value();
863 log.debug("Capabilities converted for {}", component.getUniqueId());
865 Either<ToscaNodeType, ToscaError> requirements = capabilityRequirementConverter
866 .convertRequirements(componentsCache, component, toscaNodeType);
867 if (requirements.isRight()) {
868 return Either.right(requirements.right().value());
870 toscaNodeType = requirements.left().value();
871 log.debug("Requirements converted for {}", component.getUniqueId());
873 String toscaResourceName;
874 switch (component.getComponentType()) {
876 toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition()
877 .getMetadataDataDefinition()).getToscaResourceName();
880 toscaResourceName = SERVICE_NODE_TYPE_PREFIX
881 + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName();
884 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
885 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
888 nodeTypes.put(toscaResourceName, toscaNodeType);
889 toscaNode.setNode_types(nodeTypes);
890 log.debug("finish convert node type for {}", component.getUniqueId());
891 return Either.left(toscaNode);
894 private Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplates(final Component component,
895 final Map<String, Component> componentCache,
896 final Map<String, DataTypeDefinition> dataTypes,
897 final ToscaTopolgyTemplate topologyTemplate) {
899 final Map<String, List<ComponentInstanceProperty>> componentInstancesProperties = component.getComponentInstancesProperties();
900 final Map<String, List<ComponentInstanceAttribute>> componentInstancesAttributes = component.getComponentInstancesAttributes();
901 final Map<String, List<ComponentInstanceInput>> componentInstancesInputs = component.getComponentInstancesInputs();
902 final Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces = component.getComponentInstancesInterfaces();
903 final List<RequirementCapabilityRelDef> componentInstancesRelations = component.getComponentInstancesRelations();
905 Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplatesRes = null;
906 log.debug("start convert topology template for {} for type {}", component.getUniqueId(), component.getComponentType());
907 final Map<String, ToscaNodeTemplate> nodeTemplates = new HashMap<>();
909 Map<String, ToscaGroupTemplate> groupsMap = null;
910 for (final ComponentInstance componentInstance : component.getComponentInstances()) {
911 ToscaNodeTemplate nodeTemplate = new ToscaNodeTemplate();
912 if (MapUtils.isNotEmpty(componentInstance.getToscaArtifacts())) {
913 nodeTemplate.setArtifacts(convertToNodeTemplateArtifacts(componentInstance.getToscaArtifacts()));
915 nodeTemplate.setType(componentInstance.getToscaComponentName());
916 nodeTemplate.setDirectives(componentInstance.getDirectives());
917 nodeTemplate.setNode_filter(convertToNodeTemplateNodeFilterComponent(componentInstance.getNodeFilter()));
919 final Either<Component, Boolean> originComponentRes = capabilityRequirementConverter
920 .getOriginComponent(componentCache, componentInstance);
921 if (originComponentRes.isRight()) {
922 convertNodeTemplatesRes = Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
925 final Either<ToscaNodeTemplate, ToscaError> requirements = convertComponentInstanceRequirements(component, componentInstance,
926 componentInstancesRelations, nodeTemplate, originComponentRes.left().value(), componentCache);
927 if (requirements.isRight()) {
928 convertNodeTemplatesRes = Either.right(requirements.right().value());
931 final String instanceUniqueId = componentInstance.getUniqueId();
932 log.debug("Component instance Requirements converted for instance {}", instanceUniqueId);
934 nodeTemplate = requirements.left().value();
936 final Component originalComponent = componentCache.get(componentInstance.getActualComponentUid());
938 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
939 final Component componentOfProxy = componentCache.get(componentInstance.getComponentUid());
940 nodeTemplate.setMetadata(convertMetadata(componentOfProxy, true, componentInstance));
942 nodeTemplate.setMetadata(convertMetadata(originalComponent, true, componentInstance));
945 final Either<ToscaNodeTemplate, ToscaError> capabilities =
946 capabilityRequirementConverter.convertComponentInstanceCapabilities(componentInstance, dataTypes, nodeTemplate);
947 if (capabilities.isRight()) {
948 convertNodeTemplatesRes = Either.right(capabilities.right().value());
951 log.debug("Component instance Capabilities converted for instance {}", instanceUniqueId);
953 nodeTemplate = capabilities.left().value();
954 final Map<String, Object> props = new HashMap<>();
955 final Map<String, Object> attribs = new HashMap<>();
957 if (originalComponent.getComponentType() == ComponentTypeEnum.RESOURCE) {
958 // Adds the properties of parent component to map
959 addPropertiesOfParentComponent(dataTypes, originalComponent, props);
960 addAttributesOfParentComponent(originalComponent, attribs);
963 if (null != componentInstancesProperties && componentInstancesProperties.containsKey(instanceUniqueId)) {
964 addPropertiesOfComponentInstance(componentInstancesProperties, dataTypes, instanceUniqueId, props);
966 if (null != componentInstancesAttributes && componentInstancesAttributes.containsKey(instanceUniqueId)) {
967 addAttributesOfComponentInstance(componentInstancesAttributes, instanceUniqueId, attribs);
970 if (componentInstancesInputs != null
971 && componentInstancesInputs.containsKey(instanceUniqueId)
972 && !isComponentOfTypeServiceProxy(componentInstance)) {
973 //For service proxy the inputs are already handled under instance properties above
974 addComponentInstanceInputs(dataTypes, componentInstancesInputs, instanceUniqueId, props);
977 //M3[00001] - NODE TEMPLATE INTERFACES - START
978 handleInstanceInterfaces(componentInstanceInterfaces, componentInstance, dataTypes, nodeTemplate, instanceUniqueId, component);
979 //M3[00001] - NODE TEMPLATE INTERFACES - END
980 if (MapUtils.isNotEmpty(props)) {
981 nodeTemplate.setProperties(props);
983 if (MapUtils.isNotEmpty(attribs)) {
984 nodeTemplate.setAttributes(attribs);
987 final List<GroupInstance> groupInstances = componentInstance.getGroupInstances();
988 if (CollectionUtils.isNotEmpty(groupInstances)) {
989 if (groupsMap == null) {
990 groupsMap = new HashMap<>();
992 for (final GroupInstance groupInst : groupInstances) {
993 if (CollectionUtils.isNotEmpty(groupInst.getArtifacts())) {
994 groupsMap.put(groupInst.getName(), groupExportParser.getToscaGroupTemplate(groupInst, componentInstance.getInvariantName()));
999 nodeTemplates.put(componentInstance.getName(), nodeTemplate);
1001 if (groupsMap != null) {
1002 log.debug("instance groups added");
1003 topologyTemplate.addGroups(groupsMap);
1005 if (component.getComponentType() == ComponentTypeEnum.SERVICE && isNotEmpty(
1006 ((Service) component).getForwardingPaths())) {
1007 log.debug("Starting converting paths for component {}, name {}", component.getUniqueId(), component.getName());
1008 ForwardingPathToscaUtil
1009 .addForwardingPaths((Service) component, nodeTemplates, capabilityRequirementConverter, componentCache, toscaOperationFacade);
1010 log.debug("Finished converting paths for component {}, name {}", component.getUniqueId(), component.getName());
1012 if (convertNodeTemplatesRes == null) {
1013 convertNodeTemplatesRes = Either.left(nodeTemplates);
1015 log.debug("finish convert topology template for {} for type {}", component.getUniqueId(), component.getComponentType());
1016 return convertNodeTemplatesRes;
1019 private void handleInstanceInterfaces(
1020 Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces,
1021 ComponentInstance componentInstance, Map<String, DataTypeDefinition> dataTypes, ToscaNodeTemplate nodeTemplate,
1022 String instanceUniqueId,
1023 Component parentComponent) {
1025 if (MapUtils.isEmpty(componentInstanceInterfaces)
1026 || !componentInstanceInterfaces.containsKey(instanceUniqueId)) {
1027 nodeTemplate.setInterfaces(null);
1031 final List<ComponentInstanceInterface> currServiceInterfaces =
1032 componentInstanceInterfaces.get(instanceUniqueId);
1034 final Map<String, InterfaceDefinition> tmpInterfaces = new HashMap<>();
1035 currServiceInterfaces.forEach(instInterface -> tmpInterfaces.put(instInterface
1036 .getUniqueId(), instInterface));
1038 final Map<String, Object> interfaceMap = interfacesOperationsConverter
1039 .getInterfacesMap(parentComponent, componentInstance, tmpInterfaces, dataTypes, isComponentOfTypeServiceProxy(componentInstance),
1040 isComponentOfTypeServiceProxy(componentInstance));
1042 interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
1043 nodeTemplate.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap);
1046 private boolean isComponentOfTypeServiceProxy(ComponentInstance componentInstance) {
1047 return Objects.nonNull(componentInstance.getOriginType())
1048 && componentInstance.getOriginType().getValue().equals("Service Proxy");
1051 private void addComponentInstanceInputs(Map<String, DataTypeDefinition> dataTypes,
1052 Map<String, List<ComponentInstanceInput>> componentInstancesInputs,
1053 String instanceUniqueId, Map<String, Object> props) {
1055 List<ComponentInstanceInput> instanceInputsList = componentInstancesInputs.get(instanceUniqueId);
1056 if (instanceInputsList != null) {
1057 instanceInputsList.forEach(input -> {
1058 Supplier<String> supplier = () -> input.getValue() != null && !Objects.isNull(input.getValue()) ? input.getValue() : input.getDefaultValue();
1059 propertyConvertor.convertAndAddValue(dataTypes, props, input, supplier);
1064 private void addPropertiesOfComponentInstance(final Map<String, List<ComponentInstanceProperty>> componentInstancesProperties,
1065 final Map<String, DataTypeDefinition> dataTypes,
1066 final String instanceUniqueId,
1067 final Map<String, Object> props) {
1069 if (isNotEmpty(componentInstancesProperties)) {
1070 componentInstancesProperties.get(instanceUniqueId)
1071 // Converts and adds each value to property map
1072 .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop, prop::getValue));
1076 private void addAttributesOfComponentInstance(final Map<String, List<ComponentInstanceAttribute>> componentInstancesAttributes,
1077 final String instanceUniqueId,
1078 final Map<String, Object> attribs) {
1080 if (isNotEmpty(componentInstancesAttributes) && componentInstancesAttributes.containsKey(instanceUniqueId)) {
1081 componentInstancesAttributes.get(instanceUniqueId).stream()
1082 // Filters out Attributes with empty default values
1083 .filter(attributeDefinition -> StringUtils.isNotEmpty(attributeDefinition.getDefaultValue()))
1084 // Converts and adds each value to attribute map
1085 .forEach(attributeDefinition -> attributeConverter.convertAndAddValue(attribs, attributeDefinition));
1089 private void addPropertiesOfParentComponent(Map<String, DataTypeDefinition> dataTypes,
1090 Component componentOfInstance, Map<String, Object> props) {
1092 List<PropertyDefinition> componentProperties = componentOfInstance.getProperties();
1093 if (isNotEmpty(componentProperties)) {
1094 componentProperties.stream()
1095 // Filters out properties with empty default values
1096 .filter(prop -> StringUtils.isNotEmpty(prop.getDefaultValue()))
1097 // Converts and adds each value to property map
1098 .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop, prop::getDefaultValue));
1102 private void addAttributesOfParentComponent(final Component componentOfInstance, final Map<String, Object> attribs) {
1104 final List<AttributeDefinition> componentAttributes = componentOfInstance.getAttributes();
1105 if (isNotEmpty(componentAttributes)) {
1106 componentAttributes.stream()
1107 // Filters out Attributes with empty default values
1108 .filter(attrib -> StringUtils.isNotEmpty(attrib.getDefaultValue()))
1109 // Converts and adds each value to attribute map
1110 .forEach(attributeDefinition -> attributeConverter.convertAndAddValue(attribs, attributeDefinition));
1114 private ToscaNodeType createNodeType(Component component) {
1115 ToscaNodeType toscaNodeType = new ToscaNodeType();
1116 if (ModelConverter.isAtomicComponent(component)) {
1117 if (((Resource) component).getDerivedFrom() != null) {
1118 toscaNodeType.setDerived_from(((Resource) component).getDerivedFrom().get(0));
1120 toscaNodeType.setDescription(component.getDescription());
1122 String derivedFrom = null != component.getDerivedFromGenericType() ? component.getDerivedFromGenericType()
1124 toscaNodeType.setDerived_from(derivedFrom);
1126 return toscaNodeType;
1129 private Either<Map<String, Object>, ToscaError> createProxyInterfaceTypes(Component container) {
1131 Map<String, Object> proxyInterfaceTypes = new HashMap<>();
1132 Either<Map<String, Object>, ToscaError> res = Either.left(proxyInterfaceTypes);
1133 List<ComponentInstance> componentInstances = container.getComponentInstances();
1134 if (CollectionUtils.isEmpty(componentInstances)) {
1137 Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
1138 componentInstances.stream()
1139 .filter(this::isComponentOfTypeServiceProxy)
1140 .forEach(inst -> serviceProxyInstanceList.put(inst.getToscaComponentName(), inst));
1141 if (MapUtils.isEmpty(serviceProxyInstanceList)) {
1144 for (Entry<String, ComponentInstance> entryProxy : serviceProxyInstanceList.entrySet()) {
1145 Component serviceComponent;
1146 ComponentParametersView componentParametersView = new ComponentParametersView();
1147 componentParametersView.disableAll();
1148 componentParametersView.setIgnoreInterfaces(false);
1149 Either<Component, StorageOperationStatus> service = toscaOperationFacade
1150 .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
1151 if (service.isRight()) {
1152 log.debug("Failed to fetch original service component with id {} for instance {}",
1153 entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName());
1154 return Either.right(ToscaError.GENERAL_ERROR);
1156 serviceComponent = service.left().value();
1159 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither =
1160 interfaceLifecycleOperation.getAllInterfaceLifecycleTypes(serviceComponent.getModel());
1161 if (lifecycleTypeEither.isRight()) {
1162 log.debug("Failed to retrieve global interface types :", lifecycleTypeEither.right().value());
1163 return Either.right(ToscaError.GENERAL_ERROR);
1166 List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value().values().stream()
1167 .map(InterfaceDataDefinition::getType)
1168 .collect(Collectors.toList());
1169 //Add interface types for local interfaces in the original service component for proxy
1170 Map<String, Object> localInterfaceTypes = addInterfaceTypeElement(serviceComponent,
1171 allGlobalInterfaceTypes);
1172 if (MapUtils.isNotEmpty(localInterfaceTypes)) {
1173 proxyInterfaceTypes.putAll(localInterfaceTypes);
1177 return Either.left(proxyInterfaceTypes);
1180 private Either<Map<String, ToscaNodeType>, ToscaError> createProxyNodeTypes(Map<String, Component> componentCache,
1181 Component container) {
1183 Map<String, ToscaNodeType> nodeTypesMap = new HashMap<>();
1184 Either<Map<String, ToscaNodeType>, ToscaError> res = Either.left(nodeTypesMap);
1186 List<ComponentInstance> componentInstances = container.getComponentInstances();
1188 if (componentInstances == null || componentInstances.isEmpty()) {
1191 Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
1192 List<ComponentInstance> proxyInst = componentInstances.stream()
1193 .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceProxy.name()))
1194 .collect(Collectors.toList());
1195 if (proxyInst != null && !proxyInst.isEmpty()) {
1196 for (ComponentInstance inst : proxyInst) {
1197 serviceProxyInstanceList.put(inst.getToscaComponentName(), inst);
1201 if (serviceProxyInstanceList.isEmpty()) {
1204 Either<Resource, StorageOperationStatus> serviceProxyOrigin = toscaOperationFacade
1205 .getLatestByName("serviceProxy", null);
1206 if (serviceProxyOrigin.isRight()) {
1207 log.debug("Failed to fetch normative service proxy resource by tosca name, error {}",
1208 serviceProxyOrigin.right().value());
1209 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
1211 Component origComponent = serviceProxyOrigin.left().value();
1213 for (Entry<String, ComponentInstance> entryProxy : serviceProxyInstanceList.entrySet()) {
1214 Component serviceComponent = null;
1215 ComponentParametersView componentParametersView = new ComponentParametersView();
1216 componentParametersView.disableAll();
1217 componentParametersView.setIgnoreCategories(false);
1218 componentParametersView.setIgnoreProperties(false);
1219 componentParametersView.setIgnoreInputs(false);
1220 componentParametersView.setIgnoreInterfaces(false);
1221 componentParametersView.setIgnoreRequirements(false);
1222 Either<Component, StorageOperationStatus> service = toscaOperationFacade
1223 .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
1224 if (service.isRight()) {
1225 log.debug("Failed to fetch resource with id {} for instance {}",
1226 entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName());
1228 serviceComponent = service.left().value();
1231 ToscaNodeType toscaNodeType = createProxyNodeType(componentCache, origComponent, serviceComponent,
1232 entryProxy.getValue());
1233 nodeTypesMap.put(entryProxy.getKey(), toscaNodeType);
1236 return Either.left(nodeTypesMap);
1239 private void createServiceSubstitutionNodeTypes(final Map<String, Component> componentCache,
1240 final Component container, final ToscaTemplate toscaNode) {
1241 final List<ComponentInstance> componentInstances = container.getComponentInstances();
1243 if (CollectionUtils.isEmpty(componentInstances)) {
1246 final List<ComponentInstance> serviceSubstitutionInstanceList = componentInstances.stream()
1247 .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceSubstitution.name()))
1248 .collect(Collectors.toList());
1249 if (CollectionUtils.isNotEmpty(serviceSubstitutionInstanceList)) {
1250 for (ComponentInstance inst : serviceSubstitutionInstanceList) {
1251 final Map<String, ToscaNodeType> nodeTypes =
1252 toscaNode.getNode_types() == null ? new HashMap<>() : toscaNode.getNode_types();
1253 convertInterfaceNodeType(new HashMap<>(), componentCache.get(inst.getSourceModelUid()), toscaNode,
1259 private ToscaNodeType createProxyNodeType(Map<String, Component> componentCache, Component origComponent,
1260 Component proxyComponent, ComponentInstance componentInstance) {
1261 ToscaNodeType toscaNodeType = new ToscaNodeType();
1262 String derivedFrom = ((Resource) origComponent).getToscaResourceName();
1264 toscaNodeType.setDerived_from(derivedFrom);
1265 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = applicationDataTypeCache.getAll(origComponent.getModel());
1266 if (dataTypesEither.isRight()) {
1267 log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
1269 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
1270 Map<String, ToscaCapability> capabilities = this.capabilityRequirementConverter
1271 .convertProxyCapabilities(componentCache, componentInstance, dataTypes);
1273 if (MapUtils.isNotEmpty(capabilities)) {
1274 toscaNodeType.setCapabilities(capabilities);
1276 List<Map<String, ToscaRequirement>> proxyNodeTypeRequirements = this.capabilityRequirementConverter
1277 .convertProxyRequirements(componentCache, componentInstance);
1278 if (CollectionUtils.isNotEmpty(proxyNodeTypeRequirements)) {
1279 toscaNodeType.setRequirements(proxyNodeTypeRequirements);
1281 Optional<Map<String, ToscaProperty>> proxyProperties = getProxyNodeTypeProperties(proxyComponent, dataTypes);
1282 proxyProperties.ifPresent(toscaNodeType::setProperties);
1284 Map<String, Object> interfaceMap = new HashMap<>();
1285 if (MapUtils.isEmpty(componentInstance.getInterfaces())) {
1286 final Optional<Map<String, Object>> proxyInterfaces = getProxyNodeTypeInterfaces(proxyComponent, dataTypes);
1287 if (proxyInterfaces.isPresent()) {
1288 interfaceMap = proxyInterfaces.get();
1291 interfaceMap = interfacesOperationsConverter
1292 .getInterfacesMapFromComponentInstance(proxyComponent, componentInstance, dataTypes, false, false);
1295 interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
1296 toscaNodeType.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap);
1298 return toscaNodeType;
1301 private Either<ToscaNodeTemplate, ToscaError> convertComponentInstanceRequirements(Component component,
1302 ComponentInstance componentInstance,
1303 List<RequirementCapabilityRelDef> relations,
1304 ToscaNodeTemplate nodeTypeTemplate,
1305 Component originComponent,
1306 Map<String, Component> componentCache) {
1308 final List<RequirementCapabilityRelDef> requirementDefinitionList = filterRequirements(componentInstance,
1310 if (isNotEmpty(requirementDefinitionList)) {
1312 final List<Map<String, ToscaTemplateRequirement>> toscaRequirements = buildRequirements(component, componentInstance, requirementDefinitionList, originComponent, componentCache);
1313 if (!toscaRequirements.isEmpty()) {
1314 nodeTypeTemplate.setRequirements(toscaRequirements);
1316 } catch (final Exception e) {
1317 log.debug("Failed to convert component instance requirements for the component instance {}. ",
1318 componentInstance.getName(), e);
1319 return Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
1322 log.debug("Finished to convert requirements for the node type {} ", componentInstance.getName());
1323 return Either.left(nodeTypeTemplate);
1326 private List<Map<String, ToscaTemplateRequirement>> buildRequirements(final Component component,
1327 final ComponentInstance componentInstance,
1328 final List<RequirementCapabilityRelDef> filteredRelations,
1329 final Component originComponent,
1330 final Map<String, Component> componentCache)
1331 throws ToscaExportException {
1333 final List<Map<String, ToscaTemplateRequirement>> toscaRequirements = new ArrayList<>();
1334 for (RequirementCapabilityRelDef relationshipDefinition : filteredRelations) {
1335 final Map<String, ToscaTemplateRequirement> toscaTemplateRequirementMap =
1336 buildRequirement(componentInstance, originComponent, component.getComponentInstances(), relationshipDefinition, componentCache);
1337 toscaRequirements.add(toscaTemplateRequirementMap);
1340 return toscaRequirements;
1343 private List<RequirementCapabilityRelDef> filterRequirements(ComponentInstance componentInstance,
1344 List<RequirementCapabilityRelDef> relations) {
1345 return relations.stream()
1346 .filter(p -> componentInstance.getUniqueId().equals(p.getFromNode())).collect(Collectors.toList());
1349 private Map<String, ToscaTemplateRequirement> buildRequirement(final ComponentInstance fromInstance,
1350 final Component fromOriginComponent,
1351 final List<ComponentInstance> instancesList,
1352 final RequirementCapabilityRelDef relationshipDefinition,
1353 final Map<String, Component> componentCache)
1354 throws ToscaExportException {
1356 final Map<String, List<RequirementDefinition>> reqMap = fromOriginComponent.getRequirements();
1357 final CapabilityRequirementRelationship capabilityRequirementRelationship = relationshipDefinition
1358 .getRelationships().get(0);
1359 final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation();
1361 final ComponentInstance toInstance = instancesList.stream()
1362 .filter(i -> relationshipDefinition.getToNode().equals(i.getUniqueId()))
1363 .findFirst().orElse(null);
1364 if (toInstance == null) {
1365 final String errorMsg = String
1366 .format("Failed to find a relation from the node %s to the node %s", fromInstance.getName(),
1367 relationshipDefinition.getToNode());
1368 log.debug(errorMsg);
1369 throw new ToscaExportException(errorMsg);
1371 final Optional<RequirementDefinition> reqOpt =
1372 findRequirement(fromOriginComponent, reqMap, relationshipInfo, fromInstance.getUniqueId());
1373 if (reqOpt.isEmpty()) {
1374 final String errorMsg = String
1375 .format("Failed to find a requirement with uniqueId %s on a component with uniqueId %s",
1376 relationshipInfo.getRequirementUid(), fromOriginComponent.getUniqueId());
1377 log.debug(errorMsg);
1378 throw new ToscaExportException(errorMsg);
1380 final ComponentParametersView filter = new ComponentParametersView(true);
1381 filter.setIgnoreComponentInstances(false);
1382 filter.setIgnoreCapabilities(false);
1383 filter.setIgnoreGroups(false);
1384 final Either<Component, StorageOperationStatus> getOriginRes =
1385 toscaOperationFacade.getToscaElement(toInstance.getActualComponentUid(), filter);
1386 if (getOriginRes.isRight()) {
1387 final String errorMsg = String.format(
1388 "Failed to build substituted name for the requirement %s. "
1389 + "Failed to get an origin component with uniqueId %s",
1390 reqOpt.get().getName(), toInstance.getActualComponentUid());
1391 log.debug(errorMsg);
1392 throw new ToscaExportException(errorMsg);
1394 final Component toOriginComponent = getOriginRes.left().value();
1395 Optional<CapabilityDefinition> capOpt = toOriginComponent.getCapabilities().get(reqOpt.get().getCapability()).stream()
1396 .filter(c -> isCapabilityBelongToRelation(relationshipInfo, c)).findFirst();
1397 if (capOpt.isEmpty()) {
1398 capOpt = findCapability(relationshipInfo, toOriginComponent, fromOriginComponent, reqOpt.get());
1399 if (capOpt.isEmpty()) {
1400 final String errorMsg = String
1401 .format("Failed to find a capability with name %s on a component with uniqueId %s",
1402 relationshipInfo.getCapability(), fromOriginComponent.getUniqueId());
1403 log.debug(errorMsg);
1404 throw new ToscaExportException(errorMsg);
1407 return buildRequirement(fromOriginComponent, toOriginComponent, capOpt.get(), reqOpt.get(),
1408 capabilityRequirementRelationship, toInstance, componentCache);
1411 private boolean isCapabilityBelongToRelation(RelationshipInfo reqAndRelationshipPair,
1412 CapabilityDefinition capability) {
1413 return capability.getName().equals(reqAndRelationshipPair.getCapability()) && (capability.getOwnerId() != null
1414 && capability.getOwnerId().equals(reqAndRelationshipPair.getCapabilityOwnerId()));
1417 private Optional<CapabilityDefinition> findCapability(RelationshipInfo reqAndRelationshipPair,
1418 Component toOriginComponent, Component fromOriginComponent,
1419 RequirementDefinition requirement) {
1420 Optional<CapabilityDefinition> cap = toOriginComponent.getCapabilities().get(requirement.getCapability())
1421 .stream().filter(c -> c.getType().equals(requirement.getCapability())).findFirst();
1422 if (!cap.isPresent()) {
1423 log.debug("Failed to find a capability with name {} on a component with uniqueId {}",
1424 reqAndRelationshipPair.getCapability(), fromOriginComponent.getUniqueId());
1429 private Map<String, ToscaTemplateRequirement> buildRequirement(final Component fromOriginComponent,
1430 final Component toOriginComponent,
1431 final CapabilityDefinition capability,
1432 final RequirementDefinition requirement,
1433 final CapabilityRequirementRelationship capabilityRequirementRelationship,
1434 final ComponentInstance toInstance,
1435 final Map<String, Component> componentCache)
1436 throws ToscaExportException {
1438 List<String> reducedPath = capability.getPath();
1439 if (capability.getOwnerId() != null) {
1440 reducedPath = capabilityRequirementConverter
1441 .getReducedPathByOwner(capability.getPath(), capability.getOwnerId());
1443 final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation();
1444 final Either<String, Boolean> capabilityNameEither = capabilityRequirementConverter.buildSubstitutedName(componentCache,
1445 toOriginComponent, reducedPath, relationshipInfo.getCapability(), capability.getPreviousName(), capability.getExternalName());
1446 if (capabilityNameEither.isRight()) {
1447 final String errorMsg = String.format(
1448 "Failed to build a substituted capability name for the capability with name %s on a component with uniqueId %s",
1449 capabilityRequirementRelationship.getCapability(), toOriginComponent.getUniqueId());
1452 throw new ToscaExportException(errorMsg);
1454 final Either<String, Boolean> requirementNameEither = capabilityRequirementConverter
1455 .buildSubstitutedName(componentCache, fromOriginComponent,
1456 requirement.getPath(), relationshipInfo.getRequirement(), requirement.getPreviousName(), requirement.getExternalName());
1457 if (requirementNameEither.isRight()) {
1458 final String errorMsg = String.format("Failed to build a substituted requirement name for the requirement "
1459 + "with name %s on a component with uniqueId %s",
1460 capabilityRequirementRelationship.getRequirement(), fromOriginComponent.getUniqueId());
1461 log.debug(errorMsg);
1462 throw new ToscaExportException(errorMsg);
1464 final ToscaTemplateRequirement toscaRequirement = new ToscaTemplateRequirement();
1465 final Map<String, ToscaTemplateRequirement> toscaReqMap = new HashMap<>();
1466 toscaRequirement.setNode(toInstance.getName());
1467 toscaRequirement.setCapability(capabilityNameEither.left().value());
1468 if (isNotEmpty(capabilityRequirementRelationship.getOperations())) {
1469 toscaRequirement.setRelationship(new ToscaRelationshipBuilder().from(capabilityRequirementRelationship));
1471 toscaReqMap.put(requirementNameEither.left().value(), toscaRequirement);
1475 private Optional<RequirementDefinition> findRequirement(Component fromOriginComponent,
1476 Map<String, List<RequirementDefinition>> reqMap,
1477 RelationshipInfo reqAndRelationshipPair,
1478 String fromInstanceId) {
1479 for (List<RequirementDefinition> reqList : reqMap.values()) {
1480 Optional<RequirementDefinition> reqOpt = reqList.stream().filter(
1481 r -> isRequirementBelongToRelation(fromOriginComponent, reqAndRelationshipPair, r, fromInstanceId))
1483 if (reqOpt.isPresent()) {
1487 return Optional.empty();
1491 * Allows detecting the requirement belonging to the received relationship The detection logic is: A requirement belongs to a relationship IF
1492 * 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
1493 * requirement equals to requirementOwnerId of the relation OR uniqueId of toInstance equals to capabilityOwnerId of the relation
1495 private boolean isRequirementBelongToRelation(Component originComponent, RelationshipInfo reqAndRelationshipPair,
1496 RequirementDefinition requirement, String fromInstanceId) {
1497 if (!StringUtils.equals(requirement.getName(), reqAndRelationshipPair.getRequirement())) {
1498 log.debug("Failed to find a requirement with name {} and reqAndRelationshipPair {}", requirement.getName(),
1499 reqAndRelationshipPair.getRequirement());
1502 return ModelConverter.isAtomicComponent(originComponent) || isRequirementBelongToOwner(reqAndRelationshipPair, requirement, fromInstanceId,
1506 private boolean isRequirementBelongToOwner(RelationshipInfo reqAndRelationshipPair, RequirementDefinition requirement, String fromInstanceId,
1507 Component originComponent) {
1508 return StringUtils.equals(requirement.getOwnerId(), reqAndRelationshipPair.getRequirementOwnerId()) || (
1509 isCvfc(originComponent) && StringUtils.equals(fromInstanceId, reqAndRelationshipPair.getRequirementOwnerId()) || StringUtils
1510 .equals(requirement.getOwnerId(), originComponent.getUniqueId()));
1513 private boolean isCvfc(Component component) {
1514 return component.getComponentType() == ComponentTypeEnum.RESOURCE && ((Resource) component).getResourceType() == ResourceTypeEnum.CVFC;
1517 private Either<Map<String, String[]>, ToscaError> convertSubstitutionMappingCapabilities(final Component component,
1518 final Map<String, Component> componentCache) {
1519 Either<Map<String, String[]>, ToscaError> toscaCapabilitiesRes =
1520 capabilityRequirementConverter.convertSubstitutionMappingCapabilities(componentCache, component);
1521 if (toscaCapabilitiesRes.isRight()) {
1522 log.debug("Failed convert capabilities for the component {}. ", component.getName());
1523 return Either.right(toscaCapabilitiesRes.right().value());
1525 if (isNotEmpty(toscaCapabilitiesRes.left().value())) {
1526 log.debug("Finish convert capabilities for the component {}. ", component.getName());
1527 return Either.left(toscaCapabilitiesRes.left().value());
1529 log.debug("Finished to convert capabilities for the component {}. ", component.getName());
1531 return Either.left(Collections.emptyMap());
1534 private Either<ToscaNodeType, ToscaError> convertCapabilities(Map<String, Component> componentsCache, Component component, ToscaNodeType nodeType,
1535 Map<String, DataTypeDefinition> dataTypes) {
1536 Map<String, ToscaCapability> toscaCapabilities = capabilityRequirementConverter.convertCapabilities(componentsCache, component, dataTypes);
1537 if (!toscaCapabilities.isEmpty()) {
1538 nodeType.setCapabilities(toscaCapabilities);
1540 log.debug("Finish convert Capabilities for node type");
1541 return Either.left(nodeType);
1544 private Map<String, ToscaTemplateArtifact> convertToNodeTemplateArtifacts(Map<String, ToscaArtifactDataDefinition> artifacts) {
1545 if (artifacts == null) {
1548 Map<String, ToscaTemplateArtifact> arts = new HashMap<>();
1549 for (Map.Entry<String, ToscaArtifactDataDefinition> entry : artifacts.entrySet()) {
1550 ToscaTemplateArtifact artifact = new ToscaTemplateArtifact();
1551 artifact.setFile(entry.getValue().getFile());
1552 artifact.setType(entry.getValue().getType());
1553 artifact.setProperties(entry.getValue().getProperties());
1554 arts.put(entry.getKey(), artifact);
1559 private NodeFilter convertToNodeTemplateNodeFilterComponent(CINodeFilterDataDefinition inNodeFilter) {
1560 if (inNodeFilter == null) {
1563 NodeFilter nodeFilter = new NodeFilter();
1564 ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities = inNodeFilter.getCapabilities();
1565 ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> origProperties = inNodeFilter.getProperties();
1566 List<Map<String, CapabilityFilter>> capabilitiesCopy = new ArrayList<>();
1567 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1568 copyNodeFilterCapabilitiesTemplate(origCapabilities, capabilitiesCopy);
1569 copyNodeFilterProperties(origProperties, propertiesCopy);
1570 if (CollectionUtils.isNotEmpty(capabilitiesCopy)) {
1571 nodeFilter.setCapabilities(capabilitiesCopy);
1573 if (CollectionUtils.isNotEmpty(propertiesCopy)) {
1574 nodeFilter.setProperties(propertiesCopy);
1576 nodeFilter.setTosca_id(cloneToscaId(inNodeFilter.getTosca_id()));
1577 nodeFilter = (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
1581 private NodeFilter convertToSubstitutionFilterComponent(final SubstitutionFilterDataDefinition substitutionFilterDataDefinition) {
1582 if (substitutionFilterDataDefinition == null) {
1585 NodeFilter nodeFilter = new NodeFilter();
1586 ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> origProperties = substitutionFilterDataDefinition.getProperties();
1587 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1588 copySubstitutionFilterProperties(origProperties, propertiesCopy);
1589 if (CollectionUtils.isNotEmpty(propertiesCopy)) {
1590 nodeFilter.setProperties(propertiesCopy);
1592 nodeFilter.setTosca_id(cloneToscaId(substitutionFilterDataDefinition.getTosca_id()));
1593 return (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
1596 private Object cloneToscaId(Object toscaId) {
1597 return Objects.isNull(toscaId) ? null : cloneObjectFromYml(toscaId, toscaId.getClass());
1600 private Object cloneObjectFromYml(Object objToClone, Class classOfObj) {
1601 String objectAsYml = yamlUtil.objectToYaml(objToClone);
1602 return yamlUtil.yamlToObject(objectAsYml, classOfObj);
1605 private void copyNodeFilterCapabilitiesTemplate(ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities,
1606 List<Map<String, CapabilityFilter>> capabilitiesCopy) {
1607 if (origCapabilities == null || origCapabilities.getListToscaDataDefinition() == null || origCapabilities.getListToscaDataDefinition()
1611 for (RequirementNodeFilterCapabilityDataDefinition capability : origCapabilities.getListToscaDataDefinition()) {
1612 Map<String, CapabilityFilter> capabilityFilterCopyMap = new HashMap<>();
1613 CapabilityFilter capabilityFilter = new CapabilityFilter();
1614 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1615 copyNodeFilterProperties(capability.getProperties(), propertiesCopy);
1616 capabilityFilter.setProperties(propertiesCopy);
1617 capabilityFilterCopyMap.put(capability.getName(), capabilityFilter);
1618 capabilitiesCopy.add(capabilityFilterCopyMap);
1622 private void copyNodeFilterProperties(ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> origProperties,
1623 List<Map<String, List<Object>>> propertiesCopy) {
1624 if (origProperties == null || origProperties.getListToscaDataDefinition() == null || origProperties.isEmpty()) {
1627 Map<String, List<Object>> propertyMapCopy = new HashMap<>();
1628 for (RequirementNodeFilterPropertyDataDefinition propertyDataDefinition : origProperties.getListToscaDataDefinition()) {
1629 for (String propertyInfoEntry : propertyDataDefinition.getConstraints()) {
1630 Map<String, List<Object>> propertyValObj = new YamlUtil().yamlToObject(propertyInfoEntry, Map.class);
1631 String propertyName = propertyDataDefinition.getName();
1632 if (propertyMapCopy.containsKey(propertyName)) {
1633 addPropertyConstraintValueToList(propertyName, propertyValObj, propertyMapCopy.get(propertyName));
1635 if (propertyName != null) {
1636 List<Object> propsList = new ArrayList<>();
1637 addPropertyConstraintValueToList(propertyName, propertyValObj, propsList);
1638 propertyMapCopy.put(propertyName, propsList);
1640 propertyMapCopy.putAll(propertyValObj);
1645 propertyMapCopy.entrySet().stream().forEach(entry -> addCalculatedConstraintsIntoPropertiesList(propertiesCopy, entry));
1648 private void copySubstitutionFilterProperties(final ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> origProperties,
1649 final List<Map<String, List<Object>>> propertiesCopy) {
1650 if (origProperties == null || origProperties.getListToscaDataDefinition() == null || origProperties.isEmpty()) {
1653 final Map<String, List<Object>> propertyMapCopy = new HashMap<>();
1654 for (final RequirementSubstitutionFilterPropertyDataDefinition propertyDataDefinition : origProperties.getListToscaDataDefinition()) {
1655 for (final String propertyInfoEntry : propertyDataDefinition.getConstraints()) {
1656 final Map<String, List<Object>> propertyValObj = new YamlUtil().yamlToObject(propertyInfoEntry, Map.class);
1657 final String propertyName = propertyDataDefinition.getName();
1658 if (propertyMapCopy.containsKey(propertyName)) {
1659 addPropertyConstraintValueToList(propertyName, propertyValObj, propertyMapCopy.get(propertyName));
1661 if (propertyName != null) {
1662 final List<Object> propsList = new ArrayList<>();
1663 addPropertyConstraintValueToList(propertyName, propertyValObj, propsList);
1664 propertyMapCopy.put(propertyName, propsList);
1666 propertyMapCopy.putAll(propertyValObj);
1671 propertyMapCopy.entrySet().forEach(entry -> addCalculatedConstraintsIntoPropertiesList(propertiesCopy, entry));
1674 private void addPropertyConstraintValueToList(String propertyName, Map<String, List<Object>> propertyValObj, List<Object> propsList) {
1675 if (propertyValObj.containsKey(propertyName)) {
1676 propsList.add(propertyValObj.get(propertyName));
1678 propsList.add(propertyValObj);
1682 private void addCalculatedConstraintsIntoPropertiesList(List<Map<String, List<Object>>> propertiesCopy, Entry<String, List<Object>> entry) {
1683 Map<String, List<Object>> tempMap = new HashMap<>();
1684 tempMap.put(entry.getKey(), entry.getValue());
1685 propertiesCopy.add(tempMap);
1688 private Map<String, String[]> buildSubstitutionMappingPropertyMapping(final Component component) {
1689 if (component == null || CollectionUtils.isEmpty(component.getInputs())) {
1690 return Collections.emptyMap();
1692 return component.getInputs().stream().filter(InputDefinition::isMappedToComponentProperty).map(PropertyDataDefinition::getName)
1693 .collect(Collectors.toMap(inputName -> inputName, inputName -> new String[]{inputName}, (inputName1, inputName2) -> inputName1));
1696 private Map<String, String[]> buildSubstitutionMappingAttributesMapping(final Component component) {
1697 if (component == null || CollectionUtils.isEmpty(component.getOutputs())) {
1698 return Collections.emptyMap();
1700 return component.getOutputs().stream().map(AttributeDataDefinition::getName)
1701 .collect(Collectors.toMap(outputName -> outputName, outputName -> new String[]{outputName}, (outputName1, outputName2) -> outputName1));
1704 Optional<Map<String, ToscaProperty>> getProxyNodeTypeProperties(Component proxyComponent, Map<String, DataTypeDefinition> dataTypes) {
1705 if (Objects.isNull(proxyComponent)) {
1706 return Optional.empty();
1708 Map<String, ToscaProperty> proxyProperties = new HashMap<>();
1709 addInputsToProperties(dataTypes, proxyComponent.getInputs(), proxyProperties);
1710 if (CollectionUtils.isNotEmpty(proxyComponent.getProperties())) {
1711 proxyProperties.putAll(proxyComponent.getProperties().stream()
1712 .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, proxyComponent.getInputs())).collect(Collectors
1713 .toMap(PropertyDataDefinition::getName,
1714 property -> propertyConvertor.convertProperty(dataTypes, property, PropertyConvertor.PropertyType.PROPERTY))));
1716 return MapUtils.isNotEmpty(proxyProperties) ? Optional.of(proxyProperties) : Optional.empty();
1719 void addInputsToProperties(Map<String, DataTypeDefinition> dataTypes, List<InputDefinition> componentInputs,
1720 Map<String, ToscaProperty> mergedProperties) {
1721 if (CollectionUtils.isEmpty(componentInputs)) {
1724 for (InputDefinition input : componentInputs) {
1725 ToscaProperty property = propertyConvertor.convertProperty(dataTypes, input, PropertyConvertor.PropertyType.INPUT);
1726 mergedProperties.put(input.getName(), property);
1730 Optional<Map<String, Object>> getProxyNodeTypeInterfaces(Component proxyComponent, Map<String, DataTypeDefinition> dataTypes) {
1731 if (Objects.isNull(proxyComponent) || MapUtils.isEmpty(proxyComponent.getInterfaces())) {
1732 return Optional.empty();
1734 Map<String, InterfaceDefinition> proxyComponentInterfaces = proxyComponent.getInterfaces();
1735 //Unset artifact path for operation implementation for proxy node types as for operations with artifacts it is
1737 // always available in the proxy node template
1738 removeOperationImplementationForProxyNodeType(proxyComponentInterfaces);
1740 .ofNullable(interfacesOperationsConverter.getInterfacesMap(proxyComponent, null, proxyComponentInterfaces, dataTypes, false, false));
1743 private static class CustomRepresenter extends Representer {
1745 CustomRepresenter() {
1747 this.representers.put(ToscaPropertyAssignment.class, new RepresentToscaPropertyAssignment());
1748 this.representers.put(ToscaAttribute.class, new RepresentToscaAttribute());
1749 // null representer is exceptional and it is stored as an instance
1752 this.nullRepresenter = new RepresentNull();
1755 public boolean validateGetInputValue(final Object valueObj) {
1756 if (!(valueObj instanceof List) && !(valueObj instanceof String)) {
1759 if (valueObj instanceof List) {
1760 return ((List) valueObj).size() > 1;
1765 public boolean validateGetPropertyOrAttributeValue(final Object valueObj) {
1766 if (valueObj instanceof List) {
1767 return ((List) valueObj).size() > 1;
1773 protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue, Tag customTag) {
1774 if (propertyValue == null) {
1777 // skip not relevant for Tosca property
1778 if ("dependencies".equals(property.getName())) {
1781 if (javaBean instanceof ToscaRelationshipTemplate && "name".equals(property.getName())) {
1784 removeDefaultP(propertyValue);
1785 NodeTuple defaultNode = super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
1786 if (javaBean instanceof ToscaTopolgyTemplate && "relationshipTemplates".equals(property.getName())) {
1787 return new NodeTuple(representData("relationship_templates"), defaultNode.getValueNode());
1789 return "_defaultp_".equals(property.getName()) ? new NodeTuple(representData("default"), defaultNode.getValueNode()) : defaultNode;
1792 private void removeDefaultP(final Object propertyValue) {
1793 if (propertyValue instanceof Map) {
1794 final Map mapPropertyValue = ((Map) propertyValue);
1795 final Iterator<Entry> iter = mapPropertyValue.entrySet().iterator();
1796 Object defaultValue = null;
1797 while (iter.hasNext()) {
1798 final Map.Entry entry = iter.next();
1799 if ("_defaultp_".equals(entry.getKey())) {
1800 defaultValue = entry.getValue();
1802 } else if (entry.getValue() instanceof Map) {
1803 removeDefaultP(entry.getValue());
1806 if (defaultValue != null) {
1807 mapPropertyValue.putIfAbsent("default", defaultValue);
1813 protected MappingNode representJavaBean(Set<Property> properties, Object javaBean) {
1814 // remove the bean type from the output yaml (!! ...)
1815 if (!classTags.containsKey(javaBean.getClass())) {
1816 addClassTag(javaBean.getClass(), Tag.MAP);
1818 return super.representJavaBean(properties, javaBean);
1821 private class RepresentToscaAttribute implements Represent {
1824 public Node representData(Object data) {
1825 final ToscaAttribute toscaAttribute = (ToscaAttribute) data;
1826 return represent(toscaAttribute.asToscaMap());
1830 private class RepresentToscaPropertyAssignment implements Represent {
1832 public Node representData(Object data) {
1833 final ToscaPropertyAssignment toscaOperationAssignment = (ToscaPropertyAssignment) data;
1834 if (toscaOperationAssignment.getValue() instanceof String) {
1835 final String stringValue = (String) toscaOperationAssignment.getValue();
1836 if (isPropertyOrAttributeFunction(stringValue)) {
1837 return representGetAttribute(stringValue);
1839 return representScalar(Tag.STR, stringValue);
1841 return represent(null);
1844 public Node representGetAttribute(final String getAttributeFunction) {
1845 return represent(new Yaml().load(getAttributeFunction));
1848 public boolean isPropertyOrAttributeFunction(final String value) {
1850 final Yaml yaml = new Yaml();
1851 final Object yamlObj = yaml.load(value);
1852 if (!(yamlObj instanceof Map)) {
1855 final Map<String, Object> getAttributeMap = (Map) yamlObj;
1856 if (getAttributeMap.size() != 1) {
1859 final List<String> functionList = Arrays
1860 .asList(GET_ATTRIBUTE.getFunctionName(), GET_INPUT.getFunctionName(), GET_PROPERTY.getFunctionName());
1861 final Optional<String> function = getAttributeMap.keySet().stream()
1862 .filter(key -> functionList.stream().anyMatch(function1 -> function1.equals(key))).findFirst();
1863 if (function.isEmpty()) {
1866 final String functionName = function.get();
1867 final Object getAttributeValueObj = getAttributeMap.get(functionName);
1868 if (GET_INPUT.getFunctionName().equals(functionName)) {
1869 return validateGetInputValue(getAttributeValueObj);
1871 return validateGetPropertyOrAttributeValue(getAttributeValueObj);
1873 } catch (final Exception ignored) {
1879 private class RepresentNull implements Represent {
1882 public Node representData(Object data) {
1883 // possible values are here http://yaml.org/type/null.html
1884 return representScalar(Tag.NULL, "");
1889 private static class UnsortedPropertyUtils extends PropertyUtils {
1892 protected Set<Property> createPropertySet(Class type, BeanAccess bAccess) {
1893 Collection<Property> fields = getPropertiesMap(type, BeanAccess.FIELD).values();
1894 return new LinkedHashSet<>(fields);
1898 private Configuration getConfiguration() {
1899 return ConfigurationManager.getConfigurationManager().getConfiguration();