2 * Copyright © 2016-2017 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.openecomp.core.validation.errors.ErrorMessagesFormatBuilder;
21 import org.openecomp.core.validation.types.GlobalValidationContext;
22 import org.openecomp.sdc.common.errors.Messages;
23 import org.openecomp.sdc.datatypes.error.ErrorLevel;
24 import org.openecomp.sdc.heat.datatypes.DefinedHeatParameterTypes;
25 import org.openecomp.sdc.heat.datatypes.model.Environment;
26 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
27 import org.openecomp.sdc.heat.datatypes.model.Parameter;
28 import org.openecomp.sdc.heat.datatypes.model.Resource;
29 import org.openecomp.sdc.logging.api.Logger;
30 import org.openecomp.sdc.logging.api.LoggerFactory;
31 import org.openecomp.sdc.tosca.services.YamlUtil;
32 import org.openecomp.sdc.validation.impl.validators.HeatValidator;
34 import java.io.InputStream;
35 import java.util.Collection;
36 import java.util.HashMap;
37 import java.util.HashSet;
38 import java.util.List;
40 import java.util.Objects;
41 import java.util.Optional;
45 public class HeatValidationService {
47 private static final Logger LOGGER = LoggerFactory.getLogger(HeatValidator.class);
48 private static final String NO_CONTENT_IN_FILE_MSG = "The file ' %s ' has no content";
49 private HeatValidationService(){
53 * Check artifacts existence.
55 * @param fileName the file name
56 * @param artifactsNames the artifacts names
57 * @param globalContext the global context
59 public static void checkArtifactsExistence(String fileName, Set<String> artifactsNames,
60 GlobalValidationContext globalContext) {
63 .filter(artifactName -> !globalContext.getFileContextMap().containsKey(artifactName))
64 .forEach(artifactName ->
65 globalContext.addMessage(fileName,
66 ErrorLevel.ERROR, ErrorMessagesFormatBuilder
67 .getErrorWithParameters(
68 globalContext.getMessageCode(),
69 Messages.MISSING_ARTIFACT.getErrorMessage(), artifactName)));
73 * Draw files loop string.
75 * @param filesInPath the files in path
78 public static String drawFilesLoop(List<String> filesInPath) {
79 StringBuilder stringBuilder = new StringBuilder();
80 stringBuilder.append("[");
81 int pathSize = filesInPath.size();
83 for (int i = 0; i < pathSize; i++) {
84 stringBuilder.append(filesInPath.get(i));
85 if (i != pathSize - 1) {
86 stringBuilder.append(" -- ");
89 if (!filesInPath.get(0).equals(filesInPath.get(pathSize - 1))) {
90 stringBuilder.append(" -- ");
91 stringBuilder.append(filesInPath.get(0));
93 stringBuilder.append("]");
95 return stringBuilder.toString();
99 * Check nested parameters.
101 * @param parentFileName the calling nested file name
102 * @param nestedFileName the nested file name
103 * @param globalContext the global context
104 * @param parentParameters parent parameters.
105 * @param nestedParameters nested parameters.
106 * @param nestedParametersNames nested parameter names.
108 public static void checkNestedParameters(String parentFileName, String nestedFileName,
109 GlobalValidationContext globalContext,
110 Map<String, Parameter> parentParameters,
111 Map<String, Parameter> nestedParameters,
112 Set<String> nestedParametersNames) {
113 HeatOrchestrationTemplate parentHeatOrchestrationTemplate;
114 HeatOrchestrationTemplate nestedHeatOrchestrationTemplate;
117 nestedHeatOrchestrationTemplate = getHeatOrchestrationTemplate(nestedFileName, globalContext);
118 parentHeatOrchestrationTemplate = getHeatOrchestrationTemplate(parentFileName, globalContext);
119 } catch (Exception exception) {
123 parentParameters.putAll(parentHeatOrchestrationTemplate.getParameters());
124 nestedParameters.putAll(nestedHeatOrchestrationTemplate.getParameters());
125 if (!nestedParameters.isEmpty()) {
126 nestedParametersNames.addAll(nestedHeatOrchestrationTemplate.getParameters().keySet());
130 private static HeatOrchestrationTemplate getHeatOrchestrationTemplate(String fileName,
131 GlobalValidationContext globalContext)
134 Optional<InputStream> fileContent = globalContext.getFileContent(fileName);
135 if (fileContent.isPresent()) {
136 return new YamlUtil().yamlToObject(fileContent.get(), HeatOrchestrationTemplate.class);
138 Exception exception = new Exception(String.format(NO_CONTENT_IN_FILE_MSG, fileName));
139 LOGGER.error("Error while reading file : " + fileName , exception);
144 public static void checkNestedParametersNoMissingParameterInNested(String parentFileName,
145 String nestedFileName,
147 Set<String> resourceFileProperties,
148 GlobalValidationContext globalContext) {
149 Map<String, Parameter> parentParameters = new HashMap<>();
150 Map<String, Parameter> nestedParameters = new HashMap<>();
151 Set<String> nestedParametersNames = new HashSet<>();
152 checkNestedParameters(parentFileName, nestedFileName, globalContext, parentParameters,
153 nestedParameters, nestedParametersNames);
155 checkNoMissingParameterInNested(parentFileName, nestedFileName, resourceName,
156 resourceFileProperties, nestedParametersNames, globalContext);
159 public static void checkNestedInputValuesAlignWithType(String parentFileName,
160 String nestedFileName,
161 String resourceName, Resource resource,
162 Optional<String> indexVarValue,
163 GlobalValidationContext globalContext) {
164 Map<String, Parameter> parentParameters = new HashMap<>();
165 Map<String, Parameter> nestedParameters = new HashMap<>();
166 Set<String> nestedParametersNames = new HashSet<>();
167 checkNestedParameters(parentFileName, nestedFileName, globalContext, parentParameters,
168 nestedParameters, nestedParametersNames);
170 checkNestedInputValuesAlignWithType(parentFileName, nestedFileName,
171 nestedParameters, resourceName, resource, indexVarValue, globalContext);
174 private static void checkNoMissingParameterInNested(String parentFileName, String nestedFileName,
176 Set<String> resourceFileProperties,
177 Set<String> nestedParametersNames,
178 GlobalValidationContext globalContext) {
179 if (CollectionUtils.isNotEmpty(nestedParametersNames)) {
180 resourceFileProperties
182 .filter(propertyName -> !nestedParametersNames.contains(propertyName))
183 .forEach(propertyName -> globalContext
184 .addMessage(parentFileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
185 .getErrorWithParameters(
186 globalContext.getMessageCode(),
187 Messages.MISSING_PARAMETER_IN_NESTED.getErrorMessage(),
188 nestedFileName, resourceName, propertyName)));
192 private static void checkNestedInputValuesAlignWithType(String parentFileName,
193 String nestedFileName,
194 Map<String, Parameter> nestedParameters,
195 String resourceName, Resource resource,
196 Optional<String> indexVarValue,
197 GlobalValidationContext globalContext) {
198 Map<String, Object> properties = resource.getProperties();
199 for (Map.Entry<String, Object> propertyEntry : properties.entrySet()) {
200 String parameterName = propertyEntry.getKey();
201 Object parameterInputValue = propertyEntry.getValue();
202 if (parameterInputValue instanceof String) {
203 if (indexVarValue.isPresent() && indexVarValue.get().equals(parameterInputValue)) {
204 parameterInputValue = 3; //indexVarValue is actually number value in runtime
206 validateStaticValueForNestedInputParameter(parentFileName, nestedFileName, resourceName,
207 parameterName, parameterInputValue, nestedParameters.get(parameterName),
213 private static void validateStaticValueForNestedInputParameter(String parentFileName,
214 String nestedFileName,
216 String parameterName,
218 Parameter parameterInNested,
219 GlobalValidationContext
221 if (parameterInNested == null) {
224 if (!DefinedHeatParameterTypes
225 .isValueIsFromGivenType(staticValue, parameterInNested.getType())) {
226 globalContext.addMessage(parentFileName, ErrorLevel.WARNING, ErrorMessagesFormatBuilder
227 .getErrorWithParameters(globalContext.getMessageCode(),
228 Messages.WRONG_VALUE_TYPE_ASSIGNED_NESTED_INPUT.getErrorMessage(),
229 resourceName, parameterName, nestedFileName));
235 * Is nested loop exist in file boolean.
237 * @param callingFileName the calling file name
238 * @param nestedFileName the nested file name
239 * @param filesInLoop the files in loop
240 * @param globalContext the global context
241 * @return the boolean
243 public static boolean isNestedLoopExistInFile(String callingFileName, String nestedFileName,
244 List<String> filesInLoop,
245 GlobalValidationContext globalContext) {
246 HeatOrchestrationTemplate nestedHeatOrchestrationTemplate;
248 nestedHeatOrchestrationTemplate = getNestedHeatOrchestrationTemplate(nestedFileName,
250 } catch (Exception exception) {
251 LOGGER.error("Error while reading file : " + nestedFileName, exception);
252 LOGGER.warn("HEAT Validator will not be executed on file " + nestedFileName
253 + " due to illegal HEAT format");
256 filesInLoop.add(nestedFileName);
257 Collection<Resource> nestedResources =
258 nestedHeatOrchestrationTemplate.getResources() == null ? null
259 : nestedHeatOrchestrationTemplate.getResources().values();
260 return addNestedFilesInLoopAndCheckIfNestedLoopExist(nestedResources,
261 callingFileName, filesInLoop, globalContext);
263 private static boolean addNestedFilesInLoopAndCheckIfNestedLoopExist(
264 Collection<Resource> nestedResources,String callingFileName,
265 List<String> filesInLoop,
266 GlobalValidationContext globalContext){
267 if (CollectionUtils.isNotEmpty(nestedResources)) {
268 for (Resource resource : nestedResources) {
269 String resourceType = resource.getType();
271 if (Objects.nonNull(resourceType) && isNestedResource(resourceType)) {
272 return resourceType.equals(callingFileName) || !filesInLoop.contains(resourceType)
273 && isNestedLoopExistInFile(callingFileName, resourceType, filesInLoop, globalContext);
279 private static HeatOrchestrationTemplate getNestedHeatOrchestrationTemplate( String nestedFileName,
280 GlobalValidationContext globalContext) throws Exception {
281 Optional<InputStream> fileContent = globalContext.getFileContent(nestedFileName);
282 HeatOrchestrationTemplate nestedHeatOrchestrationTemplate;
283 if (fileContent.isPresent()) {
284 nestedHeatOrchestrationTemplate =
285 new YamlUtil().yamlToObject(fileContent.get(), HeatOrchestrationTemplate.class);
287 throw new Exception(String.format(NO_CONTENT_IN_FILE_MSG, nestedFileName));
290 return nestedHeatOrchestrationTemplate;
293 public static boolean isNestedResource(String resourceType) {
294 return resourceType.contains(".yaml") || resourceType.contains(".yml");
298 * Validate env content environment.
300 * @param fileName the file name
301 * @param envFileName the env file name
302 * @param globalContext the global context
303 * @return the environment
305 public static Environment validateEnvContent(String fileName, String envFileName,
306 GlobalValidationContext globalContext) {
307 Environment envContent;
309 Optional<InputStream> fileContent = globalContext.getFileContent(envFileName);
310 if (fileContent.isPresent()) {
311 envContent = new YamlUtil().yamlToObject(fileContent.get(), Environment.class);
313 throw new Exception(String.format(NO_CONTENT_IN_FILE_MSG, envFileName));
315 } catch (Exception exception) {
316 LOGGER.error("Error while reading env file : " + envFileName, exception);
323 public static String getResourceGroupResourceName(String resourceCallingToResourceGroup) {
324 return "OS::Heat::ResourceGroup in " + resourceCallingToResourceGroup;