6afaf79cb950d89414d0ec3c540622269ec3a5ea
[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.heat.datatypes.model.HeatResourcesTypes;
25 import org.openecomp.sdc.heat.datatypes.model.Resource;
26 import org.openecomp.sdc.heat.services.HeatConstants;
27 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
28 import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
29 import org.openecomp.sdc.tosca.services.DataModelUtil;
30 import org.openecomp.sdc.tosca.services.ToscaConstants;
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("type");
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     if (substitutionNodeTemplateId.isPresent()) {
79       NodeTemplate substitutionNodeTemplate =
80           DataModelUtil.getNodeTemplate(translateTo.getServiceTemplate(), substitutionNodeTemplateId.get());
81       if(!Objects.isNull(substitutionNodeTemplate)) {
82         Map serviceTemplateFilter = (Map<String, Object>) substitutionNodeTemplate.getProperties()
83             .get(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME);
84
85         populateServiceTemplateFilterProperties(translateTo, substitutionNodeTemplate,
86             serviceTemplateFilter);
87         handlingIndexVar(translateTo, substitutionNodeTemplate);
88         DataModelUtil
89             .addNodeTemplate(translateTo.getServiceTemplate(), substitutionNodeTemplateId.get(),
90                 substitutionNodeTemplate);
91       }
92     }
93   }
94
95   private void handlingIndexVar(TranslateTo translateTo, NodeTemplate substitutionNodeTemplate) {
96     String indexVarValue = getIndexVarValue(translateTo);
97     replacePropertiesIndexVarValue(indexVarValue, substitutionNodeTemplate.getProperties());
98   }
99
100   private Map<String, List> getNewIndexVarValue() {
101     final Map<String, List> newIndexVarValue = new HashMap<>();
102     List indexVarValList = new ArrayList<>();
103     indexVarValList.add(ToscaConstants.MODELABLE_ENTITY_NAME_SELF);
104     indexVarValList.add(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME);
105     indexVarValList.add(ToscaConstants.INDEX_VALUE_PROPERTY_NAME);
106     newIndexVarValue.put(ToscaFunctions.GET_PROPERTY.getDisplayName(), indexVarValList);
107     return newIndexVarValue;
108   }
109
110   private void replacePropertiesIndexVarValue(String indexVarValue,
111                                               Map<String, Object> properties) {
112     if (properties == null || properties.isEmpty()) {
113       return;
114     }
115
116     for (Map.Entry<String, Object> propertyEntry : properties.entrySet()) {
117       Object propertyValue = propertyEntry.getValue();
118       Object newPropertyValue = getUpdatedPropertyValueWithIndex(indexVarValue, propertyValue);
119       if (newPropertyValue != null) {
120         properties.put(propertyEntry.getKey(), newPropertyValue);
121       }
122     }
123   }
124
125   private Object getUpdatedPropertyValueWithIndex(String indexVarValue, Object propertyValue) {
126     if (propertyValue != null && propertyValue instanceof String) {
127       if (propertyValue.equals(indexVarValue)) {
128         return getNewIndexVarValue();
129       }
130       if (((String) propertyValue).contains(indexVarValue)) {
131         Map<String, List<Object>> concatMap = new HashMap<>();
132         List<Object> concatList = new ArrayList<>();
133         String value = (String) propertyValue;
134
135         while (value.contains(indexVarValue)) {
136           if (value.indexOf(indexVarValue) == 0) {
137             concatList.add(getNewIndexVarValue());
138             value = value.substring(indexVarValue.length());
139           } else {
140             int end = value.indexOf(indexVarValue);
141             concatList.add(value.substring(0, end));
142             value = value.substring(end);
143           }
144         }
145         if (!value.isEmpty()) {
146           concatList.add(value);
147         }
148
149         concatMap.put(ToscaFunctions.CONCAT.getDisplayName(), concatList);
150         return concatMap;
151       }
152       return propertyValue; //no update is needed
153     } else if (propertyValue instanceof Map && !((Map) propertyValue).isEmpty()) {
154       replacePropertiesIndexVarValue(indexVarValue, (Map<String, Object>) propertyValue);
155       return propertyValue;
156     } else if (propertyValue instanceof List && !((List) propertyValue).isEmpty()) {
157       List newPropertyValueList = new ArrayList<>();
158       for (Object entry : ((List) propertyValue)) {
159         newPropertyValueList.add(getUpdatedPropertyValueWithIndex(indexVarValue, entry));
160       }
161       return newPropertyValueList;
162     }
163     return propertyValue;
164   }
165
166   private String getIndexVarValue(TranslateTo translateTo) {
167     Object indexVar =
168         translateTo.getResource().getProperties().get(HeatConstants.INDEX_PROPERTY_NAME);
169     if (indexVar == null) {
170       return HeatConstants.RESOURCE_GROUP_INDEX_VAR_DEFAULT_VALUE;
171     }
172
173     if (indexVar instanceof String) {
174       return (String) indexVar;
175     } else {
176       throw new CoreException(
177           new InvalidPropertyValueErrorBuilder("index_var", indexVar.toString(), "String").build());
178     }
179   }
180
181   private void populateServiceTemplateFilterProperties(TranslateTo translateTo,
182                                                        NodeTemplate substitutionNodeTemplate,
183                                                        Map serviceTemplateFilter) {
184     boolean mandatory = false;
185     Object countValue = TranslatorHeatToToscaPropertyConverter
186         .getToscaPropertyValue(translateTo.getServiceTemplate(),translateTo.getResourceId(),
187             ToscaConstants.COUNT_PROPERTY_NAME, translateTo.getResource().getProperties().get
188                 (ToscaConstants.COUNT_PROPERTY_NAME), null,
189             translateTo.getHeatFileName(), translateTo.getHeatOrchestrationTemplate(),
190             substitutionNodeTemplate, translateTo.getContext());
191
192     if (countValue != null) {
193       serviceTemplateFilter.put(ToscaConstants.COUNT_PROPERTY_NAME, countValue);
194     } else {
195       serviceTemplateFilter.put(ToscaConstants.COUNT_PROPERTY_NAME, 1);
196     }
197     if (countValue instanceof Integer && (Integer) countValue > 0) {
198       mandatory = true;
199     }
200     if (countValue == null) {
201       mandatory = true;
202     }
203     serviceTemplateFilter.put("mandatory", mandatory);
204   }
205 }