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.datatypes.heattotosca.to.TranslateTo;
39 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.EntityConsolidationData;
40 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.SubInterfaceTemplateConsolidationData;
41 import org.openecomp.sdc.translator.services.heattotosca.ConsolidationDataUtil;
42 import org.openecomp.sdc.translator.services.heattotosca.Constants;
43 import org.openecomp.sdc.translator.services.heattotosca.FunctionTranslation;
44 import org.openecomp.sdc.translator.services.heattotosca.FunctionTranslationFactory;
45 import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil;
46 import org.openecomp.sdc.translator.services.heattotosca.NameExtractor;
47 import org.openecomp.sdc.translator.services.heattotosca.impl.resourcetranslation.ResourceTranslationBase;
49 public class FunctionTranslationGetAttrImpl implements FunctionTranslation {
51 private static List<Object> translateGetAttributeFunctionExpression(FunctionTranslator functionTranslator) {
53 List<Object> attributeParamList = (List) functionTranslator.getFunctionValue();
54 List<Object> toscaAttributeParamList = new ArrayList<>();
56 Optional<String> targetResourceTranslatedId = Optional.empty();
57 String targetResourceId = null;
58 if (attributeParamList.get(0) instanceof String) {
59 targetResourceId = (String) attributeParamList.get(0);
60 targetResourceTranslatedId = handleResourceName(targetResourceId, functionTranslator.getHeatFileName(),
61 functionTranslator.getHeatOrchestrationTemplate(), functionTranslator.getContext());
63 if (!targetResourceTranslatedId.isPresent()) {
64 //unsupported resource
65 toscaAttributeParamList.add(functionTranslator.getUnsupportedResourcePrefix() + attributeParamList.get(0));
66 return toscaAttributeParamList;
68 toscaAttributeParamList.add(targetResourceTranslatedId.get());
69 Optional<List<Object>> toscaAttList = handleAttributeName(attributeParamList, functionTranslator);
70 if (!toscaAttList.isPresent()) {
71 //Unsupported attribute
72 toscaAttributeParamList.clear();
73 toscaAttributeParamList.add(functionTranslator.getUnsupportedAttributePrefix()
74 + attributeParamList.get(0) + "." + attributeParamList.get(1));
75 return toscaAttributeParamList;
77 toscaAttributeParamList.addAll(toscaAttList.get());
78 handleGetAttrConsolidationData(functionTranslator, targetResourceId, targetResourceTranslatedId.get(),
81 String resourceType = HeatToToscaUtil.getResourceType((String) attributeParamList.get(0), functionTranslator
82 .getHeatOrchestrationTemplate(), functionTranslator.getHeatFileName());
83 Optional<List<Object>> toscaIndexOrKey = handleAttributeIndexOrKey(functionTranslator, resourceType,
85 toscaIndexOrKey.ifPresent(toscaAttributeParamList::addAll);
86 return toscaAttributeParamList;
89 private static void handleGetAttrConsolidationData(FunctionTranslator functionTranslator,
90 String targetResourceId,
91 String targetResourceTranslatedId,
92 List<Object> toscaAttList) {
94 Optional<String> resourceTranslatedId;
95 String resourceId = functionTranslator.getResourceId();
96 String resourceTranslatedIdValue = null;
97 if (resourceId != null) {
98 resourceTranslatedId = handleResourceName(resourceId, functionTranslator.getHeatFileName(),
99 functionTranslator.getHeatOrchestrationTemplate(), functionTranslator.getContext());
100 if (resourceTranslatedId.isPresent()) {
101 resourceTranslatedIdValue = resourceTranslatedId.get();
102 handleGetAttrOutConsolidationData(functionTranslator, targetResourceTranslatedId,
103 resourceTranslatedIdValue, toscaAttList);
106 handleGetAttrInConsolidationData(functionTranslator, resourceTranslatedIdValue, targetResourceId,
107 targetResourceTranslatedId, toscaAttList);
110 private static void handleGetAttrOutConsolidationData(FunctionTranslator functionTranslator,
111 String targetTranslatedResourceId,
112 String resourceTranslatedId,
113 List<Object> toscaAttList) {
114 if (functionTranslator.getServiceTemplate() == null) {
117 Optional<EntityConsolidationData> entityConsolidationData = getEntityConsolidationData(functionTranslator,
118 functionTranslator.getResourceId(), resourceTranslatedId);
119 if (entityConsolidationData.isPresent()) {
120 String attName = (String) toscaAttList.get(0);
121 handleNodeGetAttrOut(targetTranslatedResourceId, functionTranslator, entityConsolidationData.get(),
126 private static void handleGetAttrInConsolidationData(FunctionTranslator functionTranslator,
127 String resourceTranslatedId,
128 String targetResourceId,
129 String targetResourceTranslatedId,
130 List<Object> toscaAttList) {
131 if (functionTranslator.getServiceTemplate() == null) {
134 Optional<EntityConsolidationData> entityConsolidationData = getEntityConsolidationData(functionTranslator,
135 targetResourceId, targetResourceTranslatedId);
136 if (!entityConsolidationData.isPresent()) {
139 String attName = (String) toscaAttList.get(0);
140 if (Objects.nonNull(resourceTranslatedId)) {
141 handleNodeGetAttrIn(resourceTranslatedId, functionTranslator, entityConsolidationData.get(), attName);
143 ConsolidationDataUtil.updateOutputGetAttributeInConsolidationData(entityConsolidationData.get(),
144 functionTranslator.getPropertyName(), attName);
148 private static void handleNodeGetAttrOut(String nodeTemplateId, FunctionTranslator functionTranslator,
149 EntityConsolidationData entityConsolidationData,
151 Resource resource = functionTranslator.getHeatOrchestrationTemplate().getResources().get(functionTranslator
153 boolean isNestedResource = HeatToToscaUtil.isNestedResource(resource);
154 String toscaPropertyName = functionTranslator.getPropertyName();
155 if (!isNestedResource) {
156 toscaPropertyName = HeatToToscaUtil.getToscaPropertyName(functionTranslator.getContext(), resource
157 .getType(), functionTranslator.getPropertyName());
159 ConsolidationDataUtil.updateNodeGetAttributeOut(entityConsolidationData, nodeTemplateId, toscaPropertyName,
163 private static void handleNodeGetAttrIn(String nodeTemplateId, FunctionTranslator functionTranslator,
164 EntityConsolidationData entityConsolidationData,
166 Resource resource = functionTranslator.getHeatOrchestrationTemplate().getResources().get(functionTranslator
168 boolean isNestedResource = HeatToToscaUtil.isNestedResource(resource);
169 String propertyName = functionTranslator.getPropertyName();
170 String heatPropertyName = propertyName;
171 String toscaPropertyName = propertyName;
172 //For handling get_attr in inner levels for complex properties
173 if (propertyName.contains(TRANS_MAPPING_DELIMITER_CHAR)) {
174 heatPropertyName = propertyName.substring(0, propertyName.indexOf(TRANS_MAPPING_DELIMITER_CHAR));
176 if (!isNestedResource) {
177 toscaPropertyName = HeatToToscaUtil.getToscaPropertyName(functionTranslator.getContext(), resource
178 .getType(), heatPropertyName);
180 ConsolidationDataUtil.updateNodeGetAttributeIn(entityConsolidationData, nodeTemplateId, toscaPropertyName,
184 private static Optional<EntityConsolidationData> getEntityConsolidationData(FunctionTranslator functionTranslator,
186 String resourceTranslatedId) {
187 HeatOrchestrationTemplate heatOrchestrationTemplate = functionTranslator.getHeatOrchestrationTemplate();
188 TranslationContext context = functionTranslator.getContext();
189 ServiceTemplate serviceTemplate = functionTranslator.getServiceTemplate();
190 String heatFileName = functionTranslator.getHeatFileName();
192 Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
193 if (ConsolidationDataUtil.isComputeResource(heatOrchestrationTemplate, resourceId)) {
194 String resourceType = heatOrchestrationTemplate.getResources().get(resourceId).getType();
195 NameExtractor nodeTypeNameExtractor = TranslationContext.getNameExtractorImpl(resourceType);
196 String computeType = nodeTypeNameExtractor.extractNodeTypeName(resource, resourceId, context
197 .getTranslatedIds().get(heatFileName).get(resourceId));
199 return Optional.of(ConsolidationDataUtil.getComputeTemplateConsolidationData(context, serviceTemplate,
200 computeType, resourceTranslatedId));
201 } else if (ConsolidationDataUtil.isPortResource(heatOrchestrationTemplate, resourceId)) {
202 return Optional.of(ConsolidationDataUtil
203 .getPortTemplateConsolidationData(context, serviceTemplate, resourceId, resource.getType(),
204 resourceTranslatedId));
205 } else if (HeatToToscaUtil.isSubInterfaceResource(resource, context)) {
206 TranslateTo subInterfaceTo = new TranslateTo(heatFileName, serviceTemplate, heatOrchestrationTemplate,
207 resource, resourceId, resourceTranslatedId, context);
208 Optional<SubInterfaceTemplateConsolidationData> subInterfaceTemplateConsolidationData =
209 ConsolidationDataUtil.getSubInterfaceTemplateConsolidationData(subInterfaceTo,
210 resourceTranslatedId);
211 if (subInterfaceTemplateConsolidationData.isPresent()) {
212 return Optional.of(subInterfaceTemplateConsolidationData.get());
214 } else if (HeatToToscaUtil.isNestedResource(resource)) {
215 return Optional.ofNullable(ConsolidationDataUtil
216 .getNestedTemplateConsolidationData(context, serviceTemplate, heatFileName, resourceTranslatedId));
218 return Optional.empty();
221 private static Optional<List<Object>> handleAttributeIndexOrKey(FunctionTranslator functionTranslator,
223 List<Object> attributeParamList) {
225 List<Object> attributeIndexOrKey = new ArrayList<>();
226 if (attributeParamList.size() < 3) {
227 return Optional.empty();
230 for (int i = 2; i < attributeParamList.size(); i++) {
231 if (isInteger(attributeParamList.get(i))) {
232 attributeIndexOrKey.add(attributeParamList.get(i));
233 } else if (attributeParamList.get(i) instanceof Map) {
234 attributeIndexOrKey.add(getToscaAttributeValue(functionTranslator, attributeParamList.get(i)));
236 Object toscaAttributeName = resourceType == null ? null : functionTranslator.getContext()
237 .getElementMapping(resourceType, Constants.ATTR, getAttributeFullPath(attributeParamList, i));
238 if (toscaAttributeName == null) {
239 toscaAttributeName = attributeParamList.get(i);
241 attributeIndexOrKey.add(toscaAttributeName);
245 return Optional.of(attributeIndexOrKey);
248 private static String getAttributeFullPath(List<Object> attributeParamList, int attributeIndex) {
249 if (attributeParamList.size() < 3) {
252 StringBuilder attributeFullPath = new StringBuilder();
253 attributeFullPath.append(attributeParamList.get(1));
254 for (int j = 2; j <= attributeIndex; j++) {
255 if (isInteger(attributeParamList.get(j))) {
258 attributeFullPath.append(TRANS_MAPPING_DELIMITER_CHAR);
259 attributeFullPath.append(attributeParamList.get(j));
261 return attributeFullPath.toString();
264 private static boolean isInteger(Object inputNumber) {
265 if (inputNumber == null) {
268 return StringUtils.isNumeric(String.valueOf(inputNumber));
271 private static Optional<String> handleResourceName(String resourceId, String heatFileName,
272 HeatOrchestrationTemplate heatOrchestrationTemplate,
273 TranslationContext context) {
274 return ResourceTranslationBase
275 .getResourceTranslatedId(heatFileName, heatOrchestrationTemplate, resourceId, context);
278 private static Optional<List<Object>> handleAttributeName(List<Object> attributeParamList,
279 FunctionTranslator functionTranslator) {
280 String resourceId = (String) attributeParamList.get(0);
281 Resource resource = HeatToToscaUtil.getResource(functionTranslator.getHeatOrchestrationTemplate(),
282 resourceId, functionTranslator.getHeatFileName());
283 if (attributeParamList.size() == 1) {
284 return getResourceTranslatedAttributesList(resource, functionTranslator.getContext());
286 if (!(attributeParamList.get(1) instanceof String)) {
287 return Optional.empty();
289 if (HeatToToscaUtil.isNestedResource(resource)) {
290 return getNestedResourceTranslatedAttribute((String) attributeParamList.get(1));
292 return getResourceTranslatedAttribute(resource, (String) attributeParamList.get(1), functionTranslator
297 private static Optional<List<Object>> getNestedResourceTranslatedAttribute(String attributeName) {
298 List<Object> translatedAttributesList = new ArrayList<>();
299 if (attributeName.startsWith(HeatConstants.GET_ATTR_FROM_RESOURCE_GROUP_PREFIX)) {
300 String[] attributeSplit = attributeName.split("\\.");
301 if (attributeSplit.length == 2) {
302 translatedAttributesList.add(attributeSplit[1]);
303 } else if (attributeSplit.length == 3) {
304 translatedAttributesList.add(attributeSplit[2]);
305 translatedAttributesList.add(Integer.valueOf(attributeSplit[1]));
307 return Optional.empty();
310 translatedAttributesList.add(attributeName);
312 return Optional.of(translatedAttributesList);
315 private static Optional<List<Object>> getResourceTranslatedAttributesList(Resource resource,
316 TranslationContext context) {
317 List<Object> translatedAttributes = new ArrayList<>();
318 if (HeatToToscaUtil.isNestedResource(resource)) {
319 Optional<String> nestedFile = HeatToToscaUtil.getNestedFile(resource);
320 if (!nestedFile.isPresent()) {
321 return Optional.empty();
323 HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil()
324 .yamlToObject(context.getFiles().getFileContent(nestedFile.get()), HeatOrchestrationTemplate.class);
325 translatedAttributes.addAll(nestedHeatOrchestrationTemplate.getOutputs().keySet());
326 return Optional.of(translatedAttributes);
329 Map<String, String> resourceMappingAttributes =
330 context.getElementMapping(resource.getType(), Constants.ATTR);
331 if (resourceMappingAttributes == null) {
332 return Optional.empty();
334 Set<String> mappingAttributes = new HashSet<>(new ArrayList<>(resourceMappingAttributes.values()));
335 translatedAttributes.addAll(mappingAttributes);
336 return Optional.of(translatedAttributes);
340 private static Optional<List<Object>> getResourceTranslatedAttribute(Resource resource,
341 String attributeName,
342 TranslationContext context) {
343 List<Object> translatedAttributesList = new ArrayList<>();
344 String translatedAttribute = context.getElementMapping(resource.getType(), Constants.ATTR, attributeName);
345 if (translatedAttribute != null) {
346 translatedAttributesList.add(translatedAttribute);
347 return Optional.of(translatedAttributesList);
348 } else { //unsupported attribute
349 return Optional.empty();
353 private static Object getToscaAttributeValue(FunctionTranslator functionTranslator,
354 Object attributeVal) {
355 if (attributeVal instanceof Map && !((Map) attributeVal).isEmpty()) {
356 Map.Entry<String, Object> functionMapEntry =
357 (Map.Entry<String, Object>) ((Map) attributeVal).entrySet().iterator().next();
358 Optional<FunctionTranslation> functionTranslationInstance =
359 FunctionTranslationFactory.getInstance(functionMapEntry.getKey());
360 if (functionTranslationInstance.isPresent()) {
361 functionTranslator.setFunctionValue(functionMapEntry.getValue());
362 return functionTranslationInstance.get().translateFunction(functionTranslator);
364 Map<String, Object> attrValueMap = new HashMap<>();
365 for (Map.Entry<String, Object> entry : ((Map<String, Object>) attributeVal).entrySet()) {
366 attrValueMap.put(entry.getKey(), getToscaAttributeValue(functionTranslator, entry.getValue()));
369 } else if (attributeVal instanceof List && !((List) attributeVal).isEmpty()) {
370 List<Object> propertyValueArray = new ArrayList<>();
371 for (int i = 0; i < ((List) attributeVal).size(); i++) {
372 propertyValueArray.add(getToscaAttributeValue(functionTranslator, ((List) attributeVal).get(i)));
374 return propertyValueArray;
380 public Object translateFunction(FunctionTranslator functionTranslator) {
382 List<Object> attributeFunctionExpression = translateGetAttributeFunctionExpression(functionTranslator);
383 if (functionTranslator.isResourceSupported(attributeFunctionExpression.get(0).toString())
384 && functionTranslator.isAttributeSupported(attributeFunctionExpression.get(0).toString())) {
385 Map<String, Object> getAttrValue = new HashMap<>();
386 getAttrValue.put(ToscaFunctions.GET_ATTRIBUTE.getDisplayName(), attributeFunctionExpression);
387 returnValue = getAttrValue;
389 returnValue = attributeFunctionExpression;