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=========================================================
21 package org.openecomp.sdc.be.tosca;
23 import static org.openecomp.sdc.be.tosca.utils.InterfacesOperationsToscaUtil.addInterfaceDefinitionElement;
24 import static org.openecomp.sdc.be.tosca.utils.InterfacesOperationsToscaUtil.addInterfaceTypeElement;
26 import fj.data.Either;
27 import java.beans.IntrospectionException;
28 import java.util.ArrayList;
29 import java.util.Collection;
30 import java.util.HashMap;
31 import java.util.LinkedHashSet;
32 import java.util.List;
34 import java.util.Map.Entry;
35 import java.util.Optional;
37 import java.util.function.Supplier;
38 import java.util.stream.Collectors;
39 import org.apache.commons.collections.CollectionUtils;
40 import org.apache.commons.collections.MapUtils;
41 import org.apache.commons.lang.StringUtils;
42 import org.apache.commons.lang3.tuple.ImmutablePair;
43 import org.apache.commons.lang3.tuple.ImmutableTriple;
44 import org.apache.commons.lang3.tuple.Triple;
45 import org.openecomp.sdc.be.config.ConfigurationManager;
46 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
47 import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
48 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
49 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
50 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
51 import org.openecomp.sdc.be.model.ArtifactDefinition;
52 import org.openecomp.sdc.be.model.CapabilityDefinition;
53 import org.openecomp.sdc.be.model.Component;
54 import org.openecomp.sdc.be.model.ComponentInstance;
55 import org.openecomp.sdc.be.model.ComponentInstanceInput;
56 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
57 import org.openecomp.sdc.be.model.ComponentParametersView;
58 import org.openecomp.sdc.be.model.DataTypeDefinition;
59 import org.openecomp.sdc.be.model.GroupDefinition;
60 import org.openecomp.sdc.be.model.GroupInstance;
61 import org.openecomp.sdc.be.model.GroupProperty;
62 import org.openecomp.sdc.be.model.InputDefinition;
63 import org.openecomp.sdc.be.model.PropertyDefinition;
64 import org.openecomp.sdc.be.model.RelationshipInfo;
65 import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
66 import org.openecomp.sdc.be.model.RequirementDefinition;
67 import org.openecomp.sdc.be.model.Resource;
68 import org.openecomp.sdc.be.model.Service;
69 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
70 import org.openecomp.sdc.be.model.category.CategoryDefinition;
71 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
72 import org.openecomp.sdc.be.model.jsontitan.utils.ModelConverter;
73 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
74 import org.openecomp.sdc.be.model.tosca.converters.ToscaValueBaseConverter;
75 import org.openecomp.sdc.be.tosca.model.IToscaMetadata;
76 import org.openecomp.sdc.be.tosca.model.SubstitutionMapping;
77 import org.openecomp.sdc.be.tosca.model.ToscaCapability;
78 import org.openecomp.sdc.be.tosca.model.ToscaGroupTemplate;
79 import org.openecomp.sdc.be.tosca.model.ToscaMetadata;
80 import org.openecomp.sdc.be.tosca.model.ToscaNodeTemplate;
81 import org.openecomp.sdc.be.tosca.model.ToscaNodeType;
82 import org.openecomp.sdc.be.tosca.model.ToscaProperty;
83 import org.openecomp.sdc.be.tosca.model.ToscaTemplate;
84 import org.openecomp.sdc.be.tosca.model.ToscaTemplateRequirement;
85 import org.openecomp.sdc.be.tosca.model.ToscaTopolgyTemplate;
86 import org.openecomp.sdc.be.tosca.model.VfModuleToscaMetadata;
87 import org.openecomp.sdc.be.tosca.utils.ForwardingPathToscaUtil;
88 import org.openecomp.sdc.common.api.Constants;
89 import org.slf4j.Logger;
90 import org.slf4j.LoggerFactory;
91 import org.springframework.beans.factory.annotation.Autowired;
92 import org.yaml.snakeyaml.DumperOptions;
93 import org.yaml.snakeyaml.DumperOptions.FlowStyle;
94 import org.yaml.snakeyaml.Yaml;
95 import org.yaml.snakeyaml.introspector.BeanAccess;
96 import org.yaml.snakeyaml.introspector.Property;
97 import org.yaml.snakeyaml.introspector.PropertyUtils;
98 import org.yaml.snakeyaml.nodes.MappingNode;
99 import org.yaml.snakeyaml.nodes.Node;
100 import org.yaml.snakeyaml.nodes.NodeTuple;
101 import org.yaml.snakeyaml.nodes.Tag;
102 import org.yaml.snakeyaml.representer.Represent;
103 import org.yaml.snakeyaml.representer.Representer;
105 @org.springframework.stereotype.Component("tosca-export-handler")
106 public class ToscaExportHandler {
109 private ApplicationDataTypeCache dataTypeCache;
112 private ToscaOperationFacade toscaOperationFacade;
114 private CapabiltyRequirementConvertor capabiltyRequirementConvertor;
115 private PropertyConvertor propertyConvertor = PropertyConvertor.getInstance();
117 private static final Logger log = LoggerFactory.getLogger(ToscaExportHandler.class);
119 public static final String TOSCA_VERSION = "tosca_simple_yaml_1_1";
120 private static final String SERVICE_NODE_TYPE_PREFIX = "org.openecomp.service.";
121 private static final String IMPORTS_FILE_KEY = "file";
122 public static final String TOSCA_TEMPLATE_NAME = "-template.yml";
123 private static final String TOSCA_INTERFACE_NAME = "-interface.yml";
124 static final String ASSET_TOSCA_TEMPLATE = "assettoscatemplate";
125 private static final String VF_MODULE_TYPE_KEY = "vf_module_type";
126 private static final String VF_MODULE_DESC_KEY = "vf_module_description";
127 public static final String VOLUME_GROUP_KEY = "volume_group";
128 private static final String VF_MODULE_TYPE_BASE = "Base";
129 private static final String VF_MODULE_TYPE_EXPANSION = "Expansion";
130 private static final String FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION =
131 "convertToToscaTemplate - failed to get Default Imports section from configuration";
132 private static final String NOT_SUPPORTED_COMPONENT_TYPE = "Not supported component type {}";
133 protected static final List<Map<String, Map<String, String>>> DEFAULT_IMPORTS =
134 ConfigurationManager.getConfigurationManager().getConfiguration().getDefaultImports();
136 public Either<ToscaRepresentation, ToscaError> exportComponent(Component component) {
138 Either<ToscaTemplate, ToscaError> toscaTemplateRes = convertToToscaTemplate(component);
139 if (toscaTemplateRes.isRight()) {
140 return Either.right(toscaTemplateRes.right().value());
143 ToscaTemplate toscaTemplate = toscaTemplateRes.left().value();
144 ToscaRepresentation toscaRepresentation = this.createToscaRepresentation(toscaTemplate);
145 return Either.left(toscaRepresentation);
148 public Either<ToscaRepresentation, ToscaError> exportComponentInterface(Component component) {
149 if (null == DEFAULT_IMPORTS) {
150 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
151 return Either.right(ToscaError.GENERAL_ERROR);
154 ToscaTemplate toscaTemplate = new ToscaTemplate(TOSCA_VERSION);
155 toscaTemplate.setImports(new ArrayList<>(DEFAULT_IMPORTS));
156 Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
157 Either<ToscaTemplate, ToscaError> toscaTemplateRes =
158 convertInterfaceNodeType(component, toscaTemplate, nodeTypes);
159 if (toscaTemplateRes.isRight()) {
160 return Either.right(toscaTemplateRes.right().value());
163 toscaTemplate = toscaTemplateRes.left().value();
164 ToscaRepresentation toscaRepresentation = this.createToscaRepresentation(toscaTemplate);
165 return Either.left(toscaRepresentation);
168 public ToscaRepresentation createToscaRepresentation(ToscaTemplate toscaTemplate) {
169 CustomRepresenter representer = new CustomRepresenter();
170 DumperOptions options = new DumperOptions();
171 options.setAllowReadOnlyProperties(false);
172 options.setPrettyFlow(true);
174 options.setDefaultFlowStyle(FlowStyle.FLOW);
175 options.setCanonical(false);
177 representer.addClassTag(toscaTemplate.getClass(), Tag.MAP);
179 representer.setPropertyUtils(new UnsortedPropertyUtils());
180 Yaml yaml = new Yaml(representer, options);
182 String yamlAsString = yaml.dumpAsMap(toscaTemplate);
184 StringBuilder sb = new StringBuilder();
185 sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactHeader());
186 sb.append(yamlAsString);
187 sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactFooter());
189 ToscaRepresentation toscaRepresentation = new ToscaRepresentation();
190 toscaRepresentation.setMainYaml(sb.toString());
191 toscaRepresentation.setDependencies(toscaTemplate.getDependencies());
193 return toscaRepresentation;
196 public Either<ToscaTemplate, ToscaError> getDependencies(Component component) {
197 ToscaTemplate toscaTemplate = new ToscaTemplate(null);
198 Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports =
199 fillImports(component, toscaTemplate);
200 if (fillImports.isRight()) {
201 return Either.right(fillImports.right().value());
203 return Either.left(fillImports.left().value().left);
206 private Either<ToscaTemplate, ToscaError> convertToToscaTemplate(Component component) {
207 if (null == DEFAULT_IMPORTS) {
208 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
209 return Either.right(ToscaError.GENERAL_ERROR);
212 log.trace("start tosca export for {}", component.getUniqueId());
213 ToscaTemplate toscaTemplate = new ToscaTemplate(TOSCA_VERSION);
215 toscaTemplate.setMetadata(convertMetadata(component));
216 toscaTemplate.setImports(new ArrayList<>(DEFAULT_IMPORTS));
217 Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
218 if (ModelConverter.isAtomicComponent(component)) {
219 log.trace("convert component as node type");
220 return convertNodeType(component, toscaTemplate, nodeTypes);
222 log.trace("convert component as topology template");
223 return convertToscaTemplate(component, toscaTemplate);
228 private Either<ToscaTemplate, ToscaError> convertToscaTemplate(Component component, ToscaTemplate toscaNode) {
230 Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> importsRes =
231 fillImports(component, toscaNode);
232 if (importsRes.isRight()) {
233 return Either.right(importsRes.right().value());
235 toscaNode = importsRes.left().value().left;
236 Map<String, Component> componentCache = importsRes.left().value().right;
237 Either<Map<String, ToscaNodeType>, ToscaError> nodeTypesMapEither =
238 createProxyNodeTypes(componentCache, component);
239 if (nodeTypesMapEither.isRight()) {
240 log.debug("Failed to fetch normative service proxy resource by tosca name, error {}",
241 nodeTypesMapEither.right().value());
242 return Either.right(nodeTypesMapEither.right().value());
244 Map<String, ToscaNodeType> nodeTypesMap = nodeTypesMapEither.left().value();
245 if (nodeTypesMap != null && !nodeTypesMap.isEmpty()) {
246 toscaNode.setNode_types(nodeTypesMap);
250 Either<Map<String, DataTypeDefinition>, TitanOperationStatus> dataTypesEither = dataTypeCache.getAll();
251 if (dataTypesEither.isRight()) {
252 log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
253 return Either.right(ToscaError.GENERAL_ERROR);
255 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
257 ToscaTopolgyTemplate topologyTemplate = new ToscaTopolgyTemplate();
259 Either<ToscaTopolgyTemplate, ToscaError> inputs = fillInputs(component, topologyTemplate, dataTypes);
260 if (inputs.isRight()) {
261 return Either.right(inputs.right().value());
263 topologyTemplate = inputs.left().value();
265 List<ComponentInstance> componentInstances = component.getComponentInstances();
266 Map<String, List<ComponentInstanceProperty>> componentInstancesProperties =
267 component.getComponentInstancesProperties();
268 List<GroupDefinition> groups = component.getGroups();
269 if (componentInstances != null && !componentInstances.isEmpty()) {
271 Either<Map<String, ToscaNodeTemplate>, ToscaError> nodeTemplates =
272 convertNodeTemplates(component, componentInstances, componentInstancesProperties, componentCache,
273 dataTypes, topologyTemplate);
274 if (nodeTemplates.isRight()) {
275 return Either.right(nodeTemplates.right().value());
277 log.debug("node templates converted");
279 topologyTemplate.setNode_templates(nodeTemplates.left().value());
281 Map<String, ToscaGroupTemplate> groupsMap;
282 if (groups != null && !groups.isEmpty()) {
283 groupsMap = new HashMap<>();
284 for (GroupDefinition group : groups) {
285 boolean addToTosca = true;
286 if (group.getType().equals(Constants.DEFAULT_GROUP_VF_MODULE)) {
287 List<String> artifacts = group.getArtifacts();
288 if (artifacts == null || artifacts.isEmpty()) {
293 ToscaGroupTemplate toscaGroup = convertGroup(group);
294 groupsMap.put(group.getName(), toscaGroup);
298 log.debug("groups converted");
299 topologyTemplate.addGroups(groupsMap);
301 SubstitutionMapping substitutionMapping = new SubstitutionMapping();
302 String toscaResourceName;
303 switch (component.getComponentType()) {
305 toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition()
306 .getMetadataDataDefinition())
307 .getToscaResourceName();
310 toscaResourceName = SERVICE_NODE_TYPE_PREFIX + component.getComponentMetadataDefinition()
311 .getMetadataDataDefinition().getSystemName();
314 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
315 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
317 substitutionMapping.setNode_type(toscaResourceName);
319 Either<SubstitutionMapping, ToscaError> capabilities =
320 convertCapabilities(component, substitutionMapping, componentCache);
321 if (capabilities.isRight()) {
322 return Either.right(capabilities.right().value());
324 substitutionMapping = capabilities.left().value();
326 Either<SubstitutionMapping, ToscaError> requirements = capabiltyRequirementConvertor
327 .convertSubstitutionMappingRequirements(
328 componentCache, component,
329 substitutionMapping);
330 if (requirements.isRight()) {
331 return Either.right(requirements.right().value());
333 substitutionMapping = requirements.left().value();
335 topologyTemplate.setSubstitution_mappings(substitutionMapping);
337 toscaNode.setTopology_template(topologyTemplate);
338 return Either.left(toscaNode);
341 private Either<ToscaTopolgyTemplate, ToscaError> fillInputs(Component component,
342 ToscaTopolgyTemplate topologyTemplate, Map<String, DataTypeDefinition> dataTypes) {
343 if (log.isDebugEnabled()) {
344 log.debug("fillInputs for component {}", component.getUniqueId());
346 List<InputDefinition> inputDef = component.getInputs();
347 Map<String, ToscaProperty> inputs = new HashMap<>();
349 if (inputDef != null) {
350 inputDef.forEach(i -> {
351 ToscaProperty property = propertyConvertor.convertProperty(dataTypes, i, false);
352 inputs.put(i.getName(), property);
354 if (!inputs.isEmpty()) {
355 topologyTemplate.setInputs(inputs);
358 return Either.left(topologyTemplate);
361 private ToscaMetadata convertMetadata(Component component) {
362 return convertMetadata(component, false, null);
365 private ToscaMetadata convertMetadata(Component component, boolean isInstance,
366 ComponentInstance componentInstance) {
367 ToscaMetadata toscaMetadata = new ToscaMetadata();
368 toscaMetadata.setInvariantUUID(component.getInvariantUUID());
369 toscaMetadata.setUUID(component.getUUID());
370 toscaMetadata.setDescription(component.getDescription());
371 toscaMetadata.setName(component.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
373 List<CategoryDefinition> categories = component.getCategories();
374 CategoryDefinition categoryDefinition = categories.get(0);
375 toscaMetadata.setCategory(categoryDefinition.getName());
378 toscaMetadata.setVersion(component.getVersion());
379 toscaMetadata.setCustomizationUUID(componentInstance.getCustomizationUUID());
380 if (componentInstance.getSourceModelInvariant() != null && !componentInstance.getSourceModelInvariant()
382 toscaMetadata.setVersion(componentInstance.getComponentVersion());
383 toscaMetadata.setSourceModelInvariant(componentInstance.getSourceModelInvariant());
384 toscaMetadata.setSourceModelUuid(componentInstance.getSourceModelUuid());
385 toscaMetadata.setSourceModelName(componentInstance.getSourceModelName());
386 toscaMetadata.setName(
387 componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceProxy.getDisplayValue());
388 toscaMetadata.setDescription(componentInstance.getDescription());
392 switch (component.getComponentType()) {
394 Resource resource = (Resource) component;
396 if (isInstance && componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
397 toscaMetadata.setType(componentInstance.getOriginType().getDisplayValue());
399 toscaMetadata.setType(resource.getResourceType().name());
401 toscaMetadata.setSubcategory(categoryDefinition.getSubcategories().get(0).getName());
402 toscaMetadata.setResourceVendor(resource.getVendorName());
403 toscaMetadata.setResourceVendorRelease(resource.getVendorRelease());
404 toscaMetadata.setResourceVendorModelNumber(resource.getResourceVendorModelNumber());
407 Service service = (Service) component;
408 toscaMetadata.setType(component.getComponentType().getValue());
409 toscaMetadata.setServiceType(service.getServiceType());
410 toscaMetadata.setServiceRole(service.getServiceRole());
411 toscaMetadata.setEnvironmentContext(service.getEnvironmentContext());
414 toscaMetadata.setServiceEcompNaming(((Service) component).isEcompGeneratedNaming());
415 toscaMetadata.setEcompGeneratedNaming(((Service) component).isEcompGeneratedNaming());
416 toscaMetadata.setNamingPolicy(((Service) component).getNamingPolicy());
420 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
422 return toscaMetadata;
425 private Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports(Component component,
426 ToscaTemplate toscaTemplate) {
428 if (null == DEFAULT_IMPORTS) {
429 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
430 return Either.right(ToscaError.GENERAL_ERROR);
432 Map<String, Component> componentCache = new HashMap<>();
434 if (!ModelConverter.isAtomicComponent(component)) {
435 List<ComponentInstance> componentInstances = component.getComponentInstances();
436 if (componentInstances != null && !componentInstances.isEmpty()) {
438 List<Map<String, Map<String, String>>> additionalImports =
439 toscaTemplate.getImports() == null ? new ArrayList<>(DEFAULT_IMPORTS) :
440 new ArrayList<>(toscaTemplate.getImports());
442 List<Triple<String, String, Component>> dependecies = new ArrayList<>();
444 Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
445 ArtifactDefinition artifactDefinition = toscaArtifacts.get(ToscaExportHandler.ASSET_TOSCA_TEMPLATE);
447 Map<String, Map<String, String>> importsListMember = new HashMap<>();
448 Map<String, String> interfaceFiles = new HashMap<>();
449 interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactDefinition.getArtifactName()));
450 StringBuilder keyNameBuilder = new StringBuilder();
451 keyNameBuilder.append(component.getComponentType().toString().toLowerCase());
452 keyNameBuilder.append("-");
453 keyNameBuilder.append(component.getName());
454 keyNameBuilder.append("-interface");
455 importsListMember.put(keyNameBuilder.toString(), interfaceFiles);
456 additionalImports.add(importsListMember);
458 componentInstances.forEach(ci -> createDependency(componentCache, additionalImports, dependecies, ci));
459 toscaTemplate.setDependencies(dependecies);
460 toscaTemplate.setImports(additionalImports);
463 log.debug("currently imports supported for VF and service only");
465 return Either.left(new ImmutablePair<ToscaTemplate, Map<String, Component>>(toscaTemplate, componentCache));
468 private void createDependency(Map<String, Component> componentCache, List<Map<String, Map<String, String>>> imports,
469 List<Triple<String, String, Component>> dependecies, ComponentInstance ci) {
470 Map<String, String> files = new HashMap<>();
471 Map<String, Map<String, String>> importsListMember = new HashMap<>();
472 StringBuilder keyNameBuilder;
474 Component componentRI = componentCache.get(ci.getComponentUid());
475 if (componentRI == null) {
476 // all resource must be only once!
477 Either<Component, StorageOperationStatus> resource =
478 toscaOperationFacade.getToscaFullElement(ci.getComponentUid());
479 if ((resource.isRight()) && (log.isDebugEnabled())) {
480 log.debug("Failed to fetch resource with id {} for instance {}", ci.getComponentUid(),
485 Component fetchedComponent = resource.left().value();
486 componentCache.put(fetchedComponent.getUniqueId(), fetchedComponent);
488 if (ci.getOriginType() == OriginTypeEnum.ServiceProxy) {
489 Either<Component, StorageOperationStatus> sourceService =
490 toscaOperationFacade.getToscaFullElement(ci.getSourceModelUid());
491 if (sourceService.isRight() && (log.isDebugEnabled())) {
492 log.debug("Failed to fetch source service with id {} for proxy {}", ci.getSourceModelUid(),
495 Component fetchedSource = sourceService.left().value();
496 componentCache.put(fetchedSource.getUniqueId(), fetchedSource);
499 componentRI = fetchedComponent;
501 Map<String, ArtifactDefinition> toscaArtifacts = componentRI.getToscaArtifacts();
502 ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE);
503 if (artifactDefinition != null) {
504 String artifactName = artifactDefinition.getArtifactName();
505 files.put(IMPORTS_FILE_KEY, artifactName);
506 keyNameBuilder = new StringBuilder();
507 keyNameBuilder.append(fetchedComponent.getComponentType().toString().toLowerCase());
508 keyNameBuilder.append("-");
509 keyNameBuilder.append(ci.getComponentName());
510 importsListMember.put(keyNameBuilder.toString(), files);
511 imports.add(importsListMember);
513 .add(new ImmutableTriple<String, String, Component>(artifactName, artifactDefinition.getEsId(),
516 if (!ModelConverter.isAtomicComponent(componentRI)) {
517 importsListMember = new HashMap<>();
518 Map<String, String> interfaceFiles = new HashMap<>();
519 interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactName));
520 keyNameBuilder.append("-interface");
521 importsListMember.put(keyNameBuilder.toString(), interfaceFiles);
522 imports.add(importsListMember);
528 public static String getInterfaceFilename(String artifactName) {
529 return artifactName.substring(0, artifactName.lastIndexOf('.')) + ToscaExportHandler.TOSCA_INTERFACE_NAME;
532 private Either<ToscaTemplate, ToscaError> convertNodeType(Component component, ToscaTemplate toscaNode,
533 Map<String, ToscaNodeType> nodeTypes) {
534 log.debug("start convert node type for {}", component.getUniqueId());
535 ToscaNodeType toscaNodeType = createNodeType(component);
537 Either<Map<String, DataTypeDefinition>, TitanOperationStatus> dataTypesEither = dataTypeCache.getAll();
538 if (dataTypesEither.isRight()) {
539 log.debug("Failed to fetch all data types :", dataTypesEither.right().value());
540 return Either.right(ToscaError.GENERAL_ERROR);
543 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
544 Either<ToscaNodeType, ToscaError> properties =
545 propertyConvertor.convertProperties(component, toscaNodeType, dataTypes);
546 if (properties.isRight()) {
547 return Either.right(properties.right().value());
549 toscaNodeType = properties.left().value();
550 log.debug("Properties converted for {}", component.getUniqueId());
552 // Extracted to method for code reuse
553 return convertReqCapAndTypeName(component, toscaNode, nodeTypes, toscaNodeType, dataTypes);
556 private Either<ToscaTemplate, ToscaError> convertInterfaceNodeType(Component component, ToscaTemplate toscaNode,
557 Map<String, ToscaNodeType> nodeTypes) {
558 log.debug("start convert node type for {}", component.getUniqueId());
561 toscaNode.setInterface_types(addInterfaceTypeElement(component));
563 Either<Map<String, DataTypeDefinition>, TitanOperationStatus> dataTypesEither = dataTypeCache.getAll();
564 if (dataTypesEither.isRight()) {
565 log.debug("Failed to fetch all data types :", dataTypesEither.right().value());
566 return Either.right(ToscaError.GENERAL_ERROR);
569 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
571 List<InputDefinition> inputDef = component.getInputs();
572 Map<String, ToscaProperty> inputs = new HashMap<>();
573 ToscaNodeType toscaNodeType = createNodeType(component);
574 if (inputDef != null) {
575 inputDef.forEach(i -> {
576 ToscaProperty property = propertyConvertor.convertProperty(dataTypes, i, false);
577 inputs.put(i.getName(), property);
578 addInterfaceDefinitionElement(component, toscaNodeType);
580 if (!inputs.isEmpty()) {
581 toscaNodeType.setProperties(inputs);
587 // Extracted to method for code reuse
588 return convertReqCapAndTypeName(component, toscaNode, nodeTypes, toscaNodeType, dataTypes);
591 private Either<ToscaTemplate, ToscaError> convertReqCapAndTypeName(Component component, ToscaTemplate toscaNode,
592 Map<String, ToscaNodeType> nodeTypes, ToscaNodeType toscaNodeType,
593 Map<String, DataTypeDefinition> dataTypes) {
594 Either<ToscaNodeType, ToscaError> capabilities = convertCapabilities(component, toscaNodeType, dataTypes);
595 if (capabilities.isRight()) {
596 return Either.right(capabilities.right().value());
598 toscaNodeType = capabilities.left().value();
599 log.debug("Capabilities converted for {}", component.getUniqueId());
601 Either<ToscaNodeType, ToscaError> requirements =
602 capabiltyRequirementConvertor.convertRequirements(component, toscaNodeType);
603 if (requirements.isRight()) {
604 return Either.right(requirements.right().value());
606 toscaNodeType = requirements.left().value();
607 log.debug("Requirements converted for {}", component.getUniqueId());
609 String toscaResourceName;
610 switch (component.getComponentType()) {
612 toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition()
613 .getMetadataDataDefinition())
614 .getToscaResourceName();
617 toscaResourceName = SERVICE_NODE_TYPE_PREFIX + component.getComponentMetadataDefinition()
618 .getMetadataDataDefinition().getSystemName();
621 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
622 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
625 nodeTypes.put(toscaResourceName, toscaNodeType);
626 toscaNode.setNode_types(nodeTypes);
627 log.debug("finish convert node type for {}", component.getUniqueId());
628 return Either.left(toscaNode);
631 private Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplates(Component component,
632 List<ComponentInstance> componentInstances,
633 Map<String, List<ComponentInstanceProperty>> componentInstancesProperties,
634 Map<String, Component> componentCache, Map<String, DataTypeDefinition> dataTypes,
635 ToscaTopolgyTemplate topologyTemplate) {
637 Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplatesRes = null;
638 log.debug("start convert topology template for {} for type {}", component.getUniqueId(),
639 component.getComponentType());
640 Map<String, ToscaNodeTemplate> nodeTemplates = new HashMap<>();
641 Map<String, List<ComponentInstanceInput>> componentInstancesInputs = component.getComponentInstancesInputs();
643 Map<String, ToscaGroupTemplate> groupsMap = null;
644 for (ComponentInstance componentInstance : componentInstances) {
645 ToscaNodeTemplate nodeTemplate = new ToscaNodeTemplate();
646 nodeTemplate.setType(componentInstance.getToscaComponentName());
648 Either<Component, Boolean> originComponentRes =
649 capabiltyRequirementConvertor.getOriginComponent(componentCache, componentInstance);
650 if (originComponentRes.isRight()) {
651 convertNodeTemplatesRes = Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
654 Either<ToscaNodeTemplate, ToscaError> requirements =
655 convertComponentInstanceRequirements(component, componentInstance,
656 component.getComponentInstancesRelations(), nodeTemplate, originComponentRes.left().value(),
658 if (requirements.isRight()) {
659 convertNodeTemplatesRes = Either.right(requirements.right().value());
662 String instanceUniqueId = componentInstance.getUniqueId();
663 log.debug("Component instance Requirements converted for instance {}", instanceUniqueId);
665 nodeTemplate = requirements.left().value();
667 Component originalComponent = componentCache.get(componentInstance.getActualComponentUid());
669 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
670 Component componentOfProxy = componentCache.get(componentInstance.getComponentUid());
671 nodeTemplate.setMetadata(convertMetadata(componentOfProxy, true, componentInstance));
673 nodeTemplate.setMetadata(convertMetadata(originalComponent, true, componentInstance));
676 Either<ToscaNodeTemplate, ToscaError> capabilities = capabiltyRequirementConvertor
677 .convertComponentInstanceCapabilties(
678 componentInstance, dataTypes,
680 if (capabilities.isRight()) {
681 convertNodeTemplatesRes = Either.right(requirements.right().value());
684 log.debug("Component instance Capabilities converted for instance {}", instanceUniqueId);
686 nodeTemplate = capabilities.left().value();
687 Map<String, Object> props = new HashMap<>();
689 if (originalComponent.getComponentType() == ComponentTypeEnum.RESOURCE) {
690 // Adds the properties of parent component to map
691 addPropertiesOfParentComponent(dataTypes, componentInstance, originalComponent, props);
694 if (null != componentInstancesProperties && componentInstancesProperties.containsKey(instanceUniqueId)) {
695 addPropertiesOfComponentInstance(componentInstancesProperties, dataTypes, componentInstance,
696 instanceUniqueId, props);
699 if (componentInstancesInputs != null && componentInstancesInputs.containsKey(instanceUniqueId)) {
700 addComponentInstanceInputs(dataTypes, componentInstancesInputs, componentInstance, instanceUniqueId,
703 if (props != null && !props.isEmpty()) {
704 nodeTemplate.setProperties(props);
707 List<GroupInstance> groupInstances = componentInstance.getGroupInstances();
708 if (groupInstances != null) {
709 if (groupsMap == null) {
710 groupsMap = new HashMap<>();
712 for (GroupInstance groupInst : groupInstances) {
713 boolean addToTosca = true;
715 List<String> artifacts = groupInst.getArtifacts();
716 if (artifacts == null || artifacts.isEmpty()) {
721 ToscaGroupTemplate toscaGroup = convertGroupInstance(groupInst);
722 groupsMap.put(groupInst.getName(), toscaGroup);
727 nodeTemplates.put(componentInstance.getName(), nodeTemplate);
729 if (groupsMap != null) {
730 log.debug("instance groups added");
731 topologyTemplate.addGroups(groupsMap);
733 if (component.getComponentType() == ComponentTypeEnum.SERVICE && MapUtils.isNotEmpty(
734 ((Service) component).getForwardingPaths())) {
735 log.debug("Starting converting paths for component {}, name {}", component.getUniqueId(),
736 component.getName());
737 ForwardingPathToscaUtil
738 .addForwardingPaths((Service) component, nodeTemplates, capabiltyRequirementConvertor,
739 componentCache, toscaOperationFacade);
740 log.debug("Finished converting paths for component {}, name {}", component.getUniqueId(),
741 component.getName());
743 if (convertNodeTemplatesRes == null) {
744 convertNodeTemplatesRes = Either.left(nodeTemplates);
746 log.debug("finish convert topology template for {} for type {}", component.getUniqueId(),
747 component.getComponentType());
748 return convertNodeTemplatesRes;
751 private void addComponentInstanceInputs(Map<String, DataTypeDefinition> dataTypes,
752 Map<String, List<ComponentInstanceInput>> componentInstancesInputs, ComponentInstance componentInstance,
753 String instanceUniqueId, Map<String, Object> props) {
755 List<ComponentInstanceInput> instanceInputsList = componentInstancesInputs.get(instanceUniqueId);
756 if (instanceInputsList != null) {
757 instanceInputsList.forEach(input -> {
759 Supplier<String> supplier =
760 () -> input.getValue() != null && !input.getValue().isEmpty() ? input.getValue() :
761 input.getDefaultValue();
762 convertAndAddValue(dataTypes, componentInstance, props, input, supplier);
767 private void addPropertiesOfComponentInstance(
768 Map<String, List<ComponentInstanceProperty>> componentInstancesProperties,
769 Map<String, DataTypeDefinition> dataTypes, ComponentInstance componentInstance, String instanceUniqueId,
770 Map<String, Object> props) {
772 if (!MapUtils.isEmpty(componentInstancesProperties)) {
773 componentInstancesProperties.get(instanceUniqueId).stream()
774 // Collects filtered properties to List
775 .collect(Collectors.toList()).stream()
776 // Converts and adds each value to property map
777 .forEach(prop -> convertAndAddValue(dataTypes, componentInstance, props, prop,
778 () -> prop.getValue()));
782 private void addPropertiesOfParentComponent(Map<String, DataTypeDefinition> dataTypes,
783 ComponentInstance componentInstance, Component componentOfInstance, Map<String, Object> props) {
785 List<PropertyDefinition> componentProperties = ((Resource) componentOfInstance).getProperties();
786 if (!CollectionUtils.isEmpty(componentProperties)) {
787 componentProperties.stream()
788 // Filters out properties with empty default values
789 .filter(prop -> !StringUtils.isEmpty(prop.getDefaultValue()))
790 // Collects filtered properties to List
791 .collect(Collectors.toList()).stream()
792 // Converts and adds each value to property map
793 .forEach(prop -> convertAndAddValue(dataTypes, componentInstance, props, prop,
794 () -> prop.getDefaultValue()));
800 * @param componentInstance
805 private void convertAndAddValue(Map<String, DataTypeDefinition> dataTypes, ComponentInstance componentInstance,
806 Map<String, Object> props, PropertyDefinition prop, Supplier<String> supplier) {
807 Object convertedValue = convertValue(dataTypes, componentInstance, prop, supplier);
808 if (!ToscaValueBaseConverter.isEmptyObjectValue(convertedValue)) {
809 props.put(prop.getName(), convertedValue);
813 private <T extends PropertyDefinition> Object convertValue(Map<String, DataTypeDefinition> dataTypes,
814 ComponentInstance componentInstance, T input, Supplier<String> supplier) {
815 log.debug("Convert property or input value {} for instance {}", input.getName(),
816 componentInstance.getUniqueId());
817 String propertyType = input.getType();
818 String innerType = null;
819 if (input.getSchema() != null && input.getSchema().getProperty() != null) {
820 innerType = input.getSchema().getProperty().getType();
822 return propertyConvertor.convertToToscaObject(propertyType, supplier.get(), innerType, dataTypes);
825 private ToscaGroupTemplate convertGroup(GroupDefinition group) {
826 ToscaGroupTemplate toscaGroup = new ToscaGroupTemplate();
827 Map<String, String> members = group.getMembers();
828 if (members != null) {
829 toscaGroup.setMembers(new ArrayList<String>(members.keySet()));
832 Supplier<String> supplGroupType = () -> group.getType();
833 Supplier<String> supplDescription = () -> group.getDescription();
834 Supplier<List<? extends GroupProperty>> supplProperties = () -> group.convertToGroupProperties();
835 Supplier<String> supplgroupName = () -> group.getName();
836 Supplier<String> supplInvariantUUID = () -> group.getInvariantUUID();
837 Supplier<String> supplGroupUUID = () -> group.getGroupUUID();
838 Supplier<String> supplVersion = () -> group.getVersion();
840 IToscaMetadata toscaMetadata =
841 fillGroup(toscaGroup, supplProperties, supplDescription, supplgroupName, supplInvariantUUID,
842 supplGroupUUID, supplVersion, supplGroupType);
843 toscaGroup.setMetadata(toscaMetadata);
847 private ToscaGroupTemplate convertGroupInstance(GroupInstance groupInstance) {
848 ToscaGroupTemplate toscaGroup = new ToscaGroupTemplate();
850 Supplier<String> supplGroupType = () -> groupInstance.getType();
851 Supplier<String> supplDescription = () -> groupInstance.getDescription();
852 Supplier<List<? extends GroupProperty>> supplProperties =
853 () -> groupInstance.convertToGroupInstancesProperties();
854 Supplier<String> supplgroupName = () -> groupInstance.getGroupName();
855 Supplier<String> supplInvariantUUID = () -> groupInstance.getInvariantUUID();
856 Supplier<String> supplGroupUUID = () -> groupInstance.getGroupUUID();
857 Supplier<String> supplVersion = () -> groupInstance.getVersion();
859 IToscaMetadata toscaMetadata =
860 fillGroup(toscaGroup, supplProperties, supplDescription, supplgroupName, supplInvariantUUID,
861 supplGroupUUID, supplVersion, supplGroupType);
863 toscaMetadata.setCustomizationUUID(groupInstance.getCustomizationUUID());
864 toscaGroup.setMetadata(toscaMetadata);
868 private IToscaMetadata fillGroup(ToscaGroupTemplate toscaGroup, Supplier<List<? extends GroupProperty>> props,
869 Supplier<String> description, Supplier<String> groupName, Supplier<String> invariantUUID,
870 Supplier<String> groupUUID, Supplier<String> version, Supplier<String> groupType) {
871 boolean isVfModule = groupType.get().equals(Constants.DEFAULT_GROUP_VF_MODULE) ? true : false;
872 toscaGroup.setType(groupType.get());
874 IToscaMetadata toscaMetadata;
876 toscaMetadata = new ToscaMetadata();
878 toscaMetadata = new VfModuleToscaMetadata();
880 Map<String, Object> properties = fillGroupProperties(props.get());
881 if (!properties.containsKey(VF_MODULE_DESC_KEY) || StringUtils.isEmpty(
882 (String) properties.get(VF_MODULE_DESC_KEY))) {
883 properties.put(VF_MODULE_DESC_KEY, description.get());
885 toscaGroup.setProperties(properties);
887 toscaMetadata.setName(groupName.get());
888 toscaMetadata.setInvariantUUID(invariantUUID.get());
889 toscaMetadata.setUUID(groupUUID.get());
890 toscaMetadata.setVersion(version.get());
891 return toscaMetadata;
894 private Map<String, Object> fillGroupProperties(List<? extends GroupProperty> groupProps) {
895 Map<String, Object> properties = new HashMap<>();
896 if (groupProps != null) {
897 for (GroupProperty gp : groupProps) {
898 if (gp.getName().equals(Constants.IS_BASE)) {
899 Boolean isBase = Boolean.parseBoolean(gp.getValue());
900 String type = isBase ? VF_MODULE_TYPE_BASE : VF_MODULE_TYPE_EXPANSION;
901 properties.put(VF_MODULE_TYPE_KEY, type);
904 String type = gp.getType();
908 if (gp.getValue() != null) {
909 value = Integer.valueOf(gp.getValue());
913 if (gp.getValue() != null) {
914 value = Boolean.valueOf(gp.getValue());
919 value = gp.getValue();
922 properties.put(gp.getName(), value);
929 private ToscaNodeType createNodeType(Component component) {
930 ToscaNodeType toscaNodeType = new ToscaNodeType();
931 if (ModelConverter.isAtomicComponent(component)) {
932 if (((Resource) component).getDerivedFrom() != null) {
933 toscaNodeType.setDerived_from(((Resource) component).getDerivedFrom().get(0));
935 toscaNodeType.setDescription(component.getDescription()); // or
938 String derivedFrom = null != component.getDerivedFromGenericType() ? component.getDerivedFromGenericType() :
940 toscaNodeType.setDerived_from(derivedFrom);
942 return toscaNodeType;
945 private Either<Map<String, ToscaNodeType>, ToscaError> createProxyNodeTypes(Map<String, Component> componentCache,
946 Component container) {
948 Map<String, ToscaNodeType> nodeTypesMap = null;
949 Either<Map<String, ToscaNodeType>, ToscaError> res = Either.left(nodeTypesMap);
951 List<ComponentInstance> componetInstances = container.getComponentInstances();
953 if (componetInstances == null || componetInstances.isEmpty()) {
956 Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
957 List<ComponentInstance> proxyInst = componetInstances.stream().filter(p -> p.getOriginType().name()
958 .equals(OriginTypeEnum.ServiceProxy
960 .collect(Collectors.toList());
961 if (proxyInst != null && !proxyInst.isEmpty()) {
962 for (ComponentInstance inst : proxyInst) {
963 serviceProxyInstanceList.put(inst.getToscaComponentName(), inst);
967 if (serviceProxyInstanceList.isEmpty()) {
970 ComponentParametersView filter = new ComponentParametersView(true);
971 filter.setIgnoreCapabilities(false);
972 filter.setIgnoreComponentInstances(false);
973 Either<Resource, StorageOperationStatus> serviceProxyOrigin =
974 toscaOperationFacade.getLatestByName("serviceProxy");
975 if (serviceProxyOrigin.isRight()) {
976 log.debug("Failed to fetch normative service proxy resource by tosca name, error {}",
977 serviceProxyOrigin.right().value());
978 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
980 Component origComponent = serviceProxyOrigin.left().value();
982 nodeTypesMap = new HashMap<>();
983 for (Entry<String, ComponentInstance> entryProxy : serviceProxyInstanceList.entrySet()) {
984 Component serviceComponent = null;
985 ComponentParametersView componentParametersView = new ComponentParametersView();
986 componentParametersView.disableAll();
987 componentParametersView.setIgnoreCategories(false);
988 Either<Component, StorageOperationStatus> service = toscaOperationFacade.getToscaElement(
989 entryProxy.getValue().getSourceModelUid(), componentParametersView);
990 if (service.isRight()) {
991 log.debug("Failed to fetch resource with id {} for instance {}");
993 serviceComponent = service.left().value();
996 ToscaNodeType toscaNodeType =
997 createProxyNodeType(componentCache, origComponent, serviceComponent, entryProxy.getValue());
998 nodeTypesMap.put(entryProxy.getKey(), toscaNodeType);
1001 return Either.left(nodeTypesMap);
1004 private ToscaNodeType createProxyNodeType(Map<String, Component> componentCache, Component origComponent,
1005 Component proxyComponent, ComponentInstance instance) {
1006 ToscaNodeType toscaNodeType = new ToscaNodeType();
1007 String derivedFrom = ((Resource) origComponent).getToscaResourceName();
1009 toscaNodeType.setDerived_from(derivedFrom);
1010 Either<Map<String, DataTypeDefinition>, TitanOperationStatus> dataTypesEither = dataTypeCache.getAll();
1011 if (dataTypesEither.isRight()) {
1012 log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
1014 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
1015 Map<String, ToscaCapability> capabilities = this.capabiltyRequirementConvertor
1016 .convertProxyCapabilities(componentCache, origComponent,
1017 proxyComponent, instance, dataTypes);
1019 toscaNodeType.setCapabilities(capabilities);
1021 return toscaNodeType;
1024 private Either<ToscaNodeTemplate, ToscaError> convertComponentInstanceRequirements(Component component,
1025 ComponentInstance componentInstance, List<RequirementCapabilityRelDef> relations,
1026 ToscaNodeTemplate nodeTypeTemplate, Component originComponent, Map<String, Component> componentCache) {
1028 List<Map<String, ToscaTemplateRequirement>> toscaRequirements = new ArrayList<>();
1029 if (!addRequirements(component, componentInstance, relations, originComponent, toscaRequirements,
1031 log.debug("Failed to convert component instance requirements for the component instance {}. ",
1032 componentInstance.getName());
1033 return Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
1035 if (!toscaRequirements.isEmpty()) {
1036 nodeTypeTemplate.setRequirements(toscaRequirements);
1038 log.debug("Finished to convert requirements for the node type {} ", componentInstance.getName());
1039 return Either.left(nodeTypeTemplate);
1042 private boolean addRequirements(Component component, ComponentInstance componentInstance,
1043 List<RequirementCapabilityRelDef> relations, Component originComponent,
1044 List<Map<String, ToscaTemplateRequirement>> toscaRequirements, Map<String, Component> componentCache) {
1046 List<RequirementCapabilityRelDef> filteredRelations =
1047 relations.stream().filter(p -> componentInstance.getUniqueId().equals(p.getFromNode()))
1048 .collect(Collectors.toList());
1049 if (CollectionUtils.isEmpty(filteredRelations)) {
1052 result = !filteredRelations.stream().filter(rel -> !addRequirement(componentInstance, originComponent,
1053 component.getComponentInstances(), rel, toscaRequirements, componentCache)).findFirst().isPresent();
1058 private boolean addRequirement(ComponentInstance fromInstance, Component fromOriginComponent,
1059 List<ComponentInstance> instancesList, RequirementCapabilityRelDef rel,
1060 List<Map<String, ToscaTemplateRequirement>> toscaRequirements, Map<String, Component> componentCache) {
1062 boolean result = true;
1063 Map<String, List<RequirementDefinition>> reqMap = fromOriginComponent.getRequirements();
1064 RelationshipInfo reqAndRelationshipPair = rel.getRelationships().get(0).getRelation();
1065 Either<Component, StorageOperationStatus> getOriginRes = null;
1066 Optional<RequirementDefinition> reqOpt = null;
1067 Component toOriginComponent = null;
1068 Optional<CapabilityDefinition> cap = null;
1070 ComponentInstance toInstance =
1071 instancesList.stream().filter(i -> rel.getToNode().equals(i.getUniqueId())).findFirst().orElse(null);
1072 if (toInstance == null) {
1073 log.debug("Failed to find a relation from the node {} to the node {}", fromInstance.getName(),
1078 reqOpt = findRequirement(fromOriginComponent, reqMap, reqAndRelationshipPair, fromInstance.getUniqueId());
1079 if (!reqOpt.isPresent()) {
1080 log.debug("Failed to find a requirement with uniqueId {} on a component with uniqueId {}",
1081 reqAndRelationshipPair.getRequirementUid(), fromOriginComponent.getUniqueId());
1086 ComponentParametersView filter = new ComponentParametersView(true);
1087 filter.setIgnoreComponentInstances(false);
1088 filter.setIgnoreCapabilities(false);
1089 getOriginRes = toscaOperationFacade.getToscaElement(toInstance.getActualComponentUid(), filter);
1090 if (getOriginRes.isRight()) {
1092 "Failed to build substituted name for the requirement {}. Failed to get an origin component with uniqueId {}",
1093 reqOpt.get().getName(), toInstance.getActualComponentUid());
1098 toOriginComponent = getOriginRes.left().value();
1099 cap = toOriginComponent.getCapabilities().get(reqOpt.get().getCapability()).stream()
1100 .filter(c -> isCapabilityBelongToRelation(reqAndRelationshipPair, c)).findFirst();
1101 if (!cap.isPresent()) {
1102 cap = findCapability(reqAndRelationshipPair, toOriginComponent, fromOriginComponent, reqOpt.get(),
1104 if (!cap.isPresent()) {
1106 log.debug("Failed to find a capability with name {} on a component with uniqueId {}",
1107 reqAndRelationshipPair.getCapability(), fromOriginComponent.getUniqueId());
1112 result = buildAndAddRequirement(toscaRequirements, fromOriginComponent, toOriginComponent, cap.get(),
1113 reqOpt.get(), reqAndRelationshipPair, toInstance, componentCache);
1118 private boolean isCapabilityBelongToRelation(RelationshipInfo reqAndRelationshipPair,
1119 CapabilityDefinition capability) {
1120 return capability.getName().equals(reqAndRelationshipPair.getCapability()) && (capability.getOwnerId() != null
1123 .equals(reqAndRelationshipPair
1124 .getCapabilityOwnerId()));
1127 private Optional<CapabilityDefinition> findCapability(RelationshipInfo reqAndRelationshipPair,
1128 Component toOriginComponent, Component fromOriginComponent, RequirementDefinition requirement,
1129 ComponentInstance fromInstance) {
1130 Optional<CapabilityDefinition> cap =
1131 toOriginComponent.getCapabilities().get(requirement.getCapability()).stream()
1132 .filter(c -> c.getType().equals(requirement.getCapability())).findFirst();
1133 if (!cap.isPresent()) {
1134 log.debug("Failed to find a capability with name {} on a component with uniqueId {}",
1135 reqAndRelationshipPair.getCapability(), fromOriginComponent.getUniqueId());
1140 private boolean buildAndAddRequirement(List<Map<String, ToscaTemplateRequirement>> toscaRequirements,
1141 Component fromOriginComponent, Component toOriginComponent, CapabilityDefinition capability,
1142 RequirementDefinition requirement, RelationshipInfo reqAndRelationshipPair, ComponentInstance toInstance,
1143 Map<String, Component> componentCache) {
1144 boolean result = true;
1145 Either<String, Boolean> buildReqNameRes = null;
1146 List<String> reducedPath = capability.getPath();
1147 if (capability.getOwnerId() != null) {
1149 capabiltyRequirementConvertor.getReducedPathByOwner(capability.getPath(), capability.getOwnerId());
1151 Either<String, Boolean> buildCapNameRes = capabiltyRequirementConvertor
1152 .buildSubstitutedName(componentCache, toOriginComponent,
1153 reducedPath, reqAndRelationshipPair.getCapability());
1154 if (buildCapNameRes.isRight()) {
1156 "Failed to build a substituted capability name for the capability with name {} on a component with uniqueId {}",
1157 reqAndRelationshipPair.getCapability(), fromOriginComponent.getUniqueId());
1161 buildReqNameRes = capabiltyRequirementConvertor
1162 .buildSubstitutedName(componentCache, fromOriginComponent, requirement.getPath(),
1163 reqAndRelationshipPair.getRequirement());
1164 if (buildReqNameRes.isRight()) {
1166 "Failed to build a substituted requirement name for the requirement with name {} on a component with uniqueId {}",
1167 reqAndRelationshipPair.getRequirement(), fromOriginComponent.getUniqueId());
1172 ToscaTemplateRequirement toscaRequirement = new ToscaTemplateRequirement();
1173 Map<String, ToscaTemplateRequirement> toscaReqMap = new HashMap<>();
1174 toscaRequirement.setNode(toInstance.getName());
1175 toscaRequirement.setCapability(buildCapNameRes.left().value());
1176 toscaReqMap.put(buildReqNameRes.left().value(), toscaRequirement);
1177 toscaRequirements.add(toscaReqMap);
1182 private Optional<RequirementDefinition> findRequirement(Component fromOriginComponent,
1183 Map<String, List<RequirementDefinition>> reqMap, RelationshipInfo reqAndRelationshipPair,
1184 String fromInstanceId) {
1185 for (List<RequirementDefinition> reqList : reqMap.values()) {
1186 Optional<RequirementDefinition> reqOpt = reqList.stream().filter(r -> isRequirementBelongToRelation(
1187 fromOriginComponent, reqAndRelationshipPair, r, fromInstanceId)).findFirst();
1188 if (reqOpt.isPresent()) {
1192 return Optional.empty();
1196 * Allows detecting the requirement belonging to the received relationship
1197 * The detection logic is: A requirement belongs to a relationship IF 1.The
1198 * name of the requirement equals to the "requirement" field of the
1199 * relation; AND 2. In case of a non-atomic resource, OwnerId of the
1200 * requirement equals to requirementOwnerId of the relation OR uniqueId of
1201 * toInstance equals to capabilityOwnerId of the relation
1203 private boolean isRequirementBelongToRelation(Component originComponent, RelationshipInfo reqAndRelationshipPair,
1204 RequirementDefinition requirement, String fromInstanceId) {
1205 if (!StringUtils.equals(requirement.getName(), reqAndRelationshipPair.getRequirement())) {
1206 log.debug("Failed to find a requirement with name {} and reqAndRelationshipPair {}", requirement.getName(),
1207 reqAndRelationshipPair.getRequirement());
1210 if (!ModelConverter.isAtomicComponent(originComponent)) {
1211 return isRequirementBelongToOwner(reqAndRelationshipPair, requirement, fromInstanceId, originComponent);
1216 private boolean isRequirementBelongToOwner(RelationshipInfo reqAndRelationshipPair,
1217 RequirementDefinition requirement, String fromInstanceId, Component originComponent) {
1218 return StringUtils.equals(requirement.getOwnerId(), reqAndRelationshipPair.getRequirementOwnerId()) || (
1219 isCvfc(originComponent) && StringUtils.equals(fromInstanceId,
1220 reqAndRelationshipPair.getRequirementOwnerId()));
1223 private boolean isCvfc(Component component) {
1224 if (component.getComponentType() != ComponentTypeEnum.RESOURCE) {
1227 return ((Resource) component).getResourceType() == ResourceTypeEnum.CVFC;
1230 private Either<SubstitutionMapping, ToscaError> convertCapabilities(Component component,
1231 SubstitutionMapping substitutionMappings, Map<String, Component> componentCache) {
1233 Either<SubstitutionMapping, ToscaError> result = Either.left(substitutionMappings);
1234 Either<Map<String, String[]>, ToscaError> toscaCapabilitiesRes =
1235 capabiltyRequirementConvertor.convertSubstitutionMappingCapabilities(componentCache, component);
1236 if (toscaCapabilitiesRes.isRight()) {
1237 result = Either.right(toscaCapabilitiesRes.right().value());
1238 log.error("Failed convert capabilities for the component {}. ", component.getName());
1239 } else if (MapUtils.isNotEmpty(toscaCapabilitiesRes.left().value())) {
1240 substitutionMappings.setCapabilities(toscaCapabilitiesRes.left().value());
1241 log.debug("Finish convert capabilities for the component {}. ", component.getName());
1243 log.debug("Finished to convert capabilities for the component {}. ", component.getName());
1247 private Either<ToscaNodeType, ToscaError> convertCapabilities(Component component, ToscaNodeType nodeType,
1248 Map<String, DataTypeDefinition> dataTypes) {
1249 Map<String, ToscaCapability> toscaCapabilities =
1250 capabiltyRequirementConvertor.convertCapabilities(component, dataTypes);
1251 if (!toscaCapabilities.isEmpty()) {
1252 nodeType.setCapabilities(toscaCapabilities);
1254 log.debug("Finish convert Capabilities for node type");
1256 return Either.left(nodeType);
1259 public static class CustomRepresenter extends Representer {
1261 public CustomRepresenter() {
1263 // null representer is exceptional and it is stored as an instance
1265 this.nullRepresenter = new RepresentNull();
1270 protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue,
1272 if (propertyValue == null) {
1275 // skip not relevant for Tosca property
1276 if ("dependencies".equals(property.getName())) {
1279 NodeTuple defaultNode = super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
1281 return "_defaultp_".equals(property.getName()) ?
1282 new NodeTuple(representData("default"), defaultNode.getValueNode()) : defaultNode;
1287 protected MappingNode representJavaBean(Set<Property> properties, Object javaBean) {
1288 // remove the bean type from the output yaml (!! ...)
1289 if (!classTags.containsKey(javaBean.getClass())) {
1290 addClassTag(javaBean.getClass(), Tag.MAP);
1293 return super.representJavaBean(properties, javaBean);
1296 private class RepresentNull implements Represent {
1299 public Node representData(Object data) {
1300 // possible values are here http://yaml.org/type/null.html
1301 return representScalar(Tag.NULL, "");
1306 public static class UnsortedPropertyUtils extends PropertyUtils {
1309 protected Set<Property> createPropertySet(Class<? extends Object> type, BeanAccess bAccess)
1310 throws IntrospectionException {
1311 Collection<Property> fields = getPropertiesMap(type, BeanAccess.FIELD).values();
1312 return new LinkedHashSet<>(fields);