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 java.beans.IntrospectionException;
27 import java.util.ArrayList;
28 import java.util.Collection;
29 import java.util.HashMap;
30 import java.util.LinkedHashSet;
31 import java.util.List;
33 import java.util.Map.Entry;
34 import java.util.Optional;
36 import java.util.function.Supplier;
37 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 import fj.data.Either;
107 @org.springframework.stereotype.Component("tosca-export-handler")
108 public class ToscaExportHandler {
111 private ApplicationDataTypeCache dataTypeCache;
114 private ToscaOperationFacade toscaOperationFacade;
116 private CapabiltyRequirementConvertor capabiltyRequirementConvertor;
117 private PropertyConvertor propertyConvertor = PropertyConvertor.getInstance();
119 private static final Logger log = LoggerFactory.getLogger(ToscaExportHandler.class);
121 public static final String TOSCA_VERSION = "tosca_simple_yaml_1_1";
122 private static final String SERVICE_NODE_TYPE_PREFIX = "org.openecomp.service.";
123 private static final String IMPORTS_FILE_KEY = "file";
124 public static final String TOSCA_TEMPLATE_NAME = "-template.yml";
125 private static final String TOSCA_INTERFACE_NAME = "-interface.yml";
126 static final String ASSET_TOSCA_TEMPLATE = "assettoscatemplate";
127 private static final String VF_MODULE_TYPE_KEY = "vf_module_type";
128 private static final String VF_MODULE_DESC_KEY = "vf_module_description";
129 public static final String VOLUME_GROUP_KEY = "volume_group";
130 private static final String VF_MODULE_TYPE_BASE = "Base";
131 private static final String VF_MODULE_TYPE_EXPANSION = "Expansion";
132 private static final String FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION =
133 "convertToToscaTemplate - failed to get Default Imports section from configuration";
134 private static final String NOT_SUPPORTED_COMPONENT_TYPE = "Not supported component type {}";
135 protected static final List<Map<String, Map<String, String>>> DEFAULT_IMPORTS =
136 ConfigurationManager.getConfigurationManager().getConfiguration().getDefaultImports();
138 public Either<ToscaRepresentation, ToscaError> exportComponent(Component component) {
140 Either<ToscaTemplate, ToscaError> toscaTemplateRes = convertToToscaTemplate(component);
141 if (toscaTemplateRes.isRight()) {
142 return Either.right(toscaTemplateRes.right().value());
145 ToscaTemplate toscaTemplate = toscaTemplateRes.left().value();
146 ToscaRepresentation toscaRepresentation = this.createToscaRepresentation(toscaTemplate);
147 return Either.left(toscaRepresentation);
150 public Either<ToscaRepresentation, ToscaError> exportComponentInterface(Component component) {
151 if (null == DEFAULT_IMPORTS) {
152 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
153 return Either.right(ToscaError.GENERAL_ERROR);
156 ToscaTemplate toscaTemplate = new ToscaTemplate(TOSCA_VERSION);
157 toscaTemplate.setImports(new ArrayList<>(DEFAULT_IMPORTS));
158 Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
159 Either<ToscaTemplate, ToscaError> toscaTemplateRes =
160 convertInterfaceNodeType(component, toscaTemplate, nodeTypes);
161 if (toscaTemplateRes.isRight()) {
162 return Either.right(toscaTemplateRes.right().value());
165 toscaTemplate = toscaTemplateRes.left().value();
166 ToscaRepresentation toscaRepresentation = this.createToscaRepresentation(toscaTemplate);
167 return Either.left(toscaRepresentation);
170 public ToscaRepresentation createToscaRepresentation(ToscaTemplate toscaTemplate) {
171 CustomRepresenter representer = new CustomRepresenter();
172 DumperOptions options = new DumperOptions();
173 options.setAllowReadOnlyProperties(false);
174 options.setPrettyFlow(true);
176 options.setDefaultFlowStyle(FlowStyle.FLOW);
177 options.setCanonical(false);
179 representer.addClassTag(toscaTemplate.getClass(), Tag.MAP);
181 representer.setPropertyUtils(new UnsortedPropertyUtils());
182 Yaml yaml = new Yaml(representer, options);
184 String yamlAsString = yaml.dumpAsMap(toscaTemplate);
186 StringBuilder sb = new StringBuilder();
187 sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactHeader());
188 sb.append(yamlAsString);
189 sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactFooter());
191 ToscaRepresentation toscaRepresentation = new ToscaRepresentation();
192 toscaRepresentation.setMainYaml(sb.toString());
193 toscaRepresentation.setDependencies(toscaTemplate.getDependencies());
195 return toscaRepresentation;
198 public Either<ToscaTemplate, ToscaError> getDependencies(Component component) {
199 ToscaTemplate toscaTemplate = new ToscaTemplate(null);
200 Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports =
201 fillImports(component, toscaTemplate);
202 if (fillImports.isRight()) {
203 return Either.right(fillImports.right().value());
205 return Either.left(fillImports.left().value().left);
208 private Either<ToscaTemplate, ToscaError> convertToToscaTemplate(Component component) {
209 if (null == DEFAULT_IMPORTS) {
210 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
211 return Either.right(ToscaError.GENERAL_ERROR);
214 log.trace("start tosca export for {}", component.getUniqueId());
215 ToscaTemplate toscaTemplate = new ToscaTemplate(TOSCA_VERSION);
217 toscaTemplate.setMetadata(convertMetadata(component));
218 toscaTemplate.setImports(new ArrayList<>(DEFAULT_IMPORTS));
219 Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
220 if (ModelConverter.isAtomicComponent(component)) {
221 log.trace("convert component as node type");
222 return convertNodeType(component, toscaTemplate, nodeTypes);
224 log.trace("convert component as topology template");
225 return convertToscaTemplate(component, toscaTemplate);
230 private Either<ToscaTemplate, ToscaError> convertToscaTemplate(Component component, ToscaTemplate toscaNode) {
232 Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> importsRes =
233 fillImports(component, toscaNode);
234 if (importsRes.isRight()) {
235 return Either.right(importsRes.right().value());
237 toscaNode = importsRes.left().value().left;
238 Map<String, Component> componentCache = importsRes.left().value().right;
239 Either<Map<String, ToscaNodeType>, ToscaError> nodeTypesMapEither =
240 createProxyNodeTypes(componentCache, component);
241 if (nodeTypesMapEither.isRight()) {
242 log.debug("Failed to fetch normative service proxy resource by tosca name, error {}",
243 nodeTypesMapEither.right().value());
244 return Either.right(nodeTypesMapEither.right().value());
246 Map<String, ToscaNodeType> nodeTypesMap = nodeTypesMapEither.left().value();
247 if (nodeTypesMap != null && !nodeTypesMap.isEmpty()) {
248 toscaNode.setNode_types(nodeTypesMap);
252 Either<Map<String, DataTypeDefinition>, TitanOperationStatus> dataTypesEither = dataTypeCache.getAll();
253 if (dataTypesEither.isRight()) {
254 log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
255 return Either.right(ToscaError.GENERAL_ERROR);
257 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
259 ToscaTopolgyTemplate topologyTemplate = new ToscaTopolgyTemplate();
261 Either<ToscaTopolgyTemplate, ToscaError> inputs = fillInputs(component, topologyTemplate, dataTypes);
262 if (inputs.isRight()) {
263 return Either.right(inputs.right().value());
265 topologyTemplate = inputs.left().value();
267 List<ComponentInstance> componentInstances = component.getComponentInstances();
268 Map<String, List<ComponentInstanceProperty>> componentInstancesProperties =
269 component.getComponentInstancesProperties();
270 List<GroupDefinition> groups = component.getGroups();
271 if (componentInstances != null && !componentInstances.isEmpty()) {
273 Either<Map<String, ToscaNodeTemplate>, ToscaError> nodeTemplates =
274 convertNodeTemplates(component, componentInstances, componentInstancesProperties, componentCache,
275 dataTypes, topologyTemplate);
276 if (nodeTemplates.isRight()) {
277 return Either.right(nodeTemplates.right().value());
279 log.debug("node templates converted");
281 topologyTemplate.setNode_templates(nodeTemplates.left().value());
283 Map<String, ToscaGroupTemplate> groupsMap;
284 if (groups != null && !groups.isEmpty()) {
285 groupsMap = new HashMap<>();
286 for (GroupDefinition group : groups) {
287 boolean addToTosca = true;
288 if (group.getType().equals(Constants.DEFAULT_GROUP_VF_MODULE)) {
289 List<String> artifacts = group.getArtifacts();
290 if (artifacts == null || artifacts.isEmpty()) {
295 ToscaGroupTemplate toscaGroup = convertGroup(group);
296 groupsMap.put(group.getName(), toscaGroup);
300 log.debug("groups converted");
301 topologyTemplate.addGroups(groupsMap);
303 SubstitutionMapping substitutionMapping = new SubstitutionMapping();
304 String toscaResourceName;
305 switch (component.getComponentType()) {
307 toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition()
308 .getMetadataDataDefinition())
309 .getToscaResourceName();
312 toscaResourceName = SERVICE_NODE_TYPE_PREFIX + component.getComponentMetadataDefinition()
313 .getMetadataDataDefinition().getSystemName();
316 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
317 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
319 substitutionMapping.setNode_type(toscaResourceName);
321 Either<SubstitutionMapping, ToscaError> capabilities =
322 convertCapabilities(component, substitutionMapping, componentCache);
323 if (capabilities.isRight()) {
324 return Either.right(capabilities.right().value());
326 substitutionMapping = capabilities.left().value();
328 Either<SubstitutionMapping, ToscaError> requirements = capabiltyRequirementConvertor
329 .convertSubstitutionMappingRequirements(
330 componentCache, component,
331 substitutionMapping);
332 if (requirements.isRight()) {
333 return Either.right(requirements.right().value());
335 substitutionMapping = requirements.left().value();
337 topologyTemplate.setSubstitution_mappings(substitutionMapping);
339 toscaNode.setTopology_template(topologyTemplate);
340 return Either.left(toscaNode);
343 private Either<ToscaTopolgyTemplate, ToscaError> fillInputs(Component component,
344 ToscaTopolgyTemplate topologyTemplate, Map<String, DataTypeDefinition> dataTypes) {
345 if (log.isDebugEnabled()) {
346 log.debug("fillInputs for component {}", component.getUniqueId());
348 List<InputDefinition> inputDef = component.getInputs();
349 Map<String, ToscaProperty> inputs = new HashMap<>();
351 if (inputDef != null) {
352 inputDef.forEach(i -> {
353 ToscaProperty property = propertyConvertor.convertProperty(dataTypes, i, false);
354 inputs.put(i.getName(), property);
356 if (!inputs.isEmpty()) {
357 topologyTemplate.setInputs(inputs);
360 return Either.left(topologyTemplate);
363 private ToscaMetadata convertMetadata(Component component) {
364 return convertMetadata(component, false, null);
367 private ToscaMetadata convertMetadata(Component component, boolean isInstance,
368 ComponentInstance componentInstance) {
369 ToscaMetadata toscaMetadata = new ToscaMetadata();
370 toscaMetadata.setInvariantUUID(component.getInvariantUUID());
371 toscaMetadata.setUUID(component.getUUID());
372 toscaMetadata.setDescription(component.getDescription());
373 toscaMetadata.setName(component.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
375 List<CategoryDefinition> categories = component.getCategories();
376 CategoryDefinition categoryDefinition = categories.get(0);
377 toscaMetadata.setCategory(categoryDefinition.getName());
380 toscaMetadata.setVersion(component.getVersion());
381 toscaMetadata.setCustomizationUUID(componentInstance.getCustomizationUUID());
382 if (componentInstance.getSourceModelInvariant() != null && !componentInstance.getSourceModelInvariant()
384 toscaMetadata.setVersion(componentInstance.getComponentVersion());
385 toscaMetadata.setSourceModelInvariant(componentInstance.getSourceModelInvariant());
386 toscaMetadata.setSourceModelUuid(componentInstance.getSourceModelUuid());
387 toscaMetadata.setSourceModelName(componentInstance.getSourceModelName());
388 toscaMetadata.setName(
389 componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceProxy.getDisplayValue());
390 toscaMetadata.setDescription(componentInstance.getDescription());
394 switch (component.getComponentType()) {
396 Resource resource = (Resource) component;
398 if (isInstance && componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
399 toscaMetadata.setType(componentInstance.getOriginType().getDisplayValue());
401 toscaMetadata.setType(resource.getResourceType().name());
403 toscaMetadata.setSubcategory(categoryDefinition.getSubcategories().get(0).getName());
404 toscaMetadata.setResourceVendor(resource.getVendorName());
405 toscaMetadata.setResourceVendorRelease(resource.getVendorRelease());
406 toscaMetadata.setResourceVendorModelNumber(resource.getResourceVendorModelNumber());
409 Service service = (Service) component;
410 toscaMetadata.setType(component.getComponentType().getValue());
411 toscaMetadata.setServiceType(service.getServiceType());
412 toscaMetadata.setServiceRole(service.getServiceRole());
413 toscaMetadata.setEnvironmentContext(service.getEnvironmentContext());
416 toscaMetadata.setServiceEcompNaming(((Service) component).isEcompGeneratedNaming());
417 toscaMetadata.setEcompGeneratedNaming(((Service) component).isEcompGeneratedNaming());
418 toscaMetadata.setNamingPolicy(((Service) component).getNamingPolicy());
422 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
424 return toscaMetadata;
427 private Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports(Component component,
428 ToscaTemplate toscaTemplate) {
430 if (null == DEFAULT_IMPORTS) {
431 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
432 return Either.right(ToscaError.GENERAL_ERROR);
434 Map<String, Component> componentCache = new HashMap<>();
436 if (!ModelConverter.isAtomicComponent(component)) {
437 List<ComponentInstance> componentInstances = component.getComponentInstances();
438 if (componentInstances != null && !componentInstances.isEmpty()) {
440 List<Map<String, Map<String, String>>> additionalImports =
441 toscaTemplate.getImports() == null ? new ArrayList<>(DEFAULT_IMPORTS) :
442 new ArrayList<>(toscaTemplate.getImports());
444 List<Triple<String, String, Component>> dependecies = new ArrayList<>();
446 Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
447 ArtifactDefinition artifactDefinition = toscaArtifacts.get(ToscaExportHandler.ASSET_TOSCA_TEMPLATE);
449 Map<String, Map<String, String>> importsListMember = new HashMap<>();
450 Map<String, String> interfaceFiles = new HashMap<>();
451 interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactDefinition.getArtifactName()));
452 StringBuilder keyNameBuilder = new StringBuilder();
453 keyNameBuilder.append(component.getComponentType().toString().toLowerCase());
454 keyNameBuilder.append("-");
455 keyNameBuilder.append(component.getName());
456 keyNameBuilder.append("-interface");
457 importsListMember.put(keyNameBuilder.toString(), interfaceFiles);
458 additionalImports.add(importsListMember);
460 componentInstances.forEach(ci -> createDependency(componentCache, additionalImports, dependecies, ci));
461 toscaTemplate.setDependencies(dependecies);
462 toscaTemplate.setImports(additionalImports);
465 log.debug("currently imports supported for VF and service only");
467 return Either.left(new ImmutablePair<ToscaTemplate, Map<String, Component>>(toscaTemplate, componentCache));
470 private void createDependency(Map<String, Component> componentCache, List<Map<String, Map<String, String>>> imports,
471 List<Triple<String, String, Component>> dependecies, ComponentInstance ci) {
472 Map<String, String> files = new HashMap<>();
473 Map<String, Map<String, String>> importsListMember = new HashMap<>();
474 StringBuilder keyNameBuilder;
476 Component componentRI = componentCache.get(ci.getComponentUid());
477 if (componentRI == null) {
478 // all resource must be only once!
479 Either<Component, StorageOperationStatus> resource =
480 toscaOperationFacade.getToscaFullElement(ci.getComponentUid());
481 if ((resource.isRight()) && (log.isDebugEnabled())) {
482 log.debug("Failed to fetch resource with id {} for instance {}", ci.getComponentUid(),
487 Component fetchedComponent = resource.left().value();
488 componentCache.put(fetchedComponent.getUniqueId(), fetchedComponent);
490 if (ci.getOriginType() == OriginTypeEnum.ServiceProxy) {
491 Either<Component, StorageOperationStatus> sourceService =
492 toscaOperationFacade.getToscaFullElement(ci.getSourceModelUid());
493 if (sourceService.isRight() && (log.isDebugEnabled())) {
494 log.debug("Failed to fetch source service with id {} for proxy {}", ci.getSourceModelUid(),
497 Component fetchedSource = sourceService.left().value();
498 componentCache.put(fetchedSource.getUniqueId(), fetchedSource);
501 componentRI = fetchedComponent;
503 Map<String, ArtifactDefinition> toscaArtifacts = componentRI.getToscaArtifacts();
504 ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE);
505 if (artifactDefinition != null) {
506 String artifactName = artifactDefinition.getArtifactName();
507 files.put(IMPORTS_FILE_KEY, artifactName);
508 keyNameBuilder = new StringBuilder();
509 keyNameBuilder.append(fetchedComponent.getComponentType().toString().toLowerCase());
510 keyNameBuilder.append("-");
511 keyNameBuilder.append(ci.getComponentName());
512 importsListMember.put(keyNameBuilder.toString(), files);
513 imports.add(importsListMember);
515 .add(new ImmutableTriple<String, String, Component>(artifactName, artifactDefinition.getEsId(),
518 if (!ModelConverter.isAtomicComponent(componentRI)) {
519 importsListMember = new HashMap<>();
520 Map<String, String> interfaceFiles = new HashMap<>();
521 interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactName));
522 keyNameBuilder.append("-interface");
523 importsListMember.put(keyNameBuilder.toString(), interfaceFiles);
524 imports.add(importsListMember);
530 public static String getInterfaceFilename(String artifactName) {
531 return artifactName.substring(0, artifactName.lastIndexOf('.')) + ToscaExportHandler.TOSCA_INTERFACE_NAME;
534 private Either<ToscaTemplate, ToscaError> convertNodeType(Component component, ToscaTemplate toscaNode,
535 Map<String, ToscaNodeType> nodeTypes) {
536 log.debug("start convert node type for {}", component.getUniqueId());
537 ToscaNodeType toscaNodeType = createNodeType(component);
539 Either<Map<String, DataTypeDefinition>, TitanOperationStatus> dataTypesEither = dataTypeCache.getAll();
540 if (dataTypesEither.isRight()) {
541 log.debug("Failed to fetch all data types :", dataTypesEither.right().value());
542 return Either.right(ToscaError.GENERAL_ERROR);
545 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
546 Either<ToscaNodeType, ToscaError> properties =
547 propertyConvertor.convertProperties(component, toscaNodeType, dataTypes);
548 if (properties.isRight()) {
549 return Either.right(properties.right().value());
551 toscaNodeType = properties.left().value();
552 log.debug("Properties converted for {}", component.getUniqueId());
554 // Extracted to method for code reuse
555 return convertReqCapAndTypeName(component, toscaNode, nodeTypes, toscaNodeType, dataTypes);
558 private Either<ToscaTemplate, ToscaError> convertInterfaceNodeType(Component component, ToscaTemplate toscaNode,
559 Map<String, ToscaNodeType> nodeTypes) {
560 log.debug("start convert node type for {}", component.getUniqueId());
563 toscaNode.setInterface_types(addInterfaceTypeElement(component));
565 Either<Map<String, DataTypeDefinition>, TitanOperationStatus> dataTypesEither = dataTypeCache.getAll();
566 if (dataTypesEither.isRight()) {
567 log.debug("Failed to fetch all data types :", dataTypesEither.right().value());
568 return Either.right(ToscaError.GENERAL_ERROR);
571 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
573 List<InputDefinition> inputDef = component.getInputs();
574 Map<String, ToscaProperty> inputs = new HashMap<>();
575 ToscaNodeType toscaNodeType = createNodeType(component);
576 if (inputDef != null) {
577 inputDef.forEach(i -> {
578 ToscaProperty property = propertyConvertor.convertProperty(dataTypes, i, false);
579 inputs.put(i.getName(), property);
581 if (!inputs.isEmpty()) {
582 toscaNodeType.setProperties(inputs);
583 addInterfaceDefinitionElement(component, toscaNodeType);
589 // Extracted to method for code reuse
590 return convertReqCapAndTypeName(component, toscaNode, nodeTypes, toscaNodeType, dataTypes);
593 private Either<ToscaTemplate, ToscaError> convertReqCapAndTypeName(Component component, ToscaTemplate toscaNode,
594 Map<String, ToscaNodeType> nodeTypes, ToscaNodeType toscaNodeType,
595 Map<String, DataTypeDefinition> dataTypes) {
596 Either<ToscaNodeType, ToscaError> capabilities = convertCapabilities(component, toscaNodeType, dataTypes);
597 if (capabilities.isRight()) {
598 return Either.right(capabilities.right().value());
600 toscaNodeType = capabilities.left().value();
601 log.debug("Capabilities converted for {}", component.getUniqueId());
603 Either<ToscaNodeType, ToscaError> requirements =
604 capabiltyRequirementConvertor.convertRequirements(component, toscaNodeType);
605 if (requirements.isRight()) {
606 return Either.right(requirements.right().value());
608 toscaNodeType = requirements.left().value();
609 log.debug("Requirements converted for {}", component.getUniqueId());
611 String toscaResourceName;
612 switch (component.getComponentType()) {
614 toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition()
615 .getMetadataDataDefinition())
616 .getToscaResourceName();
619 toscaResourceName = SERVICE_NODE_TYPE_PREFIX + component.getComponentMetadataDefinition()
620 .getMetadataDataDefinition().getSystemName();
623 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
624 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
627 nodeTypes.put(toscaResourceName, toscaNodeType);
628 toscaNode.setNode_types(nodeTypes);
629 log.debug("finish convert node type for {}", component.getUniqueId());
630 return Either.left(toscaNode);
633 private Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplates(Component component,
634 List<ComponentInstance> componentInstances,
635 Map<String, List<ComponentInstanceProperty>> componentInstancesProperties,
636 Map<String, Component> componentCache, Map<String, DataTypeDefinition> dataTypes,
637 ToscaTopolgyTemplate topologyTemplate) {
639 Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplatesRes = null;
640 log.debug("start convert topology template for {} for type {}", component.getUniqueId(),
641 component.getComponentType());
642 Map<String, ToscaNodeTemplate> nodeTemplates = new HashMap<>();
643 Map<String, List<ComponentInstanceInput>> componentInstancesInputs = component.getComponentInstancesInputs();
645 Map<String, ToscaGroupTemplate> groupsMap = null;
646 for (ComponentInstance componentInstance : componentInstances) {
647 ToscaNodeTemplate nodeTemplate = new ToscaNodeTemplate();
648 nodeTemplate.setType(componentInstance.getToscaComponentName());
650 Either<Component, Boolean> originComponentRes =
651 capabiltyRequirementConvertor.getOriginComponent(componentCache, componentInstance);
652 if (originComponentRes.isRight()) {
653 convertNodeTemplatesRes = Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
656 Either<ToscaNodeTemplate, ToscaError> requirements =
657 convertComponentInstanceRequirements(component, componentInstance,
658 component.getComponentInstancesRelations(), nodeTemplate, originComponentRes.left().value(),
660 if (requirements.isRight()) {
661 convertNodeTemplatesRes = Either.right(requirements.right().value());
664 String instanceUniqueId = componentInstance.getUniqueId();
665 log.debug("Component instance Requirements converted for instance {}", instanceUniqueId);
667 nodeTemplate = requirements.left().value();
669 Component originalComponent = componentCache.get(componentInstance.getActualComponentUid());
671 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
672 Component componentOfProxy = componentCache.get(componentInstance.getComponentUid());
673 nodeTemplate.setMetadata(convertMetadata(componentOfProxy, true, componentInstance));
675 nodeTemplate.setMetadata(convertMetadata(originalComponent, true, componentInstance));
678 Either<ToscaNodeTemplate, ToscaError> capabilities = capabiltyRequirementConvertor
679 .convertComponentInstanceCapabilties(
680 componentInstance, dataTypes,
682 if (capabilities.isRight()) {
683 convertNodeTemplatesRes = Either.right(capabilities.right().value());
686 log.debug("Component instance Capabilities converted for instance {}", instanceUniqueId);
688 nodeTemplate = capabilities.left().value();
689 Map<String, Object> props = new HashMap<>();
691 if (originalComponent.getComponentType() == ComponentTypeEnum.RESOURCE) {
692 // Adds the properties of parent component to map
693 addPropertiesOfParentComponent(dataTypes, componentInstance, originalComponent, props);
696 if (null != componentInstancesProperties && componentInstancesProperties.containsKey(instanceUniqueId)) {
697 addPropertiesOfComponentInstance(componentInstancesProperties, dataTypes, componentInstance,
698 instanceUniqueId, props);
701 if (componentInstancesInputs != null && componentInstancesInputs.containsKey(instanceUniqueId)) {
702 addComponentInstanceInputs(dataTypes, componentInstancesInputs, componentInstance, instanceUniqueId,
705 if (props != null && !props.isEmpty()) {
706 nodeTemplate.setProperties(props);
709 List<GroupInstance> groupInstances = componentInstance.getGroupInstances();
710 if (groupInstances != null) {
711 if (groupsMap == null) {
712 groupsMap = new HashMap<>();
714 for (GroupInstance groupInst : groupInstances) {
715 boolean addToTosca = true;
717 List<String> artifacts = groupInst.getArtifacts();
718 if (artifacts == null || artifacts.isEmpty()) {
723 ToscaGroupTemplate toscaGroup = convertGroupInstance(groupInst);
724 groupsMap.put(groupInst.getName(), toscaGroup);
729 nodeTemplates.put(componentInstance.getName(), nodeTemplate);
731 if (groupsMap != null) {
732 log.debug("instance groups added");
733 topologyTemplate.addGroups(groupsMap);
735 if (component.getComponentType() == ComponentTypeEnum.SERVICE && MapUtils.isNotEmpty(
736 ((Service) component).getForwardingPaths())) {
737 log.debug("Starting converting paths for component {}, name {}", component.getUniqueId(),
738 component.getName());
739 ForwardingPathToscaUtil
740 .addForwardingPaths((Service) component, nodeTemplates, capabiltyRequirementConvertor,
741 componentCache, toscaOperationFacade);
742 log.debug("Finished converting paths for component {}, name {}", component.getUniqueId(),
743 component.getName());
745 if (convertNodeTemplatesRes == null) {
746 convertNodeTemplatesRes = Either.left(nodeTemplates);
748 log.debug("finish convert topology template for {} for type {}", component.getUniqueId(),
749 component.getComponentType());
750 return convertNodeTemplatesRes;
753 private void addComponentInstanceInputs(Map<String, DataTypeDefinition> dataTypes,
754 Map<String, List<ComponentInstanceInput>> componentInstancesInputs, ComponentInstance componentInstance,
755 String instanceUniqueId, Map<String, Object> props) {
757 List<ComponentInstanceInput> instanceInputsList = componentInstancesInputs.get(instanceUniqueId);
758 if (instanceInputsList != null) {
759 instanceInputsList.forEach(input -> {
761 Supplier<String> supplier =
762 () -> input.getValue() != null && !input.getValue().isEmpty() ? input.getValue() :
763 input.getDefaultValue();
764 convertAndAddValue(dataTypes, componentInstance, props, input, supplier);
769 private void addPropertiesOfComponentInstance(
770 Map<String, List<ComponentInstanceProperty>> componentInstancesProperties,
771 Map<String, DataTypeDefinition> dataTypes, ComponentInstance componentInstance, String instanceUniqueId,
772 Map<String, Object> props) {
774 if (!MapUtils.isEmpty(componentInstancesProperties)) {
775 componentInstancesProperties.get(instanceUniqueId).stream()
776 // Collects filtered properties to List
777 .collect(Collectors.toList()).stream()
778 // Converts and adds each value to property map
779 .forEach(prop -> convertAndAddValue(dataTypes, componentInstance, props, prop,
780 () -> prop.getValue()));
784 private void addPropertiesOfParentComponent(Map<String, DataTypeDefinition> dataTypes,
785 ComponentInstance componentInstance, Component componentOfInstance, Map<String, Object> props) {
787 List<PropertyDefinition> componentProperties = ((Resource) componentOfInstance).getProperties();
788 if (!CollectionUtils.isEmpty(componentProperties)) {
789 componentProperties.stream()
790 // Filters out properties with empty default values
791 .filter(prop -> !StringUtils.isEmpty(prop.getDefaultValue()))
792 // Collects filtered properties to List
793 .collect(Collectors.toList()).stream()
794 // Converts and adds each value to property map
795 .forEach(prop -> convertAndAddValue(dataTypes, componentInstance, props, prop,
796 () -> prop.getDefaultValue()));
802 * @param componentInstance
807 private void convertAndAddValue(Map<String, DataTypeDefinition> dataTypes, ComponentInstance componentInstance,
808 Map<String, Object> props, PropertyDefinition prop, Supplier<String> supplier) {
809 Object convertedValue = convertValue(dataTypes, componentInstance, prop, supplier);
810 if (!ToscaValueBaseConverter.isEmptyObjectValue(convertedValue)) {
811 props.put(prop.getName(), convertedValue);
815 private <T extends PropertyDefinition> Object convertValue(Map<String, DataTypeDefinition> dataTypes,
816 ComponentInstance componentInstance, T input, Supplier<String> supplier) {
817 log.debug("Convert property or input value {} for instance {}", input.getName(),
818 componentInstance.getUniqueId());
819 String propertyType = input.getType();
820 String innerType = null;
821 if (input.getSchema() != null && input.getSchema().getProperty() != null) {
822 innerType = input.getSchema().getProperty().getType();
824 return propertyConvertor.convertToToscaObject(propertyType, supplier.get(), innerType, dataTypes);
827 private ToscaGroupTemplate convertGroup(GroupDefinition group) {
828 ToscaGroupTemplate toscaGroup = new ToscaGroupTemplate();
829 Map<String, String> members = group.getMembers();
830 if (members != null) {
831 toscaGroup.setMembers(new ArrayList<String>(members.keySet()));
834 Supplier<String> supplGroupType = () -> group.getType();
835 Supplier<String> supplDescription = () -> group.getDescription();
836 Supplier<List<? extends GroupProperty>> supplProperties = () -> group.convertToGroupProperties();
837 Supplier<String> supplgroupName = () -> group.getName();
838 Supplier<String> supplInvariantUUID = () -> group.getInvariantUUID();
839 Supplier<String> supplGroupUUID = () -> group.getGroupUUID();
840 Supplier<String> supplVersion = () -> group.getVersion();
842 IToscaMetadata toscaMetadata =
843 fillGroup(toscaGroup, supplProperties, supplDescription, supplgroupName, supplInvariantUUID,
844 supplGroupUUID, supplVersion, supplGroupType);
845 toscaGroup.setMetadata(toscaMetadata);
849 private ToscaGroupTemplate convertGroupInstance(GroupInstance groupInstance) {
850 ToscaGroupTemplate toscaGroup = new ToscaGroupTemplate();
852 Supplier<String> supplGroupType = () -> groupInstance.getType();
853 Supplier<String> supplDescription = () -> groupInstance.getDescription();
854 Supplier<List<? extends GroupProperty>> supplProperties =
855 () -> groupInstance.convertToGroupInstancesProperties();
856 Supplier<String> supplgroupName = () -> groupInstance.getGroupName();
857 Supplier<String> supplInvariantUUID = () -> groupInstance.getInvariantUUID();
858 Supplier<String> supplGroupUUID = () -> groupInstance.getGroupUUID();
859 Supplier<String> supplVersion = () -> groupInstance.getVersion();
861 IToscaMetadata toscaMetadata =
862 fillGroup(toscaGroup, supplProperties, supplDescription, supplgroupName, supplInvariantUUID,
863 supplGroupUUID, supplVersion, supplGroupType);
865 toscaMetadata.setCustomizationUUID(groupInstance.getCustomizationUUID());
866 toscaGroup.setMetadata(toscaMetadata);
870 private IToscaMetadata fillGroup(ToscaGroupTemplate toscaGroup, Supplier<List<? extends GroupProperty>> props,
871 Supplier<String> description, Supplier<String> groupName, Supplier<String> invariantUUID,
872 Supplier<String> groupUUID, Supplier<String> version, Supplier<String> groupType) {
873 boolean isVfModule = groupType.get().equals(Constants.DEFAULT_GROUP_VF_MODULE) ? true : false;
874 toscaGroup.setType(groupType.get());
876 IToscaMetadata toscaMetadata;
878 toscaMetadata = new ToscaMetadata();
880 toscaMetadata = new VfModuleToscaMetadata();
882 Map<String, Object> properties = fillGroupProperties(props.get());
883 if (!properties.containsKey(VF_MODULE_DESC_KEY) || StringUtils.isEmpty(
884 (String) properties.get(VF_MODULE_DESC_KEY))) {
885 properties.put(VF_MODULE_DESC_KEY, description.get());
887 toscaGroup.setProperties(properties);
889 toscaMetadata.setName(groupName.get());
890 toscaMetadata.setInvariantUUID(invariantUUID.get());
891 toscaMetadata.setUUID(groupUUID.get());
892 toscaMetadata.setVersion(version.get());
893 return toscaMetadata;
896 private Map<String, Object> fillGroupProperties(List<? extends GroupProperty> groupProps) {
897 Map<String, Object> properties = new HashMap<>();
898 if (groupProps != null) {
899 for (GroupProperty gp : groupProps) {
900 if (gp.getName().equals(Constants.IS_BASE)) {
901 Boolean isBase = Boolean.parseBoolean(gp.getValue());
902 String type = isBase ? VF_MODULE_TYPE_BASE : VF_MODULE_TYPE_EXPANSION;
903 properties.put(VF_MODULE_TYPE_KEY, type);
906 String type = gp.getType();
910 if (gp.getValue() != null) {
911 value = Integer.valueOf(gp.getValue());
915 if (gp.getValue() != null) {
916 value = Boolean.valueOf(gp.getValue());
921 value = gp.getValue();
924 properties.put(gp.getName(), value);
931 private ToscaNodeType createNodeType(Component component) {
932 ToscaNodeType toscaNodeType = new ToscaNodeType();
933 if (ModelConverter.isAtomicComponent(component)) {
934 if (((Resource) component).getDerivedFrom() != null) {
935 toscaNodeType.setDerived_from(((Resource) component).getDerivedFrom().get(0));
937 toscaNodeType.setDescription(component.getDescription()); // or
940 String derivedFrom = null != component.getDerivedFromGenericType() ? component.getDerivedFromGenericType() :
942 toscaNodeType.setDerived_from(derivedFrom);
944 return toscaNodeType;
947 private Either<Map<String, ToscaNodeType>, ToscaError> createProxyNodeTypes(Map<String, Component> componentCache,
948 Component container) {
950 Map<String, ToscaNodeType> nodeTypesMap = null;
951 Either<Map<String, ToscaNodeType>, ToscaError> res = Either.left(nodeTypesMap);
953 List<ComponentInstance> componetInstances = container.getComponentInstances();
955 if (componetInstances == null || componetInstances.isEmpty()) {
958 Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
959 List<ComponentInstance> proxyInst = componetInstances.stream().filter(p -> p.getOriginType().name()
960 .equals(OriginTypeEnum.ServiceProxy
962 .collect(Collectors.toList());
963 if (proxyInst != null && !proxyInst.isEmpty()) {
964 for (ComponentInstance inst : proxyInst) {
965 serviceProxyInstanceList.put(inst.getToscaComponentName(), inst);
969 if (serviceProxyInstanceList.isEmpty()) {
972 ComponentParametersView filter = new ComponentParametersView(true);
973 filter.setIgnoreCapabilities(false);
974 filter.setIgnoreComponentInstances(false);
975 Either<Resource, StorageOperationStatus> serviceProxyOrigin =
976 toscaOperationFacade.getLatestByName("serviceProxy");
977 if (serviceProxyOrigin.isRight()) {
978 log.debug("Failed to fetch normative service proxy resource by tosca name, error {}",
979 serviceProxyOrigin.right().value());
980 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
982 Component origComponent = serviceProxyOrigin.left().value();
984 nodeTypesMap = new HashMap<>();
985 for (Entry<String, ComponentInstance> entryProxy : serviceProxyInstanceList.entrySet()) {
986 Component serviceComponent = null;
987 ComponentParametersView componentParametersView = new ComponentParametersView();
988 componentParametersView.disableAll();
989 componentParametersView.setIgnoreCategories(false);
990 Either<Component, StorageOperationStatus> service = toscaOperationFacade.getToscaElement(
991 entryProxy.getValue().getSourceModelUid(), componentParametersView);
992 if (service.isRight()) {
993 log.debug("Failed to fetch resource with id {} for instance {}");
995 serviceComponent = service.left().value();
998 ToscaNodeType toscaNodeType =
999 createProxyNodeType(componentCache, origComponent, serviceComponent, entryProxy.getValue());
1000 nodeTypesMap.put(entryProxy.getKey(), toscaNodeType);
1003 return Either.left(nodeTypesMap);
1006 private ToscaNodeType createProxyNodeType(Map<String, Component> componentCache, Component origComponent,
1007 Component proxyComponent, ComponentInstance instance) {
1008 ToscaNodeType toscaNodeType = new ToscaNodeType();
1009 String derivedFrom = ((Resource) origComponent).getToscaResourceName();
1011 toscaNodeType.setDerived_from(derivedFrom);
1012 Either<Map<String, DataTypeDefinition>, TitanOperationStatus> dataTypesEither = dataTypeCache.getAll();
1013 if (dataTypesEither.isRight()) {
1014 log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
1016 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
1017 Map<String, ToscaCapability> capabilities = this.capabiltyRequirementConvertor
1018 .convertProxyCapabilities(componentCache, origComponent,
1019 proxyComponent, instance, dataTypes);
1021 toscaNodeType.setCapabilities(capabilities);
1023 return toscaNodeType;
1026 private Either<ToscaNodeTemplate, ToscaError> convertComponentInstanceRequirements(Component component,
1027 ComponentInstance componentInstance, List<RequirementCapabilityRelDef> relations,
1028 ToscaNodeTemplate nodeTypeTemplate, Component originComponent, Map<String, Component> componentCache) {
1030 List<Map<String, ToscaTemplateRequirement>> toscaRequirements = new ArrayList<>();
1031 if (!addRequirements(component, componentInstance, relations, originComponent, toscaRequirements,
1033 log.debug("Failed to convert component instance requirements for the component instance {}. ",
1034 componentInstance.getName());
1035 return Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
1037 if (!toscaRequirements.isEmpty()) {
1038 nodeTypeTemplate.setRequirements(toscaRequirements);
1040 log.debug("Finished to convert requirements for the node type {} ", componentInstance.getName());
1041 return Either.left(nodeTypeTemplate);
1044 private boolean addRequirements(Component component, ComponentInstance componentInstance,
1045 List<RequirementCapabilityRelDef> relations, Component originComponent,
1046 List<Map<String, ToscaTemplateRequirement>> toscaRequirements, Map<String, Component> componentCache) {
1048 List<RequirementCapabilityRelDef> filteredRelations =
1049 relations.stream().filter(p -> componentInstance.getUniqueId().equals(p.getFromNode()))
1050 .collect(Collectors.toList());
1051 if (CollectionUtils.isEmpty(filteredRelations)) {
1054 result = !filteredRelations.stream().filter(rel -> !addRequirement(componentInstance, originComponent,
1055 component.getComponentInstances(), rel, toscaRequirements, componentCache)).findFirst().isPresent();
1060 private boolean addRequirement(ComponentInstance fromInstance, Component fromOriginComponent,
1061 List<ComponentInstance> instancesList, RequirementCapabilityRelDef rel,
1062 List<Map<String, ToscaTemplateRequirement>> toscaRequirements, Map<String, Component> componentCache) {
1064 boolean result = true;
1065 Map<String, List<RequirementDefinition>> reqMap = fromOriginComponent.getRequirements();
1066 RelationshipInfo reqAndRelationshipPair = rel.getRelationships().get(0).getRelation();
1067 Either<Component, StorageOperationStatus> getOriginRes = null;
1068 Optional<RequirementDefinition> reqOpt = null;
1069 Component toOriginComponent = null;
1070 Optional<CapabilityDefinition> cap = null;
1072 ComponentInstance toInstance =
1073 instancesList.stream().filter(i -> rel.getToNode().equals(i.getUniqueId())).findFirst().orElse(null);
1074 if (toInstance == null) {
1075 log.debug("Failed to find a relation from the node {} to the node {}", fromInstance.getName(),
1080 reqOpt = findRequirement(fromOriginComponent, reqMap, reqAndRelationshipPair, fromInstance.getUniqueId());
1081 if (!reqOpt.isPresent()) {
1082 log.debug("Failed to find a requirement with uniqueId {} on a component with uniqueId {}",
1083 reqAndRelationshipPair.getRequirementUid(), fromOriginComponent.getUniqueId());
1088 ComponentParametersView filter = new ComponentParametersView(true);
1089 filter.setIgnoreComponentInstances(false);
1090 filter.setIgnoreCapabilities(false);
1091 getOriginRes = toscaOperationFacade.getToscaElement(toInstance.getActualComponentUid(), filter);
1092 if (getOriginRes.isRight()) {
1094 "Failed to build substituted name for the requirement {}. Failed to get an origin component with uniqueId {}",
1095 reqOpt.get().getName(), toInstance.getActualComponentUid());
1100 toOriginComponent = getOriginRes.left().value();
1101 cap = toOriginComponent.getCapabilities().get(reqOpt.get().getCapability()).stream()
1102 .filter(c -> isCapabilityBelongToRelation(reqAndRelationshipPair, c)).findFirst();
1103 if (!cap.isPresent()) {
1104 cap = findCapability(reqAndRelationshipPair, toOriginComponent, fromOriginComponent, reqOpt.get(),
1106 if (!cap.isPresent()) {
1108 log.debug("Failed to find a capability with name {} on a component with uniqueId {}",
1109 reqAndRelationshipPair.getCapability(), fromOriginComponent.getUniqueId());
1114 result = buildAndAddRequirement(toscaRequirements, fromOriginComponent, toOriginComponent, cap.get(),
1115 reqOpt.get(), reqAndRelationshipPair, toInstance, componentCache);
1120 private boolean isCapabilityBelongToRelation(RelationshipInfo reqAndRelationshipPair,
1121 CapabilityDefinition capability) {
1122 return capability.getName().equals(reqAndRelationshipPair.getCapability()) && (capability.getOwnerId() != null
1125 .equals(reqAndRelationshipPair
1126 .getCapabilityOwnerId()));
1129 private Optional<CapabilityDefinition> findCapability(RelationshipInfo reqAndRelationshipPair,
1130 Component toOriginComponent, Component fromOriginComponent, RequirementDefinition requirement,
1131 ComponentInstance fromInstance) {
1132 Optional<CapabilityDefinition> cap =
1133 toOriginComponent.getCapabilities().get(requirement.getCapability()).stream()
1134 .filter(c -> c.getType().equals(requirement.getCapability())).findFirst();
1135 if (!cap.isPresent()) {
1136 log.debug("Failed to find a capability with name {} on a component with uniqueId {}",
1137 reqAndRelationshipPair.getCapability(), fromOriginComponent.getUniqueId());
1142 private boolean buildAndAddRequirement(List<Map<String, ToscaTemplateRequirement>> toscaRequirements,
1143 Component fromOriginComponent, Component toOriginComponent, CapabilityDefinition capability,
1144 RequirementDefinition requirement, RelationshipInfo reqAndRelationshipPair, ComponentInstance toInstance,
1145 Map<String, Component> componentCache) {
1146 boolean result = true;
1147 Either<String, Boolean> buildReqNameRes = null;
1148 List<String> reducedPath = capability.getPath();
1149 if (capability.getOwnerId() != null) {
1151 capabiltyRequirementConvertor.getReducedPathByOwner(capability.getPath(), capability.getOwnerId());
1153 Either<String, Boolean> buildCapNameRes = capabiltyRequirementConvertor
1154 .buildSubstitutedName(componentCache, toOriginComponent,
1155 reducedPath, reqAndRelationshipPair.getCapability());
1156 if (buildCapNameRes.isRight()) {
1158 "Failed to build a substituted capability name for the capability with name {} on a component with uniqueId {}",
1159 reqAndRelationshipPair.getCapability(), fromOriginComponent.getUniqueId());
1163 buildReqNameRes = capabiltyRequirementConvertor
1164 .buildSubstitutedName(componentCache, fromOriginComponent, requirement.getPath(),
1165 reqAndRelationshipPair.getRequirement());
1166 if (buildReqNameRes.isRight()) {
1168 "Failed to build a substituted requirement name for the requirement with name {} on a component with uniqueId {}",
1169 reqAndRelationshipPair.getRequirement(), fromOriginComponent.getUniqueId());
1174 ToscaTemplateRequirement toscaRequirement = new ToscaTemplateRequirement();
1175 Map<String, ToscaTemplateRequirement> toscaReqMap = new HashMap<>();
1176 toscaRequirement.setNode(toInstance.getName());
1177 toscaRequirement.setCapability(buildCapNameRes.left().value());
1178 toscaReqMap.put(buildReqNameRes.left().value(), toscaRequirement);
1179 toscaRequirements.add(toscaReqMap);
1184 private Optional<RequirementDefinition> findRequirement(Component fromOriginComponent,
1185 Map<String, List<RequirementDefinition>> reqMap, RelationshipInfo reqAndRelationshipPair,
1186 String fromInstanceId) {
1187 for (List<RequirementDefinition> reqList : reqMap.values()) {
1188 Optional<RequirementDefinition> reqOpt = reqList.stream().filter(r -> isRequirementBelongToRelation(
1189 fromOriginComponent, reqAndRelationshipPair, r, fromInstanceId)).findFirst();
1190 if (reqOpt.isPresent()) {
1194 return Optional.empty();
1198 * Allows detecting the requirement belonging to the received relationship
1199 * The detection logic is: A requirement belongs to a relationship IF 1.The
1200 * name of the requirement equals to the "requirement" field of the
1201 * relation; AND 2. In case of a non-atomic resource, OwnerId of the
1202 * requirement equals to requirementOwnerId of the relation OR uniqueId of
1203 * toInstance equals to capabilityOwnerId of the relation
1205 private boolean isRequirementBelongToRelation(Component originComponent, RelationshipInfo reqAndRelationshipPair,
1206 RequirementDefinition requirement, String fromInstanceId) {
1207 if (!StringUtils.equals(requirement.getName(), reqAndRelationshipPair.getRequirement())) {
1208 log.debug("Failed to find a requirement with name {} and reqAndRelationshipPair {}", requirement.getName(),
1209 reqAndRelationshipPair.getRequirement());
1212 if (!ModelConverter.isAtomicComponent(originComponent)) {
1213 return isRequirementBelongToOwner(reqAndRelationshipPair, requirement, fromInstanceId, originComponent);
1218 private boolean isRequirementBelongToOwner(RelationshipInfo reqAndRelationshipPair,
1219 RequirementDefinition requirement, String fromInstanceId, Component originComponent) {
1220 return StringUtils.equals(requirement.getOwnerId(), reqAndRelationshipPair.getRequirementOwnerId()) || (
1221 isCvfc(originComponent) && StringUtils.equals(fromInstanceId,
1222 reqAndRelationshipPair.getRequirementOwnerId()));
1225 private boolean isCvfc(Component component) {
1226 if (component.getComponentType() != ComponentTypeEnum.RESOURCE) {
1229 return ((Resource) component).getResourceType() == ResourceTypeEnum.CVFC;
1232 private Either<SubstitutionMapping, ToscaError> convertCapabilities(Component component,
1233 SubstitutionMapping substitutionMappings, Map<String, Component> componentCache) {
1235 Either<SubstitutionMapping, ToscaError> result = Either.left(substitutionMappings);
1236 Either<Map<String, String[]>, ToscaError> toscaCapabilitiesRes =
1237 capabiltyRequirementConvertor.convertSubstitutionMappingCapabilities(componentCache, component);
1238 if (toscaCapabilitiesRes.isRight()) {
1239 result = Either.right(toscaCapabilitiesRes.right().value());
1240 log.error("Failed convert capabilities for the component {}. ", component.getName());
1241 } else if (MapUtils.isNotEmpty(toscaCapabilitiesRes.left().value())) {
1242 substitutionMappings.setCapabilities(toscaCapabilitiesRes.left().value());
1243 log.debug("Finish convert capabilities for the component {}. ", component.getName());
1245 log.debug("Finished to convert capabilities for the component {}. ", component.getName());
1249 private Either<ToscaNodeType, ToscaError> convertCapabilities(Component component, ToscaNodeType nodeType,
1250 Map<String, DataTypeDefinition> dataTypes) {
1251 Map<String, ToscaCapability> toscaCapabilities =
1252 capabiltyRequirementConvertor.convertCapabilities(component, dataTypes);
1253 if (!toscaCapabilities.isEmpty()) {
1254 nodeType.setCapabilities(toscaCapabilities);
1256 log.debug("Finish convert Capabilities for node type");
1258 return Either.left(nodeType);
1261 public static class CustomRepresenter extends Representer {
1263 public CustomRepresenter() {
1265 // null representer is exceptional and it is stored as an instance
1267 this.nullRepresenter = new RepresentNull();
1272 protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue,
1274 if (propertyValue == null) {
1277 // skip not relevant for Tosca property
1278 if ("dependencies".equals(property.getName())) {
1281 NodeTuple defaultNode = super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
1283 return "_defaultp_".equals(property.getName()) ?
1284 new NodeTuple(representData("default"), defaultNode.getValueNode()) : defaultNode;
1289 protected MappingNode representJavaBean(Set<Property> properties, Object javaBean) {
1290 // remove the bean type from the output yaml (!! ...)
1291 if (!classTags.containsKey(javaBean.getClass())) {
1292 addClassTag(javaBean.getClass(), Tag.MAP);
1295 return super.representJavaBean(properties, javaBean);
1298 private class RepresentNull implements Represent {
1301 public Node representData(Object data) {
1302 // possible values are here http://yaml.org/type/null.html
1303 return representScalar(Tag.NULL, "");
1308 public static class UnsortedPropertyUtils extends PropertyUtils {
1311 protected Set<Property> createPropertySet(Class<? extends Object> type, BeanAccess bAccess)
1312 throws IntrospectionException {
1313 Collection<Property> fields = getPropertiesMap(type, BeanAccess.FIELD).values();
1314 return new LinkedHashSet<>(fields);