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.services.YamlUtil;
32 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
33 import org.openecomp.sdc.heat.datatypes.model.Resource;
34 import org.openecomp.sdc.heat.services.HeatConstants;
35 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
36 import org.openecomp.sdc.translator.datatypes.heattotosca.TranslationContext;
37 import org.openecomp.sdc.translator.services.heattotosca.ConsolidationDataUtil;
38 import org.openecomp.sdc.translator.services.heattotosca.Constants;
39 import org.openecomp.sdc.translator.services.heattotosca.FunctionTranslation;
40 import org.openecomp.sdc.translator.services.heattotosca.FunctionTranslationFactory;
41 import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil;
42 import org.openecomp.sdc.translator.services.heattotosca.impl.resourcetranslation.ResourceTranslationBase;
44 public class FunctionTranslationGetAttrImpl implements FunctionTranslation {
46 private static List<Object> translateGetAttributeFunctionExpression(FunctionTranslator functionTranslator) {
48 List<Object> attributeParamList = (List) functionTranslator.getFunctionValue();
49 List<Object> toscaAttributeParamList = new ArrayList<>();
51 Optional<String> targetResourceTranslatedId = Optional.empty();
52 String targetResourceId = null;
53 if (attributeParamList.get(0) instanceof String) {
54 targetResourceId = (String) attributeParamList.get(0);
55 targetResourceTranslatedId = handleResourceName(targetResourceId, functionTranslator.getHeatFileName(),
56 functionTranslator.getHeatOrchestrationTemplate(), functionTranslator.getContext());
58 if (!targetResourceTranslatedId.isPresent()) {
59 //unsupported resource
60 toscaAttributeParamList.add(functionTranslator.getUnsupportedResourcePrefix() + attributeParamList.get(0));
61 return toscaAttributeParamList;
63 toscaAttributeParamList.add(targetResourceTranslatedId.get());
64 Optional<List<Object>> toscaAttList = handleAttributeName(attributeParamList, functionTranslator);
65 if (!toscaAttList.isPresent()) {
66 //Unsupported attribute
67 toscaAttributeParamList.clear();
68 toscaAttributeParamList.add(functionTranslator.getUnsupportedAttributePrefix()
69 + attributeParamList.get(0) + "." + attributeParamList.get(1));
70 return toscaAttributeParamList;
72 toscaAttributeParamList.addAll(toscaAttList.get());
73 handleGetAttrConsolidationData(functionTranslator, targetResourceId, targetResourceTranslatedId.get(),
76 String resourceType = HeatToToscaUtil.getResourceType((String) attributeParamList.get(0), functionTranslator
77 .getHeatOrchestrationTemplate(), functionTranslator.getHeatFileName());
78 Optional<List<Object>> toscaIndexOrKey = handleAttributeIndexOrKey(functionTranslator, resourceType,
80 toscaIndexOrKey.ifPresent(toscaAttributeParamList::addAll);
81 return toscaAttributeParamList;
84 private static void handleGetAttrConsolidationData(FunctionTranslator functionTranslator,
85 String targetResourceId,
86 String targetResourceTranslatedId,
87 List<Object> toscaAttList) {
88 Optional<String> resourceTranslatedId;
89 String resourceId = functionTranslator.getResourceId();
90 String resourceTranslatedIdValue = null;
91 if (resourceId != null) {
92 resourceTranslatedId = handleResourceName(resourceId, functionTranslator.getHeatFileName(),
93 functionTranslator.getHeatOrchestrationTemplate(), functionTranslator.getContext());
94 if (resourceTranslatedId.isPresent()) {
95 resourceTranslatedIdValue = resourceTranslatedId.get();
96 handleGetAttrOutConsolidationData(functionTranslator, targetResourceTranslatedId,
97 resourceTranslatedIdValue, toscaAttList);
100 handleGetAttrInConsolidationData(functionTranslator, resourceTranslatedIdValue,
101 targetResourceId, targetResourceTranslatedId, toscaAttList);
104 private static void handleGetAttrOutConsolidationData(FunctionTranslator functionTranslator,
105 String targetTranslatedResourceId,
106 String resourceTranslatedId,
107 List<Object> toscaAttList) {
108 if (functionTranslator.getServiceTemplate() == null) {
112 String attName = (String) toscaAttList.get(0);
113 ConsolidationDataUtil.updateNodeGetAttributeOut(functionTranslator, targetTranslatedResourceId,
114 resourceTranslatedId, attName);
118 private static void handleGetAttrInConsolidationData(FunctionTranslator functionTranslator,
119 String resourceTranslatedId,
120 String targetResourceId,
121 String targetResourceTranslatedId,
122 List<Object> toscaAttList) {
123 if (functionTranslator.getServiceTemplate() == null) {
126 String attName = (String) toscaAttList.get(0);
127 if (Objects.nonNull(resourceTranslatedId)) {
128 ConsolidationDataUtil.updateNodeGetAttributeIn(functionTranslator, resourceTranslatedId,
129 targetResourceId, targetResourceTranslatedId, attName);
131 ConsolidationDataUtil.updateOutputParamGetAttrIn(functionTranslator, targetResourceId,
132 targetResourceTranslatedId, functionTranslator.getPropertyName(), attName);
136 private static Optional<List<Object>> handleAttributeIndexOrKey(FunctionTranslator functionTranslator,
138 List<Object> attributeParamList) {
140 List<Object> attributeIndexOrKey = new ArrayList<>();
141 if (attributeParamList.size() < 3) {
142 return Optional.empty();
145 for (int i = 2; i < attributeParamList.size(); i++) {
146 if (isInteger(attributeParamList.get(i))) {
147 attributeIndexOrKey.add(attributeParamList.get(i));
148 } else if (attributeParamList.get(i) instanceof Map) {
149 attributeIndexOrKey.add(getToscaAttributeValue(functionTranslator, attributeParamList.get(i)));
151 Object toscaAttributeName = resourceType == null ? null : functionTranslator.getContext()
152 .getElementMapping(resourceType, Constants.ATTR, getAttributeFullPath(attributeParamList, i));
153 if (toscaAttributeName == null) {
154 toscaAttributeName = attributeParamList.get(i);
156 attributeIndexOrKey.add(toscaAttributeName);
160 return Optional.of(attributeIndexOrKey);
163 private static String getAttributeFullPath(List<Object> attributeParamList, int attributeIndex) {
164 if (attributeParamList.size() < 3) {
167 StringBuilder attributeFullPath = new StringBuilder();
168 attributeFullPath.append(attributeParamList.get(1));
169 for (int j = 2; j <= attributeIndex; j++) {
170 if (isInteger(attributeParamList.get(j))) {
173 attributeFullPath.append(TRANS_MAPPING_DELIMITER_CHAR);
174 attributeFullPath.append(attributeParamList.get(j));
176 return attributeFullPath.toString();
179 private static boolean isInteger(Object inputNumber) {
180 if (inputNumber == null) {
183 return StringUtils.isNumeric(String.valueOf(inputNumber));
186 private static Optional<String> handleResourceName(String resourceId, String heatFileName,
187 HeatOrchestrationTemplate heatOrchestrationTemplate,
188 TranslationContext context) {
189 return ResourceTranslationBase
190 .getResourceTranslatedId(heatFileName, heatOrchestrationTemplate, resourceId, context);
193 private static Optional<List<Object>> handleAttributeName(List<Object> attributeParamList,
194 FunctionTranslator functionTranslator) {
195 String resourceId = (String) attributeParamList.get(0);
196 Resource resource = HeatToToscaUtil.getResource(functionTranslator.getHeatOrchestrationTemplate(),
197 resourceId, functionTranslator.getHeatFileName());
198 if (attributeParamList.size() == 1) {
199 return getResourceTranslatedAttributesList(resource, functionTranslator.getContext());
201 if (!(attributeParamList.get(1) instanceof String)) {
202 return Optional.empty();
204 if (HeatToToscaUtil.isNestedResource(resource)) {
205 return getNestedResourceTranslatedAttribute((String) attributeParamList.get(1));
207 return getResourceTranslatedAttribute(resource, (String) attributeParamList.get(1), functionTranslator
212 private static Optional<List<Object>> getNestedResourceTranslatedAttribute(String attributeName) {
213 List<Object> translatedAttributesList = new ArrayList<>();
214 if (attributeName.startsWith(HeatConstants.GET_ATTR_FROM_RESOURCE_GROUP_PREFIX)) {
215 String[] attributeSplit = attributeName.split("\\.");
216 if (attributeSplit.length == 2) {
217 translatedAttributesList.add(attributeSplit[1]);
218 } else if (attributeSplit.length == 3) {
219 translatedAttributesList.add(attributeSplit[2]);
220 translatedAttributesList.add(Integer.valueOf(attributeSplit[1]));
222 return Optional.empty();
225 translatedAttributesList.add(attributeName);
227 return Optional.of(translatedAttributesList);
230 private static Optional<List<Object>> getResourceTranslatedAttributesList(Resource resource,
231 TranslationContext context) {
232 List<Object> translatedAttributes = new ArrayList<>();
233 if (HeatToToscaUtil.isNestedResource(resource)) {
234 Optional<String> nestedFile = HeatToToscaUtil.getNestedFile(resource);
235 if (!nestedFile.isPresent()) {
236 return Optional.empty();
238 HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil()
239 .yamlToObject(context.getFiles().getFileContentAsStream(nestedFile.get()), HeatOrchestrationTemplate.class);
240 translatedAttributes.addAll(nestedHeatOrchestrationTemplate.getOutputs().keySet());
241 return Optional.of(translatedAttributes);
244 Map<String, String> resourceMappingAttributes =
245 context.getElementMapping(resource.getType(), Constants.ATTR);
246 if (resourceMappingAttributes == null) {
247 return Optional.empty();
249 Set<String> mappingAttributes = new HashSet<>(new ArrayList<>(resourceMappingAttributes.values()));
250 translatedAttributes.addAll(mappingAttributes);
251 return Optional.of(translatedAttributes);
255 private static Optional<List<Object>> getResourceTranslatedAttribute(Resource resource,
256 String attributeName,
257 TranslationContext context) {
258 List<Object> translatedAttributesList = new ArrayList<>();
259 String translatedAttribute = context.getElementMapping(resource.getType(), Constants.ATTR, attributeName);
260 if (translatedAttribute != null) {
261 translatedAttributesList.add(translatedAttribute);
262 return Optional.of(translatedAttributesList);
263 } else { //unsupported attribute
264 return Optional.empty();
268 private static Object getToscaAttributeValue(FunctionTranslator functionTranslator,
269 Object attributeVal) {
270 if (attributeVal instanceof Map && !((Map) attributeVal).isEmpty()) {
271 Map.Entry<String, Object> functionMapEntry =
272 (Map.Entry<String, Object>) ((Map) attributeVal).entrySet().iterator().next();
273 Optional<FunctionTranslation> functionTranslationInstance =
274 FunctionTranslationFactory.getInstance(functionMapEntry.getKey());
275 if (functionTranslationInstance.isPresent()) {
276 functionTranslator.setFunctionValue(functionMapEntry.getValue());
277 return functionTranslationInstance.get().translateFunction(functionTranslator);
279 Map<String, Object> attrValueMap = new HashMap<>();
280 for (Map.Entry<String, Object> entry : ((Map<String, Object>) attributeVal).entrySet()) {
281 attrValueMap.put(entry.getKey(), getToscaAttributeValue(functionTranslator, entry.getValue()));
284 } else if (attributeVal instanceof List && !((List) attributeVal).isEmpty()) {
285 List<Object> propertyValueArray = new ArrayList<>();
286 for (int i = 0; i < ((List) attributeVal).size(); i++) {
287 propertyValueArray.add(getToscaAttributeValue(functionTranslator, ((List) attributeVal).get(i)));
289 return propertyValueArray;
295 public Object translateFunction(FunctionTranslator functionTranslator) {
297 List<Object> attributeFunctionExpression = translateGetAttributeFunctionExpression(functionTranslator);
298 if (functionTranslator.isResourceSupported(attributeFunctionExpression.get(0).toString())
299 && functionTranslator.isAttributeSupported(attributeFunctionExpression.get(0).toString())) {
300 Map<String, Object> getAttrValue = new HashMap<>();
301 getAttrValue.put(ToscaFunctions.GET_ATTRIBUTE.getFunctionName(), attributeFunctionExpression);
302 returnValue = getAttrValue;
304 returnValue = attributeFunctionExpression;