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 java.lang.reflect.InvocationTargetException;
20 import java.util.ArrayList;
21 import java.util.Collection;
22 import java.util.Collections;
23 import java.util.HashMap;
24 import java.util.HashSet;
25 import java.util.List;
27 import java.util.Objects;
28 import java.util.Optional;
30 import org.apache.commons.collections4.CollectionUtils;
31 import org.apache.commons.collections4.MapUtils;
32 import org.apache.commons.lang3.StringUtils;
33 import org.onap.sdc.tosca.datatypes.model.AttributeDefinition;
34 import org.onap.sdc.tosca.datatypes.model.CapabilityDefinition;
35 import org.onap.sdc.tosca.datatypes.model.CapabilityType;
36 import org.onap.sdc.tosca.datatypes.model.DataType;
37 import org.onap.sdc.tosca.datatypes.model.DefinitionOfDataType;
38 import org.onap.sdc.tosca.datatypes.model.Import;
39 import org.onap.sdc.tosca.datatypes.model.InterfaceDefinitionType;
40 import org.onap.sdc.tosca.datatypes.model.NodeTemplate;
41 import org.onap.sdc.tosca.datatypes.model.NodeType;
42 import org.onap.sdc.tosca.datatypes.model.ParameterDefinition;
43 import org.onap.sdc.tosca.datatypes.model.PropertyDefinition;
44 import org.onap.sdc.tosca.datatypes.model.PropertyType;
45 import org.onap.sdc.tosca.datatypes.model.RequirementAssignment;
46 import org.onap.sdc.tosca.datatypes.model.RequirementDefinition;
47 import org.onap.sdc.tosca.datatypes.model.ServiceTemplate;
48 import org.onap.sdc.tosca.services.ToscaExtensionYamlUtil;
49 import org.openecomp.core.utilities.CommonMethods;
50 import org.openecomp.sdc.common.errors.CoreException;
51 import org.openecomp.sdc.common.errors.SdcRuntimeException;
52 import org.openecomp.sdc.tosca.datatypes.ToscaElementTypes;
53 import org.openecomp.sdc.tosca.datatypes.ToscaFlatData;
54 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
55 import org.openecomp.sdc.tosca.errors.ToscaElementTypeNotFoundErrorBuilder;
56 import org.openecomp.sdc.tosca.errors.ToscaFileNotFoundErrorBuilder;
57 import org.openecomp.sdc.tosca.errors.ToscaInvalidEntryNotFoundErrorBuilder;
58 import org.openecomp.sdc.tosca.errors.ToscaInvalidSubstituteNodeTemplatePropertiesErrorBuilder;
59 import org.openecomp.sdc.tosca.errors.ToscaInvalidSubstitutionServiceTemplateErrorBuilder;
60 import org.openecomp.sdc.tosca.services.DataModelUtil;
61 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
62 import org.openecomp.sdc.tosca.services.ToscaConstants;
63 import org.openecomp.sdc.tosca.services.ToscaUtil;
65 public class ToscaAnalyzerServiceImpl implements ToscaAnalyzerService {
67 private static final String GET_NODE_TYPE_METHOD_NAME = "getNode_types";
68 private static final String GET_DERIVED_FROM_METHOD_NAME = "getDerived_from";
69 private static final String GET_TYPE_METHOD_NAME = "getType";
70 private static final String GET_DATA_TYPE_METHOD_NAME = "getData_types";
71 private static final String GET_INTERFACE_TYPE_METHOD_NAME = "getNormalizeInterfaceTypes";
72 private static final String GET_CAPABILITY_TYPE_METHOD_NAME = "getCapability_types";
73 private static final String TOSCA_DOT = "tosca.";
74 private static final String DOT_ROOT = ".Root";
77 public List<Map<String, RequirementDefinition>> calculateExposedRequirements(
78 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(
114 List<Map<String, RequirementDefinition>> nodeTypeRequirementsDefinitionList,
115 Map.Entry<String, RequirementAssignment> entry, 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(
143 Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition,
144 Map<String, Map<String, RequirementAssignment>> fullFilledRequirementsDefinitionMap) {
146 String capabilityKey;
149 for (Map.Entry<String, Map<String, RequirementAssignment>> entry : fullFilledRequirementsDefinitionMap
151 for (Map.Entry<String, RequirementAssignment> fullFilledEntry : entry.getValue().entrySet()) {
154 capability = fullFilledEntry.getValue().getCapability();
155 node = fullFilledEntry.getValue().getNode();
156 capabilityKey = capability + "_" + node;
157 CapabilityDefinition capabilityDefinition = nodeTypeCapabilitiesDefinition.get(capabilityKey);
158 if (capabilityDefinition != null) {
159 CapabilityDefinition clonedCapabilityDefinition = capabilityDefinition.clone();
160 nodeTypeCapabilitiesDefinition.put(capabilityKey, capabilityDefinition.clone());
161 updateNodeTypeCapabilitiesDefinition(nodeTypeCapabilitiesDefinition, capabilityKey,
162 clonedCapabilityDefinition);
167 Map<String, CapabilityDefinition> exposedCapabilitiesDefinition = new HashMap<>();
168 for (Map.Entry<String, CapabilityDefinition> entry : nodeTypeCapabilitiesDefinition.entrySet()) {
169 exposedCapabilitiesDefinition.put(entry.getKey(), entry.getValue());
171 return exposedCapabilitiesDefinition;
174 private void updateNodeTypeCapabilitiesDefinition(Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition,
175 String capabilityKey, CapabilityDefinition clonedCapabilityDefinition) {
176 if (evaluateCapabilityFulfillment(clonedCapabilityDefinition)) {
177 nodeTypeCapabilitiesDefinition.remove(capabilityKey);
179 nodeTypeCapabilitiesDefinition.put(capabilityKey, clonedCapabilityDefinition);
183 private static boolean evaluateCapabilityFulfillment(CapabilityDefinition capabilityDefinition) {
185 Object[] occurrences = capabilityDefinition.getOccurrences();
186 if (occurrences == null) {
187 capabilityDefinition.setOccurrences(new Object[] {1, ToscaConstants.UNBOUNDED});
190 if (occurrences[1].equals(ToscaConstants.UNBOUNDED)) {
194 if (occurrences[1].equals(1)) {
197 occurrences[1] = (Integer) occurrences[1] - 1;
202 node template with type equal to node type or derived from node type
205 public Map<String, NodeTemplate> getNodeTemplatesByType(ServiceTemplate serviceTemplate, String nodeType,
206 ToscaServiceModel toscaServiceModel) {
207 Map<String, NodeTemplate> nodeTemplates = new HashMap<>();
209 if (Objects.nonNull(serviceTemplate.getTopology_template()) && MapUtils.isNotEmpty(
210 serviceTemplate.getTopology_template().getNode_templates())) {
211 for (Map.Entry<String, NodeTemplate> nodeTemplateEntry : serviceTemplate.getTopology_template()
212 .getNode_templates().entrySet()) {
213 if (isTypeOf(nodeTemplateEntry.getValue(), nodeType, serviceTemplate, toscaServiceModel)) {
214 nodeTemplates.put(nodeTemplateEntry.getKey(), nodeTemplateEntry.getValue());
219 return nodeTemplates;
223 public Optional<NodeType> fetchNodeType(String nodeTypeKey, Collection<ServiceTemplate> serviceTemplates) {
224 Optional<Map<String, NodeType>> nodeTypeMap = serviceTemplates.stream().map(ServiceTemplate::getNode_types)
225 .filter(nodeTypes -> Objects.nonNull(nodeTypes)
226 && nodeTypes.containsKey(nodeTypeKey)).findFirst();
227 return nodeTypeMap.map(stringNodeTypeMap -> stringNodeTypeMap.get(nodeTypeKey));
231 public boolean isTypeOf(NodeTemplate nodeTemplate, String nodeType, ServiceTemplate serviceTemplate,
232 ToscaServiceModel toscaServiceModel) {
233 return isTypeOf(nodeTemplate, nodeType, GET_NODE_TYPE_METHOD_NAME, serviceTemplate, toscaServiceModel);
237 public boolean isTypeOf(InterfaceDefinitionType interfaceDefinition, String interfaceType,
238 ServiceTemplate serviceTemplate, ToscaServiceModel toscaServiceModel) {
239 return isTypeOf(interfaceDefinition, interfaceType, GET_INTERFACE_TYPE_METHOD_NAME, serviceTemplate,
244 public boolean isTypeOf(DefinitionOfDataType parameterDefinition, String dataType, ServiceTemplate serviceTemplate,
245 ToscaServiceModel toscaServiceModel) {
246 return isTypeOf(parameterDefinition, dataType, GET_DATA_TYPE_METHOD_NAME, serviceTemplate, toscaServiceModel);
250 public boolean isTypeOf(CapabilityDefinition capabilityDefinition, String capabilityType,
251 ServiceTemplate serviceTemplate, ToscaServiceModel toscaServiceModel) {
252 return isTypeOf(capabilityDefinition, capabilityType, GET_CAPABILITY_TYPE_METHOD_NAME, serviceTemplate,
257 public List<RequirementAssignment> getRequirements(NodeTemplate nodeTemplate, String requirementId) {
258 List<RequirementAssignment> requirements = new ArrayList<>();
259 List<Map<String, RequirementAssignment>> requirementList = nodeTemplate.getRequirements();
260 if (requirementList != null) {
261 requirementList.stream().filter(reqMap -> reqMap.get(requirementId) != null).forEach(reqMap -> {
262 ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
263 RequirementAssignment reqAssignment = toscaExtensionYamlUtil.yamlToObject(
264 toscaExtensionYamlUtil.objectToYaml(reqMap.get(requirementId)), RequirementAssignment.class);
265 requirements.add(reqAssignment);
272 public Optional<NodeTemplate> getNodeTemplateById(ServiceTemplate serviceTemplate, String nodeTemplateId) {
273 if ((serviceTemplate.getTopology_template() != null) && (
274 serviceTemplate.getTopology_template().getNode_templates() != null) && (
275 serviceTemplate.getTopology_template().getNode_templates().get(nodeTemplateId) != null)) {
276 return Optional.of(serviceTemplate.getTopology_template().getNode_templates().get(nodeTemplateId));
278 return Optional.empty();
282 public Optional<String> getSubstituteServiceTemplateName(String substituteNodeTemplateId,
283 NodeTemplate substitutableNodeTemplate) {
284 if (!isSubstitutableNodeTemplate(substitutableNodeTemplate)) {
285 return Optional.empty();
288 if (substitutableNodeTemplate.getProperties() != null
289 && substitutableNodeTemplate.getProperties().get(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME)
291 Object serviceTemplateFilter =
292 substitutableNodeTemplate.getProperties().get(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME);
293 if (serviceTemplateFilter instanceof Map) {
294 Object substituteServiceTemplate =
295 ((Map) serviceTemplateFilter).get(ToscaConstants.SUBSTITUTE_SERVICE_TEMPLATE_PROPERTY_NAME);
296 handleNoSubstituteServiceTemplate(substituteNodeTemplateId, substituteServiceTemplate);
297 return Optional.of(substituteServiceTemplate.toString());
300 throw new CoreException(
301 new ToscaInvalidSubstituteNodeTemplatePropertiesErrorBuilder(substituteNodeTemplateId).build());
304 private void handleNoSubstituteServiceTemplate(String substituteNodeTemplateId, Object substituteServiceTemplate) {
305 if (substituteServiceTemplate == null) {
306 throw new CoreException(
307 new ToscaInvalidSubstituteNodeTemplatePropertiesErrorBuilder(substituteNodeTemplateId).build());
312 public Map<String, NodeTemplate> getSubstitutableNodeTemplates(ServiceTemplate serviceTemplate) {
313 Map<String, NodeTemplate> substitutableNodeTemplates = new HashMap<>();
315 if (serviceTemplate == null || serviceTemplate.getTopology_template() == null
316 || serviceTemplate.getTopology_template().getNode_templates() == null) {
317 return substitutableNodeTemplates;
320 Map<String, NodeTemplate> nodeTemplates = serviceTemplate.getTopology_template().getNode_templates();
321 for (Map.Entry<String, NodeTemplate> entry : nodeTemplates.entrySet()) {
322 String nodeTemplateId = entry.getKey();
323 NodeTemplate nodeTemplate = entry.getValue();
324 if (isSubstitutableNodeTemplate(nodeTemplate)) {
325 substitutableNodeTemplates.put(nodeTemplateId, nodeTemplate);
329 return substitutableNodeTemplates;
333 public Optional<Map.Entry<String, NodeTemplate>> getSubstitutionMappedNodeTemplateByExposedReq(
334 String substituteServiceTemplateFileName, ServiceTemplate substituteServiceTemplate, String requirementId) {
335 if (isSubstitutionServiceTemplate(substituteServiceTemplateFileName, substituteServiceTemplate)) {
336 Map<String, List<String>> substitutionMappingRequirements =
337 substituteServiceTemplate.getTopology_template().getSubstitution_mappings().getRequirements();
338 if (substitutionMappingRequirements != null) {
339 List<String> requirementMapping = substitutionMappingRequirements.get(requirementId);
340 if (requirementMapping != null && !requirementMapping.isEmpty()) {
341 String mappedNodeTemplateId = requirementMapping.get(0);
342 Optional<NodeTemplate> mappedNodeTemplate =
343 getNodeTemplateById(substituteServiceTemplate, mappedNodeTemplateId);
344 mappedNodeTemplate.orElseThrow(() -> new CoreException(
345 new ToscaInvalidEntryNotFoundErrorBuilder("Node Template", mappedNodeTemplateId).build()));
346 Map.Entry<String, NodeTemplate> mappedNodeTemplateEntry = new Map.Entry<String, NodeTemplate>() {
348 public String getKey() {
349 return mappedNodeTemplateId;
353 public NodeTemplate getValue() {
354 return mappedNodeTemplate.get();
358 public NodeTemplate setValue(NodeTemplate value) {
362 return Optional.of(mappedNodeTemplateEntry);
366 return Optional.empty();
370 match only for the input which is not null
373 public boolean isDesiredRequirementAssignment(RequirementAssignment requirementAssignment, String capability,
374 String node, String relationship) {
375 if (isSameCapability(requirementAssignment, capability)) {
379 if (isSameRequirement(requirementAssignment, node)) {
383 if (isSameRelationship(requirementAssignment, relationship)) {
387 return !(capability == null && node == null && relationship == null);
391 private boolean isSameRelationship(RequirementAssignment requirementAssignment, String relationship) {
392 return relationship != null
393 && (requirementAssignment.getRelationship() == null
394 || !requirementAssignment.getRelationship().equals(relationship));
397 private boolean isSameRequirement(RequirementAssignment requirementAssignment, String node) {
398 return node != null && (requirementAssignment.getNode() == null || !requirementAssignment.getNode()
402 private boolean isSameCapability(RequirementAssignment requirementAssignment, String capability) {
403 return capability != null && (requirementAssignment.getCapability() == null || !requirementAssignment
405 .equals(capability));
409 public ToscaFlatData getFlatEntity(ToscaElementTypes elementType, String typeId, ServiceTemplate serviceTemplate,
410 ToscaServiceModel toscaModel) {
411 ToscaFlatData flatData = new ToscaFlatData();
412 flatData.setElementType(elementType);
414 switch (elementType) {
415 case CAPABILITY_TYPE:
416 flatData.setFlatEntity(new CapabilityType());
419 flatData.setFlatEntity(new NodeType());
422 flatData.setFlatEntity(new DataType());
425 throw new SdcRuntimeException("Entity[" + elementType + "] id[" + typeId + "] flat not supported");
428 boolean isEntityFound =
429 scanAnFlatEntity(elementType, typeId, flatData, serviceTemplate, toscaModel, new ArrayList<>(), 0);
430 if (!isEntityFound) {
431 throw new CoreException(new ToscaElementTypeNotFoundErrorBuilder(typeId).build());
438 public boolean isSubstitutableNodeTemplate(NodeTemplate nodeTemplate) {
439 return nodeTemplate.getDirectives() != null && nodeTemplate.getDirectives().contains(
440 ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
443 private <T> Optional<Boolean> isTypeExistInServiceTemplateHierarchy(String typeToMatch, String typeToSearch,
444 String getTypesMethodName, ServiceTemplate serviceTemplate, ToscaServiceModel toscaServiceModel,
445 Set<String> analyzedImportFiles)
446 throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
447 Map<String, T> searchableTypes =
448 (Map<String, T>) serviceTemplate.getClass().getMethod(getTypesMethodName).invoke(serviceTemplate);
450 if (!MapUtils.isEmpty(searchableTypes)) {
451 T typeObject = searchableTypes.get(typeToSearch);
452 if (Objects.nonNull(typeObject)) {
453 String derivedFromTypeVal =
454 (String) typeObject.getClass().getMethod(GET_DERIVED_FROM_METHOD_NAME).invoke(typeObject);
455 if (Objects.equals(derivedFromTypeVal, typeToMatch)) {
456 return Optional.of(true);
457 } else if (Objects.isNull(derivedFromTypeVal) || isTypeIsToscaRoot(derivedFromTypeVal)) {
458 return Optional.of(false);
460 return isTypeExistInServiceTemplateHierarchy(typeToMatch, derivedFromTypeVal, getTypesMethodName,
461 serviceTemplate, toscaServiceModel, null);
464 return isTypeExistInImports(typeToMatch, typeToSearch, getTypesMethodName, serviceTemplate,
465 toscaServiceModel, analyzedImportFiles);
468 return isTypeExistInImports(typeToMatch, typeToSearch, getTypesMethodName, serviceTemplate, toscaServiceModel,
469 analyzedImportFiles);
472 private Optional<Boolean> isTypeExistInImports(String typeToMatch, String typeToSearch, String getTypesMethodName,
473 ServiceTemplate serviceTemplate, ToscaServiceModel toscaServiceModel, Set<String> filesScanned)
474 throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
475 List<Map<String, Import>> imports = serviceTemplate.getImports();
476 if (CollectionUtils.isEmpty(imports)) {
477 return Optional.empty();
480 Set<String> createdFilesScanned = createFilesScannedSet(filesScanned);
482 for (Map<String, Import> map : imports) {
483 ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
484 Import anImport = toscaExtensionYamlUtil
485 .yamlToObject(toscaExtensionYamlUtil.objectToYaml(map.values().iterator().next()),
487 handleImportWithNoFileEntry(anImport);
488 String importFile = anImport.getFile();
489 ServiceTemplate template = toscaServiceModel.getServiceTemplates().get(fetchFileNameForImport(importFile,
490 serviceTemplate.getMetadata() == null ? null : serviceTemplate.getMetadata().get("filename")));
491 if (Objects.isNull(template) || createdFilesScanned
492 .contains(ToscaUtil.getServiceTemplateFileName(template))) {
495 createdFilesScanned.add(ToscaUtil.getServiceTemplateFileName(template));
497 Optional<Boolean> typeExistInServiceTemplateHierarchy =
498 isTypeExistInServiceTemplateHierarchy(typeToMatch, typeToSearch, getTypesMethodName, template,
499 toscaServiceModel, createdFilesScanned);
500 if (typeExistInServiceTemplateHierarchy.isPresent() && (typeExistInServiceTemplateHierarchy.get())) {
501 createdFilesScanned.clear();
502 return Optional.of(true);
506 return Optional.of(false);
509 private void handleImportWithNoFileEntry(Import anImport) {
510 if (Objects.isNull(anImport) || Objects.isNull(anImport.getFile())) {
511 throw new SdcRuntimeException("import without file entry");
515 private Set<String> createFilesScannedSet(Set<String> filesScanned) {
516 Set<String> retFileScanned = filesScanned;
517 if (Objects.isNull(retFileScanned)) {
518 retFileScanned = new HashSet<>();
520 return retFileScanned;
523 private boolean isTypeIsToscaRoot(String type) {
524 return (type.contains(TOSCA_DOT) && type.contains(DOT_ROOT));
527 private boolean isSubstitutionServiceTemplate(String substituteServiceTemplateFileName,
528 ServiceTemplate substituteServiceTemplate) {
529 if (substituteServiceTemplate != null && substituteServiceTemplate.getTopology_template() != null
530 && substituteServiceTemplate.getTopology_template().getSubstitution_mappings() != null) {
531 if (substituteServiceTemplate.getTopology_template().getSubstitution_mappings().getNode_type() == null) {
532 throw new CoreException(
533 new ToscaInvalidSubstitutionServiceTemplateErrorBuilder(substituteServiceTemplateFileName)
542 private boolean scanAnFlatEntity(ToscaElementTypes elementType, String typeId, ToscaFlatData flatData,
543 ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel, List<String> filesScanned,
544 int rootScanStartInx) {
547 boolean entityFound =
548 enrichEntityFromCurrentServiceTemplate(elementType, typeId, flatData, serviceTemplate, toscaModel,
549 filesScanned, rootScanStartInx);
551 List<Map<String, Import>> imports = serviceTemplate.getImports();
552 if (CollectionUtils.isEmpty(imports)) {
555 boolean found = false;
556 for (Map<String, Import> importMap : imports) {
560 found = isFlatEntity(importMap, flatData, serviceTemplate, filesScanned, toscaModel, elementType,
568 private boolean isFlatEntity(Map<String, Import> importMap, ToscaFlatData flatData, ServiceTemplate serviceTemplate,
569 List<String> filesScanned, ToscaServiceModel toscaModel, ToscaElementTypes elementType, String typeId) {
570 boolean found = false;
571 ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
572 for (Object importObject : importMap.values()) {
573 Import importServiceTemplate = toscaExtensionYamlUtil
574 .yamlToObject(toscaExtensionYamlUtil.objectToYaml(importObject),
576 String fileName = fetchFileNameForImport(importServiceTemplate.getFile(),
577 serviceTemplate.getMetadata() == null ? null : serviceTemplate.getMetadata().get("filename"));
578 if (filesScanned.contains(fileName)) {
581 filesScanned.add(fileName);
583 ServiceTemplate template = toscaModel.getServiceTemplates().get(fileName);
584 if (Objects.isNull(template)) {
585 throw new CoreException(new ToscaFileNotFoundErrorBuilder(fileName).build());
587 found = scanAnFlatEntity(elementType, typeId, flatData, template, toscaModel, filesScanned,
588 filesScanned.size());
593 private String fetchFileNameForImport(String importServiceTemplateFile, String currentMetadatafileName) {
594 if (importServiceTemplateFile.contains("../")) {
595 return importServiceTemplateFile.replace("../", "");
596 } else if (currentMetadatafileName != null && currentMetadatafileName.indexOf('/') != -1) {
597 return currentMetadatafileName.substring(0, currentMetadatafileName.indexOf('/')) + "/"
598 + importServiceTemplateFile;
600 return importServiceTemplateFile;
605 private boolean enrichEntityFromCurrentServiceTemplate(ToscaElementTypes elementType, String typeId,
606 ToscaFlatData flatData, ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel,
607 List<String> filesScanned, int rootScanStartInx) {
608 switch (elementType) {
609 case CAPABILITY_TYPE:
610 if (enrichCapabilityType(elementType, typeId, flatData, serviceTemplate, toscaModel, filesScanned,
616 if (enrichNodeTypeInfo(elementType, typeId, flatData, serviceTemplate, toscaModel, filesScanned,
622 if (enrichDataTypeInfo(elementType, typeId, flatData, serviceTemplate, toscaModel, filesScanned,
628 throw new SdcRuntimeException("Entity[" + elementType + "] id[" + typeId + "] flat not supported");
636 private boolean enrichNodeTypeInfo(ToscaElementTypes elementType, String typeId, ToscaFlatData flatData,
637 ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel, List<String> filesScanned,
638 int rootScanStartInx) {
640 if (serviceTemplate.getNode_types() != null && serviceTemplate.getNode_types().containsKey(typeId)) {
642 filesScanned.clear();
643 flatData.addInheritanceHierarchyType(typeId);
644 NodeType targetNodeType = (NodeType) flatData.getFlatEntity();
645 NodeType sourceNodeType = serviceTemplate.getNode_types().get(typeId);
646 derivedFrom = sourceNodeType.getDerived_from();
647 if (derivedFrom != null) {
648 boolean isEntityFound =
649 scanAnFlatEntity(elementType, derivedFrom, flatData, serviceTemplate, toscaModel, filesScanned,
651 if (!isEntityFound) {
652 throw new CoreException(new ToscaElementTypeNotFoundErrorBuilder(typeId).build());
655 combineNodeTypeInfo(sourceNodeType, targetNodeType);
662 private boolean enrichDataTypeInfo(ToscaElementTypes elementType, String typeId, ToscaFlatData flatData,
663 ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel, List<String> filesScanned,
664 int rootScanStartInx) {
666 if (serviceTemplate.getData_types() != null && serviceTemplate.getData_types().containsKey(typeId)) {
668 filesScanned.clear();
669 flatData.addInheritanceHierarchyType(typeId);
670 DataType targetDataType = (DataType) flatData.getFlatEntity();
671 DataType sourceDataType = serviceTemplate.getData_types().get(typeId);
672 derivedFrom = sourceDataType.getDerived_from();
673 if (derivedFrom != null && !isPrimitiveType(derivedFrom)) {
674 boolean isEntityFound =
675 scanAnFlatEntity(elementType, derivedFrom, flatData, serviceTemplate, toscaModel, filesScanned,
677 if (!isEntityFound) {
678 throw new CoreException(new ToscaElementTypeNotFoundErrorBuilder(typeId).build());
681 combineDataTypeInfo(sourceDataType, targetDataType);
688 private static boolean isPrimitiveType(String toscaType) {
689 return (toscaType.equals(PropertyType.STRING.getDisplayName()) || toscaType.equals(PropertyType.INTEGER
691 || toscaType.equals(PropertyType.FLOAT.getDisplayName()));
694 private boolean enrichCapabilityType(ToscaElementTypes elementType, String typeId, ToscaFlatData flatData,
695 ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel, List<String> filesScanned,
696 int rootScanStartInx) {
698 if (serviceTemplate.getCapability_types() != null && serviceTemplate.getCapability_types()
699 .containsKey(typeId)) {
701 filesScanned.clear();
702 flatData.addInheritanceHierarchyType(typeId);
703 CapabilityType targetCapabilityType = (CapabilityType) flatData.getFlatEntity();
704 CapabilityType sourceCapabilityType = serviceTemplate.getCapability_types().get(typeId);
705 derivedFrom = sourceCapabilityType.getDerived_from();
706 if (derivedFrom != null) {
707 boolean isEntityFound =
708 scanAnFlatEntity(elementType, derivedFrom, flatData, serviceTemplate, toscaModel, filesScanned,
710 if (!isEntityFound) {
711 throw new CoreException(new ToscaElementTypeNotFoundErrorBuilder(typeId).build());
714 combineCapabilityTypeInfo(sourceCapabilityType, targetCapabilityType);
721 private void combineNodeTypeInfo(NodeType sourceNodeType, NodeType targetNodeType) {
722 targetNodeType.setDerived_from(sourceNodeType.getDerived_from());
723 targetNodeType.setDescription(sourceNodeType.getDescription());
724 targetNodeType.setVersion(sourceNodeType.getVersion());
726 .setProperties(CommonMethods.mergeMaps(targetNodeType.getProperties(), sourceNodeType.getProperties()));
727 combineNodeTypeInterfaceInfo(sourceNodeType, targetNodeType);
729 .setArtifacts(CommonMethods.mergeMaps(targetNodeType.getArtifacts(), sourceNodeType.getArtifacts()));
731 .setAttributes(CommonMethods.mergeMaps(targetNodeType.getAttributes(), sourceNodeType.getAttributes()));
732 targetNodeType.setCapabilities(
733 CommonMethods.mergeMaps(targetNodeType.getCapabilities(), sourceNodeType.getCapabilities()));
734 targetNodeType.setRequirements(
735 CommonMethods.mergeListsOfMap(targetNodeType.getRequirements(), sourceNodeType.getRequirements()));
739 private void combineNodeTypeInterfaceInfo(NodeType sourceNodeType, NodeType targetNodeType) {
740 Optional<Map<String, Object>> interfaceNoMerge = combineInterfaceNoMerge(sourceNodeType, targetNodeType);
741 if (interfaceNoMerge.isPresent()) {
742 targetNodeType.setInterfaces(interfaceNoMerge.get());
745 targetNodeType.setInterfaces(combineInterfaces(sourceNodeType, targetNodeType));
748 private Map<String, Object> combineInterfaces(NodeType sourceNodeType, NodeType targetNodeType) {
749 Map<String, Object> combineInterfaces = new HashMap<>();
750 for (Map.Entry<String, Object> sourceInterfaceDefEntry : sourceNodeType.getInterfaces().entrySet()) {
751 String interfaceName = sourceInterfaceDefEntry.getKey();
752 if (!MapUtils.isEmpty(targetNodeType.getInterfaces()) && targetNodeType.getInterfaces()
753 .containsKey(interfaceName)) {
754 combineInterfaces.put(interfaceName,
755 combineInterfaceDefinition(sourceInterfaceDefEntry.getValue(),
756 targetNodeType.getInterfaces().get(interfaceName)));
758 combineInterfaces.put(sourceInterfaceDefEntry.getKey(), sourceInterfaceDefEntry.getValue());
762 for (Map.Entry<String, Object> targetInterfaceDefEntry : targetNodeType.getInterfaces().entrySet()) {
763 String interfaceName = targetInterfaceDefEntry.getKey();
764 if (!sourceNodeType.getInterfaces().containsKey(interfaceName)) {
765 combineInterfaces.put(targetInterfaceDefEntry.getKey(), targetInterfaceDefEntry.getValue());
769 return combineInterfaces;
772 private Optional<Map<String, Object>> combineInterfaceNoMerge(NodeType sourceNodeType, NodeType targetNodeType) {
773 if ((MapUtils.isEmpty(sourceNodeType.getInterfaces()) && MapUtils.isEmpty(targetNodeType.getInterfaces()))) {
774 return Optional.empty();
777 if (MapUtils.isEmpty(sourceNodeType.getInterfaces()) && !MapUtils.isEmpty(targetNodeType.getInterfaces())) {
778 return Optional.of(targetNodeType.getInterfaces());
781 if (!MapUtils.isEmpty(sourceNodeType.getInterfaces()) && MapUtils.isEmpty(targetNodeType.getInterfaces())) {
782 return Optional.of(sourceNodeType.getInterfaces());
784 return Optional.empty();
788 private Object combineInterfaceDefinition(Object sourceInterfaceDefType, Object targetInterfaceDefType) {
789 InterfaceDefinitionType sourceInterface = new InterfaceDefinitionType(sourceInterfaceDefType);
790 InterfaceDefinitionType targetInterface = new InterfaceDefinitionType(targetInterfaceDefType);
791 InterfaceDefinitionType combineInterface = new InterfaceDefinitionType();
792 combineInterface.setType(sourceInterface.getType());
793 combineInterface.setInputs(CommonMethods.mergeMaps(targetInterface.getInputs(), sourceInterface.getInputs()));
794 combineInterface.setOperations(
795 CommonMethods.mergeMaps(targetInterface.getOperations(), sourceInterface.getOperations()));
797 Optional<Object> interfaceDefObject = combineInterface.convertInterfaceDefinitionTypeToToscaObj();
798 if (!interfaceDefObject.isPresent()) {
799 throw new SdcRuntimeException("Illegal Statement");
801 return interfaceDefObject.get();
804 private void combineDataTypeInfo(DataType sourceDataType, DataType targetDataType) {
805 targetDataType.setDerived_from(sourceDataType.getDerived_from());
806 targetDataType.setDescription(sourceDataType.getDescription());
807 targetDataType.setVersion(sourceDataType.getVersion());
809 .setProperties(CommonMethods.mergeMaps(targetDataType.getProperties(), sourceDataType.getProperties()));
810 targetDataType.setConstraints(
811 CommonMethods.mergeLists(targetDataType.getConstraints(), sourceDataType.getConstraints()));
814 private void combineCapabilityTypeInfo(CapabilityType sourceCapabilityType, CapabilityType targetCapabilityType) {
816 targetCapabilityType.setAttributes(
817 CommonMethods.mergeMaps(targetCapabilityType.getAttributes(), sourceCapabilityType.getAttributes()));
818 targetCapabilityType.setProperties(
819 CommonMethods.mergeMaps(targetCapabilityType.getProperties(), sourceCapabilityType.getProperties()));
820 targetCapabilityType.setValid_source_types(CommonMethods
821 .mergeLists(targetCapabilityType.getValid_source_types(),
822 sourceCapabilityType.getValid_source_types()));
824 if (StringUtils.isNotEmpty(sourceCapabilityType.getDerived_from())) {
825 targetCapabilityType.setDerived_from(sourceCapabilityType.getDerived_from());
827 if (StringUtils.isNotEmpty(sourceCapabilityType.getDescription())) {
828 targetCapabilityType.setDescription(sourceCapabilityType.getDescription());
830 if (StringUtils.isNotEmpty(sourceCapabilityType.getVersion())) {
831 targetCapabilityType.setVersion(sourceCapabilityType.getVersion());
839 * Create node type according to the input substitution service template, while the substitution
840 * service template can be mappted to this node type, for substitution mapping.
842 * @param substitutionServiceTemplate substitution serivce template
843 * @param nodeTypeDerivedFromValue derived from value for the created node type
844 * @return the node type
847 public NodeType createInitSubstitutionNodeType(ServiceTemplate substitutionServiceTemplate,
848 String nodeTypeDerivedFromValue) {
849 NodeType substitutionNodeType = new NodeType();
850 substitutionNodeType.setDerived_from(nodeTypeDerivedFromValue);
851 substitutionNodeType.setDescription(substitutionServiceTemplate.getDescription());
852 substitutionNodeType.setProperties(manageSubstitutionNodeTypeProperties(substitutionServiceTemplate));
853 substitutionNodeType.setAttributes(manageSubstitutionNodeTypeAttributes(substitutionServiceTemplate));
854 return substitutionNodeType;
858 public Map<String, PropertyDefinition> manageSubstitutionNodeTypeProperties(
859 ServiceTemplate substitutionServiceTemplate) {
860 Map<String, PropertyDefinition> substitutionNodeTypeProperties = new HashMap<>();
861 Map<String, ParameterDefinition> properties = substitutionServiceTemplate.getTopology_template().getInputs();
862 if (properties == null) {
866 PropertyDefinition propertyDefinition;
867 String toscaPropertyName;
868 for (Map.Entry<String, ParameterDefinition> entry : properties.entrySet()) {
869 toscaPropertyName = entry.getKey();
870 propertyDefinition = new PropertyDefinition();
871 ParameterDefinition parameterDefinition =
872 substitutionServiceTemplate.getTopology_template().getInputs().get(toscaPropertyName);
873 propertyDefinition.setType(parameterDefinition.getType());
874 propertyDefinition.setDescription(parameterDefinition.getDescription());
875 propertyDefinition.set_default(parameterDefinition.get_default());
876 if (parameterDefinition.getRequired() != null) {
877 propertyDefinition.setRequired(parameterDefinition.getRequired());
879 if (propertyDefinition.get_default() != null) {
880 propertyDefinition.setRequired(false);
882 if (!CollectionUtils.isEmpty(parameterDefinition.getConstraints())) {
883 propertyDefinition.setConstraints(parameterDefinition.getConstraints());
885 propertyDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
886 if (parameterDefinition.getStatus() != null) {
887 propertyDefinition.setStatus(parameterDefinition.getStatus());
889 substitutionNodeTypeProperties.put(toscaPropertyName, propertyDefinition);
891 return substitutionNodeTypeProperties;
895 private Map<String, AttributeDefinition> manageSubstitutionNodeTypeAttributes(
896 ServiceTemplate substitutionServiceTemplate) {
897 Map<String, AttributeDefinition> substitutionNodeTypeAttributes = new HashMap<>();
898 Map<String, ParameterDefinition> attributes = substitutionServiceTemplate.getTopology_template().getOutputs();
899 if (attributes == null) {
902 AttributeDefinition attributeDefinition;
903 String toscaAttributeName;
905 for (Map.Entry<String, ParameterDefinition> entry : attributes.entrySet()) {
906 attributeDefinition = new AttributeDefinition();
907 toscaAttributeName = entry.getKey();
908 ParameterDefinition parameterDefinition =
909 substitutionServiceTemplate.getTopology_template().getOutputs().get(toscaAttributeName);
910 if (parameterDefinition.getType() != null && !parameterDefinition.getType().isEmpty()) {
911 attributeDefinition.setType(parameterDefinition.getType());
913 attributeDefinition.setType(PropertyType.STRING.getDisplayName());
915 attributeDefinition.setDescription(parameterDefinition.getDescription());
916 attributeDefinition.set_default(parameterDefinition.get_default());
917 attributeDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
918 if (Objects.nonNull(parameterDefinition.getStatus())) {
919 attributeDefinition.setStatus(parameterDefinition.getStatus());
921 substitutionNodeTypeAttributes.put(toscaAttributeName, attributeDefinition);
923 return substitutionNodeTypeAttributes;
927 * Checks if the requirement exists in the node template.
929 * @param nodeTemplate the node template
930 * @param requirementId the requirement id
931 * @param requirementAssignment the requirement assignment
932 * @return true if the requirement already exists and false otherwise
935 public boolean isRequirementExistInNodeTemplate(NodeTemplate nodeTemplate, String requirementId,
936 RequirementAssignment requirementAssignment) {
937 List<Map<String, RequirementAssignment>> nodeTemplateRequirements = nodeTemplate.getRequirements();
938 return nodeTemplateRequirements != null && nodeTemplateRequirements.stream().anyMatch(
939 requirement -> requirement.containsKey(requirementId) && DataModelUtil.compareRequirementAssignment(
940 requirementAssignment, requirement.get(requirementId)));
943 private <T> boolean isTypeOf(T object, String type, String getTypesMethodName, ServiceTemplate serviceTemplate,
944 ToscaServiceModel toscaServiceModel) {
945 if (object == null) {
950 String objectType = (String) object.getClass().getMethod(GET_TYPE_METHOD_NAME).invoke(object);
951 if (Objects.equals(objectType, type)) {
955 Optional<Boolean> typeExistInServiceTemplateHierarchy =
956 isTypeExistInServiceTemplateHierarchy(type, objectType, getTypesMethodName, serviceTemplate,
957 toscaServiceModel, null);
958 return typeExistInServiceTemplateHierarchy.orElseThrow(
959 () -> new CoreException(new ToscaElementTypeNotFoundErrorBuilder(objectType).build()));
961 } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
962 throw new SdcRuntimeException(e);