ab41d43cc97a37a50c0ca1779ccae3252bcdcee9
[sdc.git] / openecomp-be / lib / openecomp-sdc-translator-lib / openecomp-sdc-translator-core / src / main / java / org / openecomp / sdc / translator / services / heattotosca / TranslationService.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;
22
23 import org.apache.commons.collections4.MapUtils;
24 import org.openecomp.core.translator.datatypes.TranslatorOutput;
25 import org.openecomp.core.utilities.file.FileContentHandler;
26 import org.openecomp.core.utilities.file.FileUtils;
27 import org.openecomp.core.utilities.yaml.YamlUtil;
28 import org.openecomp.sdc.common.errors.CoreException;
29 import org.openecomp.sdc.datatypes.error.ErrorLevel;
30 import org.openecomp.sdc.heat.datatypes.manifest.FileData;
31 import org.openecomp.sdc.heat.datatypes.model.Environment;
32 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
33 import org.openecomp.sdc.heat.datatypes.model.Output;
34 import org.openecomp.sdc.heat.datatypes.model.Resource;
35 import org.openecomp.sdc.heat.datatypes.structure.ValidationStructureList;
36 import org.openecomp.sdc.heat.services.tree.HeatTreeManager;
37 import org.openecomp.sdc.heat.services.tree.HeatTreeManagerUtil;
38 import org.openecomp.sdc.logging.api.Logger;
39 import org.openecomp.sdc.logging.api.LoggerFactory;
40 import org.openecomp.sdc.logging.context.impl.MdcDataDebugMessage;
41 import org.openecomp.sdc.logging.context.impl.MdcDataErrorMessage;
42 import org.openecomp.sdc.logging.types.LoggerConstants;
43 import org.openecomp.sdc.logging.types.LoggerErrorCode;
44 import org.openecomp.sdc.logging.types.LoggerErrorDescription;
45 import org.openecomp.sdc.logging.types.LoggerTragetServiceName;
46 import org.openecomp.sdc.tosca.datatypes.ToscaGroupType;
47 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
48 import org.openecomp.sdc.tosca.datatypes.model.GroupDefinition;
49 import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
50 import org.openecomp.sdc.tosca.datatypes.model.ParameterDefinition;
51 import org.openecomp.sdc.tosca.datatypes.model.PropertyType;
52 import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate;
53 import org.openecomp.sdc.tosca.datatypes.model.TopologyTemplate;
54 import org.openecomp.sdc.tosca.services.DataModelUtil;
55 import org.openecomp.sdc.tosca.services.ToscaConstants;
56 import org.openecomp.sdc.tosca.services.ToscaFileOutputService;
57 import org.openecomp.sdc.tosca.services.ToscaUtil;
58 import org.openecomp.sdc.tosca.services.impl.ToscaFileOutputServiceCsarImpl;
59 import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedResourceId;
60 import org.openecomp.sdc.translator.datatypes.heattotosca.TranslationContext;
61 import org.openecomp.sdc.translator.datatypes.heattotosca.to.FileDataCollection;
62 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.EntityConsolidationData;
63 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.GetAttrFuncData;
64 import org.openecomp.sdc.translator.services.heattotosca.errors.ResourceNotFoundInHeatFileErrorBuilder;
65 import org.openecomp.sdc.translator.services.heattotosca.globaltypes.GlobalTypesGenerator;
66 import org.openecomp.sdc.translator.services.heattotosca.mapping.TranslatorHeatToToscaParameterConverter;
67
68 import java.util.ArrayList;
69 import java.util.HashMap;
70 import java.util.HashSet;
71 import java.util.Iterator;
72 import java.util.List;
73 import java.util.Map;
74 import java.util.Objects;
75 import java.util.Optional;
76 import java.util.Set;
77
78 public class TranslationService {
79
80   protected static Logger logger = (Logger) LoggerFactory.getLogger(TranslationService.class);
81   protected static MdcDataDebugMessage mdcDataDebugMessage = new MdcDataDebugMessage();
82
83   /**
84    * Gets types to process by translator.
85    *
86    * @return the types to process by translator
87    */
88   public static Set<FileData.Type> getTypesToProcessByTranslator() {
89     Set<FileData.Type> types = new HashSet<>();
90     types.add(FileData.Type.HEAT);
91     types.add(FileData.Type.HEAT_VOL);
92     return types;
93   }
94
95   /**
96    * Translate heat files translator output.
97    *
98    * @param translationContext the translation context
99    * @return the translator output
100    */
101   public TranslatorOutput translateHeatFiles(TranslationContext translationContext) {
102     mdcDataDebugMessage.debugEntryMessage(null, null);
103
104     ServiceTemplate mainServiceTemplate = createMainServiceTemplate(translationContext);
105     List<FileData> fileDataList = translationContext.getManifest().getContent().getData();
106     FileDataCollection fileDataCollection = HeatToToscaUtil.getFileCollectionsByFilter(fileDataList,
107         TranslationService.getTypesToProcessByTranslator(), translationContext);
108
109     if (fileDataCollection.getBaseFile() != null) {
110       for (FileData fileData : fileDataCollection.getBaseFile()) {
111         translateHeatFile(mainServiceTemplate, fileData, translationContext);
112       }
113     }
114     if (fileDataCollection.getAddOnFiles() != null) {
115       for (FileData fileData : fileDataCollection.getAddOnFiles()) {
116         translateHeatFile(mainServiceTemplate, fileData, translationContext);
117       }
118     }
119
120     ToscaServiceModel toscaServiceModel =
121         HeatToToscaUtil.createToscaServiceModel(mainServiceTemplate, translationContext);
122
123     TranslatorOutput translatorOutput = new TranslatorOutput();
124     translatorOutput.setToscaServiceModel(toscaServiceModel);
125
126     mdcDataDebugMessage.debugExitMessage(null, null);
127     return translatorOutput;
128   }
129
130   private ServiceTemplate createMainServiceTemplate(TranslationContext translationContext) {
131
132
133     mdcDataDebugMessage.debugEntryMessage(null, null);
134
135     ServiceTemplate mainServiceTemplate = new ServiceTemplate();
136     translationContext.getTranslatedServiceTemplates()
137         .put(Constants.MAIN_TEMPLATE_NAME, mainServiceTemplate);
138     Map<String, String> templateMetadata = new HashMap<>();
139     templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, Constants.MAIN_TEMPLATE_NAME);
140     mainServiceTemplate.setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
141     mainServiceTemplate.setMetadata(templateMetadata);
142     mainServiceTemplate.setTopology_template(new TopologyTemplate());
143     mainServiceTemplate.setImports(GlobalTypesGenerator.getGlobalTypesImportList());
144
145     mdcDataDebugMessage.debugExitMessage(null, null);
146     return mainServiceTemplate;
147   }
148
149   /**
150    * Translate heat file.
151    *
152    * @param serviceTemplate the service template
153    * @param heatFileData    the heat file data
154    * @param context         the context
155    */
156   public void translateHeatFile(ServiceTemplate serviceTemplate, FileData heatFileData,
157                                 TranslationContext context) {
158
159
160     mdcDataDebugMessage.debugEntryMessage(null, null);
161
162     String heatFileName = heatFileData.getFile();
163     HeatOrchestrationTemplate heatOrchestrationTemplate = new YamlUtil()
164         .yamlToObject(context.getFileContent(heatFileName), HeatOrchestrationTemplate.class);
165
166     translateInputParameters(serviceTemplate, heatOrchestrationTemplate, heatFileData, context,
167         heatFileName);
168     translateResources(heatFileName, serviceTemplate, heatOrchestrationTemplate, context);
169     translateOutputParameters(serviceTemplate, heatOrchestrationTemplate, heatFileData,
170         heatFileName, context);
171     createHeatStackGroup(serviceTemplate, heatFileData, heatOrchestrationTemplate, context);
172     handleHeatPseudoParam(heatFileName, serviceTemplate, context);
173
174     if (Objects.nonNull(heatFileData.getData())) {
175       heatFileData.getData().stream().filter(data -> data.getType() == FileData.Type.HEAT_VOL)
176           .forEach(data -> translateHeatFile(serviceTemplate, data, context));
177     }
178
179     mdcDataDebugMessage.debugExitMessage(null, null);
180   }
181
182   private void handleHeatPseudoParam(String heatFileName, ServiceTemplate serviceTemplate,
183                                      TranslationContext context) {
184     Map<String, String> translatedHeatPseudoParam =
185         context.getUsedHeatPseudoParams().get(heatFileName);
186     if (Objects.nonNull(translatedHeatPseudoParam)) {
187       for (String heatPseudoParam : translatedHeatPseudoParam.keySet()) {
188         if (!serviceTemplate.getTopology_template().getInputs().containsKey(heatPseudoParam)) {
189           ParameterDefinition parameterDefinition = new ParameterDefinition();
190           parameterDefinition.setType(PropertyType.STRING.getDisplayName());
191           parameterDefinition.setRequired(false);
192           String parameterDefinitionId = translatedHeatPseudoParam.get(heatPseudoParam);
193           DataModelUtil.addInputParameterToTopologyTemplate(serviceTemplate, parameterDefinitionId,
194               parameterDefinition);
195         }
196       }
197     }
198   }
199
200   private void createHeatStackGroup(ServiceTemplate serviceTemplate, FileData heatFileData,
201                                     HeatOrchestrationTemplate heatOrchestrationTemplate,
202                                     TranslationContext context) {
203
204
205     mdcDataDebugMessage.debugEntryMessage(null, null);
206
207     ToscaFileOutputService toscaFileOutputService = new ToscaFileOutputServiceCsarImpl();
208     final String fileName = heatFileData.getFile();
209     final String heatStackGroupId = FileUtils.getFileWithoutExtention(fileName) + "_group";
210
211     GroupDefinition groupDefinition = new GroupDefinition();
212     groupDefinition.setType(ToscaGroupType.HEAT_STACK);
213     groupDefinition.setProperties(new HashMap<>());
214     groupDefinition.getProperties()
215         .put("heat_file", "../" + toscaFileOutputService.getArtifactsFolderName() + "/" + fileName);
216     String hotDescription = heatOrchestrationTemplate.getDescription();
217     if (hotDescription != null && !hotDescription.isEmpty()) {
218       groupDefinition.getProperties().put(Constants.DESCRIPTION_PROPERTY_NAME, hotDescription);
219     }
220     groupDefinition.setMembers(new ArrayList<>());
221     Map<String, Set<String>> heatStackGroupMembers = context.getHeatStackGroupMembers();
222     if (heatStackGroupMembers.get(fileName) == null) {
223       return; //not creating a group when no resources are present in the heat input
224     }
225     groupDefinition.getMembers().addAll(heatStackGroupMembers.get(fileName));
226     DataModelUtil
227         .addGroupDefinitionToTopologyTemplate(serviceTemplate, heatStackGroupId, groupDefinition);
228
229     mdcDataDebugMessage.debugExitMessage(null, null);
230   }
231
232   private void translateInputParameters(ServiceTemplate serviceTemplate,
233                                         HeatOrchestrationTemplate heatOrchestrationTemplate,
234                                         FileData heatFileData, TranslationContext context,
235                                         String heatFileName) {
236
237
238     mdcDataDebugMessage.debugEntryMessage(null, null);
239
240     if (heatOrchestrationTemplate.getParameters() == null) {
241       return;
242     }
243
244     Map<String, ParameterDefinition> parameterDefinitionMap =
245         TranslatorHeatToToscaParameterConverter
246             .parameterConverter(serviceTemplate,heatOrchestrationTemplate.getParameters(),
247                 heatOrchestrationTemplate, heatFileName, context);
248     Environment heatEnvFile = getHeatEnvFile(heatFileData, context);
249     Map<String, Object> parameters = heatEnvFile.getParameters();
250     Object parameterValue;
251     if (parameters != null) {
252       for (Map.Entry<String, ParameterDefinition> entry : parameterDefinitionMap.entrySet()) {
253         String paramName = entry.getKey();
254         parameterValue = parameters.get(paramName);
255         if (parameterValue != null) {
256           entry.getValue().set_default(TranslatorHeatToToscaParameterConverter
257               .getToscaParameterDefaultValue(null, null, parameterValue, entry.getValue().getType(),
258                   heatFileName, heatOrchestrationTemplate, context));
259         }
260       }
261     }
262
263     Map<String, ParameterDefinition> inputs = serviceTemplate.getTopology_template().getInputs();
264     if (Objects.isNull(inputs)) {
265       serviceTemplate.getTopology_template().setInputs(parameterDefinitionMap);
266     } else {
267       inputs.putAll(parameterDefinitionMap);
268     }
269
270     mdcDataDebugMessage.debugExitMessage(null, null);
271   }
272
273   private void translateOutputParameters(ServiceTemplate serviceTemplate,
274                                          HeatOrchestrationTemplate heatOrchestrationTemplate,
275                                          FileData heatFileData, String heatFileName,
276                                          TranslationContext context) {
277
278
279     mdcDataDebugMessage.debugEntryMessage(null, null);
280
281     if (heatOrchestrationTemplate.getOutputs() == null) {
282       return;
283     }
284     Map<String, ParameterDefinition> parameterDefinitionMap =
285         TranslatorHeatToToscaParameterConverter
286             .parameterOutputConverter(serviceTemplate,heatOrchestrationTemplate.getOutputs(),
287                 heatOrchestrationTemplate, heatFileName, context);
288     if (serviceTemplate.getTopology_template().getOutputs() != null) {
289       serviceTemplate.getTopology_template().getOutputs().putAll(parameterDefinitionMap);
290     } else {
291       serviceTemplate.getTopology_template().setOutputs(parameterDefinitionMap);
292     }
293
294     if (heatFileData.getBase() != null && heatFileData.getBase().equals(true)) {
295       updateSharedResources(serviceTemplate, heatFileName, heatOrchestrationTemplate,
296           heatOrchestrationTemplate.getOutputs(), context);
297     }
298
299     mdcDataDebugMessage.debugExitMessage(null, null);
300   }
301
302   private void updateSharedResources(ServiceTemplate serviceTemplate, String heatFileName,
303                                      HeatOrchestrationTemplate heatOrchestrationTemplate,
304                                      Map<String, Output> outputs, TranslationContext context) {
305
306
307     mdcDataDebugMessage.debugEntryMessage(null, null);
308
309     for (Map.Entry<String, Output> parameter : outputs.entrySet()) {
310       Optional<AttachedResourceId> attachedSharedResourceId = HeatToToscaUtil
311           .extractAttachedResourceId(heatFileName, heatOrchestrationTemplate, context,
312               parameter.getValue().getValue());
313       if (attachedSharedResourceId.isPresent() && attachedSharedResourceId.get().isGetResource()
314           && attachedSharedResourceId.get().getTranslatedId() != null) {
315         String sharedTranslatedResourceId =
316             attachedSharedResourceId.get().getTranslatedId().toString();
317         updateSharedResource(serviceTemplate, context, parameter, sharedTranslatedResourceId,
318             heatOrchestrationTemplate.getResources()
319                 .get(attachedSharedResourceId.get().getEntityId()));
320       } else {
321         Optional<String> contrailSharedResourceId = HeatToToscaUtil
322             .extractContrailGetResourceAttachedHeatResourceId(parameter.getValue().getValue());
323         if (contrailSharedResourceId.isPresent()
324             && context.getTranslatedIds().get(heatFileName).get(contrailSharedResourceId.get())
325             != null) {
326           String sharedTranslatedResourceId = context.getTranslatedIds().get(heatFileName).get
327               (contrailSharedResourceId.get());
328           ConsolidationDataUtil.removeSharedResource(serviceTemplate, heatOrchestrationTemplate,
329               context, parameter.getKey(),contrailSharedResourceId.get(), sharedTranslatedResourceId);
330           updateSharedResource(serviceTemplate, context, parameter,sharedTranslatedResourceId,
331               heatOrchestrationTemplate.getResources().get(contrailSharedResourceId.get()));
332         }
333       }
334     }
335     if (serviceTemplate.getTopology_template().getOutputs() != null
336         && serviceTemplate.getTopology_template().getOutputs().size() == 0) {
337       serviceTemplate.getTopology_template().setOutputs(null);
338     }
339
340     mdcDataDebugMessage.debugExitMessage(null, null);
341   }
342
343   private void updateSharedResource(ServiceTemplate serviceTemplate, TranslationContext context,
344                                     Map.Entry<String, Output> paramName,
345                                     String sharedTranslatedResourceId, Resource resource) {
346
347
348     mdcDataDebugMessage.debugEntryMessage(null, null);
349
350     context.addHeatSharedResourcesByParam(paramName.getKey(), sharedTranslatedResourceId, resource);
351     serviceTemplate.getTopology_template().getOutputs().remove(paramName.getKey());
352
353     mdcDataDebugMessage.debugExitMessage(null, null);
354   }
355
356   private void translateResources(String heatFileName, ServiceTemplate serviceTemplate,
357                                   HeatOrchestrationTemplate heatOrchestrationTemplate,
358                                   TranslationContext context) {
359
360
361     mdcDataDebugMessage.debugEntryMessage(null, null);
362
363     if(MapUtils.isEmpty(heatOrchestrationTemplate.getResources())){
364       return;
365     }
366
367     for (String resourceId : heatOrchestrationTemplate.getResources().keySet()) {
368       Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
369       if (resource == null) {
370         MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
371             LoggerTragetServiceName.TRANSLATE_RESOURCE, ErrorLevel.ERROR.name(),
372             LoggerErrorCode.DATA_ERROR.getErrorCode(), LoggerErrorDescription.TRANSLATE_HEAT);
373         throw new CoreException(
374             new ResourceNotFoundInHeatFileErrorBuilder(resourceId, heatFileName).build());
375       }
376       ResourceTranslationFactory.getInstance(resource)
377           .translateResource(heatFileName, serviceTemplate, heatOrchestrationTemplate, resource,
378               resourceId, context);
379     }
380
381     mdcDataDebugMessage.debugExitMessage(null, null);
382   }
383
384   private Environment getHeatEnvFile(FileData heatFileData, TranslationContext context) {
385     List<FileData> fileRelatedDataList = heatFileData.getData();
386     if (fileRelatedDataList == null) {
387       return new Environment();
388     }
389     for (FileData fileRelatedData : fileRelatedDataList) {
390       if (fileRelatedData.getType().equals(FileData.Type.HEAT_ENV)) {
391         return new YamlUtil().yamlToObject(context.getFileContent(fileRelatedData.getFile()),
392             Environment.class);
393       }
394     }
395     return new Environment();
396   }
397
398
399 }