2 * Copyright 2017 Huawei Technologies Co., Ltd.
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.onap.cli.fw.schema;
19 import org.onap.cli.fw.error.OnapCommandInvalidSchema;
20 import org.onap.cli.fw.utils.OnapCommandUtils;
21 import org.springframework.core.io.Resource;
22 import org.yaml.snakeyaml.Yaml;
23 import org.yaml.snakeyaml.parser.ParserException;
25 import static org.onap.cli.fw.conf.Constants.*;
28 import java.io.FileInputStream;
29 import java.io.FileNotFoundException;
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.Collections;
35 import java.util.HashMap;
36 import java.util.HashSet;
37 import java.util.List;
39 import java.util.Map.Entry;
43 * Abstract schema validation class.
46 public abstract class AbstractSchemaValidate implements SchemaValidate {
49 * Supported schema types.
52 protected enum SchemaType {
56 protected List<String> schemaErrors = new ArrayList<>();
57 protected Map<String, Object> yamlMap = new HashMap<>();
58 protected Map<String, Object> defaultYamlMap = new HashMap<>();
60 protected static final List<String> HTTP_SCHEMA_LIST = Arrays.asList(ONAP_CMD_SCHEMA_VERSION, NAME, DESCRIPTION,
61 SERVICE, PARAMETERS, RESULTS, HTTP);
63 protected static final List<String> HTTP_SCHEMA_MANDATORY_LIST = Arrays.asList(ONAP_CMD_SCHEMA_VERSION, NAME,
64 DESCRIPTION, SERVICE, HTTP);
65 protected static final List<String> BASIC_SCHEMA_LIST = Arrays.asList(ONAP_CMD_SCHEMA_VERSION, NAME, DESCRIPTION,
68 protected static final List<String> BASIC_SCHEMA_MANDATORY_LIST = Arrays.asList(ONAP_CMD_SCHEMA_VERSION, NAME,
69 DESCRIPTION, PARAMETERS);
71 protected static final List<String> TOP_LEVEL_PARAMS_LIST = Arrays.asList(ONAP_CMD_SCHEMA_VERSION, NAME,
74 protected static final List<String> TOP_LEVEL_MANDATORY_LIST = Arrays.asList(ONAP_CMD_SCHEMA_VERSION, NAME,
77 protected static final List<String> SERVICE_PARAMS_LIST = Arrays.asList(NAME, VERSION, AUTH);
79 protected static final List<String> SERVICE_PARAMS_MANDATORY_LIST = Arrays.asList(NAME, VERSION);
81 protected static final List<String> INPUT_PARAMS_LIST = Arrays.asList(NAME, DESCRIPTION, TYPE, SHORT_OPTION,
82 LONG_OPTION, IS_OPTIONAL, DEFAULT_VALUE, IS_SECURED);
84 protected static final List<String> INPUT_PARAMS_MANDATORY_LIST = Arrays.asList(NAME, DESCRIPTION, TYPE);
86 protected static final List<String> PARAMETER_TYPES = Arrays.asList(PARAMETER_TYPE_JSON, PARAMETER_TYPE_YAML,
87 PARAMETER_TYPE_STRING, PARAMETER_TYPE_LONG, PARAMETER_TYPE_URL, PARAMETER_TYPE_BOOL, PARAMETER_TYPE_ARRAY,
88 PARAMETER_TYPE_MAP, PARAMETER_TYPE_BINARY);
90 protected static final List<String> RESULT_PARAMS_LIST = Arrays.asList(NAME, DESCRIPTION, TYPE, SHORT_OPTION,
91 LONG_OPTION, IS_OPTIONAL, DEFAULT_VALUE, IS_SECURED);
93 protected static final List<String> RESULT_PARAMS_MANDATORY_LIST = Arrays.asList(NAME, DESCRIPTION, TYPE);
95 protected static final List<String> HTTP_PARAMS_LIST = Arrays.asList(URI, METHOD, BODY, HEADERS, QUERIES);
97 protected static final List<String> HTTP_PARAMS_MANDATORY_LIST = Arrays.asList(URI, METHOD, BODY, HEADERS, QUERIES);
99 protected static final List<String> HTTP_MANDATORY_SECTIONS = Arrays.asList(REQUEST, SUCCESS_CODES);
101 protected static final List<String> HTTP_SECTIONS = Arrays.asList(REQUEST, SUCCESS_CODES, RESULT_MAP,
104 protected static final List<String> HTTP_REQUEST_MANDATORY_PARAMS = Arrays.asList(URI, METHOD);
106 protected static final List<String> HTTP_REQUEST_PARAMS = Arrays.asList(URI, METHOD, BODY, HEADERS, QUERIES);
108 protected static final List<String> BOOLEAN_VALUES = Arrays.asList(BOOLEAN_TRUE, BOOLEAN_FALSE);
109 protected static final List<String> DIRECTIONS = Arrays.asList(DIRECTION_PORTRAIT, DIRECTION_LANDSCAPE);
110 protected static final List<String> RESULT_SCOPES = Arrays.asList(RESULT_SCOPE_SHORT, RESULT_SCOPE_LONG);
112 protected static final List<String> HTTP_METHODS = Arrays.asList(POST, GET, DELETE, PUT, HEAD);
119 * @throws OnapCommandInvalidSchema
122 public AbstractSchemaValidate(File schemaFile) throws OnapCommandInvalidSchema {
123 loadYaml(schemaFile);
132 * @throws OnapCommandInvalidSchema
135 public AbstractSchemaValidate(String schemaFile) throws OnapCommandInvalidSchema {
138 Resource res = OnapCommandUtils.getExternalResource(schemaFile, EXTERNAL_SCHEMA_PATH_PATERN);
139 InputStream inputStream;
141 inputStream = OnapCommandUtils.class.getClassLoader().getResourceAsStream(schemaFile);
143 inputStream = res.getInputStream();
146 if (inputStream != null) {
147 loadYamlFromInputStream(schemaFile, inputStream);
149 throw new OnapCommandInvalidSchema(schemaFile, SCHEMA_FILE_NOT_EXIST);
152 } catch (IOException e) {
153 throw new OnapCommandInvalidSchema(schemaFile, e);
158 private final void loadYaml(File schemaFile) throws OnapCommandInvalidSchema {
159 if (!schemaFile.isFile()) {
160 throw new OnapCommandInvalidSchema(schemaFile.getName(), SCHEMA_FILE_NOT_EXIST);
162 String fileName = schemaFile.getName();
164 if (!fileName.endsWith(".yaml")) {
165 throw new OnapCommandInvalidSchema(fileName, SCHEMA_FILE_WRONG_EXTN);
169 InputStream inputStream = new FileInputStream(schemaFile);
170 loadYamlFromInputStream(schemaFile.getName(), inputStream);
171 } catch (FileNotFoundException e) {
172 throw new OnapCommandInvalidSchema(fileName, e);
176 @SuppressWarnings("unchecked")
177 private final void loadYamlFromInputStream(String fileName, InputStream inputStream)
178 throws OnapCommandInvalidSchema {
180 yamlMap = (Map<String, Object>) new Yaml().load(inputStream);
181 } catch (ParserException e) {
182 throw new OnapCommandInvalidSchema(fileName, e);
184 if (inputStream != null) {
187 } catch (IOException e) {
188 throw new OnapCommandInvalidSchema(fileName, e); // NOSONAR
193 if (yamlMap == null) {
194 throw new OnapCommandInvalidSchema(fileName, SCHEMA_FILE_EMPTY);
198 @SuppressWarnings("unchecked")
199 private final void loadDefaultYaml() throws OnapCommandInvalidSchema {
200 InputStream inputStream = AbstractSchemaValidate.class.getClassLoader()
201 .getResourceAsStream(DEFAULT_SCHEMA_FILE_NAME);
203 defaultYamlMap = (Map<String, Object>) new Yaml().load(inputStream);
204 } catch (ParserException e) {
205 throw new OnapCommandInvalidSchema(DEFAULT_SCHEMA_FILE_NAME, e);
208 if (defaultYamlMap == null) {
209 throw new OnapCommandInvalidSchema(DEFAULT_SCHEMA_FILE_NAME, SCHEMA_FILE_EMPTY);
216 * @throws OnapCommandInvalidSchema exception
219 public List<String> validate() throws OnapCommandInvalidSchema {
222 Set<String> mainSections = yamlMap.keySet();
223 if (mainSections.containsAll(HTTP_SCHEMA_MANDATORY_LIST)) {
224 type = SchemaType.HTTP;
225 } else if (mainSections.containsAll(BASIC_SCHEMA_MANDATORY_LIST)) {
226 type = SchemaType.BASIC;
228 schemaErrors.add(SchemaValidate.invalidSections(mainSections, HTTP_SCHEMA_MANDATORY_LIST,
229 BASIC_SCHEMA_MANDATORY_LIST));
233 if (type.equals(SchemaType.BASIC)) {
234 validateTopLevelAttributes();
235 validateInputParameters();
236 validateResultParameters();
238 validateTopLevelAttributes();
239 validateServiceAttributes();
240 validateInputParameters();
241 validateResultParameters();
242 validateSpecificSchema(SchemaType.HTTP);
247 private void validateResultAttributes(List<Map<String, Object>> resultAttributes) {
248 Set<String> resultParamNames = new HashSet<>();
249 for (Map<String, Object> attribute : resultAttributes) {
251 // Validate mandatory parameters
252 validateMandatoryParams(attribute, RESULT_PARAMS_LIST, RESULT_PARAMS_MANDATORY_LIST, ATTRIBUTES);
254 String name = String.valueOf(attribute.get(NAME));
256 if (resultParamNames.contains(name)) {
257 schemaErrors.add(SchemaValidate.attributeNameExist(name, ATTRIBUTES));
259 resultParamNames.add(name);
262 // Validate specific parameters
263 Object type = attribute.get(TYPE);
264 String value = String.valueOf(type);
265 if (!PARAMETER_TYPES.contains(value.toLowerCase())) {
266 schemaErrors.add(SchemaValidate.invalidType(ATTRIBUTES, name, PARAMETER_TYPES));
269 Object scope = attribute.get(SCOPE);
271 schemaErrors.add(SchemaValidate.attributeScopeEmpty(name));
272 } else if (!RESULT_SCOPES.contains(scope)) {
273 schemaErrors.add(SchemaValidate.invalidAttributeScope(name, RESULT_SCOPES));
276 Object isSecured = attribute.get(IS_SECURED);
277 if (isSecured != null) {
278 String value2 = String.valueOf(isSecured);
279 if (!validateBoolean(value2)) {
280 schemaErrors.add(SchemaValidate.invalidBooleanValueMessage(ATTRIBUTES, IS_SECURED, value2));
287 private void validateResultParameters() {
288 @SuppressWarnings("unchecked")
289 Map<String, Object> resultParams = (Map<String, Object>) yamlMap.get(RESULTS);
291 if (resultParams == null || resultParams.isEmpty()) {
295 Object direction = resultParams.get(DIRECTION);
297 if (direction != null && !DIRECTIONS.contains(direction)) {
298 schemaErrors.add(SchemaValidate.invalidType(PARAMETERS, DIRECTION, DIRECTIONS));
301 @SuppressWarnings("unchecked")
302 List<Map<String, Object>> resultAttributes = (List<Map<String, Object>>) resultParams.get(ATTRIBUTES);
303 validateResultAttributes(resultAttributes);
307 * Get all default short options.
311 protected Set<String> getDefaultShortOptions() {
313 Set<String> set = new HashSet<>();
315 @SuppressWarnings("unchecked")
316 List<Map<String, Object>> inputParams = (List<Map<String, Object>>) defaultYamlMap.get(PARAMETERS);
317 for (Map<String, Object> parameter : inputParams) {
318 Object name = parameter.get(SHORT_OPTION);
319 if (name != null && !String.valueOf(name).isEmpty() && !"null".equals(name)) {
320 set.add(String.valueOf(name));
328 * Get all default long options.
332 protected Set<String> getDefaultLongOptions() {
334 Set<String> set = new HashSet<>();
336 @SuppressWarnings("unchecked")
337 List<Map<String, Object>> inputParams = (List<Map<String, Object>>) defaultYamlMap.get(PARAMETERS);
338 for (Map<String, Object> parameter : inputParams) {
339 Object name = parameter.get(LONG_OPTION);
340 if (name != null && !String.valueOf(name).isEmpty() && !"null".equals(name)) {
341 set.add(String.valueOf(name));
348 private void validateTopLevelAttributes() {
349 validateMandatoryParams(yamlMap, TOP_LEVEL_PARAMS_LIST, TOP_LEVEL_MANDATORY_LIST, "root level");
352 private void validateServiceAttributes() {
354 @SuppressWarnings("unchecked")
355 Map<String, Object> serviceMap = (Map<String, Object>) yamlMap.get(SERVICE);
357 if (serviceMap == null) {
358 schemaErrors.add(SchemaValidate.emptySection(SERVICE));
362 validateMandatoryParams(serviceMap, SERVICE_PARAMS_LIST, SERVICE_PARAMS_MANDATORY_LIST, SERVICE);
364 // Validate specific parameters
366 if (serviceMap.containsKey(AUTH)) {
367 Object obj = serviceMap.get(AUTH);
369 schemaErrors.add(SchemaValidate.emptyValue(SERVICE, AUTH));
371 String value = String.valueOf(obj);
372 if (validateBoolean(value)) {
373 schemaErrors.add(SchemaValidate.invalidBooleanValueMessage(SERVICE, AUTH, value));
380 private void validateInputParameters() {
382 @SuppressWarnings("unchecked")
383 List<Map<String, Object>> inputParams = (List<Map<String, Object>>) yamlMap.get(PARAMETERS);
384 if (inputParams == null) {
387 validateInputAttributes(inputParams);
390 protected abstract void validateSpecificSchema(SchemaType type) throws OnapCommandInvalidSchema;
392 private void validateInputAttributes(List<Map<String, Object>> inputParams) {
393 Set<String> inputParamNames = new HashSet<>();
394 Set<String> inputShortOptions = new HashSet<>();
395 Set<String> inputLongOptions = new HashSet<>();
397 Set<String> defaultShortOptions = getDefaultShortOptions();
398 Set<String> defaultLongOptions = getDefaultLongOptions();
400 for (Map<String, Object> parameter : inputParams) {
402 // Validate mandatory parameters
403 validateMandatoryParams(parameter, INPUT_PARAMS_LIST, INPUT_PARAMS_MANDATORY_LIST, PARAMETERS);
405 // Validate specific parameters
407 String name = String.valueOf(parameter.get(NAME));
409 if (inputParamNames.contains(name)) {
410 schemaErrors.add(SchemaValidate.nameExist(name, PARAMETERS));
412 inputParamNames.add(name);
415 String value = String.valueOf(parameter.get(TYPE));
417 if (!PARAMETER_TYPES.contains(value.toLowerCase())) {
418 schemaErrors.add(SchemaValidate.invalidAttrType(name, PARAMETERS, PARAMETER_TYPES));
421 Object isOptional = parameter.get(IS_OPTIONAL);
422 if (isOptional != null) {
423 String value1 = String.valueOf(isOptional);
424 if (!validateBoolean(value1)) {
425 schemaErrors.add(SchemaValidate.invalidBooleanValueMessage(name, IS_OPTIONAL, value1));
429 Object isSecured = parameter.get(IS_SECURED);
430 if (isSecured != null) {
431 String value2 = String.valueOf(isSecured);
432 if (!validateBoolean(value2)) {
433 schemaErrors.add(SchemaValidate.invalidBooleanValueMessage(name, IS_SECURED, value2));
437 String shortOption = String.valueOf(parameter.get(SHORT_OPTION));
438 String longOption = String.valueOf(parameter.get(LONG_OPTION));
440 if (inputShortOptions.contains(shortOption)) {
441 schemaErrors.add(SchemaValidate.optionExist(SHORT_OPTION, shortOption, name));
442 } else if (defaultShortOptions.contains(shortOption)) {
445 .add(SchemaValidate.optionDefaultExist(SHORT_OPTION, shortOption, name, defaultShortOptions));
447 } else if (shortOption != null && !shortOption.isEmpty() && !"null".equals(shortOption)) {
448 inputShortOptions.add(shortOption);
451 if (inputLongOptions.contains(longOption)) {
452 schemaErrors.add(SchemaValidate.optionExist(LONG_OPTION, longOption, name));
453 } else if (defaultLongOptions.contains(longOption)) {
455 schemaErrors.add(SchemaValidate.optionDefaultExist(LONG_OPTION, longOption, name, defaultLongOptions));
456 } else if (longOption != null && !longOption.isEmpty() && !"null".equals(shortOption)) {
457 inputLongOptions.add(longOption);
465 * Validate mandatory parameters.
471 * @param mandatoryParams
476 protected void validateMandatoryParams(Map<String, Object> yamlMap, List<String> totalParams,
477 List<String> mandatoryParams, String section) {
479 for (String param : totalParams) {
480 boolean isMandatory = mandatoryParams.contains(param);
481 boolean isYamlContains = yamlMap.containsKey(param);
483 if (!isYamlContains) {
484 schemaErrors.add(SchemaValidate.mandatoryAttrMissing(param, section));
486 String value = String.valueOf(yamlMap.get(param));
487 if (value == null || "".equals(value) || "null".equals(value)) {
488 schemaErrors.add(SchemaValidate.mandatoryAttrEmpty(param, section));
496 * Load result attributes.
500 @SuppressWarnings("unchecked")
501 protected Set<String> getResultAttributes() {
503 Set<String> set = new HashSet<>();
505 List<Map<String, Object>> resultAttributes = yamlMap.get(RESULTS) != null
506 ? (List<Map<String, Object>>) ((Map<String, Object>) yamlMap.get(RESULTS)).get(ATTRIBUTES)
507 : Collections.emptyList();
509 if (resultAttributes != null) {
510 for (Map<String, Object> map : resultAttributes) {
511 for (Entry<String, Object> entry : map.entrySet()) {
512 Object key = entry.getKey();
514 if (NAME.equals(key)) {
515 set.add(String.valueOf(entry.getValue()));
526 * Get request parameters.
530 protected Set<String> getRequestParams() {
532 Set<String> set = new HashSet<>();
534 @SuppressWarnings("unchecked")
535 List<Map<String, Object>> inputParams = (List<Map<String, Object>>) yamlMap.get(PARAMETERS);
537 if (inputParams != null) {
538 for (Map<String, Object> map : inputParams) {
539 for (Entry<String, Object> entry : map.entrySet()) {
540 Object key = entry.getKey();
542 if (NAME.equals(key)) {
543 set.add(String.valueOf(entry.getValue()));
560 protected static boolean validateBoolean(String toValidate) {
561 return BOOLEAN_VALUES.contains(toValidate.toLowerCase());