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;
36 import java.io.StringReader;
37 import java.nio.file.Path;
38 import java.util.ArrayList;
39 import java.util.Arrays;
40 import java.util.Collection;
41 import java.util.Collections;
42 import java.util.HashMap;
43 import java.util.HashSet;
44 import java.util.Iterator;
45 import java.util.LinkedHashMap;
46 import java.util.LinkedHashSet;
47 import java.util.List;
49 import java.util.Map.Entry;
50 import java.util.Objects;
51 import java.util.Optional;
53 import java.util.function.Supplier;
54 import java.util.stream.Collectors;
55 import org.apache.commons.collections.CollectionUtils;
56 import org.apache.commons.collections.MapUtils;
57 import org.apache.commons.io.FilenameUtils;
58 import org.apache.commons.lang3.StringUtils;
59 import org.apache.commons.lang3.tuple.ImmutablePair;
60 import org.apache.commons.lang3.tuple.ImmutableTriple;
61 import org.apache.commons.lang3.tuple.Triple;
62 import org.onap.sdc.tosca.services.YamlUtil;
63 import org.openecomp.sdc.be.components.impl.exceptions.SdcResourceNotFoundException;
64 import org.openecomp.sdc.be.config.Configuration;
65 import org.openecomp.sdc.be.config.ConfigurationManager;
66 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
67 import org.openecomp.sdc.be.data.model.ToscaImportByModel;
68 import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
69 import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition;
70 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
71 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
72 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
73 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
74 import org.openecomp.sdc.be.datatypes.elements.PropertyFilterConstraintDataDefinition;
75 import org.openecomp.sdc.be.datatypes.elements.PropertyFilterDataDefinition;
76 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition;
77 import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition;
78 import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterPropertyDataDefinition;
79 import org.openecomp.sdc.be.datatypes.elements.ToscaArtifactDataDefinition;
80 import org.openecomp.sdc.be.datatypes.elements.ToscaFunction;
81 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
82 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
83 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
84 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
85 import org.openecomp.sdc.be.exception.ToscaExportException;
86 import org.openecomp.sdc.be.model.ArtifactDefinition;
87 import org.openecomp.sdc.be.model.AttributeDefinition;
88 import org.openecomp.sdc.be.model.CapabilityDefinition;
89 import org.openecomp.sdc.be.model.CapabilityRequirementRelationship;
90 import org.openecomp.sdc.be.model.Component;
91 import org.openecomp.sdc.be.model.ComponentInstance;
92 import org.openecomp.sdc.be.model.ComponentInstanceAttribute;
93 import org.openecomp.sdc.be.model.ComponentInstanceInput;
94 import org.openecomp.sdc.be.model.ComponentInstanceInterface;
95 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
96 import org.openecomp.sdc.be.model.ComponentParametersView;
97 import org.openecomp.sdc.be.model.DataTypeDefinition;
98 import org.openecomp.sdc.be.model.GroupInstance;
99 import org.openecomp.sdc.be.model.InputDefinition;
100 import org.openecomp.sdc.be.model.InterfaceDefinition;
101 import org.openecomp.sdc.be.model.PropertyDefinition;
102 import org.openecomp.sdc.be.model.RelationshipInfo;
103 import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
104 import org.openecomp.sdc.be.model.RequirementDefinition;
105 import org.openecomp.sdc.be.model.Resource;
106 import org.openecomp.sdc.be.model.Service;
107 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
108 import org.openecomp.sdc.be.model.category.CategoryDefinition;
109 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
110 import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter;
111 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
112 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
113 import org.openecomp.sdc.be.model.operations.impl.ModelOperation;
114 import org.openecomp.sdc.be.model.tosca.converters.ToscaMapValueConverter;
115 import org.openecomp.sdc.be.tosca.PropertyConvertor.PropertyType;
116 import org.openecomp.sdc.be.tosca.builder.ToscaRelationshipBuilder;
117 import org.openecomp.sdc.be.tosca.exception.ToscaConversionException;
118 import org.openecomp.sdc.be.tosca.model.CapabilityFilter;
119 import org.openecomp.sdc.be.tosca.model.NodeFilter;
120 import org.openecomp.sdc.be.tosca.model.SubstitutionMapping;
121 import org.openecomp.sdc.be.tosca.model.ToscaAttribute;
122 import org.openecomp.sdc.be.tosca.model.ToscaCapability;
123 import org.openecomp.sdc.be.tosca.model.ToscaDataType;
124 import org.openecomp.sdc.be.tosca.model.ToscaGroupTemplate;
125 import org.openecomp.sdc.be.tosca.model.ToscaNodeTemplate;
126 import org.openecomp.sdc.be.tosca.model.ToscaNodeType;
127 import org.openecomp.sdc.be.tosca.model.ToscaPolicyTemplate;
128 import org.openecomp.sdc.be.tosca.model.ToscaProperty;
129 import org.openecomp.sdc.be.tosca.model.ToscaPropertyAssignment;
130 import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraint;
131 import org.openecomp.sdc.be.tosca.model.ToscaRelationshipTemplate;
132 import org.openecomp.sdc.be.tosca.model.ToscaRequirement;
133 import org.openecomp.sdc.be.tosca.model.ToscaTemplate;
134 import org.openecomp.sdc.be.tosca.model.ToscaTemplateArtifact;
135 import org.openecomp.sdc.be.tosca.model.ToscaTemplateRequirement;
136 import org.openecomp.sdc.be.tosca.model.ToscaTopolgyTemplate;
137 import org.openecomp.sdc.be.tosca.utils.ForwardingPathToscaUtil;
138 import org.openecomp.sdc.be.tosca.utils.InputConverter;
139 import org.openecomp.sdc.be.tosca.utils.OutputConverter;
140 import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
141 import org.openecomp.sdc.common.log.wrappers.Logger;
142 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
143 import org.springframework.beans.factory.annotation.Autowired;
144 import org.yaml.snakeyaml.DumperOptions;
145 import org.yaml.snakeyaml.DumperOptions.FlowStyle;
146 import org.yaml.snakeyaml.Yaml;
147 import org.yaml.snakeyaml.introspector.BeanAccess;
148 import org.yaml.snakeyaml.introspector.Property;
149 import org.yaml.snakeyaml.introspector.PropertyUtils;
150 import org.yaml.snakeyaml.nodes.MappingNode;
151 import org.yaml.snakeyaml.nodes.Node;
152 import org.yaml.snakeyaml.nodes.NodeTuple;
153 import org.yaml.snakeyaml.nodes.Tag;
154 import org.yaml.snakeyaml.representer.Represent;
155 import org.yaml.snakeyaml.representer.Representer;
157 @org.springframework.stereotype.Component("tosca-export-handler")
158 public class ToscaExportHandler {
160 public static final String ASSET_TOSCA_TEMPLATE = "assettoscatemplate";
161 private static final Logger log = Logger.getLogger(ToscaExportHandler.class);
162 private static final String INVARIANT_UUID = "invariantUUID";
163 private static final String TOSCA_VERSION = "tosca_simple_yaml_1_3";
164 private static final String SERVICE_NODE_TYPE_PREFIX = "org.openecomp.service.";
165 private static final String IMPORTS_FILE_KEY = "file";
166 private static final String TOSCA_INTERFACE_NAME = "-interface.yml";
167 private static final String FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION = "convertToToscaTemplate - failed to get Default Imports section from configuration";
168 private static final String NOT_SUPPORTED_COMPONENT_TYPE = "Not supported component type {}";
169 private static final String NATIVE_ROOT = "tosca.nodes.Root";
170 private static final List<String> EXCLUDED_CATEGORY_SPECIFIC_METADATA = List
171 .of("Service Function", "Service Role", "Naming Policy", "Service Type");
172 private static final YamlUtil yamlUtil = new YamlUtil();
173 private final ApplicationDataTypeCache applicationDataTypeCache;
174 private final ToscaOperationFacade toscaOperationFacade;
175 private final CapabilityRequirementConverter capabilityRequirementConverter;
176 private final PolicyExportParser policyExportParser;
177 private final GroupExportParser groupExportParser;
178 private final PropertyConvertor propertyConvertor;
179 private final AttributeConverter attributeConverter;
180 private final InputConverter inputConverter;
181 private final OutputConverter outputConverter;
182 private final InterfaceLifecycleOperation interfaceLifecycleOperation;
183 private final InterfacesOperationsConverter interfacesOperationsConverter;
184 private final ModelOperation modelOperation;
187 public ToscaExportHandler(final ApplicationDataTypeCache applicationDataTypeCache,
188 final ToscaOperationFacade toscaOperationFacade,
189 final CapabilityRequirementConverter capabilityRequirementConverter,
190 final PolicyExportParser policyExportParser,
191 final GroupExportParser groupExportParser,
192 final PropertyConvertor propertyConvertor,
193 final AttributeConverter attributeConverter,
194 final InputConverter inputConverter,
195 final OutputConverter outputConverter,
196 final InterfaceLifecycleOperation interfaceLifecycleOperation,
197 final InterfacesOperationsConverter interfacesOperationsConverter,
198 final ModelOperation modelOperation) {
199 this.applicationDataTypeCache = applicationDataTypeCache;
200 this.toscaOperationFacade = toscaOperationFacade;
201 this.capabilityRequirementConverter = capabilityRequirementConverter;
202 this.policyExportParser = policyExportParser;
203 this.groupExportParser = groupExportParser;
204 this.propertyConvertor = propertyConvertor;
205 this.attributeConverter = attributeConverter;
206 this.inputConverter = inputConverter;
207 this.outputConverter = outputConverter;
208 this.interfaceLifecycleOperation = interfaceLifecycleOperation;
209 this.interfacesOperationsConverter = interfacesOperationsConverter;
210 this.modelOperation = modelOperation;
213 public static String getInterfaceFilename(String artifactName) {
214 return artifactName.substring(0, artifactName.lastIndexOf('.')) + TOSCA_INTERFACE_NAME;
217 private static void removeOperationImplementationForProxyNodeType(Map<String, InterfaceDefinition> proxyComponentInterfaces) {
218 if (MapUtils.isEmpty(proxyComponentInterfaces)) {
221 proxyComponentInterfaces.values().stream().map(InterfaceDataDefinition::getOperations).filter(MapUtils::isNotEmpty)
222 .forEach(operations -> operations.values().forEach(operation -> operation.setImplementation(null)));
225 public Either<ToscaRepresentation, ToscaError> exportComponent(Component component) {
226 return convertToToscaTemplate(component).left().map(this::createToscaRepresentation);
229 public Either<ToscaRepresentation, ToscaError> exportDataType(DataTypeDefinition dataTypeDefinition) {
230 return convertDataTypeToToscaTemplate(dataTypeDefinition).left().map(this::createToscaRepresentation);
233 public Either<ToscaRepresentation, ToscaError> exportComponentInterface(final Component component, final boolean isAssociatedComponent) {
234 final List<Map<String, Map<String, String>>> imports = new ArrayList<>(getDefaultToscaImports(component.getModel()));
235 if (CollectionUtils.isEmpty(imports)) {
236 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
237 return Either.right(ToscaError.GENERAL_ERROR);
239 List<Triple<String, String, Component>> dependencies = new ArrayList<>();
240 if (component.getDerivedFromGenericType() != null && !component.getDerivedFromGenericType()
241 .startsWith("org.openecomp.resource.abstract.nodes.")) {
242 final Either<Component, StorageOperationStatus> baseType = toscaOperationFacade
243 .getByToscaResourceNameAndVersion(component.getDerivedFromGenericType(), component.getDerivedFromGenericVersion(),
244 component.getModel());
245 if (baseType.isLeft() && baseType.left().value() != null) {
246 addDependencies(imports, dependencies, baseType.left().value());
248 log.debug("Failed to fetch derived from type {}", component.getDerivedFromGenericType());
252 String toscaVersion = null;
253 if (component instanceof Resource) {
254 toscaVersion = ((Resource) component).getToscaVersion();
256 ToscaTemplate toscaTemplate = new ToscaTemplate(toscaVersion != null ? toscaVersion : TOSCA_VERSION);
257 toscaTemplate.setImports(imports);
258 final Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
259 final Either<ToscaTemplate, ToscaError> toscaTemplateRes = convertInterfaceNodeType(new HashMap<>(), component, toscaTemplate, nodeTypes,
260 isAssociatedComponent);
261 if (toscaTemplateRes.isRight()) {
262 return Either.right(toscaTemplateRes.right().value());
264 toscaTemplate = toscaTemplateRes.left().value();
265 toscaTemplate.setDependencies(dependencies);
266 ToscaRepresentation toscaRepresentation = this.createToscaRepresentation(toscaTemplate);
267 return Either.left(toscaRepresentation);
270 private ToscaRepresentation createToscaRepresentation(ToscaTemplate toscaTemplate) {
271 CustomRepresenter representer = new CustomRepresenter();
272 DumperOptions options = new DumperOptions();
273 options.setAllowReadOnlyProperties(false);
274 options.setPrettyFlow(true);
275 options.setDefaultFlowStyle(FlowStyle.FLOW);
276 options.setCanonical(false);
277 representer.addClassTag(toscaTemplate.getClass(), Tag.MAP);
278 representer.setPropertyUtils(new UnsortedPropertyUtils());
281 Yaml yaml = new Yaml(representer, options);
282 String yamlAsString = yaml.dumpAsMap(toscaTemplate);
283 StringBuilder sb = new StringBuilder();
284 sb.append(getConfiguration().getHeatEnvArtifactHeader());
285 sb.append(yamlAsString);
286 sb.append(getConfiguration().getHeatEnvArtifactFooter());
287 return ToscaRepresentation.make(sb.toString().getBytes(), toscaTemplate);
290 public Either<ToscaTemplate, ToscaError> getDependencies(Component component) {
291 ToscaTemplate toscaTemplate = new ToscaTemplate(null);
292 Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports = fillImports(component, toscaTemplate);
293 if (fillImports.isRight()) {
294 return Either.right(fillImports.right().value());
296 return Either.left(fillImports.left().value().left);
299 public Either<ToscaTemplate, ToscaError> convertToToscaTemplate(final Component component) {
300 final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImports(component.getModel());
301 if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
302 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
303 return Either.right(ToscaError.GENERAL_ERROR);
305 log.trace("start tosca export for {}", component.getUniqueId());
306 String toscaVersion = null;
307 if (component instanceof Resource) {
308 toscaVersion = ((Resource) component).getToscaVersion();
310 final ToscaTemplate toscaTemplate = new ToscaTemplate(toscaVersion != null ? toscaVersion : TOSCA_VERSION);
311 toscaTemplate.setMetadata(convertMetadata(component));
312 toscaTemplate.setImports(new ArrayList<>(defaultToscaImportConfig));
313 final Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
314 if (ModelConverter.isAtomicComponent(component)) {
315 log.trace("convert component as node type");
316 return convertNodeType(new HashMap<>(), component, toscaTemplate, nodeTypes);
318 log.trace("convert component as topology template");
319 return convertToscaTemplate(component, toscaTemplate);
323 private Either<ToscaTemplate, ToscaError> convertDataTypeToToscaTemplate(final DataTypeDefinition dataTypeDefinition) {
324 final ToscaTemplate toscaTemplate = new ToscaTemplate(TOSCA_VERSION);
325 return convertDataTypeTosca(dataTypeDefinition, toscaTemplate);
328 private Either<ToscaTemplate, ToscaError> convertDataTypeTosca(final DataTypeDefinition dataTypeDefinition, final ToscaTemplate toscaTemplate) {
329 final var dataTypesEither = applicationDataTypeCache.getAll(dataTypeDefinition.getModel());
330 if (dataTypesEither.isRight()) {
331 log.debug("Failed to fetch all data types :", dataTypesEither.right().value());
332 return Either.right(ToscaError.GENERAL_ERROR);
334 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
335 if (!dataTypeDefinition.isEmpty()) {
336 Map<String, ToscaDataType> toscaDataTypeMap = new HashMap<>();
337 ToscaDataType toscaDataType = new ToscaDataType();
338 toscaDataType.setDerived_from(dataTypeDefinition.getDerivedFromName());
339 toscaDataType.setDescription(dataTypeDefinition.getDescription());
340 toscaDataType.setVersion(dataTypeDefinition.getVersion());
341 if (CollectionUtils.isNotEmpty(dataTypeDefinition.getProperties())) {
342 toscaDataType.setProperties(dataTypeDefinition.getProperties().stream()
343 .collect(Collectors.toMap(
344 PropertyDataDefinition::getName,
345 s -> propertyConvertor.convertProperty(dataTypes, s, PropertyType.PROPERTY),
346 (toscaPropertyTobeValidated, toscaProperty) -> validateToscaProperty((List<DataTypeDefinition>) dataTypeDefinition, toscaPropertyTobeValidated,
350 toscaDataTypeMap.put(dataTypeDefinition.getName(), toscaDataType);
351 toscaTemplate.setData_types(toscaDataTypeMap);
353 return Either.left(toscaTemplate);
356 private List<Map<String, Map<String, String>>> getDefaultToscaImports(final String modelId) {
357 if (modelId == null) {
358 return getDefaultToscaImportConfig();
361 final List<ToscaImportByModel> allModelImports = modelOperation.findAllModelImports(modelId, true);
362 final List<Map<String, Map<String, String>>> importList = new ArrayList<>();
363 final Set<Path> addedPathList = new HashSet<>();
364 for (final ToscaImportByModel toscaImportByModel : allModelImports) {
365 var importPath = Path.of(toscaImportByModel.getFullPath());
366 if (addedPathList.contains(importPath)) {
367 importPath = ToscaDefaultImportHelper.addModelAsFilePrefix(importPath, toscaImportByModel.getModelId());
369 final String fileName = FilenameUtils.getBaseName(importPath.toString());
370 importList.add(Map.of(fileName, Map.of("file", importPath.toString())));
371 addedPathList.add(importPath);
376 private Either<ToscaTemplate, ToscaError> convertToscaTemplate(Component component, ToscaTemplate toscaNode) {
377 Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> importsRes = fillImports(component, toscaNode);
378 if (importsRes.isRight()) {
379 return Either.right(importsRes.right().value());
381 toscaNode = importsRes.left().value().left;
382 Map<String, Component> componentCache = importsRes.left().value().right;
383 Either<Map<String, ToscaNodeType>, ToscaError> nodeTypesMapEither = createProxyNodeTypes(componentCache, component);
384 if (nodeTypesMapEither.isRight()) {
385 log.debug("Failed to fetch normative service proxy resource by tosca name, error {}", nodeTypesMapEither.right().value());
386 return Either.right(nodeTypesMapEither.right().value());
388 Map<String, ToscaNodeType> nodeTypesMap = nodeTypesMapEither.left().value();
389 if (nodeTypesMap != null && !nodeTypesMap.isEmpty()) {
390 toscaNode.setNode_types(nodeTypesMap);
392 createServiceSubstitutionNodeTypes(componentCache, component, toscaNode);
393 Either<Map<String, Object>, ToscaError> proxyInterfaceTypesEither = createProxyInterfaceTypes(component);
394 if (proxyInterfaceTypesEither.isRight()) {
395 log.debug("Failed to populate service proxy local interface types in tosca, error {}", nodeTypesMapEither.right().value());
396 return Either.right(proxyInterfaceTypesEither.right().value());
398 Map<String, Object> proxyInterfaceTypes = proxyInterfaceTypesEither.left().value();
399 if (MapUtils.isNotEmpty(proxyInterfaceTypes)) {
400 toscaNode.setInterface_types(proxyInterfaceTypes);
402 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = applicationDataTypeCache.getAll(component.getModel());
403 if (dataTypesEither.isRight()) {
404 log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
405 return Either.right(ToscaError.GENERAL_ERROR);
407 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
408 ToscaTopolgyTemplate topologyTemplate = new ToscaTopolgyTemplate();
409 List<InputDefinition> inputDef = component.getInputs();
410 Map<String, ToscaProperty> inputs = inputConverter.convertInputs(inputDef, dataTypes);
411 if (!inputs.isEmpty()) {
412 topologyTemplate.setInputs(inputs);
414 final Map<String, ToscaProperty> outputs;
416 outputs = outputConverter.convert(component.getOutputs(), dataTypes);
417 } catch (final ToscaConversionException e) {
418 log.error(EcompLoggerErrorCode.SCHEMA_ERROR, ToscaExportHandler.class.getName(),
419 "Could not parse component '{}' outputs. Component unique id '{}'.", component.getName(), component.getUniqueId(), e);
420 return Either.right(ToscaError.GENERAL_ERROR);
422 if (!outputs.isEmpty()) {
423 topologyTemplate.setOutputs(outputs);
425 if (CollectionUtils.isNotEmpty(component.getComponentInstances())) {
426 final Either<Map<String, ToscaNodeTemplate>, ToscaError> nodeTemplates =
427 convertNodeTemplates(component, componentCache, dataTypes, topologyTemplate);
428 if (nodeTemplates.isRight()) {
429 return Either.right(nodeTemplates.right().value());
431 log.debug("node templates converted");
432 topologyTemplate.setNode_templates(nodeTemplates.left().value());
434 final Map<String, ToscaRelationshipTemplate> relationshipTemplatesMap = new ToscaExportRelationshipTemplatesHandler()
435 .createFrom(topologyTemplate.getNode_templates());
436 if (!relationshipTemplatesMap.isEmpty()) {
437 topologyTemplate.setRelationshipTemplates(relationshipTemplatesMap);
439 addGroupsToTopologyTemplate(component, topologyTemplate);
441 addPoliciesToTopologyTemplate(component, topologyTemplate);
442 } catch (SdcResourceNotFoundException e) {
443 log.debug("Fail to add policies to topology template:", e);
444 return Either.right(ToscaError.GENERAL_ERROR);
447 createSubstitutionMapping(component, componentCache).ifPresent(topologyTemplate::setSubstitution_mappings);
448 } catch (final ToscaExportException e) {
449 log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, ToscaExportHandler.class.getName(), e.getMessage());
450 return Either.right(e.getToscaError());
452 if (!topologyTemplate.isEmpty()) {
453 toscaNode.setTopology_template(topologyTemplate);
455 return Either.left(toscaNode);
458 private Either<String, ToscaError> createComponentToscaName(final Component component) {
459 switch (component.getComponentType()) {
461 final ResourceMetadataDataDefinition resourceMetadata =
462 (ResourceMetadataDataDefinition) component.getComponentMetadataDefinition().getMetadataDataDefinition();
463 return Either.left(resourceMetadata.getToscaResourceName());
465 return Either.left(SERVICE_NODE_TYPE_PREFIX + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName());
467 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
468 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
472 private Optional<SubstitutionMapping> createSubstitutionMapping(final Component component,
473 final Map<String, Component> componentCache) throws ToscaExportException {
474 if (component instanceof Service && !((Service) component).isSubstituteCandidate()) {
475 return Optional.empty();
478 final Either<String, ToscaError> toscaResourceNameEither = createComponentToscaName(component);
479 if (toscaResourceNameEither.isRight()) {
480 throw new ToscaExportException("Could not create component TOSCA name", toscaResourceNameEither.right().value());
482 final String toscaResourceName = toscaResourceNameEither.left().value();
484 final SubstitutionMapping substitutionMapping = new SubstitutionMapping();
485 substitutionMapping.setNode_type(toscaResourceName);
486 convertSubstitutionMappingFilter(component).ifPresent(substitutionMapping::setSubstitution_filter);
488 final Either<Map<String, String[]>, ToscaError> capabilitiesEither = convertSubstitutionMappingCapabilities(component, componentCache);
489 if (capabilitiesEither.isRight()) {
490 throw new ToscaExportException("Could not convert substitution mapping capabilities", capabilitiesEither.right().value());
492 final Map<String, String[]> capabilityMap = capabilitiesEither.left().value();
493 if (!capabilityMap.isEmpty()) {
494 substitutionMapping.setCapabilities(capabilityMap);
497 final Either<Map<String, String[]>, ToscaError> requirements =
498 capabilityRequirementConverter.convertSubstitutionMappingRequirements(component, componentCache);
499 if (requirements.isRight()) {
500 throw new ToscaExportException("Could not convert substitution mapping requirements", requirements.right().value());
502 final Map<String, String[]> requirementMap = requirements.left().value();
503 if (MapUtils.isNotEmpty(requirementMap)) {
504 substitutionMapping.setRequirements(requirementMap);
507 final Map<String, String[]> propertyMappingMap = buildSubstitutionMappingPropertyMapping(component);
508 if (MapUtils.isNotEmpty(propertyMappingMap)) {
509 substitutionMapping.setProperties(propertyMappingMap);
512 final Map<String, String[]> attributesMappingMap = buildSubstitutionMappingAttributesMapping(component);
513 if (MapUtils.isNotEmpty(attributesMappingMap)) {
514 substitutionMapping.setAttributes(attributesMappingMap);
517 return Optional.of(substitutionMapping);
520 private Optional<NodeFilter> convertSubstitutionMappingFilter(final Component component) {
521 if (component.getSubstitutionFilter() == null || (component.getSubstitutionFilter().getProperties()).getListToscaDataDefinition() == null) {
522 return Optional.empty();
525 return Optional.ofNullable(convertToSubstitutionFilterComponent(component.getSubstitutionFilter()));
528 private void addGroupsToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate) {
529 Map<String, ToscaGroupTemplate> groups = groupExportParser.getGroups(component);
530 if (groups != null) {
531 topologyTemplate.addGroups(groups);
535 private void addPoliciesToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate) throws SdcResourceNotFoundException {
536 Map<String, ToscaPolicyTemplate> policies = policyExportParser.getPolicies(component);
537 if (policies != null) {
538 topologyTemplate.addPolicies(policies);
542 private Map<String, String> convertMetadata(Component component) {
543 return convertMetadata(component, false, null);
546 private Map<String, String> convertMetadata(Component component, boolean isInstance, ComponentInstance componentInstance) {
547 Map<String, String> toscaMetadata = new LinkedHashMap<>();
548 toscaMetadata.put(convertMetadataKey(JsonPresentationFields.INVARIANT_UUID), component.getInvariantUUID());
549 toscaMetadata.put(JsonPresentationFields.UUID.getPresentation(), component.getUUID());
551 .put(JsonPresentationFields.NAME.getPresentation(), component.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
552 toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), component.getDescription());
553 List<CategoryDefinition> categories = component.getCategories();
554 CategoryDefinition categoryDefinition = categories.get(0);
555 toscaMetadata.put(JsonPresentationFields.MODEL.getPresentation(), component.getModel());
556 toscaMetadata.put(JsonPresentationFields.CATEGORY.getPresentation(), categoryDefinition.getName());
558 toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), component.getVersion());
559 toscaMetadata.put(JsonPresentationFields.CUSTOMIZATION_UUID.getPresentation(), componentInstance.getCustomizationUUID());
560 if (componentInstance.getSourceModelInvariant() != null && !componentInstance.getSourceModelInvariant().isEmpty()) {
561 toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), componentInstance.getComponentVersion());
562 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_INVARIANT.getPresentation(), componentInstance.getSourceModelInvariant());
563 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_UUID.getPresentation(), componentInstance.getSourceModelUuid());
564 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_NAME.getPresentation(), componentInstance.getSourceModelName());
565 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
566 toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(),
567 componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceProxy.getDisplayValue());
568 } else if (componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
569 toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(),
570 componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceSubstitution.getDisplayValue());
572 toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), componentInstance.getDescription());
575 switch (component.getComponentType()) {
577 Resource resource = (Resource) component;
578 if (isInstance && (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy
579 || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution)) {
580 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), componentInstance.getOriginType().getDisplayValue());
582 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), resource.getResourceType().name());
584 toscaMetadata.put(JsonPresentationFields.SUB_CATEGORY.getPresentation(), categoryDefinition.getSubcategories().get(0).getName());
585 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR.getPresentation(), resource.getVendorName());
586 if (resource.getTenant() != null) {
587 toscaMetadata.put(JsonPresentationFields.TENANT.getPresentation(), resource.getTenant());
589 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_RELEASE.getPresentation(), resource.getVendorRelease());
590 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_MODEL_NUMBER.getPresentation(), resource.getResourceVendorModelNumber());
593 Service service = (Service) component;
594 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), component.getComponentType().getValue());
595 toscaMetadata.put(JsonPresentationFields.SERVICE_TYPE.getPresentation(), service.getServiceType());
596 toscaMetadata.put(JsonPresentationFields.SERVICE_ROLE.getPresentation(), service.getServiceRole());
597 toscaMetadata.put(JsonPresentationFields.SERVICE_FUNCTION.getPresentation(), service.getServiceFunction());
598 toscaMetadata.put(JsonPresentationFields.ENVIRONMENT_CONTEXT.getPresentation(), service.getEnvironmentContext());
599 toscaMetadata.put(JsonPresentationFields.INSTANTIATION_TYPE.getPresentation(),
600 service.getEnvironmentContext() == null ? StringUtils.EMPTY : service.getInstantiationType());
603 toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming().toString());
604 toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming().toString());
605 toscaMetadata.put(JsonPresentationFields.NAMING_POLICY.getPresentation(), service.getNamingPolicy());
609 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
611 for (final String key : component.getCategorySpecificMetadata().keySet()) {
612 if (!EXCLUDED_CATEGORY_SPECIFIC_METADATA.contains(key)) {
613 toscaMetadata.put(key, component.getCategorySpecificMetadata().get(key));
616 return toscaMetadata;
619 private String convertMetadataKey(JsonPresentationFields jsonPresentationField) {
620 if (JsonPresentationFields.INVARIANT_UUID.equals(jsonPresentationField)) {
621 return INVARIANT_UUID;
623 return jsonPresentationField.getPresentation();
626 private Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports(Component component, ToscaTemplate toscaTemplate) {
627 final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImports(component.getModel());
628 if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
629 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
630 return Either.right(ToscaError.GENERAL_ERROR);
632 Map<String, Component> componentCache = new HashMap<>();
633 if (!ModelConverter.isAtomicComponent(component)) {
634 final List<Map<String, Map<String, String>>> additionalImports =
635 toscaTemplate.getImports() == null ? new ArrayList<>(defaultToscaImportConfig) : new ArrayList<>(toscaTemplate.getImports());
636 List<Triple<String, String, Component>> dependencies = new ArrayList<>();
637 Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
638 final Map<String, Map<String, String>> substituteTypeImportEntry = generateComponentSubstituteTypeImport(component, toscaArtifacts);
639 if (!substituteTypeImportEntry.isEmpty()) {
640 additionalImports.add(substituteTypeImportEntry);
642 List<ComponentInstance> componentInstances = component.getComponentInstances();
643 if (componentInstances != null && !componentInstances.isEmpty()) {
644 componentInstances.forEach(ci -> createDependency(componentCache, additionalImports, dependencies, ci));
646 toscaTemplate.setDependencies(dependencies);
647 toscaTemplate.setImports(additionalImports);
649 log.debug("currently imports supported for VF and service only");
651 return Either.left(new ImmutablePair<>(toscaTemplate, componentCache));
654 private Map<String, Map<String, String>> generateComponentSubstituteTypeImport(final Component component,
655 final Map<String, ArtifactDefinition> toscaArtifacts) {
657 if (component instanceof Service && !((Service) component).isSubstituteCandidate()) {
658 return Collections.emptyMap();
660 if (MapUtils.isEmpty(toscaArtifacts)) {
661 return Collections.emptyMap();
663 final ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE);
664 if (artifactDefinition == null) {
665 return Collections.emptyMap();
667 final var importEntryName = component.getComponentType().toString().toLowerCase() + "-" + component.getName() + "-interface";
668 return Map.of(importEntryName,
669 Map.of(IMPORTS_FILE_KEY, getInterfaceFilename(artifactDefinition.getArtifactName()))
673 private List<Map<String, Map<String, String>>> getDefaultToscaImportConfig() {
674 return getConfiguration().getDefaultImports();
677 private void createDependency(final Map<String, Component> componentCache, final List<Map<String, Map<String, String>>> imports,
678 final List<Triple<String, String, Component>> dependencies, final ComponentInstance componentInstance) {
679 log.debug("createDependency componentCache {}", componentCache);
680 Component componentRI = componentCache.get(componentInstance.getComponentUid());
681 if (componentRI == null || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
682 // all resource must be only once!
683 final Either<Component, StorageOperationStatus> resource = toscaOperationFacade.getToscaFullElement(componentInstance.getComponentUid());
684 if ((resource.isRight()) && (log.isDebugEnabled())) {
685 log.debug("Failed to fetch resource with id {} for instance {}", componentInstance.getComponentUid(),
686 componentInstance.getUniqueId());
689 final Component fetchedComponent = resource.left().value();
690 componentRI = setComponentCache(componentCache, componentInstance, fetchedComponent);
691 addDependencies(imports, dependencies, componentRI);
696 * Sets a componentCache from the given component/resource.
698 private Component setComponentCache(final Map<String, Component> componentCache, final ComponentInstance componentInstance,
699 final Component fetchedComponent) {
700 componentCache.put(fetchedComponent.getUniqueId(), fetchedComponent);
701 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy
702 || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
703 final Either<Component, StorageOperationStatus> sourceService = toscaOperationFacade
704 .getToscaFullElement(componentInstance.getSourceModelUid());
705 if (sourceService.isRight() && (log.isDebugEnabled())) {
706 log.debug("Failed to fetch source service with id {} for proxy {}", componentInstance.getSourceModelUid(),
707 componentInstance.getUniqueId());
709 final Component fetchedSource = sourceService.left().value();
710 componentCache.put(fetchedSource.getUniqueId(), fetchedSource);
711 return fetchedSource;
713 return fetchedComponent;
717 * Retrieves all derived_from nodes and stores it in a predictable order.
719 private void addDependencies(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
720 final Component fetchedComponent) {
721 final Set<Component> componentsList = new LinkedHashSet<>();
722 if (fetchedComponent instanceof Resource) {
723 log.debug("fetchedComponent is a resource {}", fetchedComponent);
724 final Optional<Map<String, String>> derivedFromMapOfIdToName = getDerivedFromMapOfIdToName(fetchedComponent, componentsList);
725 if (derivedFromMapOfIdToName.isPresent() && !derivedFromMapOfIdToName.get().isEmpty()) {
726 derivedFromMapOfIdToName.get().entrySet().forEach(entry -> {
727 log.debug("Started entry.getValue() : {}", entry.getValue());
728 if (!NATIVE_ROOT.equals(entry.getValue())) {
729 Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade.getToscaElement(entry.getKey());
730 if (resourcefetched != null && resourcefetched.isLeft()) {
731 componentsList.add(resourcefetched.left().value());
735 setImports(imports, dependencies, componentsList);
737 setImports(imports, dependencies, fetchedComponent);
743 * Returns all derived_from nodes found.
745 private Optional<Map<String, String>> getDerivedFromMapOfIdToName(final Component fetchedComponent, final Set<Component> componentsList) {
746 final Resource parentResource = (Resource) fetchedComponent;
747 Map<String, String> derivedFromMapOfIdToName = new HashMap<>();
748 if (CollectionUtils.isNotEmpty(parentResource.getComponentInstances())) {
749 componentsList.add(fetchedComponent);
750 for (final ComponentInstance componentInstance : parentResource.getComponentInstances()) {
751 final Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade
752 .getToscaElement(componentInstance.getComponentUid());
753 if (resourcefetched != null && resourcefetched.isLeft()) {
754 final Map<String, String> derivedWithId = resourcefetched.left().value().getDerivedFromMapOfIdToName();
755 if (MapUtils.isNotEmpty(derivedWithId)) {
756 derivedFromMapOfIdToName.putAll(derivedWithId);
761 derivedFromMapOfIdToName = parentResource.getDerivedFromMapOfIdToName();
763 log.debug("Started derivedFromMapOfIdToName: {}", derivedFromMapOfIdToName);
764 return Optional.ofNullable(derivedFromMapOfIdToName);
768 * Creates a resource map and adds it to the import list.
770 private void setImports(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
771 final Set<Component> componentsList) {
772 componentsList.forEach(component -> setImports(imports, dependencies, component));
775 private void setImports(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
776 final Component component) {
777 final Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
778 final ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE);
779 if (artifactDefinition != null) {
780 final Map<String, String> files = new HashMap<>();
781 final String artifactName = artifactDefinition.getArtifactName();
782 files.put(IMPORTS_FILE_KEY, artifactName);
783 final StringBuilder keyNameBuilder = new StringBuilder();
784 keyNameBuilder.append(component.getComponentType().toString().toLowerCase());
785 keyNameBuilder.append("-");
786 keyNameBuilder.append(component.getName());
787 addImports(imports, keyNameBuilder, files);
788 dependencies.add(new ImmutableTriple<>(artifactName, artifactDefinition.getEsId(), component));
789 if (!ModelConverter.isAtomicComponent(component)) {
790 final Map<String, String> interfaceFiles = new HashMap<>();
791 interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactName));
792 keyNameBuilder.append("-interface");
793 addImports(imports, keyNameBuilder, interfaceFiles);
799 * Adds the found resource to the import definition list.
801 private void addImports(final List<Map<String, Map<String, String>>> imports, final StringBuilder keyNameBuilder,
802 final Map<String, String> files) {
803 final String mapKey = keyNameBuilder.toString();
804 if (imports.stream().allMatch(stringMapMap -> stringMapMap.get(mapKey) == null)) {
805 final Map<String, Map<String, String>> importsListMember = new HashMap<>();
806 importsListMember.put(keyNameBuilder.toString(), files);
807 imports.add(importsListMember);
811 private Either<ToscaTemplate, ToscaError> convertNodeType(Map<String, Component> componentsCache, Component component, ToscaTemplate toscaNode,
812 Map<String, ToscaNodeType> nodeTypes) {
813 return convertInterfaceNodeType(componentsCache, component, toscaNode, nodeTypes, false);
816 public Either<ToscaTemplate, ToscaError> convertInterfaceNodeType(Map<String, Component> componentsCache, Component component,
817 ToscaTemplate toscaNode, Map<String, ToscaNodeType> nodeTypes,
818 boolean isAssociatedComponent) {
819 log.debug("start convert node type for {}", component.getUniqueId());
820 ToscaNodeType toscaNodeType = createNodeType(component);
821 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither = interfaceLifecycleOperation
822 .getAllInterfaceLifecycleTypes(component.getModel());
823 if (lifecycleTypeEither.isRight() && !StorageOperationStatus.NOT_FOUND.equals(lifecycleTypeEither.right().value())) {
824 log.debug("Failed to fetch all interface types :", lifecycleTypeEither.right().value());
825 return Either.right(ToscaError.GENERAL_ERROR);
827 if (lifecycleTypeEither.isLeft()) {
828 List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value().values().stream().map(InterfaceDataDefinition::getType)
829 .collect(Collectors.toList());
830 toscaNode.setInterface_types(interfacesOperationsConverter.addInterfaceTypeElement(component, allGlobalInterfaceTypes));
832 final var dataTypesEither = applicationDataTypeCache.getAll(component.getModel());
833 if (dataTypesEither.isRight()) {
834 log.debug("Failed to fetch all data types :", dataTypesEither.right().value());
835 return Either.right(ToscaError.GENERAL_ERROR);
837 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
838 List<InputDefinition> inputDef = component.getInputs();
839 interfacesOperationsConverter.addInterfaceDefinitionElement(component, toscaNodeType, dataTypes, isAssociatedComponent);
840 final var toscaAttributeMap = convertToToscaAttributes(component.getAttributes(), dataTypes);
841 if (!toscaAttributeMap.isEmpty()) {
842 toscaNodeType.setAttributes(toscaAttributeMap);
844 final var mergedProperties = convertInputsToProperties(dataTypes, inputDef, component.getUniqueId());
845 if (CollectionUtils.isNotEmpty(component.getProperties())) {
846 List<PropertyDefinition> properties = component.getProperties();
847 Map<String, ToscaProperty> convertedProperties = properties.stream()
848 .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, component.getInputs())).collect(Collectors
849 .toMap(PropertyDataDefinition::getName,
850 property -> propertyConvertor.convertProperty(dataTypes, property, PropertyConvertor.PropertyType.PROPERTY)));
851 // merge component properties and inputs properties
852 mergedProperties.putAll(convertedProperties);
854 if (MapUtils.isNotEmpty(mergedProperties)) {
855 toscaNodeType.setProperties(mergedProperties);
857 /* convert private data_types */
858 List<DataTypeDefinition> privateDataTypes = component.getDataTypes();
859 if (CollectionUtils.isNotEmpty(privateDataTypes)) {
860 Map<String, ToscaDataType> toscaDataTypeMap = new HashMap<>();
861 for (DataTypeDefinition dataType : privateDataTypes) {
862 log.debug("Emitting private data type: component.name={} dataType.name={}",
863 component.getNormalizedName(), dataType.getName());
864 ToscaDataType toscaDataType = new ToscaDataType();
865 toscaDataType.setDerived_from(dataType.getDerivedFromName());
866 toscaDataType.setDescription(dataType.getDescription());
867 toscaDataType.setVersion(dataType.getVersion());
868 if (CollectionUtils.isNotEmpty(dataType.getProperties())) {
869 toscaDataType.setProperties(dataType.getProperties().stream()
870 .collect(Collectors.toMap(
871 PropertyDataDefinition::getName,
872 s -> propertyConvertor.convertProperty(dataTypes, s, PropertyType.PROPERTY),
873 (toscaPropertyTobeValidated, toscaProperty) -> validateToscaProperty(privateDataTypes, toscaPropertyTobeValidated,
877 toscaDataTypeMap.put(dataType.getName(), toscaDataType);
879 toscaNode.setData_types(toscaDataTypeMap);
882 // Extracted to method for code reuse
883 return convertReqCapAndTypeName(componentsCache, component, toscaNode, nodeTypes, toscaNodeType, dataTypes);
886 private ToscaProperty validateToscaProperty(final List<DataTypeDefinition> privateDataTypes, final ToscaProperty toscaPropertyTobeValidated,
887 final ToscaProperty toscaProperty) {
888 final Optional<DataTypeDefinition> match = privateDataTypes.stream()
889 .filter(dataType -> dataType.getName().equals(toscaPropertyTobeValidated.getType())).findFirst();
890 return match.isPresent() ? toscaPropertyTobeValidated : toscaProperty;
893 private Map<String, ToscaAttribute> convertToToscaAttributes(final List<AttributeDefinition> attributeList,
894 final Map<String, DataTypeDefinition> dataTypes) {
895 if (CollectionUtils.isEmpty(attributeList)) {
896 return Collections.emptyMap();
898 final AttributeConverter converter = new AttributeConverter(dataTypes);
899 final Map<String, ToscaAttribute> toscaAttributeMap = new HashMap<>();
900 for (final AttributeDefinition attributeDefinition : attributeList) {
901 toscaAttributeMap.put(attributeDefinition.getName(), converter.convert(attributeDefinition));
903 return toscaAttributeMap;
906 private Either<ToscaTemplate, ToscaError> convertReqCapAndTypeName(Map<String, Component> componentsCache,
907 Component component, ToscaTemplate toscaNode,
908 Map<String, ToscaNodeType> nodeTypes,
909 ToscaNodeType toscaNodeType,
910 Map<String, DataTypeDefinition> dataTypes) {
911 Either<ToscaNodeType, ToscaError> capabilities = convertCapabilities(componentsCache, component, toscaNodeType,
913 if (capabilities.isRight()) {
914 return Either.right(capabilities.right().value());
916 toscaNodeType = capabilities.left().value();
917 log.debug("Capabilities converted for {}", component.getUniqueId());
919 Either<ToscaNodeType, ToscaError> requirements = capabilityRequirementConverter
920 .convertRequirements(componentsCache, component, toscaNodeType);
921 if (requirements.isRight()) {
922 return Either.right(requirements.right().value());
924 toscaNodeType = requirements.left().value();
925 log.debug("Requirements converted for {}", component.getUniqueId());
927 String toscaResourceName;
928 switch (component.getComponentType()) {
930 toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition()
931 .getMetadataDataDefinition()).getToscaResourceName();
934 toscaResourceName = SERVICE_NODE_TYPE_PREFIX
935 + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName();
938 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
939 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
942 nodeTypes.put(toscaResourceName, toscaNodeType);
943 toscaNode.setNode_types(nodeTypes);
944 log.debug("finish convert node type for {}", component.getUniqueId());
945 return Either.left(toscaNode);
948 private Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplates(final Component component,
949 final Map<String, Component> componentCache,
950 final Map<String, DataTypeDefinition> dataTypes,
951 final ToscaTopolgyTemplate topologyTemplate) {
953 final Map<String, List<ComponentInstanceProperty>> componentInstancesProperties = component.getComponentInstancesProperties();
954 final Map<String, List<ComponentInstanceAttribute>> componentInstancesAttributes = component.getComponentInstancesAttributes();
955 final Map<String, List<ComponentInstanceInput>> componentInstancesInputs = component.getComponentInstancesInputs();
956 final Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces = component.getComponentInstancesInterfaces();
957 final List<RequirementCapabilityRelDef> componentInstancesRelations = component.getComponentInstancesRelations();
959 Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplatesRes = null;
960 log.debug("start convert topology template for {} for type {}", component.getUniqueId(), component.getComponentType());
961 final Map<String, ToscaNodeTemplate> nodeTemplates = new HashMap<>();
963 Map<String, ToscaGroupTemplate> groupsMap = null;
964 for (final ComponentInstance componentInstance : component.getComponentInstances()) {
965 ToscaNodeTemplate nodeTemplate = new ToscaNodeTemplate();
966 if (MapUtils.isNotEmpty(componentInstance.getToscaArtifacts())) {
967 nodeTemplate.setArtifacts(convertToNodeTemplateArtifacts(componentInstance.getToscaArtifacts()));
969 if (componentInstance.getMinOccurrences() != null && componentInstance.getMaxOccurrences() != null) {
970 List<Object> occur = new ArrayList<>();
971 occur.add(parseToIntIfPossible(componentInstance.getMinOccurrences()));
972 occur.add(parseToIntIfPossible(componentInstance.getMaxOccurrences()));
973 nodeTemplate.setOccurrences(occur);
975 if (componentInstance.getInstanceCount() != null) {
976 ObjectMapper objectMapper = new ObjectMapper();
977 Object obj = convertToToscaObject(componentInstance.getInstanceCount());
979 Map<String, String> map = objectMapper.convertValue(obj, Map.class);
980 nodeTemplate.setInstance_count(map);
983 nodeTemplate.setType(componentInstance.getToscaComponentName());
984 nodeTemplate.setDirectives(componentInstance.getDirectives());
985 NodeFilter nodeFilter = convertToNodeTemplateNodeFilterComponent(componentInstance.getNodeFilter());
986 if(nodeFilter != null && nodeFilter.hasData()){
987 nodeTemplate.setNode_filter(nodeFilter);
989 final Either<Component, Boolean> originComponentRes = capabilityRequirementConverter
990 .getOriginComponent(componentCache, componentInstance);
991 if (originComponentRes.isRight()) {
992 convertNodeTemplatesRes = Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
995 final Either<ToscaNodeTemplate, ToscaError> requirements = convertComponentInstanceRequirements(component, componentInstance,
996 componentInstancesRelations, nodeTemplate, originComponentRes.left().value(), componentCache);
997 if (requirements.isRight()) {
998 convertNodeTemplatesRes = Either.right(requirements.right().value());
1001 final String instanceUniqueId = componentInstance.getUniqueId();
1002 log.debug("Component instance Requirements converted for instance {}", instanceUniqueId);
1004 nodeTemplate = requirements.left().value();
1006 final Component originalComponent = componentCache.get(componentInstance.getActualComponentUid());
1008 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
1009 final Component componentOfProxy = componentCache.get(componentInstance.getComponentUid());
1010 nodeTemplate.setMetadata(convertMetadata(componentOfProxy, true, componentInstance));
1012 nodeTemplate.setMetadata(convertMetadata(originalComponent, true, componentInstance));
1015 final Either<ToscaNodeTemplate, ToscaError> capabilities =
1016 capabilityRequirementConverter.convertComponentInstanceCapabilities(componentInstance, dataTypes, nodeTemplate);
1017 if (capabilities.isRight()) {
1018 convertNodeTemplatesRes = Either.right(capabilities.right().value());
1021 log.debug("Component instance Capabilities converted for instance {}", instanceUniqueId);
1023 nodeTemplate = capabilities.left().value();
1024 final Map<String, Object> props = new HashMap<>();
1025 final Map<String, Object> attribs = new HashMap<>();
1027 if (originalComponent.getComponentType() == ComponentTypeEnum.RESOURCE) {
1028 // Adds the properties of parent component to map
1029 addPropertiesOfParentComponent(dataTypes, originalComponent, props);
1030 addAttributesOfParentComponent(originalComponent, attribs);
1033 if (null != componentInstancesProperties && componentInstancesProperties.containsKey(instanceUniqueId)) {
1034 addPropertiesOfComponentInstance(componentInstancesProperties, dataTypes, instanceUniqueId, props);
1036 if (null != componentInstancesAttributes && componentInstancesAttributes.containsKey(instanceUniqueId)) {
1037 addAttributesOfComponentInstance(componentInstancesAttributes, instanceUniqueId, attribs);
1040 if (componentInstancesInputs != null
1041 && componentInstancesInputs.containsKey(instanceUniqueId)
1042 && !isComponentOfTypeServiceProxy(componentInstance)) {
1043 //For service proxy the inputs are already handled under instance properties above
1044 addComponentInstanceInputs(dataTypes, componentInstancesInputs, instanceUniqueId, props);
1047 //M3[00001] - NODE TEMPLATE INTERFACES - START
1048 handleInstanceInterfaces(componentInstanceInterfaces, componentInstance, dataTypes, nodeTemplate, instanceUniqueId, component);
1049 //M3[00001] - NODE TEMPLATE INTERFACES - END
1050 if (MapUtils.isNotEmpty(props)) {
1051 nodeTemplate.setProperties(props);
1053 if (MapUtils.isNotEmpty(attribs)) {
1054 nodeTemplate.setAttributes(attribs);
1057 final List<GroupInstance> groupInstances = componentInstance.getGroupInstances();
1058 if (CollectionUtils.isNotEmpty(groupInstances)) {
1059 if (groupsMap == null) {
1060 groupsMap = new HashMap<>();
1062 for (final GroupInstance groupInst : groupInstances) {
1063 if (CollectionUtils.isNotEmpty(groupInst.getArtifacts())) {
1064 groupsMap.put(groupInst.getName(), groupExportParser.getToscaGroupTemplate(groupInst, componentInstance.getInvariantName()));
1069 nodeTemplates.put(componentInstance.getName(), nodeTemplate);
1071 if (groupsMap != null) {
1072 log.debug("instance groups added");
1073 topologyTemplate.addGroups(groupsMap);
1075 if (component.getComponentType() == ComponentTypeEnum.SERVICE && isNotEmpty(
1076 ((Service) component).getForwardingPaths())) {
1077 log.debug("Starting converting paths for component {}, name {}", component.getUniqueId(), component.getName());
1078 ForwardingPathToscaUtil
1079 .addForwardingPaths((Service) component, nodeTemplates, capabilityRequirementConverter, componentCache, toscaOperationFacade);
1080 log.debug("Finished converting paths for component {}, name {}", component.getUniqueId(), component.getName());
1082 if (convertNodeTemplatesRes == null) {
1083 convertNodeTemplatesRes = Either.left(nodeTemplates);
1085 log.debug("finish convert topology template for {} for type {}", component.getUniqueId(), component.getComponentType());
1086 return convertNodeTemplatesRes;
1089 private Object convertToToscaObject(String value) {
1091 ToscaMapValueConverter mapConverterInst = ToscaMapValueConverter.getInstance();
1092 StringReader reader = new StringReader(value);
1093 JsonReader jsonReader = new JsonReader(reader);
1094 jsonReader.setLenient(true);
1095 JsonElement jsonElement = JsonParser.parseReader(jsonReader);
1096 if (jsonElement.isJsonObject()) {
1097 JsonObject jsonObj = jsonElement.getAsJsonObject();
1098 if (jsonObj.entrySet().size() == 1 && jsonObj.has(ToscaFunctions.GET_INPUT.getFunctionName())) {
1099 return mapConverterInst.handleComplexJsonValue(jsonElement);
1103 } catch (Exception e) {
1104 log.debug("convertToToscaValue failed to parse json value :", e);
1109 private Object parseToIntIfPossible(final String value) {
1110 final Integer intValue = Ints.tryParse(value);
1111 return intValue == null ? value : intValue;
1114 private void handleInstanceInterfaces(Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces,
1115 ComponentInstance componentInstance, Map<String, DataTypeDefinition> dataTypes,
1116 ToscaNodeTemplate nodeTemplate, String instanceUniqueId, Component parentComponent) {
1118 if (MapUtils.isEmpty(componentInstanceInterfaces) || !componentInstanceInterfaces.containsKey(instanceUniqueId)) {
1119 nodeTemplate.setInterfaces(null);
1123 final List<ComponentInstanceInterface> currServiceInterfaces = componentInstanceInterfaces.get(instanceUniqueId);
1125 final Map<String, InterfaceDefinition> tmpInterfaces = new HashMap<>();
1126 currServiceInterfaces.forEach(instInterface -> tmpInterfaces.put(instInterface.getUniqueId(), instInterface));
1128 final Map<String, Object> interfaceMap = interfacesOperationsConverter
1129 .getInterfacesMap(parentComponent, componentInstance, tmpInterfaces, dataTypes, isComponentOfTypeServiceProxy(componentInstance));
1131 interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
1132 nodeTemplate.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap);
1135 private boolean isComponentOfTypeServiceProxy(ComponentInstance componentInstance) {
1136 return Objects.nonNull(componentInstance.getOriginType())
1137 && componentInstance.getOriginType().getValue().equals("Service Proxy");
1140 private void addComponentInstanceInputs(Map<String, DataTypeDefinition> dataTypes,
1141 Map<String, List<ComponentInstanceInput>> componentInstancesInputs,
1142 String instanceUniqueId, Map<String, Object> props) {
1144 List<ComponentInstanceInput> instanceInputsList = componentInstancesInputs.get(instanceUniqueId);
1145 if (instanceInputsList != null) {
1146 instanceInputsList.forEach(input -> {
1147 Supplier<String> supplier = () -> input.getValue() != null && !Objects.isNull(input.getValue()) ? input.getValue()
1148 : input.getDefaultValue();
1149 propertyConvertor.convertAndAddValue(dataTypes, props, input, supplier);
1154 private void addPropertiesOfComponentInstance(final Map<String, List<ComponentInstanceProperty>> componentInstancesProperties,
1155 final Map<String, DataTypeDefinition> dataTypes,
1156 final String instanceUniqueId,
1157 final Map<String, Object> props) {
1159 if (isNotEmpty(componentInstancesProperties)) {
1160 componentInstancesProperties.get(instanceUniqueId)
1161 // Converts and adds each value to property map
1162 .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop, prop::getValue));
1166 private void addAttributesOfComponentInstance(final Map<String, List<ComponentInstanceAttribute>> componentInstancesAttributes,
1167 final String instanceUniqueId,
1168 final Map<String, Object> attribs) {
1170 if (isNotEmpty(componentInstancesAttributes) && componentInstancesAttributes.containsKey(instanceUniqueId)) {
1171 componentInstancesAttributes.get(instanceUniqueId)
1172 .forEach(attributeDefinition -> attributeConverter.convertAndAddValue(attribs, attributeDefinition));
1176 private void addPropertiesOfParentComponent(Map<String, DataTypeDefinition> dataTypes,
1177 Component componentOfInstance, Map<String, Object> props) {
1179 List<PropertyDefinition> componentProperties = componentOfInstance.getProperties();
1180 if (isNotEmpty(componentProperties)) {
1181 componentProperties.stream()
1182 // Filters out properties with empty default values
1183 .filter(prop -> StringUtils.isNotEmpty(prop.getDefaultValue()))
1184 // Converts and adds each value to property map
1185 .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop, prop::getDefaultValue));
1189 private void addAttributesOfParentComponent(final Component componentOfInstance, final Map<String, Object> attribs) {
1191 final List<AttributeDefinition> componentAttributes = componentOfInstance.getAttributes();
1192 if (isNotEmpty(componentAttributes)) {
1193 componentAttributes.stream()
1194 // Filters out Attributes with empty default values
1195 .filter(attrib -> StringUtils.isNotEmpty(attrib.getDefaultValue()))
1196 // Converts and adds each value to attribute map
1197 .forEach(attributeDefinition -> attributeConverter.convertAndAddValue(attribs, attributeDefinition));
1201 private ToscaNodeType createNodeType(Component component) {
1202 ToscaNodeType toscaNodeType = new ToscaNodeType();
1203 if (ModelConverter.isAtomicComponent(component)) {
1204 if (((Resource) component).getDerivedFrom() != null) {
1205 toscaNodeType.setDerived_from(((Resource) component).getDerivedFrom().get(0));
1207 toscaNodeType.setDescription(component.getDescription());
1209 String derivedFrom = null != component.getDerivedFromGenericType() ? component.getDerivedFromGenericType()
1211 toscaNodeType.setDerived_from(derivedFrom);
1213 return toscaNodeType;
1216 private Either<Map<String, Object>, ToscaError> createProxyInterfaceTypes(Component container) {
1218 Map<String, Object> proxyInterfaceTypes = new HashMap<>();
1219 Either<Map<String, Object>, ToscaError> res = Either.left(proxyInterfaceTypes);
1220 List<ComponentInstance> componentInstances = container.getComponentInstances();
1221 if (CollectionUtils.isEmpty(componentInstances)) {
1224 Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
1225 componentInstances.stream()
1226 .filter(this::isComponentOfTypeServiceProxy)
1227 .forEach(inst -> serviceProxyInstanceList.put(inst.getToscaComponentName(), inst));
1228 if (MapUtils.isEmpty(serviceProxyInstanceList)) {
1231 for (Entry<String, ComponentInstance> entryProxy : serviceProxyInstanceList.entrySet()) {
1232 Component serviceComponent;
1233 ComponentParametersView componentParametersView = new ComponentParametersView();
1234 componentParametersView.disableAll();
1235 componentParametersView.setIgnoreInterfaces(false);
1236 Either<Component, StorageOperationStatus> service = toscaOperationFacade
1237 .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
1238 if (service.isRight()) {
1239 log.debug("Failed to fetch original service component with id {} for instance {}",
1240 entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName());
1241 return Either.right(ToscaError.GENERAL_ERROR);
1243 serviceComponent = service.left().value();
1246 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither =
1247 interfaceLifecycleOperation.getAllInterfaceLifecycleTypes(serviceComponent.getModel());
1248 if (lifecycleTypeEither.isRight()) {
1249 log.debug("Failed to retrieve global interface types :", lifecycleTypeEither.right().value());
1250 return Either.right(ToscaError.GENERAL_ERROR);
1253 List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value().values().stream()
1254 .map(InterfaceDataDefinition::getType)
1255 .collect(Collectors.toList());
1256 //Add interface types for local interfaces in the original service component for proxy
1257 Map<String, Object> localInterfaceTypes = interfacesOperationsConverter.addInterfaceTypeElement(serviceComponent,
1258 allGlobalInterfaceTypes);
1259 if (MapUtils.isNotEmpty(localInterfaceTypes)) {
1260 proxyInterfaceTypes.putAll(localInterfaceTypes);
1264 return Either.left(proxyInterfaceTypes);
1267 private Either<Map<String, ToscaNodeType>, ToscaError> createProxyNodeTypes(Map<String, Component> componentCache,
1268 Component container) {
1270 Map<String, ToscaNodeType> nodeTypesMap = new HashMap<>();
1271 Either<Map<String, ToscaNodeType>, ToscaError> res = Either.left(nodeTypesMap);
1273 List<ComponentInstance> componentInstances = container.getComponentInstances();
1275 if (componentInstances == null || componentInstances.isEmpty()) {
1278 Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
1279 List<ComponentInstance> proxyInst = componentInstances.stream()
1280 .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceProxy.name()))
1281 .collect(Collectors.toList());
1282 if (proxyInst != null && !proxyInst.isEmpty()) {
1283 for (ComponentInstance inst : proxyInst) {
1284 serviceProxyInstanceList.put(inst.getToscaComponentName(), inst);
1288 if (serviceProxyInstanceList.isEmpty()) {
1291 Either<Resource, StorageOperationStatus> serviceProxyOrigin = toscaOperationFacade
1292 .getLatestByName("serviceProxy", null);
1293 if (serviceProxyOrigin.isRight()) {
1294 log.debug("Failed to fetch normative service proxy resource by tosca name, error {}",
1295 serviceProxyOrigin.right().value());
1296 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
1298 Component origComponent = serviceProxyOrigin.left().value();
1300 for (Entry<String, ComponentInstance> entryProxy : serviceProxyInstanceList.entrySet()) {
1301 Component serviceComponent = null;
1302 ComponentParametersView componentParametersView = new ComponentParametersView();
1303 componentParametersView.disableAll();
1304 componentParametersView.setIgnoreCategories(false);
1305 componentParametersView.setIgnoreProperties(false);
1306 componentParametersView.setIgnoreInputs(false);
1307 componentParametersView.setIgnoreInterfaces(false);
1308 componentParametersView.setIgnoreRequirements(false);
1309 Either<Component, StorageOperationStatus> service = toscaOperationFacade
1310 .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
1311 if (service.isRight()) {
1312 log.debug("Failed to fetch resource with id {} for instance {}",
1313 entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName());
1315 serviceComponent = service.left().value();
1318 ToscaNodeType toscaNodeType = createProxyNodeType(componentCache, origComponent, serviceComponent,
1319 entryProxy.getValue());
1320 nodeTypesMap.put(entryProxy.getKey(), toscaNodeType);
1323 return Either.left(nodeTypesMap);
1326 private void createServiceSubstitutionNodeTypes(final Map<String, Component> componentCache,
1327 final Component container, final ToscaTemplate toscaNode) {
1328 final List<ComponentInstance> componentInstances = container.getComponentInstances();
1330 if (CollectionUtils.isEmpty(componentInstances)) {
1333 final List<ComponentInstance> serviceSubstitutionInstanceList = componentInstances.stream()
1334 .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceSubstitution.name()))
1335 .collect(Collectors.toList());
1336 if (CollectionUtils.isNotEmpty(serviceSubstitutionInstanceList)) {
1337 for (ComponentInstance inst : serviceSubstitutionInstanceList) {
1338 final Map<String, ToscaNodeType> nodeTypes =
1339 toscaNode.getNode_types() == null ? new HashMap<>() : toscaNode.getNode_types();
1340 convertInterfaceNodeType(new HashMap<>(), componentCache.get(inst.getSourceModelUid()), toscaNode,
1346 private ToscaNodeType createProxyNodeType(Map<String, Component> componentCache, Component origComponent,
1347 Component proxyComponent, ComponentInstance componentInstance) {
1348 ToscaNodeType toscaNodeType = new ToscaNodeType();
1349 String derivedFrom = ((Resource) origComponent).getToscaResourceName();
1351 toscaNodeType.setDerived_from(derivedFrom);
1352 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = applicationDataTypeCache.getAll(
1353 origComponent.getModel());
1354 if (dataTypesEither.isRight()) {
1355 log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
1357 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
1358 Map<String, ToscaCapability> capabilities = this.capabilityRequirementConverter
1359 .convertProxyCapabilities(componentCache, componentInstance, dataTypes);
1361 if (MapUtils.isNotEmpty(capabilities)) {
1362 toscaNodeType.setCapabilities(capabilities);
1364 List<Map<String, ToscaRequirement>> proxyNodeTypeRequirements = this.capabilityRequirementConverter
1365 .convertProxyRequirements(componentCache, componentInstance);
1366 if (CollectionUtils.isNotEmpty(proxyNodeTypeRequirements)) {
1367 toscaNodeType.setRequirements(proxyNodeTypeRequirements);
1369 Optional<Map<String, ToscaProperty>> proxyProperties = getProxyNodeTypeProperties(proxyComponent, dataTypes);
1370 proxyProperties.ifPresent(toscaNodeType::setProperties);
1372 Map<String, Object> interfaceMap = new HashMap<>();
1373 if (MapUtils.isEmpty(componentInstance.getInterfaces())) {
1374 final Optional<Map<String, Object>> proxyInterfaces = getProxyNodeTypeInterfaces(proxyComponent, dataTypes);
1375 if (proxyInterfaces.isPresent()) {
1376 interfaceMap = proxyInterfaces.get();
1379 interfaceMap = interfacesOperationsConverter.getInterfacesMapFromComponentInstance(proxyComponent, componentInstance, dataTypes, false);
1382 interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
1383 toscaNodeType.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap);
1385 return toscaNodeType;
1388 private Either<ToscaNodeTemplate, ToscaError> convertComponentInstanceRequirements(Component component,
1389 ComponentInstance componentInstance,
1390 List<RequirementCapabilityRelDef> relations,
1391 ToscaNodeTemplate nodeTypeTemplate,
1392 Component originComponent,
1393 Map<String, Component> componentCache) {
1395 final List<RequirementCapabilityRelDef> requirementDefinitionList = filterRequirements(componentInstance,
1397 if (isNotEmpty(requirementDefinitionList)) {
1399 final List<Map<String, ToscaTemplateRequirement>> toscaRequirements = buildRequirements(component, componentInstance,
1400 requirementDefinitionList, originComponent, componentCache);
1401 if (!toscaRequirements.isEmpty()) {
1402 nodeTypeTemplate.setRequirements(toscaRequirements);
1404 } catch (final Exception e) {
1405 log.debug("Failed to convert component instance requirements for the component instance {}. ",
1406 componentInstance.getName(), e);
1407 return Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
1410 log.debug("Finished to convert requirements for the node type {} ", componentInstance.getName());
1411 return Either.left(nodeTypeTemplate);
1414 private List<Map<String, ToscaTemplateRequirement>> buildRequirements(final Component component,
1415 final ComponentInstance componentInstance,
1416 final List<RequirementCapabilityRelDef> filteredRelations,
1417 final Component originComponent,
1418 final Map<String, Component> componentCache)
1419 throws ToscaExportException {
1421 final List<Map<String, ToscaTemplateRequirement>> toscaRequirements = new ArrayList<>();
1422 for (RequirementCapabilityRelDef relationshipDefinition : filteredRelations) {
1423 final Map<String, ToscaTemplateRequirement> toscaTemplateRequirementMap =
1424 buildRequirement(componentInstance, originComponent, component.getComponentInstances(), relationshipDefinition, componentCache);
1425 toscaRequirements.add(toscaTemplateRequirementMap);
1428 return toscaRequirements;
1431 private List<RequirementCapabilityRelDef> filterRequirements(ComponentInstance componentInstance,
1432 List<RequirementCapabilityRelDef> relations) {
1433 return relations.stream()
1434 .filter(p -> componentInstance.getUniqueId().equals(p.getFromNode())).collect(Collectors.toList());
1437 private Map<String, ToscaTemplateRequirement> buildRequirement(final ComponentInstance fromInstance,
1438 final Component fromOriginComponent,
1439 final List<ComponentInstance> instancesList,
1440 final RequirementCapabilityRelDef relationshipDefinition,
1441 final Map<String, Component> componentCache)
1442 throws ToscaExportException {
1444 final Map<String, List<RequirementDefinition>> reqMap = fromOriginComponent.getRequirements();
1445 final CapabilityRequirementRelationship capabilityRequirementRelationship = relationshipDefinition
1446 .getRelationships().get(0);
1447 final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation();
1449 final ComponentInstance toInstance = instancesList.stream()
1450 .filter(i -> relationshipDefinition.getToNode().equals(i.getUniqueId()))
1451 .findFirst().orElse(null);
1452 if (toInstance == null) {
1453 final String errorMsg = String
1454 .format("Failed to find a relation from the node %s to the node %s", fromInstance.getName(),
1455 relationshipDefinition.getToNode());
1456 log.debug(errorMsg);
1457 throw new ToscaExportException(errorMsg);
1459 final Optional<RequirementDefinition> reqOpt =
1460 findRequirement(fromOriginComponent, reqMap, relationshipInfo, fromInstance.getUniqueId());
1461 if (reqOpt.isEmpty()) {
1462 final String errorMsg = String
1463 .format("Failed to find a requirement with uniqueId %s on a component with uniqueId %s",
1464 relationshipInfo.getRequirementUid(), fromOriginComponent.getUniqueId());
1465 log.debug(errorMsg);
1466 throw new ToscaExportException(errorMsg);
1468 final ComponentParametersView filter = new ComponentParametersView(true);
1469 filter.setIgnoreComponentInstances(false);
1470 filter.setIgnoreCapabilities(false);
1471 filter.setIgnoreGroups(false);
1472 final Either<Component, StorageOperationStatus> getOriginRes =
1473 toscaOperationFacade.getToscaElement(toInstance.getActualComponentUid(), filter);
1474 if (getOriginRes.isRight()) {
1475 final String errorMsg = String.format(
1476 "Failed to build substituted name for the requirement %s. "
1477 + "Failed to get an origin component with uniqueId %s",
1478 reqOpt.get().getName(), toInstance.getActualComponentUid());
1479 log.debug(errorMsg);
1480 throw new ToscaExportException(errorMsg);
1482 final Component toOriginComponent = getOriginRes.left().value();
1483 Optional<CapabilityDefinition> capOpt = toOriginComponent.getCapabilities().get(reqOpt.get().getCapability()).stream()
1484 .filter(c -> isCapabilityBelongToRelation(relationshipInfo, c)).findFirst();
1485 if (capOpt.isEmpty()) {
1486 capOpt = findCapability(relationshipInfo, toOriginComponent, fromOriginComponent, reqOpt.get());
1487 if (capOpt.isEmpty()) {
1488 final String errorMsg = String
1489 .format("Failed to find a capability with name %s on a component with uniqueId %s",
1490 relationshipInfo.getCapability(), fromOriginComponent.getUniqueId());
1491 log.debug(errorMsg);
1492 throw new ToscaExportException(errorMsg);
1495 return buildRequirement(fromOriginComponent, toOriginComponent, capOpt.get(), reqOpt.get(),
1496 capabilityRequirementRelationship, toInstance, componentCache);
1499 private boolean isCapabilityBelongToRelation(RelationshipInfo reqAndRelationshipPair,
1500 CapabilityDefinition capability) {
1501 return capability.getName().equals(reqAndRelationshipPair.getCapability()) && (capability.getOwnerId() != null
1502 && capability.getOwnerId().equals(reqAndRelationshipPair.getCapabilityOwnerId()));
1505 private Optional<CapabilityDefinition> findCapability(RelationshipInfo reqAndRelationshipPair,
1506 Component toOriginComponent, Component fromOriginComponent,
1507 RequirementDefinition requirement) {
1508 Optional<CapabilityDefinition> cap = toOriginComponent.getCapabilities().get(requirement.getCapability())
1509 .stream().filter(c -> c.getType().equals(requirement.getCapability())).findFirst();
1510 if (!cap.isPresent()) {
1511 log.debug("Failed to find a capability with name {} on a component with uniqueId {}",
1512 reqAndRelationshipPair.getCapability(), fromOriginComponent.getUniqueId());
1517 private Map<String, ToscaTemplateRequirement> buildRequirement(final Component fromOriginComponent,
1518 final Component toOriginComponent,
1519 final CapabilityDefinition capability,
1520 final RequirementDefinition requirement,
1521 final CapabilityRequirementRelationship capabilityRequirementRelationship,
1522 final ComponentInstance toInstance,
1523 final Map<String, Component> componentCache)
1524 throws ToscaExportException {
1526 List<String> reducedPath = capability.getPath();
1527 if (capability.getOwnerId() != null) {
1528 reducedPath = capabilityRequirementConverter
1529 .getReducedPathByOwner(capability.getPath(), capability.getOwnerId());
1531 final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation();
1532 final Either<String, Boolean> capabilityNameEither = capabilityRequirementConverter.buildSubstitutedName(componentCache,
1533 toOriginComponent, reducedPath, relationshipInfo.getCapability(), capability.getPreviousName(), capability.getExternalName());
1534 if (capabilityNameEither.isRight()) {
1535 final String errorMsg = String.format(
1536 "Failed to build a substituted capability name for the capability with name %s on a component with uniqueId %s",
1537 capabilityRequirementRelationship.getCapability(), toOriginComponent.getUniqueId());
1540 throw new ToscaExportException(errorMsg);
1542 final Either<String, Boolean> requirementNameEither = capabilityRequirementConverter
1543 .buildSubstitutedName(componentCache, fromOriginComponent,
1544 requirement.getPath(), relationshipInfo.getRequirement(), requirement.getPreviousName(), requirement.getExternalName());
1545 if (requirementNameEither.isRight()) {
1546 final String errorMsg = String.format("Failed to build a substituted requirement name for the requirement "
1547 + "with name %s on a component with uniqueId %s",
1548 capabilityRequirementRelationship.getRequirement(), fromOriginComponent.getUniqueId());
1549 log.debug(errorMsg);
1550 throw new ToscaExportException(errorMsg);
1552 final ToscaTemplateRequirement toscaRequirement = new ToscaTemplateRequirement();
1553 final Map<String, ToscaTemplateRequirement> toscaReqMap = new HashMap<>();
1554 toscaRequirement.setNode(toInstance.getName());
1555 toscaRequirement.setCapability(capabilityNameEither.left().value());
1556 if (isNotEmpty(capabilityRequirementRelationship.getOperations())) {
1557 toscaRequirement.setRelationship(new ToscaRelationshipBuilder().from(capabilityRequirementRelationship));
1559 toscaReqMap.put(requirementNameEither.left().value(), toscaRequirement);
1563 private Optional<RequirementDefinition> findRequirement(Component fromOriginComponent,
1564 Map<String, List<RequirementDefinition>> reqMap,
1565 RelationshipInfo reqAndRelationshipPair,
1566 String fromInstanceId) {
1567 for (List<RequirementDefinition> reqList : reqMap.values()) {
1568 Optional<RequirementDefinition> reqOpt = reqList.stream().filter(
1569 r -> isRequirementBelongToRelation(fromOriginComponent, reqAndRelationshipPair, r, fromInstanceId))
1571 if (reqOpt.isPresent()) {
1575 return Optional.empty();
1579 * Allows detecting the requirement belonging to the received relationship The detection logic is: A requirement belongs to a relationship IF
1580 * 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
1581 * requirement equals to requirementOwnerId of the relation OR uniqueId of toInstance equals to capabilityOwnerId of the relation
1583 private boolean isRequirementBelongToRelation(Component originComponent, RelationshipInfo reqAndRelationshipPair,
1584 RequirementDefinition requirement, String fromInstanceId) {
1585 if (!StringUtils.equals(requirement.getName(), reqAndRelationshipPair.getRequirement())) {
1586 log.debug("Failed to find a requirement with name {} and reqAndRelationshipPair {}", requirement.getName(),
1587 reqAndRelationshipPair.getRequirement());
1590 return ModelConverter.isAtomicComponent(originComponent) || isRequirementBelongToOwner(reqAndRelationshipPair, requirement, fromInstanceId,
1594 private boolean isRequirementBelongToOwner(RelationshipInfo reqAndRelationshipPair, RequirementDefinition requirement, String fromInstanceId,
1595 Component originComponent) {
1596 return StringUtils.equals(requirement.getOwnerId(), reqAndRelationshipPair.getRequirementOwnerId()) || (
1597 isCvfc(originComponent) && StringUtils.equals(fromInstanceId, reqAndRelationshipPair.getRequirementOwnerId()) || StringUtils
1598 .equals(requirement.getOwnerId(), originComponent.getUniqueId()));
1601 private boolean isCvfc(Component component) {
1602 return component.getComponentType() == ComponentTypeEnum.RESOURCE && ((Resource) component).getResourceType() == ResourceTypeEnum.CVFC;
1605 private Either<Map<String, String[]>, ToscaError> convertSubstitutionMappingCapabilities(final Component component,
1606 final Map<String, Component> componentCache) {
1607 Either<Map<String, String[]>, ToscaError> toscaCapabilitiesRes =
1608 capabilityRequirementConverter.convertSubstitutionMappingCapabilities(componentCache, component);
1609 if (toscaCapabilitiesRes.isRight()) {
1610 log.debug("Failed convert capabilities for the component {}. ", component.getName());
1611 return Either.right(toscaCapabilitiesRes.right().value());
1613 if (isNotEmpty(toscaCapabilitiesRes.left().value())) {
1614 log.debug("Finish convert capabilities for the component {}. ", component.getName());
1615 return Either.left(toscaCapabilitiesRes.left().value());
1617 log.debug("Finished to convert capabilities for the component {}. ", component.getName());
1619 return Either.left(Collections.emptyMap());
1622 private Either<ToscaNodeType, ToscaError> convertCapabilities(Map<String, Component> componentsCache, Component component, ToscaNodeType nodeType,
1623 Map<String, DataTypeDefinition> dataTypes) {
1624 Map<String, ToscaCapability> toscaCapabilities = capabilityRequirementConverter.convertCapabilities(componentsCache, component, dataTypes);
1625 if (!toscaCapabilities.isEmpty()) {
1626 nodeType.setCapabilities(toscaCapabilities);
1628 log.debug("Finish convert Capabilities for node type");
1629 return Either.left(nodeType);
1632 private Map<String, ToscaTemplateArtifact> convertToNodeTemplateArtifacts(Map<String, ToscaArtifactDataDefinition> artifacts) {
1633 if (artifacts == null) {
1636 Map<String, ToscaTemplateArtifact> arts = new HashMap<>();
1637 for (Map.Entry<String, ToscaArtifactDataDefinition> entry : artifacts.entrySet()) {
1638 ToscaTemplateArtifact artifact = new ToscaTemplateArtifact();
1639 artifact.setFile(entry.getValue().getFile());
1640 artifact.setType(entry.getValue().getType());
1641 artifact.setProperties(entry.getValue().getProperties());
1642 arts.put(entry.getKey(), artifact);
1647 private NodeFilter convertToNodeTemplateNodeFilterComponent(CINodeFilterDataDefinition inNodeFilter) {
1648 if (inNodeFilter == null) {
1651 NodeFilter nodeFilter = new NodeFilter();
1652 ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities = inNodeFilter.getCapabilities();
1653 ListDataDefinition<PropertyFilterDataDefinition> origProperties = inNodeFilter.getProperties();
1654 List<Map<String, CapabilityFilter>> capabilitiesCopy = new ArrayList<>();
1655 copyNodeFilterCapabilitiesTemplate(origCapabilities, capabilitiesCopy);
1656 if (CollectionUtils.isNotEmpty(capabilitiesCopy)) {
1657 nodeFilter.setCapabilities(capabilitiesCopy);
1659 final List<Map<String, List<Object>>> propertiesCopy = copyNodeFilterProperties(origProperties);
1660 if (CollectionUtils.isNotEmpty(propertiesCopy)) {
1661 nodeFilter.setProperties(propertiesCopy);
1663 nodeFilter.setTosca_id(cloneToscaId(inNodeFilter.getTosca_id()));
1664 nodeFilter = (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
1668 private NodeFilter convertToSubstitutionFilterComponent(final SubstitutionFilterDataDefinition substitutionFilterDataDefinition) {
1669 if (substitutionFilterDataDefinition == null) {
1672 NodeFilter nodeFilter = new NodeFilter();
1673 final List<Map<String, List<Object>>> propertiesCopy = copySubstitutionPropertiesFilter(substitutionFilterDataDefinition.getProperties());
1674 if (!propertiesCopy.isEmpty()) {
1675 nodeFilter.setProperties(propertiesCopy);
1677 nodeFilter.setTosca_id(cloneToscaId(substitutionFilterDataDefinition.getTosca_id()));
1678 return (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
1681 private Object cloneToscaId(Object toscaId) {
1682 return Objects.isNull(toscaId) ? null : cloneObjectFromYml(toscaId, toscaId.getClass());
1685 private Object cloneObjectFromYml(Object objToClone, Class classOfObj) {
1686 String objectAsYml = yamlUtil.objectToYaml(objToClone);
1687 return yamlUtil.yamlToObject(objectAsYml, classOfObj);
1690 private void copyNodeFilterCapabilitiesTemplate(ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities,
1691 List<Map<String, CapabilityFilter>> capabilitiesCopy) {
1692 if (origCapabilities == null || origCapabilities.getListToscaDataDefinition() == null || origCapabilities.getListToscaDataDefinition()
1696 for (RequirementNodeFilterCapabilityDataDefinition capability : origCapabilities.getListToscaDataDefinition()) {
1697 Map<String, CapabilityFilter> capabilityFilterCopyMap = new HashMap<>();
1698 final var capabilityFilter = new CapabilityFilter();
1699 capabilityFilter.setProperties(copyNodeFilterProperties(capability.getProperties()));
1700 capabilityFilterCopyMap.put(capability.getName(), capabilityFilter);
1701 capabilitiesCopy.add(capabilityFilterCopyMap);
1705 private List<Map<String, List<Object>>> copyNodeFilterProperties(final ListDataDefinition<PropertyFilterDataDefinition> origProperties) {
1706 if (origProperties == null || origProperties.getListToscaDataDefinition() == null || origProperties.isEmpty()) {
1707 return Collections.emptyList();
1709 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1710 Map<String, List<Object>> propertyFilterDefinitionMap = new HashMap<>();
1711 for (final PropertyFilterDataDefinition propertyFilter : origProperties.getListToscaDataDefinition()) {
1712 final String propertyName = propertyFilter.getName();
1713 for (final PropertyFilterConstraintDataDefinition filterConstraint : propertyFilter.getConstraints()) {
1714 propertyFilterDefinitionMap.compute(propertyName, (propertyName1, constraints) -> {
1715 if (constraints == null) {
1716 constraints = new ArrayList<>();
1718 constraints.add(buildNodeFilterValue(filterConstraint));
1723 propertyFilterDefinitionMap.entrySet().stream()
1724 .map(entry -> Map.of(entry.getKey(), entry.getValue()))
1725 .forEach(propertiesCopy::add);
1726 return propertiesCopy;
1729 private List<Map<String, List<Object>>> copySubstitutionPropertiesFilter(
1730 final ListDataDefinition<SubstitutionFilterPropertyDataDefinition> origProperties) {
1732 if (origProperties == null || origProperties.getListToscaDataDefinition() == null || origProperties.isEmpty()) {
1733 return Collections.emptyList();
1735 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1736 Map<String, List<Object>> propertyFilterDefinitionMap = new HashMap<>();
1737 for (final SubstitutionFilterPropertyDataDefinition propertyFilter : origProperties.getListToscaDataDefinition()) {
1738 final String propertyName = propertyFilter.getName();
1739 for (final PropertyFilterConstraintDataDefinition filterConstraint : propertyFilter.getConstraints()) {
1740 propertyFilterDefinitionMap.compute(propertyName, (propertyName1, constraints) -> {
1741 if (constraints == null) {
1742 constraints = new ArrayList<>();
1744 constraints.add(buildNodeFilterValue(filterConstraint));
1749 propertyFilterDefinitionMap.entrySet().stream()
1750 .map(entry -> Map.of(entry.getKey(), entry.getValue()))
1751 .forEach(propertiesCopy::add);
1752 return propertiesCopy;
1755 private static Object buildNodeFilterValue(final PropertyFilterConstraintDataDefinition filterConstraint) {
1756 if (filterConstraint.getValue() instanceof ToscaFunction) {
1757 return Map.of(filterConstraint.getOperator().getType(), ((ToscaFunction) filterConstraint.getValue()).getJsonObjectValue());
1759 return Map.of(filterConstraint.getOperator().getType(), filterConstraint.getValue());
1763 private Map<String, String[]> buildSubstitutionMappingPropertyMapping(final Component component) {
1764 if (component == null || CollectionUtils.isEmpty(component.getInputs())) {
1765 return Collections.emptyMap();
1767 Map<String, String[]> propertyMapping = new HashMap<>();
1768 List<InputDefinition> propertyMappedInputList = component.getInputs().stream().filter(InputDefinition::isMappedToComponentProperty).collect(
1769 Collectors.toList());
1771 if (CollectionUtils.isNotEmpty(propertyMappedInputList)) {
1772 propertyMappedInputList.forEach(inputDefinition -> {
1773 if (StringUtils.isNotEmpty(inputDefinition.getPropertyId())) {
1774 Optional<PropertyDefinition> property = component.getProperties().stream()
1775 .filter(propertyDefinition -> propertyDefinition.getUniqueId().equals(inputDefinition.getPropertyId())).findFirst();
1776 if (property.isPresent()) {
1777 propertyMapping.put(property.get().getName(), new String[]{inputDefinition.getName()});
1780 propertyMapping.put(inputDefinition.getName(), new String[]{inputDefinition.getName()});
1784 return propertyMapping;
1787 private Map<String, String[]> buildSubstitutionMappingAttributesMapping(final Component component) {
1788 if (component == null || CollectionUtils.isEmpty(component.getOutputs())) {
1789 return Collections.emptyMap();
1791 return component.getOutputs().stream().map(AttributeDataDefinition::getName)
1792 .collect(Collectors.toMap(outputName -> outputName, outputName -> new String[]{outputName}, (outputName1, outputName2) -> outputName1));
1795 private Optional<Map<String, ToscaProperty>> getProxyNodeTypeProperties(Component proxyComponent, Map<String, DataTypeDefinition> dataTypes) {
1796 if (Objects.isNull(proxyComponent)) {
1797 return Optional.empty();
1799 final var proxyProperties = convertInputsToProperties(dataTypes, proxyComponent.getInputs(), proxyComponent.getUniqueId());
1800 if (CollectionUtils.isNotEmpty(proxyComponent.getProperties())) {
1801 proxyProperties.putAll(proxyComponent.getProperties().stream()
1802 .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, proxyComponent.getInputs())).collect(Collectors
1803 .toMap(PropertyDataDefinition::getName,
1804 property -> propertyConvertor.convertProperty(dataTypes, property, PropertyType.PROPERTY))));
1806 return MapUtils.isNotEmpty(proxyProperties) ? Optional.of(proxyProperties) : Optional.empty();
1809 private Map<String, ToscaProperty> convertInputsToProperties(Map<String, DataTypeDefinition> dataTypes, List<InputDefinition> componentInputs,
1810 String componentUniqueId) {
1811 if (CollectionUtils.isEmpty(componentInputs)) {
1812 return new HashMap<>();
1814 return componentInputs.stream().filter(input -> componentUniqueId.equals(input.getInstanceUniqueId()))
1815 .collect(Collectors.toMap(InputDefinition::getName, i -> propertyConvertor.convertProperty(dataTypes, i, PropertyType.INPUT)));
1818 private Optional<Map<String, Object>> getProxyNodeTypeInterfaces(Component proxyComponent, Map<String, DataTypeDefinition> dataTypes) {
1819 if (Objects.isNull(proxyComponent) || MapUtils.isEmpty(proxyComponent.getInterfaces())) {
1820 return Optional.empty();
1822 Map<String, InterfaceDefinition> proxyComponentInterfaces = proxyComponent.getInterfaces();
1823 //Unset artifact path for operation implementation for proxy node types as for operations with artifacts it is
1825 // always available in the proxy node template
1826 removeOperationImplementationForProxyNodeType(proxyComponentInterfaces);
1827 return Optional.ofNullable(interfacesOperationsConverter.getInterfacesMap(proxyComponent, null, proxyComponentInterfaces, dataTypes, false));
1830 private static class CustomRepresenter extends Representer {
1832 CustomRepresenter() {
1834 this.representers.put(ToscaPropertyAssignment.class, new RepresentToscaPropertyAssignment());
1835 this.representers.put(ToscaAttribute.class, new RepresentToscaAttribute());
1836 // null representer is exceptional and it is stored as an instance
1839 this.nullRepresenter = new RepresentNull();
1842 public boolean validateGetInputValue(final Object valueObj) {
1843 if (!(valueObj instanceof List) && !(valueObj instanceof String)) {
1846 if (valueObj instanceof List) {
1847 return ((List) valueObj).size() > 1;
1852 public boolean validateGetPropertyOrAttributeValue(final Object valueObj) {
1853 if (valueObj instanceof List) {
1854 return ((List) valueObj).size() > 1;
1860 protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue, Tag customTag) {
1861 if (propertyValue == null) {
1864 // skip not relevant for Tosca property
1865 if ("dependencies".equals(property.getName())) {
1868 if (javaBean instanceof ToscaRelationshipTemplate && "name".equals(property.getName())) {
1871 if (javaBean instanceof ToscaPropertyConstraint) {
1872 return handleToscaPropertyConstraint((ToscaPropertyConstraint)javaBean, property, propertyValue, customTag);
1874 removeDefaultP(propertyValue);
1875 NodeTuple defaultNode = super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
1876 if (javaBean instanceof ToscaTopolgyTemplate && "relationshipTemplates".equals(property.getName())) {
1877 return new NodeTuple(representData("relationship_templates"), defaultNode.getValueNode());
1879 return "_defaultp_".equals(property.getName()) ? new NodeTuple(representData("default"), defaultNode.getValueNode()) : defaultNode;
1882 private NodeTuple handleToscaPropertyConstraint(final ToscaPropertyConstraint javaBean, final Property property, final Object propertyValue,
1883 final Tag customTag) {
1884 final NodeTuple nodeTuple = super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
1885 final String entryToscaName = javaBean.getEntryToscaName(property.getName());
1886 return new NodeTuple(representData(entryToscaName), nodeTuple.getValueNode());
1889 private void removeDefaultP(final Object propertyValue) {
1890 if (propertyValue instanceof Map) {
1891 final Map mapPropertyValue = ((Map) propertyValue);
1892 final Iterator<Entry> iter = mapPropertyValue.entrySet().iterator();
1893 Object defaultValue = null;
1894 while (iter.hasNext()) {
1895 final Map.Entry entry = iter.next();
1896 if ("_defaultp_".equals(entry.getKey())) {
1897 defaultValue = entry.getValue();
1899 } else if (entry.getValue() instanceof Map) {
1900 removeDefaultP(entry.getValue());
1903 if (defaultValue != null) {
1904 mapPropertyValue.putIfAbsent("default", defaultValue);
1910 protected MappingNode representJavaBean(Set<Property> properties, Object javaBean) {
1911 // remove the bean type from the output yaml (!! ...)
1912 if (!classTags.containsKey(javaBean.getClass())) {
1913 addClassTag(javaBean.getClass(), Tag.MAP);
1915 return super.representJavaBean(properties, javaBean);
1918 private class RepresentToscaAttribute implements Represent {
1921 public Node representData(Object data) {
1922 final ToscaAttribute toscaAttribute = (ToscaAttribute) data;
1923 return represent(toscaAttribute.asToscaMap());
1927 private class RepresentToscaPropertyAssignment implements Represent {
1929 public Node representData(Object data) {
1930 final ToscaPropertyAssignment toscaOperationAssignment = (ToscaPropertyAssignment) data;
1931 if (toscaOperationAssignment.getValue() instanceof String) {
1932 final String stringValue = (String) toscaOperationAssignment.getValue();
1933 if (isPropertyOrAttributeFunction(stringValue)) {
1934 return representGetAttribute(stringValue);
1936 return representScalar(Tag.STR, stringValue);
1938 return represent(null);
1941 public Node representGetAttribute(final String getAttributeFunction) {
1942 return represent(new Yaml().load(getAttributeFunction));
1945 public boolean isPropertyOrAttributeFunction(final String value) {
1947 final Yaml yaml = new Yaml();
1948 final Object yamlObj = yaml.load(value);
1949 if (!(yamlObj instanceof Map)) {
1952 final Map<String, Object> getAttributeMap = (Map) yamlObj;
1953 if (getAttributeMap.size() != 1) {
1956 final List<String> functionList = Arrays
1957 .asList(GET_ATTRIBUTE.getFunctionName(), GET_INPUT.getFunctionName(), GET_PROPERTY.getFunctionName());
1958 final Optional<String> function = getAttributeMap.keySet().stream()
1959 .filter(key -> functionList.stream().anyMatch(function1 -> function1.equals(key))).findFirst();
1960 if (function.isEmpty()) {
1963 final String functionName = function.get();
1964 final Object getAttributeValueObj = getAttributeMap.get(functionName);
1965 if (GET_INPUT.getFunctionName().equals(functionName)) {
1966 return validateGetInputValue(getAttributeValueObj);
1968 return validateGetPropertyOrAttributeValue(getAttributeValueObj);
1970 } catch (final Exception ignored) {
1976 private class RepresentNull implements Represent {
1979 public Node representData(Object data) {
1980 // possible values are here http://yaml.org/type/null.html
1981 return representScalar(Tag.NULL, "");
1986 private static class UnsortedPropertyUtils extends PropertyUtils {
1989 protected Set<Property> createPropertySet(Class type, BeanAccess bAccess) {
1990 Collection<Property> fields = getPropertiesMap(type, BeanAccess.FIELD).values();
1991 return new LinkedHashSet<>(fields);
1995 private Configuration getConfiguration() {
1996 return ConfigurationManager.getConfigurationManager().getConfiguration();