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