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