[sdc] docker file fix for cassandra
[sdc.git] / openecomp-be / lib / openecomp-sdc-translator-lib / openecomp-sdc-translator-core / src / main / java / org / openecomp / sdc / translator / services / heattotosca / impl / ResourceTranslationNestedImpl.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.translator.services.heattotosca.impl;
22
23 import org.apache.commons.collections4.CollectionUtils;
24 import org.apache.commons.collections4.MapUtils;
25 import org.openecomp.core.utilities.file.FileUtils;
26 import org.openecomp.sdc.heat.datatypes.manifest.FileData;
27 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
28 import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
29 import org.openecomp.sdc.heat.datatypes.model.Resource;
30 import org.openecomp.sdc.heat.services.HeatConstants;
31 import org.openecomp.sdc.tosca.datatypes.ToscaCapabilityType;
32 import org.openecomp.sdc.tosca.datatypes.ToscaNodeType;
33 import org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType;
34 import org.openecomp.sdc.tosca.datatypes.model.AttributeDefinition;
35 import org.openecomp.sdc.tosca.datatypes.model.CapabilityDefinition;
36 import org.openecomp.sdc.tosca.datatypes.model.Metadata;
37 import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
38 import org.openecomp.sdc.tosca.datatypes.model.NodeType;
39 import org.openecomp.sdc.tosca.datatypes.model.ParameterDefinition;
40 import org.openecomp.sdc.tosca.datatypes.model.PropertyDefinition;
41 import org.openecomp.sdc.tosca.datatypes.model.PropertyType;
42 import org.openecomp.sdc.tosca.datatypes.model.RequirementAssignment;
43 import org.openecomp.sdc.tosca.datatypes.model.RequirementDefinition;
44 import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate;
45 import org.openecomp.sdc.tosca.datatypes.model.SubstitutionMapping;
46 import org.openecomp.sdc.tosca.datatypes.model.Template;
47 import org.openecomp.sdc.tosca.datatypes.model.TopologyTemplate;
48 import org.openecomp.sdc.tosca.services.DataModelUtil;
49 import org.openecomp.sdc.tosca.services.ToscaConstants;
50 import org.openecomp.sdc.tosca.services.ToscaUtil;
51 import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedResourceId;
52 import org.openecomp.sdc.translator.datatypes.heattotosca.to.ResourceFileDataAndIDs;
53 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslateTo;
54 import org.openecomp.sdc.translator.services.heattotosca.Constants;
55 import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil;
56 import org.openecomp.sdc.translator.services.heattotosca.TranslationContext;
57 import org.openecomp.sdc.translator.services.heattotosca.TranslationService;
58 import org.openecomp.sdc.translator.services.heattotosca.globaltypes.GlobalTypesGenerator;
59 import org.openecomp.sdc.translator.services.heattotosca.globaltypes.GlobalTypesUtil;
60 import org.openecomp.sdc.translator.services.heattotosca.mapping.TranslatorHeatToToscaPropertyConverter;
61 import org.slf4j.Logger;
62 import org.slf4j.LoggerFactory;
63
64 import java.util.ArrayList;
65 import java.util.HashMap;
66 import java.util.List;
67 import java.util.Map;
68 import java.util.Objects;
69 import java.util.Optional;
70
71 public class ResourceTranslationNestedImpl extends ResourceTranslationBase {
72
73   protected static Logger logger = LoggerFactory.getLogger(ResourceTranslationNestedImpl.class);
74
75   @Override
76   public void translate(TranslateTo translateTo) {
77     FileData nestedFileData =
78         getFileData(translateTo.getResource().getType(), translateTo.getContext());
79     String templateName = FileUtils.getFileWithoutExtention(translateTo.getResource().getType());
80     String substitutionNodeTypeKey = ToscaConstants.NODES_SUBSTITUTION_PREFIX + templateName;
81
82     if (!translateTo.getContext().getTranslatedServiceTemplates()
83         .containsKey(translateTo.getResource().getType())) {
84
85       //substitution template
86       ServiceTemplate nestedSubstitutionServiceTemplate = new ServiceTemplate();
87       Metadata templateMetadata = new Metadata();
88       templateMetadata.setTemplate_name(templateName);
89       nestedSubstitutionServiceTemplate.setMetadata(templateMetadata);
90       nestedSubstitutionServiceTemplate
91           .setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
92       nestedSubstitutionServiceTemplate.setTopology_template(new TopologyTemplate());
93       nestedSubstitutionServiceTemplate.setImports(GlobalTypesGenerator.getGlobalTypesImportList());
94       nestedSubstitutionServiceTemplate.getImports()
95           .put(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME, GlobalTypesUtil
96               .createServiceTemplateImport(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
97
98       TranslationService translationService = new TranslationService();
99
100       translationService.translateHeatFile(nestedSubstitutionServiceTemplate, nestedFileData,
101           translateTo.getContext());
102
103       //global substitution template
104       ServiceTemplate globalSubstitutionServiceTemplate;
105       globalSubstitutionServiceTemplate = translateTo.getContext().getTranslatedServiceTemplates()
106           .get(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
107       if (globalSubstitutionServiceTemplate == null) {
108         globalSubstitutionServiceTemplate = new ServiceTemplate();
109         templateMetadata = new Metadata();
110         templateMetadata.setTemplate_name(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
111         globalSubstitutionServiceTemplate.setMetadata(templateMetadata);
112         globalSubstitutionServiceTemplate
113             .setImports(GlobalTypesGenerator.getGlobalTypesImportList());
114         globalSubstitutionServiceTemplate
115             .setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
116       }
117       translateTo.getServiceTemplate().getImports()
118           .put(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME, GlobalTypesUtil
119               .createServiceTemplateImport(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
120
121
122       //substitution node type
123       NodeType substitutionNodeType = new NodeType();
124       substitutionNodeType.setDerived_from(ToscaNodeType.ABSTRACT_SUBSTITUTE.getDisplayName());
125       substitutionNodeType.setDescription(nestedSubstitutionServiceTemplate.getDescription());
126       substitutionNodeType
127           .setProperties(manageSubstitutionNodeTypeProperties(nestedSubstitutionServiceTemplate));
128       substitutionNodeType
129           .setAttributes(manageSubstitutionNodeTypeAttributes(nestedSubstitutionServiceTemplate));
130       DataModelUtil.addNodeType(globalSubstitutionServiceTemplate, substitutionNodeTypeKey,
131           substitutionNodeType);
132       Map<String, Map<String, List<String>>> substitutionMapping =
133           manageSubstitutionNodeTypeCapabilitiesAndRequirements(substitutionNodeType,
134               nestedSubstitutionServiceTemplate, translateTo);
135       //calculate substitution mapping after capability and requirement expose calculation
136       nestedSubstitutionServiceTemplate.getTopology_template().setSubstitution_mappings(
137           manageSubstitutionTemplateSubstitutionMapping(substitutionNodeTypeKey,
138               substitutionNodeType, substitutionMapping));
139
140       //add new service template
141       translateTo.getContext().getTranslatedServiceTemplates()
142           .put(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME,
143               globalSubstitutionServiceTemplate);
144       translateTo.getContext().getTranslatedServiceTemplates()
145           .put(translateTo.getResource().getType(), nestedSubstitutionServiceTemplate);
146     }
147
148     NodeTemplate substitutionNodeTemplate = new NodeTemplate();
149     List<String> directiveList = new ArrayList<>();
150     directiveList.add(ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
151     substitutionNodeTemplate.setDirectives(directiveList);
152     substitutionNodeTemplate.setType(substitutionNodeTypeKey);
153     substitutionNodeTemplate.setProperties(
154         managerSubstitutionNodeTemplateProperties(translateTo, substitutionNodeTemplate,
155             templateName));
156     manageSubstitutionNodeTemplateConnectionPoint(translateTo, nestedFileData,
157         substitutionNodeTemplate);
158     DataModelUtil.addNodeTemplate(translateTo.getServiceTemplate(), translateTo.getTranslatedId(),
159         substitutionNodeTemplate);
160   }
161
162   private void manageSubstitutionNodeTemplateConnectionPoint(TranslateTo translateTo,
163                                                            FileData nestedFileData,
164                                                            NodeTemplate substitutionNodeTemplate) {
165     ServiceTemplate globalSubstitutionTemplate =
166         translateTo.getContext().getTranslatedServiceTemplates()
167             .get(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
168     NodeType nodeType = globalSubstitutionTemplate.getNode_types().get(
169         ToscaConstants.NODES_SUBSTITUTION_PREFIX
170             + FileUtils.getFileWithoutExtention(translateTo.getResource().getType()));
171     handlePortToNetConnections(translateTo, nestedFileData, substitutionNodeTemplate, nodeType);
172     handleSecurityRulesToPortConnections(translateTo, nestedFileData, substitutionNodeTemplate,
173         nodeType);
174     handleNovaToVolConnection(translateTo, nestedFileData, substitutionNodeTemplate, nodeType);
175     handleContrailV2VmInterfaceToNetworkConnection(translateTo, nestedFileData,
176         substitutionNodeTemplate, nodeType);
177   }
178
179   private void handleContrailV2VmInterfaceToNetworkConnection(TranslateTo translateTo,
180                                                               FileData nestedFileData,
181                                                               NodeTemplate substitutionNodeTemplate,
182                                                               NodeType nodeType) {
183     ContrailV2VmInterfaceToNetResourceConnection linker =
184         new ContrailV2VmInterfaceToNetResourceConnection(this, translateTo, nestedFileData,
185             substitutionNodeTemplate, nodeType);
186     linker.connect();
187   }
188
189   private void handleNovaToVolConnection(TranslateTo translateTo, FileData nestedFileData,
190                                          NodeTemplate substitutionNodeTemplate, NodeType nodeType) {
191     NovaToVolResourceConnection linker =
192         new NovaToVolResourceConnection(this, translateTo, nestedFileData, substitutionNodeTemplate,
193             nodeType);
194     linker.connect();
195   }
196
197   private void handleSecurityRulesToPortConnections(TranslateTo translateTo,
198                                                     FileData nestedFileData,
199                                                     NodeTemplate substitutionNodeTemplate,
200                                                     NodeType nodeType) {
201     SecurityRulesToPortResourceConnection linker =
202         new SecurityRulesToPortResourceConnection(this, translateTo, nestedFileData,
203             substitutionNodeTemplate, nodeType);
204     linker.connect();
205   }
206
207   private void handlePortToNetConnections(TranslateTo translateTo, FileData nestedFileData,
208                                           NodeTemplate substitutionNodeTemplate,
209                                           NodeType nodeType) {
210     PortToNetResourceConnection linker =
211         new PortToNetResourceConnection(this, translateTo, nestedFileData, substitutionNodeTemplate,
212             nodeType);
213     linker.connect();
214   }
215
216   private List<Map<String, RequirementDefinition>> getVolumeRequirements(NodeType nodeType) {
217     List<Map<String, RequirementDefinition>> volumeRequirementsList = new ArrayList<>();
218     List<Map<String, RequirementDefinition>> requirementsList = nodeType.getRequirements();
219
220     for (int i = 0; requirementsList != null && i < requirementsList.size(); i++) {
221       RequirementDefinition req;
222       for (Map.Entry<String, RequirementDefinition> entry : requirementsList.get(i).entrySet()) {
223         req = entry.getValue();
224         if (isVolumeRequirement(req, ToscaCapabilityType.ATTACHMENT.getDisplayName(),
225             ToscaNodeType.BLOCK_STORAGE.getDisplayName(),
226             ToscaRelationshipType.NATIVE_ATTACHES_TO.getDisplayName())) {
227           Map<String, RequirementDefinition> volumeRequirementsMap = new HashMap<>();
228           volumeRequirementsMap.put(entry.getKey(), entry.getValue());
229           volumeRequirementsList.add(volumeRequirementsMap);
230         }
231
232       }
233     }
234     return volumeRequirementsList;
235   }
236
237   private boolean isVolumeRequirement(RequirementDefinition req, String capability, String node,
238                                       String relationship) {
239     return req.getCapability().equals(capability) && req.getRelationship().equals(relationship)
240         && req.getNode().equals(node);
241   }
242
243   private String getVolumeIdProperty(HeatOrchestrationTemplate heatOrchestrationTemplate,
244                                      String resourceId) {
245
246     String novaResourceId;
247     String volumeId = null;
248     for (Resource resource : heatOrchestrationTemplate.getResources().values()) {
249       if (resource.getType()
250           .equals(HeatResourcesTypes.CINDER_VOLUME_ATTACHMENT_RESOURCE_TYPE.getHeatResource())) {
251         Optional<String> optNovaResourceId =
252             getToscaPropertyValueSource(HeatConstants.INSTANCE_UUID_PROPERTY_NAME, resource,
253                 "get_resource");
254         if (optNovaResourceId.isPresent()) {
255           novaResourceId = optNovaResourceId.get();
256           if (novaResourceId.equals(resourceId)) {
257             Optional<String> optVolumeId =
258                 getToscaPropertyValueSource(HeatConstants.VOLUME_ID_PROPERTY_NAME, resource,
259                     "get_param");
260             if (optVolumeId.isPresent()) {
261               volumeId = optVolumeId.get();
262             }
263           } else {
264             logger.warn("property:" + HeatConstants.VOLUME_ID_PROPERTY_NAME + " of resource type:"
265                 + resource.getType() + " should contain 'get_param' function");
266           }
267         }
268       }
269     }
270     return volumeId;
271   }
272
273   private String getTranslatedVolumeIdByVolumeIdProperty(String volumeId, TranslateTo translateTo) {
274     Optional<AttachedResourceId> volumeIdInfo =
275         HeatToToscaUtil.extractAttachedResourceId(translateTo, volumeId);
276     if (volumeIdInfo.isPresent()) {
277       if (volumeIdInfo.get().isGetResource()) {
278         return null;//(String) volumeIdInfo.get().getTranslatedId();
279       } else if (volumeIdInfo.get().isGetParam()) {
280         List<FileData> allFilesData = translateTo.getContext().getManifest().getContent().getData();
281         Optional<List<FileData>> fileDataList = HeatToToscaUtil
282             .buildListOfFilesToSearch(translateTo.getHeatFileName(), allFilesData,
283                 FileData.Type.HEAT_VOL);
284         if (fileDataList.isPresent()) {
285           Optional<ResourceFileDataAndIDs> resourceFileDataAndIDs =
286               getFileDataContainingResource(fileDataList.get(),
287                   (String) volumeIdInfo.get().getEntityId(), translateTo.getContext(),
288                   FileData.Type.HEAT_VOL);
289           if (resourceFileDataAndIDs.isPresent()) {
290             return resourceFileDataAndIDs.get().getTranslatedResourceId();
291           } else {
292             logger.warn("The attached volume based on volume_id property: " + volumeId + " in "
293                 + translateTo.getResourceId()
294                 + " can't be found, searching for volume resource id - "
295                 + volumeIdInfo.get().getEntityId());
296             return null;
297           }
298         } else {
299           return null;
300         }
301       } else {
302         logger.warn("property:" + volumeId + " of resource :" + volumeIdInfo.get().getEntityId()
303             + " should contain 'get_param' or 'get_resource' function");
304         return null;
305       }
306     } else {
307       logger.warn("property:" + volumeId + " of resource :" + translateTo.getResource().toString()
308           + " is not exist");
309       return null;
310     }
311   }
312
313   private Optional<String> getToscaPropertyValueSource(String propertyName, Resource resource,
314                                                        String key) {
315     Object propertyInstanceUuIdValue;
316     propertyInstanceUuIdValue = resource.getProperties().get(propertyName);
317     if (propertyInstanceUuIdValue instanceof Map) {
318       return Optional.ofNullable((String) ((Map) propertyInstanceUuIdValue).get(key));
319     } else {
320       logger.warn("property:" + propertyName + " of resource type:" + resource.getType()
321           + " should have a value in key value format");
322
323     }
324     return Optional.empty();
325
326   }
327
328   private Map<String, Map<String, List<String>>>
329       manageSubstitutionNodeTypeCapabilitiesAndRequirements(
330       NodeType substitutionNodeType, ServiceTemplate substitutionServiceTemplate,
331       TranslateTo translateTo) {
332
333     Map<String, NodeTemplate> nodeTemplates =
334         substitutionServiceTemplate.getTopology_template().getNode_templates();
335     String templateName;
336     NodeTemplate template;
337     String type;
338     Map<String, Map<String, List<String>>> substitutionMapping = new HashMap<>();
339     if (nodeTemplates == null) {
340       return substitutionMapping;
341     }
342
343     Map<String, List<String>> capabilitySubstitutionMapping = new HashMap<>();
344     Map<String, List<String>> requirementSubstitutionMapping = new HashMap<>();
345     substitutionMapping.put("capability", capabilitySubstitutionMapping);
346     substitutionMapping.put("requirement", requirementSubstitutionMapping);
347     List<Map<String, RequirementDefinition>> nodeTypeRequirementsDefinition;
348     Map<String, RequirementAssignment> nodeTemplateRequirementsAssignment;
349     List<Map<String, RequirementDefinition>> exposedRequirementsDefinition;
350     Map<String, Map<String, RequirementAssignment>> fullFilledRequirementsDefinition =
351         new HashMap<>();
352     Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition = new HashMap<>();
353     Map<String, CapabilityDefinition> exposedCapabilitiesDefinition;
354
355     for (Map.Entry<String, NodeTemplate> entry : nodeTemplates.entrySet()) {
356       templateName = entry.getKey();
357       template = entry.getValue();
358       type = template.getType();
359
360       // get requirements
361       nodeTypeRequirementsDefinition =
362           getNodeTypeRequirements(type, templateName, substitutionServiceTemplate,
363               requirementSubstitutionMapping, translateTo.getContext());
364       nodeTemplateRequirementsAssignment = getNodeTemplateRequirements(template);
365       fullFilledRequirementsDefinition.put(templateName, nodeTemplateRequirementsAssignment);
366       //set substitution node type requirements
367       exposedRequirementsDefinition = calculateExposedRequirements(nodeTypeRequirementsDefinition,
368           nodeTemplateRequirementsAssignment);
369       addSubstitutionNodeTypeRequirements(substitutionNodeType, exposedRequirementsDefinition,
370           templateName);
371
372       //get capabilities
373       getNodeTypeCapabilities(nodeTypeCapabilitiesDefinition, capabilitySubstitutionMapping, type,
374           templateName, substitutionServiceTemplate, translateTo.getContext());
375
376     }
377
378     exposedCapabilitiesDefinition = calculateExposedCapabilities(nodeTypeCapabilitiesDefinition,
379         fullFilledRequirementsDefinition);
380     addSubstitutionNodeTypeCapabilities(substitutionNodeType, exposedCapabilitiesDefinition);
381     return substitutionMapping;
382   }
383
384   private Map<String, CapabilityDefinition> calculateExposedCapabilities(
385       Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition,
386       Map<String, Map<String, RequirementAssignment>> fullFilledRequirementsDefinitionMap) {
387
388     String capabilityKey;
389     String capability;
390     String node;
391     CapabilityDefinition capabilityDefinition;
392     CapabilityDefinition clonedCapabilityDefinition;
393     for (Map.Entry<String, Map<String, RequirementAssignment>> entry
394         : fullFilledRequirementsDefinitionMap.entrySet()) {
395       for (Map.Entry<String, RequirementAssignment> fullFilledEntry : entry.getValue().entrySet()) {
396
397         capability = fullFilledEntry.getValue().getCapability();
398         fullFilledEntry.getValue().getOccurrences();
399         node = fullFilledEntry.getValue().getNode();
400         capabilityKey = capability + "_" + node;
401         capabilityDefinition = nodeTypeCapabilitiesDefinition.get(capabilityKey);
402         if (capabilityDefinition != null) {
403           clonedCapabilityDefinition = capabilityDefinition.clone();
404           nodeTypeCapabilitiesDefinition.put(capabilityKey, capabilityDefinition.clone());
405           if (evaluateCapabilityFullFilament(clonedCapabilityDefinition)) {
406             nodeTypeCapabilitiesDefinition.remove(capabilityKey);
407           } else {
408             nodeTypeCapabilitiesDefinition.put(capabilityKey, clonedCapabilityDefinition);
409           }
410         }
411       }
412     }
413
414     Map<String, CapabilityDefinition> exposedCapabilitiesDefinition = new HashMap<>();
415     for (Map.Entry<String, CapabilityDefinition> entry : nodeTypeCapabilitiesDefinition
416         .entrySet()) {
417       exposedCapabilitiesDefinition.put(entry.getKey(), entry.getValue());
418     }
419     return exposedCapabilitiesDefinition;
420   }
421
422   private boolean evaluateCapabilityFullFilament(CapabilityDefinition capabilityDefinition) {
423     Object[] occurrences = capabilityDefinition.getOccurrences();
424     if (occurrences == null) {
425       capabilityDefinition.setOccurrences(new Object[]{"0", ToscaConstants.UNBOUNDED});
426       return false;
427     }
428     if (occurrences[1].equals(ToscaConstants.UNBOUNDED)) {
429       return false;
430     }
431
432     if (occurrences[1].equals(1)) {
433       return true;
434     }
435     occurrences[1] = (Integer) occurrences[1] - 1;
436     return false;
437   }
438
439   private boolean evaluateRequirementFullFilament(RequirementDefinition requirementDefinition) {
440     Object[] occurrences = requirementDefinition.getOccurrences();
441     if (occurrences == null) {
442       requirementDefinition.setOccurrences(new Object[]{"0", ToscaConstants.UNBOUNDED});
443       return false;
444     }
445     if (occurrences[1].equals(ToscaConstants.UNBOUNDED)) {
446       return false;
447     }
448
449     if (occurrences[1].equals(1)) {
450       return true;
451     }
452     occurrences[1] = (Integer) occurrences[1] - 1;
453     return false;
454   }
455
456   private void getNodeTypeCapabilities(
457       Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition,
458       Map<String, List<String>> capabilitySubstitutionMapping, String type, String templateName,
459       ServiceTemplate serviceTemplate, TranslationContext context) {
460     NodeType nodeType = getNodeTypeWithFlatHierarchy(type, serviceTemplate, context);
461     String capabilityKey;
462     List<String> capabilityMapping;
463     if (nodeType.getCapabilities() != null) {
464       for (Map.Entry<String, CapabilityDefinition> capabilityNodeEntry : nodeType.getCapabilities()
465           .entrySet()) {
466         capabilityKey = capabilityNodeEntry.getKey() + "_" + templateName;
467         nodeTypeCapabilitiesDefinition.put(capabilityKey, capabilityNodeEntry.getValue().clone());
468         capabilityMapping = new ArrayList<>();
469         capabilityMapping.add(templateName);
470         capabilityMapping.add(capabilityNodeEntry.getKey());
471         capabilitySubstitutionMapping.put(capabilityKey, capabilityMapping);
472       }
473     }
474
475     String derivedFrom = nodeType.getDerived_from();
476     if (derivedFrom != null) {
477       getNodeTypeCapabilities(nodeTypeCapabilitiesDefinition, capabilitySubstitutionMapping,
478           derivedFrom, templateName, serviceTemplate, context);
479     }
480   }
481
482   private List<Map<String, RequirementDefinition>> calculateExposedRequirements(
483       List<Map<String, RequirementDefinition>> nodeTypeRequirementsDefinitionList,
484       Map<String, RequirementAssignment> nodeTemplateRequirementsAssignment) {
485     if (nodeTypeRequirementsDefinitionList == null) {
486       return null;
487     }
488     for (Map.Entry<String, RequirementAssignment> entry : nodeTemplateRequirementsAssignment
489         .entrySet()) {
490       if (entry.getValue().getNode() != null) {
491         RequirementDefinition requirementDefinition =
492             getRequirementDefinition(nodeTypeRequirementsDefinitionList, entry.getKey());
493         RequirementDefinition cloneRequirementDefinition;
494         if (requirementDefinition != null) {
495           cloneRequirementDefinition = requirementDefinition.clone();
496           if (!evaluateRequirementFullFilament(cloneRequirementDefinition)) {
497             this.mergeEntryInList(entry.getKey(), cloneRequirementDefinition,
498                 nodeTypeRequirementsDefinitionList);
499           } else {
500             removeRequirementsDefinition(nodeTypeRequirementsDefinitionList, entry.getKey());
501           }
502         }
503       } else {
504         for (Map<String, RequirementDefinition> nodeTypeRequirementsMap
505             : nodeTypeRequirementsDefinitionList) {
506           Object max = nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences() != null
507               && nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences().length > 0
508               ? nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences()[1] : 1;
509           Object min = nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences() != null
510               && nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences().length > 0
511               ? nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences()[0] : 1;
512           nodeTypeRequirementsMap.get(entry.getKey()).setOccurrences(new Object[]{min, max});
513         }
514       }
515     }
516     return nodeTypeRequirementsDefinitionList;
517   }
518
519   private void removeRequirementsDefinition(
520       List<Map<String, RequirementDefinition>> nodeTypeRequirementsDefinitionList,
521       String requirementKey) {
522     for (Map<String, RequirementDefinition> reqMap : nodeTypeRequirementsDefinitionList) {
523       reqMap.remove(requirementKey);
524     }
525   }
526
527   private RequirementDefinition getRequirementDefinition(
528       List<Map<String, RequirementDefinition>> nodeTypeRequirementsDefinitionList,
529       String requirementKey) {
530     for (Map<String, RequirementDefinition> requirementMap : nodeTypeRequirementsDefinitionList) {
531       if (requirementMap.containsKey(requirementKey)) {
532         return requirementMap.get(requirementKey);
533       }
534     }
535     return null;
536   }
537
538   private Map<String, RequirementAssignment> getNodeTemplateRequirements(NodeTemplate template) {
539     List<Map<String, RequirementAssignment>> templateRequirements = template.getRequirements();
540
541     Map<String, RequirementAssignment> nodeTemplateRequirementsDefinition = new HashMap<>();
542     if (CollectionUtils.isEmpty(templateRequirements)) {
543       return nodeTemplateRequirementsDefinition;
544     }
545     for (Map<String, RequirementAssignment> requirementAssignmentMap : templateRequirements) {
546       for (Map.Entry<String, RequirementAssignment> requirementEntry : requirementAssignmentMap
547           .entrySet()) {
548         nodeTemplateRequirementsDefinition
549             .put(requirementEntry.getKey(), requirementEntry.getValue());
550       }
551     }
552     return nodeTemplateRequirementsDefinition;
553   }
554
555   private List<Map<String, RequirementDefinition>> getNodeTypeRequirements(String type,
556                                           String templateName,
557                                           ServiceTemplate serviceTemplate,
558                                           Map<String, List<String>> requirementSubstitutionMapping,
559                                           TranslationContext context) {
560     List<Map<String, RequirementDefinition>> requirementList = null;
561     NodeType nodeType = getNodeTypeWithFlatHierarchy(type, serviceTemplate, context);
562     String derivedFrom = nodeType.getDerived_from();
563     List<String> requirementMapping;
564     if (derivedFrom != null) {
565       requirementList = getNodeTypeRequirements(derivedFrom, templateName, serviceTemplate,
566           requirementSubstitutionMapping, context);
567     }
568     if (requirementList == null) {
569       requirementList = new ArrayList<>();
570     }
571
572     if (nodeType.getRequirements() != null) {
573       for (Map<String, RequirementDefinition> requirementMap : nodeType.getRequirements()) {
574         for (Map.Entry<String, RequirementDefinition> requirementNodeEntry : requirementMap
575             .entrySet()) {
576           if (requirementNodeEntry.getValue().getOccurrences() == null) {
577             requirementNodeEntry.getValue().setOccurrences(new Object[]{1, 1});
578           }
579           Map<String, RequirementDefinition> requirementDef = new HashMap<>();
580           requirementDef.put(requirementNodeEntry.getKey(), requirementNodeEntry.getValue());
581           addRequirementToList(requirementList, requirementDef);
582           requirementMapping = new ArrayList<>();
583           requirementMapping.add(templateName);
584           requirementMapping.add(requirementNodeEntry.getKey());
585           requirementSubstitutionMapping
586               .put(requirementNodeEntry.getKey() + "_" + templateName, requirementMapping);
587           if (requirementNodeEntry.getValue().getNode() == null) {
588             requirementNodeEntry.getValue().setOccurrences(new Object[]{1, 1});
589           }
590         }
591       }
592     }
593
594     return requirementList;
595   }
596
597   private void addRequirementToList(List<Map<String, RequirementDefinition>> requirementList,
598                                     Map<String, RequirementDefinition> requirementDef) {
599     for (Map.Entry<String, RequirementDefinition> entry : requirementDef.entrySet()) {
600       this.mergeEntryInList(entry.getKey(), entry.getValue(), requirementList);
601     }
602   }
603
604   private void addSubstitutionNodeTypeCapabilities(NodeType substitutionNodeType,
605                                                    Map<String, CapabilityDefinition> capabilities) {
606     if (capabilities == null || capabilities.entrySet().size() == 0) {
607       return;
608     }
609
610     if (MapUtils.isEmpty(substitutionNodeType.getCapabilities())) {
611       substitutionNodeType.setCapabilities(new HashMap<>());
612     }
613     if (capabilities.size() > 0) {
614       substitutionNodeType.setCapabilities(new HashMap<>());
615     }
616     for (Map.Entry<String, CapabilityDefinition> entry : capabilities.entrySet()) {
617       substitutionNodeType.getCapabilities().put(entry.getKey(), entry.getValue());
618     }
619   }
620
621   private void addSubstitutionNodeTypeRequirements(NodeType substitutionNodeType,
622                                     List<Map<String, RequirementDefinition>> requirementsList,
623                                     String templateName) {
624     if (requirementsList == null || requirementsList.size() == 0) {
625       return;
626     }
627
628     if (substitutionNodeType.getRequirements() == null) {
629       substitutionNodeType.setRequirements(new ArrayList<>());
630     }
631
632     for (Map<String, RequirementDefinition> requirementDef : requirementsList) {
633       for (Map.Entry<String, RequirementDefinition> entry : requirementDef.entrySet()) {
634         Map<String, RequirementDefinition> requirementMap = new HashMap<>();
635         requirementMap.put(entry.getKey() + "_" + templateName, entry.getValue().clone());
636         substitutionNodeType.getRequirements().add(requirementMap);
637       }
638     }
639   }
640
641
642   private SubstitutionMapping manageSubstitutionTemplateSubstitutionMapping(String nodeTypeKey,
643                                        NodeType substitutionNodeType,
644                                        Map<String, Map<String, List<String>>> mapping) {
645     SubstitutionMapping substitutionMapping = new SubstitutionMapping();
646     substitutionMapping.setNode_type(nodeTypeKey);
647     substitutionMapping.setCapabilities(
648         manageCapabilityMapping(substitutionNodeType.getCapabilities(), mapping.get("capability")));
649     substitutionMapping.setRequirements(
650         manageRequirementMapping(substitutionNodeType.getRequirements(),
651             mapping.get("requirement")));
652     return substitutionMapping;
653   }
654
655   private Map<String, List<String>> manageCapabilityMapping(
656       Map<String, CapabilityDefinition> capabilities,
657       Map<String, List<String>> capabilitySubstitutionMapping) {
658     if (capabilities == null) {
659       return null;
660     }
661
662     Map<String, List<String>> capabilityMapping = new HashMap<>();
663     String capabilityKey;
664     List<String> capabilityMap;
665     for (Map.Entry<String, CapabilityDefinition> entry : capabilities.entrySet()) {
666       capabilityKey = entry.getKey();
667       capabilityMap = capabilitySubstitutionMapping.get(capabilityKey);
668       capabilityMapping.put(capabilityKey, capabilityMap);
669     }
670     return capabilityMapping;
671   }
672
673   private Map<String, List<String>> manageRequirementMapping(
674       List<Map<String, RequirementDefinition>> requirementList,
675       Map<String, List<String>> requirementSubstitutionMapping) {
676     if (requirementList == null) {
677       return null;
678     }
679     Map<String, List<String>> requirementMapping = new HashMap<>();
680     String requirementKey;
681     List<String> requirementMap;
682     for (Map<String, RequirementDefinition> requirementDefMap : requirementList) {
683       for (Map.Entry<String, RequirementDefinition> entry : requirementDefMap.entrySet()) {
684         requirementKey = entry.getKey();
685         requirementMap = requirementSubstitutionMapping.get(requirementKey);
686         requirementMapping.put(requirementKey, requirementMap);
687       }
688     }
689     return requirementMapping;
690   }
691
692
693   private Map<String, AttributeDefinition> manageSubstitutionNodeTypeAttributes(
694       ServiceTemplate substitutionServiceTemplate) {
695
696     Map<String, AttributeDefinition> substitutionNodeTypeAttributes = new HashMap<>();
697     Map<String, ParameterDefinition> attributes =
698         substitutionServiceTemplate.getTopology_template().getOutputs();
699     if (attributes == null) {
700       return null;
701     }
702     AttributeDefinition attributeDefinition;
703     String toscaAttributeName;
704
705     for (Map.Entry<String, ParameterDefinition> entry : attributes.entrySet()) {
706       attributeDefinition = new AttributeDefinition();
707       toscaAttributeName = entry.getKey();
708       ParameterDefinition parameterDefinition =
709           substitutionServiceTemplate.getTopology_template().getOutputs().get(toscaAttributeName);
710       if (parameterDefinition.getType() != null && !parameterDefinition.getType().isEmpty()) {
711         attributeDefinition.setType(parameterDefinition.getType());
712       } else {
713         attributeDefinition.setType(PropertyType.STRING.getDisplayName());
714       }
715       attributeDefinition.setDescription(parameterDefinition.getDescription());
716       attributeDefinition.set_default(parameterDefinition.get_default());
717       attributeDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
718       attributeDefinition.setStatus(parameterDefinition.getStatus());
719       substitutionNodeTypeAttributes.put(toscaAttributeName, attributeDefinition);
720     }
721     return substitutionNodeTypeAttributes;
722   }
723
724   private Map<String, PropertyDefinition> manageSubstitutionNodeTypeProperties(
725       ServiceTemplate substitutionServiceTemplate) {
726     Map<String, PropertyDefinition> substitutionNodeTypeProperties = new HashMap<>();
727     Map<String, ParameterDefinition> properties =
728         substitutionServiceTemplate.getTopology_template().getInputs();
729     if (properties == null) {
730       return null;
731     }
732
733     PropertyDefinition propertyDefinition;
734     String toscaPropertyName;
735     for (Map.Entry<String, ParameterDefinition> entry : properties.entrySet()) {
736       toscaPropertyName = entry.getKey();
737       propertyDefinition = new PropertyDefinition();
738       ParameterDefinition parameterDefinition =
739           substitutionServiceTemplate.getTopology_template().getInputs().get(toscaPropertyName);
740       propertyDefinition.setType(parameterDefinition.getType());
741       propertyDefinition.setDescription(parameterDefinition.getDescription());
742       propertyDefinition.setRequired(parameterDefinition.getRequired());
743       propertyDefinition.set_default(parameterDefinition.get_default());
744       propertyDefinition.setConstraints(parameterDefinition.getConstraints());
745       propertyDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
746       propertyDefinition.setStatus(parameterDefinition.getStatus());
747       substitutionNodeTypeProperties.put(toscaPropertyName, propertyDefinition);
748     }
749     return substitutionNodeTypeProperties;
750   }
751
752   private Map<String, Object> managerSubstitutionNodeTemplateProperties(TranslateTo translateTo,
753                                                                         Template template,
754                                                                         String templateName) {
755     Map<String, Object> substitutionProperties = new HashMap<>();
756     Map<String, Object> heatProperties = translateTo.getResource().getProperties();
757     if (Objects.nonNull(heatProperties)) {
758       for (Map.Entry<String, Object> entry : heatProperties.entrySet()) {
759
760         Object property = TranslatorHeatToToscaPropertyConverter
761             .getToscaPropertyValue(entry.getKey(), entry.getValue(), null,
762                 translateTo.getHeatFileName(), translateTo.getHeatOrchestrationTemplate(), template,
763                 translateTo.getContext());
764         substitutionProperties.put(entry.getKey(), property);
765       }
766     }
767
768     return addAbstractSubstitutionProperty(templateName, substitutionProperties);
769   }
770
771   private Map<String, Object> addAbstractSubstitutionProperty(String templateName,
772                                               Map<String, Object> substitutionProperties) {
773     Map<String, Object> innerProps = new HashMap<>();
774     innerProps.put(ToscaConstants.SUBSTITUTE_SERVICE_TEMPLATE_PROPERTY_NAME,
775         ToscaUtil.getServiceTemplateFileName(templateName));
776     substitutionProperties.put(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME, innerProps);
777     return substitutionProperties;
778   }
779
780
781 }