re base code
[sdc.git] / openecomp-be / lib / openecomp-sdc-validation-lib / openecomp-sdc-validation-impl / src / main / java / org / openecomp / sdc / validation / impl / validators / HeatResourceValidator.java
1 /*
2  * Copyright © 2016-2017 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.validation.impl.validators;
18
19 import java.util.ArrayList;
20 import java.util.Collection;
21 import java.util.HashMap;
22 import java.util.HashSet;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Objects;
26 import java.util.Set;
27
28 import org.openecomp.core.validation.types.GlobalValidationContext;
29 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
30 import org.openecomp.sdc.heat.datatypes.model.Output;
31 import org.openecomp.sdc.heat.datatypes.model.Resource;
32 import org.openecomp.sdc.heat.datatypes.model.ResourceReferenceFunctions;
33 import org.openecomp.sdc.heat.services.HeatStructureUtil;
34 import org.openecomp.sdc.logging.api.Logger;
35 import org.openecomp.sdc.logging.api.LoggerFactory;
36 import org.openecomp.sdc.validation.ValidationContext;
37 import org.openecomp.sdc.validation.base.ResourceBaseValidator;
38 import org.openecomp.sdc.validation.type.ConfigConstants;
39 import org.openecomp.sdc.validation.type.HeatResourceValidationContext;
40
41 public class HeatResourceValidator extends ResourceBaseValidator {
42   private static final Logger LOGGER = LoggerFactory.getLogger(ResourceBaseValidator.class);
43   private static final String GET_ATTR = "get_attr";
44
45   @Override
46   public void init(Map<String, Object> properties) {
47     super.init((Map<String, Object>) properties.get(ConfigConstants.Resource_Base_Validator));
48   }
49
50   @Override
51   public ValidationContext createValidationContext(String fileName,
52                                                    String envFileName,
53                                                    HeatOrchestrationTemplate heatOrchestrationTemplate,
54                                                    GlobalValidationContext globalContext) {
55     Map<String, Resource> resourcesMap =
56         heatOrchestrationTemplate.getResources() == null ? new HashMap<>()
57             : heatOrchestrationTemplate.getResources();
58
59     Map<String, Output> outputMap = heatOrchestrationTemplate.getOutputs() == null ? new HashMap<>()
60         : heatOrchestrationTemplate.getOutputs();
61
62     Map<String, Map<String, Map<String, List<String>>>>
63         typeToPointingResourcesMap = new HashMap<>();
64
65     initTypeRelationsMap (fileName, resourcesMap, outputMap,
66              typeToPointingResourcesMap, globalContext);
67
68     return new HeatResourceValidationContext (heatOrchestrationTemplate, typeToPointingResourcesMap,
69             envFileName );
70   }
71
72   private void initTypeRelationsMap (String fileName,
73                      Map<String, Resource> resourceMap,
74                      Map<String, Output> outputMap,
75                      Map<String, Map<String, Map<String, List<String>>>> typeToPointingResourcesMap,
76                      GlobalValidationContext globalContext ) {
77     initTypeRelationsMapFromResourcesMap (fileName, resourceMap,
78             typeToPointingResourcesMap, globalContext);
79
80     initTypeRelationsMapFromOutputsMap (fileName, resourceMap, outputMap,
81             typeToPointingResourcesMap, globalContext);
82   }
83
84   private void initTypeRelationsMapFromOutputsMap (String fileName,
85                                                   Map<String, Resource> resourceMap,
86                                                   Map<String, Output> outputMap,
87                                                   Map<String, Map<String, Map<String, List<String>>>> typeToPointingResourcesMap,
88                                                   GlobalValidationContext globalContext ) {
89     for (Map.Entry<String, Output> outputEntry : outputMap.entrySet()) {
90       Object outputValue = outputEntry.getValue().getValue();
91       Set<String> referencedResources = HeatStructureUtil
92           .getReferencedValuesByFunctionName(fileName,
93               ResourceReferenceFunctions.GET_RESOURCE.getFunction(), outputValue, globalContext);
94
95       updateRelationsMapWithOutputsReferences (outputEntry, resourceMap, referencedResources, typeToPointingResourcesMap);
96     }
97   }
98
99   private void updateRelationsMapWithOutputsReferences (Map.Entry<String, Output> outputEntry,
100                                                        Map<String, Resource> resourceMap,
101                                                        Set<String> referencedResources,
102                                                        Map<String, Map<String, Map<String, List<String>>>> typeToPointingResourcesMap ) {
103
104     for (String pointedResourceName : referencedResources) {
105       Resource pointedResource = resourceMap.get(pointedResourceName);
106
107       if (Objects.nonNull(pointedResource)) {
108         initCurrentResourceTypeInMap(pointedResourceName, pointedResource.getType(),
109             "output", typeToPointingResourcesMap);
110
111         typeToPointingResourcesMap
112             .get(pointedResource.getType()).get(pointedResourceName)
113             .get("output").add(outputEntry.getKey());
114       }
115     }
116   }
117
118   private void initTypeRelationsMapFromResourcesMap(String fileName,
119                                                     Map<String, Resource> resourceMap,
120                                                     Map<String, Map<String, Map<String, List<String>>>> typeToPointingResourcesMap,
121                                                     GlobalValidationContext globalContext) {
122     for (Map.Entry<String, Resource> resourceEntry : resourceMap.entrySet()) {
123       Resource pointingResource = resourceEntry.getValue();
124       Map<String, Object> properties =
125           pointingResource.getProperties() == null ? new HashMap<>()
126               : pointingResource.getProperties();
127
128       Set<String> referencedResourcesByGetResource =
129           getResourcesIdsPointedByCurrentResource(fileName, ResourceReferenceFunctions.GET_RESOURCE,
130               properties, globalContext);
131
132       Set<String> referencedResourcesByGetAttr =
133           handleGetAttrBetweenResources(properties);
134
135       referencedResourcesByGetResource.addAll(referencedResourcesByGetAttr);
136
137       updateRelationsMapWithCurrentResourceReferences
138           (resourceMap, resourceEntry, referencedResourcesByGetResource, typeToPointingResourcesMap);
139     }
140   }
141
142   private void updateRelationsMapWithCurrentResourceReferences(Map<String, Resource> resourceMap,
143                                                                Map.Entry<String, Resource> currentResourceEntry,
144                                                                Set<String> referencedResourcesFromCurrentResource,
145                                                                Map<String, Map<String, Map<String, List<String>>>> typeToPointingResourcesMap) {
146
147     for (String pointedResourceName : referencedResourcesFromCurrentResource) {
148       Resource pointedResource = resourceMap.get(pointedResourceName);
149       if (Objects.nonNull(pointedResource)) {
150         String pointedResourceType = pointedResource.getType();
151
152         updateMapWithRelationsBetweenResources (pointedResourceName, pointedResourceType,
153                 currentResourceEntry, typeToPointingResourcesMap);
154       }
155     }
156   }
157
158   private void updateMapWithRelationsBetweenResources(String pointedResourceName,
159                                                       String pointedResourceType,
160                                                       Map.Entry<String, Resource> currentResourceEntry,
161                                                       Map<String, Map<String, Map<String, List<String>>>> typeToPointingResourcesMap) {
162
163     initCurrentResourceTypeInMap(pointedResourceName, pointedResourceType,
164         currentResourceEntry.getValue().getType(), typeToPointingResourcesMap);
165
166     typeToPointingResourcesMap.get(pointedResourceType).get(pointedResourceName)
167             .get(currentResourceEntry.getValue().getType()).add(currentResourceEntry.getKey());
168   }
169
170   private void initCurrentResourceTypeInMap(String resourceName, String resourceType,
171                                             String pointingResourceType,
172                                             Map<String, Map<String, Map<String, List<String>>>> typeToPointingResourcesMap) {
173
174     typeToPointingResourcesMap.putIfAbsent(resourceType, new HashMap<>());
175     typeToPointingResourcesMap.get(resourceType).putIfAbsent(resourceName, new HashMap<>());
176     typeToPointingResourcesMap.get(resourceType).get(resourceName)
177             .putIfAbsent (pointingResourceType, new ArrayList<>());
178   }
179
180   private Set<String> handleGetAttrBetweenResources (Map<String, Object> properties) {
181     Set<String> referencedResourcesByGetAttr = new HashSet<>();
182     for (Map.Entry<String, Object> proprtyEntry : properties.entrySet()) {
183       referencedResourcesByGetAttr.addAll(getGetAttrReferencesInCaseOfContrail(proprtyEntry
184           .getValue()));
185     }
186
187     return referencedResourcesByGetAttr;
188   }
189
190
191   private Set<String> getGetAttrReferencesInCaseOfContrail(Object propertyValue) {
192     Set<String> getAttrReferences = new HashSet<>();
193
194     if (propertyValue instanceof Map) {
195       if (((Map) propertyValue).containsKey(GET_ATTR)) {
196         if (validatePropertyValueAndAddAttrReferencesInSet(propertyValue, getAttrReferences)) {
197           return getAttrReferences;
198         }
199       } else {
200         Collection<Object> valCollection = ((Map) propertyValue).values();
201         for (Object entryValue : valCollection) {
202           getAttrReferences.addAll(getGetAttrReferencesInCaseOfContrail(entryValue));
203         }
204       }
205     } else if (propertyValue instanceof List) {
206       for (Object prop : (List) propertyValue) {
207         getAttrReferences.addAll(getGetAttrReferencesInCaseOfContrail(prop));
208       }
209     }
210
211     return getAttrReferences;
212   }
213
214   private boolean validatePropertyValueAndAddAttrReferencesInSet(Object propertyValue,
215                                                      Set<String> getAttrReferences) {
216     Object value = ((Map) propertyValue).get(GET_ATTR );
217     if (value instanceof List && ((List) value).size() == 2
218             && ("fq_name").equals(((List) value).get(1))) {
219       if (((List) value).get(0) instanceof String) {
220         String attrReference = (((List) value).get(0)).toString();
221         getAttrReferences.add(attrReference);
222         return true;
223       } else {
224         LOGGER.warn("invalid format of 'get_attr' function - " + propertyValue.toString());
225       }
226   }
227     return false;
228   }
229
230
231   private Set<String> getResourcesIdsPointedByCurrentResource(String fileName,
232                                                               ResourceReferenceFunctions function,
233                                                               Map<String, Object> properties,
234                                                               GlobalValidationContext globalContext) {
235
236     Set<String> referencedResources = new HashSet<>();
237     for (Map.Entry<String, Object> propertyEntry : properties.entrySet()) {
238       referencedResources
239           .addAll(HeatStructureUtil
240               .getReferencedValuesByFunctionName(fileName,
241                   function.getFunction(),
242                   propertyEntry.getValue(),
243                   globalContext));
244     }
245
246     return referencedResources;
247   }
248 }