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.CollectionUtils;
24 import org.openecomp.core.utilities.yaml.YamlUtil;
25 import org.openecomp.sdc.common.errors.CoreException;
26 import org.openecomp.sdc.heat.datatypes.HeatBoolean;
27 import org.openecomp.sdc.heat.datatypes.manifest.FileData;
28 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
29 import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
30 import org.openecomp.sdc.heat.datatypes.model.Resource;
31 import org.openecomp.sdc.heat.services.HeatConstants;
32 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
33 import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
34 import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate;
35 import org.openecomp.sdc.tosca.services.ToscaUtil;
36 import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedResourceId;
37 import org.openecomp.sdc.translator.datatypes.heattotosca.ResourceReferenceType;
38 import org.openecomp.sdc.translator.datatypes.heattotosca.to.FileDataCollection;
39 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslateTo;
40 import org.openecomp.sdc.translator.services.heattotosca.errors.ResourceNotFoundInHeatFileErrorBuilder;
41 import org.openecomp.sdc.translator.services.heattotosca.mapping.TranslatorHeatToToscaFunctionConverter;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
45 import java.util.ArrayList;
46 import java.util.Collection;
47 import java.util.HashMap;
48 import java.util.HashSet;
49 import java.util.List;
51 import java.util.Objects;
52 import java.util.Optional;
54 import java.util.stream.Collectors;
56 public class HeatToToscaUtil {
58 protected static Logger logger = LoggerFactory.getLogger(HeatToToscaUtil.class);
62 * Build list of files to search optional.
64 * @param heatFileName the heat file name
65 * @param filesDataList the files data list
66 * @param types the types
67 * @return the optional
69 public static Optional<List<FileData>> buildListOfFilesToSearch(String heatFileName,
70 List<FileData> filesDataList,
71 FileData.Type... types) {
72 List<FileData> list = new ArrayList<>(filesDataList);
73 Optional<FileData> resourceFileData = HeatToToscaUtil.getFileData(heatFileName, filesDataList);
74 if (resourceFileData.isPresent() && Objects.nonNull(resourceFileData.get().getData())) {
75 list.addAll(resourceFileData.get().getData());
77 return Optional.ofNullable(HeatToToscaUtil.getFilteredListOfFileDataByTypes(list, types));
80 public static List<FileData> getFilteredListOfFileDataByTypes(List<FileData> filesToSearch,
81 FileData.Type... types) {
82 return filesToSearch.stream().filter(FileData.buildFileDataPredicateByType(types))
83 .collect(Collectors.toList());
89 * @param heatFileName the heat file name
90 * @param fileDataList the file data list
91 * @return the file data
93 public static Optional<FileData> getFileData(String heatFileName,
94 Collection<FileData> fileDataList) {
95 for (FileData file : fileDataList) {
96 if (file.getFile().equals(heatFileName)) {
97 return Optional.of(file);
100 return Optional.empty();
103 static FileDataCollection getFileCollectionsByFilter(List<FileData> fileDataList,
104 Set<FileData.Type> typeFilter,
105 TranslationContext translationContext) {
106 FileDataCollection fileDataCollection = new FileDataCollection();
107 Map<String, FileData> filteredFiles = filterFileDataListByType(fileDataList, typeFilter);
108 Set<String> referenced = new HashSet<>();
109 List<String> filenames = extractFilenamesFromFileDataList(filteredFiles.values());
111 for (FileData fileData : filteredFiles.values()) {
112 String fileName = fileData.getFile();
114 if (FileData.isHeatFile(fileData.getType())) {
115 if (fileData.getBase() != null && fileData.getBase().equals(true)) {
116 fileDataCollection.addBaseFiles(fileData);
118 HeatOrchestrationTemplate heatOrchestrationTemplate = new YamlUtil()
119 .yamlToObject(translationContext.getFileContent(fileName),
120 HeatOrchestrationTemplate.class);
121 for (Resource resource : heatOrchestrationTemplate.getResources().values()) {
122 if (filenames.contains(resource.getType())) {
123 handleNestedFile(translationContext, fileDataCollection, filteredFiles, referenced,
125 } else if (resource.getType()
126 .equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
128 resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
129 Object innerTypeDef = ((Map) resourceDef).get("type");
130 if (innerTypeDef instanceof String) {
131 String internalResourceType = (String) innerTypeDef;
132 if (filenames.contains(internalResourceType)) {
133 handleNestedFile(translationContext, fileDataCollection, filteredFiles, referenced,
134 internalResourceType);
141 fileDataCollection.addArtifactFiles(fileData);
142 filteredFiles.remove(fileData.getFile());
146 referenced.forEach(filteredFiles::remove);
147 if (!CollectionUtils.isEmpty(fileDataCollection.getBaseFile())) {
148 for (FileData fileData : fileDataCollection.getBaseFile()) {
149 filteredFiles.remove(fileData.getFile());
152 fileDataCollection.setAddOnFiles(filteredFiles.values());
153 return fileDataCollection;
156 private static void handleNestedFile(TranslationContext translationContext,
157 FileDataCollection fileDataCollection,
158 Map<String, FileData> filteredFiles, Set<String> referenced,
159 String nestedFileName) {
160 referenced.add(nestedFileName);
161 fileDataCollection.addNestedFiles(filteredFiles.get(nestedFileName));
162 translationContext.getNestedHeatsFiles().add(nestedFileName);
165 private static Map<String, FileData> filterFileDataListByType(List<FileData> fileDataList,
166 Set<FileData.Type> typesToGet) {
167 Map<String, FileData> filtered = new HashMap<>();
168 fileDataList.stream().filter(file -> typesToGet.contains(file.getType()))
169 .forEach(file -> filtered.put(file.getFile(), file));
173 private static List<String> extractFilenamesFromFileDataList(Collection<FileData> fileDataList) {
174 return fileDataList.stream().map(FileData::getFile).collect(Collectors.toList());
178 * Extract attached resource id optional.
180 * @param translateTo the translate to
181 * @param propertyName the property name
182 * @return the optional
184 public static Optional<AttachedResourceId> extractAttachedResourceId(TranslateTo translateTo,
185 String propertyName) {
186 Object propertyValue = translateTo.getResource().getProperties().get(propertyName);
187 if (propertyValue == null) {
188 return Optional.empty();
190 return extractAttachedResourceId(translateTo.getHeatFileName(),
191 translateTo.getHeatOrchestrationTemplate(), translateTo.getContext(), propertyValue);
195 * Extract attached resource id optional.
197 * @param heatFileName the heat file name
198 * @param heatOrchestrationTemplate the heat orchestration template
199 * @param context the context
200 * @param propertyValue the property value
201 * @return the optional
203 public static Optional<AttachedResourceId> extractAttachedResourceId(String heatFileName,
204 HeatOrchestrationTemplate heatOrchestrationTemplate,
205 TranslationContext context,
206 Object propertyValue) {
211 if (Objects.isNull(propertyValue)) {
212 return Optional.empty();
215 ResourceReferenceType referenceType = ResourceReferenceType.OTHER;
216 if (propertyValue instanceof Map && !((Map) propertyValue).isEmpty()) {
217 Map<String, Object> propMap = (Map) propertyValue;
218 Map.Entry<String, Object> entry = propMap.entrySet().iterator().next();
219 entity = entry.getValue();
220 String key = entry.getKey();
223 referenceType = ResourceReferenceType.GET_RESOURCE;
226 referenceType = ResourceReferenceType.GET_PARAM;
229 referenceType = ResourceReferenceType.GET_ATTR;
233 translatedId = TranslatorHeatToToscaFunctionConverter
234 .getToscaFunction(entry.getKey(), entry.getValue(), heatFileName,
235 heatOrchestrationTemplate, null, context);
236 if (translatedId instanceof String
237 && !TranslatorHeatToToscaFunctionConverter.isResourceSupported((String) translatedId)) {
242 translatedId = propertyValue;
243 entity = propertyValue;
246 return Optional.of(new AttachedResourceId(translatedId, entity, referenceType));
250 * Gets contrail attached heat resource id.
252 * @param attachedResource the attached resource
253 * @return the contrail attached heat resource id
255 public static Optional<String> getContrailAttachedHeatResourceId(
256 AttachedResourceId attachedResource) {
257 if (attachedResource == null) {
258 return Optional.empty();
261 if (attachedResource.isGetResource()) {
262 return Optional.of((String) attachedResource.getEntityId());
264 if (attachedResource.isGetAttr() && (attachedResource.getEntityId() instanceof List)
265 && ((List) attachedResource.getEntityId()).size() > 1
266 && ((List) attachedResource.getEntityId()).get(1).equals("fq_name")) {
267 return Optional.of((String) ((List) attachedResource.getEntityId()).get(0));
270 return Optional.empty();
274 * Extract property optional.
276 * @param propertyValue the property value
277 * @return the optional
279 public static Optional<AttachedResourceId> extractProperty(Object propertyValue) {
282 if (Objects.isNull(propertyValue)) {
283 return Optional.empty();
286 ResourceReferenceType referenceType = ResourceReferenceType.OTHER;
287 if (propertyValue instanceof Map && !((Map) propertyValue).isEmpty()) {
288 Map<String, Object> propMap = (Map) propertyValue;
289 Map.Entry<String, Object> entry = propMap.entrySet().iterator().next();
290 entity = entry.getValue();
291 String key = entry.getKey();
294 referenceType = ResourceReferenceType.GET_RESOURCE;
297 referenceType = ResourceReferenceType.GET_PARAM;
300 referenceType = ResourceReferenceType.GET_ATTR;
306 entity = propertyValue;
309 return Optional.of(new AttachedResourceId(null, entity, referenceType));
315 * @param nodeTemplate the node template
316 * @param propertyKey the property key
318 public static void mapBoolean(NodeTemplate nodeTemplate, String propertyKey) {
319 Object value = nodeTemplate.getProperties().get(propertyKey);
320 if (value != null && !(value instanceof Map)) {
321 nodeTemplate.getProperties().put(propertyKey, HeatBoolean.eval(value));
328 * @param nodeTemplate the node template
329 * @param propertyListKey the property list key
331 public static void mapBooleanList(NodeTemplate nodeTemplate, String propertyListKey) {
332 Object listValue = nodeTemplate.getProperties().get(propertyListKey);
333 if (listValue instanceof List) {
334 List booleanList = ((List) listValue);
335 for (int i = 0; i < booleanList.size(); i++) {
336 Object value = booleanList.get(i);
337 if (value != null && !(value instanceof Map)) {
338 booleanList.set(i, HeatBoolean.eval(value));
345 public static boolean isYmlFileType(String filename) {
346 return (filename.indexOf("yaml") > 0 || filename.indexOf("yml") > 0);
350 * Is nested resource boolean.
352 * @param resource the resource
353 * @return the boolean
355 public static boolean isNestedResource(Resource resource) {
356 String resourceType = resource.getType();
358 if (resourceType.equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
359 Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
360 String internalResourceType = (String) ((Map) resourceDef).get("type");
361 if (isYamlFile(internalResourceType)) {
364 } else if (isYamlFile(resourceType)) {
373 * @param resource the resource
374 * @return the nested file
376 public static Optional<String> getNestedFile(Resource resource) {
377 if (!isNestedResource(resource)) {
378 return Optional.empty();
380 String resourceType = resource.getType();
381 if (resourceType.equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
382 Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
383 String internalResourceType = (String) ((Map) resourceDef).get("type");
384 return Optional.of(internalResourceType);
386 return Optional.of(resourceType);
390 private static boolean isYamlFile(String fileName) {
391 return fileName.endsWith(".yaml") || fileName.endsWith(".yml");
397 * @param heatOrchestrationTemplate the heat orchestration template
398 * @param resourceId the resource id
399 * @param heatFileName the heat file name
400 * @return the resource
402 public static Resource getResource(HeatOrchestrationTemplate heatOrchestrationTemplate,
403 String resourceId, String heatFileName) {
404 Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
405 if (resource == null) {
406 throw new CoreException(
407 new ResourceNotFoundInHeatFileErrorBuilder(resourceId, heatFileName).build());
412 public static boolean isHeatFileNested(TranslateTo translateTo, String heatFileName) {
413 return translateTo.getContext().getNestedHeatsFiles().contains(heatFileName);
417 * Extract contrail get resource attached heat resource id string.
419 * @param propertyValue the property value
422 public static String extractContrailGetResourceAttachedHeatResourceId(Object propertyValue) {
423 if (propertyValue == null) {
428 if (propertyValue instanceof Map) {
429 if (((Map) propertyValue).containsKey("get_attr")) {
430 value = ((Map) propertyValue).get("get_attr");
431 if (value instanceof List) {
432 if (((List) value).size() == 2 && ((List) value).get(1).equals("fq_name")) {
433 if (((List) value).get(0) instanceof String) {
434 return (String) ((List) value).get(0);
436 logger.warn("invalid format of 'get_attr' function - " + propertyValue.toString());
440 } else if (((Map) propertyValue).containsKey("get_resource")) {
441 value = ((Map) propertyValue).get("get_resource");
442 if (value instanceof String) {
443 return (String) value;
445 logger.warn("invalid format of 'get_resource' function - " + propertyValue.toString());
448 Collection<Object> valCollection = ((Map) propertyValue).values();
449 for (Object entryValue : valCollection) {
450 String ret = extractContrailGetResourceAttachedHeatResourceId(entryValue);
457 } else if (propertyValue instanceof List) {
458 for (Object prop : (List) propertyValue) {
459 String ret = extractContrailGetResourceAttachedHeatResourceId(prop);
469 * Gets tosca service model.
471 * @param translateTo the translate to
472 * @return the tosca service model
474 public static ToscaServiceModel getToscaServiceModel(TranslateTo translateTo) {
475 Map<String, ServiceTemplate> serviceTemplates =
476 new HashMap<>(translateTo.getContext().getGlobalServiceTemplates());
477 Collection<ServiceTemplate> tmpServiceTemplates =
478 translateTo.getContext().getTranslatedServiceTemplates().values();
479 for (ServiceTemplate serviceTemplate : tmpServiceTemplates) {
480 ToscaUtil.addServiceTemplateToMapWithKeyFileName(serviceTemplates, serviceTemplate);
482 return new ToscaServiceModel(null, serviceTemplates,
483 ToscaUtil.getServiceTemplateFileName(translateTo.getResource().getType()));
487 * Gets service template from context.
489 * @param serviceTemplateFileName the service template file name
490 * @param context the context
491 * @return the service template from context
493 public static Optional<ServiceTemplate> getServiceTemplateFromContext(
494 String serviceTemplateFileName, TranslationContext context) {
495 for (ServiceTemplate serviceTemplate : context.getTranslatedServiceTemplates().values()) {
496 if (ToscaUtil.getServiceTemplateFileName(serviceTemplate).equals(serviceTemplateFileName)) {
497 return Optional.of(serviceTemplate);
501 return Optional.empty();