2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.openecomp.sdc.translator.services.heattotosca.impl.functiontranslation;
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;
44 import java.util.ArrayList;
45 import java.util.HashMap;
46 import java.util.HashSet;
47 import java.util.List;
49 import java.util.Optional;
51 import java.util.stream.Collectors;
53 public class FunctionTranslationGetAttrImpl implements FunctionTranslation {
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,
67 if (FunctionTranslationHelper.isResourceSupported(attributeFunctionExpression.get(0).toString())
68 && FunctionTranslationHelper.isAttributeSupported(attributeFunctionExpression.get(0)
71 .put(ToscaFunctions.GET_ATTRIBUTE.getDisplayName(), attributeFunctionExpression);
73 returnValue = attributeFunctionExpression;
79 private static List<Object> translateGetAttributeFunctionExpression(
80 ServiceTemplate serviceTemplate,
85 HeatOrchestrationTemplate heatOrchestrationTemplate,
86 NodeTemplate nodeTemplate,
87 TranslationContext context) {
89 List<Object> attributeParamList = (List) functionValue;
90 List<Object> toscaAttributeParamList = new ArrayList<>();
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,
100 if (!targetResourceTranslatedId.isPresent()) {
101 //unsupported resource
102 toscaAttributeParamList
104 FunctionTranslationHelper.getUnsupportedResourcePrefix() + attributeParamList.get(0));
105 return toscaAttributeParamList;
107 toscaAttributeParamList.add(targetResourceTranslatedId.get());
110 Optional<List<Object>> toscaAttList =
111 handleAttributeName(attributeParamList, heatOrchestrationTemplate, propertyName,
112 heatFileName, serviceTemplate,
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;
122 toscaAttributeParamList.addAll(toscaAttList.get());
124 handleGetAttrConsolidationData(serviceTemplate, resourceId, propertyName, heatFileName,
125 heatOrchestrationTemplate, context, targetResourceId,
126 targetResourceTranslatedId,
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);
137 return toscaAttributeParamList;
140 private static void handleGetAttrConsolidationData(
141 ServiceTemplate serviceTemplate,
142 String resourceId, String propertyName,
144 HeatOrchestrationTemplate heatOrchestrationTemplate,
145 TranslationContext context,
146 String targetResourceId,
147 Optional<String> targetResourceTranslatedId,
148 List<Object> toscaAttList) {
150 Optional<String> resourceTranslatedId = Optional.empty();
151 if (resourceId != null) {
152 resourceTranslatedId =
153 handleResourceName(resourceId, heatFileName, heatOrchestrationTemplate,
156 .ifPresent(resourceTranslatedIdValue -> handleGetAttrOutConsolidationData(serviceTemplate,
158 heatOrchestrationTemplate, context, resourceId, targetResourceTranslatedId.get(),
159 resourceTranslatedIdValue, toscaAttList, heatFileName));
162 if (targetResourceTranslatedId.isPresent()) {
163 handleGetAttrInConsolidationData(serviceTemplate, resourceId, resourceTranslatedId,
164 propertyName, heatOrchestrationTemplate, context, targetResourceId,
165 targetResourceTranslatedId.get(), toscaAttList, heatFileName);
169 private static void handleGetAttrOutConsolidationData(
170 ServiceTemplate serviceTemplate,
172 HeatOrchestrationTemplate heatOrchestrationTemplate,
173 TranslationContext context,
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);
191 private static void handleGetAttrInConsolidationData(
192 ServiceTemplate serviceTemplate,
194 Optional<String> resourceTranslatedId,
196 HeatOrchestrationTemplate heatOrchestrationTemplate,
197 TranslationContext context,
198 String targetResourceId,
199 String targetResourceTranslatedId,
200 List<Object> toscaAttList,
201 String heatFileName) {
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,
212 resourceId, entityConsolidationData.get(), attName);
214 ConsolidationDataUtil
215 .updateOutputGetAttributeInConsolidationData(entityConsolidationData.get(),
216 propertyName, attName);
222 private static void handleNodeGetAttrOut(String nodeTemplateId, String propertyName,
223 HeatOrchestrationTemplate heatOrchestrationTemplate,
224 TranslationContext context, String resourceId,
225 EntityConsolidationData entityConsolidationData,
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);
234 ConsolidationDataUtil
235 .updateNodeGetAttributeOut(entityConsolidationData,
236 nodeTemplateId, toscaPropertyName, attName);
239 private static void handleNodeGetAttrIn(String nodeTemplateId, String propertyName,
240 HeatOrchestrationTemplate heatOrchestrationTemplate,
241 TranslationContext context, String resourceId,
242 EntityConsolidationData entityConsolidationData,
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);
251 ConsolidationDataUtil
252 .updateNodeGetAttributeIn(entityConsolidationData,
253 nodeTemplateId, toscaPropertyName, attName);
256 private static Optional<EntityConsolidationData> getEntityConsolidationData(
257 ServiceTemplate serviceTemplate,
258 HeatOrchestrationTemplate heatOrchestrationTemplate,
259 TranslationContext context,
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);
269 nodeTypeNameExtractor.extractNodeTypeName(
270 resource, resourceId, context.getTranslatedIds().get(heatFileName).get(resourceId));
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));
282 return Optional.empty();
285 private static Optional<List<Object>> handleAttributeIndexOrKey(
286 ServiceTemplate serviceTemplate,
287 String resourceId, String propertyName,
289 List<Object> attributeParamList,
290 TranslationContext context,
292 HeatOrchestrationTemplate heatOrchestrationTemplate) {
294 List<Object> attributeIndexOrKey = new ArrayList<>();
295 if (attributeParamList.size() < 3) {
296 return Optional.empty();
299 Object attributeName = attributeParamList.get(1);
300 for (int i = 2; i < attributeParamList.size(); i++) {
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));
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);
316 attributeIndexOrKey.add(toscaAttributeName);
320 return Optional.of(attributeIndexOrKey);
323 private static String getAttributeFullPath(List<Object> attributeParamList, int attributeIndex) {
324 if (attributeParamList.size() < 3) {
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))) {
333 attributeFullPath.append(ConfigConstants.TRANS_MAPPING_DELIMITER_CHAR);
334 attributeFullPath.append(attributeParamList.get(j));
336 return attributeFullPath.toString();
339 private static boolean isInteger(Object inputNumber) {
340 if (inputNumber == null) {
345 Integer.parseInt(String.valueOf(inputNumber));
347 } catch (NumberFormatException exception) {
350 if(StringUtils.isNumeric(String.valueOf(inputNumber))){
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);
365 private static Optional<List<Object>> handleAttributeName(List<Object> attributeParamList,
366 HeatOrchestrationTemplate
367 heatOrchestrationTemplate,
370 ServiceTemplate serviceTemplate,
371 TranslationContext context) {
372 String resourceId = (String) attributeParamList.get(0);
374 HeatToToscaUtil.getResource(heatOrchestrationTemplate, resourceId, heatFileName);
376 if (attributeParamList.size() == 1) {
377 return getResourceTranslatedAttributesList(resource, context);
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();
392 if (HeatToToscaUtil.isNestedResource(resource)) {
393 return getNestedResourceTranslatedAttribute((String) attributeParamList.get(1));
395 return getResourceTranslatedAttribute(resource, (String) attributeParamList.get(1), context);
399 private static Optional<List<Object>> getNestedResourceTranslatedAttribute(String attributeName) {
400 List<Object> translatedAttributesList = new ArrayList<>();
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]));
410 return Optional.empty();
413 translatedAttributesList.add(attributeName);
415 return Optional.of(translatedAttributesList);
418 private static Optional<List<Object>> getResourceTranslatedAttributesList(Resource resource,
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();
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);
434 Map<String, String> resourceMappingAttributes =
435 context.getElementMapping(resource.getType(), Constants.ATTR);
436 if (resourceMappingAttributes == null) {
437 return Optional.empty();
439 Set<String> mappingAttributes = new HashSet<>();
441 .addAll(resourceMappingAttributes.values().stream().collect(Collectors.toList()));
442 translatedAttributes.addAll(mappingAttributes);
443 return Optional.of(translatedAttributes);
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();
461 private static Object getToscaAttributeValue(ServiceTemplate serviceTemplate,
462 String resourceId, String propertyName,
463 Object attributeVal, String resourceType,
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);
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));
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));
491 return propertyValueArray;