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);
146 private static final String INVARIANT_UUID = "invariantUUID";
148 private ApplicationDataTypeCache dataTypeCache;
149 private ToscaOperationFacade toscaOperationFacade;
150 private CapabilityRequirementConverter capabilityRequirementConverter;
151 private PolicyExportParser policyExportParser;
152 private GroupExportParser groupExportParser;
153 private PropertyConvertor propertyConvertor;
154 private InputConverter inputConverter;
155 private OutputConverter outputConverter;
156 private InterfaceLifecycleOperation interfaceLifecycleOperation;
157 private InterfacesOperationsConverter interfacesOperationsConverter;
160 public ToscaExportHandler(final ApplicationDataTypeCache dataTypeCache,
161 final ToscaOperationFacade toscaOperationFacade,
162 final CapabilityRequirementConverter capabilityRequirementConverter,
163 final PolicyExportParser policyExportParser,
164 final GroupExportParser groupExportParser,
165 final PropertyConvertor propertyConvertor,
166 final InputConverter inputConverter,
167 final OutputConverter outputConverter,
168 final InterfaceLifecycleOperation interfaceLifecycleOperation,
169 final InterfacesOperationsConverter interfacesOperationsConverter) {
170 this.dataTypeCache = dataTypeCache;
171 this.toscaOperationFacade = toscaOperationFacade;
172 this.capabilityRequirementConverter = capabilityRequirementConverter;
173 this.policyExportParser = policyExportParser;
174 this.groupExportParser = groupExportParser;
175 this.propertyConvertor = propertyConvertor;
176 this.inputConverter = inputConverter;
177 this.outputConverter = outputConverter;
178 this.interfaceLifecycleOperation = interfaceLifecycleOperation;
179 this.interfacesOperationsConverter = interfacesOperationsConverter;
182 private static final String TOSCA_VERSION = "tosca_simple_yaml_1_3";
183 private static final String SERVICE_NODE_TYPE_PREFIX = "org.openecomp.service.";
184 private static final String IMPORTS_FILE_KEY = "file";
185 private static final String TOSCA_INTERFACE_NAME = "-interface.yml";
186 public static final String ASSET_TOSCA_TEMPLATE = "assettoscatemplate";
187 private static final String FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION = "convertToToscaTemplate - failed to get Default Imports section from configuration";
188 private static final String NOT_SUPPORTED_COMPONENT_TYPE = "Not supported component type {}";
189 private static final String NATIVE_ROOT = "tosca.nodes.Root";
190 private static final YamlUtil yamlUtil = new YamlUtil();
192 public Either<ToscaRepresentation, ToscaError> exportComponent(Component component) {
193 return convertToToscaTemplate(component).left().map(this::createToscaRepresentation);
196 public Either<ToscaRepresentation, ToscaError> exportComponentInterface(final Component component,
197 final boolean isAssociatedComponent) {
198 final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImportConfig();
199 if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
200 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
201 return Either.right(ToscaError.GENERAL_ERROR);
204 String toscaVersion = null;
205 if (component instanceof Resource) {
206 toscaVersion = ((Resource) component).getToscaVersion();
208 ToscaTemplate toscaTemplate = new ToscaTemplate(toscaVersion != null ? toscaVersion : TOSCA_VERSION);
209 toscaTemplate.setImports(new ArrayList<>(defaultToscaImportConfig));
210 final Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
211 final Either<ToscaTemplate, ToscaError> toscaTemplateRes =
212 convertInterfaceNodeType(new HashMap<>(), component, toscaTemplate, nodeTypes, isAssociatedComponent);
213 if (toscaTemplateRes.isRight()) {
214 return Either.right(toscaTemplateRes.right().value());
217 toscaTemplate = toscaTemplateRes.left().value();
218 ToscaRepresentation toscaRepresentation = this.createToscaRepresentation(toscaTemplate);
219 return Either.left(toscaRepresentation);
222 public ToscaRepresentation createToscaRepresentation(ToscaTemplate toscaTemplate) {
223 CustomRepresenter representer = new CustomRepresenter();
224 DumperOptions options = new DumperOptions();
225 options.setAllowReadOnlyProperties(false);
226 options.setPrettyFlow(true);
228 options.setDefaultFlowStyle(FlowStyle.FLOW);
229 options.setCanonical(false);
231 representer.addClassTag(toscaTemplate.getClass(), Tag.MAP);
233 representer.setPropertyUtils(new UnsortedPropertyUtils());
234 Yaml yaml = new Yaml(representer, options);
236 String yamlAsString = yaml.dumpAsMap(toscaTemplate);
238 StringBuilder sb = new StringBuilder();
239 sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactHeader());
240 sb.append(yamlAsString);
241 sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactFooter());
243 return ToscaRepresentation.make(sb.toString().getBytes(), toscaTemplate);
246 public Either<ToscaTemplate, ToscaError> getDependencies(Component component) {
247 ToscaTemplate toscaTemplate = new ToscaTemplate(null);
248 Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports = fillImports(component,
250 if (fillImports.isRight()) {
251 return Either.right(fillImports.right().value());
253 return Either.left(fillImports.left().value().left);
256 public Either<ToscaTemplate, ToscaError> convertToToscaTemplate(final Component component) {
257 final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImportConfig();
258 if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
259 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
260 return Either.right(ToscaError.GENERAL_ERROR);
262 log.trace("start tosca export for {}", component.getUniqueId());
263 String toscaVersion = null;
264 if (component instanceof Resource) {
265 toscaVersion = ((Resource) component).getToscaVersion();
267 final ToscaTemplate toscaTemplate = new ToscaTemplate(toscaVersion != null ? toscaVersion : TOSCA_VERSION);
268 toscaTemplate.setMetadata(convertMetadata(component));
269 toscaTemplate.setImports(new ArrayList<>(defaultToscaImportConfig));
270 final Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
271 if (ModelConverter.isAtomicComponent(component)) {
272 log.trace("convert component as node type");
273 return convertNodeType(new HashMap<>(), component, toscaTemplate, nodeTypes);
275 log.trace("convert component as topology template");
276 return convertToscaTemplate(component, toscaTemplate);
281 private Either<ToscaTemplate, ToscaError> convertToscaTemplate(Component component, ToscaTemplate toscaNode) {
283 Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> importsRes = fillImports(component,
285 if (importsRes.isRight()) {
286 return Either.right(importsRes.right().value());
288 toscaNode = importsRes.left().value().left;
289 Map<String, Component> componentCache = importsRes.left().value().right;
290 Either<Map<String, ToscaNodeType>, ToscaError> nodeTypesMapEither = createProxyNodeTypes(componentCache,
292 if (nodeTypesMapEither.isRight()) {
293 log.debug("Failed to fetch normative service proxy resource by tosca name, error {}",
294 nodeTypesMapEither.right().value());
295 return Either.right(nodeTypesMapEither.right().value());
297 Map<String, ToscaNodeType> nodeTypesMap = nodeTypesMapEither.left().value();
298 if (nodeTypesMap != null && !nodeTypesMap.isEmpty()) {
299 toscaNode.setNode_types(nodeTypesMap);
302 createServiceSubstitutionNodeTypes(componentCache, component, toscaNode);
304 Either<Map<String, Object>, ToscaError> proxyInterfaceTypesEither = createProxyInterfaceTypes(component);
305 if (proxyInterfaceTypesEither.isRight()) {
306 log.debug("Failed to populate service proxy local interface types in tosca, error {}",
307 nodeTypesMapEither.right().value());
308 return Either.right(proxyInterfaceTypesEither.right().value());
310 Map<String, Object> proxyInterfaceTypes = proxyInterfaceTypesEither.left().value();
311 if (MapUtils.isNotEmpty(proxyInterfaceTypes)) {
312 toscaNode.setInterface_types(proxyInterfaceTypes);
315 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = dataTypeCache.getAll();
316 if (dataTypesEither.isRight()) {
317 log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
318 return Either.right(ToscaError.GENERAL_ERROR);
320 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
321 ToscaTopolgyTemplate topologyTemplate = new ToscaTopolgyTemplate();
322 List<InputDefinition> inputDef = component.getInputs();
323 Map<String, ToscaProperty> inputs = inputConverter.convertInputs(inputDef, dataTypes);
325 if (!inputs.isEmpty()) {
326 topologyTemplate.setInputs(inputs);
329 final Map<String, ToscaProperty> outputs;
331 outputs = outputConverter.convert(component.getOutputs(), dataTypes);
332 } catch (final ToscaConversionException e) {
333 log.error(EcompLoggerErrorCode.SCHEMA_ERROR, ToscaExportHandler.class.getName(),
334 "Could not parse component '{}' outputs. Component unique id '{}'.",
335 new Object[]{component.getName(), component.getUniqueId(), e});
336 return Either.right(ToscaError.GENERAL_ERROR);
338 if (!outputs.isEmpty()) {
339 topologyTemplate.setOutputs(outputs);
342 final List<ComponentInstance> componentInstances = component.getComponentInstances();
343 Map<String, List<ComponentInstanceProperty>> componentInstancesProperties = component.getComponentInstancesProperties();
344 Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces = component.getComponentInstancesInterfaces();
345 if (CollectionUtils.isNotEmpty(componentInstances)) {
346 final Either<Map<String, ToscaNodeTemplate>, ToscaError> nodeTemplates = convertNodeTemplates(component, componentInstances,
347 componentInstancesProperties, componentInstanceInterfaces, componentCache, dataTypes, topologyTemplate);
348 if (nodeTemplates.isRight()) {
349 return Either.right(nodeTemplates.right().value());
351 log.debug("node templates converted");
352 topologyTemplate.setNode_templates(nodeTemplates.left().value());
354 final Map<String, ToscaRelationshipTemplate> relationshipTemplatesMap =
355 new ToscaExportRelationshipTemplatesHandler().createFrom(topologyTemplate.getNode_templates());
356 if (!relationshipTemplatesMap.isEmpty()) {
357 topologyTemplate.setRelationshipTemplates(relationshipTemplatesMap);
360 SubstitutionMapping substitutionMapping = new SubstitutionMapping();
361 convertSubstitutionMappingFilter(component, substitutionMapping);
363 addGroupsToTopologyTemplate(component, topologyTemplate);
366 addPoliciesToTopologyTemplate(component, topologyTemplate);
367 } catch (SdcResourceNotFoundException e) {
368 log.debug("Fail to add policies to topology template:", e);
369 return Either.right(ToscaError.GENERAL_ERROR);
372 String toscaResourceName;
373 switch (component.getComponentType()) {
375 toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition()
376 .getMetadataDataDefinition()).getToscaResourceName();
379 toscaResourceName = SERVICE_NODE_TYPE_PREFIX
380 + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName();
383 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
384 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
386 substitutionMapping.setNode_type(toscaResourceName);
387 Either<SubstitutionMapping, ToscaError> capabilities = convertCapabilities(component, substitutionMapping,
389 if (capabilities.isRight()) {
390 return Either.right(capabilities.right().value());
392 substitutionMapping = capabilities.left().value();
394 Either<SubstitutionMapping, ToscaError> requirements = capabilityRequirementConverter
395 .convertSubstitutionMappingRequirements(componentCache, component, substitutionMapping);
396 if (requirements.isRight()) {
397 return Either.right(requirements.right().value());
399 substitutionMapping = requirements.left().value();
400 final Map<String, String[]> propertyMappingMap = buildSubstitutionMappingPropertyMapping(component);
401 if (!propertyMappingMap.isEmpty()) {
402 substitutionMapping.setProperties(propertyMappingMap);
405 final Map<String, String[]> attributesMappingMap = buildSubstitutionMappingAttributesMapping(component);
406 if (!attributesMappingMap.isEmpty()) {
407 substitutionMapping.setAttributes(attributesMappingMap);
410 topologyTemplate.setSubstitution_mappings(substitutionMapping);
412 toscaNode.setTopology_template(topologyTemplate);
414 return Either.left(toscaNode);
417 private void convertSubstitutionMappingFilter(final Component component,
418 final SubstitutionMapping substitutionMapping) {
419 if (component.getSubstitutionFilter() != null
420 && (component.getSubstitutionFilter().getProperties()).getListToscaDataDefinition() != null) {
422 .setSubstitution_filter(convertToSubstitutionFilterComponent(component.getSubstitutionFilter()));
426 private void addGroupsToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate) {
427 Map<String, ToscaGroupTemplate> groups = groupExportParser.getGroups(component);
428 if (groups != null) {
429 topologyTemplate.addGroups(groups);
433 private void addPoliciesToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate)
434 throws SdcResourceNotFoundException {
435 Map<String, ToscaPolicyTemplate> policies = policyExportParser.getPolicies(component);
436 if (policies != null) {
437 topologyTemplate.addPolicies(policies);
441 private Map<String, String> convertMetadata(Component component) {
442 return convertMetadata(component, false, null);
445 private Map<String, String> convertMetadata(Component component, boolean isInstance,
446 ComponentInstance componentInstance) {
447 Map<String, String> toscaMetadata = new LinkedHashMap<>();
448 toscaMetadata.put(convertMetadataKey(JsonPresentationFields.INVARIANT_UUID), component.getInvariantUUID());
449 toscaMetadata.put(JsonPresentationFields.UUID.getPresentation(), component.getUUID());
451 .put(JsonPresentationFields.NAME.getPresentation(), component.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
452 toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), component.getDescription());
454 List<CategoryDefinition> categories = component.getCategories();
455 CategoryDefinition categoryDefinition = categories.get(0);
456 toscaMetadata.put(JsonPresentationFields.CATEGORY.getPresentation(), categoryDefinition.getName());
459 toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), component.getVersion());
460 toscaMetadata.put(JsonPresentationFields.CUSTOMIZATION_UUID.getPresentation(), componentInstance.getCustomizationUUID());
461 if (componentInstance.getSourceModelInvariant() != null
462 && !componentInstance.getSourceModelInvariant().isEmpty()) {
463 toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), componentInstance.getComponentVersion());
464 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_INVARIANT.getPresentation(), componentInstance.getSourceModelInvariant());
465 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_UUID.getPresentation(), componentInstance.getSourceModelUuid());
466 toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_NAME.getPresentation(), componentInstance.getSourceModelName());
467 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
468 toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(),
469 componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceProxy.getDisplayValue());
470 } else if (componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
471 toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(),
472 componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceSubstitution
475 toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), componentInstance.getDescription());
479 switch (component.getComponentType()) {
481 Resource resource = (Resource) component;
483 if (isInstance && (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy
484 || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution)) {
485 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), componentInstance.getOriginType().getDisplayValue());
487 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), resource.getResourceType().name());
489 toscaMetadata.put(JsonPresentationFields.SUB_CATEGORY.getPresentation(), categoryDefinition.getSubcategories().get(0).getName());
490 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR.getPresentation(), resource.getVendorName());
491 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_RELEASE.getPresentation(), resource.getVendorRelease());
492 toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_MODEL_NUMBER.getPresentation(), resource.getResourceVendorModelNumber());
495 Service service = (Service) component;
496 toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), component.getComponentType().getValue());
497 toscaMetadata.put(JsonPresentationFields.SERVICE_TYPE.getPresentation(), service.getServiceType());
498 toscaMetadata.put(JsonPresentationFields.SERVICE_ROLE.getPresentation(), service.getServiceRole());
499 toscaMetadata.put(JsonPresentationFields.SERVICE_FUNCTION.getPresentation(), service.getServiceFunction());
500 toscaMetadata.put(JsonPresentationFields.ENVIRONMENT_CONTEXT.getPresentation(), service.getEnvironmentContext());
501 toscaMetadata.put(JsonPresentationFields.INSTANTIATION_TYPE.getPresentation(),
502 service.getEnvironmentContext() == null ? StringUtils.EMPTY : service.getInstantiationType());
505 toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming().toString());
506 toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming().toString());
507 toscaMetadata.put(JsonPresentationFields.NAMING_POLICY.getPresentation(), service.getNamingPolicy());
511 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
514 for (final String key : component.getCategorySpecificMetadata().keySet()) {
515 toscaMetadata.put(key, component.getCategorySpecificMetadata().get(key));
517 return toscaMetadata;
520 private String convertMetadataKey(JsonPresentationFields jsonPresentationField) {
521 if (JsonPresentationFields.INVARIANT_UUID.equals(jsonPresentationField)) {
522 return INVARIANT_UUID;
524 return jsonPresentationField.getPresentation();
527 private Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports(Component component,
528 ToscaTemplate toscaTemplate) {
530 final List<Map<String, Map<String, String>>> defaultToscaImportConfig = getDefaultToscaImportConfig();
531 if (CollectionUtils.isEmpty(defaultToscaImportConfig)) {
532 log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION);
533 return Either.right(ToscaError.GENERAL_ERROR);
535 Map<String, Component> componentCache = new HashMap<>();
537 if (!ModelConverter.isAtomicComponent(component)) {
538 final List<Map<String, Map<String, String>>> additionalImports =
539 toscaTemplate.getImports() == null ? new ArrayList<>(defaultToscaImportConfig)
540 : new ArrayList<>(toscaTemplate.getImports());
542 List<Triple<String, String, Component>> dependecies = new ArrayList<>();
544 Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
545 if (isNotEmpty(toscaArtifacts)) {
546 ArtifactDefinition artifactDefinition = toscaArtifacts.get(ToscaExportHandler.ASSET_TOSCA_TEMPLATE);
547 if (artifactDefinition != null) {
548 Map<String, Map<String, String>> importsListMember = new HashMap<>();
549 Map<String, String> interfaceFiles = new HashMap<>();
550 interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactDefinition.getArtifactName()));
551 StringBuilder keyNameBuilder = new StringBuilder();
552 keyNameBuilder.append(component.getComponentType().toString().toLowerCase()).append("-")
553 .append(component.getName()).append("-interface");
554 importsListMember.put(keyNameBuilder.toString(), interfaceFiles);
555 additionalImports.add(importsListMember);
558 List<ComponentInstance> componentInstances = component.getComponentInstances();
559 if (componentInstances != null && !componentInstances.isEmpty()) {
560 componentInstances.forEach(ci -> createDependency(componentCache, additionalImports, dependecies, ci));
562 toscaTemplate.setDependencies(dependecies);
563 toscaTemplate.setImports(additionalImports);
565 log.debug("currently imports supported for VF and service only");
567 return Either.left(new ImmutablePair<>(toscaTemplate, componentCache));
570 private List<Map<String, Map<String, String>>> getDefaultToscaImportConfig() {
571 return ConfigurationManager.getConfigurationManager().getConfiguration().getDefaultImports();
574 private void createDependency(final Map<String, Component> componentCache,
575 final List<Map<String, Map<String, String>>> imports,
576 final List<Triple<String, String, Component>> dependencies,
577 final ComponentInstance componentInstance) {
578 log.debug("createDependency componentCache {}", componentCache);
579 Component componentRI = componentCache.get(componentInstance.getComponentUid());
580 if (componentRI == null || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
581 // all resource must be only once!
582 final Either<Component, StorageOperationStatus> resource = toscaOperationFacade
583 .getToscaFullElement(componentInstance.getComponentUid());
584 if ((resource.isRight()) && (log.isDebugEnabled())) {
585 log.debug("Failed to fetch resource with id {} for instance {}", componentInstance.getComponentUid(),
586 componentInstance.getUniqueId());
589 final Component fetchedComponent = resource.left().value();
590 componentRI = setComponentCache(componentCache, componentInstance, fetchedComponent);
591 addDependencies(imports, dependencies, componentRI);
596 * Sets a componentCache from the given component/resource.
598 private Component setComponentCache(final Map<String, Component> componentCache,
599 final ComponentInstance componentInstance,
600 final Component fetchedComponent) {
601 componentCache.put(fetchedComponent.getUniqueId(), fetchedComponent);
602 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy
603 || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) {
604 final Either<Component, StorageOperationStatus> sourceService = toscaOperationFacade
605 .getToscaFullElement(componentInstance.getSourceModelUid());
606 if (sourceService.isRight() && (log.isDebugEnabled())) {
607 log.debug("Failed to fetch source service with id {} for proxy {}",
608 componentInstance.getSourceModelUid(), componentInstance.getUniqueId());
610 final Component fetchedSource = sourceService.left().value();
611 componentCache.put(fetchedSource.getUniqueId(), fetchedSource);
612 return fetchedSource;
614 return fetchedComponent;
618 * Retrieves all derived_from nodes and stores it in a predictable order.
620 private void addDependencies(final List<Map<String, Map<String, String>>> imports,
621 final List<Triple<String, String, Component>> dependencies,
622 final Component fetchedComponent) {
623 final Set<Component> componentsList = new LinkedHashSet<>();
624 if (fetchedComponent instanceof Resource) {
625 log.debug("fetchedComponent is a resource {}", fetchedComponent);
627 final Optional<Map<String, String>> derivedFromMapOfIdToName = getDerivedFromMapOfIdToName(fetchedComponent,
629 if (derivedFromMapOfIdToName.isPresent() && !derivedFromMapOfIdToName.get().isEmpty()) {
630 derivedFromMapOfIdToName.get().entrySet().forEach(entry -> {
631 log.debug("Started entry.getValue() : {}", entry.getValue());
632 if (!NATIVE_ROOT.equals(entry.getValue())) {
633 Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade
634 .getToscaElement(entry.getKey());
635 if (resourcefetched != null && resourcefetched.isLeft()) {
636 componentsList.add(resourcefetched.left().value());
640 setImports(imports, dependencies, componentsList);
642 setImports(imports, dependencies, fetchedComponent);
649 * Returns all derived_from nodes found.
651 private Optional<Map<String, String>> getDerivedFromMapOfIdToName(final Component fetchedComponent,
652 final Set<Component> componentsList) {
653 final Resource parentResource = (Resource) fetchedComponent;
654 Map<String, String> derivedFromMapOfIdToName = new HashMap<>();
655 if (CollectionUtils.isNotEmpty(parentResource.getComponentInstances())) {
656 componentsList.add(fetchedComponent);
657 for (final ComponentInstance componentInstance : parentResource.getComponentInstances()) {
658 final Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade
659 .getToscaElement(componentInstance.getComponentUid());
660 if (resourcefetched != null && resourcefetched.isLeft()) {
661 final Map<String, String> derivedWithId = resourcefetched.left().value()
662 .getDerivedFromMapOfIdToName();
663 if (MapUtils.isNotEmpty(derivedWithId)) {
664 derivedFromMapOfIdToName.putAll(derivedWithId);
669 derivedFromMapOfIdToName = parentResource.getDerivedFromMapOfIdToName();
671 log.debug("Started derivedFromMapOfIdToName: {}", derivedFromMapOfIdToName);
672 return Optional.ofNullable(derivedFromMapOfIdToName);
676 * Creates a resource map and adds it to the import list.
678 private void setImports(final List<Map<String, Map<String, String>>> imports,
679 final List<Triple<String, String, Component>> dependencies,
680 final Set<Component> componentsList) {
681 componentsList.forEach(component -> setImports(imports, dependencies, component));
684 private void setImports(final List<Map<String, Map<String, String>>> imports,
685 final List<Triple<String, String, Component>> dependencies,
686 final Component component) {
687 final Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
688 final ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE);
689 if (artifactDefinition != null) {
690 final Map<String, String> files = new HashMap<>();
691 final String artifactName = artifactDefinition.getArtifactName();
692 files.put(IMPORTS_FILE_KEY, artifactName);
693 final StringBuilder keyNameBuilder = new StringBuilder();
694 keyNameBuilder.append(component.getComponentType().toString().toLowerCase());
695 keyNameBuilder.append("-");
696 keyNameBuilder.append(component.getName());
697 addImports(imports, keyNameBuilder, files);
699 .add(new ImmutableTriple<>(artifactName, artifactDefinition.getEsId(), component));
701 if (!ModelConverter.isAtomicComponent(component)) {
702 final Map<String, String> interfaceFiles = new HashMap<>();
703 interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactName));
704 keyNameBuilder.append("-interface");
705 addImports(imports, keyNameBuilder, interfaceFiles);
711 * Adds the found resource to the import definition list.
713 private void addImports(final List<Map<String, Map<String, String>>> imports,
714 final StringBuilder keyNameBuilder,
715 final Map<String, String> files) {
716 final String mapKey = keyNameBuilder.toString();
717 if (imports.stream().allMatch(stringMapMap -> stringMapMap.get(mapKey) == null)) {
718 final Map<String, Map<String, String>> importsListMember = new HashMap<>();
719 importsListMember.put(keyNameBuilder.toString(), files);
720 imports.add(importsListMember);
724 public static String getInterfaceFilename(String artifactName) {
725 return artifactName.substring(0, artifactName.lastIndexOf('.')) + ToscaExportHandler.TOSCA_INTERFACE_NAME;
728 private Either<ToscaTemplate, ToscaError> convertNodeType(Map<String, Component> componentsCache,
729 Component component, ToscaTemplate toscaNode,
730 Map<String, ToscaNodeType> nodeTypes) {
731 return convertInterfaceNodeType(componentsCache, component, toscaNode, nodeTypes, false);
734 public Either<ToscaTemplate, ToscaError> convertInterfaceNodeType(Map<String, Component> componentsCache,
735 Component component, ToscaTemplate toscaNode,
736 Map<String, ToscaNodeType> nodeTypes,
737 boolean isAssociatedComponent) {
738 log.debug("start convert node type for {}", component.getUniqueId());
739 ToscaNodeType toscaNodeType = createNodeType(component);
741 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither =
742 interfaceLifecycleOperation.getAllInterfaceLifecycleTypes();
743 if (lifecycleTypeEither.isRight()) {
744 log.debug("Failed to fetch all interface types :", lifecycleTypeEither.right().value());
745 return Either.right(ToscaError.GENERAL_ERROR);
747 List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value()
750 .map(InterfaceDataDefinition::getType)
751 .collect(Collectors.toList());
752 toscaNode.setInterface_types(addInterfaceTypeElement(component, allGlobalInterfaceTypes));
754 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = dataTypeCache.getAll();
755 if (dataTypesEither.isRight()) {
756 log.debug("Failed to fetch all data types :", dataTypesEither.right().value());
757 return Either.right(ToscaError.GENERAL_ERROR);
760 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
762 List<InputDefinition> inputDef = component.getInputs();
763 Map<String, ToscaProperty> mergedProperties = new HashMap<>();
764 interfacesOperationsConverter
765 .addInterfaceDefinitionElement(component, toscaNodeType, dataTypes, isAssociatedComponent);
766 addInputsToProperties(dataTypes, inputDef, mergedProperties);
768 final Map<String, ToscaAttribute> toscaAttributeMap;
770 toscaAttributeMap = convertToToscaAttributes(component.getAttributes(), dataTypes);
771 } catch (final ToscaConversionException e) {
772 log.error(EcompLoggerErrorCode.SCHEMA_ERROR, ToscaExportHandler.class.getName(),
773 "Could not parse component '{}' attributes. Component unique id '{}'.",
774 new Object[]{component.getName(), component.getUniqueId(), e});
775 return Either.right(ToscaError.GENERAL_ERROR);
777 if (!toscaAttributeMap.isEmpty()) {
778 toscaNodeType.setAttributes(toscaAttributeMap);
780 if (CollectionUtils.isNotEmpty(component.getProperties())) {
781 List<PropertyDefinition> properties = component.getProperties();
782 Map<String, ToscaProperty> convertedProperties = properties.stream()
783 .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, component.getInputs()))
784 .collect(Collectors.toMap(PropertyDataDefinition::getName,
785 property -> propertyConvertor.convertProperty(dataTypes, property,
786 PropertyConvertor.PropertyType.PROPERTY)));
787 // merge component properties and inputs properties
788 mergedProperties.putAll(convertedProperties);
790 if (MapUtils.isNotEmpty(mergedProperties)) {
791 toscaNodeType.setProperties(mergedProperties);
794 /* convert private data_types */
795 List<DataTypeDefinition> privateDataTypes = component.getDataTypes();
796 if (CollectionUtils.isNotEmpty(privateDataTypes)) {
797 Map<String, ToscaDataType> toscaDataTypeMap = new HashMap<>();
798 for (DataTypeDefinition dataType : privateDataTypes) {
799 log.debug("Emitting private data type: component.name={} dataType.name={}",
800 component.getNormalizedName(), dataType.getName());
801 ToscaDataType toscaDataType = new ToscaDataType();
802 toscaDataType.setDerived_from(dataType.getDerivedFromName());
803 toscaDataType.setDescription(dataType.getDescription());
804 toscaDataType.setVersion(dataType.getVersion());
805 if (CollectionUtils.isNotEmpty(dataType.getProperties())) {
806 toscaDataType.setProperties(dataType.getProperties().stream()
807 .collect(Collectors.toMap(
808 PropertyDataDefinition::getName,
809 s -> propertyConvertor
810 .convertProperty(dataTypes, s, PropertyType.PROPERTY)
813 toscaDataTypeMap.put(dataType.getName(), toscaDataType);
815 toscaNode.setData_types(toscaDataTypeMap);
818 // Extracted to method for code reuse
819 return convertReqCapAndTypeName(componentsCache, component, toscaNode, nodeTypes, toscaNodeType, dataTypes);
822 private Map<String, ToscaAttribute> convertToToscaAttributes(final List<AttributeDefinition> attributeList,
823 final Map<String, DataTypeDefinition> dataTypes) throws ToscaConversionException {
824 if (CollectionUtils.isEmpty(attributeList)) {
825 return Collections.emptyMap();
827 final AttributeConverter attributeConverter = new AttributeConverter(dataTypes);
828 final Map<String, ToscaAttribute> toscaAttributeMap = new HashMap<>();
829 for (final AttributeDefinition attributeDefinition : attributeList) {
830 toscaAttributeMap.put(attributeDefinition.getName(), attributeConverter.convert(attributeDefinition));
832 return toscaAttributeMap;
835 private Either<ToscaTemplate, ToscaError> convertReqCapAndTypeName(Map<String, Component> componentsCache,
836 Component component, ToscaTemplate toscaNode,
837 Map<String, ToscaNodeType> nodeTypes,
838 ToscaNodeType toscaNodeType,
839 Map<String, DataTypeDefinition> dataTypes) {
840 Either<ToscaNodeType, ToscaError> capabilities = convertCapabilities(componentsCache, component, toscaNodeType,
842 if (capabilities.isRight()) {
843 return Either.right(capabilities.right().value());
845 toscaNodeType = capabilities.left().value();
846 log.debug("Capabilities converted for {}", component.getUniqueId());
848 Either<ToscaNodeType, ToscaError> requirements = capabilityRequirementConverter
849 .convertRequirements(componentsCache, component,
851 if (requirements.isRight()) {
852 return Either.right(requirements.right().value());
854 toscaNodeType = requirements.left().value();
855 log.debug("Requirements converted for {}", component.getUniqueId());
857 String toscaResourceName;
858 switch (component.getComponentType()) {
860 toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition()
861 .getMetadataDataDefinition()).getToscaResourceName();
864 toscaResourceName = SERVICE_NODE_TYPE_PREFIX
865 + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName();
868 log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType());
869 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
872 nodeTypes.put(toscaResourceName, toscaNodeType);
873 toscaNode.setNode_types(nodeTypes);
874 log.debug("finish convert node type for {}", component.getUniqueId());
875 return Either.left(toscaNode);
878 protected Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplates(
880 List<ComponentInstance> componentInstances,
881 Map<String, List<ComponentInstanceProperty>> componentInstancesProperties,
882 Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces,
883 Map<String, Component> componentCache, Map<String, DataTypeDefinition> dataTypes,
884 ToscaTopolgyTemplate topologyTemplate) {
886 Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplatesRes = null;
887 log.debug("start convert topology template for {} for type {}", component.getUniqueId(),
888 component.getComponentType());
889 Map<String, ToscaNodeTemplate> nodeTemplates = new HashMap<>();
890 Map<String, List<ComponentInstanceInput>> componentInstancesInputs = component.getComponentInstancesInputs();
892 Map<String, ToscaGroupTemplate> groupsMap = null;
893 for (ComponentInstance componentInstance : componentInstances) {
894 ToscaNodeTemplate nodeTemplate = new ToscaNodeTemplate();
895 if (MapUtils.isNotEmpty(componentInstance.getToscaArtifacts())) {
896 nodeTemplate.setArtifacts(convertToNodeTemplateArtifacts(componentInstance.getToscaArtifacts()));
898 nodeTemplate.setType(componentInstance.getToscaComponentName());
899 nodeTemplate.setDirectives(componentInstance.getDirectives());
900 nodeTemplate.setNode_filter(convertToNodeTemplateNodeFilterComponent(componentInstance.getNodeFilter()));
902 Either<Component, Boolean> originComponentRes = capabilityRequirementConverter
903 .getOriginComponent(componentCache, componentInstance);
904 if (originComponentRes.isRight()) {
905 convertNodeTemplatesRes = Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
908 Either<ToscaNodeTemplate, ToscaError> requirements = convertComponentInstanceRequirements(component,
909 componentInstance, component.getComponentInstancesRelations(), nodeTemplate,
910 originComponentRes.left().value(), componentCache);
911 if (requirements.isRight()) {
912 convertNodeTemplatesRes = Either.right(requirements.right().value());
915 String instanceUniqueId = componentInstance.getUniqueId();
916 log.debug("Component instance Requirements converted for instance {}", instanceUniqueId);
918 nodeTemplate = requirements.left().value();
920 Component originalComponent = componentCache.get(componentInstance.getActualComponentUid());
922 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
923 Component componentOfProxy = componentCache.get(componentInstance.getComponentUid());
924 nodeTemplate.setMetadata(convertMetadata(componentOfProxy, true, componentInstance));
926 nodeTemplate.setMetadata(convertMetadata(originalComponent, true, componentInstance));
929 Either<ToscaNodeTemplate, ToscaError> capabilities = capabilityRequirementConverter
930 .convertComponentInstanceCapabilities(componentInstance, dataTypes, nodeTemplate);
931 if (capabilities.isRight()) {
932 convertNodeTemplatesRes = Either.right(capabilities.right().value());
935 log.debug("Component instance Capabilities converted for instance {}", instanceUniqueId);
937 nodeTemplate = capabilities.left().value();
938 Map<String, Object> props = new HashMap<>();
940 if (originalComponent.getComponentType() == ComponentTypeEnum.RESOURCE) {
941 // Adds the properties of parent component to map
942 addPropertiesOfParentComponent(dataTypes, originalComponent, props);
945 if (null != componentInstancesProperties && componentInstancesProperties.containsKey(instanceUniqueId)) {
946 addPropertiesOfComponentInstance(componentInstancesProperties, dataTypes, instanceUniqueId,
950 if (componentInstancesInputs != null && componentInstancesInputs.containsKey(instanceUniqueId)
951 && !isComponentOfTypeServiceProxy(componentInstance)) {
952 //For service proxy the inputs are already handled under instance properties above
953 addComponentInstanceInputs(dataTypes, componentInstancesInputs, instanceUniqueId, props);
956 //M3[00001] - NODE TEMPLATE INTERFACES - START
957 handleInstanceInterfaces(componentInstanceInterfaces, componentInstance, dataTypes, nodeTemplate,
958 instanceUniqueId, component);
959 //M3[00001] - NODE TEMPLATE INTERFACES - END
960 if (props != null && !props.isEmpty()) {
961 nodeTemplate.setProperties(props);
964 List<GroupInstance> groupInstances = componentInstance.getGroupInstances();
965 if (groupInstances != null) {
966 if (groupsMap == null) {
967 groupsMap = new HashMap<>();
969 for (GroupInstance groupInst : groupInstances) {
970 boolean addToTosca = true;
972 List<String> artifacts = groupInst.getArtifacts();
973 if (artifacts == null || artifacts.isEmpty()) {
978 ToscaGroupTemplate toscaGroup = groupExportParser
979 .getToscaGroupTemplate(groupInst, componentInstance.getInvariantName());
980 groupsMap.put(groupInst.getName(), toscaGroup);
985 nodeTemplates.put(componentInstance.getName(), nodeTemplate);
987 if (groupsMap != null) {
988 log.debug("instance groups added");
989 topologyTemplate.addGroups(groupsMap);
991 if (component.getComponentType() == ComponentTypeEnum.SERVICE && isNotEmpty(
992 ((Service) component).getForwardingPaths())) {
993 log.debug("Starting converting paths for component {}, name {}", component.getUniqueId(),
994 component.getName());
995 ForwardingPathToscaUtil
996 .addForwardingPaths((Service) component, nodeTemplates, capabilityRequirementConverter, componentCache,
997 toscaOperationFacade);
998 log.debug("Finished converting paths for component {}, name {}", component.getUniqueId(),
999 component.getName());
1001 if (convertNodeTemplatesRes == null) {
1002 convertNodeTemplatesRes = Either.left(nodeTemplates);
1004 log.debug("finish convert topology template for {} for type {}", component.getUniqueId(),
1005 component.getComponentType());
1006 return convertNodeTemplatesRes;
1009 private void handleInstanceInterfaces(
1010 Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces,
1011 ComponentInstance componentInstance, Map<String, DataTypeDefinition> dataTypes, ToscaNodeTemplate nodeTemplate,
1012 String instanceUniqueId,
1013 Component parentComponent) {
1015 if (MapUtils.isEmpty(componentInstanceInterfaces)
1016 || !componentInstanceInterfaces.containsKey(instanceUniqueId)) {
1017 nodeTemplate.setInterfaces(null);
1021 final List<ComponentInstanceInterface> currServiceInterfaces =
1022 componentInstanceInterfaces.get(instanceUniqueId);
1024 final Map<String, InterfaceDefinition> tmpInterfaces = new HashMap<>();
1025 currServiceInterfaces.forEach(instInterface -> tmpInterfaces.put(instInterface
1026 .getUniqueId(), instInterface));
1028 final Map<String, Object> interfaceMap = interfacesOperationsConverter
1029 .getInterfacesMap(parentComponent, componentInstance, tmpInterfaces, dataTypes, isComponentOfTypeServiceProxy(componentInstance),
1030 isComponentOfTypeServiceProxy(componentInstance));
1032 interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
1033 nodeTemplate.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap);
1036 private boolean isComponentOfTypeServiceProxy(ComponentInstance componentInstance) {
1037 return Objects.nonNull(componentInstance.getOriginType())
1038 && componentInstance.getOriginType().getValue().equals("Service Proxy");
1041 private void addComponentInstanceInputs(Map<String, DataTypeDefinition> dataTypes,
1042 Map<String, List<ComponentInstanceInput>> componentInstancesInputs,
1043 String instanceUniqueId, Map<String, Object> props) {
1045 List<ComponentInstanceInput> instanceInputsList = componentInstancesInputs.get(instanceUniqueId);
1046 if (instanceInputsList != null) {
1047 instanceInputsList.forEach(input -> {
1049 Supplier<String> supplier = () -> input.getValue() != null && !Objects.isNull(input.getValue())
1050 ? input.getValue() : input.getDefaultValue();
1051 propertyConvertor.convertAndAddValue(dataTypes, props, input, supplier);
1056 private void addPropertiesOfComponentInstance(
1057 Map<String, List<ComponentInstanceProperty>> componentInstancesProperties,
1058 Map<String, DataTypeDefinition> dataTypes, String instanceUniqueId,
1059 Map<String, Object> props) {
1061 if (isNotEmpty(componentInstancesProperties)) {
1062 componentInstancesProperties.get(instanceUniqueId)
1063 // Converts and adds each value to property map
1064 .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop,
1069 private void addPropertiesOfParentComponent(Map<String, DataTypeDefinition> dataTypes,
1070 Component componentOfInstance, Map<String, Object> props) {
1072 List<PropertyDefinition> componentProperties = componentOfInstance.getProperties();
1073 if (isNotEmpty(componentProperties)) {
1074 componentProperties.stream()
1075 // Filters out properties with empty default values
1076 .filter(prop -> StringUtils.isNotEmpty(prop.getDefaultValue()))
1077 // Converts and adds each value to property map
1078 .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop,
1079 prop::getDefaultValue));
1083 private ToscaNodeType createNodeType(Component component) {
1084 ToscaNodeType toscaNodeType = new ToscaNodeType();
1085 if (ModelConverter.isAtomicComponent(component)) {
1086 if (((Resource) component).getDerivedFrom() != null) {
1087 toscaNodeType.setDerived_from(((Resource) component).getDerivedFrom().get(0));
1089 toscaNodeType.setDescription(component.getDescription());
1091 String derivedFrom = null != component.getDerivedFromGenericType() ? component.getDerivedFromGenericType()
1093 toscaNodeType.setDerived_from(derivedFrom);
1095 return toscaNodeType;
1098 private Either<Map<String, Object>, ToscaError> createProxyInterfaceTypes(Component container) {
1100 Map<String, Object> proxyInterfaceTypes = new HashMap<>();
1101 Either<Map<String, Object>, ToscaError> res = Either.left(proxyInterfaceTypes);
1102 List<ComponentInstance> componentInstances = container.getComponentInstances();
1103 if (CollectionUtils.isEmpty(componentInstances)) {
1106 Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
1107 componentInstances.stream()
1108 .filter(this::isComponentOfTypeServiceProxy)
1109 .forEach(inst -> serviceProxyInstanceList.put(inst.getToscaComponentName(), inst));
1110 if (MapUtils.isEmpty(serviceProxyInstanceList)) {
1113 for (Entry<String, ComponentInstance> entryProxy : serviceProxyInstanceList.entrySet()) {
1114 Component serviceComponent;
1115 ComponentParametersView componentParametersView = new ComponentParametersView();
1116 componentParametersView.disableAll();
1117 componentParametersView.setIgnoreInterfaces(false);
1118 Either<Component, StorageOperationStatus> service = toscaOperationFacade
1119 .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
1120 if (service.isRight()) {
1121 log.debug("Failed to fetch original service component with id {} for instance {}",
1122 entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName());
1123 return Either.right(ToscaError.GENERAL_ERROR);
1125 serviceComponent = service.left().value();
1128 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> lifecycleTypeEither =
1129 interfaceLifecycleOperation.getAllInterfaceLifecycleTypes();
1130 if (lifecycleTypeEither.isRight()) {
1131 log.debug("Failed to retrieve global interface types :", lifecycleTypeEither.right().value());
1132 return Either.right(ToscaError.GENERAL_ERROR);
1135 List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value().values().stream()
1136 .map(InterfaceDataDefinition::getType)
1137 .collect(Collectors.toList());
1138 //Add interface types for local interfaces in the original service component for proxy
1139 Map<String, Object> localInterfaceTypes = addInterfaceTypeElement(serviceComponent,
1140 allGlobalInterfaceTypes);
1141 if (MapUtils.isNotEmpty(localInterfaceTypes)) {
1142 proxyInterfaceTypes.putAll(localInterfaceTypes);
1146 return Either.left(proxyInterfaceTypes);
1149 private Either<Map<String, ToscaNodeType>, ToscaError> createProxyNodeTypes(Map<String, Component> componentCache,
1150 Component container) {
1152 Map<String, ToscaNodeType> nodeTypesMap = new HashMap<>();
1153 Either<Map<String, ToscaNodeType>, ToscaError> res = Either.left(nodeTypesMap);
1155 List<ComponentInstance> componentInstances = container.getComponentInstances();
1157 if (componentInstances == null || componentInstances.isEmpty()) {
1160 Map<String, ComponentInstance> serviceProxyInstanceList = new HashMap<>();
1161 List<ComponentInstance> proxyInst = componentInstances.stream()
1162 .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceProxy.name()))
1163 .collect(Collectors.toList());
1164 if (proxyInst != null && !proxyInst.isEmpty()) {
1165 for (ComponentInstance inst : proxyInst) {
1166 serviceProxyInstanceList.put(inst.getToscaComponentName(), inst);
1170 if (serviceProxyInstanceList.isEmpty()) {
1173 Either<Resource, StorageOperationStatus> serviceProxyOrigin = toscaOperationFacade
1174 .getLatestByName("serviceProxy");
1175 if (serviceProxyOrigin.isRight()) {
1176 log.debug("Failed to fetch normative service proxy resource by tosca name, error {}",
1177 serviceProxyOrigin.right().value());
1178 return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE);
1180 Component origComponent = serviceProxyOrigin.left().value();
1182 for (Entry<String, ComponentInstance> entryProxy : serviceProxyInstanceList.entrySet()) {
1183 Component serviceComponent = null;
1184 ComponentParametersView componentParametersView = new ComponentParametersView();
1185 componentParametersView.disableAll();
1186 componentParametersView.setIgnoreCategories(false);
1187 componentParametersView.setIgnoreProperties(false);
1188 componentParametersView.setIgnoreInputs(false);
1189 componentParametersView.setIgnoreInterfaces(false);
1190 componentParametersView.setIgnoreRequirements(false);
1191 Either<Component, StorageOperationStatus> service = toscaOperationFacade
1192 .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView);
1193 if (service.isRight()) {
1194 log.debug("Failed to fetch resource with id {} for instance {}",
1195 entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName());
1197 serviceComponent = service.left().value();
1200 ToscaNodeType toscaNodeType = createProxyNodeType(componentCache, origComponent, serviceComponent,
1201 entryProxy.getValue());
1202 nodeTypesMap.put(entryProxy.getKey(), toscaNodeType);
1205 return Either.left(nodeTypesMap);
1208 private void createServiceSubstitutionNodeTypes(final Map<String, Component> componentCache,
1209 final Component container, final ToscaTemplate toscaNode) {
1210 final List<ComponentInstance> componentInstances = container.getComponentInstances();
1212 if (CollectionUtils.isEmpty(componentInstances)) {
1215 final List<ComponentInstance> serviceSubstitutionInstanceList = componentInstances.stream()
1216 .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceSubstitution.name()))
1217 .collect(Collectors.toList());
1218 if (CollectionUtils.isNotEmpty(serviceSubstitutionInstanceList)) {
1219 for (ComponentInstance inst : serviceSubstitutionInstanceList) {
1220 final Map<String, ToscaNodeType> nodeTypes =
1221 toscaNode.getNode_types() == null ? new HashMap<>() : toscaNode.getNode_types();
1222 convertInterfaceNodeType(new HashMap<>(), componentCache.get(inst.getSourceModelUid()), toscaNode,
1228 private ToscaNodeType createProxyNodeType(Map<String, Component> componentCache, Component origComponent,
1229 Component proxyComponent, ComponentInstance componentInstance) {
1230 ToscaNodeType toscaNodeType = new ToscaNodeType();
1231 String derivedFrom = ((Resource) origComponent).getToscaResourceName();
1233 toscaNodeType.setDerived_from(derivedFrom);
1234 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = dataTypeCache.getAll();
1235 if (dataTypesEither.isRight()) {
1236 log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value());
1238 Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
1239 Map<String, ToscaCapability> capabilities = this.capabilityRequirementConverter
1240 .convertProxyCapabilities(componentCache, componentInstance, dataTypes);
1242 if (MapUtils.isNotEmpty(capabilities)) {
1243 toscaNodeType.setCapabilities(capabilities);
1245 List<Map<String, ToscaRequirement>> proxyNodeTypeRequirements = this.capabilityRequirementConverter
1246 .convertProxyRequirements(componentCache, componentInstance);
1247 if (CollectionUtils.isNotEmpty(proxyNodeTypeRequirements)) {
1248 toscaNodeType.setRequirements(proxyNodeTypeRequirements);
1250 Optional<Map<String, ToscaProperty>> proxyProperties = getProxyNodeTypeProperties(proxyComponent, dataTypes);
1251 proxyProperties.ifPresent(toscaNodeType::setProperties);
1253 Map<String, Object> interfaceMap = new HashMap<>();
1254 if (MapUtils.isEmpty(componentInstance.getInterfaces())) {
1255 final Optional<Map<String, Object>> proxyInterfaces = getProxyNodeTypeInterfaces(proxyComponent, dataTypes);
1256 if (proxyInterfaces.isPresent()) {
1257 interfaceMap = proxyInterfaces.get();
1260 interfaceMap = interfacesOperationsConverter
1261 .getInterfacesMapFromComponentInstance(proxyComponent, componentInstance, dataTypes, false, false);
1264 interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
1265 toscaNodeType.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap);
1267 return toscaNodeType;
1270 private Either<ToscaNodeTemplate, ToscaError> convertComponentInstanceRequirements(Component component,
1271 ComponentInstance componentInstance,
1272 List<RequirementCapabilityRelDef> relations,
1273 ToscaNodeTemplate nodeTypeTemplate,
1274 Component originComponent,
1275 Map<String, Component> componentCache) {
1277 final List<Map<String, ToscaTemplateRequirement>> toscaRequirements;
1278 final List<RequirementCapabilityRelDef> requirementDefinitionList = filterRequirements(componentInstance,
1280 if (isNotEmpty(requirementDefinitionList)) {
1282 toscaRequirements = buildRequirements(component, componentInstance,
1283 requirementDefinitionList, originComponent, componentCache);
1284 if (!toscaRequirements.isEmpty()) {
1285 nodeTypeTemplate.setRequirements(toscaRequirements);
1287 } catch (final Exception e) {
1288 log.debug("Failed to convert component instance requirements for the component instance {}. ",
1289 componentInstance.getName(), e);
1290 return Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR);
1293 log.debug("Finished to convert requirements for the node type {} ", componentInstance.getName());
1294 return Either.left(nodeTypeTemplate);
1297 private List<Map<String, ToscaTemplateRequirement>> buildRequirements(final Component component,
1298 final ComponentInstance componentInstance,
1299 final List<RequirementCapabilityRelDef> filteredRelations,
1300 final Component originComponent,
1301 final Map<String, Component> componentCache)
1302 throws ToscaExportException {
1304 final List<Map<String, ToscaTemplateRequirement>> toscaRequirements = new ArrayList<>();
1305 for (RequirementCapabilityRelDef relationshipDefinition : filteredRelations) {
1306 final Map<String, ToscaTemplateRequirement> toscaTemplateRequirementMap =
1307 buildRequirement(componentInstance, originComponent, component.getComponentInstances(),
1308 relationshipDefinition, componentCache);
1309 toscaRequirements.add(toscaTemplateRequirementMap);
1312 return toscaRequirements;
1315 private List<RequirementCapabilityRelDef> filterRequirements(ComponentInstance componentInstance,
1316 List<RequirementCapabilityRelDef> relations) {
1317 return relations.stream()
1318 .filter(p -> componentInstance.getUniqueId().equals(p.getFromNode())).collect(Collectors.toList());
1321 private Map<String, ToscaTemplateRequirement> buildRequirement(final ComponentInstance fromInstance,
1322 final Component fromOriginComponent,
1323 final List<ComponentInstance> instancesList,
1324 final RequirementCapabilityRelDef relationshipDefinition,
1325 final Map<String, Component> componentCache)
1326 throws ToscaExportException {
1328 final Map<String, List<RequirementDefinition>> reqMap = fromOriginComponent.getRequirements();
1329 final CapabilityRequirementRelationship capabilityRequirementRelationship = relationshipDefinition
1330 .getRelationships().get(0);
1331 final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation();
1333 final ComponentInstance toInstance = instancesList.stream()
1334 .filter(i -> relationshipDefinition.getToNode().equals(i.getUniqueId()))
1335 .findFirst().orElse(null);
1336 if (toInstance == null) {
1337 final String errorMsg = String
1338 .format("Failed to find a relation from the node %s to the node %s", fromInstance.getName(),
1339 relationshipDefinition.getToNode());
1340 log.debug(errorMsg);
1341 throw new ToscaExportException(errorMsg);
1343 final Optional<RequirementDefinition> reqOpt =
1344 findRequirement(fromOriginComponent, reqMap, relationshipInfo, fromInstance.getUniqueId());
1345 if (reqOpt.isEmpty()) {
1346 final String errorMsg = String
1347 .format("Failed to find a requirement with uniqueId %s on a component with uniqueId %s",
1348 relationshipInfo.getRequirementUid(), fromOriginComponent.getUniqueId());
1349 log.debug(errorMsg);
1350 throw new ToscaExportException(errorMsg);
1352 final ComponentParametersView filter = new ComponentParametersView(true);
1353 filter.setIgnoreComponentInstances(false);
1354 filter.setIgnoreCapabilities(false);
1355 filter.setIgnoreGroups(false);
1356 final Either<Component, StorageOperationStatus> getOriginRes =
1357 toscaOperationFacade.getToscaElement(toInstance.getActualComponentUid(), filter);
1358 if (getOriginRes.isRight()) {
1359 final String errorMsg = String.format(
1360 "Failed to build substituted name for the requirement %s. "
1361 + "Failed to get an origin component with uniqueId %s",
1362 reqOpt.get().getName(), toInstance.getActualComponentUid());
1363 log.debug(errorMsg);
1364 throw new ToscaExportException(errorMsg);
1366 final Component toOriginComponent = getOriginRes.left().value();
1367 Optional<CapabilityDefinition> capOpt = toOriginComponent.getCapabilities().get(reqOpt.get().getCapability()).stream()
1368 .filter(c -> isCapabilityBelongToRelation(relationshipInfo, c)).findFirst();
1369 if (capOpt.isEmpty()) {
1370 capOpt = findCapability(relationshipInfo, toOriginComponent, fromOriginComponent, reqOpt.get());
1371 if (capOpt.isEmpty()) {
1372 final String errorMsg = String
1373 .format("Failed to find a capability with name %s on a component with uniqueId %s",
1374 relationshipInfo.getCapability(), fromOriginComponent.getUniqueId());
1375 log.debug(errorMsg);
1376 throw new ToscaExportException(errorMsg);
1379 return buildRequirement(fromOriginComponent, toOriginComponent, capOpt.get(), reqOpt.get(),
1380 capabilityRequirementRelationship, toInstance, componentCache);
1383 private boolean isCapabilityBelongToRelation(RelationshipInfo reqAndRelationshipPair,
1384 CapabilityDefinition capability) {
1385 return capability.getName().equals(reqAndRelationshipPair.getCapability()) && (capability.getOwnerId() != null
1386 && capability.getOwnerId().equals(reqAndRelationshipPair.getCapabilityOwnerId()));
1389 private Optional<CapabilityDefinition> findCapability(RelationshipInfo reqAndRelationshipPair,
1390 Component toOriginComponent, Component fromOriginComponent,
1391 RequirementDefinition requirement) {
1392 Optional<CapabilityDefinition> cap = toOriginComponent.getCapabilities().get(requirement.getCapability())
1393 .stream().filter(c -> c.getType().equals(requirement.getCapability())).findFirst();
1394 if (!cap.isPresent()) {
1395 log.debug("Failed to find a capability with name {} on a component with uniqueId {}",
1396 reqAndRelationshipPair.getCapability(), fromOriginComponent.getUniqueId());
1401 private Map<String, ToscaTemplateRequirement> buildRequirement(final Component fromOriginComponent,
1402 final Component toOriginComponent,
1403 final CapabilityDefinition capability,
1404 final RequirementDefinition requirement,
1405 final CapabilityRequirementRelationship capabilityRequirementRelationship,
1406 final ComponentInstance toInstance,
1407 final Map<String, Component> componentCache)
1408 throws ToscaExportException {
1410 List<String> reducedPath = capability.getPath();
1411 if (capability.getOwnerId() != null) {
1412 reducedPath = capabilityRequirementConverter
1413 .getReducedPathByOwner(capability.getPath(), capability.getOwnerId());
1415 final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation();
1416 final Either<String, Boolean> capabilityNameEither = capabilityRequirementConverter.buildSubstitutedName(componentCache,
1417 toOriginComponent, reducedPath, relationshipInfo.getCapability(), capability.getPreviousName());
1418 if (capabilityNameEither.isRight()) {
1419 final String errorMsg = String.format(
1420 "Failed to build a substituted capability name for the capability with name %s on a component with uniqueId %s",
1421 capabilityRequirementRelationship.getCapability(), toOriginComponent.getUniqueId());
1424 throw new ToscaExportException(errorMsg);
1426 final Either<String, Boolean> requirementNameEither = capabilityRequirementConverter
1427 .buildSubstitutedName(componentCache, fromOriginComponent,
1428 requirement.getPath(), relationshipInfo.getRequirement(), requirement.getPreviousName());
1429 if (requirementNameEither.isRight()) {
1430 final String errorMsg = String.format("Failed to build a substituted requirement name for the requirement "
1431 + "with name %s on a component with uniqueId %s",
1432 capabilityRequirementRelationship.getRequirement(), fromOriginComponent.getUniqueId());
1433 log.debug(errorMsg);
1434 throw new ToscaExportException(errorMsg);
1436 final ToscaTemplateRequirement toscaRequirement = new ToscaTemplateRequirement();
1437 final Map<String, ToscaTemplateRequirement> toscaReqMap = new HashMap<>();
1438 toscaRequirement.setNode(toInstance.getName());
1439 toscaRequirement.setCapability(capabilityNameEither.left().value());
1440 if (isNotEmpty(capabilityRequirementRelationship.getOperations())) {
1441 toscaRequirement.setRelationship(new ToscaRelationshipBuilder().from(capabilityRequirementRelationship));
1443 toscaReqMap.put(requirementNameEither.left().value(), toscaRequirement);
1447 private Optional<RequirementDefinition> findRequirement(Component fromOriginComponent,
1448 Map<String, List<RequirementDefinition>> reqMap,
1449 RelationshipInfo reqAndRelationshipPair,
1450 String fromInstanceId) {
1451 for (List<RequirementDefinition> reqList : reqMap.values()) {
1452 Optional<RequirementDefinition> reqOpt = reqList.stream().filter(
1453 r -> isRequirementBelongToRelation(fromOriginComponent, reqAndRelationshipPair, r, fromInstanceId))
1455 if (reqOpt.isPresent()) {
1459 return Optional.empty();
1463 * Allows detecting the requirement belonging to the received relationship The detection logic is: A requirement belongs to a relationship IF
1464 * 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
1465 * requirement equals to requirementOwnerId of the relation OR uniqueId of toInstance equals to capabilityOwnerId of the relation
1467 private boolean isRequirementBelongToRelation(Component originComponent, RelationshipInfo reqAndRelationshipPair,
1468 RequirementDefinition requirement, String fromInstanceId) {
1469 if (!StringUtils.equals(requirement.getName(), reqAndRelationshipPair.getRequirement())) {
1470 log.debug("Failed to find a requirement with name {} and reqAndRelationshipPair {}",
1471 requirement.getName(), reqAndRelationshipPair.getRequirement());
1474 return ModelConverter.isAtomicComponent(originComponent) ||
1475 isRequirementBelongToOwner(reqAndRelationshipPair, requirement, fromInstanceId, originComponent);
1478 private boolean isRequirementBelongToOwner(RelationshipInfo reqAndRelationshipPair,
1479 RequirementDefinition requirement, String fromInstanceId,
1480 Component originComponent) {
1481 return StringUtils.equals(requirement.getOwnerId(), reqAndRelationshipPair.getRequirementOwnerId())
1482 || (isCvfc(originComponent) && StringUtils
1483 .equals(fromInstanceId, reqAndRelationshipPair.getRequirementOwnerId())
1484 || StringUtils.equals(requirement.getOwnerId(), originComponent.getUniqueId()));
1487 private boolean isCvfc(Component component) {
1488 return component.getComponentType() == ComponentTypeEnum.RESOURCE &&
1489 ((Resource) component).getResourceType() == ResourceTypeEnum.CVFC;
1492 private Either<SubstitutionMapping, ToscaError> convertCapabilities(Component component,
1493 SubstitutionMapping substitutionMappings,
1494 Map<String, Component> componentCache) {
1496 Either<SubstitutionMapping, ToscaError> result = Either.left(substitutionMappings);
1497 Either<Map<String, String[]>, ToscaError> toscaCapabilitiesRes = capabilityRequirementConverter
1498 .convertSubstitutionMappingCapabilities(componentCache, component);
1499 if (toscaCapabilitiesRes.isRight()) {
1500 result = Either.right(toscaCapabilitiesRes.right().value());
1501 log.debug("Failed convert capabilities for the component {}. ", component.getName());
1502 } else if (isNotEmpty(toscaCapabilitiesRes.left().value())) {
1503 substitutionMappings.setCapabilities(toscaCapabilitiesRes.left().value());
1504 log.debug("Finish convert capabilities for the component {}. ", component.getName());
1506 log.debug("Finished to convert capabilities for the component {}. ", component.getName());
1510 private Either<ToscaNodeType, ToscaError> convertCapabilities(Map<String, Component> componentsCache,
1511 Component component, ToscaNodeType nodeType,
1512 Map<String, DataTypeDefinition> dataTypes) {
1513 Map<String, ToscaCapability> toscaCapabilities = capabilityRequirementConverter
1514 .convertCapabilities(componentsCache, component,
1516 if (!toscaCapabilities.isEmpty()) {
1517 nodeType.setCapabilities(toscaCapabilities);
1519 log.debug("Finish convert Capabilities for node type");
1521 return Either.left(nodeType);
1524 private Map<String, ToscaTemplateArtifact> convertToNodeTemplateArtifacts(
1525 Map<String, ToscaArtifactDataDefinition> artifacts) {
1526 if (artifacts == null) {
1529 Map<String, ToscaTemplateArtifact> arts = new HashMap<>();
1530 for (Map.Entry<String, ToscaArtifactDataDefinition> entry : artifacts.entrySet()) {
1531 ToscaTemplateArtifact artifact = new ToscaTemplateArtifact();
1532 artifact.setFile(entry.getValue().getFile());
1533 artifact.setType(entry.getValue().getType());
1534 arts.put(entry.getKey(), artifact);
1539 protected NodeFilter convertToNodeTemplateNodeFilterComponent(CINodeFilterDataDefinition inNodeFilter) {
1540 if (inNodeFilter == null) {
1543 NodeFilter nodeFilter = new NodeFilter();
1545 ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities =
1546 inNodeFilter.getCapabilities();
1548 ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> origProperties = inNodeFilter.getProperties();
1550 List<Map<String, CapabilityFilter>> capabilitiesCopy = new ArrayList<>();
1551 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1553 copyNodeFilterCapabilitiesTemplate(origCapabilities, capabilitiesCopy);
1554 copyNodeFilterProperties(origProperties, propertiesCopy);
1556 if (CollectionUtils.isNotEmpty(capabilitiesCopy)) {
1557 nodeFilter.setCapabilities(capabilitiesCopy);
1560 if (CollectionUtils.isNotEmpty(propertiesCopy)) {
1561 nodeFilter.setProperties(propertiesCopy);
1564 nodeFilter.setTosca_id(cloneToscaId(inNodeFilter.getTosca_id()));
1566 nodeFilter = (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
1571 private NodeFilter convertToSubstitutionFilterComponent(
1572 final SubstitutionFilterDataDefinition substitutionFilterDataDefinition) {
1574 if (substitutionFilterDataDefinition == null) {
1577 NodeFilter nodeFilter = new NodeFilter();
1579 ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> origProperties =
1580 substitutionFilterDataDefinition.getProperties();
1581 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1583 copySubstitutionFilterProperties(origProperties, propertiesCopy);
1585 if (CollectionUtils.isNotEmpty(propertiesCopy)) {
1586 nodeFilter.setProperties(propertiesCopy);
1588 nodeFilter.setTosca_id(cloneToscaId(substitutionFilterDataDefinition.getTosca_id()));
1590 return (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
1593 private Object cloneToscaId(Object toscaId) {
1594 return Objects.isNull(toscaId) ? null
1595 : cloneObjectFromYml(toscaId, toscaId.getClass());
1598 private Object cloneObjectFromYml(Object objToClone, Class classOfObj) {
1599 String objectAsYml = yamlUtil.objectToYaml(objToClone);
1600 return yamlUtil.yamlToObject(objectAsYml, classOfObj);
1603 private void copyNodeFilterCapabilitiesTemplate(
1604 ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities,
1605 List<Map<String, CapabilityFilter>> capabilitiesCopy) {
1606 if (origCapabilities == null || origCapabilities.getListToscaDataDefinition() == null ||
1607 origCapabilities.getListToscaDataDefinition().isEmpty()) {
1610 for (RequirementNodeFilterCapabilityDataDefinition capability : origCapabilities.getListToscaDataDefinition()) {
1611 Map<String, CapabilityFilter> capabilityFilterCopyMap = new HashMap<>();
1612 CapabilityFilter capabilityFilter = new CapabilityFilter();
1613 List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
1614 copyNodeFilterProperties(capability.getProperties(), propertiesCopy);
1615 capabilityFilter.setProperties(propertiesCopy);
1616 capabilityFilterCopyMap.put(capability.getName(), capabilityFilter);
1617 capabilitiesCopy.add(capabilityFilterCopyMap);
1621 private void copyNodeFilterProperties(
1622 ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> origProperties,
1623 List<Map<String, List<Object>>> propertiesCopy) {
1624 if (origProperties == null || origProperties.getListToscaDataDefinition() == null ||
1625 origProperties.isEmpty()) {
1628 Map<String, List<Object>> propertyMapCopy = new HashMap<>();
1629 for (RequirementNodeFilterPropertyDataDefinition propertyDataDefinition : origProperties
1630 .getListToscaDataDefinition()) {
1631 for (String propertyInfoEntry : propertyDataDefinition.getConstraints()) {
1632 Map propertyValObj = new YamlUtil().yamlToObject(propertyInfoEntry, Map.class);
1633 String propertyName = propertyDataDefinition.getName();
1634 if (propertyMapCopy.containsKey(propertyName)) {
1635 addPropertyConstraintValueToList(propertyName, propertyValObj, propertyMapCopy.get(propertyName));
1637 if (propertyName != null) {
1638 List<Object> propsList = new ArrayList<>();
1639 addPropertyConstraintValueToList(propertyName, propertyValObj, propsList);
1640 propertyMapCopy.put(propertyName, propsList);
1642 propertyMapCopy.putAll(propertyValObj);
1647 propertyMapCopy.entrySet().stream().forEach(entry ->
1648 addCalculatedConstraintsIntoPropertiesList(propertiesCopy, entry));
1651 private void copySubstitutionFilterProperties(
1652 final ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> origProperties,
1653 final List<Map<String, List<Object>>> propertiesCopy) {
1654 if (origProperties == null || origProperties.getListToscaDataDefinition() == null ||
1655 origProperties.isEmpty()) {
1658 final Map<String, List<Object>> propertyMapCopy = new HashMap<>();
1659 for (final RequirementSubstitutionFilterPropertyDataDefinition propertyDataDefinition : origProperties
1660 .getListToscaDataDefinition()) {
1661 for (final String propertyInfoEntry : propertyDataDefinition.getConstraints()) {
1662 final Map<String, List<Object>> propertyValObj = new YamlUtil()
1663 .yamlToObject(propertyInfoEntry, Map.class);
1664 final String propertyName = propertyDataDefinition.getName();
1665 if (propertyMapCopy.containsKey(propertyName)) {
1666 addPropertyConstraintValueToList(propertyName, propertyValObj, propertyMapCopy.get(propertyName));
1668 if (propertyName != null) {
1669 final List<Object> propsList = new ArrayList<>();
1670 addPropertyConstraintValueToList(propertyName, propertyValObj, propsList);
1671 propertyMapCopy.put(propertyName, propsList);
1673 propertyMapCopy.putAll(propertyValObj);
1678 propertyMapCopy.entrySet().forEach(entry ->
1679 addCalculatedConstraintsIntoPropertiesList(propertiesCopy, entry));
1682 private void addPropertyConstraintValueToList(String propertyName, Map<String, List<Object>> propertyValObj, List<Object> propsList) {
1683 if (propertyValObj.containsKey(propertyName)) {
1684 propsList.add(propertyValObj.get(propertyName));
1686 propsList.add(propertyValObj);
1690 private void addCalculatedConstraintsIntoPropertiesList(List<Map<String, List<Object>>> propertiesCopy,
1691 Entry<String, List<Object>> entry) {
1692 Map<String, List<Object>> tempMap = new HashMap<>();
1693 tempMap.put(entry.getKey(), entry.getValue());
1694 propertiesCopy.add(tempMap);
1697 private static class CustomRepresenter extends Representer {
1699 CustomRepresenter() {
1701 this.representers.put(ToscaPropertyAssignment.class, new RepresentToscaPropertyAssignment());
1702 this.representers.put(ToscaAttribute.class, new RepresentToscaAttribute());
1703 // null representer is exceptional and it is stored as an instance
1705 this.nullRepresenter = new RepresentNull();
1709 private class RepresentToscaAttribute implements Represent {
1712 public Node representData(Object data) {
1713 final ToscaAttribute toscaAttribute = (ToscaAttribute) data;
1714 return represent(toscaAttribute.asToscaMap());
1718 private class RepresentToscaPropertyAssignment implements Represent {
1720 public Node representData(Object data) {
1721 final ToscaPropertyAssignment toscaOperationAssignment = (ToscaPropertyAssignment) data;
1722 if (toscaOperationAssignment.getValue() instanceof String) {
1723 final String stringValue = (String) toscaOperationAssignment.getValue();
1724 if (isPropertyOrAttributeFunction(stringValue)) {
1725 return representGetAttribute(stringValue);
1728 return representScalar(Tag.STR, stringValue);
1730 return represent(null);
1733 public Node representGetAttribute(final String getAttributeFunction) {
1734 return represent(new Yaml().load(getAttributeFunction));
1737 public boolean isPropertyOrAttributeFunction(final String value) {
1739 final Yaml yaml = new Yaml();
1740 final Object yamlObj = yaml.load(value);
1741 if (!(yamlObj instanceof Map)) {
1744 final Map<String, Object> getAttributeMap = (Map) yamlObj;
1745 if (getAttributeMap.size() != 1) {
1748 final List<String> functionList = Arrays
1749 .asList(GET_ATTRIBUTE.getFunctionName(), GET_INPUT.getFunctionName(),
1750 GET_PROPERTY.getFunctionName());
1751 final Optional<String> function = getAttributeMap.keySet().stream()
1752 .filter(key -> functionList.stream().anyMatch(function1 -> function1.equals(key))).findFirst();
1754 if (function.isEmpty()) {
1757 final String functionName = function.get();
1758 final Object getAttributeValueObj = getAttributeMap.get(functionName);
1759 if (GET_INPUT.getFunctionName().equals(functionName)) {
1760 return validateGetInputValue(getAttributeValueObj);
1762 return validateGetPropertyOrAttributeValue(getAttributeValueObj);
1764 } catch (final Exception ignored) {
1770 public boolean validateGetInputValue(final Object valueObj) {
1771 if (!(valueObj instanceof List) && !(valueObj instanceof String)) {
1774 if (valueObj instanceof List) {
1775 return ((List) valueObj).size() > 1;
1781 public boolean validateGetPropertyOrAttributeValue(final Object valueObj) {
1782 if (valueObj instanceof List) {
1783 return ((List) valueObj).size() > 1;
1790 protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue,
1792 if (propertyValue == null) {
1795 // skip not relevant for Tosca property
1796 if ("dependencies".equals(property.getName())) {
1799 if (javaBean instanceof ToscaRelationshipTemplate && "name".equals(property.getName())) {
1803 removeDefaultP(propertyValue);
1804 NodeTuple defaultNode = super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
1806 if (javaBean instanceof ToscaTopolgyTemplate && "relationshipTemplates".equals(property.getName())) {
1807 return new NodeTuple(representData("relationship_templates"), defaultNode.getValueNode());
1810 return "_defaultp_".equals(property.getName())
1811 ? new NodeTuple(representData("default"), defaultNode.getValueNode()) : defaultNode;
1814 private void removeDefaultP(final Object propertyValue) {
1815 if (propertyValue instanceof Map) {
1816 final Map mapPropertyValue = ((Map) propertyValue);
1818 final Iterator<Entry> iter = mapPropertyValue.entrySet().iterator();
1819 Object defaultValue = null;
1820 while (iter.hasNext()) {
1821 final Map.Entry entry = iter.next();
1823 if ("_defaultp_".equals(entry.getKey())) {
1824 defaultValue = entry.getValue();
1826 } else if (entry.getValue() instanceof Map) {
1827 removeDefaultP(entry.getValue());
1830 if (defaultValue != null) {
1831 mapPropertyValue.putIfAbsent("default", defaultValue);
1837 protected MappingNode representJavaBean(Set<Property> properties, Object javaBean) {
1838 // remove the bean type from the output yaml (!! ...)
1839 if (!classTags.containsKey(javaBean.getClass())) {
1840 addClassTag(javaBean.getClass(), Tag.MAP);
1843 return super.representJavaBean(properties, javaBean);
1846 private class RepresentNull implements Represent {
1849 public Node representData(Object data) {
1850 // possible values are here http://yaml.org/type/null.html
1851 return representScalar(Tag.NULL, "");
1856 private static class UnsortedPropertyUtils extends PropertyUtils {
1859 protected Set<Property> createPropertySet(Class type, BeanAccess bAccess) {
1860 Collection<Property> fields = getPropertiesMap(type, BeanAccess.FIELD).values();
1861 return new LinkedHashSet<>(fields);
1865 private Map<String, String[]> buildSubstitutionMappingPropertyMapping(final Component component) {
1866 if (component == null || CollectionUtils.isEmpty(component.getInputs())) {
1867 return Collections.emptyMap();
1869 return component.getInputs().stream().filter(input -> input.isMappedToComponentProperty())
1870 .map(PropertyDataDefinition::getName)
1873 inputName -> inputName,
1874 inputName -> new String[]{inputName},
1875 (inputName1, inputName2) -> inputName1)
1879 private Map<String, String[]> buildSubstitutionMappingAttributesMapping(final Component component) {
1880 if (component == null || CollectionUtils.isEmpty(component.getOutputs())) {
1881 return Collections.emptyMap();
1883 return component.getOutputs().stream()
1884 .map(AttributeDataDefinition::getName)
1887 outputName -> outputName,
1888 outputName -> new String[]{outputName},
1889 (outputName1, outputName2) -> outputName1)
1893 Optional<Map<String, ToscaProperty>> getProxyNodeTypeProperties(Component proxyComponent,
1894 Map<String, DataTypeDefinition>
1896 if (Objects.isNull(proxyComponent)) {
1897 return Optional.empty();
1899 Map<String, ToscaProperty> proxyProperties = new HashMap<>();
1900 addInputsToProperties(dataTypes, proxyComponent.getInputs(), proxyProperties);
1901 if (CollectionUtils.isNotEmpty(proxyComponent.getProperties())) {
1902 proxyProperties.putAll(proxyComponent.getProperties().stream()
1903 .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition,
1904 proxyComponent.getInputs()))
1905 .collect(Collectors.toMap(PropertyDataDefinition::getName,
1906 property -> propertyConvertor.convertProperty(dataTypes, property,
1907 PropertyConvertor.PropertyType.PROPERTY))));
1909 return MapUtils.isNotEmpty(proxyProperties) ? Optional.of(proxyProperties) : Optional.empty();
1912 void addInputsToProperties(Map<String, DataTypeDefinition> dataTypes,
1913 List<InputDefinition> componentInputs,
1914 Map<String, ToscaProperty> mergedProperties) {
1915 if (CollectionUtils.isEmpty(componentInputs)) {
1918 for (InputDefinition input : componentInputs) {
1919 ToscaProperty property = propertyConvertor.convertProperty(dataTypes, input,
1920 PropertyConvertor.PropertyType.INPUT);
1921 mergedProperties.put(input.getName(), property);
1925 Optional<Map<String, Object>> getProxyNodeTypeInterfaces(Component proxyComponent,
1926 Map<String, DataTypeDefinition> dataTypes) {
1927 if (Objects.isNull(proxyComponent) || MapUtils.isEmpty(proxyComponent.getInterfaces())) {
1928 return Optional.empty();
1930 Map<String, InterfaceDefinition> proxyComponentInterfaces = proxyComponent.getInterfaces();
1931 //Unset artifact path for operation implementation for proxy node types as for operations with artifacts it is
1932 // always available in the proxy node template
1933 removeOperationImplementationForProxyNodeType(proxyComponentInterfaces);
1934 return Optional.ofNullable(interfacesOperationsConverter
1935 .getInterfacesMap(proxyComponent, null, proxyComponentInterfaces, dataTypes,
1939 private static void removeOperationImplementationForProxyNodeType(
1940 Map<String, InterfaceDefinition> proxyComponentInterfaces) {
1941 if (MapUtils.isEmpty(proxyComponentInterfaces)) {
1944 proxyComponentInterfaces.values().stream().map(InterfaceDataDefinition::getOperations)
1945 .filter(MapUtils::isNotEmpty)
1946 .forEach(operations -> operations.values().forEach(operation -> operation.setImplementation(null)));