[SDC] Onboarding 1710 rebase.
[sdc.git] / openecomp-be / lib / openecomp-sdc-translator-lib / openecomp-sdc-translator-core / src / main / java / org / openecomp / sdc / translator / services / heattotosca / impl / functiontranslation / FunctionTranslationGetAttrImpl.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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=========================================================
19  */
20
21 package org.openecomp.sdc.translator.services.heattotosca.impl.functiontranslation;
22
23 import org.openecomp.sdc.tosca.services.YamlUtil;
24 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
25 import org.openecomp.sdc.heat.datatypes.model.Resource;
26 import org.openecomp.sdc.heat.services.HeatConstants;
27 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
28 import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
29 import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate;
30 import org.openecomp.sdc.tosca.datatypes.model.Template;
31 import org.openecomp.sdc.translator.datatypes.heattotosca.TranslationContext;
32 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.EntityConsolidationData;
33 import org.openecomp.sdc.translator.services.heattotosca.ConfigConstants;
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;
42
43 import java.util.ArrayList;
44 import java.util.HashMap;
45 import java.util.HashSet;
46 import java.util.List;
47 import java.util.Map;
48 import java.util.Optional;
49 import java.util.Set;
50 import java.util.stream.Collectors;
51
52 public class FunctionTranslationGetAttrImpl implements FunctionTranslation {
53
54
55   @Override
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,
65             context);
66     if (FunctionTranslationHelper.isResourceSupported(attributeFunctionExpression.get(0).toString())
67         && FunctionTranslationHelper.isAttributeSupported(attributeFunctionExpression.get(0)
68         .toString())) {
69       ((Map) returnValue)
70           .put(ToscaFunctions.GET_ATTRIBUTE.getDisplayName(), attributeFunctionExpression);
71     } else {
72       returnValue = attributeFunctionExpression;
73     }
74
75     return returnValue;
76   }
77
78   private static List<Object> translateGetAttributeFunctionExpression(
79       ServiceTemplate serviceTemplate,
80       String resourceId,
81       Object functionValue,
82       String propertyName,
83       String heatFileName,
84       HeatOrchestrationTemplate heatOrchestrationTemplate,
85       NodeTemplate nodeTemplate,
86       TranslationContext context) {
87
88     List<Object> attributeParamList = (List) functionValue;
89     List<Object> toscaAttributeParamList = new ArrayList<>();
90
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,
97               context);
98     }
99     if (!targetResourceTranslatedId.isPresent()) {
100       //unsupported resource
101       toscaAttributeParamList
102           .add(
103               FunctionTranslationHelper.getUnsupportedResourcePrefix() + attributeParamList.get(0));
104       return toscaAttributeParamList;
105     } else {
106       toscaAttributeParamList.add(targetResourceTranslatedId.get());
107     }
108
109     Optional<List<Object>> toscaAttList =
110         handleAttributeName(attributeParamList, heatOrchestrationTemplate, propertyName,
111             heatFileName, serviceTemplate,
112             context);
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;
120     } else {
121       toscaAttributeParamList.addAll(toscaAttList.get());
122
123       handleGetAttrConsolidationData(serviceTemplate, resourceId, propertyName, heatFileName,
124           heatOrchestrationTemplate, context, targetResourceId,
125           targetResourceTranslatedId,
126           toscaAttList.get());
127     }
128
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);
135
136     return toscaAttributeParamList;
137   }
138
139   private static void handleGetAttrConsolidationData(
140       ServiceTemplate serviceTemplate,
141       String resourceId, String propertyName,
142       String heatFileName,
143       HeatOrchestrationTemplate heatOrchestrationTemplate,
144       TranslationContext context,
145       String targetResourceId,
146       Optional<String> targetResourceTranslatedId,
147       List<Object> toscaAttList) {
148
149     Optional<String> resourceTranslatedId = Optional.empty();
150     if (resourceId != null) {
151       resourceTranslatedId =
152           handleResourceName(resourceId, heatFileName, heatOrchestrationTemplate,
153               context);
154       resourceTranslatedId
155           .ifPresent(resourceTranslatedIdValue -> handleGetAttrOutConsolidationData(serviceTemplate,
156               propertyName,
157               heatOrchestrationTemplate, context, resourceId, targetResourceTranslatedId.get(),
158               resourceTranslatedIdValue, toscaAttList, heatFileName));
159     }
160
161     if (targetResourceTranslatedId.isPresent()) {
162       handleGetAttrInConsolidationData(serviceTemplate, resourceId, resourceTranslatedId,
163           propertyName, heatOrchestrationTemplate, context, targetResourceId,
164           targetResourceTranslatedId.get(), toscaAttList, heatFileName);
165     }
166   }
167
168   private static void handleGetAttrOutConsolidationData(
169       ServiceTemplate serviceTemplate,
170       String propertyName,
171       HeatOrchestrationTemplate heatOrchestrationTemplate,
172       TranslationContext context,
173       String resourceId,
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);
186       }
187     }
188   }
189
190   private static void handleGetAttrInConsolidationData(
191       ServiceTemplate serviceTemplate,
192       String resourceId,
193       Optional<String> resourceTranslatedId,
194       String propertyName,
195       HeatOrchestrationTemplate heatOrchestrationTemplate,
196       TranslationContext context,
197       String targetResourceId,
198       String targetResourceTranslatedId,
199       List<Object> toscaAttList,
200       String  heatFileName) {
201
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,
210               context,
211               resourceId, entityConsolidationData.get(), attName);
212         } else {
213           ConsolidationDataUtil
214               .updateOutputGetAttributeInConsolidationData(entityConsolidationData.get(),
215                   propertyName, attName);
216         }
217       }
218     }
219   }
220
221   private static void handleNodeGetAttrOut(String nodeTemplateId, String propertyName,
222                                            HeatOrchestrationTemplate heatOrchestrationTemplate,
223                                            TranslationContext context, String resourceId,
224                                            EntityConsolidationData entityConsolidationData,
225                                            String attName) {
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);
232     }
233     ConsolidationDataUtil
234         .updateNodeGetAttributeOut(entityConsolidationData,
235             nodeTemplateId, toscaPropertyName, attName);
236   }
237
238   private static void handleNodeGetAttrIn(String nodeTemplateId, String propertyName,
239                                           HeatOrchestrationTemplate heatOrchestrationTemplate,
240                                           TranslationContext context, String resourceId,
241                                           EntityConsolidationData entityConsolidationData,
242                                           String attName) {
243     Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
244     boolean isNestedResource = HeatToToscaUtil.isNestedResource(resource);
245     String toscaPropertyName = propertyName;
246     if (!isNestedResource) {
247       toscaPropertyName = HeatToToscaUtil.getToscaPropertyName(context, resource
248           .getType(), propertyName);
249     }
250     ConsolidationDataUtil
251         .updateNodeGetAttributeIn(entityConsolidationData,
252             nodeTemplateId, toscaPropertyName, attName);
253   }
254
255   private static Optional<EntityConsolidationData> getEntityConsolidationData(
256       ServiceTemplate serviceTemplate,
257       HeatOrchestrationTemplate heatOrchestrationTemplate,
258       TranslationContext context,
259       String resourceId,
260       String resourceTranslatedId,
261       String heatFileName) {
262     Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
263     if (ConsolidationDataUtil.isComputeResource(heatOrchestrationTemplate, resourceId)) {
264       String resourceType = heatOrchestrationTemplate.getResources().get(resourceId).getType();
265       NameExtractor nodeTypeNameExtractor =
266           context.getNameExtractorImpl(resourceType);
267       String computeType =
268           nodeTypeNameExtractor.extractNodeTypeName(
269               resource, resourceId, context.getTranslatedIds().get(heatFileName).get(resourceId));
270
271       return Optional.of(
272           ConsolidationDataUtil.getComputeTemplateConsolidationData(context, serviceTemplate,
273               computeType, resourceId));
274     } else if (ConsolidationDataUtil.isPortResource(heatOrchestrationTemplate, resourceId)) {
275       return Optional.of(ConsolidationDataUtil
276           .getPortTemplateConsolidationData(context, serviceTemplate, resourceId));
277     } else if (HeatToToscaUtil.isNestedResource(resource)) {
278       return Optional.of(ConsolidationDataUtil
279           .getNestedTemplateConsolidationData(context, serviceTemplate, heatFileName, resourceId));
280     }
281     return Optional.empty();
282   }
283
284   private static Optional<List<Object>> handleAttributeIndexOrKey(
285       ServiceTemplate serviceTemplate,
286       String resourceId, String propertyName,
287       String resourceType,
288       List<Object> attributeParamList,
289       TranslationContext context,
290       String heatFileName,
291       HeatOrchestrationTemplate heatOrchestrationTemplate) {
292
293     List<Object> attributeIndexOrKey = new ArrayList<>();
294     if (attributeParamList.size() < 3) {
295       return Optional.empty();
296     }
297
298     Object attributeName = attributeParamList.get(1);
299     for (int i = 2; i < attributeParamList.size(); i++) {
300
301       if (isInteger(attributeParamList.get(i))) {
302         attributeIndexOrKey.add(attributeParamList.get(i));
303       } else if (attributeParamList.get(i) instanceof Map) {
304         attributeIndexOrKey.add(getToscaAttributeValue(serviceTemplate, resourceId,
305             propertyName, attributeParamList.get(i), resourceType, heatFileName,
306             heatOrchestrationTemplate, null, context));
307
308       } else {
309         Object toscaAttributeName = resourceType == null ? null : context
310             .getElementMapping(resourceType, Constants.ATTR,
311                 getAttributeFullPath(attributeParamList, i));
312         if (toscaAttributeName == null) {
313           toscaAttributeName = attributeParamList.get(i);
314         }
315         attributeIndexOrKey.add(toscaAttributeName);
316       }
317     }
318
319     return Optional.of(attributeIndexOrKey);
320   }
321
322   private static String getAttributeFullPath(List<Object> attributeParamList, int attributeIndex) {
323     if (attributeParamList.size() < 3) {
324       return null;
325     }
326     StringBuffer attributeFullPath = new StringBuffer();
327     attributeFullPath.append(attributeParamList.get(1));
328     for (int j = 2; j <= attributeIndex; j++) {
329       if (isInteger(attributeParamList.get(j))) {
330         continue;
331       }
332       attributeFullPath.append(ConfigConstants.TRANS_MAPPING_DELIMITER_CHAR);
333       attributeFullPath.append(attributeParamList.get(j));
334     }
335     return attributeFullPath.toString();
336   }
337
338   private static boolean isInteger(Object inputNumber) {
339     if (inputNumber == null) {
340       return false;
341     }
342
343     try {
344       Integer.parseInt(String.valueOf(inputNumber));
345       return true;
346     } catch (NumberFormatException exception) {
347       return false;
348     }
349   }
350
351   private static Optional<String> handleResourceName(String resourceId, String heatFileName,
352                                                      HeatOrchestrationTemplate
353                                                          heatOrchestrationTemplate,
354                                                      TranslationContext context) {
355     return ResourceTranslationBase
356         .getResourceTranslatedId(heatFileName, heatOrchestrationTemplate, resourceId, context);
357   }
358
359   private static Optional<List<Object>> handleAttributeName(List<Object> attributeParamList,
360                                                             HeatOrchestrationTemplate
361                                                                 heatOrchestrationTemplate,
362                                                             String propertyName,
363                                                             String heatFileName,
364                                                             ServiceTemplate serviceTemplate,
365                                                             TranslationContext context) {
366     String resourceId = (String) attributeParamList.get(0);
367     Resource resource =
368         HeatToToscaUtil.getResource(heatOrchestrationTemplate, resourceId, heatFileName);
369
370     if (attributeParamList.size() == 1) {
371       return getResourceTranslatedAttributesList(resource, context);
372     }
373
374     if(!(attributeParamList.get(1) instanceof String)){
375       //todo - once dynamic attr name will be supported the commented line will be support it in
376       // the first translation phase.
377 //      Object toscaAttributeValue = getToscaAttributeValue(serviceTemplate, resourceId, propertyName,
378 //          attributeParamList.get(1), resource
379 //              .getType(), heatFileName, heatOrchestrationTemplate, null, context);
380 //      List<Object> dynamicAttrValue = new ArrayList<>();
381 //      dynamicAttrValue.add(toscaAttributeValue);
382 //      return Optional.of(dynamicAttrValue);
383       return Optional.empty();
384     }
385
386     if (HeatToToscaUtil.isNestedResource(resource)) {
387       return getNestedResourceTranslatedAttribute((String) attributeParamList.get(1));
388     } else {
389       return getResourceTranslatedAttribute(resource, (String) attributeParamList.get(1), context);
390     }
391   }
392
393   private static Optional<List<Object>> getNestedResourceTranslatedAttribute(String attributeName) {
394     List<Object> translatedAttributesList = new ArrayList<>();
395
396     if (attributeName.startsWith(HeatConstants.GET_ATTR_FROM_RESOURCE_GROUP_PREFIX)) {
397       String[] attributeSplit = attributeName.split("\\.");
398       if (attributeSplit.length == 2) {
399         translatedAttributesList.add(attributeSplit[1]);
400       } else if (attributeSplit.length == 3) {
401         translatedAttributesList.add(attributeSplit[2]);
402         translatedAttributesList.add(Integer.valueOf(attributeSplit[1]));
403       } else {
404         return Optional.empty();
405       }
406     } else {
407       translatedAttributesList.add(attributeName);
408     }
409     return Optional.of(translatedAttributesList);
410   }
411
412   private static Optional<List<Object>> getResourceTranslatedAttributesList(Resource resource,
413                                                                             TranslationContext
414                                                                                 context) {
415     List<Object> translatedAttributes = new ArrayList<>();
416     if (HeatToToscaUtil.isNestedResource(resource)) {
417       Optional<String> nestedFile = HeatToToscaUtil.getNestedFile(resource);
418       if (!nestedFile.isPresent()) {
419         return Optional.empty();
420       }
421       HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil()
422           .yamlToObject(context.getFiles().getFileContent(nestedFile.get()),
423               HeatOrchestrationTemplate.class);
424       translatedAttributes.addAll(nestedHeatOrchestrationTemplate.getOutputs().keySet());
425       return Optional.of(translatedAttributes);
426
427     } else {
428       Map<String, String> resourceMappingAttributes =
429           context.getElementMapping(resource.getType(), Constants.ATTR);
430       if (resourceMappingAttributes == null) {
431         return Optional.empty();
432       }
433       Set<String> mappingAttributes = new HashSet<>();
434       mappingAttributes
435           .addAll(resourceMappingAttributes.values().stream().collect(Collectors.toList()));
436       translatedAttributes.addAll(mappingAttributes);
437       return Optional.of(translatedAttributes);
438     }
439   }
440
441   private static Optional<List<Object>> getResourceTranslatedAttribute(Resource resource,
442                                                                        String attributeName,
443                                                                        TranslationContext context) {
444     List<Object> translatedAttributesList = new ArrayList<>();
445     String translatedAttribute =
446         context.getElementMapping(resource.getType(), Constants.ATTR, attributeName);
447     if (translatedAttribute != null) {
448       translatedAttributesList.add(translatedAttribute);
449       return Optional.of(translatedAttributesList);
450     } else {   //unsupported attribute
451       return Optional.empty();
452     }
453   }
454
455   private static Object getToscaAttributeValue(ServiceTemplate serviceTemplate,
456                                                String resourceId, String propertyName,
457                                                Object attributeVal, String resourceType,
458                                                String heatFileName,
459                                                HeatOrchestrationTemplate heatOrchestrationTemplate,
460                                                Template template, TranslationContext context) {
461     if (attributeVal instanceof Map && !((Map) attributeVal).isEmpty()) {
462       Map.Entry<String, Object> functionMapEntry =
463           (Map.Entry<String, Object>) ((Map) attributeVal).entrySet().iterator().next();
464       if (FunctionTranslationFactory.getInstance(functionMapEntry.getKey()).isPresent()) {
465         return FunctionTranslationFactory.getInstance(functionMapEntry.getKey()).get()
466             .translateFunction(serviceTemplate, resourceId, propertyName,
467                 functionMapEntry.getKey(), functionMapEntry
468                     .getValue(), heatFileName, heatOrchestrationTemplate, template, context);
469       }
470       Map<String, Object> attrValueMap = new HashMap<>();
471       for (Map.Entry<String, Object> entry : ((Map<String, Object>) attributeVal).entrySet()) {
472         attrValueMap.put(entry.getKey(),
473             getToscaAttributeValue(serviceTemplate, resourceId, propertyName, entry.getValue(),
474                 resourceType, heatFileName, heatOrchestrationTemplate, template, context));
475       }
476       return attrValueMap;
477     } else if (attributeVal instanceof List && !((List) attributeVal).isEmpty()) {
478       List propertyValueArray = new ArrayList<>();
479       for (int i = 0; i < ((List) attributeVal).size(); i++) {
480         propertyValueArray.add(
481             getToscaAttributeValue(serviceTemplate, resourceId, propertyName,
482                 ((List) attributeVal).get(i), resourceType, heatFileName,
483                 heatOrchestrationTemplate, template, context));
484       }
485       return propertyValueArray;
486     }
487     return attributeVal;
488   }
489
490
491 }