bd672e387fa8bec3e0c16130f0d5c3d2c7fb0711
[sdc.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
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
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
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=========================================================
19  */
20
21 package org.openecomp.sdc.translator.services.heattotosca.impl.resourcetranslation;
22
23 import org.openecomp.sdc.common.errors.CoreException;
24 import org.openecomp.sdc.common.utils.CommonUtil;
25 import org.openecomp.sdc.datatypes.error.ErrorLevel;
26 import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
27 import org.openecomp.sdc.heat.datatypes.model.Resource;
28 import org.openecomp.sdc.heat.services.HeatConstants;
29 import org.openecomp.sdc.logging.context.impl.MdcDataErrorMessage;
30 import org.openecomp.sdc.logging.types.LoggerConstants;
31 import org.openecomp.sdc.logging.types.LoggerErrorCode;
32 import org.openecomp.sdc.logging.types.LoggerErrorDescription;
33 import org.openecomp.sdc.logging.types.LoggerTragetServiceName;
34 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
35 import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
36 import org.openecomp.sdc.tosca.services.DataModelUtil;
37 import org.openecomp.sdc.tosca.services.ToscaConstants;
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 import java.util.ArrayList;
45 import java.util.HashMap;
46 import java.util.List;
47 import java.util.Map;
48 import java.util.Objects;
49 import java.util.Optional;
50
51 public class ResourceTranslationResourceGroupImpl extends ResourceTranslationBase {
52
53   @Override
54   protected void translate(TranslateTo translateTo) {
55
56
57     mdcDataDebugMessage.debugEntryMessage(null, null);
58
59     final String heatFileName = translateTo.getHeatFileName();
60     Object resourceDef =
61         translateTo.getResource().getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
62     Resource nestedResource = new Resource();
63     Object typeDefinition = ((Map) resourceDef).get("type");
64     if (!(typeDefinition instanceof String)) {
65       logger.warn("Resource '" + translateTo.getResourceId() + "' of type'"
66           + HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource()
67           + "' with resourceDef which is not pointing to nested heat file is not supported and "
68           + "will be ignored in the translation ");
69       return;
70     }
71     String type = (String) typeDefinition;
72     if (!HeatToToscaUtil.isYmlFileType(type)) {
73       logger.warn("Resource '" + translateTo.getResourceId() + "' of type'"
74           + HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource()
75           + "' with resourceDef which is not pointing to nested heat file is not supported and "
76           + "will be ignored in the translation ");
77
78       mdcDataDebugMessage.debugExitMessage(null, null);
79       return;
80     }
81
82     nestedResource.setType(type);
83     nestedResource.setProperties((Map<String, Object>) ((Map) resourceDef).get("properties"));
84     nestedResource.setMetadata(((Map) resourceDef).get("metadata"));
85
86     Optional<String> substitutionNodeTemplateId =
87         ResourceTranslationFactory.getInstance(nestedResource)
88             .translateResource(heatFileName, translateTo.getServiceTemplate(),
89                 translateTo.getHeatOrchestrationTemplate(), nestedResource,
90                 translateTo.getResourceId(), translateTo.getContext());
91     if (substitutionNodeTemplateId.isPresent()) {
92       NodeTemplate substitutionNodeTemplate =
93           DataModelUtil.getNodeTemplate(translateTo.getServiceTemplate(), substitutionNodeTemplateId.get());
94       if(!Objects.isNull(substitutionNodeTemplate)) {
95         Map serviceTemplateFilter = (Map<String, Object>) substitutionNodeTemplate.getProperties()
96             .get(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME);
97
98         populateServiceTemplateFilterProperties(translateTo, substitutionNodeTemplate,
99             serviceTemplateFilter);
100         handlingIndexVar(translateTo, substitutionNodeTemplate);
101         DataModelUtil
102             .addNodeTemplate(translateTo.getServiceTemplate(), substitutionNodeTemplateId.get(),
103                 substitutionNodeTemplate);
104       }
105     }
106
107     mdcDataDebugMessage.debugExitMessage(null, null);
108   }
109
110   private void handlingIndexVar(TranslateTo translateTo, NodeTemplate substitutionNodeTemplate) {
111
112
113     mdcDataDebugMessage.debugEntryMessage(null, null);
114
115     String indexVarValue = getIndexVarValue(translateTo);
116     replacePropertiesIndexVarValue(indexVarValue, substitutionNodeTemplate.getProperties());
117
118     mdcDataDebugMessage.debugExitMessage(null, null);
119   }
120
121   private Map<String, List> getNewIndexVarValue() {
122     final Map<String, List> newIndexVarValue = new HashMap<>();
123     List indexVarValList = new ArrayList<>();
124     indexVarValList.add(ToscaConstants.MODELABLE_ENTITY_NAME_SELF);
125     indexVarValList.add(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME);
126     indexVarValList.add(ToscaConstants.INDEX_VALUE_PROPERTY_NAME);
127     newIndexVarValue.put(ToscaFunctions.GET_PROPERTY.getDisplayName(), indexVarValList);
128     return newIndexVarValue;
129   }
130
131   private void replacePropertiesIndexVarValue(String indexVarValue,
132                                               Map<String, Object> properties) {
133
134
135     mdcDataDebugMessage.debugEntryMessage(null, null);
136
137     if (properties == null || properties.isEmpty()) {
138       return;
139     }
140
141     for (Map.Entry<String, Object> propertyEntry : properties.entrySet()) {
142       Object propertyValue = propertyEntry.getValue();
143       Object newPropertyValue = getUpdatedPropertyValueWithIndex(indexVarValue, propertyValue);
144       if (newPropertyValue != null) {
145         properties.put(propertyEntry.getKey(), newPropertyValue);
146       }
147     }
148
149     mdcDataDebugMessage.debugExitMessage(null, null);
150   }
151
152   private Object getUpdatedPropertyValueWithIndex(String indexVarValue, Object propertyValue) {
153
154
155     mdcDataDebugMessage.debugEntryMessage(null, null);
156
157     if (propertyValue instanceof String && propertyValue != null) {
158       if (propertyValue.equals(indexVarValue)) {
159         return getNewIndexVarValue();
160       }
161       if (((String) propertyValue).contains(indexVarValue)) {
162         Map<String, List<Object>> concatMap = new HashMap<>();
163         List<Object> concatList = new ArrayList<>();
164         String value = (String) propertyValue;
165
166         while (value.contains(indexVarValue)) {
167           if (value.indexOf(indexVarValue) == 0) {
168             concatList.add(getNewIndexVarValue());
169             value = value.substring(indexVarValue.length());
170           } else {
171             int end = value.indexOf(indexVarValue);
172             concatList.add(value.substring(0, end));
173             value = value.substring(end);
174           }
175         }
176         if (!value.isEmpty()) {
177           concatList.add(value);
178         }
179
180         concatMap.put(ToscaFunctions.CONCAT.getDisplayName(), concatList);
181         return concatMap;
182       }
183
184       mdcDataDebugMessage.debugExitMessage(null, null);
185       return propertyValue; //no update is needed
186     } else if (propertyValue instanceof Map && !((Map) propertyValue).isEmpty()) {
187       replacePropertiesIndexVarValue(indexVarValue, (Map<String, Object>) propertyValue);
188       return propertyValue;
189     } else if (propertyValue instanceof List && !((List) propertyValue).isEmpty()) {
190       List newPropertyValueList = new ArrayList<>();
191       for (Object entry : ((List) propertyValue)) {
192         newPropertyValueList.add(getUpdatedPropertyValueWithIndex(indexVarValue, entry));
193       }
194
195       mdcDataDebugMessage.debugExitMessage(null, null);
196       return newPropertyValueList;
197     }
198
199     mdcDataDebugMessage.debugExitMessage(null, null);
200     return propertyValue;
201   }
202
203   private String getIndexVarValue(TranslateTo translateTo) {
204
205     mdcDataDebugMessage.debugEntryMessage(null, null);
206
207     Object indexVar =
208         translateTo.getResource().getProperties().get(HeatConstants.INDEX_PROPERTY_NAME);
209     if (indexVar == null) {
210       return HeatConstants.RESOURCE_GROUP_INDEX_VAR_DEFAULT_VALUE;
211     }
212
213     if (indexVar instanceof String) {
214
215       mdcDataDebugMessage.debugExitMessage(null, null);
216       return (String) indexVar;
217     } else {
218       MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
219           LoggerTragetServiceName.GET_RESOURCE, ErrorLevel.ERROR.name(),
220           LoggerErrorCode.DATA_ERROR.getErrorCode(), LoggerErrorDescription.INVALID_PROPERTY);
221       throw new CoreException(
222           new InvalidPropertyValueErrorBuilder("index_var", indexVar.toString(), "String").build());
223     }
224   }
225
226   private void populateServiceTemplateFilterProperties(TranslateTo translateTo,
227                                                        NodeTemplate substitutionNodeTemplate,
228                                                        Map serviceTemplateFilter) {
229
230
231     mdcDataDebugMessage.debugEntryMessage(null, null);
232
233     boolean mandatory = false;
234     Object countValue = TranslatorHeatToToscaPropertyConverter
235         .getToscaPropertyValue(translateTo.getServiceTemplate(),translateTo.getResourceId(),
236             ToscaConstants.COUNT_PROPERTY_NAME, translateTo.getResource().getProperties().get
237                 (ToscaConstants.COUNT_PROPERTY_NAME), null,
238             translateTo.getHeatFileName(), translateTo.getHeatOrchestrationTemplate(),
239             substitutionNodeTemplate, translateTo.getContext());
240
241     if (countValue != null) {
242       serviceTemplateFilter.put(ToscaConstants.COUNT_PROPERTY_NAME, countValue);
243     } else {
244       serviceTemplateFilter.put(ToscaConstants.COUNT_PROPERTY_NAME, 1);
245     }
246     if (countValue instanceof Integer && (Integer) countValue > 0) {
247       mandatory = true;
248     }
249     if (countValue == null) {
250       mandatory = true;
251     }
252     serviceTemplateFilter.put("mandatory", mandatory);
253
254     mdcDataDebugMessage.debugExitMessage(null, null);
255   }
256 }