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.resourcetranslation;
19 import static org.openecomp.sdc.heat.services.HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME;
20 import static org.openecomp.sdc.heat.services.HeatConstants.RESOURCE_GROUP_INDEX_VAR_DEFAULT_VALUE;
22 import java.util.ArrayList;
23 import java.util.HashMap;
24 import java.util.List;
26 import java.util.Objects;
27 import java.util.Optional;
29 import org.onap.sdc.tosca.datatypes.model.NodeTemplate;
30 import org.openecomp.sdc.common.errors.CoreException;
31 import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
32 import org.openecomp.sdc.heat.datatypes.model.Resource;
33 import org.openecomp.sdc.heat.services.HeatConstants;
34 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
35 import org.openecomp.sdc.tosca.services.DataModelUtil;
36 import org.openecomp.sdc.tosca.services.ToscaConstants;
37 import org.openecomp.sdc.tosca.services.ToscaUtil;
38 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslateTo;
39 import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil;
40 import org.openecomp.sdc.translator.services.heattotosca.ResourceTranslationFactory;
41 import org.openecomp.sdc.translator.services.heattotosca.errors.InvalidPropertyValueErrorBuilder;
42 import org.openecomp.sdc.translator.services.heattotosca.mapping.TranslatorHeatToToscaPropertyConverter;
44 public class ResourceTranslationResourceGroupImpl extends ResourceTranslationBase {
46 private static final String NESTED_RESOURCE_METADATA = "metadata";
49 protected void translate(TranslateTo translateTo) {
50 final String heatFileName = translateTo.getHeatFileName();
52 translateTo.getResource().getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
53 Resource nestedResource = new Resource();
54 Object typeDefinition = ((Map) resourceDef).get(RESOURCE_DEF_TYPE_PROPERTY_NAME);
55 if (!(typeDefinition instanceof String)) {
56 logger.warn("Resource '{}' of type '{}' with resourceDef which is not pointing to nested heat file is not"
57 + " supported and will be ignored in the translation ", translateTo.getResourceId(),
58 HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource());
61 String type = (String) typeDefinition;
62 if (!HeatToToscaUtil.isYmlFileType(type)) {
63 logger.warn("Resource '{}' of type '{}' with resourceDef which is not pointing to nested heat file is not"
64 + " supported and will be ignored in the translation ", translateTo.getResourceId(),
65 HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource());
69 nestedResource.setType(type);
70 nestedResource.setProperties((Map<String, Object>) ((Map) resourceDef).get(HeatConstants
71 .RESOURCE_DEF_PROPERTIES));
72 nestedResource.setMetadata(((Map) resourceDef).get(NESTED_RESOURCE_METADATA));
74 Optional<String> substitutionNodeTemplateId =
75 ResourceTranslationFactory.getInstance(nestedResource)
76 .translateResource(heatFileName, translateTo.getServiceTemplate(),
77 translateTo.getHeatOrchestrationTemplate(), nestedResource,
78 translateTo.getResourceId(), translateTo.getContext());
80 substitutionNodeTemplateId.ifPresent(nodeTemplateId -> addSubstitutionNodeTemplate(translateTo,
84 private void addSubstitutionNodeTemplate(TranslateTo translateTo, String substitutionNodeTemplateId) {
85 NodeTemplate substitutionNodeTemplate =
86 DataModelUtil.getNodeTemplate(translateTo.getServiceTemplate(), substitutionNodeTemplateId);
87 if (Objects.isNull(substitutionNodeTemplate)) {
90 Map<String, Object> serviceTemplateFilter = (Map<String, Object>) substitutionNodeTemplate
91 .getProperties().get(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME);
92 populateServiceTemplateFilterProperties(translateTo, substitutionNodeTemplate, serviceTemplateFilter);
93 handlingIndexVar(translateTo, substitutionNodeTemplate);
94 DataModelUtil.addNodeTemplate(translateTo.getServiceTemplate(), substitutionNodeTemplateId,
95 substitutionNodeTemplate);
98 private void handlingIndexVar(TranslateTo translateTo, NodeTemplate substitutionNodeTemplate) {
99 List<String> indexVarProperties = new ArrayList<>();
100 String indexVarValue = getIndexVarValue(translateTo);
101 replacePropertiesIndexVarValue(indexVarValue, substitutionNodeTemplate.getProperties(), indexVarProperties,
103 //Add index var properties to context for unified model later
104 translateTo.getContext().addIndexVarProperties(ToscaUtil.getServiceTemplateFileName(translateTo
105 .getServiceTemplate()), translateTo.getTranslatedId(), indexVarProperties);
108 private Map<String, List<String>> getNewIndexVarValue() {
109 final Map<String, List<String>> newIndexVarValue = new HashMap<>();
110 List<String> indexVarValList = new ArrayList<>();
111 indexVarValList.add(ToscaConstants.MODELABLE_ENTITY_NAME_SELF);
112 indexVarValList.add(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME);
113 indexVarValList.add(ToscaConstants.INDEX_VALUE_PROPERTY_NAME);
114 newIndexVarValue.put(ToscaFunctions.GET_PROPERTY.getDisplayName(), indexVarValList);
115 return newIndexVarValue;
118 private void replacePropertiesIndexVarValue(String indexVarValue,
119 Map<String, Object> properties,
120 List<String> indexVarProperties,
121 TranslateTo translateTo) {
122 if (properties == null || properties.isEmpty()) {
126 for (Map.Entry<String, Object> propertyEntry : properties.entrySet()) {
127 Object propertyValue = propertyEntry.getValue();
128 if (propertyValue != null && propertyValue.equals(RESOURCE_GROUP_INDEX_VAR_DEFAULT_VALUE)) {
129 indexVarProperties.add(propertyEntry.getKey());
131 Object newPropertyValue = getUpdatedPropertyValueWithIndex(indexVarValue, propertyValue,
132 indexVarProperties, translateTo);
133 if (newPropertyValue != null) {
134 properties.put(propertyEntry.getKey(), newPropertyValue);
139 private Object getUpdatedPropertyValueWithIndex(String indexVarValue, Object propertyValue,
140 List<String> indexVarProperties,
141 TranslateTo translateTo) {
142 if (propertyValue instanceof String) {
143 return handleStringPropertyValueWithIndex(indexVarValue, propertyValue);
144 } else if (propertyValue instanceof Map && !((Map) propertyValue).isEmpty()) {
145 return handleMapPropertyValueWithIndex(indexVarValue, propertyValue, indexVarProperties, translateTo);
146 } else if (propertyValue instanceof List && !((List) propertyValue).isEmpty()) {
147 return handleListPropertyValueWithIndex(indexVarValue, (List) propertyValue, indexVarProperties,
150 return propertyValue;
153 private Object handleListPropertyValueWithIndex(String indexVarValue, List propertyValue,
154 List<String> indexVarProperties, TranslateTo translateTo) {
155 List<Object> newPropertyValueList = new ArrayList<>();
156 for (Object entry : propertyValue) {
157 newPropertyValueList.add(getUpdatedPropertyValueWithIndex(indexVarValue, entry,
158 indexVarProperties, translateTo));
160 return newPropertyValueList;
163 private Object handleMapPropertyValueWithIndex(String indexVarValue, Object propertyValue,
164 List<String> indexVarProperties, TranslateTo translateTo) {
165 replacePropertiesIndexVarValue(indexVarValue, (Map<String, Object>) propertyValue, indexVarProperties,
167 return propertyValue;
170 private Object handleStringPropertyValueWithIndex(String indexVarValue, Object propertyValue) {
171 if (propertyValue.equals(indexVarValue)) {
172 return getNewIndexVarValue();
174 if (((String) propertyValue).contains(indexVarValue)) {
175 Map<String, List<Object>> concatMap = new HashMap<>();
176 List<Object> concatList = new ArrayList<>();
177 String value = (String) propertyValue;
179 while (value.contains(indexVarValue)) {
180 if (value.indexOf(indexVarValue) == 0) {
181 concatList.add(getNewIndexVarValue());
182 value = value.substring(indexVarValue.length());
184 int end = value.indexOf(indexVarValue);
185 concatList.add(value.substring(0, end));
186 value = value.substring(end);
189 if (!value.isEmpty()) {
190 concatList.add(value);
193 concatMap.put(ToscaFunctions.CONCAT.getDisplayName(), concatList);
196 return propertyValue; //no update is needed
199 private String getIndexVarValue(TranslateTo translateTo) {
200 Object indexVar = translateTo.getResource().getProperties().get(HeatConstants.INDEX_PROPERTY_NAME);
201 if (indexVar == null) {
202 return HeatConstants.RESOURCE_GROUP_INDEX_VAR_DEFAULT_VALUE;
205 if (indexVar instanceof String) {
206 return (String) indexVar;
208 throw new CoreException(
209 new InvalidPropertyValueErrorBuilder(HeatConstants.INDEX_PROPERTY_NAME,
210 indexVar.toString(), "String").build());
213 private void populateServiceTemplateFilterProperties(TranslateTo translateTo,
214 NodeTemplate substitutionNodeTemplate,
215 Map<String, Object> serviceTemplateFilter) {
216 boolean mandatory = false;
217 Object countValue = TranslatorHeatToToscaPropertyConverter
218 .getToscaPropertyValue(translateTo.getServiceTemplate(), translateTo.getResourceId(),
219 ToscaConstants.COUNT_PROPERTY_NAME, translateTo.getResource().getProperties()
220 .get(ToscaConstants.COUNT_PROPERTY_NAME), null,
221 translateTo.getHeatFileName(), translateTo.getHeatOrchestrationTemplate(),
222 substitutionNodeTemplate, translateTo.getContext());
224 if (countValue != null) {
225 serviceTemplateFilter.put(ToscaConstants.COUNT_PROPERTY_NAME, countValue);
227 serviceTemplateFilter.put(ToscaConstants.COUNT_PROPERTY_NAME, 1);
229 if (countValue instanceof Integer && (Integer) countValue > 0) {
232 if (countValue == null) {
235 serviceTemplateFilter.put(ToscaConstants.MANDATORY_PROPERTY_NAME, mandatory);