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 fj.data.Either;
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.Collection;
35 import java.util.Collections;
36 import java.util.HashMap;
37 import java.util.Iterator;
38 import java.util.LinkedHashMap;
39 import java.util.LinkedHashSet;
40 import java.util.List;
42 import java.util.Map.Entry;
43 import java.util.Objects;
44 import java.util.Optional;
46 import java.util.function.Supplier;
47 import java.util.stream.Collectors;
48 import lombok.NoArgsConstructor;
49 import org.apache.commons.collections.CollectionUtils;
50 import org.apache.commons.collections.MapUtils;
51 import org.apache.commons.lang.StringUtils;
52 import org.apache.commons.lang3.tuple.ImmutablePair;
53 import org.apache.commons.lang3.tuple.ImmutableTriple;
54 import org.apache.commons.lang3.tuple.Triple;
55 import org.onap.sdc.tosca.services.YamlUtil;
56 import org.openecomp.sdc.be.components.impl.exceptions.SdcResourceNotFoundException;
57 import org.openecomp.sdc.be.config.ConfigurationManager;
58 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
59 import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
60 import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition;
61 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
62 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
63 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
64 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
65 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition;
66 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition;
67 import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterPropertyDataDefinition;
68 import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition;
69 import org.openecomp.sdc.be.datatypes.elements.ToscaArtifactDataDefinition;
70 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
71 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
72 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
73 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
74 import org.openecomp.sdc.be.exception.ToscaExportException;
75 import org.openecomp.sdc.be.model.ArtifactDefinition;
76 import org.openecomp.sdc.be.model.AttributeDefinition;
77 import org.openecomp.sdc.be.model.CapabilityDefinition;
78 import org.openecomp.sdc.be.model.CapabilityRequirementRelationship;
79 import org.openecomp.sdc.be.model.Component;
80 import org.openecomp.sdc.be.model.ComponentInstance;
81 import org.openecomp.sdc.be.model.ComponentInstanceInput;
82 import org.openecomp.sdc.be.model.ComponentInstanceInterface;
83 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
84 import org.openecomp.sdc.be.model.ComponentParametersView;
85 import org.openecomp.sdc.be.model.DataTypeDefinition;
86 import org.openecomp.sdc.be.model.GroupInstance;
87 import org.openecomp.sdc.be.model.InputDefinition;
88 import org.openecomp.sdc.be.model.InterfaceDefinition;
89 import org.openecomp.sdc.be.model.PropertyDefinition;
90 import org.openecomp.sdc.be.model.RelationshipInfo;
91 import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
92 import org.openecomp.sdc.be.model.RequirementDefinition;
93 import org.openecomp.sdc.be.model.Resource;
94 import org.openecomp.sdc.be.model.Service;
95 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
96 import org.openecomp.sdc.be.model.category.CategoryDefinition;
97 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
98 import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter;
99 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
100 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
101 import org.openecomp.sdc.be.tosca.PropertyConvertor.PropertyType;
102 import org.openecomp.sdc.be.tosca.builder.ToscaRelationshipBuilder;
103 import org.openecomp.sdc.be.tosca.exception.ToscaConversionException;
104 import org.openecomp.sdc.be.tosca.model.CapabilityFilter;
105 import org.openecomp.sdc.be.tosca.model.NodeFilter;
106 import org.openecomp.sdc.be.tosca.model.SubstitutionMapping;
107 import org.openecomp.sdc.be.tosca.model.ToscaAttribute;
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.enums.EcompLoggerErrorCode;
126 import org.openecomp.sdc.common.log.wrappers.Logger;
127 import org.springframework.beans.factory.annotation.Autowired;
128 import org.yaml.snakeyaml.DumperOptions;
129 import org.yaml.snakeyaml.DumperOptions.FlowStyle;
130 import org.yaml.snakeyaml.Yaml;
131 import org.yaml.snakeyaml.introspector.BeanAccess;
132 import org.yaml.snakeyaml.introspector.Property;
133 import org.yaml.snakeyaml.introspector.PropertyUtils;
134 import org.yaml.snakeyaml.nodes.MappingNode;
135 import org.yaml.snakeyaml.nodes.Node;
136 import org.yaml.snakeyaml.nodes.NodeTuple;
137 import org.yaml.snakeyaml.nodes.Tag;
138 import org.yaml.snakeyaml.representer.Represent;
139 import org.yaml.snakeyaml.representer.Representer;
142 @org.springframework.stereotype.Component("tosca-export-handler")
143 public class ToscaExportHandler {
145 private static final Logger log = Logger.getLogger(ToscaExportHandler.class);
147 private ApplicationDataTypeCache dataTypeCache;
148 private ToscaOperationFacade toscaOperationFacade;
149 private CapabilityRequirementConverter capabilityRequirementConverter;
150 private PolicyExportParser policyExportParser;
151 private GroupExportParser groupExportParser;
152 private PropertyConvertor propertyConvertor;
153 private InputConverter inputConverter;
154 private OutputConverter outputConverter;
155 private InterfaceLifecycleOperation interfaceLifecycleOperation;
156 private InterfacesOperationsConverter interfacesOperationsConverter;
159 public ToscaExportHandler(final ApplicationDataTypeCache dataTypeCache,
160 final ToscaOperationFacade toscaOperationFacade,
161 final CapabilityRequirementConverter capabilityRequirementConverter,
162 final PolicyExportParser policyExportParser,
163 final GroupExportParser groupExportParser,
164 final PropertyConvertor propertyConvertor,
165 final InputConverter inputConverter,
166 final OutputConverter outputConverter,
167 final InterfaceLifecycleOperation interfaceLifecycleOperation,
168 final InterfacesOperationsConverter interfacesOperationsConverter) {
169 this.dataTypeCache = dataTypeCache;
170 this.toscaOperationFacade = toscaOperationFacade;
171 this.capabilityRequirementConverter = capabilityRequirementConverter;
172 this.policyExportParser = policyExportParser;
173 this.groupExportParser = groupExportParser;
174 this.propertyConvertor = propertyConvertor;
175 this.inputConverter = inputConverter;
176 this.outputConverter = outputConverter;
177 this.interfaceLifecycleOperation = interfaceLifecycleOperation;
178 this.interfacesOperationsConverter = interfacesOperationsConverter;
181 private static final String TOSCA_VERSION = "tosca_simple_yaml_1_3";
182 private static final String SERVICE_NODE_TYPE_PREFIX = "org.openecomp.service.";
183 private static final String IMPORTS_FILE_KEY = "file";
184 private static final String TOSCA_INTERFACE_NAME = "-interface.yml";
185 public static final String ASSET_TOSCA_TEMPLATE = "assettoscatemplate";
186 private static final String FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION = "convertToToscaTemplate - failed to get Default Imports section from configuration";
187 private static final String NOT_SUPPORTED_COMPONENT_TYPE = "Not supported component type {}";
188 private static final String NATIVE_ROOT = "tosca.nodes.Root";
189 private static final YamlUtil yamlUtil = new YamlUtil();
191 public Either<ToscaRepresentation, ToscaError> exportComponent(Component component) {
192 return convertToToscaTemplate(component).left().map(this::createToscaRepresentation);
195 public Either<ToscaRepresentation, ToscaError> exportComponentInterface(final Component component,
196 final boolean isAssociatedComponent) {
197 final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImportConfig();
198 if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
199 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
200 return Either.right(ToscaError.GENERAL_ERROR);
203 String toscaVersion = null;
204 if (component instanceof Resource) {
205 toscaVersion = ((Resource) component).getToscaVersion();
207 ToscaTemplate toscaTemplate = new ToscaTemplate(toscaVersion != null ? toscaVersion : TOSCA_VERSION);
208 toscaTemplate.setImports(new ArrayList<>(defaultToscaImportConfig));
209 final Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
210 final Either<ToscaTemplate, ToscaError> toscaTemplateRes =
211 convertInterfaceNodeType(new HashMap<>(), component, toscaTemplate, nodeTypes, isAssociatedComponent);
212 if (toscaTemplateRes.isRight()) {
213 return Either.right(toscaTemplateRes.right().value());
216 toscaTemplate = toscaTemplateRes.left().value();
217 ToscaRepresentation toscaRepresentation = this.createToscaRepresentation(toscaTemplate);
218 return Either.left(toscaRepresentation);
221 public ToscaRepresentation createToscaRepresentation(ToscaTemplate toscaTemplate) {
222 CustomRepresenter representer = new CustomRepresenter();
223 DumperOptions options = new DumperOptions();
224 options.setAllowReadOnlyProperties(false);
225 options.setPrettyFlow(true);
227 options.setDefaultFlowStyle(FlowStyle.FLOW);
228 options.setCanonical(false);
230 representer.addClassTag(toscaTemplate.getClass(), Tag.MAP);
232 representer.setPropertyUtils(new UnsortedPropertyUtils());
233 Yaml yaml = new Yaml(representer, options);
235 String yamlAsString = yaml.dumpAsMap(toscaTemplate);
237 StringBuilder sb = new StringBuilder();
238 sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactHeader());
239 sb.append(yamlAsString);
240 sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactFooter());
242 return ToscaRepresentation.make(sb.toString().getBytes(), toscaTemplate);
245 public Either<ToscaTemplate, ToscaError> getDependencies(Component component) {
246 ToscaTemplate toscaTemplate = new ToscaTemplate(null);
247 Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports = fillImports(component,
249 if (fillImports.isRight()) {
250 return Either.right(fillImports.right().value());
252 return Either.left(fillImports.left().value().left);
255 public Either<ToscaTemplate, ToscaError> convertToToscaTemplate(final Component component) {
256 final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImportConfig();
257 if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
258 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
259 return Either.right(ToscaError.GENERAL_ERROR);
261 log.trace("start tosca export for {}", component.getUniqueId());
262 String toscaVersion = null;
263 if (component instanceof Resource) {
264 toscaVersion = ((Resource) component).getToscaVersion();
266 final ToscaTemplate toscaTemplate = new ToscaTemplate(toscaVersion != null ? toscaVersion : TOSCA_VERSION);
267 toscaTemplate.setMetadata(convertMetadata(component));
268 toscaTemplate.setImports(new ArrayList<>(defaultToscaImportConfig));
269 final Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
270 if (ModelConverter.isAtomicComponent(component)) {
271 log.trace("convert component as node type");
272 return convertNodeType(new HashMap<>(), component, toscaTemplate, nodeTypes);
274 log.trace("convert component as topology template");
275 return convertToscaTemplate(component, toscaTemplate);
280 private Either<ToscaTemplate, ToscaError> convertToscaTemplate(Component component, ToscaTemplate toscaNode) {
282 Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> importsRes = fillImports(component,
284 if (importsRes.isRight()) {
285 return Either.right(importsRes.right().value());
287 toscaNode = importsRes.left().value().left;
288 Map<String, Component> componentCache = importsRes.left().value().right;
289 Either<Map<String, ToscaNodeType>, ToscaError> nodeTypesMapEither = createProxyNodeTypes(componentCache,
291 if (nodeTypesMapEither.isRight()) {
292 log.debug("Failed to fetch normative service proxy resource by tosca name, error {}",
293 nodeTypesMapEither.right().value());
294 return Either.right(nodeTypesMapEither.right().value());
296 Map<String, ToscaNodeType> nodeTypesMap = nodeTypesMapEither.left().value();
297 if (nodeTypesMap != null && !nodeTypesMap.isEmpty()) {
298 toscaNode.setNode_types(nodeTypesMap);
301 createServiceSubstitutionNodeTypes(componentCache, component, toscaNode);
303 Either<Map<String, Object>, ToscaError> proxyInterfaceTypesEither = createProxyInterfaceTypes(component);
304 if (proxyInterfaceTypesEither.isRight()) {
305 log.debug("Failed to populate service proxy local interface types in tosca, error {}",
306 nodeTypesMapEither.right().value());
307 return Either.right(proxyInterfaceTypesEither.right().value());
309 Map<String, Object> proxyInterfaceTypes = proxyInterfaceTypesEither.left().value();
310 if (MapUtils.isNotEmpty(proxyInterfaceTypes)) {
311 toscaNode.setInterface_types(proxyInterfaceTypes);
314 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = dataTypeCache.getAll();
315 if (dataTypesEither.isRight()) {
316 log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
317 return Either.right(ToscaError.GENERAL_ERROR);
319 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
320 ToscaTopolgyTemplate topologyTemplate = new ToscaTopolgyTemplate();
321 List<InputDefinition> inputDef = component.getInputs();
322 Map<String, ToscaProperty> inputs = inputConverter.convertInputs(inputDef, dataTypes);
324 if (!inputs.isEmpty()) {
325 topologyTemplate.setInputs(inputs);
328 final Map<String, ToscaProperty> outputs;
330 outputs = outputConverter.convert(component.getOutputs(), dataTypes);
331 } catch (final ToscaConversionException e) {
332 log.error(EcompLoggerErrorCode.SCHEMA_ERROR, ToscaExportHandler.class.getName(),
333 "Could not parse component '{}' outputs. Component unique id '{}'.",
334 new Object[]{component.getName(), component.getUniqueId(), e});
335 return Either.right(ToscaError.GENERAL_ERROR);
337 if (!outputs.isEmpty()) {
338 topologyTemplate.setOutputs(outputs);
341 final List<ComponentInstance> componentInstances = component.getComponentInstances();
342 Map<String, List<ComponentInstanceProperty>> componentInstancesProperties = component.getComponentInstancesProperties();
343 Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces = component.getComponentInstancesInterfaces();
344 if (CollectionUtils.isNotEmpty(componentInstances)) {
345 final Either<Map<String, ToscaNodeTemplate>, ToscaError> nodeTemplates = convertNodeTemplates(component, componentInstances,
346 componentInstancesProperties, componentInstanceInterfaces, componentCache, dataTypes, topologyTemplate);
347 if (nodeTemplates.isRight()) {
348 return Either.right(nodeTemplates.right().value());
350 log.debug("node templates converted");
351 topologyTemplate.setNode_templates(nodeTemplates.left().value());
353 final Map<String, ToscaRelationshipTemplate> relationshipTemplatesMap =
354 new ToscaExportRelationshipTemplatesHandler().createFrom(topologyTemplate.getNode_templates());
355 if (!relationshipTemplatesMap.isEmpty()) {
356 topologyTemplate.setRelationshipTemplates(relationshipTemplatesMap);
359 SubstitutionMapping substitutionMapping = new SubstitutionMapping();
360 convertSubstitutionMappingFilter(component, substitutionMapping);
362 addGroupsToTopologyTemplate(component, topologyTemplate);
365 addPoliciesToTopologyTemplate(component, topologyTemplate);
366 } catch (SdcResourceNotFoundException e) {
367 log.debug("Fail to add policies to topology template:", e);
368 return Either.right(ToscaError.GENERAL_ERROR);
371 String toscaResourceName;
372 switch (component.getComponentType()) {
374 toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition()
375 .getMetadataDataDefinition()).getToscaResourceName();
378 toscaResourceName = SERVICE_NODE_TYPE_PREFIX
379 + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName();
382 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
383 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
385 substitutionMapping.setNode_type(toscaResourceName);
386 Either<SubstitutionMapping, ToscaError> capabilities = convertCapabilities(component, substitutionMapping,
388 if (capabilities.isRight()) {
389 return Either.right(capabilities.right().value());
391 substitutionMapping = capabilities.left().value();
393 Either<SubstitutionMapping, ToscaError> requirements = capabilityRequirementConverter
394 .convertSubstitutionMappingRequirements(componentCache, component, substitutionMapping);
395 if (requirements.isRight()) {
396 return Either.right(requirements.right().value());
398 substitutionMapping = requirements.left().value();
399 final Map<String, String[]> propertyMappingMap = buildSubstitutionMappingPropertyMapping(component);
400 if (!propertyMappingMap.isEmpty()) {
401 substitutionMapping.setProperties(propertyMappingMap);
404 final Map<String, String[]> attributesMappingMap = buildSubstitutionMappingAttributesMapping(component);
405 if (!attributesMappingMap.isEmpty()) {
406 substitutionMapping.setAttributes(attributesMappingMap);
409 topologyTemplate.setSubstitution_mappings(substitutionMapping);
411 toscaNode.setTopology_template(topologyTemplate);
413 return Either.left(toscaNode);
416 private void convertSubstitutionMappingFilter(final Component component,
417 final SubstitutionMapping substitutionMapping) {
418 if (component.getSubstitutionFilter() != null
419 && (component.getSubstitutionFilter().getProperties()).getListToscaDataDefinition() != null) {
421 .setSubstitution_filter(convertToSubstitutionFilterComponent(component.getSubstitutionFilter()));
425 private void addGroupsToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate) {
426 Map<String, ToscaGroupTemplate> groups = groupExportParser.getGroups(component);
427 if (groups != null) {
428 topologyTemplate.addGroups(groups);
432 private void addPoliciesToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate)
433 throws SdcResourceNotFoundException {
434 Map<String, ToscaPolicyTemplate> policies = policyExportParser.getPolicies(component);
435 if (policies != null) {
436 topologyTemplate.addPolicies(policies);
440 private Map<String, String> convertMetadata(Component component) {
441 return convertMetadata(component, false, null);
444 private Map<String, String> convertMetadata(Component component, boolean isInstance,
445 ComponentInstance componentInstance) {
446 Map<String, String> toscaMetadata = new LinkedHashMap<>();
447 toscaMetadata.put(JsonPresentationFields.INVARIANT_UUID.getPresentation(), component.getInvariantUUID());
448 toscaMetadata.put(JsonPresentationFields.UUID.getPresentation(), component.getUUID());
450 .put(JsonPresentationFields.NAME.getPresentation(), component.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
451 toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), component.getDescription());
453 List<CategoryDefinition> categories = component.getCategories();
454 CategoryDefinition categoryDefinition = categories.get(0);
455 toscaMetadata.put(JsonPresentationFields.CATEGORY.getPresentation(), categoryDefinition.getName());
458 toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), component.getVersion());
459 toscaMetadata.put(JsonPresentationFields.CUSTOMIZATION_UUID.getPresentation(), componentInstance.getCustomizationUUID());
460 if (componentInstance.getSourceModelInvariant() != null
461 && !componentInstance.getSourceModelInvariant().isEmpty()) {
462 toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), componentInstance.getComponentVersion());
463 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_INVARIANT.getPresentation(), componentInstance.getSourceModelInvariant());
464 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_UUID.getPresentation(), componentInstance.getSourceModelUuid());
465 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_NAME.getPresentation(), componentInstance.getSourceModelName());
466 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
467 toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(),
468 componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceProxy.getDisplayValue());
469 } else if (componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
470 toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(),
471 componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceSubstitution
474 toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), componentInstance.getDescription());
478 switch (component.getComponentType()) {
480 Resource resource = (Resource) component;
482 if (isInstance && (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy
483 || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution)) {
484 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), componentInstance.getOriginType().getDisplayValue());
486 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), resource.getResourceType().name());
488 toscaMetadata.put(JsonPresentationFields.SUB_CATEGORY.getPresentation(), categoryDefinition.getSubcategories().get(0).getName());
489 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR.getPresentation(), resource.getVendorName());
490 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_RELEASE.getPresentation(), resource.getVendorRelease());
491 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_MODEL_NUMBER.getPresentation(), resource.getResourceVendorModelNumber());
494 Service service = (Service) component;
495 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), component.getComponentType().getValue());
496 toscaMetadata.put(JsonPresentationFields.SERVICE_TYPE.getPresentation(), service.getServiceType());
497 toscaMetadata.put(JsonPresentationFields.SERVICE_ROLE.getPresentation(), service.getServiceRole());
498 toscaMetadata.put(JsonPresentationFields.SERVICE_FUNCTION.getPresentation(), service.getServiceFunction());
499 toscaMetadata.put(JsonPresentationFields.ENVIRONMENT_CONTEXT.getPresentation(), service.getEnvironmentContext());
500 toscaMetadata.put(JsonPresentationFields.INSTANTIATION_TYPE.getPresentation(),
501 service.getEnvironmentContext() == null ? StringUtils.EMPTY : service.getInstantiationType());
504 toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming().toString());
505 toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming().toString());
506 toscaMetadata.put(JsonPresentationFields.NAMING_POLICY.getPresentation(), service.getNamingPolicy());
510 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
513 for (final String key : component.getCategorySpecificMetadata().keySet()) {
514 toscaMetadata.put(key, component.getCategorySpecificMetadata().get(key));
516 return toscaMetadata;
519 private Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports(Component component,
520 ToscaTemplate toscaTemplate) {
522 final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImportConfig();
523 if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
524 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
525 return Either.right(ToscaError.GENERAL_ERROR);
527 Map<String, Component> componentCache = new HashMap<>();
529 if (!ModelConverter.isAtomicComponent(component)) {
530 final List<Map<String, Map<String, String>>> additionalImports =
531 toscaTemplate.getImports() == null ? new ArrayList<>(defaultToscaImportConfig)
532 : new ArrayList<>(toscaTemplate.getImports());
534 List<Triple<String, String, Component>> dependecies = new ArrayList<>();
536 Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
537 if (isNotEmpty(toscaArtifacts)) {
538 ArtifactDefinition artifactDefinition = toscaArtifacts.get(ToscaExportHandler.ASSET_TOSCA_TEMPLATE);
539 if (artifactDefinition != null) {
540 Map<String, Map<String, String>> importsListMember = new HashMap<>();
541 Map<String, String> interfaceFiles = new HashMap<>();
542 interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactDefinition.getArtifactName()));
543 StringBuilder keyNameBuilder = new StringBuilder();
544 keyNameBuilder.append(component.getComponentType().toString().toLowerCase()).append("-")
545 .append(component.getName()).append("-interface");
546 importsListMember.put(keyNameBuilder.toString(), interfaceFiles);
547 additionalImports.add(importsListMember);
550 List<ComponentInstance> componentInstances = component.getComponentInstances();
551 if (componentInstances != null && !componentInstances.isEmpty()) {
552 componentInstances.forEach(ci -> createDependency(componentCache, additionalImports, dependecies, ci));
554 toscaTemplate.setDependencies(dependecies);
555 toscaTemplate.setImports(additionalImports);
557 log.debug("currently imports supported for VF and service only");
559 return Either.left(new ImmutablePair<>(toscaTemplate, componentCache));
562 private List<Map<String, Map<String, String>>> getDefaultToscaImportConfig() {
563 return ConfigurationManager.getConfigurationManager().getConfiguration().getDefaultImports();
566 private void createDependency(final Map<String, Component> componentCache,
567 final List<Map<String, Map<String, String>>> imports,
568 final List<Triple<String, String, Component>> dependencies,
569 final ComponentInstance componentInstance) {
570 log.debug("createDependency componentCache {}", componentCache);
571 Component componentRI = componentCache.get(componentInstance.getComponentUid());
572 if (componentRI == null || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
573 // all resource must be only once!
574 final Either<Component, StorageOperationStatus> resource = toscaOperationFacade
575 .getToscaFullElement(componentInstance.getComponentUid());
576 if ((resource.isRight()) && (log.isDebugEnabled())) {
577 log.debug("Failed to fetch resource with id {} for instance {}", componentInstance.getComponentUid(),
578 componentInstance.getUniqueId());
581 final Component fetchedComponent = resource.left().value();
582 componentRI = setComponentCache(componentCache, componentInstance, fetchedComponent);
583 addDependencies(imports, dependencies, componentRI);
588 * Sets a componentCache from the given component/resource.
590 private Component setComponentCache(final Map<String, Component> componentCache,
591 final ComponentInstance componentInstance,
592 final Component fetchedComponent) {
593 componentCache.put(fetchedComponent.getUniqueId(), fetchedComponent);
594 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy
595 || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
596 final Either<Component, StorageOperationStatus> sourceService = toscaOperationFacade
597 .getToscaFullElement(componentInstance.getSourceModelUid());
598 if (sourceService.isRight() && (log.isDebugEnabled())) {
599 log.debug("Failed to fetch source service with id {} for proxy {}",
600 componentInstance.getSourceModelUid(), componentInstance.getUniqueId());
602 final Component fetchedSource = sourceService.left().value();
603 componentCache.put(fetchedSource.getUniqueId(), fetchedSource);
604 return fetchedSource;
606 return fetchedComponent;
610 * Retrieves all derived_from nodes and stores it in a predictable order.
612 private void addDependencies(final List<Map<String, Map<String, String>>> imports,
613 final List<Triple<String, String, Component>> dependencies,
614 final Component fetchedComponent) {
615 final Set<Component> componentsList = new LinkedHashSet<>();
616 if (fetchedComponent instanceof Resource) {
617 log.debug("fetchedComponent is a resource {}", fetchedComponent);
619 final Optional<Map<String, String>> derivedFromMapOfIdToName = getDerivedFromMapOfIdToName(fetchedComponent,
621 if (derivedFromMapOfIdToName.isPresent() && !derivedFromMapOfIdToName.get().isEmpty()) {
622 derivedFromMapOfIdToName.get().entrySet().forEach(entry -> {
623 log.debug("Started entry.getValue() : {}", entry.getValue());
624 if (!NATIVE_ROOT.equals(entry.getValue())) {
625 Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade
626 .getToscaElement(entry.getKey());
627 if (resourcefetched != null && resourcefetched.isLeft()) {
628 componentsList.add(resourcefetched.left().value());
632 setImports(imports, dependencies, componentsList);
634 setImports(imports, dependencies, fetchedComponent);
641 * Returns all derived_from nodes found.
643 private Optional<Map<String, String>> getDerivedFromMapOfIdToName(final Component fetchedComponent,
644 final Set<Component> componentsList) {
645 final Resource parentResource = (Resource) fetchedComponent;
646 Map<String, String> derivedFromMapOfIdToName = new HashMap<>();
647 if (CollectionUtils.isNotEmpty(parentResource.getComponentInstances())) {
648 componentsList.add(fetchedComponent);
649 for (final ComponentInstance componentInstance : parentResource.getComponentInstances()) {
650 final Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade
651 .getToscaElement(componentInstance.getComponentUid());
652 if (resourcefetched != null && resourcefetched.isLeft()) {
653 final Map<String, String> derivedWithId = resourcefetched.left().value()
654 .getDerivedFromMapOfIdToName();
655 if (MapUtils.isNotEmpty(derivedWithId)) {
656 derivedFromMapOfIdToName.putAll(derivedWithId);
661 derivedFromMapOfIdToName = parentResource.getDerivedFromMapOfIdToName();
663 log.debug("Started derivedFromMapOfIdToName: {}", derivedFromMapOfIdToName);
664 return Optional.ofNullable(derivedFromMapOfIdToName);
668 * Creates a resource map and adds it to the import list.
670 private void setImports(final List<Map<String, Map<String, String>>> imports,
671 final List<Triple<String, String, Component>> dependencies,
672 final Set<Component> componentsList) {
673 componentsList.forEach(component -> setImports(imports, dependencies, component));
676 private void setImports(final List<Map<String, Map<String, String>>> imports,
677 final List<Triple<String, String, Component>> dependencies,
678 final Component component) {
679 final Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
680 final ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE);
681 if (artifactDefinition != null) {
682 final Map<String, String> files = new HashMap<>();
683 final String artifactName = artifactDefinition.getArtifactName();
684 files.put(IMPORTS_FILE_KEY, artifactName);
685 final StringBuilder keyNameBuilder = new StringBuilder();
686 keyNameBuilder.append(component.getComponentType().toString().toLowerCase());
687 keyNameBuilder.append("-");
688 keyNameBuilder.append(component.getName());
689 addImports(imports, keyNameBuilder, files);
691 .add(new ImmutableTriple<>(artifactName, artifactDefinition.getEsId(), component));
693 if (!ModelConverter.isAtomicComponent(component)) {
694 final Map<String, String> interfaceFiles = new HashMap<>();
695 interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactName));
696 keyNameBuilder.append("-interface");
697 addImports(imports, keyNameBuilder, interfaceFiles);
703 * Adds the found resource to the import definition list.
705 private void addImports(final List<Map<String, Map<String, String>>> imports,
706 final StringBuilder keyNameBuilder,
707 final Map<String, String> files) {
708 final String mapKey = keyNameBuilder.toString();
709 if (imports.stream().allMatch(stringMapMap -> stringMapMap.get(mapKey) == null)) {
710 final Map<String, Map<String, String>> importsListMember = new HashMap<>();
711 importsListMember.put(keyNameBuilder.toString(), files);
712 imports.add(importsListMember);
716 public static String getInterfaceFilename(String artifactName) {
717 return artifactName.substring(0, artifactName.lastIndexOf('.')) + ToscaExportHandler.TOSCA_INTERFACE_NAME;
720 private Either<ToscaTemplate, ToscaError> convertNodeType(Map<String, Component> componentsCache,
721 Component component, ToscaTemplate toscaNode,
722 Map<String, ToscaNodeType> nodeTypes) {
723 return convertInterfaceNodeType(componentsCache, component, toscaNode, nodeTypes, false);
726 public Either<ToscaTemplate, ToscaError> convertInterfaceNodeType(Map<String, Component> componentsCache,
727 Component component, ToscaTemplate toscaNode,
728 Map<String, ToscaNodeType> nodeTypes,
729 boolean isAssociatedComponent) {
730 log.debug("start convert node type for {}", component.getUniqueId());
731 ToscaNodeType toscaNodeType = createNodeType(component);
733 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither =
734 interfaceLifecycleOperation.getAllInterfaceLifecycleTypes();
735 if (lifecycleTypeEither.isRight()) {
736 log.debug("Failed to fetch all interface types :", lifecycleTypeEither.right().value());
737 return Either.right(ToscaError.GENERAL_ERROR);
739 List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value()
742 .map(InterfaceDataDefinition::getType)
743 .collect(Collectors.toList());
744 toscaNode.setInterface_types(addInterfaceTypeElement(component, allGlobalInterfaceTypes));
746 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = dataTypeCache.getAll();
747 if (dataTypesEither.isRight()) {
748 log.debug("Failed to fetch all data types :", dataTypesEither.right().value());
749 return Either.right(ToscaError.GENERAL_ERROR);
752 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
754 List<InputDefinition> inputDef = component.getInputs();
755 Map<String, ToscaProperty> mergedProperties = new HashMap<>();
756 interfacesOperationsConverter
757 .addInterfaceDefinitionElement(component, toscaNodeType, dataTypes, isAssociatedComponent);
758 addInputsToProperties(dataTypes, inputDef, mergedProperties);
760 final Map<String, ToscaAttribute> toscaAttributeMap;
762 toscaAttributeMap = convertToToscaAttributes(component.getAttributes(), dataTypes);
763 } catch (final ToscaConversionException e) {
764 log.error(EcompLoggerErrorCode.SCHEMA_ERROR, ToscaExportHandler.class.getName(),
765 "Could not parse component '{}' attributes. Component unique id '{}'.",
766 new Object[]{component.getName(), component.getUniqueId(), e});
767 return Either.right(ToscaError.GENERAL_ERROR);
769 if (!toscaAttributeMap.isEmpty()) {
770 toscaNodeType.setAttributes(toscaAttributeMap);
772 if (CollectionUtils.isNotEmpty(component.getProperties())) {
773 List<PropertyDefinition> properties = component.getProperties();
774 Map<String, ToscaProperty> convertedProperties = properties.stream()
775 .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, component.getInputs()))
776 .collect(Collectors.toMap(PropertyDataDefinition::getName,
777 property -> propertyConvertor.convertProperty(dataTypes, property,
778 PropertyConvertor.PropertyType.PROPERTY)));
779 // merge component properties and inputs properties
780 mergedProperties.putAll(convertedProperties);
782 if (MapUtils.isNotEmpty(mergedProperties)) {
783 toscaNodeType.setProperties(mergedProperties);
786 /* convert private data_types */
787 List<DataTypeDefinition> privateDataTypes = component.getDataTypes();
788 if (CollectionUtils.isNotEmpty(privateDataTypes)) {
789 Map<String, ToscaDataType> toscaDataTypeMap = new HashMap<>();
790 for (DataTypeDefinition dataType : privateDataTypes) {
791 log.debug("Emitting private data type: component.name={} dataType.name={}",
792 component.getNormalizedName(), dataType.getName());
793 ToscaDataType toscaDataType = new ToscaDataType();
794 toscaDataType.setDerived_from(dataType.getDerivedFromName());
795 toscaDataType.setDescription(dataType.getDescription());
796 toscaDataType.setVersion(dataType.getVersion());
797 if (CollectionUtils.isNotEmpty(dataType.getProperties())) {
798 toscaDataType.setProperties(dataType.getProperties().stream()
799 .collect(Collectors.toMap(
800 PropertyDataDefinition::getName,
801 s -> propertyConvertor
802 .convertProperty(dataTypes, s, PropertyType.PROPERTY)
805 toscaDataTypeMap.put(dataType.getName(), toscaDataType);
807 toscaNode.setData_types(toscaDataTypeMap);
810 // Extracted to method for code reuse
811 return convertReqCapAndTypeName(componentsCache, component, toscaNode, nodeTypes, toscaNodeType, dataTypes);
814 private Map<String, ToscaAttribute> convertToToscaAttributes(final List<AttributeDefinition> attributeList,
815 final Map<String, DataTypeDefinition> dataTypes) throws ToscaConversionException {
816 if (CollectionUtils.isEmpty(attributeList)) {
817 return Collections.emptyMap();
819 final AttributeConverter attributeConverter = new AttributeConverter(dataTypes);
820 final Map<String, ToscaAttribute> toscaAttributeMap = new HashMap<>();
821 for (final AttributeDefinition attributeDefinition : attributeList) {
822 toscaAttributeMap.put(attributeDefinition.getName(), attributeConverter.convert(attributeDefinition));
824 return toscaAttributeMap;
827 private Either<ToscaTemplate, ToscaError> convertReqCapAndTypeName(Map<String, Component> componentsCache,
828 Component component, ToscaTemplate toscaNode,
829 Map<String, ToscaNodeType> nodeTypes,
830 ToscaNodeType toscaNodeType,
831 Map<String, DataTypeDefinition> dataTypes) {
832 Either<ToscaNodeType, ToscaError> capabilities = convertCapabilities(componentsCache, component, toscaNodeType,
834 if (capabilities.isRight()) {
835 return Either.right(capabilities.right().value());
837 toscaNodeType = capabilities.left().value();
838 log.debug("Capabilities converted for {}", component.getUniqueId());
840 Either<ToscaNodeType, ToscaError> requirements = capabilityRequirementConverter
841 .convertRequirements(componentsCache, component,
843 if (requirements.isRight()) {
844 return Either.right(requirements.right().value());
846 toscaNodeType = requirements.left().value();
847 log.debug("Requirements converted for {}", component.getUniqueId());
849 String toscaResourceName;
850 switch (component.getComponentType()) {
852 toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition()
853 .getMetadataDataDefinition()).getToscaResourceName();
856 toscaResourceName = SERVICE_NODE_TYPE_PREFIX
857 + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName();
860 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
861 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
864 nodeTypes.put(toscaResourceName, toscaNodeType);
865 toscaNode.setNode_types(nodeTypes);
866 log.debug("finish convert node type for {}", component.getUniqueId());
867 return Either.left(toscaNode);
870 protected Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplates(
872 List<ComponentInstance> componentInstances,
873 Map<String, List<ComponentInstanceProperty>> componentInstancesProperties,
874 Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces,
875 Map<String, Component> componentCache, Map<String, DataTypeDefinition> dataTypes,
876 ToscaTopolgyTemplate topologyTemplate) {
878 Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplatesRes = null;
879 log.debug("start convert topology template for {} for type {}", component.getUniqueId(),
880 component.getComponentType());
881 Map<String, ToscaNodeTemplate> nodeTemplates = new HashMap<>();
882 Map<String, List<ComponentInstanceInput>> componentInstancesInputs = component.getComponentInstancesInputs();
884 Map<String, ToscaGroupTemplate> groupsMap = null;
885 for (ComponentInstance componentInstance : componentInstances) {
886 ToscaNodeTemplate nodeTemplate = new ToscaNodeTemplate();
887 if (MapUtils.isNotEmpty(componentInstance.getToscaArtifacts())) {
888 nodeTemplate.setArtifacts(convertToNodeTemplateArtifacts(componentInstance.getToscaArtifacts()));
890 nodeTemplate.setType(componentInstance.getToscaComponentName());
891 nodeTemplate.setDirectives(componentInstance.getDirectives());
892 nodeTemplate.setNode_filter(convertToNodeTemplateNodeFilterComponent(componentInstance.getNodeFilter()));
894 Either<Component, Boolean> originComponentRes = capabilityRequirementConverter
895 .getOriginComponent(componentCache, componentInstance);
896 if (originComponentRes.isRight()) {
897 convertNodeTemplatesRes = Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
900 Either<ToscaNodeTemplate, ToscaError> requirements = convertComponentInstanceRequirements(component,
901 componentInstance, component.getComponentInstancesRelations(), nodeTemplate,
902 originComponentRes.left().value(), componentCache);
903 if (requirements.isRight()) {
904 convertNodeTemplatesRes = Either.right(requirements.right().value());
907 String instanceUniqueId = componentInstance.getUniqueId();
908 log.debug("Component instance Requirements converted for instance {}", instanceUniqueId);
910 nodeTemplate = requirements.left().value();
912 Component originalComponent = componentCache.get(componentInstance.getActualComponentUid());
914 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
915 Component componentOfProxy = componentCache.get(componentInstance.getComponentUid());
916 nodeTemplate.setMetadata(convertMetadata(componentOfProxy, true, componentInstance));
918 nodeTemplate.setMetadata(convertMetadata(originalComponent, true, componentInstance));
921 Either<ToscaNodeTemplate, ToscaError> capabilities = capabilityRequirementConverter
922 .convertComponentInstanceCapabilities(componentInstance, dataTypes, nodeTemplate);
923 if (capabilities.isRight()) {
924 convertNodeTemplatesRes = Either.right(capabilities.right().value());
927 log.debug("Component instance Capabilities converted for instance {}", instanceUniqueId);
929 nodeTemplate = capabilities.left().value();
930 Map<String, Object> props = new HashMap<>();
932 if (originalComponent.getComponentType() == ComponentTypeEnum.RESOURCE) {
933 // Adds the properties of parent component to map
934 addPropertiesOfParentComponent(dataTypes, originalComponent, props);
937 if (null != componentInstancesProperties && componentInstancesProperties.containsKey(instanceUniqueId)) {
938 addPropertiesOfComponentInstance(componentInstancesProperties, dataTypes, instanceUniqueId,
942 if (componentInstancesInputs != null && componentInstancesInputs.containsKey(instanceUniqueId)
943 && !isComponentOfTypeServiceProxy(componentInstance)) {
944 //For service proxy the inputs are already handled under instance properties above
945 addComponentInstanceInputs(dataTypes, componentInstancesInputs, instanceUniqueId, props);
948 //M3[00001] - NODE TEMPLATE INTERFACES - START
949 handleInstanceInterfaces(componentInstanceInterfaces, componentInstance, dataTypes, nodeTemplate,
950 instanceUniqueId, component);
951 //M3[00001] - NODE TEMPLATE INTERFACES - END
952 if (props != null && !props.isEmpty()) {
953 nodeTemplate.setProperties(props);
956 List<GroupInstance> groupInstances = componentInstance.getGroupInstances();
957 if (groupInstances != null) {
958 if (groupsMap == null) {
959 groupsMap = new HashMap<>();
961 for (GroupInstance groupInst : groupInstances) {
962 boolean addToTosca = true;
964 List<String> artifacts = groupInst.getArtifacts();
965 if (artifacts == null || artifacts.isEmpty()) {
970 ToscaGroupTemplate toscaGroup = groupExportParser
971 .getToscaGroupTemplate(groupInst, componentInstance.getInvariantName());
972 groupsMap.put(groupInst.getName(), toscaGroup);
977 nodeTemplates.put(componentInstance.getName(), nodeTemplate);
979 if (groupsMap != null) {
980 log.debug("instance groups added");
981 topologyTemplate.addGroups(groupsMap);
983 if (component.getComponentType() == ComponentTypeEnum.SERVICE && isNotEmpty(
984 ((Service) component).getForwardingPaths())) {
985 log.debug("Starting converting paths for component {}, name {}", component.getUniqueId(),
986 component.getName());
987 ForwardingPathToscaUtil
988 .addForwardingPaths((Service) component, nodeTemplates, capabilityRequirementConverter, componentCache,
989 toscaOperationFacade);
990 log.debug("Finished converting paths for component {}, name {}", component.getUniqueId(),
991 component.getName());
993 if (convertNodeTemplatesRes == null) {
994 convertNodeTemplatesRes = Either.left(nodeTemplates);
996 log.debug("finish convert topology template for {} for type {}", component.getUniqueId(),
997 component.getComponentType());
998 return convertNodeTemplatesRes;
1001 private void handleInstanceInterfaces(
1002 Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces,
1003 ComponentInstance componentInstance, Map<String, DataTypeDefinition> dataTypes, ToscaNodeTemplate nodeTemplate,
1004 String instanceUniqueId,
1005 Component parentComponent) {
1007 if (MapUtils.isEmpty(componentInstanceInterfaces)
1008 || !componentInstanceInterfaces.containsKey(instanceUniqueId)) {
1009 nodeTemplate.setInterfaces(null);
1013 final List<ComponentInstanceInterface> currServiceInterfaces =
1014 componentInstanceInterfaces.get(instanceUniqueId);
1016 final Map<String, InterfaceDefinition> tmpInterfaces = new HashMap<>();
1017 currServiceInterfaces.forEach(instInterface -> tmpInterfaces.put(instInterface
1018 .getUniqueId(), instInterface));
1020 final Map<String, Object> interfaceMap = interfacesOperationsConverter
1021 .getInterfacesMap(parentComponent, componentInstance, tmpInterfaces, dataTypes, isComponentOfTypeServiceProxy(componentInstance),
1022 isComponentOfTypeServiceProxy(componentInstance));
1024 interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
1025 nodeTemplate.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap);
1028 private boolean isComponentOfTypeServiceProxy(ComponentInstance componentInstance) {
1029 return Objects.nonNull(componentInstance.getOriginType())
1030 && componentInstance.getOriginType().getValue().equals("Service Proxy");
1033 private void addComponentInstanceInputs(Map<String, DataTypeDefinition> dataTypes,
1034 Map<String, List<ComponentInstanceInput>> componentInstancesInputs,
1035 String instanceUniqueId, Map<String, Object> props) {
1037 List<ComponentInstanceInput> instanceInputsList = componentInstancesInputs.get(instanceUniqueId);
1038 if (instanceInputsList != null) {
1039 instanceInputsList.forEach(input -> {
1041 Supplier<String> supplier = () -> input.getValue() != null && !Objects.isNull(input.getValue())
1042 ? input.getValue() : input.getDefaultValue();
1043 propertyConvertor.convertAndAddValue(dataTypes, props, input, supplier);
1048 private void addPropertiesOfComponentInstance(
1049 Map<String, List<ComponentInstanceProperty>> componentInstancesProperties,
1050 Map<String, DataTypeDefinition> dataTypes, String instanceUniqueId,
1051 Map<String, Object> props) {
1053 if (isNotEmpty(componentInstancesProperties)) {
1054 componentInstancesProperties.get(instanceUniqueId)
1055 // Converts and adds each value to property map
1056 .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop,
1061 private void addPropertiesOfParentComponent(Map<String, DataTypeDefinition> dataTypes,
1062 Component componentOfInstance, Map<String, Object> props) {
1064 List<PropertyDefinition> componentProperties = componentOfInstance.getProperties();
1065 if (isNotEmpty(componentProperties)) {
1066 componentProperties.stream()
1067 // Filters out properties with empty default values
1068 .filter(prop -> StringUtils.isNotEmpty(prop.getDefaultValue()))
1069 // Converts and adds each value to property map
1070 .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop,
1071 prop::getDefaultValue));
1075 private ToscaNodeType createNodeType(Component component) {
1076 ToscaNodeType toscaNodeType = new ToscaNodeType();
1077 if (ModelConverter.isAtomicComponent(component)) {
1078 if (((Resource) component).getDerivedFrom() != null) {
1079 toscaNodeType.setDerived_from(((Resource) component).getDerivedFrom().get(0));
1081 toscaNodeType.setDescription(component.getDescription());
1083 String derivedFrom = null != component.getDerivedFromGenericType() ? component.getDerivedFromGenericType()
1085 toscaNodeType.setDerived_from(derivedFrom);
1087 return toscaNodeType;
1090 private Either<Map<String, Object>, ToscaError> createProxyInterfaceTypes(Component container) {
1092 Map<String, Object> proxyInterfaceTypes = new HashMap<>();
1093 Either<Map<String, Object>, ToscaError> res = Either.left(proxyInterfaceTypes);
1094 List<ComponentInstance> componentInstances = container.getComponentInstances();
1095 if (CollectionUtils.isEmpty(componentInstances)) {
1098 Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
1099 componentInstances.stream()
1100 .filter(this::isComponentOfTypeServiceProxy)
1101 .forEach(inst -> serviceProxyInstanceList.put(inst.getToscaComponentName(), inst));
1102 if (MapUtils.isEmpty(serviceProxyInstanceList)) {
1105 for (Entry<String, ComponentInstance> entryProxy : serviceProxyInstanceList.entrySet()) {
1106 Component serviceComponent;
1107 ComponentParametersView componentParametersView = new ComponentParametersView();
1108 componentParametersView.disableAll();
1109 componentParametersView.setIgnoreInterfaces(false);
1110 Either<Component, StorageOperationStatus> service = toscaOperationFacade
1111 .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
1112 if (service.isRight()) {
1113 log.debug("Failed to fetch original service component with id {} for instance {}",
1114 entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName());
1115 return Either.right(ToscaError.GENERAL_ERROR);
1117 serviceComponent = service.left().value();
1120 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither =
1121 interfaceLifecycleOperation.getAllInterfaceLifecycleTypes();
1122 if (lifecycleTypeEither.isRight()) {
1123 log.debug("Failed to retrieve global interface types :", lifecycleTypeEither.right().value());
1124 return Either.right(ToscaError.GENERAL_ERROR);
1127 List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value().values().stream()
1128 .map(InterfaceDataDefinition::getType)
1129 .collect(Collectors.toList());
1130 //Add interface types for local interfaces in the original service component for proxy
1131 Map<String, Object> localInterfaceTypes = addInterfaceTypeElement(serviceComponent,
1132 allGlobalInterfaceTypes);
1133 if (MapUtils.isNotEmpty(localInterfaceTypes)) {
1134 proxyInterfaceTypes.putAll(localInterfaceTypes);
1138 return Either.left(proxyInterfaceTypes);
1141 private Either<Map<String, ToscaNodeType>, ToscaError> createProxyNodeTypes(Map<String, Component> componentCache,
1142 Component container) {
1144 Map<String, ToscaNodeType> nodeTypesMap = new HashMap<>();
1145 Either<Map<String, ToscaNodeType>, ToscaError> res = Either.left(nodeTypesMap);
1147 List<ComponentInstance> componentInstances = container.getComponentInstances();
1149 if (componentInstances == null || componentInstances.isEmpty()) {
1152 Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
1153 List<ComponentInstance> proxyInst = componentInstances.stream()
1154 .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceProxy.name()))
1155 .collect(Collectors.toList());
1156 if (proxyInst != null && !proxyInst.isEmpty()) {
1157 for (ComponentInstance inst : proxyInst) {
1158 serviceProxyInstanceList.put(inst.getToscaComponentName(), inst);
1162 if (serviceProxyInstanceList.isEmpty()) {
1165 Either<Resource, StorageOperationStatus> serviceProxyOrigin = toscaOperationFacade
1166 .getLatestByName("serviceProxy");
1167 if (serviceProxyOrigin.isRight()) {
1168 log.debug("Failed to fetch normative service proxy resource by tosca name, error {}",
1169 serviceProxyOrigin.right().value());
1170 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
1172 Component origComponent = serviceProxyOrigin.left().value();
1174 for (Entry<String, ComponentInstance> entryProxy : serviceProxyInstanceList.entrySet()) {
1175 Component serviceComponent = null;
1176 ComponentParametersView componentParametersView = new ComponentParametersView();
1177 componentParametersView.disableAll();
1178 componentParametersView.setIgnoreCategories(false);
1179 componentParametersView.setIgnoreProperties(false);
1180 componentParametersView.setIgnoreInputs(false);
1181 componentParametersView.setIgnoreInterfaces(false);
1182 componentParametersView.setIgnoreRequirements(false);
1183 Either<Component, StorageOperationStatus> service = toscaOperationFacade
1184 .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
1185 if (service.isRight()) {
1186 log.debug("Failed to fetch resource with id {} for instance {}",
1187 entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName());
1189 serviceComponent = service.left().value();
1192 ToscaNodeType toscaNodeType = createProxyNodeType(componentCache, origComponent, serviceComponent,
1193 entryProxy.getValue());
1194 nodeTypesMap.put(entryProxy.getKey(), toscaNodeType);
1197 return Either.left(nodeTypesMap);
1200 private void createServiceSubstitutionNodeTypes(final Map<String, Component> componentCache,
1201 final Component container, final ToscaTemplate toscaNode) {
1202 final List<ComponentInstance> componentInstances = container.getComponentInstances();
1204 if (CollectionUtils.isEmpty(componentInstances)) {
1207 final List<ComponentInstance> serviceSubstitutionInstanceList = componentInstances.stream()
1208 .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceSubstitution.name()))
1209 .collect(Collectors.toList());
1210 if (CollectionUtils.isNotEmpty(serviceSubstitutionInstanceList)) {
1211 for (ComponentInstance inst : serviceSubstitutionInstanceList) {
1212 final Map<String, ToscaNodeType> nodeTypes =
1213 toscaNode.getNode_types() == null ? new HashMap<>() : toscaNode.getNode_types();
1214 convertInterfaceNodeType(new HashMap<>(), componentCache.get(inst.getSourceModelUid()), toscaNode,
1220 private ToscaNodeType createProxyNodeType(Map<String, Component> componentCache, Component origComponent,
1221 Component proxyComponent, ComponentInstance componentInstance) {
1222 ToscaNodeType toscaNodeType = new ToscaNodeType();
1223 String derivedFrom = ((Resource) origComponent).getToscaResourceName();
1225 toscaNodeType.setDerived_from(derivedFrom);
1226 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = dataTypeCache.getAll();
1227 if (dataTypesEither.isRight()) {
1228 log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
1230 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
1231 Map<String, ToscaCapability> capabilities = this.capabilityRequirementConverter
1232 .convertProxyCapabilities(componentCache, componentInstance, dataTypes);
1234 if (MapUtils.isNotEmpty(capabilities)) {
1235 toscaNodeType.setCapabilities(capabilities);
1237 List<Map<String, ToscaRequirement>> proxyNodeTypeRequirements = this.capabilityRequirementConverter
1238 .convertProxyRequirements(componentCache, componentInstance);
1239 if (CollectionUtils.isNotEmpty(proxyNodeTypeRequirements)) {
1240 toscaNodeType.setRequirements(proxyNodeTypeRequirements);
1242 Optional<Map<String, ToscaProperty>> proxyProperties = getProxyNodeTypeProperties(proxyComponent, dataTypes);
1243 proxyProperties.ifPresent(toscaNodeType::setProperties);
1245 Map<String, Object> interfaceMap = new HashMap<>();
1246 if (MapUtils.isEmpty(componentInstance.getInterfaces())) {
1247 final Optional<Map<String, Object>> proxyInterfaces = getProxyNodeTypeInterfaces(proxyComponent, dataTypes);
1248 if (proxyInterfaces.isPresent()) {
1249 interfaceMap = proxyInterfaces.get();
1252 interfaceMap = interfacesOperationsConverter
1253 .getInterfacesMapFromComponentInstance(proxyComponent, componentInstance, dataTypes, false, false);
1256 interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
1257 toscaNodeType.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap);
1259 return toscaNodeType;
1262 private Either<ToscaNodeTemplate, ToscaError> convertComponentInstanceRequirements(Component component,
1263 ComponentInstance componentInstance,
1264 List<RequirementCapabilityRelDef> relations,
1265 ToscaNodeTemplate nodeTypeTemplate,
1266 Component originComponent,
1267 Map<String, Component> componentCache) {
1269 final List<Map<String, ToscaTemplateRequirement>> toscaRequirements;
1270 final List<RequirementCapabilityRelDef> requirementDefinitionList = filterRequirements(componentInstance,
1272 if (isNotEmpty(requirementDefinitionList)) {
1274 toscaRequirements = buildRequirements(component, componentInstance,
1275 requirementDefinitionList, originComponent, componentCache);
1276 if (!toscaRequirements.isEmpty()) {
1277 nodeTypeTemplate.setRequirements(toscaRequirements);
1279 } catch (final Exception e) {
1280 log.debug("Failed to convert component instance requirements for the component instance {}. ",
1281 componentInstance.getName(), e);
1282 return Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
1285 log.debug("Finished to convert requirements for the node type {} ", componentInstance.getName());
1286 return Either.left(nodeTypeTemplate);
1289 private List<Map<String, ToscaTemplateRequirement>> buildRequirements(final Component component,
1290 final ComponentInstance componentInstance,
1291 final List<RequirementCapabilityRelDef> filteredRelations,
1292 final Component originComponent,
1293 final Map<String, Component> componentCache)
1294 throws ToscaExportException {
1296 final List<Map<String, ToscaTemplateRequirement>> toscaRequirements = new ArrayList<>();
1297 for (RequirementCapabilityRelDef relationshipDefinition : filteredRelations) {
1298 final Map<String, ToscaTemplateRequirement> toscaTemplateRequirementMap =
1299 buildRequirement(componentInstance, originComponent, component.getComponentInstances(),
1300 relationshipDefinition, componentCache);
1301 toscaRequirements.add(toscaTemplateRequirementMap);
1304 return toscaRequirements;
1307 private List<RequirementCapabilityRelDef> filterRequirements(ComponentInstance componentInstance,
1308 List<RequirementCapabilityRelDef> relations) {
1309 return relations.stream()
1310 .filter(p -> componentInstance.getUniqueId().equals(p.getFromNode())).collect(Collectors.toList());
1313 private Map<String, ToscaTemplateRequirement> buildRequirement(final ComponentInstance fromInstance,
1314 final Component fromOriginComponent,
1315 final List<ComponentInstance> instancesList,
1316 final RequirementCapabilityRelDef relationshipDefinition,
1317 final Map<String, Component> componentCache)
1318 throws ToscaExportException {
1320 final Map<String, List<RequirementDefinition>> reqMap = fromOriginComponent.getRequirements();
1321 final CapabilityRequirementRelationship capabilityRequirementRelationship = relationshipDefinition
1322 .getRelationships().get(0);
1323 final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation();
1325 final ComponentInstance toInstance = instancesList.stream()
1326 .filter(i -> relationshipDefinition.getToNode().equals(i.getUniqueId()))
1327 .findFirst().orElse(null);
1328 if (toInstance == null) {
1329 final String errorMsg = String
1330 .format("Failed to find a relation from the node %s to the node %s", fromInstance.getName(),
1331 relationshipDefinition.getToNode());
1332 log.debug(errorMsg);
1333 throw new ToscaExportException(errorMsg);
1335 final Optional<RequirementDefinition> reqOpt =
1336 findRequirement(fromOriginComponent, reqMap, relationshipInfo, fromInstance.getUniqueId());
1337 if (reqOpt.isEmpty()) {
1338 final String errorMsg = String
1339 .format("Failed to find a requirement with uniqueId %s on a component with uniqueId %s",
1340 relationshipInfo.getRequirementUid(), fromOriginComponent.getUniqueId());
1341 log.debug(errorMsg);
1342 throw new ToscaExportException(errorMsg);
1344 final ComponentParametersView filter = new ComponentParametersView(true);
1345 filter.setIgnoreComponentInstances(false);
1346 filter.setIgnoreCapabilities(false);
1347 filter.setIgnoreGroups(false);
1348 final Either<Component, StorageOperationStatus> getOriginRes =
1349 toscaOperationFacade.getToscaElement(toInstance.getActualComponentUid(), filter);
1350 if (getOriginRes.isRight()) {
1351 final String errorMsg = String.format(
1352 "Failed to build substituted name for the requirement %s. "
1353 + "Failed to get an origin component with uniqueId %s",
1354 reqOpt.get().getName(), toInstance.getActualComponentUid());
1355 log.debug(errorMsg);
1356 throw new ToscaExportException(errorMsg);
1358 final Component toOriginComponent = getOriginRes.left().value();
1359 Optional<CapabilityDefinition> capOpt = toOriginComponent.getCapabilities().get(reqOpt.get().getCapability()).stream()
1360 .filter(c -> isCapabilityBelongToRelation(relationshipInfo, c)).findFirst();
1361 if (capOpt.isEmpty()) {
1362 capOpt = findCapability(relationshipInfo, toOriginComponent, fromOriginComponent, reqOpt.get());
1363 if (capOpt.isEmpty()) {
1364 final String errorMsg = String
1365 .format("Failed to find a capability with name %s on a component with uniqueId %s",
1366 relationshipInfo.getCapability(), fromOriginComponent.getUniqueId());
1367 log.debug(errorMsg);
1368 throw new ToscaExportException(errorMsg);
1371 return buildRequirement(fromOriginComponent, toOriginComponent, capOpt.get(), reqOpt.get(),
1372 capabilityRequirementRelationship, toInstance, componentCache);
1375 private boolean isCapabilityBelongToRelation(RelationshipInfo reqAndRelationshipPair,
1376 CapabilityDefinition capability) {
1377 return capability.getName().equals(reqAndRelationshipPair.getCapability()) && (capability.getOwnerId() != null
1378 && capability.getOwnerId().equals(reqAndRelationshipPair.getCapabilityOwnerId()));
1381 private Optional<CapabilityDefinition> findCapability(RelationshipInfo reqAndRelationshipPair,
1382 Component toOriginComponent, Component fromOriginComponent,
1383 RequirementDefinition requirement) {
1384 Optional<CapabilityDefinition> cap = toOriginComponent.getCapabilities().get(requirement.getCapability())
1385 .stream().filter(c -> c.getType().equals(requirement.getCapability())).findFirst();
1386 if (!cap.isPresent()) {
1387 log.debug("Failed to find a capability with name {} on a component with uniqueId {}",
1388 reqAndRelationshipPair.getCapability(), fromOriginComponent.getUniqueId());
1393 private Map<String, ToscaTemplateRequirement> buildRequirement(final Component fromOriginComponent,
1394 final Component toOriginComponent,
1395 final CapabilityDefinition capability,
1396 final RequirementDefinition requirement,
1397 final CapabilityRequirementRelationship capabilityRequirementRelationship,
1398 final ComponentInstance toInstance,
1399 final Map<String, Component> componentCache)
1400 throws ToscaExportException {
1402 List<String> reducedPath = capability.getPath();
1403 if (capability.getOwnerId() != null) {
1404 reducedPath = capabilityRequirementConverter
1405 .getReducedPathByOwner(capability.getPath(), capability.getOwnerId());
1407 final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation();
1408 final Either<String, Boolean> capabilityNameEither = capabilityRequirementConverter.buildSubstitutedName(componentCache,
1409 toOriginComponent, reducedPath, relationshipInfo.getCapability(), capability.getPreviousName());
1410 if (capabilityNameEither.isRight()) {
1411 final String errorMsg = String.format(
1412 "Failed to build a substituted capability name for the capability with name %s on a component with uniqueId %s",
1413 capabilityRequirementRelationship.getCapability(), toOriginComponent.getUniqueId());
1416 throw new ToscaExportException(errorMsg);
1418 final Either<String, Boolean> requirementNameEither = capabilityRequirementConverter
1419 .buildSubstitutedName(componentCache, fromOriginComponent,
1420 requirement.getPath(), relationshipInfo.getRequirement(), requirement.getPreviousName());
1421 if (requirementNameEither.isRight()) {
1422 final String errorMsg = String.format("Failed to build a substituted requirement name for the requirement "
1423 + "with name %s on a component with uniqueId %s",
1424 capabilityRequirementRelationship.getRequirement(), fromOriginComponent.getUniqueId());
1425 log.debug(errorMsg);
1426 throw new ToscaExportException(errorMsg);
1428 final ToscaTemplateRequirement toscaRequirement = new ToscaTemplateRequirement();
1429 final Map<String, ToscaTemplateRequirement> toscaReqMap = new HashMap<>();
1430 toscaRequirement.setNode(toInstance.getName());
1431 toscaRequirement.setCapability(capabilityNameEither.left().value());
1432 if (isNotEmpty(capabilityRequirementRelationship.getOperations())) {
1433 toscaRequirement.setRelationship(new ToscaRelationshipBuilder().from(capabilityRequirementRelationship));
1435 toscaReqMap.put(requirementNameEither.left().value(), toscaRequirement);
1439 private Optional<RequirementDefinition> findRequirement(Component fromOriginComponent,
1440 Map<String, List<RequirementDefinition>> reqMap,
1441 RelationshipInfo reqAndRelationshipPair,
1442 String fromInstanceId) {
1443 for (List<RequirementDefinition> reqList : reqMap.values()) {
1444 Optional<RequirementDefinition> reqOpt = reqList.stream().filter(
1445 r -> isRequirementBelongToRelation(fromOriginComponent, reqAndRelationshipPair, r, fromInstanceId))
1447 if (reqOpt.isPresent()) {
1451 return Optional.empty();
1455 * Allows detecting the requirement belonging to the received relationship The detection logic is: A requirement belongs to a relationship IF
1456 * 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
1457 * requirement equals to requirementOwnerId of the relation OR uniqueId of toInstance equals to capabilityOwnerId of the relation
1459 private boolean isRequirementBelongToRelation(Component originComponent, RelationshipInfo reqAndRelationshipPair,
1460 RequirementDefinition requirement, String fromInstanceId) {
1461 if (!StringUtils.equals(requirement.getName(), reqAndRelationshipPair.getRequirement())) {
1462 log.debug("Failed to find a requirement with name {} and reqAndRelationshipPair {}",
1463 requirement.getName(), reqAndRelationshipPair.getRequirement());
1466 return ModelConverter.isAtomicComponent(originComponent) ||
1467 isRequirementBelongToOwner(reqAndRelationshipPair, requirement, fromInstanceId, originComponent);
1470 private boolean isRequirementBelongToOwner(RelationshipInfo reqAndRelationshipPair,
1471 RequirementDefinition requirement, String fromInstanceId,
1472 Component originComponent) {
1473 return StringUtils.equals(requirement.getOwnerId(), reqAndRelationshipPair.getRequirementOwnerId())
1474 || (isCvfc(originComponent) && StringUtils
1475 .equals(fromInstanceId, reqAndRelationshipPair.getRequirementOwnerId())
1476 || StringUtils.equals(requirement.getOwnerId(), originComponent.getUniqueId()));
1479 private boolean isCvfc(Component component) {
1480 return component.getComponentType() == ComponentTypeEnum.RESOURCE &&
1481 ((Resource) component).getResourceType() == ResourceTypeEnum.CVFC;
1484 private Either<SubstitutionMapping, ToscaError> convertCapabilities(Component component,
1485 SubstitutionMapping substitutionMappings,
1486 Map<String, Component> componentCache) {
1488 Either<SubstitutionMapping, ToscaError> result = Either.left(substitutionMappings);
1489 Either<Map<String, String[]>, ToscaError> toscaCapabilitiesRes = capabilityRequirementConverter
1490 .convertSubstitutionMappingCapabilities(componentCache, component);
1491 if (toscaCapabilitiesRes.isRight()) {
1492 result = Either.right(toscaCapabilitiesRes.right().value());
1493 log.debug("Failed convert capabilities for the component {}. ", component.getName());
1494 } else if (isNotEmpty(toscaCapabilitiesRes.left().value())) {
1495 substitutionMappings.setCapabilities(toscaCapabilitiesRes.left().value());
1496 log.debug("Finish convert capabilities for the component {}. ", component.getName());
1498 log.debug("Finished to convert capabilities for the component {}. ", component.getName());
1502 private Either<ToscaNodeType, ToscaError> convertCapabilities(Map<String, Component> componentsCache,
1503 Component component, ToscaNodeType nodeType,
1504 Map<String, DataTypeDefinition> dataTypes) {
1505 Map<String, ToscaCapability> toscaCapabilities = capabilityRequirementConverter
1506 .convertCapabilities(componentsCache, component,
1508 if (!toscaCapabilities.isEmpty()) {
1509 nodeType.setCapabilities(toscaCapabilities);
1511 log.debug("Finish convert Capabilities for node type");
1513 return Either.left(nodeType);
1516 private Map<String, ToscaTemplateArtifact> convertToNodeTemplateArtifacts(
1517 Map<String, ToscaArtifactDataDefinition> artifacts) {
1518 if (artifacts == null) {
1521 Map<String, ToscaTemplateArtifact> arts = new HashMap<>();
1522 for (Map.Entry<String, ToscaArtifactDataDefinition> entry : artifacts.entrySet()) {
1523 ToscaTemplateArtifact artifact = new ToscaTemplateArtifact();
1524 artifact.setFile(entry.getValue().getFile());
1525 artifact.setType(entry.getValue().getType());
1526 arts.put(entry.getKey(), artifact);
1531 protected NodeFilter convertToNodeTemplateNodeFilterComponent(CINodeFilterDataDefinition inNodeFilter) {
1532 if (inNodeFilter == null) {
1535 NodeFilter nodeFilter = new NodeFilter();
1537 ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities =
1538 inNodeFilter.getCapabilities();
1540 ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> origProperties = inNodeFilter.getProperties();
1542 List<Map<String, CapabilityFilter>> capabilitiesCopy = new ArrayList<>();
1543 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1545 copyNodeFilterCapabilitiesTemplate(origCapabilities, capabilitiesCopy);
1546 copyNodeFilterProperties(origProperties, propertiesCopy);
1548 if (CollectionUtils.isNotEmpty(capabilitiesCopy)) {
1549 nodeFilter.setCapabilities(capabilitiesCopy);
1552 if (CollectionUtils.isNotEmpty(propertiesCopy)) {
1553 nodeFilter.setProperties(propertiesCopy);
1556 nodeFilter.setTosca_id(cloneToscaId(inNodeFilter.getTosca_id()));
1558 nodeFilter = (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
1563 private NodeFilter convertToSubstitutionFilterComponent(
1564 final SubstitutionFilterDataDefinition substitutionFilterDataDefinition) {
1566 if (substitutionFilterDataDefinition == null) {
1569 NodeFilter nodeFilter = new NodeFilter();
1571 ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> origProperties =
1572 substitutionFilterDataDefinition.getProperties();
1573 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1575 copySubstitutionFilterProperties(origProperties, propertiesCopy);
1577 if (CollectionUtils.isNotEmpty(propertiesCopy)) {
1578 nodeFilter.setProperties(propertiesCopy);
1580 nodeFilter.setTosca_id(cloneToscaId(substitutionFilterDataDefinition.getTosca_id()));
1582 return (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
1585 private Object cloneToscaId(Object toscaId) {
1586 return Objects.isNull(toscaId) ? null
1587 : cloneObjectFromYml(toscaId, toscaId.getClass());
1590 private Object cloneObjectFromYml(Object objToClone, Class classOfObj) {
1591 String objectAsYml = yamlUtil.objectToYaml(objToClone);
1592 return yamlUtil.yamlToObject(objectAsYml, classOfObj);
1595 private void copyNodeFilterCapabilitiesTemplate(
1596 ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities,
1597 List<Map<String, CapabilityFilter>> capabilitiesCopy) {
1598 if (origCapabilities == null || origCapabilities.getListToscaDataDefinition() == null ||
1599 origCapabilities.getListToscaDataDefinition().isEmpty()) {
1602 for (RequirementNodeFilterCapabilityDataDefinition capability : origCapabilities.getListToscaDataDefinition()) {
1603 Map<String, CapabilityFilter> capabilityFilterCopyMap = new HashMap<>();
1604 CapabilityFilter capabilityFilter = new CapabilityFilter();
1605 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1606 copyNodeFilterProperties(capability.getProperties(), propertiesCopy);
1607 capabilityFilter.setProperties(propertiesCopy);
1608 capabilityFilterCopyMap.put(capability.getName(), capabilityFilter);
1609 capabilitiesCopy.add(capabilityFilterCopyMap);
1613 private void copyNodeFilterProperties(
1614 ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> origProperties,
1615 List<Map<String, List<Object>>> propertiesCopy) {
1616 if (origProperties == null || origProperties.getListToscaDataDefinition() == null ||
1617 origProperties.isEmpty()) {
1620 Map<String, List<Object>> propertyMapCopy = new HashMap<>();
1621 for (RequirementNodeFilterPropertyDataDefinition propertyDataDefinition : origProperties
1622 .getListToscaDataDefinition()) {
1623 for (String propertyInfoEntry : propertyDataDefinition.getConstraints()) {
1624 Map propertyValObj = new YamlUtil().yamlToObject(propertyInfoEntry, Map.class);
1625 String propertyName = propertyDataDefinition.getName();
1626 if (propertyMapCopy.containsKey(propertyName)) {
1627 addPropertyConstraintValueToList(propertyName, propertyValObj, propertyMapCopy.get(propertyName));
1629 if (propertyName != null) {
1630 List<Object> propsList = new ArrayList<>();
1631 addPropertyConstraintValueToList(propertyName, propertyValObj, propsList);
1632 propertyMapCopy.put(propertyName, propsList);
1634 propertyMapCopy.putAll(propertyValObj);
1639 propertyMapCopy.entrySet().stream().forEach(entry ->
1640 addCalculatedConstraintsIntoPropertiesList(propertiesCopy, entry));
1643 private void copySubstitutionFilterProperties(
1644 final ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> origProperties,
1645 final List<Map<String, List<Object>>> propertiesCopy) {
1646 if (origProperties == null || origProperties.getListToscaDataDefinition() == null ||
1647 origProperties.isEmpty()) {
1650 final Map<String, List<Object>> propertyMapCopy = new HashMap<>();
1651 for (final RequirementSubstitutionFilterPropertyDataDefinition propertyDataDefinition : origProperties
1652 .getListToscaDataDefinition()) {
1653 for (final String propertyInfoEntry : propertyDataDefinition.getConstraints()) {
1654 final Map<String, List<Object>> propertyValObj = new YamlUtil()
1655 .yamlToObject(propertyInfoEntry, Map.class);
1656 final String propertyName = propertyDataDefinition.getName();
1657 if (propertyMapCopy.containsKey(propertyName)) {
1658 addPropertyConstraintValueToList(propertyName, propertyValObj, propertyMapCopy.get(propertyName));
1660 if (propertyName != null) {
1661 final List<Object> propsList = new ArrayList<>();
1662 addPropertyConstraintValueToList(propertyName, propertyValObj, propsList);
1663 propertyMapCopy.put(propertyName, propsList);
1665 propertyMapCopy.putAll(propertyValObj);
1670 propertyMapCopy.entrySet().forEach(entry ->
1671 addCalculatedConstraintsIntoPropertiesList(propertiesCopy, entry));
1674 private void addPropertyConstraintValueToList(String propertyName, Map<String, List<Object>> propertyValObj, List<Object> propsList) {
1675 if (propertyValObj.containsKey(propertyName)) {
1676 propsList.add(propertyValObj.get(propertyName));
1678 propsList.add(propertyValObj);
1682 private void addCalculatedConstraintsIntoPropertiesList(List<Map<String, List<Object>>> propertiesCopy,
1683 Entry<String, List<Object>> entry) {
1684 Map<String, List<Object>> tempMap = new HashMap<>();
1685 tempMap.put(entry.getKey(), entry.getValue());
1686 propertiesCopy.add(tempMap);
1689 private static class CustomRepresenter extends Representer {
1691 CustomRepresenter() {
1693 this.representers.put(ToscaPropertyAssignment.class, new RepresentToscaPropertyAssignment());
1694 this.representers.put(ToscaAttribute.class, new RepresentToscaAttribute());
1695 // null representer is exceptional and it is stored as an instance
1697 this.nullRepresenter = new RepresentNull();
1701 private class RepresentToscaAttribute implements Represent {
1704 public Node representData(Object data) {
1705 final ToscaAttribute toscaAttribute = (ToscaAttribute) data;
1706 return represent(toscaAttribute.asToscaMap());
1710 private class RepresentToscaPropertyAssignment implements Represent {
1712 public Node representData(Object data) {
1713 final ToscaPropertyAssignment toscaOperationAssignment = (ToscaPropertyAssignment) data;
1714 if (toscaOperationAssignment.getValue() instanceof String) {
1715 final String stringValue = (String) toscaOperationAssignment.getValue();
1716 if (isPropertyOrAttributeFunction(stringValue)) {
1717 return representGetAttribute(stringValue);
1720 return representScalar(Tag.STR, stringValue);
1722 return represent(null);
1725 public Node representGetAttribute(final String getAttributeFunction) {
1726 return represent(new Yaml().load(getAttributeFunction));
1729 public boolean isPropertyOrAttributeFunction(final String value) {
1731 final Yaml yaml = new Yaml();
1732 final Object yamlObj = yaml.load(value);
1733 if (!(yamlObj instanceof Map)) {
1736 final Map<String, Object> getAttributeMap = (Map) yamlObj;
1737 if (getAttributeMap.size() != 1) {
1740 final List<String> functionList = Arrays
1741 .asList(GET_ATTRIBUTE.getFunctionName(), GET_INPUT.getFunctionName(),
1742 GET_PROPERTY.getFunctionName());
1743 final Optional<String> function = getAttributeMap.keySet().stream()
1744 .filter(key -> functionList.stream().anyMatch(function1 -> function1.equals(key))).findFirst();
1746 if (function.isEmpty()) {
1749 final String functionName = function.get();
1750 final Object getAttributeValueObj = getAttributeMap.get(functionName);
1751 if (GET_INPUT.getFunctionName().equals(functionName)) {
1752 return validateGetInputValue(getAttributeValueObj);
1754 return validateGetPropertyOrAttributeValue(getAttributeValueObj);
1756 } catch (final Exception ignored) {
1762 public boolean validateGetInputValue(final Object valueObj) {
1763 if (!(valueObj instanceof List) && !(valueObj instanceof String)) {
1766 if (valueObj instanceof List) {
1767 return ((List) valueObj).size() > 1;
1773 public boolean validateGetPropertyOrAttributeValue(final Object valueObj) {
1774 if (valueObj instanceof List) {
1775 return ((List) valueObj).size() > 1;
1782 protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue,
1784 if (propertyValue == null) {
1787 // skip not relevant for Tosca property
1788 if ("dependencies".equals(property.getName())) {
1791 if (javaBean instanceof ToscaRelationshipTemplate && "name".equals(property.getName())) {
1795 removeDefaultP(propertyValue);
1796 NodeTuple defaultNode = super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
1798 if (javaBean instanceof ToscaTopolgyTemplate && "relationshipTemplates".equals(property.getName())) {
1799 return new NodeTuple(representData("relationship_templates"), defaultNode.getValueNode());
1802 return "_defaultp_".equals(property.getName())
1803 ? new NodeTuple(representData("default"), defaultNode.getValueNode()) : defaultNode;
1806 private void removeDefaultP(final Object propertyValue) {
1807 if (propertyValue instanceof Map) {
1808 final Map mapPropertyValue = ((Map) propertyValue);
1810 final Iterator<Entry> iter = mapPropertyValue.entrySet().iterator();
1811 Object defaultValue = null;
1812 while (iter.hasNext()) {
1813 final Map.Entry entry = iter.next();
1815 if ("_defaultp_".equals(entry.getKey())) {
1816 defaultValue = entry.getValue();
1818 } else if (entry.getValue() instanceof Map) {
1819 removeDefaultP(entry.getValue());
1822 if (defaultValue != null) {
1823 mapPropertyValue.putIfAbsent("default", defaultValue);
1829 protected MappingNode representJavaBean(Set<Property> properties, Object javaBean) {
1830 // remove the bean type from the output yaml (!! ...)
1831 if (!classTags.containsKey(javaBean.getClass())) {
1832 addClassTag(javaBean.getClass(), Tag.MAP);
1835 return super.representJavaBean(properties, javaBean);
1838 private class RepresentNull implements Represent {
1841 public Node representData(Object data) {
1842 // possible values are here http://yaml.org/type/null.html
1843 return representScalar(Tag.NULL, "");
1848 private static class UnsortedPropertyUtils extends PropertyUtils {
1851 protected Set<Property> createPropertySet(Class type, BeanAccess bAccess) {
1852 Collection<Property> fields = getPropertiesMap(type, BeanAccess.FIELD).values();
1853 return new LinkedHashSet<>(fields);
1857 private Map<String, String[]> buildSubstitutionMappingPropertyMapping(final Component component) {
1858 if (component == null || CollectionUtils.isEmpty(component.getInputs())) {
1859 return Collections.emptyMap();
1861 return component.getInputs().stream()
1862 .map(PropertyDataDefinition::getName)
1865 inputName -> inputName,
1866 inputName -> new String[]{inputName},
1867 (inputName1, inputName2) -> inputName1)
1871 private Map<String, String[]> buildSubstitutionMappingAttributesMapping(final Component component) {
1872 if (component == null || CollectionUtils.isEmpty(component.getOutputs())) {
1873 return Collections.emptyMap();
1875 return component.getOutputs().stream()
1876 .map(AttributeDataDefinition::getName)
1879 outputName -> outputName,
1880 outputName -> new String[]{outputName},
1881 (outputName1, outputName2) -> outputName1)
1885 Optional<Map<String, ToscaProperty>> getProxyNodeTypeProperties(Component proxyComponent,
1886 Map<String, DataTypeDefinition>
1888 if (Objects.isNull(proxyComponent)) {
1889 return Optional.empty();
1891 Map<String, ToscaProperty> proxyProperties = new HashMap<>();
1892 addInputsToProperties(dataTypes, proxyComponent.getInputs(), proxyProperties);
1893 if (CollectionUtils.isNotEmpty(proxyComponent.getProperties())) {
1894 proxyProperties.putAll(proxyComponent.getProperties().stream()
1895 .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition,
1896 proxyComponent.getInputs()))
1897 .collect(Collectors.toMap(PropertyDataDefinition::getName,
1898 property -> propertyConvertor.convertProperty(dataTypes, property,
1899 PropertyConvertor.PropertyType.PROPERTY))));
1901 return MapUtils.isNotEmpty(proxyProperties) ? Optional.of(proxyProperties) : Optional.empty();
1904 void addInputsToProperties(Map<String, DataTypeDefinition> dataTypes,
1905 List<InputDefinition> componentInputs,
1906 Map<String, ToscaProperty> mergedProperties) {
1907 if (CollectionUtils.isEmpty(componentInputs)) {
1910 for (InputDefinition input : componentInputs) {
1911 ToscaProperty property = propertyConvertor.convertProperty(dataTypes, input,
1912 PropertyConvertor.PropertyType.INPUT);
1913 mergedProperties.put(input.getName(), property);
1917 Optional<Map<String, Object>> getProxyNodeTypeInterfaces(Component proxyComponent,
1918 Map<String, DataTypeDefinition> dataTypes) {
1919 if (Objects.isNull(proxyComponent) || MapUtils.isEmpty(proxyComponent.getInterfaces())) {
1920 return Optional.empty();
1922 Map<String, InterfaceDefinition> proxyComponentInterfaces = proxyComponent.getInterfaces();
1923 //Unset artifact path for operation implementation for proxy node types as for operations with artifacts it is
1924 // always available in the proxy node template
1925 removeOperationImplementationForProxyNodeType(proxyComponentInterfaces);
1926 return Optional.ofNullable(interfacesOperationsConverter
1927 .getInterfacesMap(proxyComponent, null, proxyComponentInterfaces, dataTypes,
1931 private static void removeOperationImplementationForProxyNodeType(
1932 Map<String, InterfaceDefinition> proxyComponentInterfaces) {
1933 if (MapUtils.isEmpty(proxyComponentInterfaces)) {
1936 proxyComponentInterfaces.values().stream().map(InterfaceDataDefinition::getOperations)
1937 .filter(MapUtils::isNotEmpty)
1938 .forEach(operations -> operations.values().forEach(operation -> operation.setImplementation(null)));