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.onap.sdc.tosca.datatypes.model.AttributeDefinition;
27 import org.onap.sdc.tosca.datatypes.model.CapabilityDefinition;
28 import org.onap.sdc.tosca.datatypes.model.CapabilityType;
29 import org.onap.sdc.tosca.datatypes.model.DefinitionOfDataType;
30 import org.onap.sdc.tosca.datatypes.model.DataType;
31 import org.onap.sdc.tosca.datatypes.model.Import;
32 import org.onap.sdc.tosca.datatypes.model.InterfaceDefinitionType;
33 import org.onap.sdc.tosca.datatypes.model.NodeTemplate;
34 import org.onap.sdc.tosca.datatypes.model.NodeType;
35 import org.onap.sdc.tosca.datatypes.model.ParameterDefinition;
36 import org.onap.sdc.tosca.datatypes.model.PropertyDefinition;
37 import org.onap.sdc.tosca.datatypes.model.PropertyType;
38 import org.onap.sdc.tosca.datatypes.model.RequirementAssignment;
39 import org.onap.sdc.tosca.datatypes.model.RequirementDefinition;
40 import org.onap.sdc.tosca.datatypes.model.ServiceTemplate;
41 import org.openecomp.sdc.tosca.errors.ToscaElementTypeNotFoundErrorBuilder;
42 import org.openecomp.sdc.tosca.errors.ToscaInvalidEntryNotFoundErrorBuilder;
43 import org.openecomp.sdc.tosca.errors.ToscaInvalidSubstituteNodeTemplatePropertiesErrorBuilder;
44 import org.openecomp.sdc.tosca.errors.ToscaInvalidSubstitutionServiceTemplateErrorBuilder;
45 import org.openecomp.sdc.tosca.services.DataModelUtil;
46 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
47 import org.openecomp.sdc.tosca.services.ToscaConstants;
48 import org.onap.sdc.tosca.services.ToscaExtensionYamlUtil;
49 import org.openecomp.sdc.tosca.services.ToscaUtil;
51 import java.lang.reflect.InvocationTargetException;
52 import java.util.ArrayList;
53 import java.util.Collection;
54 import java.util.Collections;
55 import java.util.HashMap;
56 import java.util.HashSet;
57 import java.util.List;
59 import java.util.Objects;
60 import java.util.Optional;
63 public class ToscaAnalyzerServiceImpl implements ToscaAnalyzerService {
64 private final String GET_NODE_TYPE_METHOD_NAME = "getNode_types";
65 private final String GET_DERIVED_FROM_METHOD_NAME = "getDerived_from";
66 private final String GET_TYPE_METHOD_NAME = "getType";
67 private final String GET_DATA_TYPE_METHOD_NAME = "getData_types";
68 private final String GET_INTERFACE_TYPE_METHOD_NAME = "getInterface_types";
69 private final String TOSCA_DOT = "tosca.";
70 private final String DOT_ROOT = ".Root";
73 public List<Map<String, RequirementDefinition>> calculateExposedRequirements(
74 List<Map<String, RequirementDefinition>> nodeTypeRequirementsDefinitionList,
75 Map<String, RequirementAssignment> nodeTemplateRequirementsAssignment) {
77 if (nodeTypeRequirementsDefinitionList == null) {
78 return Collections.emptyList();
80 for (Map.Entry<String, RequirementAssignment> entry : nodeTemplateRequirementsAssignment
82 if (entry.getValue().getNode() != null) {
83 Optional<RequirementDefinition> requirementDefinition =
84 DataModelUtil.getRequirementDefinition(nodeTypeRequirementsDefinitionList, entry
86 RequirementDefinition cloneRequirementDefinition;
87 if (requirementDefinition.isPresent()) {
88 cloneRequirementDefinition = requirementDefinition.get().clone();
89 updateRequirementDefinition(nodeTypeRequirementsDefinitionList, entry,
90 cloneRequirementDefinition);
93 for (Map<String, RequirementDefinition> nodeTypeRequirementsMap :
94 nodeTypeRequirementsDefinitionList) {
95 updateMinMaxOccurencesForNodeTypeRequirement(entry, nodeTypeRequirementsMap);
99 return nodeTypeRequirementsDefinitionList;
102 private void updateMinMaxOccurencesForNodeTypeRequirement(
103 Map.Entry<String, RequirementAssignment> entry,
104 Map<String, RequirementDefinition> nodeTypeRequirementsMap) {
105 Object max = nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences() != null
106 && nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences().length > 0
107 ? nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences()[1] : 1;
108 Object min = nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences() != null
109 && nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences().length > 0
110 ? nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences()[0] : 1;
111 nodeTypeRequirementsMap.get(entry.getKey()).setOccurrences(new Object[]{min, max});
114 private void updateRequirementDefinition(
115 List<Map<String, RequirementDefinition>> nodeTypeRequirementsDefinitionList,
116 Map.Entry<String, RequirementAssignment> entry,
117 RequirementDefinition cloneRequirementDefinition) {
118 if (!evaluateRequirementFulfillment(cloneRequirementDefinition)) {
119 CommonMethods.mergeEntryInList(entry.getKey(), cloneRequirementDefinition,
120 nodeTypeRequirementsDefinitionList);
122 DataModelUtil.removeRequirementsDefinition(nodeTypeRequirementsDefinitionList, entry
127 private static boolean evaluateRequirementFulfillment(RequirementDefinition
128 requirementDefinition) {
129 Object[] occurrences = requirementDefinition.getOccurrences();
130 if (occurrences == null) {
131 requirementDefinition.setOccurrences(new Object[]{1, 1});
134 if (occurrences[1].equals(ToscaConstants.UNBOUNDED)) {
138 if (occurrences[1].equals(1)) {
141 occurrences[1] = (Integer) occurrences[1] - 1;
146 public Map<String, CapabilityDefinition> calculateExposedCapabilities(
147 Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition,
148 Map<String, Map<String, RequirementAssignment>> fullFilledRequirementsDefinitionMap) {
150 String capabilityKey;
153 for (Map.Entry<String, Map<String, RequirementAssignment>> entry :
154 fullFilledRequirementsDefinitionMap.entrySet()) {
155 for (Map.Entry<String, RequirementAssignment> fullFilledEntry : entry.getValue().entrySet()) {
157 capability = fullFilledEntry.getValue().getCapability();
158 node = fullFilledEntry.getValue().getNode();
159 capabilityKey = capability + "_" + node;
160 CapabilityDefinition capabilityDefinition = nodeTypeCapabilitiesDefinition.get(
162 if (capabilityDefinition != null) {
163 CapabilityDefinition clonedCapabilityDefinition = capabilityDefinition.clone();
164 nodeTypeCapabilitiesDefinition.put(capabilityKey, capabilityDefinition.clone());
165 updateNodeTypeCapabilitiesDefinition(nodeTypeCapabilitiesDefinition, capabilityKey,
166 clonedCapabilityDefinition);
171 Map<String, CapabilityDefinition> exposedCapabilitiesDefinition = new HashMap<>();
172 for (Map.Entry<String, CapabilityDefinition> entry : nodeTypeCapabilitiesDefinition
174 exposedCapabilitiesDefinition.put(entry.getKey(), entry.getValue());
176 return exposedCapabilitiesDefinition;
179 private void updateNodeTypeCapabilitiesDefinition(
180 Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition, String capabilityKey,
181 CapabilityDefinition clonedCapabilityDefinition) {
182 if (evaluateCapabilityFulfillment(clonedCapabilityDefinition)) {
183 nodeTypeCapabilitiesDefinition.remove(capabilityKey);
185 nodeTypeCapabilitiesDefinition.put(capabilityKey, clonedCapabilityDefinition);
189 private static boolean evaluateCapabilityFulfillment(CapabilityDefinition capabilityDefinition) {
191 Object[] occurrences = capabilityDefinition.getOccurrences();
192 if (occurrences == null) {
193 capabilityDefinition.setOccurrences(new Object[]{1, ToscaConstants.UNBOUNDED});
196 if (occurrences[1].equals(ToscaConstants.UNBOUNDED)) {
200 if (occurrences[1].equals(1)) {
203 occurrences[1] = (Integer) occurrences[1] - 1;
208 node template with type equal to node type or derived from node type
211 public Map<String, NodeTemplate> getNodeTemplatesByType(ServiceTemplate serviceTemplate,
213 ToscaServiceModel toscaServiceModel) {
214 Map<String, NodeTemplate> nodeTemplates = new HashMap<>();
216 if (Objects.nonNull(serviceTemplate.getTopology_template())
217 && MapUtils.isNotEmpty(serviceTemplate.getTopology_template().getNode_templates())) {
218 for (Map.Entry<String, NodeTemplate> nodeTemplateEntry : serviceTemplate
219 .getTopology_template().getNode_templates().entrySet()) {
220 if (isTypeOf(nodeTemplateEntry.getValue(), nodeType, serviceTemplate, toscaServiceModel)) {
221 nodeTemplates.put(nodeTemplateEntry.getKey(), nodeTemplateEntry.getValue());
226 return nodeTemplates;
230 public Optional<NodeType> fetchNodeType(String nodeTypeKey, Collection<ServiceTemplate>
232 Optional<Map<String, NodeType>> nodeTypeMap = serviceTemplates.stream()
233 .map(ServiceTemplate::getNode_types)
234 .filter(nodeTypes -> Objects.nonNull(nodeTypes) && nodeTypes.containsKey(nodeTypeKey))
236 return nodeTypeMap.map(stringNodeTypeMap -> stringNodeTypeMap.get(nodeTypeKey));
240 public boolean isTypeOf(NodeTemplate nodeTemplate, String nodeType,
241 ServiceTemplate serviceTemplate, ToscaServiceModel toscaServiceModel) {
242 return isTypeOf(nodeTemplate, nodeType, GET_NODE_TYPE_METHOD_NAME, serviceTemplate,
247 public List<RequirementAssignment> getRequirements(NodeTemplate nodeTemplate,
248 String requirementId) {
249 List<RequirementAssignment> requirements = new ArrayList<>();
250 List<Map<String, RequirementAssignment>> requirementList = nodeTemplate.getRequirements();
251 if (requirementList != null) {
252 requirementList.stream().filter(reqMap -> reqMap.get(requirementId) != null)
254 ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
255 RequirementAssignment reqAssignment = toscaExtensionYamlUtil
256 .yamlToObject(toscaExtensionYamlUtil.objectToYaml(reqMap.get(requirementId)),
257 RequirementAssignment.class);
258 requirements.add(reqAssignment);
265 public Optional<NodeTemplate> getNodeTemplateById(ServiceTemplate serviceTemplate,
266 String nodeTemplateId) {
267 if ((serviceTemplate.getTopology_template() != null)
268 && (serviceTemplate.getTopology_template().getNode_templates() != null)
269 && (serviceTemplate.getTopology_template().getNode_templates().get(nodeTemplateId)
272 .of(serviceTemplate.getTopology_template().getNode_templates().get(nodeTemplateId));
274 return Optional.empty();
278 public Optional<String> getSubstituteServiceTemplateName(String substituteNodeTemplateId,
279 NodeTemplate substitutableNodeTemplate) {
280 if (!isSubstitutableNodeTemplate(substitutableNodeTemplate)) {
281 return Optional.empty();
284 if (substitutableNodeTemplate.getProperties() != null
285 && substitutableNodeTemplate.getProperties()
286 .get(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME) != null) {
287 Object serviceTemplateFilter = substitutableNodeTemplate.getProperties()
288 .get(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME);
289 if (serviceTemplateFilter != null && serviceTemplateFilter instanceof Map) {
290 Object substituteServiceTemplate = ((Map) serviceTemplateFilter)
291 .get(ToscaConstants.SUBSTITUTE_SERVICE_TEMPLATE_PROPERTY_NAME);
292 handleNoSubstituteServiceTemplate(substituteNodeTemplateId, substituteServiceTemplate);
293 return Optional.of(substituteServiceTemplate.toString());
296 throw new CoreException(
297 new ToscaInvalidSubstituteNodeTemplatePropertiesErrorBuilder(substituteNodeTemplateId)
301 private void handleNoSubstituteServiceTemplate(String substituteNodeTemplateId,
302 Object substituteServiceTemplate) {
303 if (substituteServiceTemplate == null) {
304 throw new CoreException(
305 new ToscaInvalidSubstituteNodeTemplatePropertiesErrorBuilder(substituteNodeTemplateId)
311 public Map<String, NodeTemplate> getSubstitutableNodeTemplates(ServiceTemplate serviceTemplate) {
312 Map<String, NodeTemplate> substitutableNodeTemplates = new HashMap<>();
314 if (serviceTemplate == null
315 || serviceTemplate.getTopology_template() == null
316 || serviceTemplate.getTopology_template().getNode_templates() == null) {
317 return substitutableNodeTemplates;
320 Map<String, NodeTemplate> nodeTemplates =
321 serviceTemplate.getTopology_template().getNode_templates();
322 for (Map.Entry<String, NodeTemplate> entry : nodeTemplates.entrySet()) {
323 String nodeTemplateId = entry.getKey();
324 NodeTemplate nodeTemplate = entry.getValue();
325 if (isSubstitutableNodeTemplate(nodeTemplate)) {
326 substitutableNodeTemplates.put(nodeTemplateId, nodeTemplate);
330 return substitutableNodeTemplates;
334 public Optional<Map.Entry<String, NodeTemplate>> getSubstitutionMappedNodeTemplateByExposedReq(
335 String substituteServiceTemplateFileName, ServiceTemplate substituteServiceTemplate,
336 String requirementId) {
337 if (isSubstitutionServiceTemplate(substituteServiceTemplateFileName,
338 substituteServiceTemplate)) {
339 Map<String, List<String>> substitutionMappingRequirements =
340 substituteServiceTemplate.getTopology_template().getSubstitution_mappings()
342 if (substitutionMappingRequirements != null) {
343 List<String> requirementMapping = substitutionMappingRequirements.get(requirementId);
344 if (requirementMapping != null && !requirementMapping.isEmpty()) {
345 String mappedNodeTemplateId = requirementMapping.get(0);
346 Optional<NodeTemplate> mappedNodeTemplate =
347 getNodeTemplateById(substituteServiceTemplate, mappedNodeTemplateId);
348 mappedNodeTemplate.orElseThrow(() -> new CoreException(
349 new ToscaInvalidEntryNotFoundErrorBuilder("Node Template", mappedNodeTemplateId)
351 Map.Entry<String, NodeTemplate> mappedNodeTemplateEntry =
352 new Map.Entry<String, NodeTemplate>() {
354 public String getKey() {
355 return mappedNodeTemplateId;
359 public NodeTemplate getValue() {
360 return mappedNodeTemplate.get();
364 public NodeTemplate setValue(NodeTemplate value) {
368 return Optional.of(mappedNodeTemplateEntry);
372 return Optional.empty();
376 match only for the input which is not null
379 public boolean isDesiredRequirementAssignment(RequirementAssignment requirementAssignment,
380 String capability, String node,
381 String relationship) {
382 if (isSameCapability(requirementAssignment, capability)) {
386 if (isSameRequirement(requirementAssignment, node)) {
390 if (isSameRelationship(requirementAssignment, relationship)) {
394 return !(capability == null && node == null && relationship == null);
398 private boolean isSameRelationship(RequirementAssignment requirementAssignment,
399 String relationship) {
400 return relationship != null && (requirementAssignment.getRelationship() == null
401 || !requirementAssignment.getRelationship().equals(relationship));
404 private boolean isSameRequirement(RequirementAssignment requirementAssignment, String node) {
405 return node != null && (requirementAssignment.getNode() == null
406 || !requirementAssignment.getNode().equals(node));
409 private boolean isSameCapability(RequirementAssignment requirementAssignment, String capability) {
410 return capability != null && (requirementAssignment.getCapability() == null
411 || !requirementAssignment.getCapability().equals(capability));
415 public Object getFlatEntity(ToscaElementTypes elementType, String typeId,
416 ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel) {
419 switch (elementType) {
420 case CAPABILITY_TYPE:
421 returnEntity = new CapabilityType();
424 returnEntity = new NodeType();
427 returnEntity = new DataType();
430 throw new RuntimeException(
431 "Entity[" + elementType + "] id[" + typeId + "] flat not supported");
434 boolean isEntityFound =
435 scanAnFlatEntity(elementType, typeId, returnEntity, serviceTemplate, toscaModel,
436 new ArrayList<>(), 0);
437 if (!isEntityFound) {
438 throw new CoreException(new ToscaElementTypeNotFoundErrorBuilder(typeId).build());
445 public boolean isSubstitutableNodeTemplate(NodeTemplate nodeTemplate) {
446 return nodeTemplate.getDirectives() != null
447 && nodeTemplate.getDirectives().contains(ToscaConstants
448 .NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
451 private <T> Optional<Boolean> isTypeExistInServiceTemplateHierarchy(String typeToMatch,
453 String getTypesMethodName,
454 ServiceTemplate serviceTemplate,
455 ToscaServiceModel toscaServiceModel,
456 Set<String> analyzedImportFiles)
457 throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
458 Map<String, T> searchableTypes =
459 (Map<String, T>) serviceTemplate.getClass().getMethod(getTypesMethodName)
460 .invoke(serviceTemplate);
462 if (!MapUtils.isEmpty(searchableTypes)) {
463 T typeObject = searchableTypes.get(typeToSearch);
464 if (Objects.nonNull(typeObject)) {
465 String derivedFromTypeVal =
466 (String) typeObject.getClass().getMethod(GET_DERIVED_FROM_METHOD_NAME).invoke(typeObject);
467 if (Objects.equals(derivedFromTypeVal, typeToMatch)) {
468 return Optional.of(true);
469 } else if (Objects.isNull(derivedFromTypeVal) || isTypeIsToscaRoot(derivedFromTypeVal)) {
470 return Optional.of(false);
472 return isTypeExistInServiceTemplateHierarchy(typeToMatch,
473 derivedFromTypeVal, getTypesMethodName, serviceTemplate, toscaServiceModel, null);
476 return isTypeExistInImports(typeToMatch, typeToSearch, getTypesMethodName,
477 serviceTemplate, toscaServiceModel, analyzedImportFiles);
480 return isTypeExistInImports(typeToMatch, typeToSearch, getTypesMethodName, serviceTemplate,
481 toscaServiceModel, analyzedImportFiles);
484 private Optional<Boolean> isTypeExistInImports(String typeToMatch,
486 String getTypesMethodName,
487 ServiceTemplate serviceTemplate,
488 ToscaServiceModel toscaServiceModel,
489 Set<String> filesScanned)
490 throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
491 List<Map<String, Import>> imports = serviceTemplate.getImports();
492 if (CollectionUtils.isEmpty(imports)) {
493 return Optional.empty();
496 Set<String> createdFilesScanned = createFilesScannedSet(filesScanned);
498 for (Map<String, Import> map : imports) {
499 ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
500 Import anImport = toscaExtensionYamlUtil
501 .yamlToObject(toscaExtensionYamlUtil.objectToYaml(map.values().iterator().next()),
503 handleImportWithNoFileEntry(anImport);
504 String importFile = anImport.getFile();
505 ServiceTemplate template =
506 toscaServiceModel.getServiceTemplates().get(fetchFileNameForImport(importFile,
507 serviceTemplate.getMetadata() == null ? null
508 : serviceTemplate.getMetadata().get("filename")));
509 if (Objects.isNull(template)
510 || createdFilesScanned.contains(ToscaUtil.getServiceTemplateFileName(template))) {
513 createdFilesScanned.add(ToscaUtil.getServiceTemplateFileName(template));
515 Optional<Boolean> typeExistInServiceTemplateHierarchy =
516 isTypeExistInServiceTemplateHierarchy(typeToMatch, typeToSearch, getTypesMethodName,
517 template, toscaServiceModel, createdFilesScanned);
518 if (typeExistInServiceTemplateHierarchy.isPresent()
519 && (typeExistInServiceTemplateHierarchy.get())) {
520 createdFilesScanned.clear();
521 return Optional.of(true);
525 return Optional.of(false);
528 private void handleImportWithNoFileEntry(Import anImport) {
529 if (Objects.isNull(anImport) || Objects.isNull(anImport.getFile())) {
530 throw new RuntimeException("import without file entry");
534 private Set<String> createFilesScannedSet(Set<String> filesScanned) {
535 Set<String> retFileScanned = filesScanned;
536 if (Objects.isNull(retFileScanned)) {
537 retFileScanned = new HashSet<>();
539 return retFileScanned;
542 private boolean isTypeIsToscaRoot(String type) {
543 return (type.contains(TOSCA_DOT) && type.contains(DOT_ROOT));
546 private boolean isSubstitutionServiceTemplate(String substituteServiceTemplateFileName,
547 ServiceTemplate substituteServiceTemplate) {
548 if (substituteServiceTemplate != null
549 && substituteServiceTemplate.getTopology_template() != null
550 && substituteServiceTemplate.getTopology_template().getSubstitution_mappings() != null) {
551 if (substituteServiceTemplate.getTopology_template().getSubstitution_mappings()
552 .getNode_type() == null) {
553 throw new CoreException(new ToscaInvalidSubstitutionServiceTemplateErrorBuilder(
554 substituteServiceTemplateFileName).build());
562 private boolean scanAnFlatEntity(ToscaElementTypes elementType, String typeId, Object entity,
563 ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel,
564 List<String> filesScanned, int rootScanStartInx) {
567 boolean entityFound = enrichEntityFromCurrentServiceTemplate(elementType, typeId, entity,
568 serviceTemplate, toscaModel, filesScanned, rootScanStartInx);
570 List<Map<String, Import>> imports = serviceTemplate.getImports();
571 if (CollectionUtils.isEmpty(imports)) {
574 boolean found = false;
575 for (Map<String, Import> importMap : imports) {
579 found = isFlatEntity(importMap, entity, serviceTemplate, filesScanned,
580 toscaModel, elementType, typeId);
587 private boolean isFlatEntity(Map<String, Import> importMap,
589 ServiceTemplate serviceTemplate,
590 List<String> filesScanned,
591 ToscaServiceModel toscaModel,
592 ToscaElementTypes elementType, String typeId) {
593 boolean found = false;
594 ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
595 for (Object importObject : importMap.values()) {
596 Import importServiceTemplate = toscaExtensionYamlUtil
597 .yamlToObject(toscaExtensionYamlUtil.objectToYaml(importObject), Import.class);
598 String fileName = fetchFileNameForImport(importServiceTemplate.getFile(),
599 serviceTemplate.getMetadata() == null ? null : serviceTemplate.getMetadata().get(
601 if (filesScanned.contains(fileName)) {
604 filesScanned.add(fileName);
606 ServiceTemplate template = toscaModel.getServiceTemplates().get(fileName);
607 found = scanAnFlatEntity(elementType, typeId, entity, template, toscaModel,
608 filesScanned, filesScanned.size());
613 private String fetchFileNameForImport(String importServiceTemplateFile,
614 String currentMetadatafileName) {
615 if (importServiceTemplateFile.contains("../")) {
616 return importServiceTemplateFile.replace("../", "");
617 } else if (currentMetadatafileName != null) {
618 return currentMetadatafileName.substring(0, currentMetadatafileName.indexOf('/')) + "/"
619 + importServiceTemplateFile;
621 return importServiceTemplateFile;
626 private boolean enrichEntityFromCurrentServiceTemplate(ToscaElementTypes elementType,
627 String typeId, Object entity,
628 ServiceTemplate serviceTemplate,
629 ToscaServiceModel toscaModel,
630 List<String> filesScanned,
631 int rootScanStartInx) {
632 switch (elementType) {
633 case CAPABILITY_TYPE:
634 if (enrichCapabilityType(elementType, typeId, entity, serviceTemplate, toscaModel,
635 filesScanned, rootScanStartInx)) {
640 if (enrichNodeTypeInfo(elementType, typeId, entity, serviceTemplate, toscaModel,
641 filesScanned, rootScanStartInx)) {
646 if (enrichDataTypeInfo(elementType, typeId, entity, serviceTemplate, toscaModel,
647 filesScanned, rootScanStartInx)) {
652 throw new RuntimeException(
653 "Entity[" + elementType + "] id[" + typeId + "] flat not supported");
661 private boolean enrichNodeTypeInfo(ToscaElementTypes elementType, String typeId, Object entity,
662 ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel,
663 List<String> filesScanned, int rootScanStartInx) {
665 if (serviceTemplate.getNode_types() != null
666 && serviceTemplate.getNode_types().containsKey(typeId)) {
668 filesScanned.clear();
669 NodeType targetNodeType = (NodeType) entity;
670 NodeType sourceNodeType = serviceTemplate.getNode_types().get(typeId);
671 derivedFrom = sourceNodeType.getDerived_from();
672 if (derivedFrom != null) {
673 scanAnFlatEntity(elementType, derivedFrom, entity, serviceTemplate, toscaModel,
674 filesScanned, rootScanStartInx);
676 combineNodeTypeInfo(sourceNodeType, targetNodeType);
683 private boolean enrichDataTypeInfo(ToscaElementTypes elementType, String typeId, Object entity,
684 ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel,
685 List<String> filesScanned, int rootScanStartInx) {
687 if (serviceTemplate.getData_types() != null
688 && serviceTemplate.getData_types().containsKey(typeId)) {
690 filesScanned.clear();
691 DataType targetDataType = (DataType) entity;
692 DataType sourceDataType = serviceTemplate.getData_types().get(typeId);
693 derivedFrom = sourceDataType.getDerived_from();
694 if (derivedFrom != null) {
695 scanAnFlatEntity(elementType, derivedFrom, entity, serviceTemplate, toscaModel,
696 filesScanned, rootScanStartInx);
698 combineDataTypeInfo(sourceDataType, targetDataType);
705 private boolean enrichCapabilityType(ToscaElementTypes elementType, String typeId, Object entity,
706 ServiceTemplate serviceTemplate,
707 ToscaServiceModel toscaModel, List<String> filesScanned,
708 int rootScanStartInx) {
710 if (serviceTemplate.getCapability_types() != null
711 && serviceTemplate.getCapability_types().containsKey(typeId)) {
713 filesScanned.clear();
714 CapabilityType targetCapabilityType = (CapabilityType) entity;
715 CapabilityType sourceCapabilityType = serviceTemplate.getCapability_types().get(typeId);
716 derivedFrom = sourceCapabilityType.getDerived_from();
717 if (derivedFrom != null) {
718 scanAnFlatEntity(elementType, derivedFrom, entity, serviceTemplate, toscaModel,
719 filesScanned, rootScanStartInx);
721 combineCapabilityTypeInfo(sourceCapabilityType, targetCapabilityType);
728 private void combineNodeTypeInfo(NodeType sourceNodeType, NodeType targetNodeType) {
729 targetNodeType.setDerived_from(sourceNodeType.getDerived_from());
730 targetNodeType.setDescription(sourceNodeType.getDescription());
731 targetNodeType.setVersion(sourceNodeType.getVersion());
732 targetNodeType.setProperties(
733 CommonMethods.mergeMaps(targetNodeType.getProperties(), sourceNodeType.getProperties()));
734 targetNodeType.setInterfaces(
735 CommonMethods.mergeMaps(targetNodeType.getInterfaces(), sourceNodeType.getInterfaces()));
736 targetNodeType.setArtifacts(
737 CommonMethods.mergeMaps(targetNodeType.getArtifacts(), sourceNodeType.getArtifacts()));
738 targetNodeType.setAttributes(
739 CommonMethods.mergeMaps(targetNodeType.getAttributes(), sourceNodeType.getAttributes()));
740 targetNodeType.setCapabilities(CommonMethods
741 .mergeMaps(targetNodeType.getCapabilities(), sourceNodeType.getCapabilities()));
742 targetNodeType.setRequirements(CommonMethods
743 .mergeListsOfMap(targetNodeType.getRequirements(), sourceNodeType.getRequirements()));
747 private void combineDataTypeInfo(DataType sourceDataType, DataType targetDataType) {
748 targetDataType.setDerived_from(sourceDataType.getDerived_from());
749 targetDataType.setDescription(sourceDataType.getDescription());
750 targetDataType.setVersion(sourceDataType.getVersion());
751 targetDataType.setProperties(
752 CommonMethods.mergeMaps(targetDataType.getProperties(), sourceDataType.getProperties()));
753 targetDataType.setConstraints(
754 CommonMethods.mergeLists(targetDataType.getConstraints(), sourceDataType.getConstraints()));
758 private void combineCapabilityTypeInfo(CapabilityType sourceCapabilityType,
759 CapabilityType targetCapabilityType) {
761 targetCapabilityType.setAttributes(CommonMethods
762 .mergeMaps(targetCapabilityType.getAttributes(), sourceCapabilityType.getAttributes()));
763 targetCapabilityType.setProperties(CommonMethods
764 .mergeMaps(targetCapabilityType.getProperties(), sourceCapabilityType.getProperties()));
765 targetCapabilityType.setValid_source_types(CommonMethods
766 .mergeLists(targetCapabilityType.getValid_source_types(),
767 sourceCapabilityType.getValid_source_types()));
769 if (StringUtils.isNotEmpty(sourceCapabilityType.getDerived_from())) {
770 targetCapabilityType.setDerived_from(sourceCapabilityType.getDerived_from());
772 if (StringUtils.isNotEmpty(sourceCapabilityType.getDescription())) {
773 targetCapabilityType.setDescription(sourceCapabilityType.getDescription());
775 if (StringUtils.isNotEmpty(sourceCapabilityType.getVersion())) {
776 targetCapabilityType.setVersion(sourceCapabilityType.getVersion());
784 * Create node type according to the input substitution service template, while the substitution
785 * service template can be mappted to this node type, for substitution mapping.
787 * @param substitutionServiceTemplate substitution serivce template
788 * @param nodeTypeDerivedFromValue derived from value for the created node type
789 * @return the node type
792 public NodeType createInitSubstitutionNodeType(ServiceTemplate substitutionServiceTemplate,
793 String nodeTypeDerivedFromValue) {
794 NodeType substitutionNodeType = new NodeType();
795 substitutionNodeType.setDerived_from(nodeTypeDerivedFromValue);
796 substitutionNodeType.setDescription(substitutionServiceTemplate.getDescription());
798 .setProperties(manageSubstitutionNodeTypeProperties(substitutionServiceTemplate));
800 .setAttributes(manageSubstitutionNodeTypeAttributes(substitutionServiceTemplate));
801 return substitutionNodeType;
805 public Map<String, PropertyDefinition> manageSubstitutionNodeTypeProperties(
806 ServiceTemplate substitutionServiceTemplate) {
807 Map<String, PropertyDefinition> substitutionNodeTypeProperties = new HashMap<>();
808 Map<String, ParameterDefinition> properties =
809 substitutionServiceTemplate.getTopology_template().getInputs();
810 if (properties == null) {
814 PropertyDefinition propertyDefinition;
815 String toscaPropertyName;
816 for (Map.Entry<String, ParameterDefinition> entry : properties.entrySet()) {
817 toscaPropertyName = entry.getKey();
818 propertyDefinition = new PropertyDefinition();
819 ParameterDefinition parameterDefinition =
820 substitutionServiceTemplate.getTopology_template().getInputs().get(toscaPropertyName);
821 propertyDefinition.setType(parameterDefinition.getType());
822 propertyDefinition.setDescription(parameterDefinition.getDescription());
823 propertyDefinition.set_default(parameterDefinition.get_default());
824 if (parameterDefinition.getRequired() != null) {
825 propertyDefinition.setRequired(parameterDefinition.getRequired());
827 if (propertyDefinition.get_default() != null) {
828 propertyDefinition.setRequired(false);
830 if (!CollectionUtils.isEmpty(parameterDefinition.getConstraints())) {
831 propertyDefinition.setConstraints(parameterDefinition.getConstraints());
833 propertyDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
834 if (parameterDefinition.getStatus() != null) {
835 propertyDefinition.setStatus(parameterDefinition.getStatus());
837 substitutionNodeTypeProperties.put(toscaPropertyName, propertyDefinition);
839 return substitutionNodeTypeProperties;
843 private Map<String, AttributeDefinition> manageSubstitutionNodeTypeAttributes(
844 ServiceTemplate substitutionServiceTemplate) {
845 Map<String, AttributeDefinition> substitutionNodeTypeAttributes = new HashMap<>();
846 Map<String, ParameterDefinition> attributes =
847 substitutionServiceTemplate.getTopology_template().getOutputs();
848 if (attributes == null) {
851 AttributeDefinition attributeDefinition;
852 String toscaAttributeName;
854 for (Map.Entry<String, ParameterDefinition> entry : attributes.entrySet()) {
855 attributeDefinition = new AttributeDefinition();
856 toscaAttributeName = entry.getKey();
857 ParameterDefinition parameterDefinition =
858 substitutionServiceTemplate.getTopology_template().getOutputs().get(toscaAttributeName);
859 if (parameterDefinition.getType() != null && !parameterDefinition.getType().isEmpty()) {
860 attributeDefinition.setType(parameterDefinition.getType());
862 attributeDefinition.setType(PropertyType.STRING.getDisplayName());
864 attributeDefinition.setDescription(parameterDefinition.getDescription());
865 attributeDefinition.set_default(parameterDefinition.get_default());
866 attributeDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
867 if (Objects.nonNull(parameterDefinition.getStatus())) {
868 attributeDefinition.setStatus(parameterDefinition.getStatus());
870 substitutionNodeTypeAttributes.put(toscaAttributeName, attributeDefinition);
872 return substitutionNodeTypeAttributes;
876 * Checks if the requirement exists in the node template.
878 * @param nodeTemplate the node template
879 * @param requirementId the requirement id
880 * @param requirementAssignment the requirement assignment
881 * @return true if the requirement already exists and false otherwise
884 public boolean isRequirementExistInNodeTemplate(NodeTemplate nodeTemplate,
885 String requirementId,
886 RequirementAssignment requirementAssignment) {
887 List<Map<String, RequirementAssignment>> nodeTemplateRequirements = nodeTemplate
889 return nodeTemplateRequirements != null && nodeTemplateRequirements.stream().anyMatch(
890 requirement -> requirement.containsKey(requirementId) && DataModelUtil
891 .compareRequirementAssignment(requirementAssignment, requirement.get(requirementId)));
895 public boolean isTypeOf(InterfaceDefinitionType interfaceDefinition, String interfaceType,
896 ServiceTemplate serviceTemplate, ToscaServiceModel toscaServiceModel) {
897 return isTypeOf(interfaceDefinition, interfaceType, GET_INTERFACE_TYPE_METHOD_NAME, serviceTemplate,
902 public boolean isTypeOf(DefinitionOfDataType parameterDefinition, String dataType,
903 ServiceTemplate serviceTemplate, ToscaServiceModel toscaServiceModel) {
904 return isTypeOf(parameterDefinition, dataType, GET_DATA_TYPE_METHOD_NAME, serviceTemplate,
908 private <T> boolean isTypeOf(T object, String type, String getTypesMethodName,
909 ServiceTemplate serviceTemplate,
910 ToscaServiceModel toscaServiceModel) {
911 if (object == null) {
916 String objectType = (String) object.getClass().getMethod(GET_TYPE_METHOD_NAME).invoke(object);
917 if (Objects.equals(objectType, type)) {
921 Optional<Boolean> typeExistInServiceTemplateHierarchy =
922 isTypeExistInServiceTemplateHierarchy(type, objectType, getTypesMethodName,
923 serviceTemplate, toscaServiceModel, null);
924 return typeExistInServiceTemplateHierarchy.orElseThrow(() -> new CoreException(
925 new ToscaElementTypeNotFoundErrorBuilder(objectType).build()));
927 } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
928 throw new RuntimeException(e);