[SDC-29] rebase continue work to align source
[sdc.git] / openecomp-be / lib / openecomp-tosca-lib / src / main / java / org / openecomp / sdc / tosca / services / impl / ToscaAnalyzerServiceImpl.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
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
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
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=========================================================
19  */
20
21 package org.openecomp.sdc.tosca.services.impl;
22
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.MdcDataErrorMessage;
29 import org.openecomp.sdc.logging.types.LoggerConstants;
30 import org.openecomp.sdc.logging.types.LoggerErrorCode;
31 import org.openecomp.sdc.logging.types.LoggerErrorDescription;
32 import org.openecomp.sdc.logging.types.LoggerTragetServiceName;
33 import org.openecomp.sdc.tosca.datatypes.ToscaElementTypes;
34 import org.openecomp.sdc.tosca.datatypes.ToscaNodeType;
35 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
36 import org.openecomp.sdc.tosca.datatypes.model.AttributeDefinition;
37 import org.openecomp.sdc.tosca.datatypes.model.CapabilityType;
38 import org.openecomp.sdc.tosca.datatypes.model.Import;
39 import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
40 import org.openecomp.sdc.tosca.datatypes.model.NodeType;
41 import org.openecomp.sdc.tosca.datatypes.model.ParameterDefinition;
42 import org.openecomp.sdc.tosca.datatypes.model.PropertyDefinition;
43 import org.openecomp.sdc.tosca.datatypes.model.PropertyType;
44 import org.openecomp.sdc.tosca.datatypes.model.RequirementAssignment;
45 import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate;
46 import org.openecomp.sdc.tosca.errors.ToscaInvalidEntryNotFoundErrorBuilder;
47 import org.openecomp.sdc.tosca.errors.ToscaInvalidSubstituteNodeTemplatePropertiesErrorBuilder;
48 import org.openecomp.sdc.tosca.errors.ToscaInvalidSubstitutionServiceTemplateErrorBuilder;
49 import org.openecomp.sdc.tosca.errors.ToscaNodeTypeNotFoundErrorBuilder;
50 import org.openecomp.sdc.tosca.services.DataModelUtil;
51 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
52 import org.openecomp.sdc.tosca.services.ToscaConstants;
53 import org.openecomp.sdc.tosca.services.ToscaUtil;
54 import org.openecomp.sdc.tosca.services.yamlutil.ToscaExtensionYamlUtil;
55
56 import java.util.ArrayList;
57 import java.util.Collection;
58 import java.util.HashMap;
59 import java.util.HashSet;
60 import java.util.List;
61 import java.util.Map;
62 import java.util.Objects;
63 import java.util.Optional;
64 import java.util.Set;
65
66 public class ToscaAnalyzerServiceImpl implements ToscaAnalyzerService {
67   /*
68   node template with type equal to node type or derived from node type
69    */
70   @Override
71   public Map<String, NodeTemplate> getNodeTemplatesByType(ServiceTemplate serviceTemplate,
72                                                           String nodeType,
73                                                           ToscaServiceModel toscaServiceModel) {
74     Map<String, NodeTemplate> nodeTemplates = new HashMap<>();
75
76     if (Objects.nonNull(serviceTemplate.getTopology_template())
77         && MapUtils.isNotEmpty(serviceTemplate.getTopology_template().getNode_templates())) {
78       for (Map.Entry<String, NodeTemplate> nodeTemplateEntry : serviceTemplate
79           .getTopology_template().getNode_templates().entrySet()) {
80         if (isTypeOf(nodeTemplateEntry.getValue(), nodeType, serviceTemplate, toscaServiceModel)) {
81           nodeTemplates.put(nodeTemplateEntry.getKey(), nodeTemplateEntry.getValue());
82         }
83
84       }
85     }
86     return nodeTemplates;
87   }
88
89   @Override
90   public Optional<NodeType> fetchNodeType(String nodeTypeKey, Collection<ServiceTemplate>
91       serviceTemplates) {
92     Optional<Map<String, NodeType>> nodeTypeMap = serviceTemplates.stream()
93         .map(st -> st.getNode_types())
94         .filter(nodeTypes -> Objects.nonNull(nodeTypes) && nodeTypes.containsKey(nodeTypeKey))
95         .findFirst();
96     if (nodeTypeMap.isPresent()) {
97       return Optional.ofNullable(nodeTypeMap.get().get(nodeTypeKey));
98     }
99     return Optional.empty();
100   }
101
102   @Override
103   public boolean isTypeOf(NodeTemplate nodeTemplate, String nodeType,
104                           ServiceTemplate serviceTemplate, ToscaServiceModel toscaServiceModel) {
105     if (nodeTemplate == null) {
106       return false;
107     }
108
109     if (isNodeTemplateOfTypeNodeType(nodeTemplate, nodeType)) {
110       return true;
111     }
112
113     Optional<Boolean> nodeTypeExistInServiceTemplateHierarchy =
114         isNodeTypeExistInServiceTemplateHierarchy(nodeType, nodeTemplate.getType(), serviceTemplate,
115             toscaServiceModel, null);
116     return nodeTypeExistInServiceTemplateHierarchy.orElseThrow(() -> new CoreException(
117         new ToscaNodeTypeNotFoundErrorBuilder(nodeTemplate.getType()).build()));
118   }
119
120   @Override
121   public List<RequirementAssignment> getRequirements(NodeTemplate nodeTemplate,
122                                                      String requirementId) {
123     List<RequirementAssignment> requirements = new ArrayList<>();
124     List<Map<String, RequirementAssignment>> requirementList = nodeTemplate.getRequirements();
125     if (requirementList != null) {
126       requirementList.stream().filter(reqMap -> reqMap.get(requirementId) != null)
127           .forEach(reqMap -> {
128             ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
129             RequirementAssignment reqAssignment = toscaExtensionYamlUtil
130                 .yamlToObject(toscaExtensionYamlUtil.objectToYaml(reqMap.get(requirementId)),
131                     RequirementAssignment.class);
132             requirements.add(reqAssignment);
133           });
134     }
135     return requirements;
136   }
137
138   @Override
139   public Optional<NodeTemplate> getNodeTemplateById(ServiceTemplate serviceTemplate,
140                                                     String nodeTemplateId) {
141     if ((serviceTemplate.getTopology_template() != null)
142         && (serviceTemplate.getTopology_template().getNode_templates() != null)
143         && (serviceTemplate.getTopology_template().getNode_templates().get(nodeTemplateId)
144         != null)) {
145       return Optional
146           .of(serviceTemplate.getTopology_template().getNode_templates().get(nodeTemplateId));
147     }
148     return Optional.empty();
149   }
150
151   @Override
152   public Optional<String> getSubstituteServiceTemplateName(String substituteNodeTemplateId,
153                                                            NodeTemplate substitutableNodeTemplate) {
154     if (!isSubstitutableNodeTemplate(substitutableNodeTemplate)) {
155       return Optional.empty();
156     }
157
158     if (substitutableNodeTemplate.getProperties() != null
159         && substitutableNodeTemplate.getProperties()
160         .get(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME) != null) {
161       Object serviceTemplateFilter = substitutableNodeTemplate.getProperties()
162           .get(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME);
163       if (serviceTemplateFilter != null && serviceTemplateFilter instanceof Map) {
164         Object substituteServiceTemplate = ((Map) serviceTemplateFilter)
165             .get(ToscaConstants.SUBSTITUTE_SERVICE_TEMPLATE_PROPERTY_NAME);
166         if (substituteServiceTemplate == null) {
167           MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
168               LoggerTragetServiceName.ADD_ENTITIES_TO_TOSCA, ErrorLevel.ERROR.name(),
169               LoggerErrorCode.DATA_ERROR.getErrorCode(), LoggerErrorDescription.INVALID_PROPERTY);
170           throw new CoreException(
171               new ToscaInvalidSubstituteNodeTemplatePropertiesErrorBuilder(substituteNodeTemplateId)
172                   .build());
173         }
174         return Optional.of(substituteServiceTemplate.toString());
175       }
176     }
177     MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
178         LoggerTragetServiceName.ADD_ENTITIES_TO_TOSCA, ErrorLevel.ERROR.name(),
179         LoggerErrorCode.DATA_ERROR.getErrorCode(), LoggerErrorDescription.INVALID_PROPERTY);
180     throw new CoreException(
181         new ToscaInvalidSubstituteNodeTemplatePropertiesErrorBuilder(substituteNodeTemplateId)
182             .build());
183   }
184
185   @Override
186   public Map<String, NodeTemplate> getSubstitutableNodeTemplates(ServiceTemplate serviceTemplate) {
187     Map<String, NodeTemplate> substitutableNodeTemplates = new HashMap<>();
188
189     if (serviceTemplate == null
190         || serviceTemplate.getTopology_template() == null
191         || serviceTemplate.getTopology_template().getNode_templates() == null) {
192       return substitutableNodeTemplates;
193     }
194
195     Map<String, NodeTemplate> nodeTemplates =
196         serviceTemplate.getTopology_template().getNode_templates();
197     for (String nodeTemplateId : nodeTemplates.keySet()) {
198       NodeTemplate nodeTemplate = nodeTemplates.get(nodeTemplateId);
199       if (isSubstitutableNodeTemplate(nodeTemplate)) {
200         substitutableNodeTemplates.put(nodeTemplateId, nodeTemplate);
201       }
202     }
203
204     return substitutableNodeTemplates;
205   }
206
207   @Override
208   public Optional<Map.Entry<String, NodeTemplate>> getSubstitutionMappedNodeTemplateByExposedReq(
209       String substituteServiceTemplateFileName, ServiceTemplate substituteServiceTemplate,
210       String requirementId) {
211     if (isSubstitutionServiceTemplate(substituteServiceTemplateFileName,
212         substituteServiceTemplate)) {
213       Map<String, List<String>> substitutionMappingRequirements =
214           substituteServiceTemplate.getTopology_template().getSubstitution_mappings()
215               .getRequirements();
216       if (substitutionMappingRequirements != null) {
217         List<String> requirementMapping = substitutionMappingRequirements.get(requirementId);
218         if (requirementMapping != null && !requirementMapping.isEmpty()) {
219           String mappedNodeTemplateId = requirementMapping.get(0);
220           Optional<NodeTemplate> mappedNodeTemplate =
221               getNodeTemplateById(substituteServiceTemplate, mappedNodeTemplateId);
222           mappedNodeTemplate.orElseThrow(() -> new CoreException(
223               new ToscaInvalidEntryNotFoundErrorBuilder("Node Template", mappedNodeTemplateId)
224                   .build()));
225           Map.Entry<String, NodeTemplate> mappedNodeTemplateEntry =
226               new Map.Entry<String, NodeTemplate>() {
227                 @Override
228                 public String getKey() {
229                   return mappedNodeTemplateId;
230                 }
231
232                 @Override
233                 public NodeTemplate getValue() {
234                   return mappedNodeTemplate.get();
235                 }
236
237                 @Override
238                 public NodeTemplate setValue(NodeTemplate value) {
239                   return null;
240                 }
241               };
242           return Optional.of(mappedNodeTemplateEntry);
243         }
244       }
245     }
246     return Optional.empty();
247   }
248
249   /*
250   match only for the input which is not null
251    */
252   @Override
253   public boolean isDesiredRequirementAssignment(RequirementAssignment requirementAssignment,
254                                                 String capability, String node,
255                                                 String relationship) {
256     if (capability != null) {
257       if (requirementAssignment.getCapability() == null
258           || !requirementAssignment.getCapability().equals(capability)) {
259         return false;
260       }
261     }
262
263     if (node != null) {
264       if (requirementAssignment.getNode() == null
265           || !requirementAssignment.getNode().equals(node)) {
266         return false;
267       }
268     }
269
270     if (relationship != null) {
271       if (requirementAssignment.getRelationship() == null
272           || !requirementAssignment.getRelationship().equals(relationship)) {
273         return false;
274       }
275     }
276
277     return !(capability == null && node == null && relationship == null);
278
279   }
280
281   @Override
282   public Object getFlatEntity(ToscaElementTypes elementType, String typeId,
283                               ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel) {
284     Object returnEntity;
285
286     switch (elementType) {
287       case CAPABILITY_TYPE:
288         returnEntity = new CapabilityType();
289         break;
290       case NODE_TYPE:
291         returnEntity = new NodeType();
292         break;
293       default:
294         MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
295             LoggerTragetServiceName.ADD_ENTITIES_TO_TOSCA, ErrorLevel.ERROR.name(),
296             LoggerErrorCode.DATA_ERROR.getErrorCode(), LoggerErrorDescription.UNSUPPORTED_ENTITY);
297         throw new RuntimeException(
298             "Entity[" + elementType + "] id[" + typeId + "] flat not supported");
299     }
300
301     scanAnFlatEntity(elementType, typeId, returnEntity, serviceTemplate, toscaModel,
302         new ArrayList<String>(), 0);
303
304
305     return returnEntity;
306   }
307
308   @Override
309   public boolean isSubstitutableNodeTemplate(NodeTemplate nodeTemplate) {
310     return nodeTemplate.getDirectives() != null
311         && nodeTemplate.getDirectives().contains(ToscaConstants
312         .NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
313   }
314
315   private Optional<Boolean> isNodeTypeExistInServiceTemplateHierarchy(
316       String nodeTypeToMatch,
317       String nodeTypeToSearch,
318       ServiceTemplate serviceTemplate,
319       ToscaServiceModel toscaServiceModel,
320       Set<String> analyzedImportFiles) {
321     Map<String, NodeType> searchableNodeTypes = serviceTemplate.getNode_types();
322     if (!MapUtils.isEmpty(searchableNodeTypes)) {
323       NodeType nodeType = searchableNodeTypes.get(nodeTypeToSearch);
324       if (Objects.nonNull(nodeType)) {
325         if (Objects.equals(nodeType.getDerived_from(), nodeTypeToMatch)) {
326           return Optional.of(true);
327         } else if (isNodeTypeIsToscaRoot(nodeType)) {
328           return Optional.of(false);
329         } else {
330           return isNodeTypeExistInServiceTemplateHierarchy(nodeTypeToMatch,
331               nodeType.getDerived_from(), serviceTemplate, toscaServiceModel, null);
332         }
333       } else {
334         return isNodeTypeExistInImports(nodeTypeToMatch, nodeTypeToSearch, serviceTemplate,
335             toscaServiceModel, analyzedImportFiles);
336       }
337     }
338     return isNodeTypeExistInImports(nodeTypeToMatch, nodeTypeToSearch, serviceTemplate,
339         toscaServiceModel, analyzedImportFiles);
340
341   }
342
343   private Optional<Boolean> isNodeTypeExistInImports(String nodeTypeToMatch,
344                                                      String nodeTypeToSearch,
345                                                      ServiceTemplate serviceTemplate,
346                                                      ToscaServiceModel toscaServiceModel,
347                                                      Set<String> filesScanned) {
348     List<Map<String, Import>> imports = serviceTemplate.getImports();
349     if (CollectionUtils.isEmpty(imports)) {
350       return Optional.empty();
351     }
352
353     filesScanned = createFilesScannedSet(filesScanned);
354
355     for (Map<String, Import> map : imports) {
356       ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
357       Import anImport = toscaExtensionYamlUtil
358           .yamlToObject(toscaExtensionYamlUtil.objectToYaml(map.values().iterator().next()),
359               Import.class);
360       if (Objects.isNull(anImport) || Objects.isNull(anImport.getFile())) {
361         throw new RuntimeException("import without file entry");
362       }
363       String importFile = anImport.getFile();
364       ServiceTemplate template =
365           toscaServiceModel.getServiceTemplates().get(fetchFileNameForImport(importFile,
366               serviceTemplate.getMetadata() == null ? null
367                   : serviceTemplate.getMetadata().get("filename")));
368       if (filesScanned.contains(ToscaUtil.getServiceTemplateFileName(template))) {
369         continue;
370       } else {
371         filesScanned.add(ToscaUtil.getServiceTemplateFileName(template));
372       }
373       Optional<Boolean> nodeTypeExistInServiceTemplateHierarchy =
374           isNodeTypeExistInServiceTemplateHierarchy(nodeTypeToMatch, nodeTypeToSearch, template,
375               toscaServiceModel, filesScanned);
376       if (nodeTypeExistInServiceTemplateHierarchy.isPresent()) {
377         if (nodeTypeExistInServiceTemplateHierarchy.get()) {
378           filesScanned.clear();
379           return Optional.of(true);
380         }
381       }
382
383     }
384     return Optional.of(false);
385   }
386
387   private Set<String> addImportFileToAnalyzedImportFilesSet(Set<String> analyzedImportFiles,
388                                                             String importFile) {
389     analyzedImportFiles.add(importFile);
390     return analyzedImportFiles;
391   }
392
393   private Set<String> createFilesScannedSet(Set<String> filesScanned) {
394     if (Objects.isNull(filesScanned)) {
395       filesScanned = new HashSet<>();
396     }
397     return filesScanned;
398   }
399
400   private boolean isNodeTypeIsToscaRoot(NodeType stNodeType) {
401     return Objects.equals(stNodeType.getDerived_from(), ToscaNodeType.NATIVE_ROOT);
402   }
403
404   private boolean isNodeTemplateOfTypeNodeType(NodeTemplate nodeTemplate, String nodeType) {
405     return Objects.equals(nodeTemplate.getType(), nodeType);
406   }
407
408   private boolean isSubstitutionServiceTemplate(String substituteServiceTemplateFileName,
409                                                 ServiceTemplate substituteServiceTemplate) {
410     if (substituteServiceTemplate != null
411         && substituteServiceTemplate.getTopology_template() != null
412         && substituteServiceTemplate.getTopology_template().getSubstitution_mappings() != null) {
413       if (substituteServiceTemplate.getTopology_template().getSubstitution_mappings()
414           .getNode_type() == null) {
415         throw new CoreException(new ToscaInvalidSubstitutionServiceTemplateErrorBuilder(
416             substituteServiceTemplateFileName).build());
417       }
418       return true;
419     }
420     return false;
421
422   }
423
424   private boolean scanAnFlatEntity(ToscaElementTypes elementType, String typeId, Object entity,
425                                    ServiceTemplate serviceTemplate, ToscaServiceModel toscaModel,
426                                    List<String> filesScanned, int rootScanStartInx) {
427
428
429     boolean entityFound =
430         enrichEntityFromCurrentServiceTemplate(elementType, typeId, entity, serviceTemplate,
431             toscaModel, filesScanned, rootScanStartInx);
432     if (!entityFound) {
433       List<Map<String, Import>> imports = serviceTemplate.getImports();
434       if (CollectionUtils.isEmpty(imports)) {
435         return false;
436       }
437       ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
438       boolean found = false;
439       for (Map<String, Import> importMap : imports) {
440         if (found) {
441           return true;
442         }
443         String filename = "";
444         for (Object importObject : importMap.values()) {
445           Import importServiceTemplate = toscaExtensionYamlUtil
446               .yamlToObject(toscaExtensionYamlUtil.objectToYaml(importObject), Import.class);
447           filename = fetchFileNameForImport(importServiceTemplate.getFile(),
448               serviceTemplate.getMetadata() == null ? null : serviceTemplate.getMetadata().get
449                   ("filename"));
450           if (filesScanned.contains(filename)) {
451             return false;
452           } else {
453             filesScanned.add(filename);
454           }
455           ServiceTemplate template =
456               toscaModel.getServiceTemplates()
457                   .get(filename);
458           found =
459               scanAnFlatEntity(elementType, typeId, entity, template, toscaModel, filesScanned,
460                   filesScanned.size());
461         }
462       }
463       return found;
464     }
465     return true;
466   }
467
468   private String fetchFileNameForImport(String importServiceTemplateFile,
469                                         String currentMetadatafileName) {
470     if (importServiceTemplateFile.contains("../")) {
471       return importServiceTemplateFile.replace("../", "");
472     } else if (importServiceTemplateFile.contains("/")) {
473       return importServiceTemplateFile;
474     } else if (currentMetadatafileName != null) {
475       return currentMetadatafileName.substring(0, currentMetadatafileName.indexOf("/")) + "/" +
476           importServiceTemplateFile;
477     } else {
478       return importServiceTemplateFile;
479     }
480
481   }
482
483   private boolean enrichEntityFromCurrentServiceTemplate(ToscaElementTypes elementType,
484                                                          String typeId, Object entity,
485                                                          ServiceTemplate serviceTemplate,
486                                                          ToscaServiceModel toscaModel,
487                                                          List<String> filesScanned,
488                                                          int rootScanStartInx) {
489     String derivedFrom;
490     switch (elementType) {
491       case CAPABILITY_TYPE:
492         if (serviceTemplate.getCapability_types() != null
493             && serviceTemplate.getCapability_types().containsKey(typeId)) {
494
495           filesScanned.clear();
496           CapabilityType targetCapabilityType = ((CapabilityType) entity);
497           CapabilityType sourceCapabilityType = serviceTemplate.getCapability_types().get(typeId);
498           derivedFrom = sourceCapabilityType.getDerived_from();
499           if (derivedFrom != null) {
500             scanAnFlatEntity(elementType, derivedFrom, entity, serviceTemplate, toscaModel,
501                 filesScanned, rootScanStartInx);
502           }
503           combineCapabilityTypeInfo(sourceCapabilityType, targetCapabilityType);
504         } else {
505           return false;
506         }
507         break;
508       case NODE_TYPE:
509         if (serviceTemplate.getNode_types() != null
510             && serviceTemplate.getNode_types().containsKey(typeId)) {
511
512           filesScanned.clear();
513           NodeType targetNodeType = ((NodeType) entity);
514           NodeType sourceNodeType = serviceTemplate.getNode_types().get(typeId);
515           derivedFrom = sourceNodeType.getDerived_from();
516           if (derivedFrom != null) {
517             scanAnFlatEntity(elementType, derivedFrom, entity, serviceTemplate, toscaModel,
518                 filesScanned, rootScanStartInx);
519           }
520           combineNodeTypeInfo(sourceNodeType, targetNodeType);
521         } else {
522           return false;
523         }
524         break;
525       default:
526         MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
527             LoggerTragetServiceName.ADD_ENTITIES_TO_TOSCA, ErrorLevel.ERROR.name(),
528             LoggerErrorCode.DATA_ERROR.getErrorCode(), LoggerErrorDescription.UNSUPPORTED_ENTITY);
529         throw new RuntimeException(
530             "Entity[" + elementType + "] id[" + typeId + "] flat not supported");
531     }
532
533     return true;
534
535
536   }
537
538   private void combineNodeTypeInfo(NodeType sourceNodeType, NodeType targetNodeType) {
539     targetNodeType.setDerived_from(sourceNodeType.getDerived_from());
540     targetNodeType.setDescription(sourceNodeType.getDescription());
541     targetNodeType.setVersion(sourceNodeType.getVersion());
542     targetNodeType.setProperties(
543         CommonMethods.mergeMaps(targetNodeType.getProperties(), sourceNodeType.getProperties()));
544     targetNodeType.setInterfaces(
545         CommonMethods.mergeMaps(targetNodeType.getInterfaces(), sourceNodeType.getInterfaces()));
546     targetNodeType.setArtifacts(
547         CommonMethods.mergeMaps(targetNodeType.getArtifacts(), sourceNodeType.getArtifacts()));
548     targetNodeType.setAttributes(
549         CommonMethods.mergeMaps(targetNodeType.getAttributes(), sourceNodeType.getAttributes()));
550     targetNodeType.setCapabilities(CommonMethods
551         .mergeMaps(targetNodeType.getCapabilities(), sourceNodeType.getCapabilities()));
552     targetNodeType.setRequirements(CommonMethods
553         .mergeListsOfMap(targetNodeType.getRequirements(), sourceNodeType.getRequirements()));
554
555   }
556
557
558   private void combineCapabilityTypeInfo(CapabilityType sourceCapabilityType,
559                                          CapabilityType targetCapabilityType) {
560
561     targetCapabilityType.setAttributes(CommonMethods
562         .mergeMaps(targetCapabilityType.getAttributes(), sourceCapabilityType.getAttributes()));
563     targetCapabilityType.setProperties(CommonMethods
564         .mergeMaps(targetCapabilityType.getProperties(), sourceCapabilityType.getProperties()));
565     targetCapabilityType.setValid_source_types(CommonMethods
566         .mergeLists(targetCapabilityType.getValid_source_types(),
567             sourceCapabilityType.getValid_source_types()));
568
569     if (!CommonMethods.isEmpty(sourceCapabilityType.getDerived_from())) {
570       targetCapabilityType.setDerived_from(sourceCapabilityType.getDerived_from());
571     }
572     if (!CommonMethods.isEmpty(sourceCapabilityType.getDescription())) {
573       targetCapabilityType.setDescription(sourceCapabilityType.getDescription());
574     }
575     if (!CommonMethods.isEmpty(sourceCapabilityType.getVersion())) {
576       targetCapabilityType.setVersion(sourceCapabilityType.getVersion());
577     }
578
579
580   }
581
582
583   /*
584  * Create node type according to the input substitution service template, while the substitution
585  * service template can be mappted to this node type, for substitution mapping.
586  *
587  * @param substitutionServiceTemplate  substitution serivce template
588  * @param nodeTypeDerivedFromValue derived from value for the created node type
589  * @return the node type
590  */
591   @Override
592   public NodeType createInitSubstitutionNodeType(ServiceTemplate substitutionServiceTemplate,
593                                                  String nodeTypeDerivedFromValue) {
594     NodeType substitutionNodeType = new NodeType();
595     substitutionNodeType.setDerived_from(nodeTypeDerivedFromValue);
596     substitutionNodeType.setDescription(substitutionServiceTemplate.getDescription());
597     substitutionNodeType
598         .setProperties(manageSubstitutionNodeTypeProperties(substitutionServiceTemplate));
599     substitutionNodeType
600         .setAttributes(manageSubstitutionNodeTypeAttributes(substitutionServiceTemplate));
601     return substitutionNodeType;
602   }
603
604   public Map<String, PropertyDefinition> manageSubstitutionNodeTypeProperties(
605       ServiceTemplate substitutionServiceTemplate) {
606     Map<String, PropertyDefinition> substitutionNodeTypeProperties = new HashMap<>();
607     Map<String, ParameterDefinition> properties =
608         substitutionServiceTemplate.getTopology_template().getInputs();
609     if (properties == null) {
610       return null;
611     }
612
613     PropertyDefinition propertyDefinition;
614     String toscaPropertyName;
615     for (Map.Entry<String, ParameterDefinition> entry : properties.entrySet()) {
616       toscaPropertyName = entry.getKey();
617       propertyDefinition = new PropertyDefinition();
618       ParameterDefinition parameterDefinition =
619           substitutionServiceTemplate.getTopology_template().getInputs().get(toscaPropertyName);
620       propertyDefinition.setType(parameterDefinition.getType());
621       propertyDefinition.setDescription(parameterDefinition.getDescription());
622       propertyDefinition.set_default(parameterDefinition.get_default());
623       if (parameterDefinition.getRequired() != null) {
624         propertyDefinition.setRequired(parameterDefinition.getRequired());
625       }
626       if (propertyDefinition.get_default() != null) {
627         propertyDefinition.setRequired(false);
628       }
629       if (!CollectionUtils.isEmpty(parameterDefinition.getConstraints())) {
630         propertyDefinition.setConstraints(parameterDefinition.getConstraints());
631       }
632       propertyDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
633       if (parameterDefinition.getStatus() != null) {
634         propertyDefinition.setStatus(parameterDefinition.getStatus());
635       }
636       substitutionNodeTypeProperties.put(toscaPropertyName, propertyDefinition);
637     }
638     return substitutionNodeTypeProperties;
639   }
640
641   private Map<String, AttributeDefinition> manageSubstitutionNodeTypeAttributes(
642       ServiceTemplate substitutionServiceTemplate) {
643     Map<String, AttributeDefinition> substitutionNodeTypeAttributes = new HashMap<>();
644     Map<String, ParameterDefinition> attributes =
645         substitutionServiceTemplate.getTopology_template().getOutputs();
646     if (attributes == null) {
647       return null;
648     }
649     AttributeDefinition attributeDefinition;
650     String toscaAttributeName;
651
652     for (Map.Entry<String, ParameterDefinition> entry : attributes.entrySet()) {
653       attributeDefinition = new AttributeDefinition();
654       toscaAttributeName = entry.getKey();
655       ParameterDefinition parameterDefinition =
656           substitutionServiceTemplate.getTopology_template().getOutputs().get(toscaAttributeName);
657       if (parameterDefinition.getType() != null && !parameterDefinition.getType().isEmpty()) {
658         attributeDefinition.setType(parameterDefinition.getType());
659       } else {
660         attributeDefinition.setType(PropertyType.STRING.getDisplayName());
661       }
662       attributeDefinition.setDescription(parameterDefinition.getDescription());
663       attributeDefinition.set_default(parameterDefinition.get_default());
664       attributeDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
665       if (Objects.nonNull(parameterDefinition.getStatus())) {
666         attributeDefinition.setStatus(parameterDefinition.getStatus());
667       }
668       substitutionNodeTypeAttributes.put(toscaAttributeName, attributeDefinition);
669     }
670     return substitutionNodeTypeAttributes;
671   }
672
673   /**
674    * Checks if the requirement exists in the node template.
675    *
676    * @param nodeTemplate          the node template
677    * @param requirementId         the requirement id
678    * @param requirementAssignment the requirement assignment
679    * @return true if the requirement already exists and false otherwise
680    */
681   public boolean isRequirementExistInNodeTemplate(NodeTemplate nodeTemplate,
682                                                   String requirementId,
683                                                   RequirementAssignment requirementAssignment) {
684     boolean result = false;
685     List<Map<String, RequirementAssignment>> nodeTemplateRequirements = nodeTemplate
686         .getRequirements();
687     if (nodeTemplateRequirements != null) {
688       for (Map<String, RequirementAssignment> requirement : nodeTemplateRequirements) {
689         if (requirement.containsKey(requirementId)) {
690           result = DataModelUtil.compareRequirementAssignment(requirementAssignment,
691               requirement.get(requirementId));
692           if (result) {
693             break;
694           }
695         }
696       }
697     }
698     return result;
699   }
700 }