2 * Copyright © 2016-2018 European Support Limited
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package org.openecomp.sdc.validation.impl.util;
19 import org.apache.commons.collections4.CollectionUtils;
20 import org.onap.sdc.tosca.services.YamlUtil;
21 import org.openecomp.core.validation.errors.ErrorMessagesFormatBuilder;
22 import org.openecomp.core.validation.types.GlobalValidationContext;
23 import org.openecomp.sdc.common.errors.Messages;
24 import org.openecomp.sdc.datatypes.error.ErrorLevel;
25 import org.openecomp.sdc.heat.datatypes.DefinedHeatParameterTypes;
26 import org.openecomp.sdc.heat.datatypes.model.Environment;
27 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
28 import org.openecomp.sdc.heat.datatypes.model.Parameter;
29 import org.openecomp.sdc.heat.datatypes.model.Resource;
30 import org.openecomp.sdc.heat.services.HeatStructureUtil;
31 import org.openecomp.sdc.logging.api.Logger;
32 import org.openecomp.sdc.logging.api.LoggerFactory;
33 import org.openecomp.sdc.validation.impl.validators.HeatValidator;
34 import org.openecomp.sdc.validation.type.HeatResourceValidationContext;
36 import java.io.InputStream;
37 import java.util.Collection;
38 import java.util.HashMap;
39 import java.util.HashSet;
40 import java.util.List;
42 import java.util.Objects;
43 import java.util.Optional;
47 public class HeatValidationService {
49 private static final Logger LOGGER = LoggerFactory.getLogger(HeatValidator.class);
50 private static final String NO_CONTENT_IN_FILE_MSG = "The file ' %s ' has no content";
51 private HeatValidationService(){
55 * Check artifacts existence.
57 * @param fileName the file name
58 * @param artifactsNames the artifacts names
59 * @param globalContext the global context
61 public static void checkArtifactsExistence(String fileName, Set<String> artifactsNames,
62 GlobalValidationContext globalContext) {
65 .filter(artifactName -> !globalContext.getFileContextMap().containsKey(artifactName))
66 .forEach(artifactName ->
67 globalContext.addMessage(fileName,
68 ErrorLevel.ERROR, ErrorMessagesFormatBuilder
69 .getErrorWithParameters(
70 globalContext.getMessageCode(),
71 Messages.MISSING_ARTIFACT.getErrorMessage(), artifactName)));
75 * Draw files loop string.
77 * @param filesInPath the files in path
80 public static String drawFilesLoop(List<String> filesInPath) {
81 StringBuilder stringBuilder = new StringBuilder();
82 stringBuilder.append("[");
83 int pathSize = filesInPath.size();
85 for (int i = 0; i < pathSize; i++) {
86 stringBuilder.append(filesInPath.get(i));
87 if (i != pathSize - 1) {
88 stringBuilder.append(" -- ");
91 if (!filesInPath.get(0).equals(filesInPath.get(pathSize - 1))) {
92 stringBuilder.append(" -- ");
93 stringBuilder.append(filesInPath.get(0));
95 stringBuilder.append("]");
97 return stringBuilder.toString();
101 * Check nested parameters.
103 * @param parentFileName the calling nested file name
104 * @param nestedFileName the nested file name
105 * @param globalContext the global context
106 * @param parentParameters parent parameters.
107 * @param nestedParameters nested parameters.
108 * @param nestedParametersNames nested parameter names.
110 private static void checkNestedParameters(String parentFileName, String nestedFileName,
111 GlobalValidationContext globalContext,
112 Map<String, Parameter> parentParameters,
113 Map<String, Parameter> nestedParameters,
114 Set<String> nestedParametersNames) {
115 HeatOrchestrationTemplate parentHeatOrchestrationTemplate;
116 HeatOrchestrationTemplate nestedHeatOrchestrationTemplate;
119 nestedHeatOrchestrationTemplate = getHeatOrchestrationTemplate(nestedFileName, globalContext);
120 parentHeatOrchestrationTemplate = getHeatOrchestrationTemplate(parentFileName, globalContext);
121 } catch (Exception exception) {
125 parentParameters.putAll(parentHeatOrchestrationTemplate.getParameters());
126 nestedParameters.putAll(nestedHeatOrchestrationTemplate.getParameters());
127 if (!nestedParameters.isEmpty()) {
128 nestedParametersNames.addAll(nestedHeatOrchestrationTemplate.getParameters().keySet());
132 private static HeatOrchestrationTemplate getHeatOrchestrationTemplate(String fileName,
133 GlobalValidationContext globalContext)
136 Optional<InputStream> fileContent = globalContext.getFileContent(fileName);
137 if (fileContent.isPresent()) {
138 return new YamlUtil().yamlToObject(fileContent.get(), HeatOrchestrationTemplate.class);
140 Exception exception = new Exception(String.format(NO_CONTENT_IN_FILE_MSG, fileName));
141 LOGGER.error("Error while reading file : " + fileName , exception);
146 public static void checkNestedParametersNoMissingParameterInNested(String parentFileName,
147 String nestedFileName,
149 Set<String> resourceFileProperties,
150 GlobalValidationContext globalContext) {
151 Map<String, Parameter> parentParameters = new HashMap<>();
152 Map<String, Parameter> nestedParameters = new HashMap<>();
153 Set<String> nestedParametersNames = new HashSet<>();
154 checkNestedParameters(parentFileName, nestedFileName, globalContext, parentParameters,
155 nestedParameters, nestedParametersNames);
157 checkNoMissingParameterInNested(parentFileName, nestedFileName, resourceName,
158 resourceFileProperties, nestedParametersNames, globalContext);
161 public static void checkNestedInputValuesAlignWithType(String parentFileName,
162 String nestedFileName,
163 String resourceName, Resource resource,
164 Optional<String> indexVarValue,
165 GlobalValidationContext globalContext) {
166 Map<String, Parameter> parentParameters = new HashMap<>();
167 Map<String, Parameter> nestedParameters = new HashMap<>();
168 Set<String> nestedParametersNames = new HashSet<>();
169 checkNestedParameters(parentFileName, nestedFileName, globalContext, parentParameters,
170 nestedParameters, nestedParametersNames);
172 checkNestedInputValuesAlignWithType(parentFileName, nestedFileName,
173 nestedParameters, resourceName, resource, indexVarValue, globalContext);
176 private static void checkNoMissingParameterInNested(String parentFileName, String nestedFileName,
178 Set<String> resourceFileProperties,
179 Set<String> nestedParametersNames,
180 GlobalValidationContext globalContext) {
181 if (CollectionUtils.isNotEmpty(nestedParametersNames)) {
182 resourceFileProperties
184 .filter(propertyName -> !nestedParametersNames.contains(propertyName))
185 .forEach(propertyName -> globalContext
186 .addMessage(parentFileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
187 .getErrorWithParameters(
188 globalContext.getMessageCode(),
189 Messages.MISSING_PARAMETER_IN_NESTED.getErrorMessage(),
190 nestedFileName, resourceName, propertyName)));
194 private static void checkNestedInputValuesAlignWithType(String parentFileName,
195 String nestedFileName,
196 Map<String, Parameter> nestedParameters,
197 String resourceName, Resource resource,
198 Optional<String> indexVarValue,
199 GlobalValidationContext globalContext) {
200 Map<String, Object> properties = resource.getProperties();
201 for (Map.Entry<String, Object> propertyEntry : properties.entrySet()) {
202 String parameterName = propertyEntry.getKey();
203 Object parameterInputValue = propertyEntry.getValue();
204 if (parameterInputValue instanceof String) {
205 if (indexVarValue.isPresent() && indexVarValue.get().equals(parameterInputValue)) {
206 parameterInputValue = 3; //indexVarValue is actually number value in runtime
208 validateStaticValueForNestedInputParameter(parentFileName, nestedFileName, resourceName,
209 parameterName, parameterInputValue, nestedParameters.get(parameterName),
215 private static void validateStaticValueForNestedInputParameter(String parentFileName,
216 String nestedFileName,
218 String parameterName,
220 Parameter parameterInNested,
221 GlobalValidationContext
223 if (parameterInNested == null) {
226 if (!DefinedHeatParameterTypes
227 .isValueIsFromGivenType(staticValue, parameterInNested.getType())) {
228 globalContext.addMessage(parentFileName, ErrorLevel.WARNING, ErrorMessagesFormatBuilder
229 .getErrorWithParameters(globalContext.getMessageCode(),
230 Messages.WRONG_VALUE_TYPE_ASSIGNED_NESTED_INPUT.getErrorMessage(),
231 resourceName, parameterName, nestedFileName));
237 * Is nested loop exist in file boolean.
239 * @param callingFileName the calling file name
240 * @param nestedFileName the nested file name
241 * @param filesInLoop the files in loop
242 * @param globalContext the global context
243 * @return the boolean
245 public static boolean isNestedLoopExistInFile(String callingFileName, String nestedFileName,
246 List<String> filesInLoop,
247 GlobalValidationContext globalContext) {
248 HeatOrchestrationTemplate nestedHeatOrchestrationTemplate;
250 nestedHeatOrchestrationTemplate = getNestedHeatOrchestrationTemplate(nestedFileName,
252 } catch (Exception exception) {
253 LOGGER.error("Error while reading file : " + nestedFileName, exception);
254 LOGGER.warn("HEAT Validator will not be executed on file " + nestedFileName
255 + " due to illegal HEAT format");
258 filesInLoop.add(nestedFileName);
259 Collection<Resource> nestedResources =
260 nestedHeatOrchestrationTemplate.getResources() == null ? null
261 : nestedHeatOrchestrationTemplate.getResources().values();
262 return addNestedFilesInLoopAndCheckIfNestedLoopExist(nestedResources,
263 callingFileName, filesInLoop, globalContext);
265 private static boolean addNestedFilesInLoopAndCheckIfNestedLoopExist(
266 Collection<Resource> nestedResources,String callingFileName,
267 List<String> filesInLoop,
268 GlobalValidationContext globalContext){
269 if (CollectionUtils.isNotEmpty(nestedResources)) {
270 for (Resource resource : nestedResources) {
271 String resourceType = resource.getType();
273 if (Objects.nonNull(resourceType) && isNestedResource(resourceType)) {
274 return resourceType.equals(callingFileName) || !filesInLoop.contains(resourceType)
275 && isNestedLoopExistInFile(callingFileName, resourceType, filesInLoop, globalContext);
285 private static HeatOrchestrationTemplate getNestedHeatOrchestrationTemplate( String nestedFileName,
286 GlobalValidationContext globalContext) throws Exception {
287 Optional<InputStream> fileContent = globalContext.getFileContent(nestedFileName);
288 HeatOrchestrationTemplate nestedHeatOrchestrationTemplate;
289 if (fileContent.isPresent()) {
290 nestedHeatOrchestrationTemplate =
291 new YamlUtil().yamlToObject(fileContent.get(), HeatOrchestrationTemplate.class);
293 throw new Exception(String.format(NO_CONTENT_IN_FILE_MSG, nestedFileName));
296 return nestedHeatOrchestrationTemplate;
299 public static boolean isNestedResource(String resourceType) {
300 return resourceType.contains(".yaml") || resourceType.contains(".yml");
304 * Validate env content environment.
306 * @param fileName the file name
307 * @param envFileName the env file name
308 * @param globalContext the global context
309 * @return the environment
311 public static Environment validateEnvContent(String fileName, String envFileName,
312 GlobalValidationContext globalContext) {
313 Environment envContent;
315 Optional<InputStream> fileContent = globalContext.getFileContent(envFileName);
316 if (fileContent.isPresent()) {
317 envContent = new YamlUtil().yamlToObject(fileContent.get(), Environment.class);
319 throw new Exception(String.format(NO_CONTENT_IN_FILE_MSG, envFileName));
321 } catch (Exception exception) {
322 LOGGER.error("Error while reading env file : " + envFileName, exception);
329 * This method verifies whether the propertyValue contains a single parent port
330 * @param fileName on which the validation is currently run
331 * @param globalContext global validation context
332 * @param heatResourceValidationContext heat resource validation context
333 * @param propertyValue the value which is examined
334 * @return whether the vlan has single parent port
336 public static boolean hasSingleParentPort(String fileName, GlobalValidationContext globalContext,
337 HeatResourceValidationContext heatResourceValidationContext,
338 Object propertyValue) {
339 final boolean isList = propertyValue instanceof List;
340 if (!isList || ((List) propertyValue).size() != 1) {
344 final Object listValue = ((List) propertyValue).get(0);
346 final Set<String> getParamValues =
347 HeatStructureUtil.getReferencedValuesByFunctionName(fileName, "get_param",
348 listValue, globalContext);
350 return getParamValues.isEmpty() || (getParamValues.size() == 1) &&
351 validateGetParamValueOfType(getParamValues, heatResourceValidationContext,
352 DefinedHeatParameterTypes.STRING.getType());
357 private static boolean validateGetParamValueOfType(Set<String> values,
358 HeatResourceValidationContext
359 heatResourceValidationContext, String type) {
361 return values.stream().anyMatch(e -> Objects.equals(
362 heatResourceValidationContext.getHeatOrchestrationTemplate().getParameters().get(e).getType(), type));