2 * Copyright © 2016-2018 European Support Limited
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.openecomp.sdc.tosca.services.impl;
19 import org.apache.commons.collections4.CollectionUtils;
20 import org.apache.commons.collections4.MapUtils;
21 import org.apache.commons.lang3.StringUtils;
22 import org.openecomp.core.utilities.CommonMethods;
23 import org.openecomp.sdc.common.errors.CoreException;
24 import org.openecomp.sdc.tosca.datatypes.ToscaElementTypes;
25 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
26 import org.openecomp.sdc.tosca.datatypes.model.AttributeDefinition;
27 import org.openecomp.sdc.tosca.datatypes.model.CapabilityDefinition;
28 import org.openecomp.sdc.tosca.datatypes.model.CapabilityType;
29 import org.openecomp.sdc.tosca.datatypes.model.DefinitionOfDataType;
30 import org.openecomp.sdc.tosca.datatypes.model.Import;
31 import org.openecomp.sdc.tosca.datatypes.model.InterfaceDefinitionType;
32 import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
33 import org.openecomp.sdc.tosca.datatypes.model.NodeType;
34 import org.openecomp.sdc.tosca.datatypes.model.ParameterDefinition;
35 import org.openecomp.sdc.tosca.datatypes.model.PropertyDefinition;
36 import org.openecomp.sdc.tosca.datatypes.model.PropertyType;
37 import org.openecomp.sdc.tosca.datatypes.model.RequirementAssignment;
38 import org.openecomp.sdc.tosca.datatypes.model.RequirementDefinition;
39 import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate;
40 import org.openecomp.sdc.tosca.errors.ToscaElementTypeNotFoundErrorBuilder;
41 import org.openecomp.sdc.tosca.errors.ToscaInvalidEntryNotFoundErrorBuilder;
42 import org.openecomp.sdc.tosca.errors.ToscaInvalidSubstituteNodeTemplatePropertiesErrorBuilder;
43 import org.openecomp.sdc.tosca.errors.ToscaInvalidSubstitutionServiceTemplateErrorBuilder;
44 import org.openecomp.sdc.tosca.services.DataModelUtil;
45 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
46 import org.openecomp.sdc.tosca.services.ToscaConstants;
47 import org.openecomp.sdc.tosca.services.ToscaExtensionYamlUtil;
48 import org.openecomp.sdc.tosca.services.ToscaUtil;
50 import java.lang.reflect.InvocationTargetException;
51 import java.util.ArrayList;
52 import java.util.Collection;
53 import java.util.Collections;
54 import java.util.HashMap;
55 import java.util.HashSet;
56 import java.util.List;
58 import java.util.Objects;
59 import java.util.Optional;
62 public class ToscaAnalyzerServiceImpl implements ToscaAnalyzerService {
63 private final String GET_NODE_TYPE_METHOD_NAME = "getNode_types";
64 private final String GET_DERIVED_FROM_METHOD_NAME = "getDerived_from";
65 private final String GET_TYPE_METHOD_NAME = "getType";
66 private final String GET_DATA_TYPE_METHOD_NAME = "getData_types";
67 private final String GET_INTERFACE_TYPE_METHOD_NAME = "getInterface_types";
68 private final String TOSCA_DOT = "tosca.";
69 private final String DOT_ROOT = ".Root";
72 public List<Map<String, RequirementDefinition>> calculateExposedRequirements(
73 List<Map<String, RequirementDefinition>> nodeTypeRequirementsDefinitionList,
74 Map<String, RequirementAssignment> nodeTemplateRequirementsAssignment) {
76 if (nodeTypeRequirementsDefinitionList == null) {
77 return Collections.emptyList();
79 for (Map.Entry<String, RequirementAssignment> entry : nodeTemplateRequirementsAssignment
81 if (entry.getValue().getNode() != null) {
82 Optional<RequirementDefinition> requirementDefinition =
83 DataModelUtil.getRequirementDefinition(nodeTypeRequirementsDefinitionList, entry
85 RequirementDefinition cloneRequirementDefinition;
86 if (requirementDefinition.isPresent()) {
87 cloneRequirementDefinition = requirementDefinition.get().clone();
88 updateRequirementDefinition(nodeTypeRequirementsDefinitionList, entry,
89 cloneRequirementDefinition);
92 for (Map<String, RequirementDefinition> nodeTypeRequirementsMap :
93 nodeTypeRequirementsDefinitionList) {
94 updateMinMaxOccurencesForNodeTypeRequirement(entry, nodeTypeRequirementsMap);
98 return nodeTypeRequirementsDefinitionList;
101 private void updateMinMaxOccurencesForNodeTypeRequirement(
102 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,
116 RequirementDefinition cloneRequirementDefinition) {
117 if (!evaluateRequirementFulfillment(cloneRequirementDefinition)) {
118 CommonMethods.mergeEntryInList(entry.getKey(), cloneRequirementDefinition,
119 nodeTypeRequirementsDefinitionList);
121 DataModelUtil.removeRequirementsDefinition(nodeTypeRequirementsDefinitionList, entry
126 private static boolean evaluateRequirementFulfillment(RequirementDefinition
127 requirementDefinition) {
128 Object[] occurrences = requirementDefinition.getOccurrences();
129 if (occurrences == null) {
130 requirementDefinition.setOccurrences(new Object[]{1, 1});
133 if (occurrences[1].equals(ToscaConstants.UNBOUNDED)) {
137 if (occurrences[1].equals(1)) {
140 occurrences[1] = (Integer) occurrences[1] - 1;
145 public Map<String, CapabilityDefinition> calculateExposedCapabilities(
146 Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition,
147 Map<String, Map<String, RequirementAssignment>> fullFilledRequirementsDefinitionMap) {
149 String capabilityKey;
152 for (Map.Entry<String, Map<String, RequirementAssignment>> entry :
153 fullFilledRequirementsDefinitionMap.entrySet()) {
154 for (Map.Entry<String, RequirementAssignment> fullFilledEntry : entry.getValue().entrySet()) {
156 capability = fullFilledEntry.getValue().getCapability();
157 node = fullFilledEntry.getValue().getNode();
158 capabilityKey = capability + "_" + node;
159 CapabilityDefinition capabilityDefinition = nodeTypeCapabilitiesDefinition.get(
161 if (capabilityDefinition != null) {
162 CapabilityDefinition clonedCapabilityDefinition = capabilityDefinition.clone();
163 nodeTypeCapabilitiesDefinition.put(capabilityKey, capabilityDefinition.clone());
164 updateNodeTypeCapabilitiesDefinition(nodeTypeCapabilitiesDefinition, capabilityKey,
165 clonedCapabilityDefinition);
170 Map<String, CapabilityDefinition> exposedCapabilitiesDefinition = new HashMap<>();
171 for (Map.Entry<String, CapabilityDefinition> entry : nodeTypeCapabilitiesDefinition
173 exposedCapabilitiesDefinition.put(entry.getKey(), entry.getValue());
175 return exposedCapabilitiesDefinition;
178 private void updateNodeTypeCapabilitiesDefinition(
179 Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition, String capabilityKey,
180 CapabilityDefinition clonedCapabilityDefinition) {
181 if (evaluateCapabilityFulfillment(clonedCapabilityDefinition)) {
182 nodeTypeCapabilitiesDefinition.remove(capabilityKey);
184 nodeTypeCapabilitiesDefinition.put(capabilityKey, clonedCapabilityDefinition);
188 private static boolean evaluateCapabilityFulfillment(CapabilityDefinition capabilityDefinition) {
190 Object[] occurrences = capabilityDefinition.getOccurrences();
191 if (occurrences == null) {
192 capabilityDefinition.setOccurrences(new Object[]{1, ToscaConstants.UNBOUNDED});
195 if (occurrences[1].equals(ToscaConstants.UNBOUNDED)) {
199 if (occurrences[1].equals(1)) {
202 occurrences[1] = (Integer) occurrences[1] - 1;
207 node template with type equal to node type or derived from node type
210 public Map<String, NodeTemplate> getNodeTemplatesByType(ServiceTemplate serviceTemplate,
212 ToscaServiceModel toscaServiceModel) {
213 Map<String, NodeTemplate> nodeTemplates = new HashMap<>();
215 if (Objects.nonNull(serviceTemplate.getTopology_template())
216 && MapUtils.isNotEmpty(serviceTemplate.getTopology_template().getNode_templates())) {
217 for (Map.Entry<String, NodeTemplate> nodeTemplateEntry : serviceTemplate
218 .getTopology_template().getNode_templates().entrySet()) {
219 if (isTypeOf(nodeTemplateEntry.getValue(), nodeType, serviceTemplate, toscaServiceModel)) {
220 nodeTemplates.put(nodeTemplateEntry.getKey(), nodeTemplateEntry.getValue());
225 return nodeTemplates;
229 public Optional<NodeType> fetchNodeType(String nodeTypeKey, Collection<ServiceTemplate>
231 Optional<Map<String, NodeType>> nodeTypeMap = serviceTemplates.stream()
232 .map(ServiceTemplate::getNode_types)
233 .filter(nodeTypes -> Objects.nonNull(nodeTypes) && nodeTypes.containsKey(nodeTypeKey))
235 return nodeTypeMap.map(stringNodeTypeMap -> stringNodeTypeMap.get(nodeTypeKey));
239 public boolean isTypeOf(NodeTemplate nodeTemplate, String nodeType,
240 ServiceTemplate serviceTemplate, ToscaServiceModel toscaServiceModel) {
241 return isTypeOf(nodeTemplate, nodeType, GET_NODE_TYPE_METHOD_NAME, serviceTemplate,
246 public List<RequirementAssignment> getRequirements(NodeTemplate nodeTemplate,
247 String requirementId) {
248 List<RequirementAssignment> requirements = new ArrayList<>();
249 List<Map<String, RequirementAssignment>> requirementList = nodeTemplate.getRequirements();
250 if (requirementList != null) {
251 requirementList.stream().filter(reqMap -> reqMap.get(requirementId) != null)
253 ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
254 RequirementAssignment reqAssignment = toscaExtensionYamlUtil
255 .yamlToObject(toscaExtensionYamlUtil.objectToYaml(reqMap.get(requirementId)),
256 RequirementAssignment.class);
257 requirements.add(reqAssignment);
264 public Optional<NodeTemplate> getNodeTemplateById(ServiceTemplate serviceTemplate,
265 String nodeTemplateId) {
266 if ((serviceTemplate.getTopology_template() != null)
267 && (serviceTemplate.getTopology_template().getNode_templates() != null)
268 && (serviceTemplate.getTopology_template().getNode_templates().get(nodeTemplateId)
271 .of(serviceTemplate.getTopology_template().getNode_templates().get(nodeTemplateId));
273 return Optional.empty();
277 public Optional<String> getSubstituteServiceTemplateName(String substituteNodeTemplateId,
278 NodeTemplate substitutableNodeTemplate) {
279 if (!isSubstitutableNodeTemplate(substitutableNodeTemplate)) {
280 return Optional.empty();
283 if (substitutableNodeTemplate.getProperties() != null
284 && substitutableNodeTemplate.getProperties()
285 .get(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME) != null) {
286 Object serviceTemplateFilter = substitutableNodeTemplate.getProperties()
287 .get(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME);
288 if (serviceTemplateFilter != null && serviceTemplateFilter instanceof Map) {
289 Object substituteServiceTemplate = ((Map) serviceTemplateFilter)
290 .get(ToscaConstants.SUBSTITUTE_SERVICE_TEMPLATE_PROPERTY_NAME);
291 handleNoSubstituteServiceTemplate(substituteNodeTemplateId, substituteServiceTemplate);
292 return Optional.of(substituteServiceTemplate.toString());
295 throw new CoreException(
296 new ToscaInvalidSubstituteNodeTemplatePropertiesErrorBuilder(substituteNodeTemplateId)
300 private void handleNoSubstituteServiceTemplate(String substituteNodeTemplateId,
301 Object substituteServiceTemplate) {
302 if (substituteServiceTemplate == null) {
303 throw new CoreException(
304 new ToscaInvalidSubstituteNodeTemplatePropertiesErrorBuilder(substituteNodeTemplateId)
310 public Map<String, NodeTemplate> getSubstitutableNodeTemplates(ServiceTemplate serviceTemplate) {
311 Map<String, NodeTemplate> substitutableNodeTemplates = new HashMap<>();
313 if (serviceTemplate == null
314 || serviceTemplate.getTopology_template() == null
315 || serviceTemplate.getTopology_template().getNode_templates() == null) {
316 return substitutableNodeTemplates;
319 Map<String, NodeTemplate> nodeTemplates =
320 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,
335 String requirementId) {
336 if (isSubstitutionServiceTemplate(substituteServiceTemplateFileName,
337 substituteServiceTemplate)) {
338 Map<String, List<String>> substitutionMappingRequirements =
339 substituteServiceTemplate.getTopology_template().getSubstitution_mappings()
341 if (substitutionMappingRequirements != null) {
342 List<String> requirementMapping = substitutionMappingRequirements.get(requirementId);
343 if (requirementMapping != null && !requirementMapping.isEmpty()) {
344 String mappedNodeTemplateId = requirementMapping.get(0);
345 Optional<NodeTemplate> mappedNodeTemplate =
346 getNodeTemplateById(substituteServiceTemplate, mappedNodeTemplateId);
347 mappedNodeTemplate.orElseThrow(() -> new CoreException(
348 new ToscaInvalidEntryNotFoundErrorBuilder("Node Template", mappedNodeTemplateId)
350 Map.Entry<String, NodeTemplate> mappedNodeTemplateEntry =
351 new Map.Entry<String, NodeTemplate>() {
353 public String getKey() {
354 return mappedNodeTemplateId;
358 public NodeTemplate getValue() {
359 return mappedNodeTemplate.get();
363 public NodeTemplate setValue(NodeTemplate value) {
367 return Optional.of(mappedNodeTemplateEntry);
371 return Optional.empty();
375 match only for the input which is not null
378 public boolean isDesiredRequirementAssignment(RequirementAssignment requirementAssignment,
379 String capability, String node,
380 String relationship) {
381 if (isSameCapability(requirementAssignment, capability)) {
385 if (isSameRequirement(requirementAssignment, node)) {
389 if (isSameRelationship(requirementAssignment, relationship)) {
393 return !(capability == null && node == null && relationship == null);
397 private boolean isSameRelationship(RequirementAssignment requirementAssignment,
398 String relationship) {
399 return relationship != null && (requirementAssignment.getRelationship() == null
400 || !requirementAssignment.getRelationship().equals(relationship));
403 private boolean isSameRequirement(RequirementAssignment requirementAssignment, String node) {
404 return node != null && (requirementAssignment.getNode() == null
405 || !requirementAssignment.getNode().equals(node));
408 private boolean isSameCapability(RequirementAssignment requirementAssignment, String capability) {
409 return capability != null && (requirementAssignment.getCapability() == null
410 || !requirementAssignment.getCapability().equals(capability));
414 public Object getFlatEntity(ToscaElementTypes elementType, String typeId,
415 ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel) {
418 switch (elementType) {
419 case CAPABILITY_TYPE:
420 returnEntity = new CapabilityType();
423 returnEntity = new NodeType();
426 throw new RuntimeException(
427 "Entity[" + elementType + "] id[" + typeId + "] flat not supported");
430 scanAnFlatEntity(elementType, typeId, returnEntity, serviceTemplate, toscaModel,
431 new ArrayList<>(), 0);
438 public boolean isSubstitutableNodeTemplate(NodeTemplate nodeTemplate) {
439 return nodeTemplate.getDirectives() != null
440 && nodeTemplate.getDirectives().contains(ToscaConstants
441 .NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
444 private <T> Optional<Boolean> isTypeExistInServiceTemplateHierarchy(String typeToMatch,
446 String getTypesMethodName,
447 ServiceTemplate serviceTemplate,
448 ToscaServiceModel toscaServiceModel,
449 Set<String> analyzedImportFiles)
450 throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
451 Map<String, T> searchableTypes =
452 (Map<String, T>) serviceTemplate.getClass().getMethod(getTypesMethodName)
453 .invoke(serviceTemplate);
455 if (!MapUtils.isEmpty(searchableTypes)) {
456 T typeObject = searchableTypes.get(typeToSearch);
457 if (Objects.nonNull(typeObject)) {
458 String derivedFromTypeVal =
459 (String) typeObject.getClass().getMethod(GET_DERIVED_FROM_METHOD_NAME).invoke(typeObject);
460 if (Objects.equals(derivedFromTypeVal, typeToMatch)) {
461 return Optional.of(true);
462 } else if (Objects.isNull(derivedFromTypeVal) || isTypeIsToscaRoot(derivedFromTypeVal)) {
463 return Optional.of(false);
465 return isTypeExistInServiceTemplateHierarchy(typeToMatch,
466 derivedFromTypeVal, getTypesMethodName, serviceTemplate, toscaServiceModel, null);
469 return isTypeExistInImports(typeToMatch, typeToSearch, getTypesMethodName,
470 serviceTemplate, toscaServiceModel, analyzedImportFiles);
473 return isTypeExistInImports(typeToMatch, typeToSearch, getTypesMethodName, serviceTemplate,
474 toscaServiceModel, analyzedImportFiles);
477 private Optional<Boolean> isTypeExistInImports(String typeToMatch,
479 String getTypesMethodName,
480 ServiceTemplate serviceTemplate,
481 ToscaServiceModel toscaServiceModel,
482 Set<String> filesScanned)
483 throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
484 List<Map<String, Import>> imports = serviceTemplate.getImports();
485 if (CollectionUtils.isEmpty(imports)) {
486 return Optional.empty();
489 Set<String> createdFilesScanned = createFilesScannedSet(filesScanned);
491 for (Map<String, Import> map : imports) {
492 ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
493 Import anImport = toscaExtensionYamlUtil
494 .yamlToObject(toscaExtensionYamlUtil.objectToYaml(map.values().iterator().next()),
496 handleImportWithNoFileEntry(anImport);
497 String importFile = anImport.getFile();
498 ServiceTemplate template =
499 toscaServiceModel.getServiceTemplates().get(fetchFileNameForImport(importFile,
500 serviceTemplate.getMetadata() == null ? null
501 : serviceTemplate.getMetadata().get("filename")));
502 if (Objects.isNull(template)
503 || createdFilesScanned.contains(ToscaUtil.getServiceTemplateFileName(template))) {
506 createdFilesScanned.add(ToscaUtil.getServiceTemplateFileName(template));
508 Optional<Boolean> typeExistInServiceTemplateHierarchy =
509 isTypeExistInServiceTemplateHierarchy(typeToMatch, typeToSearch, getTypesMethodName,
510 template, toscaServiceModel, createdFilesScanned);
511 if (typeExistInServiceTemplateHierarchy.isPresent()
512 && (typeExistInServiceTemplateHierarchy.get())) {
513 createdFilesScanned.clear();
514 return Optional.of(true);
518 return Optional.of(false);
521 private void handleImportWithNoFileEntry(Import anImport) {
522 if (Objects.isNull(anImport) || Objects.isNull(anImport.getFile())) {
523 throw new RuntimeException("import without file entry");
527 private Set<String> createFilesScannedSet(Set<String> filesScanned) {
528 Set<String> retFileScanned = filesScanned;
529 if (Objects.isNull(retFileScanned)) {
530 retFileScanned = new HashSet<>();
532 return retFileScanned;
535 private boolean isTypeIsToscaRoot(String type) {
536 return (type.contains(TOSCA_DOT) && type.contains(DOT_ROOT));
539 private boolean isSubstitutionServiceTemplate(String substituteServiceTemplateFileName,
540 ServiceTemplate substituteServiceTemplate) {
541 if (substituteServiceTemplate != null
542 && substituteServiceTemplate.getTopology_template() != null
543 && substituteServiceTemplate.getTopology_template().getSubstitution_mappings() != null) {
544 if (substituteServiceTemplate.getTopology_template().getSubstitution_mappings()
545 .getNode_type() == null) {
546 throw new CoreException(new ToscaInvalidSubstitutionServiceTemplateErrorBuilder(
547 substituteServiceTemplateFileName).build());
555 private boolean scanAnFlatEntity(ToscaElementTypes elementType, String typeId, Object entity,
556 ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel,
557 List<String> filesScanned, int rootScanStartInx) {
560 boolean entityFound = enrichEntityFromCurrentServiceTemplate(elementType, typeId, entity,
561 serviceTemplate, toscaModel, filesScanned, rootScanStartInx);
563 List<Map<String, Import>> imports = serviceTemplate.getImports();
564 if (CollectionUtils.isEmpty(imports)) {
567 boolean found = false;
568 for (Map<String, Import> importMap : imports) {
572 found = isFlatEntity(importMap, entity, serviceTemplate, filesScanned,
573 toscaModel, elementType, typeId);
580 private boolean isFlatEntity(Map<String, Import> importMap,
582 ServiceTemplate serviceTemplate,
583 List<String> filesScanned,
584 ToscaServiceModel toscaModel,
585 ToscaElementTypes elementType, String typeId) {
586 boolean found = false;
587 ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
588 for (Object importObject : importMap.values()) {
589 Import importServiceTemplate = toscaExtensionYamlUtil
590 .yamlToObject(toscaExtensionYamlUtil.objectToYaml(importObject), Import.class);
591 String fileName = fetchFileNameForImport(importServiceTemplate.getFile(),
592 serviceTemplate.getMetadata() == null ? null : serviceTemplate.getMetadata().get(
594 if (filesScanned.contains(fileName)) {
597 filesScanned.add(fileName);
599 ServiceTemplate template = toscaModel.getServiceTemplates().get(fileName);
600 found = scanAnFlatEntity(elementType, typeId, entity, template, toscaModel,
601 filesScanned, filesScanned.size());
606 private String fetchFileNameForImport(String importServiceTemplateFile,
607 String currentMetadatafileName) {
608 if (importServiceTemplateFile.contains("../")) {
609 return importServiceTemplateFile.replace("../", "");
610 } else if (currentMetadatafileName != null) {
611 return currentMetadatafileName.substring(0, currentMetadatafileName.indexOf('/')) + "/"
612 + importServiceTemplateFile;
614 return importServiceTemplateFile;
619 private boolean enrichEntityFromCurrentServiceTemplate(ToscaElementTypes elementType,
620 String typeId, Object entity,
621 ServiceTemplate serviceTemplate,
622 ToscaServiceModel toscaModel,
623 List<String> filesScanned,
624 int rootScanStartInx) {
625 switch (elementType) {
626 case CAPABILITY_TYPE:
627 if (enrichCapabilityType(elementType, typeId, entity, serviceTemplate, toscaModel,
628 filesScanned, rootScanStartInx)) {
633 if (enrichNodeTypeInfo(elementType, typeId, entity, serviceTemplate, toscaModel,
634 filesScanned, rootScanStartInx)) {
639 throw new RuntimeException(
640 "Entity[" + elementType + "] id[" + typeId + "] flat not supported");
648 private boolean enrichNodeTypeInfo(ToscaElementTypes elementType, String typeId, Object entity,
649 ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel,
650 List<String> filesScanned, int rootScanStartInx) {
652 if (serviceTemplate.getNode_types() != null
653 && serviceTemplate.getNode_types().containsKey(typeId)) {
655 filesScanned.clear();
656 NodeType targetNodeType = (NodeType) entity;
657 NodeType sourceNodeType = serviceTemplate.getNode_types().get(typeId);
658 derivedFrom = sourceNodeType.getDerived_from();
659 if (derivedFrom != null) {
660 scanAnFlatEntity(elementType, derivedFrom, entity, serviceTemplate, toscaModel,
661 filesScanned, rootScanStartInx);
663 combineNodeTypeInfo(sourceNodeType, targetNodeType);
670 private boolean enrichCapabilityType(ToscaElementTypes elementType, String typeId, Object entity,
671 ServiceTemplate serviceTemplate,
672 ToscaServiceModel toscaModel, List<String> filesScanned,
673 int rootScanStartInx) {
675 if (serviceTemplate.getCapability_types() != null
676 && serviceTemplate.getCapability_types().containsKey(typeId)) {
678 filesScanned.clear();
679 CapabilityType targetCapabilityType = (CapabilityType) entity;
680 CapabilityType sourceCapabilityType = serviceTemplate.getCapability_types().get(typeId);
681 derivedFrom = sourceCapabilityType.getDerived_from();
682 if (derivedFrom != null) {
683 scanAnFlatEntity(elementType, derivedFrom, entity, serviceTemplate, toscaModel,
684 filesScanned, rootScanStartInx);
686 combineCapabilityTypeInfo(sourceCapabilityType, targetCapabilityType);
693 private void combineNodeTypeInfo(NodeType sourceNodeType, NodeType targetNodeType) {
694 targetNodeType.setDerived_from(sourceNodeType.getDerived_from());
695 targetNodeType.setDescription(sourceNodeType.getDescription());
696 targetNodeType.setVersion(sourceNodeType.getVersion());
697 targetNodeType.setProperties(
698 CommonMethods.mergeMaps(targetNodeType.getProperties(), sourceNodeType.getProperties()));
699 targetNodeType.setInterfaces(
700 CommonMethods.mergeMaps(targetNodeType.getInterfaces(), sourceNodeType.getInterfaces()));
701 targetNodeType.setArtifacts(
702 CommonMethods.mergeMaps(targetNodeType.getArtifacts(), sourceNodeType.getArtifacts()));
703 targetNodeType.setAttributes(
704 CommonMethods.mergeMaps(targetNodeType.getAttributes(), sourceNodeType.getAttributes()));
705 targetNodeType.setCapabilities(CommonMethods
706 .mergeMaps(targetNodeType.getCapabilities(), sourceNodeType.getCapabilities()));
707 targetNodeType.setRequirements(CommonMethods
708 .mergeListsOfMap(targetNodeType.getRequirements(), sourceNodeType.getRequirements()));
713 private void combineCapabilityTypeInfo(CapabilityType sourceCapabilityType,
714 CapabilityType targetCapabilityType) {
716 targetCapabilityType.setAttributes(CommonMethods
717 .mergeMaps(targetCapabilityType.getAttributes(), sourceCapabilityType.getAttributes()));
718 targetCapabilityType.setProperties(CommonMethods
719 .mergeMaps(targetCapabilityType.getProperties(), sourceCapabilityType.getProperties()));
720 targetCapabilityType.setValid_source_types(CommonMethods
721 .mergeLists(targetCapabilityType.getValid_source_types(),
722 sourceCapabilityType.getValid_source_types()));
724 if (StringUtils.isNotEmpty(sourceCapabilityType.getDerived_from())) {
725 targetCapabilityType.setDerived_from(sourceCapabilityType.getDerived_from());
727 if (StringUtils.isNotEmpty(sourceCapabilityType.getDescription())) {
728 targetCapabilityType.setDescription(sourceCapabilityType.getDescription());
730 if (StringUtils.isNotEmpty(sourceCapabilityType.getVersion())) {
731 targetCapabilityType.setVersion(sourceCapabilityType.getVersion());
739 * Create node type according to the input substitution service template, while the substitution
740 * service template can be mappted to this node type, for substitution mapping.
742 * @param substitutionServiceTemplate substitution serivce template
743 * @param nodeTypeDerivedFromValue derived from value for the created node type
744 * @return the node type
747 public NodeType createInitSubstitutionNodeType(ServiceTemplate substitutionServiceTemplate,
748 String nodeTypeDerivedFromValue) {
749 NodeType substitutionNodeType = new NodeType();
750 substitutionNodeType.setDerived_from(nodeTypeDerivedFromValue);
751 substitutionNodeType.setDescription(substitutionServiceTemplate.getDescription());
753 .setProperties(manageSubstitutionNodeTypeProperties(substitutionServiceTemplate));
755 .setAttributes(manageSubstitutionNodeTypeAttributes(substitutionServiceTemplate));
756 return substitutionNodeType;
760 public Map<String, PropertyDefinition> manageSubstitutionNodeTypeProperties(
761 ServiceTemplate substitutionServiceTemplate) {
762 Map<String, PropertyDefinition> substitutionNodeTypeProperties = new HashMap<>();
763 Map<String, ParameterDefinition> properties =
764 substitutionServiceTemplate.getTopology_template().getInputs();
765 if (properties == null) {
769 PropertyDefinition propertyDefinition;
770 String toscaPropertyName;
771 for (Map.Entry<String, ParameterDefinition> entry : properties.entrySet()) {
772 toscaPropertyName = entry.getKey();
773 propertyDefinition = new PropertyDefinition();
774 ParameterDefinition parameterDefinition =
775 substitutionServiceTemplate.getTopology_template().getInputs().get(toscaPropertyName);
776 propertyDefinition.setType(parameterDefinition.getType());
777 propertyDefinition.setDescription(parameterDefinition.getDescription());
778 propertyDefinition.set_default(parameterDefinition.get_default());
779 if (parameterDefinition.getRequired() != null) {
780 propertyDefinition.setRequired(parameterDefinition.getRequired());
782 if (propertyDefinition.get_default() != null) {
783 propertyDefinition.setRequired(false);
785 if (!CollectionUtils.isEmpty(parameterDefinition.getConstraints())) {
786 propertyDefinition.setConstraints(parameterDefinition.getConstraints());
788 propertyDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
789 if (parameterDefinition.getStatus() != null) {
790 propertyDefinition.setStatus(parameterDefinition.getStatus());
792 substitutionNodeTypeProperties.put(toscaPropertyName, propertyDefinition);
794 return substitutionNodeTypeProperties;
798 private Map<String, AttributeDefinition> manageSubstitutionNodeTypeAttributes(
799 ServiceTemplate substitutionServiceTemplate) {
800 Map<String, AttributeDefinition> substitutionNodeTypeAttributes = new HashMap<>();
801 Map<String, ParameterDefinition> attributes =
802 substitutionServiceTemplate.getTopology_template().getOutputs();
803 if (attributes == null) {
806 AttributeDefinition attributeDefinition;
807 String toscaAttributeName;
809 for (Map.Entry<String, ParameterDefinition> entry : attributes.entrySet()) {
810 attributeDefinition = new AttributeDefinition();
811 toscaAttributeName = entry.getKey();
812 ParameterDefinition parameterDefinition =
813 substitutionServiceTemplate.getTopology_template().getOutputs().get(toscaAttributeName);
814 if (parameterDefinition.getType() != null && !parameterDefinition.getType().isEmpty()) {
815 attributeDefinition.setType(parameterDefinition.getType());
817 attributeDefinition.setType(PropertyType.STRING.getDisplayName());
819 attributeDefinition.setDescription(parameterDefinition.getDescription());
820 attributeDefinition.set_default(parameterDefinition.get_default());
821 attributeDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
822 if (Objects.nonNull(parameterDefinition.getStatus())) {
823 attributeDefinition.setStatus(parameterDefinition.getStatus());
825 substitutionNodeTypeAttributes.put(toscaAttributeName, attributeDefinition);
827 return substitutionNodeTypeAttributes;
831 * Checks if the requirement exists in the node template.
833 * @param nodeTemplate the node template
834 * @param requirementId the requirement id
835 * @param requirementAssignment the requirement assignment
836 * @return true if the requirement already exists and false otherwise
839 public boolean isRequirementExistInNodeTemplate(NodeTemplate nodeTemplate,
840 String requirementId,
841 RequirementAssignment requirementAssignment) {
842 List<Map<String, RequirementAssignment>> nodeTemplateRequirements = nodeTemplate
844 return nodeTemplateRequirements != null && nodeTemplateRequirements.stream().anyMatch(
845 requirement -> requirement.containsKey(requirementId) && DataModelUtil
846 .compareRequirementAssignment(requirementAssignment, requirement.get(requirementId)));
850 public boolean isTypeOf(InterfaceDefinitionType interfaceDefinition, String interfaceType,
851 ServiceTemplate serviceTemplate, ToscaServiceModel toscaServiceModel) {
852 return isTypeOf(interfaceDefinition, interfaceType, GET_INTERFACE_TYPE_METHOD_NAME, serviceTemplate,
857 public boolean isTypeOf(DefinitionOfDataType parameterDefinition, String dataType,
858 ServiceTemplate serviceTemplate, ToscaServiceModel toscaServiceModel) {
859 return isTypeOf(parameterDefinition, dataType, GET_DATA_TYPE_METHOD_NAME, serviceTemplate,
863 private <T> boolean isTypeOf(T object, String type, String getTypesMethodName,
864 ServiceTemplate serviceTemplate,
865 ToscaServiceModel toscaServiceModel) {
866 if (object == null) {
871 String objectType = (String) object.getClass().getMethod(GET_TYPE_METHOD_NAME).invoke(object);
872 if (Objects.equals(objectType, type)) {
876 Optional<Boolean> typeExistInServiceTemplateHierarchy =
877 isTypeExistInServiceTemplateHierarchy(type, objectType, getTypesMethodName,
878 serviceTemplate, toscaServiceModel, null);
879 return typeExistInServiceTemplateHierarchy.orElseThrow(() -> new CoreException(
880 new ToscaElementTypeNotFoundErrorBuilder(objectType).build()));
882 } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
883 throw new RuntimeException(e);