diff options
author | Kanagaraj Manickam <kanagaraj.manickam@huawei.com> | 2017-08-18 07:17:00 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@onap.org> | 2017-08-18 07:17:00 +0000 |
commit | 68f717bc5d832aabe44c12c28eff8ceaeff3ae19 (patch) | |
tree | ef2de5fc4a0f939f06f15b08b2aab4c60d19d29a /framework/src/main/java/org/onap | |
parent | 29ede3adb4aedb3810b19d7a6c2ad1f60bcdc79d (diff) | |
parent | 8d3d394a5effe4127e8480c812de82d81fe5e5ae (diff) |
Merge changes I8fdb8450,I68855caf
* changes:
Move schema validation to load schema
Move schema validation to load schema
Diffstat (limited to 'framework/src/main/java/org/onap')
10 files changed, 630 insertions, 1322 deletions
diff --git a/framework/src/main/java/org/onap/cli/fw/OnapCommand.java b/framework/src/main/java/org/onap/cli/fw/OnapCommand.java index 1cc78f23..78ab5517 100644 --- a/framework/src/main/java/org/onap/cli/fw/OnapCommand.java +++ b/framework/src/main/java/org/onap/cli/fw/OnapCommand.java @@ -43,6 +43,7 @@ import org.onap.cli.fw.utils.OnapCommandUtils; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; /** @@ -170,7 +171,7 @@ public abstract class OnapCommand { */ public void initializeSchema(String schema) throws OnapCommandException { this.setSchemaName(schema); - OnapCommandUtils.loadSchema(this, schema, true); + OnapCommandUtils.loadSchema(this, schema, true, false); this.initializeProfileSchema(); this.isInitialzied = true; } @@ -190,10 +191,10 @@ public abstract class OnapCommand { param.validate(); } catch (OnapCommandParameterMissing e) { if (OnapCommandConfg.getExcludeParamsForNoAuthEnableExternalCmd().contains(param.getName())) { - OnapCommandParameter noAuthParam = this.getParameters().stream().filter(p -> p.getName() - .equalsIgnoreCase(Constants.DEFAULT_PARAMETER_OUTPUT_NO_AUTH)).findFirst().get(); + Optional<OnapCommandParameter> noAuthParamOpt = this.getParameters().stream().filter(p -> p.getName() + .equalsIgnoreCase(Constants.DEFAULT_PARAMETER_OUTPUT_NO_AUTH)).findFirst(); - if ("true".equalsIgnoreCase(noAuthParam.getValue().toString())) { + if (noAuthParamOpt.isPresent() && "true".equalsIgnoreCase(noAuthParamOpt.get().getValue().toString())) { continue; } } diff --git a/framework/src/main/java/org/onap/cli/fw/cmd/OnapHttpCommand.java b/framework/src/main/java/org/onap/cli/fw/cmd/OnapHttpCommand.java index d5f51f00..9438102f 100644 --- a/framework/src/main/java/org/onap/cli/fw/cmd/OnapHttpCommand.java +++ b/framework/src/main/java/org/onap/cli/fw/cmd/OnapHttpCommand.java @@ -73,7 +73,7 @@ public class OnapHttpCommand extends OnapCommand { @Override protected void initializeProfileSchema() throws OnapCommandException { - OnapCommandUtils.loadSchema(this, this.getSchemaName()); + OnapCommandUtils.loadHTTPSchemaSection(this, this.getSchemaName(), false); } @Override diff --git a/framework/src/main/java/org/onap/cli/fw/cmd/OnapSchemaValidateCommand.java b/framework/src/main/java/org/onap/cli/fw/cmd/OnapSchemaValidateCommand.java index a4d4e7d4..b1811483 100644 --- a/framework/src/main/java/org/onap/cli/fw/cmd/OnapSchemaValidateCommand.java +++ b/framework/src/main/java/org/onap/cli/fw/cmd/OnapSchemaValidateCommand.java @@ -20,17 +20,14 @@ import org.onap.cli.fw.OnapCommand; import org.onap.cli.fw.OnapCommandSchema; import org.onap.cli.fw.error.OnapCommandException; import org.onap.cli.fw.input.OnapCommandParameter; -import org.onap.cli.fw.schema.SchemaValidate; -import org.onap.cli.fw.schema.SchemaValidator; +import org.onap.cli.fw.utils.OnapCommandUtils; -import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * Validate schema command. - * */ @OnapCommandSchema(name = "schema-validate", schema = "schema-validate.yaml") public class OnapSchemaValidateCommand extends OnapCommand { @@ -42,15 +39,20 @@ public class OnapSchemaValidateCommand extends OnapCommand { String location = String.valueOf(locationParam.getValue()); OnapCommandParameter interSchemaParam = paramMap.get("internal-schema"); boolean isInternalSchema = Boolean.valueOf(String.valueOf(interSchemaParam.getValue())); - SchemaValidate schema; if (isInternalSchema) { location = location.substring(1); - schema = new SchemaValidator(location); - } else { - schema = new SchemaValidator(new File(location)); } - List<String> error = schema.validate(); + List<String> error = OnapCommandUtils.loadSchema(new OnapCommand() { + @Override + protected void run() throws OnapCommandException { + } + }, location, true, true); + + + error.addAll(OnapCommandUtils.loadHTTPSchemaSection(new OnapHttpCommand(), + location, true)); + List<String> slNumber = new ArrayList<>(); for (int i = 1; i <= error.size(); i++) { slNumber.add(String.valueOf(i)); diff --git a/framework/src/main/java/org/onap/cli/fw/conf/Constants.java b/framework/src/main/java/org/onap/cli/fw/conf/Constants.java index f6a4193f..d559f7aa 100644 --- a/framework/src/main/java/org/onap/cli/fw/conf/Constants.java +++ b/framework/src/main/java/org/onap/cli/fw/conf/Constants.java @@ -22,6 +22,25 @@ package org.onap.cli.fw.conf; */ public class Constants { + // schema validation + public static final String TOP_LEVEL_PARAMS_LIST ="cli.schema.top_level_params_list"; + public static final String TOP_LEVEL_MANDATORY_LIST ="cli.schema.top_level_mandatory_list"; + public static final String SERVICE_PARAMS_LIST ="cli.schema.service_params_list"; + public static final String SERVICE_PARAMS_MANDATORY_LIST ="cli.schema.service_params_mandatory_list"; + public static final String INPUT_PARAMS_LIST ="cli.schema.input_params_list"; + public static final String INPUT_PARAMS_MANDATORY_LIST ="cli.schema.input_params_mandatory_list"; + public static final String RESULT_PARAMS_LIST ="cli.schema.result_params_list"; + public static final String RESULT_PARAMS_MANDATORY_LIST ="cli.schema.result_params_mandatory_list"; + public static final String HTTP_SECTIONS ="cli.schema.http_sections"; + public static final String HTTP_MANDATORY_SECTIONS ="cli.schema.http_mandatory_sections"; + public static final String HTTP_REQUEST_PARAMS ="cli.schema.http_request_params"; + public static final String HTTP_REQUEST_MANDATORY_PARAMS ="cli.schema.http_request_mandatory_params"; + public static final String HTTP_METHODS ="cli.schema.http_methods"; + public static final String BOOLEAN_VALUE ="cli.schema.boolean_values"; + public static final String AUTH_VALUES="cli.schema.auth_values"; + public static final String MODE_VALUES="cli.schema.mode_values"; + + public static final String SSLCONTEST_TLS = "TLSV1.2"; public static final String APPLICATION_JSON = "application/json"; public static final String X_AUTH_TOKEN = "x-auth-token"; diff --git a/framework/src/main/java/org/onap/cli/fw/conf/OnapCommandConfg.java b/framework/src/main/java/org/onap/cli/fw/conf/OnapCommandConfg.java index acb2c2b0..1dfd345c 100644 --- a/framework/src/main/java/org/onap/cli/fw/conf/OnapCommandConfg.java +++ b/framework/src/main/java/org/onap/cli/fw/conf/OnapCommandConfg.java @@ -19,6 +19,7 @@ package org.onap.cli.fw.conf; import java.io.IOException; import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; @@ -133,4 +134,9 @@ public final class OnapCommandConfg { return Arrays.stream(prps.getProperty(Constants.NO_AUTH_ENABLE_INCLUDE_PARAMS_EXTERNAL_CMD) .split(",")).map(String::trim).collect(Collectors.toSet()); } + + public static List<String> getSchemaAttrInfo(String key) { + return Arrays.stream(prps.getProperty(key).split(",")).map(String::trim).collect(Collectors.toList()); + } + } diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandHttpInvalidResultMap.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandHttpInvalidResultMap.java new file mode 100644 index 00000000..491f18cb --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandHttpInvalidResultMap.java @@ -0,0 +1,32 @@ +/* + * Copyright 2017 Huawei Technologies Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.cli.fw.error; + +import java.util.List; + +/** + * Invalid result map in HTTP section. + * + */ +public class OnapCommandHttpInvalidResultMap extends OnapCommandException { + + private static final long serialVersionUID = 6676137916023457963L; + + public OnapCommandHttpInvalidResultMap(List<String> invalidParams) { + super("0x0028", "Invalide result map parameters : " + invalidParams.toString()); + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/schema/AbstractSchemaValidate.java b/framework/src/main/java/org/onap/cli/fw/schema/AbstractSchemaValidate.java deleted file mode 100644 index 1b0a2beb..00000000 --- a/framework/src/main/java/org/onap/cli/fw/schema/AbstractSchemaValidate.java +++ /dev/null @@ -1,563 +0,0 @@ -/* - * Copyright 2017 Huawei Technologies Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onap.cli.fw.schema; - -import org.onap.cli.fw.error.OnapCommandInvalidSchema; -import org.onap.cli.fw.utils.OnapCommandUtils; -import org.springframework.core.io.Resource; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.parser.ParserException; - -import static org.onap.cli.fw.conf.Constants.*; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -/** - * Abstract schema validation class. - * - */ -public abstract class AbstractSchemaValidate implements SchemaValidate { - - /** - * Supported schema types. - * - */ - protected enum SchemaType { - HTTP, BASIC - } - - protected List<String> schemaErrors = new ArrayList<>(); - protected Map<String, Object> yamlMap = new HashMap<>(); - protected Map<String, Object> defaultYamlMap = new HashMap<>(); - - protected static final List<String> HTTP_SCHEMA_LIST = Arrays.asList(ONAP_CMD_SCHEMA_VERSION, NAME, DESCRIPTION, - SERVICE, PARAMETERS, RESULTS, HTTP); - - protected static final List<String> HTTP_SCHEMA_MANDATORY_LIST = Arrays.asList(ONAP_CMD_SCHEMA_VERSION, NAME, - DESCRIPTION, SERVICE, HTTP); - protected static final List<String> BASIC_SCHEMA_LIST = Arrays.asList(ONAP_CMD_SCHEMA_VERSION, NAME, DESCRIPTION, - PARAMETERS, RESULTS); - - protected static final List<String> BASIC_SCHEMA_MANDATORY_LIST = Arrays.asList(ONAP_CMD_SCHEMA_VERSION, NAME, - DESCRIPTION, PARAMETERS); - - protected static final List<String> TOP_LEVEL_PARAMS_LIST = Arrays.asList(ONAP_CMD_SCHEMA_VERSION, NAME, - DESCRIPTION); - - protected static final List<String> TOP_LEVEL_MANDATORY_LIST = Arrays.asList(ONAP_CMD_SCHEMA_VERSION, NAME, - DESCRIPTION); - - protected static final List<String> SERVICE_PARAMS_LIST = Arrays.asList(NAME, VERSION, AUTH); - - protected static final List<String> SERVICE_PARAMS_MANDATORY_LIST = Arrays.asList(NAME, VERSION); - - protected static final List<String> INPUT_PARAMS_LIST = Arrays.asList(NAME, DESCRIPTION, TYPE, SHORT_OPTION, - LONG_OPTION, IS_OPTIONAL, DEFAULT_VALUE, IS_SECURED); - - protected static final List<String> INPUT_PARAMS_MANDATORY_LIST = Arrays.asList(NAME, DESCRIPTION, TYPE); - - protected static final List<String> PARAMETER_TYPES = Arrays.asList(PARAMETER_TYPE_JSON, PARAMETER_TYPE_YAML, - PARAMETER_TYPE_STRING, PARAMETER_TYPE_LONG, PARAMETER_TYPE_URL, PARAMETER_TYPE_BOOL, PARAMETER_TYPE_ARRAY, - PARAMETER_TYPE_MAP, PARAMETER_TYPE_BINARY); - - protected static final List<String> RESULT_PARAMS_LIST = Arrays.asList(NAME, DESCRIPTION, TYPE, SHORT_OPTION, - LONG_OPTION, IS_OPTIONAL, DEFAULT_VALUE, IS_SECURED); - - protected static final List<String> RESULT_PARAMS_MANDATORY_LIST = Arrays.asList(NAME, DESCRIPTION, TYPE); - - protected static final List<String> HTTP_PARAMS_LIST = Arrays.asList(URI, METHOD, BODY, HEADERS, QUERIES); - - protected static final List<String> HTTP_PARAMS_MANDATORY_LIST = Arrays.asList(URI, METHOD, BODY, HEADERS, QUERIES); - - protected static final List<String> HTTP_MANDATORY_SECTIONS = Arrays.asList(REQUEST, SUCCESS_CODES); - - protected static final List<String> HTTP_SECTIONS = Arrays.asList(REQUEST, SUCCESS_CODES, RESULT_MAP, - SAMPLE_RESPONSE); - - protected static final List<String> HTTP_REQUEST_MANDATORY_PARAMS = Arrays.asList(URI, METHOD); - - protected static final List<String> HTTP_REQUEST_PARAMS = Arrays.asList(URI, METHOD, BODY, HEADERS, QUERIES); - - protected static final List<String> BOOLEAN_VALUES = Arrays.asList(BOOLEAN_TRUE, BOOLEAN_FALSE); - protected static final List<String> DIRECTIONS = Arrays.asList(DIRECTION_PORTRAIT, DIRECTION_LANDSCAPE); - protected static final List<String> RESULT_SCOPES = Arrays.asList(RESULT_SCOPE_SHORT, RESULT_SCOPE_LONG); - - protected static final List<String> HTTP_METHODS = Arrays.asList(POST, GET, DELETE, PUT, HEAD); - - /** - * Constructor. - * - * @param schemaFile - * schemafile - * @throws OnapCommandInvalidSchema - * exception - */ - public AbstractSchemaValidate(File schemaFile) throws OnapCommandInvalidSchema { - loadYaml(schemaFile); - loadDefaultYaml(); - } - - /** - * Constructor. - * - * @param schemaFile - * resourceName - * @throws OnapCommandInvalidSchema - * exception - */ - public AbstractSchemaValidate(String schemaFile) throws OnapCommandInvalidSchema { - - try { - Resource res = OnapCommandUtils.getExternalResource(schemaFile, EXTERNAL_SCHEMA_PATH_PATERN); - InputStream inputStream; - if (res == null) { - inputStream = OnapCommandUtils.class.getClassLoader().getResourceAsStream(schemaFile); - } else { - inputStream = res.getInputStream(); - } - - if (inputStream != null) { - loadYamlFromInputStream(schemaFile, inputStream); - } else { - throw new OnapCommandInvalidSchema(schemaFile, SCHEMA_FILE_NOT_EXIST); - } - - } catch (IOException e) { - throw new OnapCommandInvalidSchema(schemaFile, e); - } - loadDefaultYaml(); - } - - private final void loadYaml(File schemaFile) throws OnapCommandInvalidSchema { - if (!schemaFile.isFile()) { - throw new OnapCommandInvalidSchema(schemaFile.getName(), SCHEMA_FILE_NOT_EXIST); - } - String fileName = schemaFile.getName(); - - if (!fileName.endsWith(".yaml")) { - throw new OnapCommandInvalidSchema(fileName, SCHEMA_FILE_WRONG_EXTN); - } - - try { - InputStream inputStream = new FileInputStream(schemaFile); - loadYamlFromInputStream(schemaFile.getName(), inputStream); - } catch (FileNotFoundException e) { - throw new OnapCommandInvalidSchema(fileName, e); - } - } - - @SuppressWarnings("unchecked") - private final void loadYamlFromInputStream(String fileName, InputStream inputStream) - throws OnapCommandInvalidSchema { - try { - yamlMap = (Map<String, Object>) new Yaml().load(inputStream); - } catch (ParserException e) { - throw new OnapCommandInvalidSchema(fileName, e); - } finally { - if (inputStream != null) { - try { - inputStream.close(); - } catch (IOException e) { - throw new OnapCommandInvalidSchema(fileName, e); // NOSONAR - } - } - } - - if (yamlMap == null) { - throw new OnapCommandInvalidSchema(fileName, SCHEMA_FILE_EMPTY); - } - } - - @SuppressWarnings("unchecked") - private final void loadDefaultYaml() throws OnapCommandInvalidSchema { - InputStream inputStream = AbstractSchemaValidate.class.getClassLoader() - .getResourceAsStream(DEFAULT_SCHEMA_FILE_NAME); - try { - defaultYamlMap = (Map<String, Object>) new Yaml().load(inputStream); - } catch (ParserException e) { - throw new OnapCommandInvalidSchema(DEFAULT_SCHEMA_FILE_NAME, e); - } - - if (defaultYamlMap == null) { - throw new OnapCommandInvalidSchema(DEFAULT_SCHEMA_FILE_NAME, SCHEMA_FILE_EMPTY); - } - } - - /* - * Validate method. - * - * @throws OnapCommandInvalidSchema exception - */ - @Override - public List<String> validate() throws OnapCommandInvalidSchema { - - SchemaType type; - Set<String> mainSections = yamlMap.keySet(); - if (mainSections.containsAll(HTTP_SCHEMA_MANDATORY_LIST)) { - type = SchemaType.HTTP; - } else if (mainSections.containsAll(BASIC_SCHEMA_MANDATORY_LIST)) { - type = SchemaType.BASIC; - } else { - schemaErrors.add(SchemaValidate.invalidSections(mainSections, HTTP_SCHEMA_MANDATORY_LIST, - BASIC_SCHEMA_MANDATORY_LIST)); - return schemaErrors; - } - - if (type.equals(SchemaType.BASIC)) { - validateTopLevelAttributes(); - validateInputParameters(); - validateResultParameters(); - } else { - validateTopLevelAttributes(); - validateServiceAttributes(); - validateInputParameters(); - validateResultParameters(); - validateSpecificSchema(SchemaType.HTTP); - } - return schemaErrors; - } - - private void validateResultAttributes(List<Map<String, Object>> resultAttributes) { - Set<String> resultParamNames = new HashSet<>(); - for (Map<String, Object> attribute : resultAttributes) { - - // Validate mandatory parameters - validateMandatoryParams(attribute, RESULT_PARAMS_LIST, RESULT_PARAMS_MANDATORY_LIST, ATTRIBUTES); - - String name = String.valueOf(attribute.get(NAME)); - - if (resultParamNames.contains(name)) { - schemaErrors.add(SchemaValidate.attributeNameExist(name, ATTRIBUTES)); - } else { - resultParamNames.add(name); - } - - // Validate specific parameters - Object type = attribute.get(TYPE); - String value = String.valueOf(type); - if (!PARAMETER_TYPES.contains(value.toLowerCase())) { - schemaErrors.add(SchemaValidate.invalidType(ATTRIBUTES, name, PARAMETER_TYPES)); - } - - Object scope = attribute.get(SCOPE); - if (scope == null) { - schemaErrors.add(SchemaValidate.attributeScopeEmpty(name)); - } else if (!RESULT_SCOPES.contains(scope)) { - schemaErrors.add(SchemaValidate.invalidAttributeScope(name, RESULT_SCOPES)); - } - - Object isSecured = attribute.get(IS_SECURED); - if (isSecured != null) { - String value2 = String.valueOf(isSecured); - if (!validateBoolean(value2)) { - schemaErrors.add(SchemaValidate.invalidBooleanValueMessage(ATTRIBUTES, IS_SECURED, value2)); - } - } - } - - } - - private void validateResultParameters() { - @SuppressWarnings("unchecked") - Map<String, Object> resultParams = (Map<String, Object>) yamlMap.get(RESULTS); - - if (resultParams == null || resultParams.isEmpty()) { - return; - } - - Object direction = resultParams.get(DIRECTION); - - if (direction != null && !DIRECTIONS.contains(direction)) { - schemaErrors.add(SchemaValidate.invalidType(PARAMETERS, DIRECTION, DIRECTIONS)); - } - - @SuppressWarnings("unchecked") - List<Map<String, Object>> resultAttributes = (List<Map<String, Object>>) resultParams.get(ATTRIBUTES); - validateResultAttributes(resultAttributes); - } - - /** - * Get all default short options. - * - * @return set - */ - protected Set<String> getDefaultShortOptions() { - - Set<String> set = new HashSet<>(); - - @SuppressWarnings("unchecked") - List<Map<String, Object>> inputParams = (List<Map<String, Object>>) defaultYamlMap.get(PARAMETERS); - for (Map<String, Object> parameter : inputParams) { - Object name = parameter.get(SHORT_OPTION); - if (name != null && !String.valueOf(name).isEmpty() && !"null".equals(name)) { - set.add(String.valueOf(name)); - } - } - - return set; - } - - /** - * Get all default long options. - * - * @return set - */ - protected Set<String> getDefaultLongOptions() { - - Set<String> set = new HashSet<>(); - - @SuppressWarnings("unchecked") - List<Map<String, Object>> inputParams = (List<Map<String, Object>>) defaultYamlMap.get(PARAMETERS); - for (Map<String, Object> parameter : inputParams) { - Object name = parameter.get(LONG_OPTION); - if (name != null && !String.valueOf(name).isEmpty() && !"null".equals(name)) { - set.add(String.valueOf(name)); - } - } - - return set; - } - - private void validateTopLevelAttributes() { - validateMandatoryParams(yamlMap, TOP_LEVEL_PARAMS_LIST, TOP_LEVEL_MANDATORY_LIST, "root level"); - } - - private void validateServiceAttributes() { - - @SuppressWarnings("unchecked") - Map<String, Object> serviceMap = (Map<String, Object>) yamlMap.get(SERVICE); - - if (serviceMap == null) { - schemaErrors.add(SchemaValidate.emptySection(SERVICE)); - return; - } - - validateMandatoryParams(serviceMap, SERVICE_PARAMS_LIST, SERVICE_PARAMS_MANDATORY_LIST, SERVICE); - - // Validate specific parameters - - if (serviceMap.containsKey(AUTH)) { - Object obj = serviceMap.get(AUTH); - if (obj == null) { - schemaErrors.add(SchemaValidate.emptyValue(SERVICE, AUTH)); - } else { - String value = String.valueOf(obj); - if (validateBoolean(value)) { - schemaErrors.add(SchemaValidate.invalidBooleanValueMessage(SERVICE, AUTH, value)); - } - } - } - - } - - private void validateInputParameters() { - - @SuppressWarnings("unchecked") - List<Map<String, Object>> inputParams = (List<Map<String, Object>>) yamlMap.get(PARAMETERS); - if (inputParams == null) { - return; - } - validateInputAttributes(inputParams); - } - - protected abstract void validateSpecificSchema(SchemaType type) throws OnapCommandInvalidSchema; - - private void validateInputAttributes(List<Map<String, Object>> inputParams) { - Set<String> inputParamNames = new HashSet<>(); - Set<String> inputShortOptions = new HashSet<>(); - Set<String> inputLongOptions = new HashSet<>(); - - Set<String> defaultShortOptions = getDefaultShortOptions(); - Set<String> defaultLongOptions = getDefaultLongOptions(); - - for (Map<String, Object> parameter : inputParams) { - - // Validate mandatory parameters - validateMandatoryParams(parameter, INPUT_PARAMS_LIST, INPUT_PARAMS_MANDATORY_LIST, PARAMETERS); - - // Validate specific parameters - - String name = String.valueOf(parameter.get(NAME)); - - if (inputParamNames.contains(name)) { - schemaErrors.add(SchemaValidate.nameExist(name, PARAMETERS)); - } else { - inputParamNames.add(name); - } - - String value = String.valueOf(parameter.get(TYPE)); - - if (!PARAMETER_TYPES.contains(value.toLowerCase())) { - schemaErrors.add(SchemaValidate.invalidAttrType(name, PARAMETERS, PARAMETER_TYPES)); - } - - Object isOptional = parameter.get(IS_OPTIONAL); - if (isOptional != null) { - String value1 = String.valueOf(isOptional); - if (!validateBoolean(value1)) { - schemaErrors.add(SchemaValidate.invalidBooleanValueMessage(name, IS_OPTIONAL, value1)); - } - } - - Object isSecured = parameter.get(IS_SECURED); - if (isSecured != null) { - String value2 = String.valueOf(isSecured); - if (!validateBoolean(value2)) { - schemaErrors.add(SchemaValidate.invalidBooleanValueMessage(name, IS_SECURED, value2)); - } - } - - String shortOption = String.valueOf(parameter.get(SHORT_OPTION)); - String longOption = String.valueOf(parameter.get(LONG_OPTION)); - - if (inputShortOptions.contains(shortOption)) { - schemaErrors.add(SchemaValidate.optionExist(SHORT_OPTION, shortOption, name)); - } else if (defaultShortOptions.contains(shortOption)) { - - schemaErrors - .add(SchemaValidate.optionDefaultExist(SHORT_OPTION, shortOption, name, defaultShortOptions)); - - } else if (shortOption != null && !shortOption.isEmpty() && !"null".equals(shortOption)) { - inputShortOptions.add(shortOption); - } - - if (inputLongOptions.contains(longOption)) { - schemaErrors.add(SchemaValidate.optionExist(LONG_OPTION, longOption, name)); - } else if (defaultLongOptions.contains(longOption)) { - - schemaErrors.add(SchemaValidate.optionDefaultExist(LONG_OPTION, longOption, name, defaultLongOptions)); - } else if (longOption != null && !longOption.isEmpty() && !"null".equals(shortOption)) { - inputLongOptions.add(longOption); - } - - } - - } - - /** - * Validate mandatory parameters. - * - * @param yamlMap - * yaml map - * @param totalParams - * list - * @param mandatoryParams - * list - * @param section - * section - */ - protected void validateMandatoryParams(Map<String, Object> yamlMap, List<String> totalParams, - List<String> mandatoryParams, String section) { - - for (String param : totalParams) { - boolean isMandatory = mandatoryParams.contains(param); - boolean isYamlContains = yamlMap.containsKey(param); - if (isMandatory) { - if (!isYamlContains) { - schemaErrors.add(SchemaValidate.mandatoryAttrMissing(param, section)); - } else { - String value = String.valueOf(yamlMap.get(param)); - if (value == null || "".equals(value) || "null".equals(value)) { - schemaErrors.add(SchemaValidate.mandatoryAttrEmpty(param, section)); - } - } - } - } - } - - /** - * Load result attributes. - * - * @return set - */ - @SuppressWarnings("unchecked") - protected Set<String> getResultAttributes() { - - Set<String> set = new HashSet<>(); - - List<Map<String, Object>> resultAttributes = yamlMap.get(RESULTS) != null - ? (List<Map<String, Object>>) ((Map<String, Object>) yamlMap.get(RESULTS)).get(ATTRIBUTES) - : Collections.emptyList(); - - if (resultAttributes != null) { - for (Map<String, Object> map : resultAttributes) { - for (Entry<String, Object> entry : map.entrySet()) { - Object key = entry.getKey(); - - if (NAME.equals(key)) { - set.add(String.valueOf(entry.getValue())); - break; - } - } - } - } - - return set; - } - - /** - * Get request parameters. - * - * @return set - */ - protected Set<String> getRequestParams() { - - Set<String> set = new HashSet<>(); - - @SuppressWarnings("unchecked") - List<Map<String, Object>> inputParams = (List<Map<String, Object>>) yamlMap.get(PARAMETERS); - - if (inputParams != null) { - for (Map<String, Object> map : inputParams) { - for (Entry<String, Object> entry : map.entrySet()) { - Object key = entry.getKey(); - - if (NAME.equals(key)) { - set.add(String.valueOf(entry.getValue())); - break; - } - } - } - } - - return set; - } - - /** - * Validate Boolean. - * - * @param toValidate - * string - * @return boolean - */ - protected static boolean validateBoolean(String toValidate) { - return BOOLEAN_VALUES.contains(toValidate.toLowerCase()); - } -} diff --git a/framework/src/main/java/org/onap/cli/fw/schema/SchemaValidate.java b/framework/src/main/java/org/onap/cli/fw/schema/SchemaValidate.java deleted file mode 100644 index 27bc4661..00000000 --- a/framework/src/main/java/org/onap/cli/fw/schema/SchemaValidate.java +++ /dev/null @@ -1,324 +0,0 @@ -/* - * Copyright 2017 Huawei Technologies Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onap.cli.fw.schema; - -import org.onap.cli.fw.error.OnapCommandInvalidSchema; - -import java.util.List; -import java.util.Set; - -/** - * Schema validate interface. - * - */ -@FunctionalInterface -public interface SchemaValidate { - /** - * Validates HTTP or Basic Schema. - * - * @return List of errors - * @throws OnapCommandInvalidSchema - * Failed to load schema file - */ - public List<String> validate() throws OnapCommandInvalidSchema; - - /** - * Static interface method. - * - * @param section - * section - * @return errorMessage - */ - public static String defaultYamlSchema(String section) { - return "The section '" + section + ":' cann't be null or empty"; - } - - /** - * Static interface method. - * - * @param section - * string - * @param attribute - * string - * @param value - * string - * @return string - */ - public static String invalidBooleanValueMessage(String section, String attribute, String value) { - return "The value '" + value + "' of '" + attribute + "' present under '" + section + "' should be boolean"; - } - - /** - * Static interface method. - * - * @param section - * string - * @param attribute - * string - * @return string - */ - public static String emptyValue(String section, String attribute) { - return "Attribute '" + attribute + "' under '" + section + "' is null or empty"; - } - - /** - * Static interface method. - * - * @param section - * string - * @param attribute - * string - * @param types - * list - * @return string - */ - public static String invalidType(String section, String attribute, List<String> types) { - return "Attribute '" + attribute + "' under '" + section + "' is invalid, correct types are " - + types.toString(); - } - - /** - * Static interface method. - * - * @param subSection - * string - * @param attribute - * string - * @return string - */ - public static String invalidRequestParam(String subSection, String attribute) { - return "The http request '" + subSection + "' parameter '" + attribute - + "' is not declared under 'parameters:' section"; - } - - /** - * Static interface method. - * - * @param section - * string - * @return string - */ - public static String emptySection(String section) { - return "The section '" + section + ":' cann't be null or empty"; - } - - /** - * Static interface method. - * - * @param mainSections - * list - * @param http - * list - * @param basic - * list - * @return string - */ - public static String invalidSections(Set<String> mainSections, List<String> http, List<String> basic) { - return "No matching schema type found due to extra or missing sections in the file" + mainSections.toString() - + " , Supported schema sections are http" + http.toString() + " and basic" + basic.toString(); - } - - /** - * Static interface method. - * - * @param name - * string - * @param section - * string - * @return string - */ - public static String attributeNameExist(String name, String section) { - return "Attribute name='" + name + "' under '" + section + ":' is already used, Take different one."; - } - - /** - * Static interface method. - * - * @param name - * string - * @param scopes - * list - * @return string - */ - public static String invalidAttributeScope(String name, List<String> scopes) { - return "The attribute '" + name + "' scope is invalid, valid scopes are " + scopes.toString(); - } - - /** - * Static interface method. - * - * @param name - * string - * @return string - */ - public static String attributeScopeEmpty(String name) { - return "The attribute '" + name + "' scope is null or empty."; - } - - /** - * Static interface method. - * - * @param option - * string - * @param attrValue - * string - * @param name - * string - * @return string - */ - public static String optionExist(String option, String attrValue, String name) { - return "Attribute " + option + " option '" + attrValue + "' of parameter '" + name - + "' is already used, Take different one."; - } - - /** - * Static interface method. - * - * @param option - * string - * @param attrValue - * string - * @param name - * string - * @param list - * list - * @return string - */ - public static String optionDefaultExist(String option, String attrValue, String name, Set<String> list) { - return "Attribute " + option + " option '" + attrValue + "' of parameter '" + name - + "' is already used in default parameters list " + list.toString() + ", Take different one."; - } - - /** - * Static interface method. - * - * @param name - * string - * @return string - */ - public static String longOptionExist(String name) { - return "The attribute '" + name + "' scope is null or empty."; - } - - /** - * Static interface method. - * - * @param name - * string - * @return string - */ - public static String shortOptionExist(String name) { - return "The attribute '" + name + "' scope is null or empty."; - } - - /** - * Static interface method. - * - * @param name - * string - * @param section - * string - * @return string - */ - public static String nameExist(String name, String section) { - - return "Attribute name='" + name + "' under '" + section + ":' is already used, Take different one."; - } - - /** - * Static interface method. - * - * @param name - * string - * @param section - * string - * @param types - * list - * @return string - */ - public static String invalidAttrType(String name, String section, List<String> types) { - return "Attribute type of '" + name + "' under '" + section + "' is invalid, correct types are " - + types.toString(); - } - - /** - * Static interface method. - * - * @param param - * string - * @param section - * string - * @return string - */ - public static String mandatoryAttrMissing(String param, String section) { - - return "Mandatory attribute '" + param + "' is missing under '" + section + "'"; - } - - /** - * Static interface method. - * - * @param param - * string - * @param section - * string - * @return string - */ - public static String mandatoryAttrEmpty(String param, String section) { - - return "Mandatory attribute '" + param + "' under '" + section + "' shouldn't be null or empty"; - } - - /** - * Static interface method. - * - * @param attribute - * string - * @return string - */ - public static String missingInResultMap(String attribute) { - - return "The attribute '" + attribute - + "' declared under result 'attributes:' section is missing from http 'result_map:'."; - } - - /** - * Static interface method. - * - * @param attribute - * string - * @return string - */ - public static String missingInResultAttribute(String attribute) { - - return "Mapped attribute '" + attribute + "' is missing declaration in result attributes section."; - } - - /** - * Static interface method. - * - * @param declaredParam - * string - * @return string - */ - public static String parameterNotMapped(String declaredParam) { - - return "The parameter '" + declaredParam - + "' declared under 'parameters:' section is not mapped into request section."; - } - -} diff --git a/framework/src/main/java/org/onap/cli/fw/schema/SchemaValidator.java b/framework/src/main/java/org/onap/cli/fw/schema/SchemaValidator.java deleted file mode 100644 index bb1248b9..00000000 --- a/framework/src/main/java/org/onap/cli/fw/schema/SchemaValidator.java +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright 2017 Huawei Technologies Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onap.cli.fw.schema; - -import com.fasterxml.jackson.databind.ObjectMapper; -import net.minidev.json.JSONObject; - -import org.onap.cli.fw.error.OnapCommandInvalidSchema; - -import static org.onap.cli.fw.conf.Constants.*; - -import java.io.File; -import java.io.IOException; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import java.util.Set; - -/** - * Schema Validation impl. - * - */ -public class SchemaValidator extends AbstractSchemaValidate { - - /** - * Constructor. - * - * @param schemaFile - * file - * @throws OnapCommandInvalidSchema - * exception - */ - public SchemaValidator(File schemaFile) throws OnapCommandInvalidSchema { - super(schemaFile); - } - - public SchemaValidator(String schemaFile) throws OnapCommandInvalidSchema { - super(schemaFile); - } - - @Override - protected void validateSpecificSchema(SchemaType type) throws OnapCommandInvalidSchema { - if (type.equals(SchemaType.HTTP)) { - validateHttpParameters(); - } - } - - @SuppressWarnings("unchecked") - private void validateHttpParameters() { - - Map<String, Object> httpMap = (Map<String, Object>) yamlMap.get(HTTP); - - if (httpMap == null || httpMap.isEmpty()) { - schemaErrors.add(HTTP_SECTION_EMPTY); - return; - } - - validateMandatoryParams(httpMap, HTTP_SECTIONS, HTTP_MANDATORY_SECTIONS, PARAMETERS); - - Map<String, Object> requestMap = (Map<String, Object>) httpMap.get(REQUEST); - - if (requestMap != null && !requestMap.isEmpty()) { - validateHttpRequestParams(requestMap); - } else { - schemaErrors.add(SchemaValidate.emptySection(REQUEST)); - } - - List<Object> requestSuccessCodes = (List<Object>) httpMap.get(SUCCESS_CODES); - if (requestSuccessCodes != null && !requestSuccessCodes.isEmpty()) { - validateHttpSccessCodes(requestSuccessCodes); - } else { - schemaErrors.add(SchemaValidate.emptySection(SUCCESS_CODES)); - } - - Map<String, Object> resultMap = (Map<String, Object>) httpMap.get(RESULT_MAP); - - if (resultMap != null && !resultMap.isEmpty()) { - validateHttpResultMapping(resultMap); - } - - Object object = httpMap.get(SAMPLE_RESPONSE); - if (object != null) { - if (object instanceof String) { - schemaErrors.add(HTTP_SAMPLE_RESPONSE_FAILED_PARSING); - } else { - validateSampleResponse((Map<String, Object>) object); - } - } - } - - private void validateHttpRequestParams(Map<String, Object> requestMap) { - - if (requestMap == null || requestMap.isEmpty()) { - return; - } - // validate mandatory parameters - validateMandatoryParams(requestMap, HTTP_REQUEST_PARAMS, HTTP_REQUEST_MANDATORY_PARAMS, REQUEST); - - // Validate method types - String method = (String) requestMap.get(METHOD); - if (method != null && !method.isEmpty()) { - if (!HTTP_METHODS.contains(method.toLowerCase())) { - schemaErrors.add(SchemaValidate.invalidType(REQUEST, METHOD, HTTP_METHODS)); - } - } else { - schemaErrors.add("Http request method cann't be null or empty"); - } - - Set<String> requestParams = getRequestParams(); - - // validate uriParams - Set<String> uriParams = validateHttpUri(requestMap); - - // validate body - Set<String> bodyParams = validateHttpBody(requestMap); - - // validate header - Set<String> headerParams = validateHttpHeaders(requestMap); - - // validate queries - Set<String> queryParams = validateHttpQueries(requestMap); - - for (String declaredParam : requestParams) { - if (!uriParams.contains(declaredParam) && !bodyParams.contains(declaredParam) - && !headerParams.contains(declaredParam) && !queryParams.contains(declaredParam)) { - schemaErrors.add(SchemaValidate.parameterNotMapped(declaredParam)); - } - } - - Set<String> totalParams = new HashSet<>(); - totalParams.addAll(uriParams); - totalParams.addAll(bodyParams); - totalParams.addAll(queryParams); - totalParams.addAll(headerParams); - - for (String definedParam : totalParams) { - if (!requestParams.contains(definedParam)) { - if (uriParams.contains(definedParam)) { - schemaErrors.add(SchemaValidate.invalidRequestParam(URI, definedParam)); - } else if (bodyParams.contains(definedParam)) { - schemaErrors.add(SchemaValidate.invalidRequestParam(BODY, definedParam)); - } else if (queryParams.contains(definedParam)) { - schemaErrors.add(SchemaValidate.invalidRequestParam(QUERIES, definedParam)); - } else if (headerParams.contains(definedParam)) { - schemaErrors.add(SchemaValidate.invalidRequestParam(HEADERS, definedParam)); - } - } - } - - } - - private Set<String> validateHttpUri(Map<String, Object> requestMap) { - Set<String> uriParamNames = new HashSet<>(); - String uri = (String) requestMap.get(URI); - if (uri == null || uri.isEmpty()) { - schemaErrors.add(SchemaValidate.emptySection(URI)); - return uriParamNames; - } - parseParameters(uri, uriParamNames); - return uriParamNames; - } - - @SuppressWarnings("unchecked") - private Set<String> validateHttpHeaders(Map<String, Object> requestMap) { - - Map<String, Object> headers = (Map<String, Object>) requestMap.get(HEADERS); - Set<String> headerParamNames = new HashSet<>(); - if (headers != null) { - for (Entry<String, Object> entry : headers.entrySet()) { - parseParameters(String.valueOf(entry.getValue()), headerParamNames); - } - } - return headerParamNames; - } - - @SuppressWarnings("unchecked") - private Set<String> validateHttpQueries(Map<String, Object> requestMap) { - Map<String, Object> queries = (Map<String, Object>) requestMap.get(QUERIES); - Set<String> queryParamNames = new HashSet<>(); - if (queries != null) { - for (Entry<String, Object> entry : queries.entrySet()) { - parseParameters(String.valueOf(entry.getValue()), queryParamNames); - } - } - return queryParamNames; - } - - private Set<String> validateHttpBody(Map<String, Object> requestMap) { - Set<String> bodyParamNames = new HashSet<>(); - Object bodyString = requestMap.get(BODY); - if (bodyString == null) { - return bodyParamNames; - } - - String body = String.valueOf(bodyString); - JSONObject obj = null; - try { - obj = new ObjectMapper().readValue(body, JSONObject.class); - } catch (IOException e1) { // NOSONAR - schemaErrors.add(HTTP_BODY_FAILED_PARSING); - } - if (obj == null || "".equals(obj.toString())) { - schemaErrors.add(HTTP_BODY_JSON_EMPTY); - } - parseParameters(body, bodyParamNames); - - return bodyParamNames; - } - - private void parseParameters(String line, Set<String> paramNames) { - - int currentIdx = 0; - while (currentIdx < line.length()) { - int idxS = line.indexOf("${", currentIdx); - if (idxS == -1) { - break; - } - int idxE = line.indexOf("}", idxS); - String paramName = line.substring(idxS + 2, idxE); - paramNames.add(paramName.trim()); - - currentIdx = idxE + 1; - } - - } - - private void validateHttpSccessCodes(List<Object> requestSuccessCodes) { - - for (Object successCode : requestSuccessCodes) { - Integer code = (Integer) successCode; - if (code < 200 || code >= 300) { - schemaErrors.add(HTTP_SUCCESS_CODE_INVALID); - } - } - - } - - private void validateHttpResultMapping(Map<String, Object> resultMap) { - Set<String> resultAttributes = getResultAttributes(); - - // Validate if all result attributes are used in the result mapping - for (String attribute : resultAttributes) { - if (!resultMap.containsKey(attribute)) { - schemaErrors.add(SchemaValidate.missingInResultMap(attribute)); - } - } - - // Validate if all result mapping keys are defined in the result attributes - for (Entry<String, Object> entry : resultMap.entrySet()) { - if (!resultAttributes.contains(entry.getKey())) { - schemaErrors.add(SchemaValidate.missingInResultAttribute(entry.getKey())); - } - } - } - - private void validateSampleResponse(Map<String, Object> sampleResponseBodyMap) { - - // validate the json - Object json = sampleResponseBodyMap.get(BODY); - if (json == null) { - schemaErrors.add(HTTP_SAMPLE_RESPONSE_EMPTY); - return; - } - String jsonString = json.toString(); - try { - if (jsonString.startsWith("[")) { - new ObjectMapper().readValue(jsonString, JSONObject[].class); - } else { - new ObjectMapper().readValue(jsonString, JSONObject.class); - } - } catch (IOException e1) { // NOSONAR - schemaErrors.add(HTTP_SAMPLE_RESPONSE_FAILED_PARSING); - } - } - -} diff --git a/framework/src/main/java/org/onap/cli/fw/utils/OnapCommandUtils.java b/framework/src/main/java/org/onap/cli/fw/utils/OnapCommandUtils.java index 512d0b22..b6e64f2a 100644 --- a/framework/src/main/java/org/onap/cli/fw/utils/OnapCommandUtils.java +++ b/framework/src/main/java/org/onap/cli/fw/utils/OnapCommandUtils.java @@ -19,6 +19,7 @@ package org.onap.cli.fw.utils; import com.fasterxml.jackson.databind.ObjectMapper; import com.jayway.jsonpath.JsonPath; import net.minidev.json.JSONArray; +import net.minidev.json.JSONObject; import org.onap.cli.fw.OnapCommand; import org.onap.cli.fw.ad.OnapCredentials; import org.onap.cli.fw.ad.OnapService; @@ -31,6 +32,7 @@ import org.onap.cli.fw.error.OnapCommandException; import org.onap.cli.fw.error.OnapCommandHelpFailed; import org.onap.cli.fw.error.OnapCommandHttpHeaderNotFound; import org.onap.cli.fw.error.OnapCommandHttpInvalidResponseBody; +import org.onap.cli.fw.error.OnapCommandHttpInvalidResultMap; import org.onap.cli.fw.error.OnapCommandInvalidDefaultParameter; import org.onap.cli.fw.error.OnapCommandInvalidParameterType; import org.onap.cli.fw.error.OnapCommandInvalidParameterValue; @@ -60,6 +62,8 @@ import org.springframework.core.io.support.ResourcePatternResolver; import org.yaml.snakeyaml.Yaml; import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; @@ -75,6 +79,75 @@ import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; +import static org.onap.cli.fw.conf.Constants.API; +import static org.onap.cli.fw.conf.Constants.ATTRIBUTES; +import static org.onap.cli.fw.conf.Constants.AUTH; +import static org.onap.cli.fw.conf.Constants.AUTH_VALUES; +import static org.onap.cli.fw.conf.Constants.BODY; +import static org.onap.cli.fw.conf.Constants.BOOLEAN_VALUE; +import static org.onap.cli.fw.conf.Constants.CLIENT; +import static org.onap.cli.fw.conf.Constants.DEAFULT_PARAMETER_HOST_URL; +import static org.onap.cli.fw.conf.Constants.DEAFULT_PARAMETER_PASS_WORD; +import static org.onap.cli.fw.conf.Constants.DEAFULT_PARAMETER_USERNAME; +import static org.onap.cli.fw.conf.Constants.DEFAULT_PARAMETERS; +import static org.onap.cli.fw.conf.Constants.DEFAULT_PARAMETERS_EXCLUDE; +import static org.onap.cli.fw.conf.Constants.DEFAULT_PARAMETERS_INCLUDE; +import static org.onap.cli.fw.conf.Constants.DEFAULT_PARAMETER_FILE_NAME; +import static org.onap.cli.fw.conf.Constants.DEFAULT_VALUE; +import static org.onap.cli.fw.conf.Constants.DESCRIPTION; +import static org.onap.cli.fw.conf.Constants.DIRECTION; +import static org.onap.cli.fw.conf.Constants.ENTITY; +import static org.onap.cli.fw.conf.Constants.EXCEPTION; +import static org.onap.cli.fw.conf.Constants.EXECUTOR; +import static org.onap.cli.fw.conf.Constants.EXTERNAL_DISCOVERY_DIRECTORY; +import static org.onap.cli.fw.conf.Constants.EXTERNAL_DISCOVERY_DIRECTORY_PATTERN; +import static org.onap.cli.fw.conf.Constants.EXTERNAL_DISCOVERY_FILE; +import static org.onap.cli.fw.conf.Constants.EXTERNAL_SCHEMA_DIRECTORY; +import static org.onap.cli.fw.conf.Constants.EXTERNAL_SCHEMA_PATH_PATERN; +import static org.onap.cli.fw.conf.Constants.HEADERS; +import static org.onap.cli.fw.conf.Constants.HTTP; +import static org.onap.cli.fw.conf.Constants.HTTP_BODY_FAILED_PARSING; +import static org.onap.cli.fw.conf.Constants.HTTP_BODY_JSON_EMPTY; +import static org.onap.cli.fw.conf.Constants.HTTP_MANDATORY_SECTIONS; +import static org.onap.cli.fw.conf.Constants.HTTP_METHODS; +import static org.onap.cli.fw.conf.Constants.HTTP_REQUEST_MANDATORY_PARAMS; +import static org.onap.cli.fw.conf.Constants.HTTP_REQUEST_PARAMS; +import static org.onap.cli.fw.conf.Constants.HTTP_SECTIONS; +import static org.onap.cli.fw.conf.Constants.HTTP_SUCCESS_CODE_INVALID; +import static org.onap.cli.fw.conf.Constants.INPUT_PARAMS_LIST; +import static org.onap.cli.fw.conf.Constants.INPUT_PARAMS_MANDATORY_LIST; +import static org.onap.cli.fw.conf.Constants.IS_OPTIONAL; +import static org.onap.cli.fw.conf.Constants.IS_SECURED; +import static org.onap.cli.fw.conf.Constants.LONG_OPTION; +import static org.onap.cli.fw.conf.Constants.MERHOD; +import static org.onap.cli.fw.conf.Constants.METHOD; +import static org.onap.cli.fw.conf.Constants.MODE; +import static org.onap.cli.fw.conf.Constants.MODE_VALUES; +import static org.onap.cli.fw.conf.Constants.NAME; +import static org.onap.cli.fw.conf.Constants.ONAP_CMD_SCHEMA_VERSION; +import static org.onap.cli.fw.conf.Constants.PARAMETERS; +import static org.onap.cli.fw.conf.Constants.QUERIES; +import static org.onap.cli.fw.conf.Constants.REQUEST; +import static org.onap.cli.fw.conf.Constants.RESULTS; +import static org.onap.cli.fw.conf.Constants.RESULT_MAP; +import static org.onap.cli.fw.conf.Constants.RESULT_PARAMS_LIST; +import static org.onap.cli.fw.conf.Constants.RESULT_PARAMS_MANDATORY_LIST; +import static org.onap.cli.fw.conf.Constants.SAMPLE_RESPONSE; +import static org.onap.cli.fw.conf.Constants.SCHEMA_FILE_NOT_EXIST; +import static org.onap.cli.fw.conf.Constants.SCHEMA_FILE_WRONG_EXTN; +import static org.onap.cli.fw.conf.Constants.SCHEMA_INVALID_DEFAULT_PARAMS_SECTION; +import static org.onap.cli.fw.conf.Constants.SCOPE; +import static org.onap.cli.fw.conf.Constants.SERVICE; +import static org.onap.cli.fw.conf.Constants.SERVICE_PARAMS_LIST; +import static org.onap.cli.fw.conf.Constants.SERVICE_PARAMS_MANDATORY_LIST; +import static org.onap.cli.fw.conf.Constants.SHORT_OPTION; +import static org.onap.cli.fw.conf.Constants.SUCCESS_CODES; +import static org.onap.cli.fw.conf.Constants.TOP_LEVEL_MANDATORY_LIST; +import static org.onap.cli.fw.conf.Constants.TOP_LEVEL_PARAMS_LIST; +import static org.onap.cli.fw.conf.Constants.TYPE; +import static org.onap.cli.fw.conf.Constants.URI; +import static org.onap.cli.fw.conf.Constants.VERSION; + /** * Provides helper method to parse Yaml files and produce required objects. * @@ -102,7 +175,7 @@ public class OnapCommandUtils { InputStream inputStream = OnapCommandUtils.class.getClassLoader().getResourceAsStream(schemaName); try { - Resource resource = getExternalResource(schemaName, Constants.EXTERNAL_SCHEMA_PATH_PATERN); + Resource resource = getExternalResource(schemaName, EXTERNAL_SCHEMA_PATH_PATERN); if (resource != null) { inputStream = resource.getInputStream(); @@ -112,7 +185,7 @@ public class OnapCommandUtils { throw new OnapCommandSchemaNotFound(schemaName, e); } if (inputStream == null) { - throw new OnapCommandSchemaNotFound(schemaName); + inputStream = loadSchemaFromFile(schemaName); } Map<String, ?> values = null; @@ -122,8 +195,8 @@ public class OnapCommandUtils { throw new OnapCommandInvalidSchema(schemaName, e); } String schemaVersion = ""; - if (values.keySet().contains(Constants.ONAP_CMD_SCHEMA_VERSION)) { - Object obj = values.get(Constants.ONAP_CMD_SCHEMA_VERSION); + if (values.keySet().contains(ONAP_CMD_SCHEMA_VERSION)) { + Object obj = values.get(ONAP_CMD_SCHEMA_VERSION); schemaVersion = obj.toString(); } @@ -134,12 +207,30 @@ public class OnapCommandUtils { return values; } + private static InputStream loadSchemaFromFile(String schemaLocation) throws OnapCommandInvalidSchema { + File schemaFile = new File(schemaLocation); + try { + FileInputStream inputFileStream = new FileInputStream(schemaFile); + if (!schemaFile.isFile()) { + throw new OnapCommandInvalidSchema(schemaFile.getName(), SCHEMA_FILE_NOT_EXIST); + } + + if (!schemaFile.getName().endsWith(".yaml")) { + throw new OnapCommandInvalidSchema(schemaFile.getName(), SCHEMA_FILE_WRONG_EXTN); + } + return inputFileStream; + }catch (FileNotFoundException e) { + throw new OnapCommandInvalidSchema(schemaFile.getName(), e); + } + } + /** * Retrieve OnapCommand from schema. * * @param cmd OnapCommand * @param schemaName schema name * @param includeDefault include if default + * @param validateSchema flag to represent validation * @throws OnapCommandParameterNameConflict param name conflict exception * @throws OnapCommandParameterOptionConflict param option conflict exception * @throws OnapCommandInvalidParameterType invalid param type exception @@ -149,26 +240,26 @@ public class OnapCommandUtils { * @throws OnapCommandInvalidSchema invalid schema * @throws OnapCommandInvalidSchemaVersion invalid schema version */ - public static void loadSchema(OnapCommand cmd, String schemaName, boolean includeDefault) - throws OnapCommandException { + public static List<String> loadSchema(OnapCommand cmd, String schemaName, boolean includeDefault, + boolean validateSchema) throws OnapCommandException { try { Map<String, ?> defaultParameterMap = includeDefault ? - validateSchemaVersion(Constants.DEFAULT_PARAMETER_FILE_NAME, cmd.getSchemaVersion()) : new HashMap<>(); + validateSchemaVersion(DEFAULT_PARAMETER_FILE_NAME, cmd.getSchemaVersion()) : new HashMap<>(); Map<String, List<Map<String, String>>> commandYamlMap = (Map<String, List<Map<String, String>>>)validateSchemaVersion(schemaName, cmd.getSchemaVersion()); List<String> defParams = new ArrayList<>(); if (includeDefault) { - if (commandYamlMap.get(Constants.PARAMETERS) == null) { - commandYamlMap.put(Constants.PARAMETERS, (List<Map<String, String>>) defaultParameterMap.get(Constants.PARAMETERS)); + if (commandYamlMap.get(PARAMETERS) == null) { + commandYamlMap.put(PARAMETERS, (List<Map<String, String>>) defaultParameterMap.get(PARAMETERS)); } else { - commandYamlMap.get(Constants.PARAMETERS).addAll((List<Map<String, String>>) defaultParameterMap.get(Constants.PARAMETERS)); + commandYamlMap.get(PARAMETERS).addAll((List<Map<String, String>>) defaultParameterMap.get(PARAMETERS)); } - defParams = ((List<Map<String, String>>) defaultParameterMap.get(Constants.PARAMETERS)).stream() - .map(p -> p.get(Constants.NAME)).collect(Collectors.toList()); + defParams = ((List<Map<String, String>>) defaultParameterMap.get(PARAMETERS)).stream() + .map(p -> p.get(NAME)).collect(Collectors.toList()); } - parseSchema(cmd, commandYamlMap, defParams); + return parseSchema(cmd, commandYamlMap, defParams, validateSchema); } catch (OnapCommandException e) { throw e; } catch (Exception e) { @@ -212,80 +303,152 @@ public class OnapCommandUtils { } } - private static void parseSchema(OnapCommand cmd, - final Map<String, ?> values, - final List<String> defaultParamNames) throws OnapCommandException { + private static void throwOrCollect(OnapCommandException ex, List<String> list, + boolean shouldCollectException) throws OnapCommandException { + if (shouldCollectException) { + list.add(ex.getMessage()); + } else { + throw ex; + } + } + + private static void validateTags(List<String> schemaErrors, Map<String, ?> yamlMap, + List<String> totalParams, List<String> mandatoryParams, + String section) { + for (String param : totalParams) { + boolean isMandatory = mandatoryParams.contains(param); + boolean isYamlContains = yamlMap.containsKey(param); + if (isMandatory) { + if (!isYamlContains) { + schemaErrors.add("Mandatory attribute '" + param + "' is missing under '" + section + "'"); + } else { + String value = String.valueOf(yamlMap.get(param)); + if (value == null || value.isEmpty()) { + schemaErrors.add("Mandatory attribute '" + param + "' under '" + section + + "' shouldn't be null or empty"); + } + } + } + } + } + /** + * Validate Boolean. + * + * @param toValidate + * string + * @return boolean + */ + protected static boolean validateBoolean(String toValidate) { + return OnapCommandConfg.getSchemaAttrInfo(BOOLEAN_VALUE).contains(toValidate.toLowerCase()); + } + + private static List<String> parseSchema(OnapCommand cmd, + final Map<String, ?> values, + final List<String> defaultParamNames, + boolean validate) throws OnapCommandException { + + List<String> exceptionList = new ArrayList<>(); List<String> shortOptions = new ArrayList<>(); List<String> longOptions = new ArrayList<>(); - List<String> names = new ArrayList<>(); Set<String> filteredDefaultParams = new HashSet<>(); - List<String> sections = Arrays.asList(Constants.NAME, Constants.DESCRIPTION, Constants.SERVICE, - Constants.DEFAULT_PARAMETERS, Constants.PARAMETERS, Constants.RESULTS); + if (validate) { + validateTags(exceptionList, (Map<String, Object>) values, OnapCommandConfg.getSchemaAttrInfo(TOP_LEVEL_PARAMS_LIST), + OnapCommandConfg.getSchemaAttrInfo(TOP_LEVEL_MANDATORY_LIST), "root level"); + } + + + List<String> sections = Arrays.asList(NAME, DESCRIPTION, SERVICE, + DEFAULT_PARAMETERS, PARAMETERS, RESULTS); for (String key : sections) { - if (Constants.NAME.equals(key)) { + if (NAME.equals(key) && values.containsKey(key)) { Object val = values.get(key); if (val != null) { cmd.setName(val.toString()); } - } else if (Constants.DESCRIPTION.equals(key)) { + } else if (DESCRIPTION.equals(key) && values.containsKey(key)) { Object val = values.get(key); if (val != null) { cmd.setDescription(val.toString()); } - } else if (Constants.SERVICE.equals(key)) { + } else if (SERVICE.equals(key) && values.containsKey(key)) { Map<String, String> map = (Map<String, String>) values.get(key); + + if (validate) { + validateTags(exceptionList, (Map<String, Object>)values.get(key), + OnapCommandConfg.getSchemaAttrInfo(SERVICE_PARAMS_LIST), + OnapCommandConfg.getSchemaAttrInfo(SERVICE_PARAMS_MANDATORY_LIST), SERVICE); + + HashMap<String, String> validationMap = new HashMap<>(); + validationMap.put(AUTH, AUTH_VALUES); + validationMap.put(MODE, MODE_VALUES); + + for (String secKey : validationMap.keySet()) { + if (map.containsKey(secKey)) { + Object obj = map.get(secKey); + if (obj == null) { + exceptionList.add("Attribute '" + secKey + "' under '" + SERVICE + "' is empty"); + } else { + String value = String.valueOf(obj); + if (!OnapCommandConfg.getSchemaAttrInfo(validationMap.get(secKey)).contains(value)) { + exceptionList.add("Attribute '" + secKey + "' contains invalid value. Valide values are " + + OnapCommandConfg.getSchemaAttrInfo(validationMap.get(key))); // + } + } + } + } + } + if (map != null) { OnapService srv = new OnapService(); for (Map.Entry<String, String> entry1 : map.entrySet()) { String key1 = entry1.getKey(); - if (Constants.NAME.equals(key1)) { + if (NAME.equals(key1)) { srv.setName(map.get(key1)); - } else if (Constants.VERSION.equals(key1)) { + } else if (VERSION.equals(key1)) { srv.setVersion(map.get(key1)); - } else if (Constants.AUTH.equals(key1)) { + } else if (AUTH.equals(key1)) { Object obj = map.get(key1); - //TODO mrkanag Validate and raise exception for invalid case srv.setAuthType(obj.toString()); } else if (Constants.MODE.equals(key1)) { Object obj = map.get(key1); - //TODO mrkanag Validate and raise exception for invalid case srv.setMode(obj.toString()); } } cmd.setService(srv); } - } else if (Constants.DEFAULT_PARAMETERS.equals(key)) { + } else if (DEFAULT_PARAMETERS.equals(key)) { - Map<String, List<String>> defParameters = (Map) values.get(Constants.DEFAULT_PARAMETERS); + Map<String, List<String>> defParameters = (Map) values.get(DEFAULT_PARAMETERS); List<String> includeParams = new ArrayList<>(); List<String> excludeParams = new ArrayList<>(); - if (values.containsKey(Constants.DEFAULT_PARAMETERS) && defParameters == null) { + if (values.containsKey(DEFAULT_PARAMETERS) && defParameters == null) { // if default parameter section is available then it must have either include // or exclude sub-section. - throw new OnapCommandInvalidSchema(Constants.SCHEMA_INVALID_DEFAULT_PARAMS_SECTION); + throwOrCollect(new OnapCommandInvalidSchema(SCHEMA_INVALID_DEFAULT_PARAMS_SECTION), + exceptionList, validate); } if (defParameters != null) { // validate default parameters - if (defParameters.containsKey(Constants.DEFAULT_PARAMETERS_INCLUDE)) { - includeParams = defParameters.get(Constants.DEFAULT_PARAMETERS_INCLUDE); + if (defParameters.containsKey(DEFAULT_PARAMETERS_INCLUDE)) { + includeParams = defParameters.get(DEFAULT_PARAMETERS_INCLUDE); } List<String> invInclude = includeParams.stream() .filter(p -> !defaultParamNames.contains(p)) .collect(Collectors.toList()); - if (defParameters.containsKey(Constants.DEFAULT_PARAMETERS_EXCLUDE)) { - excludeParams = defParameters.get(Constants.DEFAULT_PARAMETERS_EXCLUDE); + if (defParameters.containsKey(DEFAULT_PARAMETERS_EXCLUDE)) { + excludeParams = defParameters.get(DEFAULT_PARAMETERS_EXCLUDE); } List<String> invExclude = excludeParams.stream().filter(p -> !defaultParamNames.contains(p)) @@ -293,8 +456,10 @@ public class OnapCommandUtils { if (!invExclude.isEmpty() || !invInclude.isEmpty()) { - throw new OnapCommandInvalidDefaultParameter(Stream.concat(invInclude.stream(), invExclude.stream()) - .collect(Collectors.toList())); + + throwOrCollect(new OnapCommandInvalidDefaultParameter(Stream.concat(invInclude.stream(), + invExclude.stream()).collect(Collectors.toList())), + exceptionList, validate); } if (!includeParams.isEmpty()) { @@ -307,50 +472,80 @@ public class OnapCommandUtils { } else { filteredDefaultParams.addAll(defaultParamNames); } - processNoAuth(filteredDefaultParams, cmd, includeParams, excludeParams); - } else if (Constants.PARAMETERS.equals(key)) { + try { + processNoAuth(filteredDefaultParams, cmd, includeParams, excludeParams); + } catch (OnapCommandException e) { + throwOrCollect(e, exceptionList, validate); + } + } else if (PARAMETERS.equals(key) && values.containsKey(key)) { List<Map<String, String>> parameters = (List) values.get(key); if (parameters != null) { + Set<String> names = new HashSet<>(); + Set<String> inputShortOptions = new HashSet<>(); + Set<String> inputLongOptions = new HashSet<>(); + for (Map<String, String> map : parameters) { OnapCommandParameter param = new OnapCommandParameter(); + if (validate) { + validateTags(exceptionList, map, OnapCommandConfg.getSchemaAttrInfo(INPUT_PARAMS_LIST), + OnapCommandConfg.getSchemaAttrInfo(INPUT_PARAMS_MANDATORY_LIST), PARAMETERS); + } + for (Map.Entry<String, String> entry1 : map.entrySet()) { String key2 = entry1.getKey(); - if (Constants.NAME.equals(key2)) { + if (NAME.equals(key2)) { if (names.contains(map.get(key2))) { - throw new OnapCommandParameterNameConflict(map.get(key2)); + throwOrCollect(new OnapCommandParameterNameConflict(map.get(key2)), exceptionList, validate); } names.add(map.get(key2)); param.setName(map.get(key2)); - } else if (Constants.DESCRIPTION.equals(key2)) { + } else if (DESCRIPTION.equals(key2)) { param.setDescription(map.get(key2)); - } else if (Constants.SHORT_OPTION.equals(key2)) { + } else if (SHORT_OPTION.equals(key2)) { if (shortOptions.contains(map.get(key2))) { - throw new OnapCommandParameterOptionConflict(map.get(key2)); + throwOrCollect(new OnapCommandParameterOptionConflict(map.get(key2)), exceptionList, validate); } shortOptions.add(map.get(key2)); param.setShortOption(map.get(key2)); - } else if (Constants.LONG_OPTION.equals(key2)) { + } else if (LONG_OPTION.equals(key2)) { if (longOptions.contains(map.get(key2))) { - throw new OnapCommandParameterOptionConflict(map.get(key2)); + throwOrCollect(new OnapCommandParameterOptionConflict(map.get(key2)), exceptionList, validate); } longOptions.add(map.get(key2)); param.setLongOption(map.get(key2)); - } else if (Constants.DEFAULT_VALUE.equals(key2)) { + } else if (DEFAULT_VALUE.equals(key2)) { Object obj = map.get(key2); param.setDefaultValue(obj.toString()); - } else if (Constants.TYPE.equals(key2)) { - param.setParameterType(ParameterType.get(map.get(key2))); - } else if (Constants.IS_OPTIONAL.equals(key2)) { + } else if (TYPE.equals(key2)) { + try { + param.setParameterType(ParameterType.get(map.get(key2))); + } catch (OnapCommandException ex) { + throwOrCollect(ex, exceptionList, validate); + } + } else if (IS_OPTIONAL.equals(key2)) { + if (validate) { + if (!validateBoolean(String.valueOf(map.get(key2)))) { + exceptionList.add(invalidBooleanValueMessage(map.get(NAME), + IS_SECURED, map.get(key2))); + } + } if ("true".equalsIgnoreCase(String.valueOf(map.get(key2)))) { param.setOptional(true); } else { param.setOptional(false); } - } else if (Constants.IS_SECURED.equals(key2)) { + } else if (IS_SECURED.equals(key2)) { + if (validate) { + if (!validateBoolean(String.valueOf(map.get(key2)))) { + exceptionList.add(invalidBooleanValueMessage(map.get(NAME), + IS_SECURED, map.get(key2))); + } + } + if ("true".equalsIgnoreCase(String.valueOf(map.get(key2)))) { param.setSecured(true); } else { @@ -367,32 +562,64 @@ public class OnapCommandUtils { } } } - } else if (Constants.RESULTS.equals(key)) { + } else if (RESULTS.equals(key) && values.containsKey(key)) { Map<String, ?> valueMap = (Map<String, ?>) values.get(key); if (valueMap != null) { OnapCommandResult result = new OnapCommandResult(); for (Map.Entry<String, ?> entry1 : valueMap.entrySet()) { String key3 = entry1.getKey(); - if (Constants.DIRECTION.equals(key3)) { - result.setPrintDirection(PrintDirection.get((String) valueMap.get(key3))); - } else if (Constants.ATTRIBUTES.equals(key3)) { + if (DIRECTION.equals(key3)) { + try { + result.setPrintDirection(PrintDirection.get((String) valueMap.get(key3))); + } catch (OnapCommandException ex) { + throwOrCollect(ex, exceptionList, validate); + } + } else if (ATTRIBUTES.equals(key3)) { List<Map<String, String>> attrs = (ArrayList) valueMap.get(key3); for (Map<String, String> map : attrs) { OnapCommandResultAttribute attr = new OnapCommandResultAttribute(); + if (validate) { + validateTags(exceptionList, map, OnapCommandConfg.getSchemaAttrInfo(RESULT_PARAMS_LIST), + OnapCommandConfg.getSchemaAttrInfo(RESULT_PARAMS_MANDATORY_LIST), ATTRIBUTES); + } + + Set<String> resultParamNames = new HashSet<>(); + for (Map.Entry<String, String> entry4 : map.entrySet()) { String key4 = entry4.getKey(); - if (Constants.NAME.equals(key4)) { - attr.setName(map.get(key4)); - } else if (Constants.DESCRIPTION.equals(key4)) { + if (NAME.equals(key4)) { + if (resultParamNames.contains(map.get(key4))) { + exceptionList.add("Attribute name='" + map.get(key4) + "' under '" + + ATTRIBUTES + ":' is already used, Take different one."); + + } else { + attr.setName(map.get(key4)); + resultParamNames.add(map.get(key4)); + } + } else if (DESCRIPTION.equals(key4)) { attr.setDescription(map.get(key4)); - } else if (Constants.SCOPE.equals(key4)) { - attr.setScope(OnapCommandResultAttributeScope.get(map.get(key4))); - } else if (Constants.TYPE.equals(key4)) { - attr.setType(ParameterType.get(map.get(key4))); - } else if (Constants.IS_SECURED.equals(key4)) { + } else if (SCOPE.equals(key4)) { + try { + attr.setScope(OnapCommandResultAttributeScope.get(map.get(key4))); + } catch (OnapCommandException ex) { + throwOrCollect(ex, exceptionList, validate); + } + } else if (TYPE.equals(key4)) { + try { + attr.setType(ParameterType.get(map.get(key4))); + } catch (OnapCommandException ex) { + throwOrCollect(ex, exceptionList, validate); + } + } else if (IS_SECURED.equals(key4)) { + if (validate) { + if (!validateBoolean(String.valueOf(map.get(key4)))) { + exceptionList.add(invalidBooleanValueMessage(ATTRIBUTES, + IS_SECURED, map.get(key4))); + } + } if ("true".equals(String.valueOf(map.get(key4)))) { attr.setSecured(true); } else { @@ -409,6 +636,112 @@ public class OnapCommandUtils { } } } + return exceptionList; + } + + private static String emptySection(String section) { + return "The section '" + section + ":' cann't be null or empty"; + } + + private static String invalidBooleanValueMessage(String section, String attribute, String value) { + return "The value '" + value + "' of '" + attribute + "' present under '" + section + "' should be boolean"; + } + + private static Set<String> validateHttpQueries(Map<String, Object> requestMap) { + Map<String, Object> queries = (Map<String, Object>) requestMap.get(QUERIES); + Set<String> queryParamNames = new HashSet<>(); + if (queries != null) { + for (Entry<String, Object> entry : queries.entrySet()) { + parseParameters(String.valueOf(entry.getValue()), queryParamNames); + } + } + return queryParamNames; + } + + + private static Set<String> validateHttpHeaders(Map<String, Object> requestMap) { + + Map<String, Object> headers = (Map<String, Object>) requestMap.get(HEADERS); + Set<String> headerParamNames = new HashSet<>(); + if (headers != null) { + for (Entry<String, Object> entry : headers.entrySet()) { + parseParameters(String.valueOf(entry.getValue()), headerParamNames); + } + } + return headerParamNames; + } + + private static Set<String> validateHttpBody(List<String> errorList, Map<String, Object> requestMap) { + Set<String> bodyParamNames = new HashSet<>(); + Object bodyString = requestMap.get(BODY); + if (bodyString == null) { + return bodyParamNames; + } + + String body = String.valueOf(bodyString); + JSONObject obj = null; + try { + obj = new ObjectMapper().readValue(body, JSONObject.class); + } catch (IOException e1) { // NOSONAR + errorList.add(HTTP_BODY_FAILED_PARSING); + } + if (obj == null || "".equals(obj.toString())) { + errorList.add(HTTP_BODY_JSON_EMPTY); + } + parseParameters(body, bodyParamNames); + + return bodyParamNames; + } + + private static Set<String> validateHttpUri(List<String> errorList, Map<String, Object> requestMap) { + Set<String> uriParamNames = new HashSet<>(); + String uri = (String) requestMap.get(URI); + if (uri == null || uri.isEmpty()) { + errorList.add(emptySection(URI)); + return uriParamNames; + } + parseParameters(uri, uriParamNames); + return uriParamNames; + } + + private static void parseParameters(String line, Set<String> paramNames) { + + int currentIdx = 0; + while (currentIdx < line.length()) { + int idxS = line.indexOf("${", currentIdx); + if (idxS == -1) { + break; + } + int idxE = line.indexOf("}", idxS); + String paramName = line.substring(idxS + 2, idxE); + paramNames.add(paramName.trim()); + + currentIdx = idxE + 1; + } + + } + + private static Set<String> getRequestParams(Map<String, ?> yamlMap) { + + Set<String> set = new HashSet<>(); + + @SuppressWarnings("unchecked") + List<Map<String, Object>> inputParams = (List<Map<String, Object>>) yamlMap.get(PARAMETERS); + + if (inputParams != null) { + for (Map<String, Object> map : inputParams) { + for (Entry<String, Object> entry : map.entrySet()) { + Object key = entry.getKey(); + + if (NAME.equals(key)) { + set.add(String.valueOf(entry.getValue())); + break; + } + } + } + } + + return set; } /** @@ -438,21 +771,21 @@ public class OnapCommandUtils { public static void loadSchema(OnapSwaggerCommand cmd, String schemaName) throws OnapCommandException { try { Map<String, ?> values = (Map<String, ?>) validateSchemaVersion(schemaName, cmd.getSchemaVersion()); - Map<String, String> valueMap = (Map<String, String>) values.get(Constants.EXECUTOR); + Map<String, String> valueMap = (Map<String, String>) values.get(EXECUTOR); OnapCommandExecutor exec = new OnapCommandExecutor(); for (Map.Entry<String, String> entry1 : valueMap.entrySet()) { String key1 = entry1.getKey(); - if (Constants.API.equals(key1)) { + if (API.equals(key1)) { exec.setApi(valueMap.get(key1)); - } else if (Constants.CLIENT.equals(key1)) { + } else if (CLIENT.equals(key1)) { exec.setClient(valueMap.get(key1)); - } else if (Constants.ENTITY.equals(key1)) { + } else if (ENTITY.equals(key1)) { exec.setEntity(valueMap.get(key1)); - } else if (Constants.EXCEPTION.equals(key1)) { + } else if (EXCEPTION.equals(key1)) { exec.setException(valueMap.get(key1)); - } else if (Constants.METHOD.equals(key1)) { + } else if (METHOD.equals(key1)) { exec.setMethod(valueMap.get(key1)); } } @@ -489,53 +822,148 @@ public class OnapCommandUtils { * @throws OnapCommandInvalidSchemaVersion * invalid schema version */ - public static void loadSchema(OnapHttpCommand cmd, String schemaName) throws OnapCommandException { + public static ArrayList<String> loadHTTPSchemaSection(OnapHttpCommand cmd, String schemaName, + boolean validate) throws OnapCommandException { + ArrayList<String> errorList = new ArrayList<>(); try { Map<String, ?> values = (Map<String, ?>) validateSchemaVersion(schemaName, cmd.getSchemaVersion()); - Map<String, ?> valMap = (Map<String, ?>) values.get(Constants.HTTP); + Map<String, ?> valMap = (Map<String, ?>) values.get(HTTP); - for (Map.Entry<String, ?> entry1 : valMap.entrySet()) { - String key1 = entry1.getKey(); - if (Constants.REQUEST.equals(key1)) { - Map<String, ?> map = (Map<String, ?>) valMap.get(key1); - - for (Map.Entry<String, ?> entry2 : map.entrySet()) { - String key2 = entry2.getKey(); - - if (Constants.URI.equals(key2)) { - Object obj = map.get(key2); - cmd.getInput().setUri(obj.toString()); - } else if (Constants.MERHOD.equals(key2)) { - Object obj = map.get(key2); - cmd.getInput().setMethod(obj.toString()); - } else if (Constants.BODY.equals(key2)) { - Object obj = map.get(key2); - cmd.getInput().setBody(obj.toString()); - } else if (Constants.HEADERS.equals(key2)) { - Map<String, String> head = (Map<String, String>) map.get(key2); - cmd.getInput().setReqHeaders(head); - } else if (Constants.QUERIES.equals(key2)) { - Map<String, String> query = (Map<String, String>) map.get(key2); - - cmd.getInput().setReqQueries(query); + if (valMap != null) { + if (validate) { + validateTags(errorList, valMap, OnapCommandConfg.getSchemaAttrInfo(HTTP_SECTIONS), + OnapCommandConfg.getSchemaAttrInfo(HTTP_MANDATORY_SECTIONS), PARAMETERS); + errorList.addAll(validateHttpSchemaSection(values)); + } + for (Map.Entry<String, ?> entry1 : valMap.entrySet()) { + String key1 = entry1.getKey(); + if (REQUEST.equals(key1)) { + Map<String, ?> map = (Map<String, ?>) valMap.get(key1); + + for (Map.Entry<String, ?> entry2 : map.entrySet()) { + try { + String key2 = entry2.getKey(); + if (URI.equals(key2)) { + Object obj = map.get(key2); + cmd.getInput().setUri(obj.toString()); + } else if (MERHOD.equals(key2)) { + Object obj = map.get(key2); + cmd.getInput().setMethod(obj.toString()); + } else if (BODY.equals(key2)) { + Object obj = map.get(key2); + cmd.getInput().setBody(obj.toString()); + } else if (HEADERS.equals(key2)) { + Map<String, String> head = (Map<String, String>) map.get(key2); + cmd.getInput().setReqHeaders(head); + } else if (QUERIES.equals(key2)) { + Map<String, String> query = (Map<String, String>) map.get(key2); + + cmd.getInput().setReqQueries(query); + } + }catch (Exception ex) { + throwOrCollect(new OnapCommandInvalidSchema(schemaName, ex), errorList, validate); + } + } + } else if (SUCCESS_CODES.equals(key1)) { + if (validate) { + validateHttpSccessCodes(errorList, (List<Object>) valMap.get(key1)); } + cmd.setSuccessStatusCodes((ArrayList) valMap.get(key1)); + } else if (RESULT_MAP.equals(key1)) { + if (validate) { + validateHttpResultMap(errorList, values); + } + cmd.setResultMap((Map<String, String>) valMap.get(key1)); + } else if (SAMPLE_RESPONSE.equals(key1)) { + // (mrkanag) implement sample response handling } - } else if (Constants.SUCCESS_CODES.equals(key1)) { - cmd.setSuccessStatusCodes((ArrayList) valMap.get(key1)); - } else if (Constants.RESULT_MAP.equals(key1)) { - cmd.setResultMap((Map<String, String>) valMap.get(key1)); - } else if (Constants.SAMPLE_RESPONSE.equals(key1)) { - // (mrkanag) implement sample response handling } } + }catch (OnapCommandException e) { + throwOrCollect(e, errorList, validate); + } + return errorList; + } - } catch (OnapCommandException e) { - throw e; - } catch (Exception e) { - throw new OnapCommandInvalidSchema(schemaName, e); + private static void validateHttpResultMap(List<String> errorList, Map<String, ?> values) throws OnapCommandException { + Map<String, ?> valMap = (Map<String, ?>) values.get(HTTP); + List<Map<String, String>> attributes = (List<Map<String, String>>) ((Map<String, ?>)values.get(RESULTS)).get(ATTRIBUTES); + Set<String> resultMapParams = ((Map<String, String>) valMap.get(RESULT_MAP)).keySet(); + + Set<String> resultAttNames = attributes.stream().map(map -> map.get(NAME)) + .collect(Collectors.toSet()); + + List<String> invaliResultMapParams = resultMapParams.stream() + .filter(p -> !resultAttNames.contains(p)).collect(Collectors.toList()); + + if (!invaliResultMapParams.isEmpty()) { + throwOrCollect(new OnapCommandHttpInvalidResultMap(invaliResultMapParams), errorList, true); } } + private static void validateHttpSccessCodes(List<String> errorList, List<Object> requestSuccessCodes) { + + if (requestSuccessCodes == null || requestSuccessCodes.isEmpty()) { + errorList.add(HTTP_SUCCESS_CODE_INVALID); + return; + } + + for (Object successCode : requestSuccessCodes) { + Integer code = (Integer) successCode; + if (code < 200 || code >= 300) { + errorList.add(HTTP_SUCCESS_CODE_INVALID); + } + } + + } + + + private static ArrayList<String> validateHttpSchemaSection(Map<String, ?> values) { + + ArrayList<String> errorList = new ArrayList<>(); + Map<String, ?> map = (Map<String, ?>) values.get(HTTP); + Map<String, Object> requestMap = (Map<String, Object>) map.get(REQUEST); + + if (requestMap != null && !requestMap.isEmpty()) { + validateTags(errorList, requestMap, OnapCommandConfg.getSchemaAttrInfo(HTTP_REQUEST_PARAMS), + OnapCommandConfg.getSchemaAttrInfo(HTTP_REQUEST_MANDATORY_PARAMS), REQUEST); + String method = (String) requestMap.get(METHOD); + if (method != null && !method.isEmpty()) { + if (!OnapCommandConfg.getSchemaAttrInfo(HTTP_METHODS).contains(method.toLowerCase())) { + errorList.add("Attribute '" + METHOD + "' under '" + REQUEST + "' is invalid, correct types are " + + OnapCommandConfg.getSchemaAttrInfo(HTTP_METHODS).toString()); + } + } else { + errorList.add("Http request method cann't be null or empty"); + } + + Set<String> requestParams = getRequestParams(values); + + Set<String> uriParams = validateHttpUri(errorList, requestMap); + + Set<String> bodyParams = validateHttpBody(errorList, requestMap); + + Set<String> headerParams = validateHttpHeaders(requestMap); + + Set<String> queryParams = validateHttpQueries(requestMap); + + HashSet<String> totoalParams = new HashSet<>(uriParams); + totoalParams.addAll(bodyParams); + totoalParams.addAll(headerParams); + totoalParams.addAll(queryParams); + + List<String> nonDeclaredParams = totoalParams.stream().filter(param -> !requestParams.contains(param)) + .collect(Collectors.toList()); + + nonDeclaredParams.stream().forEach(p -> errorList.add("The parameter '" + p + + "' declared under 'parameters:' section is not mapped into request section.")); + } else { + errorList.add(emptySection(REQUEST)); + } + return errorList; + } + + /** * Returns Help. * @@ -565,14 +993,14 @@ public class OnapCommandUtils { paramTable.setIncludeSeparator(false); OnapCommandResultAttribute attrName = new OnapCommandResultAttribute(); - attrName.setName(Constants.NAME); - attrName.setDescription(Constants.NAME); + attrName.setName(NAME); + attrName.setDescription(NAME); attrName.setScope(OnapCommandResultAttributeScope.SHORT); paramTable.getRecords().add(attrName); OnapCommandResultAttribute attrDescription = new OnapCommandResultAttribute(); - attrDescription.setName(Constants.DESCRIPTION); - attrDescription.setDescription(Constants.DESCRIPTION); + attrDescription.setName(DESCRIPTION); + attrDescription.setDescription(DESCRIPTION); attrDescription.setScope(OnapCommandResultAttributeScope.SHORT); paramTable.getRecords().add(attrDescription); @@ -680,10 +1108,9 @@ public class OnapCommandUtils { for (OnapCommandParameter param : params) { paramMap.put(param.getName(), param.getValue().toString()); } - - return new OnapCredentials(paramMap.get(Constants.DEAFULT_PARAMETER_USERNAME), - paramMap.get(Constants.DEAFULT_PARAMETER_PASS_WORD), - paramMap.get(Constants.DEAFULT_PARAMETER_HOST_URL)); + return new OnapCredentials(paramMap.get(DEAFULT_PARAMETER_USERNAME), + paramMap.get(DEAFULT_PARAMETER_PASS_WORD), + paramMap.get(DEAFULT_PARAMETER_HOST_URL)); } /** @@ -1005,7 +1432,7 @@ public class OnapCommandUtils { public static List<ExternalSchema> findAllExternalSchemas() throws OnapCommandException { List<ExternalSchema> extSchemas = new ArrayList<>(); try { - Resource[] res = getExternalResources(Constants.EXTERNAL_SCHEMA_PATH_PATERN); + Resource[] res = getExternalResources(EXTERNAL_SCHEMA_PATH_PATERN); if (res != null && res.length > 0) { Map<String, ?> resourceMap; for (Resource resource : res) { @@ -1013,15 +1440,15 @@ public class OnapCommandUtils { if (resourceMap != null && resourceMap.size() > 0) { ExternalSchema schema = new ExternalSchema(); schema.setSchemaName(resource.getFilename()); - schema.setCmdName((String) resourceMap.get(Constants.NAME)); - Object obj = resourceMap.get(Constants.ONAP_CMD_SCHEMA_VERSION); + schema.setCmdName((String) resourceMap.get(NAME)); + Object obj = resourceMap.get(ONAP_CMD_SCHEMA_VERSION); schema.setVersion(obj.toString()); extSchemas.add(schema); } } } } catch (IOException e) { - throw new OnapCommandDiscoveryFailed(Constants.EXTERNAL_SCHEMA_DIRECTORY, e); + throw new OnapCommandDiscoveryFailed(EXTERNAL_SCHEMA_DIRECTORY, e); } return extSchemas; @@ -1094,16 +1521,16 @@ public class OnapCommandUtils { public static void persist(List<ExternalSchema> schemas) throws OnapCommandDiscoveryFailed { if (schemas != null) { try { - Resource[] resources = getExternalResources(Constants.EXTERNAL_DISCOVERY_DIRECTORY); + Resource[] resources = getExternalResources(EXTERNAL_DISCOVERY_DIRECTORY); if (resources != null && resources.length == 1) { String path = resources[0].getURI().getPath(); - File file = new File(path + File.separator + Constants.EXTERNAL_DISCOVERY_FILE); + File file = new File(path + File.separator + EXTERNAL_DISCOVERY_FILE); ObjectMapper mapper = new ObjectMapper(); mapper.writerWithDefaultPrettyPrinter().writeValue(file, schemas); } } catch (IOException e1) { - throw new OnapCommandDiscoveryFailed(Constants.EXTERNAL_DISCOVERY_DIRECTORY, - Constants.EXTERNAL_DISCOVERY_FILE, e1); + throw new OnapCommandDiscoveryFailed(EXTERNAL_DISCOVERY_DIRECTORY, + EXTERNAL_DISCOVERY_FILE, e1); } } } @@ -1118,14 +1545,14 @@ public class OnapCommandUtils { public static boolean isJsonFileDiscovered() throws OnapCommandDiscoveryFailed { Resource resource = null; try { - resource = getExternalResource(Constants.EXTERNAL_DISCOVERY_FILE, - Constants.EXTERNAL_DISCOVERY_DIRECTORY_PATTERN); + resource = getExternalResource(EXTERNAL_DISCOVERY_FILE, + EXTERNAL_DISCOVERY_DIRECTORY_PATTERN); if (resource != null) { return true; } } catch (IOException e) { - throw new OnapCommandDiscoveryFailed(Constants.EXTERNAL_DISCOVERY_DIRECTORY, - Constants.EXTERNAL_DISCOVERY_FILE, e); + throw new OnapCommandDiscoveryFailed(EXTERNAL_DISCOVERY_DIRECTORY, + EXTERNAL_DISCOVERY_FILE, e); } return false; @@ -1149,8 +1576,8 @@ public class OnapCommandUtils { } } else { try { - Resource resource = getExternalResource(Constants.EXTERNAL_DISCOVERY_FILE, - Constants.EXTERNAL_DISCOVERY_DIRECTORY_PATTERN); + Resource resource = getExternalResource(EXTERNAL_DISCOVERY_FILE, + EXTERNAL_DISCOVERY_DIRECTORY_PATTERN); if (resource != null) { File file = new File(resource.getURI().getPath()); ObjectMapper mapper = new ObjectMapper(); @@ -1158,8 +1585,8 @@ public class OnapCommandUtils { schemas.addAll(Arrays.asList(list)); } } catch (IOException e) { - throw new OnapCommandDiscoveryFailed(Constants.EXTERNAL_DISCOVERY_DIRECTORY, - Constants.EXTERNAL_DISCOVERY_FILE, e); + throw new OnapCommandDiscoveryFailed(EXTERNAL_DISCOVERY_DIRECTORY, + EXTERNAL_DISCOVERY_FILE, e); } } |