Refactor Onboarding Translator code
[sdc.git] / openecomp-be / lib / openecomp-sdc-translator-lib / openecomp-sdc-translator-core / src / main / java / org / openecomp / sdc / translator / services / heattotosca / impl / resourcetranslation / ResourceTranslationResourceGroupImpl.java
1 /*
2  * Copyright © 2016-2018 European Support Limited
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 package org.openecomp.sdc.translator.services.heattotosca.impl.resourcetranslation;
18
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;
21
22 import java.util.ArrayList;
23 import java.util.HashMap;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Objects;
27 import java.util.Optional;
28
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;
43
44 public class ResourceTranslationResourceGroupImpl extends ResourceTranslationBase {
45
46     private static final String NESTED_RESOURCE_METADATA = "metadata";
47
48     @Override
49     protected void translate(TranslateTo translateTo) {
50         final String heatFileName = translateTo.getHeatFileName();
51         Object resourceDef =
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());
59             return;
60         }
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());
66             return;
67         }
68
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));
73
74         Optional<String> substitutionNodeTemplateId =
75                 ResourceTranslationFactory.getInstance(nestedResource)
76                     .translateResource(heatFileName, translateTo.getServiceTemplate(),
77                     translateTo.getHeatOrchestrationTemplate(), nestedResource,
78                     translateTo.getResourceId(), translateTo.getContext());
79
80         substitutionNodeTemplateId.ifPresent(nodeTemplateId -> addSubstitutionNodeTemplate(translateTo,
81                 nodeTemplateId));
82     }
83
84     private void addSubstitutionNodeTemplate(TranslateTo translateTo, String substitutionNodeTemplateId) {
85         NodeTemplate substitutionNodeTemplate =
86                 DataModelUtil.getNodeTemplate(translateTo.getServiceTemplate(), substitutionNodeTemplateId);
87         if (Objects.isNull(substitutionNodeTemplate)) {
88             return;
89         }
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);
96     }
97
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,
102                 translateTo);
103         //Add index var properties to context for unified model later
104         translateTo.getContext().addIndexVarProperties(ToscaUtil.getServiceTemplateFileName(translateTo
105                 .getServiceTemplate()), translateTo.getTranslatedId(), indexVarProperties);
106     }
107
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;
116     }
117
118     private void replacePropertiesIndexVarValue(String indexVarValue,
119                                                 Map<String, Object> properties,
120                                                 List<String> indexVarProperties,
121                                                 TranslateTo translateTo) {
122         if (properties == null || properties.isEmpty()) {
123             return;
124         }
125
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());
130             }
131             Object newPropertyValue = getUpdatedPropertyValueWithIndex(indexVarValue, propertyValue,
132                     indexVarProperties, translateTo);
133             if (newPropertyValue != null) {
134                 properties.put(propertyEntry.getKey(), newPropertyValue);
135             }
136         }
137     }
138
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,
148                 translateTo);
149         }
150         return propertyValue;
151     }
152
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));
159         }
160         return newPropertyValueList;
161     }
162
163     private Object handleMapPropertyValueWithIndex(String indexVarValue, Object propertyValue,
164                                                    List<String> indexVarProperties, TranslateTo translateTo) {
165         replacePropertiesIndexVarValue(indexVarValue, (Map<String, Object>) propertyValue, indexVarProperties,
166                 translateTo);
167         return propertyValue;
168     }
169
170     private Object handleStringPropertyValueWithIndex(String indexVarValue, Object propertyValue) {
171         if (propertyValue.equals(indexVarValue)) {
172             return getNewIndexVarValue();
173         }
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;
178
179             while (value.contains(indexVarValue)) {
180                 if (value.indexOf(indexVarValue) == 0) {
181                     concatList.add(getNewIndexVarValue());
182                     value = value.substring(indexVarValue.length());
183                 } else {
184                     int end = value.indexOf(indexVarValue);
185                     concatList.add(value.substring(0, end));
186                     value = value.substring(end);
187                 }
188             }
189             if (!value.isEmpty()) {
190                 concatList.add(value);
191             }
192
193             concatMap.put(ToscaFunctions.CONCAT.getDisplayName(), concatList);
194             return concatMap;
195         }
196         return propertyValue; //no update is needed
197     }
198
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;
203         }
204
205         if (indexVar instanceof String) {
206             return (String) indexVar;
207         }
208         throw new CoreException(
209             new InvalidPropertyValueErrorBuilder(HeatConstants.INDEX_PROPERTY_NAME,
210                     indexVar.toString(), "String").build());
211     }
212
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());
223
224         if (countValue != null) {
225             serviceTemplateFilter.put(ToscaConstants.COUNT_PROPERTY_NAME, countValue);
226         } else {
227             serviceTemplateFilter.put(ToscaConstants.COUNT_PROPERTY_NAME, 1);
228         }
229         if (countValue instanceof Integer && (Integer) countValue > 0) {
230             mandatory = true;
231         }
232         if (countValue == null) {
233             mandatory = true;
234         }
235         serviceTemplateFilter.put(ToscaConstants.MANDATORY_PROPERTY_NAME, mandatory);
236     }
237 }