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.onap.sdc.tosca.datatypes.model.*;
23 import org.onap.sdc.tosca.services.ToscaExtensionYamlUtil;
24 import org.openecomp.core.utilities.CommonMethods;
25 import org.openecomp.sdc.common.errors.CoreException;
26 import org.openecomp.sdc.common.errors.SdcRuntimeException;
27 import org.openecomp.sdc.tosca.datatypes.ToscaElementTypes;
28 import org.openecomp.sdc.tosca.datatypes.ToscaFlatData;
29 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
30 import org.openecomp.sdc.tosca.errors.*;
31 import org.openecomp.sdc.tosca.services.DataModelUtil;
32 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
33 import org.openecomp.sdc.tosca.services.ToscaConstants;
34 import org.openecomp.sdc.tosca.services.ToscaUtil;
36 import java.lang.reflect.InvocationTargetException;
39 public class ToscaAnalyzerServiceImpl implements ToscaAnalyzerService {
41 private final String GET_NODE_TYPE_METHOD_NAME = "getNode_types";
42 private final String GET_DERIVED_FROM_METHOD_NAME = "getDerived_from";
43 private final String GET_TYPE_METHOD_NAME = "getType";
44 private final String GET_DATA_TYPE_METHOD_NAME = "getData_types";
45 private final String GET_INTERFACE_TYPE_METHOD_NAME = "getInterface_types";
46 private final String TOSCA_DOT = "tosca.";
47 private final String DOT_ROOT = ".Root";
50 public List<Map<String, RequirementDefinition>> calculateExposedRequirements(List<Map<String, RequirementDefinition>> nodeTypeRequirementsDefinitionList,
51 Map<String, RequirementAssignment> nodeTemplateRequirementsAssignment) {
53 if (nodeTypeRequirementsDefinitionList == null) {
54 return Collections.emptyList();
56 for (Map.Entry<String, RequirementAssignment> entry : nodeTemplateRequirementsAssignment.entrySet()) {
57 if (entry.getValue().getNode() != null) {
58 Optional<RequirementDefinition> requirementDefinition =
59 DataModelUtil.getRequirementDefinition(nodeTypeRequirementsDefinitionList, entry.getKey());
60 RequirementDefinition cloneRequirementDefinition;
61 if (requirementDefinition.isPresent()) {
62 cloneRequirementDefinition = requirementDefinition.get().clone();
63 updateRequirementDefinition(nodeTypeRequirementsDefinitionList, entry, cloneRequirementDefinition);
66 for (Map<String, RequirementDefinition> nodeTypeRequirementsMap : nodeTypeRequirementsDefinitionList) {
67 updateMinMaxOccurencesForNodeTypeRequirement(entry, nodeTypeRequirementsMap);
71 return nodeTypeRequirementsDefinitionList;
74 private void updateMinMaxOccurencesForNodeTypeRequirement(Map.Entry<String, RequirementAssignment> entry,
75 Map<String, RequirementDefinition> nodeTypeRequirementsMap) {
76 Object max = nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences() != null
77 && nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences().length > 0 ?
78 nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences()[1] : 1;
79 Object min = nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences() != null
80 && nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences().length > 0 ?
81 nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences()[0] : 1;
82 nodeTypeRequirementsMap.get(entry.getKey()).setOccurrences(new Object[] {min, max});
85 private void updateRequirementDefinition(List<Map<String, RequirementDefinition>> nodeTypeRequirementsDefinitionList,
86 Map.Entry<String, RequirementAssignment> entry,
87 RequirementDefinition cloneRequirementDefinition) {
88 if (!evaluateRequirementFulfillment(cloneRequirementDefinition)) {
90 .mergeEntryInList(entry.getKey(), cloneRequirementDefinition, nodeTypeRequirementsDefinitionList);
92 DataModelUtil.removeRequirementsDefinition(nodeTypeRequirementsDefinitionList, entry.getKey());
96 private static boolean evaluateRequirementFulfillment(RequirementDefinition requirementDefinition) {
97 Object[] occurrences = requirementDefinition.getOccurrences();
98 if (occurrences == null) {
99 requirementDefinition.setOccurrences(new Object[] {1, 1});
102 if (occurrences[1].equals(ToscaConstants.UNBOUNDED)) {
106 if (occurrences[1].equals(1)) {
109 occurrences[1] = (Integer) occurrences[1] - 1;
114 public Map<String, CapabilityDefinition> calculateExposedCapabilities(Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition,
115 Map<String, Map<String, RequirementAssignment>> fullFilledRequirementsDefinitionMap) {
117 String capabilityKey;
120 for (Map.Entry<String, Map<String, RequirementAssignment>> entry : fullFilledRequirementsDefinitionMap
122 for (Map.Entry<String, RequirementAssignment> fullFilledEntry : entry.getValue().entrySet()) {
124 capability = fullFilledEntry.getValue().getCapability();
125 node = fullFilledEntry.getValue().getNode();
126 capabilityKey = capability + "_" + node;
127 CapabilityDefinition capabilityDefinition = nodeTypeCapabilitiesDefinition.get(capabilityKey);
128 if (capabilityDefinition != null) {
129 CapabilityDefinition clonedCapabilityDefinition = capabilityDefinition.clone();
130 nodeTypeCapabilitiesDefinition.put(capabilityKey, capabilityDefinition.clone());
131 updateNodeTypeCapabilitiesDefinition(nodeTypeCapabilitiesDefinition, capabilityKey,
132 clonedCapabilityDefinition);
137 Map<String, CapabilityDefinition> exposedCapabilitiesDefinition = new HashMap<>();
138 for (Map.Entry<String, CapabilityDefinition> entry : nodeTypeCapabilitiesDefinition.entrySet()) {
139 exposedCapabilitiesDefinition.put(entry.getKey(), entry.getValue());
141 return exposedCapabilitiesDefinition;
144 private void updateNodeTypeCapabilitiesDefinition(Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition,
145 String capabilityKey,
146 CapabilityDefinition clonedCapabilityDefinition) {
147 if (evaluateCapabilityFulfillment(clonedCapabilityDefinition)) {
148 nodeTypeCapabilitiesDefinition.remove(capabilityKey);
150 nodeTypeCapabilitiesDefinition.put(capabilityKey, clonedCapabilityDefinition);
154 private static boolean evaluateCapabilityFulfillment(CapabilityDefinition capabilityDefinition) {
156 Object[] occurrences = capabilityDefinition.getOccurrences();
157 if (occurrences == null) {
158 capabilityDefinition.setOccurrences(new Object[] {1, ToscaConstants.UNBOUNDED});
161 if (occurrences[1].equals(ToscaConstants.UNBOUNDED)) {
165 if (occurrences[1].equals(1)) {
168 occurrences[1] = (Integer) occurrences[1] - 1;
173 node template with type equal to node type or derived from node type
176 public Map<String, NodeTemplate> getNodeTemplatesByType(ServiceTemplate serviceTemplate, String nodeType,
177 ToscaServiceModel toscaServiceModel) {
178 Map<String, NodeTemplate> nodeTemplates = new HashMap<>();
180 if (Objects.nonNull(serviceTemplate.getTopology_template()) && MapUtils.isNotEmpty(
181 serviceTemplate.getTopology_template().getNode_templates())) {
182 for (Map.Entry<String, NodeTemplate> nodeTemplateEntry : serviceTemplate.getTopology_template()
183 .getNode_templates().entrySet()) {
184 if (isTypeOf(nodeTemplateEntry.getValue(), nodeType, serviceTemplate, toscaServiceModel)) {
185 nodeTemplates.put(nodeTemplateEntry.getKey(), nodeTemplateEntry.getValue());
190 return nodeTemplates;
194 public Optional<NodeType> fetchNodeType(String nodeTypeKey, Collection<ServiceTemplate> serviceTemplates) {
195 Optional<Map<String, NodeType>> nodeTypeMap = serviceTemplates.stream().map(ServiceTemplate::getNode_types)
196 .filter(nodeTypes -> Objects.nonNull(nodeTypes)
201 return nodeTypeMap.map(stringNodeTypeMap -> stringNodeTypeMap.get(nodeTypeKey));
205 public boolean isTypeOf(NodeTemplate nodeTemplate, String nodeType, ServiceTemplate serviceTemplate,
206 ToscaServiceModel toscaServiceModel) {
207 return isTypeOf(nodeTemplate, nodeType, GET_NODE_TYPE_METHOD_NAME, serviceTemplate, toscaServiceModel);
211 public List<RequirementAssignment> getRequirements(NodeTemplate nodeTemplate, String requirementId) {
212 List<RequirementAssignment> requirements = new ArrayList<>();
213 List<Map<String, RequirementAssignment>> requirementList = nodeTemplate.getRequirements();
214 if (requirementList != null) {
215 requirementList.stream().filter(reqMap -> reqMap.get(requirementId) != null).forEach(reqMap -> {
216 ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
217 RequirementAssignment reqAssignment = toscaExtensionYamlUtil.yamlToObject(
218 toscaExtensionYamlUtil.objectToYaml(reqMap.get(requirementId)), RequirementAssignment.class);
219 requirements.add(reqAssignment);
226 public Optional<NodeTemplate> getNodeTemplateById(ServiceTemplate serviceTemplate, String nodeTemplateId) {
227 if ((serviceTemplate.getTopology_template() != null) && (serviceTemplate.getTopology_template()
228 .getNode_templates() != null)
229 && (serviceTemplate.getTopology_template().getNode_templates().get(nodeTemplateId) != null)) {
230 return Optional.of(serviceTemplate.getTopology_template().getNode_templates().get(nodeTemplateId));
232 return Optional.empty();
236 public Optional<String> getSubstituteServiceTemplateName(String substituteNodeTemplateId,
237 NodeTemplate substitutableNodeTemplate) {
238 if (!isSubstitutableNodeTemplate(substitutableNodeTemplate)) {
239 return Optional.empty();
242 if (substitutableNodeTemplate.getProperties() != null &&
243 substitutableNodeTemplate.getProperties().get(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME)
245 Object serviceTemplateFilter =
246 substitutableNodeTemplate.getProperties().get(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME);
247 if (serviceTemplateFilter instanceof Map) {
248 Object substituteServiceTemplate =
249 ((Map) serviceTemplateFilter).get(ToscaConstants.SUBSTITUTE_SERVICE_TEMPLATE_PROPERTY_NAME);
250 handleNoSubstituteServiceTemplate(substituteNodeTemplateId, substituteServiceTemplate);
251 return Optional.of(substituteServiceTemplate.toString());
254 throw new CoreException(new ToscaInvalidSubstituteNodeTemplatePropertiesErrorBuilder(substituteNodeTemplateId)
258 private void handleNoSubstituteServiceTemplate(String substituteNodeTemplateId, Object substituteServiceTemplate) {
259 if (substituteServiceTemplate == null) {
260 throw new CoreException(new ToscaInvalidSubstituteNodeTemplatePropertiesErrorBuilder(substituteNodeTemplateId)
266 public Map<String, NodeTemplate> getSubstitutableNodeTemplates(ServiceTemplate serviceTemplate) {
267 Map<String, NodeTemplate> substitutableNodeTemplates = new HashMap<>();
269 if (serviceTemplate == null || serviceTemplate.getTopology_template() == null
270 || serviceTemplate.getTopology_template().getNode_templates() == null) {
271 return substitutableNodeTemplates;
274 Map<String, NodeTemplate> nodeTemplates = serviceTemplate.getTopology_template().getNode_templates();
275 for (Map.Entry<String, NodeTemplate> entry : nodeTemplates.entrySet()) {
276 String nodeTemplateId = entry.getKey();
277 NodeTemplate nodeTemplate = entry.getValue();
278 if (isSubstitutableNodeTemplate(nodeTemplate)) {
279 substitutableNodeTemplates.put(nodeTemplateId, nodeTemplate);
283 return substitutableNodeTemplates;
287 public Optional<Map.Entry<String, NodeTemplate>> getSubstitutionMappedNodeTemplateByExposedReq(String substituteServiceTemplateFileName,
288 ServiceTemplate substituteServiceTemplate,
289 String requirementId) {
290 if (isSubstitutionServiceTemplate(substituteServiceTemplateFileName, substituteServiceTemplate)) {
291 Map<String, List<String>> substitutionMappingRequirements =
292 substituteServiceTemplate.getTopology_template().getSubstitution_mappings().getRequirements();
293 if (substitutionMappingRequirements != null) {
294 List<String> requirementMapping = substitutionMappingRequirements.get(requirementId);
295 if (requirementMapping != null && !requirementMapping.isEmpty()) {
296 String mappedNodeTemplateId = requirementMapping.get(0);
297 Optional<NodeTemplate> mappedNodeTemplate =
298 getNodeTemplateById(substituteServiceTemplate, mappedNodeTemplateId);
299 mappedNodeTemplate.orElseThrow(
300 () -> new CoreException(new ToscaInvalidEntryNotFoundErrorBuilder("Node Template",
301 mappedNodeTemplateId)
303 Map.Entry<String, NodeTemplate> mappedNodeTemplateEntry = new Map.Entry<String, NodeTemplate>() {
305 public String getKey() {
306 return mappedNodeTemplateId;
310 public NodeTemplate getValue() {
311 return mappedNodeTemplate.get();
315 public NodeTemplate setValue(NodeTemplate value) {
319 return Optional.of(mappedNodeTemplateEntry);
323 return Optional.empty();
327 match only for the input which is not null
330 public boolean isDesiredRequirementAssignment(RequirementAssignment requirementAssignment, String capability,
331 String node, String relationship) {
332 if (isSameCapability(requirementAssignment, capability)) {
336 if (isSameRequirement(requirementAssignment, node)) {
340 if (isSameRelationship(requirementAssignment, relationship)) {
344 return !(capability == null && node == null && relationship == null);
348 private boolean isSameRelationship(RequirementAssignment requirementAssignment, String relationship) {
349 return relationship != null && (requirementAssignment.getRelationship() == null || !requirementAssignment
351 .equals(relationship));
354 private boolean isSameRequirement(RequirementAssignment requirementAssignment, String node) {
355 return node != null && (requirementAssignment.getNode() == null || !requirementAssignment.getNode()
359 private boolean isSameCapability(RequirementAssignment requirementAssignment, String capability) {
360 return capability != null && (requirementAssignment.getCapability() == null || !requirementAssignment
362 .equals(capability));
366 public ToscaFlatData getFlatEntity(ToscaElementTypes elementType, String typeId, ServiceTemplate serviceTemplate,
367 ToscaServiceModel toscaModel) {
368 ToscaFlatData flatData = new ToscaFlatData();
369 flatData.setElementType(elementType);
371 switch (elementType) {
372 case CAPABILITY_TYPE:
373 flatData.setFlatEntity(new CapabilityType());
376 flatData.setFlatEntity(new NodeType());
379 flatData.setFlatEntity(new DataType());
382 throw new RuntimeException("Entity[" + elementType + "] id[" + typeId + "] flat not supported");
385 boolean isEntityFound =
386 scanAnFlatEntity(elementType, typeId, flatData, serviceTemplate, toscaModel, new ArrayList<>(), 0);
387 if (!isEntityFound) {
388 throw new CoreException(new ToscaElementTypeNotFoundErrorBuilder(typeId).build());
395 public boolean isSubstitutableNodeTemplate(NodeTemplate nodeTemplate) {
396 return nodeTemplate.getDirectives() != null && nodeTemplate.getDirectives().contains(
397 ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
400 private <T> Optional<Boolean> isTypeExistInServiceTemplateHierarchy(String typeToMatch, String typeToSearch,
401 String getTypesMethodName,
402 ServiceTemplate serviceTemplate,
403 ToscaServiceModel toscaServiceModel,
404 Set<String> analyzedImportFiles)
405 throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
406 Map<String, T> searchableTypes =
407 (Map<String, T>) serviceTemplate.getClass().getMethod(getTypesMethodName).invoke(serviceTemplate);
409 if (!MapUtils.isEmpty(searchableTypes)) {
410 T typeObject = searchableTypes.get(typeToSearch);
411 if (Objects.nonNull(typeObject)) {
412 String derivedFromTypeVal =
413 (String) typeObject.getClass().getMethod(GET_DERIVED_FROM_METHOD_NAME).invoke(typeObject);
414 if (Objects.equals(derivedFromTypeVal, typeToMatch)) {
415 return Optional.of(true);
416 } else if (Objects.isNull(derivedFromTypeVal) || isTypeIsToscaRoot(derivedFromTypeVal)) {
417 return Optional.of(false);
419 return isTypeExistInServiceTemplateHierarchy(typeToMatch, derivedFromTypeVal, getTypesMethodName,
420 serviceTemplate, toscaServiceModel, null);
423 return isTypeExistInImports(typeToMatch, typeToSearch, getTypesMethodName, serviceTemplate,
424 toscaServiceModel, analyzedImportFiles);
427 return isTypeExistInImports(typeToMatch, typeToSearch, getTypesMethodName, serviceTemplate, toscaServiceModel,
428 analyzedImportFiles);
431 private Optional<Boolean> isTypeExistInImports(String typeToMatch, String typeToSearch, String getTypesMethodName,
432 ServiceTemplate serviceTemplate,
433 ToscaServiceModel toscaServiceModel, Set<String> filesScanned)
434 throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
435 List<Map<String, Import>> imports = serviceTemplate.getImports();
436 if (CollectionUtils.isEmpty(imports)) {
437 return Optional.empty();
440 Set<String> createdFilesScanned = createFilesScannedSet(filesScanned);
442 for (Map<String, Import> map : imports) {
443 ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
444 Import anImport = toscaExtensionYamlUtil
445 .yamlToObject(toscaExtensionYamlUtil.objectToYaml(map.values().iterator().next()),
447 handleImportWithNoFileEntry(anImport);
448 String importFile = anImport.getFile();
449 ServiceTemplate template = toscaServiceModel.getServiceTemplates().get(fetchFileNameForImport(importFile,
450 serviceTemplate.getMetadata() == null ? null : serviceTemplate.getMetadata().get("filename")));
451 if (Objects.isNull(template) || createdFilesScanned
452 .contains(ToscaUtil.getServiceTemplateFileName(template))) {
455 createdFilesScanned.add(ToscaUtil.getServiceTemplateFileName(template));
457 Optional<Boolean> typeExistInServiceTemplateHierarchy =
458 isTypeExistInServiceTemplateHierarchy(typeToMatch, typeToSearch, getTypesMethodName, template,
459 toscaServiceModel, createdFilesScanned);
460 if (typeExistInServiceTemplateHierarchy.isPresent() && (typeExistInServiceTemplateHierarchy.get())) {
461 createdFilesScanned.clear();
462 return Optional.of(true);
466 return Optional.of(false);
469 private void handleImportWithNoFileEntry(Import anImport) {
470 if (Objects.isNull(anImport) || Objects.isNull(anImport.getFile())) {
471 throw new RuntimeException("import without file entry");
475 private Set<String> createFilesScannedSet(Set<String> filesScanned) {
476 Set<String> retFileScanned = filesScanned;
477 if (Objects.isNull(retFileScanned)) {
478 retFileScanned = new HashSet<>();
480 return retFileScanned;
483 private boolean isTypeIsToscaRoot(String type) {
484 return (type.contains(TOSCA_DOT) && type.contains(DOT_ROOT));
487 private boolean isSubstitutionServiceTemplate(String substituteServiceTemplateFileName,
488 ServiceTemplate substituteServiceTemplate) {
489 if (substituteServiceTemplate != null && substituteServiceTemplate.getTopology_template() != null
490 && substituteServiceTemplate.getTopology_template().getSubstitution_mappings() != null) {
491 if (substituteServiceTemplate.getTopology_template().getSubstitution_mappings().getNode_type() == null) {
492 throw new CoreException(new ToscaInvalidSubstitutionServiceTemplateErrorBuilder(substituteServiceTemplateFileName)
501 private boolean scanAnFlatEntity(ToscaElementTypes elementType, String typeId, ToscaFlatData flatData,
502 ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel,
503 List<String> filesScanned, int rootScanStartInx) {
506 boolean entityFound =
507 enrichEntityFromCurrentServiceTemplate(elementType, typeId, flatData, serviceTemplate, toscaModel,
508 filesScanned, rootScanStartInx);
510 List<Map<String, Import>> imports = serviceTemplate.getImports();
511 if (CollectionUtils.isEmpty(imports)) {
514 boolean found = false;
515 for (Map<String, Import> importMap : imports) {
519 found = isFlatEntity(importMap, flatData, serviceTemplate, filesScanned, toscaModel, elementType,
527 private boolean isFlatEntity(Map<String, Import> importMap, ToscaFlatData flatData, ServiceTemplate serviceTemplate,
528 List<String> filesScanned, ToscaServiceModel toscaModel,
529 ToscaElementTypes elementType, String typeId) {
530 boolean found = false;
531 ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
532 for (Object importObject : importMap.values()) {
533 Import importServiceTemplate = toscaExtensionYamlUtil
534 .yamlToObject(toscaExtensionYamlUtil.objectToYaml(importObject),
536 String fileName = fetchFileNameForImport(importServiceTemplate.getFile(),
537 serviceTemplate.getMetadata() == null ? null : serviceTemplate.getMetadata().get("filename"));
538 if (filesScanned.contains(fileName)) {
541 filesScanned.add(fileName);
543 ServiceTemplate template = toscaModel.getServiceTemplates().get(fileName);
544 if (Objects.isNull(template)) {
545 throw new CoreException(new ToscaFileNotFoundErrorBuilder(fileName).build());
547 found = scanAnFlatEntity(elementType, typeId, flatData, template, toscaModel, filesScanned,
548 filesScanned.size());
553 private String fetchFileNameForImport(String importServiceTemplateFile, String currentMetadatafileName) {
554 if (importServiceTemplateFile.contains("../")) {
555 return importServiceTemplateFile.replace("../", "");
556 } else if (currentMetadatafileName != null && currentMetadatafileName.indexOf('/') != -1) {
557 return currentMetadatafileName.substring(0, currentMetadatafileName.indexOf('/')) + "/"
558 + importServiceTemplateFile;
560 return importServiceTemplateFile;
565 private boolean enrichEntityFromCurrentServiceTemplate(ToscaElementTypes elementType, String typeId,
566 ToscaFlatData flatData,
567 ServiceTemplate serviceTemplate,
568 ToscaServiceModel toscaModel,
569 List<String> filesScanned, int rootScanStartInx) {
570 switch (elementType) {
571 case CAPABILITY_TYPE:
572 if (enrichCapabilityType(elementType, typeId, flatData, serviceTemplate, toscaModel, filesScanned,
578 if (enrichNodeTypeInfo(elementType, typeId, flatData, serviceTemplate, toscaModel, filesScanned,
584 if (enrichDataTypeInfo(elementType, typeId, flatData, serviceTemplate, toscaModel, filesScanned,
590 throw new RuntimeException("Entity[" + elementType + "] id[" + typeId + "] flat not supported");
598 private boolean enrichNodeTypeInfo(ToscaElementTypes elementType, String typeId, ToscaFlatData flatData,
599 ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel,
600 List<String> filesScanned, int rootScanStartInx) {
602 if (serviceTemplate.getNode_types() != null && serviceTemplate.getNode_types().containsKey(typeId)) {
604 filesScanned.clear();
605 flatData.addInheritanceHierarchyType(typeId);
606 NodeType targetNodeType = (NodeType) flatData.getFlatEntity();
607 NodeType sourceNodeType = serviceTemplate.getNode_types().get(typeId);
608 derivedFrom = sourceNodeType.getDerived_from();
609 if (derivedFrom != null) {
610 boolean isEntityFound =
611 scanAnFlatEntity(elementType, derivedFrom, flatData, serviceTemplate, toscaModel, filesScanned,
613 if (!isEntityFound) {
614 throw new CoreException(new ToscaElementTypeNotFoundErrorBuilder(typeId).build());
617 combineNodeTypeInfo(sourceNodeType, targetNodeType);
624 private boolean enrichDataTypeInfo(ToscaElementTypes elementType, String typeId, ToscaFlatData flatData,
625 ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel,
626 List<String> filesScanned, int rootScanStartInx) {
628 if (serviceTemplate.getData_types() != null && serviceTemplate.getData_types().containsKey(typeId)) {
630 filesScanned.clear();
631 flatData.addInheritanceHierarchyType(typeId);
632 DataType targetDataType = (DataType) flatData.getFlatEntity();
633 DataType sourceDataType = serviceTemplate.getData_types().get(typeId);
634 derivedFrom = sourceDataType.getDerived_from();
635 if (derivedFrom != null && !isPrimitiveType(derivedFrom)) {
636 boolean isEntityFound =
637 scanAnFlatEntity(elementType, derivedFrom, flatData, serviceTemplate, toscaModel, filesScanned,
639 if (!isEntityFound) {
640 throw new CoreException(new ToscaElementTypeNotFoundErrorBuilder(typeId).build());
643 combineDataTypeInfo(sourceDataType, targetDataType);
650 private static boolean isPrimitiveType(String toscaType) {
651 return (toscaType.equals(PropertyType.STRING.getDisplayName()) || toscaType.equals(PropertyType.INTEGER
653 || toscaType.equals(PropertyType.FLOAT.getDisplayName()));
656 private boolean enrichCapabilityType(ToscaElementTypes elementType, String typeId, ToscaFlatData flatData,
657 ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel,
658 List<String> filesScanned, int rootScanStartInx) {
660 if (serviceTemplate.getCapability_types() != null && serviceTemplate.getCapability_types()
661 .containsKey(typeId)) {
663 filesScanned.clear();
664 flatData.addInheritanceHierarchyType(typeId);
665 CapabilityType targetCapabilityType = (CapabilityType) flatData.getFlatEntity();
666 CapabilityType sourceCapabilityType = serviceTemplate.getCapability_types().get(typeId);
667 derivedFrom = sourceCapabilityType.getDerived_from();
668 if (derivedFrom != null) {
669 boolean isEntityFound =
670 scanAnFlatEntity(elementType, derivedFrom, flatData, serviceTemplate, toscaModel, filesScanned,
672 if (!isEntityFound) {
673 throw new CoreException(new ToscaElementTypeNotFoundErrorBuilder(typeId).build());
676 combineCapabilityTypeInfo(sourceCapabilityType, targetCapabilityType);
683 private void combineNodeTypeInfo(NodeType sourceNodeType, NodeType targetNodeType) {
684 targetNodeType.setDerived_from(sourceNodeType.getDerived_from());
685 targetNodeType.setDescription(sourceNodeType.getDescription());
686 targetNodeType.setVersion(sourceNodeType.getVersion());
688 .setProperties(CommonMethods.mergeMaps(targetNodeType.getProperties(), sourceNodeType.getProperties()));
689 combineNodeTypeInterfaceInfo(sourceNodeType, targetNodeType);
691 .setArtifacts(CommonMethods.mergeMaps(targetNodeType.getArtifacts(), sourceNodeType.getArtifacts()));
693 .setAttributes(CommonMethods.mergeMaps(targetNodeType.getAttributes(), sourceNodeType.getAttributes()));
694 targetNodeType.setCapabilities(
695 CommonMethods.mergeMaps(targetNodeType.getCapabilities(), sourceNodeType.getCapabilities()));
696 targetNodeType.setRequirements(
697 CommonMethods.mergeListsOfMap(targetNodeType.getRequirements(), sourceNodeType.getRequirements()));
701 private InterfaceDefinitionType getInterfaceDefinitionType(String interfaceName, Object interfaceDefTypeObj) {
702 Optional<InterfaceDefinitionType> interfaceDefinitionType = DataModelUtil.convertObjToInterfaceDefinition(
703 interfaceName, interfaceDefTypeObj, InterfaceDefinitionType.class);
704 if (!interfaceDefinitionType.isPresent()) {
705 throw new CoreException(new CreateInterfaceObjectErrorBuilder("InterfaceDefinitionType", interfaceName,
706 "Invalid interface object").build());
708 return interfaceDefinitionType.get();
711 private void combineNodeTypeInterfaceInfo(NodeType sourceNodeType, NodeType targetNodeType) {
712 Optional<Map<String, Object>> interfaceNoMerge = combineInterfaceNoMerge(sourceNodeType, targetNodeType);
713 if (interfaceNoMerge.isPresent()) {
714 targetNodeType.setInterfaces(interfaceNoMerge.get());
717 targetNodeType.setInterfaces(combineInterfaces(sourceNodeType, targetNodeType));
720 private Map<String, Object> combineInterfaces(NodeType sourceNodeType, NodeType targetNodeType) {
721 Map<String, Object> combineInterfaces = new HashMap<>();
722 for (Map.Entry<String, Object> sourceInterfaceDefEntry : sourceNodeType.getInterfaces().entrySet()) {
723 String interfaceName = sourceInterfaceDefEntry.getKey();
724 if (!MapUtils.isEmpty(targetNodeType.getInterfaces()) && targetNodeType.getInterfaces()
725 .containsKey(interfaceName)) {
726 combineInterfaces.put(interfaceName,
727 combineInterfaceDefinition(interfaceName, sourceInterfaceDefEntry.getValue(),
728 targetNodeType.getInterfaces().get(interfaceName)));
730 combineInterfaces.put(sourceInterfaceDefEntry.getKey(), sourceInterfaceDefEntry.getValue());
734 for (Map.Entry<String, Object> targetInterfaceDefEntry : targetNodeType.getInterfaces().entrySet()) {
735 String interfaceName = targetInterfaceDefEntry.getKey();
736 if (!sourceNodeType.getInterfaces().containsKey(interfaceName)) {
737 combineInterfaces.put(targetInterfaceDefEntry.getKey(), targetInterfaceDefEntry.getValue());
741 return combineInterfaces;
744 private Optional<Map<String, Object>> combineInterfaceNoMerge(NodeType sourceNodeType, NodeType targetNodeType) {
745 if ((MapUtils.isEmpty(sourceNodeType.getInterfaces()) && MapUtils.isEmpty(targetNodeType.getInterfaces()))) {
746 return Optional.empty();
749 if (MapUtils.isEmpty(sourceNodeType.getInterfaces()) && !MapUtils.isEmpty(targetNodeType.getInterfaces())) {
750 return Optional.of(targetNodeType.getInterfaces());
753 if (!MapUtils.isEmpty(sourceNodeType.getInterfaces()) && MapUtils.isEmpty(targetNodeType.getInterfaces())) {
754 return Optional.of(sourceNodeType.getInterfaces());
756 return Optional.empty();
760 private Object combineInterfaceDefinition(String interfaceName, Object sourceInterfaceDefType,
761 Object targetInterfaceDefType) {
762 InterfaceDefinitionType sourceInterface = getInterfaceDefinitionType(interfaceName, sourceInterfaceDefType);
763 InterfaceDefinitionType targetInterface = getInterfaceDefinitionType(interfaceName, targetInterfaceDefType);
764 InterfaceDefinitionType combineInterface = new InterfaceDefinitionType();
765 combineInterface.setType(sourceInterface.getType());
766 combineInterface.setInputs(CommonMethods.mergeMaps(targetInterface.getInputs(), sourceInterface.getInputs()));
767 combineInterface.setOperations(
768 CommonMethods.mergeMaps(targetInterface.getOperations(), sourceInterface.getOperations()));
770 Optional<Object> interfaceDefObject = DataModelUtil.convertInterfaceDefinitionTypeToObj(combineInterface);
771 if( !interfaceDefObject.isPresent()){
772 throw new SdcRuntimeException("Illegal Statement");
774 return interfaceDefObject.get();
777 private void combineDataTypeInfo(DataType sourceDataType, DataType targetDataType) {
778 targetDataType.setDerived_from(sourceDataType.getDerived_from());
779 targetDataType.setDescription(sourceDataType.getDescription());
780 targetDataType.setVersion(sourceDataType.getVersion());
782 .setProperties(CommonMethods.mergeMaps(targetDataType.getProperties(), sourceDataType.getProperties()));
783 targetDataType.setConstraints(
784 CommonMethods.mergeLists(targetDataType.getConstraints(), sourceDataType.getConstraints()));
788 private void combineCapabilityTypeInfo(CapabilityType sourceCapabilityType, CapabilityType targetCapabilityType) {
790 targetCapabilityType.setAttributes(
791 CommonMethods.mergeMaps(targetCapabilityType.getAttributes(), sourceCapabilityType.getAttributes()));
792 targetCapabilityType.setProperties(
793 CommonMethods.mergeMaps(targetCapabilityType.getProperties(), sourceCapabilityType.getProperties()));
794 targetCapabilityType.setValid_source_types(CommonMethods
795 .mergeLists(targetCapabilityType.getValid_source_types(),
796 sourceCapabilityType.getValid_source_types()));
798 if (StringUtils.isNotEmpty(sourceCapabilityType.getDerived_from())) {
799 targetCapabilityType.setDerived_from(sourceCapabilityType.getDerived_from());
801 if (StringUtils.isNotEmpty(sourceCapabilityType.getDescription())) {
802 targetCapabilityType.setDescription(sourceCapabilityType.getDescription());
804 if (StringUtils.isNotEmpty(sourceCapabilityType.getVersion())) {
805 targetCapabilityType.setVersion(sourceCapabilityType.getVersion());
813 * Create node type according to the input substitution service template, while the substitution
814 * service template can be mappted to this node type, for substitution mapping.
816 * @param substitutionServiceTemplate substitution serivce template
817 * @param nodeTypeDerivedFromValue derived from value for the created node type
818 * @return the node type
821 public NodeType createInitSubstitutionNodeType(ServiceTemplate substitutionServiceTemplate,
822 String nodeTypeDerivedFromValue) {
823 NodeType substitutionNodeType = new NodeType();
824 substitutionNodeType.setDerived_from(nodeTypeDerivedFromValue);
825 substitutionNodeType.setDescription(substitutionServiceTemplate.getDescription());
826 substitutionNodeType.setProperties(manageSubstitutionNodeTypeProperties(substitutionServiceTemplate));
827 substitutionNodeType.setAttributes(manageSubstitutionNodeTypeAttributes(substitutionServiceTemplate));
828 return substitutionNodeType;
832 public Map<String, PropertyDefinition> manageSubstitutionNodeTypeProperties(ServiceTemplate substitutionServiceTemplate) {
833 Map<String, PropertyDefinition> substitutionNodeTypeProperties = new HashMap<>();
834 Map<String, ParameterDefinition> properties = substitutionServiceTemplate.getTopology_template().getInputs();
835 if (properties == null) {
839 PropertyDefinition propertyDefinition;
840 String toscaPropertyName;
841 for (Map.Entry<String, ParameterDefinition> entry : properties.entrySet()) {
842 toscaPropertyName = entry.getKey();
843 propertyDefinition = new PropertyDefinition();
844 ParameterDefinition parameterDefinition =
845 substitutionServiceTemplate.getTopology_template().getInputs().get(toscaPropertyName);
846 propertyDefinition.setType(parameterDefinition.getType());
847 propertyDefinition.setDescription(parameterDefinition.getDescription());
848 propertyDefinition.set_default(parameterDefinition.get_default());
849 if (parameterDefinition.getRequired() != null) {
850 propertyDefinition.setRequired(parameterDefinition.getRequired());
852 if (propertyDefinition.get_default() != null) {
853 propertyDefinition.setRequired(false);
855 if (!CollectionUtils.isEmpty(parameterDefinition.getConstraints())) {
856 propertyDefinition.setConstraints(parameterDefinition.getConstraints());
858 propertyDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
859 if (parameterDefinition.getStatus() != null) {
860 propertyDefinition.setStatus(parameterDefinition.getStatus());
862 substitutionNodeTypeProperties.put(toscaPropertyName, propertyDefinition);
864 return substitutionNodeTypeProperties;
868 private Map<String, AttributeDefinition> manageSubstitutionNodeTypeAttributes(ServiceTemplate substitutionServiceTemplate) {
869 Map<String, AttributeDefinition> substitutionNodeTypeAttributes = new HashMap<>();
870 Map<String, ParameterDefinition> attributes = substitutionServiceTemplate.getTopology_template().getOutputs();
871 if (attributes == null) {
874 AttributeDefinition attributeDefinition;
875 String toscaAttributeName;
877 for (Map.Entry<String, ParameterDefinition> entry : attributes.entrySet()) {
878 attributeDefinition = new AttributeDefinition();
879 toscaAttributeName = entry.getKey();
880 ParameterDefinition parameterDefinition =
881 substitutionServiceTemplate.getTopology_template().getOutputs().get(toscaAttributeName);
882 if (parameterDefinition.getType() != null && !parameterDefinition.getType().isEmpty()) {
883 attributeDefinition.setType(parameterDefinition.getType());
885 attributeDefinition.setType(PropertyType.STRING.getDisplayName());
887 attributeDefinition.setDescription(parameterDefinition.getDescription());
888 attributeDefinition.set_default(parameterDefinition.get_default());
889 attributeDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
890 if (Objects.nonNull(parameterDefinition.getStatus())) {
891 attributeDefinition.setStatus(parameterDefinition.getStatus());
893 substitutionNodeTypeAttributes.put(toscaAttributeName, attributeDefinition);
895 return substitutionNodeTypeAttributes;
899 * Checks if the requirement exists in the node template.
901 * @param nodeTemplate the node template
902 * @param requirementId the requirement id
903 * @param requirementAssignment the requirement assignment
904 * @return true if the requirement already exists and false otherwise
907 public boolean isRequirementExistInNodeTemplate(NodeTemplate nodeTemplate, String requirementId,
908 RequirementAssignment requirementAssignment) {
909 List<Map<String, RequirementAssignment>> nodeTemplateRequirements = nodeTemplate.getRequirements();
910 return nodeTemplateRequirements != null && nodeTemplateRequirements.stream().anyMatch(
911 requirement -> requirement.containsKey(requirementId) && DataModelUtil.compareRequirementAssignment(
912 requirementAssignment, requirement.get(requirementId)));
916 public boolean isTypeOf(InterfaceDefinitionType interfaceDefinition, String interfaceType,
917 ServiceTemplate serviceTemplate, ToscaServiceModel toscaServiceModel) {
918 return isTypeOf(interfaceDefinition, interfaceType, GET_INTERFACE_TYPE_METHOD_NAME, serviceTemplate,
923 public boolean isTypeOf(DefinitionOfDataType parameterDefinition, String dataType, ServiceTemplate serviceTemplate,
924 ToscaServiceModel toscaServiceModel) {
925 return isTypeOf(parameterDefinition, dataType, GET_DATA_TYPE_METHOD_NAME, serviceTemplate, toscaServiceModel);
928 private <T> boolean isTypeOf(T object, String type, String getTypesMethodName, ServiceTemplate serviceTemplate,
929 ToscaServiceModel toscaServiceModel) {
930 if (object == null) {
935 String objectType = (String) object.getClass().getMethod(GET_TYPE_METHOD_NAME).invoke(object);
936 if (Objects.equals(objectType, type)) {
940 Optional<Boolean> typeExistInServiceTemplateHierarchy =
941 isTypeExistInServiceTemplateHierarchy(type, objectType, getTypesMethodName, serviceTemplate,
942 toscaServiceModel, null);
943 return typeExistInServiceTemplateHierarchy.orElseThrow(
944 () -> new CoreException(new ToscaElementTypeNotFoundErrorBuilder(objectType).build()));
946 } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
947 throw new RuntimeException(e);