2 * Copyright © 2016-2018 European Support Limited
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.openecomp.sdc.translator.services.heattotosca.impl.functiontranslation;
19 import static org.openecomp.sdc.translator.services.heattotosca.ConfigConstants.TRANS_MAPPING_DELIMITER_CHAR;
21 import org.apache.commons.lang3.StringUtils;
22 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
23 import org.openecomp.sdc.heat.datatypes.model.Resource;
24 import org.openecomp.sdc.heat.services.HeatConstants;
25 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
26 import org.onap.sdc.tosca.datatypes.model.NodeTemplate;
27 import org.onap.sdc.tosca.datatypes.model.ServiceTemplate;
28 import org.onap.sdc.tosca.datatypes.model.Template;
29 import org.onap.sdc.tosca.services.YamlUtil;
30 import org.openecomp.sdc.translator.datatypes.heattotosca.TranslationContext;
31 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslateTo;
32 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.EntityConsolidationData;
33 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.SubInterfaceTemplateConsolidationData;
34 import org.openecomp.sdc.translator.services.heattotosca.ConsolidationDataUtil;
35 import org.openecomp.sdc.translator.services.heattotosca.Constants;
36 import org.openecomp.sdc.translator.services.heattotosca.FunctionTranslation;
37 import org.openecomp.sdc.translator.services.heattotosca.FunctionTranslationFactory;
38 import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil;
39 import org.openecomp.sdc.translator.services.heattotosca.NameExtractor;
40 import org.openecomp.sdc.translator.services.heattotosca.helper.FunctionTranslationHelper;
41 import org.openecomp.sdc.translator.services.heattotosca.impl.resourcetranslation.ResourceTranslationBase;
43 import java.util.ArrayList;
44 import java.util.HashMap;
45 import java.util.HashSet;
46 import java.util.List;
48 import java.util.Optional;
50 import java.util.stream.Collectors;
52 public class FunctionTranslationGetAttrImpl implements FunctionTranslation {
56 public Object translateFunction(ServiceTemplate serviceTemplate,
57 String resourceId, String propertyName, String functionKey,
58 Object functionValue, String heatFileName,
59 HeatOrchestrationTemplate heatOrchestrationTemplate,
60 Template toscaTemplate, TranslationContext context) {
61 Object returnValue = new HashMap<>();
62 List<Object> attributeFunctionExpression =
63 translateGetAttributeFunctionExpression(serviceTemplate, resourceId, functionValue,
64 propertyName, heatFileName, heatOrchestrationTemplate, (NodeTemplate) toscaTemplate,
66 if (FunctionTranslationHelper.isResourceSupported(attributeFunctionExpression.get(0).toString())
67 && FunctionTranslationHelper.isAttributeSupported(attributeFunctionExpression.get(0)
70 .put(ToscaFunctions.GET_ATTRIBUTE.getDisplayName(), attributeFunctionExpression);
72 returnValue = attributeFunctionExpression;
78 private static List<Object> translateGetAttributeFunctionExpression(
79 ServiceTemplate serviceTemplate,
84 HeatOrchestrationTemplate heatOrchestrationTemplate,
85 NodeTemplate nodeTemplate,
86 TranslationContext context) {
88 List<Object> attributeParamList = (List) functionValue;
89 List<Object> toscaAttributeParamList = new ArrayList<>();
91 Optional<String> targetResourceTranslatedId = Optional.empty();
92 String targetResourceId = null;
93 if( attributeParamList.get(0) instanceof String) {
94 targetResourceId = (String) attributeParamList.get(0);
95 targetResourceTranslatedId =
96 handleResourceName(targetResourceId, heatFileName, heatOrchestrationTemplate,
99 if (!targetResourceTranslatedId.isPresent()) {
100 //unsupported resource
101 toscaAttributeParamList
103 FunctionTranslationHelper.getUnsupportedResourcePrefix() + attributeParamList.get(0));
104 return toscaAttributeParamList;
106 toscaAttributeParamList.add(targetResourceTranslatedId.get());
109 Optional<List<Object>> toscaAttList =
110 handleAttributeName(attributeParamList, heatOrchestrationTemplate, propertyName,
111 heatFileName, serviceTemplate,
113 if (!toscaAttList.isPresent()) {
114 //Unsupported attribute
115 toscaAttributeParamList.clear();
116 toscaAttributeParamList
117 .add(FunctionTranslationHelper.getUnsupportedAttributePrefix() + attributeParamList.get(0)
118 + "." + attributeParamList.get(1));
119 return toscaAttributeParamList;
121 toscaAttributeParamList.addAll(toscaAttList.get());
123 handleGetAttrConsolidationData(serviceTemplate, resourceId, propertyName, heatFileName,
124 heatOrchestrationTemplate, context, targetResourceId,
125 targetResourceTranslatedId,
129 Optional<List<Object>> toscaIndexOrKey = handleAttributeIndexOrKey(serviceTemplate,
130 resourceId, propertyName, HeatToToscaUtil
131 .getResourceType((String) attributeParamList.get(0), heatOrchestrationTemplate,
132 heatFileName), attributeParamList, context, heatFileName,
133 heatOrchestrationTemplate);
134 toscaIndexOrKey.ifPresent(toscaAttributeParamList::addAll);
136 return toscaAttributeParamList;
139 private static void handleGetAttrConsolidationData(
140 ServiceTemplate serviceTemplate,
141 String resourceId, String propertyName,
143 HeatOrchestrationTemplate heatOrchestrationTemplate,
144 TranslationContext context,
145 String targetResourceId,
146 Optional<String> targetResourceTranslatedId,
147 List<Object> toscaAttList) {
149 Optional<String> resourceTranslatedId = Optional.empty();
150 if (resourceId != null) {
151 resourceTranslatedId =
152 handleResourceName(resourceId, heatFileName, heatOrchestrationTemplate,
155 .ifPresent(resourceTranslatedIdValue -> handleGetAttrOutConsolidationData(serviceTemplate,
157 heatOrchestrationTemplate, context, resourceId, targetResourceTranslatedId.get(),
158 resourceTranslatedIdValue, toscaAttList, heatFileName));
161 if (targetResourceTranslatedId.isPresent()) {
162 handleGetAttrInConsolidationData(serviceTemplate, resourceId, resourceTranslatedId,
163 propertyName, heatOrchestrationTemplate, context, targetResourceId,
164 targetResourceTranslatedId.get(), toscaAttList, heatFileName);
168 private static void handleGetAttrOutConsolidationData(
169 ServiceTemplate serviceTemplate,
171 HeatOrchestrationTemplate heatOrchestrationTemplate,
172 TranslationContext context,
174 String targetTranslatedResourceId,
175 String resourceTranslatedId,
176 List<Object> toscaAttList,
177 String heatFileName) {
178 if (serviceTemplate != null) {
179 Optional<EntityConsolidationData> entityConsolidationData =
180 getEntityConsolidationData(serviceTemplate, heatOrchestrationTemplate, context,
181 resourceId, resourceTranslatedId, heatFileName);
182 if (entityConsolidationData.isPresent()) {
183 String attName = (String) toscaAttList.get(0);
184 handleNodeGetAttrOut(targetTranslatedResourceId, propertyName, heatOrchestrationTemplate,
185 context, resourceId, entityConsolidationData.get(), attName);
190 private static void handleGetAttrInConsolidationData(
191 ServiceTemplate serviceTemplate,
193 Optional<String> resourceTranslatedId,
195 HeatOrchestrationTemplate heatOrchestrationTemplate,
196 TranslationContext context,
197 String targetResourceId,
198 String targetResourceTranslatedId,
199 List<Object> toscaAttList,
200 String heatFileName) {
202 if (serviceTemplate != null) {
203 Optional<EntityConsolidationData> entityConsolidationData =
204 getEntityConsolidationData(serviceTemplate, heatOrchestrationTemplate, context,
205 targetResourceId, targetResourceTranslatedId, heatFileName);
206 if (entityConsolidationData.isPresent()) {
207 String attName = (String) toscaAttList.get(0);
208 if (resourceTranslatedId.isPresent()) {
209 handleNodeGetAttrIn(resourceTranslatedId.get(), propertyName, heatOrchestrationTemplate,
211 resourceId, entityConsolidationData.get(), attName);
213 ConsolidationDataUtil
214 .updateOutputGetAttributeInConsolidationData(entityConsolidationData.get(),
215 propertyName, attName);
221 private static void handleNodeGetAttrOut(String nodeTemplateId, String propertyName,
222 HeatOrchestrationTemplate heatOrchestrationTemplate,
223 TranslationContext context, String resourceId,
224 EntityConsolidationData entityConsolidationData,
226 Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
227 boolean isNestedResource = HeatToToscaUtil.isNestedResource(resource);
228 String toscaPropertyName = propertyName;
229 if (!isNestedResource) {
230 toscaPropertyName = HeatToToscaUtil.getToscaPropertyName(context, resource
231 .getType(), propertyName);
233 ConsolidationDataUtil
234 .updateNodeGetAttributeOut(entityConsolidationData,
235 nodeTemplateId, toscaPropertyName, attName);
238 private static void handleNodeGetAttrIn(String nodeTemplateId, String propertyName,
239 HeatOrchestrationTemplate heatOrchestrationTemplate,
240 TranslationContext context, String resourceId,
241 EntityConsolidationData entityConsolidationData,
243 Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
244 boolean isNestedResource = HeatToToscaUtil.isNestedResource(resource);
245 String heatPropertyName = propertyName;
246 String toscaPropertyName = propertyName;
247 //For handling get_attr in inner levels for complex properties
248 if (propertyName.contains(TRANS_MAPPING_DELIMITER_CHAR)) {
249 heatPropertyName = propertyName.substring(0,
250 propertyName.indexOf(TRANS_MAPPING_DELIMITER_CHAR));
252 if (!isNestedResource) {
253 toscaPropertyName = HeatToToscaUtil.getToscaPropertyName(context, resource
254 .getType(), heatPropertyName);
256 ConsolidationDataUtil
257 .updateNodeGetAttributeIn(entityConsolidationData,
258 nodeTemplateId, toscaPropertyName, attName);
261 private static Optional<EntityConsolidationData> getEntityConsolidationData(
262 ServiceTemplate serviceTemplate,
263 HeatOrchestrationTemplate heatOrchestrationTemplate,
264 TranslationContext context,
266 String resourceTranslatedId,
267 String heatFileName) {
268 Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
269 if (ConsolidationDataUtil.isComputeResource(heatOrchestrationTemplate, resourceId)) {
270 String resourceType = heatOrchestrationTemplate.getResources().get(resourceId).getType();
271 NameExtractor nodeTypeNameExtractor =
272 context.getNameExtractorImpl(resourceType);
274 nodeTypeNameExtractor.extractNodeTypeName(
275 resource, resourceId, context.getTranslatedIds().get(heatFileName).get(resourceId));
278 ConsolidationDataUtil.getComputeTemplateConsolidationData(context, serviceTemplate,
279 computeType, resourceTranslatedId));
280 } else if (ConsolidationDataUtil.isPortResource(heatOrchestrationTemplate, resourceId)) {
281 return Optional.of(ConsolidationDataUtil
282 .getPortTemplateConsolidationData(context, serviceTemplate, resourceId, resource.getType(),
283 resourceTranslatedId));
284 } else if (HeatToToscaUtil.isSubInterfaceResource(resource, context)) {
285 TranslateTo subInterfaceTo = new TranslateTo(heatFileName, serviceTemplate, heatOrchestrationTemplate,
286 resource, resourceId, resourceTranslatedId, context);
287 Optional<SubInterfaceTemplateConsolidationData> subInterfaceTemplateConsolidationData =
288 ConsolidationDataUtil.getSubInterfaceTemplateConsolidationData(subInterfaceTo, resourceTranslatedId);
289 if (subInterfaceTemplateConsolidationData.isPresent()) {
290 return Optional.of(subInterfaceTemplateConsolidationData.get());
292 } else if (HeatToToscaUtil.isNestedResource(resource)) {
293 return Optional.ofNullable(ConsolidationDataUtil
294 .getNestedTemplateConsolidationData(context, serviceTemplate, heatFileName, resourceTranslatedId));
296 return Optional.empty();
299 private static Optional<List<Object>> handleAttributeIndexOrKey(
300 ServiceTemplate serviceTemplate,
301 String resourceId, String propertyName,
303 List<Object> attributeParamList,
304 TranslationContext context,
306 HeatOrchestrationTemplate heatOrchestrationTemplate) {
308 List<Object> attributeIndexOrKey = new ArrayList<>();
309 if (attributeParamList.size() < 3) {
310 return Optional.empty();
313 Object attributeName = attributeParamList.get(1);
314 for (int i = 2; i < attributeParamList.size(); i++) {
316 if (isInteger(attributeParamList.get(i))) {
317 attributeIndexOrKey.add(attributeParamList.get(i));
318 } else if (attributeParamList.get(i) instanceof Map) {
319 attributeIndexOrKey.add(getToscaAttributeValue(serviceTemplate, resourceId,
320 propertyName, attributeParamList.get(i), resourceType, heatFileName,
321 heatOrchestrationTemplate, null, context));
324 Object toscaAttributeName = resourceType == null ? null : context
325 .getElementMapping(resourceType, Constants.ATTR,
326 getAttributeFullPath(attributeParamList, i));
327 if (toscaAttributeName == null) {
328 toscaAttributeName = attributeParamList.get(i);
330 attributeIndexOrKey.add(toscaAttributeName);
334 return Optional.of(attributeIndexOrKey);
337 private static String getAttributeFullPath(List<Object> attributeParamList, int attributeIndex) {
338 if (attributeParamList.size() < 3) {
341 StringBuilder attributeFullPath = new StringBuilder();
342 attributeFullPath.append(attributeParamList.get(1));
343 for (int j = 2; j <= attributeIndex; j++) {
344 if (isInteger(attributeParamList.get(j))) {
347 attributeFullPath.append(TRANS_MAPPING_DELIMITER_CHAR);
348 attributeFullPath.append(attributeParamList.get(j));
350 return attributeFullPath.toString();
353 private static boolean isInteger(Object inputNumber) {
354 if (inputNumber == null) {
358 if (StringUtils.isNumeric(String.valueOf(inputNumber))){
365 private static Optional<String> handleResourceName(String resourceId, String heatFileName,
366 HeatOrchestrationTemplate
367 heatOrchestrationTemplate,
368 TranslationContext context) {
369 return ResourceTranslationBase
370 .getResourceTranslatedId(heatFileName, heatOrchestrationTemplate, resourceId, context);
373 private static Optional<List<Object>> handleAttributeName(List<Object> attributeParamList,
374 HeatOrchestrationTemplate
375 heatOrchestrationTemplate,
378 ServiceTemplate serviceTemplate,
379 TranslationContext context) {
380 String resourceId = (String) attributeParamList.get(0);
382 HeatToToscaUtil.getResource(heatOrchestrationTemplate, resourceId, heatFileName);
384 if (attributeParamList.size() == 1) {
385 return getResourceTranslatedAttributesList(resource, context);
388 if (!(attributeParamList.get(1) instanceof String)) {
389 return Optional.empty();
392 if (HeatToToscaUtil.isNestedResource(resource)) {
393 return getNestedResourceTranslatedAttribute((String) attributeParamList.get(1));
395 return getResourceTranslatedAttribute(resource, (String) attributeParamList.get(1), context);
399 private static Optional<List<Object>> getNestedResourceTranslatedAttribute(String attributeName) {
400 List<Object> translatedAttributesList = new ArrayList<>();
402 if (attributeName.startsWith(HeatConstants.GET_ATTR_FROM_RESOURCE_GROUP_PREFIX)) {
403 String[] attributeSplit = attributeName.split("\\.");
404 if (attributeSplit.length == 2) {
405 translatedAttributesList.add(attributeSplit[1]);
406 } else if (attributeSplit.length == 3) {
407 translatedAttributesList.add(attributeSplit[2]);
408 translatedAttributesList.add(Integer.valueOf(attributeSplit[1]));
410 return Optional.empty();
413 translatedAttributesList.add(attributeName);
415 return Optional.of(translatedAttributesList);
418 private static Optional<List<Object>> getResourceTranslatedAttributesList(Resource resource,
421 List<Object> translatedAttributes = new ArrayList<>();
422 if (HeatToToscaUtil.isNestedResource(resource)) {
423 Optional<String> nestedFile = HeatToToscaUtil.getNestedFile(resource);
424 if (!nestedFile.isPresent()) {
425 return Optional.empty();
427 HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil()
428 .yamlToObject(context.getFiles().getFileContent(nestedFile.get()),
429 HeatOrchestrationTemplate.class);
430 translatedAttributes.addAll(nestedHeatOrchestrationTemplate.getOutputs().keySet());
431 return Optional.of(translatedAttributes);
434 Map<String, String> resourceMappingAttributes =
435 context.getElementMapping(resource.getType(), Constants.ATTR);
436 if (resourceMappingAttributes == null) {
437 return Optional.empty();
439 Set<String> mappingAttributes = new HashSet<>();
441 .addAll(resourceMappingAttributes.values().stream().collect(Collectors.toList()));
442 translatedAttributes.addAll(mappingAttributes);
443 return Optional.of(translatedAttributes);
447 private static Optional<List<Object>> getResourceTranslatedAttribute(Resource resource,
448 String attributeName,
449 TranslationContext context) {
450 List<Object> translatedAttributesList = new ArrayList<>();
451 String translatedAttribute =
452 context.getElementMapping(resource.getType(), Constants.ATTR, attributeName);
453 if (translatedAttribute != null) {
454 translatedAttributesList.add(translatedAttribute);
455 return Optional.of(translatedAttributesList);
456 } else { //unsupported attribute
457 return Optional.empty();
461 private static Object getToscaAttributeValue(ServiceTemplate serviceTemplate,
462 String resourceId, String propertyName,
463 Object attributeVal, String resourceType,
465 HeatOrchestrationTemplate heatOrchestrationTemplate,
466 Template template, TranslationContext context) {
467 if (attributeVal instanceof Map && !((Map) attributeVal).isEmpty()) {
468 Map.Entry<String, Object> functionMapEntry =
469 (Map.Entry<String, Object>) ((Map) attributeVal).entrySet().iterator().next();
470 if (FunctionTranslationFactory.getInstance(functionMapEntry.getKey()).isPresent()) {
471 return FunctionTranslationFactory.getInstance(functionMapEntry.getKey()).get()
472 .translateFunction(serviceTemplate, resourceId, propertyName,
473 functionMapEntry.getKey(), functionMapEntry
474 .getValue(), heatFileName, heatOrchestrationTemplate, template, context);
476 Map<String, Object> attrValueMap = new HashMap<>();
477 for (Map.Entry<String, Object> entry : ((Map<String, Object>) attributeVal).entrySet()) {
478 attrValueMap.put(entry.getKey(),
479 getToscaAttributeValue(serviceTemplate, resourceId, propertyName, entry.getValue(),
480 resourceType, heatFileName, heatOrchestrationTemplate, template, context));
483 } else if (attributeVal instanceof List && !((List) attributeVal).isEmpty()) {
484 List propertyValueArray = new ArrayList<>();
485 for (int i = 0; i < ((List) attributeVal).size(); i++) {
486 propertyValueArray.add(
487 getToscaAttributeValue(serviceTemplate, resourceId, propertyName,
488 ((List) attributeVal).get(i), resourceType, heatFileName,
489 heatOrchestrationTemplate, template, context));
491 return propertyValueArray;