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.ToscaFileNotFoundErrorBuilder;
43 import org.openecomp.sdc.tosca.errors.ToscaInvalidEntryNotFoundErrorBuilder;
44 import org.openecomp.sdc.tosca.errors.ToscaInvalidSubstituteNodeTemplatePropertiesErrorBuilder;
45 import org.openecomp.sdc.tosca.errors.ToscaInvalidSubstitutionServiceTemplateErrorBuilder;
46 import org.openecomp.sdc.tosca.services.DataModelUtil;
47 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
48 import org.openecomp.sdc.tosca.services.ToscaConstants;
49 import org.onap.sdc.tosca.services.ToscaExtensionYamlUtil;
50 import org.openecomp.sdc.tosca.services.ToscaUtil;
52 import java.lang.reflect.InvocationTargetException;
53 import java.util.ArrayList;
54 import java.util.Collection;
55 import java.util.Collections;
56 import java.util.HashMap;
57 import java.util.HashSet;
58 import java.util.List;
60 import java.util.Objects;
61 import java.util.Optional;
64 public class ToscaAnalyzerServiceImpl implements ToscaAnalyzerService {
65 private final String GET_NODE_TYPE_METHOD_NAME = "getNode_types";
66 private final String GET_DERIVED_FROM_METHOD_NAME = "getDerived_from";
67 private final String GET_TYPE_METHOD_NAME = "getType";
68 private final String GET_DATA_TYPE_METHOD_NAME = "getData_types";
69 private final String GET_INTERFACE_TYPE_METHOD_NAME = "getInterface_types";
70 private final String TOSCA_DOT = "tosca.";
71 private final String DOT_ROOT = ".Root";
74 public List<Map<String, RequirementDefinition>> calculateExposedRequirements(
75 List<Map<String, RequirementDefinition>> nodeTypeRequirementsDefinitionList,
76 Map<String, RequirementAssignment> nodeTemplateRequirementsAssignment) {
78 if (nodeTypeRequirementsDefinitionList == null) {
79 return Collections.emptyList();
81 for (Map.Entry<String, RequirementAssignment> entry : nodeTemplateRequirementsAssignment
83 if (entry.getValue().getNode() != null) {
84 Optional<RequirementDefinition> requirementDefinition =
85 DataModelUtil.getRequirementDefinition(nodeTypeRequirementsDefinitionList, entry
87 RequirementDefinition cloneRequirementDefinition;
88 if (requirementDefinition.isPresent()) {
89 cloneRequirementDefinition = requirementDefinition.get().clone();
90 updateRequirementDefinition(nodeTypeRequirementsDefinitionList, entry,
91 cloneRequirementDefinition);
94 for (Map<String, RequirementDefinition> nodeTypeRequirementsMap :
95 nodeTypeRequirementsDefinitionList) {
96 updateMinMaxOccurencesForNodeTypeRequirement(entry, nodeTypeRequirementsMap);
100 return nodeTypeRequirementsDefinitionList;
103 private void updateMinMaxOccurencesForNodeTypeRequirement(
104 Map.Entry<String, RequirementAssignment> entry,
105 Map<String, RequirementDefinition> nodeTypeRequirementsMap) {
106 Object max = nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences() != null
107 && nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences().length > 0
108 ? nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences()[1] : 1;
109 Object min = nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences() != null
110 && nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences().length > 0
111 ? nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences()[0] : 1;
112 nodeTypeRequirementsMap.get(entry.getKey()).setOccurrences(new Object[]{min, max});
115 private void updateRequirementDefinition(
116 List<Map<String, RequirementDefinition>> nodeTypeRequirementsDefinitionList,
117 Map.Entry<String, RequirementAssignment> entry,
118 RequirementDefinition cloneRequirementDefinition) {
119 if (!evaluateRequirementFulfillment(cloneRequirementDefinition)) {
120 CommonMethods.mergeEntryInList(entry.getKey(), cloneRequirementDefinition,
121 nodeTypeRequirementsDefinitionList);
123 DataModelUtil.removeRequirementsDefinition(nodeTypeRequirementsDefinitionList, entry
128 private static boolean evaluateRequirementFulfillment(RequirementDefinition
129 requirementDefinition) {
130 Object[] occurrences = requirementDefinition.getOccurrences();
131 if (occurrences == null) {
132 requirementDefinition.setOccurrences(new Object[]{1, 1});
135 if (occurrences[1].equals(ToscaConstants.UNBOUNDED)) {
139 if (occurrences[1].equals(1)) {
142 occurrences[1] = (Integer) occurrences[1] - 1;
147 public Map<String, CapabilityDefinition> calculateExposedCapabilities(
148 Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition,
149 Map<String, Map<String, RequirementAssignment>> fullFilledRequirementsDefinitionMap) {
151 String capabilityKey;
154 for (Map.Entry<String, Map<String, RequirementAssignment>> entry :
155 fullFilledRequirementsDefinitionMap.entrySet()) {
156 for (Map.Entry<String, RequirementAssignment> fullFilledEntry : entry.getValue().entrySet()) {
158 capability = fullFilledEntry.getValue().getCapability();
159 node = fullFilledEntry.getValue().getNode();
160 capabilityKey = capability + "_" + node;
161 CapabilityDefinition capabilityDefinition = nodeTypeCapabilitiesDefinition.get(
163 if (capabilityDefinition != null) {
164 CapabilityDefinition clonedCapabilityDefinition = capabilityDefinition.clone();
165 nodeTypeCapabilitiesDefinition.put(capabilityKey, capabilityDefinition.clone());
166 updateNodeTypeCapabilitiesDefinition(nodeTypeCapabilitiesDefinition, capabilityKey,
167 clonedCapabilityDefinition);
172 Map<String, CapabilityDefinition> exposedCapabilitiesDefinition = new HashMap<>();
173 for (Map.Entry<String, CapabilityDefinition> entry : nodeTypeCapabilitiesDefinition
175 exposedCapabilitiesDefinition.put(entry.getKey(), entry.getValue());
177 return exposedCapabilitiesDefinition;
180 private void updateNodeTypeCapabilitiesDefinition(
181 Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition, String capabilityKey,
182 CapabilityDefinition clonedCapabilityDefinition) {
183 if (evaluateCapabilityFulfillment(clonedCapabilityDefinition)) {
184 nodeTypeCapabilitiesDefinition.remove(capabilityKey);
186 nodeTypeCapabilitiesDefinition.put(capabilityKey, clonedCapabilityDefinition);
190 private static boolean evaluateCapabilityFulfillment(CapabilityDefinition capabilityDefinition) {
192 Object[] occurrences = capabilityDefinition.getOccurrences();
193 if (occurrences == null) {
194 capabilityDefinition.setOccurrences(new Object[]{1, ToscaConstants.UNBOUNDED});
197 if (occurrences[1].equals(ToscaConstants.UNBOUNDED)) {
201 if (occurrences[1].equals(1)) {
204 occurrences[1] = (Integer) occurrences[1] - 1;
209 node template with type equal to node type or derived from node type
212 public Map<String, NodeTemplate> getNodeTemplatesByType(ServiceTemplate serviceTemplate,
214 ToscaServiceModel toscaServiceModel) {
215 Map<String, NodeTemplate> nodeTemplates = new HashMap<>();
217 if (Objects.nonNull(serviceTemplate.getTopology_template())
218 && MapUtils.isNotEmpty(serviceTemplate.getTopology_template().getNode_templates())) {
219 for (Map.Entry<String, NodeTemplate> nodeTemplateEntry : serviceTemplate
220 .getTopology_template().getNode_templates().entrySet()) {
221 if (isTypeOf(nodeTemplateEntry.getValue(), nodeType, serviceTemplate, toscaServiceModel)) {
222 nodeTemplates.put(nodeTemplateEntry.getKey(), nodeTemplateEntry.getValue());
227 return nodeTemplates;
231 public Optional<NodeType> fetchNodeType(String nodeTypeKey, Collection<ServiceTemplate>
233 Optional<Map<String, NodeType>> nodeTypeMap = serviceTemplates.stream()
234 .map(ServiceTemplate::getNode_types)
235 .filter(nodeTypes -> Objects.nonNull(nodeTypes) && nodeTypes.containsKey(nodeTypeKey))
237 return nodeTypeMap.map(stringNodeTypeMap -> stringNodeTypeMap.get(nodeTypeKey));
241 public boolean isTypeOf(NodeTemplate nodeTemplate, String nodeType,
242 ServiceTemplate serviceTemplate, ToscaServiceModel toscaServiceModel) {
243 return isTypeOf(nodeTemplate, nodeType, GET_NODE_TYPE_METHOD_NAME, serviceTemplate,
248 public List<RequirementAssignment> getRequirements(NodeTemplate nodeTemplate,
249 String requirementId) {
250 List<RequirementAssignment> requirements = new ArrayList<>();
251 List<Map<String, RequirementAssignment>> requirementList = nodeTemplate.getRequirements();
252 if (requirementList != null) {
253 requirementList.stream().filter(reqMap -> reqMap.get(requirementId) != null)
255 ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
256 RequirementAssignment reqAssignment = toscaExtensionYamlUtil
257 .yamlToObject(toscaExtensionYamlUtil.objectToYaml(reqMap.get(requirementId)),
258 RequirementAssignment.class);
259 requirements.add(reqAssignment);
266 public Optional<NodeTemplate> getNodeTemplateById(ServiceTemplate serviceTemplate,
267 String nodeTemplateId) {
268 if ((serviceTemplate.getTopology_template() != null)
269 && (serviceTemplate.getTopology_template().getNode_templates() != null)
270 && (serviceTemplate.getTopology_template().getNode_templates().get(nodeTemplateId)
273 .of(serviceTemplate.getTopology_template().getNode_templates().get(nodeTemplateId));
275 return Optional.empty();
279 public Optional<String> getSubstituteServiceTemplateName(String substituteNodeTemplateId,
280 NodeTemplate substitutableNodeTemplate) {
281 if (!isSubstitutableNodeTemplate(substitutableNodeTemplate)) {
282 return Optional.empty();
285 if (substitutableNodeTemplate.getProperties() != null
286 && substitutableNodeTemplate.getProperties()
287 .get(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME) != null) {
288 Object serviceTemplateFilter = substitutableNodeTemplate.getProperties()
289 .get(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME);
290 if (serviceTemplateFilter != null && serviceTemplateFilter instanceof Map) {
291 Object substituteServiceTemplate = ((Map) serviceTemplateFilter)
292 .get(ToscaConstants.SUBSTITUTE_SERVICE_TEMPLATE_PROPERTY_NAME);
293 handleNoSubstituteServiceTemplate(substituteNodeTemplateId, substituteServiceTemplate);
294 return Optional.of(substituteServiceTemplate.toString());
297 throw new CoreException(
298 new ToscaInvalidSubstituteNodeTemplatePropertiesErrorBuilder(substituteNodeTemplateId)
302 private void handleNoSubstituteServiceTemplate(String substituteNodeTemplateId,
303 Object substituteServiceTemplate) {
304 if (substituteServiceTemplate == null) {
305 throw new CoreException(
306 new ToscaInvalidSubstituteNodeTemplatePropertiesErrorBuilder(substituteNodeTemplateId)
312 public Map<String, NodeTemplate> getSubstitutableNodeTemplates(ServiceTemplate serviceTemplate) {
313 Map<String, NodeTemplate> substitutableNodeTemplates = new HashMap<>();
315 if (serviceTemplate == null
316 || serviceTemplate.getTopology_template() == null
317 || serviceTemplate.getTopology_template().getNode_templates() == null) {
318 return substitutableNodeTemplates;
321 Map<String, NodeTemplate> nodeTemplates =
322 serviceTemplate.getTopology_template().getNode_templates();
323 for (Map.Entry<String, NodeTemplate> entry : nodeTemplates.entrySet()) {
324 String nodeTemplateId = entry.getKey();
325 NodeTemplate nodeTemplate = entry.getValue();
326 if (isSubstitutableNodeTemplate(nodeTemplate)) {
327 substitutableNodeTemplates.put(nodeTemplateId, nodeTemplate);
331 return substitutableNodeTemplates;
335 public Optional<Map.Entry<String, NodeTemplate>> getSubstitutionMappedNodeTemplateByExposedReq(
336 String substituteServiceTemplateFileName, ServiceTemplate substituteServiceTemplate,
337 String requirementId) {
338 if (isSubstitutionServiceTemplate(substituteServiceTemplateFileName,
339 substituteServiceTemplate)) {
340 Map<String, List<String>> substitutionMappingRequirements =
341 substituteServiceTemplate.getTopology_template().getSubstitution_mappings()
343 if (substitutionMappingRequirements != null) {
344 List<String> requirementMapping = substitutionMappingRequirements.get(requirementId);
345 if (requirementMapping != null && !requirementMapping.isEmpty()) {
346 String mappedNodeTemplateId = requirementMapping.get(0);
347 Optional<NodeTemplate> mappedNodeTemplate =
348 getNodeTemplateById(substituteServiceTemplate, mappedNodeTemplateId);
349 mappedNodeTemplate.orElseThrow(() -> new CoreException(
350 new ToscaInvalidEntryNotFoundErrorBuilder("Node Template", mappedNodeTemplateId)
352 Map.Entry<String, NodeTemplate> mappedNodeTemplateEntry =
353 new Map.Entry<String, NodeTemplate>() {
355 public String getKey() {
356 return mappedNodeTemplateId;
360 public NodeTemplate getValue() {
361 return mappedNodeTemplate.get();
365 public NodeTemplate setValue(NodeTemplate value) {
369 return Optional.of(mappedNodeTemplateEntry);
373 return Optional.empty();
377 match only for the input which is not null
380 public boolean isDesiredRequirementAssignment(RequirementAssignment requirementAssignment,
381 String capability, String node,
382 String relationship) {
383 if (isSameCapability(requirementAssignment, capability)) {
387 if (isSameRequirement(requirementAssignment, node)) {
391 if (isSameRelationship(requirementAssignment, relationship)) {
395 return !(capability == null && node == null && relationship == null);
399 private boolean isSameRelationship(RequirementAssignment requirementAssignment,
400 String relationship) {
401 return relationship != null && (requirementAssignment.getRelationship() == null
402 || !requirementAssignment.getRelationship().equals(relationship));
405 private boolean isSameRequirement(RequirementAssignment requirementAssignment, String node) {
406 return node != null && (requirementAssignment.getNode() == null
407 || !requirementAssignment.getNode().equals(node));
410 private boolean isSameCapability(RequirementAssignment requirementAssignment, String capability) {
411 return capability != null && (requirementAssignment.getCapability() == null
412 || !requirementAssignment.getCapability().equals(capability));
416 public Object getFlatEntity(ToscaElementTypes elementType, String typeId,
417 ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel) {
420 switch (elementType) {
421 case CAPABILITY_TYPE:
422 returnEntity = new CapabilityType();
425 returnEntity = new NodeType();
428 returnEntity = new DataType();
431 throw new RuntimeException(
432 "Entity[" + elementType + "] id[" + typeId + "] flat not supported");
435 boolean isEntityFound =
436 scanAnFlatEntity(elementType, typeId, returnEntity, serviceTemplate, toscaModel,
437 new ArrayList<>(), 0);
438 if (!isEntityFound) {
439 throw new CoreException(new ToscaElementTypeNotFoundErrorBuilder(typeId).build());
446 public boolean isSubstitutableNodeTemplate(NodeTemplate nodeTemplate) {
447 return nodeTemplate.getDirectives() != null
448 && nodeTemplate.getDirectives().contains(ToscaConstants
449 .NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
452 private <T> Optional<Boolean> isTypeExistInServiceTemplateHierarchy(String typeToMatch,
454 String getTypesMethodName,
455 ServiceTemplate serviceTemplate,
456 ToscaServiceModel toscaServiceModel,
457 Set<String> analyzedImportFiles)
458 throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
459 Map<String, T> searchableTypes =
460 (Map<String, T>) serviceTemplate.getClass().getMethod(getTypesMethodName)
461 .invoke(serviceTemplate);
463 if (!MapUtils.isEmpty(searchableTypes)) {
464 T typeObject = searchableTypes.get(typeToSearch);
465 if (Objects.nonNull(typeObject)) {
466 String derivedFromTypeVal =
467 (String) typeObject.getClass().getMethod(GET_DERIVED_FROM_METHOD_NAME).invoke(typeObject);
468 if (Objects.equals(derivedFromTypeVal, typeToMatch)) {
469 return Optional.of(true);
470 } else if (Objects.isNull(derivedFromTypeVal) || isTypeIsToscaRoot(derivedFromTypeVal)) {
471 return Optional.of(false);
473 return isTypeExistInServiceTemplateHierarchy(typeToMatch,
474 derivedFromTypeVal, getTypesMethodName, serviceTemplate, toscaServiceModel, null);
477 return isTypeExistInImports(typeToMatch, typeToSearch, getTypesMethodName,
478 serviceTemplate, toscaServiceModel, analyzedImportFiles);
481 return isTypeExistInImports(typeToMatch, typeToSearch, getTypesMethodName, serviceTemplate,
482 toscaServiceModel, analyzedImportFiles);
485 private Optional<Boolean> isTypeExistInImports(String typeToMatch,
487 String getTypesMethodName,
488 ServiceTemplate serviceTemplate,
489 ToscaServiceModel toscaServiceModel,
490 Set<String> filesScanned)
491 throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
492 List<Map<String, Import>> imports = serviceTemplate.getImports();
493 if (CollectionUtils.isEmpty(imports)) {
494 return Optional.empty();
497 Set<String> createdFilesScanned = createFilesScannedSet(filesScanned);
499 for (Map<String, Import> map : imports) {
500 ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
501 Import anImport = toscaExtensionYamlUtil
502 .yamlToObject(toscaExtensionYamlUtil.objectToYaml(map.values().iterator().next()),
504 handleImportWithNoFileEntry(anImport);
505 String importFile = anImport.getFile();
506 ServiceTemplate template =
507 toscaServiceModel.getServiceTemplates().get(fetchFileNameForImport(importFile,
508 serviceTemplate.getMetadata() == null ? null
509 : serviceTemplate.getMetadata().get("filename")));
510 if (Objects.isNull(template)
511 || createdFilesScanned.contains(ToscaUtil.getServiceTemplateFileName(template))) {
514 createdFilesScanned.add(ToscaUtil.getServiceTemplateFileName(template));
516 Optional<Boolean> typeExistInServiceTemplateHierarchy =
517 isTypeExistInServiceTemplateHierarchy(typeToMatch, typeToSearch, getTypesMethodName,
518 template, toscaServiceModel, createdFilesScanned);
519 if (typeExistInServiceTemplateHierarchy.isPresent()
520 && (typeExistInServiceTemplateHierarchy.get())) {
521 createdFilesScanned.clear();
522 return Optional.of(true);
526 return Optional.of(false);
529 private void handleImportWithNoFileEntry(Import anImport) {
530 if (Objects.isNull(anImport) || Objects.isNull(anImport.getFile())) {
531 throw new RuntimeException("import without file entry");
535 private Set<String> createFilesScannedSet(Set<String> filesScanned) {
536 Set<String> retFileScanned = filesScanned;
537 if (Objects.isNull(retFileScanned)) {
538 retFileScanned = new HashSet<>();
540 return retFileScanned;
543 private boolean isTypeIsToscaRoot(String type) {
544 return (type.contains(TOSCA_DOT) && type.contains(DOT_ROOT));
547 private boolean isSubstitutionServiceTemplate(String substituteServiceTemplateFileName,
548 ServiceTemplate substituteServiceTemplate) {
549 if (substituteServiceTemplate != null
550 && substituteServiceTemplate.getTopology_template() != null
551 && substituteServiceTemplate.getTopology_template().getSubstitution_mappings() != null) {
552 if (substituteServiceTemplate.getTopology_template().getSubstitution_mappings()
553 .getNode_type() == null) {
554 throw new CoreException(new ToscaInvalidSubstitutionServiceTemplateErrorBuilder(
555 substituteServiceTemplateFileName).build());
563 private boolean scanAnFlatEntity(ToscaElementTypes elementType, String typeId, Object entity,
564 ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel,
565 List<String> filesScanned, int rootScanStartInx) {
568 boolean entityFound = enrichEntityFromCurrentServiceTemplate(elementType, typeId, entity,
569 serviceTemplate, toscaModel, filesScanned, rootScanStartInx);
571 List<Map<String, Import>> imports = serviceTemplate.getImports();
572 if (CollectionUtils.isEmpty(imports)) {
575 boolean found = false;
576 for (Map<String, Import> importMap : imports) {
580 found = isFlatEntity(importMap, entity, serviceTemplate, filesScanned,
581 toscaModel, elementType, typeId);
588 private boolean isFlatEntity(Map<String, Import> importMap,
590 ServiceTemplate serviceTemplate,
591 List<String> filesScanned,
592 ToscaServiceModel toscaModel,
593 ToscaElementTypes elementType, String typeId) {
594 boolean found = false;
595 ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
596 for (Object importObject : importMap.values()) {
597 Import importServiceTemplate = toscaExtensionYamlUtil
598 .yamlToObject(toscaExtensionYamlUtil.objectToYaml(importObject), Import.class);
599 String fileName = fetchFileNameForImport(importServiceTemplate.getFile(),
600 serviceTemplate.getMetadata() == null ? null : serviceTemplate.getMetadata().get(
602 if (filesScanned.contains(fileName)) {
605 filesScanned.add(fileName);
607 ServiceTemplate template = toscaModel.getServiceTemplates().get(fileName);
608 if (Objects.isNull(template)) {
609 throw new CoreException(
610 new ToscaFileNotFoundErrorBuilder(fileName).build());
612 found = scanAnFlatEntity(elementType, typeId, entity, template, toscaModel,
613 filesScanned, filesScanned.size());
618 private String fetchFileNameForImport(String importServiceTemplateFile,
619 String currentMetadatafileName) {
620 if (importServiceTemplateFile.contains("../")) {
621 return importServiceTemplateFile.replace("../", "");
622 } else if (currentMetadatafileName != null) {
623 return currentMetadatafileName.substring(0, currentMetadatafileName.indexOf('/')) + "/"
624 + importServiceTemplateFile;
626 return importServiceTemplateFile;
631 private boolean enrichEntityFromCurrentServiceTemplate(ToscaElementTypes elementType,
632 String typeId, Object entity,
633 ServiceTemplate serviceTemplate,
634 ToscaServiceModel toscaModel,
635 List<String> filesScanned,
636 int rootScanStartInx) {
637 switch (elementType) {
638 case CAPABILITY_TYPE:
639 if (enrichCapabilityType(elementType, typeId, entity, serviceTemplate, toscaModel,
640 filesScanned, rootScanStartInx)) {
645 if (enrichNodeTypeInfo(elementType, typeId, entity, serviceTemplate, toscaModel,
646 filesScanned, rootScanStartInx)) {
651 if (enrichDataTypeInfo(elementType, typeId, entity, serviceTemplate, toscaModel,
652 filesScanned, rootScanStartInx)) {
657 throw new RuntimeException(
658 "Entity[" + elementType + "] id[" + typeId + "] flat not supported");
666 private boolean enrichNodeTypeInfo(ToscaElementTypes elementType, String typeId, Object entity,
667 ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel,
668 List<String> filesScanned, int rootScanStartInx) {
670 if (serviceTemplate.getNode_types() != null
671 && serviceTemplate.getNode_types().containsKey(typeId)) {
673 filesScanned.clear();
674 NodeType targetNodeType = (NodeType) entity;
675 NodeType sourceNodeType = serviceTemplate.getNode_types().get(typeId);
676 derivedFrom = sourceNodeType.getDerived_from();
677 if (derivedFrom != null) {
678 scanAnFlatEntity(elementType, derivedFrom, entity, serviceTemplate, toscaModel,
679 filesScanned, rootScanStartInx);
681 combineNodeTypeInfo(sourceNodeType, targetNodeType);
688 private boolean enrichDataTypeInfo(ToscaElementTypes elementType, String typeId, Object entity,
689 ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel,
690 List<String> filesScanned, int rootScanStartInx) {
692 if (serviceTemplate.getData_types() != null
693 && serviceTemplate.getData_types().containsKey(typeId)) {
695 filesScanned.clear();
696 DataType targetDataType = (DataType) entity;
697 DataType sourceDataType = serviceTemplate.getData_types().get(typeId);
698 derivedFrom = sourceDataType.getDerived_from();
699 if (derivedFrom != null) {
700 scanAnFlatEntity(elementType, derivedFrom, entity, serviceTemplate, toscaModel,
701 filesScanned, rootScanStartInx);
703 combineDataTypeInfo(sourceDataType, targetDataType);
710 private boolean enrichCapabilityType(ToscaElementTypes elementType, String typeId, Object entity,
711 ServiceTemplate serviceTemplate,
712 ToscaServiceModel toscaModel, List<String> filesScanned,
713 int rootScanStartInx) {
715 if (serviceTemplate.getCapability_types() != null
716 && serviceTemplate.getCapability_types().containsKey(typeId)) {
718 filesScanned.clear();
719 CapabilityType targetCapabilityType = (CapabilityType) entity;
720 CapabilityType sourceCapabilityType = serviceTemplate.getCapability_types().get(typeId);
721 derivedFrom = sourceCapabilityType.getDerived_from();
722 if (derivedFrom != null) {
723 scanAnFlatEntity(elementType, derivedFrom, entity, serviceTemplate, toscaModel,
724 filesScanned, rootScanStartInx);
726 combineCapabilityTypeInfo(sourceCapabilityType, targetCapabilityType);
733 private void combineNodeTypeInfo(NodeType sourceNodeType, NodeType targetNodeType) {
734 targetNodeType.setDerived_from(sourceNodeType.getDerived_from());
735 targetNodeType.setDescription(sourceNodeType.getDescription());
736 targetNodeType.setVersion(sourceNodeType.getVersion());
737 targetNodeType.setProperties(
738 CommonMethods.mergeMaps(targetNodeType.getProperties(), sourceNodeType.getProperties()));
739 targetNodeType.setInterfaces(
740 CommonMethods.mergeMaps(targetNodeType.getInterfaces(), sourceNodeType.getInterfaces()));
741 targetNodeType.setArtifacts(
742 CommonMethods.mergeMaps(targetNodeType.getArtifacts(), sourceNodeType.getArtifacts()));
743 targetNodeType.setAttributes(
744 CommonMethods.mergeMaps(targetNodeType.getAttributes(), sourceNodeType.getAttributes()));
745 targetNodeType.setCapabilities(CommonMethods
746 .mergeMaps(targetNodeType.getCapabilities(), sourceNodeType.getCapabilities()));
747 targetNodeType.setRequirements(CommonMethods
748 .mergeListsOfMap(targetNodeType.getRequirements(), sourceNodeType.getRequirements()));
752 private void combineDataTypeInfo(DataType sourceDataType, DataType targetDataType) {
753 targetDataType.setDerived_from(sourceDataType.getDerived_from());
754 targetDataType.setDescription(sourceDataType.getDescription());
755 targetDataType.setVersion(sourceDataType.getVersion());
756 targetDataType.setProperties(
757 CommonMethods.mergeMaps(targetDataType.getProperties(), sourceDataType.getProperties()));
758 targetDataType.setConstraints(
759 CommonMethods.mergeLists(targetDataType.getConstraints(), sourceDataType.getConstraints()));
763 private void combineCapabilityTypeInfo(CapabilityType sourceCapabilityType,
764 CapabilityType targetCapabilityType) {
766 targetCapabilityType.setAttributes(CommonMethods
767 .mergeMaps(targetCapabilityType.getAttributes(), sourceCapabilityType.getAttributes()));
768 targetCapabilityType.setProperties(CommonMethods
769 .mergeMaps(targetCapabilityType.getProperties(), sourceCapabilityType.getProperties()));
770 targetCapabilityType.setValid_source_types(CommonMethods
771 .mergeLists(targetCapabilityType.getValid_source_types(),
772 sourceCapabilityType.getValid_source_types()));
774 if (StringUtils.isNotEmpty(sourceCapabilityType.getDerived_from())) {
775 targetCapabilityType.setDerived_from(sourceCapabilityType.getDerived_from());
777 if (StringUtils.isNotEmpty(sourceCapabilityType.getDescription())) {
778 targetCapabilityType.setDescription(sourceCapabilityType.getDescription());
780 if (StringUtils.isNotEmpty(sourceCapabilityType.getVersion())) {
781 targetCapabilityType.setVersion(sourceCapabilityType.getVersion());
789 * Create node type according to the input substitution service template, while the substitution
790 * service template can be mappted to this node type, for substitution mapping.
792 * @param substitutionServiceTemplate substitution serivce template
793 * @param nodeTypeDerivedFromValue derived from value for the created node type
794 * @return the node type
797 public NodeType createInitSubstitutionNodeType(ServiceTemplate substitutionServiceTemplate,
798 String nodeTypeDerivedFromValue) {
799 NodeType substitutionNodeType = new NodeType();
800 substitutionNodeType.setDerived_from(nodeTypeDerivedFromValue);
801 substitutionNodeType.setDescription(substitutionServiceTemplate.getDescription());
803 .setProperties(manageSubstitutionNodeTypeProperties(substitutionServiceTemplate));
805 .setAttributes(manageSubstitutionNodeTypeAttributes(substitutionServiceTemplate));
806 return substitutionNodeType;
810 public Map<String, PropertyDefinition> manageSubstitutionNodeTypeProperties(
811 ServiceTemplate substitutionServiceTemplate) {
812 Map<String, PropertyDefinition> substitutionNodeTypeProperties = new HashMap<>();
813 Map<String, ParameterDefinition> properties =
814 substitutionServiceTemplate.getTopology_template().getInputs();
815 if (properties == null) {
819 PropertyDefinition propertyDefinition;
820 String toscaPropertyName;
821 for (Map.Entry<String, ParameterDefinition> entry : properties.entrySet()) {
822 toscaPropertyName = entry.getKey();
823 propertyDefinition = new PropertyDefinition();
824 ParameterDefinition parameterDefinition =
825 substitutionServiceTemplate.getTopology_template().getInputs().get(toscaPropertyName);
826 propertyDefinition.setType(parameterDefinition.getType());
827 propertyDefinition.setDescription(parameterDefinition.getDescription());
828 propertyDefinition.set_default(parameterDefinition.get_default());
829 if (parameterDefinition.getRequired() != null) {
830 propertyDefinition.setRequired(parameterDefinition.getRequired());
832 if (propertyDefinition.get_default() != null) {
833 propertyDefinition.setRequired(false);
835 if (!CollectionUtils.isEmpty(parameterDefinition.getConstraints())) {
836 propertyDefinition.setConstraints(parameterDefinition.getConstraints());
838 propertyDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
839 if (parameterDefinition.getStatus() != null) {
840 propertyDefinition.setStatus(parameterDefinition.getStatus());
842 substitutionNodeTypeProperties.put(toscaPropertyName, propertyDefinition);
844 return substitutionNodeTypeProperties;
848 private Map<String, AttributeDefinition> manageSubstitutionNodeTypeAttributes(
849 ServiceTemplate substitutionServiceTemplate) {
850 Map<String, AttributeDefinition> substitutionNodeTypeAttributes = new HashMap<>();
851 Map<String, ParameterDefinition> attributes =
852 substitutionServiceTemplate.getTopology_template().getOutputs();
853 if (attributes == null) {
856 AttributeDefinition attributeDefinition;
857 String toscaAttributeName;
859 for (Map.Entry<String, ParameterDefinition> entry : attributes.entrySet()) {
860 attributeDefinition = new AttributeDefinition();
861 toscaAttributeName = entry.getKey();
862 ParameterDefinition parameterDefinition =
863 substitutionServiceTemplate.getTopology_template().getOutputs().get(toscaAttributeName);
864 if (parameterDefinition.getType() != null && !parameterDefinition.getType().isEmpty()) {
865 attributeDefinition.setType(parameterDefinition.getType());
867 attributeDefinition.setType(PropertyType.STRING.getDisplayName());
869 attributeDefinition.setDescription(parameterDefinition.getDescription());
870 attributeDefinition.set_default(parameterDefinition.get_default());
871 attributeDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
872 if (Objects.nonNull(parameterDefinition.getStatus())) {
873 attributeDefinition.setStatus(parameterDefinition.getStatus());
875 substitutionNodeTypeAttributes.put(toscaAttributeName, attributeDefinition);
877 return substitutionNodeTypeAttributes;
881 * Checks if the requirement exists in the node template.
883 * @param nodeTemplate the node template
884 * @param requirementId the requirement id
885 * @param requirementAssignment the requirement assignment
886 * @return true if the requirement already exists and false otherwise
889 public boolean isRequirementExistInNodeTemplate(NodeTemplate nodeTemplate,
890 String requirementId,
891 RequirementAssignment requirementAssignment) {
892 List<Map<String, RequirementAssignment>> nodeTemplateRequirements = nodeTemplate
894 return nodeTemplateRequirements != null && nodeTemplateRequirements.stream().anyMatch(
895 requirement -> requirement.containsKey(requirementId) && DataModelUtil
896 .compareRequirementAssignment(requirementAssignment, requirement.get(requirementId)));
900 public boolean isTypeOf(InterfaceDefinitionType interfaceDefinition, String interfaceType,
901 ServiceTemplate serviceTemplate, ToscaServiceModel toscaServiceModel) {
902 return isTypeOf(interfaceDefinition, interfaceType, GET_INTERFACE_TYPE_METHOD_NAME, serviceTemplate,
907 public boolean isTypeOf(DefinitionOfDataType parameterDefinition, String dataType,
908 ServiceTemplate serviceTemplate, ToscaServiceModel toscaServiceModel) {
909 return isTypeOf(parameterDefinition, dataType, GET_DATA_TYPE_METHOD_NAME, serviceTemplate,
913 private <T> boolean isTypeOf(T object, String type, String getTypesMethodName,
914 ServiceTemplate serviceTemplate,
915 ToscaServiceModel toscaServiceModel) {
916 if (object == null) {
921 String objectType = (String) object.getClass().getMethod(GET_TYPE_METHOD_NAME).invoke(object);
922 if (Objects.equals(objectType, type)) {
926 Optional<Boolean> typeExistInServiceTemplateHierarchy =
927 isTypeExistInServiceTemplateHierarchy(type, objectType, getTypesMethodName,
928 serviceTemplate, toscaServiceModel, null);
929 return typeExistInServiceTemplateHierarchy.orElseThrow(() -> new CoreException(
930 new ToscaElementTypeNotFoundErrorBuilder(objectType).build()));
932 } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
933 throw new RuntimeException(e);