a42e4c3366c555bb3664a61e9cdaf46553d2ebf1
[sdc.git] /
1 /*
2  * Copyright © 2016-2018 European Support Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.openecomp.sdc.translator.services.heattotosca.impl.resourcetranslation;
18
19 import java.util.Map;
20 import java.util.Objects;
21 import java.util.Optional;
22
23 import org.apache.commons.collections4.CollectionUtils;
24 import org.apache.commons.lang3.StringUtils;
25 import org.onap.sdc.tosca.datatypes.model.NodeTemplate;
26 import org.onap.sdc.tosca.datatypes.model.NodeType;
27 import org.onap.sdc.tosca.datatypes.model.RequirementAssignment;
28 import org.onap.sdc.tosca.datatypes.model.ServiceTemplate;
29 import org.openecomp.core.utilities.file.FileUtils;
30 import org.openecomp.sdc.heat.datatypes.manifest.FileData;
31 import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
32 import org.openecomp.sdc.heat.datatypes.model.Resource;
33 import org.openecomp.sdc.heat.services.HeatConstants;
34 import org.openecomp.sdc.logging.api.Logger;
35 import org.openecomp.sdc.logging.api.LoggerFactory;
36 import org.openecomp.sdc.tosca.datatypes.ToscaCapabilityType;
37 import org.openecomp.sdc.tosca.datatypes.ToscaNodeType;
38 import org.openecomp.sdc.tosca.services.DataModelUtil;
39 import org.openecomp.sdc.tosca.services.ToscaUtil;
40 import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl;
41 import org.openecomp.sdc.translator.datatypes.heattotosca.TranslationContext;
42 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslateTo;
43 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.SubInterfaceTemplateConsolidationData;
44 import org.openecomp.sdc.translator.services.heattotosca.ConsolidationDataUtil;
45 import org.openecomp.sdc.translator.services.heattotosca.Constants;
46 import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil;
47 import org.openecomp.sdc.translator.services.heattotosca.TranslationService;
48
49 public class ResourceTranslationNestedImpl extends ResourceTranslationBase {
50
51     private static final String SUB_INTERFACE_COUNT = "count";
52     protected static Logger log = LoggerFactory.getLogger(ResourceTranslationNestedImpl.class);
53
54     @Override
55     public void translate(TranslateTo translateTo) {
56         TranslationContext context = translateTo.getContext();
57         FileData nestedFileData = HeatToToscaUtil.getFileData(translateTo.getResource().getType(), context);
58         if (nestedFileData == null) {
59             log.warn("Nested File '{}' is not exist, therefore, the nested resource with the ID '{}' will be ignored "
60                     + "in TOSCA translation", translateTo.getResource().getType(), translateTo.getResourceId());
61             return;
62         }
63         String templateName = FileUtils.getFileWithoutExtention(translateTo.getResource().getType());
64         String substitutionNodeTypeKey = HeatToToscaUtil.getNestedResourceTypePrefix(translateTo) + templateName;
65         if (!context.getTranslatedServiceTemplates().containsKey(translateTo.getResource().getType())) {
66             translateNestedHeat(translateTo, nestedFileData, templateName, substitutionNodeTypeKey);
67         }
68         ServiceTemplate substitutionServiceTemplate = context.getTranslatedServiceTemplates()
69                 .get(translateTo.getResource().getType());
70         if (DataModelUtil.isNodeTemplateSectionMissingFromServiceTemplate(substitutionServiceTemplate)) {
71             handleSubstitutionServiceTemplateWithoutNodeTemplates(templateName, translateTo);
72             return;
73         }
74         NodeTemplate substitutionNodeTemplate = HeatToToscaUtil.createAbstractSubstitutionNodeTemplate(translateTo,
75                 templateName, substitutionNodeTypeKey);
76         manageSubstitutionNodeTemplateConnectionPoint(translateTo, nestedFileData, substitutionNodeTemplate,
77                 substitutionNodeTypeKey);
78         DataModelUtil.addNodeTemplate(translateTo.getServiceTemplate(), translateTo.getTranslatedId(),
79                 substitutionNodeTemplate);
80         //Add nested node template id to consolidation data
81         ConsolidationDataUtil.updateNestedNodeTemplateId(translateTo);
82         //Gather consolidation data if the resource group represents a sub interface
83         if (isResourceGroupSubInterface(substitutionNodeTypeKey)) {
84             populateSubInterfaceTemplateConsolidationData(translateTo, substitutionNodeTemplate);
85         }
86     }
87
88     private boolean isResourceGroupSubInterface(String substitutionNodeTypeKey) {
89         return StringUtils.isNotBlank(substitutionNodeTypeKey)
90                 && substitutionNodeTypeKey.contains(ToscaNodeType.VLAN_SUB_INTERFACE_RESOURCE_TYPE_PREFIX);
91     }
92
93     private void translateNestedHeat(TranslateTo translateTo, FileData nestedFileData, String templateName,
94                                      String substitutionNodeTypeKey) {
95         TranslationContext context = translateTo.getContext();
96         //substitution service template
97         ServiceTemplate nestedSubstitutionServiceTemplate =
98                 createSubstitutionServiceTemplate(translateTo, nestedFileData, templateName);
99         //global substitution service template
100         ServiceTemplate globalSubstitutionServiceTemplate = HeatToToscaUtil
101                 .fetchGlobalSubstitutionServiceTemplate(translateTo.getServiceTemplate(), context);
102         //substitution node type
103         NodeType substitutionNodeType = new ToscaAnalyzerServiceImpl()
104                 .createInitSubstitutionNodeType(nestedSubstitutionServiceTemplate, ToscaNodeType.ABSTRACT_SUBSTITUTE);
105         DataModelUtil.addNodeType(globalSubstitutionServiceTemplate, substitutionNodeTypeKey,
106                 substitutionNodeType);
107         //substitution mapping
108         HeatToToscaUtil.handleSubstitutionMapping(context, substitutionNodeTypeKey,
109                 nestedSubstitutionServiceTemplate, substitutionNodeType);
110         //add new nested service template
111         context.getTranslatedServiceTemplates().put(translateTo.getResource().getType(),
112                 nestedSubstitutionServiceTemplate);
113     }
114
115     private void populateSubInterfaceTemplateConsolidationData(TranslateTo translateTo,
116                                                                NodeTemplate nodeTemplate) {
117
118         Optional<SubInterfaceTemplateConsolidationData> subInterfaceTemplateConsolidationData =
119                 ConsolidationDataUtil.getSubInterfaceTemplateConsolidationData(translateTo, translateTo
120                         .getTranslatedId());
121         if (!subInterfaceTemplateConsolidationData.isPresent()) {
122             return;
123         }
124         Optional<String> subInterfaceNetworkRole =
125                 HeatToToscaUtil.getNetworkRoleFromSubInterfaceId(translateTo.getResource(), translateTo.getContext());
126         subInterfaceNetworkRole.ifPresent(subInterfaceTemplateConsolidationData.get()::setNetworkRole);
127         subInterfaceTemplateConsolidationData.get()
128                 .setResourceGroupCount(getSubInterfaceCountFromResourceProperties(translateTo));
129         if (CollectionUtils.isEmpty(nodeTemplate.getRequirements())) {
130             return;
131         }
132         //Add connectivity to network in consolidation data based on resource group link requirements
133         nodeTemplate.getRequirements().forEach((Map<String, RequirementAssignment> requirementMap) ->
134                 requirementMap.entrySet().stream()
135                         .filter(requirementAssignmentEntry -> ToscaCapabilityType.NATIVE_NETWORK_LINKABLE
136                                 .equals(requirementAssignmentEntry.getValue().getCapability()))
137                         .forEach(requirementAssignmentEntry -> subInterfaceTemplateConsolidationData.get()
138                                 .addNodesConnectedOut(requirementAssignmentEntry.getValue().getNode(),
139                                         requirementAssignmentEntry.getKey(),
140                                         requirementAssignmentEntry.getValue())
141                         )
142         );
143     }
144
145     private Object getSubInterfaceCountFromResourceProperties(TranslateTo translateTo) {
146         if (Objects.nonNull(translateTo.getHeatOrchestrationTemplate().getResources().get(translateTo
147                 .getResourceId()))) {
148             Resource resource = translateTo.getHeatOrchestrationTemplate().getResources().get(translateTo
149                     .getResourceId());
150             if (HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource().equals(resource.getType())) {
151                 return resource.getProperties().get(SUB_INTERFACE_COUNT);
152             } else if (HeatToToscaUtil.isYamlFile(resource.getType())) {
153                 return HeatConstants.DEFAULT_NESTED_HEAT_RESOURCE_COUNT;
154             }
155         }
156         return null;
157     }
158
159     private void handleSubstitutionServiceTemplateWithoutNodeTemplates(String templateName,
160                                                                        TranslateTo translateTo) {
161         translateTo.getContext().addServiceTemplateWithoutNodeTemplates(templateName);
162         translateTo.getContext()
163                 .addNestedNodeTemplateIdPointsToStWithoutNodeTemplates(translateTo.getTranslatedId());
164         translateTo.getContext().getTranslatedServiceTemplates().remove(translateTo.getResource().getType());
165     }
166
167     private ServiceTemplate createSubstitutionServiceTemplate(TranslateTo translateTo,
168                                                               FileData nestedFileData,
169                                                               String templateName) {
170         ServiceTemplate nestedSubstitutionServiceTemplate =
171                 HeatToToscaUtil.createInitSubstitutionServiceTemplate(templateName);
172         translateTo.getContext().addNestedHeatFileName(ToscaUtil.getServiceTemplateFileName(templateName),
173                         translateTo.getResource().getType());
174         new TranslationService().translateHeatFile(nestedSubstitutionServiceTemplate, nestedFileData, translateTo
175                 .getContext());
176         return nestedSubstitutionServiceTemplate;
177     }
178
179
180     private void manageSubstitutionNodeTemplateConnectionPoint(TranslateTo translateTo,
181                                                                FileData nestedFileData,
182                                                                NodeTemplate substitutionNodeTemplate,
183                                                                String substitutionNodeTypeId) {
184         ServiceTemplate globalSubstitutionTemplate =
185                 translateTo.getContext().getTranslatedServiceTemplates()
186                         .get(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
187         NodeType nodeType = globalSubstitutionTemplate.getNode_types().get(substitutionNodeTypeId);
188         handlePortToNetConnections(translateTo, nestedFileData, substitutionNodeTemplate, nodeType);
189         handleSecurityRulesToPortConnections(translateTo, nestedFileData, substitutionNodeTemplate,
190                 nodeType);
191         handleNovaToVolConnection(translateTo, nestedFileData, substitutionNodeTemplate, nodeType);
192         handleContrailV2VmInterfaceToNetworkConnection(translateTo, nestedFileData,
193                 substitutionNodeTemplate, nodeType);
194         handleContrailPortToNetConnections(translateTo, nestedFileData, substitutionNodeTemplate,
195                 nodeType);
196         handleVlanSubInterfaceToInterfaceConnections(translateTo, nestedFileData,
197                 substitutionNodeTemplate, nodeType);
198     }
199
200     private void handleVlanSubInterfaceToInterfaceConnections(TranslateTo translateTo,
201                                                               FileData nestedFileData,
202                                                               NodeTemplate substitutionNodeTemplate,
203                                                               NodeType nodeType) {
204         ContrailV2VlanToInterfaceResourceConnection linker =
205                 new ContrailV2VlanToInterfaceResourceConnection(this, translateTo, nestedFileData,
206                         substitutionNodeTemplate, nodeType);
207         linker.connect();
208     }
209
210
211     private void handleContrailV2VmInterfaceToNetworkConnection(TranslateTo translateTo,
212                                                                 FileData nestedFileData,
213                                                                 NodeTemplate substitutionNodeTemplate,
214                                                                 NodeType nodeType) {
215         ContrailV2VmInterfaceToNetResourceConnection linker =
216                 new ContrailV2VmInterfaceToNetResourceConnection(this, translateTo, nestedFileData,
217                         substitutionNodeTemplate, nodeType);
218         linker.connect();
219     }
220
221     private void handleNovaToVolConnection(TranslateTo translateTo, FileData nestedFileData,
222                                            NodeTemplate substitutionNodeTemplate, NodeType nodeType) {
223         NovaToVolResourceConnection linker =
224                 new NovaToVolResourceConnection(this, translateTo, nestedFileData, substitutionNodeTemplate,
225                         nodeType);
226         linker.connect();
227     }
228
229     private void handleSecurityRulesToPortConnections(TranslateTo translateTo,
230                                                       FileData nestedFileData,
231                                                       NodeTemplate substitutionNodeTemplate,
232                                                       NodeType nodeType) {
233         SecurityRulesToPortResourceConnection linker =
234                 new SecurityRulesToPortResourceConnection(this, translateTo, nestedFileData,
235                         substitutionNodeTemplate, nodeType);
236         linker.connect();
237     }
238
239     private void handlePortToNetConnections(TranslateTo translateTo, FileData nestedFileData,
240                                             NodeTemplate substitutionNodeTemplate,
241                                             NodeType nodeType) {
242         PortToNetResourceConnection linker =
243                 new PortToNetResourceConnection(this, translateTo, nestedFileData, substitutionNodeTemplate,
244                         nodeType);
245         linker.connect();
246     }
247
248     private void handleContrailPortToNetConnections(TranslateTo translateTo, FileData nestedFileData,
249                                                     NodeTemplate substitutionNodeTemplate,
250                                                     NodeType nodeType) {
251         ContrailPortToNetResourceConnection linker =
252                 new ContrailPortToNetResourceConnection(this, translateTo, nestedFileData,
253                         substitutionNodeTemplate, nodeType);
254         linker.connect();
255     }
256
257 }