Add collaboration feature
[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.apache.commons.lang3.StringUtils;
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.tosca.services.YamlUtil;
32 import org.openecomp.sdc.translator.datatypes.heattotosca.TranslationContext;
33 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.EntityConsolidationData;
34 import org.openecomp.sdc.translator.services.heattotosca.ConfigConstants;
35 import org.openecomp.sdc.translator.services.heattotosca.ConsolidationDataUtil;
36 import org.openecomp.sdc.translator.services.heattotosca.Constants;
37 import org.openecomp.sdc.translator.services.heattotosca.FunctionTranslation;
38 import org.openecomp.sdc.translator.services.heattotosca.FunctionTranslationFactory;
39 import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil;
40 import org.openecomp.sdc.translator.services.heattotosca.NameExtractor;
41 import org.openecomp.sdc.translator.services.heattotosca.helper.FunctionTranslationHelper;
42 import org.openecomp.sdc.translator.services.heattotosca.impl.resourcetranslation.ResourceTranslationBase;
43
44 import java.util.ArrayList;
45 import java.util.HashMap;
46 import java.util.HashSet;
47 import java.util.List;
48 import java.util.Map;
49 import java.util.Optional;
50 import java.util.Set;
51 import java.util.stream.Collectors;
52
53 public class FunctionTranslationGetAttrImpl implements FunctionTranslation {
54
55
56   @Override
57   public Object translateFunction(ServiceTemplate serviceTemplate,
58                                   String resourceId, String propertyName, String functionKey,
59                                   Object functionValue, String heatFileName,
60                                   HeatOrchestrationTemplate heatOrchestrationTemplate,
61                                   Template toscaTemplate, TranslationContext context) {
62     Object returnValue = new HashMap<>();
63     List<Object> attributeFunctionExpression =
64         translateGetAttributeFunctionExpression(serviceTemplate, resourceId, functionValue,
65             propertyName, heatFileName, heatOrchestrationTemplate, (NodeTemplate) toscaTemplate,
66             context);
67     if (FunctionTranslationHelper.isResourceSupported(attributeFunctionExpression.get(0).toString())
68         && FunctionTranslationHelper.isAttributeSupported(attributeFunctionExpression.get(0)
69         .toString())) {
70       ((Map) returnValue)
71           .put(ToscaFunctions.GET_ATTRIBUTE.getDisplayName(), attributeFunctionExpression);
72     } else {
73       returnValue = attributeFunctionExpression;
74     }
75
76     return returnValue;
77   }
78
79   private static List<Object> translateGetAttributeFunctionExpression(
80       ServiceTemplate serviceTemplate,
81       String resourceId,
82       Object functionValue,
83       String propertyName,
84       String heatFileName,
85       HeatOrchestrationTemplate heatOrchestrationTemplate,
86       NodeTemplate nodeTemplate,
87       TranslationContext context) {
88
89     List<Object> attributeParamList = (List) functionValue;
90     List<Object> toscaAttributeParamList = new ArrayList<>();
91
92     Optional<String> targetResourceTranslatedId = Optional.empty();
93     String targetResourceId = null;
94     if( attributeParamList.get(0) instanceof String) {
95       targetResourceId = (String) attributeParamList.get(0);
96       targetResourceTranslatedId =
97           handleResourceName(targetResourceId, heatFileName, heatOrchestrationTemplate,
98               context);
99     }
100     if (!targetResourceTranslatedId.isPresent()) {
101       //unsupported resource
102       toscaAttributeParamList
103           .add(
104               FunctionTranslationHelper.getUnsupportedResourcePrefix() + attributeParamList.get(0));
105       return toscaAttributeParamList;
106     } else {
107       toscaAttributeParamList.add(targetResourceTranslatedId.get());
108     }
109
110     Optional<List<Object>> toscaAttList =
111         handleAttributeName(attributeParamList, heatOrchestrationTemplate, propertyName,
112             heatFileName, serviceTemplate,
113             context);
114     if (!toscaAttList.isPresent()) {
115       //Unsupported attribute
116       toscaAttributeParamList.clear();
117       toscaAttributeParamList
118           .add(FunctionTranslationHelper.getUnsupportedAttributePrefix() + attributeParamList.get(0)
119               + "." + attributeParamList.get(1));
120       return toscaAttributeParamList;
121     } else {
122       toscaAttributeParamList.addAll(toscaAttList.get());
123
124       handleGetAttrConsolidationData(serviceTemplate, resourceId, propertyName, heatFileName,
125           heatOrchestrationTemplate, context, targetResourceId,
126           targetResourceTranslatedId,
127           toscaAttList.get());
128     }
129
130     Optional<List<Object>> toscaIndexOrKey = handleAttributeIndexOrKey(serviceTemplate,
131         resourceId, propertyName, HeatToToscaUtil
132             .getResourceType((String) attributeParamList.get(0), heatOrchestrationTemplate,
133                 heatFileName), attributeParamList, context, heatFileName,
134         heatOrchestrationTemplate);
135     toscaIndexOrKey.ifPresent(toscaAttributeParamList::addAll);
136
137     return toscaAttributeParamList;
138   }
139
140   private static void handleGetAttrConsolidationData(
141       ServiceTemplate serviceTemplate,
142       String resourceId, String propertyName,
143       String heatFileName,
144       HeatOrchestrationTemplate heatOrchestrationTemplate,
145       TranslationContext context,
146       String targetResourceId,
147       Optional<String> targetResourceTranslatedId,
148       List<Object> toscaAttList) {
149
150     Optional<String> resourceTranslatedId = Optional.empty();
151     if (resourceId != null) {
152       resourceTranslatedId =
153           handleResourceName(resourceId, heatFileName, heatOrchestrationTemplate,
154               context);
155       resourceTranslatedId
156           .ifPresent(resourceTranslatedIdValue -> handleGetAttrOutConsolidationData(serviceTemplate,
157               propertyName,
158               heatOrchestrationTemplate, context, resourceId, targetResourceTranslatedId.get(),
159               resourceTranslatedIdValue, toscaAttList, heatFileName));
160     }
161
162     if (targetResourceTranslatedId.isPresent()) {
163       handleGetAttrInConsolidationData(serviceTemplate, resourceId, resourceTranslatedId,
164           propertyName, heatOrchestrationTemplate, context, targetResourceId,
165           targetResourceTranslatedId.get(), toscaAttList, heatFileName);
166     }
167   }
168
169   private static void handleGetAttrOutConsolidationData(
170       ServiceTemplate serviceTemplate,
171       String propertyName,
172       HeatOrchestrationTemplate heatOrchestrationTemplate,
173       TranslationContext context,
174       String resourceId,
175       String targetTranslatedResourceId,
176       String resourceTranslatedId,
177       List<Object> toscaAttList,
178       String heatFileName) {
179     if (serviceTemplate != null) {
180       Optional<EntityConsolidationData> entityConsolidationData =
181           getEntityConsolidationData(serviceTemplate, heatOrchestrationTemplate, context,
182               resourceId, resourceTranslatedId, heatFileName);
183       if (entityConsolidationData.isPresent()) {
184         String attName = (String) toscaAttList.get(0);
185         handleNodeGetAttrOut(targetTranslatedResourceId, propertyName, heatOrchestrationTemplate,
186             context, resourceId, entityConsolidationData.get(), attName);
187       }
188     }
189   }
190
191   private static void handleGetAttrInConsolidationData(
192       ServiceTemplate serviceTemplate,
193       String resourceId,
194       Optional<String> resourceTranslatedId,
195       String propertyName,
196       HeatOrchestrationTemplate heatOrchestrationTemplate,
197       TranslationContext context,
198       String targetResourceId,
199       String targetResourceTranslatedId,
200       List<Object> toscaAttList,
201       String  heatFileName) {
202
203     if (serviceTemplate != null) {
204       Optional<EntityConsolidationData> entityConsolidationData =
205           getEntityConsolidationData(serviceTemplate, heatOrchestrationTemplate, context,
206               targetResourceId, targetResourceTranslatedId, heatFileName);
207       if (entityConsolidationData.isPresent()) {
208         String attName = (String) toscaAttList.get(0);
209         if (resourceTranslatedId.isPresent()) {
210           handleNodeGetAttrIn(resourceTranslatedId.get(), propertyName, heatOrchestrationTemplate,
211               context,
212               resourceId, entityConsolidationData.get(), attName);
213         } else {
214           ConsolidationDataUtil
215               .updateOutputGetAttributeInConsolidationData(entityConsolidationData.get(),
216                   propertyName, attName);
217         }
218       }
219     }
220   }
221
222   private static void handleNodeGetAttrOut(String nodeTemplateId, String propertyName,
223                                            HeatOrchestrationTemplate heatOrchestrationTemplate,
224                                            TranslationContext context, String resourceId,
225                                            EntityConsolidationData entityConsolidationData,
226                                            String attName) {
227     Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
228     boolean isNestedResource = HeatToToscaUtil.isNestedResource(resource);
229     String toscaPropertyName = propertyName;
230     if (!isNestedResource) {
231       toscaPropertyName = HeatToToscaUtil.getToscaPropertyName(context, resource
232           .getType(), propertyName);
233     }
234     ConsolidationDataUtil
235         .updateNodeGetAttributeOut(entityConsolidationData,
236             nodeTemplateId, toscaPropertyName, attName);
237   }
238
239   private static void handleNodeGetAttrIn(String nodeTemplateId, String propertyName,
240                                           HeatOrchestrationTemplate heatOrchestrationTemplate,
241                                           TranslationContext context, String resourceId,
242                                           EntityConsolidationData entityConsolidationData,
243                                           String attName) {
244     Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
245     boolean isNestedResource = HeatToToscaUtil.isNestedResource(resource);
246     String toscaPropertyName = propertyName;
247     if (!isNestedResource) {
248       toscaPropertyName = HeatToToscaUtil.getToscaPropertyName(context, resource
249           .getType(), propertyName);
250     }
251     ConsolidationDataUtil
252         .updateNodeGetAttributeIn(entityConsolidationData,
253             nodeTemplateId, toscaPropertyName, attName);
254   }
255
256   private static Optional<EntityConsolidationData> getEntityConsolidationData(
257       ServiceTemplate serviceTemplate,
258       HeatOrchestrationTemplate heatOrchestrationTemplate,
259       TranslationContext context,
260       String resourceId,
261       String resourceTranslatedId,
262       String heatFileName) {
263     Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
264     if (ConsolidationDataUtil.isComputeResource(heatOrchestrationTemplate, resourceId)) {
265       String resourceType = heatOrchestrationTemplate.getResources().get(resourceId).getType();
266       NameExtractor nodeTypeNameExtractor =
267           context.getNameExtractorImpl(resourceType);
268       String computeType =
269           nodeTypeNameExtractor.extractNodeTypeName(
270               resource, resourceId, context.getTranslatedIds().get(heatFileName).get(resourceId));
271
272       return Optional.of(
273           ConsolidationDataUtil.getComputeTemplateConsolidationData(context, serviceTemplate,
274               computeType, resourceId));
275     } else if (ConsolidationDataUtil.isPortResource(heatOrchestrationTemplate, resourceId)) {
276       return Optional.of(ConsolidationDataUtil
277           .getPortTemplateConsolidationData(context, serviceTemplate, resourceId));
278     } else if (HeatToToscaUtil.isNestedResource(resource)) {
279       return Optional.ofNullable(ConsolidationDataUtil
280           .getNestedTemplateConsolidationData(context, serviceTemplate, heatFileName, resourceId));
281     }
282     return Optional.empty();
283   }
284
285   private static Optional<List<Object>> handleAttributeIndexOrKey(
286       ServiceTemplate serviceTemplate,
287       String resourceId, String propertyName,
288       String resourceType,
289       List<Object> attributeParamList,
290       TranslationContext context,
291       String heatFileName,
292       HeatOrchestrationTemplate heatOrchestrationTemplate) {
293
294     List<Object> attributeIndexOrKey = new ArrayList<>();
295     if (attributeParamList.size() < 3) {
296       return Optional.empty();
297     }
298
299     Object attributeName = attributeParamList.get(1);
300     for (int i = 2; i < attributeParamList.size(); i++) {
301
302       if (isInteger(attributeParamList.get(i))) {
303         attributeIndexOrKey.add(attributeParamList.get(i));
304       } else if (attributeParamList.get(i) instanceof Map) {
305         attributeIndexOrKey.add(getToscaAttributeValue(serviceTemplate, resourceId,
306             propertyName, attributeParamList.get(i), resourceType, heatFileName,
307             heatOrchestrationTemplate, null, context));
308
309       } else {
310         Object toscaAttributeName = resourceType == null ? null : context
311             .getElementMapping(resourceType, Constants.ATTR,
312                 getAttributeFullPath(attributeParamList, i));
313         if (toscaAttributeName == null) {
314           toscaAttributeName = attributeParamList.get(i);
315         }
316         attributeIndexOrKey.add(toscaAttributeName);
317       }
318     }
319
320     return Optional.of(attributeIndexOrKey);
321   }
322
323   private static String getAttributeFullPath(List<Object> attributeParamList, int attributeIndex) {
324     if (attributeParamList.size() < 3) {
325       return null;
326     }
327     StringBuilder attributeFullPath = new StringBuilder();
328     attributeFullPath.append(attributeParamList.get(1));
329     for (int j = 2; j <= attributeIndex; j++) {
330       if (isInteger(attributeParamList.get(j))) {
331         continue;
332       }
333       attributeFullPath.append(ConfigConstants.TRANS_MAPPING_DELIMITER_CHAR);
334       attributeFullPath.append(attributeParamList.get(j));
335     }
336     return attributeFullPath.toString();
337   }
338
339   private static boolean isInteger(Object inputNumber) {
340     if (inputNumber == null) {
341       return false;
342     }
343
344     /*try {
345       Integer.parseInt(String.valueOf(inputNumber));
346       return true;
347     } catch (NumberFormatException exception) {
348       return false;
349     }*/
350     if(StringUtils.isNumeric(String.valueOf(inputNumber))){
351       return true;
352     } else {
353       return false;
354     }
355   }
356
357   private static Optional<String> handleResourceName(String resourceId, String heatFileName,
358                                                      HeatOrchestrationTemplate
359                                                          heatOrchestrationTemplate,
360                                                      TranslationContext context) {
361     return ResourceTranslationBase
362         .getResourceTranslatedId(heatFileName, heatOrchestrationTemplate, resourceId, context);
363   }
364
365   private static Optional<List<Object>> handleAttributeName(List<Object> attributeParamList,
366                                                             HeatOrchestrationTemplate
367                                                                 heatOrchestrationTemplate,
368                                                             String propertyName,
369                                                             String heatFileName,
370                                                             ServiceTemplate serviceTemplate,
371                                                             TranslationContext context) {
372     String resourceId = (String) attributeParamList.get(0);
373     Resource resource =
374         HeatToToscaUtil.getResource(heatOrchestrationTemplate, resourceId, heatFileName);
375
376     if (attributeParamList.size() == 1) {
377       return getResourceTranslatedAttributesList(resource, context);
378     }
379
380     if(!(attributeParamList.get(1) instanceof String)){
381       //todo - once dynamic attr name will be supported the commented line will be support it in
382       // the first translation phase.
383 //      Object toscaAttributeValue = getToscaAttributeValue(serviceTemplate, resourceId, propertyName,
384 //          attributeParamList.get(1), resource
385 //              .getType(), heatFileName, heatOrchestrationTemplate, null, context);
386 //      List<Object> dynamicAttrValue = new ArrayList<>();
387 //      dynamicAttrValue.add(toscaAttributeValue);
388 //      return Optional.of(dynamicAttrValue);
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 }