Rename packages from openecomp to onap.
[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 org.openecomp.sdc.common.errors.CoreException;
23 import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
24 import org.openecomp.sdc.heat.datatypes.model.Resource;
25 import org.openecomp.sdc.heat.services.HeatConstants;
26 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
27 import org.onap.sdc.tosca.datatypes.model.NodeTemplate;
28 import org.openecomp.sdc.tosca.services.DataModelUtil;
29 import org.openecomp.sdc.tosca.services.ToscaConstants;
30 import org.openecomp.sdc.tosca.services.ToscaUtil;
31 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslateTo;
32 import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil;
33 import org.openecomp.sdc.translator.services.heattotosca.ResourceTranslationFactory;
34 import org.openecomp.sdc.translator.services.heattotosca.errors.InvalidPropertyValueErrorBuilder;
35 import org.openecomp.sdc.translator.services.heattotosca.mapping.TranslatorHeatToToscaPropertyConverter;
36
37 import java.util.ArrayList;
38 import java.util.HashMap;
39 import java.util.List;
40 import java.util.Map;
41 import java.util.Objects;
42 import java.util.Optional;
43
44 public class ResourceTranslationResourceGroupImpl extends ResourceTranslationBase {
45
46   @Override
47   protected void translate(TranslateTo translateTo) {
48     final String heatFileName = translateTo.getHeatFileName();
49     Object resourceDef =
50         translateTo.getResource().getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
51     Resource nestedResource = new Resource();
52     Object typeDefinition = ((Map) resourceDef).get(RESOURCE_DEF_TYPE_PROPERTY_NAME);
53     if (!(typeDefinition instanceof String)) {
54       logger.warn("Resource '" + translateTo.getResourceId() + "' of type'"
55           + HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource()
56           + "' with resourceDef which is not pointing to nested heat file is not supported and "
57           + "will be ignored in the translation ");
58       return;
59     }
60     String type = (String) typeDefinition;
61     if (!HeatToToscaUtil.isYmlFileType(type)) {
62       logger.warn("Resource '" + translateTo.getResourceId() + "' of type'"
63           + HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource()
64           + "' with resourceDef which is not pointing to nested heat file is not supported and "
65           + "will be ignored in the translation ");
66       return;
67     }
68
69     nestedResource.setType(type);
70     nestedResource.setProperties((Map<String, Object>) ((Map) resourceDef).get("properties"));
71     nestedResource.setMetadata(((Map) resourceDef).get("metadata"));
72
73     Optional<String> substitutionNodeTemplateId =
74         ResourceTranslationFactory.getInstance(nestedResource)
75             .translateResource(heatFileName, translateTo.getServiceTemplate(),
76                 translateTo.getHeatOrchestrationTemplate(), nestedResource,
77                 translateTo.getResourceId(), translateTo.getContext());
78
79     if (substitutionNodeTemplateId.isPresent()) {
80       NodeTemplate substitutionNodeTemplate =
81           DataModelUtil.getNodeTemplate(translateTo.getServiceTemplate(),
82               substitutionNodeTemplateId.get());
83       if (!Objects.isNull(substitutionNodeTemplate)) {
84         Map serviceTemplateFilter = (Map<String, Object>) substitutionNodeTemplate.getProperties()
85             .get(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME);
86
87         populateServiceTemplateFilterProperties(translateTo, substitutionNodeTemplate,
88             serviceTemplateFilter);
89         handlingIndexVar(translateTo, substitutionNodeTemplate);
90         DataModelUtil
91             .addNodeTemplate(translateTo.getServiceTemplate(), substitutionNodeTemplateId.get(),
92                 substitutionNodeTemplate);
93       }
94     }
95   }
96
97   private void handlingIndexVar(TranslateTo translateTo, NodeTemplate substitutionNodeTemplate) {
98     List<String> indexVarProperties = new ArrayList<>();
99     String indexVarValue = getIndexVarValue(translateTo);
100     replacePropertiesIndexVarValue(indexVarValue, substitutionNodeTemplate.getProperties(),
101         indexVarProperties, translateTo);
102     //Add index var properties to context for unified model later
103     translateTo.getContext().addIndexVarProperties(ToscaUtil.getServiceTemplateFileName(translateTo
104             .getServiceTemplate()), translateTo.getTranslatedId(), indexVarProperties);
105   }
106
107   private Map<String, List> getNewIndexVarValue() {
108     final Map<String, List> newIndexVarValue = new HashMap<>();
109     List indexVarValList = new ArrayList<>();
110     indexVarValList.add(ToscaConstants.MODELABLE_ENTITY_NAME_SELF);
111     indexVarValList.add(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME);
112     indexVarValList.add(ToscaConstants.INDEX_VALUE_PROPERTY_NAME);
113     newIndexVarValue.put(ToscaFunctions.GET_PROPERTY.getDisplayName(), indexVarValList);
114     return newIndexVarValue;
115   }
116
117   private void replacePropertiesIndexVarValue(String indexVarValue,
118                                               Map<String, Object> properties,
119                                               List<String> indexVarProperties,
120                                               TranslateTo translateTo) {
121     if (properties == null || properties.isEmpty()) {
122       return;
123     }
124
125     for (Map.Entry<String, Object> propertyEntry : properties.entrySet()) {
126       Object propertyValue = propertyEntry.getValue();
127       if (propertyValue != null && propertyValue.equals(RESOURCE_GROUP_INDEX_VAR_DEFAULT_VALUE)) {
128         indexVarProperties.add(propertyEntry.getKey());
129       }
130       Object newPropertyValue = getUpdatedPropertyValueWithIndex(indexVarValue, propertyValue,
131           indexVarProperties, translateTo);
132       if (newPropertyValue != null) {
133         properties.put(propertyEntry.getKey(), newPropertyValue);
134       }
135     }
136   }
137
138   private Object getUpdatedPropertyValueWithIndex(String indexVarValue, Object propertyValue,
139                                                   List<String> indexVarProperties,
140                                                   TranslateTo translateTo) {
141     if (propertyValue != null && propertyValue instanceof String) {
142       if (propertyValue.equals(indexVarValue)) {
143         return getNewIndexVarValue();
144       }
145       if (((String) propertyValue).contains(indexVarValue)) {
146         Map<String, List<Object>> concatMap = new HashMap<>();
147         List<Object> concatList = new ArrayList<>();
148         String value = (String) propertyValue;
149
150         while (value.contains(indexVarValue)) {
151           if (value.indexOf(indexVarValue) == 0) {
152             concatList.add(getNewIndexVarValue());
153             value = value.substring(indexVarValue.length());
154           } else {
155             int end = value.indexOf(indexVarValue);
156             concatList.add(value.substring(0, end));
157             value = value.substring(end);
158           }
159         }
160         if (!value.isEmpty()) {
161           concatList.add(value);
162         }
163
164         concatMap.put(ToscaFunctions.CONCAT.getDisplayName(), concatList);
165         return concatMap;
166       }
167       return propertyValue; //no update is needed
168     } else if (propertyValue instanceof Map && !((Map) propertyValue).isEmpty()) {
169       replacePropertiesIndexVarValue(indexVarValue, (Map<String, Object>) propertyValue,
170           indexVarProperties, translateTo);
171       return propertyValue;
172     } else if (propertyValue instanceof List && !((List) propertyValue).isEmpty()) {
173       List newPropertyValueList = new ArrayList<>();
174       for (Object entry : (List) propertyValue) {
175         newPropertyValueList.add(getUpdatedPropertyValueWithIndex(indexVarValue, entry,
176             indexVarProperties, translateTo));
177       }
178       return newPropertyValueList;
179     }
180     return propertyValue;
181   }
182
183   private String getIndexVarValue(TranslateTo translateTo) {
184     Object indexVar =
185         translateTo.getResource().getProperties().get(HeatConstants.INDEX_PROPERTY_NAME);
186     if (indexVar == null) {
187       return HeatConstants.RESOURCE_GROUP_INDEX_VAR_DEFAULT_VALUE;
188     }
189
190     if (indexVar instanceof String) {
191       return (String) indexVar;
192     } else {
193       throw new CoreException(
194           new InvalidPropertyValueErrorBuilder("index_var", indexVar.toString(), "String").build());
195     }
196   }
197
198   private void populateServiceTemplateFilterProperties(TranslateTo translateTo,
199                                                        NodeTemplate substitutionNodeTemplate,
200                                                        Map serviceTemplateFilter) {
201     boolean mandatory = false;
202     Object countValue = TranslatorHeatToToscaPropertyConverter
203         .getToscaPropertyValue(translateTo.getServiceTemplate(), translateTo.getResourceId(),
204             ToscaConstants.COUNT_PROPERTY_NAME, translateTo.getResource().getProperties().get
205                 (ToscaConstants.COUNT_PROPERTY_NAME), null,
206             translateTo.getHeatFileName(), translateTo.getHeatOrchestrationTemplate(),
207             substitutionNodeTemplate, translateTo.getContext());
208
209     if (countValue != null) {
210       serviceTemplateFilter.put(ToscaConstants.COUNT_PROPERTY_NAME, countValue);
211     } else {
212       serviceTemplateFilter.put(ToscaConstants.COUNT_PROPERTY_NAME, 1);
213     }
214     if (countValue instanceof Integer && (Integer) countValue > 0) {
215       mandatory = true;
216     }
217     if (countValue == null) {
218       mandatory = true;
219     }
220     serviceTemplateFilter.put("mandatory", mandatory);
221   }
222 }