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.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;
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;
74 import java.util.Objects;
75 import java.util.Optional;
78 public class TranslationService {
80 protected static Logger logger = (Logger) LoggerFactory.getLogger(TranslationService.class);
81 protected static MdcDataDebugMessage mdcDataDebugMessage = new MdcDataDebugMessage();
84 * Gets types to process by translator.
86 * @return the types to process by translator
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);
96 * Translate heat files translator output.
98 * @param translationContext the translation context
99 * @return the translator output
101 public TranslatorOutput translateHeatFiles(TranslationContext translationContext) {
102 mdcDataDebugMessage.debugEntryMessage(null, null);
104 ServiceTemplate mainServiceTemplate = createMainServiceTemplate(translationContext);
105 List<FileData> fileDataList = translationContext.getManifest().getContent().getData();
106 FileDataCollection fileDataCollection = HeatToToscaUtil.getFileCollectionsByFilter(fileDataList,
107 TranslationService.getTypesToProcessByTranslator(), translationContext);
109 if (fileDataCollection.getBaseFile() != null) {
110 for (FileData fileData : fileDataCollection.getBaseFile()) {
111 translateHeatFile(mainServiceTemplate, fileData, translationContext);
114 if (fileDataCollection.getAddOnFiles() != null) {
115 for (FileData fileData : fileDataCollection.getAddOnFiles()) {
116 translateHeatFile(mainServiceTemplate, fileData, translationContext);
120 ToscaServiceModel toscaServiceModel =
121 HeatToToscaUtil.createToscaServiceModel(mainServiceTemplate, translationContext);
123 TranslatorOutput translatorOutput = new TranslatorOutput();
124 translatorOutput.setToscaServiceModel(toscaServiceModel);
126 mdcDataDebugMessage.debugExitMessage(null, null);
127 return translatorOutput;
130 private ServiceTemplate createMainServiceTemplate(TranslationContext translationContext) {
133 mdcDataDebugMessage.debugEntryMessage(null, null);
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());
145 mdcDataDebugMessage.debugExitMessage(null, null);
146 return mainServiceTemplate;
150 * Translate heat file.
152 * @param serviceTemplate the service template
153 * @param heatFileData the heat file data
154 * @param context the context
156 public void translateHeatFile(ServiceTemplate serviceTemplate, FileData heatFileData,
157 TranslationContext context) {
160 mdcDataDebugMessage.debugEntryMessage(null, null);
162 String heatFileName = heatFileData.getFile();
163 HeatOrchestrationTemplate heatOrchestrationTemplate = new YamlUtil()
164 .yamlToObject(context.getFileContent(heatFileName), HeatOrchestrationTemplate.class);
166 translateInputParameters(serviceTemplate, heatOrchestrationTemplate, heatFileData, context,
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);
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));
179 mdcDataDebugMessage.debugExitMessage(null, null);
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);
200 private void createHeatStackGroup(ServiceTemplate serviceTemplate, FileData heatFileData,
201 HeatOrchestrationTemplate heatOrchestrationTemplate,
202 TranslationContext context) {
205 mdcDataDebugMessage.debugEntryMessage(null, null);
207 ToscaFileOutputService toscaFileOutputService = new ToscaFileOutputServiceCsarImpl();
208 final String fileName = heatFileData.getFile();
209 final String heatStackGroupId = FileUtils.getFileWithoutExtention(fileName) + "_group";
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);
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
225 groupDefinition.getMembers().addAll(heatStackGroupMembers.get(fileName));
227 .addGroupDefinitionToTopologyTemplate(serviceTemplate, heatStackGroupId, groupDefinition);
229 mdcDataDebugMessage.debugExitMessage(null, null);
232 private void translateInputParameters(ServiceTemplate serviceTemplate,
233 HeatOrchestrationTemplate heatOrchestrationTemplate,
234 FileData heatFileData, TranslationContext context,
235 String heatFileName) {
238 mdcDataDebugMessage.debugEntryMessage(null, null);
240 if (heatOrchestrationTemplate.getParameters() == null) {
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));
263 Map<String, ParameterDefinition> inputs = serviceTemplate.getTopology_template().getInputs();
264 if (Objects.isNull(inputs)) {
265 serviceTemplate.getTopology_template().setInputs(parameterDefinitionMap);
267 inputs.putAll(parameterDefinitionMap);
270 mdcDataDebugMessage.debugExitMessage(null, null);
273 private void translateOutputParameters(ServiceTemplate serviceTemplate,
274 HeatOrchestrationTemplate heatOrchestrationTemplate,
275 FileData heatFileData, String heatFileName,
276 TranslationContext context) {
279 mdcDataDebugMessage.debugEntryMessage(null, null);
281 if (heatOrchestrationTemplate.getOutputs() == null) {
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);
291 serviceTemplate.getTopology_template().setOutputs(parameterDefinitionMap);
294 if (heatFileData.getBase() != null && heatFileData.getBase().equals(true)) {
295 updateSharedResources(serviceTemplate, heatFileName, heatOrchestrationTemplate,
296 heatOrchestrationTemplate.getOutputs(), context);
299 mdcDataDebugMessage.debugExitMessage(null, null);
302 private void updateSharedResources(ServiceTemplate serviceTemplate, String heatFileName,
303 HeatOrchestrationTemplate heatOrchestrationTemplate,
304 Map<String, Output> outputs, TranslationContext context) {
307 mdcDataDebugMessage.debugEntryMessage(null, null);
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()));
321 Optional<String> contrailSharedResourceId = HeatToToscaUtil
322 .extractContrailGetResourceAttachedHeatResourceId(parameter.getValue().getValue());
323 if (contrailSharedResourceId.isPresent()
324 && context.getTranslatedIds().get(heatFileName).get(contrailSharedResourceId.get())
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()));
335 if (serviceTemplate.getTopology_template().getOutputs() != null
336 && serviceTemplate.getTopology_template().getOutputs().size() == 0) {
337 serviceTemplate.getTopology_template().setOutputs(null);
340 mdcDataDebugMessage.debugExitMessage(null, null);
343 private void updateSharedResource(ServiceTemplate serviceTemplate, TranslationContext context,
344 Map.Entry<String, Output> paramName,
345 String sharedTranslatedResourceId, Resource resource) {
348 mdcDataDebugMessage.debugEntryMessage(null, null);
350 context.addHeatSharedResourcesByParam(paramName.getKey(), sharedTranslatedResourceId, resource);
351 serviceTemplate.getTopology_template().getOutputs().remove(paramName.getKey());
353 mdcDataDebugMessage.debugExitMessage(null, null);
356 private void translateResources(String heatFileName, ServiceTemplate serviceTemplate,
357 HeatOrchestrationTemplate heatOrchestrationTemplate,
358 TranslationContext context) {
361 mdcDataDebugMessage.debugEntryMessage(null, null);
363 if(MapUtils.isEmpty(heatOrchestrationTemplate.getResources())){
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());
376 ResourceTranslationFactory.getInstance(resource)
377 .translateResource(heatFileName, serviceTemplate, heatOrchestrationTemplate, resource,
378 resourceId, context);
381 mdcDataDebugMessage.debugExitMessage(null, null);
384 private Environment getHeatEnvFile(FileData heatFileData, TranslationContext context) {
385 List<FileData> fileRelatedDataList = heatFileData.getData();
386 if (fileRelatedDataList == null) {
387 return new Environment();
389 for (FileData fileRelatedData : fileRelatedDataList) {
390 if (fileRelatedData.getType().equals(FileData.Type.HEAT_ENV)) {
391 return new YamlUtil().yamlToObject(context.getFileContent(fileRelatedData.getFile()),
395 return new Environment();