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