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 fj.data.Either;
24 import org.apache.commons.collections.CollectionUtils;
25 import org.apache.commons.collections.MapUtils;
26 import org.apache.commons.lang.StringUtils;
27 import org.apache.commons.lang3.tuple.ImmutablePair;
28 import org.apache.commons.lang3.tuple.ImmutableTriple;
29 import org.apache.commons.lang3.tuple.Triple;
30 import org.openecomp.sdc.be.config.ConfigurationManager;
31 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
32 import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
33 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
34 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
35 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
36 import org.openecomp.sdc.be.model.*;
37 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
38 import org.openecomp.sdc.be.model.category.CategoryDefinition;
39 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
40 import org.openecomp.sdc.be.model.jsontitan.utils.ModelConverter;
41 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
42 import org.openecomp.sdc.be.model.tosca.converters.ToscaValueBaseConverter;
43 import org.openecomp.sdc.be.tosca.model.*;
44 import org.openecomp.sdc.be.tosca.utils.ForwardingPathToscaUtil;
45 import org.openecomp.sdc.common.api.Constants;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
48 import org.springframework.beans.factory.annotation.Autowired;
49 import org.yaml.snakeyaml.DumperOptions;
50 import org.yaml.snakeyaml.DumperOptions.FlowStyle;
51 import org.yaml.snakeyaml.Yaml;
52 import org.yaml.snakeyaml.introspector.BeanAccess;
53 import org.yaml.snakeyaml.introspector.Property;
54 import org.yaml.snakeyaml.introspector.PropertyUtils;
55 import org.yaml.snakeyaml.nodes.MappingNode;
56 import org.yaml.snakeyaml.nodes.Node;
57 import org.yaml.snakeyaml.nodes.NodeTuple;
58 import org.yaml.snakeyaml.nodes.Tag;
59 import org.yaml.snakeyaml.representer.Represent;
60 import org.yaml.snakeyaml.representer.Representer;
62 import java.beans.IntrospectionException;
63 import java.util.ArrayList;
64 import java.util.Collection;
65 import java.util.HashMap;
66 import java.util.LinkedHashSet;
67 import java.util.List;
69 import java.util.Map.Entry;
70 import java.util.Optional;
72 import java.util.function.Supplier;
73 import java.util.stream.Collectors;
75 @org.springframework.stereotype.Component("tosca-export-handler")
76 public class ToscaExportHandler {
79 private ApplicationDataTypeCache dataTypeCache;
82 private ToscaOperationFacade toscaOperationFacade;
84 private CapabiltyRequirementConvertor capabiltyRequirementConvertor;
85 private PropertyConvertor propertyConvertor = PropertyConvertor.getInstance();
87 private static final Logger log = LoggerFactory.getLogger(ToscaExportHandler.class);
89 public static final String TOSCA_VERSION = "tosca_simple_yaml_1_1";
90 public static final String SERVICE_NODE_TYPE_PREFIX = "org.openecomp.service.";
91 public static final String IMPORTS_FILE_KEY = "file";
92 public static final String TOSCA_TEMPLATE_NAME = "-template.yml";
93 public static final String TOSCA_INTERFACE_NAME = "-interface.yml";
94 public static final String ASSET_TOSCA_TEMPLATE = "assettoscatemplate";
95 public static final String VF_MODULE_TYPE_KEY = "vf_module_type";
96 public static final String VF_MODULE_DESC_KEY = "vf_module_description";
97 public static final String VOLUME_GROUP_KEY = "volume_group";
98 public static final String VF_MODULE_TYPE_BASE = "Base";
99 public static final String VF_MODULE_TYPE_EXPANSION = "Expansion";
100 private static final String FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION = "convertToToscaTemplate - failed to get Default Imports section from configuration";
101 private static final String NOT_SUPPORTED_COMPONENT_TYPE = "Not supported component type {}";
102 protected static final List<Map<String, Map<String, String>>> DEFAULT_IMPORTS = ConfigurationManager
103 .getConfigurationManager().getConfiguration().getDefaultImports();
105 public Either<ToscaRepresentation, ToscaError> exportComponent(Component component) {
107 Either<ToscaTemplate, ToscaError> toscaTemplateRes = convertToToscaTemplate(component);
108 if (toscaTemplateRes.isRight()) {
109 return Either.right(toscaTemplateRes.right().value());
112 ToscaTemplate toscaTemplate = toscaTemplateRes.left().value();
113 ToscaRepresentation toscaRepresentation = this.createToscaRepresentation(toscaTemplate);
114 return Either.left(toscaRepresentation);
117 public Either<ToscaRepresentation, ToscaError> exportComponentInterface(Component component) {
118 if (null == DEFAULT_IMPORTS) {
119 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
120 return Either.right(ToscaError.GENERAL_ERROR);
123 ToscaTemplate toscaTemplate = new ToscaTemplate(TOSCA_VERSION);
124 toscaTemplate.setImports(new ArrayList<>(DEFAULT_IMPORTS));
125 Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
126 Either<ToscaTemplate, ToscaError> toscaTemplateRes = convertInterfaceNodeType(component, toscaTemplate,
128 if (toscaTemplateRes.isRight()) {
129 return Either.right(toscaTemplateRes.right().value());
132 toscaTemplate = toscaTemplateRes.left().value();
133 ToscaRepresentation toscaRepresentation = this.createToscaRepresentation(toscaTemplate);
134 return Either.left(toscaRepresentation);
137 public ToscaRepresentation createToscaRepresentation(ToscaTemplate toscaTemplate) {
138 CustomRepresenter representer = new CustomRepresenter();
139 DumperOptions options = new DumperOptions();
140 options.setAllowReadOnlyProperties(false);
141 options.setPrettyFlow(true);
143 options.setDefaultFlowStyle(FlowStyle.FLOW);
144 options.setCanonical(false);
146 representer.addClassTag(toscaTemplate.getClass(), Tag.MAP);
148 representer.setPropertyUtils(new UnsortedPropertyUtils());
149 Yaml yaml = new Yaml(representer, options);
151 String yamlAsString = yaml.dumpAsMap(toscaTemplate);
153 StringBuilder sb = new StringBuilder();
154 sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactHeader());
155 sb.append(yamlAsString);
156 sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactFooter());
158 ToscaRepresentation toscaRepresentation = new ToscaRepresentation();
159 toscaRepresentation.setMainYaml(sb.toString());
160 toscaRepresentation.setDependencies(toscaTemplate.getDependencies());
162 return toscaRepresentation;
165 public Either<ToscaTemplate, ToscaError> getDependencies(Component component) {
166 ToscaTemplate toscaTemplate = new ToscaTemplate(null);
167 Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports = fillImports(component,
169 if (fillImports.isRight()) {
170 return Either.right(fillImports.right().value());
172 return Either.left(fillImports.left().value().left);
175 private Either<ToscaTemplate, ToscaError> convertToToscaTemplate(Component component) {
176 if (null == DEFAULT_IMPORTS) {
177 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
178 return Either.right(ToscaError.GENERAL_ERROR);
181 log.trace("start tosca export for {}", component.getUniqueId());
182 ToscaTemplate toscaTemplate = new ToscaTemplate(TOSCA_VERSION);
184 toscaTemplate.setMetadata(convertMetadata(component));
185 toscaTemplate.setImports(new ArrayList<>(DEFAULT_IMPORTS));
186 Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
187 if (ModelConverter.isAtomicComponent(component)) {
188 log.trace("convert component as node type");
189 return convertNodeType(component, toscaTemplate, nodeTypes);
191 log.trace("convert component as topology template");
192 return convertToscaTemplate(component, toscaTemplate);
197 private Either<ToscaTemplate, ToscaError> convertToscaTemplate(Component component, ToscaTemplate toscaNode) {
199 Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> importsRes = fillImports(component,
201 if (importsRes.isRight()) {
202 return Either.right(importsRes.right().value());
204 toscaNode = importsRes.left().value().left;
205 Map<String, Component> componentCache = importsRes.left().value().right;
206 Either<Map<String, ToscaNodeType>, ToscaError> nodeTypesMapEither = createProxyNodeTypes(componentCache , component );
207 if (nodeTypesMapEither.isRight()) {
208 log.debug("Failed to fetch normative service proxy resource by tosca name, error {}",
209 nodeTypesMapEither.right().value());
210 return Either.right(nodeTypesMapEither.right().value());
212 Map<String, ToscaNodeType> nodeTypesMap = nodeTypesMapEither.left().value();
213 if (nodeTypesMap != null && !nodeTypesMap.isEmpty())
214 toscaNode.setNode_types(nodeTypesMap);
217 Either<Map<String, DataTypeDefinition>, TitanOperationStatus> dataTypesEither = dataTypeCache.getAll();
218 if (dataTypesEither.isRight()) {
219 log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
220 return Either.right(ToscaError.GENERAL_ERROR);
222 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
224 ToscaTopolgyTemplate topologyTemplate = new ToscaTopolgyTemplate();
226 Either<ToscaTopolgyTemplate, ToscaError> inputs = fillInputs(component, topologyTemplate, dataTypes);
227 if (inputs.isRight()) {
228 return Either.right(inputs.right().value());
230 topologyTemplate = inputs.left().value();
232 List<ComponentInstance> componentInstances = component.getComponentInstances();
233 Map<String, List<ComponentInstanceProperty>> componentInstancesProperties = component
234 .getComponentInstancesProperties();
235 List<GroupDefinition> groups = component.getGroups();
236 if (componentInstances != null && !componentInstances.isEmpty()) {
238 Either<Map<String, ToscaNodeTemplate>, ToscaError> nodeTemplates = convertNodeTemplates(component,
239 componentInstances, componentInstancesProperties, componentCache, dataTypes, topologyTemplate);
240 if (nodeTemplates.isRight()) {
241 return Either.right(nodeTemplates.right().value());
243 log.debug("node templates converted");
245 topologyTemplate.setNode_templates(nodeTemplates.left().value());
247 Map<String, ToscaGroupTemplate> groupsMap;
248 if (groups != null && !groups.isEmpty()) {
249 groupsMap = new HashMap<>();
250 for (GroupDefinition group : groups) {
251 boolean addToTosca = true;
252 if (group.getType().equals(Constants.DEFAULT_GROUP_VF_MODULE)) {
253 List<String> artifacts = group.getArtifacts();
254 if (artifacts == null || artifacts.isEmpty()) {
259 ToscaGroupTemplate toscaGroup = convertGroup(group);
260 groupsMap.put(group.getName(), toscaGroup);
264 log.debug("groups converted");
265 topologyTemplate.addGroups(groupsMap);
267 SubstitutionMapping substitutionMapping = new SubstitutionMapping();
268 String toscaResourceName;
269 switch (component.getComponentType()) {
271 toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition()
272 .getMetadataDataDefinition()).getToscaResourceName();
275 toscaResourceName = SERVICE_NODE_TYPE_PREFIX
276 + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName();
279 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
280 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
282 substitutionMapping.setNode_type(toscaResourceName);
284 Either<SubstitutionMapping, ToscaError> capabilities = convertCapabilities(component, substitutionMapping, componentCache);
285 if (capabilities.isRight()) {
286 return Either.right(capabilities.right().value());
288 substitutionMapping = capabilities.left().value();
290 Either<SubstitutionMapping, ToscaError> requirements = capabiltyRequirementConvertor
291 .convertSubstitutionMappingRequirements(componentCache, component, substitutionMapping);
292 if (requirements.isRight()) {
293 return Either.right(requirements.right().value());
295 substitutionMapping = requirements.left().value();
297 topologyTemplate.setSubstitution_mappings(substitutionMapping);
299 toscaNode.setTopology_template(topologyTemplate);
300 return Either.left(toscaNode);
303 private Either<ToscaTopolgyTemplate, ToscaError> fillInputs(Component component,
304 ToscaTopolgyTemplate topologyTemplate, Map<String, DataTypeDefinition> dataTypes) {
305 if (log.isDebugEnabled())
306 log.debug("fillInputs for component {}", component.getUniqueId());
307 List<InputDefinition> inputDef = component.getInputs();
308 Map<String, ToscaProperty> inputs = new HashMap<>();
310 if (inputDef != null) {
311 inputDef.forEach(i -> {
312 ToscaProperty property = propertyConvertor.convertProperty(dataTypes, i, false);
313 inputs.put(i.getName(), property);
315 if (!inputs.isEmpty()) {
316 topologyTemplate.setInputs(inputs);
319 return Either.left(topologyTemplate);
322 private ToscaMetadata convertMetadata(Component component) {
323 return convertMetadata(component, false, null);
326 private ToscaMetadata convertMetadata(Component component, boolean isInstance,
327 ComponentInstance componentInstance) {
328 ToscaMetadata toscaMetadata = new ToscaMetadata();
329 toscaMetadata.setInvariantUUID(component.getInvariantUUID());
330 toscaMetadata.setUUID(component.getUUID());
331 toscaMetadata.setDescription(component.getDescription());
332 toscaMetadata.setName(component.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
334 List<CategoryDefinition> categories = component.getCategories();
335 CategoryDefinition categoryDefinition = categories.get(0);
336 toscaMetadata.setCategory(categoryDefinition.getName());
339 toscaMetadata.setVersion(component.getVersion());
340 toscaMetadata.setCustomizationUUID(componentInstance.getCustomizationUUID());
341 if (componentInstance.getSourceModelInvariant() != null
342 && !componentInstance.getSourceModelInvariant().isEmpty()) {
343 toscaMetadata.setVersion(componentInstance.getComponentVersion());
344 toscaMetadata.setSourceModelInvariant(componentInstance.getSourceModelInvariant());
345 toscaMetadata.setSourceModelUuid(componentInstance.getSourceModelUuid());
346 toscaMetadata.setSourceModelName(componentInstance.getSourceModelName());
347 toscaMetadata.setName(
348 componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceProxy.getDisplayValue());
349 toscaMetadata.setDescription(componentInstance.getDescription());
353 switch (component.getComponentType()) {
355 Resource resource = (Resource) component;
357 if (isInstance && componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
358 toscaMetadata.setType(componentInstance.getOriginType().getDisplayValue());
360 toscaMetadata.setType(resource.getResourceType().name());
361 toscaMetadata.setSubcategory(categoryDefinition.getSubcategories().get(0).getName());
362 toscaMetadata.setResourceVendor(resource.getVendorName());
363 toscaMetadata.setResourceVendorRelease(resource.getVendorRelease());
364 toscaMetadata.setResourceVendorModelNumber(resource.getResourceVendorModelNumber());
367 Service service = (Service) component;
368 toscaMetadata.setType(component.getComponentType().getValue());
369 toscaMetadata.setServiceType(service.getServiceType());
370 toscaMetadata.setServiceRole(service.getServiceRole());
371 toscaMetadata.setEnvironmentContext(service.getEnvironmentContext());
374 toscaMetadata.setServiceEcompNaming(((Service) component).isEcompGeneratedNaming());
375 toscaMetadata.setEcompGeneratedNaming(((Service) component).isEcompGeneratedNaming());
376 toscaMetadata.setNamingPolicy(((Service) component).getNamingPolicy());
380 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
382 return toscaMetadata;
385 private Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports(Component component,
386 ToscaTemplate toscaTemplate) {
388 if (null == DEFAULT_IMPORTS) {
389 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
390 return Either.right(ToscaError.GENERAL_ERROR);
392 Map<String, Component> componentCache = new HashMap<>();
394 if (!ModelConverter.isAtomicComponent(component)) {
395 List<ComponentInstance> componentInstances = component.getComponentInstances();
396 if (componentInstances != null && !componentInstances.isEmpty()) {
398 List<Map<String, Map<String, String>>> additionalImports = toscaTemplate.getImports() == null
399 ? new ArrayList<>(DEFAULT_IMPORTS) : new ArrayList<>(toscaTemplate.getImports());
401 List<Triple<String, String, Component>> dependecies = new ArrayList<>();
403 Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
404 ArtifactDefinition artifactDefinition = toscaArtifacts.get(ToscaExportHandler.ASSET_TOSCA_TEMPLATE);
406 Map<String, Map<String, String>> importsListMember = new HashMap<>();
407 Map<String, String> interfaceFiles = new HashMap<>();
408 interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactDefinition.getArtifactName()));
409 StringBuilder keyNameBuilder = new StringBuilder();
410 keyNameBuilder.append(component.getComponentType().toString().toLowerCase());
411 keyNameBuilder.append("-");
412 keyNameBuilder.append(component.getName());
413 keyNameBuilder.append("-interface");
414 importsListMember.put(keyNameBuilder.toString(), interfaceFiles);
415 additionalImports.add(importsListMember);
417 componentInstances.forEach(ci -> createDependency(componentCache, additionalImports, dependecies, ci));
418 toscaTemplate.setDependencies(dependecies);
419 toscaTemplate.setImports(additionalImports);
422 log.debug("currently imports supported for VF and service only");
424 return Either.left(new ImmutablePair<ToscaTemplate, Map<String, Component>>(toscaTemplate, componentCache));
427 private void createDependency(Map<String, Component> componentCache, List<Map<String, Map<String, String>>> imports,
428 List<Triple<String, String, Component>> dependecies, ComponentInstance ci) {
429 Map<String, String> files = new HashMap<>();
430 Map<String, Map<String, String>> importsListMember = new HashMap<>();
431 StringBuilder keyNameBuilder;
433 Component componentRI = componentCache.get(ci.getComponentUid());
434 if (componentRI == null) {
435 // all resource must be only once!
436 Either<Component, StorageOperationStatus> resource = toscaOperationFacade
437 .getToscaFullElement(ci.getComponentUid());
438 if ((resource.isRight()) && (log.isDebugEnabled())) {
439 log.debug("Failed to fetch resource with id {} for instance {}",ci.getComponentUid() ,ci.getUniqueId());
443 Component fetchedComponent = resource.left().value();
444 componentCache.put(fetchedComponent.getUniqueId(), fetchedComponent);
446 if (ci.getOriginType() == OriginTypeEnum.ServiceProxy){
447 Either<Component, StorageOperationStatus> sourceService = toscaOperationFacade
448 .getToscaFullElement(ci.getSourceModelUid());
449 if (sourceService.isRight() && (log.isDebugEnabled())) {
450 log.debug("Failed to fetch source service with id {} for proxy {}", ci.getSourceModelUid(), ci.getUniqueId());
452 Component fetchedSource = sourceService.left().value();
453 componentCache.put(fetchedSource.getUniqueId(), fetchedSource);
456 componentRI = fetchedComponent;
458 Map<String, ArtifactDefinition> toscaArtifacts = componentRI.getToscaArtifacts();
459 ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE);
460 if (artifactDefinition != null) {
461 String artifactName = artifactDefinition.getArtifactName();
462 files.put(IMPORTS_FILE_KEY, artifactName);
463 keyNameBuilder = new StringBuilder();
464 keyNameBuilder.append(fetchedComponent.getComponentType().toString().toLowerCase());
465 keyNameBuilder.append("-");
466 keyNameBuilder.append(ci.getComponentName());
467 importsListMember.put(keyNameBuilder.toString(), files);
468 imports.add(importsListMember);
469 dependecies.add(new ImmutableTriple<String, String, Component>(artifactName,
470 artifactDefinition.getEsId(), fetchedComponent));
472 if (!ModelConverter.isAtomicComponent(componentRI)) {
473 importsListMember = new HashMap<>();
474 Map<String, String> interfaceFiles = new HashMap<>();
475 interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactName));
476 keyNameBuilder.append("-interface");
477 importsListMember.put(keyNameBuilder.toString(), interfaceFiles);
478 imports.add(importsListMember);
484 public static String getInterfaceFilename(String artifactName) {
485 return artifactName.substring(0, artifactName.lastIndexOf('.')) + ToscaExportHandler.TOSCA_INTERFACE_NAME;
488 private Either<ToscaTemplate, ToscaError> convertNodeType(Component component, ToscaTemplate toscaNode,
489 Map<String, ToscaNodeType> nodeTypes) {
490 log.debug("start convert node type for {}", component.getUniqueId());
491 ToscaNodeType toscaNodeType = createNodeType(component);
493 Either<Map<String, DataTypeDefinition>, TitanOperationStatus> dataTypesEither = dataTypeCache.getAll();
494 if (dataTypesEither.isRight()) {
495 log.debug("Failed to fetch all data types :", dataTypesEither.right().value());
496 return Either.right(ToscaError.GENERAL_ERROR);
499 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
500 Either<ToscaNodeType, ToscaError> properties = propertyConvertor.convertProperties(component, toscaNodeType,
502 if (properties.isRight()) {
503 return Either.right(properties.right().value());
505 toscaNodeType = properties.left().value();
506 log.debug("Properties converted for {}", component.getUniqueId());
508 // Extracted to method for code reuse
509 return convertReqCapAndTypeName(component, toscaNode, nodeTypes, toscaNodeType, dataTypes);
512 private Either<ToscaTemplate, ToscaError> convertInterfaceNodeType(Component component, ToscaTemplate toscaNode,
513 Map<String, ToscaNodeType> nodeTypes) {
514 log.debug("start convert node type for {}", component.getUniqueId());
515 ToscaNodeType toscaNodeType = createNodeType(component);
517 Either<Map<String, DataTypeDefinition>, TitanOperationStatus> dataTypesEither = dataTypeCache.getAll();
518 if (dataTypesEither.isRight()) {
519 log.debug("Failed to fetch all data types :", dataTypesEither.right().value());
520 return Either.right(ToscaError.GENERAL_ERROR);
523 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
525 List<InputDefinition> inputDef = component.getInputs();
526 Map<String, ToscaProperty> inputs = new HashMap<>();
528 if (inputDef != null) {
529 inputDef.forEach(i -> {
530 ToscaProperty property = propertyConvertor.convertProperty(dataTypes, i, false);
531 inputs.put(i.getName(), property);
533 if (!inputs.isEmpty()) {
534 toscaNodeType.setProperties(inputs);
538 // Extracted to method for code reuse
539 return convertReqCapAndTypeName(component, toscaNode, nodeTypes, toscaNodeType, dataTypes);
542 private Either<ToscaTemplate, ToscaError> convertReqCapAndTypeName(Component component, ToscaTemplate toscaNode,
543 Map<String, ToscaNodeType> nodeTypes, ToscaNodeType toscaNodeType,
544 Map<String, DataTypeDefinition> dataTypes) {
545 Either<ToscaNodeType, ToscaError> capabilities = convertCapabilities(component, toscaNodeType, dataTypes);
546 if (capabilities.isRight()) {
547 return Either.right(capabilities.right().value());
549 toscaNodeType = capabilities.left().value();
550 log.debug("Capabilities converted for {}", component.getUniqueId());
552 Either<ToscaNodeType, ToscaError> requirements = capabiltyRequirementConvertor.convertRequirements(component,
554 if (requirements.isRight()) {
555 return Either.right(requirements.right().value());
557 toscaNodeType = requirements.left().value();
558 log.debug("Requirements converted for {}", component.getUniqueId());
560 String toscaResourceName;
561 switch (component.getComponentType()) {
563 toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition()
564 .getMetadataDataDefinition()).getToscaResourceName();
567 toscaResourceName = SERVICE_NODE_TYPE_PREFIX
568 + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName();
571 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
572 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
575 nodeTypes.put(toscaResourceName, toscaNodeType);
576 toscaNode.setNode_types(nodeTypes);
577 log.debug("finish convert node type for {}", component.getUniqueId());
578 return Either.left(toscaNode);
581 private Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplates(Component component,
582 List<ComponentInstance> componentInstances,
583 Map<String, List<ComponentInstanceProperty>> componentInstancesProperties,
584 Map<String, Component> componentCache, Map<String, DataTypeDefinition> dataTypes,
585 ToscaTopolgyTemplate topologyTemplate) {
587 Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplatesRes = null;
588 log.debug("start convert topology template for {} for type {}", component.getUniqueId(),
589 component.getComponentType());
590 Map<String, ToscaNodeTemplate> nodeTemplates = new HashMap<>();
591 Map<String, List<ComponentInstanceInput>> componentInstancesInputs = component.getComponentInstancesInputs();
593 Map<String, ToscaGroupTemplate> groupsMap = null;
594 for (ComponentInstance componentInstance : componentInstances) {
595 ToscaNodeTemplate nodeTemplate = new ToscaNodeTemplate();
596 nodeTemplate.setType(componentInstance.getToscaComponentName());
598 Either<Component, Boolean> originComponentRes = capabiltyRequirementConvertor
599 .getOriginComponent(componentCache, componentInstance);
600 if (originComponentRes.isRight()) {
601 convertNodeTemplatesRes = Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
604 Either<ToscaNodeTemplate, ToscaError> requirements = convertComponentInstanceRequirements(component,
605 componentInstance, component.getComponentInstancesRelations(), nodeTemplate,
606 originComponentRes.left().value(), componentCache);
607 if (requirements.isRight()) {
608 convertNodeTemplatesRes = Either.right(requirements.right().value());
611 String instanceUniqueId = componentInstance.getUniqueId();
612 log.debug("Component instance Requirements converted for instance {}", instanceUniqueId);
614 nodeTemplate = requirements.left().value();
616 Component originalComponent = componentCache.get(componentInstance.getActualComponentUid());
618 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy){
619 Component componentOfProxy = componentCache.get(componentInstance.getComponentUid());
620 nodeTemplate.setMetadata(convertMetadata(componentOfProxy, true, componentInstance));
622 nodeTemplate.setMetadata(convertMetadata(originalComponent, true, componentInstance));
625 Either<ToscaNodeTemplate, ToscaError> capabilities = capabiltyRequirementConvertor
626 .convertComponentInstanceCapabilties(componentInstance, dataTypes, nodeTemplate);
627 if (capabilities.isRight()) {
628 convertNodeTemplatesRes = Either.right(requirements.right().value());
631 log.debug("Component instance Capabilities converted for instance {}", instanceUniqueId);
633 nodeTemplate = capabilities.left().value();
634 Map<String, Object> props = new HashMap<>();
636 if (originalComponent.getComponentType() == ComponentTypeEnum.RESOURCE) {
637 // Adds the properties of parent component to map
638 addPropertiesOfParentComponent(dataTypes, componentInstance, originalComponent, props);
641 if (null != componentInstancesProperties && componentInstancesProperties.containsKey(instanceUniqueId)) {
642 addPropertiesOfComponentInstance(componentInstancesProperties, dataTypes, componentInstance,
643 instanceUniqueId, props);
646 if (componentInstancesInputs != null && componentInstancesInputs.containsKey(instanceUniqueId)) {
647 addComponentInstanceInputs(dataTypes, componentInstancesInputs, componentInstance, instanceUniqueId,
650 if (props != null && !props.isEmpty()) {
651 nodeTemplate.setProperties(props);
654 List<GroupInstance> groupInstances = componentInstance.getGroupInstances();
655 if (groupInstances != null) {
656 if (groupsMap == null) {
657 groupsMap = new HashMap<>();
659 for (GroupInstance groupInst : groupInstances) {
660 boolean addToTosca = true;
662 List<String> artifacts = groupInst.getArtifacts();
663 if (artifacts == null || artifacts.isEmpty()) {
668 ToscaGroupTemplate toscaGroup = convertGroupInstance(groupInst);
669 groupsMap.put(groupInst.getName(), toscaGroup);
674 nodeTemplates.put(componentInstance.getName(), nodeTemplate);
676 if (groupsMap != null) {
677 log.debug("instance groups added");
678 topologyTemplate.addGroups(groupsMap);
680 if (component.getComponentType() == ComponentTypeEnum.SERVICE && MapUtils.isNotEmpty(((Service) component).getForwardingPaths())) {
681 log.debug("Starting converting paths for component {}, name {}", component.getUniqueId(),
682 component.getName());
683 ForwardingPathToscaUtil.addForwardingPaths((Service) component, nodeTemplates, capabiltyRequirementConvertor, componentCache, toscaOperationFacade);
684 log.debug("Finished converting paths for component {}, name {}", component.getUniqueId(),
685 component.getName());
687 if (convertNodeTemplatesRes == null) {
688 convertNodeTemplatesRes = Either.left(nodeTemplates);
690 log.debug("finish convert topology template for {} for type {}", component.getUniqueId(),
691 component.getComponentType());
692 return convertNodeTemplatesRes;
695 private void addComponentInstanceInputs(Map<String, DataTypeDefinition> dataTypes,
696 Map<String, List<ComponentInstanceInput>> componentInstancesInputs, ComponentInstance componentInstance,
697 String instanceUniqueId, Map<String, Object> props) {
699 List<ComponentInstanceInput> instanceInputsList = componentInstancesInputs.get(instanceUniqueId);
700 if (instanceInputsList != null) {
701 instanceInputsList.forEach(input -> {
703 Supplier<String> supplier = () -> input.getValue() != null && !input.getValue().isEmpty()
704 ? input.getValue() : input.getDefaultValue();
705 convertAndAddValue(dataTypes, componentInstance, props, input, supplier);
710 private void addPropertiesOfComponentInstance(
711 Map<String, List<ComponentInstanceProperty>> componentInstancesProperties,
712 Map<String, DataTypeDefinition> dataTypes, ComponentInstance componentInstance, String instanceUniqueId,
713 Map<String, Object> props) {
715 if (!MapUtils.isEmpty(componentInstancesProperties)) {
716 componentInstancesProperties.get(instanceUniqueId).stream()
717 // Collects filtered properties to List
718 .collect(Collectors.toList()).stream()
719 // Converts and adds each value to property map
720 .forEach(prop -> convertAndAddValue(dataTypes, componentInstance, props, prop,
721 () -> prop.getValue()));
725 private void addPropertiesOfParentComponent(Map<String, DataTypeDefinition> dataTypes,
726 ComponentInstance componentInstance, Component componentOfInstance, Map<String, Object> props) {
728 List<PropertyDefinition> componentProperties = ((Resource) componentOfInstance).getProperties();
729 if (!CollectionUtils.isEmpty(componentProperties)) {
730 componentProperties.stream()
731 // Filters out properties with empty default values
732 .filter(prop -> !StringUtils.isEmpty(prop.getDefaultValue()))
733 // Collects filtered properties to List
734 .collect(Collectors.toList()).stream()
735 // Converts and adds each value to property map
736 .forEach(prop -> convertAndAddValue(dataTypes, componentInstance, props, prop,
737 () -> prop.getDefaultValue()));
743 * @param componentInstance
748 private void convertAndAddValue(Map<String, DataTypeDefinition> dataTypes, ComponentInstance componentInstance,
749 Map<String, Object> props, PropertyDefinition prop, Supplier<String> supplier) {
750 Object convertedValue = convertValue(dataTypes, componentInstance, prop, supplier);
751 if (!ToscaValueBaseConverter.isEmptyObjectValue(convertedValue)) {
752 props.put(prop.getName(), convertedValue);
756 private <T extends PropertyDefinition> Object convertValue(Map<String, DataTypeDefinition> dataTypes,
757 ComponentInstance componentInstance, T input, Supplier<String> supplier) {
758 log.debug("Convert property or input value {} for instance {}", input.getName(),
759 componentInstance.getUniqueId());
760 String propertyType = input.getType();
761 String innerType = null;
762 if (input.getSchema() != null && input.getSchema().getProperty() != null) {
763 innerType = input.getSchema().getProperty().getType();
765 return propertyConvertor.convertToToscaObject(propertyType, supplier.get(), innerType, dataTypes);
768 private ToscaGroupTemplate convertGroup(GroupDefinition group) {
769 ToscaGroupTemplate toscaGroup = new ToscaGroupTemplate();
770 Map<String, String> members = group.getMembers();
772 toscaGroup.setMembers(new ArrayList<String>(members.keySet()));
774 Supplier<String> supplGroupType = () -> group.getType();
775 Supplier<String> supplDescription = () -> group.getDescription();
776 Supplier<List<? extends GroupProperty>> supplProperties = () -> group.convertToGroupProperties();
777 Supplier<String> supplgroupName = () -> group.getName();
778 Supplier<String> supplInvariantUUID = () -> group.getInvariantUUID();
779 Supplier<String> supplGroupUUID = () -> group.getGroupUUID();
780 Supplier<String> supplVersion = () -> group.getVersion();
782 IToscaMetadata toscaMetadata = fillGroup(toscaGroup, supplProperties, supplDescription, supplgroupName,
783 supplInvariantUUID, supplGroupUUID, supplVersion, supplGroupType);
784 toscaGroup.setMetadata(toscaMetadata);
788 private ToscaGroupTemplate convertGroupInstance(GroupInstance groupInstance) {
789 ToscaGroupTemplate toscaGroup = new ToscaGroupTemplate();
791 Supplier<String> supplGroupType = () -> groupInstance.getType();
792 Supplier<String> supplDescription = () -> groupInstance.getDescription();
793 Supplier<List<? extends GroupProperty>> supplProperties = () -> groupInstance
794 .convertToGroupInstancesProperties();
795 Supplier<String> supplgroupName = () -> groupInstance.getGroupName();
796 Supplier<String> supplInvariantUUID = () -> groupInstance.getInvariantUUID();
797 Supplier<String> supplGroupUUID = () -> groupInstance.getGroupUUID();
798 Supplier<String> supplVersion = () -> groupInstance.getVersion();
800 IToscaMetadata toscaMetadata = fillGroup(toscaGroup, supplProperties, supplDescription, supplgroupName,
801 supplInvariantUUID, supplGroupUUID, supplVersion, supplGroupType);
803 toscaMetadata.setCustomizationUUID(groupInstance.getCustomizationUUID());
804 toscaGroup.setMetadata(toscaMetadata);
808 private IToscaMetadata fillGroup(ToscaGroupTemplate toscaGroup, Supplier<List<? extends GroupProperty>> props,
809 Supplier<String> description, Supplier<String> groupName, Supplier<String> invariantUUID,
810 Supplier<String> groupUUID, Supplier<String> version, Supplier<String> groupType) {
811 boolean isVfModule = groupType.get().equals(Constants.DEFAULT_GROUP_VF_MODULE) ? true : false;
812 toscaGroup.setType(groupType.get());
814 IToscaMetadata toscaMetadata;
816 toscaMetadata = new ToscaMetadata();
818 toscaMetadata = new VfModuleToscaMetadata();
820 Map<String, Object> properties = fillGroupProperties(props.get());
821 if (!properties.containsKey(VF_MODULE_DESC_KEY)
822 || StringUtils.isEmpty((String) properties.get(VF_MODULE_DESC_KEY))) {
823 properties.put(VF_MODULE_DESC_KEY, description.get());
825 toscaGroup.setProperties(properties);
827 toscaMetadata.setName(groupName.get());
828 toscaMetadata.setInvariantUUID(invariantUUID.get());
829 toscaMetadata.setUUID(groupUUID.get());
830 toscaMetadata.setVersion(version.get());
831 return toscaMetadata;
834 private Map<String, Object> fillGroupProperties(List<? extends GroupProperty> groupProps) {
835 Map<String, Object> properties = new HashMap<>();
836 if (groupProps != null) {
837 for (GroupProperty gp : groupProps) {
838 if (gp.getName().equals(Constants.IS_BASE)) {
839 Boolean isBase = Boolean.parseBoolean(gp.getValue());
840 String type = isBase ? VF_MODULE_TYPE_BASE : VF_MODULE_TYPE_EXPANSION;
841 properties.put(VF_MODULE_TYPE_KEY, type);
844 String type = gp.getType();
848 if (gp.getValue() != null) {
849 value = Integer.valueOf(gp.getValue());
853 if (gp.getValue() != null) {
854 value = Boolean.valueOf(gp.getValue());
859 value = gp.getValue();
862 properties.put(gp.getName(), value);
869 private ToscaNodeType createNodeType(Component component) {
870 ToscaNodeType toscaNodeType = new ToscaNodeType();
871 if (ModelConverter.isAtomicComponent(component)) {
872 if (((Resource) component).getDerivedFrom() != null) {
873 toscaNodeType.setDerived_from(((Resource) component).getDerivedFrom().get(0));
875 toscaNodeType.setDescription(component.getDescription()); // or
878 String derivedFrom = null != component.getDerivedFromGenericType() ? component.getDerivedFromGenericType()
879 : "tosca.nodes.Root";
880 toscaNodeType.setDerived_from(derivedFrom);
882 return toscaNodeType;
885 private Either<Map<String, ToscaNodeType>, ToscaError> createProxyNodeTypes(Map<String, Component> componentCache ,Component container ) {
887 Map<String, ToscaNodeType> nodeTypesMap = null;
888 Either<Map<String, ToscaNodeType>, ToscaError> res = Either.left(nodeTypesMap);
890 List<ComponentInstance> componetInstances = container.getComponentInstances();
892 if (componetInstances == null || componetInstances.isEmpty())
894 Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
895 List<ComponentInstance> proxyInst = componetInstances.stream()
896 .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceProxy.name()))
897 .collect(Collectors.toList());
898 if (proxyInst != null && !proxyInst.isEmpty()) {
899 for (ComponentInstance inst : proxyInst) {
900 serviceProxyInstanceList.put(inst.getToscaComponentName(), inst);
904 if (serviceProxyInstanceList.isEmpty())
906 ComponentParametersView filter = new ComponentParametersView(true);
907 filter.setIgnoreCapabilities(false);
908 filter.setIgnoreComponentInstances(false);
909 Either<Resource, StorageOperationStatus> serviceProxyOrigin = toscaOperationFacade
910 .getLatestByName("serviceProxy");
911 if (serviceProxyOrigin.isRight()) {
912 log.debug("Failed to fetch normative service proxy resource by tosca name, error {}",
913 serviceProxyOrigin.right().value());
914 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
916 Component origComponent = serviceProxyOrigin.left().value();
918 nodeTypesMap = new HashMap<>();
919 for (Entry<String, ComponentInstance> entryProxy : serviceProxyInstanceList.entrySet()) {
920 Component serviceComponent = null;
921 ComponentParametersView componentParametersView = new ComponentParametersView();
922 componentParametersView.disableAll();
923 componentParametersView.setIgnoreCategories(false);
924 Either<Component, StorageOperationStatus> service = toscaOperationFacade
925 .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
926 if (service.isRight()) {
927 log.debug("Failed to fetch resource with id {} for instance {}");
929 serviceComponent = service.left().value();
931 ToscaNodeType toscaNodeType = createProxyNodeType(componentCache , origComponent, serviceComponent, entryProxy.getValue());
932 nodeTypesMap.put(entryProxy.getKey(), toscaNodeType);
935 return Either.left(nodeTypesMap);
938 private ToscaNodeType createProxyNodeType(Map<String, Component> componentCache , Component origComponent, Component proxyComponent,
939 ComponentInstance instance) {
940 ToscaNodeType toscaNodeType = new ToscaNodeType();
941 String derivedFrom = ((Resource) origComponent).getToscaResourceName();
943 toscaNodeType.setDerived_from(derivedFrom);
944 Either<Map<String, DataTypeDefinition>, TitanOperationStatus> dataTypesEither = dataTypeCache.getAll();
945 if (dataTypesEither.isRight()) {
946 log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
948 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
949 Map<String, ToscaCapability> capabilities = this.capabiltyRequirementConvertor
950 .convertProxyCapabilities( componentCache ,origComponent, proxyComponent, instance, dataTypes);
952 toscaNodeType.setCapabilities(capabilities);
954 return toscaNodeType;
957 private Either<ToscaNodeTemplate, ToscaError> convertComponentInstanceRequirements(Component component,
958 ComponentInstance componentInstance, List<RequirementCapabilityRelDef> relations,
959 ToscaNodeTemplate nodeTypeTemplate, Component originComponent, Map<String, Component> componentCache) {
961 List<Map<String, ToscaTemplateRequirement>> toscaRequirements = new ArrayList<>();
962 if (!addRequirements(component, componentInstance, relations, originComponent, toscaRequirements, componentCache)) {
963 log.debug("Failed to convert component instance requirements for the component instance {}. ",
964 componentInstance.getName());
965 return Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
967 if (!toscaRequirements.isEmpty()) {
968 nodeTypeTemplate.setRequirements(toscaRequirements);
970 log.debug("Finished to convert requirements for the node type {} ", componentInstance.getName());
971 return Either.left(nodeTypeTemplate);
974 private boolean addRequirements(Component component, ComponentInstance componentInstance,
975 List<RequirementCapabilityRelDef> relations, Component originComponent,
976 List<Map<String, ToscaTemplateRequirement>> toscaRequirements, Map<String, Component> componentCache) {
978 List<RequirementCapabilityRelDef> filteredRelations = relations.stream()
979 .filter(p -> componentInstance.getUniqueId().equals(p.getFromNode())).collect(Collectors.toList());
980 if (CollectionUtils.isEmpty(filteredRelations)) {
983 result = !filteredRelations.stream().filter(rel -> !addRequirement(componentInstance, originComponent,
984 component.getComponentInstances(), rel, toscaRequirements, componentCache)).findFirst().isPresent();
989 private boolean addRequirement(ComponentInstance fromInstance, Component fromOriginComponent,
990 List<ComponentInstance> instancesList, RequirementCapabilityRelDef rel,
991 List<Map<String, ToscaTemplateRequirement>> toscaRequirements, Map<String, Component> componentCache) {
993 boolean result = true;
994 Map<String, List<RequirementDefinition>> reqMap = fromOriginComponent.getRequirements();
995 RelationshipInfo reqAndRelationshipPair = rel.getRelationships().get(0).getRelation();
996 Either<Component, StorageOperationStatus> getOriginRes = null;
997 Optional<RequirementDefinition> reqOpt = null;
998 Component toOriginComponent = null;
999 Optional<CapabilityDefinition> cap = null;
1001 ComponentInstance toInstance = instancesList.stream().filter(i -> rel.getToNode().equals(i.getUniqueId()))
1002 .findFirst().orElse(null);
1003 if (toInstance == null) {
1004 log.debug("Failed to find a relation from the node {} to the node {}", fromInstance.getName(),
1009 reqOpt = findRequirement(fromOriginComponent, reqMap, reqAndRelationshipPair, fromInstance.getUniqueId());
1010 if (!reqOpt.isPresent()) {
1011 log.debug("Failed to find a requirement with uniqueId {} on a component with uniqueId {}",
1012 reqAndRelationshipPair.getRequirementUid(), fromOriginComponent.getUniqueId());
1017 ComponentParametersView filter = new ComponentParametersView(true);
1018 filter.setIgnoreComponentInstances(false);
1019 filter.setIgnoreCapabilities(false);
1020 getOriginRes = toscaOperationFacade.getToscaElement(toInstance.getActualComponentUid(), filter);
1021 if (getOriginRes.isRight()) {
1022 log.debug("Failed to build substituted name for the requirement {}. Failed to get an origin component with uniqueId {}",
1023 reqOpt.get().getName(), toInstance.getActualComponentUid());
1028 toOriginComponent = getOriginRes.left().value();
1029 cap = toOriginComponent.getCapabilities().get(reqOpt.get().getCapability()).stream()
1030 .filter(c -> isCapabilityBelongToRelation(reqAndRelationshipPair, c)).findFirst();
1031 if (!cap.isPresent()) {
1032 cap = findCapability(reqAndRelationshipPair, toOriginComponent, fromOriginComponent, reqOpt.get(), fromInstance);
1033 if(!cap.isPresent()){
1035 log.debug("Failed to find a capability with name {} on a component with uniqueId {}",
1036 reqAndRelationshipPair.getCapability(), fromOriginComponent.getUniqueId());
1041 result = buildAndAddRequirement(toscaRequirements, fromOriginComponent, toOriginComponent, cap.get(),
1042 reqOpt.get(), reqAndRelationshipPair, toInstance, componentCache);
1047 private boolean isCapabilityBelongToRelation(RelationshipInfo reqAndRelationshipPair, CapabilityDefinition capability) {
1048 return capability.getName().equals(reqAndRelationshipPair.getCapability()) && (capability.getOwnerId() !=null && capability.getOwnerId().equals(reqAndRelationshipPair.getCapabilityOwnerId()));
1051 private Optional<CapabilityDefinition> findCapability(RelationshipInfo reqAndRelationshipPair, Component toOriginComponent, Component fromOriginComponent, RequirementDefinition requirement, ComponentInstance fromInstance) {
1052 Optional<CapabilityDefinition> cap = toOriginComponent.getCapabilities().get(requirement.getCapability()).stream().filter(c -> c.getType().equals(requirement.getCapability())).findFirst();
1053 if (!cap.isPresent()) {
1054 log.debug("Failed to find a capability with name {} on a component with uniqueId {}", reqAndRelationshipPair.getCapability(), fromOriginComponent.getUniqueId());
1059 private boolean buildAndAddRequirement(List<Map<String, ToscaTemplateRequirement>> toscaRequirements, Component fromOriginComponent, Component toOriginComponent, CapabilityDefinition capability, RequirementDefinition requirement, RelationshipInfo reqAndRelationshipPair, ComponentInstance toInstance, Map<String, Component> componentCache) {
1060 boolean result = true;
1061 Either<String, Boolean> buildReqNameRes = null;
1062 List<String> reducedPath = capability.getPath();
1063 if(capability.getOwnerId() !=null){
1064 reducedPath = capabiltyRequirementConvertor.getReducedPathByOwner(capability.getPath() , capability.getOwnerId() );
1066 Either<String, Boolean> buildCapNameRes = capabiltyRequirementConvertor.buildSubstitutedName(componentCache,
1067 toOriginComponent, reducedPath, reqAndRelationshipPair.getCapability());
1068 if (buildCapNameRes.isRight()) {
1070 "Failed to build a substituted capability name for the capability with name {} on a component with uniqueId {}",
1071 reqAndRelationshipPair.getCapability(), fromOriginComponent.getUniqueId());
1075 buildReqNameRes = capabiltyRequirementConvertor.buildSubstitutedName(componentCache, fromOriginComponent,
1076 requirement.getPath(), reqAndRelationshipPair.getRequirement());
1077 if (buildReqNameRes.isRight()) {
1079 "Failed to build a substituted requirement name for the requirement with name {} on a component with uniqueId {}",
1080 reqAndRelationshipPair.getRequirement(), fromOriginComponent.getUniqueId());
1085 ToscaTemplateRequirement toscaRequirement = new ToscaTemplateRequirement();
1086 Map<String, ToscaTemplateRequirement> toscaReqMap = new HashMap<>();
1087 toscaRequirement.setNode(toInstance.getName());
1088 toscaRequirement.setCapability(buildCapNameRes.left().value());
1089 toscaReqMap.put(buildReqNameRes.left().value(), toscaRequirement);
1090 toscaRequirements.add(toscaReqMap);
1095 private Optional<RequirementDefinition> findRequirement(Component fromOriginComponent, Map<String, List<RequirementDefinition>> reqMap, RelationshipInfo reqAndRelationshipPair, String fromInstanceId) {
1096 for(List<RequirementDefinition> reqList: reqMap.values()){
1097 Optional<RequirementDefinition> reqOpt = reqList.stream().filter(r -> isRequirementBelongToRelation(fromOriginComponent, reqAndRelationshipPair, r, fromInstanceId)).findFirst();
1098 if(reqOpt.isPresent()){
1102 return Optional.empty();
1106 * Allows detecting the requirement belonging to the received relationship
1107 * The detection logic is: A requirement belongs to a relationship IF 1.The
1108 * name of the requirement equals to the "requirement" field of the
1109 * relation; AND 2. In case of a non-atomic resource, OwnerId of the
1110 * requirement equals to requirementOwnerId of the relation OR uniqueId of
1111 * toInstance equals to capabilityOwnerId of the relation
1113 private boolean isRequirementBelongToRelation(Component originComponent, RelationshipInfo reqAndRelationshipPair, RequirementDefinition requirement, String fromInstanceId) {
1114 if (!StringUtils.equals(requirement.getName(), reqAndRelationshipPair.getRequirement())){
1115 log.debug("Failed to find a requirement with name {} and reqAndRelationshipPair {}",
1116 requirement.getName(), reqAndRelationshipPair.getRequirement());
1119 if (!ModelConverter.isAtomicComponent(originComponent))
1120 return isRequirementBelongToOwner(reqAndRelationshipPair, requirement, fromInstanceId, originComponent);
1124 private boolean isRequirementBelongToOwner(RelationshipInfo reqAndRelationshipPair, RequirementDefinition requirement, String fromInstanceId, Component originComponent) {
1125 return StringUtils.equals(requirement.getOwnerId(), reqAndRelationshipPair.getRequirementOwnerId()) || (isCvfc(originComponent) && StringUtils.equals(fromInstanceId, reqAndRelationshipPair.getRequirementOwnerId()));
1128 private boolean isCvfc(Component component) {
1129 if (component.getComponentType() != ComponentTypeEnum.RESOURCE)
1131 return ((Resource) component).getResourceType() == ResourceTypeEnum.CVFC;
1134 private Either<SubstitutionMapping, ToscaError> convertCapabilities(Component component,
1135 SubstitutionMapping substitutionMappings, Map<String, Component> componentCache) {
1137 Either<SubstitutionMapping, ToscaError> result = Either.left(substitutionMappings);
1138 Either<Map<String, String[]>, ToscaError> toscaCapabilitiesRes = capabiltyRequirementConvertor
1139 .convertSubstitutionMappingCapabilities(componentCache, component);
1140 if (toscaCapabilitiesRes.isRight()) {
1141 result = Either.right(toscaCapabilitiesRes.right().value());
1142 log.error("Failed convert capabilities for the component {}. ", component.getName());
1143 } else if (MapUtils.isNotEmpty(toscaCapabilitiesRes.left().value())) {
1144 substitutionMappings.setCapabilities(toscaCapabilitiesRes.left().value());
1145 log.debug("Finish convert capabilities for the component {}. ", component.getName());
1147 log.debug("Finished to convert capabilities for the component {}. ", component.getName());
1151 private Either<ToscaNodeType, ToscaError> convertCapabilities(Component component, ToscaNodeType nodeType,
1152 Map<String, DataTypeDefinition> dataTypes) {
1153 Map<String, ToscaCapability> toscaCapabilities = capabiltyRequirementConvertor.convertCapabilities(component,
1155 if (!toscaCapabilities.isEmpty()) {
1156 nodeType.setCapabilities(toscaCapabilities);
1158 log.debug("Finish convert Capabilities for node type");
1160 return Either.left(nodeType);
1163 private static class CustomRepresenter extends Representer {
1164 public CustomRepresenter() {
1166 // null representer is exceptional and it is stored as an instance
1168 this.nullRepresenter = new RepresentNull();
1173 protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue,
1175 if (propertyValue == null) {
1178 // skip not relevant for Tosca property
1179 if ("dependencies".equals(property.getName())) {
1182 NodeTuple defaultNode = super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
1184 return "_defaultp_".equals(property.getName())
1185 ? new NodeTuple(representData("default"), defaultNode.getValueNode()) : defaultNode;
1190 protected MappingNode representJavaBean(Set<Property> properties, Object javaBean) {
1191 // remove the bean type from the output yaml (!! ...)
1192 if (!classTags.containsKey(javaBean.getClass()))
1193 addClassTag(javaBean.getClass(), Tag.MAP);
1195 return super.representJavaBean(properties, javaBean);
1198 private class RepresentNull implements Represent {
1200 public Node representData(Object data) {
1201 // possible values are here http://yaml.org/type/null.html
1202 return representScalar(Tag.NULL, "");
1207 private static class UnsortedPropertyUtils extends PropertyUtils {
1209 protected Set<Property> createPropertySet(Class<? extends Object> type, BeanAccess bAccess)
1210 throws IntrospectionException {
1211 Collection<Property> fields = getPropertiesMap(type, BeanAccess.FIELD).values();
1212 return new LinkedHashSet<>(fields);