05f94df76bd899cbe2d56512dd93bd1b6d784bf7
[sdc.git] /
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 org.apache.commons.collections4.CollectionUtils;
20 import org.openecomp.core.utilities.CommonMethods;
21 import org.openecomp.core.validation.ErrorMessageCode;
22 import org.openecomp.core.validation.errors.ErrorMessagesFormatBuilder;
23 import org.openecomp.core.validation.types.GlobalValidationContext;
24 import org.openecomp.sdc.common.errors.Messages;
25 import org.openecomp.sdc.common.utils.SdcCommon;
26 import org.openecomp.sdc.datatypes.error.ErrorLevel;
27 import org.openecomp.sdc.heat.datatypes.manifest.FileData;
28 import org.openecomp.sdc.heat.datatypes.manifest.ManifestContent;
29 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
30 import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
31 import org.openecomp.sdc.heat.datatypes.model.ResourceReferenceFunctions;
32 import org.openecomp.sdc.heat.services.HeatStructureUtil;
33 import org.openecomp.sdc.heat.services.manifest.ManifestUtil;
34 import org.openecomp.sdc.logging.api.Logger;
35 import org.openecomp.sdc.logging.api.LoggerFactory;
36 import org.openecomp.sdc.logging.types.LoggerErrorDescription;
37 import org.openecomp.sdc.logging.types.LoggerTragetServiceName;
38 import org.openecomp.sdc.validation.Validator;
39 import org.openecomp.sdc.validation.util.ValidationUtil;
40
41 import java.util.HashSet;
42 import java.util.Map;
43 import java.util.Set;
44
45 public class SharedResourceGuideLineValidator implements Validator {
46   private static final Logger LOGGER = LoggerFactory.getLogger(
47           SharedResourceGuideLineValidator.class);
48   private static final ErrorMessageCode ERROR_CODE_SRG_1 = new ErrorMessageCode("SRG1");
49   private static final ErrorMessageCode ERROR_CODE_SRG_2 = new ErrorMessageCode("SRG2");
50   private static final ErrorMessageCode ERROR_CODE_SRG_3 = new ErrorMessageCode("SRG3");
51   private static final ErrorMessageCode ERROR_CODE_SRG_4 = new ErrorMessageCode("SRG4");
52   private static final ErrorMessageCode ERROR_CODE_SRG_5 = new ErrorMessageCode("SRG5");
53   private static final ErrorMessageCode ERROR_CODE_SRG_6 = new ErrorMessageCode("SRG6");
54
55   @Override
56   public void validate(GlobalValidationContext globalContext) {
57     ManifestContent manifestContent;
58     try {
59       manifestContent = ValidationUtil.validateManifest(globalContext);
60     } catch (Exception exception) {
61       LOGGER.error("Fialed to check  Validation PreCondition ",exception);
62       return;
63     }
64
65     Set<String> baseFiles = validateManifest(manifestContent, globalContext);
66
67     Map<String, FileData.Type> fileTypeMap = ManifestUtil.getFileTypeMap(manifestContent);
68     globalContext.getFiles().stream()
69         .filter(fileName -> FileData
70             .isHeatFile(fileTypeMap.get(fileName)))
71         .forEach(fileName -> validate(fileName,
72             fileTypeMap, baseFiles, globalContext));
73
74
75   }
76
77   private Set<String> validateManifest(ManifestContent manifestContent,
78                                               GlobalValidationContext globalContext) {
79     Set<String> baseFiles = ManifestUtil.getBaseFiles(manifestContent);
80     if (baseFiles == null || baseFiles.isEmpty()) {
81       globalContext.addMessage(
82           SdcCommon.MANIFEST_NAME,
83           ErrorLevel.WARNING,
84           ErrorMessagesFormatBuilder
85               .getErrorWithParameters(ERROR_CODE_SRG_3,Messages
86                   .MISSIN_BASE_HEAT_FILE.getErrorMessage()),
87           LoggerTragetServiceName.VALIDATE_BASE_FILE,
88           LoggerErrorDescription.MISSING_BASE_HEAT);
89     } else if (baseFiles.size() > 1) {
90       String baseFileList = getElementListAsString(baseFiles);
91       globalContext.addMessage(
92           SdcCommon.MANIFEST_NAME,
93           ErrorLevel.WARNING,
94           ErrorMessagesFormatBuilder
95               .getErrorWithParameters(ERROR_CODE_SRG_4,Messages
96                       .MULTI_BASE_HEAT_FILE.getErrorMessage(),
97                   baseFileList),
98           LoggerTragetServiceName.VALIDATE_BASE_FILE,
99           LoggerErrorDescription.MULTI_BASE_HEAT);
100     }
101     return baseFiles;
102   }
103
104   private static String getElementListAsString(Set<String> elementCollection) {
105     return "["
106         + CommonMethods.collectionToCommaSeparatedString(elementCollection)
107         +  "]";
108   }
109
110   private void validate(String fileName, Map<String, FileData.Type> fileTypeMap,
111                         Set<String> baseFiles, GlobalValidationContext globalContext) {
112     globalContext.setMessageCode(ERROR_CODE_SRG_5);
113     HeatOrchestrationTemplate
114         heatOrchestrationTemplate = ValidationUtil
115         .checkHeatOrchestrationPreCondition(fileName, globalContext);
116     if (heatOrchestrationTemplate == null) {
117       return;
118     }
119
120     validateBaseFile(fileName, baseFiles, heatOrchestrationTemplate, globalContext);
121     validateHeatVolumeFile(fileName, fileTypeMap, heatOrchestrationTemplate, globalContext);
122   }
123
124
125   private void validateBaseFile(String fileName, Set<String> baseFiles,
126                                 HeatOrchestrationTemplate heatOrchestrationTemplate,
127                                 GlobalValidationContext globalContext) {
128     //if not base return
129     if (baseFiles == null || !baseFiles.contains(fileName)) {
130       return;
131     }
132
133     //if no resources exist return
134     if (heatOrchestrationTemplate.getResources() == null
135         || heatOrchestrationTemplate.getResources().size() == 0) {
136       return;
137     }
138
139     Set<String> expectedExposedResources = new HashSet<>();
140     heatOrchestrationTemplate.getResources()
141         .entrySet()
142         .stream()
143         .filter(entry -> ValidationUtil.isExpectedToBeExposed(entry.getValue().getType()))
144         .forEach(entry -> expectedExposedResources.add(entry.getKey()));
145     Set<String> actualExposedResources = new HashSet<>();
146
147     if (heatOrchestrationTemplate.getOutputs() != null) {
148       globalContext.setMessageCode(ERROR_CODE_SRG_6);
149       heatOrchestrationTemplate.getOutputs().entrySet()
150           .stream()
151           .filter(entry -> isPropertyValueGetResource(fileName, entry.getValue().getValue(),
152               globalContext))
153           .forEach(entry -> actualExposedResources.add(
154               getResourceIdFromPropertyValue(fileName, entry.getValue().getValue(),
155                   globalContext)));
156     }
157     ValidationUtil.removeExposedResourcesCalledByGetResource(fileName, actualExposedResources,
158         heatOrchestrationTemplate, globalContext);
159
160     actualExposedResources.forEach(expectedExposedResources::remove);
161
162     if (CollectionUtils.isNotEmpty(expectedExposedResources)) {
163       expectedExposedResources
164           .stream()
165           .forEach(name -> globalContext.addMessage(
166               fileName,
167               ErrorLevel.WARNING, ErrorMessagesFormatBuilder
168                   .getErrorWithParameters(ERROR_CODE_SRG_1,Messages
169                           .RESOURCE_NOT_DEFINED_IN_OUTPUT.getErrorMessage(),
170                       name),
171               LoggerTragetServiceName.VALIDATE_BASE_FILE,
172               LoggerErrorDescription.RESOURCE_NOT_DEFINED_AS_OUTPUT));
173     }
174   }
175
176   private void validateHeatVolumeFile(String fileName, Map<String, FileData.Type> fileTypeMap,
177                                       HeatOrchestrationTemplate heatOrchestrationTemplate,
178                                       GlobalValidationContext globalContext) {
179     //if not heat volume return
180     if (!fileTypeMap.get(fileName).equals(FileData.Type.HEAT_VOL)) {
181       return;
182     }
183
184     //if no resources exist return
185     if (heatOrchestrationTemplate.getResources() == null
186         || heatOrchestrationTemplate.getResources().size() == 0) {
187       return;
188     }
189
190     Set<String> expectedExposedResources = new HashSet<>();
191     Set<String> actualExposedResources = new HashSet<>();
192     heatOrchestrationTemplate.getResources()
193         .entrySet()
194         .stream()
195         .filter(entry -> entry.getValue().getType()
196             .equals(HeatResourcesTypes.CINDER_VOLUME_RESOURCE_TYPE.getHeatResource()))
197         .forEach(entry -> expectedExposedResources.add(entry.getKey()));
198
199     if (heatOrchestrationTemplate.getOutputs() != null) {
200       globalContext.setMessageCode(ERROR_CODE_SRG_6);
201       heatOrchestrationTemplate.getOutputs().entrySet()
202           .stream()
203           .filter(entry -> isPropertyValueGetResource(fileName, entry.getValue().getValue(),
204               globalContext))
205           .forEach(entry -> actualExposedResources.add(
206               getResourceIdFromPropertyValue(fileName, entry.getValue().getValue(),
207                   globalContext)));
208     }
209
210     actualExposedResources.forEach(expectedExposedResources::remove);
211
212     if (CollectionUtils.isNotEmpty(expectedExposedResources)) {
213       expectedExposedResources
214           .stream()
215           .forEach(name -> globalContext.addMessage(
216               fileName,
217               ErrorLevel.WARNING, ErrorMessagesFormatBuilder
218                   .getErrorWithParameters(ERROR_CODE_SRG_2,Messages
219                       .VOLUME_HEAT_NOT_EXPOSED.getErrorMessage(), name),
220               LoggerTragetServiceName.VALIDATE_VOLUME_FILE,
221               LoggerErrorDescription.VOLUME_FILE_NOT_EXPOSED));
222     }
223   }
224
225
226   private boolean isPropertyValueGetResource(String filename, Object value,
227                                              GlobalValidationContext globalContext) {
228     Set<String> referenceValues = HeatStructureUtil.getReferencedValuesByFunctionName(filename,
229         ResourceReferenceFunctions.GET_RESOURCE.getFunction(), value, globalContext);
230     return referenceValues != null && (CollectionUtils.isNotEmpty(referenceValues));
231   }
232
233   private String getResourceIdFromPropertyValue(String filename, Object value,
234                                                 GlobalValidationContext globalContext) {
235     Set<String> referenceValues = HeatStructureUtil.getReferencedValuesByFunctionName(filename,
236         ResourceReferenceFunctions.GET_RESOURCE.getFunction(), value, globalContext);
237     if (referenceValues != null && CollectionUtils.isNotEmpty(referenceValues)) {
238       return (String) referenceValues.toArray()[0];
239     }
240     return null;
241   }
242
243 }