2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.openecomp.sdc.translator.services.heattotosca;
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;
55 import java.util.ArrayList;
56 import java.util.HashMap;
57 import java.util.HashSet;
58 import java.util.List;
60 import java.util.Objects;
61 import java.util.Optional;
65 public class TranslationService {
67 protected static Logger logger = LoggerFactory.getLogger(TranslationService.class);
70 * Gets types to process by translator.
72 * @return the types to process by translator
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);
82 * Translate heat files translator output.
84 * @param translationContext the translation context
85 * @return the translator output
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);
93 if (fileDataCollection.getBaseFile() != null) {
94 for (FileData fileData : fileDataCollection.getBaseFile()) {
95 translateHeatFile(mainServiceTemplate, fileData, translationContext);
98 if (fileDataCollection.getAddOnFiles() != null) {
99 for (FileData fileData : fileDataCollection.getAddOnFiles()) {
100 translateHeatFile(mainServiceTemplate, fileData, translationContext);
104 ToscaServiceModel toscaServiceModel =
105 createToscaServiceModel(mainServiceTemplate, translationContext);
107 TranslatorOutput translatorOutput = new TranslatorOutput();
108 translatorOutput.setToscaServiceModel(toscaServiceModel);
109 return translatorOutput;
112 private ToscaServiceModel createToscaServiceModel(ServiceTemplate entryDefinitionServiceTemplate,
113 TranslationContext translationContext) {
114 return new ToscaServiceModel(getCsarArtifactFiles(translationContext),
115 getServiceTemplates(translationContext),
116 ToscaUtil.getServiceTemplateFileName(entryDefinitionServiceTemplate));
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<>();
125 for (ServiceTemplate template : serviceTemplates) {
126 serviceTemplatesMap.put(ToscaUtil.getServiceTemplateFileName(template), template);
128 return serviceTemplatesMap;
131 private FileContentHandler getCsarArtifactFiles(TranslationContext translationContext) {
132 FileContentHandler artifactFiles = new FileContentHandler();
133 artifactFiles.setFiles(translationContext.getFiles());
134 artifactFiles.setFiles(translationContext.getExternalArtifacts());
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);
145 return artifactFiles;
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());
158 return mainServiceTemplate;
162 * Translate heat file.
164 * @param serviceTemplate the service template
165 * @param heatFileData the heat file data
166 * @param context the context
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);
174 translateInputParameters(serviceTemplate, heatOrchestrationTemplate, heatFileData, context,
176 translateResources(heatFileName, serviceTemplate, heatOrchestrationTemplate, context);
177 translateOutputParameters(serviceTemplate, heatOrchestrationTemplate, heatFileData,
178 heatFileName, context);
179 createHeatStackGroup(serviceTemplate, heatFileData, heatOrchestrationTemplate, context);
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));
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];
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);
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
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);
214 serviceTemplate.getTopology_template().getGroups().put(fileNameWoExtension, groupDefinition);
217 private void translateInputParameters(ServiceTemplate serviceTemplate,
218 HeatOrchestrationTemplate heatOrchestrationTemplate,
219 FileData heatFileData, TranslationContext context,
220 String heatFileName) {
222 if (heatOrchestrationTemplate.getParameters() == null) {
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));
245 Map<String, ParameterDefinition> inputs = serviceTemplate.getTopology_template().getInputs();
246 if (Objects.isNull(inputs)) {
247 serviceTemplate.getTopology_template().setInputs(parameterDefinitionMap);
249 inputs.putAll(parameterDefinitionMap);
253 private void translateOutputParameters(ServiceTemplate serviceTemplate,
254 HeatOrchestrationTemplate heatOrchestrationTemplate,
255 FileData heatFileData, String heatFileName,
256 TranslationContext context) {
257 if (heatOrchestrationTemplate.getOutputs() == null) {
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);
267 serviceTemplate.getTopology_template().setOutputs(parameterDefinitionMap);
270 if (heatFileData.getBase() != null && heatFileData.getBase().equals(true)) {
271 updateSharedResources(serviceTemplate, heatFileName, heatOrchestrationTemplate,
272 heatOrchestrationTemplate.getOutputs(), context);
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()));
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));
301 if (serviceTemplate.getTopology_template().getOutputs() != null
302 && serviceTemplate.getTopology_template().getOutputs().size() == 0) {
303 serviceTemplate.getTopology_template().setOutputs(null);
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());
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());
323 ResourceTranslationFactory.getInstance(resource)
324 .translateResource(heatFileName, serviceTemplate, heatOrchestrationTemplate, resource,
325 resourceId, context);
329 private Environment getHeatEnvFile(FileData heatFileData, TranslationContext context) {
330 List<FileData> fileRelatedDataList = heatFileData.getData();
331 if (fileRelatedDataList == null) {
332 return new Environment();
334 for (FileData fileRelatedData : fileRelatedDataList) {
335 if (fileRelatedData.getType().equals(FileData.Type.HEAT_ENV)) {
336 return new YamlUtil().yamlToObject(context.getFileContent(fileRelatedData.getFile()),
340 return new Environment();