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.apache.commons.collections.CollectionUtils.isNotEmpty;
24 import static org.apache.commons.collections.MapUtils.isNotEmpty;
25 import static org.openecomp.sdc.be.components.utils.PropertiesUtils.resolvePropertyValueFromInput;
26 import static org.openecomp.sdc.be.tosca.InterfacesOperationsConverter.addInterfaceTypeElement;
27 import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_ATTRIBUTE;
28 import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_INPUT;
29 import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_PROPERTY;
31 import com.fasterxml.jackson.databind.ObjectMapper;
32 import fj.data.Either;
33 import java.beans.IntrospectionException;
34 import java.util.ArrayList;
35 import java.util.Arrays;
36 import java.util.Collection;
37 import java.util.Collections;
38 import java.util.HashMap;
39 import java.util.Iterator;
40 import java.util.LinkedHashMap;
41 import java.util.LinkedHashSet;
42 import java.util.List;
44 import java.util.Map.Entry;
45 import java.util.Objects;
46 import java.util.Optional;
48 import java.util.function.Supplier;
49 import java.util.stream.Collectors;
50 import lombok.NoArgsConstructor;
51 import org.apache.commons.collections.CollectionUtils;
52 import org.apache.commons.collections.MapUtils;
53 import org.apache.commons.lang.StringUtils;
54 import org.apache.commons.lang3.tuple.ImmutablePair;
55 import org.apache.commons.lang3.tuple.ImmutableTriple;
56 import org.apache.commons.lang3.tuple.Triple;
57 import org.onap.sdc.tosca.services.YamlUtil;
58 import org.openecomp.sdc.be.components.impl.exceptions.SdcResourceNotFoundException;
59 import org.openecomp.sdc.be.config.ConfigurationManager;
60 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
61 import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
62 import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition;
63 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
64 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
65 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
66 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
67 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition;
68 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition;
69 import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterPropertyDataDefinition;
70 import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition;
71 import org.openecomp.sdc.be.datatypes.elements.ToscaArtifactDataDefinition;
72 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
73 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
74 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
75 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
76 import org.openecomp.sdc.be.exception.ToscaExportException;
77 import org.openecomp.sdc.be.model.ArtifactDefinition;
78 import org.openecomp.sdc.be.model.AttributeDefinition;
79 import org.openecomp.sdc.be.model.CapabilityDefinition;
80 import org.openecomp.sdc.be.model.CapabilityRequirementRelationship;
81 import org.openecomp.sdc.be.model.Component;
82 import org.openecomp.sdc.be.model.ComponentInstance;
83 import org.openecomp.sdc.be.model.ComponentInstanceInput;
84 import org.openecomp.sdc.be.model.ComponentInstanceInterface;
85 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
86 import org.openecomp.sdc.be.model.ComponentParametersView;
87 import org.openecomp.sdc.be.model.DataTypeDefinition;
88 import org.openecomp.sdc.be.model.GroupInstance;
89 import org.openecomp.sdc.be.model.InputDefinition;
90 import org.openecomp.sdc.be.model.InterfaceDefinition;
91 import org.openecomp.sdc.be.model.PropertyDefinition;
92 import org.openecomp.sdc.be.model.RelationshipInfo;
93 import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
94 import org.openecomp.sdc.be.model.RequirementDefinition;
95 import org.openecomp.sdc.be.model.Resource;
96 import org.openecomp.sdc.be.model.Service;
97 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
98 import org.openecomp.sdc.be.model.category.CategoryDefinition;
99 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
100 import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter;
101 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
102 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
103 import org.openecomp.sdc.be.tosca.PropertyConvertor.PropertyType;
104 import org.openecomp.sdc.be.tosca.builder.ToscaRelationshipBuilder;
105 import org.openecomp.sdc.be.tosca.model.CapabilityFilter;
106 import org.openecomp.sdc.be.tosca.model.NodeFilter;
107 import org.openecomp.sdc.be.tosca.model.SubstitutionMapping;
108 import org.openecomp.sdc.be.tosca.model.ToscaCapability;
109 import org.openecomp.sdc.be.tosca.model.ToscaDataType;
110 import org.openecomp.sdc.be.tosca.model.ToscaGroupTemplate;
111 import org.openecomp.sdc.be.tosca.model.ToscaNodeTemplate;
112 import org.openecomp.sdc.be.tosca.model.ToscaNodeType;
113 import org.openecomp.sdc.be.tosca.model.ToscaPolicyTemplate;
114 import org.openecomp.sdc.be.tosca.model.ToscaProperty;
115 import org.openecomp.sdc.be.tosca.model.ToscaPropertyAssignment;
116 import org.openecomp.sdc.be.tosca.model.ToscaRelationshipTemplate;
117 import org.openecomp.sdc.be.tosca.model.ToscaRequirement;
118 import org.openecomp.sdc.be.tosca.model.ToscaTemplate;
119 import org.openecomp.sdc.be.tosca.model.ToscaTemplateArtifact;
120 import org.openecomp.sdc.be.tosca.model.ToscaTemplateRequirement;
121 import org.openecomp.sdc.be.tosca.model.ToscaTopolgyTemplate;
122 import org.openecomp.sdc.be.tosca.utils.ForwardingPathToscaUtil;
123 import org.openecomp.sdc.be.tosca.utils.InputConverter;
124 import org.openecomp.sdc.be.tosca.utils.OutputConverter;
125 import org.openecomp.sdc.common.log.wrappers.Logger;
126 import org.springframework.beans.factory.annotation.Autowired;
127 import org.yaml.snakeyaml.DumperOptions;
128 import org.yaml.snakeyaml.DumperOptions.FlowStyle;
129 import org.yaml.snakeyaml.Yaml;
130 import org.yaml.snakeyaml.introspector.BeanAccess;
131 import org.yaml.snakeyaml.introspector.Property;
132 import org.yaml.snakeyaml.introspector.PropertyUtils;
133 import org.yaml.snakeyaml.nodes.MappingNode;
134 import org.yaml.snakeyaml.nodes.Node;
135 import org.yaml.snakeyaml.nodes.NodeTuple;
136 import org.yaml.snakeyaml.nodes.Tag;
137 import org.yaml.snakeyaml.representer.Represent;
138 import org.yaml.snakeyaml.representer.Representer;
141 @org.springframework.stereotype.Component("tosca-export-handler")
142 public class ToscaExportHandler {
144 private static final Logger log = Logger.getLogger(ToscaExportHandler.class);
146 private ApplicationDataTypeCache dataTypeCache;
147 private ToscaOperationFacade toscaOperationFacade;
148 private CapabilityRequirementConverter capabilityRequirementConverter;
149 private PolicyExportParser policyExportParser;
150 private GroupExportParser groupExportParser;
151 private PropertyConvertor propertyConvertor;
152 private InputConverter inputConverter;
153 private OutputConverter outputConverter;
154 private InterfaceLifecycleOperation interfaceLifecycleOperation;
155 private InterfacesOperationsConverter interfacesOperationsConverter;
158 public ToscaExportHandler(final ApplicationDataTypeCache dataTypeCache,
159 final ToscaOperationFacade toscaOperationFacade,
160 final CapabilityRequirementConverter capabilityRequirementConverter,
161 final PolicyExportParser policyExportParser,
162 final GroupExportParser groupExportParser,
163 final PropertyConvertor propertyConvertor,
164 final InputConverter inputConverter,
165 final OutputConverter outputConverter,
166 final InterfaceLifecycleOperation interfaceLifecycleOperation,
167 final InterfacesOperationsConverter interfacesOperationsConverter) {
168 this.dataTypeCache = dataTypeCache;
169 this.toscaOperationFacade = toscaOperationFacade;
170 this.capabilityRequirementConverter = capabilityRequirementConverter;
171 this.policyExportParser = policyExportParser;
172 this.groupExportParser = groupExportParser;
173 this.propertyConvertor = propertyConvertor;
174 this.inputConverter = inputConverter;
175 this.outputConverter = outputConverter;
176 this.interfaceLifecycleOperation = interfaceLifecycleOperation;
177 this.interfacesOperationsConverter = interfacesOperationsConverter;
180 private static final String TOSCA_VERSION = "tosca_simple_yaml_1_3";
181 private static final String SERVICE_NODE_TYPE_PREFIX = "org.openecomp.service.";
182 private static final String IMPORTS_FILE_KEY = "file";
183 private static final String TOSCA_INTERFACE_NAME = "-interface.yml";
184 public static final String ASSET_TOSCA_TEMPLATE = "assettoscatemplate";
185 private static final String FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION = "convertToToscaTemplate - failed to get Default Imports section from configuration";
186 private static final String NOT_SUPPORTED_COMPONENT_TYPE = "Not supported component type {}";
187 private static final String NATIVE_ROOT = "tosca.nodes.Root";
188 private static final YamlUtil yamlUtil = new YamlUtil();
190 public Either<ToscaRepresentation, ToscaError> exportComponent(Component component) {
191 return convertToToscaTemplate(component).left().map(this::createToscaRepresentation);
194 public Either<ToscaRepresentation, ToscaError> exportComponentInterface(final Component component,
195 final boolean isAssociatedComponent) {
196 final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImportConfig();
197 if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
198 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
199 return Either.right(ToscaError.GENERAL_ERROR);
202 String toscaVersion = null;
203 if (component instanceof Resource) {
204 toscaVersion = ((Resource) component).getToscaVersion();
206 ToscaTemplate toscaTemplate = new ToscaTemplate(toscaVersion != null ? toscaVersion : TOSCA_VERSION);
207 toscaTemplate.setImports(new ArrayList<>(defaultToscaImportConfig));
208 final Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
209 final Either<ToscaTemplate, ToscaError> toscaTemplateRes =
210 convertInterfaceNodeType(new HashMap<>(), component, toscaTemplate, nodeTypes, isAssociatedComponent);
211 if (toscaTemplateRes.isRight()) {
212 return Either.right(toscaTemplateRes.right().value());
215 toscaTemplate = toscaTemplateRes.left().value();
216 ToscaRepresentation toscaRepresentation = this.createToscaRepresentation(toscaTemplate);
217 return Either.left(toscaRepresentation);
220 public ToscaRepresentation createToscaRepresentation(ToscaTemplate toscaTemplate) {
221 CustomRepresenter representer = new CustomRepresenter();
222 DumperOptions options = new DumperOptions();
223 options.setAllowReadOnlyProperties(false);
224 options.setPrettyFlow(true);
226 options.setDefaultFlowStyle(FlowStyle.FLOW);
227 options.setCanonical(false);
229 representer.addClassTag(toscaTemplate.getClass(), Tag.MAP);
231 representer.setPropertyUtils(new UnsortedPropertyUtils());
232 Yaml yaml = new Yaml(representer, options);
234 String yamlAsString = yaml.dumpAsMap(toscaTemplate);
236 StringBuilder sb = new StringBuilder();
237 sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactHeader());
238 sb.append(yamlAsString);
239 sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactFooter());
241 return ToscaRepresentation.make(sb.toString().getBytes(), toscaTemplate);
244 public Either<ToscaTemplate, ToscaError> getDependencies(Component component) {
245 ToscaTemplate toscaTemplate = new ToscaTemplate(null);
246 Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports = fillImports(component,
248 if (fillImports.isRight()) {
249 return Either.right(fillImports.right().value());
251 return Either.left(fillImports.left().value().left);
254 public Either<ToscaTemplate, ToscaError> convertToToscaTemplate(final Component component) {
255 final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImportConfig();
256 if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
257 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
258 return Either.right(ToscaError.GENERAL_ERROR);
260 log.trace("start tosca export for {}", component.getUniqueId());
261 String toscaVersion = null;
262 if (component instanceof Resource) {
263 toscaVersion = ((Resource) component).getToscaVersion();
265 final ToscaTemplate toscaTemplate = new ToscaTemplate(toscaVersion != null ? toscaVersion : TOSCA_VERSION);
266 toscaTemplate.setMetadata(convertMetadata(component));
267 toscaTemplate.setImports(new ArrayList<>(defaultToscaImportConfig));
268 final Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
269 if (ModelConverter.isAtomicComponent(component)) {
270 log.trace("convert component as node type");
271 return convertNodeType(new HashMap<>(), component, toscaTemplate, nodeTypes);
273 log.trace("convert component as topology template");
274 return convertToscaTemplate(component, toscaTemplate);
279 private Either<ToscaTemplate, ToscaError> convertToscaTemplate(Component component, ToscaTemplate toscaNode) {
281 Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> importsRes = fillImports(component,
283 if (importsRes.isRight()) {
284 return Either.right(importsRes.right().value());
286 toscaNode = importsRes.left().value().left;
287 Map<String, Component> componentCache = importsRes.left().value().right;
288 Either<Map<String, ToscaNodeType>, ToscaError> nodeTypesMapEither = createProxyNodeTypes(componentCache,
290 if (nodeTypesMapEither.isRight()) {
291 log.debug("Failed to fetch normative service proxy resource by tosca name, error {}",
292 nodeTypesMapEither.right().value());
293 return Either.right(nodeTypesMapEither.right().value());
295 Map<String, ToscaNodeType> nodeTypesMap = nodeTypesMapEither.left().value();
296 if (nodeTypesMap != null && !nodeTypesMap.isEmpty()) {
297 toscaNode.setNode_types(nodeTypesMap);
300 createServiceSubstitutionNodeTypes(componentCache, component, toscaNode);
302 Either<Map<String, Object>, ToscaError> proxyInterfaceTypesEither = createProxyInterfaceTypes(component);
303 if (proxyInterfaceTypesEither.isRight()) {
304 log.debug("Failed to populate service proxy local interface types in tosca, error {}",
305 nodeTypesMapEither.right().value());
306 return Either.right(proxyInterfaceTypesEither.right().value());
308 Map<String, Object> proxyInterfaceTypes = proxyInterfaceTypesEither.left().value();
309 if (MapUtils.isNotEmpty(proxyInterfaceTypes)) {
310 toscaNode.setInterface_types(proxyInterfaceTypes);
313 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = dataTypeCache.getAll();
314 if (dataTypesEither.isRight()) {
315 log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
316 return Either.right(ToscaError.GENERAL_ERROR);
318 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
319 ToscaTopolgyTemplate topologyTemplate = new ToscaTopolgyTemplate();
320 List<InputDefinition> inputDef = component.getInputs();
321 Map<String, ToscaProperty> inputs = inputConverter.convertInputs(inputDef, dataTypes);
323 if (!inputs.isEmpty()) {
324 topologyTemplate.setInputs(inputs);
327 final Map<String, ToscaProperty> outputs = outputConverter.convert(component.getOutputs(), dataTypes);
328 if (!outputs.isEmpty()) {
329 topologyTemplate.setOutputs(outputs);
332 final List<ComponentInstance> componentInstances = component.getComponentInstances();
333 Map<String, List<ComponentInstanceProperty>> componentInstancesProperties = component.getComponentInstancesProperties();
334 Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces = component.getComponentInstancesInterfaces();
335 if (CollectionUtils.isNotEmpty(componentInstances)) {
336 final Either<Map<String, ToscaNodeTemplate>, ToscaError> nodeTemplates = convertNodeTemplates(component, componentInstances,
337 componentInstancesProperties, componentInstanceInterfaces, componentCache, dataTypes, topologyTemplate);
338 if (nodeTemplates.isRight()) {
339 return Either.right(nodeTemplates.right().value());
341 log.debug("node templates converted");
342 topologyTemplate.setNode_templates(nodeTemplates.left().value());
344 final Map<String, ToscaRelationshipTemplate> relationshipTemplatesMap =
345 new ToscaExportRelationshipTemplatesHandler().createFrom(topologyTemplate.getNode_templates());
346 if (!relationshipTemplatesMap.isEmpty()) {
347 topologyTemplate.setRelationshipTemplates(relationshipTemplatesMap);
350 SubstitutionMapping substitutionMapping = new SubstitutionMapping();
351 convertSubstitutionMappingFilter(component, substitutionMapping);
353 addGroupsToTopologyTemplate(component, topologyTemplate);
356 addPoliciesToTopologyTemplate(component, topologyTemplate);
357 } catch (SdcResourceNotFoundException e) {
358 log.debug("Fail to add policies to topology template:", e);
359 return Either.right(ToscaError.GENERAL_ERROR);
362 String toscaResourceName;
363 switch (component.getComponentType()) {
365 toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition()
366 .getMetadataDataDefinition()).getToscaResourceName();
369 toscaResourceName = SERVICE_NODE_TYPE_PREFIX
370 + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName();
373 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
374 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
376 substitutionMapping.setNode_type(toscaResourceName);
377 Either<SubstitutionMapping, ToscaError> capabilities = convertCapabilities(component, substitutionMapping,
379 if (capabilities.isRight()) {
380 return Either.right(capabilities.right().value());
382 substitutionMapping = capabilities.left().value();
384 Either<SubstitutionMapping, ToscaError> requirements = capabilityRequirementConverter
385 .convertSubstitutionMappingRequirements(componentCache, component, substitutionMapping);
386 if (requirements.isRight()) {
387 return Either.right(requirements.right().value());
389 substitutionMapping = requirements.left().value();
390 final Map<String, String[]> propertyMappingMap = buildSubstitutionMappingPropertyMapping(component);
391 if (!propertyMappingMap.isEmpty()) {
392 substitutionMapping.setProperties(propertyMappingMap);
395 final Map<String, String[]> attributesMappingMap = buildSubstitutionMappingAttributesMapping(component);
396 if (!attributesMappingMap.isEmpty()) {
397 substitutionMapping.setAttributes(attributesMappingMap);
400 topologyTemplate.setSubstitution_mappings(substitutionMapping);
402 toscaNode.setTopology_template(topologyTemplate);
404 return Either.left(toscaNode);
407 private void convertSubstitutionMappingFilter(final Component component,
408 final SubstitutionMapping substitutionMapping) {
409 if (component.getSubstitutionFilter() != null
410 && (component.getSubstitutionFilter().getProperties()).getListToscaDataDefinition() != null) {
412 .setSubstitution_filter(convertToSubstitutionFilterComponent(component.getSubstitutionFilter()));
416 private void addGroupsToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate) {
417 Map<String, ToscaGroupTemplate> groups = groupExportParser.getGroups(component);
418 if (groups != null) {
419 topologyTemplate.addGroups(groups);
423 private void addPoliciesToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate)
424 throws SdcResourceNotFoundException {
425 Map<String, ToscaPolicyTemplate> policies = policyExportParser.getPolicies(component);
426 if (policies != null) {
427 topologyTemplate.addPolicies(policies);
431 private Map<String, String> convertMetadata(Component component) {
432 return convertMetadata(component, false, null);
435 private Map<String, String> convertMetadata(Component component, boolean isInstance,
436 ComponentInstance componentInstance) {
437 Map<String, String> toscaMetadata = new LinkedHashMap<>();
438 toscaMetadata.put(JsonPresentationFields.INVARIANT_UUID.getPresentation(), component.getInvariantUUID());
439 toscaMetadata.put(JsonPresentationFields.UUID.getPresentation(), component.getUUID());
441 .put(JsonPresentationFields.NAME.getPresentation(), component.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
442 toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), component.getDescription());
444 List<CategoryDefinition> categories = component.getCategories();
445 CategoryDefinition categoryDefinition = categories.get(0);
446 toscaMetadata.put(JsonPresentationFields.CATEGORY.getPresentation(), categoryDefinition.getName());
449 toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), component.getVersion());
450 toscaMetadata.put(JsonPresentationFields.CUSTOMIZATION_UUID.getPresentation(), componentInstance.getCustomizationUUID());
451 if (componentInstance.getSourceModelInvariant() != null
452 && !componentInstance.getSourceModelInvariant().isEmpty()) {
453 toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), componentInstance.getComponentVersion());
454 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_INVARIANT.getPresentation(), componentInstance.getSourceModelInvariant());
455 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_UUID.getPresentation(), componentInstance.getSourceModelUuid());
456 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_NAME.getPresentation(), componentInstance.getSourceModelName());
457 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
458 toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(),
459 componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceProxy.getDisplayValue());
460 } else if (componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
461 toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(),
462 componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceSubstitution
465 toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), componentInstance.getDescription());
469 switch (component.getComponentType()) {
471 Resource resource = (Resource) component;
473 if (isInstance && (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy
474 || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution)) {
475 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), componentInstance.getOriginType().getDisplayValue());
477 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), resource.getResourceType().name());
479 toscaMetadata.put(JsonPresentationFields.SUB_CATEGORY.getPresentation(), categoryDefinition.getSubcategories().get(0).getName());
480 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR.getPresentation(), resource.getVendorName());
481 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_RELEASE.getPresentation(), resource.getVendorRelease());
482 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_MODEL_NUMBER.getPresentation(), resource.getResourceVendorModelNumber());
485 Service service = (Service) component;
486 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), component.getComponentType().getValue());
487 toscaMetadata.put(JsonPresentationFields.SERVICE_TYPE.getPresentation(), service.getServiceType());
488 toscaMetadata.put(JsonPresentationFields.SERVICE_ROLE.getPresentation(), service.getServiceRole());
489 toscaMetadata.put(JsonPresentationFields.SERVICE_FUNCTION.getPresentation(), service.getServiceFunction());
490 toscaMetadata.put(JsonPresentationFields.ENVIRONMENT_CONTEXT.getPresentation(), service.getEnvironmentContext());
491 toscaMetadata.put(JsonPresentationFields.INSTANTIATION_TYPE.getPresentation(),
492 service.getEnvironmentContext() == null ? StringUtils.EMPTY : service.getInstantiationType());
495 toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming().toString());
496 toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming().toString());
497 toscaMetadata.put(JsonPresentationFields.NAMING_POLICY.getPresentation(), service.getNamingPolicy());
501 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
504 for (final String key : component.getCategorySpecificMetadata().keySet()) {
505 toscaMetadata.put(key, component.getCategorySpecificMetadata().get(key));
507 return toscaMetadata;
510 private Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports(Component component,
511 ToscaTemplate toscaTemplate) {
513 final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImportConfig();
514 if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
515 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
516 return Either.right(ToscaError.GENERAL_ERROR);
518 Map<String, Component> componentCache = new HashMap<>();
520 if (!ModelConverter.isAtomicComponent(component)) {
521 final List<Map<String, Map<String, String>>> additionalImports =
522 toscaTemplate.getImports() == null ? new ArrayList<>(defaultToscaImportConfig)
523 : new ArrayList<>(toscaTemplate.getImports());
525 List<Triple<String, String, Component>> dependecies = new ArrayList<>();
527 Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
528 if (isNotEmpty(toscaArtifacts)) {
529 ArtifactDefinition artifactDefinition = toscaArtifacts.get(ToscaExportHandler.ASSET_TOSCA_TEMPLATE);
530 if (artifactDefinition != null) {
531 Map<String, Map<String, String>> importsListMember = new HashMap<>();
532 Map<String, String> interfaceFiles = new HashMap<>();
533 interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactDefinition.getArtifactName()));
534 StringBuilder keyNameBuilder = new StringBuilder();
535 keyNameBuilder.append(component.getComponentType().toString().toLowerCase()).append("-")
536 .append(component.getName()).append("-interface");
537 importsListMember.put(keyNameBuilder.toString(), interfaceFiles);
538 additionalImports.add(importsListMember);
541 List<ComponentInstance> componentInstances = component.getComponentInstances();
542 if (componentInstances != null && !componentInstances.isEmpty()) {
543 componentInstances.forEach(ci -> createDependency(componentCache, additionalImports, dependecies, ci));
545 toscaTemplate.setDependencies(dependecies);
546 toscaTemplate.setImports(additionalImports);
548 log.debug("currently imports supported for VF and service only");
550 return Either.left(new ImmutablePair<>(toscaTemplate, componentCache));
553 private List<Map<String, Map<String, String>>> getDefaultToscaImportConfig() {
554 return ConfigurationManager.getConfigurationManager().getConfiguration().getDefaultImports();
557 private void createDependency(final Map<String, Component> componentCache,
558 final List<Map<String, Map<String, String>>> imports,
559 final List<Triple<String, String, Component>> dependencies,
560 final ComponentInstance componentInstance) {
561 log.debug("createDependency componentCache {}", componentCache);
562 Component componentRI = componentCache.get(componentInstance.getComponentUid());
563 if (componentRI == null || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
564 // all resource must be only once!
565 final Either<Component, StorageOperationStatus> resource = toscaOperationFacade
566 .getToscaFullElement(componentInstance.getComponentUid());
567 if ((resource.isRight()) && (log.isDebugEnabled())) {
568 log.debug("Failed to fetch resource with id {} for instance {}", componentInstance.getComponentUid(),
569 componentInstance.getUniqueId());
572 final Component fetchedComponent = resource.left().value();
573 componentRI = setComponentCache(componentCache, componentInstance, fetchedComponent);
574 addDependencies(imports, dependencies, componentRI);
579 * Sets a componentCache from the given component/resource.
581 private Component setComponentCache(final Map<String, Component> componentCache,
582 final ComponentInstance componentInstance,
583 final Component fetchedComponent) {
584 componentCache.put(fetchedComponent.getUniqueId(), fetchedComponent);
585 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy
586 || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
587 final Either<Component, StorageOperationStatus> sourceService = toscaOperationFacade
588 .getToscaFullElement(componentInstance.getSourceModelUid());
589 if (sourceService.isRight() && (log.isDebugEnabled())) {
590 log.debug("Failed to fetch source service with id {} for proxy {}",
591 componentInstance.getSourceModelUid(), componentInstance.getUniqueId());
593 final Component fetchedSource = sourceService.left().value();
594 componentCache.put(fetchedSource.getUniqueId(), fetchedSource);
595 return fetchedSource;
597 return fetchedComponent;
601 * Retrieves all derived_from nodes and stores it in a predictable order.
603 private void addDependencies(final List<Map<String, Map<String, String>>> imports,
604 final List<Triple<String, String, Component>> dependencies,
605 final Component fetchedComponent) {
606 final Set<Component> componentsList = new LinkedHashSet<>();
607 if (fetchedComponent instanceof Resource) {
608 log.debug("fetchedComponent is a resource {}", fetchedComponent);
610 final Optional<Map<String, String>> derivedFromMapOfIdToName = getDerivedFromMapOfIdToName(fetchedComponent,
612 if (derivedFromMapOfIdToName.isPresent() && !derivedFromMapOfIdToName.get().isEmpty()) {
613 derivedFromMapOfIdToName.get().entrySet().forEach(entry -> {
614 log.debug("Started entry.getValue() : {}", entry.getValue());
615 if (!NATIVE_ROOT.equals(entry.getValue())) {
616 Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade
617 .getToscaElement(entry.getKey());
618 if (resourcefetched != null && resourcefetched.isLeft()) {
619 componentsList.add(resourcefetched.left().value());
623 setImports(imports, dependencies, componentsList);
625 setImports(imports, dependencies, fetchedComponent);
632 * Returns all derived_from nodes found.
634 private Optional<Map<String, String>> getDerivedFromMapOfIdToName(final Component fetchedComponent,
635 final Set<Component> componentsList) {
636 final Resource parentResource = (Resource) fetchedComponent;
637 Map<String, String> derivedFromMapOfIdToName = new HashMap<>();
638 if (CollectionUtils.isNotEmpty(parentResource.getComponentInstances())) {
639 componentsList.add(fetchedComponent);
640 for (final ComponentInstance componentInstance : parentResource.getComponentInstances()) {
641 final Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade
642 .getToscaElement(componentInstance.getComponentUid());
643 if (resourcefetched != null && resourcefetched.isLeft()) {
644 final Map<String, String> derivedWithId = resourcefetched.left().value()
645 .getDerivedFromMapOfIdToName();
646 if (MapUtils.isNotEmpty(derivedWithId)) {
647 derivedFromMapOfIdToName.putAll(derivedWithId);
652 derivedFromMapOfIdToName = parentResource.getDerivedFromMapOfIdToName();
654 log.debug("Started derivedFromMapOfIdToName: {}", derivedFromMapOfIdToName);
655 return Optional.ofNullable(derivedFromMapOfIdToName);
659 * Creates a resource map and adds it to the import list.
661 private void setImports(final List<Map<String, Map<String, String>>> imports,
662 final List<Triple<String, String, Component>> dependencies,
663 final Set<Component> componentsList) {
664 componentsList.forEach(component -> setImports(imports, dependencies, component));
667 private void setImports(final List<Map<String, Map<String, String>>> imports,
668 final List<Triple<String, String, Component>> dependencies,
669 final Component component) {
670 final Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
671 final ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE);
672 if (artifactDefinition != null) {
673 final Map<String, String> files = new HashMap<>();
674 final String artifactName = artifactDefinition.getArtifactName();
675 files.put(IMPORTS_FILE_KEY, artifactName);
676 final StringBuilder keyNameBuilder = new StringBuilder();
677 keyNameBuilder.append(component.getComponentType().toString().toLowerCase());
678 keyNameBuilder.append("-");
679 keyNameBuilder.append(component.getName());
680 addImports(imports, keyNameBuilder, files);
682 .add(new ImmutableTriple<>(artifactName, artifactDefinition.getEsId(), component));
684 if (!ModelConverter.isAtomicComponent(component)) {
685 final Map<String, String> interfaceFiles = new HashMap<>();
686 interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactName));
687 keyNameBuilder.append("-interface");
688 addImports(imports, keyNameBuilder, interfaceFiles);
694 * Adds the found resource to the import definition list.
696 private void addImports(final List<Map<String, Map<String, String>>> imports,
697 final StringBuilder keyNameBuilder,
698 final Map<String, String> files) {
699 final String mapKey = keyNameBuilder.toString();
700 if (imports.stream().allMatch(stringMapMap -> stringMapMap.get(mapKey) == null)) {
701 final Map<String, Map<String, String>> importsListMember = new HashMap<>();
702 importsListMember.put(keyNameBuilder.toString(), files);
703 imports.add(importsListMember);
707 public static String getInterfaceFilename(String artifactName) {
708 return artifactName.substring(0, artifactName.lastIndexOf('.')) + ToscaExportHandler.TOSCA_INTERFACE_NAME;
711 private Either<ToscaTemplate, ToscaError> convertNodeType(Map<String, Component> componentsCache,
712 Component component, ToscaTemplate toscaNode,
713 Map<String, ToscaNodeType> nodeTypes) {
714 return convertInterfaceNodeType(componentsCache, component, toscaNode, nodeTypes, false);
717 public Either<ToscaTemplate, ToscaError> convertInterfaceNodeType(Map<String, Component> componentsCache,
718 Component component, ToscaTemplate toscaNode,
719 Map<String, ToscaNodeType> nodeTypes,
720 boolean isAssociatedComponent) {
721 log.debug("start convert node type for {}", component.getUniqueId());
722 ToscaNodeType toscaNodeType = createNodeType(component);
724 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither =
725 interfaceLifecycleOperation.getAllInterfaceLifecycleTypes();
726 if (lifecycleTypeEither.isRight()) {
727 log.debug("Failed to fetch all interface types :", lifecycleTypeEither.right().value());
728 return Either.right(ToscaError.GENERAL_ERROR);
730 List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value()
733 .map(InterfaceDataDefinition::getType)
734 .collect(Collectors.toList());
735 toscaNode.setInterface_types(addInterfaceTypeElement(component, allGlobalInterfaceTypes));
737 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = dataTypeCache.getAll();
738 if (dataTypesEither.isRight()) {
739 log.debug("Failed to fetch all data types :", dataTypesEither.right().value());
740 return Either.right(ToscaError.GENERAL_ERROR);
743 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
745 List<InputDefinition> inputDef = component.getInputs();
746 Map<String, ToscaProperty> mergedProperties = new HashMap<>();
747 interfacesOperationsConverter
748 .addInterfaceDefinitionElement(component, toscaNodeType, dataTypes, isAssociatedComponent);
749 addInputsToProperties(dataTypes, inputDef, mergedProperties);
751 if (CollectionUtils.isNotEmpty(component.getProperties())) {
752 List<PropertyDefinition> properties = component.getProperties();
753 Map<String, ToscaProperty> convertedProperties = properties.stream()
754 .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, component.getInputs()))
755 .collect(Collectors.toMap(PropertyDataDefinition::getName,
756 property -> propertyConvertor.convertProperty(dataTypes, property,
757 PropertyConvertor.PropertyType.PROPERTY)));
758 // merge component properties and inputs properties
759 mergedProperties.putAll(convertedProperties);
761 if (MapUtils.isNotEmpty(mergedProperties)) {
762 toscaNodeType.setProperties(mergedProperties);
765 /* convert private data_types */
766 List<DataTypeDefinition> privateDataTypes = component.getDataTypes();
767 if (CollectionUtils.isNotEmpty(privateDataTypes)) {
768 Map<String, ToscaDataType> toscaDataTypeMap = new HashMap<>();
769 for (DataTypeDefinition dataType : privateDataTypes) {
770 log.debug("Emitting private data type: component.name={} dataType.name={}",
771 component.getNormalizedName(), dataType.getName());
772 ToscaDataType toscaDataType = new ToscaDataType();
773 toscaDataType.setDerived_from(dataType.getDerivedFromName());
774 toscaDataType.setDescription(dataType.getDescription());
775 toscaDataType.setVersion(dataType.getVersion());
776 if (CollectionUtils.isNotEmpty(dataType.getProperties())) {
777 toscaDataType.setProperties(dataType.getProperties().stream()
778 .collect(Collectors.toMap(
779 PropertyDataDefinition::getName,
780 s -> propertyConvertor
781 .convertProperty(dataTypes, s, PropertyType.PROPERTY)
784 toscaDataTypeMap.put(dataType.getName(), toscaDataType);
786 toscaNode.setData_types(toscaDataTypeMap);
789 // Extracted to method for code reuse
790 return convertReqCapAndTypeName(componentsCache, component, toscaNode, nodeTypes, toscaNodeType, dataTypes);
793 private Either<ToscaTemplate, ToscaError> convertReqCapAndTypeName(Map<String, Component> componentsCache,
794 Component component, ToscaTemplate toscaNode,
795 Map<String, ToscaNodeType> nodeTypes,
796 ToscaNodeType toscaNodeType,
797 Map<String, DataTypeDefinition> dataTypes) {
798 Either<ToscaNodeType, ToscaError> capabilities = convertCapabilities(componentsCache, component, toscaNodeType,
800 if (capabilities.isRight()) {
801 return Either.right(capabilities.right().value());
803 toscaNodeType = capabilities.left().value();
804 log.debug("Capabilities converted for {}", component.getUniqueId());
806 Either<ToscaNodeType, ToscaError> requirements = capabilityRequirementConverter
807 .convertRequirements(componentsCache, component,
809 if (requirements.isRight()) {
810 return Either.right(requirements.right().value());
812 toscaNodeType = requirements.left().value();
813 log.debug("Requirements converted for {}", component.getUniqueId());
815 String toscaResourceName;
816 switch (component.getComponentType()) {
818 toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition()
819 .getMetadataDataDefinition()).getToscaResourceName();
822 toscaResourceName = SERVICE_NODE_TYPE_PREFIX
823 + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName();
826 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
827 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
830 nodeTypes.put(toscaResourceName, toscaNodeType);
831 toscaNode.setNode_types(nodeTypes);
832 log.debug("finish convert node type for {}", component.getUniqueId());
833 return Either.left(toscaNode);
836 protected Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplates(
838 List<ComponentInstance> componentInstances,
839 Map<String, List<ComponentInstanceProperty>> componentInstancesProperties,
840 Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces,
841 Map<String, Component> componentCache, Map<String, DataTypeDefinition> dataTypes,
842 ToscaTopolgyTemplate topologyTemplate) {
844 Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplatesRes = null;
845 log.debug("start convert topology template for {} for type {}", component.getUniqueId(),
846 component.getComponentType());
847 Map<String, ToscaNodeTemplate> nodeTemplates = new HashMap<>();
848 Map<String, List<ComponentInstanceInput>> componentInstancesInputs = component.getComponentInstancesInputs();
850 Map<String, ToscaGroupTemplate> groupsMap = null;
851 for (ComponentInstance componentInstance : componentInstances) {
852 ToscaNodeTemplate nodeTemplate = new ToscaNodeTemplate();
853 if (MapUtils.isNotEmpty(componentInstance.getToscaArtifacts())) {
854 nodeTemplate.setArtifacts(convertToNodeTemplateArtifacts(componentInstance.getToscaArtifacts()));
856 nodeTemplate.setType(componentInstance.getToscaComponentName());
857 nodeTemplate.setDirectives(componentInstance.getDirectives());
858 nodeTemplate.setNode_filter(convertToNodeTemplateNodeFilterComponent(componentInstance.getNodeFilter()));
860 Either<Component, Boolean> originComponentRes = capabilityRequirementConverter
861 .getOriginComponent(componentCache, componentInstance);
862 if (originComponentRes.isRight()) {
863 convertNodeTemplatesRes = Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
866 Either<ToscaNodeTemplate, ToscaError> requirements = convertComponentInstanceRequirements(component,
867 componentInstance, component.getComponentInstancesRelations(), nodeTemplate,
868 originComponentRes.left().value(), componentCache);
869 if (requirements.isRight()) {
870 convertNodeTemplatesRes = Either.right(requirements.right().value());
873 String instanceUniqueId = componentInstance.getUniqueId();
874 log.debug("Component instance Requirements converted for instance {}", instanceUniqueId);
876 nodeTemplate = requirements.left().value();
878 Component originalComponent = componentCache.get(componentInstance.getActualComponentUid());
880 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
881 Component componentOfProxy = componentCache.get(componentInstance.getComponentUid());
882 nodeTemplate.setMetadata(convertMetadata(componentOfProxy, true, componentInstance));
884 nodeTemplate.setMetadata(convertMetadata(originalComponent, true, componentInstance));
887 Either<ToscaNodeTemplate, ToscaError> capabilities = capabilityRequirementConverter
888 .convertComponentInstanceCapabilities(componentInstance, dataTypes, nodeTemplate);
889 if (capabilities.isRight()) {
890 convertNodeTemplatesRes = Either.right(capabilities.right().value());
893 log.debug("Component instance Capabilities converted for instance {}", instanceUniqueId);
895 nodeTemplate = capabilities.left().value();
896 Map<String, Object> props = new HashMap<>();
898 if (originalComponent.getComponentType() == ComponentTypeEnum.RESOURCE) {
899 // Adds the properties of parent component to map
900 addPropertiesOfParentComponent(dataTypes, originalComponent, props);
903 if (null != componentInstancesProperties && componentInstancesProperties.containsKey(instanceUniqueId)) {
904 addPropertiesOfComponentInstance(componentInstancesProperties, dataTypes, instanceUniqueId,
908 if (componentInstancesInputs != null && componentInstancesInputs.containsKey(instanceUniqueId)
909 && !isComponentOfTypeServiceProxy(componentInstance)) {
910 //For service proxy the inputs are already handled under instance properties above
911 addComponentInstanceInputs(dataTypes, componentInstancesInputs, instanceUniqueId, props);
914 //M3[00001] - NODE TEMPLATE INTERFACES - START
915 handleInstanceInterfaces(componentInstanceInterfaces, componentInstance, dataTypes, nodeTemplate,
916 instanceUniqueId, component);
917 //M3[00001] - NODE TEMPLATE INTERFACES - END
918 if (props != null && !props.isEmpty()) {
919 nodeTemplate.setProperties(props);
922 List<GroupInstance> groupInstances = componentInstance.getGroupInstances();
923 if (groupInstances != null) {
924 if (groupsMap == null) {
925 groupsMap = new HashMap<>();
927 for (GroupInstance groupInst : groupInstances) {
928 boolean addToTosca = true;
930 List<String> artifacts = groupInst.getArtifacts();
931 if (artifacts == null || artifacts.isEmpty()) {
936 ToscaGroupTemplate toscaGroup = groupExportParser
937 .getToscaGroupTemplate(groupInst, componentInstance.getInvariantName());
938 groupsMap.put(groupInst.getName(), toscaGroup);
943 nodeTemplates.put(componentInstance.getName(), nodeTemplate);
945 if (groupsMap != null) {
946 log.debug("instance groups added");
947 topologyTemplate.addGroups(groupsMap);
949 if (component.getComponentType() == ComponentTypeEnum.SERVICE && isNotEmpty(
950 ((Service) component).getForwardingPaths())) {
951 log.debug("Starting converting paths for component {}, name {}", component.getUniqueId(),
952 component.getName());
953 ForwardingPathToscaUtil
954 .addForwardingPaths((Service) component, nodeTemplates, capabilityRequirementConverter, componentCache,
955 toscaOperationFacade);
956 log.debug("Finished converting paths for component {}, name {}", component.getUniqueId(),
957 component.getName());
959 if (convertNodeTemplatesRes == null) {
960 convertNodeTemplatesRes = Either.left(nodeTemplates);
962 log.debug("finish convert topology template for {} for type {}", component.getUniqueId(),
963 component.getComponentType());
964 return convertNodeTemplatesRes;
967 private void handleInstanceInterfaces(
968 Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces,
969 ComponentInstance componentInstance, Map<String, DataTypeDefinition> dataTypes, ToscaNodeTemplate nodeTemplate,
970 String instanceUniqueId,
971 Component parentComponent) {
973 if (MapUtils.isEmpty(componentInstanceInterfaces)
974 || !componentInstanceInterfaces.containsKey(instanceUniqueId)) {
975 nodeTemplate.setInterfaces(null);
979 final List<ComponentInstanceInterface> currServiceInterfaces =
980 componentInstanceInterfaces.get(instanceUniqueId);
982 final Map<String, InterfaceDefinition> tmpInterfaces = new HashMap<>();
983 currServiceInterfaces.forEach(instInterface -> tmpInterfaces.put(instInterface
984 .getUniqueId(), instInterface));
986 final Map<String, Object> interfaceMap = interfacesOperationsConverter
987 .getInterfacesMap(parentComponent, componentInstance, tmpInterfaces, dataTypes, isComponentOfTypeServiceProxy(componentInstance),
988 isComponentOfTypeServiceProxy(componentInstance));
990 interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
991 nodeTemplate.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap);
994 private boolean isComponentOfTypeServiceProxy(ComponentInstance componentInstance) {
995 return Objects.nonNull(componentInstance.getOriginType())
996 && componentInstance.getOriginType().getValue().equals("Service Proxy");
999 private void addComponentInstanceInputs(Map<String, DataTypeDefinition> dataTypes,
1000 Map<String, List<ComponentInstanceInput>> componentInstancesInputs,
1001 String instanceUniqueId, Map<String, Object> props) {
1003 List<ComponentInstanceInput> instanceInputsList = componentInstancesInputs.get(instanceUniqueId);
1004 if (instanceInputsList != null) {
1005 instanceInputsList.forEach(input -> {
1007 Supplier<String> supplier = () -> input.getValue() != null && !Objects.isNull(input.getValue())
1008 ? input.getValue() : input.getDefaultValue();
1009 propertyConvertor.convertAndAddValue(dataTypes, props, input, supplier);
1014 private void addPropertiesOfComponentInstance(
1015 Map<String, List<ComponentInstanceProperty>> componentInstancesProperties,
1016 Map<String, DataTypeDefinition> dataTypes, String instanceUniqueId,
1017 Map<String, Object> props) {
1019 if (isNotEmpty(componentInstancesProperties)) {
1020 componentInstancesProperties.get(instanceUniqueId)
1021 // Converts and adds each value to property map
1022 .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop,
1027 private void addPropertiesOfParentComponent(Map<String, DataTypeDefinition> dataTypes,
1028 Component componentOfInstance, Map<String, Object> props) {
1030 List<PropertyDefinition> componentProperties = componentOfInstance.getProperties();
1031 if (isNotEmpty(componentProperties)) {
1032 componentProperties.stream()
1033 // Filters out properties with empty default values
1034 .filter(prop -> StringUtils.isNotEmpty(prop.getDefaultValue()))
1035 // Converts and adds each value to property map
1036 .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop,
1037 prop::getDefaultValue));
1041 private ToscaNodeType createNodeType(Component component) {
1042 ToscaNodeType toscaNodeType = new ToscaNodeType();
1043 if (ModelConverter.isAtomicComponent(component)) {
1044 if (((Resource) component).getDerivedFrom() != null) {
1045 toscaNodeType.setDerived_from(((Resource) component).getDerivedFrom().get(0));
1047 toscaNodeType.setDescription(component.getDescription());
1049 String derivedFrom = null != component.getDerivedFromGenericType() ? component.getDerivedFromGenericType()
1051 toscaNodeType.setDerived_from(derivedFrom);
1053 if (component instanceof Resource) {
1054 final List<AttributeDefinition> attributes = ((Resource) component).getAttributes();
1055 if (CollectionUtils.isNotEmpty(attributes)) {
1056 final Map<String, Object> attributeDataDefinitionMap = new HashMap<>();
1057 attributes.forEach(attributeDataDefinition ->
1058 buildAttributeData(attributeDataDefinition, attributeDataDefinitionMap));
1060 toscaNodeType.setAttributes(attributeDataDefinitionMap);
1063 return toscaNodeType;
1066 private void buildAttributeData(final AttributeDefinition originalAttributeDefinition,
1067 final Map<String, Object> attributeDataDefinitionMap) {
1069 attributeDataDefinitionMap.put(originalAttributeDefinition.getName(),
1070 new ObjectMapper().convertValue(new org.onap.sdc.tosca.datatypes.model.AttributeDefinition(
1071 originalAttributeDefinition.getType(),
1072 originalAttributeDefinition.getDescription(),
1073 originalAttributeDefinition.get_default(),
1074 originalAttributeDefinition.getStatus(),
1075 originalAttributeDefinition.getEntry_schema()), Object.class));
1078 private Either<Map<String, Object>, ToscaError> createProxyInterfaceTypes(Component container) {
1080 Map<String, Object> proxyInterfaceTypes = new HashMap<>();
1081 Either<Map<String, Object>, ToscaError> res = Either.left(proxyInterfaceTypes);
1082 List<ComponentInstance> componentInstances = container.getComponentInstances();
1083 if (CollectionUtils.isEmpty(componentInstances)) {
1086 Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
1087 componentInstances.stream()
1088 .filter(this::isComponentOfTypeServiceProxy)
1089 .forEach(inst -> serviceProxyInstanceList.put(inst.getToscaComponentName(), inst));
1090 if (MapUtils.isEmpty(serviceProxyInstanceList)) {
1093 for (Entry<String, ComponentInstance> entryProxy : serviceProxyInstanceList.entrySet()) {
1094 Component serviceComponent;
1095 ComponentParametersView componentParametersView = new ComponentParametersView();
1096 componentParametersView.disableAll();
1097 componentParametersView.setIgnoreInterfaces(false);
1098 Either<Component, StorageOperationStatus> service = toscaOperationFacade
1099 .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
1100 if (service.isRight()) {
1101 log.debug("Failed to fetch original service component with id {} for instance {}",
1102 entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName());
1103 return Either.right(ToscaError.GENERAL_ERROR);
1105 serviceComponent = service.left().value();
1108 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither =
1109 interfaceLifecycleOperation.getAllInterfaceLifecycleTypes();
1110 if (lifecycleTypeEither.isRight()) {
1111 log.debug("Failed to retrieve global interface types :", lifecycleTypeEither.right().value());
1112 return Either.right(ToscaError.GENERAL_ERROR);
1115 List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value().values().stream()
1116 .map(InterfaceDataDefinition::getType)
1117 .collect(Collectors.toList());
1118 //Add interface types for local interfaces in the original service component for proxy
1119 Map<String, Object> localInterfaceTypes = addInterfaceTypeElement(serviceComponent,
1120 allGlobalInterfaceTypes);
1121 if (MapUtils.isNotEmpty(localInterfaceTypes)) {
1122 proxyInterfaceTypes.putAll(localInterfaceTypes);
1126 return Either.left(proxyInterfaceTypes);
1129 private Either<Map<String, ToscaNodeType>, ToscaError> createProxyNodeTypes(Map<String, Component> componentCache,
1130 Component container) {
1132 Map<String, ToscaNodeType> nodeTypesMap = new HashMap<>();
1133 Either<Map<String, ToscaNodeType>, ToscaError> res = Either.left(nodeTypesMap);
1135 List<ComponentInstance> componentInstances = container.getComponentInstances();
1137 if (componentInstances == null || componentInstances.isEmpty()) {
1140 Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
1141 List<ComponentInstance> proxyInst = componentInstances.stream()
1142 .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceProxy.name()))
1143 .collect(Collectors.toList());
1144 if (proxyInst != null && !proxyInst.isEmpty()) {
1145 for (ComponentInstance inst : proxyInst) {
1146 serviceProxyInstanceList.put(inst.getToscaComponentName(), inst);
1150 if (serviceProxyInstanceList.isEmpty()) {
1153 Either<Resource, StorageOperationStatus> serviceProxyOrigin = toscaOperationFacade
1154 .getLatestByName("serviceProxy");
1155 if (serviceProxyOrigin.isRight()) {
1156 log.debug("Failed to fetch normative service proxy resource by tosca name, error {}",
1157 serviceProxyOrigin.right().value());
1158 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
1160 Component origComponent = serviceProxyOrigin.left().value();
1162 for (Entry<String, ComponentInstance> entryProxy : serviceProxyInstanceList.entrySet()) {
1163 Component serviceComponent = null;
1164 ComponentParametersView componentParametersView = new ComponentParametersView();
1165 componentParametersView.disableAll();
1166 componentParametersView.setIgnoreCategories(false);
1167 componentParametersView.setIgnoreProperties(false);
1168 componentParametersView.setIgnoreInputs(false);
1169 componentParametersView.setIgnoreInterfaces(false);
1170 componentParametersView.setIgnoreRequirements(false);
1171 Either<Component, StorageOperationStatus> service = toscaOperationFacade
1172 .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
1173 if (service.isRight()) {
1174 log.debug("Failed to fetch resource with id {} for instance {}",
1175 entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName());
1177 serviceComponent = service.left().value();
1180 ToscaNodeType toscaNodeType = createProxyNodeType(componentCache, origComponent, serviceComponent,
1181 entryProxy.getValue());
1182 nodeTypesMap.put(entryProxy.getKey(), toscaNodeType);
1185 return Either.left(nodeTypesMap);
1188 private void createServiceSubstitutionNodeTypes(final Map<String, Component> componentCache,
1189 final Component container, final ToscaTemplate toscaNode) {
1190 final List<ComponentInstance> componentInstances = container.getComponentInstances();
1192 if (CollectionUtils.isEmpty(componentInstances)) {
1195 final List<ComponentInstance> serviceSubstitutionInstanceList = componentInstances.stream()
1196 .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceSubstitution.name()))
1197 .collect(Collectors.toList());
1198 if (CollectionUtils.isNotEmpty(serviceSubstitutionInstanceList)) {
1199 for (ComponentInstance inst : serviceSubstitutionInstanceList) {
1200 final Map<String, ToscaNodeType> nodeTypes =
1201 toscaNode.getNode_types() == null ? new HashMap<>() : toscaNode.getNode_types();
1202 convertInterfaceNodeType(new HashMap<>(), componentCache.get(inst.getSourceModelUid()), toscaNode,
1208 private ToscaNodeType createProxyNodeType(Map<String, Component> componentCache, Component origComponent,
1209 Component proxyComponent, ComponentInstance componentInstance) {
1210 ToscaNodeType toscaNodeType = new ToscaNodeType();
1211 String derivedFrom = ((Resource) origComponent).getToscaResourceName();
1213 toscaNodeType.setDerived_from(derivedFrom);
1214 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = dataTypeCache.getAll();
1215 if (dataTypesEither.isRight()) {
1216 log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
1218 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
1219 Map<String, ToscaCapability> capabilities = this.capabilityRequirementConverter
1220 .convertProxyCapabilities(componentCache, componentInstance, dataTypes);
1222 if (MapUtils.isNotEmpty(capabilities)) {
1223 toscaNodeType.setCapabilities(capabilities);
1225 List<Map<String, ToscaRequirement>> proxyNodeTypeRequirements = this.capabilityRequirementConverter
1226 .convertProxyRequirements(componentCache, componentInstance);
1227 if (CollectionUtils.isNotEmpty(proxyNodeTypeRequirements)) {
1228 toscaNodeType.setRequirements(proxyNodeTypeRequirements);
1230 Optional<Map<String, ToscaProperty>> proxyProperties = getProxyNodeTypeProperties(proxyComponent, dataTypes);
1231 proxyProperties.ifPresent(toscaNodeType::setProperties);
1233 Map<String, Object> interfaceMap = new HashMap<>();
1234 if (MapUtils.isEmpty(componentInstance.getInterfaces())) {
1235 final Optional<Map<String, Object>> proxyInterfaces = getProxyNodeTypeInterfaces(proxyComponent, dataTypes);
1236 if (proxyInterfaces.isPresent()) {
1237 interfaceMap = proxyInterfaces.get();
1240 interfaceMap = interfacesOperationsConverter
1241 .getInterfacesMapFromComponentInstance(proxyComponent, componentInstance, dataTypes, false, false);
1244 interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
1245 toscaNodeType.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap);
1247 return toscaNodeType;
1250 private Either<ToscaNodeTemplate, ToscaError> convertComponentInstanceRequirements(Component component,
1251 ComponentInstance componentInstance,
1252 List<RequirementCapabilityRelDef> relations,
1253 ToscaNodeTemplate nodeTypeTemplate,
1254 Component originComponent,
1255 Map<String, Component> componentCache) {
1257 final List<Map<String, ToscaTemplateRequirement>> toscaRequirements;
1258 final List<RequirementCapabilityRelDef> requirementDefinitionList = filterRequirements(componentInstance,
1260 if (isNotEmpty(requirementDefinitionList)) {
1262 toscaRequirements = buildRequirements(component, componentInstance,
1263 requirementDefinitionList, originComponent, componentCache);
1264 if (!toscaRequirements.isEmpty()) {
1265 nodeTypeTemplate.setRequirements(toscaRequirements);
1267 } catch (final Exception e) {
1268 log.debug("Failed to convert component instance requirements for the component instance {}. ",
1269 componentInstance.getName(), e);
1270 return Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
1273 log.debug("Finished to convert requirements for the node type {} ", componentInstance.getName());
1274 return Either.left(nodeTypeTemplate);
1277 private List<Map<String, ToscaTemplateRequirement>> buildRequirements(final Component component,
1278 final ComponentInstance componentInstance,
1279 final List<RequirementCapabilityRelDef> filteredRelations,
1280 final Component originComponent,
1281 final Map<String, Component> componentCache)
1282 throws ToscaExportException {
1284 final List<Map<String, ToscaTemplateRequirement>> toscaRequirements = new ArrayList<>();
1285 for (RequirementCapabilityRelDef relationshipDefinition : filteredRelations) {
1286 final Map<String, ToscaTemplateRequirement> toscaTemplateRequirementMap =
1287 buildRequirement(componentInstance, originComponent, component.getComponentInstances(),
1288 relationshipDefinition, componentCache);
1289 toscaRequirements.add(toscaTemplateRequirementMap);
1292 return toscaRequirements;
1295 private List<RequirementCapabilityRelDef> filterRequirements(ComponentInstance componentInstance,
1296 List<RequirementCapabilityRelDef> relations) {
1297 return relations.stream()
1298 .filter(p -> componentInstance.getUniqueId().equals(p.getFromNode())).collect(Collectors.toList());
1301 private Map<String, ToscaTemplateRequirement> buildRequirement(final ComponentInstance fromInstance,
1302 final Component fromOriginComponent,
1303 final List<ComponentInstance> instancesList,
1304 final RequirementCapabilityRelDef relationshipDefinition,
1305 final Map<String, Component> componentCache)
1306 throws ToscaExportException {
1308 final Map<String, List<RequirementDefinition>> reqMap = fromOriginComponent.getRequirements();
1309 final CapabilityRequirementRelationship capabilityRequirementRelationship = relationshipDefinition
1310 .getRelationships().get(0);
1311 final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation();
1313 final ComponentInstance toInstance = instancesList.stream()
1314 .filter(i -> relationshipDefinition.getToNode().equals(i.getUniqueId()))
1315 .findFirst().orElse(null);
1316 if (toInstance == null) {
1317 final String errorMsg = String
1318 .format("Failed to find a relation from the node %s to the node %s", fromInstance.getName(),
1319 relationshipDefinition.getToNode());
1320 log.debug(errorMsg);
1321 throw new ToscaExportException(errorMsg);
1323 final Optional<RequirementDefinition> reqOpt =
1324 findRequirement(fromOriginComponent, reqMap, relationshipInfo, fromInstance.getUniqueId());
1325 if (reqOpt.isEmpty()) {
1326 final String errorMsg = String
1327 .format("Failed to find a requirement with uniqueId %s on a component with uniqueId %s",
1328 relationshipInfo.getRequirementUid(), fromOriginComponent.getUniqueId());
1329 log.debug(errorMsg);
1330 throw new ToscaExportException(errorMsg);
1332 final ComponentParametersView filter = new ComponentParametersView(true);
1333 filter.setIgnoreComponentInstances(false);
1334 filter.setIgnoreCapabilities(false);
1335 filter.setIgnoreGroups(false);
1336 final Either<Component, StorageOperationStatus> getOriginRes =
1337 toscaOperationFacade.getToscaElement(toInstance.getActualComponentUid(), filter);
1338 if (getOriginRes.isRight()) {
1339 final String errorMsg = String.format(
1340 "Failed to build substituted name for the requirement %s. "
1341 + "Failed to get an origin component with uniqueId %s",
1342 reqOpt.get().getName(), toInstance.getActualComponentUid());
1343 log.debug(errorMsg);
1344 throw new ToscaExportException(errorMsg);
1346 final Component toOriginComponent = getOriginRes.left().value();
1347 Optional<CapabilityDefinition> capOpt = toOriginComponent.getCapabilities().get(reqOpt.get().getCapability()).stream()
1348 .filter(c -> isCapabilityBelongToRelation(relationshipInfo, c)).findFirst();
1349 if (capOpt.isEmpty()) {
1350 capOpt = findCapability(relationshipInfo, toOriginComponent, fromOriginComponent, reqOpt.get());
1351 if (capOpt.isEmpty()) {
1352 final String errorMsg = String
1353 .format("Failed to find a capability with name %s on a component with uniqueId %s",
1354 relationshipInfo.getCapability(), fromOriginComponent.getUniqueId());
1355 log.debug(errorMsg);
1356 throw new ToscaExportException(errorMsg);
1359 return buildRequirement(fromOriginComponent, toOriginComponent, capOpt.get(), reqOpt.get(),
1360 capabilityRequirementRelationship, toInstance, componentCache);
1363 private boolean isCapabilityBelongToRelation(RelationshipInfo reqAndRelationshipPair,
1364 CapabilityDefinition capability) {
1365 return capability.getName().equals(reqAndRelationshipPair.getCapability()) && (capability.getOwnerId() != null
1366 && capability.getOwnerId().equals(reqAndRelationshipPair.getCapabilityOwnerId()));
1369 private Optional<CapabilityDefinition> findCapability(RelationshipInfo reqAndRelationshipPair,
1370 Component toOriginComponent, Component fromOriginComponent,
1371 RequirementDefinition requirement) {
1372 Optional<CapabilityDefinition> cap = toOriginComponent.getCapabilities().get(requirement.getCapability())
1373 .stream().filter(c -> c.getType().equals(requirement.getCapability())).findFirst();
1374 if (!cap.isPresent()) {
1375 log.debug("Failed to find a capability with name {} on a component with uniqueId {}",
1376 reqAndRelationshipPair.getCapability(), fromOriginComponent.getUniqueId());
1381 private Map<String, ToscaTemplateRequirement> buildRequirement(final Component fromOriginComponent,
1382 final Component toOriginComponent,
1383 final CapabilityDefinition capability,
1384 final RequirementDefinition requirement,
1385 final CapabilityRequirementRelationship capabilityRequirementRelationship,
1386 final ComponentInstance toInstance,
1387 final Map<String, Component> componentCache)
1388 throws ToscaExportException {
1390 List<String> reducedPath = capability.getPath();
1391 if (capability.getOwnerId() != null) {
1392 reducedPath = capabilityRequirementConverter
1393 .getReducedPathByOwner(capability.getPath(), capability.getOwnerId());
1395 final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation();
1396 final Either<String, Boolean> capabilityNameEither = capabilityRequirementConverter.buildSubstitutedName(componentCache,
1397 toOriginComponent, reducedPath, relationshipInfo.getCapability(), capability.getPreviousName());
1398 if (capabilityNameEither.isRight()) {
1399 final String errorMsg = String.format(
1400 "Failed to build a substituted capability name for the capability with name %s on a component with uniqueId %s",
1401 capabilityRequirementRelationship.getCapability(), toOriginComponent.getUniqueId());
1404 throw new ToscaExportException(errorMsg);
1406 final Either<String, Boolean> requirementNameEither = capabilityRequirementConverter
1407 .buildSubstitutedName(componentCache, fromOriginComponent,
1408 requirement.getPath(), relationshipInfo.getRequirement(), requirement.getPreviousName());
1409 if (requirementNameEither.isRight()) {
1410 final String errorMsg = String.format("Failed to build a substituted requirement name for the requirement "
1411 + "with name %s on a component with uniqueId %s",
1412 capabilityRequirementRelationship.getRequirement(), fromOriginComponent.getUniqueId());
1413 log.debug(errorMsg);
1414 throw new ToscaExportException(errorMsg);
1416 final ToscaTemplateRequirement toscaRequirement = new ToscaTemplateRequirement();
1417 final Map<String, ToscaTemplateRequirement> toscaReqMap = new HashMap<>();
1418 toscaRequirement.setNode(toInstance.getName());
1419 toscaRequirement.setCapability(capabilityNameEither.left().value());
1420 if (isNotEmpty(capabilityRequirementRelationship.getOperations())) {
1421 toscaRequirement.setRelationship(new ToscaRelationshipBuilder().from(capabilityRequirementRelationship));
1423 toscaReqMap.put(requirementNameEither.left().value(), toscaRequirement);
1427 private Optional<RequirementDefinition> findRequirement(Component fromOriginComponent,
1428 Map<String, List<RequirementDefinition>> reqMap,
1429 RelationshipInfo reqAndRelationshipPair,
1430 String fromInstanceId) {
1431 for (List<RequirementDefinition> reqList : reqMap.values()) {
1432 Optional<RequirementDefinition> reqOpt = reqList.stream().filter(
1433 r -> isRequirementBelongToRelation(fromOriginComponent, reqAndRelationshipPair, r, fromInstanceId))
1435 if (reqOpt.isPresent()) {
1439 return Optional.empty();
1443 * Allows detecting the requirement belonging to the received relationship The detection logic is: A requirement belongs to a relationship IF
1444 * 1.The name of the requirement equals to the "requirement" field of the relation; AND 2. In case of a non-atomic resource, OwnerId of the
1445 * requirement equals to requirementOwnerId of the relation OR uniqueId of toInstance equals to capabilityOwnerId of the relation
1447 private boolean isRequirementBelongToRelation(Component originComponent, RelationshipInfo reqAndRelationshipPair,
1448 RequirementDefinition requirement, String fromInstanceId) {
1449 if (!StringUtils.equals(requirement.getName(), reqAndRelationshipPair.getRequirement())) {
1450 log.debug("Failed to find a requirement with name {} and reqAndRelationshipPair {}",
1451 requirement.getName(), reqAndRelationshipPair.getRequirement());
1454 return ModelConverter.isAtomicComponent(originComponent) ||
1455 isRequirementBelongToOwner(reqAndRelationshipPair, requirement, fromInstanceId, originComponent);
1458 private boolean isRequirementBelongToOwner(RelationshipInfo reqAndRelationshipPair,
1459 RequirementDefinition requirement, String fromInstanceId,
1460 Component originComponent) {
1461 return StringUtils.equals(requirement.getOwnerId(), reqAndRelationshipPair.getRequirementOwnerId())
1462 || (isCvfc(originComponent) && StringUtils
1463 .equals(fromInstanceId, reqAndRelationshipPair.getRequirementOwnerId())
1464 || StringUtils.equals(requirement.getOwnerId(), originComponent.getUniqueId()));
1467 private boolean isCvfc(Component component) {
1468 return component.getComponentType() == ComponentTypeEnum.RESOURCE &&
1469 ((Resource) component).getResourceType() == ResourceTypeEnum.CVFC;
1472 private Either<SubstitutionMapping, ToscaError> convertCapabilities(Component component,
1473 SubstitutionMapping substitutionMappings,
1474 Map<String, Component> componentCache) {
1476 Either<SubstitutionMapping, ToscaError> result = Either.left(substitutionMappings);
1477 Either<Map<String, String[]>, ToscaError> toscaCapabilitiesRes = capabilityRequirementConverter
1478 .convertSubstitutionMappingCapabilities(componentCache, component);
1479 if (toscaCapabilitiesRes.isRight()) {
1480 result = Either.right(toscaCapabilitiesRes.right().value());
1481 log.debug("Failed convert capabilities for the component {}. ", component.getName());
1482 } else if (isNotEmpty(toscaCapabilitiesRes.left().value())) {
1483 substitutionMappings.setCapabilities(toscaCapabilitiesRes.left().value());
1484 log.debug("Finish convert capabilities for the component {}. ", component.getName());
1486 log.debug("Finished to convert capabilities for the component {}. ", component.getName());
1490 private Either<ToscaNodeType, ToscaError> convertCapabilities(Map<String, Component> componentsCache,
1491 Component component, ToscaNodeType nodeType,
1492 Map<String, DataTypeDefinition> dataTypes) {
1493 Map<String, ToscaCapability> toscaCapabilities = capabilityRequirementConverter
1494 .convertCapabilities(componentsCache, component,
1496 if (!toscaCapabilities.isEmpty()) {
1497 nodeType.setCapabilities(toscaCapabilities);
1499 log.debug("Finish convert Capabilities for node type");
1501 return Either.left(nodeType);
1504 private Map<String, ToscaTemplateArtifact> convertToNodeTemplateArtifacts(
1505 Map<String, ToscaArtifactDataDefinition> artifacts) {
1506 if (artifacts == null) {
1509 Map<String, ToscaTemplateArtifact> arts = new HashMap<>();
1510 for (Map.Entry<String, ToscaArtifactDataDefinition> entry : artifacts.entrySet()) {
1511 ToscaTemplateArtifact artifact = new ToscaTemplateArtifact();
1512 artifact.setFile(entry.getValue().getFile());
1513 artifact.setType(entry.getValue().getType());
1514 arts.put(entry.getKey(), artifact);
1519 protected NodeFilter convertToNodeTemplateNodeFilterComponent(CINodeFilterDataDefinition inNodeFilter) {
1520 if (inNodeFilter == null) {
1523 NodeFilter nodeFilter = new NodeFilter();
1525 ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities =
1526 inNodeFilter.getCapabilities();
1528 ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> origProperties = inNodeFilter.getProperties();
1530 List<Map<String, CapabilityFilter>> capabilitiesCopy = new ArrayList<>();
1531 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1533 copyNodeFilterCapabilitiesTemplate(origCapabilities, capabilitiesCopy);
1534 copyNodeFilterProperties(origProperties, propertiesCopy);
1536 if (CollectionUtils.isNotEmpty(capabilitiesCopy)) {
1537 nodeFilter.setCapabilities(capabilitiesCopy);
1540 if (CollectionUtils.isNotEmpty(propertiesCopy)) {
1541 nodeFilter.setProperties(propertiesCopy);
1544 nodeFilter.setTosca_id(cloneToscaId(inNodeFilter.getTosca_id()));
1546 nodeFilter = (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
1551 private NodeFilter convertToSubstitutionFilterComponent(
1552 final SubstitutionFilterDataDefinition substitutionFilterDataDefinition) {
1554 if (substitutionFilterDataDefinition == null) {
1557 NodeFilter nodeFilter = new NodeFilter();
1559 ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> origProperties =
1560 substitutionFilterDataDefinition.getProperties();
1561 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1563 copySubstitutionFilterProperties(origProperties, propertiesCopy);
1565 if (CollectionUtils.isNotEmpty(propertiesCopy)) {
1566 nodeFilter.setProperties(propertiesCopy);
1568 nodeFilter.setTosca_id(cloneToscaId(substitutionFilterDataDefinition.getTosca_id()));
1570 return (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
1573 private Object cloneToscaId(Object toscaId) {
1574 return Objects.isNull(toscaId) ? null
1575 : cloneObjectFromYml(toscaId, toscaId.getClass());
1578 private Object cloneObjectFromYml(Object objToClone, Class classOfObj) {
1579 String objectAsYml = yamlUtil.objectToYaml(objToClone);
1580 return yamlUtil.yamlToObject(objectAsYml, classOfObj);
1583 private void copyNodeFilterCapabilitiesTemplate(
1584 ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities,
1585 List<Map<String, CapabilityFilter>> capabilitiesCopy) {
1586 if (origCapabilities == null || origCapabilities.getListToscaDataDefinition() == null ||
1587 origCapabilities.getListToscaDataDefinition().isEmpty()) {
1590 for (RequirementNodeFilterCapabilityDataDefinition capability : origCapabilities.getListToscaDataDefinition()) {
1591 Map<String, CapabilityFilter> capabilityFilterCopyMap = new HashMap<>();
1592 CapabilityFilter capabilityFilter = new CapabilityFilter();
1593 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1594 copyNodeFilterProperties(capability.getProperties(), propertiesCopy);
1595 capabilityFilter.setProperties(propertiesCopy);
1596 capabilityFilterCopyMap.put(capability.getName(), capabilityFilter);
1597 capabilitiesCopy.add(capabilityFilterCopyMap);
1601 private void copyNodeFilterProperties(
1602 ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> origProperties,
1603 List<Map<String, List<Object>>> propertiesCopy) {
1604 if (origProperties == null || origProperties.getListToscaDataDefinition() == null ||
1605 origProperties.isEmpty()) {
1608 Map<String, List<Object>> propertyMapCopy = new HashMap<>();
1609 for (RequirementNodeFilterPropertyDataDefinition propertyDataDefinition : origProperties
1610 .getListToscaDataDefinition()) {
1611 for (String propertyInfoEntry : propertyDataDefinition.getConstraints()) {
1612 Map propertyValObj = new YamlUtil().yamlToObject(propertyInfoEntry, Map.class);
1613 String propertyName = propertyDataDefinition.getName();
1614 if (propertyMapCopy.containsKey(propertyName)) {
1615 addPropertyConstraintValueToList(propertyName, propertyValObj, propertyMapCopy.get(propertyName));
1617 if (propertyName != null) {
1618 List<Object> propsList = new ArrayList<>();
1619 addPropertyConstraintValueToList(propertyName, propertyValObj, propsList);
1620 propertyMapCopy.put(propertyName, propsList);
1622 propertyMapCopy.putAll(propertyValObj);
1627 propertyMapCopy.entrySet().stream().forEach(entry ->
1628 addCalculatedConstraintsIntoPropertiesList(propertiesCopy, entry));
1631 private void copySubstitutionFilterProperties(
1632 final ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> origProperties,
1633 final List<Map<String, List<Object>>> propertiesCopy) {
1634 if (origProperties == null || origProperties.getListToscaDataDefinition() == null ||
1635 origProperties.isEmpty()) {
1638 final Map<String, List<Object>> propertyMapCopy = new HashMap<>();
1639 for (final RequirementSubstitutionFilterPropertyDataDefinition propertyDataDefinition : origProperties
1640 .getListToscaDataDefinition()) {
1641 for (final String propertyInfoEntry : propertyDataDefinition.getConstraints()) {
1642 final Map<String, List<Object>> propertyValObj = new YamlUtil()
1643 .yamlToObject(propertyInfoEntry, Map.class);
1644 final String propertyName = propertyDataDefinition.getName();
1645 if (propertyMapCopy.containsKey(propertyName)) {
1646 addPropertyConstraintValueToList(propertyName, propertyValObj, propertyMapCopy.get(propertyName));
1648 if (propertyName != null) {
1649 final List<Object> propsList = new ArrayList<>();
1650 addPropertyConstraintValueToList(propertyName, propertyValObj, propsList);
1651 propertyMapCopy.put(propertyName, propsList);
1653 propertyMapCopy.putAll(propertyValObj);
1658 propertyMapCopy.entrySet().forEach(entry ->
1659 addCalculatedConstraintsIntoPropertiesList(propertiesCopy, entry));
1662 private void addPropertyConstraintValueToList(String propertyName, Map<String, List<Object>> propertyValObj, List<Object> propsList) {
1663 if (propertyValObj.containsKey(propertyName)) {
1664 propsList.add(propertyValObj.get(propertyName));
1666 propsList.add(propertyValObj);
1670 private void addCalculatedConstraintsIntoPropertiesList(List<Map<String, List<Object>>> propertiesCopy,
1671 Entry<String, List<Object>> entry) {
1672 Map<String, List<Object>> tempMap = new HashMap<>();
1673 tempMap.put(entry.getKey(), entry.getValue());
1674 propertiesCopy.add(tempMap);
1677 private static class CustomRepresenter extends Representer {
1679 CustomRepresenter() {
1681 this.representers.put(ToscaPropertyAssignment.class, new RepresentToscaPropertyAssignment());
1682 // null representer is exceptional and it is stored as an instance
1684 this.nullRepresenter = new RepresentNull();
1688 private class RepresentToscaPropertyAssignment implements Represent {
1690 public Node representData(Object data) {
1691 final ToscaPropertyAssignment toscaOperationAssignment = (ToscaPropertyAssignment) data;
1692 if (toscaOperationAssignment.getValue() instanceof String) {
1693 final String stringValue = (String) toscaOperationAssignment.getValue();
1694 if (isPropertyOrAttributeFunction(stringValue)) {
1695 return representGetAttribute(stringValue);
1698 return representScalar(Tag.STR, stringValue);
1700 return represent(null);
1703 public Node representGetAttribute(final String getAttributeFunction) {
1704 return represent(new Yaml().load(getAttributeFunction));
1707 public boolean isPropertyOrAttributeFunction(final String value) {
1709 final Yaml yaml = new Yaml();
1710 final Object yamlObj = yaml.load(value);
1711 if (!(yamlObj instanceof Map)) {
1714 final Map<String, Object> getAttributeMap = (Map) yamlObj;
1715 if (getAttributeMap.size() != 1) {
1718 final List<String> functionList = Arrays
1719 .asList(GET_ATTRIBUTE.getFunctionName(), GET_INPUT.getFunctionName(),
1720 GET_PROPERTY.getFunctionName());
1721 final Optional<String> function = getAttributeMap.keySet().stream()
1722 .filter(key -> functionList.stream().anyMatch(function1 -> function1.equals(key))).findFirst();
1724 if (function.isEmpty()) {
1727 final String functionName = function.get();
1728 final Object getAttributeValueObj = getAttributeMap.get(functionName);
1729 if (GET_INPUT.getFunctionName().equals(functionName)) {
1730 return validateGetInputValue(getAttributeValueObj);
1732 return validateGetPropertyOrAttributeValue(getAttributeValueObj);
1734 } catch (final Exception ignored) {
1740 public boolean validateGetInputValue(final Object valueObj) {
1741 if (!(valueObj instanceof List) && !(valueObj instanceof String)) {
1744 if (valueObj instanceof List) {
1745 return ((List) valueObj).size() > 1;
1751 public boolean validateGetPropertyOrAttributeValue(final Object valueObj) {
1752 if (valueObj instanceof List) {
1753 return ((List) valueObj).size() > 1;
1760 protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue,
1762 if (propertyValue == null) {
1765 // skip not relevant for Tosca property
1766 if ("dependencies".equals(property.getName())) {
1769 if (javaBean instanceof ToscaRelationshipTemplate && "name".equals(property.getName())) {
1773 removeDefaultP(propertyValue);
1774 NodeTuple defaultNode = super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
1776 if (javaBean instanceof ToscaTopolgyTemplate && "relationshipTemplates".equals(property.getName())) {
1777 return new NodeTuple(representData("relationship_templates"), defaultNode.getValueNode());
1780 return "_defaultp_".equals(property.getName())
1781 ? new NodeTuple(representData("default"), defaultNode.getValueNode()) : defaultNode;
1784 private void removeDefaultP(final Object propertyValue) {
1785 if (propertyValue instanceof Map) {
1786 final Map mapPropertyValue = ((Map) propertyValue);
1788 final Iterator<Entry> iter = mapPropertyValue.entrySet().iterator();
1789 Object defaultValue = null;
1790 while (iter.hasNext()) {
1791 final Map.Entry entry = iter.next();
1793 if ("_defaultp_".equals(entry.getKey())) {
1794 defaultValue = entry.getValue();
1796 } else if (entry.getValue() instanceof Map) {
1797 removeDefaultP(entry.getValue());
1800 if (defaultValue != null) {
1801 mapPropertyValue.putIfAbsent("default", defaultValue);
1807 protected MappingNode representJavaBean(Set<Property> properties, Object javaBean) {
1808 // remove the bean type from the output yaml (!! ...)
1809 if (!classTags.containsKey(javaBean.getClass())) {
1810 addClassTag(javaBean.getClass(), Tag.MAP);
1813 return super.representJavaBean(properties, javaBean);
1816 private class RepresentNull implements Represent {
1819 public Node representData(Object data) {
1820 // possible values are here http://yaml.org/type/null.html
1821 return representScalar(Tag.NULL, "");
1826 private static class UnsortedPropertyUtils extends PropertyUtils {
1829 protected Set<Property> createPropertySet(Class type, BeanAccess bAccess) {
1830 Collection<Property> fields = getPropertiesMap(type, BeanAccess.FIELD).values();
1831 return new LinkedHashSet<>(fields);
1835 private Map<String, String[]> buildSubstitutionMappingPropertyMapping(final Component component) {
1836 if (component == null || CollectionUtils.isEmpty(component.getInputs())) {
1837 return Collections.emptyMap();
1839 return component.getInputs().stream()
1840 .map(PropertyDataDefinition::getName)
1843 inputName -> inputName,
1844 inputName -> new String[]{inputName},
1845 (inputName1, inputName2) -> inputName1)
1849 private Map<String, String[]> buildSubstitutionMappingAttributesMapping(final Component component) {
1850 if (component == null || CollectionUtils.isEmpty(component.getOutputs())) {
1851 return Collections.emptyMap();
1853 return component.getOutputs().stream()
1854 .map(AttributeDataDefinition::getName)
1857 outputName -> outputName,
1858 outputName -> new String[]{outputName},
1859 (outputName1, outputName2) -> outputName1)
1863 Optional<Map<String, ToscaProperty>> getProxyNodeTypeProperties(Component proxyComponent,
1864 Map<String, DataTypeDefinition>
1866 if (Objects.isNull(proxyComponent)) {
1867 return Optional.empty();
1869 Map<String, ToscaProperty> proxyProperties = new HashMap<>();
1870 addInputsToProperties(dataTypes, proxyComponent.getInputs(), proxyProperties);
1871 if (CollectionUtils.isNotEmpty(proxyComponent.getProperties())) {
1872 proxyProperties.putAll(proxyComponent.getProperties().stream()
1873 .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition,
1874 proxyComponent.getInputs()))
1875 .collect(Collectors.toMap(PropertyDataDefinition::getName,
1876 property -> propertyConvertor.convertProperty(dataTypes, property,
1877 PropertyConvertor.PropertyType.PROPERTY))));
1879 return MapUtils.isNotEmpty(proxyProperties) ? Optional.of(proxyProperties) : Optional.empty();
1882 void addInputsToProperties(Map<String, DataTypeDefinition> dataTypes,
1883 List<InputDefinition> componentInputs,
1884 Map<String, ToscaProperty> mergedProperties) {
1885 if (CollectionUtils.isEmpty(componentInputs)) {
1888 for (InputDefinition input : componentInputs) {
1889 ToscaProperty property = propertyConvertor.convertProperty(dataTypes, input,
1890 PropertyConvertor.PropertyType.INPUT);
1891 mergedProperties.put(input.getName(), property);
1895 Optional<Map<String, Object>> getProxyNodeTypeInterfaces(Component proxyComponent,
1896 Map<String, DataTypeDefinition> dataTypes) {
1897 if (Objects.isNull(proxyComponent) || MapUtils.isEmpty(proxyComponent.getInterfaces())) {
1898 return Optional.empty();
1900 Map<String, InterfaceDefinition> proxyComponentInterfaces = proxyComponent.getInterfaces();
1901 //Unset artifact path for operation implementation for proxy node types as for operations with artifacts it is
1902 // always available in the proxy node template
1903 removeOperationImplementationForProxyNodeType(proxyComponentInterfaces);
1904 return Optional.ofNullable(interfacesOperationsConverter
1905 .getInterfacesMap(proxyComponent, null, proxyComponentInterfaces, dataTypes,
1909 private static void removeOperationImplementationForProxyNodeType(
1910 Map<String, InterfaceDefinition> proxyComponentInterfaces) {
1911 if (MapUtils.isEmpty(proxyComponentInterfaces)) {
1914 proxyComponentInterfaces.values().stream().map(InterfaceDataDefinition::getOperations)
1915 .filter(MapUtils::isNotEmpty)
1916 .forEach(operations -> operations.values().forEach(operation -> operation.setImplementation(null)));