2  * ============LICENSE_START=======================================================
 
   4  * ================================================================================
 
   5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
 
   6  * ================================================================================
 
   7  * Licensed under the Apache License, Version 2.0 (the "License");
 
   8  * you may not use this file except in compliance with the License.
 
   9  * You may obtain a copy of the License at
 
  11  *      http://www.apache.org/licenses/LICENSE-2.0
 
  13  * Unless required by applicable law or agreed to in writing, software
 
  14  * distributed under the License is distributed on an "AS IS" BASIS,
 
  15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  16  * See the License for the specific language governing permissions and
 
  17  * limitations under the License.
 
  18  * ============LICENSE_END=========================================================
 
  21 package org.openecomp.sdc.tosca.services.impl;
 
  23 import org.apache.commons.collections4.CollectionUtils;
 
  24 import org.apache.commons.collections4.MapUtils;
 
  25 import org.openecomp.core.utilities.CommonMethods;
 
  26 import org.openecomp.sdc.common.errors.CoreException;
 
  27 import org.openecomp.sdc.datatypes.error.ErrorLevel;
 
  28 import org.openecomp.sdc.logging.context.impl.MdcDataDebugMessage;
 
  29 import org.openecomp.sdc.logging.context.impl.MdcDataErrorMessage;
 
  30 import org.openecomp.sdc.logging.types.LoggerConstants;
 
  31 import org.openecomp.sdc.logging.types.LoggerErrorCode;
 
  32 import org.openecomp.sdc.logging.types.LoggerErrorDescription;
 
  33 import org.openecomp.sdc.logging.types.LoggerTragetServiceName;
 
  34 import org.openecomp.sdc.tosca.datatypes.ToscaElementTypes;
 
  35 import org.openecomp.sdc.tosca.datatypes.ToscaNodeType;
 
  36 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
 
  37 import org.openecomp.sdc.tosca.datatypes.model.AttributeDefinition;
 
  38 import org.openecomp.sdc.tosca.datatypes.model.CapabilityDefinition;
 
  39 import org.openecomp.sdc.tosca.datatypes.model.CapabilityType;
 
  40 import org.openecomp.sdc.tosca.datatypes.model.Import;
 
  41 import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
 
  42 import org.openecomp.sdc.tosca.datatypes.model.NodeType;
 
  43 import org.openecomp.sdc.tosca.datatypes.model.ParameterDefinition;
 
  44 import org.openecomp.sdc.tosca.datatypes.model.PropertyDefinition;
 
  45 import org.openecomp.sdc.tosca.datatypes.model.PropertyType;
 
  46 import org.openecomp.sdc.tosca.datatypes.model.RequirementAssignment;
 
  47 import org.openecomp.sdc.tosca.datatypes.model.RequirementDefinition;
 
  48 import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate;
 
  49 import org.openecomp.sdc.tosca.errors.ToscaInvalidEntryNotFoundErrorBuilder;
 
  50 import org.openecomp.sdc.tosca.errors.ToscaInvalidSubstituteNodeTemplatePropertiesErrorBuilder;
 
  51 import org.openecomp.sdc.tosca.errors.ToscaInvalidSubstitutionServiceTemplateErrorBuilder;
 
  52 import org.openecomp.sdc.tosca.errors.ToscaNodeTypeNotFoundErrorBuilder;
 
  53 import org.openecomp.sdc.tosca.services.DataModelUtil;
 
  54 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
 
  55 import org.openecomp.sdc.tosca.services.ToscaConstants;
 
  56 import org.openecomp.sdc.tosca.services.ToscaExtensionYamlUtil;
 
  57 import org.openecomp.sdc.tosca.services.ToscaUtil;
 
  59 import java.util.ArrayList;
 
  60 import java.util.Collection;
 
  61 import java.util.HashMap;
 
  62 import java.util.HashSet;
 
  63 import java.util.List;
 
  65 import java.util.Objects;
 
  66 import java.util.Optional;
 
  69 public class ToscaAnalyzerServiceImpl implements ToscaAnalyzerService {
 
  71   protected static MdcDataDebugMessage mdcDataDebugMessage = new MdcDataDebugMessage();
 
  73   public List<Map<String, RequirementDefinition>> calculateExposedRequirements(
 
  74       List<Map<String, RequirementDefinition>> nodeTypeRequirementsDefinitionList,
 
  75       Map<String, RequirementAssignment> nodeTemplateRequirementsAssignment) {
 
  76     mdcDataDebugMessage.debugEntryMessage(null, null);
 
  78     if (nodeTypeRequirementsDefinitionList == null) {
 
  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           if (!evaluateRequirementFulfillment(cloneRequirementDefinition)) {
 
  91             CommonMethods.mergeEntryInList(entry.getKey(), cloneRequirementDefinition,
 
  92                 nodeTypeRequirementsDefinitionList);
 
  94             DataModelUtil.removeRequirementsDefinition(nodeTypeRequirementsDefinitionList, entry
 
  99         for (Map<String, RequirementDefinition> nodeTypeRequirementsMap :
 
 100             nodeTypeRequirementsDefinitionList) {
 
 101           Object max = nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences() != null
 
 102               && nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences().length > 0
 
 103               ? nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences()[1] : 1;
 
 104           Object min = nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences() != null
 
 105               && nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences().length > 0
 
 106               ? nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences()[0] : 1;
 
 107           nodeTypeRequirementsMap.get(entry.getKey()).setOccurrences(new Object[]{min, max});
 
 112     mdcDataDebugMessage.debugExitMessage(null, null);
 
 113     return nodeTypeRequirementsDefinitionList;
 
 116   private static boolean evaluateRequirementFulfillment(RequirementDefinition
 
 117                                                             requirementDefinition) {
 
 118     Object[] occurrences = requirementDefinition.getOccurrences();
 
 119     if (occurrences == null) {
 
 120       requirementDefinition.setOccurrences(new Object[]{1, 1});
 
 123     if (occurrences[1].equals(ToscaConstants.UNBOUNDED)) {
 
 127     if (occurrences[1].equals(1)) {
 
 130     occurrences[1] = (Integer) occurrences[1] - 1;
 
 134   public Map<String, CapabilityDefinition> calculateExposedCapabilities(
 
 135       Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition,
 
 136       Map<String, Map<String, RequirementAssignment>> fullFilledRequirementsDefinitionMap) {
 
 139     mdcDataDebugMessage.debugEntryMessage(null, null);
 
 141     String capabilityKey;
 
 144     for (Map.Entry<String, Map<String, RequirementAssignment>> entry :
 
 145         fullFilledRequirementsDefinitionMap.entrySet()) {
 
 146       for (Map.Entry<String, RequirementAssignment> fullFilledEntry : entry.getValue().entrySet()) {
 
 148         capability = fullFilledEntry.getValue().getCapability();
 
 149         fullFilledEntry.getValue().getOccurrences();
 
 150         node = fullFilledEntry.getValue().getNode();
 
 151         capabilityKey = capability + "_" + node;
 
 152         CapabilityDefinition capabilityDefinition = nodeTypeCapabilitiesDefinition.get(
 
 154         if (capabilityDefinition != null) {
 
 155           CapabilityDefinition clonedCapabilityDefinition = capabilityDefinition.clone();
 
 156           nodeTypeCapabilitiesDefinition.put(capabilityKey, capabilityDefinition.clone());
 
 157           if (evaluateCapabilityFulfillment(clonedCapabilityDefinition)) {
 
 158             nodeTypeCapabilitiesDefinition.remove(capabilityKey);
 
 160             nodeTypeCapabilitiesDefinition.put(capabilityKey, clonedCapabilityDefinition);
 
 166     Map<String, CapabilityDefinition> exposedCapabilitiesDefinition = new HashMap<>();
 
 167     for (Map.Entry<String, CapabilityDefinition> entry : nodeTypeCapabilitiesDefinition
 
 169       exposedCapabilitiesDefinition.put(entry.getKey(), entry.getValue());
 
 172     mdcDataDebugMessage.debugExitMessage(null, null);
 
 173     return exposedCapabilitiesDefinition;
 
 176   private static boolean evaluateCapabilityFulfillment(CapabilityDefinition capabilityDefinition) {
 
 178     Object[] occurrences = capabilityDefinition.getOccurrences();
 
 179     if (occurrences == null) {
 
 180       capabilityDefinition.setOccurrences(new Object[]{1, ToscaConstants.UNBOUNDED});
 
 183     if (occurrences[1].equals(ToscaConstants.UNBOUNDED)) {
 
 187     if (occurrences[1].equals(1)) {
 
 190     occurrences[1] = (Integer) occurrences[1] - 1;
 
 195     node template with type equal to node type or derived from node type
 
 198   public Map<String, NodeTemplate> getNodeTemplatesByType(ServiceTemplate serviceTemplate,
 
 200                                                           ToscaServiceModel toscaServiceModel) {
 
 201     Map<String, NodeTemplate> nodeTemplates = new HashMap<>();
 
 203     if (Objects.nonNull(serviceTemplate.getTopology_template())
 
 204         && MapUtils.isNotEmpty(serviceTemplate.getTopology_template().getNode_templates())) {
 
 205       for (Map.Entry<String, NodeTemplate> nodeTemplateEntry : serviceTemplate
 
 206           .getTopology_template().getNode_templates().entrySet()) {
 
 207         if (isTypeOf(nodeTemplateEntry.getValue(), nodeType, serviceTemplate, toscaServiceModel)) {
 
 208           nodeTemplates.put(nodeTemplateEntry.getKey(), nodeTemplateEntry.getValue());
 
 213     return nodeTemplates;
 
 217   public Optional<NodeType> fetchNodeType(String nodeTypeKey, Collection<ServiceTemplate>
 
 219     Optional<Map<String, NodeType>> nodeTypeMap = serviceTemplates.stream()
 
 220         .map(st -> st.getNode_types())
 
 221         .filter(nodeTypes -> Objects.nonNull(nodeTypes) && nodeTypes.containsKey(nodeTypeKey))
 
 223     if (nodeTypeMap.isPresent()) {
 
 224       return Optional.ofNullable(nodeTypeMap.get().get(nodeTypeKey));
 
 226     return Optional.empty();
 
 230   public boolean isTypeOf(NodeTemplate nodeTemplate, String nodeType,
 
 231                           ServiceTemplate serviceTemplate, ToscaServiceModel toscaServiceModel) {
 
 232     if (nodeTemplate == null) {
 
 236     if (isNodeTemplateOfTypeNodeType(nodeTemplate, nodeType)) {
 
 240     Optional<Boolean> nodeTypeExistInServiceTemplateHierarchy =
 
 241         isNodeTypeExistInServiceTemplateHierarchy(nodeType, nodeTemplate.getType(), serviceTemplate,
 
 242             toscaServiceModel, null);
 
 243     return nodeTypeExistInServiceTemplateHierarchy.orElseThrow(() -> new CoreException(
 
 244         new ToscaNodeTypeNotFoundErrorBuilder(nodeTemplate.getType()).build()));
 
 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         if (substituteServiceTemplate == null) {
 
 294           MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
 
 295               LoggerTragetServiceName.ADD_ENTITIES_TO_TOSCA, ErrorLevel.ERROR.name(),
 
 296               LoggerErrorCode.DATA_ERROR.getErrorCode(), LoggerErrorDescription.INVALID_PROPERTY);
 
 297           throw new CoreException(
 
 298               new ToscaInvalidSubstituteNodeTemplatePropertiesErrorBuilder(substituteNodeTemplateId)
 
 301         return Optional.of(substituteServiceTemplate.toString());
 
 304     MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
 
 305         LoggerTragetServiceName.ADD_ENTITIES_TO_TOSCA, ErrorLevel.ERROR.name(),
 
 306         LoggerErrorCode.DATA_ERROR.getErrorCode(), LoggerErrorDescription.INVALID_PROPERTY);
 
 307     throw new CoreException(
 
 308         new ToscaInvalidSubstituteNodeTemplatePropertiesErrorBuilder(substituteNodeTemplateId)
 
 313   public Map<String, NodeTemplate> getSubstitutableNodeTemplates(ServiceTemplate serviceTemplate) {
 
 314     Map<String, NodeTemplate> substitutableNodeTemplates = new HashMap<>();
 
 316     if (serviceTemplate == null
 
 317         || serviceTemplate.getTopology_template() == null
 
 318         || serviceTemplate.getTopology_template().getNode_templates() == null) {
 
 319       return substitutableNodeTemplates;
 
 322     Map<String, NodeTemplate> nodeTemplates =
 
 323         serviceTemplate.getTopology_template().getNode_templates();
 
 324     for (String nodeTemplateId : nodeTemplates.keySet()) {
 
 325       NodeTemplate nodeTemplate = nodeTemplates.get(nodeTemplateId);
 
 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 (capability != null) {
 
 384       if (requirementAssignment.getCapability() == null
 
 385           || !requirementAssignment.getCapability().equals(capability)) {
 
 391       if (requirementAssignment.getNode() == null
 
 392           || !requirementAssignment.getNode().equals(node)) {
 
 397     if (relationship != null) {
 
 398       if (requirementAssignment.getRelationship() == null
 
 399           || !requirementAssignment.getRelationship().equals(relationship)) {
 
 404     return !(capability == null && node == null && relationship == null);
 
 409   public Object getFlatEntity(ToscaElementTypes elementType, String typeId,
 
 410                               ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel) {
 
 413     switch (elementType) {
 
 414       case CAPABILITY_TYPE:
 
 415         returnEntity = new CapabilityType();
 
 418         returnEntity = new NodeType();
 
 421         MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
 
 422             LoggerTragetServiceName.ADD_ENTITIES_TO_TOSCA, ErrorLevel.ERROR.name(),
 
 423             LoggerErrorCode.DATA_ERROR.getErrorCode(), LoggerErrorDescription.UNSUPPORTED_ENTITY);
 
 424         throw new RuntimeException(
 
 425             "Entity[" + elementType + "] id[" + typeId + "] flat not supported");
 
 428     scanAnFlatEntity(elementType, typeId, returnEntity, serviceTemplate, toscaModel,
 
 429         new ArrayList<String>(), 0);
 
 436   public boolean isSubstitutableNodeTemplate(NodeTemplate nodeTemplate) {
 
 437     return nodeTemplate.getDirectives() != null
 
 438         && nodeTemplate.getDirectives().contains(ToscaConstants
 
 439         .NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
 
 442   private Optional<Boolean> isNodeTypeExistInServiceTemplateHierarchy(
 
 443       String nodeTypeToMatch,
 
 444       String nodeTypeToSearch,
 
 445       ServiceTemplate serviceTemplate,
 
 446       ToscaServiceModel toscaServiceModel,
 
 447       Set<String> analyzedImportFiles) {
 
 448     Map<String, NodeType> searchableNodeTypes = serviceTemplate.getNode_types();
 
 449     if (!MapUtils.isEmpty(searchableNodeTypes)) {
 
 450       NodeType nodeType = searchableNodeTypes.get(nodeTypeToSearch);
 
 451       if (Objects.nonNull(nodeType)) {
 
 452         if (Objects.equals(nodeType.getDerived_from(), nodeTypeToMatch)) {
 
 453           return Optional.of(true);
 
 454         } else if (isNodeTypeIsToscaRoot(nodeType)) {
 
 455           return Optional.of(false);
 
 457           return isNodeTypeExistInServiceTemplateHierarchy(nodeTypeToMatch,
 
 458               nodeType.getDerived_from(), serviceTemplate, toscaServiceModel, null);
 
 461         return isNodeTypeExistInImports(nodeTypeToMatch, nodeTypeToSearch, serviceTemplate,
 
 462             toscaServiceModel, analyzedImportFiles);
 
 465     return isNodeTypeExistInImports(nodeTypeToMatch, nodeTypeToSearch, serviceTemplate,
 
 466         toscaServiceModel, analyzedImportFiles);
 
 470   private Optional<Boolean> isNodeTypeExistInImports(String nodeTypeToMatch,
 
 471                                                      String nodeTypeToSearch,
 
 472                                                      ServiceTemplate serviceTemplate,
 
 473                                                      ToscaServiceModel toscaServiceModel,
 
 474                                                      Set<String> filesScanned) {
 
 475     List<Map<String, Import>> imports = serviceTemplate.getImports();
 
 476     if (CollectionUtils.isEmpty(imports)) {
 
 477       return Optional.empty();
 
 480     filesScanned = createFilesScannedSet(filesScanned);
 
 482     for (Map<String, Import> map : imports) {
 
 483       ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
 
 484       Import anImport = toscaExtensionYamlUtil
 
 485           .yamlToObject(toscaExtensionYamlUtil.objectToYaml(map.values().iterator().next()),
 
 487       if (Objects.isNull(anImport) || Objects.isNull(anImport.getFile())) {
 
 488         throw new RuntimeException("import without file entry");
 
 490       String importFile = anImport.getFile();
 
 491       ServiceTemplate template =
 
 492           toscaServiceModel.getServiceTemplates().get(fetchFileNameForImport(importFile,
 
 493               serviceTemplate.getMetadata() == null ? null
 
 494                   : serviceTemplate.getMetadata().get("filename")));
 
 495       if (Objects.isNull(template) ||
 
 496           filesScanned.contains(ToscaUtil.getServiceTemplateFileName(template))) {
 
 499         filesScanned.add(ToscaUtil.getServiceTemplateFileName(template));
 
 501       Optional<Boolean> nodeTypeExistInServiceTemplateHierarchy =
 
 502           isNodeTypeExistInServiceTemplateHierarchy(nodeTypeToMatch, nodeTypeToSearch, template,
 
 503               toscaServiceModel, filesScanned);
 
 504       if (nodeTypeExistInServiceTemplateHierarchy.isPresent()) {
 
 505         if (nodeTypeExistInServiceTemplateHierarchy.get()) {
 
 506           filesScanned.clear();
 
 507           return Optional.of(true);
 
 512     return Optional.of(false);
 
 515   private Set<String> addImportFileToAnalyzedImportFilesSet(Set<String> analyzedImportFiles,
 
 517     analyzedImportFiles.add(importFile);
 
 518     return analyzedImportFiles;
 
 521   private Set<String> createFilesScannedSet(Set<String> filesScanned) {
 
 522     if (Objects.isNull(filesScanned)) {
 
 523       filesScanned = new HashSet<>();
 
 528   private boolean isNodeTypeIsToscaRoot(NodeType stNodeType) {
 
 529     return Objects.equals(stNodeType.getDerived_from(), ToscaNodeType.NATIVE_ROOT);
 
 532   private boolean isNodeTemplateOfTypeNodeType(NodeTemplate nodeTemplate, String nodeType) {
 
 533     return Objects.equals(nodeTemplate.getType(), nodeType);
 
 536   private boolean isSubstitutionServiceTemplate(String substituteServiceTemplateFileName,
 
 537                                                 ServiceTemplate substituteServiceTemplate) {
 
 538     if (substituteServiceTemplate != null
 
 539         && substituteServiceTemplate.getTopology_template() != null
 
 540         && substituteServiceTemplate.getTopology_template().getSubstitution_mappings() != null) {
 
 541       if (substituteServiceTemplate.getTopology_template().getSubstitution_mappings()
 
 542           .getNode_type() == null) {
 
 543         throw new CoreException(new ToscaInvalidSubstitutionServiceTemplateErrorBuilder(
 
 544             substituteServiceTemplateFileName).build());
 
 552   private boolean scanAnFlatEntity(ToscaElementTypes elementType, String typeId, Object entity,
 
 553                                    ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel,
 
 554                                    List<String> filesScanned, int rootScanStartInx) {
 
 557     boolean entityFound =
 
 558         enrichEntityFromCurrentServiceTemplate(elementType, typeId, entity, serviceTemplate,
 
 559             toscaModel, filesScanned, rootScanStartInx);
 
 561       List<Map<String, Import>> imports = serviceTemplate.getImports();
 
 562       if (CollectionUtils.isEmpty(imports)) {
 
 565       ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
 
 566       boolean found = false;
 
 567       for (Map<String, Import> importMap : imports) {
 
 571         String filename = "";
 
 572         for (Object importObject : importMap.values()) {
 
 573           Import importServiceTemplate = toscaExtensionYamlUtil
 
 574               .yamlToObject(toscaExtensionYamlUtil.objectToYaml(importObject), Import.class);
 
 575           filename = fetchFileNameForImport(importServiceTemplate.getFile(),
 
 576               serviceTemplate.getMetadata() == null ? null : serviceTemplate.getMetadata().get
 
 578           if (filesScanned.contains(filename)) {
 
 581             filesScanned.add(filename);
 
 583           ServiceTemplate template =
 
 584               toscaModel.getServiceTemplates()
 
 587               scanAnFlatEntity(elementType, typeId, entity, template, toscaModel, filesScanned,
 
 588                   filesScanned.size());
 
 596   private String fetchFileNameForImport(String importServiceTemplateFile,
 
 597                                         String currentMetadatafileName) {
 
 598     if (importServiceTemplateFile.contains("../")) {
 
 599       return importServiceTemplateFile.replace("../", "");
 
 600     } else if (importServiceTemplateFile.contains("/")) {
 
 601       return importServiceTemplateFile;
 
 602     } else if (currentMetadatafileName != null) {
 
 603       return currentMetadatafileName.substring(0, currentMetadatafileName.indexOf("/")) + "/" +
 
 604           importServiceTemplateFile;
 
 606       return importServiceTemplateFile;
 
 611   private boolean enrichEntityFromCurrentServiceTemplate(ToscaElementTypes elementType,
 
 612                                                          String typeId, Object entity,
 
 613                                                          ServiceTemplate serviceTemplate,
 
 614                                                          ToscaServiceModel toscaModel,
 
 615                                                          List<String> filesScanned,
 
 616                                                          int rootScanStartInx) {
 
 618     switch (elementType) {
 
 619       case CAPABILITY_TYPE:
 
 620         if (serviceTemplate.getCapability_types() != null
 
 621             && serviceTemplate.getCapability_types().containsKey(typeId)) {
 
 623           filesScanned.clear();
 
 624           CapabilityType targetCapabilityType = ((CapabilityType) entity);
 
 625           CapabilityType sourceCapabilityType = serviceTemplate.getCapability_types().get(typeId);
 
 626           derivedFrom = sourceCapabilityType.getDerived_from();
 
 627           if (derivedFrom != null) {
 
 628             scanAnFlatEntity(elementType, derivedFrom, entity, serviceTemplate, toscaModel,
 
 629                 filesScanned, rootScanStartInx);
 
 631           combineCapabilityTypeInfo(sourceCapabilityType, targetCapabilityType);
 
 637         if (serviceTemplate.getNode_types() != null
 
 638             && serviceTemplate.getNode_types().containsKey(typeId)) {
 
 640           filesScanned.clear();
 
 641           NodeType targetNodeType = ((NodeType) entity);
 
 642           NodeType sourceNodeType = serviceTemplate.getNode_types().get(typeId);
 
 643           derivedFrom = sourceNodeType.getDerived_from();
 
 644           if (derivedFrom != null) {
 
 645             scanAnFlatEntity(elementType, derivedFrom, entity, serviceTemplate, toscaModel,
 
 646                 filesScanned, rootScanStartInx);
 
 648           combineNodeTypeInfo(sourceNodeType, targetNodeType);
 
 654         MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
 
 655             LoggerTragetServiceName.ADD_ENTITIES_TO_TOSCA, ErrorLevel.ERROR.name(),
 
 656             LoggerErrorCode.DATA_ERROR.getErrorCode(), LoggerErrorDescription.UNSUPPORTED_ENTITY);
 
 657         throw new RuntimeException(
 
 658             "Entity[" + elementType + "] id[" + typeId + "] flat not supported");
 
 666   private void combineNodeTypeInfo(NodeType sourceNodeType, NodeType targetNodeType) {
 
 667     targetNodeType.setDerived_from(sourceNodeType.getDerived_from());
 
 668     targetNodeType.setDescription(sourceNodeType.getDescription());
 
 669     targetNodeType.setVersion(sourceNodeType.getVersion());
 
 670     targetNodeType.setProperties(
 
 671         CommonMethods.mergeMaps(targetNodeType.getProperties(), sourceNodeType.getProperties()));
 
 672     targetNodeType.setInterfaces(
 
 673         CommonMethods.mergeMaps(targetNodeType.getInterfaces(), sourceNodeType.getInterfaces()));
 
 674     targetNodeType.setArtifacts(
 
 675         CommonMethods.mergeMaps(targetNodeType.getArtifacts(), sourceNodeType.getArtifacts()));
 
 676     targetNodeType.setAttributes(
 
 677         CommonMethods.mergeMaps(targetNodeType.getAttributes(), sourceNodeType.getAttributes()));
 
 678     targetNodeType.setCapabilities(CommonMethods
 
 679         .mergeMaps(targetNodeType.getCapabilities(), sourceNodeType.getCapabilities()));
 
 680     targetNodeType.setRequirements(CommonMethods
 
 681         .mergeListsOfMap(targetNodeType.getRequirements(), sourceNodeType.getRequirements()));
 
 686   private void combineCapabilityTypeInfo(CapabilityType sourceCapabilityType,
 
 687                                          CapabilityType targetCapabilityType) {
 
 689     targetCapabilityType.setAttributes(CommonMethods
 
 690         .mergeMaps(targetCapabilityType.getAttributes(), sourceCapabilityType.getAttributes()));
 
 691     targetCapabilityType.setProperties(CommonMethods
 
 692         .mergeMaps(targetCapabilityType.getProperties(), sourceCapabilityType.getProperties()));
 
 693     targetCapabilityType.setValid_source_types(CommonMethods
 
 694         .mergeLists(targetCapabilityType.getValid_source_types(),
 
 695             sourceCapabilityType.getValid_source_types()));
 
 697     if (!CommonMethods.isEmpty(sourceCapabilityType.getDerived_from())) {
 
 698       targetCapabilityType.setDerived_from(sourceCapabilityType.getDerived_from());
 
 700     if (!CommonMethods.isEmpty(sourceCapabilityType.getDescription())) {
 
 701       targetCapabilityType.setDescription(sourceCapabilityType.getDescription());
 
 703     if (!CommonMethods.isEmpty(sourceCapabilityType.getVersion())) {
 
 704       targetCapabilityType.setVersion(sourceCapabilityType.getVersion());
 
 712  * Create node type according to the input substitution service template, while the substitution
 
 713  * service template can be mappted to this node type, for substitution mapping.
 
 715  * @param substitutionServiceTemplate  substitution serivce template
 
 716  * @param nodeTypeDerivedFromValue derived from value for the created node type
 
 717  * @return the node type
 
 720   public NodeType createInitSubstitutionNodeType(ServiceTemplate substitutionServiceTemplate,
 
 721                                                  String nodeTypeDerivedFromValue) {
 
 722     NodeType substitutionNodeType = new NodeType();
 
 723     substitutionNodeType.setDerived_from(nodeTypeDerivedFromValue);
 
 724     substitutionNodeType.setDescription(substitutionServiceTemplate.getDescription());
 
 726         .setProperties(manageSubstitutionNodeTypeProperties(substitutionServiceTemplate));
 
 728         .setAttributes(manageSubstitutionNodeTypeAttributes(substitutionServiceTemplate));
 
 729     return substitutionNodeType;
 
 732   public Map<String, PropertyDefinition> manageSubstitutionNodeTypeProperties(
 
 733       ServiceTemplate substitutionServiceTemplate) {
 
 734     Map<String, PropertyDefinition> substitutionNodeTypeProperties = new HashMap<>();
 
 735     Map<String, ParameterDefinition> properties =
 
 736         substitutionServiceTemplate.getTopology_template().getInputs();
 
 737     if (properties == null) {
 
 741     PropertyDefinition propertyDefinition;
 
 742     String toscaPropertyName;
 
 743     for (Map.Entry<String, ParameterDefinition> entry : properties.entrySet()) {
 
 744       toscaPropertyName = entry.getKey();
 
 745       propertyDefinition = new PropertyDefinition();
 
 746       ParameterDefinition parameterDefinition =
 
 747           substitutionServiceTemplate.getTopology_template().getInputs().get(toscaPropertyName);
 
 748       propertyDefinition.setType(parameterDefinition.getType());
 
 749       propertyDefinition.setDescription(parameterDefinition.getDescription());
 
 750       propertyDefinition.set_default(parameterDefinition.get_default());
 
 751       if (parameterDefinition.getRequired() != null) {
 
 752         propertyDefinition.setRequired(parameterDefinition.getRequired());
 
 754       if (propertyDefinition.get_default() != null) {
 
 755         propertyDefinition.setRequired(false);
 
 757       if (!CollectionUtils.isEmpty(parameterDefinition.getConstraints())) {
 
 758         propertyDefinition.setConstraints(parameterDefinition.getConstraints());
 
 760       propertyDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
 
 761       if (parameterDefinition.getStatus() != null) {
 
 762         propertyDefinition.setStatus(parameterDefinition.getStatus());
 
 764       substitutionNodeTypeProperties.put(toscaPropertyName, propertyDefinition);
 
 766     return substitutionNodeTypeProperties;
 
 769   private Map<String, AttributeDefinition> manageSubstitutionNodeTypeAttributes(
 
 770       ServiceTemplate substitutionServiceTemplate) {
 
 771     Map<String, AttributeDefinition> substitutionNodeTypeAttributes = new HashMap<>();
 
 772     Map<String, ParameterDefinition> attributes =
 
 773         substitutionServiceTemplate.getTopology_template().getOutputs();
 
 774     if (attributes == null) {
 
 777     AttributeDefinition attributeDefinition;
 
 778     String toscaAttributeName;
 
 780     for (Map.Entry<String, ParameterDefinition> entry : attributes.entrySet()) {
 
 781       attributeDefinition = new AttributeDefinition();
 
 782       toscaAttributeName = entry.getKey();
 
 783       ParameterDefinition parameterDefinition =
 
 784           substitutionServiceTemplate.getTopology_template().getOutputs().get(toscaAttributeName);
 
 785       if (parameterDefinition.getType() != null && !parameterDefinition.getType().isEmpty()) {
 
 786         attributeDefinition.setType(parameterDefinition.getType());
 
 788         attributeDefinition.setType(PropertyType.STRING.getDisplayName());
 
 790       attributeDefinition.setDescription(parameterDefinition.getDescription());
 
 791       attributeDefinition.set_default(parameterDefinition.get_default());
 
 792       attributeDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
 
 793       if (Objects.nonNull(parameterDefinition.getStatus())) {
 
 794         attributeDefinition.setStatus(parameterDefinition.getStatus());
 
 796       substitutionNodeTypeAttributes.put(toscaAttributeName, attributeDefinition);
 
 798     return substitutionNodeTypeAttributes;
 
 802    * Checks if the requirement exists in the node template.
 
 804    * @param nodeTemplate          the node template
 
 805    * @param requirementId         the requirement id
 
 806    * @param requirementAssignment the requirement assignment
 
 807    * @return true if the requirement already exists and false otherwise
 
 809   public boolean isRequirementExistInNodeTemplate(NodeTemplate nodeTemplate,
 
 810                                                   String requirementId,
 
 811                                                   RequirementAssignment requirementAssignment) {
 
 812     boolean result = false;
 
 813     List<Map<String, RequirementAssignment>> nodeTemplateRequirements = nodeTemplate
 
 815     if (nodeTemplateRequirements != null) {
 
 816       for (Map<String, RequirementAssignment> requirement : nodeTemplateRequirements) {
 
 817         if (requirement.containsKey(requirementId)) {
 
 818           result = DataModelUtil.compareRequirementAssignment(requirementAssignment,
 
 819               requirement.get(requirementId));