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