2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
20 package org.openecomp.sdc.be.tosca;
22 import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
23 import static org.apache.commons.collections.MapUtils.isNotEmpty;
24 import static org.openecomp.sdc.be.components.utils.PropertiesUtils.resolvePropertyValueFromInput;
25 import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_ATTRIBUTE;
26 import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_INPUT;
27 import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_PROPERTY;
29 import com.fasterxml.jackson.databind.ObjectMapper;
30 import com.google.common.primitives.Ints;
31 import com.google.gson.JsonElement;
32 import com.google.gson.JsonObject;
33 import com.google.gson.JsonParser;
34 import com.google.gson.stream.JsonReader;
35 import fj.data.Either;
37 import java.io.StringReader;
38 import java.nio.file.Path;
39 import java.util.ArrayList;
40 import java.util.Arrays;
41 import java.util.Collection;
42 import java.util.Collections;
43 import java.util.HashMap;
44 import java.util.HashSet;
45 import java.util.Iterator;
46 import java.util.LinkedHashMap;
47 import java.util.LinkedHashSet;
48 import java.util.List;
50 import java.util.Map.Entry;
51 import java.util.Objects;
52 import java.util.Optional;
54 import java.util.function.Supplier;
55 import java.util.stream.Collectors;
57 import org.apache.commons.collections.CollectionUtils;
58 import org.apache.commons.collections.MapUtils;
59 import org.apache.commons.io.FilenameUtils;
60 import org.apache.commons.lang3.StringUtils;
61 import org.apache.commons.lang3.tuple.ImmutablePair;
62 import org.apache.commons.lang3.tuple.ImmutableTriple;
63 import org.apache.commons.lang3.tuple.Triple;
64 import org.onap.sdc.tosca.services.YamlUtil;
65 import org.openecomp.sdc.be.components.impl.exceptions.SdcResourceNotFoundException;
66 import org.openecomp.sdc.be.config.CategoryBaseTypeConfig;
67 import org.openecomp.sdc.be.config.Configuration;
68 import org.openecomp.sdc.be.config.ConfigurationManager;
69 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
70 import org.openecomp.sdc.be.data.model.ToscaImportByModel;
71 import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
72 import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition;
73 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
74 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
75 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
76 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
77 import org.openecomp.sdc.be.datatypes.elements.PropertyFilterConstraintDataDefinition;
78 import org.openecomp.sdc.be.datatypes.elements.PropertyFilterDataDefinition;
79 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition;
80 import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition;
81 import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterPropertyDataDefinition;
82 import org.openecomp.sdc.be.datatypes.elements.ToscaArtifactDataDefinition;
83 import org.openecomp.sdc.be.datatypes.elements.ToscaFunction;
84 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
85 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
86 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
87 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
88 import org.openecomp.sdc.be.exception.ToscaExportException;
89 import org.openecomp.sdc.be.model.ArtifactDefinition;
90 import org.openecomp.sdc.be.model.AttributeDefinition;
91 import org.openecomp.sdc.be.model.CapabilityDefinition;
92 import org.openecomp.sdc.be.model.CapabilityRequirementRelationship;
93 import org.openecomp.sdc.be.model.Component;
94 import org.openecomp.sdc.be.model.ComponentInstance;
95 import org.openecomp.sdc.be.model.ComponentInstanceAttribute;
96 import org.openecomp.sdc.be.model.ComponentInstanceInput;
97 import org.openecomp.sdc.be.model.ComponentInstanceInterface;
98 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
99 import org.openecomp.sdc.be.model.ComponentParametersView;
100 import org.openecomp.sdc.be.model.DataTypeDefinition;
101 import org.openecomp.sdc.be.model.GroupInstance;
102 import org.openecomp.sdc.be.model.InputDefinition;
103 import org.openecomp.sdc.be.model.InterfaceDefinition;
104 import org.openecomp.sdc.be.model.PropertyDefinition;
105 import org.openecomp.sdc.be.model.RelationshipInfo;
106 import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
107 import org.openecomp.sdc.be.model.RequirementDefinition;
108 import org.openecomp.sdc.be.model.Resource;
109 import org.openecomp.sdc.be.model.Service;
110 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
111 import org.openecomp.sdc.be.model.category.CategoryDefinition;
112 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
113 import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter;
114 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
115 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
116 import org.openecomp.sdc.be.model.operations.impl.ModelOperation;
117 import org.openecomp.sdc.be.model.tosca.converters.ToscaMapValueConverter;
118 import org.openecomp.sdc.be.tosca.PropertyConvertor.PropertyType;
119 import org.openecomp.sdc.be.tosca.builder.ToscaRelationshipBuilder;
120 import org.openecomp.sdc.be.tosca.exception.ToscaConversionException;
121 import org.openecomp.sdc.be.tosca.model.CapabilityFilter;
122 import org.openecomp.sdc.be.tosca.model.NodeFilter;
123 import org.openecomp.sdc.be.tosca.model.SubstitutionMapping;
124 import org.openecomp.sdc.be.tosca.model.ToscaAttribute;
125 import org.openecomp.sdc.be.tosca.model.ToscaCapability;
126 import org.openecomp.sdc.be.tosca.model.ToscaDataType;
127 import org.openecomp.sdc.be.tosca.model.ToscaGroupTemplate;
128 import org.openecomp.sdc.be.tosca.model.ToscaNodeTemplate;
129 import org.openecomp.sdc.be.tosca.model.ToscaNodeType;
130 import org.openecomp.sdc.be.tosca.model.ToscaPolicyTemplate;
131 import org.openecomp.sdc.be.tosca.model.ToscaProperty;
132 import org.openecomp.sdc.be.tosca.model.ToscaPropertyAssignment;
133 import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraint;
134 import org.openecomp.sdc.be.tosca.model.ToscaRelationshipTemplate;
135 import org.openecomp.sdc.be.tosca.model.ToscaRequirement;
136 import org.openecomp.sdc.be.tosca.model.ToscaTemplate;
137 import org.openecomp.sdc.be.tosca.model.ToscaTemplateArtifact;
138 import org.openecomp.sdc.be.tosca.model.ToscaTemplateRequirement;
139 import org.openecomp.sdc.be.tosca.model.ToscaTopolgyTemplate;
140 import org.openecomp.sdc.be.tosca.utils.ForwardingPathToscaUtil;
141 import org.openecomp.sdc.be.tosca.utils.InputConverter;
142 import org.openecomp.sdc.be.tosca.utils.OutputConverter;
143 import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
144 import org.openecomp.sdc.common.log.wrappers.Logger;
145 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
146 import org.springframework.beans.factory.annotation.Autowired;
147 import org.yaml.snakeyaml.DumperOptions;
148 import org.yaml.snakeyaml.DumperOptions.FlowStyle;
149 import org.yaml.snakeyaml.Yaml;
150 import org.yaml.snakeyaml.introspector.BeanAccess;
151 import org.yaml.snakeyaml.introspector.Property;
152 import org.yaml.snakeyaml.introspector.PropertyUtils;
153 import org.yaml.snakeyaml.nodes.MappingNode;
154 import org.yaml.snakeyaml.nodes.Node;
155 import org.yaml.snakeyaml.nodes.NodeTuple;
156 import org.yaml.snakeyaml.nodes.Tag;
157 import org.yaml.snakeyaml.representer.Represent;
158 import org.yaml.snakeyaml.representer.Representer;
160 @org.springframework.stereotype.Component("tosca-export-handler")
161 public class ToscaExportHandler {
163 public static final String ASSET_TOSCA_TEMPLATE = "assettoscatemplate";
164 private static final Logger log = Logger.getLogger(ToscaExportHandler.class);
165 private static final String INVARIANT_UUID = "invariantUUID";
166 private static final String TOSCA_VERSION = "tosca_simple_yaml_1_3";
167 private static final String SERVICE_NODE_TYPE_PREFIX = "org.openecomp.service.";
168 private static final String IMPORTS_FILE_KEY = "file";
169 private static final String TOSCA_INTERFACE_NAME = "-interface.yml";
170 private static final String FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION = "convertToToscaTemplate - failed to get Default Imports section from configuration";
171 private static final String NOT_SUPPORTED_COMPONENT_TYPE = "Not supported component type {}";
172 private static final String NATIVE_ROOT = "tosca.nodes.Root";
173 private static final List<String> EXCLUDED_CATEGORY_SPECIFIC_METADATA = List
174 .of("Service Function", "Service Role", "Naming Policy", "Service Type");
175 private static final YamlUtil yamlUtil = new YamlUtil();
176 private final ApplicationDataTypeCache applicationDataTypeCache;
177 private final ToscaOperationFacade toscaOperationFacade;
178 private final CapabilityRequirementConverter capabilityRequirementConverter;
179 private final PolicyExportParser policyExportParser;
180 private final GroupExportParser groupExportParser;
181 private final PropertyConvertor propertyConvertor;
182 private final AttributeConverter attributeConverter;
183 private final InputConverter inputConverter;
184 private final OutputConverter outputConverter;
185 private final InterfaceLifecycleOperation interfaceLifecycleOperation;
186 private final InterfacesOperationsConverter interfacesOperationsConverter;
187 private final ModelOperation modelOperation;
190 public ToscaExportHandler(final ApplicationDataTypeCache applicationDataTypeCache,
191 final ToscaOperationFacade toscaOperationFacade,
192 final CapabilityRequirementConverter capabilityRequirementConverter,
193 final PolicyExportParser policyExportParser,
194 final GroupExportParser groupExportParser,
195 final PropertyConvertor propertyConvertor,
196 final AttributeConverter attributeConverter,
197 final InputConverter inputConverter,
198 final OutputConverter outputConverter,
199 final InterfaceLifecycleOperation interfaceLifecycleOperation,
200 final InterfacesOperationsConverter interfacesOperationsConverter,
201 final ModelOperation modelOperation) {
202 this.applicationDataTypeCache = applicationDataTypeCache;
203 this.toscaOperationFacade = toscaOperationFacade;
204 this.capabilityRequirementConverter = capabilityRequirementConverter;
205 this.policyExportParser = policyExportParser;
206 this.groupExportParser = groupExportParser;
207 this.propertyConvertor = propertyConvertor;
208 this.attributeConverter = attributeConverter;
209 this.inputConverter = inputConverter;
210 this.outputConverter = outputConverter;
211 this.interfaceLifecycleOperation = interfaceLifecycleOperation;
212 this.interfacesOperationsConverter = interfacesOperationsConverter;
213 this.modelOperation = modelOperation;
216 public static String getInterfaceFilename(String artifactName) {
217 return artifactName.substring(0, artifactName.lastIndexOf('.')) + TOSCA_INTERFACE_NAME;
220 private static void removeOperationImplementationForProxyNodeType(Map<String, InterfaceDefinition> proxyComponentInterfaces) {
221 if (MapUtils.isEmpty(proxyComponentInterfaces)) {
224 proxyComponentInterfaces.values().stream().map(InterfaceDataDefinition::getOperations).filter(MapUtils::isNotEmpty)
225 .forEach(operations -> operations.values().forEach(operation -> operation.setImplementation(null)));
228 private static Object buildNodeFilterValue(final PropertyFilterConstraintDataDefinition filterConstraint) {
229 if (filterConstraint.getValue() instanceof ToscaFunction) {
230 return Map.of(filterConstraint.getOperator().getType(), ((ToscaFunction) filterConstraint.getValue()).getJsonObjectValue());
232 return Map.of(filterConstraint.getOperator().getType(), filterConstraint.getValue());
236 public Either<ToscaRepresentation, ToscaError> exportComponent(Component component) {
237 return convertToToscaTemplate(component).left().map(this::createToscaRepresentation);
240 public Either<ToscaRepresentation, ToscaError> exportDataType(DataTypeDefinition dataTypeDefinition) {
241 return convertDataTypeToToscaTemplate(dataTypeDefinition).left().map(this::createToscaRepresentation);
244 public Either<ToscaRepresentation, ToscaError> exportComponentInterface(final Component component, final boolean isAssociatedComponent) {
245 final List<Map<String, Map<String, String>>> imports = new ArrayList<>(getDefaultToscaImports(component.getModel()));
246 if (CollectionUtils.isEmpty(imports)) {
247 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
248 return Either.right(ToscaError.GENERAL_ERROR);
250 List<Triple<String, String, Component>> dependencies = new ArrayList<>();
251 if (component.getDerivedFromGenericType() != null && !component.getDerivedFromGenericType()
252 .startsWith("org.openecomp.resource.abstract.nodes.")) {
253 final Either<Component, StorageOperationStatus> baseType = toscaOperationFacade
254 .getByToscaResourceNameAndVersion(component.getDerivedFromGenericType(), component.getDerivedFromGenericVersion(),
255 component.getModel());
256 if (baseType.isLeft() && baseType.left().value() != null) {
257 addDependencies(imports, dependencies, baseType.left().value());
259 log.debug("Failed to fetch derived from type {}", component.getDerivedFromGenericType());
263 String toscaVersion = null;
264 if (component instanceof Resource) {
265 toscaVersion = ((Resource) component).getToscaVersion();
267 ToscaTemplate toscaTemplate = new ToscaTemplate(toscaVersion != null ? toscaVersion : TOSCA_VERSION);
268 toscaTemplate.setImports(imports);
269 final Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
270 final Either<ToscaTemplate, ToscaError> toscaTemplateRes = convertInterfaceNodeType(new HashMap<>(), component, toscaTemplate, nodeTypes,
271 isAssociatedComponent);
272 if (toscaTemplateRes.isRight()) {
273 return Either.right(toscaTemplateRes.right().value());
275 toscaTemplate = toscaTemplateRes.left().value();
276 toscaTemplate.setDependencies(dependencies);
277 ToscaRepresentation toscaRepresentation = this.createToscaRepresentation(toscaTemplate);
278 return Either.left(toscaRepresentation);
281 private ToscaRepresentation createToscaRepresentation(ToscaTemplate toscaTemplate) {
282 CustomRepresenter representer = new CustomRepresenter();
283 DumperOptions options = new DumperOptions();
284 options.setAllowReadOnlyProperties(false);
285 options.setPrettyFlow(true);
286 options.setDefaultFlowStyle(FlowStyle.FLOW);
287 options.setCanonical(false);
288 representer.addClassTag(toscaTemplate.getClass(), Tag.MAP);
289 representer.setPropertyUtils(new UnsortedPropertyUtils());
292 Yaml yaml = new Yaml(representer, options);
293 String yamlAsString = yaml.dumpAsMap(toscaTemplate);
294 String sb = getConfiguration().getHeatEnvArtifactHeader()
296 + getConfiguration().getHeatEnvArtifactFooter();
297 return ToscaRepresentation.make(sb.getBytes(), toscaTemplate);
300 public Either<ToscaTemplate, ToscaError> getDependencies(Component component) {
301 ToscaTemplate toscaTemplate = new ToscaTemplate(null);
302 Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports = fillImports(component, toscaTemplate);
303 if (fillImports.isRight()) {
304 return Either.right(fillImports.right().value());
306 return Either.left(fillImports.left().value().left);
309 public Either<ToscaTemplate, ToscaError> convertToToscaTemplate(final Component component) {
310 final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImports(component.getModel());
311 if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
312 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
313 return Either.right(ToscaError.GENERAL_ERROR);
315 log.trace("start tosca export for {}", component.getUniqueId());
316 String toscaVersion = null;
317 if (component instanceof Resource) {
318 toscaVersion = ((Resource) component).getToscaVersion();
320 final ToscaTemplate toscaTemplate = new ToscaTemplate(toscaVersion != null ? toscaVersion : TOSCA_VERSION);
321 toscaTemplate.setMetadata(convertMetadata(component));
322 toscaTemplate.setImports(new ArrayList<>(defaultToscaImportConfig));
323 final Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
324 if (ModelConverter.isAtomicComponent(component)) {
325 log.trace("convert component as node type");
326 return convertNodeType(new HashMap<>(), component, toscaTemplate, nodeTypes);
328 log.trace("convert component as topology template");
329 return convertToscaTemplate(component, toscaTemplate);
333 private Either<ToscaTemplate, ToscaError> convertDataTypeToToscaTemplate(final DataTypeDefinition dataTypeDefinition) {
334 final ToscaTemplate toscaTemplate = new ToscaTemplate(TOSCA_VERSION);
335 return convertDataTypeTosca(dataTypeDefinition, toscaTemplate);
338 private Either<ToscaTemplate, ToscaError> convertDataTypeTosca(final DataTypeDefinition dataTypeDefinition, final ToscaTemplate toscaTemplate) {
339 final var dataTypesEither = applicationDataTypeCache.getAll(dataTypeDefinition.getModel());
340 if (dataTypesEither.isRight()) {
341 log.debug("Failed to fetch all data types :", dataTypesEither.right().value());
342 return Either.right(ToscaError.GENERAL_ERROR);
344 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
345 if (!dataTypeDefinition.isEmpty()) {
346 Map<String, ToscaDataType> toscaDataTypeMap = new HashMap<>();
347 ToscaDataType toscaDataType = new ToscaDataType();
348 toscaDataType.setDerived_from(dataTypeDefinition.getDerivedFromName());
349 toscaDataType.setDescription(dataTypeDefinition.getDescription());
350 toscaDataType.setVersion(dataTypeDefinition.getVersion());
351 if (CollectionUtils.isNotEmpty(dataTypeDefinition.getProperties())) {
352 toscaDataType.setProperties(dataTypeDefinition.getProperties().stream()
353 .collect(Collectors.toMap(
354 PropertyDataDefinition::getName,
355 s -> propertyConvertor.convertProperty(dataTypes, s, PropertyType.PROPERTY),
356 (toscaPropertyTobeValidated, toscaProperty) -> validateToscaProperty((List<DataTypeDefinition>) dataTypeDefinition, toscaPropertyTobeValidated,
360 toscaDataTypeMap.put(dataTypeDefinition.getName(), toscaDataType);
361 toscaTemplate.setData_types(toscaDataTypeMap);
363 return Either.left(toscaTemplate);
366 private List<Map<String, Map<String, String>>> getDefaultToscaImports(final String modelId) {
367 if (modelId == null) {
368 return getDefaultToscaImportConfig();
371 final List<ToscaImportByModel> allModelImports = modelOperation.findAllModelImports(modelId, true);
372 final List<Map<String, Map<String, String>>> importList = new ArrayList<>();
373 final Set<Path> addedPathList = new HashSet<>();
374 for (final ToscaImportByModel toscaImportByModel : allModelImports) {
375 var importPath = Path.of(toscaImportByModel.getFullPath());
376 if (addedPathList.contains(importPath)) {
377 importPath = ToscaDefaultImportHelper.addModelAsFilePrefix(importPath, toscaImportByModel.getModelId());
379 final String fileName = FilenameUtils.getBaseName(importPath.toString());
380 importList.add(Map.of(fileName, Map.of("file", importPath.toString())));
381 addedPathList.add(importPath);
386 private Either<ToscaTemplate, ToscaError> convertToscaTemplate(Component component, ToscaTemplate toscaNode) {
387 Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> importsRes = fillImports(component, toscaNode);
388 if (importsRes.isRight()) {
389 return Either.right(importsRes.right().value());
391 toscaNode = importsRes.left().value().left;
392 Map<String, Component> componentCache = importsRes.left().value().right;
393 Either<Map<String, ToscaNodeType>, ToscaError> nodeTypesMapEither = createProxyNodeTypes(componentCache, component);
394 if (nodeTypesMapEither.isRight()) {
395 log.debug("Failed to fetch normative service proxy resource by tosca name, error {}", nodeTypesMapEither.right().value());
396 return Either.right(nodeTypesMapEither.right().value());
398 Map<String, ToscaNodeType> nodeTypesMap = nodeTypesMapEither.left().value();
399 if (nodeTypesMap != null && !nodeTypesMap.isEmpty()) {
400 toscaNode.setNode_types(nodeTypesMap);
402 createServiceSubstitutionNodeTypes(componentCache, component, toscaNode);
403 Either<Map<String, Object>, ToscaError> proxyInterfaceTypesEither = createProxyInterfaceTypes(component);
404 if (proxyInterfaceTypesEither.isRight()) {
405 log.debug("Failed to populate service proxy local interface types in tosca, error {}", nodeTypesMapEither.right().value());
406 return Either.right(proxyInterfaceTypesEither.right().value());
408 Map<String, Object> proxyInterfaceTypes = proxyInterfaceTypesEither.left().value();
409 if (MapUtils.isNotEmpty(proxyInterfaceTypes)) {
410 toscaNode.setInterface_types(proxyInterfaceTypes);
412 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = applicationDataTypeCache.getAll(component.getModel());
413 if (dataTypesEither.isRight()) {
414 log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
415 return Either.right(ToscaError.GENERAL_ERROR);
417 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
418 ToscaTopolgyTemplate topologyTemplate = new ToscaTopolgyTemplate();
419 List<InputDefinition> inputDef = component.getInputs();
420 Map<String, ToscaProperty> inputs = inputConverter.convertInputs(inputDef, dataTypes);
421 if (!inputs.isEmpty()) {
422 topologyTemplate.setInputs(inputs);
424 final Map<String, ToscaProperty> outputs;
426 outputs = outputConverter.convert(component.getOutputs(), dataTypes);
427 } catch (final ToscaConversionException e) {
428 log.error(EcompLoggerErrorCode.SCHEMA_ERROR, ToscaExportHandler.class.getName(),
429 "Could not parse component '{}' outputs. Component unique id '{}'.", component.getName(), component.getUniqueId(), e);
430 return Either.right(ToscaError.GENERAL_ERROR);
432 if (!outputs.isEmpty()) {
433 topologyTemplate.setOutputs(outputs);
435 if (CollectionUtils.isNotEmpty(component.getComponentInstances())) {
436 final Either<Map<String, ToscaNodeTemplate>, ToscaError> nodeTemplates =
437 convertNodeTemplates(component, componentCache, dataTypes, topologyTemplate);
438 if (nodeTemplates.isRight()) {
439 return Either.right(nodeTemplates.right().value());
441 log.debug("node templates converted");
442 topologyTemplate.setNode_templates(nodeTemplates.left().value());
444 final Map<String, ToscaRelationshipTemplate> relationshipTemplatesMap = new ToscaExportRelationshipTemplatesHandler()
445 .createFrom(topologyTemplate.getNode_templates());
446 if (!relationshipTemplatesMap.isEmpty()) {
447 topologyTemplate.setRelationshipTemplates(relationshipTemplatesMap);
449 addGroupsToTopologyTemplate(component, topologyTemplate);
451 addPoliciesToTopologyTemplate(component, topologyTemplate);
452 } catch (SdcResourceNotFoundException e) {
453 log.debug("Fail to add policies to topology template:", e);
454 return Either.right(ToscaError.GENERAL_ERROR);
457 createSubstitutionMapping(component, componentCache).ifPresent(topologyTemplate::setSubstitution_mappings);
458 } catch (final ToscaExportException e) {
459 log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, ToscaExportHandler.class.getName(), e.getMessage());
460 return Either.right(e.getToscaError());
462 if (!topologyTemplate.isEmpty()) {
463 toscaNode.setTopology_template(topologyTemplate);
465 return Either.left(toscaNode);
468 private Either<String, ToscaError> createComponentToscaName(final Component component) {
469 switch (component.getComponentType()) {
471 final ResourceMetadataDataDefinition resourceMetadata =
472 (ResourceMetadataDataDefinition) component.getComponentMetadataDefinition().getMetadataDataDefinition();
473 return Either.left(resourceMetadata.getToscaResourceName());
475 return Either.left(SERVICE_NODE_TYPE_PREFIX + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName());
477 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
478 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
482 private Optional<SubstitutionMapping> createSubstitutionMapping(final Component component,
483 final Map<String, Component> componentCache) throws ToscaExportException {
484 if (component instanceof Service && !((Service) component).isSubstituteCandidate()) {
485 return Optional.empty();
488 final Either<String, ToscaError> toscaResourceNameEither = createComponentToscaName(component);
489 if (toscaResourceNameEither.isRight()) {
490 throw new ToscaExportException("Could not create component TOSCA name", toscaResourceNameEither.right().value());
492 final String toscaResourceName = toscaResourceNameEither.left().value();
494 final SubstitutionMapping substitutionMapping = new SubstitutionMapping();
495 if (doNotExtendBaseType(component)) {
496 substitutionMapping.setNode_type(component.getDerivedFromGenericType());
498 substitutionMapping.setNode_type(toscaResourceName);
500 convertSubstitutionMappingFilter(component).ifPresent(substitutionMapping::setSubstitution_filter);
502 final Either<Map<String, String[]>, ToscaError> capabilitiesEither = convertSubstitutionMappingCapabilities(component, componentCache);
503 if (capabilitiesEither.isRight()) {
504 throw new ToscaExportException("Could not convert substitution mapping capabilities", capabilitiesEither.right().value());
506 final Map<String, String[]> capabilityMap = capabilitiesEither.left().value();
507 if (!capabilityMap.isEmpty()) {
508 substitutionMapping.setCapabilities(capabilityMap);
510 final Either<Map<String, String[]>, ToscaError> requirements =
511 capabilityRequirementConverter.convertSubstitutionMappingRequirements(component, componentCache);
512 if (requirements.isRight()) {
513 throw new ToscaExportException("Could not convert substitution mapping requirements", requirements.right().value());
515 final Map<String, String[]> requirementMap = requirements.left().value();
516 if (MapUtils.isNotEmpty(requirementMap)) {
517 substitutionMapping.setRequirements(requirementMap);
520 final Map<String, String[]> propertyMappingMap = buildSubstitutionMappingPropertyMapping(component);
521 if (MapUtils.isNotEmpty(propertyMappingMap)) {
522 substitutionMapping.setProperties(propertyMappingMap);
525 final Map<String, String[]> attributesMappingMap = buildSubstitutionMappingAttributesMapping(component);
526 if (MapUtils.isNotEmpty(attributesMappingMap)) {
527 substitutionMapping.setAttributes(attributesMappingMap);
530 return Optional.of(substitutionMapping);
533 private boolean doNotExtendBaseType(final Component component) {
534 final Map<String, CategoryBaseTypeConfig> serviceNodeTypesConfig = ConfigurationManager.getConfigurationManager().getConfiguration().getServiceBaseNodeTypes();
535 List<CategoryDefinition> categories = component.getCategories();
536 if (CollectionUtils.isNotEmpty(categories) && MapUtils.isNotEmpty(serviceNodeTypesConfig) && serviceNodeTypesConfig.get(categories.get(0).getName()) != null) {
537 return serviceNodeTypesConfig.get(categories.get(0).getName()).isDoNotExtendBaseType();
542 private Optional<NodeFilter> convertSubstitutionMappingFilter(final Component component) {
543 if (component.getSubstitutionFilter() == null || (component.getSubstitutionFilter().getProperties()).getListToscaDataDefinition() == null) {
544 return Optional.empty();
547 return Optional.ofNullable(convertToSubstitutionFilterComponent(component.getSubstitutionFilter()));
550 private void addGroupsToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate) {
551 Map<String, ToscaGroupTemplate> groups = groupExportParser.getGroups(component);
552 if (groups != null) {
553 topologyTemplate.addGroups(groups);
557 private void addPoliciesToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate) throws SdcResourceNotFoundException {
558 Map<String, ToscaPolicyTemplate> policies = policyExportParser.getPolicies(component);
559 if (policies != null) {
560 topologyTemplate.addPolicies(policies);
564 private Map<String, String> convertMetadata(Component component) {
565 return convertMetadata(component, false, null);
568 private Map<String, String> convertMetadata(Component component, boolean isInstance, ComponentInstance componentInstance) {
569 Map<String, String> toscaMetadata = new LinkedHashMap<>();
570 toscaMetadata.put(convertMetadataKey(JsonPresentationFields.INVARIANT_UUID), component.getInvariantUUID());
571 toscaMetadata.put(JsonPresentationFields.UUID.getPresentation(), component.getUUID());
573 .put(JsonPresentationFields.NAME.getPresentation(), component.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
574 toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), component.getDescription());
575 List<CategoryDefinition> categories = component.getCategories();
576 CategoryDefinition categoryDefinition = categories.get(0);
577 toscaMetadata.put(JsonPresentationFields.MODEL.getPresentation(), component.getModel());
578 toscaMetadata.put(JsonPresentationFields.CATEGORY.getPresentation(), categoryDefinition.getName());
580 toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), component.getVersion());
581 toscaMetadata.put(JsonPresentationFields.CUSTOMIZATION_UUID.getPresentation(), componentInstance.getCustomizationUUID());
582 if (componentInstance.getSourceModelInvariant() != null && !componentInstance.getSourceModelInvariant().isEmpty()) {
583 toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), componentInstance.getComponentVersion());
584 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_INVARIANT.getPresentation(), componentInstance.getSourceModelInvariant());
585 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_UUID.getPresentation(), componentInstance.getSourceModelUuid());
586 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_NAME.getPresentation(), componentInstance.getSourceModelName());
587 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
588 toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(),
589 componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceProxy.getDisplayValue());
590 } else if (componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
591 toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(),
592 componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceSubstitution.getDisplayValue());
594 toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), componentInstance.getDescription());
597 switch (component.getComponentType()) {
599 Resource resource = (Resource) component;
600 if (isInstance && (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy
601 || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution)) {
602 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), componentInstance.getOriginType().getDisplayValue());
604 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), resource.getResourceType().name());
606 toscaMetadata.put(JsonPresentationFields.SUB_CATEGORY.getPresentation(), categoryDefinition.getSubcategories().get(0).getName());
607 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR.getPresentation(), resource.getVendorName());
608 if (resource.getTenant() != null) {
609 toscaMetadata.put(JsonPresentationFields.TENANT.getPresentation(), resource.getTenant());
611 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_RELEASE.getPresentation(), resource.getVendorRelease());
612 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_MODEL_NUMBER.getPresentation(), resource.getResourceVendorModelNumber());
615 Service service = (Service) component;
616 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), component.getComponentType().getValue());
617 toscaMetadata.put(JsonPresentationFields.SERVICE_TYPE.getPresentation(), service.getServiceType());
618 toscaMetadata.put(JsonPresentationFields.SERVICE_ROLE.getPresentation(), service.getServiceRole());
619 toscaMetadata.put(JsonPresentationFields.SERVICE_FUNCTION.getPresentation(), service.getServiceFunction());
620 toscaMetadata.put(JsonPresentationFields.ENVIRONMENT_CONTEXT.getPresentation(), service.getEnvironmentContext());
621 toscaMetadata.put(JsonPresentationFields.INSTANTIATION_TYPE.getPresentation(),
622 service.getEnvironmentContext() == null ? StringUtils.EMPTY : service.getInstantiationType());
625 toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming().toString());
626 toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming().toString());
627 toscaMetadata.put(JsonPresentationFields.NAMING_POLICY.getPresentation(), service.getNamingPolicy());
631 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
633 for (final String key : component.getCategorySpecificMetadata().keySet()) {
634 if (!EXCLUDED_CATEGORY_SPECIFIC_METADATA.contains(key)) {
635 toscaMetadata.put(key, component.getCategorySpecificMetadata().get(key));
638 return toscaMetadata;
641 private String convertMetadataKey(JsonPresentationFields jsonPresentationField) {
642 if (JsonPresentationFields.INVARIANT_UUID.equals(jsonPresentationField)) {
643 return INVARIANT_UUID;
645 return jsonPresentationField.getPresentation();
648 private Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports(Component component, ToscaTemplate toscaTemplate) {
649 final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImports(component.getModel());
650 if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
651 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
652 return Either.right(ToscaError.GENERAL_ERROR);
654 Map<String, Component> componentCache = new HashMap<>();
655 if (!ModelConverter.isAtomicComponent(component)) {
656 final List<Map<String, Map<String, String>>> additionalImports =
657 toscaTemplate.getImports() == null ? new ArrayList<>(defaultToscaImportConfig) : new ArrayList<>(toscaTemplate.getImports());
658 List<Triple<String, String, Component>> dependencies = new ArrayList<>();
659 Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
660 final Map<String, Map<String, String>> substituteTypeImportEntry = generateComponentSubstituteTypeImport(component, toscaArtifacts);
661 if (!substituteTypeImportEntry.isEmpty()) {
662 additionalImports.add(substituteTypeImportEntry);
664 List<ComponentInstance> componentInstances = component.getComponentInstances();
665 if (componentInstances != null && !componentInstances.isEmpty()) {
666 componentInstances.forEach(ci -> createDependency(componentCache, additionalImports, dependencies, ci));
668 toscaTemplate.setDependencies(dependencies);
669 toscaTemplate.setImports(additionalImports);
671 log.debug("currently imports supported for VF and service only");
673 return Either.left(new ImmutablePair<>(toscaTemplate, componentCache));
676 private Map<String, Map<String, String>> generateComponentSubstituteTypeImport(final Component component,
677 final Map<String, ArtifactDefinition> toscaArtifacts) {
678 if (doNotExtendBaseType(component)) {
679 return Collections.emptyMap();
681 if (component instanceof Service && !((Service) component).isSubstituteCandidate()) {
682 return Collections.emptyMap();
684 if (MapUtils.isEmpty(toscaArtifacts)) {
685 return Collections.emptyMap();
687 final ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE);
688 if (artifactDefinition == null) {
689 return Collections.emptyMap();
691 final var importEntryName = component.getComponentType().toString().toLowerCase() + "-" + component.getName() + "-interface";
692 return Map.of(importEntryName,
693 Map.of(IMPORTS_FILE_KEY, getInterfaceFilename(artifactDefinition.getArtifactName()))
697 private List<Map<String, Map<String, String>>> getDefaultToscaImportConfig() {
698 return getConfiguration().getDefaultImports();
701 private void createDependency(final Map<String, Component> componentCache, final List<Map<String, Map<String, String>>> imports,
702 final List<Triple<String, String, Component>> dependencies, final ComponentInstance componentInstance) {
703 log.debug("createDependency componentCache {}", componentCache);
704 Component componentRI = componentCache.get(componentInstance.getComponentUid());
705 if (componentRI == null || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
706 // all resource must be only once!
707 final Either<Component, StorageOperationStatus> resource = toscaOperationFacade.getToscaFullElement(componentInstance.getComponentUid());
708 if ((resource.isRight()) && (log.isDebugEnabled())) {
709 log.debug("Failed to fetch resource with id {} for instance {}", componentInstance.getComponentUid(),
710 componentInstance.getUniqueId());
713 final Component fetchedComponent = resource.left().value();
714 componentRI = setComponentCache(componentCache, componentInstance, fetchedComponent);
715 addDependencies(imports, dependencies, componentRI);
720 * Sets a componentCache from the given component/resource.
722 private Component setComponentCache(final Map<String, Component> componentCache, final ComponentInstance componentInstance,
723 final Component fetchedComponent) {
724 componentCache.put(fetchedComponent.getUniqueId(), fetchedComponent);
725 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy
726 || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
727 final Either<Component, StorageOperationStatus> sourceService = toscaOperationFacade
728 .getToscaFullElement(componentInstance.getSourceModelUid());
729 if (sourceService.isRight() && (log.isDebugEnabled())) {
730 log.debug("Failed to fetch source service with id {} for proxy {}", componentInstance.getSourceModelUid(),
731 componentInstance.getUniqueId());
733 final Component fetchedSource = sourceService.left().value();
734 componentCache.put(fetchedSource.getUniqueId(), fetchedSource);
735 return fetchedSource;
737 return fetchedComponent;
741 * Retrieves all derived_from nodes and stores it in a predictable order.
743 private void addDependencies(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
744 final Component fetchedComponent) {
745 final Set<Component> componentsList = new LinkedHashSet<>();
746 if (fetchedComponent instanceof Resource) {
747 log.debug("fetchedComponent is a resource {}", fetchedComponent);
748 final Optional<Map<String, String>> derivedFromMapOfIdToName = getDerivedFromMapOfIdToName(fetchedComponent, componentsList);
749 if (derivedFromMapOfIdToName.isPresent() && !derivedFromMapOfIdToName.get().isEmpty()) {
750 derivedFromMapOfIdToName.get().entrySet().forEach(entry -> {
751 log.debug("Started entry.getValue() : {}", entry.getValue());
752 if (!NATIVE_ROOT.equals(entry.getValue())) {
753 Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade.getToscaElement(entry.getKey());
754 if (resourcefetched != null && resourcefetched.isLeft()) {
755 componentsList.add(resourcefetched.left().value());
759 setImports(imports, dependencies, componentsList);
761 setImports(imports, dependencies, fetchedComponent);
767 * Returns all derived_from nodes found.
769 private Optional<Map<String, String>> getDerivedFromMapOfIdToName(final Component fetchedComponent, final Set<Component> componentsList) {
770 final Resource parentResource = (Resource) fetchedComponent;
771 Map<String, String> derivedFromMapOfIdToName = new HashMap<>();
772 if (CollectionUtils.isNotEmpty(parentResource.getComponentInstances())) {
773 componentsList.add(fetchedComponent);
774 for (final ComponentInstance componentInstance : parentResource.getComponentInstances()) {
775 final Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade
776 .getToscaElement(componentInstance.getComponentUid());
777 if (resourcefetched != null && resourcefetched.isLeft()) {
778 final Map<String, String> derivedWithId = resourcefetched.left().value().getDerivedFromMapOfIdToName();
779 if (MapUtils.isNotEmpty(derivedWithId)) {
780 derivedFromMapOfIdToName.putAll(derivedWithId);
785 derivedFromMapOfIdToName = parentResource.getDerivedFromMapOfIdToName();
787 log.debug("Started derivedFromMapOfIdToName: {}", derivedFromMapOfIdToName);
788 return Optional.ofNullable(derivedFromMapOfIdToName);
792 * Creates a resource map and adds it to the import list.
794 private void setImports(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
795 final Set<Component> componentsList) {
796 componentsList.forEach(component -> setImports(imports, dependencies, component));
799 private void setImports(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
800 final Component component) {
801 final Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
802 final ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE);
803 if (artifactDefinition != null) {
804 final Map<String, String> files = new HashMap<>();
805 final String artifactName = artifactDefinition.getArtifactName();
806 files.put(IMPORTS_FILE_KEY, artifactName);
807 final StringBuilder keyNameBuilder = new StringBuilder();
808 keyNameBuilder.append(component.getComponentType().toString().toLowerCase());
809 keyNameBuilder.append("-");
810 keyNameBuilder.append(component.getName());
811 addImports(imports, keyNameBuilder, files);
812 dependencies.add(new ImmutableTriple<>(artifactName, artifactDefinition.getEsId(), component));
813 if (!ModelConverter.isAtomicComponent(component)) {
814 final Map<String, String> interfaceFiles = new HashMap<>();
815 interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactName));
816 keyNameBuilder.append("-interface");
817 addImports(imports, keyNameBuilder, interfaceFiles);
823 * Adds the found resource to the import definition list.
825 private void addImports(final List<Map<String, Map<String, String>>> imports, final StringBuilder keyNameBuilder,
826 final Map<String, String> files) {
827 final String mapKey = keyNameBuilder.toString();
828 if (imports.stream().allMatch(stringMapMap -> stringMapMap.get(mapKey) == null)) {
829 final Map<String, Map<String, String>> importsListMember = new HashMap<>();
830 importsListMember.put(keyNameBuilder.toString(), files);
831 imports.add(importsListMember);
835 private Either<ToscaTemplate, ToscaError> convertNodeType(Map<String, Component> componentsCache, Component component, ToscaTemplate toscaNode,
836 Map<String, ToscaNodeType> nodeTypes) {
837 return convertInterfaceNodeType(componentsCache, component, toscaNode, nodeTypes, false);
840 public Either<ToscaTemplate, ToscaError> convertInterfaceNodeType(Map<String, Component> componentsCache, Component component,
841 ToscaTemplate toscaNode, Map<String, ToscaNodeType> nodeTypes,
842 boolean isAssociatedComponent) {
843 log.debug("start convert node type for {}", component.getUniqueId());
844 ToscaNodeType toscaNodeType = createNodeType(component);
845 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither = interfaceLifecycleOperation
846 .getAllInterfaceLifecycleTypes(component.getModel());
847 if (lifecycleTypeEither.isRight() && !StorageOperationStatus.NOT_FOUND.equals(lifecycleTypeEither.right().value())) {
848 log.debug("Failed to fetch all interface types :", lifecycleTypeEither.right().value());
849 return Either.right(ToscaError.GENERAL_ERROR);
851 if (lifecycleTypeEither.isLeft()) {
852 List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value().values().stream().map(InterfaceDataDefinition::getType)
853 .collect(Collectors.toList());
854 toscaNode.setInterface_types(interfacesOperationsConverter.addInterfaceTypeElement(component, allGlobalInterfaceTypes));
856 final var dataTypesEither = applicationDataTypeCache.getAll(component.getModel());
857 if (dataTypesEither.isRight()) {
858 log.debug("Failed to fetch all data types :", dataTypesEither.right().value());
859 return Either.right(ToscaError.GENERAL_ERROR);
861 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
862 interfacesOperationsConverter.addInterfaceDefinitionElement(component, toscaNodeType, dataTypes, isAssociatedComponent);
863 final var toscaAttributeMap = convertToToscaAttributes(component.getAttributes(), dataTypes);
864 if (!toscaAttributeMap.isEmpty()) {
865 toscaNodeType.setAttributes(toscaAttributeMap);
867 Map<String, ToscaProperty> convertedProperties = new HashMap();
868 if (CollectionUtils.isNotEmpty(component.getProperties())) {
869 List<PropertyDefinition> properties = component.getProperties();
870 convertedProperties = properties.stream()
871 .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, component.getInputs())).collect(Collectors
872 .toMap(PropertyDataDefinition::getName,
873 property -> propertyConvertor.convertProperty(dataTypes, property, PropertyConvertor.PropertyType.PROPERTY)));
875 if (MapUtils.isNotEmpty(convertedProperties)) {
876 toscaNodeType.setProperties(convertedProperties);
878 /* convert private data_types */
879 List<DataTypeDefinition> privateDataTypes = component.getDataTypes();
880 if (CollectionUtils.isNotEmpty(privateDataTypes)) {
881 Map<String, ToscaDataType> toscaDataTypeMap = new HashMap<>();
882 for (DataTypeDefinition dataType : privateDataTypes) {
883 log.debug("Emitting private data type: component.name={} dataType.name={}",
884 component.getNormalizedName(), dataType.getName());
885 ToscaDataType toscaDataType = new ToscaDataType();
886 toscaDataType.setDerived_from(dataType.getDerivedFromName());
887 toscaDataType.setDescription(dataType.getDescription());
888 toscaDataType.setVersion(dataType.getVersion());
889 if (CollectionUtils.isNotEmpty(dataType.getProperties())) {
890 toscaDataType.setProperties(dataType.getProperties().stream()
891 .collect(Collectors.toMap(
892 PropertyDataDefinition::getName,
893 s -> propertyConvertor.convertProperty(dataTypes, s, PropertyType.PROPERTY),
894 (toscaPropertyTobeValidated, toscaProperty) -> validateToscaProperty(privateDataTypes, toscaPropertyTobeValidated,
898 toscaDataTypeMap.put(dataType.getName(), toscaDataType);
900 toscaNode.setData_types(toscaDataTypeMap);
903 // Extracted to method for code reuse
904 return convertReqCapAndTypeName(componentsCache, component, toscaNode, nodeTypes, toscaNodeType, dataTypes);
907 private ToscaProperty validateToscaProperty(final List<DataTypeDefinition> privateDataTypes, final ToscaProperty toscaPropertyTobeValidated,
908 final ToscaProperty toscaProperty) {
909 final Optional<DataTypeDefinition> match = privateDataTypes.stream()
910 .filter(dataType -> dataType.getName().equals(toscaPropertyTobeValidated.getType())).findFirst();
911 return match.isPresent() ? toscaPropertyTobeValidated : toscaProperty;
914 private Map<String, ToscaAttribute> convertToToscaAttributes(final List<AttributeDefinition> attributeList,
915 final Map<String, DataTypeDefinition> dataTypes) {
916 if (CollectionUtils.isEmpty(attributeList)) {
917 return Collections.emptyMap();
919 final AttributeConverter converter = new AttributeConverter(dataTypes);
920 final Map<String, ToscaAttribute> toscaAttributeMap = new HashMap<>();
921 for (final AttributeDefinition attributeDefinition : attributeList) {
922 toscaAttributeMap.put(attributeDefinition.getName(), converter.convert(attributeDefinition));
924 return toscaAttributeMap;
927 private Either<ToscaTemplate, ToscaError> convertReqCapAndTypeName(Map<String, Component> componentsCache,
928 Component component, ToscaTemplate toscaNode,
929 Map<String, ToscaNodeType> nodeTypes,
930 ToscaNodeType toscaNodeType,
931 Map<String, DataTypeDefinition> dataTypes) {
932 Either<ToscaNodeType, ToscaError> capabilities = convertCapabilities(componentsCache, component, toscaNodeType,
934 if (capabilities.isRight()) {
935 return Either.right(capabilities.right().value());
937 toscaNodeType = capabilities.left().value();
938 log.debug("Capabilities converted for {}", component.getUniqueId());
940 Either<ToscaNodeType, ToscaError> requirements = capabilityRequirementConverter
941 .convertRequirements(componentsCache, component, toscaNodeType);
942 if (requirements.isRight()) {
943 return Either.right(requirements.right().value());
945 toscaNodeType = requirements.left().value();
946 log.debug("Requirements converted for {}", component.getUniqueId());
948 String toscaResourceName;
949 switch (component.getComponentType()) {
951 toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition()
952 .getMetadataDataDefinition()).getToscaResourceName();
955 toscaResourceName = SERVICE_NODE_TYPE_PREFIX
956 + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName();
959 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
960 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
963 nodeTypes.put(toscaResourceName, toscaNodeType);
964 toscaNode.setNode_types(nodeTypes);
965 log.debug("finish convert node type for {}", component.getUniqueId());
966 return Either.left(toscaNode);
969 private Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplates(final Component component,
970 final Map<String, Component> componentCache,
971 final Map<String, DataTypeDefinition> dataTypes,
972 final ToscaTopolgyTemplate topologyTemplate) {
974 final Map<String, List<ComponentInstanceProperty>> componentInstancesProperties = component.getComponentInstancesProperties();
975 final Map<String, List<ComponentInstanceAttribute>> componentInstancesAttributes = component.getComponentInstancesAttributes();
976 final Map<String, List<ComponentInstanceInput>> componentInstancesInputs = component.getComponentInstancesInputs();
977 final Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces = component.getComponentInstancesInterfaces();
978 final List<RequirementCapabilityRelDef> componentInstancesRelations = component.getComponentInstancesRelations();
980 Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplatesRes = null;
981 log.debug("start convert topology template for {} for type {}", component.getUniqueId(), component.getComponentType());
982 final Map<String, ToscaNodeTemplate> nodeTemplates = new HashMap<>();
984 Map<String, ToscaGroupTemplate> groupsMap = null;
985 for (final ComponentInstance componentInstance : component.getComponentInstances()) {
986 ToscaNodeTemplate nodeTemplate = new ToscaNodeTemplate();
987 if (MapUtils.isNotEmpty(componentInstance.getToscaArtifacts())) {
988 nodeTemplate.setArtifacts(convertToNodeTemplateArtifacts(componentInstance.getToscaArtifacts()));
990 if (componentInstance.getMinOccurrences() != null && componentInstance.getMaxOccurrences() != null) {
991 List<Object> occur = new ArrayList<>();
992 occur.add(parseToIntIfPossible(componentInstance.getMinOccurrences()));
993 occur.add(parseToIntIfPossible(componentInstance.getMaxOccurrences()));
994 nodeTemplate.setOccurrences(occur);
996 if (componentInstance.getInstanceCount() != null) {
997 ObjectMapper objectMapper = new ObjectMapper();
998 Object obj = convertToToscaObject(componentInstance.getInstanceCount());
1000 Map<String, String> map = objectMapper.convertValue(obj, Map.class);
1001 nodeTemplate.setInstance_count(map);
1004 nodeTemplate.setType(componentInstance.getToscaComponentName());
1005 nodeTemplate.setDirectives(componentInstance.getDirectives());
1006 NodeFilter nodeFilter = convertToNodeTemplateNodeFilterComponent(componentInstance.getNodeFilter());
1007 if (nodeFilter != null && nodeFilter.hasData()) {
1008 nodeTemplate.setNode_filter(nodeFilter);
1010 final Either<Component, Boolean> originComponentRes = capabilityRequirementConverter
1011 .getOriginComponent(componentCache, componentInstance);
1012 if (originComponentRes.isRight()) {
1013 convertNodeTemplatesRes = Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
1016 final Either<ToscaNodeTemplate, ToscaError> requirements = convertComponentInstanceRequirements(component, componentInstance,
1017 componentInstancesRelations, nodeTemplate, originComponentRes.left().value(), componentCache);
1018 if (requirements.isRight()) {
1019 convertNodeTemplatesRes = Either.right(requirements.right().value());
1022 final String instanceUniqueId = componentInstance.getUniqueId();
1023 log.debug("Component instance Requirements converted for instance {}", instanceUniqueId);
1025 nodeTemplate = requirements.left().value();
1027 final Component originalComponent = componentCache.get(componentInstance.getActualComponentUid());
1029 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
1030 final Component componentOfProxy = componentCache.get(componentInstance.getComponentUid());
1031 nodeTemplate.setMetadata(convertMetadata(componentOfProxy, true, componentInstance));
1033 nodeTemplate.setMetadata(convertMetadata(originalComponent, true, componentInstance));
1036 final Either<ToscaNodeTemplate, ToscaError> capabilities =
1037 capabilityRequirementConverter.convertComponentInstanceCapabilities(componentInstance, dataTypes, nodeTemplate);
1038 if (capabilities.isRight()) {
1039 convertNodeTemplatesRes = Either.right(capabilities.right().value());
1042 log.debug("Component instance Capabilities converted for instance {}", instanceUniqueId);
1044 nodeTemplate = capabilities.left().value();
1045 final Map<String, Object> props = new HashMap<>();
1046 final Map<String, Object> attribs = new HashMap<>();
1048 if (originalComponent.getComponentType() == ComponentTypeEnum.RESOURCE) {
1049 // Adds the properties of parent component to map
1050 addPropertiesOfParentComponent(dataTypes, originalComponent, props);
1051 addAttributesOfParentComponent(originalComponent, attribs);
1054 if (null != componentInstancesProperties && componentInstancesProperties.containsKey(instanceUniqueId)) {
1055 addPropertiesOfComponentInstance(componentInstancesProperties, dataTypes, instanceUniqueId, props);
1057 if (null != componentInstancesAttributes && componentInstancesAttributes.containsKey(instanceUniqueId)) {
1058 addAttributesOfComponentInstance(componentInstancesAttributes, instanceUniqueId, attribs);
1061 if (componentInstancesInputs != null
1062 && componentInstancesInputs.containsKey(instanceUniqueId)
1063 && !isComponentOfTypeServiceProxy(componentInstance)) {
1064 //For service proxy the inputs are already handled under instance properties above
1065 addComponentInstanceInputs(dataTypes, componentInstancesInputs, instanceUniqueId, props);
1068 //M3[00001] - NODE TEMPLATE INTERFACES - START
1069 handleInstanceInterfaces(componentInstanceInterfaces, componentInstance, dataTypes, nodeTemplate, instanceUniqueId, component);
1070 //M3[00001] - NODE TEMPLATE INTERFACES - END
1071 if (MapUtils.isNotEmpty(props)) {
1072 nodeTemplate.setProperties(props);
1074 if (MapUtils.isNotEmpty(attribs)) {
1075 nodeTemplate.setAttributes(attribs);
1078 final List<GroupInstance> groupInstances = componentInstance.getGroupInstances();
1079 if (CollectionUtils.isNotEmpty(groupInstances)) {
1080 if (groupsMap == null) {
1081 groupsMap = new HashMap<>();
1083 for (final GroupInstance groupInst : groupInstances) {
1084 if (CollectionUtils.isNotEmpty(groupInst.getArtifacts())) {
1085 groupsMap.put(groupInst.getName(), groupExportParser.getToscaGroupTemplate(groupInst, componentInstance.getInvariantName()));
1090 nodeTemplates.put(componentInstance.getName(), nodeTemplate);
1092 if (groupsMap != null) {
1093 log.debug("instance groups added");
1094 topologyTemplate.addGroups(groupsMap);
1096 if (component.getComponentType() == ComponentTypeEnum.SERVICE && isNotEmpty(
1097 ((Service) component).getForwardingPaths())) {
1098 log.debug("Starting converting paths for component {}, name {}", component.getUniqueId(), component.getName());
1099 ForwardingPathToscaUtil
1100 .addForwardingPaths((Service) component, nodeTemplates, capabilityRequirementConverter, componentCache, toscaOperationFacade);
1101 log.debug("Finished converting paths for component {}, name {}", component.getUniqueId(), component.getName());
1103 if (convertNodeTemplatesRes == null) {
1104 convertNodeTemplatesRes = Either.left(nodeTemplates);
1106 log.debug("finish convert topology template for {} for type {}", component.getUniqueId(), component.getComponentType());
1107 return convertNodeTemplatesRes;
1110 private Object convertToToscaObject(String value) {
1112 ToscaMapValueConverter mapConverterInst = ToscaMapValueConverter.getInstance();
1113 StringReader reader = new StringReader(value);
1114 JsonReader jsonReader = new JsonReader(reader);
1115 jsonReader.setLenient(true);
1116 JsonElement jsonElement = JsonParser.parseReader(jsonReader);
1117 if (jsonElement.isJsonObject()) {
1118 JsonObject jsonObj = jsonElement.getAsJsonObject();
1119 if (jsonObj.entrySet().size() == 1 && jsonObj.has(ToscaFunctions.GET_INPUT.getFunctionName())) {
1120 return mapConverterInst.handleComplexJsonValue(jsonElement);
1124 } catch (Exception e) {
1125 log.debug("convertToToscaValue failed to parse json value :", e);
1130 private Object parseToIntIfPossible(final String value) {
1131 final Integer intValue = Ints.tryParse(value);
1132 return intValue == null ? value : intValue;
1135 private void handleInstanceInterfaces(Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces,
1136 ComponentInstance componentInstance, Map<String, DataTypeDefinition> dataTypes,
1137 ToscaNodeTemplate nodeTemplate, String instanceUniqueId, Component parentComponent) {
1139 if (MapUtils.isEmpty(componentInstanceInterfaces) || !componentInstanceInterfaces.containsKey(instanceUniqueId)) {
1140 nodeTemplate.setInterfaces(null);
1144 final List<ComponentInstanceInterface> currServiceInterfaces = componentInstanceInterfaces.get(instanceUniqueId);
1146 final Map<String, InterfaceDefinition> tmpInterfaces = new HashMap<>();
1147 currServiceInterfaces.forEach(instInterface -> tmpInterfaces.put(instInterface.getUniqueId(), instInterface));
1149 final Map<String, Object> interfaceMap = interfacesOperationsConverter
1150 .getInterfacesMap(parentComponent, componentInstance, tmpInterfaces, dataTypes, isComponentOfTypeServiceProxy(componentInstance));
1152 interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
1153 nodeTemplate.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap);
1156 private boolean isComponentOfTypeServiceProxy(ComponentInstance componentInstance) {
1157 return Objects.nonNull(componentInstance.getOriginType())
1158 && componentInstance.getOriginType().getValue().equals("Service Proxy");
1161 private void addComponentInstanceInputs(Map<String, DataTypeDefinition> dataTypes,
1162 Map<String, List<ComponentInstanceInput>> componentInstancesInputs,
1163 String instanceUniqueId, Map<String, Object> props) {
1165 List<ComponentInstanceInput> instanceInputsList = componentInstancesInputs.get(instanceUniqueId);
1166 if (instanceInputsList != null) {
1167 instanceInputsList.forEach(input -> {
1168 Supplier<String> supplier = () -> input.getValue() != null && !Objects.isNull(input.getValue()) ? input.getValue()
1169 : input.getDefaultValue();
1170 propertyConvertor.convertAndAddValue(dataTypes, props, input, supplier);
1175 private void addPropertiesOfComponentInstance(final Map<String, List<ComponentInstanceProperty>> componentInstancesProperties,
1176 final Map<String, DataTypeDefinition> dataTypes,
1177 final String instanceUniqueId,
1178 final Map<String, Object> props) {
1180 if (isNotEmpty(componentInstancesProperties)) {
1181 componentInstancesProperties.get(instanceUniqueId)
1182 // Converts and adds each value to property map
1183 .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop, prop::getValue));
1187 private void addAttributesOfComponentInstance(final Map<String, List<ComponentInstanceAttribute>> componentInstancesAttributes,
1188 final String instanceUniqueId,
1189 final Map<String, Object> attribs) {
1191 if (isNotEmpty(componentInstancesAttributes) && componentInstancesAttributes.containsKey(instanceUniqueId)) {
1192 componentInstancesAttributes.get(instanceUniqueId)
1193 .forEach(attributeDefinition -> attributeConverter.convertAndAddValue(attribs, attributeDefinition));
1197 private void addPropertiesOfParentComponent(Map<String, DataTypeDefinition> dataTypes,
1198 Component componentOfInstance, Map<String, Object> props) {
1200 List<PropertyDefinition> componentProperties = componentOfInstance.getProperties();
1201 if (isNotEmpty(componentProperties)) {
1202 componentProperties.stream()
1203 // Filters out properties with empty default values
1204 .filter(prop -> StringUtils.isNotEmpty(prop.getDefaultValue()))
1205 // Converts and adds each value to property map
1206 .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop, prop::getDefaultValue));
1210 private void addAttributesOfParentComponent(final Component componentOfInstance, final Map<String, Object> attribs) {
1212 final List<AttributeDefinition> componentAttributes = componentOfInstance.getAttributes();
1213 if (isNotEmpty(componentAttributes)) {
1214 componentAttributes.stream()
1215 // Filters out Attributes with empty default values
1216 .filter(attrib -> StringUtils.isNotEmpty(attrib.getDefaultValue()))
1217 // Converts and adds each value to attribute map
1218 .forEach(attributeDefinition -> attributeConverter.convertAndAddValue(attribs, attributeDefinition));
1222 private ToscaNodeType createNodeType(Component component) {
1223 ToscaNodeType toscaNodeType = new ToscaNodeType();
1224 if (ModelConverter.isAtomicComponent(component)) {
1225 if (((Resource) component).getDerivedFrom() != null) {
1226 toscaNodeType.setDerived_from(((Resource) component).getDerivedFrom().get(0));
1228 toscaNodeType.setDescription(component.getDescription());
1230 String derivedFrom = null != component.getDerivedFromGenericType() ? component.getDerivedFromGenericType()
1232 toscaNodeType.setDerived_from(derivedFrom);
1234 return toscaNodeType;
1237 private Either<Map<String, Object>, ToscaError> createProxyInterfaceTypes(Component container) {
1239 Map<String, Object> proxyInterfaceTypes = new HashMap<>();
1240 Either<Map<String, Object>, ToscaError> res = Either.left(proxyInterfaceTypes);
1241 List<ComponentInstance> componentInstances = container.getComponentInstances();
1242 if (CollectionUtils.isEmpty(componentInstances)) {
1245 Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
1246 componentInstances.stream()
1247 .filter(this::isComponentOfTypeServiceProxy)
1248 .forEach(inst -> serviceProxyInstanceList.put(inst.getToscaComponentName(), inst));
1249 if (MapUtils.isEmpty(serviceProxyInstanceList)) {
1252 for (Entry<String, ComponentInstance> entryProxy : serviceProxyInstanceList.entrySet()) {
1253 Component serviceComponent;
1254 ComponentParametersView componentParametersView = new ComponentParametersView();
1255 componentParametersView.disableAll();
1256 componentParametersView.setIgnoreInterfaces(false);
1257 Either<Component, StorageOperationStatus> service = toscaOperationFacade
1258 .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
1259 if (service.isRight()) {
1260 log.debug("Failed to fetch original service component with id {} for instance {}",
1261 entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName());
1262 return Either.right(ToscaError.GENERAL_ERROR);
1264 serviceComponent = service.left().value();
1267 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither =
1268 interfaceLifecycleOperation.getAllInterfaceLifecycleTypes(serviceComponent.getModel());
1269 if (lifecycleTypeEither.isRight()) {
1270 log.debug("Failed to retrieve global interface types :", lifecycleTypeEither.right().value());
1271 return Either.right(ToscaError.GENERAL_ERROR);
1274 List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value().values().stream()
1275 .map(InterfaceDataDefinition::getType)
1276 .collect(Collectors.toList());
1277 //Add interface types for local interfaces in the original service component for proxy
1278 Map<String, Object> localInterfaceTypes = interfacesOperationsConverter.addInterfaceTypeElement(serviceComponent,
1279 allGlobalInterfaceTypes);
1280 if (MapUtils.isNotEmpty(localInterfaceTypes)) {
1281 proxyInterfaceTypes.putAll(localInterfaceTypes);
1285 return Either.left(proxyInterfaceTypes);
1288 private Either<Map<String, ToscaNodeType>, ToscaError> createProxyNodeTypes(Map<String, Component> componentCache,
1289 Component container) {
1291 Map<String, ToscaNodeType> nodeTypesMap = new HashMap<>();
1292 Either<Map<String, ToscaNodeType>, ToscaError> res = Either.left(nodeTypesMap);
1294 List<ComponentInstance> componentInstances = container.getComponentInstances();
1296 if (componentInstances == null || componentInstances.isEmpty()) {
1299 Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
1300 List<ComponentInstance> proxyInst = componentInstances.stream()
1301 .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceProxy.name()))
1302 .collect(Collectors.toList());
1303 if (proxyInst != null && !proxyInst.isEmpty()) {
1304 for (ComponentInstance inst : proxyInst) {
1305 serviceProxyInstanceList.put(inst.getToscaComponentName(), inst);
1309 if (serviceProxyInstanceList.isEmpty()) {
1312 Either<Resource, StorageOperationStatus> serviceProxyOrigin = toscaOperationFacade
1313 .getLatestByName("serviceProxy", null);
1314 if (serviceProxyOrigin.isRight()) {
1315 log.debug("Failed to fetch normative service proxy resource by tosca name, error {}",
1316 serviceProxyOrigin.right().value());
1317 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
1319 Component origComponent = serviceProxyOrigin.left().value();
1321 for (Entry<String, ComponentInstance> entryProxy : serviceProxyInstanceList.entrySet()) {
1322 Component serviceComponent = null;
1323 ComponentParametersView componentParametersView = new ComponentParametersView();
1324 componentParametersView.disableAll();
1325 componentParametersView.setIgnoreCategories(false);
1326 componentParametersView.setIgnoreProperties(false);
1327 componentParametersView.setIgnoreInputs(false);
1328 componentParametersView.setIgnoreInterfaces(false);
1329 componentParametersView.setIgnoreRequirements(false);
1330 Either<Component, StorageOperationStatus> service = toscaOperationFacade
1331 .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
1332 if (service.isRight()) {
1333 log.debug("Failed to fetch resource with id {} for instance {}",
1334 entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName());
1336 serviceComponent = service.left().value();
1339 ToscaNodeType toscaNodeType = createProxyNodeType(componentCache, origComponent, serviceComponent,
1340 entryProxy.getValue());
1341 nodeTypesMap.put(entryProxy.getKey(), toscaNodeType);
1344 return Either.left(nodeTypesMap);
1347 private void createServiceSubstitutionNodeTypes(final Map<String, Component> componentCache,
1348 final Component container, final ToscaTemplate toscaNode) {
1349 final List<ComponentInstance> componentInstances = container.getComponentInstances();
1351 if (CollectionUtils.isEmpty(componentInstances)) {
1354 final List<ComponentInstance> serviceSubstitutionInstanceList = componentInstances.stream()
1355 .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceSubstitution.name()))
1356 .collect(Collectors.toList());
1357 if (CollectionUtils.isNotEmpty(serviceSubstitutionInstanceList)) {
1358 for (ComponentInstance inst : serviceSubstitutionInstanceList) {
1359 final Map<String, ToscaNodeType> nodeTypes =
1360 toscaNode.getNode_types() == null ? new HashMap<>() : toscaNode.getNode_types();
1361 convertInterfaceNodeType(new HashMap<>(), componentCache.get(inst.getSourceModelUid()), toscaNode,
1367 private ToscaNodeType createProxyNodeType(Map<String, Component> componentCache, Component origComponent,
1368 Component proxyComponent, ComponentInstance componentInstance) {
1369 ToscaNodeType toscaNodeType = new ToscaNodeType();
1370 String derivedFrom = ((Resource) origComponent).getToscaResourceName();
1372 toscaNodeType.setDerived_from(derivedFrom);
1373 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = applicationDataTypeCache.getAll(
1374 origComponent.getModel());
1375 if (dataTypesEither.isRight()) {
1376 log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
1378 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
1379 Map<String, ToscaCapability> capabilities = this.capabilityRequirementConverter
1380 .convertProxyCapabilities(componentCache, componentInstance, dataTypes);
1382 if (MapUtils.isNotEmpty(capabilities)) {
1383 toscaNodeType.setCapabilities(capabilities);
1385 List<Map<String, ToscaRequirement>> proxyNodeTypeRequirements = this.capabilityRequirementConverter
1386 .convertProxyRequirements(componentCache, componentInstance);
1387 if (CollectionUtils.isNotEmpty(proxyNodeTypeRequirements)) {
1388 toscaNodeType.setRequirements(proxyNodeTypeRequirements);
1390 Optional<Map<String, ToscaProperty>> proxyProperties = getProxyNodeTypeProperties(proxyComponent, dataTypes);
1391 proxyProperties.ifPresent(toscaNodeType::setProperties);
1393 Map<String, Object> interfaceMap = new HashMap<>();
1394 if (MapUtils.isEmpty(componentInstance.getInterfaces())) {
1395 final Optional<Map<String, Object>> proxyInterfaces = getProxyNodeTypeInterfaces(proxyComponent, dataTypes);
1396 if (proxyInterfaces.isPresent()) {
1397 interfaceMap = proxyInterfaces.get();
1400 interfaceMap = interfacesOperationsConverter.getInterfacesMapFromComponentInstance(proxyComponent, componentInstance, dataTypes, false);
1403 interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
1404 toscaNodeType.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap);
1406 return toscaNodeType;
1409 private Either<ToscaNodeTemplate, ToscaError> convertComponentInstanceRequirements(Component component,
1410 ComponentInstance componentInstance,
1411 List<RequirementCapabilityRelDef> relations,
1412 ToscaNodeTemplate nodeTypeTemplate,
1413 Component originComponent,
1414 Map<String, Component> componentCache) {
1416 final List<RequirementCapabilityRelDef> requirementDefinitionList = filterRequirements(componentInstance,
1418 if (isNotEmpty(requirementDefinitionList)) {
1420 final List<Map<String, ToscaTemplateRequirement>> toscaRequirements = buildRequirements(component, componentInstance,
1421 requirementDefinitionList, originComponent, componentCache);
1422 if (!toscaRequirements.isEmpty()) {
1423 nodeTypeTemplate.setRequirements(toscaRequirements);
1425 } catch (final Exception e) {
1426 log.debug("Failed to convert component instance requirements for the component instance {}. ",
1427 componentInstance.getName(), e);
1428 return Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
1431 log.debug("Finished to convert requirements for the node type {} ", componentInstance.getName());
1432 return Either.left(nodeTypeTemplate);
1435 private List<Map<String, ToscaTemplateRequirement>> buildRequirements(final Component component,
1436 final ComponentInstance componentInstance,
1437 final List<RequirementCapabilityRelDef> filteredRelations,
1438 final Component originComponent,
1439 final Map<String, Component> componentCache)
1440 throws ToscaExportException {
1442 final List<Map<String, ToscaTemplateRequirement>> toscaRequirements = new ArrayList<>();
1443 for (RequirementCapabilityRelDef relationshipDefinition : filteredRelations) {
1444 final Map<String, ToscaTemplateRequirement> toscaTemplateRequirementMap =
1445 buildRequirement(componentInstance, originComponent, component.getComponentInstances(), relationshipDefinition, componentCache);
1446 toscaRequirements.add(toscaTemplateRequirementMap);
1449 return toscaRequirements;
1452 private List<RequirementCapabilityRelDef> filterRequirements(ComponentInstance componentInstance,
1453 List<RequirementCapabilityRelDef> relations) {
1454 return relations.stream()
1455 .filter(p -> componentInstance.getUniqueId().equals(p.getFromNode())).collect(Collectors.toList());
1458 private Map<String, ToscaTemplateRequirement> buildRequirement(final ComponentInstance fromInstance,
1459 final Component fromOriginComponent,
1460 final List<ComponentInstance> instancesList,
1461 final RequirementCapabilityRelDef relationshipDefinition,
1462 final Map<String, Component> componentCache)
1463 throws ToscaExportException {
1465 final Map<String, List<RequirementDefinition>> reqMap = fromOriginComponent.getRequirements();
1466 final CapabilityRequirementRelationship capabilityRequirementRelationship = relationshipDefinition
1467 .getRelationships().get(0);
1468 final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation();
1470 final ComponentInstance toInstance = instancesList.stream()
1471 .filter(i -> relationshipDefinition.getToNode().equals(i.getUniqueId()))
1472 .findFirst().orElse(null);
1473 if (toInstance == null) {
1474 final String errorMsg = String
1475 .format("Failed to find a relation from the node %s to the node %s", fromInstance.getName(),
1476 relationshipDefinition.getToNode());
1477 log.debug(errorMsg);
1478 throw new ToscaExportException(errorMsg);
1480 final Optional<RequirementDefinition> reqOpt =
1481 findRequirement(fromOriginComponent, reqMap, relationshipInfo, fromInstance.getUniqueId());
1482 if (reqOpt.isEmpty()) {
1483 final String errorMsg = String
1484 .format("Failed to find a requirement with uniqueId %s on a component with uniqueId %s",
1485 relationshipInfo.getRequirementUid(), fromOriginComponent.getUniqueId());
1486 log.debug(errorMsg);
1487 throw new ToscaExportException(errorMsg);
1489 final ComponentParametersView filter = new ComponentParametersView(true);
1490 filter.setIgnoreComponentInstances(false);
1491 filter.setIgnoreCapabilities(false);
1492 filter.setIgnoreGroups(false);
1493 final Either<Component, StorageOperationStatus> getOriginRes =
1494 toscaOperationFacade.getToscaElement(toInstance.getActualComponentUid(), filter);
1495 if (getOriginRes.isRight()) {
1496 final String errorMsg = String.format(
1497 "Failed to build substituted name for the requirement %s. "
1498 + "Failed to get an origin component with uniqueId %s",
1499 reqOpt.get().getName(), toInstance.getActualComponentUid());
1500 log.debug(errorMsg);
1501 throw new ToscaExportException(errorMsg);
1503 final Component toOriginComponent = getOriginRes.left().value();
1504 Optional<CapabilityDefinition> capOpt = toOriginComponent.getCapabilities().get(reqOpt.get().getCapability()).stream()
1505 .filter(c -> isCapabilityBelongToRelation(relationshipInfo, c)).findFirst();
1506 if (capOpt.isEmpty()) {
1507 capOpt = findCapability(relationshipInfo, toOriginComponent, fromOriginComponent, reqOpt.get());
1508 if (capOpt.isEmpty()) {
1509 final String errorMsg = String
1510 .format("Failed to find a capability with name %s on a component with uniqueId %s",
1511 relationshipInfo.getCapability(), fromOriginComponent.getUniqueId());
1512 log.debug(errorMsg);
1513 throw new ToscaExportException(errorMsg);
1516 return buildRequirement(fromOriginComponent, toOriginComponent, capOpt.get(), reqOpt.get(),
1517 capabilityRequirementRelationship, toInstance, componentCache);
1520 private boolean isCapabilityBelongToRelation(RelationshipInfo reqAndRelationshipPair,
1521 CapabilityDefinition capability) {
1522 return capability.getName().equals(reqAndRelationshipPair.getCapability()) && (capability.getOwnerId() != null
1523 && capability.getOwnerId().equals(reqAndRelationshipPair.getCapabilityOwnerId()));
1526 private Optional<CapabilityDefinition> findCapability(RelationshipInfo reqAndRelationshipPair,
1527 Component toOriginComponent, Component fromOriginComponent,
1528 RequirementDefinition requirement) {
1529 Optional<CapabilityDefinition> cap = toOriginComponent.getCapabilities().get(requirement.getCapability())
1530 .stream().filter(c -> c.getType().equals(requirement.getCapability())).findFirst();
1531 if (!cap.isPresent()) {
1532 log.debug("Failed to find a capability with name {} on a component with uniqueId {}",
1533 reqAndRelationshipPair.getCapability(), fromOriginComponent.getUniqueId());
1538 private Map<String, ToscaTemplateRequirement> buildRequirement(final Component fromOriginComponent,
1539 final Component toOriginComponent,
1540 final CapabilityDefinition capability,
1541 final RequirementDefinition requirement,
1542 final CapabilityRequirementRelationship capabilityRequirementRelationship,
1543 final ComponentInstance toInstance,
1544 final Map<String, Component> componentCache)
1545 throws ToscaExportException {
1547 List<String> reducedPath = capability.getPath();
1548 if (capability.getOwnerId() != null) {
1549 reducedPath = capabilityRequirementConverter
1550 .getReducedPathByOwner(capability.getPath(), capability.getOwnerId());
1552 final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation();
1553 final Either<String, Boolean> capabilityNameEither = capabilityRequirementConverter.buildSubstitutedName(componentCache,
1554 toOriginComponent, reducedPath, relationshipInfo.getCapability(), capability.getPreviousName(), capability.getExternalName());
1555 if (capabilityNameEither.isRight()) {
1556 final String errorMsg = String.format(
1557 "Failed to build a substituted capability name for the capability with name %s on a component with uniqueId %s",
1558 capabilityRequirementRelationship.getCapability(), toOriginComponent.getUniqueId());
1561 throw new ToscaExportException(errorMsg);
1563 final Either<String, Boolean> requirementNameEither = capabilityRequirementConverter
1564 .buildSubstitutedName(componentCache, fromOriginComponent,
1565 requirement.getPath(), relationshipInfo.getRequirement(), requirement.getPreviousName(), requirement.getExternalName());
1566 if (requirementNameEither.isRight()) {
1567 final String errorMsg = String.format("Failed to build a substituted requirement name for the requirement "
1568 + "with name %s on a component with uniqueId %s",
1569 capabilityRequirementRelationship.getRequirement(), fromOriginComponent.getUniqueId());
1570 log.debug(errorMsg);
1571 throw new ToscaExportException(errorMsg);
1573 final ToscaTemplateRequirement toscaRequirement = new ToscaTemplateRequirement();
1574 final Map<String, ToscaTemplateRequirement> toscaReqMap = new HashMap<>();
1575 toscaRequirement.setNode(toInstance.getName());
1576 toscaRequirement.setCapability(capabilityNameEither.left().value());
1577 if (isNotEmpty(capabilityRequirementRelationship.getOperations())) {
1578 toscaRequirement.setRelationship(new ToscaRelationshipBuilder().from(capabilityRequirementRelationship));
1580 toscaReqMap.put(requirementNameEither.left().value(), toscaRequirement);
1584 private Optional<RequirementDefinition> findRequirement(Component fromOriginComponent,
1585 Map<String, List<RequirementDefinition>> reqMap,
1586 RelationshipInfo reqAndRelationshipPair,
1587 String fromInstanceId) {
1588 for (List<RequirementDefinition> reqList : reqMap.values()) {
1589 Optional<RequirementDefinition> reqOpt = reqList.stream().filter(
1590 r -> isRequirementBelongToRelation(fromOriginComponent, reqAndRelationshipPair, r, fromInstanceId))
1592 if (reqOpt.isPresent()) {
1596 return Optional.empty();
1600 * Allows detecting the requirement belonging to the received relationship The detection logic is: A requirement belongs to a relationship IF
1601 * 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
1602 * requirement equals to requirementOwnerId of the relation OR uniqueId of toInstance equals to capabilityOwnerId of the relation
1604 private boolean isRequirementBelongToRelation(Component originComponent, RelationshipInfo reqAndRelationshipPair,
1605 RequirementDefinition requirement, String fromInstanceId) {
1606 if (originComponent.isService() && requirement.getUniqueId().equals(reqAndRelationshipPair.getRequirementUid())) {
1609 if (!StringUtils.equals(requirement.getName(), reqAndRelationshipPair.getRequirement())) {
1610 log.debug("Failed to find a requirement with name {} and reqAndRelationshipPair {}", requirement.getName(),
1611 reqAndRelationshipPair.getRequirement());
1614 return ModelConverter.isAtomicComponent(originComponent) || isRequirementBelongToOwner(reqAndRelationshipPair, requirement, fromInstanceId,
1618 private boolean isRequirementBelongToOwner(RelationshipInfo reqAndRelationshipPair, RequirementDefinition requirement, String fromInstanceId,
1619 Component originComponent) {
1620 return StringUtils.equals(requirement.getOwnerId(), reqAndRelationshipPair.getRequirementOwnerId()) || (
1621 isCvfc(originComponent) && StringUtils.equals(fromInstanceId, reqAndRelationshipPair.getRequirementOwnerId()) || StringUtils
1622 .equals(requirement.getOwnerId(), originComponent.getUniqueId()));
1625 private boolean isCvfc(Component component) {
1626 return component.getComponentType() == ComponentTypeEnum.RESOURCE && ((Resource) component).getResourceType() == ResourceTypeEnum.CVFC;
1629 private Either<Map<String, String[]>, ToscaError> convertSubstitutionMappingCapabilities(final Component component,
1630 final Map<String, Component> componentCache) {
1631 Either<Map<String, String[]>, ToscaError> toscaCapabilitiesRes =
1632 capabilityRequirementConverter.convertSubstitutionMappingCapabilities(componentCache, component);
1633 if (toscaCapabilitiesRes.isRight()) {
1634 log.debug("Failed convert capabilities for the component {}. ", component.getName());
1635 return Either.right(toscaCapabilitiesRes.right().value());
1637 if (isNotEmpty(toscaCapabilitiesRes.left().value())) {
1638 log.debug("Finish convert capabilities for the component {}. ", component.getName());
1639 return Either.left(toscaCapabilitiesRes.left().value());
1641 log.debug("Finished to convert capabilities for the component {}. ", component.getName());
1643 return Either.left(Collections.emptyMap());
1646 private Either<ToscaNodeType, ToscaError> convertCapabilities(Map<String, Component> componentsCache, Component component, ToscaNodeType nodeType,
1647 Map<String, DataTypeDefinition> dataTypes) {
1648 Map<String, ToscaCapability> toscaCapabilities = capabilityRequirementConverter.convertCapabilities(componentsCache, component, dataTypes);
1649 if (!toscaCapabilities.isEmpty()) {
1650 nodeType.setCapabilities(toscaCapabilities);
1652 log.debug("Finish convert Capabilities for node type");
1653 return Either.left(nodeType);
1656 private Map<String, ToscaTemplateArtifact> convertToNodeTemplateArtifacts(Map<String, ToscaArtifactDataDefinition> artifacts) {
1657 if (artifacts == null) {
1660 Map<String, ToscaTemplateArtifact> arts = new HashMap<>();
1661 for (Map.Entry<String, ToscaArtifactDataDefinition> entry : artifacts.entrySet()) {
1662 ToscaTemplateArtifact artifact = new ToscaTemplateArtifact();
1663 artifact.setFile(entry.getValue().getFile());
1664 artifact.setType(entry.getValue().getType());
1665 artifact.setProperties(entry.getValue().getProperties());
1666 arts.put(entry.getKey(), artifact);
1671 private NodeFilter convertToNodeTemplateNodeFilterComponent(CINodeFilterDataDefinition inNodeFilter) {
1672 if (inNodeFilter == null) {
1675 NodeFilter nodeFilter = new NodeFilter();
1676 ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities = inNodeFilter.getCapabilities();
1677 ListDataDefinition<PropertyFilterDataDefinition> origProperties = inNodeFilter.getProperties();
1678 List<Map<String, CapabilityFilter>> capabilitiesCopy = new ArrayList<>();
1679 copyNodeFilterCapabilitiesTemplate(origCapabilities, capabilitiesCopy);
1680 if (CollectionUtils.isNotEmpty(capabilitiesCopy)) {
1681 nodeFilter.setCapabilities(capabilitiesCopy);
1683 final List<Map<String, List<Object>>> propertiesCopy = copyNodeFilterProperties(origProperties);
1684 if (CollectionUtils.isNotEmpty(propertiesCopy)) {
1685 nodeFilter.setProperties(propertiesCopy);
1687 nodeFilter.setTosca_id(cloneToscaId(inNodeFilter.getTosca_id()));
1688 nodeFilter = (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
1692 private NodeFilter convertToSubstitutionFilterComponent(final SubstitutionFilterDataDefinition substitutionFilterDataDefinition) {
1693 if (substitutionFilterDataDefinition == null) {
1696 NodeFilter nodeFilter = new NodeFilter();
1697 final List<Map<String, List<Object>>> propertiesCopy = copySubstitutionPropertiesFilter(substitutionFilterDataDefinition.getProperties());
1698 if (!propertiesCopy.isEmpty()) {
1699 nodeFilter.setProperties(propertiesCopy);
1701 nodeFilter.setTosca_id(cloneToscaId(substitutionFilterDataDefinition.getTosca_id()));
1702 return (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
1705 private Object cloneToscaId(Object toscaId) {
1706 return Objects.isNull(toscaId) ? null : cloneObjectFromYml(toscaId, toscaId.getClass());
1709 private Object cloneObjectFromYml(Object objToClone, Class classOfObj) {
1710 String objectAsYml = yamlUtil.objectToYaml(objToClone);
1711 return yamlUtil.yamlToObject(objectAsYml, classOfObj);
1714 private void copyNodeFilterCapabilitiesTemplate(ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities,
1715 List<Map<String, CapabilityFilter>> capabilitiesCopy) {
1716 if (origCapabilities == null || origCapabilities.getListToscaDataDefinition() == null || origCapabilities.getListToscaDataDefinition()
1720 for (RequirementNodeFilterCapabilityDataDefinition capability : origCapabilities.getListToscaDataDefinition()) {
1721 Map<String, CapabilityFilter> capabilityFilterCopyMap = new HashMap<>();
1722 final var capabilityFilter = new CapabilityFilter();
1723 capabilityFilter.setProperties(copyNodeFilterProperties(capability.getProperties()));
1724 capabilityFilterCopyMap.put(capability.getName(), capabilityFilter);
1725 capabilitiesCopy.add(capabilityFilterCopyMap);
1729 private List<Map<String, List<Object>>> copyNodeFilterProperties(final ListDataDefinition<PropertyFilterDataDefinition> origProperties) {
1730 if (origProperties == null || origProperties.getListToscaDataDefinition() == null || origProperties.isEmpty()) {
1731 return Collections.emptyList();
1733 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1734 Map<String, List<Object>> propertyFilterDefinitionMap = new HashMap<>();
1735 for (final PropertyFilterDataDefinition propertyFilter : origProperties.getListToscaDataDefinition()) {
1736 final String propertyName = propertyFilter.getName();
1737 for (final PropertyFilterConstraintDataDefinition filterConstraint : propertyFilter.getConstraints()) {
1738 propertyFilterDefinitionMap.compute(propertyName, (propertyName1, constraints) -> {
1739 if (constraints == null) {
1740 constraints = new ArrayList<>();
1742 constraints.add(buildNodeFilterValue(filterConstraint));
1747 propertyFilterDefinitionMap.entrySet().stream()
1748 .map(entry -> Map.of(entry.getKey(), entry.getValue()))
1749 .forEach(propertiesCopy::add);
1750 return propertiesCopy;
1753 private List<Map<String, List<Object>>> copySubstitutionPropertiesFilter(
1754 final ListDataDefinition<SubstitutionFilterPropertyDataDefinition> origProperties) {
1756 if (origProperties == null || origProperties.getListToscaDataDefinition() == null || origProperties.isEmpty()) {
1757 return Collections.emptyList();
1759 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1760 Map<String, List<Object>> propertyFilterDefinitionMap = new HashMap<>();
1761 for (final SubstitutionFilterPropertyDataDefinition propertyFilter : origProperties.getListToscaDataDefinition()) {
1762 final String propertyName = propertyFilter.getName();
1763 for (final PropertyFilterConstraintDataDefinition filterConstraint : propertyFilter.getConstraints()) {
1764 propertyFilterDefinitionMap.compute(propertyName, (propertyName1, constraints) -> {
1765 if (constraints == null) {
1766 constraints = new ArrayList<>();
1768 constraints.add(buildNodeFilterValue(filterConstraint));
1773 propertyFilterDefinitionMap.entrySet().stream()
1774 .map(entry -> Map.of(entry.getKey(), entry.getValue()))
1775 .forEach(propertiesCopy::add);
1776 return propertiesCopy;
1779 private Map<String, String[]> buildSubstitutionMappingPropertyMapping(final Component component) {
1780 if (component == null || CollectionUtils.isEmpty(component.getInputs())) {
1781 return Collections.emptyMap();
1783 Map<String, String[]> propertyMapping = new HashMap<>();
1784 List<InputDefinition> propertyMappedInputList = component.getInputs().stream().filter(InputDefinition::isMappedToComponentProperty).collect(
1785 Collectors.toList());
1787 if (CollectionUtils.isNotEmpty(propertyMappedInputList)) {
1788 propertyMappedInputList.forEach(inputDefinition -> {
1789 if (StringUtils.isNotEmpty(inputDefinition.getPropertyId())) {
1790 Optional<PropertyDefinition> property = component.getProperties().stream()
1791 .filter(propertyDefinition -> propertyDefinition.getUniqueId().equals(inputDefinition.getPropertyId())).findFirst();
1792 if (property.isPresent()) {
1793 propertyMapping.put(property.get().getName(), new String[]{inputDefinition.getName()});
1796 propertyMapping.put(inputDefinition.getName(), new String[]{inputDefinition.getName()});
1800 return propertyMapping;
1803 private Map<String, String[]> buildSubstitutionMappingAttributesMapping(final Component component) {
1804 if (component == null || CollectionUtils.isEmpty(component.getOutputs())) {
1805 return Collections.emptyMap();
1807 return component.getOutputs().stream().map(AttributeDataDefinition::getName)
1808 .collect(Collectors.toMap(outputName -> outputName, outputName -> new String[]{outputName}, (outputName1, outputName2) -> outputName1));
1811 private Optional<Map<String, ToscaProperty>> getProxyNodeTypeProperties(Component proxyComponent, Map<String, DataTypeDefinition> dataTypes) {
1812 if (Objects.isNull(proxyComponent)) {
1813 return Optional.empty();
1815 final var proxyProperties = convertInputsToProperties(dataTypes, proxyComponent.getInputs(), proxyComponent.getUniqueId());
1816 if (CollectionUtils.isNotEmpty(proxyComponent.getProperties())) {
1817 proxyProperties.putAll(proxyComponent.getProperties().stream()
1818 .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, proxyComponent.getInputs())).collect(Collectors
1819 .toMap(PropertyDataDefinition::getName,
1820 property -> propertyConvertor.convertProperty(dataTypes, property, PropertyType.PROPERTY))));
1822 return MapUtils.isNotEmpty(proxyProperties) ? Optional.of(proxyProperties) : Optional.empty();
1825 private Map<String, ToscaProperty> convertInputsToProperties(Map<String, DataTypeDefinition> dataTypes, List<InputDefinition> componentInputs,
1826 String componentUniqueId) {
1827 if (CollectionUtils.isEmpty(componentInputs)) {
1828 return new HashMap<>();
1830 return componentInputs.stream().filter(input -> componentUniqueId.equals(input.getInstanceUniqueId()))
1831 .collect(Collectors.toMap(InputDefinition::getName, i -> propertyConvertor.convertProperty(dataTypes, i, PropertyType.INPUT)));
1834 private Optional<Map<String, Object>> getProxyNodeTypeInterfaces(Component proxyComponent, Map<String, DataTypeDefinition> dataTypes) {
1835 if (Objects.isNull(proxyComponent) || MapUtils.isEmpty(proxyComponent.getInterfaces())) {
1836 return Optional.empty();
1838 Map<String, InterfaceDefinition> proxyComponentInterfaces = proxyComponent.getInterfaces();
1839 //Unset artifact path for operation implementation for proxy node types as for operations with artifacts it is
1841 // always available in the proxy node template
1842 removeOperationImplementationForProxyNodeType(proxyComponentInterfaces);
1843 return Optional.ofNullable(interfacesOperationsConverter.getInterfacesMap(proxyComponent, null, proxyComponentInterfaces, dataTypes, false));
1846 private Configuration getConfiguration() {
1847 return ConfigurationManager.getConfigurationManager().getConfiguration();
1850 private static class CustomRepresenter extends Representer {
1852 CustomRepresenter() {
1854 this.representers.put(ToscaPropertyAssignment.class, new RepresentToscaPropertyAssignment());
1855 this.representers.put(ToscaAttribute.class, new RepresentToscaAttribute());
1856 // null representer is exceptional and it is stored as an instance
1859 this.nullRepresenter = new RepresentNull();
1862 public boolean validateGetInputValue(final Object valueObj) {
1863 if (!(valueObj instanceof List) && !(valueObj instanceof String)) {
1866 if (valueObj instanceof List) {
1867 return ((List) valueObj).size() > 1;
1872 public boolean validateGetPropertyOrAttributeValue(final Object valueObj) {
1873 if (valueObj instanceof List) {
1874 return ((List) valueObj).size() > 1;
1880 protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue, Tag customTag) {
1881 if (propertyValue == null) {
1884 // skip not relevant for Tosca property
1885 if ("dependencies".equals(property.getName())) {
1888 if (javaBean instanceof ToscaRelationshipTemplate && "name".equals(property.getName())) {
1891 if (javaBean instanceof ToscaPropertyConstraint) {
1892 return handleToscaPropertyConstraint((ToscaPropertyConstraint) javaBean, property, propertyValue, customTag);
1894 removeDefaultP(propertyValue);
1895 NodeTuple defaultNode = super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
1896 if (javaBean instanceof ToscaTopolgyTemplate && "relationshipTemplates".equals(property.getName())) {
1897 return new NodeTuple(representData("relationship_templates"), defaultNode.getValueNode());
1899 return "_defaultp_".equals(property.getName()) ? new NodeTuple(representData("default"), defaultNode.getValueNode()) : defaultNode;
1902 private NodeTuple handleToscaPropertyConstraint(final ToscaPropertyConstraint javaBean, final Property property, final Object propertyValue,
1903 final Tag customTag) {
1904 final NodeTuple nodeTuple = super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
1905 final String entryToscaName = javaBean.getEntryToscaName(property.getName());
1906 return new NodeTuple(representData(entryToscaName), nodeTuple.getValueNode());
1909 private void removeDefaultP(final Object propertyValue) {
1910 if (propertyValue instanceof Map) {
1911 final Map mapPropertyValue = ((Map) propertyValue);
1912 final Iterator<Entry> iter = mapPropertyValue.entrySet().iterator();
1913 Object defaultValue = null;
1914 while (iter.hasNext()) {
1915 final Map.Entry entry = iter.next();
1916 if ("_defaultp_".equals(entry.getKey())) {
1917 defaultValue = entry.getValue();
1919 } else if (entry.getValue() instanceof Map) {
1920 removeDefaultP(entry.getValue());
1923 if (defaultValue != null) {
1924 mapPropertyValue.putIfAbsent("default", defaultValue);
1930 protected MappingNode representJavaBean(Set<Property> properties, Object javaBean) {
1931 // remove the bean type from the output yaml (!! ...)
1932 if (!classTags.containsKey(javaBean.getClass())) {
1933 addClassTag(javaBean.getClass(), Tag.MAP);
1935 return super.representJavaBean(properties, javaBean);
1938 private class RepresentToscaAttribute implements Represent {
1941 public Node representData(Object data) {
1942 final ToscaAttribute toscaAttribute = (ToscaAttribute) data;
1943 return represent(toscaAttribute.asToscaMap());
1947 private class RepresentToscaPropertyAssignment implements Represent {
1949 public Node representData(Object data) {
1950 final ToscaPropertyAssignment toscaOperationAssignment = (ToscaPropertyAssignment) data;
1951 if (toscaOperationAssignment.getValue() instanceof String) {
1952 final String stringValue = (String) toscaOperationAssignment.getValue();
1953 if (isPropertyOrAttributeFunction(stringValue)) {
1954 return representGetAttribute(stringValue);
1956 return representScalar(Tag.STR, stringValue);
1958 return represent(null);
1961 public Node representGetAttribute(final String getAttributeFunction) {
1962 return represent(new Yaml().load(getAttributeFunction));
1965 public boolean isPropertyOrAttributeFunction(final String value) {
1967 final Yaml yaml = new Yaml();
1968 final Object yamlObj = yaml.load(value);
1969 if (!(yamlObj instanceof Map)) {
1972 final Map<String, Object> getAttributeMap = (Map) yamlObj;
1973 if (getAttributeMap.size() != 1) {
1976 final List<String> functionList = Arrays
1977 .asList(GET_ATTRIBUTE.getFunctionName(), GET_INPUT.getFunctionName(), GET_PROPERTY.getFunctionName());
1978 final Optional<String> function = getAttributeMap.keySet().stream()
1979 .filter(key -> functionList.stream().anyMatch(function1 -> function1.equals(key))).findFirst();
1980 if (function.isEmpty()) {
1983 final String functionName = function.get();
1984 final Object getAttributeValueObj = getAttributeMap.get(functionName);
1985 if (GET_INPUT.getFunctionName().equals(functionName)) {
1986 return validateGetInputValue(getAttributeValueObj);
1988 return validateGetPropertyOrAttributeValue(getAttributeValueObj);
1990 } catch (final Exception ignored) {
1996 private class RepresentNull implements Represent {
1999 public Node representData(Object data) {
2000 // possible values are here http://yaml.org/type/null.html
2001 return representScalar(Tag.NULL, "");
2006 private static class UnsortedPropertyUtils extends PropertyUtils {
2009 protected Set<Property> createPropertySet(Class type, BeanAccess bAccess) {
2010 Collection<Property> fields = getPropertiesMap(type, BeanAccess.FIELD).values();
2011 return new LinkedHashSet<>(fields);