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