re base code
[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 java.util.ArrayList;
22 import java.util.HashMap;
23 import java.util.HashSet;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Objects;
27 import java.util.Optional;
28 import java.util.Set;
29
30 import org.apache.commons.lang3.StringUtils;
31 import org.onap.sdc.tosca.datatypes.model.ServiceTemplate;
32 import org.onap.sdc.tosca.services.YamlUtil;
33 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
34 import org.openecomp.sdc.heat.datatypes.model.Resource;
35 import org.openecomp.sdc.heat.services.HeatConstants;
36 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
37 import org.openecomp.sdc.translator.datatypes.heattotosca.TranslationContext;
38 import org.openecomp.sdc.translator.services.heattotosca.ConsolidationDataUtil;
39 import org.openecomp.sdc.translator.services.heattotosca.Constants;
40 import org.openecomp.sdc.translator.services.heattotosca.FunctionTranslation;
41 import org.openecomp.sdc.translator.services.heattotosca.FunctionTranslationFactory;
42 import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil;
43 import org.openecomp.sdc.translator.services.heattotosca.impl.resourcetranslation.ResourceTranslationBase;
44
45 public class FunctionTranslationGetAttrImpl implements FunctionTranslation {
46
47     private static List<Object> translateGetAttributeFunctionExpression(FunctionTranslator functionTranslator) {
48
49         List<Object> attributeParamList = (List) functionTranslator.getFunctionValue();
50         List<Object> toscaAttributeParamList = new ArrayList<>();
51
52         Optional<String> targetResourceTranslatedId = Optional.empty();
53         String targetResourceId = null;
54         if (attributeParamList.get(0) instanceof String) {
55             targetResourceId = (String) attributeParamList.get(0);
56             targetResourceTranslatedId = handleResourceName(targetResourceId, functionTranslator.getHeatFileName(),
57                     functionTranslator.getHeatOrchestrationTemplate(), functionTranslator.getContext());
58         }
59         if (!targetResourceTranslatedId.isPresent()) {
60             //unsupported resource
61             toscaAttributeParamList.add(functionTranslator.getUnsupportedResourcePrefix() + attributeParamList.get(0));
62             return toscaAttributeParamList;
63         }
64         toscaAttributeParamList.add(targetResourceTranslatedId.get());
65         Optional<List<Object>> toscaAttList = handleAttributeName(attributeParamList, functionTranslator);
66         if (!toscaAttList.isPresent()) {
67             //Unsupported attribute
68             toscaAttributeParamList.clear();
69             toscaAttributeParamList.add(functionTranslator.getUnsupportedAttributePrefix()
70                     + attributeParamList.get(0) + "." + attributeParamList.get(1));
71             return toscaAttributeParamList;
72         }
73         toscaAttributeParamList.addAll(toscaAttList.get());
74         handleGetAttrConsolidationData(functionTranslator, targetResourceId, targetResourceTranslatedId.get(),
75                 toscaAttList.get());
76
77         String resourceType = HeatToToscaUtil.getResourceType((String) attributeParamList.get(0), functionTranslator
78                 .getHeatOrchestrationTemplate(), functionTranslator.getHeatFileName());
79         Optional<List<Object>> toscaIndexOrKey = handleAttributeIndexOrKey(functionTranslator, resourceType,
80                 attributeParamList);
81         toscaIndexOrKey.ifPresent(toscaAttributeParamList::addAll);
82         return toscaAttributeParamList;
83     }
84
85     private static void handleGetAttrConsolidationData(FunctionTranslator functionTranslator,
86                                                        String targetResourceId,
87                                                        String targetResourceTranslatedId,
88                                                        List<Object> toscaAttList) {
89         Optional<String> resourceTranslatedId;
90         String resourceId = functionTranslator.getResourceId();
91         String resourceTranslatedIdValue = null;
92         if (resourceId != null) {
93             resourceTranslatedId = handleResourceName(resourceId, functionTranslator.getHeatFileName(),
94                     functionTranslator.getHeatOrchestrationTemplate(), functionTranslator.getContext());
95             if (resourceTranslatedId.isPresent()) {
96                 resourceTranslatedIdValue = resourceTranslatedId.get();
97                 handleGetAttrOutConsolidationData(functionTranslator, targetResourceTranslatedId,
98                         resourceTranslatedIdValue, toscaAttList);
99             }
100         }
101         handleGetAttrInConsolidationData(functionTranslator, resourceTranslatedIdValue,
102                 targetResourceId, targetResourceTranslatedId, toscaAttList);
103     }
104
105     private static void handleGetAttrOutConsolidationData(FunctionTranslator functionTranslator,
106                                                           String targetTranslatedResourceId,
107                                                           String resourceTranslatedId,
108                                                           List<Object> toscaAttList) {
109         if (functionTranslator.getServiceTemplate() == null) {
110             return;
111         }
112
113         String attName = (String) toscaAttList.get(0);
114         ConsolidationDataUtil.updateNodeGetAttributeOut(functionTranslator, targetTranslatedResourceId,
115                 resourceTranslatedId, attName);
116
117     }
118
119     private static void handleGetAttrInConsolidationData(FunctionTranslator functionTranslator,
120                                                          String resourceTranslatedId,
121                                                          String targetResourceId,
122                                                          String targetResourceTranslatedId,
123                                                          List<Object> toscaAttList) {
124         if (functionTranslator.getServiceTemplate() == null) {
125             return;
126         }
127         String attName = (String) toscaAttList.get(0);
128         if (Objects.nonNull(resourceTranslatedId)) {
129             ConsolidationDataUtil.updateNodeGetAttributeIn(functionTranslator, resourceTranslatedId,
130                     targetResourceId, targetResourceTranslatedId, attName);
131         } else {
132             ConsolidationDataUtil.updateOutputParamGetAttrIn(functionTranslator, targetResourceId,
133                     targetResourceTranslatedId, functionTranslator.getPropertyName(), attName);
134         }
135     }
136
137     private static Optional<List<Object>> handleAttributeIndexOrKey(FunctionTranslator functionTranslator,
138                                                                     String resourceType,
139                                                                     List<Object> attributeParamList) {
140
141         List<Object> attributeIndexOrKey = new ArrayList<>();
142         if (attributeParamList.size() < 3) {
143             return Optional.empty();
144         }
145
146         for (int i = 2; i < attributeParamList.size(); i++) {
147             if (isInteger(attributeParamList.get(i))) {
148                 attributeIndexOrKey.add(attributeParamList.get(i));
149             } else if (attributeParamList.get(i) instanceof Map) {
150                 attributeIndexOrKey.add(getToscaAttributeValue(functionTranslator, attributeParamList.get(i)));
151             } else {
152                 Object toscaAttributeName = resourceType == null ? null : functionTranslator.getContext()
153                         .getElementMapping(resourceType, Constants.ATTR, getAttributeFullPath(attributeParamList, i));
154                 if (toscaAttributeName == null) {
155                     toscaAttributeName = attributeParamList.get(i);
156                 }
157                 attributeIndexOrKey.add(toscaAttributeName);
158             }
159         }
160
161         return Optional.of(attributeIndexOrKey);
162     }
163
164     private static String getAttributeFullPath(List<Object> attributeParamList, int attributeIndex) {
165         if (attributeParamList.size() < 3) {
166             return null;
167         }
168         StringBuilder attributeFullPath = new StringBuilder();
169         attributeFullPath.append(attributeParamList.get(1));
170         for (int j = 2; j <= attributeIndex; j++) {
171             if (isInteger(attributeParamList.get(j))) {
172                 continue;
173             }
174             attributeFullPath.append(TRANS_MAPPING_DELIMITER_CHAR);
175             attributeFullPath.append(attributeParamList.get(j));
176         }
177         return attributeFullPath.toString();
178     }
179
180     private static boolean isInteger(Object inputNumber) {
181         if (inputNumber == null) {
182             return false;
183         }
184         return StringUtils.isNumeric(String.valueOf(inputNumber));
185     }
186
187     private static Optional<String> handleResourceName(String resourceId, String heatFileName,
188                                                        HeatOrchestrationTemplate heatOrchestrationTemplate,
189                                                        TranslationContext context) {
190         return ResourceTranslationBase
191                 .getResourceTranslatedId(heatFileName, heatOrchestrationTemplate, resourceId, context);
192     }
193
194     private static Optional<List<Object>> handleAttributeName(List<Object> attributeParamList,
195                                                               FunctionTranslator functionTranslator) {
196         String resourceId = (String) attributeParamList.get(0);
197         Resource resource = HeatToToscaUtil.getResource(functionTranslator.getHeatOrchestrationTemplate(),
198                 resourceId, functionTranslator.getHeatFileName());
199         if (attributeParamList.size() == 1) {
200             return getResourceTranslatedAttributesList(resource, functionTranslator.getContext());
201         }
202         if (!(attributeParamList.get(1) instanceof String)) {
203             return Optional.empty();
204         }
205         if (HeatToToscaUtil.isNestedResource(resource)) {
206             return getNestedResourceTranslatedAttribute((String) attributeParamList.get(1));
207         } else {
208             return getResourceTranslatedAttribute(resource, (String) attributeParamList.get(1), functionTranslator
209                     .getContext());
210         }
211     }
212
213     private static Optional<List<Object>> getNestedResourceTranslatedAttribute(String attributeName) {
214         List<Object> translatedAttributesList = new ArrayList<>();
215         if (attributeName.startsWith(HeatConstants.GET_ATTR_FROM_RESOURCE_GROUP_PREFIX)) {
216             String[] attributeSplit = attributeName.split("\\.");
217             if (attributeSplit.length == 2) {
218                 translatedAttributesList.add(attributeSplit[1]);
219             } else if (attributeSplit.length == 3) {
220                 translatedAttributesList.add(attributeSplit[2]);
221                 translatedAttributesList.add(Integer.valueOf(attributeSplit[1]));
222             } else {
223                 return Optional.empty();
224             }
225         } else {
226             translatedAttributesList.add(attributeName);
227         }
228         return Optional.of(translatedAttributesList);
229     }
230
231     private static Optional<List<Object>> getResourceTranslatedAttributesList(Resource resource,
232                                                                               TranslationContext context) {
233         List<Object> translatedAttributes = new ArrayList<>();
234         if (HeatToToscaUtil.isNestedResource(resource)) {
235             Optional<String> nestedFile = HeatToToscaUtil.getNestedFile(resource);
236             if (!nestedFile.isPresent()) {
237                 return Optional.empty();
238             }
239             HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil()
240                     .yamlToObject(context.getFiles().getFileContent(nestedFile.get()), HeatOrchestrationTemplate.class);
241             translatedAttributes.addAll(nestedHeatOrchestrationTemplate.getOutputs().keySet());
242             return Optional.of(translatedAttributes);
243
244         } else {
245             Map<String, String> resourceMappingAttributes =
246                     context.getElementMapping(resource.getType(), Constants.ATTR);
247             if (resourceMappingAttributes == null) {
248                 return Optional.empty();
249             }
250             Set<String> mappingAttributes = new HashSet<>(new ArrayList<>(resourceMappingAttributes.values()));
251             translatedAttributes.addAll(mappingAttributes);
252             return Optional.of(translatedAttributes);
253         }
254     }
255
256     private static Optional<List<Object>> getResourceTranslatedAttribute(Resource resource,
257                                                                          String attributeName,
258                                                                          TranslationContext context) {
259         List<Object> translatedAttributesList = new ArrayList<>();
260         String translatedAttribute = context.getElementMapping(resource.getType(), Constants.ATTR, attributeName);
261         if (translatedAttribute != null) {
262             translatedAttributesList.add(translatedAttribute);
263             return Optional.of(translatedAttributesList);
264         } else {   //unsupported attribute
265             return Optional.empty();
266         }
267     }
268
269     private static Object getToscaAttributeValue(FunctionTranslator functionTranslator,
270                                                  Object attributeVal) {
271         if (attributeVal instanceof Map && !((Map) attributeVal).isEmpty()) {
272             Map.Entry<String, Object> functionMapEntry =
273                     (Map.Entry<String, Object>) ((Map) attributeVal).entrySet().iterator().next();
274             Optional<FunctionTranslation> functionTranslationInstance =
275                     FunctionTranslationFactory.getInstance(functionMapEntry.getKey());
276             if (functionTranslationInstance.isPresent()) {
277                 functionTranslator.setFunctionValue(functionMapEntry.getValue());
278                 return functionTranslationInstance.get().translateFunction(functionTranslator);
279             }
280             Map<String, Object> attrValueMap = new HashMap<>();
281             for (Map.Entry<String, Object> entry : ((Map<String, Object>) attributeVal).entrySet()) {
282                 attrValueMap.put(entry.getKey(), getToscaAttributeValue(functionTranslator, entry.getValue()));
283             }
284             return attrValueMap;
285         } else if (attributeVal instanceof List && !((List) attributeVal).isEmpty()) {
286             List<Object> propertyValueArray = new ArrayList<>();
287             for (int i = 0; i < ((List) attributeVal).size(); i++) {
288                 propertyValueArray.add(getToscaAttributeValue(functionTranslator, ((List) attributeVal).get(i)));
289             }
290             return propertyValueArray;
291         }
292         return attributeVal;
293     }
294
295     @Override
296     public Object translateFunction(FunctionTranslator functionTranslator) {
297         Object returnValue;
298         List<Object> attributeFunctionExpression = translateGetAttributeFunctionExpression(functionTranslator);
299         if (functionTranslator.isResourceSupported(attributeFunctionExpression.get(0).toString())
300                 && functionTranslator.isAttributeSupported(attributeFunctionExpression.get(0).toString())) {
301             Map<String, Object> getAttrValue = new HashMap<>();
302             getAttrValue.put(ToscaFunctions.GET_ATTRIBUTE.getDisplayName(), attributeFunctionExpression);
303             returnValue = getAttrValue;
304         } else {
305             returnValue = attributeFunctionExpression;
306         }
307         return returnValue;
308     }
309 }