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.openecomp.core.utilities.yaml.YamlUtil;
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.translator.datatypes.heattotosca.TranslationContext;
32 import org.openecomp.sdc.translator.datatypes.heattotosca.unifiedmodel.consolidation.EntityConsolidationData;
33 import org.openecomp.sdc.translator.services.heattotosca.ConfigConstants;
34 import org.openecomp.sdc.translator.services.heattotosca.ConsolidationDataUtil;
35 import org.openecomp.sdc.translator.services.heattotosca.Constants;
36 import org.openecomp.sdc.translator.services.heattotosca.FunctionTranslation;
37 import org.openecomp.sdc.translator.services.heattotosca.FunctionTranslationFactory;
38 import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil;
39 import org.openecomp.sdc.translator.services.heattotosca.NameExtractor;
40 import org.openecomp.sdc.translator.services.heattotosca.helper.FunctionTranslationHelper;
41 import org.openecomp.sdc.translator.services.heattotosca.impl.resourcetranslation.ResourceTranslationBase;
43 import java.util.ArrayList;
44 import java.util.HashMap;
45 import java.util.HashSet;
46 import java.util.List;
48 import java.util.Optional;
50 import java.util.stream.Collectors;
52 public class FunctionTranslationGetAttrImpl implements FunctionTranslation {
56 public Object translateFunction(ServiceTemplate serviceTemplate,
57 String resourceId, String propertyName, String functionKey,
58 Object functionValue, String heatFileName,
59 HeatOrchestrationTemplate heatOrchestrationTemplate,
60 Template toscaTemplate, TranslationContext context) {
61 Object returnValue = new HashMap<>();
62 List<Object> attributeFunctionExpression =
63 translateGetAttributeFunctionExpression(serviceTemplate, resourceId, functionValue,
64 propertyName, heatFileName, heatOrchestrationTemplate, (NodeTemplate) toscaTemplate,
66 if (FunctionTranslationHelper.isResourceSupported(attributeFunctionExpression.get(0).toString())
67 && FunctionTranslationHelper.isAttributeSupported(attributeFunctionExpression.get(0)
70 .put(ToscaFunctions.GET_ATTRIBUTE.getDisplayName(), attributeFunctionExpression);
72 returnValue = attributeFunctionExpression;
78 private static List<Object> translateGetAttributeFunctionExpression(
79 ServiceTemplate serviceTemplate,
84 HeatOrchestrationTemplate heatOrchestrationTemplate,
85 NodeTemplate nodeTemplate,
86 TranslationContext context) {
88 List<Object> attributeParamList = (List) functionValue;
89 List<Object> toscaAttributeParamList = new ArrayList<>();
91 Optional<String> targetResourceTranslatedId = Optional.empty();
92 String targetResourceId = null;
93 if( attributeParamList.get(0) instanceof String) {
94 targetResourceId = (String) attributeParamList.get(0);
95 targetResourceTranslatedId =
96 handleResourceName(targetResourceId, heatFileName, heatOrchestrationTemplate,
99 if (!targetResourceTranslatedId.isPresent()) {
100 //unsupported resource
101 toscaAttributeParamList
103 FunctionTranslationHelper.getUnsupportedResourcePrefix() + attributeParamList.get(0));
104 return toscaAttributeParamList;
106 toscaAttributeParamList.add(targetResourceTranslatedId.get());
109 Optional<List<Object>> toscaAttList =
110 handleAttributeName(attributeParamList, heatOrchestrationTemplate, propertyName,
111 heatFileName, serviceTemplate,
113 if (!toscaAttList.isPresent()) {
114 //Unsupported attribute
115 toscaAttributeParamList.clear();
116 toscaAttributeParamList
117 .add(FunctionTranslationHelper.getUnsupportedAttributePrefix() + attributeParamList.get(0)
118 + "." + attributeParamList.get(1));
119 return toscaAttributeParamList;
121 toscaAttributeParamList.addAll(toscaAttList.get());
123 handleGetAttrConsolidationData(serviceTemplate, resourceId, propertyName, heatFileName,
124 heatOrchestrationTemplate, context, targetResourceId,
125 targetResourceTranslatedId,
129 Optional<List<Object>> toscaIndexOrKey = handleAttributeIndexOrKey(serviceTemplate,
130 resourceId, propertyName, HeatToToscaUtil
131 .getResourceType((String) attributeParamList.get(0), heatOrchestrationTemplate,
132 heatFileName), attributeParamList, context, heatFileName,
133 heatOrchestrationTemplate);
134 toscaIndexOrKey.ifPresent(toscaAttributeParamList::addAll);
136 return toscaAttributeParamList;
139 private static void handleGetAttrConsolidationData(
140 ServiceTemplate serviceTemplate,
141 String resourceId, String propertyName,
143 HeatOrchestrationTemplate heatOrchestrationTemplate,
144 TranslationContext context,
145 String targetResourceId,
146 Optional<String> targetResourceTranslatedId,
147 List<Object> toscaAttList) {
149 Optional<String> resourceTranslatedId = Optional.empty();
150 if (resourceId != null) {
151 resourceTranslatedId =
152 handleResourceName(resourceId, heatFileName, heatOrchestrationTemplate,
155 .ifPresent(resourceTranslatedIdValue -> handleGetAttrOutConsolidationData(serviceTemplate,
157 heatOrchestrationTemplate, context, resourceId, targetResourceTranslatedId.get(),
158 resourceTranslatedIdValue, toscaAttList, heatFileName));
161 if (targetResourceTranslatedId.isPresent()) {
162 handleGetAttrInConsolidationData(serviceTemplate, resourceId, resourceTranslatedId,
163 propertyName, heatOrchestrationTemplate, context, targetResourceId,
164 targetResourceTranslatedId.get(), toscaAttList, heatFileName);
168 private static void handleGetAttrOutConsolidationData(
169 ServiceTemplate serviceTemplate,
171 HeatOrchestrationTemplate heatOrchestrationTemplate,
172 TranslationContext context,
174 String targetTranslatedResourceId,
175 String resourceTranslatedId,
176 List<Object> toscaAttList,
177 String heatFileName) {
178 if (serviceTemplate != null) {
179 Optional<EntityConsolidationData> entityConsolidationData =
180 getEntityConsolidationData(serviceTemplate, heatOrchestrationTemplate, context,
181 resourceId, resourceTranslatedId, heatFileName);
182 if (entityConsolidationData.isPresent()) {
183 String attName = (String) toscaAttList.get(0);
184 handleNodeGetAttrOut(targetTranslatedResourceId, propertyName, heatOrchestrationTemplate,
185 context, resourceId, entityConsolidationData.get(), attName);
190 private static void handleGetAttrInConsolidationData(
191 ServiceTemplate serviceTemplate,
193 Optional<String> resourceTranslatedId,
195 HeatOrchestrationTemplate heatOrchestrationTemplate,
196 TranslationContext context,
197 String targetResourceId,
198 String targetResourceTranslatedId,
199 List<Object> toscaAttList,
200 String heatFileName) {
202 if (serviceTemplate != null) {
203 Optional<EntityConsolidationData> entityConsolidationData =
204 getEntityConsolidationData(serviceTemplate, heatOrchestrationTemplate, context,
205 targetResourceId, targetResourceTranslatedId, heatFileName);
206 if (entityConsolidationData.isPresent()) {
207 String attName = (String) toscaAttList.get(0);
208 if (resourceTranslatedId.isPresent()) {
209 handleNodeGetAttrIn(resourceTranslatedId.get(), propertyName, heatOrchestrationTemplate,
211 resourceId, entityConsolidationData.get(), attName);
213 ConsolidationDataUtil
214 .updateOutputGetAttributeInConsolidationData(entityConsolidationData.get(),
215 propertyName, attName);
221 private static void handleNodeGetAttrOut(String nodeTemplateId, String propertyName,
222 HeatOrchestrationTemplate heatOrchestrationTemplate,
223 TranslationContext context, String resourceId,
224 EntityConsolidationData entityConsolidationData,
226 Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
227 boolean isNestedResource = HeatToToscaUtil.isNestedResource(resource);
228 String toscaPropertyName = propertyName;
229 if (!isNestedResource) {
230 toscaPropertyName = HeatToToscaUtil.getToscaPropertyName(context, resource
231 .getType(), propertyName);
233 ConsolidationDataUtil
234 .updateNodeGetAttributeOut(entityConsolidationData,
235 nodeTemplateId, toscaPropertyName, attName);
238 private static void handleNodeGetAttrIn(String nodeTemplateId, String propertyName,
239 HeatOrchestrationTemplate heatOrchestrationTemplate,
240 TranslationContext context, String resourceId,
241 EntityConsolidationData entityConsolidationData,
243 Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
244 boolean isNestedResource = HeatToToscaUtil.isNestedResource(resource);
245 String toscaPropertyName = propertyName;
246 if (!isNestedResource) {
247 toscaPropertyName = HeatToToscaUtil.getToscaPropertyName(context, resource
248 .getType(), propertyName);
250 ConsolidationDataUtil
251 .updateNodeGetAttributeIn(entityConsolidationData,
252 nodeTemplateId, toscaPropertyName, attName);
255 private static Optional<EntityConsolidationData> getEntityConsolidationData(
256 ServiceTemplate serviceTemplate,
257 HeatOrchestrationTemplate heatOrchestrationTemplate,
258 TranslationContext context,
260 String resourceTranslatedId,
261 String heatFileName) {
262 Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
263 if (ConsolidationDataUtil.isComputeResource(heatOrchestrationTemplate, resourceId)) {
264 String resourceType = heatOrchestrationTemplate.getResources().get(resourceId).getType();
265 NameExtractor nodeTypeNameExtractor =
266 context.getNameExtractorImpl(resourceType);
268 nodeTypeNameExtractor.extractNodeTypeName(
269 resource, resourceId, context.getTranslatedIds().get(heatFileName).get(resourceId));
272 ConsolidationDataUtil.getComputeTemplateConsolidationData(context, serviceTemplate,
273 computeType, resourceId));
274 } else if (ConsolidationDataUtil.isPortResource(heatOrchestrationTemplate, resourceId)) {
275 return Optional.of(ConsolidationDataUtil
276 .getPortTemplateConsolidationData(context, serviceTemplate, resourceId));
277 } else if (HeatToToscaUtil.isNestedResource(resource)) {
278 return Optional.of(ConsolidationDataUtil
279 .getNestedTemplateConsolidationData(context, serviceTemplate, resourceId));
281 return Optional.empty();
284 private static Optional<List<Object>> handleAttributeIndexOrKey(
285 ServiceTemplate serviceTemplate,
286 String resourceId, String propertyName,
288 List<Object> attributeParamList,
289 TranslationContext context,
291 HeatOrchestrationTemplate heatOrchestrationTemplate) {
293 List<Object> attributeIndexOrKey = new ArrayList<>();
294 if (attributeParamList.size() < 3) {
295 return Optional.empty();
298 Object attributeName = attributeParamList.get(1);
299 for (int i = 2; i < attributeParamList.size(); i++) {
301 if (isInteger(attributeParamList.get(i))) {
302 attributeIndexOrKey.add(attributeParamList.get(i));
303 } else if (attributeParamList.get(i) instanceof Map) {
304 attributeIndexOrKey.add(getToscaAttributeValue(serviceTemplate, resourceId,
305 propertyName, attributeParamList.get(i), resourceType, heatFileName,
306 heatOrchestrationTemplate, null, context));
309 Object toscaAttributeName = resourceType == null ? null : context
310 .getElementMapping(resourceType, Constants.ATTR,
311 getAttributeFullPath(attributeParamList, i));
312 if (toscaAttributeName == null) {
313 toscaAttributeName = attributeParamList.get(i);
315 attributeIndexOrKey.add(toscaAttributeName);
319 return Optional.of(attributeIndexOrKey);
322 private static String getAttributeFullPath(List<Object> attributeParamList, int attributeIndex) {
323 if (attributeParamList.size() < 3) {
326 StringBuffer attributeFullPath = new StringBuffer();
327 attributeFullPath.append(attributeParamList.get(1));
328 for (int j = 2; j <= attributeIndex; j++) {
329 if (isInteger(attributeParamList.get(j))) {
332 attributeFullPath.append(ConfigConstants.TRANS_MAPPING_DELIMITER_CHAR);
333 attributeFullPath.append(attributeParamList.get(j));
335 return attributeFullPath.toString();
338 private static boolean isInteger(Object inputNumber) {
339 if (inputNumber == null) {
344 Integer.parseInt(String.valueOf(inputNumber));
346 } catch (NumberFormatException exception) {
351 private static Optional<String> handleResourceName(String resourceId, String heatFileName,
352 HeatOrchestrationTemplate
353 heatOrchestrationTemplate,
354 TranslationContext context) {
355 return ResourceTranslationBase
356 .getResourceTranslatedId(heatFileName, heatOrchestrationTemplate, resourceId, context);
359 private static Optional<List<Object>> handleAttributeName(List<Object> attributeParamList,
360 HeatOrchestrationTemplate
361 heatOrchestrationTemplate,
364 ServiceTemplate serviceTemplate,
365 TranslationContext context) {
366 String resourceId = (String) attributeParamList.get(0);
368 HeatToToscaUtil.getResource(heatOrchestrationTemplate, resourceId, heatFileName);
370 if (attributeParamList.size() == 1) {
371 return getResourceTranslatedAttributesList(resource, context);
374 if(!(attributeParamList.get(1) instanceof String)){
375 //todo - once dynamic attr name will be supported the commented line will be support it in
376 // the first translation phase.
377 // Object toscaAttributeValue = getToscaAttributeValue(serviceTemplate, resourceId, propertyName,
378 // attributeParamList.get(1), resource
379 // .getType(), heatFileName, heatOrchestrationTemplate, null, context);
380 // List<Object> dynamicAttrValue = new ArrayList<>();
381 // dynamicAttrValue.add(toscaAttributeValue);
382 // return Optional.of(dynamicAttrValue);
383 return Optional.empty();
386 if (HeatToToscaUtil.isNestedResource(resource)) {
387 return getNestedResourceTranslatedAttribute((String) attributeParamList.get(1));
389 return getResourceTranslatedAttribute(resource, (String) attributeParamList.get(1), context);
393 private static Optional<List<Object>> getNestedResourceTranslatedAttribute(String attributeName) {
394 List<Object> translatedAttributesList = new ArrayList<>();
396 if (attributeName.startsWith(HeatConstants.GET_ATTR_FROM_RESOURCE_GROUP_PREFIX)) {
397 String[] attributeSplit = attributeName.split("\\.");
398 if (attributeSplit.length == 2) {
399 translatedAttributesList.add(attributeSplit[1]);
400 } else if (attributeSplit.length == 3) {
401 translatedAttributesList.add(attributeSplit[2]);
402 translatedAttributesList.add(Integer.valueOf(attributeSplit[1]));
404 return Optional.empty();
407 translatedAttributesList.add(attributeName);
409 return Optional.of(translatedAttributesList);
412 private static Optional<List<Object>> getResourceTranslatedAttributesList(Resource resource,
415 List<Object> translatedAttributes = new ArrayList<>();
416 if (HeatToToscaUtil.isNestedResource(resource)) {
417 Optional<String> nestedFile = HeatToToscaUtil.getNestedFile(resource);
418 if (!nestedFile.isPresent()) {
419 return Optional.empty();
421 HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil()
422 .yamlToObject(context.getFiles().getFileContent(nestedFile.get()),
423 HeatOrchestrationTemplate.class);
424 translatedAttributes.addAll(nestedHeatOrchestrationTemplate.getOutputs().keySet());
425 return Optional.of(translatedAttributes);
428 Map<String, String> resourceMappingAttributes =
429 context.getElementMapping(resource.getType(), Constants.ATTR);
430 if (resourceMappingAttributes == null) {
431 return Optional.empty();
433 Set<String> mappingAttributes = new HashSet<>();
435 .addAll(resourceMappingAttributes.values().stream().collect(Collectors.toList()));
436 translatedAttributes.addAll(mappingAttributes);
437 return Optional.of(translatedAttributes);
441 private static Optional<List<Object>> getResourceTranslatedAttribute(Resource resource,
442 String attributeName,
443 TranslationContext context) {
444 List<Object> translatedAttributesList = new ArrayList<>();
445 String translatedAttribute =
446 context.getElementMapping(resource.getType(), Constants.ATTR, attributeName);
447 if (translatedAttribute != null) {
448 translatedAttributesList.add(translatedAttribute);
449 return Optional.of(translatedAttributesList);
450 } else { //unsupported attribute
451 return Optional.empty();
455 private static Object getToscaAttributeValue(ServiceTemplate serviceTemplate,
456 String resourceId, String propertyName,
457 Object attributeVal, String resourceType,
459 HeatOrchestrationTemplate heatOrchestrationTemplate,
460 Template template, TranslationContext context) {
461 if (attributeVal instanceof Map && !((Map) attributeVal).isEmpty()) {
462 Map.Entry<String, Object> functionMapEntry =
463 (Map.Entry<String, Object>) ((Map) attributeVal).entrySet().iterator().next();
464 if (FunctionTranslationFactory.getInstance(functionMapEntry.getKey()).isPresent()) {
465 return FunctionTranslationFactory.getInstance(functionMapEntry.getKey()).get()
466 .translateFunction(serviceTemplate, resourceId, propertyName,
467 functionMapEntry.getKey(), functionMapEntry
468 .getValue(), heatFileName, heatOrchestrationTemplate, template, context);
470 Map<String, Object> attrValueMap = new HashMap<>();
471 for (Map.Entry<String, Object> entry : ((Map<String, Object>) attributeVal).entrySet()) {
472 attrValueMap.put(entry.getKey(),
473 getToscaAttributeValue(serviceTemplate, resourceId, propertyName, entry.getValue(),
474 resourceType, heatFileName, heatOrchestrationTemplate, template, context));
477 } else if (attributeVal instanceof List && !((List) attributeVal).isEmpty()) {
478 List propertyValueArray = new ArrayList<>();
479 for (int i = 0; i < ((List) attributeVal).size(); i++) {
480 propertyValueArray.add(
481 getToscaAttributeValue(serviceTemplate, resourceId, propertyName,
482 ((List) attributeVal).get(i), resourceType, heatFileName,
483 heatOrchestrationTemplate, template, context));
485 return propertyValueArray;