push addional code
[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.openecomp.core.translator.datatypes.TranslatorOutput;
24 import org.openecomp.core.utilities.file.FileContentHandler;
25 import org.openecomp.core.utilities.file.FileUtils;
26 import org.openecomp.core.utilities.yaml.YamlUtil;
27 import org.openecomp.sdc.common.errors.CoreException;
28 import org.openecomp.sdc.heat.datatypes.manifest.FileData;
29 import org.openecomp.sdc.heat.datatypes.model.Environment;
30 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
31 import org.openecomp.sdc.heat.datatypes.model.Output;
32 import org.openecomp.sdc.heat.datatypes.model.Resource;
33 import org.openecomp.sdc.heat.datatypes.structure.ValidationStructureList;
34 import org.openecomp.sdc.heat.services.tree.HeatTreeManager;
35 import org.openecomp.sdc.heat.services.tree.HeatTreeManagerUtil;
36 import org.openecomp.sdc.tosca.datatypes.ToscaGroupType;
37 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
38 import org.openecomp.sdc.tosca.datatypes.model.GroupDefinition;
39 import org.openecomp.sdc.tosca.datatypes.model.Metadata;
40 import org.openecomp.sdc.tosca.datatypes.model.ParameterDefinition;
41 import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate;
42 import org.openecomp.sdc.tosca.datatypes.model.TopologyTemplate;
43 import org.openecomp.sdc.tosca.services.ToscaConstants;
44 import org.openecomp.sdc.tosca.services.ToscaFileOutputService;
45 import org.openecomp.sdc.tosca.services.ToscaUtil;
46 import org.openecomp.sdc.tosca.services.impl.ToscaFileOutputServiceCsarImpl;
47 import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedResourceId;
48 import org.openecomp.sdc.translator.datatypes.heattotosca.to.FileDataCollection;
49 import org.openecomp.sdc.translator.services.heattotosca.errors.ResourceNotFoundInHeatFileErrorBuilder;
50 import org.openecomp.sdc.translator.services.heattotosca.globaltypes.GlobalTypesGenerator;
51 import org.openecomp.sdc.translator.services.heattotosca.mapping.TranslatorHeatToToscaParameterConverter;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54
55 import java.util.ArrayList;
56 import java.util.HashMap;
57 import java.util.HashSet;
58 import java.util.List;
59 import java.util.Map;
60 import java.util.Objects;
61 import java.util.Optional;
62 import java.util.Set;
63
64
65 public class TranslationService {
66
67   protected static Logger logger = LoggerFactory.getLogger(TranslationService.class);
68
69   /**
70    * Gets types to process by translator.
71    *
72    * @return the types to process by translator
73    */
74   public static Set<FileData.Type> getTypesToProcessByTranslator() {
75     Set<FileData.Type> types = new HashSet<>();
76     types.add(FileData.Type.HEAT);
77     types.add(FileData.Type.HEAT_VOL);
78     return types;
79   }
80
81   /**
82    * Translate heat files translator output.
83    *
84    * @param translationContext the translation context
85    * @return the translator output
86    */
87   public TranslatorOutput translateHeatFiles(TranslationContext translationContext) {
88     ServiceTemplate mainServiceTemplate = createMainServiceTemplate(translationContext);
89     List<FileData> fileDataList = translationContext.getManifest().getContent().getData();
90     FileDataCollection fileDataCollection = HeatToToscaUtil.getFileCollectionsByFilter(fileDataList,
91         TranslationService.getTypesToProcessByTranslator(), translationContext);
92
93     if (fileDataCollection.getBaseFile() != null) {
94       for (FileData fileData : fileDataCollection.getBaseFile()) {
95         translateHeatFile(mainServiceTemplate, fileData, translationContext);
96       }
97     }
98     if (fileDataCollection.getAddOnFiles() != null) {
99       for (FileData fileData : fileDataCollection.getAddOnFiles()) {
100         translateHeatFile(mainServiceTemplate, fileData, translationContext);
101       }
102     }
103
104     ToscaServiceModel toscaServiceModel =
105         createToscaServiceModel(mainServiceTemplate, translationContext);
106
107     TranslatorOutput translatorOutput = new TranslatorOutput();
108     translatorOutput.setToscaServiceModel(toscaServiceModel);
109     return translatorOutput;
110   }
111
112   private ToscaServiceModel createToscaServiceModel(ServiceTemplate entryDefinitionServiceTemplate,
113                                                     TranslationContext translationContext) {
114     return new ToscaServiceModel(getCsarArtifactFiles(translationContext),
115         getServiceTemplates(translationContext),
116         ToscaUtil.getServiceTemplateFileName(entryDefinitionServiceTemplate));
117   }
118
119   private Map<String, ServiceTemplate> getServiceTemplates(TranslationContext translationContext) {
120     List<ServiceTemplate> serviceTemplates = new ArrayList<>();
121     serviceTemplates.addAll(GlobalTypesGenerator.getGlobalTypesServiceTemplate().values());
122     serviceTemplates.addAll(translationContext.getTranslatedServiceTemplates().values());
123     Map<String, ServiceTemplate> serviceTemplatesMap = new HashMap<>();
124
125     for (ServiceTemplate template : serviceTemplates) {
126       serviceTemplatesMap.put(ToscaUtil.getServiceTemplateFileName(template), template);
127     }
128     return serviceTemplatesMap;
129   }
130
131   private FileContentHandler getCsarArtifactFiles(TranslationContext translationContext) {
132     FileContentHandler artifactFiles = new FileContentHandler();
133     artifactFiles.setFiles(translationContext.getFiles());
134     artifactFiles.setFiles(translationContext.getExternalArtifacts());
135
136     HeatTreeManager heatTreeManager =
137         HeatTreeManagerUtil.initHeatTreeManager(translationContext.getFiles());
138     heatTreeManager.createTree();
139     ValidationStructureList validationStructureList =
140         new ValidationStructureList(heatTreeManager.getTree());
141     byte[] validationStructureFile =
142         FileUtils.convertToBytes(validationStructureList, FileUtils.FileExtension.JSON);
143     artifactFiles.addFile("HEAT.meta", validationStructureFile);
144
145     return artifactFiles;
146   }
147
148   private ServiceTemplate createMainServiceTemplate(TranslationContext translationContext) {
149     ServiceTemplate mainServiceTemplate = new ServiceTemplate();
150     translationContext.getTranslatedServiceTemplates().put("Main", mainServiceTemplate);
151     Metadata templateMetadata = new Metadata();
152     templateMetadata.setTemplate_name("Main");
153     mainServiceTemplate.setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
154     mainServiceTemplate.setMetadata(templateMetadata);
155     mainServiceTemplate.setTopology_template(new TopologyTemplate());
156     mainServiceTemplate.setImports(GlobalTypesGenerator.getGlobalTypesImportList());
157
158     return mainServiceTemplate;
159   }
160
161   /**
162    * Translate heat file.
163    *
164    * @param serviceTemplate the service template
165    * @param heatFileData    the heat file data
166    * @param context         the context
167    */
168   public void translateHeatFile(ServiceTemplate serviceTemplate, FileData heatFileData,
169                                 TranslationContext context) {
170     String heatFileName = heatFileData.getFile();
171     HeatOrchestrationTemplate heatOrchestrationTemplate = new YamlUtil()
172         .yamlToObject(context.getFileContent(heatFileName), HeatOrchestrationTemplate.class);
173
174     translateInputParameters(serviceTemplate, heatOrchestrationTemplate, heatFileData, context,
175         heatFileName);
176     translateResources(heatFileName, serviceTemplate, heatOrchestrationTemplate, context);
177     translateOutputParameters(serviceTemplate, heatOrchestrationTemplate, heatFileData,
178         heatFileName, context);
179     createHeatStackGroup(serviceTemplate, heatFileData, heatOrchestrationTemplate, context);
180
181     if (Objects.nonNull(heatFileData.getData())) {
182       heatFileData.getData().stream().filter(data -> data.getType() == FileData.Type.HEAT_VOL)
183           .forEach(data -> translateHeatFile(serviceTemplate, data, context));
184     }
185   }
186
187   private void createHeatStackGroup(ServiceTemplate serviceTemplate, FileData heatFileData,
188                                     HeatOrchestrationTemplate heatOrchestrationTemplate,
189                                     TranslationContext context) {
190     ToscaFileOutputService toscaFileOutputService = new ToscaFileOutputServiceCsarImpl();
191     String fileName = heatFileData.getFile();
192     final String fileNameWoExtension =
193         FileUtils.getFileWithoutExtention(fileName);//.heatFileData.getFile().split("\\.")[0];
194
195     GroupDefinition groupDefinition = new GroupDefinition();
196     groupDefinition.setType(ToscaGroupType.HEAT_STACK.getDisplayName());
197     groupDefinition.setProperties(new HashMap<>());
198     groupDefinition.getProperties()
199         .put("heat_file", "../" + toscaFileOutputService.getArtifactsFolderName() + "/" + fileName);
200     String hotDescription = heatOrchestrationTemplate.getDescription();
201     if (hotDescription != null && !hotDescription.isEmpty()) {
202       groupDefinition.getProperties().put(Constants.DESCRIPTION_PROPERTY_NAME, hotDescription);
203     }
204     groupDefinition.setMembers(new ArrayList<>());
205     Map<String, Set<String>> heatStackGroupMembers = context.getHeatStackGroupMembers();
206     if (heatStackGroupMembers.get(fileName) == null) {
207       return; //not creating a group when no resources are present in the heat input
208     }
209     groupDefinition.getMembers().addAll(heatStackGroupMembers.get(fileName));
210     if (serviceTemplate.getTopology_template().getGroups() == null) {
211       Map<String, GroupDefinition> groups = new HashMap<>();
212       serviceTemplate.getTopology_template().setGroups(groups);
213     }
214     serviceTemplate.getTopology_template().getGroups().put(fileNameWoExtension, groupDefinition);
215   }
216
217   private void translateInputParameters(ServiceTemplate serviceTemplate,
218                                         HeatOrchestrationTemplate heatOrchestrationTemplate,
219                                         FileData heatFileData, TranslationContext context,
220                                         String heatFileName) {
221
222     if (heatOrchestrationTemplate.getParameters() == null) {
223       return;
224     }
225
226     Map<String, ParameterDefinition> parameterDefinitionMap =
227         TranslatorHeatToToscaParameterConverter
228             .parameterConverter(heatOrchestrationTemplate.getParameters(),
229                 heatOrchestrationTemplate, heatFileName, context);
230     Environment heatEnvFile = getHeatEnvFile(heatFileData, context);
231     Map<String, Object> parameters = heatEnvFile.getParameters();
232     Object parameterValue;
233     if (parameters != null) {
234       for (Map.Entry<String, ParameterDefinition> entry : parameterDefinitionMap.entrySet()) {
235         String paramName = entry.getKey();
236         parameterValue = parameters.get(paramName);
237         if (parameterValue != null) {
238           entry.getValue().set_default(TranslatorHeatToToscaParameterConverter
239               .getToscaParameterDefaultValue(parameterValue, entry.getValue().getType(),
240                   heatFileName, heatOrchestrationTemplate, context));
241         }
242       }
243     }
244
245     Map<String, ParameterDefinition> inputs = serviceTemplate.getTopology_template().getInputs();
246     if (Objects.isNull(inputs)) {
247       serviceTemplate.getTopology_template().setInputs(parameterDefinitionMap);
248     } else {
249       inputs.putAll(parameterDefinitionMap);
250     }
251   }
252
253   private void translateOutputParameters(ServiceTemplate serviceTemplate,
254                                          HeatOrchestrationTemplate heatOrchestrationTemplate,
255                                          FileData heatFileData, String heatFileName,
256                                          TranslationContext context) {
257     if (heatOrchestrationTemplate.getOutputs() == null) {
258       return;
259     }
260     Map<String, ParameterDefinition> parameterDefinitionMap =
261         TranslatorHeatToToscaParameterConverter
262             .parameterOutputConverter(heatOrchestrationTemplate.getOutputs(),
263                 heatOrchestrationTemplate, heatFileName, context);
264     if (serviceTemplate.getTopology_template().getOutputs() != null) {
265       serviceTemplate.getTopology_template().getOutputs().putAll(parameterDefinitionMap);
266     } else {
267       serviceTemplate.getTopology_template().setOutputs(parameterDefinitionMap);
268     }
269
270     if (heatFileData.getBase() != null && heatFileData.getBase().equals(true)) {
271       updateSharedResources(serviceTemplate, heatFileName, heatOrchestrationTemplate,
272           heatOrchestrationTemplate.getOutputs(), context);
273     }
274   }
275
276   private void updateSharedResources(ServiceTemplate serviceTemplate, String heatFileName,
277                                      HeatOrchestrationTemplate heatOrchestrationTemplate,
278                                      Map<String, Output> outputs, TranslationContext context) {
279     for (Map.Entry<String, Output> paramName : outputs.entrySet()) {
280       Optional<AttachedResourceId> attachedSharedResourceId = HeatToToscaUtil
281           .extractAttachedResourceId(heatFileName, heatOrchestrationTemplate, context,
282               paramName.getValue().getValue());
283       if (attachedSharedResourceId.isPresent() && attachedSharedResourceId.get().isGetResource()
284           && attachedSharedResourceId.get().getTranslatedId() != null) {
285         String sharedTranslatedResourceId =
286             attachedSharedResourceId.get().getTranslatedId().toString();
287         updateSharedResource(serviceTemplate, context, paramName, sharedTranslatedResourceId,
288             heatOrchestrationTemplate.getResources()
289                 .get(attachedSharedResourceId.get().getEntityId()));
290       } else {
291         String contrailSharedResourceId = HeatToToscaUtil
292             .extractContrailGetResourceAttachedHeatResourceId(paramName.getValue().getValue());
293         if (contrailSharedResourceId != null
294             && context.getTranslatedIds().get(heatFileName).get(contrailSharedResourceId) != null) {
295           updateSharedResource(serviceTemplate, context, paramName,
296               context.getTranslatedIds().get(heatFileName).get(contrailSharedResourceId),
297               heatOrchestrationTemplate.getResources().get(contrailSharedResourceId));
298         }
299       }
300     }
301     if (serviceTemplate.getTopology_template().getOutputs() != null
302         && serviceTemplate.getTopology_template().getOutputs().size() == 0) {
303       serviceTemplate.getTopology_template().setOutputs(null);
304     }
305   }
306
307   private void updateSharedResource(ServiceTemplate serviceTemplate, TranslationContext context,
308                                     Map.Entry<String, Output> paramName,
309                                     String sharedTranslatedResourceId, Resource resource) {
310     context.addHeatSharedResourcesByParam(paramName.getKey(), sharedTranslatedResourceId, resource);
311     serviceTemplate.getTopology_template().getOutputs().remove(paramName.getKey());
312   }
313
314   private void translateResources(String heatFileName, ServiceTemplate serviceTemplate,
315                                   HeatOrchestrationTemplate heatOrchestrationTemplate,
316                                   TranslationContext context) {
317     for (String resourceId : heatOrchestrationTemplate.getResources().keySet()) {
318       Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
319       if (resource == null) {
320         throw new CoreException(
321             new ResourceNotFoundInHeatFileErrorBuilder(resourceId, heatFileName).build());
322       }
323       ResourceTranslationFactory.getInstance(resource)
324           .translateResource(heatFileName, serviceTemplate, heatOrchestrationTemplate, resource,
325               resourceId, context);
326     }
327   }
328
329   private Environment getHeatEnvFile(FileData heatFileData, TranslationContext context) {
330     List<FileData> fileRelatedDataList = heatFileData.getData();
331     if (fileRelatedDataList == null) {
332       return new Environment();
333     }
334     for (FileData fileRelatedData : fileRelatedDataList) {
335       if (fileRelatedData.getType().equals(FileData.Type.HEAT_ENV)) {
336         return new YamlUtil().yamlToObject(context.getFileContent(fileRelatedData.getFile()),
337             Environment.class);
338       }
339     }
340     return new Environment();
341   }
342
343
344 }