2 * Copyright © 2016-2018 European Support Limited
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.openecomp.sdc.tosca.services.impl;
19 import org.apache.commons.collections4.CollectionUtils;
20 import org.apache.commons.collections4.MapUtils;
21 import org.apache.commons.lang3.StringUtils;
22 import org.openecomp.core.utilities.CommonMethods;
23 import org.openecomp.sdc.common.errors.CoreException;
24 import org.openecomp.sdc.tosca.datatypes.ToscaElementTypes;
25 import org.openecomp.sdc.tosca.datatypes.ToscaFlatData;
26 import org.onap.sdc.tosca.datatypes.model.AttributeDefinition;
27 import org.onap.sdc.tosca.datatypes.model.CapabilityDefinition;
28 import org.onap.sdc.tosca.datatypes.model.CapabilityType;
29 import org.onap.sdc.tosca.datatypes.model.DefinitionOfDataType;
30 import org.onap.sdc.tosca.datatypes.model.DataType;
31 import org.onap.sdc.tosca.datatypes.model.Import;
32 import org.onap.sdc.tosca.datatypes.model.InterfaceDefinitionType;
33 import org.onap.sdc.tosca.datatypes.model.NodeTemplate;
34 import org.onap.sdc.tosca.datatypes.model.NodeType;
35 import org.onap.sdc.tosca.datatypes.model.ParameterDefinition;
36 import org.onap.sdc.tosca.datatypes.model.PropertyDefinition;
37 import org.onap.sdc.tosca.datatypes.model.PropertyType;
38 import org.onap.sdc.tosca.datatypes.model.RequirementAssignment;
39 import org.onap.sdc.tosca.datatypes.model.RequirementDefinition;
40 import org.onap.sdc.tosca.datatypes.model.ServiceTemplate;
41 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
42 import org.openecomp.sdc.tosca.errors.CreateInterfaceObjectErrorBuilder;
43 import org.openecomp.sdc.tosca.errors.ToscaElementTypeNotFoundErrorBuilder;
44 import org.openecomp.sdc.tosca.errors.ToscaFileNotFoundErrorBuilder;
45 import org.openecomp.sdc.tosca.errors.ToscaInvalidEntryNotFoundErrorBuilder;
46 import org.openecomp.sdc.tosca.errors.ToscaInvalidSubstituteNodeTemplatePropertiesErrorBuilder;
47 import org.openecomp.sdc.tosca.errors.ToscaInvalidSubstitutionServiceTemplateErrorBuilder;
48 import org.openecomp.sdc.tosca.services.DataModelUtil;
49 import org.onap.sdc.tosca.services.ToscaExtensionYamlUtil;
50 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
51 import org.openecomp.sdc.tosca.services.ToscaConstants;
53 import java.util.ArrayList;
54 import java.util.Collection;
55 import java.util.Collections;
56 import java.util.HashMap;
57 import java.util.HashSet;
58 import java.util.List;
60 import java.util.Objects;
61 import java.util.Optional;
63 import java.lang.reflect.InvocationTargetException;
65 import org.openecomp.sdc.tosca.services.ToscaUtil;
67 public class ToscaAnalyzerServiceImpl implements ToscaAnalyzerService {
69 private final String GET_NODE_TYPE_METHOD_NAME = "getNode_types";
70 private final String GET_DERIVED_FROM_METHOD_NAME = "getDerived_from";
71 private final String GET_TYPE_METHOD_NAME = "getType";
72 private final String GET_DATA_TYPE_METHOD_NAME = "getData_types";
73 private final String GET_INTERFACE_TYPE_METHOD_NAME = "getInterface_types";
74 private final String TOSCA_DOT = "tosca.";
75 private final String DOT_ROOT = ".Root";
78 public List<Map<String, RequirementDefinition>> calculateExposedRequirements(List<Map<String, RequirementDefinition>> nodeTypeRequirementsDefinitionList,
79 Map<String, RequirementAssignment> nodeTemplateRequirementsAssignment) {
81 if (nodeTypeRequirementsDefinitionList == null) {
82 return Collections.emptyList();
84 for (Map.Entry<String, RequirementAssignment> entry : nodeTemplateRequirementsAssignment.entrySet()) {
85 if (entry.getValue().getNode() != null) {
86 Optional<RequirementDefinition> requirementDefinition =
87 DataModelUtil.getRequirementDefinition(nodeTypeRequirementsDefinitionList, entry.getKey());
88 RequirementDefinition cloneRequirementDefinition;
89 if (requirementDefinition.isPresent()) {
90 cloneRequirementDefinition = requirementDefinition.get().clone();
91 updateRequirementDefinition(nodeTypeRequirementsDefinitionList, entry, cloneRequirementDefinition);
94 for (Map<String, RequirementDefinition> nodeTypeRequirementsMap : nodeTypeRequirementsDefinitionList) {
95 updateMinMaxOccurencesForNodeTypeRequirement(entry, nodeTypeRequirementsMap);
99 return nodeTypeRequirementsDefinitionList;
102 private void updateMinMaxOccurencesForNodeTypeRequirement(Map.Entry<String, RequirementAssignment> entry,
103 Map<String, RequirementDefinition> nodeTypeRequirementsMap) {
104 Object max = nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences() != null
105 && nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences().length > 0 ?
106 nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences()[1] : 1;
107 Object min = nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences() != null
108 && nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences().length > 0 ?
109 nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences()[0] : 1;
110 nodeTypeRequirementsMap.get(entry.getKey()).setOccurrences(new Object[] {min, max});
113 private void updateRequirementDefinition(List<Map<String, RequirementDefinition>> nodeTypeRequirementsDefinitionList,
114 Map.Entry<String, RequirementAssignment> entry,
115 RequirementDefinition cloneRequirementDefinition) {
116 if (!evaluateRequirementFulfillment(cloneRequirementDefinition)) {
118 .mergeEntryInList(entry.getKey(), cloneRequirementDefinition, nodeTypeRequirementsDefinitionList);
120 DataModelUtil.removeRequirementsDefinition(nodeTypeRequirementsDefinitionList, entry.getKey());
124 private static boolean evaluateRequirementFulfillment(RequirementDefinition requirementDefinition) {
125 Object[] occurrences = requirementDefinition.getOccurrences();
126 if (occurrences == null) {
127 requirementDefinition.setOccurrences(new Object[] {1, 1});
130 if (occurrences[1].equals(ToscaConstants.UNBOUNDED)) {
134 if (occurrences[1].equals(1)) {
137 occurrences[1] = (Integer) occurrences[1] - 1;
142 public Map<String, CapabilityDefinition> calculateExposedCapabilities(Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition,
143 Map<String, Map<String, RequirementAssignment>> fullFilledRequirementsDefinitionMap) {
145 String capabilityKey;
148 for (Map.Entry<String, Map<String, RequirementAssignment>> entry : fullFilledRequirementsDefinitionMap
150 for (Map.Entry<String, RequirementAssignment> fullFilledEntry : entry.getValue().entrySet()) {
152 capability = fullFilledEntry.getValue().getCapability();
153 node = fullFilledEntry.getValue().getNode();
154 capabilityKey = capability + "_" + node;
155 CapabilityDefinition capabilityDefinition = nodeTypeCapabilitiesDefinition.get(capabilityKey);
156 if (capabilityDefinition != null) {
157 CapabilityDefinition clonedCapabilityDefinition = capabilityDefinition.clone();
158 nodeTypeCapabilitiesDefinition.put(capabilityKey, capabilityDefinition.clone());
159 updateNodeTypeCapabilitiesDefinition(nodeTypeCapabilitiesDefinition, capabilityKey,
160 clonedCapabilityDefinition);
165 Map<String, CapabilityDefinition> exposedCapabilitiesDefinition = new HashMap<>();
166 for (Map.Entry<String, CapabilityDefinition> entry : nodeTypeCapabilitiesDefinition.entrySet()) {
167 exposedCapabilitiesDefinition.put(entry.getKey(), entry.getValue());
169 return exposedCapabilitiesDefinition;
172 private void updateNodeTypeCapabilitiesDefinition(Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition,
173 String capabilityKey,
174 CapabilityDefinition clonedCapabilityDefinition) {
175 if (evaluateCapabilityFulfillment(clonedCapabilityDefinition)) {
176 nodeTypeCapabilitiesDefinition.remove(capabilityKey);
178 nodeTypeCapabilitiesDefinition.put(capabilityKey, clonedCapabilityDefinition);
182 private static boolean evaluateCapabilityFulfillment(CapabilityDefinition capabilityDefinition) {
184 Object[] occurrences = capabilityDefinition.getOccurrences();
185 if (occurrences == null) {
186 capabilityDefinition.setOccurrences(new Object[] {1, ToscaConstants.UNBOUNDED});
189 if (occurrences[1].equals(ToscaConstants.UNBOUNDED)) {
193 if (occurrences[1].equals(1)) {
196 occurrences[1] = (Integer) occurrences[1] - 1;
201 node template with type equal to node type or derived from node type
204 public Map<String, NodeTemplate> getNodeTemplatesByType(ServiceTemplate serviceTemplate, String nodeType,
205 ToscaServiceModel toscaServiceModel) {
206 Map<String, NodeTemplate> nodeTemplates = new HashMap<>();
208 if (Objects.nonNull(serviceTemplate.getTopology_template()) && MapUtils.isNotEmpty(
209 serviceTemplate.getTopology_template().getNode_templates())) {
210 for (Map.Entry<String, NodeTemplate> nodeTemplateEntry : serviceTemplate.getTopology_template()
211 .getNode_templates().entrySet()) {
212 if (isTypeOf(nodeTemplateEntry.getValue(), nodeType, serviceTemplate, toscaServiceModel)) {
213 nodeTemplates.put(nodeTemplateEntry.getKey(), nodeTemplateEntry.getValue());
218 return nodeTemplates;
222 public Optional<NodeType> fetchNodeType(String nodeTypeKey, Collection<ServiceTemplate> serviceTemplates) {
223 Optional<Map<String, NodeType>> nodeTypeMap = serviceTemplates.stream().map(ServiceTemplate::getNode_types)
224 .filter(nodeTypes -> Objects.nonNull(nodeTypes)
229 return nodeTypeMap.map(stringNodeTypeMap -> stringNodeTypeMap.get(nodeTypeKey));
233 public boolean isTypeOf(NodeTemplate nodeTemplate, String nodeType, ServiceTemplate serviceTemplate,
234 ToscaServiceModel toscaServiceModel) {
235 return isTypeOf(nodeTemplate, nodeType, GET_NODE_TYPE_METHOD_NAME, serviceTemplate, toscaServiceModel);
239 public List<RequirementAssignment> getRequirements(NodeTemplate nodeTemplate, String requirementId) {
240 List<RequirementAssignment> requirements = new ArrayList<>();
241 List<Map<String, RequirementAssignment>> requirementList = nodeTemplate.getRequirements();
242 if (requirementList != null) {
243 requirementList.stream().filter(reqMap -> reqMap.get(requirementId) != null).forEach(reqMap -> {
244 ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
245 RequirementAssignment reqAssignment = toscaExtensionYamlUtil.yamlToObject(
246 toscaExtensionYamlUtil.objectToYaml(reqMap.get(requirementId)), RequirementAssignment.class);
247 requirements.add(reqAssignment);
254 public Optional<NodeTemplate> getNodeTemplateById(ServiceTemplate serviceTemplate, String nodeTemplateId) {
255 if ((serviceTemplate.getTopology_template() != null) && (serviceTemplate.getTopology_template()
256 .getNode_templates() != null)
257 && (serviceTemplate.getTopology_template().getNode_templates().get(nodeTemplateId) != null)) {
258 return Optional.of(serviceTemplate.getTopology_template().getNode_templates().get(nodeTemplateId));
260 return Optional.empty();
264 public Optional<String> getSubstituteServiceTemplateName(String substituteNodeTemplateId,
265 NodeTemplate substitutableNodeTemplate) {
266 if (!isSubstitutableNodeTemplate(substitutableNodeTemplate)) {
267 return Optional.empty();
270 if (substitutableNodeTemplate.getProperties() != null &&
271 substitutableNodeTemplate.getProperties().get(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME)
273 Object serviceTemplateFilter =
274 substitutableNodeTemplate.getProperties().get(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME);
275 if (serviceTemplateFilter != null && serviceTemplateFilter instanceof Map) {
276 Object substituteServiceTemplate =
277 ((Map) serviceTemplateFilter).get(ToscaConstants.SUBSTITUTE_SERVICE_TEMPLATE_PROPERTY_NAME);
278 handleNoSubstituteServiceTemplate(substituteNodeTemplateId, substituteServiceTemplate);
279 return Optional.of(substituteServiceTemplate.toString());
282 throw new CoreException(new ToscaInvalidSubstituteNodeTemplatePropertiesErrorBuilder(substituteNodeTemplateId)
286 private void handleNoSubstituteServiceTemplate(String substituteNodeTemplateId, Object substituteServiceTemplate) {
287 if (substituteServiceTemplate == null) {
288 throw new CoreException(new ToscaInvalidSubstituteNodeTemplatePropertiesErrorBuilder(substituteNodeTemplateId)
294 public Map<String, NodeTemplate> getSubstitutableNodeTemplates(ServiceTemplate serviceTemplate) {
295 Map<String, NodeTemplate> substitutableNodeTemplates = new HashMap<>();
297 if (serviceTemplate == null || serviceTemplate.getTopology_template() == null
298 || serviceTemplate.getTopology_template().getNode_templates() == null) {
299 return substitutableNodeTemplates;
302 Map<String, NodeTemplate> nodeTemplates = serviceTemplate.getTopology_template().getNode_templates();
303 for (Map.Entry<String, NodeTemplate> entry : nodeTemplates.entrySet()) {
304 String nodeTemplateId = entry.getKey();
305 NodeTemplate nodeTemplate = entry.getValue();
306 if (isSubstitutableNodeTemplate(nodeTemplate)) {
307 substitutableNodeTemplates.put(nodeTemplateId, nodeTemplate);
311 return substitutableNodeTemplates;
315 public Optional<Map.Entry<String, NodeTemplate>> getSubstitutionMappedNodeTemplateByExposedReq(String substituteServiceTemplateFileName,
316 ServiceTemplate substituteServiceTemplate,
317 String requirementId) {
318 if (isSubstitutionServiceTemplate(substituteServiceTemplateFileName, substituteServiceTemplate)) {
319 Map<String, List<String>> substitutionMappingRequirements =
320 substituteServiceTemplate.getTopology_template().getSubstitution_mappings().getRequirements();
321 if (substitutionMappingRequirements != null) {
322 List<String> requirementMapping = substitutionMappingRequirements.get(requirementId);
323 if (requirementMapping != null && !requirementMapping.isEmpty()) {
324 String mappedNodeTemplateId = requirementMapping.get(0);
325 Optional<NodeTemplate> mappedNodeTemplate =
326 getNodeTemplateById(substituteServiceTemplate, mappedNodeTemplateId);
327 mappedNodeTemplate.orElseThrow(
328 () -> new CoreException(new ToscaInvalidEntryNotFoundErrorBuilder("Node Template",
329 mappedNodeTemplateId)
331 Map.Entry<String, NodeTemplate> mappedNodeTemplateEntry = new Map.Entry<String, NodeTemplate>() {
333 public String getKey() {
334 return mappedNodeTemplateId;
338 public NodeTemplate getValue() {
339 return mappedNodeTemplate.get();
343 public NodeTemplate setValue(NodeTemplate value) {
347 return Optional.of(mappedNodeTemplateEntry);
351 return Optional.empty();
355 match only for the input which is not null
358 public boolean isDesiredRequirementAssignment(RequirementAssignment requirementAssignment, String capability,
359 String node, String relationship) {
360 if (isSameCapability(requirementAssignment, capability)) {
364 if (isSameRequirement(requirementAssignment, node)) {
368 if (isSameRelationship(requirementAssignment, relationship)) {
372 return !(capability == null && node == null && relationship == null);
376 private boolean isSameRelationship(RequirementAssignment requirementAssignment, String relationship) {
377 return relationship != null && (requirementAssignment.getRelationship() == null || !requirementAssignment
379 .equals(relationship));
382 private boolean isSameRequirement(RequirementAssignment requirementAssignment, String node) {
383 return node != null && (requirementAssignment.getNode() == null || !requirementAssignment.getNode()
387 private boolean isSameCapability(RequirementAssignment requirementAssignment, String capability) {
388 return capability != null && (requirementAssignment.getCapability() == null || !requirementAssignment
390 .equals(capability));
394 public ToscaFlatData getFlatEntity(ToscaElementTypes elementType, String typeId, ServiceTemplate serviceTemplate,
395 ToscaServiceModel toscaModel) {
396 ToscaFlatData flatData = new ToscaFlatData();
397 flatData.setElementType(elementType);
399 switch (elementType) {
400 case CAPABILITY_TYPE:
401 flatData.setFlatEntity(new CapabilityType());
404 flatData.setFlatEntity(new NodeType());
407 flatData.setFlatEntity(new DataType());
410 throw new RuntimeException("Entity[" + elementType + "] id[" + typeId + "] flat not supported");
413 boolean isEntityFound =
414 scanAnFlatEntity(elementType, typeId, flatData, serviceTemplate, toscaModel, new ArrayList<>(), 0);
415 if (!isEntityFound) {
416 throw new CoreException(new ToscaElementTypeNotFoundErrorBuilder(typeId).build());
423 public boolean isSubstitutableNodeTemplate(NodeTemplate nodeTemplate) {
424 return nodeTemplate.getDirectives() != null && nodeTemplate.getDirectives().contains(
425 ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
428 private <T> Optional<Boolean> isTypeExistInServiceTemplateHierarchy(String typeToMatch, String typeToSearch,
429 String getTypesMethodName,
430 ServiceTemplate serviceTemplate,
431 ToscaServiceModel toscaServiceModel,
432 Set<String> analyzedImportFiles)
433 throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
434 Map<String, T> searchableTypes =
435 (Map<String, T>) serviceTemplate.getClass().getMethod(getTypesMethodName).invoke(serviceTemplate);
437 if (!MapUtils.isEmpty(searchableTypes)) {
438 T typeObject = searchableTypes.get(typeToSearch);
439 if (Objects.nonNull(typeObject)) {
440 String derivedFromTypeVal =
441 (String) typeObject.getClass().getMethod(GET_DERIVED_FROM_METHOD_NAME).invoke(typeObject);
442 if (Objects.equals(derivedFromTypeVal, typeToMatch)) {
443 return Optional.of(true);
444 } else if (Objects.isNull(derivedFromTypeVal) || isTypeIsToscaRoot(derivedFromTypeVal)) {
445 return Optional.of(false);
447 return isTypeExistInServiceTemplateHierarchy(typeToMatch, derivedFromTypeVal, getTypesMethodName,
448 serviceTemplate, toscaServiceModel, null);
451 return isTypeExistInImports(typeToMatch, typeToSearch, getTypesMethodName, serviceTemplate,
452 toscaServiceModel, analyzedImportFiles);
455 return isTypeExistInImports(typeToMatch, typeToSearch, getTypesMethodName, serviceTemplate, toscaServiceModel,
456 analyzedImportFiles);
459 private Optional<Boolean> isTypeExistInImports(String typeToMatch, String typeToSearch, String getTypesMethodName,
460 ServiceTemplate serviceTemplate,
461 ToscaServiceModel toscaServiceModel, Set<String> filesScanned)
462 throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
463 List<Map<String, Import>> imports = serviceTemplate.getImports();
464 if (CollectionUtils.isEmpty(imports)) {
465 return Optional.empty();
468 Set<String> createdFilesScanned = createFilesScannedSet(filesScanned);
470 for (Map<String, Import> map : imports) {
471 ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
472 Import anImport = toscaExtensionYamlUtil
473 .yamlToObject(toscaExtensionYamlUtil.objectToYaml(map.values().iterator().next()),
475 handleImportWithNoFileEntry(anImport);
476 String importFile = anImport.getFile();
477 ServiceTemplate template = toscaServiceModel.getServiceTemplates().get(fetchFileNameForImport(importFile,
478 serviceTemplate.getMetadata() == null ? null : serviceTemplate.getMetadata().get("filename")));
479 if (Objects.isNull(template) || createdFilesScanned
480 .contains(ToscaUtil.getServiceTemplateFileName(template))) {
483 createdFilesScanned.add(ToscaUtil.getServiceTemplateFileName(template));
485 Optional<Boolean> typeExistInServiceTemplateHierarchy =
486 isTypeExistInServiceTemplateHierarchy(typeToMatch, typeToSearch, getTypesMethodName, template,
487 toscaServiceModel, createdFilesScanned);
488 if (typeExistInServiceTemplateHierarchy.isPresent() && (typeExistInServiceTemplateHierarchy.get())) {
489 createdFilesScanned.clear();
490 return Optional.of(true);
494 return Optional.of(false);
497 private void handleImportWithNoFileEntry(Import anImport) {
498 if (Objects.isNull(anImport) || Objects.isNull(anImport.getFile())) {
499 throw new RuntimeException("import without file entry");
503 private Set<String> createFilesScannedSet(Set<String> filesScanned) {
504 Set<String> retFileScanned = filesScanned;
505 if (Objects.isNull(retFileScanned)) {
506 retFileScanned = new HashSet<>();
508 return retFileScanned;
511 private boolean isTypeIsToscaRoot(String type) {
512 return (type.contains(TOSCA_DOT) && type.contains(DOT_ROOT));
515 private boolean isSubstitutionServiceTemplate(String substituteServiceTemplateFileName,
516 ServiceTemplate substituteServiceTemplate) {
517 if (substituteServiceTemplate != null && substituteServiceTemplate.getTopology_template() != null
518 && substituteServiceTemplate.getTopology_template().getSubstitution_mappings() != null) {
519 if (substituteServiceTemplate.getTopology_template().getSubstitution_mappings().getNode_type() == null) {
520 throw new CoreException(new ToscaInvalidSubstitutionServiceTemplateErrorBuilder(substituteServiceTemplateFileName)
529 private boolean scanAnFlatEntity(ToscaElementTypes elementType, String typeId, ToscaFlatData flatData,
530 ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel,
531 List<String> filesScanned, int rootScanStartInx) {
534 boolean entityFound =
535 enrichEntityFromCurrentServiceTemplate(elementType, typeId, flatData, serviceTemplate, toscaModel,
536 filesScanned, rootScanStartInx);
538 List<Map<String, Import>> imports = serviceTemplate.getImports();
539 if (CollectionUtils.isEmpty(imports)) {
542 boolean found = false;
543 for (Map<String, Import> importMap : imports) {
547 found = isFlatEntity(importMap, flatData, serviceTemplate, filesScanned, toscaModel, elementType,
555 private boolean isFlatEntity(Map<String, Import> importMap, ToscaFlatData flatData, ServiceTemplate serviceTemplate,
556 List<String> filesScanned, ToscaServiceModel toscaModel,
557 ToscaElementTypes elementType, String typeId) {
558 boolean found = false;
559 ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
560 for (Object importObject : importMap.values()) {
561 Import importServiceTemplate = toscaExtensionYamlUtil
562 .yamlToObject(toscaExtensionYamlUtil.objectToYaml(importObject),
564 String fileName = fetchFileNameForImport(importServiceTemplate.getFile(),
565 serviceTemplate.getMetadata() == null ? null : serviceTemplate.getMetadata().get("filename"));
566 if (filesScanned.contains(fileName)) {
569 filesScanned.add(fileName);
571 ServiceTemplate template = toscaModel.getServiceTemplates().get(fileName);
572 if (Objects.isNull(template)) {
573 throw new CoreException(new ToscaFileNotFoundErrorBuilder(fileName).build());
575 found = scanAnFlatEntity(elementType, typeId, flatData, template, toscaModel, filesScanned,
576 filesScanned.size());
581 private String fetchFileNameForImport(String importServiceTemplateFile, String currentMetadatafileName) {
582 if (importServiceTemplateFile.contains("../")) {
583 return importServiceTemplateFile.replace("../", "");
584 } else if (currentMetadatafileName != null && currentMetadatafileName.indexOf('/') != -1) {
585 return currentMetadatafileName.substring(0, currentMetadatafileName.indexOf('/')) + "/"
586 + importServiceTemplateFile;
588 return importServiceTemplateFile;
593 private boolean enrichEntityFromCurrentServiceTemplate(ToscaElementTypes elementType, String typeId,
594 ToscaFlatData flatData,
595 ServiceTemplate serviceTemplate,
596 ToscaServiceModel toscaModel,
597 List<String> filesScanned, int rootScanStartInx) {
598 switch (elementType) {
599 case CAPABILITY_TYPE:
600 if (enrichCapabilityType(elementType, typeId, flatData, serviceTemplate, toscaModel, filesScanned,
606 if (enrichNodeTypeInfo(elementType, typeId, flatData, serviceTemplate, toscaModel, filesScanned,
612 if (enrichDataTypeInfo(elementType, typeId, flatData, serviceTemplate, toscaModel, filesScanned,
618 throw new RuntimeException("Entity[" + elementType + "] id[" + typeId + "] flat not supported");
626 private boolean enrichNodeTypeInfo(ToscaElementTypes elementType, String typeId, ToscaFlatData flatData,
627 ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel,
628 List<String> filesScanned, int rootScanStartInx) {
630 if (serviceTemplate.getNode_types() != null && serviceTemplate.getNode_types().containsKey(typeId)) {
632 filesScanned.clear();
633 flatData.addInheritanceHierarchyType(typeId);
634 NodeType targetNodeType = (NodeType) flatData.getFlatEntity();
635 NodeType sourceNodeType = serviceTemplate.getNode_types().get(typeId);
636 derivedFrom = sourceNodeType.getDerived_from();
637 if (derivedFrom != null) {
638 boolean isEntityFound =
639 scanAnFlatEntity(elementType, derivedFrom, flatData, serviceTemplate, toscaModel, filesScanned,
641 if (!isEntityFound) {
642 throw new CoreException(new ToscaElementTypeNotFoundErrorBuilder(typeId).build());
645 combineNodeTypeInfo(sourceNodeType, targetNodeType);
652 private boolean enrichDataTypeInfo(ToscaElementTypes elementType, String typeId, ToscaFlatData flatData,
653 ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel,
654 List<String> filesScanned, int rootScanStartInx) {
656 if (serviceTemplate.getData_types() != null && serviceTemplate.getData_types().containsKey(typeId)) {
658 filesScanned.clear();
659 flatData.addInheritanceHierarchyType(typeId);
660 DataType targetDataType = (DataType) flatData.getFlatEntity();
661 DataType sourceDataType = serviceTemplate.getData_types().get(typeId);
662 derivedFrom = sourceDataType.getDerived_from();
663 if (derivedFrom != null) {
664 boolean isEntityFound =
665 scanAnFlatEntity(elementType, derivedFrom, flatData, serviceTemplate, toscaModel, filesScanned,
667 if (!isEntityFound) {
668 throw new CoreException(new ToscaElementTypeNotFoundErrorBuilder(typeId).build());
671 combineDataTypeInfo(sourceDataType, targetDataType);
678 private boolean enrichCapabilityType(ToscaElementTypes elementType, String typeId, ToscaFlatData flatData,
679 ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel,
680 List<String> filesScanned, int rootScanStartInx) {
682 if (serviceTemplate.getCapability_types() != null && serviceTemplate.getCapability_types()
683 .containsKey(typeId)) {
685 filesScanned.clear();
686 flatData.addInheritanceHierarchyType(typeId);
687 CapabilityType targetCapabilityType = (CapabilityType) flatData.getFlatEntity();
688 CapabilityType sourceCapabilityType = serviceTemplate.getCapability_types().get(typeId);
689 derivedFrom = sourceCapabilityType.getDerived_from();
690 if (derivedFrom != null) {
691 boolean isEntityFound =
692 scanAnFlatEntity(elementType, derivedFrom, flatData, serviceTemplate, toscaModel, filesScanned,
694 if (!isEntityFound) {
695 throw new CoreException(new ToscaElementTypeNotFoundErrorBuilder(typeId).build());
698 combineCapabilityTypeInfo(sourceCapabilityType, targetCapabilityType);
705 private void combineNodeTypeInfo(NodeType sourceNodeType, NodeType targetNodeType) {
706 targetNodeType.setDerived_from(sourceNodeType.getDerived_from());
707 targetNodeType.setDescription(sourceNodeType.getDescription());
708 targetNodeType.setVersion(sourceNodeType.getVersion());
710 .setProperties(CommonMethods.mergeMaps(targetNodeType.getProperties(), sourceNodeType.getProperties()));
711 combineNodeTypeInterfaceInfo(sourceNodeType, targetNodeType);
713 .setArtifacts(CommonMethods.mergeMaps(targetNodeType.getArtifacts(), sourceNodeType.getArtifacts()));
715 .setAttributes(CommonMethods.mergeMaps(targetNodeType.getAttributes(), sourceNodeType.getAttributes()));
716 targetNodeType.setCapabilities(
717 CommonMethods.mergeMaps(targetNodeType.getCapabilities(), sourceNodeType.getCapabilities()));
718 targetNodeType.setRequirements(
719 CommonMethods.mergeListsOfMap(targetNodeType.getRequirements(), sourceNodeType.getRequirements()));
723 private InterfaceDefinitionType getInterfaceDefinitionType(String interfaceName, Object interfaceDefTypeObj) {
724 Optional<InterfaceDefinitionType> interfaceDefinitionType = DataModelUtil.convertObjToInterfaceDefinition(
725 interfaceName, interfaceDefTypeObj, InterfaceDefinitionType.class);
726 if (!interfaceDefinitionType.isPresent()) {
727 throw new CoreException(new CreateInterfaceObjectErrorBuilder("InterfaceDefinitionType", interfaceName,
728 "Invalid interface object").build());
730 return interfaceDefinitionType.get();
733 private void combineNodeTypeInterfaceInfo(NodeType sourceNodeType, NodeType targetNodeType) {
734 Optional<Map<String, Object>> interfaceNoMerge = combineInterfaceNoMerge(sourceNodeType, targetNodeType);
735 if (interfaceNoMerge.isPresent()) {
736 targetNodeType.setInterfaces(interfaceNoMerge.get());
739 targetNodeType.setInterfaces(combineInterfaces(sourceNodeType, targetNodeType));
742 private Map<String, Object> combineInterfaces(NodeType sourceNodeType, NodeType targetNodeType) {
743 Map<String, Object> combineInterfaces = new HashMap<>();
744 for (Map.Entry<String, Object> sourceInterfaceDefEntry : sourceNodeType.getInterfaces().entrySet()) {
745 String interfaceName = sourceInterfaceDefEntry.getKey();
746 if (!MapUtils.isEmpty(targetNodeType.getInterfaces()) && targetNodeType.getInterfaces()
747 .containsKey(interfaceName)) {
748 combineInterfaces.put(interfaceName,
749 combineInterfaceDefinition(interfaceName, sourceInterfaceDefEntry.getValue(),
750 targetNodeType.getInterfaces().get(interfaceName)));
752 combineInterfaces.put(sourceInterfaceDefEntry.getKey(), sourceInterfaceDefEntry.getValue());
756 for (Map.Entry<String, Object> targetInterfaceDefEntry : targetNodeType.getInterfaces().entrySet()) {
757 String interfaceName = targetInterfaceDefEntry.getKey();
758 if (!sourceNodeType.getInterfaces().containsKey(interfaceName)) {
759 combineInterfaces.put(targetInterfaceDefEntry.getKey(), targetInterfaceDefEntry.getValue());
763 return combineInterfaces;
766 private Optional<Map<String, Object>> combineInterfaceNoMerge(NodeType sourceNodeType, NodeType targetNodeType) {
767 if ((MapUtils.isEmpty(sourceNodeType.getInterfaces()) && MapUtils.isEmpty(targetNodeType.getInterfaces()))) {
768 return Optional.empty();
771 if (MapUtils.isEmpty(sourceNodeType.getInterfaces()) && !MapUtils.isEmpty(targetNodeType.getInterfaces())) {
772 return Optional.of(targetNodeType.getInterfaces());
775 if (!MapUtils.isEmpty(sourceNodeType.getInterfaces()) && MapUtils.isEmpty(targetNodeType.getInterfaces())) {
776 return Optional.of(sourceNodeType.getInterfaces());
778 return Optional.empty();
782 private Object combineInterfaceDefinition(String interfaceName, Object sourceInterfaceDefType,
783 Object targetInterfaceDefType) {
784 InterfaceDefinitionType sourceInterface = getInterfaceDefinitionType(interfaceName, sourceInterfaceDefType);
785 InterfaceDefinitionType targetInterface = getInterfaceDefinitionType(interfaceName, targetInterfaceDefType);
786 InterfaceDefinitionType combineInterface = new InterfaceDefinitionType();
787 combineInterface.setType(sourceInterface.getType());
788 combineInterface.setInputs(CommonMethods.mergeMaps(targetInterface.getInputs(), sourceInterface.getInputs()));
789 combineInterface.setOperations(
790 CommonMethods.mergeMaps(targetInterface.getOperations(), sourceInterface.getOperations()));
792 return DataModelUtil.convertInterfaceDefinitionTypeToObj(combineInterface).get();
795 private void combineDataTypeInfo(DataType sourceDataType, DataType targetDataType) {
796 targetDataType.setDerived_from(sourceDataType.getDerived_from());
797 targetDataType.setDescription(sourceDataType.getDescription());
798 targetDataType.setVersion(sourceDataType.getVersion());
800 .setProperties(CommonMethods.mergeMaps(targetDataType.getProperties(), sourceDataType.getProperties()));
801 targetDataType.setConstraints(
802 CommonMethods.mergeLists(targetDataType.getConstraints(), sourceDataType.getConstraints()));
806 private void combineCapabilityTypeInfo(CapabilityType sourceCapabilityType, CapabilityType targetCapabilityType) {
808 targetCapabilityType.setAttributes(
809 CommonMethods.mergeMaps(targetCapabilityType.getAttributes(), sourceCapabilityType.getAttributes()));
810 targetCapabilityType.setProperties(
811 CommonMethods.mergeMaps(targetCapabilityType.getProperties(), sourceCapabilityType.getProperties()));
812 targetCapabilityType.setValid_source_types(CommonMethods
813 .mergeLists(targetCapabilityType.getValid_source_types(),
814 sourceCapabilityType.getValid_source_types()));
816 if (StringUtils.isNotEmpty(sourceCapabilityType.getDerived_from())) {
817 targetCapabilityType.setDerived_from(sourceCapabilityType.getDerived_from());
819 if (StringUtils.isNotEmpty(sourceCapabilityType.getDescription())) {
820 targetCapabilityType.setDescription(sourceCapabilityType.getDescription());
822 if (StringUtils.isNotEmpty(sourceCapabilityType.getVersion())) {
823 targetCapabilityType.setVersion(sourceCapabilityType.getVersion());
831 * Create node type according to the input substitution service template, while the substitution
832 * service template can be mappted to this node type, for substitution mapping.
834 * @param substitutionServiceTemplate substitution serivce template
835 * @param nodeTypeDerivedFromValue derived from value for the created node type
836 * @return the node type
839 public NodeType createInitSubstitutionNodeType(ServiceTemplate substitutionServiceTemplate,
840 String nodeTypeDerivedFromValue) {
841 NodeType substitutionNodeType = new NodeType();
842 substitutionNodeType.setDerived_from(nodeTypeDerivedFromValue);
843 substitutionNodeType.setDescription(substitutionServiceTemplate.getDescription());
844 substitutionNodeType.setProperties(manageSubstitutionNodeTypeProperties(substitutionServiceTemplate));
845 substitutionNodeType.setAttributes(manageSubstitutionNodeTypeAttributes(substitutionServiceTemplate));
846 return substitutionNodeType;
850 public Map<String, PropertyDefinition> manageSubstitutionNodeTypeProperties(ServiceTemplate substitutionServiceTemplate) {
851 Map<String, PropertyDefinition> substitutionNodeTypeProperties = new HashMap<>();
852 Map<String, ParameterDefinition> properties = substitutionServiceTemplate.getTopology_template().getInputs();
853 if (properties == null) {
857 PropertyDefinition propertyDefinition;
858 String toscaPropertyName;
859 for (Map.Entry<String, ParameterDefinition> entry : properties.entrySet()) {
860 toscaPropertyName = entry.getKey();
861 propertyDefinition = new PropertyDefinition();
862 ParameterDefinition parameterDefinition =
863 substitutionServiceTemplate.getTopology_template().getInputs().get(toscaPropertyName);
864 propertyDefinition.setType(parameterDefinition.getType());
865 propertyDefinition.setDescription(parameterDefinition.getDescription());
866 propertyDefinition.set_default(parameterDefinition.get_default());
867 if (parameterDefinition.getRequired() != null) {
868 propertyDefinition.setRequired(parameterDefinition.getRequired());
870 if (propertyDefinition.get_default() != null) {
871 propertyDefinition.setRequired(false);
873 if (!CollectionUtils.isEmpty(parameterDefinition.getConstraints())) {
874 propertyDefinition.setConstraints(parameterDefinition.getConstraints());
876 propertyDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
877 if (parameterDefinition.getStatus() != null) {
878 propertyDefinition.setStatus(parameterDefinition.getStatus());
880 substitutionNodeTypeProperties.put(toscaPropertyName, propertyDefinition);
882 return substitutionNodeTypeProperties;
886 private Map<String, AttributeDefinition> manageSubstitutionNodeTypeAttributes(ServiceTemplate substitutionServiceTemplate) {
887 Map<String, AttributeDefinition> substitutionNodeTypeAttributes = new HashMap<>();
888 Map<String, ParameterDefinition> attributes = substitutionServiceTemplate.getTopology_template().getOutputs();
889 if (attributes == null) {
892 AttributeDefinition attributeDefinition;
893 String toscaAttributeName;
895 for (Map.Entry<String, ParameterDefinition> entry : attributes.entrySet()) {
896 attributeDefinition = new AttributeDefinition();
897 toscaAttributeName = entry.getKey();
898 ParameterDefinition parameterDefinition =
899 substitutionServiceTemplate.getTopology_template().getOutputs().get(toscaAttributeName);
900 if (parameterDefinition.getType() != null && !parameterDefinition.getType().isEmpty()) {
901 attributeDefinition.setType(parameterDefinition.getType());
903 attributeDefinition.setType(PropertyType.STRING.getDisplayName());
905 attributeDefinition.setDescription(parameterDefinition.getDescription());
906 attributeDefinition.set_default(parameterDefinition.get_default());
907 attributeDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
908 if (Objects.nonNull(parameterDefinition.getStatus())) {
909 attributeDefinition.setStatus(parameterDefinition.getStatus());
911 substitutionNodeTypeAttributes.put(toscaAttributeName, attributeDefinition);
913 return substitutionNodeTypeAttributes;
917 * Checks if the requirement exists in the node template.
919 * @param nodeTemplate the node template
920 * @param requirementId the requirement id
921 * @param requirementAssignment the requirement assignment
922 * @return true if the requirement already exists and false otherwise
925 public boolean isRequirementExistInNodeTemplate(NodeTemplate nodeTemplate, String requirementId,
926 RequirementAssignment requirementAssignment) {
927 List<Map<String, RequirementAssignment>> nodeTemplateRequirements = nodeTemplate.getRequirements();
928 return nodeTemplateRequirements != null && nodeTemplateRequirements.stream().anyMatch(
929 requirement -> requirement.containsKey(requirementId) && DataModelUtil.compareRequirementAssignment(
930 requirementAssignment, requirement.get(requirementId)));
934 public boolean isTypeOf(InterfaceDefinitionType interfaceDefinition, String interfaceType,
935 ServiceTemplate serviceTemplate, ToscaServiceModel toscaServiceModel) {
936 return isTypeOf(interfaceDefinition, interfaceType, GET_INTERFACE_TYPE_METHOD_NAME, serviceTemplate,
941 public boolean isTypeOf(DefinitionOfDataType parameterDefinition, String dataType, ServiceTemplate serviceTemplate,
942 ToscaServiceModel toscaServiceModel) {
943 return isTypeOf(parameterDefinition, dataType, GET_DATA_TYPE_METHOD_NAME, serviceTemplate, toscaServiceModel);
946 private <T> boolean isTypeOf(T object, String type, String getTypesMethodName, ServiceTemplate serviceTemplate,
947 ToscaServiceModel toscaServiceModel) {
948 if (object == null) {
953 String objectType = (String) object.getClass().getMethod(GET_TYPE_METHOD_NAME).invoke(object);
954 if (Objects.equals(objectType, type)) {
958 Optional<Boolean> typeExistInServiceTemplateHierarchy =
959 isTypeExistInServiceTemplateHierarchy(type, objectType, getTypesMethodName, serviceTemplate,
960 toscaServiceModel, null);
961 return typeExistInServiceTemplateHierarchy.orElseThrow(
962 () -> new CoreException(new ToscaElementTypeNotFoundErrorBuilder(objectType).build()));
964 } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
965 throw new RuntimeException(e);