2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
20 package org.openecomp.sdc.be.tosca;
22 import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
23 import static org.apache.commons.collections.MapUtils.isNotEmpty;
24 import static org.openecomp.sdc.be.components.utils.PropertiesUtils.resolvePropertyValueFromInput;
25 import static org.openecomp.sdc.be.tosca.InterfacesOperationsConverter.addInterfaceTypeElement;
26 import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_ATTRIBUTE;
27 import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_INPUT;
28 import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_PROPERTY;
30 import fj.data.Either;
31 import java.util.ArrayList;
32 import java.util.Arrays;
33 import java.util.Collection;
34 import java.util.Collections;
35 import java.util.HashMap;
36 import java.util.Iterator;
37 import java.util.LinkedHashMap;
38 import java.util.LinkedHashSet;
39 import java.util.List;
41 import java.util.Map.Entry;
42 import java.util.Objects;
43 import java.util.Optional;
45 import java.util.function.Supplier;
46 import java.util.stream.Collectors;
47 import lombok.NoArgsConstructor;
48 import org.apache.commons.collections.CollectionUtils;
49 import org.apache.commons.collections.MapUtils;
50 import org.apache.commons.lang3.StringUtils;
51 import org.apache.commons.lang3.tuple.ImmutablePair;
52 import org.apache.commons.lang3.tuple.ImmutableTriple;
53 import org.apache.commons.lang3.tuple.Triple;
54 import org.onap.sdc.tosca.services.YamlUtil;
55 import org.openecomp.sdc.be.components.impl.exceptions.SdcResourceNotFoundException;
56 import org.openecomp.sdc.be.config.Configuration;
57 import org.openecomp.sdc.be.config.ConfigurationManager;
58 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
59 import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
60 import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition;
61 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
62 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
63 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
64 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
65 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition;
66 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition;
67 import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterPropertyDataDefinition;
68 import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition;
69 import org.openecomp.sdc.be.datatypes.elements.ToscaArtifactDataDefinition;
70 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
71 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
72 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
73 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
74 import org.openecomp.sdc.be.exception.ToscaExportException;
75 import org.openecomp.sdc.be.model.ArtifactDefinition;
76 import org.openecomp.sdc.be.model.AttributeDefinition;
77 import org.openecomp.sdc.be.model.CapabilityDefinition;
78 import org.openecomp.sdc.be.model.CapabilityRequirementRelationship;
79 import org.openecomp.sdc.be.model.Component;
80 import org.openecomp.sdc.be.model.ComponentInstance;
81 import org.openecomp.sdc.be.model.ComponentInstanceAttribute;
82 import org.openecomp.sdc.be.model.ComponentInstanceInput;
83 import org.openecomp.sdc.be.model.ComponentInstanceInterface;
84 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
85 import org.openecomp.sdc.be.model.ComponentParametersView;
86 import org.openecomp.sdc.be.model.DataTypeDefinition;
87 import org.openecomp.sdc.be.model.GroupInstance;
88 import org.openecomp.sdc.be.model.InputDefinition;
89 import org.openecomp.sdc.be.model.InterfaceDefinition;
90 import org.openecomp.sdc.be.model.PropertyDefinition;
91 import org.openecomp.sdc.be.model.RelationshipInfo;
92 import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
93 import org.openecomp.sdc.be.model.RequirementDefinition;
94 import org.openecomp.sdc.be.model.Resource;
95 import org.openecomp.sdc.be.model.Service;
96 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
97 import org.openecomp.sdc.be.model.category.CategoryDefinition;
98 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
99 import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter;
100 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
101 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
102 import org.openecomp.sdc.be.tosca.PropertyConvertor.PropertyType;
103 import org.openecomp.sdc.be.tosca.builder.ToscaRelationshipBuilder;
104 import org.openecomp.sdc.be.tosca.exception.ToscaConversionException;
105 import org.openecomp.sdc.be.tosca.model.CapabilityFilter;
106 import org.openecomp.sdc.be.tosca.model.NodeFilter;
107 import org.openecomp.sdc.be.tosca.model.SubstitutionMapping;
108 import org.openecomp.sdc.be.tosca.model.ToscaAttribute;
109 import org.openecomp.sdc.be.tosca.model.ToscaCapability;
110 import org.openecomp.sdc.be.tosca.model.ToscaDataType;
111 import org.openecomp.sdc.be.tosca.model.ToscaGroupTemplate;
112 import org.openecomp.sdc.be.tosca.model.ToscaNodeTemplate;
113 import org.openecomp.sdc.be.tosca.model.ToscaNodeType;
114 import org.openecomp.sdc.be.tosca.model.ToscaPolicyTemplate;
115 import org.openecomp.sdc.be.tosca.model.ToscaProperty;
116 import org.openecomp.sdc.be.tosca.model.ToscaPropertyAssignment;
117 import org.openecomp.sdc.be.tosca.model.ToscaRelationshipTemplate;
118 import org.openecomp.sdc.be.tosca.model.ToscaRequirement;
119 import org.openecomp.sdc.be.tosca.model.ToscaTemplate;
120 import org.openecomp.sdc.be.tosca.model.ToscaTemplateArtifact;
121 import org.openecomp.sdc.be.tosca.model.ToscaTemplateRequirement;
122 import org.openecomp.sdc.be.tosca.model.ToscaTopolgyTemplate;
123 import org.openecomp.sdc.be.tosca.utils.ForwardingPathToscaUtil;
124 import org.openecomp.sdc.be.tosca.utils.InputConverter;
125 import org.openecomp.sdc.be.tosca.utils.OutputConverter;
126 import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
127 import org.openecomp.sdc.common.log.wrappers.Logger;
128 import org.springframework.beans.factory.annotation.Autowired;
129 import org.yaml.snakeyaml.DumperOptions;
130 import org.yaml.snakeyaml.DumperOptions.FlowStyle;
131 import org.yaml.snakeyaml.Yaml;
132 import org.yaml.snakeyaml.introspector.BeanAccess;
133 import org.yaml.snakeyaml.introspector.Property;
134 import org.yaml.snakeyaml.introspector.PropertyUtils;
135 import org.yaml.snakeyaml.nodes.MappingNode;
136 import org.yaml.snakeyaml.nodes.Node;
137 import org.yaml.snakeyaml.nodes.NodeTuple;
138 import org.yaml.snakeyaml.nodes.Tag;
139 import org.yaml.snakeyaml.representer.Represent;
140 import org.yaml.snakeyaml.representer.Representer;
143 @org.springframework.stereotype.Component("tosca-export-handler")
144 public class ToscaExportHandler {
146 public static final String ASSET_TOSCA_TEMPLATE = "assettoscatemplate";
147 private static final Logger log = Logger.getLogger(ToscaExportHandler.class);
148 private static final String INVARIANT_UUID = "invariantUUID";
149 private static final String TOSCA_VERSION = "tosca_simple_yaml_1_3";
150 private static final String SERVICE_NODE_TYPE_PREFIX = "org.openecomp.service.";
151 private static final String IMPORTS_FILE_KEY = "file";
152 private static final String TOSCA_INTERFACE_NAME = "-interface.yml";
153 private static final String FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION = "convertToToscaTemplate - failed to get Default Imports section from configuration";
154 private static final String NOT_SUPPORTED_COMPONENT_TYPE = "Not supported component type {}";
155 private static final String NATIVE_ROOT = "tosca.nodes.Root";
156 private static final List<String> EXCLUDED_CATEGORY_SPECIFIC_METADATA = List
157 .of("Service Function", "Service Role", "Naming Policy", "Service Type");
158 private static final YamlUtil yamlUtil = new YamlUtil();
159 private static final String COULD_NOT_PARSE_COMPONENT_ATTRIBUTES_COMPONENT_UNIQUE_ID = "Could not parse component '{}' attributes. Component unique id '{}'.";
160 private ApplicationDataTypeCache applicationDataTypeCache;
161 private ToscaOperationFacade toscaOperationFacade;
162 private CapabilityRequirementConverter capabilityRequirementConverter;
163 private PolicyExportParser policyExportParser;
164 private GroupExportParser groupExportParser;
165 private PropertyConvertor propertyConvertor;
166 private AttributeConverter attributeConverter;
167 private InputConverter inputConverter;
168 private OutputConverter outputConverter;
169 private InterfaceLifecycleOperation interfaceLifecycleOperation;
170 private InterfacesOperationsConverter interfacesOperationsConverter;
173 public ToscaExportHandler(final ApplicationDataTypeCache applicationDataTypeCache,
174 final ToscaOperationFacade toscaOperationFacade,
175 final CapabilityRequirementConverter capabilityRequirementConverter,
176 final PolicyExportParser policyExportParser,
177 final GroupExportParser groupExportParser,
178 final PropertyConvertor propertyConvertor,
179 final AttributeConverter attributeConverter,
180 final InputConverter inputConverter,
181 final OutputConverter outputConverter,
182 final InterfaceLifecycleOperation interfaceLifecycleOperation,
183 final InterfacesOperationsConverter interfacesOperationsConverter) {
184 this.applicationDataTypeCache = applicationDataTypeCache;
185 this.toscaOperationFacade = toscaOperationFacade;
186 this.capabilityRequirementConverter = capabilityRequirementConverter;
187 this.policyExportParser = policyExportParser;
188 this.groupExportParser = groupExportParser;
189 this.propertyConvertor = propertyConvertor;
190 this.attributeConverter = attributeConverter;
191 this.inputConverter = inputConverter;
192 this.outputConverter = outputConverter;
193 this.interfaceLifecycleOperation = interfaceLifecycleOperation;
194 this.interfacesOperationsConverter = interfacesOperationsConverter;
197 public static String getInterfaceFilename(String artifactName) {
198 return artifactName.substring(0, artifactName.lastIndexOf('.')) + TOSCA_INTERFACE_NAME;
201 private static void removeOperationImplementationForProxyNodeType(Map<String, InterfaceDefinition> proxyComponentInterfaces) {
202 if (MapUtils.isEmpty(proxyComponentInterfaces)) {
205 proxyComponentInterfaces.values().stream().map(InterfaceDataDefinition::getOperations).filter(MapUtils::isNotEmpty)
206 .forEach(operations -> operations.values().forEach(operation -> operation.setImplementation(null)));
209 public Either<ToscaRepresentation, ToscaError> exportComponent(Component component) {
210 return convertToToscaTemplate(component).left().map(this::createToscaRepresentation);
213 public Either<ToscaRepresentation, ToscaError> exportComponentInterface(final Component component, final boolean isAssociatedComponent) {
214 final List<Map<String, Map<String, String>>> imports = new ArrayList<>(getDefaultToscaImportConfig());
215 if (CollectionUtils.isEmpty(imports)) {
216 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
217 return Either.right(ToscaError.GENERAL_ERROR);
219 List<Triple<String, String, Component>> dependencies = new ArrayList<>();
220 if (component.getDerivedFromGenericType() != null && !component.getDerivedFromGenericType()
221 .startsWith("org.openecomp.resource.abstract.nodes.")) {
222 final Either<Component, StorageOperationStatus> baseType = toscaOperationFacade
223 .getByToscaResourceNameAndVersion(component.getDerivedFromGenericType(), component.getDerivedFromGenericVersion());
224 if (baseType.isLeft() && baseType.left().value() != null) {
225 addDependencies(imports, dependencies, baseType.left().value());
227 log.debug("Failed to fetch derived from type {}", component.getDerivedFromGenericType());
231 String toscaVersion = null;
232 if (component instanceof Resource) {
233 toscaVersion = ((Resource) component).getToscaVersion();
235 ToscaTemplate toscaTemplate = new ToscaTemplate(toscaVersion != null ? toscaVersion : TOSCA_VERSION);
236 toscaTemplate.setImports(imports);
237 final Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
238 final Either<ToscaTemplate, ToscaError> toscaTemplateRes = convertInterfaceNodeType(new HashMap<>(), component, toscaTemplate, nodeTypes,
239 isAssociatedComponent);
240 if (toscaTemplateRes.isRight()) {
241 return Either.right(toscaTemplateRes.right().value());
243 toscaTemplate = toscaTemplateRes.left().value();
244 toscaTemplate.setDependencies(dependencies);
245 ToscaRepresentation toscaRepresentation = this.createToscaRepresentation(toscaTemplate);
246 return Either.left(toscaRepresentation);
249 public ToscaRepresentation createToscaRepresentation(ToscaTemplate toscaTemplate) {
250 CustomRepresenter representer = new CustomRepresenter();
251 DumperOptions options = new DumperOptions();
252 options.setAllowReadOnlyProperties(false);
253 options.setPrettyFlow(true);
254 options.setDefaultFlowStyle(FlowStyle.FLOW);
255 options.setCanonical(false);
256 representer.addClassTag(toscaTemplate.getClass(), Tag.MAP);
257 representer.setPropertyUtils(new UnsortedPropertyUtils());
258 Yaml yaml = new Yaml(representer, options);
259 String yamlAsString = yaml.dumpAsMap(toscaTemplate);
260 StringBuilder sb = new StringBuilder();
261 sb.append(getConfiguration().getHeatEnvArtifactHeader());
262 sb.append(yamlAsString);
263 sb.append(getConfiguration().getHeatEnvArtifactFooter());
264 return ToscaRepresentation.make(sb.toString().getBytes(), toscaTemplate);
267 public Either<ToscaTemplate, ToscaError> getDependencies(Component component) {
268 ToscaTemplate toscaTemplate = new ToscaTemplate(null);
269 Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports = fillImports(component, toscaTemplate);
270 if (fillImports.isRight()) {
271 return Either.right(fillImports.right().value());
273 return Either.left(fillImports.left().value().left);
276 public Either<ToscaTemplate, ToscaError> convertToToscaTemplate(final Component component) {
277 final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImportConfig();
278 if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
279 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
280 return Either.right(ToscaError.GENERAL_ERROR);
282 log.trace("start tosca export for {}", component.getUniqueId());
283 String toscaVersion = null;
284 if (component instanceof Resource) {
285 toscaVersion = ((Resource) component).getToscaVersion();
287 final ToscaTemplate toscaTemplate = new ToscaTemplate(toscaVersion != null ? toscaVersion : TOSCA_VERSION);
288 toscaTemplate.setMetadata(convertMetadata(component));
289 toscaTemplate.setImports(new ArrayList<>(defaultToscaImportConfig));
290 final Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
291 if (ModelConverter.isAtomicComponent(component)) {
292 log.trace("convert component as node type");
293 return convertNodeType(new HashMap<>(), component, toscaTemplate, nodeTypes);
295 log.trace("convert component as topology template");
296 return convertToscaTemplate(component, toscaTemplate);
300 private Either<ToscaTemplate, ToscaError> convertToscaTemplate(Component component, ToscaTemplate toscaNode) {
301 Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> importsRes = fillImports(component, toscaNode);
302 if (importsRes.isRight()) {
303 return Either.right(importsRes.right().value());
305 toscaNode = importsRes.left().value().left;
306 Map<String, Component> componentCache = importsRes.left().value().right;
307 Either<Map<String, ToscaNodeType>, ToscaError> nodeTypesMapEither = createProxyNodeTypes(componentCache, component);
308 if (nodeTypesMapEither.isRight()) {
309 log.debug("Failed to fetch normative service proxy resource by tosca name, error {}", nodeTypesMapEither.right().value());
310 return Either.right(nodeTypesMapEither.right().value());
312 Map<String, ToscaNodeType> nodeTypesMap = nodeTypesMapEither.left().value();
313 if (nodeTypesMap != null && !nodeTypesMap.isEmpty()) {
314 toscaNode.setNode_types(nodeTypesMap);
316 createServiceSubstitutionNodeTypes(componentCache, component, toscaNode);
317 Either<Map<String, Object>, ToscaError> proxyInterfaceTypesEither = createProxyInterfaceTypes(component);
318 if (proxyInterfaceTypesEither.isRight()) {
319 log.debug("Failed to populate service proxy local interface types in tosca, error {}", nodeTypesMapEither.right().value());
320 return Either.right(proxyInterfaceTypesEither.right().value());
322 Map<String, Object> proxyInterfaceTypes = proxyInterfaceTypesEither.left().value();
323 if (MapUtils.isNotEmpty(proxyInterfaceTypes)) {
324 toscaNode.setInterface_types(proxyInterfaceTypes);
326 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = applicationDataTypeCache.getAll(component.getModel());
327 if (dataTypesEither.isRight()) {
328 log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
329 return Either.right(ToscaError.GENERAL_ERROR);
331 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
332 ToscaTopolgyTemplate topologyTemplate = new ToscaTopolgyTemplate();
333 List<InputDefinition> inputDef = component.getInputs();
334 Map<String, ToscaProperty> inputs = inputConverter.convertInputs(inputDef, dataTypes);
335 if (!inputs.isEmpty()) {
336 topologyTemplate.setInputs(inputs);
338 final Map<String, ToscaProperty> outputs;
340 outputs = outputConverter.convert(component.getOutputs(), dataTypes);
341 } catch (final ToscaConversionException e) {
342 log.error(EcompLoggerErrorCode.SCHEMA_ERROR, ToscaExportHandler.class.getName(),
343 "Could not parse component '{}' outputs. Component unique id '{}'.", component.getName(), component.getUniqueId(), e);
344 return Either.right(ToscaError.GENERAL_ERROR);
346 if (!outputs.isEmpty()) {
347 topologyTemplate.setOutputs(outputs);
349 if (CollectionUtils.isNotEmpty(component.getComponentInstances())) {
350 final Either<Map<String, ToscaNodeTemplate>, ToscaError> nodeTemplates =
351 convertNodeTemplates(component, componentCache, dataTypes, topologyTemplate);
352 if (nodeTemplates.isRight()) {
353 return Either.right(nodeTemplates.right().value());
355 log.debug("node templates converted");
356 topologyTemplate.setNode_templates(nodeTemplates.left().value());
358 final Map<String, ToscaRelationshipTemplate> relationshipTemplatesMap = new ToscaExportRelationshipTemplatesHandler()
359 .createFrom(topologyTemplate.getNode_templates());
360 if (!relationshipTemplatesMap.isEmpty()) {
361 topologyTemplate.setRelationshipTemplates(relationshipTemplatesMap);
363 SubstitutionMapping substitutionMapping = new SubstitutionMapping();
364 convertSubstitutionMappingFilter(component, substitutionMapping);
365 addGroupsToTopologyTemplate(component, topologyTemplate);
367 addPoliciesToTopologyTemplate(component, topologyTemplate);
368 } catch (SdcResourceNotFoundException e) {
369 log.debug("Fail to add policies to topology template:", e);
370 return Either.right(ToscaError.GENERAL_ERROR);
372 String toscaResourceName;
373 switch (component.getComponentType()) {
375 toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition().getMetadataDataDefinition())
376 .getToscaResourceName();
379 toscaResourceName = SERVICE_NODE_TYPE_PREFIX + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName();
382 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
383 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
385 substitutionMapping.setNode_type(toscaResourceName);
386 Either<SubstitutionMapping, ToscaError> capabilities = convertCapabilities(component, substitutionMapping, componentCache);
387 if (capabilities.isRight()) {
388 return Either.right(capabilities.right().value());
390 substitutionMapping = capabilities.left().value();
391 Either<SubstitutionMapping, ToscaError> requirements = capabilityRequirementConverter
392 .convertSubstitutionMappingRequirements(componentCache, component, substitutionMapping);
393 if (requirements.isRight()) {
394 return Either.right(requirements.right().value());
396 substitutionMapping = requirements.left().value();
397 final Map<String, String[]> propertyMappingMap = buildSubstitutionMappingPropertyMapping(component);
398 if (!propertyMappingMap.isEmpty()) {
399 substitutionMapping.setProperties(propertyMappingMap);
401 final Map<String, String[]> attributesMappingMap = buildSubstitutionMappingAttributesMapping(component);
402 if (!attributesMappingMap.isEmpty()) {
403 substitutionMapping.setAttributes(attributesMappingMap);
405 topologyTemplate.setSubstitution_mappings(substitutionMapping);
406 toscaNode.setTopology_template(topologyTemplate);
407 return Either.left(toscaNode);
410 private void convertSubstitutionMappingFilter(final Component component, final SubstitutionMapping substitutionMapping) {
411 if (component.getSubstitutionFilter() != null && (component.getSubstitutionFilter().getProperties()).getListToscaDataDefinition() != null) {
412 substitutionMapping.setSubstitution_filter(convertToSubstitutionFilterComponent(component.getSubstitutionFilter()));
416 private void addGroupsToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate) {
417 Map<String, ToscaGroupTemplate> groups = groupExportParser.getGroups(component);
418 if (groups != null) {
419 topologyTemplate.addGroups(groups);
423 private void addPoliciesToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate) throws SdcResourceNotFoundException {
424 Map<String, ToscaPolicyTemplate> policies = policyExportParser.getPolicies(component);
425 if (policies != null) {
426 topologyTemplate.addPolicies(policies);
430 private Map<String, String> convertMetadata(Component component) {
431 return convertMetadata(component, false, null);
434 private Map<String, String> convertMetadata(Component component, boolean isInstance, ComponentInstance componentInstance) {
435 Map<String, String> toscaMetadata = new LinkedHashMap<>();
436 toscaMetadata.put(convertMetadataKey(JsonPresentationFields.INVARIANT_UUID), component.getInvariantUUID());
437 toscaMetadata.put(JsonPresentationFields.UUID.getPresentation(), component.getUUID());
439 .put(JsonPresentationFields.NAME.getPresentation(), component.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
440 toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), component.getDescription());
441 List<CategoryDefinition> categories = component.getCategories();
442 CategoryDefinition categoryDefinition = categories.get(0);
443 toscaMetadata.put(JsonPresentationFields.CATEGORY.getPresentation(), categoryDefinition.getName());
445 toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), component.getVersion());
446 toscaMetadata.put(JsonPresentationFields.CUSTOMIZATION_UUID.getPresentation(), componentInstance.getCustomizationUUID());
447 if (componentInstance.getSourceModelInvariant() != null && !componentInstance.getSourceModelInvariant().isEmpty()) {
448 toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), componentInstance.getComponentVersion());
449 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_INVARIANT.getPresentation(), componentInstance.getSourceModelInvariant());
450 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_UUID.getPresentation(), componentInstance.getSourceModelUuid());
451 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_NAME.getPresentation(), componentInstance.getSourceModelName());
452 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
453 toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(),
454 componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceProxy.getDisplayValue());
455 } else if (componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
456 toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(),
457 componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceSubstitution.getDisplayValue());
459 toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), componentInstance.getDescription());
462 switch (component.getComponentType()) {
464 Resource resource = (Resource) component;
465 if (isInstance && (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy
466 || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution)) {
467 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), componentInstance.getOriginType().getDisplayValue());
469 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), resource.getResourceType().name());
471 toscaMetadata.put(JsonPresentationFields.SUB_CATEGORY.getPresentation(), categoryDefinition.getSubcategories().get(0).getName());
472 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR.getPresentation(), resource.getVendorName());
473 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_RELEASE.getPresentation(), resource.getVendorRelease());
474 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_MODEL_NUMBER.getPresentation(), resource.getResourceVendorModelNumber());
477 Service service = (Service) component;
478 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), component.getComponentType().getValue());
479 toscaMetadata.put(JsonPresentationFields.SERVICE_TYPE.getPresentation(), service.getServiceType());
480 toscaMetadata.put(JsonPresentationFields.SERVICE_ROLE.getPresentation(), service.getServiceRole());
481 toscaMetadata.put(JsonPresentationFields.SERVICE_FUNCTION.getPresentation(), service.getServiceFunction());
482 toscaMetadata.put(JsonPresentationFields.ENVIRONMENT_CONTEXT.getPresentation(), service.getEnvironmentContext());
483 toscaMetadata.put(JsonPresentationFields.INSTANTIATION_TYPE.getPresentation(),
484 service.getEnvironmentContext() == null ? StringUtils.EMPTY : service.getInstantiationType());
487 toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming().toString());
488 toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming().toString());
489 toscaMetadata.put(JsonPresentationFields.NAMING_POLICY.getPresentation(), service.getNamingPolicy());
493 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
495 for (final String key : component.getCategorySpecificMetadata().keySet()) {
496 if (!EXCLUDED_CATEGORY_SPECIFIC_METADATA.contains(key)) {
497 toscaMetadata.put(key, component.getCategorySpecificMetadata().get(key));
500 return toscaMetadata;
503 private String convertMetadataKey(JsonPresentationFields jsonPresentationField) {
504 if (JsonPresentationFields.INVARIANT_UUID.equals(jsonPresentationField)) {
505 return INVARIANT_UUID;
507 return jsonPresentationField.getPresentation();
510 private Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports(Component component, ToscaTemplate toscaTemplate) {
511 final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImportConfig();
512 if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
513 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
514 return Either.right(ToscaError.GENERAL_ERROR);
516 Map<String, Component> componentCache = new HashMap<>();
517 if (!ModelConverter.isAtomicComponent(component)) {
518 final List<Map<String, Map<String, String>>> additionalImports =
519 toscaTemplate.getImports() == null ? new ArrayList<>(defaultToscaImportConfig) : new ArrayList<>(toscaTemplate.getImports());
520 List<Triple<String, String, Component>> dependencies = new ArrayList<>();
521 Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
522 if (isNotEmpty(toscaArtifacts)) {
523 ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE);
524 if (artifactDefinition != null) {
525 Map<String, Map<String, String>> importsListMember = new HashMap<>();
526 Map<String, String> interfaceFiles = new HashMap<>();
527 interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactDefinition.getArtifactName()));
528 StringBuilder keyNameBuilder = new StringBuilder();
529 keyNameBuilder.append(component.getComponentType().toString().toLowerCase()).append("-").append(component.getName())
530 .append("-interface");
531 importsListMember.put(keyNameBuilder.toString(), interfaceFiles);
532 additionalImports.add(importsListMember);
535 List<ComponentInstance> componentInstances = component.getComponentInstances();
536 if (componentInstances != null && !componentInstances.isEmpty()) {
537 componentInstances.forEach(ci -> createDependency(componentCache, additionalImports, dependencies, ci));
539 toscaTemplate.setDependencies(dependencies);
540 toscaTemplate.setImports(additionalImports);
542 log.debug("currently imports supported for VF and service only");
544 return Either.left(new ImmutablePair<>(toscaTemplate, componentCache));
547 private List<Map<String, Map<String, String>>> getDefaultToscaImportConfig() {
548 return getConfiguration().getDefaultImports();
551 private void createDependency(final Map<String, Component> componentCache, final List<Map<String, Map<String, String>>> imports,
552 final List<Triple<String, String, Component>> dependencies, final ComponentInstance componentInstance) {
553 log.debug("createDependency componentCache {}", componentCache);
554 Component componentRI = componentCache.get(componentInstance.getComponentUid());
555 if (componentRI == null || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
556 // all resource must be only once!
557 final Either<Component, StorageOperationStatus> resource = toscaOperationFacade.getToscaFullElement(componentInstance.getComponentUid());
558 if ((resource.isRight()) && (log.isDebugEnabled())) {
559 log.debug("Failed to fetch resource with id {} for instance {}", componentInstance.getComponentUid(),
560 componentInstance.getUniqueId());
563 final Component fetchedComponent = resource.left().value();
564 componentRI = setComponentCache(componentCache, componentInstance, fetchedComponent);
565 addDependencies(imports, dependencies, componentRI);
570 * Sets a componentCache from the given component/resource.
572 private Component setComponentCache(final Map<String, Component> componentCache, final ComponentInstance componentInstance,
573 final Component fetchedComponent) {
574 componentCache.put(fetchedComponent.getUniqueId(), fetchedComponent);
575 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy
576 || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
577 final Either<Component, StorageOperationStatus> sourceService = toscaOperationFacade
578 .getToscaFullElement(componentInstance.getSourceModelUid());
579 if (sourceService.isRight() && (log.isDebugEnabled())) {
580 log.debug("Failed to fetch source service with id {} for proxy {}", componentInstance.getSourceModelUid(),
581 componentInstance.getUniqueId());
583 final Component fetchedSource = sourceService.left().value();
584 componentCache.put(fetchedSource.getUniqueId(), fetchedSource);
585 return fetchedSource;
587 return fetchedComponent;
591 * Retrieves all derived_from nodes and stores it in a predictable order.
593 private void addDependencies(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
594 final Component fetchedComponent) {
595 final Set<Component> componentsList = new LinkedHashSet<>();
596 if (fetchedComponent instanceof Resource) {
597 log.debug("fetchedComponent is a resource {}", fetchedComponent);
598 final Optional<Map<String, String>> derivedFromMapOfIdToName = getDerivedFromMapOfIdToName(fetchedComponent, componentsList);
599 if (derivedFromMapOfIdToName.isPresent() && !derivedFromMapOfIdToName.get().isEmpty()) {
600 derivedFromMapOfIdToName.get().entrySet().forEach(entry -> {
601 log.debug("Started entry.getValue() : {}", entry.getValue());
602 if (!NATIVE_ROOT.equals(entry.getValue())) {
603 Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade.getToscaElement(entry.getKey());
604 if (resourcefetched != null && resourcefetched.isLeft()) {
605 componentsList.add(resourcefetched.left().value());
609 setImports(imports, dependencies, componentsList);
611 setImports(imports, dependencies, fetchedComponent);
617 * Returns all derived_from nodes found.
619 private Optional<Map<String, String>> getDerivedFromMapOfIdToName(final Component fetchedComponent, final Set<Component> componentsList) {
620 final Resource parentResource = (Resource) fetchedComponent;
621 Map<String, String> derivedFromMapOfIdToName = new HashMap<>();
622 if (CollectionUtils.isNotEmpty(parentResource.getComponentInstances())) {
623 componentsList.add(fetchedComponent);
624 for (final ComponentInstance componentInstance : parentResource.getComponentInstances()) {
625 final Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade
626 .getToscaElement(componentInstance.getComponentUid());
627 if (resourcefetched != null && resourcefetched.isLeft()) {
628 final Map<String, String> derivedWithId = resourcefetched.left().value().getDerivedFromMapOfIdToName();
629 if (MapUtils.isNotEmpty(derivedWithId)) {
630 derivedFromMapOfIdToName.putAll(derivedWithId);
635 derivedFromMapOfIdToName = parentResource.getDerivedFromMapOfIdToName();
637 log.debug("Started derivedFromMapOfIdToName: {}", derivedFromMapOfIdToName);
638 return Optional.ofNullable(derivedFromMapOfIdToName);
642 * Creates a resource map and adds it to the import list.
644 private void setImports(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
645 final Set<Component> componentsList) {
646 componentsList.forEach(component -> setImports(imports, dependencies, component));
649 private void setImports(final List<Map<String, Map<String, String>>> imports, final List<Triple<String, String, Component>> dependencies,
650 final Component component) {
651 final Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
652 final ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE);
653 if (artifactDefinition != null) {
654 final Map<String, String> files = new HashMap<>();
655 final String artifactName = artifactDefinition.getArtifactName();
656 files.put(IMPORTS_FILE_KEY, artifactName);
657 final StringBuilder keyNameBuilder = new StringBuilder();
658 keyNameBuilder.append(component.getComponentType().toString().toLowerCase());
659 keyNameBuilder.append("-");
660 keyNameBuilder.append(component.getName());
661 addImports(imports, keyNameBuilder, files);
662 dependencies.add(new ImmutableTriple<>(artifactName, artifactDefinition.getEsId(), component));
663 if (!ModelConverter.isAtomicComponent(component)) {
664 final Map<String, String> interfaceFiles = new HashMap<>();
665 interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactName));
666 keyNameBuilder.append("-interface");
667 addImports(imports, keyNameBuilder, interfaceFiles);
673 * Adds the found resource to the import definition list.
675 private void addImports(final List<Map<String, Map<String, String>>> imports, final StringBuilder keyNameBuilder,
676 final Map<String, String> files) {
677 final String mapKey = keyNameBuilder.toString();
678 if (imports.stream().allMatch(stringMapMap -> stringMapMap.get(mapKey) == null)) {
679 final Map<String, Map<String, String>> importsListMember = new HashMap<>();
680 importsListMember.put(keyNameBuilder.toString(), files);
681 imports.add(importsListMember);
685 private Either<ToscaTemplate, ToscaError> convertNodeType(Map<String, Component> componentsCache, Component component, ToscaTemplate toscaNode,
686 Map<String, ToscaNodeType> nodeTypes) {
687 return convertInterfaceNodeType(componentsCache, component, toscaNode, nodeTypes, false);
690 public Either<ToscaTemplate, ToscaError> convertInterfaceNodeType(Map<String, Component> componentsCache, Component component,
691 ToscaTemplate toscaNode, Map<String, ToscaNodeType> nodeTypes,
692 boolean isAssociatedComponent) {
693 log.debug("start convert node type for {}", component.getUniqueId());
694 ToscaNodeType toscaNodeType = createNodeType(component);
695 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither = interfaceLifecycleOperation
696 .getAllInterfaceLifecycleTypes(component.getModel());
697 if (lifecycleTypeEither.isRight()) {
698 log.debug("Failed to fetch all interface types :", lifecycleTypeEither.right().value());
699 return Either.right(ToscaError.GENERAL_ERROR);
701 List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value().values().stream().map(InterfaceDataDefinition::getType)
702 .collect(Collectors.toList());
703 toscaNode.setInterface_types(addInterfaceTypeElement(component, allGlobalInterfaceTypes));
704 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = applicationDataTypeCache.getAll(component.getModel());
705 if (dataTypesEither.isRight()) {
706 log.debug("Failed to fetch all data types :", dataTypesEither.right().value());
707 return Either.right(ToscaError.GENERAL_ERROR);
709 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
710 List<InputDefinition> inputDef = component.getInputs();
711 Map<String, ToscaProperty> mergedProperties = new HashMap<>();
712 interfacesOperationsConverter.addInterfaceDefinitionElement(component, toscaNodeType, dataTypes, isAssociatedComponent);
713 addInputsToProperties(dataTypes, inputDef, mergedProperties);
714 final Map<String, ToscaAttribute> toscaAttributeMap;
715 toscaAttributeMap = convertToToscaAttributes(component.getAttributes(), dataTypes);
716 if (!toscaAttributeMap.isEmpty()) {
717 toscaNodeType.setAttributes(toscaAttributeMap);
719 if (CollectionUtils.isNotEmpty(component.getProperties())) {
720 List<PropertyDefinition> properties = component.getProperties();
721 Map<String, ToscaProperty> convertedProperties = properties.stream()
722 .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, component.getInputs())).collect(Collectors
723 .toMap(PropertyDataDefinition::getName,
724 property -> propertyConvertor.convertProperty(dataTypes, property, PropertyConvertor.PropertyType.PROPERTY)));
725 // merge component properties and inputs properties
726 mergedProperties.putAll(convertedProperties);
728 if (MapUtils.isNotEmpty(mergedProperties)) {
729 toscaNodeType.setProperties(mergedProperties);
731 /* convert private data_types */
732 List<DataTypeDefinition> privateDataTypes = component.getDataTypes();
733 if (CollectionUtils.isNotEmpty(privateDataTypes)) {
734 Map<String, ToscaDataType> toscaDataTypeMap = new HashMap<>();
735 for (DataTypeDefinition dataType : privateDataTypes) {
736 log.debug("Emitting private data type: component.name={} dataType.name={}",
737 component.getNormalizedName(), dataType.getName());
738 ToscaDataType toscaDataType = new ToscaDataType();
739 toscaDataType.setDerived_from(dataType.getDerivedFromName());
740 toscaDataType.setDescription(dataType.getDescription());
741 toscaDataType.setVersion(dataType.getVersion());
742 if (CollectionUtils.isNotEmpty(dataType.getProperties())) {
743 toscaDataType.setProperties(dataType.getProperties().stream()
744 .collect(Collectors.toMap(
745 PropertyDataDefinition::getName,
746 s -> propertyConvertor
747 .convertProperty(dataTypes, s, PropertyType.PROPERTY)
750 toscaDataTypeMap.put(dataType.getName(), toscaDataType);
752 toscaNode.setData_types(toscaDataTypeMap);
755 // Extracted to method for code reuse
756 return convertReqCapAndTypeName(componentsCache, component, toscaNode, nodeTypes, toscaNodeType, dataTypes);
759 private Map<String, ToscaAttribute> convertToToscaAttributes(final List<AttributeDefinition> attributeList,
760 final Map<String, DataTypeDefinition> dataTypes) {
761 if (CollectionUtils.isEmpty(attributeList)) {
762 return Collections.emptyMap();
764 final AttributeConverter converter = new AttributeConverter(dataTypes);
765 final Map<String, ToscaAttribute> toscaAttributeMap = new HashMap<>();
766 for (final AttributeDefinition attributeDefinition : attributeList) {
767 toscaAttributeMap.put(attributeDefinition.getName(), converter.convert(attributeDefinition));
769 return toscaAttributeMap;
772 private Either<ToscaTemplate, ToscaError> convertReqCapAndTypeName(Map<String, Component> componentsCache,
773 Component component, ToscaTemplate toscaNode,
774 Map<String, ToscaNodeType> nodeTypes,
775 ToscaNodeType toscaNodeType,
776 Map<String, DataTypeDefinition> dataTypes) {
777 Either<ToscaNodeType, ToscaError> capabilities = convertCapabilities(componentsCache, component, toscaNodeType,
779 if (capabilities.isRight()) {
780 return Either.right(capabilities.right().value());
782 toscaNodeType = capabilities.left().value();
783 log.debug("Capabilities converted for {}", component.getUniqueId());
785 Either<ToscaNodeType, ToscaError> requirements = capabilityRequirementConverter
786 .convertRequirements(componentsCache, component, toscaNodeType);
787 if (requirements.isRight()) {
788 return Either.right(requirements.right().value());
790 toscaNodeType = requirements.left().value();
791 log.debug("Requirements converted for {}", component.getUniqueId());
793 String toscaResourceName;
794 switch (component.getComponentType()) {
796 toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition()
797 .getMetadataDataDefinition()).getToscaResourceName();
800 toscaResourceName = SERVICE_NODE_TYPE_PREFIX
801 + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName();
804 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
805 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
808 nodeTypes.put(toscaResourceName, toscaNodeType);
809 toscaNode.setNode_types(nodeTypes);
810 log.debug("finish convert node type for {}", component.getUniqueId());
811 return Either.left(toscaNode);
814 private Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplates(final Component component,
815 final Map<String, Component> componentCache,
816 final Map<String, DataTypeDefinition> dataTypes,
817 final ToscaTopolgyTemplate topologyTemplate) {
819 final Map<String, List<ComponentInstanceProperty>> componentInstancesProperties = component.getComponentInstancesProperties();
820 final Map<String, List<ComponentInstanceAttribute>> componentInstancesAttributes = component.getComponentInstancesAttributes();
821 final Map<String, List<ComponentInstanceInput>> componentInstancesInputs = component.getComponentInstancesInputs();
822 final Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces = component.getComponentInstancesInterfaces();
823 final List<RequirementCapabilityRelDef> componentInstancesRelations = component.getComponentInstancesRelations();
825 Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplatesRes = null;
826 log.debug("start convert topology template for {} for type {}", component.getUniqueId(), component.getComponentType());
827 final Map<String, ToscaNodeTemplate> nodeTemplates = new HashMap<>();
829 Map<String, ToscaGroupTemplate> groupsMap = null;
830 for (final ComponentInstance componentInstance : component.getComponentInstances()) {
831 ToscaNodeTemplate nodeTemplate = new ToscaNodeTemplate();
832 if (MapUtils.isNotEmpty(componentInstance.getToscaArtifacts())) {
833 nodeTemplate.setArtifacts(convertToNodeTemplateArtifacts(componentInstance.getToscaArtifacts()));
835 nodeTemplate.setType(componentInstance.getToscaComponentName());
836 nodeTemplate.setDirectives(componentInstance.getDirectives());
837 nodeTemplate.setNode_filter(convertToNodeTemplateNodeFilterComponent(componentInstance.getNodeFilter()));
839 final Either<Component, Boolean> originComponentRes = capabilityRequirementConverter
840 .getOriginComponent(componentCache, componentInstance);
841 if (originComponentRes.isRight()) {
842 convertNodeTemplatesRes = Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
845 final Either<ToscaNodeTemplate, ToscaError> requirements = convertComponentInstanceRequirements(component, componentInstance,
846 componentInstancesRelations, nodeTemplate, originComponentRes.left().value(), componentCache);
847 if (requirements.isRight()) {
848 convertNodeTemplatesRes = Either.right(requirements.right().value());
851 final String instanceUniqueId = componentInstance.getUniqueId();
852 log.debug("Component instance Requirements converted for instance {}", instanceUniqueId);
854 nodeTemplate = requirements.left().value();
856 final Component originalComponent = componentCache.get(componentInstance.getActualComponentUid());
858 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
859 final Component componentOfProxy = componentCache.get(componentInstance.getComponentUid());
860 nodeTemplate.setMetadata(convertMetadata(componentOfProxy, true, componentInstance));
862 nodeTemplate.setMetadata(convertMetadata(originalComponent, true, componentInstance));
865 final Either<ToscaNodeTemplate, ToscaError> capabilities =
866 capabilityRequirementConverter.convertComponentInstanceCapabilities(componentInstance, dataTypes, nodeTemplate);
867 if (capabilities.isRight()) {
868 convertNodeTemplatesRes = Either.right(capabilities.right().value());
871 log.debug("Component instance Capabilities converted for instance {}", instanceUniqueId);
873 nodeTemplate = capabilities.left().value();
874 final Map<String, Object> props = new HashMap<>();
875 final Map<String, Object> attribs = new HashMap<>();
877 if (originalComponent.getComponentType() == ComponentTypeEnum.RESOURCE) {
878 // Adds the properties of parent component to map
879 addPropertiesOfParentComponent(dataTypes, originalComponent, props);
880 addAttributesOfParentComponent(originalComponent, attribs);
883 if (null != componentInstancesProperties && componentInstancesProperties.containsKey(instanceUniqueId)) {
884 addPropertiesOfComponentInstance(componentInstancesProperties, dataTypes, instanceUniqueId, props);
886 if (null != componentInstancesAttributes && componentInstancesAttributes.containsKey(instanceUniqueId)) {
887 addAttributesOfComponentInstance(componentInstancesAttributes, instanceUniqueId, attribs);
890 if (componentInstancesInputs != null
891 && componentInstancesInputs.containsKey(instanceUniqueId)
892 && !isComponentOfTypeServiceProxy(componentInstance)) {
893 //For service proxy the inputs are already handled under instance properties above
894 addComponentInstanceInputs(dataTypes, componentInstancesInputs, instanceUniqueId, props);
897 //M3[00001] - NODE TEMPLATE INTERFACES - START
898 handleInstanceInterfaces(componentInstanceInterfaces, componentInstance, dataTypes, nodeTemplate, instanceUniqueId, component);
899 //M3[00001] - NODE TEMPLATE INTERFACES - END
900 if (MapUtils.isNotEmpty(props)) {
901 nodeTemplate.setProperties(props);
903 if (MapUtils.isNotEmpty(attribs)) {
904 nodeTemplate.setAttributes(attribs);
907 final List<GroupInstance> groupInstances = componentInstance.getGroupInstances();
908 if (CollectionUtils.isNotEmpty(groupInstances)) {
909 if (groupsMap == null) {
910 groupsMap = new HashMap<>();
912 for (final GroupInstance groupInst : groupInstances) {
913 if (CollectionUtils.isNotEmpty(groupInst.getArtifacts())) {
914 groupsMap.put(groupInst.getName(), groupExportParser.getToscaGroupTemplate(groupInst, componentInstance.getInvariantName()));
919 nodeTemplates.put(componentInstance.getName(), nodeTemplate);
921 if (groupsMap != null) {
922 log.debug("instance groups added");
923 topologyTemplate.addGroups(groupsMap);
925 if (component.getComponentType() == ComponentTypeEnum.SERVICE && isNotEmpty(
926 ((Service) component).getForwardingPaths())) {
927 log.debug("Starting converting paths for component {}, name {}", component.getUniqueId(), component.getName());
928 ForwardingPathToscaUtil
929 .addForwardingPaths((Service) component, nodeTemplates, capabilityRequirementConverter, componentCache, toscaOperationFacade);
930 log.debug("Finished converting paths for component {}, name {}", component.getUniqueId(), component.getName());
932 if (convertNodeTemplatesRes == null) {
933 convertNodeTemplatesRes = Either.left(nodeTemplates);
935 log.debug("finish convert topology template for {} for type {}", component.getUniqueId(), component.getComponentType());
936 return convertNodeTemplatesRes;
939 private void handleInstanceInterfaces(
940 Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces,
941 ComponentInstance componentInstance, Map<String, DataTypeDefinition> dataTypes, ToscaNodeTemplate nodeTemplate,
942 String instanceUniqueId,
943 Component parentComponent) {
945 if (MapUtils.isEmpty(componentInstanceInterfaces)
946 || !componentInstanceInterfaces.containsKey(instanceUniqueId)) {
947 nodeTemplate.setInterfaces(null);
951 final List<ComponentInstanceInterface> currServiceInterfaces =
952 componentInstanceInterfaces.get(instanceUniqueId);
954 final Map<String, InterfaceDefinition> tmpInterfaces = new HashMap<>();
955 currServiceInterfaces.forEach(instInterface -> tmpInterfaces.put(instInterface
956 .getUniqueId(), instInterface));
958 final Map<String, Object> interfaceMap = interfacesOperationsConverter
959 .getInterfacesMap(parentComponent, componentInstance, tmpInterfaces, dataTypes, isComponentOfTypeServiceProxy(componentInstance),
960 isComponentOfTypeServiceProxy(componentInstance));
962 interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
963 nodeTemplate.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap);
966 private boolean isComponentOfTypeServiceProxy(ComponentInstance componentInstance) {
967 return Objects.nonNull(componentInstance.getOriginType())
968 && componentInstance.getOriginType().getValue().equals("Service Proxy");
971 private void addComponentInstanceInputs(Map<String, DataTypeDefinition> dataTypes,
972 Map<String, List<ComponentInstanceInput>> componentInstancesInputs,
973 String instanceUniqueId, Map<String, Object> props) {
975 List<ComponentInstanceInput> instanceInputsList = componentInstancesInputs.get(instanceUniqueId);
976 if (instanceInputsList != null) {
977 instanceInputsList.forEach(input -> {
978 Supplier<String> supplier = () -> input.getValue() != null && !Objects.isNull(input.getValue()) ? input.getValue() : input.getDefaultValue();
979 propertyConvertor.convertAndAddValue(dataTypes, props, input, supplier);
984 private void addPropertiesOfComponentInstance(final Map<String, List<ComponentInstanceProperty>> componentInstancesProperties,
985 final Map<String, DataTypeDefinition> dataTypes,
986 final String instanceUniqueId,
987 final Map<String, Object> props) {
989 if (isNotEmpty(componentInstancesProperties)) {
990 componentInstancesProperties.get(instanceUniqueId)
991 // Converts and adds each value to property map
992 .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop, prop::getValue));
996 private void addAttributesOfComponentInstance(final Map<String, List<ComponentInstanceAttribute>> componentInstancesAttributes,
997 final String instanceUniqueId,
998 final Map<String, Object> attribs) {
1000 if (isNotEmpty(componentInstancesAttributes) && componentInstancesAttributes.containsKey(instanceUniqueId)) {
1001 componentInstancesAttributes.get(instanceUniqueId).stream()
1002 // Filters out Attributes with empty default values
1003 .filter(attributeDefinition -> StringUtils.isNotEmpty(attributeDefinition.getDefaultValue()))
1004 // Converts and adds each value to attribute map
1005 .forEach(attributeDefinition -> attributeConverter.convertAndAddValue(attribs, attributeDefinition));
1009 private void addPropertiesOfParentComponent(Map<String, DataTypeDefinition> dataTypes,
1010 Component componentOfInstance, Map<String, Object> props) {
1012 List<PropertyDefinition> componentProperties = componentOfInstance.getProperties();
1013 if (isNotEmpty(componentProperties)) {
1014 componentProperties.stream()
1015 // Filters out properties with empty default values
1016 .filter(prop -> StringUtils.isNotEmpty(prop.getDefaultValue()))
1017 // Converts and adds each value to property map
1018 .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop, prop::getDefaultValue));
1022 private void addAttributesOfParentComponent(final Component componentOfInstance, final Map<String, Object> attribs) {
1024 final List<AttributeDefinition> componentAttributes = componentOfInstance.getAttributes();
1025 if (isNotEmpty(componentAttributes)) {
1026 componentAttributes.stream()
1027 // Filters out Attributes with empty default values
1028 .filter(attrib -> StringUtils.isNotEmpty(attrib.getDefaultValue()))
1029 // Converts and adds each value to attribute map
1030 .forEach(attributeDefinition -> attributeConverter.convertAndAddValue(attribs, attributeDefinition));
1034 private ToscaNodeType createNodeType(Component component) {
1035 ToscaNodeType toscaNodeType = new ToscaNodeType();
1036 if (ModelConverter.isAtomicComponent(component)) {
1037 if (((Resource) component).getDerivedFrom() != null) {
1038 toscaNodeType.setDerived_from(((Resource) component).getDerivedFrom().get(0));
1040 toscaNodeType.setDescription(component.getDescription());
1042 String derivedFrom = null != component.getDerivedFromGenericType() ? component.getDerivedFromGenericType()
1044 toscaNodeType.setDerived_from(derivedFrom);
1046 return toscaNodeType;
1049 private Either<Map<String, Object>, ToscaError> createProxyInterfaceTypes(Component container) {
1051 Map<String, Object> proxyInterfaceTypes = new HashMap<>();
1052 Either<Map<String, Object>, ToscaError> res = Either.left(proxyInterfaceTypes);
1053 List<ComponentInstance> componentInstances = container.getComponentInstances();
1054 if (CollectionUtils.isEmpty(componentInstances)) {
1057 Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
1058 componentInstances.stream()
1059 .filter(this::isComponentOfTypeServiceProxy)
1060 .forEach(inst -> serviceProxyInstanceList.put(inst.getToscaComponentName(), inst));
1061 if (MapUtils.isEmpty(serviceProxyInstanceList)) {
1064 for (Entry<String, ComponentInstance> entryProxy : serviceProxyInstanceList.entrySet()) {
1065 Component serviceComponent;
1066 ComponentParametersView componentParametersView = new ComponentParametersView();
1067 componentParametersView.disableAll();
1068 componentParametersView.setIgnoreInterfaces(false);
1069 Either<Component, StorageOperationStatus> service = toscaOperationFacade
1070 .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
1071 if (service.isRight()) {
1072 log.debug("Failed to fetch original service component with id {} for instance {}",
1073 entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName());
1074 return Either.right(ToscaError.GENERAL_ERROR);
1076 serviceComponent = service.left().value();
1079 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither =
1080 interfaceLifecycleOperation.getAllInterfaceLifecycleTypes(serviceComponent.getModel());
1081 if (lifecycleTypeEither.isRight()) {
1082 log.debug("Failed to retrieve global interface types :", lifecycleTypeEither.right().value());
1083 return Either.right(ToscaError.GENERAL_ERROR);
1086 List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value().values().stream()
1087 .map(InterfaceDataDefinition::getType)
1088 .collect(Collectors.toList());
1089 //Add interface types for local interfaces in the original service component for proxy
1090 Map<String, Object> localInterfaceTypes = addInterfaceTypeElement(serviceComponent,
1091 allGlobalInterfaceTypes);
1092 if (MapUtils.isNotEmpty(localInterfaceTypes)) {
1093 proxyInterfaceTypes.putAll(localInterfaceTypes);
1097 return Either.left(proxyInterfaceTypes);
1100 private Either<Map<String, ToscaNodeType>, ToscaError> createProxyNodeTypes(Map<String, Component> componentCache,
1101 Component container) {
1103 Map<String, ToscaNodeType> nodeTypesMap = new HashMap<>();
1104 Either<Map<String, ToscaNodeType>, ToscaError> res = Either.left(nodeTypesMap);
1106 List<ComponentInstance> componentInstances = container.getComponentInstances();
1108 if (componentInstances == null || componentInstances.isEmpty()) {
1111 Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
1112 List<ComponentInstance> proxyInst = componentInstances.stream()
1113 .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceProxy.name()))
1114 .collect(Collectors.toList());
1115 if (proxyInst != null && !proxyInst.isEmpty()) {
1116 for (ComponentInstance inst : proxyInst) {
1117 serviceProxyInstanceList.put(inst.getToscaComponentName(), inst);
1121 if (serviceProxyInstanceList.isEmpty()) {
1124 Either<Resource, StorageOperationStatus> serviceProxyOrigin = toscaOperationFacade
1125 .getLatestByName("serviceProxy", null);
1126 if (serviceProxyOrigin.isRight()) {
1127 log.debug("Failed to fetch normative service proxy resource by tosca name, error {}",
1128 serviceProxyOrigin.right().value());
1129 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
1131 Component origComponent = serviceProxyOrigin.left().value();
1133 for (Entry<String, ComponentInstance> entryProxy : serviceProxyInstanceList.entrySet()) {
1134 Component serviceComponent = null;
1135 ComponentParametersView componentParametersView = new ComponentParametersView();
1136 componentParametersView.disableAll();
1137 componentParametersView.setIgnoreCategories(false);
1138 componentParametersView.setIgnoreProperties(false);
1139 componentParametersView.setIgnoreInputs(false);
1140 componentParametersView.setIgnoreInterfaces(false);
1141 componentParametersView.setIgnoreRequirements(false);
1142 Either<Component, StorageOperationStatus> service = toscaOperationFacade
1143 .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
1144 if (service.isRight()) {
1145 log.debug("Failed to fetch resource with id {} for instance {}",
1146 entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName());
1148 serviceComponent = service.left().value();
1151 ToscaNodeType toscaNodeType = createProxyNodeType(componentCache, origComponent, serviceComponent,
1152 entryProxy.getValue());
1153 nodeTypesMap.put(entryProxy.getKey(), toscaNodeType);
1156 return Either.left(nodeTypesMap);
1159 private void createServiceSubstitutionNodeTypes(final Map<String, Component> componentCache,
1160 final Component container, final ToscaTemplate toscaNode) {
1161 final List<ComponentInstance> componentInstances = container.getComponentInstances();
1163 if (CollectionUtils.isEmpty(componentInstances)) {
1166 final List<ComponentInstance> serviceSubstitutionInstanceList = componentInstances.stream()
1167 .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceSubstitution.name()))
1168 .collect(Collectors.toList());
1169 if (CollectionUtils.isNotEmpty(serviceSubstitutionInstanceList)) {
1170 for (ComponentInstance inst : serviceSubstitutionInstanceList) {
1171 final Map<String, ToscaNodeType> nodeTypes =
1172 toscaNode.getNode_types() == null ? new HashMap<>() : toscaNode.getNode_types();
1173 convertInterfaceNodeType(new HashMap<>(), componentCache.get(inst.getSourceModelUid()), toscaNode,
1179 private ToscaNodeType createProxyNodeType(Map<String, Component> componentCache, Component origComponent,
1180 Component proxyComponent, ComponentInstance componentInstance) {
1181 ToscaNodeType toscaNodeType = new ToscaNodeType();
1182 String derivedFrom = ((Resource) origComponent).getToscaResourceName();
1184 toscaNodeType.setDerived_from(derivedFrom);
1185 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = applicationDataTypeCache.getAll(origComponent.getModel());
1186 if (dataTypesEither.isRight()) {
1187 log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
1189 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
1190 Map<String, ToscaCapability> capabilities = this.capabilityRequirementConverter
1191 .convertProxyCapabilities(componentCache, componentInstance, dataTypes);
1193 if (MapUtils.isNotEmpty(capabilities)) {
1194 toscaNodeType.setCapabilities(capabilities);
1196 List<Map<String, ToscaRequirement>> proxyNodeTypeRequirements = this.capabilityRequirementConverter
1197 .convertProxyRequirements(componentCache, componentInstance);
1198 if (CollectionUtils.isNotEmpty(proxyNodeTypeRequirements)) {
1199 toscaNodeType.setRequirements(proxyNodeTypeRequirements);
1201 Optional<Map<String, ToscaProperty>> proxyProperties = getProxyNodeTypeProperties(proxyComponent, dataTypes);
1202 proxyProperties.ifPresent(toscaNodeType::setProperties);
1204 Map<String, Object> interfaceMap = new HashMap<>();
1205 if (MapUtils.isEmpty(componentInstance.getInterfaces())) {
1206 final Optional<Map<String, Object>> proxyInterfaces = getProxyNodeTypeInterfaces(proxyComponent, dataTypes);
1207 if (proxyInterfaces.isPresent()) {
1208 interfaceMap = proxyInterfaces.get();
1211 interfaceMap = interfacesOperationsConverter
1212 .getInterfacesMapFromComponentInstance(proxyComponent, componentInstance, dataTypes, false, false);
1215 interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
1216 toscaNodeType.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap);
1218 return toscaNodeType;
1221 private Either<ToscaNodeTemplate, ToscaError> convertComponentInstanceRequirements(Component component,
1222 ComponentInstance componentInstance,
1223 List<RequirementCapabilityRelDef> relations,
1224 ToscaNodeTemplate nodeTypeTemplate,
1225 Component originComponent,
1226 Map<String, Component> componentCache) {
1228 final List<RequirementCapabilityRelDef> requirementDefinitionList = filterRequirements(componentInstance,
1230 if (isNotEmpty(requirementDefinitionList)) {
1232 final List<Map<String, ToscaTemplateRequirement>> toscaRequirements = buildRequirements(component, componentInstance, requirementDefinitionList, originComponent, componentCache);
1233 if (!toscaRequirements.isEmpty()) {
1234 nodeTypeTemplate.setRequirements(toscaRequirements);
1236 } catch (final Exception e) {
1237 log.debug("Failed to convert component instance requirements for the component instance {}. ",
1238 componentInstance.getName(), e);
1239 return Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
1242 log.debug("Finished to convert requirements for the node type {} ", componentInstance.getName());
1243 return Either.left(nodeTypeTemplate);
1246 private List<Map<String, ToscaTemplateRequirement>> buildRequirements(final Component component,
1247 final ComponentInstance componentInstance,
1248 final List<RequirementCapabilityRelDef> filteredRelations,
1249 final Component originComponent,
1250 final Map<String, Component> componentCache)
1251 throws ToscaExportException {
1253 final List<Map<String, ToscaTemplateRequirement>> toscaRequirements = new ArrayList<>();
1254 for (RequirementCapabilityRelDef relationshipDefinition : filteredRelations) {
1255 final Map<String, ToscaTemplateRequirement> toscaTemplateRequirementMap =
1256 buildRequirement(componentInstance, originComponent, component.getComponentInstances(), relationshipDefinition, componentCache);
1257 toscaRequirements.add(toscaTemplateRequirementMap);
1260 return toscaRequirements;
1263 private List<RequirementCapabilityRelDef> filterRequirements(ComponentInstance componentInstance,
1264 List<RequirementCapabilityRelDef> relations) {
1265 return relations.stream()
1266 .filter(p -> componentInstance.getUniqueId().equals(p.getFromNode())).collect(Collectors.toList());
1269 private Map<String, ToscaTemplateRequirement> buildRequirement(final ComponentInstance fromInstance,
1270 final Component fromOriginComponent,
1271 final List<ComponentInstance> instancesList,
1272 final RequirementCapabilityRelDef relationshipDefinition,
1273 final Map<String, Component> componentCache)
1274 throws ToscaExportException {
1276 final Map<String, List<RequirementDefinition>> reqMap = fromOriginComponent.getRequirements();
1277 final CapabilityRequirementRelationship capabilityRequirementRelationship = relationshipDefinition
1278 .getRelationships().get(0);
1279 final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation();
1281 final ComponentInstance toInstance = instancesList.stream()
1282 .filter(i -> relationshipDefinition.getToNode().equals(i.getUniqueId()))
1283 .findFirst().orElse(null);
1284 if (toInstance == null) {
1285 final String errorMsg = String
1286 .format("Failed to find a relation from the node %s to the node %s", fromInstance.getName(),
1287 relationshipDefinition.getToNode());
1288 log.debug(errorMsg);
1289 throw new ToscaExportException(errorMsg);
1291 final Optional<RequirementDefinition> reqOpt =
1292 findRequirement(fromOriginComponent, reqMap, relationshipInfo, fromInstance.getUniqueId());
1293 if (reqOpt.isEmpty()) {
1294 final String errorMsg = String
1295 .format("Failed to find a requirement with uniqueId %s on a component with uniqueId %s",
1296 relationshipInfo.getRequirementUid(), fromOriginComponent.getUniqueId());
1297 log.debug(errorMsg);
1298 throw new ToscaExportException(errorMsg);
1300 final ComponentParametersView filter = new ComponentParametersView(true);
1301 filter.setIgnoreComponentInstances(false);
1302 filter.setIgnoreCapabilities(false);
1303 filter.setIgnoreGroups(false);
1304 final Either<Component, StorageOperationStatus> getOriginRes =
1305 toscaOperationFacade.getToscaElement(toInstance.getActualComponentUid(), filter);
1306 if (getOriginRes.isRight()) {
1307 final String errorMsg = String.format(
1308 "Failed to build substituted name for the requirement %s. "
1309 + "Failed to get an origin component with uniqueId %s",
1310 reqOpt.get().getName(), toInstance.getActualComponentUid());
1311 log.debug(errorMsg);
1312 throw new ToscaExportException(errorMsg);
1314 final Component toOriginComponent = getOriginRes.left().value();
1315 Optional<CapabilityDefinition> capOpt = toOriginComponent.getCapabilities().get(reqOpt.get().getCapability()).stream()
1316 .filter(c -> isCapabilityBelongToRelation(relationshipInfo, c)).findFirst();
1317 if (capOpt.isEmpty()) {
1318 capOpt = findCapability(relationshipInfo, toOriginComponent, fromOriginComponent, reqOpt.get());
1319 if (capOpt.isEmpty()) {
1320 final String errorMsg = String
1321 .format("Failed to find a capability with name %s on a component with uniqueId %s",
1322 relationshipInfo.getCapability(), fromOriginComponent.getUniqueId());
1323 log.debug(errorMsg);
1324 throw new ToscaExportException(errorMsg);
1327 return buildRequirement(fromOriginComponent, toOriginComponent, capOpt.get(), reqOpt.get(),
1328 capabilityRequirementRelationship, toInstance, componentCache);
1331 private boolean isCapabilityBelongToRelation(RelationshipInfo reqAndRelationshipPair,
1332 CapabilityDefinition capability) {
1333 return capability.getName().equals(reqAndRelationshipPair.getCapability()) && (capability.getOwnerId() != null
1334 && capability.getOwnerId().equals(reqAndRelationshipPair.getCapabilityOwnerId()));
1337 private Optional<CapabilityDefinition> findCapability(RelationshipInfo reqAndRelationshipPair,
1338 Component toOriginComponent, Component fromOriginComponent,
1339 RequirementDefinition requirement) {
1340 Optional<CapabilityDefinition> cap = toOriginComponent.getCapabilities().get(requirement.getCapability())
1341 .stream().filter(c -> c.getType().equals(requirement.getCapability())).findFirst();
1342 if (!cap.isPresent()) {
1343 log.debug("Failed to find a capability with name {} on a component with uniqueId {}",
1344 reqAndRelationshipPair.getCapability(), fromOriginComponent.getUniqueId());
1349 private Map<String, ToscaTemplateRequirement> buildRequirement(final Component fromOriginComponent,
1350 final Component toOriginComponent,
1351 final CapabilityDefinition capability,
1352 final RequirementDefinition requirement,
1353 final CapabilityRequirementRelationship capabilityRequirementRelationship,
1354 final ComponentInstance toInstance,
1355 final Map<String, Component> componentCache)
1356 throws ToscaExportException {
1358 List<String> reducedPath = capability.getPath();
1359 if (capability.getOwnerId() != null) {
1360 reducedPath = capabilityRequirementConverter
1361 .getReducedPathByOwner(capability.getPath(), capability.getOwnerId());
1363 final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation();
1364 final Either<String, Boolean> capabilityNameEither = capabilityRequirementConverter.buildSubstitutedName(componentCache,
1365 toOriginComponent, reducedPath, relationshipInfo.getCapability(), capability.getPreviousName());
1366 if (capabilityNameEither.isRight()) {
1367 final String errorMsg = String.format(
1368 "Failed to build a substituted capability name for the capability with name %s on a component with uniqueId %s",
1369 capabilityRequirementRelationship.getCapability(), toOriginComponent.getUniqueId());
1372 throw new ToscaExportException(errorMsg);
1374 final Either<String, Boolean> requirementNameEither = capabilityRequirementConverter
1375 .buildSubstitutedName(componentCache, fromOriginComponent,
1376 requirement.getPath(), relationshipInfo.getRequirement(), requirement.getPreviousName());
1377 if (requirementNameEither.isRight()) {
1378 final String errorMsg = String.format("Failed to build a substituted requirement name for the requirement "
1379 + "with name %s on a component with uniqueId %s",
1380 capabilityRequirementRelationship.getRequirement(), fromOriginComponent.getUniqueId());
1381 log.debug(errorMsg);
1382 throw new ToscaExportException(errorMsg);
1384 final ToscaTemplateRequirement toscaRequirement = new ToscaTemplateRequirement();
1385 final Map<String, ToscaTemplateRequirement> toscaReqMap = new HashMap<>();
1386 toscaRequirement.setNode(toInstance.getName());
1387 toscaRequirement.setCapability(capabilityNameEither.left().value());
1388 if (isNotEmpty(capabilityRequirementRelationship.getOperations())) {
1389 toscaRequirement.setRelationship(new ToscaRelationshipBuilder().from(capabilityRequirementRelationship));
1391 toscaReqMap.put(requirementNameEither.left().value(), toscaRequirement);
1395 private Optional<RequirementDefinition> findRequirement(Component fromOriginComponent,
1396 Map<String, List<RequirementDefinition>> reqMap,
1397 RelationshipInfo reqAndRelationshipPair,
1398 String fromInstanceId) {
1399 for (List<RequirementDefinition> reqList : reqMap.values()) {
1400 Optional<RequirementDefinition> reqOpt = reqList.stream().filter(
1401 r -> isRequirementBelongToRelation(fromOriginComponent, reqAndRelationshipPair, r, fromInstanceId))
1403 if (reqOpt.isPresent()) {
1407 return Optional.empty();
1411 * Allows detecting the requirement belonging to the received relationship The detection logic is: A requirement belongs to a relationship IF
1412 * 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
1413 * requirement equals to requirementOwnerId of the relation OR uniqueId of toInstance equals to capabilityOwnerId of the relation
1415 private boolean isRequirementBelongToRelation(Component originComponent, RelationshipInfo reqAndRelationshipPair,
1416 RequirementDefinition requirement, String fromInstanceId) {
1417 if (!StringUtils.equals(requirement.getName(), reqAndRelationshipPair.getRequirement())) {
1418 log.debug("Failed to find a requirement with name {} and reqAndRelationshipPair {}", requirement.getName(),
1419 reqAndRelationshipPair.getRequirement());
1422 return ModelConverter.isAtomicComponent(originComponent) || isRequirementBelongToOwner(reqAndRelationshipPair, requirement, fromInstanceId,
1426 private boolean isRequirementBelongToOwner(RelationshipInfo reqAndRelationshipPair, RequirementDefinition requirement, String fromInstanceId,
1427 Component originComponent) {
1428 return StringUtils.equals(requirement.getOwnerId(), reqAndRelationshipPair.getRequirementOwnerId()) || (
1429 isCvfc(originComponent) && StringUtils.equals(fromInstanceId, reqAndRelationshipPair.getRequirementOwnerId()) || StringUtils
1430 .equals(requirement.getOwnerId(), originComponent.getUniqueId()));
1433 private boolean isCvfc(Component component) {
1434 return component.getComponentType() == ComponentTypeEnum.RESOURCE && ((Resource) component).getResourceType() == ResourceTypeEnum.CVFC;
1437 private Either<SubstitutionMapping, ToscaError> convertCapabilities(Component component, SubstitutionMapping substitutionMappings,
1438 Map<String, Component> componentCache) {
1439 Either<SubstitutionMapping, ToscaError> result = Either.left(substitutionMappings);
1440 Either<Map<String, String[]>, ToscaError> toscaCapabilitiesRes = capabilityRequirementConverter
1441 .convertSubstitutionMappingCapabilities(componentCache, component);
1442 if (toscaCapabilitiesRes.isRight()) {
1443 result = Either.right(toscaCapabilitiesRes.right().value());
1444 log.debug("Failed convert capabilities for the component {}. ", component.getName());
1445 } else if (isNotEmpty(toscaCapabilitiesRes.left().value())) {
1446 substitutionMappings.setCapabilities(toscaCapabilitiesRes.left().value());
1447 log.debug("Finish convert capabilities for the component {}. ", component.getName());
1449 log.debug("Finished to convert capabilities for the component {}. ", component.getName());
1453 private Either<ToscaNodeType, ToscaError> convertCapabilities(Map<String, Component> componentsCache, Component component, ToscaNodeType nodeType,
1454 Map<String, DataTypeDefinition> dataTypes) {
1455 Map<String, ToscaCapability> toscaCapabilities = capabilityRequirementConverter.convertCapabilities(componentsCache, component, dataTypes);
1456 if (!toscaCapabilities.isEmpty()) {
1457 nodeType.setCapabilities(toscaCapabilities);
1459 log.debug("Finish convert Capabilities for node type");
1460 return Either.left(nodeType);
1463 private Map<String, ToscaTemplateArtifact> convertToNodeTemplateArtifacts(Map<String, ToscaArtifactDataDefinition> artifacts) {
1464 if (artifacts == null) {
1467 Map<String, ToscaTemplateArtifact> arts = new HashMap<>();
1468 for (Map.Entry<String, ToscaArtifactDataDefinition> entry : artifacts.entrySet()) {
1469 ToscaTemplateArtifact artifact = new ToscaTemplateArtifact();
1470 artifact.setFile(entry.getValue().getFile());
1471 artifact.setType(entry.getValue().getType());
1472 arts.put(entry.getKey(), artifact);
1477 private NodeFilter convertToNodeTemplateNodeFilterComponent(CINodeFilterDataDefinition inNodeFilter) {
1478 if (inNodeFilter == null) {
1481 NodeFilter nodeFilter = new NodeFilter();
1482 ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities = inNodeFilter.getCapabilities();
1483 ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> origProperties = inNodeFilter.getProperties();
1484 List<Map<String, CapabilityFilter>> capabilitiesCopy = new ArrayList<>();
1485 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1486 copyNodeFilterCapabilitiesTemplate(origCapabilities, capabilitiesCopy);
1487 copyNodeFilterProperties(origProperties, propertiesCopy);
1488 if (CollectionUtils.isNotEmpty(capabilitiesCopy)) {
1489 nodeFilter.setCapabilities(capabilitiesCopy);
1491 if (CollectionUtils.isNotEmpty(propertiesCopy)) {
1492 nodeFilter.setProperties(propertiesCopy);
1494 nodeFilter.setTosca_id(cloneToscaId(inNodeFilter.getTosca_id()));
1495 nodeFilter = (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
1499 private NodeFilter convertToSubstitutionFilterComponent(final SubstitutionFilterDataDefinition substitutionFilterDataDefinition) {
1500 if (substitutionFilterDataDefinition == null) {
1503 NodeFilter nodeFilter = new NodeFilter();
1504 ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> origProperties = substitutionFilterDataDefinition.getProperties();
1505 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1506 copySubstitutionFilterProperties(origProperties, propertiesCopy);
1507 if (CollectionUtils.isNotEmpty(propertiesCopy)) {
1508 nodeFilter.setProperties(propertiesCopy);
1510 nodeFilter.setTosca_id(cloneToscaId(substitutionFilterDataDefinition.getTosca_id()));
1511 return (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
1514 private Object cloneToscaId(Object toscaId) {
1515 return Objects.isNull(toscaId) ? null : cloneObjectFromYml(toscaId, toscaId.getClass());
1518 private Object cloneObjectFromYml(Object objToClone, Class classOfObj) {
1519 String objectAsYml = yamlUtil.objectToYaml(objToClone);
1520 return yamlUtil.yamlToObject(objectAsYml, classOfObj);
1523 private void copyNodeFilterCapabilitiesTemplate(ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities,
1524 List<Map<String, CapabilityFilter>> capabilitiesCopy) {
1525 if (origCapabilities == null || origCapabilities.getListToscaDataDefinition() == null || origCapabilities.getListToscaDataDefinition()
1529 for (RequirementNodeFilterCapabilityDataDefinition capability : origCapabilities.getListToscaDataDefinition()) {
1530 Map<String, CapabilityFilter> capabilityFilterCopyMap = new HashMap<>();
1531 CapabilityFilter capabilityFilter = new CapabilityFilter();
1532 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1533 copyNodeFilterProperties(capability.getProperties(), propertiesCopy);
1534 capabilityFilter.setProperties(propertiesCopy);
1535 capabilityFilterCopyMap.put(capability.getName(), capabilityFilter);
1536 capabilitiesCopy.add(capabilityFilterCopyMap);
1540 private void copyNodeFilterProperties(ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> origProperties,
1541 List<Map<String, List<Object>>> propertiesCopy) {
1542 if (origProperties == null || origProperties.getListToscaDataDefinition() == null || origProperties.isEmpty()) {
1545 Map<String, List<Object>> propertyMapCopy = new HashMap<>();
1546 for (RequirementNodeFilterPropertyDataDefinition propertyDataDefinition : origProperties.getListToscaDataDefinition()) {
1547 for (String propertyInfoEntry : propertyDataDefinition.getConstraints()) {
1548 Map<String, List<Object>> propertyValObj = new YamlUtil().yamlToObject(propertyInfoEntry, Map.class);
1549 String propertyName = propertyDataDefinition.getName();
1550 if (propertyMapCopy.containsKey(propertyName)) {
1551 addPropertyConstraintValueToList(propertyName, propertyValObj, propertyMapCopy.get(propertyName));
1553 if (propertyName != null) {
1554 List<Object> propsList = new ArrayList<>();
1555 addPropertyConstraintValueToList(propertyName, propertyValObj, propsList);
1556 propertyMapCopy.put(propertyName, propsList);
1558 propertyMapCopy.putAll(propertyValObj);
1563 propertyMapCopy.entrySet().stream().forEach(entry -> addCalculatedConstraintsIntoPropertiesList(propertiesCopy, entry));
1566 private void copySubstitutionFilterProperties(final ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> origProperties,
1567 final List<Map<String, List<Object>>> propertiesCopy) {
1568 if (origProperties == null || origProperties.getListToscaDataDefinition() == null || origProperties.isEmpty()) {
1571 final Map<String, List<Object>> propertyMapCopy = new HashMap<>();
1572 for (final RequirementSubstitutionFilterPropertyDataDefinition propertyDataDefinition : origProperties.getListToscaDataDefinition()) {
1573 for (final String propertyInfoEntry : propertyDataDefinition.getConstraints()) {
1574 final Map<String, List<Object>> propertyValObj = new YamlUtil().yamlToObject(propertyInfoEntry, Map.class);
1575 final String propertyName = propertyDataDefinition.getName();
1576 if (propertyMapCopy.containsKey(propertyName)) {
1577 addPropertyConstraintValueToList(propertyName, propertyValObj, propertyMapCopy.get(propertyName));
1579 if (propertyName != null) {
1580 final List<Object> propsList = new ArrayList<>();
1581 addPropertyConstraintValueToList(propertyName, propertyValObj, propsList);
1582 propertyMapCopy.put(propertyName, propsList);
1584 propertyMapCopy.putAll(propertyValObj);
1589 propertyMapCopy.entrySet().forEach(entry -> addCalculatedConstraintsIntoPropertiesList(propertiesCopy, entry));
1592 private void addPropertyConstraintValueToList(String propertyName, Map<String, List<Object>> propertyValObj, List<Object> propsList) {
1593 if (propertyValObj.containsKey(propertyName)) {
1594 propsList.add(propertyValObj.get(propertyName));
1596 propsList.add(propertyValObj);
1600 private void addCalculatedConstraintsIntoPropertiesList(List<Map<String, List<Object>>> propertiesCopy, Entry<String, List<Object>> entry) {
1601 Map<String, List<Object>> tempMap = new HashMap<>();
1602 tempMap.put(entry.getKey(), entry.getValue());
1603 propertiesCopy.add(tempMap);
1606 private Map<String, String[]> buildSubstitutionMappingPropertyMapping(final Component component) {
1607 if (component == null || CollectionUtils.isEmpty(component.getInputs())) {
1608 return Collections.emptyMap();
1610 return component.getInputs().stream().filter(InputDefinition::isMappedToComponentProperty).map(PropertyDataDefinition::getName)
1611 .collect(Collectors.toMap(inputName -> inputName, inputName -> new String[]{inputName}, (inputName1, inputName2) -> inputName1));
1614 private Map<String, String[]> buildSubstitutionMappingAttributesMapping(final Component component) {
1615 if (component == null || CollectionUtils.isEmpty(component.getOutputs())) {
1616 return Collections.emptyMap();
1618 return component.getOutputs().stream().map(AttributeDataDefinition::getName)
1619 .collect(Collectors.toMap(outputName -> outputName, outputName -> new String[]{outputName}, (outputName1, outputName2) -> outputName1));
1622 Optional<Map<String, ToscaProperty>> getProxyNodeTypeProperties(Component proxyComponent, Map<String, DataTypeDefinition> dataTypes) {
1623 if (Objects.isNull(proxyComponent)) {
1624 return Optional.empty();
1626 Map<String, ToscaProperty> proxyProperties = new HashMap<>();
1627 addInputsToProperties(dataTypes, proxyComponent.getInputs(), proxyProperties);
1628 if (CollectionUtils.isNotEmpty(proxyComponent.getProperties())) {
1629 proxyProperties.putAll(proxyComponent.getProperties().stream()
1630 .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, proxyComponent.getInputs())).collect(Collectors
1631 .toMap(PropertyDataDefinition::getName,
1632 property -> propertyConvertor.convertProperty(dataTypes, property, PropertyConvertor.PropertyType.PROPERTY))));
1634 return MapUtils.isNotEmpty(proxyProperties) ? Optional.of(proxyProperties) : Optional.empty();
1637 void addInputsToProperties(Map<String, DataTypeDefinition> dataTypes, List<InputDefinition> componentInputs,
1638 Map<String, ToscaProperty> mergedProperties) {
1639 if (CollectionUtils.isEmpty(componentInputs)) {
1642 for (InputDefinition input : componentInputs) {
1643 ToscaProperty property = propertyConvertor.convertProperty(dataTypes, input, PropertyConvertor.PropertyType.INPUT);
1644 mergedProperties.put(input.getName(), property);
1648 Optional<Map<String, Object>> getProxyNodeTypeInterfaces(Component proxyComponent, Map<String, DataTypeDefinition> dataTypes) {
1649 if (Objects.isNull(proxyComponent) || MapUtils.isEmpty(proxyComponent.getInterfaces())) {
1650 return Optional.empty();
1652 Map<String, InterfaceDefinition> proxyComponentInterfaces = proxyComponent.getInterfaces();
1653 //Unset artifact path for operation implementation for proxy node types as for operations with artifacts it is
1655 // always available in the proxy node template
1656 removeOperationImplementationForProxyNodeType(proxyComponentInterfaces);
1658 .ofNullable(interfacesOperationsConverter.getInterfacesMap(proxyComponent, null, proxyComponentInterfaces, dataTypes, false, false));
1661 private static class CustomRepresenter extends Representer {
1663 CustomRepresenter() {
1665 this.representers.put(ToscaPropertyAssignment.class, new RepresentToscaPropertyAssignment());
1666 this.representers.put(ToscaAttribute.class, new RepresentToscaAttribute());
1667 // null representer is exceptional and it is stored as an instance
1670 this.nullRepresenter = new RepresentNull();
1673 public boolean validateGetInputValue(final Object valueObj) {
1674 if (!(valueObj instanceof List) && !(valueObj instanceof String)) {
1677 if (valueObj instanceof List) {
1678 return ((List) valueObj).size() > 1;
1683 public boolean validateGetPropertyOrAttributeValue(final Object valueObj) {
1684 if (valueObj instanceof List) {
1685 return ((List) valueObj).size() > 1;
1691 protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue, Tag customTag) {
1692 if (propertyValue == null) {
1695 // skip not relevant for Tosca property
1696 if ("dependencies".equals(property.getName())) {
1699 if (javaBean instanceof ToscaRelationshipTemplate && "name".equals(property.getName())) {
1702 removeDefaultP(propertyValue);
1703 NodeTuple defaultNode = super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
1704 if (javaBean instanceof ToscaTopolgyTemplate && "relationshipTemplates".equals(property.getName())) {
1705 return new NodeTuple(representData("relationship_templates"), defaultNode.getValueNode());
1707 return "_defaultp_".equals(property.getName()) ? new NodeTuple(representData("default"), defaultNode.getValueNode()) : defaultNode;
1710 private void removeDefaultP(final Object propertyValue) {
1711 if (propertyValue instanceof Map) {
1712 final Map mapPropertyValue = ((Map) propertyValue);
1713 final Iterator<Entry> iter = mapPropertyValue.entrySet().iterator();
1714 Object defaultValue = null;
1715 while (iter.hasNext()) {
1716 final Map.Entry entry = iter.next();
1717 if ("_defaultp_".equals(entry.getKey())) {
1718 defaultValue = entry.getValue();
1720 } else if (entry.getValue() instanceof Map) {
1721 removeDefaultP(entry.getValue());
1724 if (defaultValue != null) {
1725 mapPropertyValue.putIfAbsent("default", defaultValue);
1731 protected MappingNode representJavaBean(Set<Property> properties, Object javaBean) {
1732 // remove the bean type from the output yaml (!! ...)
1733 if (!classTags.containsKey(javaBean.getClass())) {
1734 addClassTag(javaBean.getClass(), Tag.MAP);
1736 return super.representJavaBean(properties, javaBean);
1739 private class RepresentToscaAttribute implements Represent {
1742 public Node representData(Object data) {
1743 final ToscaAttribute toscaAttribute = (ToscaAttribute) data;
1744 return represent(toscaAttribute.asToscaMap());
1748 private class RepresentToscaPropertyAssignment implements Represent {
1750 public Node representData(Object data) {
1751 final ToscaPropertyAssignment toscaOperationAssignment = (ToscaPropertyAssignment) data;
1752 if (toscaOperationAssignment.getValue() instanceof String) {
1753 final String stringValue = (String) toscaOperationAssignment.getValue();
1754 if (isPropertyOrAttributeFunction(stringValue)) {
1755 return representGetAttribute(stringValue);
1757 return representScalar(Tag.STR, stringValue);
1759 return represent(null);
1762 public Node representGetAttribute(final String getAttributeFunction) {
1763 return represent(new Yaml().load(getAttributeFunction));
1766 public boolean isPropertyOrAttributeFunction(final String value) {
1768 final Yaml yaml = new Yaml();
1769 final Object yamlObj = yaml.load(value);
1770 if (!(yamlObj instanceof Map)) {
1773 final Map<String, Object> getAttributeMap = (Map) yamlObj;
1774 if (getAttributeMap.size() != 1) {
1777 final List<String> functionList = Arrays
1778 .asList(GET_ATTRIBUTE.getFunctionName(), GET_INPUT.getFunctionName(), GET_PROPERTY.getFunctionName());
1779 final Optional<String> function = getAttributeMap.keySet().stream()
1780 .filter(key -> functionList.stream().anyMatch(function1 -> function1.equals(key))).findFirst();
1781 if (function.isEmpty()) {
1784 final String functionName = function.get();
1785 final Object getAttributeValueObj = getAttributeMap.get(functionName);
1786 if (GET_INPUT.getFunctionName().equals(functionName)) {
1787 return validateGetInputValue(getAttributeValueObj);
1789 return validateGetPropertyOrAttributeValue(getAttributeValueObj);
1791 } catch (final Exception ignored) {
1797 private class RepresentNull implements Represent {
1800 public Node representData(Object data) {
1801 // possible values are here http://yaml.org/type/null.html
1802 return representScalar(Tag.NULL, "");
1807 private static class UnsortedPropertyUtils extends PropertyUtils {
1810 protected Set<Property> createPropertySet(Class type, BeanAccess bAccess) {
1811 Collection<Property> fields = getPropertiesMap(type, BeanAccess.FIELD).values();
1812 return new LinkedHashSet<>(fields);
1816 private Configuration getConfiguration() {
1817 return ConfigurationManager.getConfigurationManager().getConfiguration();