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 static final String GET_NODE_TYPE_METHOD_NAME = "getNode_types";
42 private static final String GET_DERIVED_FROM_METHOD_NAME = "getDerived_from";
43 private static final String GET_TYPE_METHOD_NAME = "getType";
44 private static final String GET_DATA_TYPE_METHOD_NAME = "getData_types";
45 private static final String GET_INTERFACE_TYPE_METHOD_NAME = "getInterface_types";
46 private static final String GET_CAPABILITY_TYPE_METHOD_NAME = "getCapability_types";
47 private static final String TOSCA_DOT = "tosca.";
48 private static final String DOT_ROOT = ".Root";
51 public List<Map<String, RequirementDefinition>> calculateExposedRequirements(List<Map<String, RequirementDefinition>> nodeTypeRequirementsDefinitionList,
52 Map<String, RequirementAssignment> nodeTemplateRequirementsAssignment) {
54 if (nodeTypeRequirementsDefinitionList == null) {
55 return Collections.emptyList();
57 for (Map.Entry<String, RequirementAssignment> entry : nodeTemplateRequirementsAssignment.entrySet()) {
58 if (entry.getValue().getNode() != null) {
59 Optional<RequirementDefinition> requirementDefinition =
60 DataModelUtil.getRequirementDefinition(nodeTypeRequirementsDefinitionList, entry.getKey());
61 RequirementDefinition cloneRequirementDefinition;
62 if (requirementDefinition.isPresent()) {
63 cloneRequirementDefinition = requirementDefinition.get().clone();
64 updateRequirementDefinition(nodeTypeRequirementsDefinitionList, entry, cloneRequirementDefinition);
67 for (Map<String, RequirementDefinition> nodeTypeRequirementsMap : nodeTypeRequirementsDefinitionList) {
68 updateMinMaxOccurencesForNodeTypeRequirement(entry, nodeTypeRequirementsMap);
72 return nodeTypeRequirementsDefinitionList;
75 private void updateMinMaxOccurencesForNodeTypeRequirement(Map.Entry<String, RequirementAssignment> entry,
76 Map<String, RequirementDefinition> nodeTypeRequirementsMap) {
77 Object max = nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences() != null
78 && nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences().length > 0 ?
79 nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences()[1] : 1;
80 Object min = nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences() != null
81 && nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences().length > 0 ?
82 nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences()[0] : 1;
83 nodeTypeRequirementsMap.get(entry.getKey()).setOccurrences(new Object[] {min, max});
86 private void updateRequirementDefinition(List<Map<String, RequirementDefinition>> nodeTypeRequirementsDefinitionList,
87 Map.Entry<String, RequirementAssignment> entry,
88 RequirementDefinition cloneRequirementDefinition) {
89 if (!evaluateRequirementFulfillment(cloneRequirementDefinition)) {
91 .mergeEntryInList(entry.getKey(), cloneRequirementDefinition, nodeTypeRequirementsDefinitionList);
93 DataModelUtil.removeRequirementsDefinition(nodeTypeRequirementsDefinitionList, entry.getKey());
97 private static boolean evaluateRequirementFulfillment(RequirementDefinition requirementDefinition) {
98 Object[] occurrences = requirementDefinition.getOccurrences();
99 if (occurrences == null) {
100 requirementDefinition.setOccurrences(new Object[] {1, 1});
103 if (occurrences[1].equals(ToscaConstants.UNBOUNDED)) {
107 if (occurrences[1].equals(1)) {
110 occurrences[1] = (Integer) occurrences[1] - 1;
115 public Map<String, CapabilityDefinition> calculateExposedCapabilities(Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition,
116 Map<String, Map<String, RequirementAssignment>> fullFilledRequirementsDefinitionMap) {
118 String capabilityKey;
121 for (Map.Entry<String, Map<String, RequirementAssignment>> entry : fullFilledRequirementsDefinitionMap
123 for (Map.Entry<String, RequirementAssignment> fullFilledEntry : entry.getValue().entrySet()) {
125 capability = fullFilledEntry.getValue().getCapability();
126 node = fullFilledEntry.getValue().getNode();
127 capabilityKey = capability + "_" + node;
128 CapabilityDefinition capabilityDefinition = nodeTypeCapabilitiesDefinition.get(capabilityKey);
129 if (capabilityDefinition != null) {
130 CapabilityDefinition clonedCapabilityDefinition = capabilityDefinition.clone();
131 nodeTypeCapabilitiesDefinition.put(capabilityKey, capabilityDefinition.clone());
132 updateNodeTypeCapabilitiesDefinition(nodeTypeCapabilitiesDefinition, capabilityKey,
133 clonedCapabilityDefinition);
138 Map<String, CapabilityDefinition> exposedCapabilitiesDefinition = new HashMap<>();
139 for (Map.Entry<String, CapabilityDefinition> entry : nodeTypeCapabilitiesDefinition.entrySet()) {
140 exposedCapabilitiesDefinition.put(entry.getKey(), entry.getValue());
142 return exposedCapabilitiesDefinition;
145 private void updateNodeTypeCapabilitiesDefinition(Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition,
146 String capabilityKey,
147 CapabilityDefinition clonedCapabilityDefinition) {
148 if (evaluateCapabilityFulfillment(clonedCapabilityDefinition)) {
149 nodeTypeCapabilitiesDefinition.remove(capabilityKey);
151 nodeTypeCapabilitiesDefinition.put(capabilityKey, clonedCapabilityDefinition);
155 private static boolean evaluateCapabilityFulfillment(CapabilityDefinition capabilityDefinition) {
157 Object[] occurrences = capabilityDefinition.getOccurrences();
158 if (occurrences == null) {
159 capabilityDefinition.setOccurrences(new Object[] {1, ToscaConstants.UNBOUNDED});
162 if (occurrences[1].equals(ToscaConstants.UNBOUNDED)) {
166 if (occurrences[1].equals(1)) {
169 occurrences[1] = (Integer) occurrences[1] - 1;
174 node template with type equal to node type or derived from node type
177 public Map<String, NodeTemplate> getNodeTemplatesByType(ServiceTemplate serviceTemplate, String nodeType,
178 ToscaServiceModel toscaServiceModel) {
179 Map<String, NodeTemplate> nodeTemplates = new HashMap<>();
181 if (Objects.nonNull(serviceTemplate.getTopology_template()) && MapUtils.isNotEmpty(
182 serviceTemplate.getTopology_template().getNode_templates())) {
183 for (Map.Entry<String, NodeTemplate> nodeTemplateEntry : serviceTemplate.getTopology_template()
184 .getNode_templates().entrySet()) {
185 if (isTypeOf(nodeTemplateEntry.getValue(), nodeType, serviceTemplate, toscaServiceModel)) {
186 nodeTemplates.put(nodeTemplateEntry.getKey(), nodeTemplateEntry.getValue());
191 return nodeTemplates;
195 public Optional<NodeType> fetchNodeType(String nodeTypeKey, Collection<ServiceTemplate> serviceTemplates) {
196 Optional<Map<String, NodeType>> nodeTypeMap = serviceTemplates.stream().map(ServiceTemplate::getNode_types)
197 .filter(nodeTypes -> Objects.nonNull(nodeTypes)
202 return nodeTypeMap.map(stringNodeTypeMap -> stringNodeTypeMap.get(nodeTypeKey));
206 public boolean isTypeOf(NodeTemplate nodeTemplate, String nodeType, ServiceTemplate serviceTemplate,
207 ToscaServiceModel toscaServiceModel) {
208 return isTypeOf(nodeTemplate, nodeType, GET_NODE_TYPE_METHOD_NAME, serviceTemplate, toscaServiceModel);
212 public List<RequirementAssignment> getRequirements(NodeTemplate nodeTemplate, String requirementId) {
213 List<RequirementAssignment> requirements = new ArrayList<>();
214 List<Map<String, RequirementAssignment>> requirementList = nodeTemplate.getRequirements();
215 if (requirementList != null) {
216 requirementList.stream().filter(reqMap -> reqMap.get(requirementId) != null).forEach(reqMap -> {
217 ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
218 RequirementAssignment reqAssignment = toscaExtensionYamlUtil.yamlToObject(
219 toscaExtensionYamlUtil.objectToYaml(reqMap.get(requirementId)), RequirementAssignment.class);
220 requirements.add(reqAssignment);
227 public Optional<NodeTemplate> getNodeTemplateById(ServiceTemplate serviceTemplate, String nodeTemplateId) {
228 if ((serviceTemplate.getTopology_template() != null) && (serviceTemplate.getTopology_template()
229 .getNode_templates() != null)
230 && (serviceTemplate.getTopology_template().getNode_templates().get(nodeTemplateId) != null)) {
231 return Optional.of(serviceTemplate.getTopology_template().getNode_templates().get(nodeTemplateId));
233 return Optional.empty();
237 public Optional<String> getSubstituteServiceTemplateName(String substituteNodeTemplateId,
238 NodeTemplate substitutableNodeTemplate) {
239 if (!isSubstitutableNodeTemplate(substitutableNodeTemplate)) {
240 return Optional.empty();
243 if (substitutableNodeTemplate.getProperties() != null &&
244 substitutableNodeTemplate.getProperties().get(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME)
246 Object serviceTemplateFilter =
247 substitutableNodeTemplate.getProperties().get(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME);
248 if (serviceTemplateFilter instanceof Map) {
249 Object substituteServiceTemplate =
250 ((Map) serviceTemplateFilter).get(ToscaConstants.SUBSTITUTE_SERVICE_TEMPLATE_PROPERTY_NAME);
251 handleNoSubstituteServiceTemplate(substituteNodeTemplateId, substituteServiceTemplate);
252 return Optional.of(substituteServiceTemplate.toString());
255 throw new CoreException(new ToscaInvalidSubstituteNodeTemplatePropertiesErrorBuilder(substituteNodeTemplateId)
259 private void handleNoSubstituteServiceTemplate(String substituteNodeTemplateId, Object substituteServiceTemplate) {
260 if (substituteServiceTemplate == null) {
261 throw new CoreException(new ToscaInvalidSubstituteNodeTemplatePropertiesErrorBuilder(substituteNodeTemplateId)
267 public Map<String, NodeTemplate> getSubstitutableNodeTemplates(ServiceTemplate serviceTemplate) {
268 Map<String, NodeTemplate> substitutableNodeTemplates = new HashMap<>();
270 if (serviceTemplate == null || serviceTemplate.getTopology_template() == null
271 || serviceTemplate.getTopology_template().getNode_templates() == null) {
272 return substitutableNodeTemplates;
275 Map<String, NodeTemplate> nodeTemplates = serviceTemplate.getTopology_template().getNode_templates();
276 for (Map.Entry<String, NodeTemplate> entry : nodeTemplates.entrySet()) {
277 String nodeTemplateId = entry.getKey();
278 NodeTemplate nodeTemplate = entry.getValue();
279 if (isSubstitutableNodeTemplate(nodeTemplate)) {
280 substitutableNodeTemplates.put(nodeTemplateId, nodeTemplate);
284 return substitutableNodeTemplates;
288 public Optional<Map.Entry<String, NodeTemplate>> getSubstitutionMappedNodeTemplateByExposedReq(String substituteServiceTemplateFileName,
289 ServiceTemplate substituteServiceTemplate,
290 String requirementId) {
291 if (isSubstitutionServiceTemplate(substituteServiceTemplateFileName, substituteServiceTemplate)) {
292 Map<String, List<String>> substitutionMappingRequirements =
293 substituteServiceTemplate.getTopology_template().getSubstitution_mappings().getRequirements();
294 if (substitutionMappingRequirements != null) {
295 List<String> requirementMapping = substitutionMappingRequirements.get(requirementId);
296 if (requirementMapping != null && !requirementMapping.isEmpty()) {
297 String mappedNodeTemplateId = requirementMapping.get(0);
298 Optional<NodeTemplate> mappedNodeTemplate =
299 getNodeTemplateById(substituteServiceTemplate, mappedNodeTemplateId);
300 mappedNodeTemplate.orElseThrow(
301 () -> new CoreException(new ToscaInvalidEntryNotFoundErrorBuilder("Node Template",
302 mappedNodeTemplateId)
304 Map.Entry<String, NodeTemplate> mappedNodeTemplateEntry = new Map.Entry<String, NodeTemplate>() {
306 public String getKey() {
307 return mappedNodeTemplateId;
311 public NodeTemplate getValue() {
312 return mappedNodeTemplate.get();
316 public NodeTemplate setValue(NodeTemplate value) {
320 return Optional.of(mappedNodeTemplateEntry);
324 return Optional.empty();
328 match only for the input which is not null
331 public boolean isDesiredRequirementAssignment(RequirementAssignment requirementAssignment, String capability,
332 String node, String relationship) {
333 if (isSameCapability(requirementAssignment, capability)) {
337 if (isSameRequirement(requirementAssignment, node)) {
341 if (isSameRelationship(requirementAssignment, relationship)) {
345 return !(capability == null && node == null && relationship == null);
349 private boolean isSameRelationship(RequirementAssignment requirementAssignment, String relationship) {
350 return relationship != null && (requirementAssignment.getRelationship() == null || !requirementAssignment
352 .equals(relationship));
355 private boolean isSameRequirement(RequirementAssignment requirementAssignment, String node) {
356 return node != null && (requirementAssignment.getNode() == null || !requirementAssignment.getNode()
360 private boolean isSameCapability(RequirementAssignment requirementAssignment, String capability) {
361 return capability != null && (requirementAssignment.getCapability() == null || !requirementAssignment
363 .equals(capability));
367 public ToscaFlatData getFlatEntity(ToscaElementTypes elementType, String typeId, ServiceTemplate serviceTemplate,
368 ToscaServiceModel toscaModel) {
369 ToscaFlatData flatData = new ToscaFlatData();
370 flatData.setElementType(elementType);
372 switch (elementType) {
373 case CAPABILITY_TYPE:
374 flatData.setFlatEntity(new CapabilityType());
377 flatData.setFlatEntity(new NodeType());
380 flatData.setFlatEntity(new DataType());
383 throw new RuntimeException("Entity[" + elementType + "] id[" + typeId + "] flat not supported");
386 boolean isEntityFound =
387 scanAnFlatEntity(elementType, typeId, flatData, serviceTemplate, toscaModel, new ArrayList<>(), 0);
388 if (!isEntityFound) {
389 throw new CoreException(new ToscaElementTypeNotFoundErrorBuilder(typeId).build());
396 public boolean isSubstitutableNodeTemplate(NodeTemplate nodeTemplate) {
397 return nodeTemplate.getDirectives() != null && nodeTemplate.getDirectives().contains(
398 ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
401 private <T> Optional<Boolean> isTypeExistInServiceTemplateHierarchy(String typeToMatch, String typeToSearch,
402 String getTypesMethodName,
403 ServiceTemplate serviceTemplate,
404 ToscaServiceModel toscaServiceModel,
405 Set<String> analyzedImportFiles)
406 throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
407 Map<String, T> searchableTypes =
408 (Map<String, T>) serviceTemplate.getClass().getMethod(getTypesMethodName).invoke(serviceTemplate);
410 if (!MapUtils.isEmpty(searchableTypes)) {
411 T typeObject = searchableTypes.get(typeToSearch);
412 if (Objects.nonNull(typeObject)) {
413 String derivedFromTypeVal =
414 (String) typeObject.getClass().getMethod(GET_DERIVED_FROM_METHOD_NAME).invoke(typeObject);
415 if (Objects.equals(derivedFromTypeVal, typeToMatch)) {
416 return Optional.of(true);
417 } else if (Objects.isNull(derivedFromTypeVal) || isTypeIsToscaRoot(derivedFromTypeVal)) {
418 return Optional.of(false);
420 return isTypeExistInServiceTemplateHierarchy(typeToMatch, derivedFromTypeVal, getTypesMethodName,
421 serviceTemplate, toscaServiceModel, null);
424 return isTypeExistInImports(typeToMatch, typeToSearch, getTypesMethodName, serviceTemplate,
425 toscaServiceModel, analyzedImportFiles);
428 return isTypeExistInImports(typeToMatch, typeToSearch, getTypesMethodName, serviceTemplate, toscaServiceModel,
429 analyzedImportFiles);
432 private Optional<Boolean> isTypeExistInImports(String typeToMatch, String typeToSearch, String getTypesMethodName,
433 ServiceTemplate serviceTemplate,
434 ToscaServiceModel toscaServiceModel, Set<String> filesScanned)
435 throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
436 List<Map<String, Import>> imports = serviceTemplate.getImports();
437 if (CollectionUtils.isEmpty(imports)) {
438 return Optional.empty();
441 Set<String> createdFilesScanned = createFilesScannedSet(filesScanned);
443 for (Map<String, Import> map : imports) {
444 ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
445 Import anImport = toscaExtensionYamlUtil
446 .yamlToObject(toscaExtensionYamlUtil.objectToYaml(map.values().iterator().next()),
448 handleImportWithNoFileEntry(anImport);
449 String importFile = anImport.getFile();
450 ServiceTemplate template = toscaServiceModel.getServiceTemplates().get(fetchFileNameForImport(importFile,
451 serviceTemplate.getMetadata() == null ? null : serviceTemplate.getMetadata().get("filename")));
452 if (Objects.isNull(template) || createdFilesScanned
453 .contains(ToscaUtil.getServiceTemplateFileName(template))) {
456 createdFilesScanned.add(ToscaUtil.getServiceTemplateFileName(template));
458 Optional<Boolean> typeExistInServiceTemplateHierarchy =
459 isTypeExistInServiceTemplateHierarchy(typeToMatch, typeToSearch, getTypesMethodName, template,
460 toscaServiceModel, createdFilesScanned);
461 if (typeExistInServiceTemplateHierarchy.isPresent() && (typeExistInServiceTemplateHierarchy.get())) {
462 createdFilesScanned.clear();
463 return Optional.of(true);
467 return Optional.of(false);
470 private void handleImportWithNoFileEntry(Import anImport) {
471 if (Objects.isNull(anImport) || Objects.isNull(anImport.getFile())) {
472 throw new RuntimeException("import without file entry");
476 private Set<String> createFilesScannedSet(Set<String> filesScanned) {
477 Set<String> retFileScanned = filesScanned;
478 if (Objects.isNull(retFileScanned)) {
479 retFileScanned = new HashSet<>();
481 return retFileScanned;
484 private boolean isTypeIsToscaRoot(String type) {
485 return (type.contains(TOSCA_DOT) && type.contains(DOT_ROOT));
488 private boolean isSubstitutionServiceTemplate(String substituteServiceTemplateFileName,
489 ServiceTemplate substituteServiceTemplate) {
490 if (substituteServiceTemplate != null && substituteServiceTemplate.getTopology_template() != null
491 && substituteServiceTemplate.getTopology_template().getSubstitution_mappings() != null) {
492 if (substituteServiceTemplate.getTopology_template().getSubstitution_mappings().getNode_type() == null) {
493 throw new CoreException(new ToscaInvalidSubstitutionServiceTemplateErrorBuilder(substituteServiceTemplateFileName)
502 private boolean scanAnFlatEntity(ToscaElementTypes elementType, String typeId, ToscaFlatData flatData,
503 ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel,
504 List<String> filesScanned, int rootScanStartInx) {
507 boolean entityFound =
508 enrichEntityFromCurrentServiceTemplate(elementType, typeId, flatData, serviceTemplate, toscaModel,
509 filesScanned, rootScanStartInx);
511 List<Map<String, Import>> imports = serviceTemplate.getImports();
512 if (CollectionUtils.isEmpty(imports)) {
515 boolean found = false;
516 for (Map<String, Import> importMap : imports) {
520 found = isFlatEntity(importMap, flatData, serviceTemplate, filesScanned, toscaModel, elementType,
528 private boolean isFlatEntity(Map<String, Import> importMap, ToscaFlatData flatData, ServiceTemplate serviceTemplate,
529 List<String> filesScanned, ToscaServiceModel toscaModel,
530 ToscaElementTypes elementType, String typeId) {
531 boolean found = false;
532 ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
533 for (Object importObject : importMap.values()) {
534 Import importServiceTemplate = toscaExtensionYamlUtil
535 .yamlToObject(toscaExtensionYamlUtil.objectToYaml(importObject),
537 String fileName = fetchFileNameForImport(importServiceTemplate.getFile(),
538 serviceTemplate.getMetadata() == null ? null : serviceTemplate.getMetadata().get("filename"));
539 if (filesScanned.contains(fileName)) {
542 filesScanned.add(fileName);
544 ServiceTemplate template = toscaModel.getServiceTemplates().get(fileName);
545 if (Objects.isNull(template)) {
546 throw new CoreException(new ToscaFileNotFoundErrorBuilder(fileName).build());
548 found = scanAnFlatEntity(elementType, typeId, flatData, template, toscaModel, filesScanned,
549 filesScanned.size());
554 private String fetchFileNameForImport(String importServiceTemplateFile, String currentMetadatafileName) {
555 if (importServiceTemplateFile.contains("../")) {
556 return importServiceTemplateFile.replace("../", "");
557 } else if (currentMetadatafileName != null && currentMetadatafileName.indexOf('/') != -1) {
558 return currentMetadatafileName.substring(0, currentMetadatafileName.indexOf('/')) + "/"
559 + importServiceTemplateFile;
561 return importServiceTemplateFile;
566 private boolean enrichEntityFromCurrentServiceTemplate(ToscaElementTypes elementType, String typeId,
567 ToscaFlatData flatData,
568 ServiceTemplate serviceTemplate,
569 ToscaServiceModel toscaModel,
570 List<String> filesScanned, int rootScanStartInx) {
571 switch (elementType) {
572 case CAPABILITY_TYPE:
573 if (enrichCapabilityType(elementType, typeId, flatData, serviceTemplate, toscaModel, filesScanned,
579 if (enrichNodeTypeInfo(elementType, typeId, flatData, serviceTemplate, toscaModel, filesScanned,
585 if (enrichDataTypeInfo(elementType, typeId, flatData, serviceTemplate, toscaModel, filesScanned,
591 throw new RuntimeException("Entity[" + elementType + "] id[" + typeId + "] flat not supported");
599 private boolean enrichNodeTypeInfo(ToscaElementTypes elementType, String typeId, ToscaFlatData flatData,
600 ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel,
601 List<String> filesScanned, int rootScanStartInx) {
603 if (serviceTemplate.getNode_types() != null && serviceTemplate.getNode_types().containsKey(typeId)) {
605 filesScanned.clear();
606 flatData.addInheritanceHierarchyType(typeId);
607 NodeType targetNodeType = (NodeType) flatData.getFlatEntity();
608 NodeType sourceNodeType = serviceTemplate.getNode_types().get(typeId);
609 derivedFrom = sourceNodeType.getDerived_from();
610 if (derivedFrom != null) {
611 boolean isEntityFound =
612 scanAnFlatEntity(elementType, derivedFrom, flatData, serviceTemplate, toscaModel, filesScanned,
614 if (!isEntityFound) {
615 throw new CoreException(new ToscaElementTypeNotFoundErrorBuilder(typeId).build());
618 combineNodeTypeInfo(sourceNodeType, targetNodeType);
625 private boolean enrichDataTypeInfo(ToscaElementTypes elementType, String typeId, ToscaFlatData flatData,
626 ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel,
627 List<String> filesScanned, int rootScanStartInx) {
629 if (serviceTemplate.getData_types() != null && serviceTemplate.getData_types().containsKey(typeId)) {
631 filesScanned.clear();
632 flatData.addInheritanceHierarchyType(typeId);
633 DataType targetDataType = (DataType) flatData.getFlatEntity();
634 DataType sourceDataType = serviceTemplate.getData_types().get(typeId);
635 derivedFrom = sourceDataType.getDerived_from();
636 if (derivedFrom != null && !isPrimitiveType(derivedFrom)) {
637 boolean isEntityFound =
638 scanAnFlatEntity(elementType, derivedFrom, flatData, serviceTemplate, toscaModel, filesScanned,
640 if (!isEntityFound) {
641 throw new CoreException(new ToscaElementTypeNotFoundErrorBuilder(typeId).build());
644 combineDataTypeInfo(sourceDataType, targetDataType);
651 private static boolean isPrimitiveType(String toscaType) {
652 return (toscaType.equals(PropertyType.STRING.getDisplayName()) || toscaType.equals(PropertyType.INTEGER
654 || toscaType.equals(PropertyType.FLOAT.getDisplayName()));
657 private boolean enrichCapabilityType(ToscaElementTypes elementType, String typeId, ToscaFlatData flatData,
658 ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel,
659 List<String> filesScanned, int rootScanStartInx) {
661 if (serviceTemplate.getCapability_types() != null && serviceTemplate.getCapability_types()
662 .containsKey(typeId)) {
664 filesScanned.clear();
665 flatData.addInheritanceHierarchyType(typeId);
666 CapabilityType targetCapabilityType = (CapabilityType) flatData.getFlatEntity();
667 CapabilityType sourceCapabilityType = serviceTemplate.getCapability_types().get(typeId);
668 derivedFrom = sourceCapabilityType.getDerived_from();
669 if (derivedFrom != null) {
670 boolean isEntityFound =
671 scanAnFlatEntity(elementType, derivedFrom, flatData, serviceTemplate, toscaModel, filesScanned,
673 if (!isEntityFound) {
674 throw new CoreException(new ToscaElementTypeNotFoundErrorBuilder(typeId).build());
677 combineCapabilityTypeInfo(sourceCapabilityType, targetCapabilityType);
684 private void combineNodeTypeInfo(NodeType sourceNodeType, NodeType targetNodeType) {
685 targetNodeType.setDerived_from(sourceNodeType.getDerived_from());
686 targetNodeType.setDescription(sourceNodeType.getDescription());
687 targetNodeType.setVersion(sourceNodeType.getVersion());
689 .setProperties(CommonMethods.mergeMaps(targetNodeType.getProperties(), sourceNodeType.getProperties()));
690 combineNodeTypeInterfaceInfo(sourceNodeType, targetNodeType);
692 .setArtifacts(CommonMethods.mergeMaps(targetNodeType.getArtifacts(), sourceNodeType.getArtifacts()));
694 .setAttributes(CommonMethods.mergeMaps(targetNodeType.getAttributes(), sourceNodeType.getAttributes()));
695 targetNodeType.setCapabilities(
696 CommonMethods.mergeMaps(targetNodeType.getCapabilities(), sourceNodeType.getCapabilities()));
697 targetNodeType.setRequirements(
698 CommonMethods.mergeListsOfMap(targetNodeType.getRequirements(), sourceNodeType.getRequirements()));
702 private InterfaceDefinitionType getInterfaceDefinitionType(String interfaceName, Object interfaceDefTypeObj) {
703 Optional<InterfaceDefinitionType> interfaceDefinitionType = DataModelUtil.convertObjToInterfaceDefinition(
704 interfaceName, interfaceDefTypeObj, InterfaceDefinitionType.class);
705 if (!interfaceDefinitionType.isPresent()) {
706 throw new CoreException(new CreateInterfaceObjectErrorBuilder("InterfaceDefinitionType", interfaceName,
707 "Invalid interface object").build());
709 return interfaceDefinitionType.get();
712 private void combineNodeTypeInterfaceInfo(NodeType sourceNodeType, NodeType targetNodeType) {
713 Optional<Map<String, Object>> interfaceNoMerge = combineInterfaceNoMerge(sourceNodeType, targetNodeType);
714 if (interfaceNoMerge.isPresent()) {
715 targetNodeType.setInterfaces(interfaceNoMerge.get());
718 targetNodeType.setInterfaces(combineInterfaces(sourceNodeType, targetNodeType));
721 private Map<String, Object> combineInterfaces(NodeType sourceNodeType, NodeType targetNodeType) {
722 Map<String, Object> combineInterfaces = new HashMap<>();
723 for (Map.Entry<String, Object> sourceInterfaceDefEntry : sourceNodeType.getInterfaces().entrySet()) {
724 String interfaceName = sourceInterfaceDefEntry.getKey();
725 if (!MapUtils.isEmpty(targetNodeType.getInterfaces()) && targetNodeType.getInterfaces()
726 .containsKey(interfaceName)) {
727 combineInterfaces.put(interfaceName,
728 combineInterfaceDefinition(interfaceName, sourceInterfaceDefEntry.getValue(),
729 targetNodeType.getInterfaces().get(interfaceName)));
731 combineInterfaces.put(sourceInterfaceDefEntry.getKey(), sourceInterfaceDefEntry.getValue());
735 for (Map.Entry<String, Object> targetInterfaceDefEntry : targetNodeType.getInterfaces().entrySet()) {
736 String interfaceName = targetInterfaceDefEntry.getKey();
737 if (!sourceNodeType.getInterfaces().containsKey(interfaceName)) {
738 combineInterfaces.put(targetInterfaceDefEntry.getKey(), targetInterfaceDefEntry.getValue());
742 return combineInterfaces;
745 private Optional<Map<String, Object>> combineInterfaceNoMerge(NodeType sourceNodeType, NodeType targetNodeType) {
746 if ((MapUtils.isEmpty(sourceNodeType.getInterfaces()) && MapUtils.isEmpty(targetNodeType.getInterfaces()))) {
747 return Optional.empty();
750 if (MapUtils.isEmpty(sourceNodeType.getInterfaces()) && !MapUtils.isEmpty(targetNodeType.getInterfaces())) {
751 return Optional.of(targetNodeType.getInterfaces());
754 if (!MapUtils.isEmpty(sourceNodeType.getInterfaces()) && MapUtils.isEmpty(targetNodeType.getInterfaces())) {
755 return Optional.of(sourceNodeType.getInterfaces());
757 return Optional.empty();
761 private Object combineInterfaceDefinition(String interfaceName, Object sourceInterfaceDefType,
762 Object targetInterfaceDefType) {
763 InterfaceDefinitionType sourceInterface = getInterfaceDefinitionType(interfaceName, sourceInterfaceDefType);
764 InterfaceDefinitionType targetInterface = getInterfaceDefinitionType(interfaceName, targetInterfaceDefType);
765 InterfaceDefinitionType combineInterface = new InterfaceDefinitionType();
766 combineInterface.setType(sourceInterface.getType());
767 combineInterface.setInputs(CommonMethods.mergeMaps(targetInterface.getInputs(), sourceInterface.getInputs()));
768 combineInterface.setOperations(
769 CommonMethods.mergeMaps(targetInterface.getOperations(), sourceInterface.getOperations()));
771 Optional<Object> interfaceDefObject = DataModelUtil.convertInterfaceDefinitionTypeToObj(combineInterface);
772 if( !interfaceDefObject.isPresent()){
773 throw new SdcRuntimeException("Illegal Statement");
775 return interfaceDefObject.get();
778 private void combineDataTypeInfo(DataType sourceDataType, DataType targetDataType) {
779 targetDataType.setDerived_from(sourceDataType.getDerived_from());
780 targetDataType.setDescription(sourceDataType.getDescription());
781 targetDataType.setVersion(sourceDataType.getVersion());
783 .setProperties(CommonMethods.mergeMaps(targetDataType.getProperties(), sourceDataType.getProperties()));
784 targetDataType.setConstraints(
785 CommonMethods.mergeLists(targetDataType.getConstraints(), sourceDataType.getConstraints()));
789 private void combineCapabilityTypeInfo(CapabilityType sourceCapabilityType, CapabilityType targetCapabilityType) {
791 targetCapabilityType.setAttributes(
792 CommonMethods.mergeMaps(targetCapabilityType.getAttributes(), sourceCapabilityType.getAttributes()));
793 targetCapabilityType.setProperties(
794 CommonMethods.mergeMaps(targetCapabilityType.getProperties(), sourceCapabilityType.getProperties()));
795 targetCapabilityType.setValid_source_types(CommonMethods
796 .mergeLists(targetCapabilityType.getValid_source_types(),
797 sourceCapabilityType.getValid_source_types()));
799 if (StringUtils.isNotEmpty(sourceCapabilityType.getDerived_from())) {
800 targetCapabilityType.setDerived_from(sourceCapabilityType.getDerived_from());
802 if (StringUtils.isNotEmpty(sourceCapabilityType.getDescription())) {
803 targetCapabilityType.setDescription(sourceCapabilityType.getDescription());
805 if (StringUtils.isNotEmpty(sourceCapabilityType.getVersion())) {
806 targetCapabilityType.setVersion(sourceCapabilityType.getVersion());
814 * Create node type according to the input substitution service template, while the substitution
815 * service template can be mappted to this node type, for substitution mapping.
817 * @param substitutionServiceTemplate substitution serivce template
818 * @param nodeTypeDerivedFromValue derived from value for the created node type
819 * @return the node type
822 public NodeType createInitSubstitutionNodeType(ServiceTemplate substitutionServiceTemplate,
823 String nodeTypeDerivedFromValue) {
824 NodeType substitutionNodeType = new NodeType();
825 substitutionNodeType.setDerived_from(nodeTypeDerivedFromValue);
826 substitutionNodeType.setDescription(substitutionServiceTemplate.getDescription());
827 substitutionNodeType.setProperties(manageSubstitutionNodeTypeProperties(substitutionServiceTemplate));
828 substitutionNodeType.setAttributes(manageSubstitutionNodeTypeAttributes(substitutionServiceTemplate));
829 return substitutionNodeType;
833 public Map<String, PropertyDefinition> manageSubstitutionNodeTypeProperties(ServiceTemplate substitutionServiceTemplate) {
834 Map<String, PropertyDefinition> substitutionNodeTypeProperties = new HashMap<>();
835 Map<String, ParameterDefinition> properties = substitutionServiceTemplate.getTopology_template().getInputs();
836 if (properties == null) {
840 PropertyDefinition propertyDefinition;
841 String toscaPropertyName;
842 for (Map.Entry<String, ParameterDefinition> entry : properties.entrySet()) {
843 toscaPropertyName = entry.getKey();
844 propertyDefinition = new PropertyDefinition();
845 ParameterDefinition parameterDefinition =
846 substitutionServiceTemplate.getTopology_template().getInputs().get(toscaPropertyName);
847 propertyDefinition.setType(parameterDefinition.getType());
848 propertyDefinition.setDescription(parameterDefinition.getDescription());
849 propertyDefinition.set_default(parameterDefinition.get_default());
850 if (parameterDefinition.getRequired() != null) {
851 propertyDefinition.setRequired(parameterDefinition.getRequired());
853 if (propertyDefinition.get_default() != null) {
854 propertyDefinition.setRequired(false);
856 if (!CollectionUtils.isEmpty(parameterDefinition.getConstraints())) {
857 propertyDefinition.setConstraints(parameterDefinition.getConstraints());
859 propertyDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
860 if (parameterDefinition.getStatus() != null) {
861 propertyDefinition.setStatus(parameterDefinition.getStatus());
863 substitutionNodeTypeProperties.put(toscaPropertyName, propertyDefinition);
865 return substitutionNodeTypeProperties;
869 private Map<String, AttributeDefinition> manageSubstitutionNodeTypeAttributes(ServiceTemplate substitutionServiceTemplate) {
870 Map<String, AttributeDefinition> substitutionNodeTypeAttributes = new HashMap<>();
871 Map<String, ParameterDefinition> attributes = substitutionServiceTemplate.getTopology_template().getOutputs();
872 if (attributes == null) {
875 AttributeDefinition attributeDefinition;
876 String toscaAttributeName;
878 for (Map.Entry<String, ParameterDefinition> entry : attributes.entrySet()) {
879 attributeDefinition = new AttributeDefinition();
880 toscaAttributeName = entry.getKey();
881 ParameterDefinition parameterDefinition =
882 substitutionServiceTemplate.getTopology_template().getOutputs().get(toscaAttributeName);
883 if (parameterDefinition.getType() != null && !parameterDefinition.getType().isEmpty()) {
884 attributeDefinition.setType(parameterDefinition.getType());
886 attributeDefinition.setType(PropertyType.STRING.getDisplayName());
888 attributeDefinition.setDescription(parameterDefinition.getDescription());
889 attributeDefinition.set_default(parameterDefinition.get_default());
890 attributeDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
891 if (Objects.nonNull(parameterDefinition.getStatus())) {
892 attributeDefinition.setStatus(parameterDefinition.getStatus());
894 substitutionNodeTypeAttributes.put(toscaAttributeName, attributeDefinition);
896 return substitutionNodeTypeAttributes;
900 * Checks if the requirement exists in the node template.
902 * @param nodeTemplate the node template
903 * @param requirementId the requirement id
904 * @param requirementAssignment the requirement assignment
905 * @return true if the requirement already exists and false otherwise
908 public boolean isRequirementExistInNodeTemplate(NodeTemplate nodeTemplate, String requirementId,
909 RequirementAssignment requirementAssignment) {
910 List<Map<String, RequirementAssignment>> nodeTemplateRequirements = nodeTemplate.getRequirements();
911 return nodeTemplateRequirements != null && nodeTemplateRequirements.stream().anyMatch(
912 requirement -> requirement.containsKey(requirementId) && DataModelUtil.compareRequirementAssignment(
913 requirementAssignment, requirement.get(requirementId)));
917 public boolean isTypeOf(InterfaceDefinitionType interfaceDefinition, String interfaceType,
918 ServiceTemplate serviceTemplate, ToscaServiceModel toscaServiceModel) {
919 return isTypeOf(interfaceDefinition, interfaceType, GET_INTERFACE_TYPE_METHOD_NAME, serviceTemplate,
924 public boolean isTypeOf(DefinitionOfDataType parameterDefinition, String dataType, ServiceTemplate serviceTemplate,
925 ToscaServiceModel toscaServiceModel) {
926 return isTypeOf(parameterDefinition, dataType, GET_DATA_TYPE_METHOD_NAME, serviceTemplate, toscaServiceModel);
930 public boolean isTypeOf(CapabilityDefinition capabilityDefinition, String capabilityType,
931 ServiceTemplate serviceTemplate, ToscaServiceModel toscaServiceModel) {
932 return isTypeOf(capabilityDefinition, capabilityType, GET_CAPABILITY_TYPE_METHOD_NAME, serviceTemplate, toscaServiceModel);
936 private <T> boolean isTypeOf(T object, String type, String getTypesMethodName, ServiceTemplate serviceTemplate,
937 ToscaServiceModel toscaServiceModel) {
938 if (object == null) {
943 String objectType = (String) object.getClass().getMethod(GET_TYPE_METHOD_NAME).invoke(object);
944 if (Objects.equals(objectType, type)) {
948 Optional<Boolean> typeExistInServiceTemplateHierarchy =
949 isTypeExistInServiceTemplateHierarchy(type, objectType, getTypesMethodName, serviceTemplate,
950 toscaServiceModel, null);
951 return typeExistInServiceTemplateHierarchy.orElseThrow(
952 () -> new CoreException(new ToscaElementTypeNotFoundErrorBuilder(objectType).build()));
954 } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
955 throw new SdcRuntimeException(e);