Rename packages from openecomp to onap.
[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  * Copyright © 2016-2018 European Support Limited
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 package org.openecomp.sdc.translator.services.heattotosca.impl.functiontranslation;
18
19 import static org.openecomp.sdc.translator.services.heattotosca.ConfigConstants.TRANS_MAPPING_DELIMITER_CHAR;
20
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;
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 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));
251     }
252     if (!isNestedResource) {
253       toscaPropertyName = HeatToToscaUtil.getToscaPropertyName(context, resource
254           .getType(), heatPropertyName);
255     }
256     ConsolidationDataUtil
257         .updateNodeGetAttributeIn(entityConsolidationData,
258             nodeTemplateId, toscaPropertyName, attName);
259   }
260
261   private static Optional<EntityConsolidationData> getEntityConsolidationData(
262       ServiceTemplate serviceTemplate,
263       HeatOrchestrationTemplate heatOrchestrationTemplate,
264       TranslationContext context,
265       String resourceId,
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);
273       String computeType =
274           nodeTypeNameExtractor.extractNodeTypeName(
275               resource, resourceId, context.getTranslatedIds().get(heatFileName).get(resourceId));
276
277       return Optional.of(
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());
291       }
292     } else if (HeatToToscaUtil.isNestedResource(resource)) {
293       return Optional.ofNullable(ConsolidationDataUtil
294           .getNestedTemplateConsolidationData(context, serviceTemplate, heatFileName, resourceTranslatedId));
295     }
296     return Optional.empty();
297   }
298
299   private static Optional<List<Object>> handleAttributeIndexOrKey(
300       ServiceTemplate serviceTemplate,
301       String resourceId, String propertyName,
302       String resourceType,
303       List<Object> attributeParamList,
304       TranslationContext context,
305       String heatFileName,
306       HeatOrchestrationTemplate heatOrchestrationTemplate) {
307
308     List<Object> attributeIndexOrKey = new ArrayList<>();
309     if (attributeParamList.size() < 3) {
310       return Optional.empty();
311     }
312
313     Object attributeName = attributeParamList.get(1);
314     for (int i = 2; i < attributeParamList.size(); i++) {
315
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));
322
323       } else {
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);
329         }
330         attributeIndexOrKey.add(toscaAttributeName);
331       }
332     }
333
334     return Optional.of(attributeIndexOrKey);
335   }
336
337   private static String getAttributeFullPath(List<Object> attributeParamList, int attributeIndex) {
338     if (attributeParamList.size() < 3) {
339       return null;
340     }
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))) {
345         continue;
346       }
347       attributeFullPath.append(TRANS_MAPPING_DELIMITER_CHAR);
348       attributeFullPath.append(attributeParamList.get(j));
349     }
350     return attributeFullPath.toString();
351   }
352
353   private static boolean isInteger(Object inputNumber) {
354     if (inputNumber == null) {
355       return false;
356     }
357
358     if (StringUtils.isNumeric(String.valueOf(inputNumber))){
359       return true;
360     } else {
361       return false;
362     }
363   }
364
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);
371   }
372
373   private static Optional<List<Object>> handleAttributeName(List<Object> attributeParamList,
374                                                             HeatOrchestrationTemplate
375                                                                 heatOrchestrationTemplate,
376                                                             String propertyName,
377                                                             String heatFileName,
378                                                             ServiceTemplate serviceTemplate,
379                                                             TranslationContext context) {
380     String resourceId = (String) attributeParamList.get(0);
381     Resource resource =
382         HeatToToscaUtil.getResource(heatOrchestrationTemplate, resourceId, heatFileName);
383
384     if (attributeParamList.size() == 1) {
385       return getResourceTranslatedAttributesList(resource, context);
386     }
387
388     if (!(attributeParamList.get(1) instanceof String)) {
389       return Optional.empty();
390     }
391
392     if (HeatToToscaUtil.isNestedResource(resource)) {
393       return getNestedResourceTranslatedAttribute((String) attributeParamList.get(1));
394     } else {
395       return getResourceTranslatedAttribute(resource, (String) attributeParamList.get(1), context);
396     }
397   }
398
399   private static Optional<List<Object>> getNestedResourceTranslatedAttribute(String attributeName) {
400     List<Object> translatedAttributesList = new ArrayList<>();
401
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]));
409       } else {
410         return Optional.empty();
411       }
412     } else {
413       translatedAttributesList.add(attributeName);
414     }
415     return Optional.of(translatedAttributesList);
416   }
417
418   private static Optional<List<Object>> getResourceTranslatedAttributesList(Resource resource,
419                                                                             TranslationContext
420                                                                                 context) {
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();
426       }
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);
432
433     } else {
434       Map<String, String> resourceMappingAttributes =
435           context.getElementMapping(resource.getType(), Constants.ATTR);
436       if (resourceMappingAttributes == null) {
437         return Optional.empty();
438       }
439       Set<String> mappingAttributes = new HashSet<>();
440       mappingAttributes
441           .addAll(resourceMappingAttributes.values().stream().collect(Collectors.toList()));
442       translatedAttributes.addAll(mappingAttributes);
443       return Optional.of(translatedAttributes);
444     }
445   }
446
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();
458     }
459   }
460
461   private static Object getToscaAttributeValue(ServiceTemplate serviceTemplate,
462                                                String resourceId, String propertyName,
463                                                Object attributeVal, String resourceType,
464                                                String heatFileName,
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);
475       }
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));
481       }
482       return attrValueMap;
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));
490       }
491       return propertyValueArray;
492     }
493     return attributeVal;
494   }
495
496
497 }