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.FileUtils;
26 import org.openecomp.sdc.common.errors.CoreException;
27 import org.openecomp.sdc.datatypes.error.ErrorLevel;
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.logging.api.Logger;
34 import org.openecomp.sdc.logging.api.LoggerFactory;
35 import org.openecomp.sdc.logging.context.impl.MdcDataDebugMessage;
36 import org.openecomp.sdc.logging.context.impl.MdcDataErrorMessage;
37 import org.openecomp.sdc.logging.types.LoggerConstants;
38 import org.openecomp.sdc.logging.types.LoggerErrorCode;
39 import org.openecomp.sdc.logging.types.LoggerErrorDescription;
40 import org.openecomp.sdc.logging.types.LoggerTragetServiceName;
41 import org.openecomp.sdc.tosca.datatypes.ToscaGroupType;
42 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
43 import org.openecomp.sdc.tosca.datatypes.model.GroupDefinition;
44 import org.openecomp.sdc.tosca.datatypes.model.ParameterDefinition;
45 import org.openecomp.sdc.tosca.datatypes.model.PropertyType;
46 import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate;
47 import org.openecomp.sdc.tosca.datatypes.model.TopologyTemplate;
48 import org.openecomp.sdc.tosca.services.DataModelUtil;
49 import org.openecomp.sdc.tosca.services.ToscaConstants;
50 import org.openecomp.sdc.tosca.services.ToscaFileOutputService;
51 import org.openecomp.sdc.tosca.services.YamlUtil;
52 import org.openecomp.sdc.tosca.services.impl.ToscaFileOutputServiceCsarImpl;
53 import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedResourceId;
54 import org.openecomp.sdc.translator.datatypes.heattotosca.TranslationContext;
55 import org.openecomp.sdc.translator.datatypes.heattotosca.to.FileDataCollection;
56 import org.openecomp.sdc.translator.services.heattotosca.errors.ResourceNotFoundInHeatFileErrorBuilder;
57 import org.openecomp.sdc.translator.services.heattotosca.globaltypes.GlobalTypesGenerator;
58 import org.openecomp.sdc.translator.services.heattotosca.mapping.TranslatorHeatToToscaParameterConverter;
60 import java.util.ArrayList;
61 import java.util.HashMap;
62 import java.util.HashSet;
63 import java.util.List;
65 import java.util.Objects;
66 import java.util.Optional;
69 public class TranslationService {
71 protected static Logger logger = (Logger) LoggerFactory.getLogger(TranslationService.class);
72 protected static MdcDataDebugMessage mdcDataDebugMessage = new MdcDataDebugMessage();
75 * Gets types to process by translator.
77 * @return the types to process by translator
79 public static Set<FileData.Type> getTypesToProcessByTranslator() {
80 Set<FileData.Type> types = new HashSet<>();
81 types.add(FileData.Type.HEAT);
82 types.add(FileData.Type.HEAT_VOL);
87 * Translate heat files translator output.
89 * @param translationContext the translation context
90 * @return the translator output
92 public TranslatorOutput translateHeatFiles(TranslationContext translationContext) {
93 mdcDataDebugMessage.debugEntryMessage(null, null);
95 ServiceTemplate mainServiceTemplate = createMainServiceTemplate(translationContext);
96 List<FileData> fileDataList = translationContext.getManifest().getContent().getData();
97 FileDataCollection fileDataCollection = HeatToToscaUtil.getFileCollectionsByFilter(fileDataList,
98 TranslationService.getTypesToProcessByTranslator(), translationContext);
100 if (fileDataCollection.getBaseFile() != null) {
101 for (FileData fileData : fileDataCollection.getBaseFile()) {
102 translateHeatFile(mainServiceTemplate, fileData, translationContext);
105 if (fileDataCollection.getAddOnFiles() != null) {
106 for (FileData fileData : fileDataCollection.getAddOnFiles()) {
107 translateHeatFile(mainServiceTemplate, fileData, translationContext);
111 ToscaServiceModel toscaServiceModel =
112 HeatToToscaUtil.createToscaServiceModel(mainServiceTemplate, translationContext);
114 TranslatorOutput translatorOutput = new TranslatorOutput();
115 //Keeping a copy of tosca service model after first stage of translation for extraction of
117 translatorOutput.setNonUnifiedToscaServiceModel(
118 ToscaServiceModel.getClonedServiceModel(toscaServiceModel));
119 translatorOutput.setToscaServiceModel(toscaServiceModel);
121 mdcDataDebugMessage.debugExitMessage(null, null);
122 return translatorOutput;
125 private ServiceTemplate createMainServiceTemplate(TranslationContext translationContext) {
128 mdcDataDebugMessage.debugEntryMessage(null, null);
130 ServiceTemplate mainServiceTemplate = new ServiceTemplate();
131 translationContext.getTranslatedServiceTemplates()
132 .put(Constants.MAIN_TEMPLATE_NAME, mainServiceTemplate);
133 Map<String, String> templateMetadata = new HashMap<>();
134 templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, Constants.MAIN_TEMPLATE_NAME);
135 mainServiceTemplate.setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
136 mainServiceTemplate.setMetadata(templateMetadata);
137 mainServiceTemplate.setTopology_template(new TopologyTemplate());
138 mainServiceTemplate.setImports(GlobalTypesGenerator.getGlobalTypesImportList());
140 mdcDataDebugMessage.debugExitMessage(null, null);
141 return mainServiceTemplate;
145 * Translate heat file.
147 * @param serviceTemplate the service template
148 * @param heatFileData the heat file data
149 * @param context the context
151 public void translateHeatFile(ServiceTemplate serviceTemplate, FileData heatFileData,
152 TranslationContext context) {
155 mdcDataDebugMessage.debugEntryMessage(null, null);
157 String heatFileName = heatFileData.getFile();
158 HeatOrchestrationTemplate heatOrchestrationTemplate = new YamlUtil()
159 .yamlToObject(context.getFileContent(heatFileName), HeatOrchestrationTemplate.class);
161 translateInputParameters(serviceTemplate, heatOrchestrationTemplate, heatFileData, context,
163 translateResources(heatFileName, serviceTemplate, heatOrchestrationTemplate, context);
164 translateOutputParameters(serviceTemplate, heatOrchestrationTemplate, heatFileData,
165 heatFileName, context);
166 createHeatStackGroup(serviceTemplate, heatFileData, heatOrchestrationTemplate, context);
167 handleHeatPseudoParam(heatFileName, serviceTemplate, context);
169 if (Objects.nonNull(heatFileData.getData())) {
170 heatFileData.getData().stream().filter(data -> data.getType() == FileData.Type.HEAT_VOL)
171 .forEach(data -> translateHeatFile(serviceTemplate, data, context));
174 mdcDataDebugMessage.debugExitMessage(null, null);
177 private void handleHeatPseudoParam(String heatFileName, ServiceTemplate serviceTemplate,
178 TranslationContext context) {
179 Map<String, String> translatedHeatPseudoParam =
180 context.getUsedHeatPseudoParams().get(heatFileName);
181 if (Objects.nonNull(translatedHeatPseudoParam)) {
182 for (String heatPseudoParam : translatedHeatPseudoParam.keySet()) {
183 if (!serviceTemplate.getTopology_template().getInputs().containsKey(heatPseudoParam)) {
184 ParameterDefinition parameterDefinition = new ParameterDefinition();
185 parameterDefinition.setType(PropertyType.STRING.getDisplayName());
186 parameterDefinition.setRequired(false);
187 String parameterDefinitionId = translatedHeatPseudoParam.get(heatPseudoParam);
188 DataModelUtil.addInputParameterToTopologyTemplate(serviceTemplate, parameterDefinitionId,
189 parameterDefinition);
195 private void createHeatStackGroup(ServiceTemplate serviceTemplate, FileData heatFileData,
196 HeatOrchestrationTemplate heatOrchestrationTemplate,
197 TranslationContext context) {
200 mdcDataDebugMessage.debugEntryMessage(null, null);
202 ToscaFileOutputService toscaFileOutputService = new ToscaFileOutputServiceCsarImpl();
203 final String fileName = heatFileData.getFile();
204 final String heatStackGroupId = FileUtils.getFileWithoutExtention(fileName) + "_group";
206 GroupDefinition groupDefinition = new GroupDefinition();
207 groupDefinition.setType(ToscaGroupType.HEAT_STACK);
208 groupDefinition.setProperties(new HashMap<>());
209 groupDefinition.getProperties()
210 .put("heat_file", "../" + toscaFileOutputService.getArtifactsFolderName() + "/" + fileName);
211 String hotDescription = heatOrchestrationTemplate.getDescription();
212 if (hotDescription != null && !hotDescription.isEmpty()) {
213 groupDefinition.getProperties().put(Constants.DESCRIPTION_PROPERTY_NAME, hotDescription);
215 groupDefinition.setMembers(new ArrayList<>());
216 Map<String, Set<String>> heatStackGroupMembers = context.getHeatStackGroupMembers();
217 if (heatStackGroupMembers.get(fileName) == null) {
218 return; //not creating a group when no resources are present in the heat input
220 groupDefinition.getMembers().addAll(heatStackGroupMembers.get(fileName));
222 .addGroupDefinitionToTopologyTemplate(serviceTemplate, heatStackGroupId, groupDefinition);
224 mdcDataDebugMessage.debugExitMessage(null, null);
227 private void translateInputParameters(ServiceTemplate serviceTemplate,
228 HeatOrchestrationTemplate heatOrchestrationTemplate,
229 FileData heatFileData, TranslationContext context,
230 String heatFileName) {
233 mdcDataDebugMessage.debugEntryMessage(null, null);
235 if (heatOrchestrationTemplate.getParameters() == null) {
239 Map<String, ParameterDefinition> parameterDefinitionMap =
240 TranslatorHeatToToscaParameterConverter
241 .parameterConverter(serviceTemplate,heatOrchestrationTemplate.getParameters(),
242 heatOrchestrationTemplate, heatFileName, context);
243 Environment heatEnvFile = getHeatEnvFile(heatFileData, context);
244 Map<String, Object> parameters = heatEnvFile.getParameters();
245 Object parameterValue;
246 if (parameters != null) {
247 for (Map.Entry<String, ParameterDefinition> entry : parameterDefinitionMap.entrySet()) {
248 String paramName = entry.getKey();
249 parameterValue = parameters.get(paramName);
250 if (parameterValue != null) {
251 entry.getValue().set_default(TranslatorHeatToToscaParameterConverter
252 .getToscaParameterDefaultValue(null, null, parameterValue, entry.getValue().getType(),
253 heatFileName, heatOrchestrationTemplate, context));
258 Map<String, ParameterDefinition> inputs = serviceTemplate.getTopology_template().getInputs();
259 if (Objects.isNull(inputs)) {
260 serviceTemplate.getTopology_template().setInputs(parameterDefinitionMap);
262 inputs.putAll(parameterDefinitionMap);
265 mdcDataDebugMessage.debugExitMessage(null, null);
268 private void translateOutputParameters(ServiceTemplate serviceTemplate,
269 HeatOrchestrationTemplate heatOrchestrationTemplate,
270 FileData heatFileData, String heatFileName,
271 TranslationContext context) {
274 mdcDataDebugMessage.debugEntryMessage(null, null);
276 if (heatOrchestrationTemplate.getOutputs() == null) {
279 Map<String, ParameterDefinition> parameterDefinitionMap =
280 TranslatorHeatToToscaParameterConverter
281 .parameterOutputConverter(serviceTemplate,heatOrchestrationTemplate.getOutputs(),
282 heatOrchestrationTemplate, heatFileName, context);
283 if (serviceTemplate.getTopology_template().getOutputs() != null) {
284 serviceTemplate.getTopology_template().getOutputs().putAll(parameterDefinitionMap);
286 serviceTemplate.getTopology_template().setOutputs(parameterDefinitionMap);
289 if (heatFileData.getBase() != null && heatFileData.getBase().equals(true)) {
290 updateSharedResources(serviceTemplate, heatFileName, heatOrchestrationTemplate,
291 heatOrchestrationTemplate.getOutputs(), context);
294 mdcDataDebugMessage.debugExitMessage(null, null);
297 private void updateSharedResources(ServiceTemplate serviceTemplate, String heatFileName,
298 HeatOrchestrationTemplate heatOrchestrationTemplate,
299 Map<String, Output> outputs, TranslationContext context) {
302 mdcDataDebugMessage.debugEntryMessage(null, null);
304 for (Map.Entry<String, Output> parameter : outputs.entrySet()) {
305 Optional<AttachedResourceId> attachedSharedResourceId = HeatToToscaUtil
306 .extractAttachedResourceId(heatFileName, heatOrchestrationTemplate, context,
307 parameter.getValue().getValue());
308 if (attachedSharedResourceId.isPresent() && attachedSharedResourceId.get().isGetResource()
309 && attachedSharedResourceId.get().getTranslatedId() != null) {
310 String sharedTranslatedResourceId =
311 attachedSharedResourceId.get().getTranslatedId().toString();
312 updateSharedResource(serviceTemplate, context, parameter, sharedTranslatedResourceId,
313 heatOrchestrationTemplate.getResources()
314 .get(attachedSharedResourceId.get().getEntityId()));
316 Optional<String> contrailSharedResourceId = HeatToToscaUtil
317 .extractContrailGetResourceAttachedHeatResourceId(parameter.getValue().getValue());
318 if (contrailSharedResourceId.isPresent()
319 && context.getTranslatedIds().get(heatFileName).get(contrailSharedResourceId.get())
321 String sharedTranslatedResourceId = context.getTranslatedIds().get(heatFileName).get
322 (contrailSharedResourceId.get());
323 ConsolidationDataUtil.removeSharedResource(serviceTemplate, heatOrchestrationTemplate,
324 context, parameter.getKey(),contrailSharedResourceId.get(), sharedTranslatedResourceId);
325 updateSharedResource(serviceTemplate, context, parameter,sharedTranslatedResourceId,
326 heatOrchestrationTemplate.getResources().get(contrailSharedResourceId.get()));
330 if (serviceTemplate.getTopology_template().getOutputs() != null
331 && serviceTemplate.getTopology_template().getOutputs().size() == 0) {
332 serviceTemplate.getTopology_template().setOutputs(null);
335 mdcDataDebugMessage.debugExitMessage(null, null);
338 private void updateSharedResource(ServiceTemplate serviceTemplate, TranslationContext context,
339 Map.Entry<String, Output> paramName,
340 String sharedTranslatedResourceId, Resource resource) {
343 mdcDataDebugMessage.debugEntryMessage(null, null);
345 context.addHeatSharedResourcesByParam(paramName.getKey(), sharedTranslatedResourceId, resource);
346 serviceTemplate.getTopology_template().getOutputs().remove(paramName.getKey());
348 mdcDataDebugMessage.debugExitMessage(null, null);
351 private void translateResources(String heatFileName, ServiceTemplate serviceTemplate,
352 HeatOrchestrationTemplate heatOrchestrationTemplate,
353 TranslationContext context) {
356 mdcDataDebugMessage.debugEntryMessage(null, null);
358 if(MapUtils.isEmpty(heatOrchestrationTemplate.getResources())){
362 for (String resourceId : heatOrchestrationTemplate.getResources().keySet()) {
363 Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
364 if (resource == null) {
365 MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
366 LoggerTragetServiceName.TRANSLATE_RESOURCE, ErrorLevel.ERROR.name(),
367 LoggerErrorCode.DATA_ERROR.getErrorCode(), LoggerErrorDescription.TRANSLATE_HEAT);
368 throw new CoreException(
369 new ResourceNotFoundInHeatFileErrorBuilder(resourceId, heatFileName).build());
371 ResourceTranslationFactory.getInstance(resource)
372 .translateResource(heatFileName, serviceTemplate, heatOrchestrationTemplate, resource,
373 resourceId, context);
376 mdcDataDebugMessage.debugExitMessage(null, null);
379 private Environment getHeatEnvFile(FileData heatFileData, TranslationContext context) {
380 List<FileData> fileRelatedDataList = heatFileData.getData();
381 if (fileRelatedDataList == null) {
382 return new Environment();
384 for (FileData fileRelatedData : fileRelatedDataList) {
385 if (fileRelatedData.getType().equals(FileData.Type.HEAT_ENV)) {
386 return new YamlUtil().yamlToObject(context.getFileContent(fileRelatedData.getFile()),
390 return new Environment();