2 * Copyright © 2016-2018 European Support Limited
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.openecomp.sdc.translator.services.heattotosca.impl.functiontranslation;
19 import static org.openecomp.sdc.translator.services.heattotosca.ConfigConstants.TRANS_MAPPING_DELIMITER_CHAR;
21 import java.util.ArrayList;
22 import java.util.HashMap;
23 import java.util.HashSet;
24 import java.util.List;
26 import java.util.Objects;
27 import java.util.Optional;
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;
45 public class FunctionTranslationGetAttrImpl implements FunctionTranslation {
47 private static List<Object> translateGetAttributeFunctionExpression(FunctionTranslator functionTranslator) {
49 List<Object> attributeParamList = (List) functionTranslator.getFunctionValue();
50 List<Object> toscaAttributeParamList = new ArrayList<>();
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());
59 if (!targetResourceTranslatedId.isPresent()) {
60 //unsupported resource
61 toscaAttributeParamList.add(functionTranslator.getUnsupportedResourcePrefix() + attributeParamList.get(0));
62 return toscaAttributeParamList;
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;
73 toscaAttributeParamList.addAll(toscaAttList.get());
74 handleGetAttrConsolidationData(functionTranslator, targetResourceId, targetResourceTranslatedId.get(),
77 String resourceType = HeatToToscaUtil.getResourceType((String) attributeParamList.get(0), functionTranslator
78 .getHeatOrchestrationTemplate(), functionTranslator.getHeatFileName());
79 Optional<List<Object>> toscaIndexOrKey = handleAttributeIndexOrKey(functionTranslator, resourceType,
81 toscaIndexOrKey.ifPresent(toscaAttributeParamList::addAll);
82 return toscaAttributeParamList;
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);
101 handleGetAttrInConsolidationData(functionTranslator, resourceTranslatedIdValue,
102 targetResourceId, targetResourceTranslatedId, toscaAttList);
105 private static void handleGetAttrOutConsolidationData(FunctionTranslator functionTranslator,
106 String targetTranslatedResourceId,
107 String resourceTranslatedId,
108 List<Object> toscaAttList) {
109 if (functionTranslator.getServiceTemplate() == null) {
113 String attName = (String) toscaAttList.get(0);
114 ConsolidationDataUtil.updateNodeGetAttributeOut(functionTranslator, targetTranslatedResourceId,
115 resourceTranslatedId, attName);
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) {
127 String attName = (String) toscaAttList.get(0);
128 if (Objects.nonNull(resourceTranslatedId)) {
129 ConsolidationDataUtil.updateNodeGetAttributeIn(functionTranslator, resourceTranslatedId,
130 targetResourceId, targetResourceTranslatedId, attName);
132 ConsolidationDataUtil.updateOutputParamGetAttrIn(functionTranslator, targetResourceId,
133 targetResourceTranslatedId, functionTranslator.getPropertyName(), attName);
137 private static Optional<List<Object>> handleAttributeIndexOrKey(FunctionTranslator functionTranslator,
139 List<Object> attributeParamList) {
141 List<Object> attributeIndexOrKey = new ArrayList<>();
142 if (attributeParamList.size() < 3) {
143 return Optional.empty();
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)));
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);
157 attributeIndexOrKey.add(toscaAttributeName);
161 return Optional.of(attributeIndexOrKey);
164 private static String getAttributeFullPath(List<Object> attributeParamList, int attributeIndex) {
165 if (attributeParamList.size() < 3) {
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))) {
174 attributeFullPath.append(TRANS_MAPPING_DELIMITER_CHAR);
175 attributeFullPath.append(attributeParamList.get(j));
177 return attributeFullPath.toString();
180 private static boolean isInteger(Object inputNumber) {
181 if (inputNumber == null) {
184 return StringUtils.isNumeric(String.valueOf(inputNumber));
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);
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());
202 if (!(attributeParamList.get(1) instanceof String)) {
203 return Optional.empty();
205 if (HeatToToscaUtil.isNestedResource(resource)) {
206 return getNestedResourceTranslatedAttribute((String) attributeParamList.get(1));
208 return getResourceTranslatedAttribute(resource, (String) attributeParamList.get(1), functionTranslator
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]));
223 return Optional.empty();
226 translatedAttributesList.add(attributeName);
228 return Optional.of(translatedAttributesList);
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();
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);
245 Map<String, String> resourceMappingAttributes =
246 context.getElementMapping(resource.getType(), Constants.ATTR);
247 if (resourceMappingAttributes == null) {
248 return Optional.empty();
250 Set<String> mappingAttributes = new HashSet<>(new ArrayList<>(resourceMappingAttributes.values()));
251 translatedAttributes.addAll(mappingAttributes);
252 return Optional.of(translatedAttributes);
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();
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);
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()));
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)));
290 return propertyValueArray;
296 public Object translateFunction(FunctionTranslator functionTranslator) {
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;
305 returnValue = attributeFunctionExpression;