From: Kanagaraj Manickam k00365106 Date: Wed, 19 Jul 2017 09:44:29 +0000 (+0530) Subject: Add seed code from Open-O X-Git-Tag: 1.0.0-Amsterdam~215 X-Git-Url: https://gerrit.onap.org/r/gitweb?a=commitdiff_plain;h=refs%2Fheads%2Frelease-1.0.0;p=cli.git Add seed code from Open-O It migrated the code from Open-O into onap namespace and adds the required framework, main, deployment and some sample plugins for msb. CLI-7 CLI-8 CLI-11 Change-Id: I499e34237daccb971ef74bd10e50f50707baa4d3 Signed-off-by: Kanagaraj Manickam k00365106 --- diff --git a/.gitignore b/.gitignore index db233505..97767e14 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +bin/ +target/ +coverage-report/ .project .settings .classpath diff --git a/.gitreview b/.gitreview new file mode 100644 index 00000000..7033a4aa --- /dev/null +++ b/.gitreview @@ -0,0 +1,4 @@ +[gerrit] +host=gerrit.onap.org +port=29418 +project=cli.git diff --git a/README.md b/README.md new file mode 100644 index 00000000..737cd04d --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +Onap Command-line interface (CLI). + +One Command to command whole Onap !! It provides the unified commands +to access and operate Onap functionalities. To use this CLI, please +configure the following environment variables: + +1. ONAP_MSB_URL - Onap Micro service bus(MSB) URL +2. ONAP_USERNAME - Onap user name +3. ONAP_PASSWORD - Onap user password + +To know the CLI version, type onap [-v|--version] +To know the CLI usage, type onap [-h|--help] +To know the usage of sub commands, type onap [-h|--help] + +To know more, please refer the Onap wiki https://wiki.onap.org \ No newline at end of file diff --git a/deployment/pom.xml b/deployment/pom.xml new file mode 100644 index 00000000..b6f32c4f --- /dev/null +++ b/deployment/pom.xml @@ -0,0 +1,118 @@ + + + + 4.0.0 + + + org.onap.cli + cli + 1.0.0-SNAPSHOT + + + cli-deployment + cli/deployment + pom + + + + + org.codehaus.gmaven + gmaven-plugin + 1.5 + + + onap-cli-deployment + package + + execute + + + + System.out.println("******** Going to make release zip ********") + + deployFolder = + "${project.build.directory}/deployoutput" + deployUnzip = + "${project.build.directory}/deployunzip" + outfileName = + "${package.name}-${project.version}.zip" + ant.delete(dir: "${deployFolder}") + ant.mkdir(dir: "${deployFolder}") + + ant.delete(dir: "${deployUnzip}") + ant.mkdir(dir: "${deployUnzip}") + + ant.delete(dir: "${deployUnzip}/lib") + ant.mkdir(dir: "${deployUnzip}/lib") + + ant.delete(dir: "${deployUnzip}/onap-cli-schema") + ant.mkdir(dir: "${deployUnzip}/onap-cli-schema") + + ant.delete(dir: "${deployUnzip}/data") + ant.mkdir(dir: "${deployUnzip}/data") + + ant.copy(todir: "${deployUnzip}") { + fileset(dir: "${basedir}/src/main/release"){ + exclude(name: "**/.gitignore") + } + } + ant.copy(todir: + "${deployUnzip}/lib") { + fileset(file: + "${project.build.directory}/../../main/target/cli-main-${project.version}.jar") + fileset(dir: + "${project.build.directory}/../../main/target/lib/") + } + + ant.zip(destfile: + "${deployFolder}/${outfileName}") { + fileset(dir: "${deployUnzip}") + } + System.out.println("******** completed. ************") + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 3.0.0 + + + attach-artifacts + package + + attach-artifact + + + + + ${project.build.directory}/deployoutput/${package.name}-${project.version}.zip + zip + + + + + + + + + diff --git a/deployment/src/main/release/bin/onap.sh b/deployment/src/main/release/bin/onap.sh new file mode 100644 index 00000000..e8970848 --- /dev/null +++ b/deployment/src/main/release/bin/onap.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +#******************************************************************************* +# 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. +#******************************************************************************* + +if [ -z "$ONAP_CLI_HOME" ] +then + echo "There is no ONAP_CLI_HOME" + exit 1 +fi + +CLASSPATH=$ONAP_CLI_HOME +for entry in "$ONAP_CLI_HOME/lib"/* +do + CLASSPATH=$CLASSPATH:$entry +done + +java -classpath $CLASSPATH org.onap.cli.main.OnapCli "$@" diff --git a/framework/pom.xml b/framework/pom.xml new file mode 100644 index 00000000..87e6bc2f --- /dev/null +++ b/framework/pom.xml @@ -0,0 +1,104 @@ + + + + + 4.0.0 + + + org.onap.cli + cli + 1.0.0-SNAPSHOT + + + cli-framework + cli/framework + jar + + + org.yaml + snakeyaml + 1.17 + + + org.aspectj + aspectjrt + 1.8.10 + + + org.aspectj + aspectjweaver + 1.8.10 + + + org.slf4j + slf4j-log4j12 + 1.6.1 + + + org.apache.commons + commons-csv + 1.3 + + + org.apache.httpcomponents + httpclient + 4.3.5 + + + com.jayway.jsonpath + json-path + 2.2.0 + + + com.fasterxml.jackson.core + jackson-databind + 2.6.3 + + + org.springframework + spring-core + 3.1.0.RELEASE + + + junit + junit + 4.11 + test + + + org.jmockit + jmockit + 1.19 + test + + + org.jmockit + jmockit-coverage + 1.19 + test + + + org.apache.httpcomponents + httpmime + 4.0.1 + compile + + + diff --git a/framework/src/main/java/org/onap/cli/fw/OnapCommand.java b/framework/src/main/java/org/onap/cli/fw/OnapCommand.java new file mode 100644 index 00000000..d67538cc --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/OnapCommand.java @@ -0,0 +1,304 @@ +/* + * 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; + +import org.onap.cli.fw.ad.OnapAuthClient; +import org.onap.cli.fw.ad.OnapCredentials; +import org.onap.cli.fw.ad.OnapService; +import org.onap.cli.fw.conf.Constants; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandHelpFailed; +import org.onap.cli.fw.error.OnapCommandInvalidParameterType; +import org.onap.cli.fw.error.OnapCommandInvalidPrintDirection; +import org.onap.cli.fw.error.OnapCommandInvalidResultAttributeScope; +import org.onap.cli.fw.error.OnapCommandInvalidSchema; +import org.onap.cli.fw.error.OnapCommandInvalidSchemaVersion; +import org.onap.cli.fw.error.OnapCommandNotInitialized; +import org.onap.cli.fw.error.OnapCommandParameterNameConflict; +import org.onap.cli.fw.error.OnapCommandParameterOptionConflict; +import org.onap.cli.fw.error.OnapCommandRegistrationFailed; +import org.onap.cli.fw.error.OnapCommandSchemaNotFound; +import org.onap.cli.fw.input.OnapCommandParameter; +import org.onap.cli.fw.output.OnapCommandResult; +import org.onap.cli.fw.output.OnapCommandResultAttributeScope; +import org.onap.cli.fw.output.ResultType; +import org.onap.cli.fw.utils.OnapCommandUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * Onap Command. + * + */ +public abstract class OnapCommand { + + private String cmdDescription; + + private String cmdName; + + private String cmdSchemaName; + + private OnapService onapService = new OnapService(); + + private List cmdParameters = new ArrayList<>(); + + private OnapCommandResult cmdResult = new OnapCommandResult(); + + protected OnapAuthClient authClient; + + protected boolean isInitialzied = false; + + public String getSchemaVersion() { + return Constants.ONAP_CMD_SCHEMA_VERSION_VALUE; + } + + /** + * Onap command description, defined by derived command. + */ + public String getDescription() { + return this.cmdDescription; + } + + public void setDescription(String description) { + this.cmdDescription = description; + } + + /* + * Onap command name like user-create, ns-list, etc , defined by derived command + */ + public String getName() { + return this.cmdName; + } + + public void setName(String name) { + this.cmdName = name; + } + + /* + * Onap service, this command uses to execute it. , defined by derived command + */ + public OnapService getService() { + return this.onapService; + } + + public void setService(OnapService service) { + this.onapService = service; + } + + public void setParameters(List parameters) { + this.cmdParameters = parameters; + } + + /* + * Onap command input parameters, defined by derived command + */ + public List getParameters() { + return this.cmdParameters; + } + + /* + * Onap command input parameters, defined by derived command + */ + public Map getParametersMap() { + return OnapCommandUtils.getInputMap(this.getParameters()); + } + + /* + * Onap command output results, defined by derived command + */ + public OnapCommandResult getResult() { + return this.cmdResult; + } + + public void setResult(OnapCommandResult result) { + this.cmdResult = result; + } + + public String getSchemaName() { + return cmdSchemaName; + } + + protected void setSchemaName(String schemaName) { + this.cmdSchemaName = schemaName; + } + + /** + * Initialize this command from command schema. + * + * @throws OnapCommandRegistrationFailed + * Command Registration Exception + * @throws OnapCommandInvalidResultAttributeScope + * InvalidResultAttribute Exception + * @throws OnapCommandInvalidPrintDirection + * InvalidPrintDirection Exception + * @throws OnapCommandInvalidParameterType + * InvalidParameterType Exception + * @throws OnapCommandSchemaNotFound + * SchemaNotFound Exception + * @throws OnapCommandInvalidSchema + * InvalidSchema Exception + * @throws OnapCommandParameterOptionConflict + * ParameterOptionConflict Exception + * @throws OnapCommandParameterNameConflict + * ParameterNameConflict Exception + * @throws OnapCommandInvalidSchemaVersion + * InvalidSchemaVersion Exception + */ + public void initializeSchema(String schema) throws OnapCommandException { + this.setSchemaName(schema); + OnapCommandUtils.loadSchema(this, schema, true); + this.initializeProfileSchema(); + this.isInitialzied = true; + } + + /** + * Any additional profile based such as http/swagger schema could be initialized. + */ + protected void initializeProfileSchema() throws OnapCommandException { + + } + + /* + * Validate input parameters. This can be overridden in derived commands + */ + protected void validate() throws OnapCommandException { + for (OnapCommandParameter param : this.getParameters()) { + param.validate(); + } + } + + /** + * Onap command execute with given parameters on service. Before calling this method, its mandatory to set all + * parameters value. + * + * @throws OnapCommandException + * : General Command Exception + */ + public OnapCommandResult execute() throws OnapCommandException { + if (!this.isInitialzied) { + throw new OnapCommandNotInitialized(this.getClass().getName()); + } + + Map paramMap = this.getParametersMap(); + + // -h or --help is always higher precedence !, user can set this value to get help message + if ("true".equals(paramMap.get(Constants.DEFAULT_PARAMETER_HELP).getValue())) { + OnapCommandResult result = new OnapCommandResult(); + result.setType(ResultType.TEXT); + result.setOutput(this.printHelp()); + return result; + } + + // -v or --version is next higher precedence !, user can set this value to get help message + if ("true".equals(paramMap.get(Constants.DEFAULT_PARAMETER_VERSION).getValue())) { + OnapCommandResult result = new OnapCommandResult(); + result.setType(ResultType.TEXT); + result.setOutput(this.printVersion()); + return result; + } + + // validate + this.validate(); + + // -f or --format + this.cmdResult.setType( + ResultType.get(paramMap.get(Constants.DEFAULT_PARAMETER_OUTPUT_FORMAT).getValue().toString())); + if ("true".equals(paramMap.get(Constants.DEFAULT_PARAMETER_OUTPUT_ATTR_LONG).getValue())) { + this.cmdResult.setScope(OnapCommandResultAttributeScope.LONG); + } + // --no-title + if ("true".equals(paramMap.get(Constants.DEFAULT_PARAMETER_OUTPUT_NO_TITLE).getValue())) { + this.cmdResult.setIncludeTitle(false); + } + + // --debug + if ("true".equals(paramMap.get(Constants.DEFAULT_PARAMETER_DEBUG).getValue())) { + this.cmdResult.setDebug(true); + } + + try { + // login + OnapCredentials creds = OnapCommandUtils.fromParameters(this.getParameters()); + this.authClient = new OnapAuthClient(creds, this.getResult().isDebug()); + + if (!this.onapService.isNoAuth() + && !"true".equals(paramMap.get(Constants.DEFAULT_PARAMETER_OUTPUT_NO_AUTH).getValue())) { + this.authClient.login(); + } + + // execute + this.run(); + + // logout + if (!this.onapService.isNoAuth() + && !"true".equals(paramMap.get(Constants.DEFAULT_PARAMETER_OUTPUT_NO_AUTH).getValue())) { + this.authClient.logout(); + } + + if (this.cmdResult.isDebug()) { + this.cmdResult.setDebugInfo(this.authClient.getDebugInfo()); + } + } catch (OnapCommandException e) { + if (this.cmdResult.isDebug()) { + this.cmdResult.setDebugInfo(this.authClient.getDebugInfo()); + } + throw e; + } + + return this.cmdResult; + } + + /* + * Each command implements run method to executing the command. + * + */ + protected abstract void run() throws OnapCommandException; + + /* + * Get my service base path (endpoint). + */ + protected String getBasePath() throws OnapCommandException { + return this.authClient.getServiceBasePath(this.getService()); + } + + protected String getAuthToken() { + return this.authClient.getAuthToken(); + } + + /** + * Returns the service service version it supports. + * + * @return version + */ + public String printVersion() { + return this.getService().toString(); + } + + /** + * Provides help message for this command. + * + * @return help message + * @throws OnapCommandHelpFailed + * Failed to execute Help command. + */ + public String printHelp() throws OnapCommandHelpFailed { + return OnapCommandUtils.help(this); + } + // (mrkanag) Add toString for all command, parameter, result, etc objects in JSON format +} diff --git a/framework/src/main/java/org/onap/cli/fw/OnapCommandRegistrar.java b/framework/src/main/java/org/onap/cli/fw/OnapCommandRegistrar.java new file mode 100644 index 00000000..567e0381 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/OnapCommandRegistrar.java @@ -0,0 +1,243 @@ +/* + * 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; + +import org.onap.cli.fw.cmd.OnapHttpCommand; +import org.onap.cli.fw.conf.Constants; +import org.onap.cli.fw.conf.OnapCommandConfg; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandHelpFailed; +import org.onap.cli.fw.error.OnapCommandInvalidRegistration; +import org.onap.cli.fw.error.OnapCommandNotFound; +import org.onap.cli.fw.error.OnapCommandRegistrationFailed; +import org.onap.cli.fw.output.OnapCommandResult; +import org.onap.cli.fw.output.OnapCommandResultAttribute; +import org.onap.cli.fw.output.OnapCommandResultAttributeScope; +import org.onap.cli.fw.output.PrintDirection; +import org.onap.cli.fw.output.ResultType; +import org.onap.cli.fw.utils.ExternalSchema; +import org.onap.cli.fw.utils.OnapCommandUtils; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Onap Command registrar provides a common place, where every command would get registered automatically when its + * loaded into JVM. + * + */ +public class OnapCommandRegistrar { + /* + * static { //Start the AOP for logging new OnapCommandLogger(); } + */ + private Map> registry = new HashMap<>(); + + private static OnapCommandRegistrar registrar = null; + + /** + * Register the command into registrar and throws OnapInvalidCommandRegistration for invalid command. + * + * @param name + * Command Name + * @param cmd + * Command Class + * @throws OnapCommandInvalidRegistration + * Invalid registration exception + */ + public void register(String name, Class cmd) throws OnapCommandInvalidRegistration { + this.registry.put(name, cmd); + } + + /** + * Get global registrar. + * + * @throws OnapCommandException + * exception + */ + public static OnapCommandRegistrar getRegistrar() throws OnapCommandException { + if (registrar == null) { + registrar = new OnapCommandRegistrar(); + registrar.autoDiscover(); + registrar.autoDiscoverHttpSchemas(); + } + + return registrar; + } + + /** + * Get the list of discovered commands by registrar. + * + * @return set + */ + public Set listCommands() { + return this.registry.keySet(); + } + + /** + * Returns map of command to schema. + * + * @return map + * @throws OnapCommandException + * exception + */ + public Map getAllCommandToSchemaMap() throws OnapCommandException { + Map map = new HashMap<>(); + List schemas = OnapCommandUtils.findAllExternalSchemas(); + if (schemas != null) { + for (ExternalSchema schema : schemas) { + map.put(schema.getCmdName(), schema.getSchemaName()); + } + } + if (this.registry != null) { + for (String cmd : this.registry.keySet()) { + if (!map.containsKey(cmd) && registry.get(cmd) != null) { + map.put(cmd, this.getSchemaFileName(registry.get(cmd))); + } + } + } + + return map; + } + + /** + * Get the OnapCommand, which CLI main would use to find the command based on the command name. + * + * @param cmdName + * Name of command + * @return OnapCommand + * @throws OnapCommandException + * Exception + */ + public OnapCommand get(String cmdName) throws OnapCommandException { + OnapCommand cmd; + Class cls = registry.get(cmdName); + if (cls == null) { + throw new OnapCommandNotFound(cmdName); + } + + try { + Constructor constr = cls.getConstructor(); + cmd = (OnapCommand) constr.newInstance(); + + String schemaName; + if (cmd.getClass().equals(OnapHttpCommand.class)) { // NOSONAR + schemaName = OnapCommandUtils.loadExternalSchemaFromJson(cmdName).getSchemaName(); + } else { + schemaName = this.getSchemaFileName(cls); + } + cmd.initializeSchema(schemaName); + } catch (OnapCommandException | NoSuchMethodException | SecurityException | InstantiationException + | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + throw new OnapCommandRegistrationFailed(cmdName, e); + } + + return cmd; + } + + private void autoDiscover() throws OnapCommandInvalidRegistration { + List> cmds = OnapCommandUtils.findOnapCommands(); + + for (Class cmd : cmds) { + if (cmd.isAnnotationPresent(OnapCommandSchema.class)) { + OnapCommandSchema ano = cmd.getAnnotation(OnapCommandSchema.class); + this.register(ano.name(), cmd); + } + } + } + + private void autoDiscoverHttpSchemas() throws OnapCommandException { + List schemas = OnapCommandUtils.loadExternalSchemasFromJson(); + for (ExternalSchema schema : schemas) { + this.register(schema.getCmdName(), OnapHttpCommand.class); + } + } + + private String getSchemaFileName(Class cmd) { + OnapCommandSchema ano = (OnapCommandSchema) cmd.getAnnotation(OnapCommandSchema.class); + if (ano.schema().isEmpty()) { + return "onap-" + ano.name() + "-schema.yaml"; + } + return ano.schema(); + } + + /** + * Helps to find the Onap CLI version, could be used with --version or -v option. + * + * @return string + */ + public String getVersion() { + String version = this.getClass().getPackage().getImplementationVersion(); + if (version == null) { + version = OnapCommandConfg.getVersion(); + } + return version; + } + + /** + * Provides the help message in tabular format for all commands registered in this registrar. + * + * @return string + * @throws OnapCommandHelpFailed + * Help cmd failed + */ + public String getHelp() throws OnapCommandHelpFailed { + OnapCommandResult help = new OnapCommandResult(); + help.setType(ResultType.TABLE); + help.setPrintDirection(PrintDirection.LANDSCAPE); + + OnapCommandResultAttribute attr = new OnapCommandResultAttribute(); + attr.setName(Constants.NAME.toUpperCase()); + attr.setDescription(Constants.DESCRIPTION); + attr.setScope(OnapCommandResultAttributeScope.SHORT); + help.getRecords().add(attr); + + OnapCommandResultAttribute attrSrv = new OnapCommandResultAttribute(); + attrSrv.setName(Constants.SERVICE.toUpperCase()); + attrSrv.setDescription(Constants.SERVICE); + attrSrv.setScope(OnapCommandResultAttributeScope.SHORT); + help.getRecords().add(attrSrv); + + OnapCommandResultAttribute attrDesc = new OnapCommandResultAttribute(); + attrDesc.setName(Constants.DESCRIPTION.toUpperCase()); + attrDesc.setDescription(Constants.DESCRIPTION); + attrDesc.setScope(OnapCommandResultAttributeScope.SHORT); + help.getRecords().add(attrDesc); + + for (String cmdName : OnapCommandUtils.sort(this.listCommands())) { + OnapCommand cmd; + try { + cmd = this.get(cmdName); + } catch (OnapCommandException e) { + throw new OnapCommandHelpFailed(e); + } + + attr.getValues().add(cmd.getName()); + attrSrv.getValues().add(cmd.printVersion()); + attrDesc.getValues().add(cmd.getDescription()); + } + + try { + return "\n\nOnap sub-commands:\n" + help.print(); + } catch (OnapCommandException e) { + throw new OnapCommandHelpFailed(e); + } + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/OnapCommandSchema.java b/framework/src/main/java/org/onap/cli/fw/OnapCommandSchema.java new file mode 100644 index 00000000..853d3583 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/OnapCommandSchema.java @@ -0,0 +1,48 @@ +/* + * 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; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Provide command name and schema file location, which is placed in the main resources folder (in classpath). It is + * recommended to keep the name for schema, in the form of onap-[command-name]-schema.yaml, considered this format as + * default if the schema declaration is missing for a command abc-create, schema file name could be + * abc-create-schema.yaml, corresponding command would like as below + * + * @OnapCommandSchema(name="abc-create", schema="onap-abc-create-schema.yaml") public class AbcCreate extends + * OnapCommand { ... } + */ +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface OnapCommandSchema { + /** + * Command name + * + * @return + */ + String name(); + + /** + * Schema file name placed under class path + * + * @return + */ + String schema() default ""; +} diff --git a/framework/src/main/java/org/onap/cli/fw/ad/OnapAuthClient.java b/framework/src/main/java/org/onap/cli/fw/ad/OnapAuthClient.java new file mode 100644 index 00000000..0150ee98 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/ad/OnapAuthClient.java @@ -0,0 +1,194 @@ +/* + * 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.ad; + +import com.jayway.jsonpath.JsonPath; +import org.apache.http.HttpStatus; +import org.onap.cli.fw.conf.Constants; +import org.onap.cli.fw.conf.OnapCommandConfg; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandExecutionFailed; +import org.onap.cli.fw.error.OnapCommandHttpFailure; +import org.onap.cli.fw.error.OnapCommandLoginFailed; +import org.onap.cli.fw.error.OnapCommandLogoutFailed; +import org.onap.cli.fw.error.OnapCommandServiceNotFound; +import org.onap.cli.fw.http.HttpInput; +import org.onap.cli.fw.http.HttpResult; +import org.onap.cli.fw.http.OnapHttpConnection; + +/** + * Onap Auth client helps to do login and logout. + * + */ +public class OnapAuthClient { + + /* + * Onap credentials + */ + private OnapHttpConnection http = null; + + private OnapCredentials creds = null; + + public OnapAuthClient(OnapCredentials creds, boolean debug) throws OnapCommandHttpFailure { + this.creds = creds; + this.http = new OnapHttpConnection(creds.getMsbUrl().startsWith("https"), debug); + } + + /** + * Login. + * + * @throws OnapCommandLoginFailed + * LoginFailed Exception + * @throws OnapCommandHttpFailure + * Http request failed + * @throws OnapCommandExecutionFailed + * cmd exec failed + * @throws OnapCommandServiceNotFound + * service not found + */ + public void login() throws OnapCommandException { + + // For development purpose, its introduced and is not supported for production + if (OnapCommandConfg.isAuthIgnored()) { + return; + } + + HttpInput input = new HttpInput().setUri(this.getAuthUrl() + "/tokens") + .setBody(String.format(Constants.TOKEN, creds.getUsername(), creds.getPassword())) + .setMethod("post"); + + HttpResult result; + try { + result = this.run(input); + } catch (OnapCommandHttpFailure e) { + throw new OnapCommandLoginFailed(e); + } + if (result.getStatus() != HttpStatus.SC_OK && result.getStatus() != HttpStatus.SC_CREATED) { + throw new OnapCommandLoginFailed(result.getBody(), result.getStatus()); + } + + if (OnapCommandConfg.isCookiesBasedAuth()) { + this.http.setAuthToken(result.getRespCookies().get(Constants.X_AUTH_TOKEN)); + } else { + this.http.setAuthToken(result.getRespHeaders().get(Constants.X_AUTH_TOKEN)); + } + } + + /** + * Logout. + * + * @throws OnapCommandExecutionFailed + * cmd exec failed + * @throws OnapCommandServiceNotFound + * service not found + * @throws OnapCommandLogoutFailed + * logout failed + * @throws OnapCommandHttpFailure + * exception + */ + public void logout() throws OnapCommandException { + // For development purpose, its introduced and is not supported for production + if (OnapCommandConfg.isAuthIgnored()) { + return; + } + + HttpInput input = new HttpInput().setUri(this.getAuthUrl() + "/tokens").setMethod("delete"); + + HttpResult result; + try { + result = this.run(input); + } catch (OnapCommandHttpFailure e) { + throw new OnapCommandLogoutFailed(e); + } + if (result.getStatus() != HttpStatus.SC_NO_CONTENT) { + throw new OnapCommandLogoutFailed(result.getStatus()); + } + + this.http.close(); + } + + /** + * Find given service base path. + * + * @param srv + * onap service + * @return string + * @throws OnapCommandExecutionFailed + * Cmd execution failed exception + * @throws OnapCommandServiceNotFound + * Service not found + * @throws OnapCommandHttpFailure + * http request failed + */ + public String getServiceBasePath(OnapService srv) throws OnapCommandException { + if (srv.getName().equals(Constants.MSB)) { + return this.getMsbUrl(); + } + + HttpInput input = new HttpInput().setUri(this.creds.getMsbUrl() + + String.format(Constants.MSB_SERVICE_URI, srv.getName(), srv.getVersion())); + HttpResult result = this.http.get(input); + + if (result.getStatus() == HttpStatus.SC_NOT_FOUND) { + throw new OnapCommandServiceNotFound(srv.toString()); + } + if (!result.isSuccess()) { + throw new OnapCommandExecutionFailed("Failed to retrive service " + srv.toString()); + } + + try { + return this.creds.getMsbUrl() + JsonPath.read(result.getBody(), "url"); + } catch (Exception e) { + throw new OnapCommandExecutionFailed(e, srv.toString()); + } + } + + private String getAuthUrl() throws OnapCommandException { + OnapService srv = new OnapService(); + srv.setName(Constants.AUTH_SERVICE); + srv.setVersion(Constants.AUTH_SERVICE_VERSION); + return this.getServiceBasePath(srv); + } + + private String getMsbUrl() { + return this.creds.getMsbUrl() + Constants.MSB_URI; + } + + public String getAuthToken() { + return this.http.getAuthToken(); + } + + public String getDebugInfo() { + return this.http.getDebugInfo(); + } + + /** + * Http call to auth service. + * + * @param input + * http input + * @return http result + * @throws OnapCommandHttpFailure + * exception + */ + public HttpResult run(HttpInput input) throws OnapCommandHttpFailure { + if (OnapCommandConfg.isCookiesBasedAuth()) { + input.getReqCookies().put(Constants.X_AUTH_TOKEN, http.getAuthToken()); + } + return this.http.request(input); + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/ad/OnapCredentials.java b/framework/src/main/java/org/onap/cli/fw/ad/OnapCredentials.java new file mode 100644 index 00000000..7c3c3ac0 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/ad/OnapCredentials.java @@ -0,0 +1,67 @@ +/* + * 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.ad; + +/** + * Onap Service credentials. + */ +public class OnapCredentials { + + /* + * Onap Service username. + */ + private String username; + + /* + * Onap Service password + */ + private String password; + + /* + * Onap Service msb-url + */ + private String msbUrl; + + /** + * Onap credentials with username and password. + * + * @param username + * user name + * @param password + * password + * @param msbUrl + * msb url + */ + public OnapCredentials(String username, String password, String msbUrl) { + super(); + this.username = username; + this.password = password; + this.msbUrl = msbUrl; + } + + public String getUsername() { + return username; + } + + public String getPassword() { + return password; + } + + public String getMsbUrl() { + return msbUrl; + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/ad/OnapService.java b/framework/src/main/java/org/onap/cli/fw/ad/OnapService.java new file mode 100644 index 00000000..16752f25 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/ad/OnapService.java @@ -0,0 +1,74 @@ +/* + * 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.ad; + +/** + * Onap Service as reported in Onap MSB like msb v1 or /api/microservice/v1. + */ +public class OnapService { + /* + * Onap Service name like gso. + */ + private String serviceName; + + /* + * Onap Service API version like v1, v2, etc + */ + private String serviceVersion; + + private String basePath; + + private boolean noAuth = false; + + public boolean isNoAuth() { + return noAuth; + } + + public void setNoAuth(boolean noAuth) { + this.noAuth = noAuth; + } + + public String getName() { + return serviceName; + } + + public void setName(String name) { + this.serviceName = name; + } + + public String getVersion() { + return serviceVersion; + } + + public void setVersion(String version) { + this.serviceVersion = version; + } + + public String getBasePath() { + return basePath; + } + + public void setBasePath(String basePath) { + this.basePath = basePath; + } + + @Override + public String toString() { + return this.getName() + " " + this.getVersion(); + } + +} 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 new file mode 100644 index 00000000..d5f51f00 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/cmd/OnapHttpCommand.java @@ -0,0 +1,97 @@ +/* + * 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.cmd; + +import org.onap.cli.fw.OnapCommand; +import org.onap.cli.fw.conf.Constants; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandExecutionFailed; +import org.onap.cli.fw.http.HttpInput; +import org.onap.cli.fw.http.HttpResult; +import org.onap.cli.fw.output.OnapCommandResultAttribute; +import org.onap.cli.fw.utils.OnapCommandUtils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Onap Command. + * + */ +public class OnapHttpCommand extends OnapCommand { + + private HttpInput input = new HttpInput(); + + private List successStatusCodes = new ArrayList<>(); + + private Map resultMap = new HashMap<>(); + + public void setInput(HttpInput input) { + this.input = input; + } + + @Override + public String getSchemaVersion() { + return Constants.ONAP_CMD_SCHEMA_VERSION_VALUE; + } + + public void setSuccessStatusCodes(List successStatusCodes) { + this.successStatusCodes = successStatusCodes; + } + + public void setResultMap(Map resultMap) { + this.resultMap = resultMap; + } + + public HttpInput getInput() { + return input; + } + + public List getSuccessStatusCodes() { + return successStatusCodes; + } + + public Map getResultMap() { + return resultMap; + } + + @Override + protected void initializeProfileSchema() throws OnapCommandException { + OnapCommandUtils.loadSchema(this, this.getSchemaName()); + } + + @Override + protected void run() throws OnapCommandException { + HttpInput httpInput = OnapCommandUtils.populateParameters(this.getParametersMap(), this.getInput()); + httpInput.setUri(this.authClient.getServiceBasePath(this.getService()) + httpInput.getUri()); + + HttpResult output = this.authClient.run(httpInput); + + this.getResult().setOutput(output); + if (!this.getSuccessStatusCodes().contains(output.getStatus())) { + throw new OnapCommandExecutionFailed(this.getName(), output.getBody(), output.getStatus()); + } + + Map> results = OnapCommandUtils.populateOutputs(this.getResultMap(), output); + + for (OnapCommandResultAttribute attr : this.getResult().getRecords()) { + attr.setValues(results.get(attr.getName())); + } + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/cmd/OnapSchemaRefreshCommand.java b/framework/src/main/java/org/onap/cli/fw/cmd/OnapSchemaRefreshCommand.java new file mode 100644 index 00000000..57432751 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/cmd/OnapSchemaRefreshCommand.java @@ -0,0 +1,68 @@ +/* + * 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.cmd; + +import org.onap.cli.fw.OnapCommand; +import org.onap.cli.fw.OnapCommandSchema; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.output.OnapCommandResultAttribute; +import org.onap.cli.fw.utils.ExternalSchema; +import org.onap.cli.fw.utils.OnapCommandUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * Refresh external schema. + * + */ +@OnapCommandSchema(name = "schema-refresh", schema = "schema-refresh.yaml") +public class OnapSchemaRefreshCommand extends OnapCommand { + + @Override + protected void run() throws OnapCommandException { + + List schemas = OnapCommandUtils.findAllExternalSchemas(); + // Will override the existing json file + OnapCommandUtils.persist(schemas); + + List slNumbers = new ArrayList<>(); + List cmdNames = new ArrayList<>(); + List cmdFiles = new ArrayList<>(); + List versions = new ArrayList<>(); + + for (int i = 0; i < schemas.size(); i++) { + ExternalSchema schema = schemas.get(i); + slNumbers.add(String.valueOf(i + 1)); + cmdNames.add(schema.getCmdName()); + cmdFiles.add(schema.getSchemaName()); + versions.add(schema.getVersion()); + } + for (OnapCommandResultAttribute attribute : this.getResult().getRecords()) { + if ("sl-no".equals(attribute.getName())) { + attribute.setValues(slNumbers); + } else if ("command".equals(attribute.getName())) { + attribute.setValues(cmdNames); + } else if ("schema".equals(attribute.getName())) { + attribute.setValues(cmdFiles); + } else if ("version".equals(attribute.getName())) { + attribute.setValues(versions); + } + } + } + +} 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 new file mode 100644 index 00000000..a4d4e7d4 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/cmd/OnapSchemaValidateCommand.java @@ -0,0 +1,62 @@ +/* + * 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.cmd; + +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 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 { + + @Override + protected void run() throws OnapCommandException { + Map paramMap = getParametersMap(); + OnapCommandParameter locationParam = paramMap.get("schema-location"); + 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 error = schema.validate(); + List slNumber = new ArrayList<>(); + for (int i = 1; i <= error.size(); i++) { + slNumber.add(String.valueOf(i)); + } + this.getResult().getRecords().get(0).setValues(slNumber); + this.getResult().getRecords().get(1).setValues(error); + } + +} diff --git a/framework/src/main/java/org/onap/cli/fw/cmd/OnapSwaggerCommand.java b/framework/src/main/java/org/onap/cli/fw/cmd/OnapSwaggerCommand.java new file mode 100644 index 00000000..fa3e7d7e --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/cmd/OnapSwaggerCommand.java @@ -0,0 +1,97 @@ +/* + * 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.cmd; + +import org.onap.cli.fw.OnapCommand; +import org.onap.cli.fw.error.OnapCommandClientInitialzationFailed; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandResultInitialzationFailed; +import org.onap.cli.fw.output.OnapCommandResultAttribute; +import org.onap.cli.fw.run.OnapCommandExecutor; +import org.onap.cli.fw.utils.OnapCommandUtils; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.List; + +public abstract class OnapSwaggerCommand extends OnapCommand { + + + private OnapCommandExecutor cmdExecutor; + + public OnapCommandExecutor getExecutor() { + return cmdExecutor; + } + + public void setExecutor(OnapCommandExecutor executor) { + this.cmdExecutor = executor; + } + + /** + * Initialize the given ApiClient object with AUTH token and base path. + * + * @param client + * api client + * @throws OnapCommandClientInitialzationFailed + * client initialization failed + */ + protected T initializeApiClient(T client) throws OnapCommandClientInitialzationFailed { + try { + Method basePath = client.getClass().getMethod("setBasePath", String.class); + basePath.invoke(client, this.getBasePath()); + + if (this.getAuthToken() != null) { + Method apiKey = client.getClass().getMethod("setApiKey", String.class); + apiKey.invoke(client, this.getAuthToken()); + } + return client; + } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException + | InvocationTargetException | OnapCommandException e) { + throw new OnapCommandClientInitialzationFailed(this.getName(), e); + } + } + + protected void initializeResult(T obj) throws OnapCommandResultInitialzationFailed { + this.getResult().setOutput(obj); + if (obj instanceof List) { + this.initializeListResult((List) obj); + } else { + this.initializeRow(obj); + } + } + + private void initializeRow(T obj) throws OnapCommandResultInitialzationFailed { + for (OnapCommandResultAttribute row : this.getResult().getRecords()) { + String methodName = OnapCommandUtils.formMethodNameFromAttributeName(row.getName(), "get"); + Method get; + try { + get = obj.getClass().getMethod(methodName); + row.getValues().add(get.invoke(obj).toString()); + } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException + | InvocationTargetException e) { + throw new OnapCommandResultInitialzationFailed(this.getName(), e); + } + } + } + + protected void initializeListResult(List rows) throws OnapCommandResultInitialzationFailed { + this.getResult().setOutput(rows); + for (T row : rows) { + this.initializeRow(row); + } + } +} 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 new file mode 100644 index 00000000..928cbc79 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/conf/Constants.java @@ -0,0 +1,160 @@ +/* + * 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.conf; + +/** + * Constants. + * + */ +public class Constants { + + 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"; + + public static final String AUTH_SERVICE = "auth"; + public static final String AUTH_SERVICE_VERSION = "v1"; + public static final String TOKEN = "{\"userName\": \"%s\",\"password\": \"%s\"}"; + public static final String MSB_URI = "/api/microservices/v1"; + public static final String MSB_SERVICE_URI = MSB_URI + "/services/%s/version/%s"; + + public static final String MSB = "msb"; + + //http + public static final String URI = "uri"; + public static final String BODY = "body"; + public static final String MERHOD = "method"; + public static final String HEADERS = "headers"; + public static final String QUERIES = "queries"; + public static final String COOKIES = "cookies"; + + public static final String HTTP = "http"; + public static final String REQUEST = "request"; + public static final String SAMPLE_RESPONSE = "sample_response"; + public static final String SUCCESS_CODES = "success_codes"; + public static final String RESULT_MAP = "result_map"; + + //swagger + public static final String EXECUTOR = "exec"; + + public static final String API = "api"; + public static final String CLIENT = "client"; + public static final String ENTITY = "entity"; + public static final String METHOD = "method"; + public static final String EXCEPTION = "exception"; + + public static final String SCOPE = "scope"; + + public static final String ONAP_CMD_SCHEMA_VERSION_VALUE = "1.0"; + public static final String DESCRIPTION = "description"; + public static final String SERVICE = "service"; + public static final String PARAMETERS = "parameters"; + public static final String RESULTS = "results"; + + public static final String ONAP_CMD_SCHEMA_VERSION = "onap_cmd_schema_version"; + public static final String NAME = "name"; + public static final String VERSION = "version"; + public static final String BASE_PATH = "base_path"; + public static final String NO_AUTH = "no-auth"; + + public static final String SHORT_OPTION = "short_option"; + public static final String LONG_OPTION = "long_option"; + public static final String TYPE = "type"; + public static final String IS_OPTIONAL = "is_optional"; + public static final String DEFAULT_VALUE = "default_value"; + public static final String IS_SECURED = "is_secured"; + + public static final String DIRECTION = "direction"; + public static final String ATTRIBUTES = "attributes"; + + public static final String DEFAULT_PARAMETER_FILE_NAME = "default_input_parameters.yaml"; + + // Common parameters used across all commands. + public static final String DEAFULT_PARAMETER_USERNAME = "onap-username"; + public static final String DEAFULT_PARAMETER_PASS_WORD = "onap-password"; + public static final String DEAFULT_PARAMETER_MSB_URL = "msb-url"; + public static final String DEFAULT_PARAMETER_HELP = "help"; + public static final String DEFAULT_PARAMETER_VERSION = "version"; + public static final String DEFAULT_PARAMETER_DEBUG = "debug"; + public static final String DEFAULT_PARAMETER_OUTPUT_FORMAT = "format"; + public static final String DEFAULT_PARAMETER_OUTPUT_ATTR_LONG = "long"; + public static final String DEFAULT_PARAMETER_OUTPUT_NO_TITLE = "no-title"; + public static final String DEFAULT_PARAMETER_OUTPUT_NO_AUTH = "no-auth"; + + // Configuration properties + public static final String CONF = "onap.properties"; + public static final String ONAP_IGNORE_AUTH = "cli.ignore_auth"; + public static final String ONAP_CLI_VERSION = "cli.version"; + public static final String HTTP_API_KEY_USE_COOKIES = "http.api_key_use_cookies"; + public static final String HTTP_X_AUTH_TOKEN = "http.x_auth_token"; + + // Used while printing the column name during PORTRAIT mode print + public static final String PORTRAINT_COLUMN_NAME_PROPERTY = "property"; + public static final String PORTRAINT_COLUMN_NAME_VALUE = "value"; + + public static final String EXTERNAL_SCHEMA_DIRECTORY = "onap-cli-schema"; + public static final String EXTERNAL_YAML_PATTERN = "/**/*.yaml"; + public static final String EXTERNAL_JSON_PATTERN = "/**/*.json"; + public static final String EXTERNAL_SCHEMA_PATH_PATERN = EXTERNAL_SCHEMA_DIRECTORY + EXTERNAL_YAML_PATTERN; + public static final String EXTERNAL_DISCOVERY_DIRECTORY = "data"; + public static final String EXTERNAL_DISCOVERY_FILE = "external-schema.json"; + public static final String EXTERNAL_DISCOVERY_DIRECTORY_PATTERN = EXTERNAL_DISCOVERY_DIRECTORY + + EXTERNAL_JSON_PATTERN; + + public static final String PARAMETER_TYPE_JSON = "json"; + public static final String PARAMETER_TYPE_YAML = "yaml"; + public static final String PARAMETER_TYPE_STRING = "string"; + public static final String PARAMETER_TYPE_LONG = "long"; + public static final String PARAMETER_TYPE_URL = "url"; + public static final String PARAMETER_TYPE_BOOL = "bool"; + public static final String PARAMETER_TYPE_ARRAY = "array"; + public static final String PARAMETER_TYPE_BINARY = "binary"; + public static final String PARAMETER_TYPE_MAP = "map"; + + public static final String BOOLEAN_TRUE = "true"; + public static final String BOOLEAN_FALSE = "false"; + + public static final String DIRECTION_PORTRAIT = "portrait"; + public static final String DIRECTION_LANDSCAPE = "landscape"; + + public static final String RESULT_SCOPE_SHORT = "short"; + public static final String RESULT_SCOPE_LONG = "long"; + + public static final String POST = "post"; + public static final String GET = "get"; + public static final String DELETE = "delete"; + public static final String PUT = "put"; + public static final String HEAD = "delete"; + + public static final String DEFAULT_SCHEMA_FILE_NAME = "default_input_parameters.yaml"; + + // Error message + public static final String SCHEMA_FILE_EMPTY = "The schema file cann't be null or empty"; + public static final String SCHEMA_FILE_WRONG_EXTN = "Schema file should be '.yaml' extension"; + public static final String SCHEMA_FILE_NOT_EXIST = "Schema file doesn't exist"; + public static final String HTTP_SECTION_EMPTY = "Http Section cann't be null or empty"; + public static final String HTTP_BODY_SECTION_EMPTY = "http body section under 'request:' cann't be null or empty"; + public static final String HTTP_BODY_FAILED_PARSING = "The http body json is failed to parse"; + public static final String HTTP_BODY_JSON_EMPTY = "The http body json cann't be null or empty"; + public static final String HTTP_SUCCESS_CODE_INVALID = "Invalid http success code."; + public static final String HTTP_SAMPLE_RESPONSE_EMPTY = "Sample response cann't be null or empty"; + public static final String HTTP_SAMPLE_RESPONSE_FAILED_PARSING = "The http Sample response json is failed to parse."; + + private Constants() { + } + +} 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 new file mode 100644 index 00000000..d5025e1b --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/conf/OnapCommandConfg.java @@ -0,0 +1,79 @@ +/* + * 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.conf; + +import java.io.IOException; +import java.util.Properties; + +/** + * Onap command constants. + * + */ +public final class OnapCommandConfg { + + private static Properties prps = new Properties(); + + /** + * Private constructor. + */ + private OnapCommandConfg() { + + } + + static { + try { + prps.load(OnapCommandConfg.class.getClassLoader().getResourceAsStream(Constants.CONF)); + } catch (IOException e) { + throw new RuntimeException(e); // NOSONAR + } + } + + /** + * is auth service ignored. + * + * @return boolean + */ + public static boolean isAuthIgnored() { + if ("true".equals(prps.getProperty(Constants.ONAP_IGNORE_AUTH))) { + return true; + } + + return false; + } + + public static String getVersion() { + return prps.getProperty(Constants.ONAP_CLI_VERSION); + } + + /** + * checks if cookies based auth. + * + * @return boolean + */ + public static boolean isCookiesBasedAuth() { + if ("true".equals(prps.getProperty(Constants.HTTP_API_KEY_USE_COOKIES))) { + return true; + } + + return false; + } + + public static String getXAuthTokenName() { + return prps.getProperty(Constants.HTTP_X_AUTH_TOKEN, "X-Auth-Token"); + } + +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandClientInitialzationFailed.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandClientInitialzationFailed.java new file mode 100644 index 00000000..be88d18a --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandClientInitialzationFailed.java @@ -0,0 +1,37 @@ +/* + * 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; + +/** + * Command not registered in MSB. + * + */ +public class OnapCommandClientInitialzationFailed extends OnapCommandException { + + private static final long serialVersionUID = 8580121615330415000L; + private static final String ERROR_CODE = "0x0021"; + private static final String ERROR_MESSAGE1 = "API client for the command "; + private static final String ERROR_MESSAGE2 = " is failed, "; + + public OnapCommandClientInitialzationFailed(String cmd, String error) { + super(ERROR_CODE, ERROR_MESSAGE1 + cmd + ERROR_MESSAGE2 + error); + } + + public OnapCommandClientInitialzationFailed(String cmd, Throwable throwable) { + this(cmd, throwable.getMessage()); + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandDiscoveryFailed.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandDiscoveryFailed.java new file mode 100644 index 00000000..582e4cfc --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandDiscoveryFailed.java @@ -0,0 +1,44 @@ +/* + * 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; + +public class OnapCommandDiscoveryFailed extends OnapCommandException { + + private static final long serialVersionUID = 424464582747161435L; + + private static final String ERROR_CODE = "0x0010"; + private static final String ERROR_MESSAGE1 = "Failed auto discover schema files from "; + private static final String ERROR_MESSAGE2 = " under class path, "; + private static final String ERROR_MESSAGE3 = "' under class path directory '"; + private static final String ERROR_MESSAGE4 = "Failed auto generate json file '"; + + public OnapCommandDiscoveryFailed(String name) { + this(name, new Exception("")); + } + + public OnapCommandDiscoveryFailed(String name, Throwable throwable) { + super(ERROR_CODE, ERROR_MESSAGE1 + name + ERROR_MESSAGE2 + throwable.getMessage()); + } + + public OnapCommandDiscoveryFailed(String directory, String fileName) { + this(directory, fileName, new Exception("")); + } + + public OnapCommandDiscoveryFailed(String directory, String fileName, Throwable throwable) { + super(ERROR_CODE, ERROR_MESSAGE4 + fileName + ERROR_MESSAGE3 + directory + "' , " + throwable.getMessage()); + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandException.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandException.java new file mode 100644 index 00000000..3ef1b400 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandException.java @@ -0,0 +1,73 @@ +/* + * 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; + +/** + * Base command exception. + * + */ +public class OnapCommandException extends Exception { + + private static final long serialVersionUID = 2833124031431731711L; + + /* + * Command Error Code + */ + private final String errorCode; + + /* + * Command error message + */ + private final String errorMessage; + + /* + * Command HTTP status code + */ + private final long httpStatusCode; + + /** + * OnapCommandException constructor. + * + * @param errorCode + * error code + * @param errorMessage + * error message + * @param httpStatusCode + * http status code + */ + public OnapCommandException(String errorCode, String errorMessage, long httpStatusCode) { + super(); + this.errorCode = errorCode; + this.errorMessage = errorMessage; + this.httpStatusCode = httpStatusCode; + } + + public OnapCommandException(String errorCode, String errorMessage) { + this(errorCode, errorMessage, -1); + } + + @Override + public String getMessage() { + String message = this.errorCode + "::" + this.errorMessage; + if (this.httpStatusCode != -1) { + message = this.httpStatusCode + "::" + message; + } + + return message; + } + +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandExecutionFailed.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandExecutionFailed.java new file mode 100644 index 00000000..22d11acb --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandExecutionFailed.java @@ -0,0 +1,55 @@ +/* + * 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; + +/** + * Command execution failed. + * + */ +public class OnapCommandExecutionFailed extends OnapCommandException { + private static final long serialVersionUID = 488775545436993019L; + + private static final String ERROR_CODE = "0x0001"; + private static final String ERROR_MESSAGE1 = "Command "; + private static final String ERROR_MESSAGE2 = " failed to execute, "; + private static final String ERROR_MESSAGE3 = "Failed to retrive service url, "; + + public OnapCommandExecutionFailed(String cmdName, String error, long httpStatus) { + super(ERROR_CODE, ERROR_MESSAGE1 + cmdName + ERROR_MESSAGE2 + error, httpStatus); + } + + public OnapCommandExecutionFailed(String cmdName, Throwable throwable, long httpStatus) { + this(cmdName,throwable.getMessage(),httpStatus); + } + + public OnapCommandExecutionFailed(String error) { + super(ERROR_CODE, error); + } + + public OnapCommandExecutionFailed(Throwable throwable, String details) { + this(ERROR_MESSAGE3 + details + ", " + throwable.getMessage()); + } + + + public OnapCommandExecutionFailed(String cmdName, String error) { + super(ERROR_CODE, ERROR_MESSAGE1 + cmdName + ERROR_MESSAGE2 + error); + } + + public OnapCommandExecutionFailed(String cmd, Throwable throwable) { + this(cmd , throwable.getMessage()); + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandExecutorInfoMissing.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandExecutorInfoMissing.java new file mode 100644 index 00000000..b4945dda --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandExecutorInfoMissing.java @@ -0,0 +1,30 @@ +/* + * 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; + +/** + * Command result initialization failed. + * + */ +public class OnapCommandExecutorInfoMissing extends OnapCommandException { + + private static final long serialVersionUID = 8580121615330415456L; + + public OnapCommandExecutorInfoMissing(String cmd) { + super("0x0023", "Command " + cmd + " excutor info is missing from schema"); + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandHelpFailed.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandHelpFailed.java new file mode 100644 index 00000000..12e711e3 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandHelpFailed.java @@ -0,0 +1,39 @@ +/* + * 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; + +/** + * Command help failed. + * + */ +public class OnapCommandHelpFailed extends OnapCommandException { + private static final long serialVersionUID = -1833571383961748518L; + + /** + * Help failed exception. + * + * @param error + * message + */ + public OnapCommandHelpFailed(String error) { + super("0x0002", "Command failed to print help message, " + error); + } + + public OnapCommandHelpFailed(Throwable throwable) { + this(throwable.getMessage()); + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandHttpFailure.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandHttpFailure.java new file mode 100644 index 00000000..80f99695 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandHttpFailure.java @@ -0,0 +1,44 @@ +/* + * 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; + +/** + * Command execution failed. + * + */ +public class OnapCommandHttpFailure extends OnapCommandException { + private static final long serialVersionUID = 488775545436993345L; + + private static final String ERROR = "0x0025"; + + public OnapCommandHttpFailure(String error, long httpStatus) { + super(ERROR, error, httpStatus); + } + + public OnapCommandHttpFailure(String error) { + super(ERROR, error); + } + + public OnapCommandHttpFailure(Throwable throwable) { + this(throwable.getMessage()); + } + + public OnapCommandHttpFailure(Throwable throwable, long httpStatus) { + this(throwable.getMessage(), httpStatus); + } + +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandHttpHeaderNotFound.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandHttpHeaderNotFound.java new file mode 100644 index 00000000..ba0006ec --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandHttpHeaderNotFound.java @@ -0,0 +1,30 @@ +/* + * 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; + +/** + * OnapCommandParameterNotFound. + * + */ +public class OnapCommandHttpHeaderNotFound extends OnapCommandException { + + private static final long serialVersionUID = 6676137916079057963L; + + public OnapCommandHttpHeaderNotFound(String name) { + super("0x0027", "Http header " + name + " is not returned from the service"); + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandHttpInvalidResponseBody.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandHttpInvalidResponseBody.java new file mode 100644 index 00000000..1451440a --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandHttpInvalidResponseBody.java @@ -0,0 +1,34 @@ +/* + * 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; + +/** + * OnapCommandParameterNotFound. + * + */ +public class OnapCommandHttpInvalidResponseBody extends OnapCommandException { + + private static final long serialVersionUID = 6676137916079057963L; + + public OnapCommandHttpInvalidResponseBody(String name, String error) { + super("0x0028", "Http response body does not have json entry " + name + ", " + error); + } + + public OnapCommandHttpInvalidResponseBody(String name, Throwable throwable) { + this(name, throwable.getMessage()); + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandInvalidParameterType.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandInvalidParameterType.java new file mode 100644 index 00000000..066e2699 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandInvalidParameterType.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; + +/** + * Command input parameter type is invalid. + * + */ +public class OnapCommandInvalidParameterType extends OnapCommandException { + + private static final long serialVersionUID = 2821256032317061066L; + + public OnapCommandInvalidParameterType(String paramName) { + super("0x0003", "Parameter type " + paramName + " is invalid"); + + } + +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandInvalidParameterValue.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandInvalidParameterValue.java new file mode 100644 index 00000000..652789a6 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandInvalidParameterValue.java @@ -0,0 +1,35 @@ +/* + * 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; + +/** + * Command input parameter value is invalid. + * + */ +public class OnapCommandInvalidParameterValue extends OnapCommandException { + + private static final long serialVersionUID = 2821256032317061437L; + + public OnapCommandInvalidParameterValue(String paramName) { + this(paramName,new Exception("")); + } + + public OnapCommandInvalidParameterValue(String paramName, Throwable throwable) { + super("0x0028", "Parameter " + paramName + " value is invalid, " + throwable.getMessage()); + } + +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandInvalidPrintDirection.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandInvalidPrintDirection.java new file mode 100644 index 00000000..960bfa40 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandInvalidPrintDirection.java @@ -0,0 +1,31 @@ +/* + * 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; + +/** + * Command print direction invalid. + * + */ +public class OnapCommandInvalidPrintDirection extends OnapCommandException { + + private static final long serialVersionUID = -6008135162231523072L; + + public OnapCommandInvalidPrintDirection(String direction) { + super("0x0004", "Print direction " + direction + " is invalid"); + + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandInvalidRegistration.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandInvalidRegistration.java new file mode 100644 index 00000000..c403a4ad --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandInvalidRegistration.java @@ -0,0 +1,33 @@ +/* + * 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 org.onap.cli.fw.OnapCommand; + +/** + * Command class invalid. + * + */ +public class OnapCommandInvalidRegistration extends OnapCommandException { + + private static final long serialVersionUID = 7722163282274482532L; + + public OnapCommandInvalidRegistration(Class cls) { + super("0x0005", "Invalid commad class " + cls.getCanonicalName() + " registration, it should be derived from " + + OnapCommand.class.getCanonicalName()); + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandInvalidResultAttributeScope.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandInvalidResultAttributeScope.java new file mode 100644 index 00000000..d4a3a5ee --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandInvalidResultAttributeScope.java @@ -0,0 +1,31 @@ +/* + * 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; + +/** + * Result attribute invalid. + * + */ +public class OnapCommandInvalidResultAttributeScope extends OnapCommandException { + + private static final long serialVersionUID = 117926166492101573L; + + public OnapCommandInvalidResultAttributeScope(String attr) { + super("0x0006", "Result atrribute " + attr + " is invalid"); + + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandInvalidSchema.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandInvalidSchema.java new file mode 100644 index 00000000..a32a8f2a --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandInvalidSchema.java @@ -0,0 +1,35 @@ +/* + * 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; + +/** + * Command schema is invalid. + * + */ +public class OnapCommandInvalidSchema extends OnapCommandException { + + private static final long serialVersionUID = -3387652326582792833L; + + public OnapCommandInvalidSchema(String schema, String error) { + super("0x0007", "Command schema " + schema + " is invalid, " + error); + } + + public OnapCommandInvalidSchema(String schema, Throwable throwable) { + this(schema, throwable.getMessage()); + } + +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandInvalidSchemaVersion.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandInvalidSchemaVersion.java new file mode 100644 index 00000000..75530ab4 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandInvalidSchemaVersion.java @@ -0,0 +1,31 @@ +/* + * 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; + +/** + * Command schema version is invalid. + * + */ +public class OnapCommandInvalidSchemaVersion extends OnapCommandException { + + private static final long serialVersionUID = 4459731110721370387L; + + public OnapCommandInvalidSchemaVersion(String schemaVersion) { + super("0x0008", "Command schema onap_cmd_schema_version " + schemaVersion + " is invalid or missing"); + } + +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandLoginFailed.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandLoginFailed.java new file mode 100644 index 00000000..c2d69bc1 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandLoginFailed.java @@ -0,0 +1,41 @@ +/* + * 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; + +/** + * Login failed. + * + */ +public class OnapCommandLoginFailed extends OnapCommandException { + + private static final long serialVersionUID = 5518154493762956959L; + + private static final String ERROR_CODE = "0x0009"; + private static final String ERROR_MESSAGE1 = "Login failed, "; + + public OnapCommandLoginFailed(String error) { + super(ERROR_CODE, ERROR_MESSAGE1 + error); + } + + public OnapCommandLoginFailed(String error, int httpStatus) { + super(ERROR_CODE, ERROR_MESSAGE1 + error, httpStatus); + } + + public OnapCommandLoginFailed(Throwable throwable) { + this(throwable.getMessage()); + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandLogoutFailed.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandLogoutFailed.java new file mode 100644 index 00000000..3b415de0 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandLogoutFailed.java @@ -0,0 +1,40 @@ +/* + * 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; + +/** + * Logout failed. + * + */ +public class OnapCommandLogoutFailed extends OnapCommandException { + + private static final long serialVersionUID = 1150649507734289032L; + private static final String ERROR_CODE = "0x0010"; + private static final String ERROR_MESSAGE1 = "Logout failed, "; + + public OnapCommandLogoutFailed(String error) { + super(ERROR_CODE, ERROR_MESSAGE1 + error); + } + + public OnapCommandLogoutFailed(Throwable throwable) { + this(throwable.getMessage()); + } + + public OnapCommandLogoutFailed(int statusCode) { + super(ERROR_CODE, ERROR_MESSAGE1, statusCode); + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandNotFound.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandNotFound.java new file mode 100644 index 00000000..172d60bb --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandNotFound.java @@ -0,0 +1,30 @@ +/* + * 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; + +/** + * Command not registered in CLI registrar. + * + */ +public class OnapCommandNotFound extends OnapCommandException { + + private static final long serialVersionUID = 6676137916079057963L; + + public OnapCommandNotFound(String cmdName) { + super("0x0011", "Command " + cmdName + " is not registered"); + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandNotInitialized.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandNotInitialized.java new file mode 100644 index 00000000..8c3f6c22 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandNotInitialized.java @@ -0,0 +1,30 @@ +/* + * 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; + +/** + * Command not initialized. + * + */ +public class OnapCommandNotInitialized extends OnapCommandException { + + private static final long serialVersionUID = -2828462844645573902L; + + public OnapCommandNotInitialized(String cmdName) { + super("0x0012", "Command " + cmdName + " is not initialized"); + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandOutputFormatNotsupported.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandOutputFormatNotsupported.java new file mode 100644 index 00000000..e54171ef --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandOutputFormatNotsupported.java @@ -0,0 +1,30 @@ +/* + * 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; + +/** + * Command does not support to format of output. + * + */ +public class OnapCommandOutputFormatNotsupported extends OnapCommandException { + + private static final long serialVersionUID = 2429471829315901896L; + + public OnapCommandOutputFormatNotsupported(String format) { + super("0x0013", "Command does not support the output format " + format); + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandOutputPrintingFailed.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandOutputPrintingFailed.java new file mode 100644 index 00000000..31ee3e0b --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandOutputPrintingFailed.java @@ -0,0 +1,34 @@ +/* + * 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; + +/** + * Output print failed. + * + */ +public class OnapCommandOutputPrintingFailed extends OnapCommandException { + + private static final long serialVersionUID = -1957064141442406239L; + + public OnapCommandOutputPrintingFailed(String error) { + super("0x0014", "Command is failed to print the result, " + error); + } + + public OnapCommandOutputPrintingFailed(Throwable throwable) { + this(throwable.getMessage()); + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandParameterMissing.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandParameterMissing.java new file mode 100644 index 00000000..54e0a0de --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandParameterMissing.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; + +/** + * Command input parameters are invalid. + * + */ +public class OnapCommandParameterMissing extends OnapCommandException { + + private static final long serialVersionUID = 2821256032317061066L; + + public OnapCommandParameterMissing(String paramName) { + super("0x0015", "Parameter " + paramName + " is mandatory"); + + } + +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandParameterNameConflict.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandParameterNameConflict.java new file mode 100644 index 00000000..d5dc185c --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandParameterNameConflict.java @@ -0,0 +1,31 @@ +/* + * 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; + +/** + * Command input parameter options are conflicting. + * + */ +public class OnapCommandParameterNameConflict extends OnapCommandException { + + private static final long serialVersionUID = -993203017969910920L; + + public OnapCommandParameterNameConflict(String name) { + super("0x0016", "Parameter name " + name + " is in conflict"); + + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandParameterNotFound.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandParameterNotFound.java new file mode 100644 index 00000000..ea3eb3a8 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandParameterNotFound.java @@ -0,0 +1,30 @@ +/* + * 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; + +/** + * OnapCommandParameterNotFound. + * + */ +public class OnapCommandParameterNotFound extends OnapCommandException { + + private static final long serialVersionUID = 6676137916079057963L; + + public OnapCommandParameterNotFound(String paramName) { + super("0x0026", "Command input parameter " + paramName + " is not valid"); + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandParameterOptionConflict.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandParameterOptionConflict.java new file mode 100644 index 00000000..91decf99 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandParameterOptionConflict.java @@ -0,0 +1,31 @@ +/* + * 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; + +/** + * Command input parameter names are conflicting. + * + */ +public class OnapCommandParameterOptionConflict extends OnapCommandException { + + private static final long serialVersionUID = -3107017890769007297L; + + public OnapCommandParameterOptionConflict(String name) { + super("0x0017", "Parameter option " + name + " is in conflict, only one option is allowed with given name"); + + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandRegistrationFailed.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandRegistrationFailed.java new file mode 100644 index 00000000..d920f7d0 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandRegistrationFailed.java @@ -0,0 +1,34 @@ +/* + * 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; + +/** + * Command Not registered in Onap Command Registrar. + * + */ +public class OnapCommandRegistrationFailed extends OnapCommandException { + + private static final long serialVersionUID = 5513297861129088460L; + + public OnapCommandRegistrationFailed(String cmdName, String error) { + super("0x0018", "Command " + cmdName + " is failed to register, " + error); + } + + public OnapCommandRegistrationFailed(String cmdName, Throwable throwable) { + this(cmdName, throwable.getMessage()); + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandResultEmpty.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandResultEmpty.java new file mode 100644 index 00000000..5d7e4fd3 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandResultEmpty.java @@ -0,0 +1,33 @@ +/* + * 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; + +/** + * Command result empty. + * + */ +public class OnapCommandResultEmpty extends OnapCommandWarning { + + private static final long serialVersionUID = 8580121615330415123L; + + /** + * Command result empty. + */ + public OnapCommandResultEmpty() { + super("0x1001", "Command result is empty"); + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandResultInitialzationFailed.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandResultInitialzationFailed.java new file mode 100644 index 00000000..20060531 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandResultInitialzationFailed.java @@ -0,0 +1,34 @@ +/* + * 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; + +/** + * Command result initialization failed. + * + */ +public class OnapCommandResultInitialzationFailed extends OnapCommandException { + + private static final long serialVersionUID = 8580121615330415123L; + + public OnapCommandResultInitialzationFailed(String cmd, String error) { + super("0x0022", "Command " + cmd + " result format is failed, " + error); + } + + public OnapCommandResultInitialzationFailed(String cmd, Throwable throwable) { + this(cmd, throwable.getMessage()); + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandResultMapProcessingFailed.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandResultMapProcessingFailed.java new file mode 100644 index 00000000..191ced06 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandResultMapProcessingFailed.java @@ -0,0 +1,35 @@ +/* + * 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; + +/** + * Result map failure. + * + */ +public class OnapCommandResultMapProcessingFailed extends OnapCommandException { + private static final long serialVersionUID = 488775545436113019L; + + private static final String errorCode = "0x0028"; + + public OnapCommandResultMapProcessingFailed(String resultMap, String error) { + super(errorCode, "Failed to process the result map " + resultMap + " in http section, " + error); + } + + public OnapCommandResultMapProcessingFailed(String resultMap, Throwable throwable) { + this(resultMap, throwable.getMessage()); + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandSchemaNotFound.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandSchemaNotFound.java new file mode 100644 index 00000000..cbd6fa69 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandSchemaNotFound.java @@ -0,0 +1,34 @@ +/* + * 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; + +/** + * Command schema not found. + * + */ +public class OnapCommandSchemaNotFound extends OnapCommandException { + + private static final long serialVersionUID = -3919580583845280200L; + + public OnapCommandSchemaNotFound(String cmdName) { + this(cmdName, new Exception("")); + } + + public OnapCommandSchemaNotFound(String cmdName, Throwable throwable) { + super("0x0019", "Command schema " + cmdName + " is not found, " + throwable.getMessage()); + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandServiceNotFound.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandServiceNotFound.java new file mode 100644 index 00000000..fbbaafbd --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandServiceNotFound.java @@ -0,0 +1,30 @@ +/* + * 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; + +/** + * Command not registered in MSB. + * + */ +public class OnapCommandServiceNotFound extends OnapCommandException { + + private static final long serialVersionUID = 8580121615330415065L; + + public OnapCommandServiceNotFound(String service) { + super("0x0020", "Service " + service + " is not found in MSB"); + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandWarning.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandWarning.java new file mode 100644 index 00000000..bb102a5b --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandWarning.java @@ -0,0 +1,33 @@ +/* + * 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; + +/** + * Command warning. + * + */ +public abstract class OnapCommandWarning extends OnapCommandException { + public OnapCommandWarning(String errorCode, String errorMessage, long httpStatusCode) { + super(errorCode, errorMessage, httpStatusCode); + } + + public OnapCommandWarning(String errorCode, String errorMessage) { + super(errorCode, errorMessage); + } + + private static final long serialVersionUID = -1833571383961748520L; +} diff --git a/framework/src/main/java/org/onap/cli/fw/http/HttpInput.java b/framework/src/main/java/org/onap/cli/fw/http/HttpInput.java new file mode 100644 index 00000000..3ab6cf4b --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/http/HttpInput.java @@ -0,0 +1,128 @@ +/* + * 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.http; + +import java.util.HashMap; +import java.util.Map; + +/** + * Captures HTTP request URI, body and request &query parameters.
+ */ +public class HttpInput { + + private String reqUri = ""; + + private String reqBody = ""; + + private String reqMethod = ""; + + private Map reqHeaders = new HashMap<>(); + + private Map reqQueries = new HashMap<>(); + + private Map reqCookies = new HashMap<>(); + + private boolean binaryData; + + public String getUri() { + return this.reqUri; + } + + public HttpInput setUri(String uri) { + this.reqUri = uri; + return this; + } + + public String getBody() { + return this.reqBody; + } + + public HttpInput setBody(String body) { + this.reqBody = body; + return this; + } + + public Map getReqHeaders() { + return this.reqHeaders; + } + + /** + * header parameter setter. + * + * @param reqHeaders + * header map + * @return HttpInput + */ + public HttpInput setReqHeaders(Map reqHeaders) { + if (reqHeaders != null) { + this.reqHeaders = reqHeaders; + } + return this; + } + + public String getMethod() { + return this.reqMethod; + } + + public HttpInput setMethod(String method) { + this.reqMethod = method; + return this; + } + + public Map getReqQueries() { + return reqQueries; + } + + /** + * Request query parameters. + * + * @param reqQueries + * request queries + * @return HttpInput + */ + public HttpInput setReqQueries(Map reqQueries) { + if (reqQueries != null) { + this.reqQueries = reqQueries; + } + return this; + } + + public Map getReqCookies() { + return reqCookies; + } + + public HttpInput setReqCookies(Map reqCookies) { + this.reqCookies = reqCookies; + return this; + } + + public boolean isBinaryData() { + return binaryData; + } + + public void setBinaryData(boolean binaryData) { + this.binaryData = binaryData; + } + + @Override + public String toString() { + return "\nURL: " + this.getUri() + "\nMethod: " + this.getMethod() + "\nRequest Queries: " + + this.getReqQueries() + "\nRequest Body: " + this.getBody() + "\nRequest Headers: " + + this.getReqHeaders().toString() + "\nRequest Cookies: " + this.getReqCookies().toString() + + "\nbinaryData=" + this.binaryData; + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/http/HttpResult.java b/framework/src/main/java/org/onap/cli/fw/http/HttpResult.java new file mode 100644 index 00000000..e000ee15 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/http/HttpResult.java @@ -0,0 +1,77 @@ +/* + * 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.http; + +import java.util.HashMap; +import java.util.Map; + +/** + * Captures HTTP response status, body and headers.
+ * + */ +public class HttpResult { + + private int status; + + private String resBody; + + private Map respHeaders = new HashMap<>(); + + private Map respCookies = new HashMap<>(); + + public int getStatus() { + return this.status; + } + + public void setStatus(int status) { + this.status = status; + } + + public String getBody() { + return this.resBody; + } + + public void setBody(String body) { + this.resBody = body; + } + + public void setRespHeaders(Map respHeaders) { + this.respHeaders = respHeaders; + } + + public Map getRespHeaders() { + return this.respHeaders; + } + + public Map getRespCookies() { + return respCookies; + } + + public void setRespCookies(Map respCookies) { + this.respCookies = respCookies; + } + + public boolean isSuccess() { + return this.getStatus() >= 200 && this.getStatus() <= 300; + } + + @Override + public String toString() { + return "\nHTTP Status: " + this.getStatus() + "\nResponse Body: " + this.getBody() + "\nResponse Headers: " + + this.getRespHeaders() + "\nResponse Cookies: " + this.getRespCookies(); + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/http/OnapHttpConnection.java b/framework/src/main/java/org/onap/cli/fw/http/OnapHttpConnection.java new file mode 100644 index 00000000..5b8cf8b1 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/http/OnapHttpConnection.java @@ -0,0 +1,346 @@ +/* + * 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.http; + +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.ParseException; +import org.apache.http.client.CookieStore; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.client.protocol.ClientContext; +import org.apache.http.config.Registry; +import org.apache.http.config.RegistryBuilder; +import org.apache.http.conn.HttpClientConnectionManager; +import org.apache.http.conn.socket.ConnectionSocketFactory; +import org.apache.http.conn.ssl.AllowAllHostnameVerifier; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.conn.ssl.X509HostnameVerifier; +import org.apache.http.cookie.Cookie; +import org.apache.http.entity.StringEntity; +import org.apache.http.entity.mime.HttpMultipartMode; +import org.apache.http.entity.mime.MultipartEntity; +import org.apache.http.entity.mime.content.FileBody; +import org.apache.http.impl.client.BasicCookieStore; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.client.LaxRedirectStrategy; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.impl.cookie.BasicClientCookie; +import org.apache.http.protocol.BasicHttpContext; +import org.apache.http.protocol.HttpContext; +import org.apache.http.util.EntityUtils; +import org.onap.cli.fw.conf.Constants; +import org.onap.cli.fw.error.OnapCommandHttpFailure; + +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.security.cert.X509Certificate; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +/** + * Helps to make http connection.
+ */ +public class OnapHttpConnection { + + private HttpClient httpClient = null; + + private String xauthToken = null; + + protected boolean debug = false; + + private String debugDetails = ""; + + public static class TrustAllX509TrustManager implements X509TrustManager { + + @Override + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0]; + } + + @Override + public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) { + // No need to implement. + } + + @Override + public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) { + // No need to implement. + } + } + + /** + * OnapHttpConnection Constructor. + * + * @param isSecured + * boolean + * @param debug + * boolean + * @throws OnapCommandHttpFailure + * exception + */ + public OnapHttpConnection(boolean isSecured, boolean debug) throws OnapCommandHttpFailure { + try { + if (isSecured) { + SSLContext sslContext = SSLContext.getInstance(Constants.SSLCONTEST_TLS); + sslContext.init(null, new TrustManager[] { new TrustAllX509TrustManager() }, + new java.security.SecureRandom()); + X509HostnameVerifier hostnameVerifier = new AllowAllHostnameVerifier(); + Registry socketFactoryRegistry = RegistryBuilder + .create() + .register("https", new SSLConnectionSocketFactory(sslContext, hostnameVerifier)).build(); + HttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); + + this.httpClient = HttpClients.custom().setConnectionManager(connManager) + .setRedirectStrategy(new LaxRedirectStrategy()).build(); + } else { + this.httpClient = HttpClients.createDefault(); + } + } catch (Exception e) { + throw new OnapCommandHttpFailure(e); + } + + this.debug = debug; + } + + public String getDebugInfo() { + return this.debugDetails; + } + + public void setAuthToken(String token) { + this.xauthToken = token; + } + + public String getAuthToken() { + return this.xauthToken; + } + + private Map getHttpHeaders(HttpResponse resp) { + Map result = new HashMap<>(); + + Header[] hs = resp.getAllHeaders(); + for (int i = 0; i < hs.length; i++) { + result.put(hs[i].getName(), hs[i].getValue()); + } + + return result; + } + + private String getResponseBody(HttpResponse resp) throws OnapCommandHttpFailure { + if (resp.getEntity() == null) { + return null; + } + try { + String body = EntityUtils.toString(resp.getEntity(), StandardCharsets.UTF_8); + EntityUtils.consume(resp.getEntity()); + return body; + } catch (IOException e) { + throw new OnapCommandHttpFailure(e); + } + } + + private StringEntity getStringEntity(HttpInput input) { + return new StringEntity(input.getBody(), StandardCharsets.UTF_8); + } + + /** + * Post.
+ * + * @param input + * HttpInput Obj + * @return HttpResult + * @throws OnapCommandHttpFailure + * http failure + */ + public HttpResult post(final HttpInput input) throws OnapCommandHttpFailure { + input.setMethod("post"); + return this.request(input); + } + + /** + * Get.
+ * + * @param input + * input request + * @return HttpResult + * @throws OnapCommandHttpFailure + * excpetion + */ + public HttpResult get(final HttpInput input) throws OnapCommandHttpFailure { + input.setMethod("get"); + return this.request(input); + } + + /** + * Put.
+ * + * @param input + * input request + * @return HttpResult + * @throws OnapCommandHttpFailure + * Exception + */ + public HttpResult put(final HttpInput input) throws OnapCommandHttpFailure { + input.setMethod("put"); + return this.request(input); + } + + /** + * Delete.
+ * + * @param input + * input request + * @return HttpResult + * @throws OnapCommandHttpFailure + * exception + */ + public HttpResult delete(final HttpInput input) throws OnapCommandHttpFailure { + input.setMethod("delete"); + return this.request(input); + } + + private void addCommonHeaders(HttpInput input) { + if (!input.isBinaryData()) { + input.getReqHeaders().put("Content-Type", Constants.APPLICATION_JSON); + } + input.getReqHeaders().put("Accept", Constants.APPLICATION_JSON); + if (this.xauthToken != null) { + input.getReqHeaders().put(Constants.X_AUTH_TOKEN, this.xauthToken); + } + } + + private void addCommonCookies(CookieStore cookieStore) { + Cookie cookie = new BasicClientCookie(Constants.X_AUTH_TOKEN, this.xauthToken); + cookieStore.addCookie(cookie); + } + + private void updateResultFromCookies(HttpResult result, List cookies) { + for (Cookie cookie : cookies) { + result.getRespCookies().put(cookie.getName(), cookie.getValue()); + } + } + + private String getDomain(String url) { + try { + return new URL(url).getHost(); + } catch (MalformedURLException e) { + // url is always proper !! + return url; + } + } + + private void updateInputFromCookies(HttpInput input, CookieStore cookieStore) { + addCommonCookies(cookieStore); + for (String cookieName : input.getReqCookies().keySet()) { + BasicClientCookie cookie = new BasicClientCookie(cookieName, input.getReqCookies().get(cookieName)); + cookie.setDomain(this.getDomain(input.getUri())); + cookieStore.addCookie(cookie); + } + + } + + /** + * Handles http method requests. + * + * @param input + * HttpInput + * @return HttpResult + * @throws OnapCommandHttpFailure + * exception + */ + public HttpResult request(HttpInput input) throws OnapCommandHttpFailure { + this.addCommonHeaders(input); + + HttpRequestBase requestBase = null; + if ("post".equals(input.getMethod())) { + HttpPost httpPost = new HttpPost(); + if (input.isBinaryData()) { + httpPost.setEntity(getMultipartEntity(input)); + } else { + httpPost.setEntity(this.getStringEntity(input)); + } + requestBase = httpPost; + } else if ("put".equals(input.getMethod())) { + HttpPut httpPut = new HttpPut(); + httpPut.setEntity(this.getStringEntity(input)); + requestBase = httpPut; + } else if ("get".equals(input.getMethod())) { + requestBase = new HttpGet(); + } else if ("delete".equals(input.getMethod())) { + requestBase = new HttpDelete(); + } else { + throw new IllegalArgumentException("Invalid HTTP method"); + } + + requestBase.setURI(URI.create(input.getUri())); + + for (Entry h : input.getReqHeaders().entrySet()) { + requestBase.addHeader(h.getKey(), h.getValue()); + } + + HttpResult result = new HttpResult(); + + try { + this.debugDetails = ""; + CookieStore cookieStore = new BasicCookieStore(); + updateInputFromCookies(input, cookieStore); + HttpContext localContext = new BasicHttpContext(); + localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore); + + HttpResponse resp = this.httpClient.execute(requestBase, localContext); + String respContent = this.getResponseBody(resp); + result.setBody(respContent); + result.setStatus(resp.getStatusLine().getStatusCode()); + result.setRespHeaders(this.getHttpHeaders(resp)); + this.updateResultFromCookies(result, cookieStore.getCookies()); + } catch (ParseException | IOException e) { + throw new OnapCommandHttpFailure(e); + } finally { + if (this.debug) { + this.debugDetails = input + "" + result; + } + } + + return result; + } + + public void close() { + this.setAuthToken(null); + } + + private HttpEntity getMultipartEntity(HttpInput input) { + FileBody fileBody = new FileBody(new File(input.getBody().trim())); + MultipartEntity multipartEntity = new MultipartEntity(); + multipartEntity.addPart("file", fileBody); + return multipartEntity; + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/input/OnapCommandParameter.java b/framework/src/main/java/org/onap/cli/fw/input/OnapCommandParameter.java new file mode 100644 index 00000000..167b353d --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/input/OnapCommandParameter.java @@ -0,0 +1,254 @@ +/* + * 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.input; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandInvalidParameterValue; +import org.onap.cli.fw.error.OnapCommandParameterMissing; + +import java.io.File; +import java.util.List; +import java.util.Map; + +/** + * Onap Command's input parameter. + * + */ +public class OnapCommandParameter { + + /* + * Name, for positional parameters, the place is decided from schema file definition + */ + private String cmdName; + + /* + * Description + */ + private String cmdDescription = ""; + + /* + * Short Option, like -f, for positional parameters, its not required. + */ + private String shortOption = null; + + /* + * Long Option, like --file-path, for positional parameters, its not required. + */ + private String longOption = null; + + /* + * Parameter type such as int, json, yaml, string, etc + */ + private ParameterType parameterType; + + /* + * Default value + */ + private String defaultValue = ""; + + /* + * Is optional + */ + private boolean isOptional = false; + + /* + * Is secured + */ + private boolean isSecured = false; + + /* + * Parameter Value + */ + private Object value; + + public String getName() { + return cmdName; + } + + public void setName(String name) { + this.cmdName = name; + } + + public String getDescription() { + return cmdDescription; + } + + public void setDescription(String description) { + this.cmdDescription = description; + } + + public String getShortOption() { + return shortOption; + } + + public void setShortOption(String shortOption) { + this.shortOption = shortOption; + } + + public String getLongOption() { + return longOption; + } + + public void setLongOption(String longOption) { + this.longOption = longOption; + } + + public ParameterType getParameterType() { + return parameterType; + } + + public void setParameterType(ParameterType parameterType) { + this.parameterType = parameterType; + } + + /** + * Returns default value. + * + * @return string + */ + public String getDefaultValue() { + if (this.isDefaultValueAnEnv()) { + String envVar = this.getEnvVarNameFromDefaultValue(); + this.defaultValue = System.getenv(envVar); + } else if (this.getParameterType().equals(ParameterType.BOOL)) { + // For bool type always the default param is false + this.defaultValue = "false"; + } + + return defaultValue; + } + + /** + * check if the default value is ${ENV_VAR_NAME}. + * + * @return boolean + */ + public boolean isDefaultValueAnEnv() { + return this.defaultValue.trim().startsWith("${") && this.defaultValue.trim().endsWith("}"); + } + + /** + * check if the default value is ${ENV_VAR_NAME} and return the ENV_VAR_NAME. + * + * @return ENV_VAR_NAME + */ + public String getEnvVarNameFromDefaultValue() { + return this.defaultValue.trim().substring(2, this.defaultValue.length() - 1); + } + + public void setDefaultValue(String defaultValue) { + this.defaultValue = defaultValue; + } + + /** + * Returns param value. + * + * @return value + * @throws OnapCommandInvalidParameterValue + * exception + */ + public Object getValue() throws OnapCommandInvalidParameterValue { + if (value != null) { + if (ParameterType.URL.equals(parameterType) && !value.toString().startsWith("http") + && !value.toString().startsWith("/")) { + value = "/" + value; + } else if (ParameterType.ARRAY.equals(parameterType)) { + if (!(value instanceof List)) { + throw new OnapCommandInvalidParameterValue(this.getName()); + } + + List list = (List) value; + ObjectMapper mapper = new ObjectMapper(); + try { + return mapper.writeValueAsString(list); + } catch (JsonProcessingException e) { + throw new OnapCommandInvalidParameterValue(this.getName(), e); + } + } else if (ParameterType.MAP.equals(parameterType)) { + if (!(value instanceof Map)) { + throw new OnapCommandInvalidParameterValue(this.getName()); + } + + Map map = (Map) value; + ObjectMapper mapper = new ObjectMapper(); + try { + return mapper.writeValueAsString(map); + } catch (JsonProcessingException e) { + throw new OnapCommandInvalidParameterValue(this.getName(), e); + } + } + + return value; + } + return getDefaultValue(); + } + + public void setValue(Object value) { + this.value = value; + } + + public boolean isOptional() { + return isOptional; + } + + public void setOptional(boolean isOptional) { + this.isOptional = isOptional; + } + + public boolean isSecured() { + return isSecured; + } + + public void setSecured(boolean isSecured) { + this.isSecured = isSecured; + } + + public static String printShortOption(String option) { + return "-" + option; + } + + public static String printLongOption(String option) { + return "-" + printShortOption(option); + } + + /** + * Validate parameter value. + * + * @throws OnapCommandParameterMissing + * exception + * @throws OnapCommandInvalidParameterValue + * exception + */ + public void validate() throws OnapCommandException { + // (mrkanag) empty check needs to revisit + if (!this.isOptional() && (this.getValue() == null || this.getValue().toString().isEmpty())) { + throw new OnapCommandParameterMissing(this.getName()); + } + + if (!this.isOptional() && ParameterType.BINARY.equals(parameterType)) { + File file = new File(value.toString()); + if (!file.isFile()) { + throw new OnapCommandInvalidParameterValue(this.getName()); + } + } + + // (mrkanag) validate for type supported ParameterType using constraints + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/input/ParameterType.java b/framework/src/main/java/org/onap/cli/fw/input/ParameterType.java new file mode 100644 index 00000000..ec76e0b4 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/input/ParameterType.java @@ -0,0 +1,71 @@ +/* + * 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.input; + +import org.onap.cli.fw.error.OnapCommandInvalidParameterType; + +/** + * Parameter type supported by Onap CLI. + * + */ +public enum ParameterType { + /** + * JSON file. + */ + JSON, + /** + * YAML file. + */ + YAML, STRING, LONG, + /** + * URL location. + */ + URL, BOOL, ARRAY, MAP, BINARY; + + /** + * Get parameter type. + * + * @param name + * type name + * @return type + * @throws OnapCommandInvalidParameterType + * exception + */ + public static ParameterType get(String name) throws OnapCommandInvalidParameterType { + if (JSON.name().equalsIgnoreCase(name)) { + return JSON; + } else if (YAML.name().equalsIgnoreCase(name)) { + return YAML; + } else if (STRING.name().equalsIgnoreCase(name)) { + return STRING; + } else if (LONG.name().equalsIgnoreCase(name)) { + return LONG; + } else if (URL.name().equalsIgnoreCase(name)) { + return URL; + } else if (BOOL.name().equalsIgnoreCase(name)) { + return BOOL; + } else if (ARRAY.name().equalsIgnoreCase(name)) { + return ARRAY; + } else if (MAP.name().equalsIgnoreCase(name)) { + return MAP; + } else if (BINARY.name().equalsIgnoreCase(name)) { + return BINARY; + } else { + throw new OnapCommandInvalidParameterType(name); + } + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/log/OnapCommandLogger.java b/framework/src/main/java/org/onap/cli/fw/log/OnapCommandLogger.java new file mode 100644 index 00000000..a29d3597 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/log/OnapCommandLogger.java @@ -0,0 +1,53 @@ +/* + * 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.log; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Helps to log the command method boundary calls. + * + */ +@Aspect +public class OnapCommandLogger { + private static final Logger LOGGER = LoggerFactory.getLogger(OnapCommandLogger.class); + + //(mrkanag) verify that it logs for all classes in this project. + /** + * Logging intercepter. + * + * @param joinPoint + * joinpoint + * @return object + * @throws Throwable + * exception + */ + @Around("execution(* org.onap.cli.fw*(..))") + public Object log(ProceedingJoinPoint joinPoint) throws Throwable { // NOSONAR + LOGGER.info(joinPoint.getThis().toString() + "->" + joinPoint.getSignature().getName() + "(" + + joinPoint.getArgs() + ")"); + + Object response = joinPoint.proceed(); + LOGGER.info(response.toString()); + + return response; + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/output/OnapCommandResult.java b/framework/src/main/java/org/onap/cli/fw/output/OnapCommandResult.java new file mode 100644 index 00000000..5dd761c6 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/output/OnapCommandResult.java @@ -0,0 +1,249 @@ +/* + * 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.output; + +import org.onap.cli.fw.conf.Constants; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandOutputFormatNotsupported; +import org.onap.cli.fw.error.OnapCommandOutputPrintingFailed; +import org.onap.cli.fw.input.ParameterType; +import org.onap.cli.fw.output.print.OnapCommandPrint; +import org.onap.cli.fw.utils.OnapCommandUtils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Onap Command result holds the final output of the command. + * + */ +public class OnapCommandResult { + + /* + * if type=JSON, then JSON response of the command from back-end Onap service, by default all the command would + * set this value once the back-end call returns, which would be useful to print the output in JSON format, returned + * from the back-end service. + * + * if type=TEXT, then it holds the result in text format such as help message + */ + private Object output; + + /* + * Type requested by user + */ + private ResultType type = ResultType.TABLE; + + /* + * Scope requested by user + */ + private OnapCommandResultAttributeScope scope = OnapCommandResultAttributeScope.SHORT; + + /* + * if type=TABLE, then List of result records, which could be printed on the CLI console, loaded from schema file + */ + private List records = new ArrayList<>(); + + /* + * Print horizontally or vertically, Mostly for show command, horizontal table while for list commands , it will be + * vertically printed. Respective command should set appropriately. + * + * loaded from schema file + */ + private PrintDirection printDirection = PrintDirection.LANDSCAPE; + + private String debugInfo = ""; + + /** + * Requested by user. + */ + private boolean includeTitle = true; + + /** + * Requested by user. + */ + private boolean includeSeparator = true; + + /** + * Requested by user. + */ + private boolean isDebug = false; + + public PrintDirection getPrintDirection() { + return printDirection; + } + + public void setPrintDirection(PrintDirection printDirection) { + this.printDirection = printDirection; + } + + public Object getOutput() { + return output; + } + + public void setOutput(Object output) { + this.output = output; + } + + public List getRecords() { + return records; + } + + public void setRecords(List records) { + this.records = records; + } + + /** + * Record mapping. + * + * @return attributes + */ + public Map getRecordsMap() { + Map recordMap = new HashMap<>(); + + for (OnapCommandResultAttribute record : this.getRecords()) { + recordMap.put(record.getName(), record); + } + + return recordMap; + } + + public ResultType getType() { + return type; + } + + public void setType(ResultType type) { + this.type = type; + } + + public OnapCommandResultAttributeScope getScope() { + return scope; + } + + public void setScope(OnapCommandResultAttributeScope scope) { + this.scope = scope; + } + + public boolean isIncludeTitle() { + return includeTitle; + } + + public void setIncludeTitle(boolean includeTitle) { + this.includeTitle = includeTitle; + } + + public boolean isIncludeSeparator() { + return includeSeparator; + } + + public void setIncludeSeparator(boolean includeSeparator) { + this.includeSeparator = includeSeparator; + } + + public String getDebugInfo() { + return debugInfo; + } + + public void setDebugInfo(String debugInfo) { + this.debugInfo = debugInfo; + } + + public boolean isDebug() { + return isDebug; + } + + public void setDebug(boolean isDebug) { + this.isDebug = isDebug; + } + + /** + * Helps to print the result based on the type. + * + * @return string + * @throws OnapCommandOutputFormatNotsupported + * excpetion + * @throws OnapCommandOutputPrintingFailed + * exception + */ + public String print() throws OnapCommandException { + String printOutput = ""; + + if (this.getRecords().isEmpty()) { + return printOutput; + } + + OnapCommandPrint print = new OnapCommandPrint(); + print.setPrintTitle(this.isIncludeTitle()); + if (this.getPrintDirection().equals(PrintDirection.LANDSCAPE)) { + for (OnapCommandResultAttribute record : this.getScopedRecords()) { + if (record.getType().equals(ParameterType.JSON)) { + print.addColumn(record.getName(), OnapCommandUtils.jsonFlatten(record.getValues())); + } else { + print.addColumn(record.getName(), record.getValues()); + } + } + } else { + // Add property column + OnapCommandResultAttribute prp = new OnapCommandResultAttribute(); + prp.setName(Constants.PORTRAINT_COLUMN_NAME_PROPERTY); + prp.setScope(OnapCommandResultAttributeScope.SHORT); + // Add value column + OnapCommandResultAttribute val = new OnapCommandResultAttribute(); + val.setName(Constants.PORTRAINT_COLUMN_NAME_VALUE); + val.setScope(OnapCommandResultAttributeScope.SHORT); + + for (OnapCommandResultAttribute record : this.getScopedRecords()) { + prp.getValues().add(record.getName()); + if (record.getValues().size() == 1) { + val.getValues().add(record.getValues().get(0)); + } else { + val.getValues().add(record.getValues().toString()); + } + } + + print.addColumn(prp.getName(), prp.getValues()); + print.addColumn(val.getName(), val.getValues()); + } + + if (this.isDebug()) { + printOutput = this.getDebugInfo() + "\n"; + } + + if (this.getType().equals(ResultType.JSON)) { + return printOutput + print.printJson(); + } else if (this.getType().equals(ResultType.TABLE)) { + return printOutput + print.printTable(this.isIncludeSeparator()); + } else if (this.getType().equals(ResultType.CSV)) { + return printOutput + print.printCsv(); + } + + throw new OnapCommandOutputFormatNotsupported(this.getType().name()); + } + + private List getScopedRecords() { + List recordList = new ArrayList<>(); + for (OnapCommandResultAttribute record : this.getRecords()) { + if (record.getScope().ordinal() > this.getScope().ordinal()) { + continue; + } + recordList.add(record); + } + + return recordList; + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/output/OnapCommandResultAttribute.java b/framework/src/main/java/org/onap/cli/fw/output/OnapCommandResultAttribute.java new file mode 100644 index 00000000..73617049 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/output/OnapCommandResultAttribute.java @@ -0,0 +1,102 @@ +/* + * 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.output; + +import org.onap.cli.fw.input.ParameterType; + +import java.util.ArrayList; +import java.util.List; + +/** + * Onap command output records, helps to define the title and its description while command is defined and during run + * time, it captures the value of the output as well. + */ +public class OnapCommandResultAttribute { + + /* + * Output name + */ + private String outName; + + /* + * Output description + */ + private String outDescription; + + /* + * Output values, in case list out, it holds values for all rows for show output, it will have one value + */ + private List values = new ArrayList<>(); + + /* + * Output scope + */ + private OnapCommandResultAttributeScope outScope = OnapCommandResultAttributeScope.SHORT; + + private ParameterType paramType = ParameterType.STRING; + + private boolean isSecured = false; + + public void setValues(List values) { + this.values = values; + } + + public String getName() { + return outName; + } + + public void setName(String name) { + this.outName = name; + } + + public String getDescription() { + return outDescription; + } + + public void setDescription(String description) { + this.outDescription = description; + } + + public List getValues() { + return values; + } + + public OnapCommandResultAttributeScope getScope() { + return outScope; + } + + public void setScope(OnapCommandResultAttributeScope scope) { + this.outScope = scope; + } + + public ParameterType getType() { + return paramType; + } + + public void setType(ParameterType type) { + this.paramType = type; + } + + public boolean isSecured() { + return isSecured; + } + + public void setSecured(boolean isSecured) { + this.isSecured = isSecured; + } + +} diff --git a/framework/src/main/java/org/onap/cli/fw/output/OnapCommandResultAttributeScope.java b/framework/src/main/java/org/onap/cli/fw/output/OnapCommandResultAttributeScope.java new file mode 100644 index 00000000..e03937d3 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/output/OnapCommandResultAttributeScope.java @@ -0,0 +1,55 @@ +/* + * 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.output; + +import org.onap.cli.fw.error.OnapCommandInvalidResultAttributeScope; + +/** + * Onap command supports to print output with given set of defined attributes, and each attributes are marked with this + * visibility. + * + */ +public enum OnapCommandResultAttributeScope { + /** + * By default, all output attributes which are tagged with short would be printed. + */ + SHORT, + /** + * When user provides --long or -l, all attributes including short tagged will be printed. otherwise, attributes + * tagged with long, whould be ignored as part of output + */ + LONG; + + /** + * get attribute scope enum type. + * + * @param name + * scope + * @return type + * @throws OnapCommandInvalidResultAttributeScope + * exception + */ + public static OnapCommandResultAttributeScope get(String name) throws OnapCommandInvalidResultAttributeScope { + if (LONG.name().equalsIgnoreCase(name)) { + return LONG; + } else if (SHORT.name().equalsIgnoreCase(name)) { + return SHORT; + } + + throw new OnapCommandInvalidResultAttributeScope(name); + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/output/PrintDirection.java b/framework/src/main/java/org/onap/cli/fw/output/PrintDirection.java new file mode 100644 index 00000000..96ad713f --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/output/PrintDirection.java @@ -0,0 +1,45 @@ +/* + * 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.output; + +import org.onap.cli.fw.error.OnapCommandInvalidPrintDirection; + +/** + * How to print the result. + * + */ +public enum PrintDirection { + LANDSCAPE, PORTRAIT; + /** + * Get print direction. + * + * @param name + * direction + * @return type + * @throws OnapCommandInvalidPrintDirection + * exception + */ + public static PrintDirection get(String name) throws OnapCommandInvalidPrintDirection { + if (LANDSCAPE.name().equalsIgnoreCase(name)) { + return LANDSCAPE; + } else if (PORTRAIT.name().equalsIgnoreCase(name)) { + return PORTRAIT; + } else { + throw new OnapCommandInvalidPrintDirection(name); + } + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/output/ResultType.java b/framework/src/main/java/org/onap/cli/fw/output/ResultType.java new file mode 100644 index 00000000..37449447 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/output/ResultType.java @@ -0,0 +1,63 @@ +/* + * 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.output; + +/** + * Onap command result format. + * + */ +public enum ResultType { + TABLE, CSV, JSON, YAML, TEXT; + + /** + * Check whether the output to be formatted in tabular format. + * + * @param type + * output format type + * @return boolean + */ + public static boolean isTabularForm(String type) { + if (type.equalsIgnoreCase(TABLE.name())) { + return true; + } + + return false; + } + + /** + * Get ResultType. + * + * @param name + * format name + * @return ResultType + */ + public static ResultType get(String name) { + if (TABLE.name().equalsIgnoreCase(name)) { + return TABLE; + } + if (CSV.name().equalsIgnoreCase(name)) { + return CSV; + } + if (JSON.name().equalsIgnoreCase(name)) { + return JSON; + } + if (YAML.name().equalsIgnoreCase(name)) { + return YAML; + } + return TEXT; + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/output/print/OnapCommandPrint.java b/framework/src/main/java/org/onap/cli/fw/output/print/OnapCommandPrint.java new file mode 100644 index 00000000..48a4e6ea --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/output/print/OnapCommandPrint.java @@ -0,0 +1,252 @@ +/* + * 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.output.print; + +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVPrinter; +import org.onap.cli.fw.error.OnapCommandOutputPrintingFailed; +import org.onap.cli.fw.output.PrintDirection; + +import java.io.IOException; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; + +/** + * Onap Command Table print. + * + */ +public class OnapCommandPrint { + + public static final int MAX_COLUMN_LENGTH = 50; + + private PrintDirection direction; + + private Map> data = new LinkedHashMap<>(); + + private boolean printTitle = true; + + public PrintDirection getDirection() { + return direction; + } + + public void setDirection(PrintDirection direction) { + this.direction = direction; + } + + public void addColumn(String header, List data) { + this.data.put(header, data); + } + + /** + * Get column. + * + * @param header + * string + * @return list + */ + public List getColumn(String header) { + if (this.data.get(header) == null) { + this.data.put(header, new ArrayList()); + } + return this.data.get(header); + } + + public boolean isPrintTitle() { + return printTitle; + } + + public void setPrintTitle(boolean printTitle) { + this.printTitle = printTitle; + } + + private int findMaxRows() { + int max = 1; + if (!this.isPrintTitle()) { + max = 0; + } + for (List cols : this.data.values()) { + if (cols != null && max < cols.size()) { + max = cols.size(); + } + } + + return max; + } + + /** + * Helps to form the rows from columns. + * + * @param isNormalize + * boolean + * @return +--------------+-----------+-----------------------------+ | header1 | header 2 | header 3 | + * +--------------+-----------+-----------------------------+ | v1 | List[line| v 3 | | | 1, line2]| | + * +--------------+-----------+-----------------------------+ | null | yyyyyy 2 | xxxxxx 3 | + * +--------------+-----------+-----------------------------+ + */ + private List> formRows(boolean isNormalize) { + List> rows = new ArrayList<>(); + + // add title + if (this.isPrintTitle()) { + List list = new ArrayList<>(); + for (String key : this.data.keySet()) { + if (isNormalize && key != null && key.length() > MAX_COLUMN_LENGTH) { + list.add(splitIntoList(key, MAX_COLUMN_LENGTH)); + } else { + list.add(key); + } + } + rows.add(list); + } + + // form row + for (int i = 0; i < this.findMaxRows(); i++) { + List row = new ArrayList<>(); + for (List cols : this.data.values()) { + if (cols.size() > i) { + String value = cols.get(i); + // split the cell into multiple sub rows + if (isNormalize && value != null && value.length() > MAX_COLUMN_LENGTH) { + row.add(splitIntoList(value, MAX_COLUMN_LENGTH)); + } else { + // store as string (one entry) + row.add(value); + } + } else { + // now value exist for this column + row.add(null); + } + } + rows.add(row); + } + + return rows; + } + + /** + * Splits big strings into list of strings based on maxCharInLine size. + * + * @param input + * input string + * @param maxCharInLine + * max length + * @return list of strings + */ + public List splitIntoList(String input, int maxCharInLine) { + + String inp = input; + + if (inp == null || "".equals(inp) || maxCharInLine <= 0) { + return Collections.emptyList(); + } + // new line is converted to space char + if (inp.contains("\n")) { + inp = inp.replaceAll("\n", ""); + } + + StringTokenizer tok = new StringTokenizer(inp, " "); + StringBuilder output = new StringBuilder(inp.length()); + int lineLen = 0; + while (tok.hasMoreTokens()) { + String word = tok.nextToken(); + + while (word.length() >= maxCharInLine) { + output.append(word.substring(0, maxCharInLine - lineLen) + "\n"); + word = word.substring(maxCharInLine - lineLen); + lineLen = 0; + } + + if (lineLen + word.length() >= maxCharInLine) { + output.append("\n"); + lineLen = 0; + } + output.append(word + " "); + + lineLen += word.length() + 1; + } + String[] strArray = output.toString().split("\n"); + + return Arrays.asList(strArray); + } + + /** + * Helps to print table. + * + * @param printSeparator + * Prints with line separator + * @return +--------------+-----------+-----------------------------+ | header1 | header 2 | header 3 | + * +--------------+-----------+-----------------------------+ | v1 | line 1 | v 3 | | | line 2 | | + * +--------------+-----------+-----------------------------+ | | yyyyyy 2 | xxxxxx 3 | + * +--------------+-----------+-----------------------------+ + */ + public String printTable(boolean printSeparator) { + List> rows = this.formRows(true); + TableGenerator table = new TableGenerator(); + return table.generateTable(rows, printSeparator); + } + + /** + * Print output in csv format. + * + * @return string + * @throws OnapCommandOutputPrintingFailed + * exception + */ + public String printCsv() throws OnapCommandOutputPrintingFailed { + StringWriter writer = new StringWriter(); + CSVPrinter printer = null; + try { + CSVFormat formattor = CSVFormat.DEFAULT.withRecordSeparator(System.getProperty("line.separator")); + printer = new CSVPrinter(writer, formattor); + + List> rows = this.formRows(false); + + for (int i = 0; i < this.findMaxRows(); i++) { + printer.printRecord(rows.get(i)); + } + + return writer.toString(); + } catch (IOException e) { + throw new OnapCommandOutputPrintingFailed(e); + } finally { + try { + if (printer != null) { + printer.close(); + } + writer.close(); + } catch (IOException e) { + throw new OnapCommandOutputPrintingFailed(e); // NOSONAR + } + } + } + + public String printJson() { + // (mrkanag) print in json + return null; + } + + public String printYaml() { + // (mrkanag) print in yaml + return null; + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/output/print/TableGenerator.java b/framework/src/main/java/org/onap/cli/fw/output/print/TableGenerator.java new file mode 100644 index 00000000..8be7952d --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/output/print/TableGenerator.java @@ -0,0 +1,313 @@ +/* + * 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.output.print; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Printing Command result in Table format. + * + */ +public class TableGenerator { + + private static final int PADDING_SIZE = 1; + private static final String NEW_LINE = "\n"; + private static final String TABLE_JOINT_SYMBOL = "+"; + private static final String TABLE_V_SPLIT_SYMBOL = "|"; + private static final String TABLE_H_SPLIT_SYMBOL = "-"; + + /** + * Generate list of rows into table format. + * + * @param rowsList + * list of rows + * @param printSeparator + * boolean + * @return stringBuilder in tabular format + */ + public String generateTable(List> rowsList, boolean printSeparator) { + StringBuilder stringBuilder = new StringBuilder(); + + if (rowsList.isEmpty()) { + return stringBuilder.toString(); + } + + Map columnMaxWidthMapping = getMaximumWidhtofColumns(rowsList); + Map rowMaxWidthMapping = getMaximumWidhtofRows(rowsList); + + if (printSeparator) { + createRowLine(stringBuilder, rowsList.get(0).size(), columnMaxWidthMapping); + stringBuilder.append(NEW_LINE); + } + + for (int rowIndex = 0; rowIndex < rowsList.size(); rowIndex++) { + + List row = rowsList.get(rowIndex); + int splitRowSize = rowMaxWidthMapping.get(rowIndex); + if (splitRowSize > 1) { + for (int cellIndex = 0; cellIndex < row.size(); cellIndex++) { + Object cell = row.get(cellIndex); + String finalCell; + if (cell != null) { + if (cell instanceof String) { + finalCell = (String) cell; + } else { + finalCell = ((List) cell).get(0); + } + fillCell(stringBuilder, finalCell, cellIndex, columnMaxWidthMapping, printSeparator); + } + } + + stringBuilder.append(NEW_LINE); + + for (int splitCellIndex = 1; splitCellIndex < splitRowSize; splitCellIndex++) { + for (int cellIndex = 0; cellIndex < row.size(); cellIndex++) { + Object cell = row.get(cellIndex); + String finalCell = ""; + if (cell != null && cell instanceof List) { + List list = (List) cell; + if (splitCellIndex < list.size()) { + finalCell = list.get(splitCellIndex); + } + } + fillCell(stringBuilder, finalCell, cellIndex, columnMaxWidthMapping, printSeparator); + } + + stringBuilder.append(NEW_LINE); + } + + } else { + for (int cellIndex = 0; cellIndex < row.size(); cellIndex++) { + fillCell(stringBuilder, (String) row.get(cellIndex), cellIndex, columnMaxWidthMapping, + printSeparator); + } + stringBuilder.append(NEW_LINE); + } + + if (printSeparator) { + createRowLine(stringBuilder, rowsList.get(0).size(), columnMaxWidthMapping); + stringBuilder.append(NEW_LINE); + } + + } + return stringBuilder.toString(); + } + + /** + * Fill required space. + * + * @param stringBuilder + * table + * @param length + * No. of spaces + */ + private void fillSpace(StringBuilder stringBuilder, int length) { + for (int i = 0; i < length; i++) { + stringBuilder.append(" "); + } + } + + /** + * Create a new row line. + * + * @param stringBuilder + * table + * @param headersListSize + * No. of colums + * @param columnMaxWidthMapping + * mapping of columns with cell width + */ + private void createRowLine(StringBuilder stringBuilder, int headersListSize, + Map columnMaxWidthMapping) { + for (int i = 0; i < headersListSize; i++) { + if (i == 0) { + stringBuilder.append(TABLE_JOINT_SYMBOL); + } + + for (int j = 0; j < columnMaxWidthMapping.get(i) + PADDING_SIZE * 2; j++) { + stringBuilder.append(TABLE_H_SPLIT_SYMBOL); + } + stringBuilder.append(TABLE_JOINT_SYMBOL); + } + } + + /** + * Get max width of columns. + * + * @param rowsList + * list of rows + * @return mapping of column and max cell width + */ + private Map getMaximumWidhtofColumns(List> rowsList) { + Map columnMaxWidthMapping = new HashMap<>(); + if (rowsList == null || rowsList.isEmpty()) { + return new HashMap<>(); + } + for (int columnIndex = 0; columnIndex < rowsList.get(0).size(); columnIndex++) { + columnMaxWidthMapping.put(columnIndex, 0); + } + + for (List row : rowsList) { + updateColWidth(row, columnMaxWidthMapping); + } + + for (int columnIndex = 0; columnIndex < rowsList.get(0).size(); columnIndex++) { + + if (columnMaxWidthMapping.get(columnIndex) % 2 != 0) { + columnMaxWidthMapping.put(columnIndex, columnMaxWidthMapping.get(columnIndex) + 1); + } + } + + return columnMaxWidthMapping; + } + + /** + * update the column width. + * + * @param row + * list of values + * @param columnMaxWidthMapping + * mapping of column and max cell width + */ + private void updateColWidth(List row, Map columnMaxWidthMapping) { + for (int columnIndex = 0; columnIndex < row.size(); columnIndex++) { + Object obj = row.get(columnIndex); + if (obj instanceof String) { + String str = (String) obj; + if (str.length() > columnMaxWidthMapping.get(columnIndex)) { + columnMaxWidthMapping.put(columnIndex, str.length()); + } + } else if (obj instanceof List) { + List list = (List) obj; + + int maxLength = list.get(0).length(); + + for (String str : list) { + if (str.length() > maxLength) { + maxLength = str.length(); + } + } + + if (maxLength > columnMaxWidthMapping.get(columnIndex)) { + columnMaxWidthMapping.put(columnIndex, maxLength); + } + + } + + } + } + + /** + * Get max width of rows. + * + * @param rowsList + * list of rows + * @return map of rows and max width + */ + private Map getMaximumWidhtofRows(List> rowsList) { + Map rowMaxWidthMapping = new HashMap<>(); + + for (int rowIndex = 0; rowIndex < rowsList.size(); rowIndex++) { + rowMaxWidthMapping.put(rowIndex, 1); + } + + for (int rowIndex = 0; rowIndex < rowsList.size(); rowIndex++) { + int maxSize = 1; + for (Object obj : rowsList.get(rowIndex)) { + if (obj instanceof List && ((List) obj).size() > maxSize) { + maxSize = ((List) obj).size(); + } + } + + if (maxSize > 1) { + rowMaxWidthMapping.put(rowIndex, maxSize); + } + } + return rowMaxWidthMapping; + } + + /** + * Get optimal cell padding. + * + * @param cellIndex + * cell index + * @param datalength + * data length + * @param columnMaxWidthMapping + * map of column and max cell width + * @param cellPaddingSize + * cell padding size + * @return cell padding + */ + private int getOptimumCellPadding(int cellIndex, int datalength, Map columnMaxWidthMapping, + int cellPaddingSize) { + int datLen = datalength; + int paddingSize = cellPaddingSize; + if (datLen % 2 != 0) { + datLen++; + } + + if (datLen < columnMaxWidthMapping.get(cellIndex)) { + paddingSize = paddingSize + (columnMaxWidthMapping.get(cellIndex) - datLen) / 2; + } + + return paddingSize; + } + + /** + * Fill the cell with required value. + * + * @param stringBuilder + * table + * @param cell + * table cell value + * @param cellIndex + * cell index + * @param columnMaxWidthMapping + * map of column and max cell width + */ + private void fillCell(StringBuilder stringBuilder, String cell, int cellIndex, + Map columnMaxWidthMapping, boolean printSeparator) { + + String filledCell = cell; + + if (filledCell == null) { + filledCell = ""; + } + int cellLength = filledCell.length(); + int cellPaddingSize = getOptimumCellPadding(cellIndex, cellLength, columnMaxWidthMapping, PADDING_SIZE); + + if (cellIndex == 0 && printSeparator) { + stringBuilder.append(TABLE_V_SPLIT_SYMBOL); + } + + stringBuilder.append(filledCell); + fillSpace(stringBuilder, cellPaddingSize); + + if (cellLength % 2 != 0) { + stringBuilder.append(" "); + } + + fillSpace(stringBuilder, cellPaddingSize); + if (printSeparator) { + stringBuilder.append(TABLE_V_SPLIT_SYMBOL); + } + + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/run/OnapCommandExecutor.java b/framework/src/main/java/org/onap/cli/fw/run/OnapCommandExecutor.java new file mode 100644 index 00000000..abd04b02 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/run/OnapCommandExecutor.java @@ -0,0 +1,71 @@ +/* + * 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.run; + +/** + * Onap Command executor. + * + */ +public class OnapCommandExecutor { + + private String apiName; + private String clientName; + private String entityName; + private String methodName; + private String exceptionName; + + public String getApi() { + return this.apiName; + } + + public void setApi(String api) { + this.apiName = api; + } + + public String getClient() { + return this.clientName; + } + + public void setClient(String client) { + this.clientName = client; + } + + public String getEntity() { + return entityName; + } + + public void setEntity(String entity) { + this.entityName = entity; + } + + public String getMethod() { + return methodName; + } + + public void setMethod(String method) { + this.methodName = method; + } + + public String getException() { + return exceptionName; + } + + public void setException(String exception) { + this.exceptionName = exception; + } + +} 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 new file mode 100644 index 00000000..28671521 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/schema/AbstractSchemaValidate.java @@ -0,0 +1,563 @@ +/* + * 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 schemaErrors = new ArrayList<>(); + protected Map yamlMap = new HashMap<>(); + protected Map defaultYamlMap = new HashMap<>(); + + protected static final List HTTP_SCHEMA_LIST = Arrays.asList(ONAP_CMD_SCHEMA_VERSION, NAME, DESCRIPTION, + SERVICE, PARAMETERS, RESULTS, HTTP); + + protected static final List HTTP_SCHEMA_MANDATORY_LIST = Arrays.asList(ONAP_CMD_SCHEMA_VERSION, NAME, + DESCRIPTION, SERVICE, HTTP); + protected static final List BASIC_SCHEMA_LIST = Arrays.asList(ONAP_CMD_SCHEMA_VERSION, NAME, DESCRIPTION, + PARAMETERS, RESULTS); + + protected static final List BASIC_SCHEMA_MANDATORY_LIST = Arrays.asList(ONAP_CMD_SCHEMA_VERSION, NAME, + DESCRIPTION, PARAMETERS); + + protected static final List TOP_LEVEL_PARAMS_LIST = Arrays.asList(ONAP_CMD_SCHEMA_VERSION, NAME, + DESCRIPTION); + + protected static final List TOP_LEVEL_MANDATORY_LIST = Arrays.asList(ONAP_CMD_SCHEMA_VERSION, NAME, + DESCRIPTION); + + protected static final List SERVICE_PARAMS_LIST = Arrays.asList(NAME, VERSION, NO_AUTH); + + protected static final List SERVICE_PARAMS_MANDATORY_LIST = Arrays.asList(NAME, VERSION); + + protected static final List INPUT_PARAMS_LIST = Arrays.asList(NAME, DESCRIPTION, TYPE, SHORT_OPTION, + LONG_OPTION, IS_OPTIONAL, DEFAULT_VALUE, IS_SECURED); + + protected static final List INPUT_PARAMS_MANDATORY_LIST = Arrays.asList(NAME, DESCRIPTION, TYPE); + + protected static final List 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 RESULT_PARAMS_LIST = Arrays.asList(NAME, DESCRIPTION, TYPE, SHORT_OPTION, + LONG_OPTION, IS_OPTIONAL, DEFAULT_VALUE, IS_SECURED); + + protected static final List RESULT_PARAMS_MANDATORY_LIST = Arrays.asList(NAME, DESCRIPTION, TYPE); + + protected static final List HTTP_PARAMS_LIST = Arrays.asList(URI, METHOD, BODY, HEADERS, QUERIES); + + protected static final List HTTP_PARAMS_MANDATORY_LIST = Arrays.asList(URI, METHOD, BODY, HEADERS, QUERIES); + + protected static final List HTTP_MANDATORY_SECTIONS = Arrays.asList(REQUEST, SUCCESS_CODES); + + protected static final List HTTP_SECTIONS = Arrays.asList(REQUEST, SUCCESS_CODES, RESULT_MAP, + SAMPLE_RESPONSE); + + protected static final List HTTP_REQUEST_MANDATORY_PARAMS = Arrays.asList(URI, METHOD); + + protected static final List HTTP_REQUEST_PARAMS = Arrays.asList(URI, METHOD, BODY, HEADERS, QUERIES); + + protected static final List BOOLEAN_VALUES = Arrays.asList(BOOLEAN_TRUE, BOOLEAN_FALSE); + protected static final List DIRECTIONS = Arrays.asList(DIRECTION_PORTRAIT, DIRECTION_LANDSCAPE); + protected static final List RESULT_SCOPES = Arrays.asList(RESULT_SCOPE_SHORT, RESULT_SCOPE_LONG); + + protected static final List 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) 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) 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 validate() throws OnapCommandInvalidSchema { + + SchemaType type; + Set 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> resultAttributes) { + Set resultParamNames = new HashSet<>(); + for (Map 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 resultParams = (Map) 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> resultAttributes = (List>) resultParams.get(ATTRIBUTES); + validateResultAttributes(resultAttributes); + } + + /** + * Get all default short options. + * + * @return set + */ + protected Set getDefaultShortOptions() { + + Set set = new HashSet<>(); + + @SuppressWarnings("unchecked") + List> inputParams = (List>) defaultYamlMap.get(PARAMETERS); + for (Map 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 getDefaultLongOptions() { + + Set set = new HashSet<>(); + + @SuppressWarnings("unchecked") + List> inputParams = (List>) defaultYamlMap.get(PARAMETERS); + for (Map 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 serviceMap = (Map) 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(NO_AUTH)) { + Object obj = serviceMap.get(NO_AUTH); + if (obj == null) { + schemaErrors.add(SchemaValidate.emptyValue(SERVICE, NO_AUTH)); + } else { + String value = String.valueOf(obj); + if (!validateBoolean(value)) { + schemaErrors.add(SchemaValidate.invalidBooleanValueMessage(SERVICE, NO_AUTH, value)); + } + } + } + + } + + private void validateInputParameters() { + + @SuppressWarnings("unchecked") + List> inputParams = (List>) yamlMap.get(PARAMETERS); + if (inputParams == null) { + return; + } + validateInputAttributes(inputParams); + } + + protected abstract void validateSpecificSchema(SchemaType type) throws OnapCommandInvalidSchema; + + private void validateInputAttributes(List> inputParams) { + Set inputParamNames = new HashSet<>(); + Set inputShortOptions = new HashSet<>(); + Set inputLongOptions = new HashSet<>(); + + Set defaultShortOptions = getDefaultShortOptions(); + Set defaultLongOptions = getDefaultLongOptions(); + + for (Map 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 yamlMap, List totalParams, + List 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 getResultAttributes() { + + Set set = new HashSet<>(); + + List> resultAttributes = yamlMap.get(RESULTS) != null + ? (List>) ((Map) yamlMap.get(RESULTS)).get(ATTRIBUTES) + : Collections.emptyList(); + + if (resultAttributes != null) { + for (Map map : resultAttributes) { + for (Entry 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 getRequestParams() { + + Set set = new HashSet<>(); + + @SuppressWarnings("unchecked") + List> inputParams = (List>) yamlMap.get(PARAMETERS); + + if (inputParams != null) { + for (Map map : inputParams) { + for (Entry 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 new file mode 100644 index 00000000..27bc4661 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/schema/SchemaValidate.java @@ -0,0 +1,324 @@ +/* + * 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 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 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 mainSections, List http, List 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 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 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 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 new file mode 100644 index 00000000..bb1248b9 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/schema/SchemaValidator.java @@ -0,0 +1,292 @@ +/* + * 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 httpMap = (Map) yamlMap.get(HTTP); + + if (httpMap == null || httpMap.isEmpty()) { + schemaErrors.add(HTTP_SECTION_EMPTY); + return; + } + + validateMandatoryParams(httpMap, HTTP_SECTIONS, HTTP_MANDATORY_SECTIONS, PARAMETERS); + + Map requestMap = (Map) httpMap.get(REQUEST); + + if (requestMap != null && !requestMap.isEmpty()) { + validateHttpRequestParams(requestMap); + } else { + schemaErrors.add(SchemaValidate.emptySection(REQUEST)); + } + + List requestSuccessCodes = (List) httpMap.get(SUCCESS_CODES); + if (requestSuccessCodes != null && !requestSuccessCodes.isEmpty()) { + validateHttpSccessCodes(requestSuccessCodes); + } else { + schemaErrors.add(SchemaValidate.emptySection(SUCCESS_CODES)); + } + + Map resultMap = (Map) 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) object); + } + } + } + + private void validateHttpRequestParams(Map 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 requestParams = getRequestParams(); + + // validate uriParams + Set uriParams = validateHttpUri(requestMap); + + // validate body + Set bodyParams = validateHttpBody(requestMap); + + // validate header + Set headerParams = validateHttpHeaders(requestMap); + + // validate queries + Set 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 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 validateHttpUri(Map requestMap) { + Set 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 validateHttpHeaders(Map requestMap) { + + Map headers = (Map) requestMap.get(HEADERS); + Set headerParamNames = new HashSet<>(); + if (headers != null) { + for (Entry entry : headers.entrySet()) { + parseParameters(String.valueOf(entry.getValue()), headerParamNames); + } + } + return headerParamNames; + } + + @SuppressWarnings("unchecked") + private Set validateHttpQueries(Map requestMap) { + Map queries = (Map) requestMap.get(QUERIES); + Set queryParamNames = new HashSet<>(); + if (queries != null) { + for (Entry entry : queries.entrySet()) { + parseParameters(String.valueOf(entry.getValue()), queryParamNames); + } + } + return queryParamNames; + } + + private Set validateHttpBody(Map requestMap) { + Set 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 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 requestSuccessCodes) { + + for (Object successCode : requestSuccessCodes) { + Integer code = (Integer) successCode; + if (code < 200 || code >= 300) { + schemaErrors.add(HTTP_SUCCESS_CODE_INVALID); + } + } + + } + + private void validateHttpResultMapping(Map resultMap) { + Set 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 entry : resultMap.entrySet()) { + if (!resultAttributes.contains(entry.getKey())) { + schemaErrors.add(SchemaValidate.missingInResultAttribute(entry.getKey())); + } + } + } + + private void validateSampleResponse(Map 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/ExternalSchema.java b/framework/src/main/java/org/onap/cli/fw/utils/ExternalSchema.java new file mode 100644 index 00000000..e9f19673 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/utils/ExternalSchema.java @@ -0,0 +1,49 @@ +/* + * 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.utils; + +public class ExternalSchema { + + private String schemaName; + private String cmdName; + private String version; + + public String getSchemaName() { + return schemaName; + } + + public void setSchemaName(String schemaName) { + this.schemaName = schemaName; + } + + public String getCmdName() { + return cmdName; + } + + public void setCmdName(String cmdName) { + this.cmdName = cmdName; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + +} 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 new file mode 100644 index 00000000..79b9596c --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/utils/OnapCommandUtils.java @@ -0,0 +1,1087 @@ +/* + * 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.utils; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.jayway.jsonpath.JsonPath; +import net.minidev.json.JSONArray; + +import org.onap.cli.fw.OnapCommand; +import org.onap.cli.fw.ad.OnapCredentials; +import org.onap.cli.fw.ad.OnapService; +import org.onap.cli.fw.cmd.OnapHttpCommand; +import org.onap.cli.fw.cmd.OnapSwaggerCommand; +import org.onap.cli.fw.conf.Constants; +import org.onap.cli.fw.error.OnapCommandDiscoveryFailed; +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.OnapCommandInvalidParameterType; +import org.onap.cli.fw.error.OnapCommandInvalidParameterValue; +import org.onap.cli.fw.error.OnapCommandInvalidPrintDirection; +import org.onap.cli.fw.error.OnapCommandInvalidResultAttributeScope; +import org.onap.cli.fw.error.OnapCommandInvalidSchema; +import org.onap.cli.fw.error.OnapCommandInvalidSchemaVersion; +import org.onap.cli.fw.error.OnapCommandParameterNameConflict; +import org.onap.cli.fw.error.OnapCommandParameterNotFound; +import org.onap.cli.fw.error.OnapCommandParameterOptionConflict; +import org.onap.cli.fw.error.OnapCommandResultEmpty; +import org.onap.cli.fw.error.OnapCommandResultMapProcessingFailed; +import org.onap.cli.fw.error.OnapCommandSchemaNotFound; +import org.onap.cli.fw.http.HttpInput; +import org.onap.cli.fw.http.HttpResult; +import org.onap.cli.fw.input.OnapCommandParameter; +import org.onap.cli.fw.input.ParameterType; +import org.onap.cli.fw.output.OnapCommandResult; +import org.onap.cli.fw.output.OnapCommandResultAttribute; +import org.onap.cli.fw.output.OnapCommandResultAttributeScope; +import org.onap.cli.fw.output.PrintDirection; +import org.onap.cli.fw.output.ResultType; +import org.onap.cli.fw.run.OnapCommandExecutor; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.yaml.snakeyaml.Yaml; + +import java.io.File; +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.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.ServiceLoader; +import java.util.Set; + +/** + * Provides helper method to parse Yaml files and produce required objects. + * + */ +public class OnapCommandUtils { + + /** + * Private constructor. + */ + private OnapCommandUtils() { + + } + + /** + * Validates schema version. + * + * @param schemaName + * schema name + * @param version + * schema version + * @return map + * @throws OnapCommandInvalidSchemaVersion + * invalid schema version exception + * @throws OnapCommandInvalidSchema + * invalid schema + * @throws OnapCommandSchemaNotFound + * schema not found + */ + public static Map validateSchemaVersion(String schemaName, String version) throws OnapCommandException { + InputStream inputStream = OnapCommandUtils.class.getClassLoader().getResourceAsStream(schemaName); + + try { + Resource resource = getExternalResource(schemaName, Constants.EXTERNAL_SCHEMA_PATH_PATERN); + + if (resource != null) { + inputStream = resource.getInputStream(); + } + + } catch (IOException e) { + throw new OnapCommandSchemaNotFound(schemaName, e); + } + if (inputStream == null) { + throw new OnapCommandSchemaNotFound(schemaName); + } + + Map values = null; + try { + values = (Map) new Yaml().load(inputStream); + } catch (Exception e) { + 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); + schemaVersion = obj.toString(); + } + + if (!version.equals(schemaVersion)) { + throw new OnapCommandInvalidSchemaVersion(schemaVersion); + } + + return values; + } + + /** + * Retrieve OnapCommand from schema. + * + * @param cmd + * OnapCommand + * @param schemaName + * schema name + * @param includeDefault + * include if default + * @throws OnapCommandParameterNameConflict + * param name conflict exception + * @throws OnapCommandParameterOptionConflict + * param option conflict exception + * @throws OnapCommandInvalidParameterType + * invalid param type exception + * @throws OnapCommandInvalidPrintDirection + * invalid print direction exception + * @throws OnapCommandInvalidResultAttributeScope + * invalid scope exception + * @throws OnapCommandSchemaNotFound + * schema not found + * @throws OnapCommandInvalidSchema + * invalid schema + * @throws OnapCommandInvalidSchemaVersion + * invalid schema version + */ + public static void loadSchema(OnapCommand cmd, String schemaName, boolean includeDefault) + throws OnapCommandException { + List shortOptions = new ArrayList<>(); + List longOptions = new ArrayList<>(); + List names = new ArrayList<>(); + + if (includeDefault) { + loadSchema(cmd, Constants.DEFAULT_PARAMETER_FILE_NAME, shortOptions, longOptions, names); + } + + loadSchema(cmd, schemaName, shortOptions, longOptions, names); + + } + + private static void loadSchema(OnapCommand cmd, String schemaName, List shortOptions, + List longOptions, List names) throws OnapCommandException { + try { + Map values = validateSchemaVersion(schemaName, cmd.getSchemaVersion()); + + for (Map.Entry entry : values.entrySet()) { + String key = entry.getKey(); + + if (Constants.NAME.equals(key)) { + Object val = values.get(key); + cmd.setName(val.toString()); + } else if (Constants.DESCRIPTION.equals(key)) { + Object val = values.get(key); + cmd.setDescription(val.toString()); + } else if (Constants.SERVICE.equals(key)) { + Map map = (Map) values.get(key); + OnapService srv = new OnapService(); + + for (Map.Entry entry1 : map.entrySet()) { + String key1 = entry1.getKey(); + + if (Constants.NAME.equals(key1)) { + srv.setName(map.get(key1)); + } else if (Constants.VERSION.equals(key1)) { + srv.setVersion(map.get(key1)); + } else if (Constants.NO_AUTH.equals(key1)) { + Object obj = map.get(key1); + srv.setNoAuth("true".equalsIgnoreCase(obj.toString())); + } + } + + cmd.setService(srv); + } else if (Constants.PARAMETERS.equals(key)) { + List> list = (ArrayList) values.get(key); + + for (Map map : list) { + OnapCommandParameter param = new OnapCommandParameter(); + + for (Map.Entry entry1 : map.entrySet()) { + String key2 = entry1.getKey(); + + if (Constants.NAME.equals(key2)) { + if (names.contains(map.get(key2))) { + throw new OnapCommandParameterNameConflict(map.get(key2)); + } + names.add(map.get(key2)); + param.setName(map.get(key2)); + } else if (Constants.DESCRIPTION.equals(key2)) { + param.setDescription(map.get(key2)); + } else if (Constants.SHORT_OPTION.equals(key2)) { + if (shortOptions.contains(map.get(key2))) { + throw new OnapCommandParameterOptionConflict(map.get(key2)); + } + shortOptions.add(map.get(key2)); + param.setShortOption(map.get(key2)); + } else if (Constants.LONG_OPTION.equals(key2)) { + if (longOptions.contains(map.get(key2))) { + throw new OnapCommandParameterOptionConflict(map.get(key2)); + } + longOptions.add(map.get(key2)); + param.setLongOption(map.get(key2)); + } else if (Constants.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)) { + if ("true".equalsIgnoreCase(String.valueOf(map.get(key2)))) { + param.setOptional(true); + } else { + param.setOptional(false); + } + } else if (Constants.IS_SECURED.equals(key2)) { + if ("true".equalsIgnoreCase(String.valueOf(map.get(key2)))) { + param.setSecured(true); + } else { + param.setSecured(false); + } + } + } + cmd.getParameters().add(param); + + } + } else if (Constants.RESULTS.equals(key)) { + Map valueMap = (Map) values.get(key); + OnapCommandResult result = new OnapCommandResult(); + for (Map.Entry 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)) { + List> attrs = (ArrayList) valueMap.get(key3); + + for (Map map : attrs) { + OnapCommandResultAttribute attr = new OnapCommandResultAttribute(); + for (Map.Entry entry4 : map.entrySet()) { + String key4 = entry4.getKey(); + + if (Constants.NAME.equals(key4)) { + attr.setName(map.get(key4)); + } else if (Constants.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)) { + if ("true".equals(String.valueOf(map.get(key4)))) { + attr.setSecured(true); + } else { + attr.setSecured(false); + } + } + + } + result.getRecords().add(attr); + } + } + } + cmd.setResult(result); + } + } + } catch (OnapCommandException e) { + throw e; + } catch (Exception e) { + throw new OnapCommandInvalidSchema(schemaName, e); + } + } + + /** + * Load the schema. + * + * @param cmd + * OnapSwaggerBasedCommand + * @param schemaName + * schema name + * @throws OnapCommandParameterNameConflict + * param name conflict exception + * @throws OnapCommandParameterOptionConflict + * param option conflict exception + * @throws OnapCommandInvalidParameterType + * invalid param type exception + * @throws OnapCommandInvalidPrintDirection + * invalid print direction exception + * @throws OnapCommandInvalidResultAttributeScope + * invalid scope exception + * @throws OnapCommandSchemaNotFound + * schema not found + * @throws OnapCommandInvalidSchema + * invalid schema + * @throws OnapCommandInvalidSchemaVersion + * invalid schema version + */ + public static void loadSchema(OnapSwaggerCommand cmd, String schemaName) throws OnapCommandException { + try { + Map values = (Map) validateSchemaVersion(schemaName, cmd.getSchemaVersion()); + Map valueMap = (Map) values.get(Constants.EXECUTOR); + OnapCommandExecutor exec = new OnapCommandExecutor(); + + for (Map.Entry entry1 : valueMap.entrySet()) { + String key1 = entry1.getKey(); + + if (Constants.API.equals(key1)) { + exec.setApi(valueMap.get(key1)); + } else if (Constants.CLIENT.equals(key1)) { + exec.setClient(valueMap.get(key1)); + } else if (Constants.ENTITY.equals(key1)) { + exec.setEntity(valueMap.get(key1)); + } else if (Constants.EXCEPTION.equals(key1)) { + exec.setException(valueMap.get(key1)); + } else if (Constants.METHOD.equals(key1)) { + exec.setMethod(valueMap.get(key1)); + } + } + + cmd.setExecutor(exec); + } catch (OnapCommandException e) { + throw e; + } catch (Exception e) { + throw new OnapCommandInvalidSchema(schemaName, e); + } + } + + /** + * Load the schema. + * + * @param cmd + * OnapHttpCommand + * @param schemaName + * schema name + * @throws OnapCommandParameterNameConflict + * param name conflict exception + * @throws OnapCommandParameterOptionConflict + * param option conflict exception + * @throws OnapCommandInvalidParameterType + * invalid param type exception + * @throws OnapCommandInvalidPrintDirection + * invalid print direction exception + * @throws OnapCommandInvalidResultAttributeScope + * invalid scope exception + * @throws OnapCommandSchemaNotFound + * schema not found + * @throws OnapCommandInvalidSchema + * invalid schema + * @throws OnapCommandInvalidSchemaVersion + * invalid schema version + */ + public static void loadSchema(OnapHttpCommand cmd, String schemaName) throws OnapCommandException { + try { + Map values = (Map) validateSchemaVersion(schemaName, cmd.getSchemaVersion()); + Map valMap = (Map) values.get(Constants.HTTP); + + for (Map.Entry entry1 : valMap.entrySet()) { + String key1 = entry1.getKey(); + if (Constants.REQUEST.equals(key1)) { + Map map = (Map) valMap.get(key1); + + for (Map.Entry 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 head = (Map) map.get(key2); + cmd.getInput().setReqHeaders(head); + } else if (Constants.QUERIES.equals(key2)) { + Map query = (Map) map.get(key2); + + cmd.getInput().setReqQueries(query); + } + } + } else if (Constants.SUCCESS_CODES.equals(key1)) { + cmd.setSuccessStatusCodes((ArrayList) valMap.get(key1)); + } else if (Constants.RESULT_MAP.equals(key1)) { + cmd.setResultMap((Map) valMap.get(key1)); + } else if (Constants.SAMPLE_RESPONSE.equals(key1)) { + // (mrkanag) implement sample response handling + } + } + + } catch (OnapCommandException e) { + throw e; + } catch (Exception e) { + throw new OnapCommandInvalidSchema(schemaName, e); + } + } + + /** + * Returns Help. + * + * @param cmd + * OnapCommand + * @return help string + * @throws OnapCommandHelpFailed + * help failed exception + */ + public static String help(OnapCommand cmd) throws OnapCommandHelpFailed { + String help = "usage: onap " + cmd.getName(); + + // Add description + help += "\n\n" + cmd.getDescription(); + + // Add service + help += "\n\nOnap service: " + cmd.getService(); + + // Add whole command + String commandOptions = ""; + + // Add parameters + OnapCommandResult paramTable = new OnapCommandResult(); + paramTable.setPrintDirection(PrintDirection.LANDSCAPE); + paramTable.setType(ResultType.TABLE); + paramTable.setIncludeTitle(false); + paramTable.setIncludeSeparator(false); + + OnapCommandResultAttribute attrName = new OnapCommandResultAttribute(); + attrName.setName(Constants.NAME); + attrName.setDescription(Constants.NAME); + attrName.setScope(OnapCommandResultAttributeScope.SHORT); + paramTable.getRecords().add(attrName); + + OnapCommandResultAttribute attrDescription = new OnapCommandResultAttribute(); + attrDescription.setName(Constants.DESCRIPTION); + attrDescription.setDescription(Constants.DESCRIPTION); + attrDescription.setScope(OnapCommandResultAttributeScope.SHORT); + paramTable.getRecords().add(attrDescription); + + int newLineOptions = 0; + for (OnapCommandParameter param : cmd.getParameters()) { + // First column Option or positional args + String optFirstCol; + if (newLineOptions == 3) { + newLineOptions = 0; + commandOptions += "\n"; + } + + if (param.getShortOption() != null || param.getLongOption() != null) { + optFirstCol = OnapCommandParameter.printShortOption(param.getShortOption()) + " | " + + OnapCommandParameter.printLongOption(param.getLongOption()); + commandOptions += "[" + optFirstCol + "] "; + } else { + optFirstCol = param.getName(); + commandOptions += "<" + optFirstCol + "> "; + } + + newLineOptions++; + + attrName.getValues().add(optFirstCol); + + // Second column description + String optSecondCol = param.getDescription().trim(); + if (!optSecondCol.endsWith(".")) { + optSecondCol += "."; + } + optSecondCol += " It is of type " + param.getParameterType().name() + "."; + + if (param.getParameterType().equals(ParameterType.JSON) + || param.getParameterType().equals(ParameterType.YAML)) { + optSecondCol += " It's recommended to input the complete path of the file, which is having the value for it."; + } + if (param.isOptional()) { + optSecondCol += " It is optional."; + } + + String defaultMsg = " By default, it is "; + if (param.isDefaultValueAnEnv()) { + optSecondCol += defaultMsg + "read from environment variable " + param.getEnvVarNameFromDefaultValue() + + "."; + } else if (param.getDefaultValue() != null && !param.getDefaultValue().isEmpty()) { + optSecondCol += defaultMsg + param.getDefaultValue() + "."; + } + + if (param.isSecured()) { + optSecondCol += " Secured."; + } + // (mrkanag) Add help msg for reading default value from env + attrDescription.getValues().add(optSecondCol); + } + + try { + help += "\n\nOptions:\n" + commandOptions + "\nwhere,\n" + paramTable.print(); + } catch (OnapCommandException e) { + throw new OnapCommandHelpFailed(e); + } + + // Add results + OnapCommandResult resultTable = new OnapCommandResult(); + resultTable.setPrintDirection(PrintDirection.PORTRAIT); + resultTable.setType(ResultType.TABLE); + resultTable.setIncludeTitle(false); + resultTable.setIncludeSeparator(false); + + for (OnapCommandResultAttribute attr : cmd.getResult().getRecords()) { + OnapCommandResultAttribute attrHelp = new OnapCommandResultAttribute(); + attrHelp.setName(attr.getName()); + attrHelp.setDescription(attr.getDescription()); + String msg = attr.getDescription() + " and is of type " + attr.getType().name() + "."; + if (attr.isSecured()) { + msg += " It is secured."; + } + attrHelp.getValues().add(msg); + attrHelp.setType(attr.getType()); + resultTable.getRecords().add(attrHelp); + } + try { + help += "\n\nResults:\n" + resultTable.print(); + } catch (OnapCommandException e) { + throw new OnapCommandHelpFailed(e); + } + + // Error + help += "\n\nError:\nOn error, it prints ::::\n"; + return help; + } + + /** + * Helps to create OnapCredentials from default params. + * + * @param params + * list of parameters + * @return OnapCredentials + * @throws OnapCommandInvalidParameterValue + * exception + */ + public static OnapCredentials fromParameters(List params) + throws OnapCommandInvalidParameterValue { + Map paramMap = new HashMap<>(); + + 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_MSB_URL)); + } + + /** + * Create Dict from list of Parameters. + * + * @param inputs + * list of parameters + * @return map + */ + public static Map getInputMap(List inputs) { + Map map = new HashMap<>(); + for (OnapCommandParameter param : inputs) { + map.put(param.getName(), param); + } + return map; + } + + /** + * Discover the Onap commands. + * + * @return list + */ + public static List> findOnapCommands() { + ServiceLoader loader = ServiceLoader.load(OnapCommand.class); + List> clss = new ArrayList<>(); + for (OnapCommand implClass : loader) { + clss.add((Class) implClass.getClass()); + } + + return clss; + } + + /** + * sort the set. + * + * @param col + * set + * @return list + */ + public static List sort(Set col) { + List results = new ArrayList<>(); + results.addAll(col); + Collections.sort(results); + return results; + } + + /** + * Flatten the json list. + * + * @param jsons + * list json strings + * @return list + */ + public static List jsonFlatten(List jsons) { + List results = new ArrayList<>(); + for (String json : jsons) { + try { + results.add(JsonPath.parse(json).jsonString()); + } catch (Exception e) { // NOSONAR + results.add(json); + } + } + + return results; + } + + /** + * Construct method name. + * + * @param name + * name + * @param prefix + * prefix + * @return string + */ + public static String formMethodNameFromAttributeName(String name, String prefix) { + if (name == null || name.isEmpty()) { + return name; + } + + String methodName = prefix; + for (String tk : name.split("-")) { + methodName += Character.toString(tk.charAt(0)).toUpperCase(); + methodName += tk.substring(1); + } + return methodName; + } + + private static String replaceLineFromInputParameters(String line, Map params) + throws OnapCommandException { + String result = ""; + + if (!line.contains("${")) { + return line; + } + + int currentIdx = 0; + while (currentIdx < line.length()) { + int idxS = line.indexOf("${", currentIdx); + if (idxS == -1) { + result += line.substring(currentIdx); + break; + } + int idxE = line.indexOf("}", idxS); + String paramName = line.substring(idxS + 2, idxE); + paramName = paramName.trim(); + if (!params.containsKey(paramName)) { + throw new OnapCommandParameterNotFound(paramName); + } + + String value = params.get(paramName).getValue().toString(); + + OnapCommandParameter param = params.get(paramName); + if (ParameterType.ARRAY.equals(param.getParameterType()) + || ParameterType.MAP.equals(param.getParameterType()) + || ParameterType.JSON.equals(param.getParameterType()) + || ParameterType.YAML.equals(param.getParameterType())) { + // ignore the front and back double quotes in json body + result += line.substring(currentIdx, idxS - 1) + value; + currentIdx = idxE + 2; + } else { + result += line.substring(currentIdx, idxS) + value; + currentIdx = idxE + 1; + } + } + + return result; + } + + private static ArrayList replaceLineFromOutputResults(String line, HttpResult resultHttp) + throws OnapCommandHttpHeaderNotFound, OnapCommandHttpInvalidResponseBody, + OnapCommandResultMapProcessingFailed, OnapCommandResultEmpty { + String headerProcessedLine = ""; + + ArrayList result = new ArrayList<>(); + if (!line.contains("$b{") && !line.contains("$h{")) { + result.add(line); + return result; + } + + /** + * In case of empty response body [] or {} + **/ + if (resultHttp.getBody().length() <= 2) { + return result; + } + + /** + * Process headers macros : line: $h{abc}-$b{$.[*].xyz} , After processing line will be [abc's + * value]-$b{$.[*].xyz} + **/ + int currentIdx = 0; + while (currentIdx < line.length()) { + int idxS = line.indexOf("$h{", currentIdx); + if (idxS == -1) { + headerProcessedLine += line.substring(currentIdx); + break; + } + int idxE = line.indexOf("}", idxS); + String headerName = line.substring(idxS + 3, idxE); + headerName = headerName.trim(); + if (!resultHttp.getRespHeaders().containsKey(headerName)) { + throw new OnapCommandHttpHeaderNotFound(headerName); + } + String value = resultHttp.getRespHeaders().get(headerName); + + headerProcessedLine += line.substring(currentIdx, idxS) + value; + currentIdx = idxE + 1; + } + + // Process body jsonpath macros + List values = new ArrayList<>(); + String bodyProcessedPattern = ""; + currentIdx = 0; + int maxRows = 1; // in normal case, only one row will be there + while (currentIdx < headerProcessedLine.length()) { + int idxS = headerProcessedLine.indexOf("$b{", currentIdx); + if (idxS == -1) { + bodyProcessedPattern += headerProcessedLine.substring(currentIdx); + break; + } + int idxE = headerProcessedLine.indexOf("}", idxS); + String jsonPath = headerProcessedLine.substring(idxS + 3, idxE); + jsonPath = jsonPath.trim(); + try { + // JSONArray or String + Object value = JsonPath.read(resultHttp.getBody(), jsonPath); + if (value instanceof JSONArray) { + JSONArray arr = (JSONArray) value; + if (arr.size() > maxRows) { + maxRows = arr.size(); + } + } + bodyProcessedPattern += headerProcessedLine.substring(currentIdx, idxS) + "%s"; + values.add(value); + currentIdx = idxE + 1; + } catch (Exception e) { + throw new OnapCommandHttpInvalidResponseBody(jsonPath, e); + } + } + + if (bodyProcessedPattern.isEmpty()) { + result.add(headerProcessedLine); + return result; + } else { + for (int i = 0; i < maxRows; i++) { + currentIdx = 0; + String bodyProcessedLine = ""; + int positionalIdx = 0; // %s positional idx + while (currentIdx < bodyProcessedPattern.length()) { + int idxS = bodyProcessedPattern.indexOf("%s", currentIdx); + if (idxS == -1) { + bodyProcessedLine += bodyProcessedPattern.substring(currentIdx); + break; + } + int idxE = idxS + 2; // %s + try { + Object value = values.get(positionalIdx); + String valueS = String.valueOf(value); + if (value instanceof JSONArray) { + JSONArray arr = (JSONArray) value; + if (!arr.isEmpty()) { + valueS = arr.get(i).toString(); + } else { + throw new OnapCommandResultEmpty(); + } + } + + bodyProcessedLine += bodyProcessedPattern.substring(currentIdx, idxS) + valueS; + currentIdx = idxE; + positionalIdx++; + } catch (OnapCommandResultEmpty e) { + throw e; + } catch (Exception e) { + throw new OnapCommandResultMapProcessingFailed(line, e); + } + } + result.add(bodyProcessedLine); + } + + return result; + } + } + + /** + * Set argument to param value. + * + * @param params + * map + * @param input + * HttpInput + * @return HttpInput + * @throws OnapCommandParameterNotFound + * exception + * @throws OnapCommandInvalidParameterValue + * exception + */ + public static HttpInput populateParameters(Map params, HttpInput input) + throws OnapCommandException { + HttpInput inp = new HttpInput(); + for (OnapCommandParameter param : params.values()) { + if (ParameterType.BINARY.equals(param.getParameterType())) { + inp.setBinaryData(true); + break; + } + } + inp.setBody(replaceLineFromInputParameters(input.getBody(), params)); + inp.setUri(replaceLineFromInputParameters(input.getUri(), params)); + inp.setMethod(input.getMethod().toLowerCase()); + for (String h : input.getReqHeaders().keySet()) { + String value = input.getReqHeaders().get(h); + inp.getReqHeaders().put(h, replaceLineFromInputParameters(value, params)); + } + + for (String h : input.getReqQueries().keySet()) { + String value = input.getReqQueries().get(h); + inp.getReqQueries().put(h, replaceLineFromInputParameters(value, params)); + } + + return inp; + } + + /** + * Populate result. + * + * @param resultMap + * map + * @param resultHttp + * HttpResult + * @return map + * @throws OnapCommandHttpHeaderNotFound + * header not found exception + * @throws OnapCommandHttpInvalidResponseBody + * invalid response body exception + * @throws OnapCommandResultMapProcessingFailed + * map processing failed exception + */ + public static Map> populateOutputs(Map resultMap, HttpResult resultHttp) + throws OnapCommandException { + Map> resultsProcessed = new HashMap<>(); + + for (Entry entry : resultMap.entrySet()) { + String key = entry.getKey(); + resultsProcessed.put(key, replaceLineFromOutputResults(resultMap.get(key), resultHttp)); + } + + return resultsProcessed; + } + + /** + * Find external schema files. + * + * @return list ExternalSchema + * @throws OnapCommandDiscoveryFailed + * exception + * @throws OnapCommandInvalidSchema + * exception + */ + public static List findAllExternalSchemas() throws OnapCommandException { + List extSchemas = new ArrayList<>(); + try { + Resource[] res = getExternalResources(Constants.EXTERNAL_SCHEMA_PATH_PATERN); + if (res != null && res.length > 0) { + Map resourceMap; + for (Resource resource : res) { + resourceMap = getExternalSchemaMap(resource); + 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.setVersion(obj.toString()); + extSchemas.add(schema); + } + } + } + } catch (IOException e) { + throw new OnapCommandDiscoveryFailed(Constants.EXTERNAL_SCHEMA_DIRECTORY, e); + } + + return extSchemas; + } + + /** + * Returns all resources available under certain directory in class-path. + * + * @param pattern + * search pattern + * @return resources found resources + * @throws IOException + * exception + */ + public static Resource[] getExternalResources(String pattern) throws IOException { + ClassLoader cl = OnapCommandUtils.class.getClassLoader(); + ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(cl); + return resolver.getResources("classpath*:" + pattern); + } + + /** + * Returns a resource available under certain directory in class-path. + * + * @param pattern + * search pattern + * @return found resource + * @throws IOException + * exception + */ + public static Resource getExternalResource(String fileName, String pattern) throws IOException { + Resource[] resources = getExternalResources(pattern); + if (resources != null && resources.length > 0) { + for (Resource res : resources) { + if (res.getFilename().equals(fileName)) { + return res; + } + } + } + + return null; + } + + /** + * Get schema map. + * + * @param resource + * resource obj + * @return map + * @throws OnapCommandInvalidSchema + * exception + */ + public static Map getExternalSchemaMap(Resource resource) throws OnapCommandInvalidSchema { + Map values = null; + try { + values = (Map) new Yaml().load(resource.getInputStream()); + } catch (Exception e) { + throw new OnapCommandInvalidSchema(resource.getFilename(), e); + } + return values; + } + + /** + * Persist the external schema details. + * + * @param schemas + * list + * @throws OnapCommandDiscoveryFailed + * exception + */ + public static void persist(List schemas) throws OnapCommandDiscoveryFailed { + if (schemas != null) { + try { + Resource[] resources = getExternalResources(Constants.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); + ObjectMapper mapper = new ObjectMapper(); + mapper.writerWithDefaultPrettyPrinter().writeValue(file, schemas); + } + } catch (IOException e1) { + throw new OnapCommandDiscoveryFailed(Constants.EXTERNAL_DISCOVERY_DIRECTORY, + Constants.EXTERNAL_DISCOVERY_FILE, e1); + } + } + } + + /** + * Check if json file discovered or not. + * + * @return boolean + * @throws OnapCommandDiscoveryFailed + * exception + */ + public static boolean isJsonFileDiscovered() throws OnapCommandDiscoveryFailed { + Resource resource = null; + try { + resource = getExternalResource(Constants.EXTERNAL_DISCOVERY_FILE, + Constants.EXTERNAL_DISCOVERY_DIRECTORY_PATTERN); + if (resource != null) { + return true; + } + } catch (IOException e) { + throw new OnapCommandDiscoveryFailed(Constants.EXTERNAL_DISCOVERY_DIRECTORY, + Constants.EXTERNAL_DISCOVERY_FILE, e); + } + + return false; + } + + /** + * Load the previous discovered json file. + * + * @return list + * @throws OnapCommandInvalidSchema + * exception + * @throws OnapCommandDiscoveryFailed + * exception + */ + public static List loadExternalSchemasFromJson() throws OnapCommandException { + List schemas = new ArrayList<>(); + if (!isJsonFileDiscovered()) { + schemas = findAllExternalSchemas(); + if (!schemas.isEmpty()) { + persist(schemas); + } + } else { + try { + Resource resource = getExternalResource(Constants.EXTERNAL_DISCOVERY_FILE, + Constants.EXTERNAL_DISCOVERY_DIRECTORY_PATTERN); + if (resource != null) { + File file = new File(resource.getURI().getPath()); + ObjectMapper mapper = new ObjectMapper(); + ExternalSchema[] list = mapper.readValue(file, ExternalSchema[].class); + schemas.addAll(Arrays.asList(list)); + } + } catch (IOException e) { + throw new OnapCommandDiscoveryFailed(Constants.EXTERNAL_DISCOVERY_DIRECTORY, + Constants.EXTERNAL_DISCOVERY_FILE, e); + } + } + + return schemas; + } + + /** + * Fetch a particular schema details. + * + * @param cmd + * command name + * @return ExternalSchema obj + * @throws OnapCommandInvalidSchema + * exception + * @throws OnapCommandDiscoveryFailed + * exception + */ + public static ExternalSchema loadExternalSchemaFromJson(String cmd) throws OnapCommandException { + List list = loadExternalSchemasFromJson(); + ExternalSchema schemaStr = null; + if (list != null) { + for (ExternalSchema schema : list) { + if (cmd.equals(schema.getCmdName())) { + schemaStr = schema; + break; + } + } + } + return schemaStr; + } +} diff --git a/framework/src/main/resources/META-INF/services/org.onap.cli.fw.OnapCommand b/framework/src/main/resources/META-INF/services/org.onap.cli.fw.OnapCommand new file mode 100644 index 00000000..89648bf5 --- /dev/null +++ b/framework/src/main/resources/META-INF/services/org.onap.cli.fw.OnapCommand @@ -0,0 +1,2 @@ +org.onap.cli.fw.cmd.OnapSchemaValidateCommand +org.onap.cli.fw.cmd.OnapSchemaRefreshCommand \ No newline at end of file diff --git a/framework/src/main/resources/default_input_parameters.yaml b/framework/src/main/resources/default_input_parameters.yaml new file mode 100644 index 00000000..f1e299eb --- /dev/null +++ b/framework/src/main/resources/default_input_parameters.yaml @@ -0,0 +1,64 @@ +onap_cmd_schema_version: 1.0 +parameters: + - name: onap-username + type: string + description: Onap user name + short_option: u + long_option: onap-username + default_value: ${ONAP_USERNAME} + is_optional: false + - name: onap-password + type: string + description: Onap user password + short_option: p + long_option: onap-password + default_value: ${ONAP_PASSWORD} + is_secured: true + - name: msb-url + type: url + description: Onap MSB url + short_option: m + long_option: msb-url + default_value: ${ONAP_MSB_URL} + - name: help + type: string + description: Onap command help message + short_option: h + long_option: help + default_value: false + - name: version + type: string + description: Onap command service version + short_option: v + long_option: version + default_value: false + - name: debug + type: bool + description: Enable debug output + short_option: d + long_option: debug + default_value: false + - name: format + type: string + description: Output formats, supported formats such as table, csv, json, yaml + short_option: f + long_option: format + default_value: table + - name: long + type: bool + description: whether to print all attributes or only short attributes + short_option: s + long_option: long + default_value: false + - name: no-title + type: bool + description: whether to print title or not + short_option: t + long_option: no-title + default_value: true + - name: no-auth + type: bool + description: whether to authenticate user or not + short_option: a + long_option: no-auth + default_value: false \ No newline at end of file diff --git a/framework/src/main/resources/log4j.properties b/framework/src/main/resources/log4j.properties new file mode 100644 index 00000000..b7fe5437 --- /dev/null +++ b/framework/src/main/resources/log4j.properties @@ -0,0 +1,2 @@ +log4j.rootLogger=off, FileNetNullAppender +log4j.appender.FileNetNullAppender=org.apache.log4j.varia.NullAppender \ No newline at end of file diff --git a/framework/src/main/resources/onap.properties b/framework/src/main/resources/onap.properties new file mode 100644 index 00000000..61049cd4 --- /dev/null +++ b/framework/src/main/resources/onap.properties @@ -0,0 +1,4 @@ +cli.ignore_auth=false +cli.version=1.0 +http.api_key=X-Auth-Token +http.api_key_use_cookies=true \ No newline at end of file diff --git a/framework/src/main/resources/schema-refresh.yaml b/framework/src/main/resources/schema-refresh.yaml new file mode 100644 index 00000000..f64b0545 --- /dev/null +++ b/framework/src/main/resources/schema-refresh.yaml @@ -0,0 +1,26 @@ +onap_cmd_schema_version: 1.0 +name: schema-refresh +description: Onap command to refresh schemas stored in onap_cli_schema folders. +service: + no-auth: true + name: onap-cli + version: 1.0.0 +results: + direction: landscape + attributes: + - name: sl-no + description: Serial Number + scope: short + type: string + - name: command + description: Command name + scope: short + type: string + - name: schema + description: Schema name + scope: short + type: string + - name: version + description: Schema version + scope: short + type: string \ No newline at end of file diff --git a/framework/src/main/resources/schema-validate.yaml b/framework/src/main/resources/schema-validate.yaml new file mode 100644 index 00000000..1571fb3d --- /dev/null +++ b/framework/src/main/resources/schema-validate.yaml @@ -0,0 +1,31 @@ +onap_cmd_schema_version: 1.0 +name: schema-validate +description: Onap command to validate schema +service: + no-auth: true + name: onap-cli + version: 1.0.0 +parameters: + - name: schema-location + type: url + description: Schema file location + short_option: l + long_option: schema-location + is_optional: false + - name: internal-schema + type: bool + description: Validate existing schema file + short_option: i + long_option: internal-schema + is_optional: false +results: + direction: landscape + attributes: + - name: sl-no + description: Serial Number of error + scope: short + type: string + - name: error + description: Schema validation error + scope: short + type: string \ No newline at end of file diff --git a/framework/src/test/java/org/onap/cli/cmd/sample/OnapCommandSample.java b/framework/src/test/java/org/onap/cli/cmd/sample/OnapCommandSample.java new file mode 100644 index 00000000..69714ad7 --- /dev/null +++ b/framework/src/test/java/org/onap/cli/cmd/sample/OnapCommandSample.java @@ -0,0 +1,47 @@ +/* + * 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.cmd.sample; + +import org.onap.cli.fw.OnapCommand; +import org.onap.cli.fw.OnapCommandSchema; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandExecutionFailed; + +/** + * This command helps to test the Command functionalities. + * + */ +@OnapCommandSchema(name = "sample-test", schema = "sample-test-schema.yaml") +public class OnapCommandSample extends OnapCommand { + + public OnapCommandSample() { + this(true); + } + + public OnapCommandSample(boolean isInit) { + this.isInitialzied = isInit; + } + + public boolean failCase = false; + + @Override + protected void run() throws OnapCommandException { + if (this.failCase) + throw new OnapCommandExecutionFailed("Test case to fail"); + } + +} diff --git a/framework/src/test/java/org/onap/cli/cmd/sample/OnapCommandSampleTest.java b/framework/src/test/java/org/onap/cli/cmd/sample/OnapCommandSampleTest.java new file mode 100644 index 00000000..9cf6bdf5 --- /dev/null +++ b/framework/src/test/java/org/onap/cli/cmd/sample/OnapCommandSampleTest.java @@ -0,0 +1,157 @@ +/* + * 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.cmd.sample; + +import org.junit.Test; +import org.onap.cli.fw.conf.Constants; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandExecutionFailed; +import org.onap.cli.fw.error.OnapCommandNotInitialized; +import org.onap.cli.fw.input.OnapCommandParameter; +import org.onap.cli.fw.input.ParameterType; + +import java.util.ArrayList; +import java.util.List; + +public class OnapCommandSampleTest { + @Test + public void sampleTestVersion() { + OnapCommandSample sample = new OnapCommandSample(); + + try { + List parameters = new ArrayList(); + OnapCommandParameter v = new OnapCommandParameter(); + v.setName(Constants.DEFAULT_PARAMETER_VERSION); + v.setValue("true"); + parameters.add(v); + OnapCommandParameter h = new OnapCommandParameter(); + h.setName(Constants.DEFAULT_PARAMETER_HELP); + h.setValue("false"); + parameters.add(h); + sample.setParameters(parameters); + sample.execute(); + } catch (OnapCommandException e) { + } + } + + @Test + public void sampleTestHelp() { + OnapCommandSample sample = new OnapCommandSample(); + try { + List parameters = new ArrayList(); + OnapCommandParameter v = new OnapCommandParameter(); + v.setName(Constants.DEFAULT_PARAMETER_HELP); + v.setValue("true"); + v.setParameterType(ParameterType.BOOL); + parameters.add(v); + sample.setParameters(parameters); + sample.execute(); + } catch (OnapCommandException e) { + } + } + + @Test + public void sampleTest() { + OnapCommandSample sample = new OnapCommandSample(); + try { + List parameters = new ArrayList(); + OnapCommandParameter v = new OnapCommandParameter(); + v.setName(Constants.DEFAULT_PARAMETER_VERSION); + v.setValue("false"); + parameters.add(v); + OnapCommandParameter h = new OnapCommandParameter(); + h.setName(Constants.DEFAULT_PARAMETER_HELP); + h.setValue("false"); + parameters.add(h); + OnapCommandParameter f = new OnapCommandParameter(); + f.setName(Constants.DEFAULT_PARAMETER_OUTPUT_FORMAT); + f.setValue("table"); + parameters.add(f); + OnapCommandParameter l = new OnapCommandParameter(); + l.setName(Constants.DEFAULT_PARAMETER_OUTPUT_ATTR_LONG); + l.setValue("true"); + parameters.add(l); + OnapCommandParameter t = new OnapCommandParameter(); + t.setName(Constants.DEFAULT_PARAMETER_OUTPUT_NO_TITLE); + t.setValue("true"); + parameters.add(t); + OnapCommandParameter a = new OnapCommandParameter(); + a.setName(Constants.DEFAULT_PARAMETER_OUTPUT_NO_AUTH); + a.setValue("true"); + parameters.add(a); + OnapCommandParameter d = new OnapCommandParameter(); + d.setName(Constants.DEFAULT_PARAMETER_DEBUG); + d.setValue("true"); + parameters.add(d); + OnapCommandParameter m = new OnapCommandParameter(); + m.setName(Constants.DEAFULT_PARAMETER_MSB_URL); + m.setValue("http://localhost"); + parameters.add(m); + sample.setParameters(parameters); + sample.execute(); + } catch (OnapCommandException e) { + } + } + + @Test(expected = OnapCommandExecutionFailed.class) + public void sampleTestFailure() throws OnapCommandException { + OnapCommandSample sample = new OnapCommandSample(); + sample.failCase = true; + + List parameters = new ArrayList(); + OnapCommandParameter v = new OnapCommandParameter(); + v.setName(Constants.DEFAULT_PARAMETER_VERSION); + v.setValue("false"); + parameters.add(v); + OnapCommandParameter h = new OnapCommandParameter(); + h.setName(Constants.DEFAULT_PARAMETER_HELP); + h.setValue("false"); + parameters.add(h); + OnapCommandParameter f = new OnapCommandParameter(); + f.setName(Constants.DEFAULT_PARAMETER_OUTPUT_FORMAT); + f.setValue("table"); + parameters.add(f); + OnapCommandParameter l = new OnapCommandParameter(); + l.setName(Constants.DEFAULT_PARAMETER_OUTPUT_ATTR_LONG); + l.setValue("true"); + parameters.add(l); + OnapCommandParameter t = new OnapCommandParameter(); + t.setName(Constants.DEFAULT_PARAMETER_OUTPUT_NO_TITLE); + t.setValue("true"); + parameters.add(t); + OnapCommandParameter a = new OnapCommandParameter(); + a.setName(Constants.DEFAULT_PARAMETER_OUTPUT_NO_AUTH); + a.setValue("true"); + parameters.add(a); + OnapCommandParameter d = new OnapCommandParameter(); + d.setName(Constants.DEFAULT_PARAMETER_DEBUG); + d.setValue("true"); + parameters.add(d); + OnapCommandParameter m = new OnapCommandParameter(); + m.setName(Constants.DEAFULT_PARAMETER_MSB_URL); + m.setValue("http://localhost"); + parameters.add(m); + sample.setParameters(parameters); + sample.execute(); + } + + @Test(expected = OnapCommandNotInitialized.class) + public void sampleTestIsInitialized() throws OnapCommandException { + OnapCommandSample sample = new OnapCommandSample(false); + sample.execute(); + } +} diff --git a/framework/src/test/java/org/onap/cli/fw/OnapCommandRegistrarTest.java b/framework/src/test/java/org/onap/cli/fw/OnapCommandRegistrarTest.java new file mode 100644 index 00000000..83f3a743 --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/OnapCommandRegistrarTest.java @@ -0,0 +1,170 @@ +/* + * 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; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.junit.Before; +import org.junit.Test; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandHelpFailed; +import org.onap.cli.fw.error.OnapCommandNotFound; +import org.onap.cli.fw.error.OnapCommandRegistrationFailed; + +import java.io.File; +import java.net.URL; + +public class OnapCommandRegistrarTest { + + OnapCommandRegistrar registerar; + + @Before + public void setup() throws OnapCommandException { + registerar = OnapCommandRegistrar.getRegistrar(); + createDir(); + } + + private void createDir() { + URL url = OnapCommandRegistrarTest.class.getClassLoader().getResource("onap-cli-schema"); + if (url != null) { + String path = url.getPath(); + path = path.replaceFirst("onap-cli-schema", "data"); + File file = new File(path); + if (!file.exists()) { + file.mkdir(); + } else { + File f1 = new File(path + "/external-schema.json"); + f1.delete(); + } + } + } + + @Test + public void registerTest() throws OnapCommandException { + OnapCommand test = new OnapCommandTest(); + Class cmd = (Class) test.getClass(); + registerar.register("Test", cmd); + OnapCommand cc = registerar.get("Test"); + assertTrue(cmd == cc.getClass()); + + } + + @Test + // For Coverage + public void cmdTestSchema() throws OnapCommandException { + OnapCommand test = new OnapCommandTest(); + Class cmd = (Class) test.getClass(); + registerar.register("Test", cmd); + OnapCommand cc = registerar.get("Test"); + } + + @Test + public void onapCommandNotFoundTest() throws OnapCommandException { + try { + registerar = OnapCommandRegistrar.getRegistrar(); + registerar.get("Test1"); + fail("This should have thrown an exception"); + } catch (OnapCommandNotFound e) { + assertEquals(e.getMessage(), "0x0011::Command Test1 is not registered"); + } + } + + @Test + public void onapCommandRegistrationFailedTest() throws OnapCommandException { + + @OnapCommandSchema(name = "Test2", schema = "sample-test-schema.yaml") + class Test extends OnapCommand { + + @Override + protected void run() throws OnapCommandException { + + } + + } + + OnapCommand com = new Test(); + Class cmd = (Class) com.getClass(); + try { + registerar.register("Test2", cmd); + registerar.get("Test2"); + fail("This should have thrown an exception"); + } catch (OnapCommandRegistrationFailed e) { + assertTrue(e.getMessage().contains("0x0018::Command Test2 is failed to register")); + } + } + + @Test(expected = OnapCommandHelpFailed.class) + // For coverage + public void helpTestException() throws OnapCommandException { + OnapCommand test = new OnapCommandTest1(); + Class cmd = (Class) test.getClass(); + registerar = new OnapCommandRegistrar(); + registerar.register("test1", cmd); + String help = registerar.getHelp(); + assertNotNull(help); + } + + @Test + public void helpTest() throws OnapCommandException { + String help = registerar.getHelp(); + assertNotNull(help); + } + + @Test + public void versionTest() throws OnapCommandHelpFailed { + String version = registerar.getVersion(); + assertNotNull(version); + } + + @Test + public void listTest() { + registerar.listCommands(); + } +} + +@OnapCommandSchema(name = OnapCommandTest.CMD_NAME, schema = "sample-test-schema.yaml") +class OnapCommandTest extends OnapCommand { + + public OnapCommandTest() { + + } + + public static final String CMD_NAME = "test"; + + protected void run() throws OnapCommandException { + + } + +} + +@OnapCommandSchema(name = OnapCommandTest1.CMD_NAME, schema = "test-schema.yaml") +class OnapCommandTest1 extends OnapCommand { + + public OnapCommandTest1() { + + } + + public static final String CMD_NAME = "test1"; + + protected void run() throws OnapCommandException { + + } + +} diff --git a/framework/src/test/java/org/onap/cli/fw/ad/OnapAuthClientTest.java b/framework/src/test/java/org/onap/cli/fw/ad/OnapAuthClientTest.java new file mode 100644 index 00000000..720737b3 --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/ad/OnapAuthClientTest.java @@ -0,0 +1,201 @@ +/* + * 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.ad; + +import static org.junit.Assert.assertEquals; + +import mockit.Invocation; +import mockit.Mock; +import mockit.MockUp; + +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.Test; +import org.onap.cli.fw.conf.OnapCommandConfg; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandExecutionFailed; +import org.onap.cli.fw.error.OnapCommandHttpFailure; +import org.onap.cli.fw.error.OnapCommandServiceNotFound; +import org.onap.cli.fw.http.HttpInput; +import org.onap.cli.fw.http.HttpResult; +import org.onap.cli.fw.http.OnapHttpConnection; + +public class OnapAuthClientTest { + + OnapAuthClient client; + + @Before + public void setUp() throws OnapCommandHttpFailure { + OnapCredentials creds = new OnapCredentials("test", "test123", "http://192.168.99.10:80"); + client = new OnapAuthClient(creds, true); + } + + @Test + public void loginFailedAuthIgnoredTest() throws OnapCommandException { + OnapCredentials creds = new OnapCredentials("test", "test123", "http://192.168.99.10:80"); + OnapAuthClient client = new OnapAuthClient(creds, true); + if (OnapCommandConfg.isAuthIgnored()) { + client.getDebugInfo(); + client.login(); + assertEquals(null, client.getAuthToken()); + } + } + + @Test + public void logoutFailedAuthIgnoredTest() throws OnapCommandException { + OnapCredentials creds = new OnapCredentials("test", "test123", "http://192.168.99.10:80"); + OnapAuthClient client = new OnapAuthClient(creds, true); + if (OnapCommandConfg.isAuthIgnored()) { + client.logout(); + assertEquals(null, client.getAuthToken()); + } + } + + @Test + public void getMsbUrlTest() throws OnapCommandException { + OnapCredentials creds = new OnapCredentials("test", "test123", "http://192.168.99.10:80"); + OnapAuthClient client = new OnapAuthClient(creds, true); + OnapService srv = new OnapService(); + srv.setName("msb"); + String msb = client.getServiceBasePath(srv); + assertEquals("http://192.168.99.10:80/api/microservices/v1", msb); + } + + @Test(expected = OnapCommandServiceNotFound.class) + public void loginFailedServiceNotFoundTest() throws OnapCommandException { + mockIsAuthIgnored(false); + HttpResult result = new HttpResult(); + result.setStatus(404); + mockHttpRequest(result); + client.login(); + + } + + @Test(expected = OnapCommandExecutionFailed.class) + public void loginFailedCommandExecutionFailedTest() throws OnapCommandException { + + mockIsAuthIgnored(false); + HttpResult result = new HttpResult(); + result.setStatus(401); + mockHttpRequest(result); + client.login(); + } + + @Test(expected = OnapCommandExecutionFailed.class) + public void loginFailedWrongJasonBodyTest() throws OnapCommandException { + mockIsAuthIgnored(false); + HttpResult result = new HttpResult(); + result.setStatus(200); + mockHttpRequest(result); + client.login(); + } + + @Test + public void loginSuccessTest() { + + mockIsAuthIgnored(false); + HttpResult result = new HttpResult(); + result.setBody("{\"url\":\"http://192.168.4.47\"}"); + result.setStatus(200); + mockHttpConsecutiveRequest(result); + try { + client.login(); + } catch (OnapCommandException e) { + } + mockHttpRequest(null); + } + + @Test + public void logoutFailedTest() { + + mockIsAuthIgnored(false); + HttpResult result = new HttpResult(); + result.setBody("{\"url\":\"http://192.168.4.47\"}"); + result.setStatus(200); + mockHttpConsecutiveRequest(result); + try { + client.logout(); + } catch (OnapCommandException e) { + } + mockHttpRequest(null); + } + + @Test + public void logoutSuccessTest() { + + mockIsAuthIgnored(false); + HttpResult result = new HttpResult(); + result.setBody("{\"url\":\"http://192.168.4.47\"}"); + result.setStatus(204); + mockHttpConsecutiveRequest(result); + try { + client.logout(); + } catch (OnapCommandException e) { + } + mockHttpRequest(null); + } + + private void mockIsAuthIgnored(boolean isAuthIgnored) { + + new MockUp() { + boolean isMock = true; + + @Mock + public boolean isAuthIgnored(Invocation inv) { + if (isMock) { + isMock = false; + return isAuthIgnored; + } else { + return inv.proceed(); + } + } + }; + } + + private static void mockHttpRequest(HttpResult result) { + new MockUp() { + boolean isMock = true; + + @Mock + public HttpResult request(Invocation inv, HttpInput input) throws OnapCommandHttpFailure { + if (isMock) { + isMock = false; + return result; + } else { + return inv.proceed(input); + } + } + }; + } + + private void mockHttpConsecutiveRequest(HttpResult result) { + new MockUp() { + @Mock + public HttpResult request(Invocation inv, HttpInput input) throws OnapCommandHttpFailure { + return result; + } + }; + } + + @AfterClass + public static void clear() { + HttpResult result = new HttpResult(); + result.setBody("{\"url\":\"http://192.168.4.47\"}"); + result.setStatus(200); + mockHttpRequest(result); + } +} diff --git a/framework/src/test/java/org/onap/cli/fw/ad/OnapCredentialsTest.java b/framework/src/test/java/org/onap/cli/fw/ad/OnapCredentialsTest.java new file mode 100644 index 00000000..a1987c08 --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/ad/OnapCredentialsTest.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.ad; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class OnapCredentialsTest { + + @Test + public void credentialsTest() { + OnapCredentials cre = new OnapCredentials("test", "test123", "url"); + assertTrue(cre.getUsername().equals("test") && cre.getPassword().equals("test123") + && cre.getMsbUrl().equals("url")); + } + +} diff --git a/framework/src/test/java/org/onap/cli/fw/ad/OnapServiceTest.java b/framework/src/test/java/org/onap/cli/fw/ad/OnapServiceTest.java new file mode 100644 index 00000000..f0ec8c63 --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/ad/OnapServiceTest.java @@ -0,0 +1,37 @@ +/* + * 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.ad; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class OnapServiceTest { + + @Test + public void serviceTest() { + OnapService ser = new OnapService(); + ser.setName("name"); + ser.setVersion("1.0"); + ser.setBasePath("basePath"); + ser.setNoAuth(true); + assertTrue(ser.getName().equals("name") && ser.getVersion().equals("1.0") + && ser.getBasePath().equals("basePath") && ser.isNoAuth()); + + } + +} diff --git a/framework/src/test/java/org/onap/cli/fw/cmd/OnapCreateSwaggerBasedCommand.java b/framework/src/test/java/org/onap/cli/fw/cmd/OnapCreateSwaggerBasedCommand.java new file mode 100644 index 00000000..069ae35f --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/cmd/OnapCreateSwaggerBasedCommand.java @@ -0,0 +1,101 @@ +/* + * 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.cmd; + +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandExecutionFailed; +import org.onap.cli.fw.error.OnapCommandExecutorInfoMissing; +import org.onap.cli.fw.error.OnapCommandInvalidParameterValue; +import org.onap.cli.fw.error.OnapCommandResultInitialzationFailed; +import org.onap.cli.fw.utils.OnapCommandUtils; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.List; + +public class OnapCreateSwaggerBasedCommand extends OnapSwaggerCommand { + + private T initializeEntity(T obj, List prps) throws OnapCommandResultInitialzationFailed { + for (int i = 1; i < prps.size(); i++) { + String paramName = prps.get(i).trim(); + String prpName = paramName; + // paramName(prpName) + if (prpName.contains("(")) { + paramName = prpName.substring(0, prpName.indexOf("(")); + prpName = prpName.substring(prpName.indexOf("(") + 1, prpName.indexOf(")")); + } + String methodName = OnapCommandUtils.formMethodNameFromAttributeName(prpName, "set"); + + try { + Method set = obj.getClass().getMethod(methodName, String.class); + set.invoke(obj, this.getParametersMap().get(paramName).getValue()); + } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException + | InvocationTargetException | OnapCommandInvalidParameterValue e) { + throw new OnapCommandResultInitialzationFailed(this.getName(), e); + } + } + return obj; + } + + @Override + protected void run() throws OnapCommandException { + if (this.getExecutor() == null) { + throw new OnapCommandExecutorInfoMissing(this.getName()); + } + + try { + // Initialize client + Class clientClaz = Class.forName(this.getExecutor().getClient()); + Object client = clientClaz.getConstructor().newInstance(); + this.initializeApiClient(client); + + // Initialize api + Class apiCls = Class.forName(this.getExecutor().getApi()); + Object api = apiCls.getConstructor(clientClaz).newInstance(client); + + // invoke method + List methodTokens = Arrays.asList(this.getExecutor().getMethod().split(",")); + + List entityTokens = Arrays.asList(this.getExecutor().getEntity().split(",")); + Class entityCls = Class.forName(entityTokens.get(0)); + Object entity = entityCls.newInstance(); + Method method = api.getClass().getMethod(methodTokens.get(0), entityCls); + Object result = method.invoke(api, this.initializeEntity(entity, entityTokens)); + + // initialize result + this.initializeResult(result); + } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException + | IllegalArgumentException | InvocationTargetException e) { + throw new OnapCommandExecutionFailed(this.getName(), e); + } catch (OnapCommandException e) { + throw e; + } catch (Exception e) { + try { + Class execCls = Class.forName(this.getExecutor().getException()); + Method execMethod = execCls.getClass().getMethod("getCode"); + if (execCls.isInstance(e)) { + throw new OnapCommandExecutionFailed(this.getName(), e, (Integer) execMethod.invoke(e)); + } + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException + | ClassNotFoundException | NoSuchMethodException | SecurityException e1) { + throw new OnapCommandExecutionFailed(this.getName(), e1.getMessage()); + } + throw new OnapCommandExecutionFailed(this.getName(), e.getMessage()); + } + } +} diff --git a/framework/src/test/java/org/onap/cli/fw/cmd/OnapCreateSwaggerBasedCommandTest.java b/framework/src/test/java/org/onap/cli/fw/cmd/OnapCreateSwaggerBasedCommandTest.java new file mode 100644 index 00000000..ec4b91d4 --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/cmd/OnapCreateSwaggerBasedCommandTest.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.cmd; + +import org.junit.Test; +import org.onap.cli.fw.OnapCommand; +import org.onap.cli.fw.error.OnapCommandException; + +public class OnapCreateSwaggerBasedCommandTest { + + @Test + public void runTest() throws OnapCommandException { + OnapCommand cmd = new OnapCreateSwaggerBasedCommand(); + cmd.initializeSchema("sample-test-schema-swagger.yaml"); + //cmd.execute(); + } + +} diff --git a/framework/src/test/java/org/onap/cli/fw/cmd/OnapDeleteSwaggerBasedCommand.java b/framework/src/test/java/org/onap/cli/fw/cmd/OnapDeleteSwaggerBasedCommand.java new file mode 100644 index 00000000..1db954c6 --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/cmd/OnapDeleteSwaggerBasedCommand.java @@ -0,0 +1,75 @@ +/* + * 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.cmd; + +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandExecutionFailed; +import org.onap.cli.fw.error.OnapCommandExecutorInfoMissing; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.List; + +/** + * Helps to make delete rest calls on top of swagger generated java client. For example following one shows how MSB + * service list is achieved here exec: ... method: deleteMicroService, [input param name given under Parameters] + * + */ +public class OnapDeleteSwaggerBasedCommand extends OnapSwaggerCommand { + + @Override + protected void run() throws OnapCommandException { + if (this.getExecutor() == null) { + throw new OnapCommandExecutorInfoMissing(this.getName()); + } + + try { + // Initialize client + Class clientCls = Class.forName(this.getExecutor().getClient()); + Object client = clientCls.getConstructor().newInstance(); + this.initializeApiClient(client); + + // Initialize api + Class apiCls = Class.forName(this.getExecutor().getApi()); + Object api = apiCls.getConstructor(clientCls).newInstance(client); + + // invoke method + List methodTokens = Arrays.asList(this.getExecutor().getMethod().split(",")); + + Method method = api.getClass().getMethod(methodTokens.get(0), String.class); + method.invoke(api, this.getParametersMap().get(methodTokens.get(1)).getValue()); + } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException + | IllegalArgumentException | InvocationTargetException e) { + throw new OnapCommandExecutionFailed(this.getName(), e); + } catch (OnapCommandException e) { + throw e; + } catch (Exception e) { + try { + Class execCls = Class.forName(this.getExecutor().getException()); + Method execMethod = execCls.getClass().getMethod("getCode"); + if (execCls.isInstance(e)) { + throw new OnapCommandExecutionFailed(this.getName(), e, (Integer) execMethod.invoke(e)); + } + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException + | ClassNotFoundException | NoSuchMethodException | SecurityException e1) { + throw new OnapCommandExecutionFailed(this.getName(), e1.getMessage()); + } + throw new OnapCommandExecutionFailed(this.getName(), e.getMessage()); + } + } +} diff --git a/framework/src/test/java/org/onap/cli/fw/cmd/OnapDeleteSwaggerBasedCommandTest.java b/framework/src/test/java/org/onap/cli/fw/cmd/OnapDeleteSwaggerBasedCommandTest.java new file mode 100644 index 00000000..a242a683 --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/cmd/OnapDeleteSwaggerBasedCommandTest.java @@ -0,0 +1,21 @@ +/* + * 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.cmd; + +public class OnapDeleteSwaggerBasedCommandTest { + +} diff --git a/framework/src/test/java/org/onap/cli/fw/cmd/OnapGetSwaggerBasedCommand.java b/framework/src/test/java/org/onap/cli/fw/cmd/OnapGetSwaggerBasedCommand.java new file mode 100644 index 00000000..8ed86564 --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/cmd/OnapGetSwaggerBasedCommand.java @@ -0,0 +1,79 @@ +/* + * 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.cmd; + +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandExecutionFailed; +import org.onap.cli.fw.error.OnapCommandExecutorInfoMissing; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.List; + +/** + * Helps to make get rest calls on top of swagger generated java client. For example following one shows how MSB service + * list is achieved here exec: ... method: getMicroService, [input param name given under Parameters] + * + */ +public class OnapGetSwaggerBasedCommand extends OnapSwaggerCommand { + + @Override + protected void run() throws OnapCommandException { + if (this.getExecutor() == null) { + throw new OnapCommandExecutorInfoMissing(this.getName()); + } + + try { + // Initialize client + Class clientCls = Class.forName(this.getExecutor().getClient()); + Object client = clientCls.getConstructor().newInstance(); + this.initializeApiClient(client); + + // Initialize api + Class apiCls = Class.forName(this.getExecutor().getApi()); + Object api = apiCls.getConstructor(clientCls).newInstance(client); + + // invoke method + List methodTokens = Arrays.asList(this.getExecutor().getMethod().split(",")); + + Method method = api.getClass().getMethod(methodTokens.get(0), String.class); + Object result = method.invoke(api, this.getParametersMap().get(methodTokens.get(1)).getValue()); + + // initialize result + this.initializeResult(result); + + } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException + | IllegalArgumentException | InvocationTargetException e) { + throw new OnapCommandExecutionFailed(this.getName(), e); + } catch (OnapCommandException e) { + throw e; + } catch (Exception e) { + try { + Class execCls = Class.forName(this.getExecutor().getException()); + Method execMethod = execCls.getClass().getMethod("getCode"); + if (execCls.isInstance(e)) { + throw new OnapCommandExecutionFailed(this.getName(), e, (Integer) execMethod.invoke(e)); + } + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException + | ClassNotFoundException | NoSuchMethodException | SecurityException e1) { + throw new OnapCommandExecutionFailed(this.getName(), e1.getMessage()); + } + throw new OnapCommandExecutionFailed(this.getName(), e.getMessage()); + } + } +} diff --git a/framework/src/test/java/org/onap/cli/fw/cmd/OnapGetSwaggerBasedCommandTest.java b/framework/src/test/java/org/onap/cli/fw/cmd/OnapGetSwaggerBasedCommandTest.java new file mode 100644 index 00000000..5c301a62 --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/cmd/OnapGetSwaggerBasedCommandTest.java @@ -0,0 +1,21 @@ +/* + * 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.cmd; + +public class OnapGetSwaggerBasedCommandTest { + +} diff --git a/framework/src/test/java/org/onap/cli/fw/cmd/OnapHttpCommandTest.java b/framework/src/test/java/org/onap/cli/fw/cmd/OnapHttpCommandTest.java new file mode 100644 index 00000000..e7af1aa3 --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/cmd/OnapHttpCommandTest.java @@ -0,0 +1,79 @@ +/* + * 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.cmd; + +import org.junit.Test; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.http.HttpInput; +import org.onap.cli.fw.input.OnapCommandParameter; +import org.onap.cli.fw.input.ParameterType; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class OnapHttpCommandTest { + + @Test(expected = OnapCommandException.class) + public void runTest() throws OnapCommandException { + OnapCommandParameter param1 = new OnapCommandParameter(); + param1.setLongOption("onap-username"); + param1.setName("onap-username"); + param1.setParameterType(ParameterType.STRING); + OnapCommandParameter param2 = new OnapCommandParameter(); + param2.setLongOption("onap-password"); + param2.setName("onap-password"); + param2.setParameterType(ParameterType.STRING); + OnapCommandParameter param3 = new OnapCommandParameter(); + param3.setLongOption("msb-url"); + param3.setName("msb-url"); + param3.setParameterType(ParameterType.STRING); + OnapCommandParameter param4 = new OnapCommandParameter(); + param4.setLongOption("string-param"); + param4.setName("string-param"); + param4.setParameterType(ParameterType.STRING); + OnapCommandParameter param5 = new OnapCommandParameter(); + param5.setLongOption("long-opt"); + param5.setName("long-opt"); + param5.setParameterType(ParameterType.STRING); + + List paramslist = new ArrayList<>(); + paramslist.add(param1); + paramslist.add(param2); + paramslist.add(param3); + paramslist.add(param4); + paramslist.add(param5); + + HttpInput inp = new HttpInput(); + inp.setBody("body"); + inp.setMethod("method"); + inp.setReqCookies(new HashMap()); + inp.setReqHeaders(new HashMap()); + inp.setReqQueries(new HashMap()); + inp.setUri("uri"); + + OnapHttpCommand com = new OnapHttpCommand(); + com.setParameters(paramslist); + com.getParameters(); + com.getParametersMap(); + com.setInput(inp); + com.initializeSchema("sample-test-schema.yaml"); + com.execute(); + + } + +} diff --git a/framework/src/test/java/org/onap/cli/fw/cmd/OnapListSwaggerBasedCommand.java b/framework/src/test/java/org/onap/cli/fw/cmd/OnapListSwaggerBasedCommand.java new file mode 100644 index 00000000..a5795e75 --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/cmd/OnapListSwaggerBasedCommand.java @@ -0,0 +1,78 @@ +/* + * 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.cmd; + +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandExecutionFailed; +import org.onap.cli.fw.error.OnapCommandExecutorInfoMissing; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * Helps to make list rest calls on top of swagger generated java client. For example following one shows how MSB + * service list is achived here exec: api: + * org.onap.common_services.microservice_bus.apiroute_service.client.api.MSBServiceResourceApi client: + * org.onap.common_services.microservice_bus.apiroute_service.client.invoker.ApiClient method: getMicroService + * exception: org.onap.common_services.microservice_bus.apiroute_service.client.invoker.ApiException + * + */ +public class OnapListSwaggerBasedCommand extends OnapSwaggerCommand { + + @Override + protected void run() throws OnapCommandException { + if (this.getExecutor() == null) { + throw new OnapCommandExecutorInfoMissing(this.getName()); + } + + try { + // Initialize client + Class clientCls = Class.forName(this.getExecutor().getClient()); + Object client = clientCls.getConstructor().newInstance(); + this.initializeApiClient(client); + + // Initialize api + Class apiCls = Class.forName(this.getExecutor().getApi()); + Object api = apiCls.getConstructor(clientCls).newInstance(client); + + // invoke method + Method method = api.getClass().getMethod(this.getExecutor().getMethod()); + Object result = method.invoke(api); + + // initialize result + this.initializeResult(result); + + } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException + | IllegalArgumentException | InvocationTargetException e) { + throw new OnapCommandExecutionFailed(this.getName(), e); + } catch (OnapCommandException e) { + throw e; + } catch (Exception e) { + try { + Class execCls = Class.forName(this.getExecutor().getException()); + Method execMethod = execCls.getClass().getMethod("getCode"); + if (execCls.isInstance(e)) { + throw new OnapCommandExecutionFailed(this.getName(), e, (Integer) execMethod.invoke(e)); + } + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException + | ClassNotFoundException | NoSuchMethodException | SecurityException e1) { + throw new OnapCommandExecutionFailed(this.getName(), e1.getMessage()); + } + throw new OnapCommandExecutionFailed(this.getName(), e.getMessage()); + } + } +} diff --git a/framework/src/test/java/org/onap/cli/fw/cmd/OnapListSwaggerBasedCommandTest.java b/framework/src/test/java/org/onap/cli/fw/cmd/OnapListSwaggerBasedCommandTest.java new file mode 100644 index 00000000..5683153c --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/cmd/OnapListSwaggerBasedCommandTest.java @@ -0,0 +1,21 @@ +/* + * 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.cmd; + +public class OnapListSwaggerBasedCommandTest { + +} diff --git a/framework/src/test/java/org/onap/cli/fw/cmd/OnapSchemaRefreshCommandTest.java b/framework/src/test/java/org/onap/cli/fw/cmd/OnapSchemaRefreshCommandTest.java new file mode 100644 index 00000000..1c09c0d3 --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/cmd/OnapSchemaRefreshCommandTest.java @@ -0,0 +1,56 @@ +/* + * 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.cmd; + +import org.junit.Test; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.input.OnapCommandParameter; + +public class OnapSchemaRefreshCommandTest { + + @Test + public void validateSchemaCommandTest1() throws OnapCommandException { + OnapSchemaRefreshCommand cmd = new OnapSchemaRefreshCommand(); + cmd.initializeSchema("schema-refresh.yaml"); + for (OnapCommandParameter param : cmd.getParameters()) { + if ("onap-username".equals(param.getName())) { + param.setValue("test"); + } else if ("onap-password".equals(param.getName())) { + param.setValue("test"); + } else if ("msb-url".equals(param.getName())) { + param.setValue("test-url"); + } + } + cmd.execute(); + } + + @Test + public void validateSchemaCommandTest2() throws OnapCommandException { + OnapSchemaRefreshCommand cmd = new OnapSchemaRefreshCommand(); + cmd.initializeSchema("schema-refresh.yaml"); + for (OnapCommandParameter param : cmd.getParameters()) { + if ("onap-username".equals(param.getName())) { + param.setValue("test"); + } else if ("onap-password".equals(param.getName())) { + param.setValue("test"); + } else if ("msb-url".equals(param.getName())) { + param.setValue("test-url"); + } + } + cmd.execute(); + } +} diff --git a/framework/src/test/java/org/onap/cli/fw/cmd/OnapSchemaValidateCommandTest.java b/framework/src/test/java/org/onap/cli/fw/cmd/OnapSchemaValidateCommandTest.java new file mode 100644 index 00000000..b70bf6f9 --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/cmd/OnapSchemaValidateCommandTest.java @@ -0,0 +1,64 @@ +/* + * 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.cmd; + +import org.junit.Test; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.input.OnapCommandParameter; +import org.onap.cli.fw.schema.ValidateSchemaTest; + +public class OnapSchemaValidateCommandTest { + + @Test + public void validateSchemaCommandTest1() throws OnapCommandException { + OnapSchemaValidateCommand cmd = new OnapSchemaValidateCommand(); + cmd.initializeSchema("schema-validate.yaml"); + for (OnapCommandParameter param : cmd.getParameters()) { + if ("onap-username".equals(param.getName())) { + param.setValue("test"); + } else if ("onap-password".equals(param.getName())) { + param.setValue("test"); + } else if ("msb-url".equals(param.getName())) { + param.setValue("test-url"); + } else if ("schema-location".equals(param.getName())) { + param.setValue("schema-validate-pass.yaml"); + } else if ("internal-schema".equals(param.getName())) { + param.setValue("true"); + } + } + cmd.execute(); + } + + @Test + public void validateSchemaCommandTest2() throws OnapCommandException { + OnapSchemaValidateCommand cmd = new OnapSchemaValidateCommand(); + cmd.initializeSchema("schema-validate.yaml"); + for (OnapCommandParameter param : cmd.getParameters()) { + if ("onap-username".equals(param.getName())) { + param.setValue("test"); + } else if ("onap-password".equals(param.getName())) { + param.setValue("test"); + } else if ("msb-url".equals(param.getName())) { + param.setValue("test-url"); + } else if ("schema-location".equals(param.getName())) { + param.setValue( + ValidateSchemaTest.class.getClassLoader().getResource("schema-validate-pass.yaml").getFile()); + } + } + cmd.execute(); + } +} diff --git a/framework/src/test/java/org/onap/cli/fw/cmd/OnapSwaggerCommandTest.java b/framework/src/test/java/org/onap/cli/fw/cmd/OnapSwaggerCommandTest.java new file mode 100644 index 00000000..628b9a42 --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/cmd/OnapSwaggerCommandTest.java @@ -0,0 +1,96 @@ +/* + * 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.cmd; + +import org.junit.Test; +import org.onap.cli.fw.OnapCommand; +import org.onap.cli.fw.error.OnapCommandClientInitialzationFailed; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandResultInitialzationFailed; +import org.onap.cli.fw.input.OnapCommandParameter; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class OnapSwaggerCommandTest { + + @Test(expected = OnapCommandResultInitialzationFailed.class) + public void initializeResultTest1() throws OnapCommandException { + OnapSwaggerCommandImpl swagger = new OnapSwaggerCommandImpl(); + swagger.initializeSchema("onap-test-schema.yaml"); + List obj = new ArrayList<>(); + obj.add("name"); + obj.add("get"); + swagger.initializeResult(obj); + + Set obj1 = new HashSet<>(); + obj.add("name"); + obj.add("get"); + swagger.initializeResult(obj1); + } + + @Test(expected = OnapCommandResultInitialzationFailed.class) + public void initializeResultTest2() throws OnapCommandException { + OnapSwaggerCommandImpl swagger = new OnapSwaggerCommandImpl(); + swagger.initializeSchema("onap-test-schema.yaml"); + Set obj1 = new HashSet<>(); + obj1.add("name"); + obj1.add("get"); + swagger.initializeResult(obj1); + } + + @Test(expected = NullPointerException.class) + public void initializeResultTest3() throws OnapCommandException { + OnapSwaggerCommandImpl swagger = new OnapSwaggerCommandImpl(); + swagger.initializeSchema("onap-test-schema.yaml"); + ApiClient cit = new ApiClient(); + cit.setApiKey("apiKey"); + cit.setBasePath("basePath"); + swagger.initializeApiClient(cit); + } + + class OnapSwaggerCommandImpl extends OnapSwaggerCommand { + protected void run() throws OnapCommandException { + } + + } + + class ApiClient { + + private String basePath; + private String apiKey; + + public String getBasePath() { + return basePath; + } + + public void setBasePath(String basePath) { + this.basePath = basePath; + } + + public String getApiKey() { + return apiKey; + } + + public void setApiKey(String apiKey) { + this.apiKey = apiKey; + } + + } +} diff --git a/framework/src/test/java/org/onap/cli/fw/conf/OnapCommandConfgTest.java b/framework/src/test/java/org/onap/cli/fw/conf/OnapCommandConfgTest.java new file mode 100644 index 00000000..e345945b --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/conf/OnapCommandConfgTest.java @@ -0,0 +1,44 @@ +/* + * 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.conf; + +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; +import java.util.Properties; + +public class OnapCommandConfgTest { + + @Test + public void versionTest() { + String str = OnapCommandConfg.getVersion(); + Assert.assertTrue(str != null); + } + + @Test + public void isAuthIgnoredTest() throws IOException { + Properties prps = new Properties(); + prps.load(OnapCommandConfg.class.getClassLoader().getResourceAsStream("onap.properties")); + boolean auth = OnapCommandConfg.isAuthIgnored(); + Assert.assertTrue(auth == Boolean.valueOf(prps.getProperty("cli.ignore_auth"))); + Assert.assertTrue(OnapCommandConfg.isCookiesBasedAuth() == Boolean + .valueOf(prps.getProperty("http.api_key_use_cookies"))); + Assert.assertTrue("X-Auth-Token".equals(OnapCommandConfg.getXAuthTokenName())); + } + +} diff --git a/framework/src/test/java/org/onap/cli/fw/error/OnapCommandErrorTest.java b/framework/src/test/java/org/onap/cli/fw/error/OnapCommandErrorTest.java new file mode 100644 index 00000000..1d0c1a6b --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/error/OnapCommandErrorTest.java @@ -0,0 +1,270 @@ +/* + * 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 static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class OnapCommandErrorTest { + + @Test + public void onapCommandDiscoveryFailedTest() { + OnapCommandDiscoveryFailed failed = new OnapCommandDiscoveryFailed("name"); + assertEquals("0x0010::Failed auto discover schema files from name under class path, ", failed.getMessage()); + failed = new OnapCommandDiscoveryFailed("directory", "name"); + assertEquals("0x0010::Failed auto generate json file 'name' under class path directory 'directory' , ", + failed.getMessage()); + } + + @Test + public void onapCommandInvalidParameterValueTest() { + OnapCommandInvalidParameterValue failed = new OnapCommandInvalidParameterValue("name"); + assertEquals("0x0028::Parameter name value is invalid, ", failed.getMessage()); + } + + @Test + public void onapCommandResultMapProcessingFailedTest() { + OnapCommandResultMapProcessingFailed failed = new OnapCommandResultMapProcessingFailed("name", + new Exception("")); + assertEquals("0x0028::Failed to process the result map name in http section, ", failed.getMessage()); + } + + @Test + public void onapCommandHttpHeaderNotFoundTest() { + OnapCommandHttpHeaderNotFound failed = new OnapCommandHttpHeaderNotFound("name"); + assertEquals("0x0027::Http header name is not returned from the service", failed.getMessage()); + } + + @Test + public void onapCommandClientInitialzationFailedTest() { + OnapCommandClientInitialzationFailed failed = new OnapCommandClientInitialzationFailed("Test", + new Exception("Test Command Failed")); + assertEquals("0x0021::API client for the command Test is failed, Test Command Failed", failed.getMessage()); + } + + @Test + public void onapCommandExceptionTest1() { + OnapCommandException failed = new OnapCommandException("1", "Test Command Failed"); + assertEquals("1::Test Command Failed", failed.getMessage()); + } + + @Test + public void onapCommandExceptionTest2() { + OnapCommandException failed = new OnapCommandException("1", "Test Command Failed", 201); + assertEquals("201::1::Test Command Failed", failed.getMessage()); + } + + @Test + public void onapCommandExecutionFailedTest1() { + OnapCommandExecutionFailed failed = new OnapCommandExecutionFailed("Test", "Test Command Failed", 201); + assertEquals("201::0x0001::Command Test failed to execute, Test Command Failed", failed.getMessage()); + failed = new OnapCommandExecutionFailed("Test", new Exception("Test Command Failed"), 201); + assertEquals("201::0x0001::Command Test failed to execute, Test Command Failed", failed.getMessage()); + } + + @Test + public void onapCommandExecutionFailedTest2() { + OnapCommandExecutionFailed failed = new OnapCommandExecutionFailed("Test Command Failed"); + assertEquals("0x0001::Test Command Failed", failed.getMessage()); + } + + @Test + public void onapCommandExecutionFailedTest3() { + OnapCommandExecutionFailed failed = new OnapCommandExecutionFailed("Test", "Test Command Failed"); + assertEquals("0x0001::Command Test failed to execute, Test Command Failed", failed.getMessage()); + + failed = new OnapCommandExecutionFailed("Test", new Exception("Test Command Failed")); + assertEquals("0x0001::Command Test failed to execute, Test Command Failed", failed.getMessage()); + } + + @Test + public void onapCommandExecutorInfoMissingTest() { + OnapCommandExecutorInfoMissing failed = new OnapCommandExecutorInfoMissing("Test"); + + assertEquals("0x0023::Command Test excutor info is missing from schema", failed.getMessage()); + } + + @Test + public void onapCommandHelpFailedTest() { + OnapCommandHelpFailed failed = new OnapCommandHelpFailed(new Exception("Failed")); + + assertEquals("0x0002::Command failed to print help message, Failed", failed.getMessage()); + } + + @Test + public void onapCommandHttpFailureTest1() { + OnapCommandHttpFailure failed = new OnapCommandHttpFailure("Failed"); + assertEquals("0x0025::Failed", failed.getMessage()); + + failed = new OnapCommandHttpFailure(new Exception("failed"), 201); + assertEquals("201::0x0025::failed", failed.getMessage()); + } + + @Test + public void onapCommandHttpFailureTest2() { + OnapCommandHttpFailure failed = new OnapCommandHttpFailure("Failed", 203); + + assertEquals("203::0x0025::Failed", failed.getMessage()); + } + + @Test + public void onapCommandInvalidParameterTypeTest() { + OnapCommandInvalidParameterType failed = new OnapCommandInvalidParameterType("Failed"); + + assertEquals("0x0003::Parameter type Failed is invalid", failed.getMessage()); + } + + @Test + public void onapCommandInvalidPrintDirectionTest() { + OnapCommandInvalidPrintDirection failed = new OnapCommandInvalidPrintDirection("Direction"); + + assertEquals("0x0004::Print direction Direction is invalid", failed.getMessage()); + } + + @Test + public void onapCommandInvalidRegistrationTest() { + OnapCommandInvalidRegistration failed = new OnapCommandInvalidRegistration(OnapCommandErrorTest.class); + + assertEquals("0x0005::Invalid commad class org.onap.cli.fw.error.OnapCommandErrorTest registration, " + + "it should be derived from org.onap.cli.fw.OnapCommand", failed.getMessage()); + } + + @Test + public void onapCommandInvalidResultAttributeScopeTest() { + OnapCommandInvalidResultAttributeScope failed = new OnapCommandInvalidResultAttributeScope("Attribute"); + + assertEquals("0x0006::Result atrribute Attribute is invalid", failed.getMessage()); + } + + @Test + public void onapCommandInvalidSchemaTest() { + OnapCommandInvalidSchema failed = new OnapCommandInvalidSchema("Schema", "Failed"); + + assertEquals("0x0007::Command schema Schema is invalid, Failed", failed.getMessage()); + } + + @Test + public void onapCommandInvalidSchemaVersionTest() { + OnapCommandInvalidSchemaVersion failed = new OnapCommandInvalidSchemaVersion("1.0"); + + assertEquals("0x0008::Command schema onap_cmd_schema_version 1.0 is invalid or missing", failed.getMessage()); + } + + @Test + public void onapCommandLoginFailedTest1() { + OnapCommandLoginFailed failed = new OnapCommandLoginFailed(new Exception("Failed")); + + assertEquals("0x0009::Login failed, Failed", failed.getMessage()); + } + + @Test + public void onapCommandLoginFailedTest2() { + OnapCommandLoginFailed failed = new OnapCommandLoginFailed("Failed", 201); + + assertEquals("201::0x0009::Login failed, Failed", failed.getMessage()); + } + + @Test + public void onapCommandLogoutFailedTest() { + OnapCommandLogoutFailed failed = new OnapCommandLogoutFailed(new Exception("Failed")); + assertEquals("0x0010::Logout failed, Failed", failed.getMessage()); + + failed = new OnapCommandLogoutFailed(200); + assertEquals("200::0x0010::Logout failed, ", failed.getMessage()); + } + + @Test + public void onapCommandNotFoundTest() { + OnapCommandNotFound failed = new OnapCommandNotFound("Test"); + + assertEquals("0x0011::Command Test is not registered", failed.getMessage()); + } + + @Test + public void onapCommandNotInitializedTest() { + OnapCommandNotInitialized failed = new OnapCommandNotInitialized("Test"); + + assertEquals("0x0012::Command Test is not initialized", failed.getMessage()); + } + + @Test + public void onapCommandOutputPrintingFailedTest() { + OnapCommandOutputPrintingFailed failed = new OnapCommandOutputPrintingFailed(new Exception("error")); + + assertEquals("0x0014::Command is failed to print the result, error", failed.getMessage()); + } + + @Test + public void onapCommandParameterMissingTest() { + OnapCommandParameterMissing failed = new OnapCommandParameterMissing("paramName"); + + assertEquals("0x0015::Parameter paramName is mandatory", failed.getMessage()); + } + + @Test + public void onapCommandParameterNameConflictTest() { + OnapCommandParameterNameConflict failed = new OnapCommandParameterNameConflict("paramName"); + + assertEquals("0x0016::Parameter name paramName is in conflict", failed.getMessage()); + } + + @Test + public void onapCommandParameterOptionConflictTest() { + OnapCommandParameterOptionConflict failed = new OnapCommandParameterOptionConflict("option"); + + assertEquals("0x0017::Parameter option option is in conflict, only one option is allowed with given name", + failed.getMessage()); + } + + @Test + public void onapCommandRegistrationFailedTest() { + OnapCommandRegistrationFailed failed = new OnapCommandRegistrationFailed("Test", "error"); + + assertEquals("0x0018::Command Test is failed to register, error", failed.getMessage()); + } + + @Test + public void onapCommandResultInitialzationFailedTest() { + OnapCommandResultInitialzationFailed failed = new OnapCommandResultInitialzationFailed("Test", + new Exception("error")); + + assertEquals("0x0022::Command Test result format is failed, error", failed.getMessage()); + } + + @Test + public void onapCommandSchemaNotFoundTest() { + OnapCommandSchemaNotFound failed = new OnapCommandSchemaNotFound("Test"); + + assertEquals("0x0019::Command schema Test is not found, ", failed.getMessage()); + } + + @Test + public void onapCommandServiceNotFoundTest() { + OnapCommandServiceNotFound failed = new OnapCommandServiceNotFound("Service"); + + assertEquals("0x0020::Service Service is not found in MSB", failed.getMessage()); + } + + @Test + public void onapCommandOutputFormatNotsupportedTest() { + OnapCommandOutputFormatNotsupported failed = new OnapCommandOutputFormatNotsupported("Format"); + + assertEquals("0x0013::Command does not support the output format Format", failed.getMessage()); + } + +} diff --git a/framework/src/test/java/org/onap/cli/fw/http/HttpInputOutputTest.java b/framework/src/test/java/org/onap/cli/fw/http/HttpInputOutputTest.java new file mode 100644 index 00000000..900d72e8 --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/http/HttpInputOutputTest.java @@ -0,0 +1,67 @@ +/* + * Copyright 2016-17 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.http; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import java.util.HashMap; + +public class HttpInputOutputTest { + + @Test + public void httpInputTest() { + HttpInput inp = new HttpInput(); + inp.setBody("body"); + inp.setMethod("method"); + inp.setReqCookies(null); + inp.setReqHeaders(null); + inp.setReqQueries(null); + inp.setUri("uri"); + + assertTrue("body".equals(inp.getBody()) && "method".equals(inp.getMethod()) && null == inp.getReqCookies() + && inp.getReqHeaders().isEmpty() && inp.getReqQueries().isEmpty() && "uri".equals(inp.getUri())); + + inp.setReqCookies(new HashMap()); + inp.setReqHeaders(new HashMap()); + inp.setReqQueries(new HashMap()); + + assertTrue( + "\nURL: uri\nMethod: method\nRequest Queries: {}\nRequest Body: body\nRequest Headers: {}\nRequest Cookies: {}\nbinaryData=false" + .equals(inp.toString())); + } + + @Test + public void httpResultTest() { + HttpResult out = new HttpResult(); + out.setBody("body"); + out.setRespCookies(null); + out.setRespHeaders(null); + out.setStatus(205); + + assertTrue("body".equals(out.getBody()) && null == out.getRespCookies() && null == out.getRespHeaders() + && 205 == out.getStatus()); + + out.setRespCookies(new HashMap()); + out.setRespHeaders(new HashMap()); + out.setStatus(200); + assertTrue("\nHTTP Status: 200\nResponse Body: body\nResponse Headers: {}\nResponse Cookies: {}" + .equals(out.toString())); + } + +} diff --git a/framework/src/test/java/org/onap/cli/fw/http/OnapHttpConnectionTest.java b/framework/src/test/java/org/onap/cli/fw/http/OnapHttpConnectionTest.java new file mode 100644 index 00000000..cf6d73c1 --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/http/OnapHttpConnectionTest.java @@ -0,0 +1,207 @@ +/* + * 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.http; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import mockit.Invocation; +import mockit.Mock; +import mockit.MockUp; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.protocol.HttpContext; +import org.junit.Before; +import org.junit.Test; +import org.onap.cli.fw.error.OnapCommandHttpFailure; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +public class OnapHttpConnectionTest { + HttpInput inp = null; + OnapHttpConnection con = null; + + @Before + public void setup() { + mockHttpRequest(null); + inp = new HttpInput(); + inp.setMethod("get"); + inp.setBody("body"); + Map map1 = new HashMap<>(); + map1.put("header1", "value1"); + inp.setReqHeaders(map1); + Map map2 = new HashMap<>(); + map2.put("query1", "value1"); + inp.setReqQueries(map2); + Map map = new HashMap<>(); + map.put("cookie1", "value1"); + inp.setReqCookies(map); + inp.setUri("http://192.168.99.10:80"); + } + + @Test(expected = OnapCommandHttpFailure.class) + public void httpUnSecuredGetExceptionTest() throws OnapCommandHttpFailure { + new MockUp() { + @Mock + public CloseableHttpResponse execute(HttpUriRequest request, HttpContext context) + throws IOException, ClientProtocolException { + + throw new IOException("IO Exception"); + } + }; + inp.setMethod("get"); + con = new OnapHttpConnection(false, true); + con.getDebugInfo(); + con.setAuthToken("fdsfdsfs"); + assertTrue("fdsfdsfs".equals(con.getAuthToken())); + con.get(inp); + + } + + @Test(expected = OnapCommandHttpFailure.class) + public void httpUnSecuredPostExceptionTest() throws OnapCommandHttpFailure { + new MockUp() { + @Mock + public CloseableHttpResponse execute(HttpUriRequest request, HttpContext context) + throws IOException, ClientProtocolException { + + throw new IOException("IO Exception"); + } + }; + + inp.setMethod("post"); + con = new OnapHttpConnection(false, true); + con.post(inp); + } + + + @Test(expected = OnapCommandHttpFailure.class) + public void httpUnSecuredPostExceptionTest1() throws OnapCommandHttpFailure { + new MockUp() { + @Mock + public CloseableHttpResponse execute(HttpUriRequest request, HttpContext context) + throws IOException, ClientProtocolException { + + throw new IOException("IO Exception"); + } + }; + + inp.setMethod("post"); + inp.setBinaryData(true); + con = new OnapHttpConnection(false, true); + con.post(inp); + } + + @Test(expected = OnapCommandHttpFailure.class) + public void httpUnSecuredPutExceptionTest() throws OnapCommandHttpFailure { + new MockUp() { + @Mock + public CloseableHttpResponse execute(HttpUriRequest request, HttpContext context) + throws IOException, ClientProtocolException { + + throw new IOException("IO Exception"); + } + }; + inp.setMethod("put"); + con = new OnapHttpConnection(false, true); + con.put(inp); + } + + @Test(expected = OnapCommandHttpFailure.class) + public void httpUnSecuredDeleteExceptionTest() throws OnapCommandHttpFailure { + new MockUp() { + @Mock + public CloseableHttpResponse execute(HttpUriRequest request, HttpContext context) + throws IOException, ClientProtocolException { + + throw new IOException("IO Exception"); + } + }; + inp.setMethod("delete"); + con = new OnapHttpConnection(false, true); + con.delete(inp); + } + + @Test(expected = IllegalArgumentException.class) + public void httpUnSecuredOtherExceptionTest() throws OnapCommandHttpFailure { + new MockUp() { + @Mock + public CloseableHttpResponse execute(HttpUriRequest request, HttpContext context) + throws IOException, ClientProtocolException { + + throw new IOException("IO Exception"); + } + }; + inp.setMethod("other"); + con = new OnapHttpConnection(false, true); + con.request(inp); + } + + @Test() + public void httpUnSecuredCloseExceptionTest() throws OnapCommandHttpFailure { + inp.setMethod("other"); + con = new OnapHttpConnection(false, true); + con.close(); + } + + @Test + public void httpSecuredGetExceptionTest() { + + // ProtocolVersion p = new ProtocolVersion("http",1,0); + // HttpResponse hr = DefaultHttpResponseFactory.INSTANCE.newHttpResponse(p, 200 , null) ; + + new MockUp() { + @Mock + public CloseableHttpResponse execute(HttpUriRequest request, HttpContext context) + throws IOException, ClientProtocolException { + + throw new IOException("IO Exception"); + } + }; + try { + HttpInput inp = new HttpInput(); + inp.setMethod("get"); + inp.setBody("body"); + inp.setReqHeaders(new HashMap()); + inp.setReqQueries(new HashMap()); + inp.setUri("http://192.168.99.10:80"); + OnapHttpConnection con = new OnapHttpConnection(true, false); + con.get(inp); + } catch (OnapCommandHttpFailure e) { + assertEquals("0x0025::IO Exception", e.getMessage()); + } + } + + private static void mockHttpRequest(HttpResult result) { + new MockUp() { + boolean isMock = false; + + @Mock + public HttpResult request(Invocation inv, HttpInput input) throws OnapCommandHttpFailure { + if (isMock) { + return result; + } else { + return inv.proceed(input); + } + } + }; + } +} diff --git a/framework/src/test/java/org/onap/cli/fw/input/OnapCommandParameterTest.java b/framework/src/test/java/org/onap/cli/fw/input/OnapCommandParameterTest.java new file mode 100644 index 00000000..40b07861 --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/input/OnapCommandParameterTest.java @@ -0,0 +1,121 @@ +/* + * 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.input; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandInvalidParameterValue; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +public class OnapCommandParameterTest { + + @Test + public void parameterObjTest() throws OnapCommandInvalidParameterValue { + OnapCommandParameter param = new OnapCommandParameter(); + param.setDefaultValue("defaultValue"); + param.setDescription("description"); + param.setLongOption("longOption"); + param.setName("name"); + param.setOptional(true); + param.setParameterType(ParameterType.JSON); + param.setSecured(false); + param.setShortOption("shortOption"); + param.setValue("value"); + + assertTrue(param.getDefaultValue().equals("defaultValue") && param.getDescription().equals("description") + && param.getLongOption().equals("longOption") && param.getName().equals("name") + && param.getShortOption().equals("shortOption") && param.getValue().equals("value") + && param.isOptional() && !param.isSecured() && param.getParameterType().equals(ParameterType.JSON)); + + assertTrue("value".equals(param.getValue())); + + param.setParameterType(ParameterType.ARRAY); + param.setValue(Arrays.asList("1", "2", "3")); + assertTrue("[\"1\",\"2\",\"3\"]".equals(param.getValue())); + + param.setParameterType(ParameterType.MAP); + Map map = new HashMap<>(); + map.put("One", "1"); + map.put("Two", "2"); + map.put("Three", "3"); + param.setValue(map); + assertTrue("{\"One\":\"1\",\"Two\":\"2\",\"Three\":\"3\"}".equals(param.getValue())); + + param.setDefaultValue("${defaultValue}"); + assertTrue(null == param.getDefaultValue()); + } + + @Test + public void parameterEnvDefaultValueObjTest() { + OnapCommandParameter param = new OnapCommandParameter(); + param.setDefaultValue("${DAFAULT_VALUE}"); + boolean isDefaultValueAnEnv = param.isDefaultValueAnEnv(); + assertTrue(isDefaultValueAnEnv); + + String envValue = param.getEnvVarNameFromDefaultValue(); + + assertTrue("DAFAULT_VALUE".equals(envValue)); + } + + @Test + public void parameterValidateTest() { + OnapCommandParameter param = new OnapCommandParameter(); + param.setOptional(false); + param.setValue(""); + param.setDefaultValue(""); + param.setParameterType(ParameterType.STRING); + try { + param.validate(); + } catch (OnapCommandException e) { + assertTrue("0x0015::Parameter null is mandatory".equals(e.getMessage())); + } + } + + @Test(expected = OnapCommandInvalidParameterValue.class) + public void onapCommandInvalidParameterValueArrayExeceptionTest() throws OnapCommandInvalidParameterValue { + OnapCommandParameter param = new OnapCommandParameter(); + param.setName("name"); + param.setParameterType(ParameterType.ARRAY); + param.setValue("value"); + assertTrue("[\"1\",\"2\",\"3\"]".equals(param.getValue())); + + } + + @Test(expected = OnapCommandInvalidParameterValue.class) + public void onapCommandInvalidParameterValueMapExeceptionTest() throws OnapCommandInvalidParameterValue { + OnapCommandParameter param = new OnapCommandParameter(); + param.setName("name"); + param.setParameterType(ParameterType.MAP); + param.setValue("value"); + assertTrue("{\"One\":\"1\",\"Two\":\"2\",\"Three\":\"3\"}".equals(param.getValue())); + } + + @Test(expected = OnapCommandInvalidParameterValue.class) + public void onapCommandInvalidParameterValueBinaryExeceptionTest() throws OnapCommandException { + OnapCommandParameter param = new OnapCommandParameter(); + param.setName("name"); + param.setParameterType(ParameterType.BINARY); + param.setValue("value"); + param.validate(); + } + +} diff --git a/framework/src/test/java/org/onap/cli/fw/input/ParameterTypeTest.java b/framework/src/test/java/org/onap/cli/fw/input/ParameterTypeTest.java new file mode 100644 index 00000000..eef49ad8 --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/input/ParameterTypeTest.java @@ -0,0 +1,51 @@ +/* + * 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.input; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.junit.Test; +import org.onap.cli.fw.error.OnapCommandInvalidParameterType; + +public class ParameterTypeTest { + @Test + public void paramTypeGetTest() { + + try { + assertTrue(ParameterType.JSON.equals(ParameterType.get("json")) + && ParameterType.YAML.equals(ParameterType.get("yaml")) + && ParameterType.STRING.equals(ParameterType.get("string")) + && ParameterType.LONG.equals(ParameterType.get("long")) + && ParameterType.URL.equals(ParameterType.get("url")) + && ParameterType.BOOL.equals(ParameterType.get("bool")) + && ParameterType.MAP.equals(ParameterType.get("map")) + && ParameterType.BINARY.equals(ParameterType.get("binary")) + && ParameterType.ARRAY.equals(ParameterType.get("array"))); + } catch (OnapCommandInvalidParameterType e) { + fail("Shouldn't have thrown this exception : " + e.getMessage()); + } + + try { + ParameterType.get("name"); + } catch (OnapCommandInvalidParameterType e) { + assertTrue("0x0003::Parameter type name is invalid".equals(e.getMessage())); + } + + } + +} diff --git a/framework/src/test/java/org/onap/cli/fw/log/OnapCommandLoggerTest.java b/framework/src/test/java/org/onap/cli/fw/log/OnapCommandLoggerTest.java new file mode 100644 index 00000000..4b675edc --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/log/OnapCommandLoggerTest.java @@ -0,0 +1,134 @@ +/* + * Copyright 2016-17 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.log; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.Signature; +import org.aspectj.lang.reflect.SourceLocation; +import org.aspectj.runtime.internal.AroundClosure; +import org.junit.Test; + +public class OnapCommandLoggerTest { + + @Test + public void logTest() throws Throwable { + + + ProceedingJoinPoint point = new ProceedingJoinPoint() { + @Override + public String toShortString() { + return null; + } + + @Override + public String toLongString() { + return null; + } + + @Override + public Object getThis() { + return new Object(); + } + + @Override + public Object getTarget() { + return null; + } + + @Override + public StaticPart getStaticPart() { + return null; + } + + @Override + public SourceLocation getSourceLocation() { + return null; + } + + @Override + public Signature getSignature() { + return new Signature(){ + + @Override + public Class getDeclaringType() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getDeclaringTypeName() { + // TODO Auto-generated method stub + return null; + } + + @Override + public int getModifiers() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public String getName() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String toLongString() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String toShortString() { + // TODO Auto-generated method stub + return null; + } + + }; + } + + @Override + public String getKind() { + return null; + } + + @Override + public Object[] getArgs() { + return null; + } + + @Override + public void set$AroundClosure(AroundClosure arg0) { + } + + @Override + public Object proceed(Object[] arg0) throws Throwable { + return null; + } + + @Override + public Object proceed() throws Throwable { + return new Object(); + } + }; + + OnapCommandLogger log = new OnapCommandLogger(); + log.log(point); + } + +} diff --git a/framework/src/test/java/org/onap/cli/fw/output/OnapCommandResultAttributeScopeTest.java b/framework/src/test/java/org/onap/cli/fw/output/OnapCommandResultAttributeScopeTest.java new file mode 100644 index 00000000..ac1a6d33 --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/output/OnapCommandResultAttributeScopeTest.java @@ -0,0 +1,41 @@ +/* + * 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.output; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.onap.cli.fw.input.ParameterType; + +import java.util.Collections; + +public class OnapCommandResultAttributeScopeTest { + @Test + public void onapCommandResultAttributeTest() { + OnapCommandResultAttribute att = new OnapCommandResultAttribute(); + att.setDescription("description"); + att.setName("name"); + att.setScope(OnapCommandResultAttributeScope.LONG); + att.setSecured(true); + att.setType(ParameterType.LONG); + att.setValues(Collections.emptyList()); + assertTrue("description".equals(att.getDescription()) && "name".equals(att.getName()) + && OnapCommandResultAttributeScope.LONG.equals(att.getScope()) + && ParameterType.LONG.equals(att.getType()) && att.getValues().isEmpty()); + } + +} diff --git a/framework/src/test/java/org/onap/cli/fw/output/OnapCommandResultAttributeTest.java b/framework/src/test/java/org/onap/cli/fw/output/OnapCommandResultAttributeTest.java new file mode 100644 index 00000000..6d2612f9 --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/output/OnapCommandResultAttributeTest.java @@ -0,0 +1,44 @@ +/* + * 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.output; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.junit.Test; +import org.onap.cli.fw.error.OnapCommandInvalidResultAttributeScope; + +public class OnapCommandResultAttributeTest { + @Test + public void paramTypeGetTest() { + + try { + assertTrue(OnapCommandResultAttributeScope.LONG.equals(OnapCommandResultAttributeScope.get("long")) + && OnapCommandResultAttributeScope.SHORT.equals(OnapCommandResultAttributeScope.get("short"))); + } catch (OnapCommandInvalidResultAttributeScope e) { + fail("Shouldn't have thrown this exception : " + e.getMessage()); + } + + try { + OnapCommandResultAttributeScope.get("name"); + } catch (OnapCommandInvalidResultAttributeScope e) { + assertTrue("0x0006::Result atrribute name is invalid".equals(e.getMessage())); + } + + } + +} diff --git a/framework/src/test/java/org/onap/cli/fw/output/OnapCommandResultTest.java b/framework/src/test/java/org/onap/cli/fw/output/OnapCommandResultTest.java new file mode 100644 index 00000000..dddab1bc --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/output/OnapCommandResultTest.java @@ -0,0 +1,208 @@ +/* + * 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.output; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Ignore; +import org.junit.Test; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.input.ParameterType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class OnapCommandResultTest { + + @Test + public void commandResultObjTest() throws OnapCommandException { + OnapCommandResult res = new OnapCommandResult(); + res.setDebugInfo("debugInfo"); + res.setIncludeSeparator(true); + res.setIncludeTitle(true); + res.setOutput("Output"); + res.setPrintDirection(PrintDirection.LANDSCAPE); + res.setRecords(new ArrayList()); + res.setScope(OnapCommandResultAttributeScope.LONG); + res.setType(ResultType.TABLE); + res.setDebug(true); + + assertTrue("debugInfo".equals(res.getDebugInfo()) && res.isIncludeSeparator() + && "Output".equals(res.getOutput()) && PrintDirection.LANDSCAPE.equals(res.getPrintDirection()) + && res.getRecords().isEmpty() && OnapCommandResultAttributeScope.LONG.equals(res.getScope()) + && ResultType.TABLE.equals(res.getType())); + + String help = res.print(); + + assertTrue("".equals(help)); + + } + + @Test + public void commandResultPrintLandscapeTableTest() throws OnapCommandException { + OnapCommandResult res = new OnapCommandResult(); + res.setDebugInfo("debugInfo"); + res.setIncludeSeparator(true); + res.setIncludeTitle(true); + res.setOutput("Output"); + res.setPrintDirection(PrintDirection.LANDSCAPE); + + OnapCommandResultAttribute att = new OnapCommandResultAttribute(); + att.setName("param"); + att.setDescription("description"); + att.setType(ParameterType.STRING); + att.setValues(new ArrayList(Arrays.asList(new String[] { "value" }))); + List list = new ArrayList(); + list.add(att); + res.setRecords(list); + res.setScope(OnapCommandResultAttributeScope.LONG); + res.setType(ResultType.TABLE); + res.getRecordsMap(); + String expRes = "+--------+\n|param |\n+--------+\n|value |\n+--------+\n"; + String result = res.print(); + + assertEquals(expRes, result); + + } + + @Test + public void commandResultPrintLandscapeJsonTest() throws OnapCommandException { + OnapCommandResult res = new OnapCommandResult(); + res.setDebugInfo("debugInfo"); + res.setIncludeSeparator(true); + res.setIncludeTitle(true); + res.setOutput("Output"); + res.setPrintDirection(PrintDirection.LANDSCAPE); + + OnapCommandResultAttribute att = new OnapCommandResultAttribute(); + att.setName("param"); + att.setDescription("description"); + att.setType(ParameterType.JSON); + att.setValues( + new ArrayList(Arrays.asList(new String[] { "{\"id\": \"0001\",\"value\": \"result\"}" }))); + List list = new ArrayList(); + list.add(att); + res.setRecords(list); + res.setScope(OnapCommandResultAttributeScope.LONG); + res.setType(ResultType.JSON); + + // Will be handled after the json print is implemented + String result = res.print(); + // String expRes = "+--------+\n|param |\n+--------+\n|value + // |\n+--------+\n"; + // assertEquals(expRes,result); + + } + + @Test + @Ignore + public void commandResultPrintLandscapeCsvTest() throws OnapCommandException { + OnapCommandResult res = new OnapCommandResult(); + res.setDebugInfo("debugInfo"); + res.setIncludeSeparator(true); + res.setIncludeTitle(true); + res.setOutput("Output"); + res.setPrintDirection(PrintDirection.LANDSCAPE); + + OnapCommandResultAttribute att = new OnapCommandResultAttribute(); + att.setName("param"); + att.setDescription("description"); + att.setType(ParameterType.STRING); + att.setValues(new ArrayList(Arrays.asList(new String[] { "value" }))); + List list = new ArrayList(); + list.add(att); + OnapCommandResultAttribute a1 = new OnapCommandResultAttribute(); + a1.setName("param1"); + a1.setDescription("description1"); + a1.setType(ParameterType.STRING); + a1.setValues(new ArrayList(Arrays.asList(new String[] { "value1" }))); + + list.add(a1); + res.setRecords(list); + res.setScope(OnapCommandResultAttributeScope.LONG); + res.setType(ResultType.CSV); + + String expRes = "param,param1\r\n"; + String result = res.print(); + assertEquals(expRes, result); + + } + + @Test + @Ignore + public void commandResultPrintPortraitCsvTest() throws OnapCommandException { + OnapCommandResult res = new OnapCommandResult(); + res.setDebugInfo("debugInfo"); + res.setIncludeSeparator(true); + res.setIncludeTitle(true); + res.setOutput("Output"); + res.setPrintDirection(PrintDirection.PORTRAIT); + + OnapCommandResultAttribute att = new OnapCommandResultAttribute(); + att.setName("param"); + att.setDescription("description"); + att.setType(ParameterType.STRING); + att.setValues(new ArrayList(Arrays.asList(new String[] { "value" }))); + List list = new ArrayList(); + list.add(att); + OnapCommandResultAttribute a1 = new OnapCommandResultAttribute(); + a1.setName("param1"); + a1.setDescription("description1"); + a1.setType(ParameterType.STRING); + a1.setValues(new ArrayList(Arrays.asList(new String[] { "value1" }))); + + list.add(a1); + res.setRecords(list); + res.setScope(OnapCommandResultAttributeScope.LONG); + res.setType(ResultType.CSV); + String expRes = "property,value\r\nparam,value\r\n"; + String result = res.print(); + assertEquals(expRes, result); + } + + @Test + public void commandResultPrintPortraitTableTest() throws OnapCommandException { + OnapCommandResult res = new OnapCommandResult(); + res.setDebugInfo("debugInfo"); + res.setIncludeSeparator(true); + res.setIncludeTitle(true); + res.setOutput("Output"); + res.setPrintDirection(PrintDirection.PORTRAIT); + + OnapCommandResultAttribute att = new OnapCommandResultAttribute(); + att.setName("param"); + att.setDescription("description"); + att.setType(ParameterType.STRING); + att.setValues(new ArrayList(Arrays.asList(new String[] { "value" }))); + + List list = new ArrayList(); + list.add(att); + res.setRecords(list); + res.setScope(OnapCommandResultAttributeScope.LONG); + res.setType(ResultType.TABLE); + String expRes = "+----------+--------+\n|property |value |\n+----------+--------+" + + "\n|param |value |\n+----------+--------+\n"; + + String result = res.print(); + + assertEquals(expRes, result); + + } + +} diff --git a/framework/src/test/java/org/onap/cli/fw/output/PrintDirectionTest.java b/framework/src/test/java/org/onap/cli/fw/output/PrintDirectionTest.java new file mode 100644 index 00000000..0aa82979 --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/output/PrintDirectionTest.java @@ -0,0 +1,43 @@ +/* + * 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.output; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.junit.Test; +import org.onap.cli.fw.error.OnapCommandInvalidPrintDirection; + +public class PrintDirectionTest { + @Test + public void printDirectionGetTest() { + + try { + assertTrue(PrintDirection.LANDSCAPE.equals(PrintDirection.get("landscape")) + && PrintDirection.PORTRAIT.equals(PrintDirection.get("portrait"))); + } catch (OnapCommandInvalidPrintDirection e) { + fail("Shouldn't have thrown this exception : " + e.getMessage()); + } + + try { + PrintDirection.get("name"); + } catch (OnapCommandInvalidPrintDirection e) { + assertTrue("0x0004::Print direction name is invalid".equals(e.getMessage())); + } + + } +} diff --git a/framework/src/test/java/org/onap/cli/fw/output/ResultTypeTest.java b/framework/src/test/java/org/onap/cli/fw/output/ResultTypeTest.java new file mode 100644 index 00000000..3c4c5665 --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/output/ResultTypeTest.java @@ -0,0 +1,42 @@ +/* + * 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.output; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class ResultTypeTest { + @Test + public void resultTypeGetTest() { + assertTrue(ResultType.TABLE.equals(ResultType.get("table")) && ResultType.CSV.equals(ResultType.get("csv")) + && ResultType.JSON.equals(ResultType.get("json")) && ResultType.YAML.equals(ResultType.get("yaml")) + && ResultType.TEXT.equals(ResultType.get("text"))); + + } + + @Test + public void isTabularFormTest() { + assertTrue(ResultType.isTabularForm("table")); + } + + @Test + public void isTabularFormNotTest() { + assertFalse(ResultType.isTabularForm("text")); + } +} diff --git a/framework/src/test/java/org/onap/cli/fw/output/print/OnapCommandPrintTest.java b/framework/src/test/java/org/onap/cli/fw/output/print/OnapCommandPrintTest.java new file mode 100644 index 00000000..ae17d6d4 --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/output/print/OnapCommandPrintTest.java @@ -0,0 +1,82 @@ +/* + * 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.output.print; + +import static org.junit.Assert.assertEquals; + +import org.junit.Ignore; +import org.junit.Test; +import org.onap.cli.fw.error.OnapCommandOutputPrintingFailed; +import org.onap.cli.fw.output.PrintDirection; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class OnapCommandPrintTest { + + @Test + @Ignore + public void printCsvTest() throws OnapCommandOutputPrintingFailed { + OnapCommandPrint pr = new OnapCommandPrint(); + pr.setDirection(PrintDirection.LANDSCAPE); + pr.setPrintTitle(true); + pr.addColumn("name1", new ArrayList(Arrays.asList(new String[] { "value1" }))); + String exp = "name1\r\n"; + String result = pr.printCsv(); + assertEquals(exp, result); + } + + @Test + public void printTableTest() throws OnapCommandOutputPrintingFailed { + OnapCommandPrint pr = new OnapCommandPrint(); + List getColumnsData = new ArrayList(); + pr.setDirection(PrintDirection.LANDSCAPE); + pr.setPrintTitle(true); + pr.addColumn("name2", new ArrayList(Arrays.asList(new String[] { "value2" }))); + String exp = "+--------+\n|name2 |\n+--------+\n|value2 |\n+--------+\n"; + String result = pr.printTable(true); + getColumnsData = pr.getColumn("name2"); + assertEquals(exp, result); + } + + @Test + public void printTableNullColumnHeaderTest() throws OnapCommandOutputPrintingFailed { + OnapCommandPrint pr = new OnapCommandPrint(); + List getColumnsData = new ArrayList(); + pr.setDirection(PrintDirection.LANDSCAPE); + pr.setPrintTitle(true); + pr.addColumn("name2", new ArrayList(Arrays.asList(new String[] { "value2" }))); + String exp = "+--------+\n|name2 |\n+--------+\n|value2 |\n+--------+\n"; + String result = pr.printTable(true); + getColumnsData = pr.getColumn(null); + assertEquals(exp, result); + } + + @Test + public void printTableEmptyColumnValuesTest() throws OnapCommandOutputPrintingFailed { + OnapCommandPrint pr = new OnapCommandPrint(); + List getColumnsData = new ArrayList(); + pr.setDirection(PrintDirection.LANDSCAPE); + pr.setPrintTitle(true); + pr.addColumn("name2", new ArrayList(Arrays.asList(new String[] { "" }))); + String exp = "+--------+\n|name2 |\n+--------+\n| |\n+--------+\n"; + String result = pr.printTable(true); + getColumnsData = pr.getColumn("name2"); + assertEquals(exp, result); + } +} diff --git a/framework/src/test/java/org/onap/cli/fw/output/print/TableGeneratorTest.java b/framework/src/test/java/org/onap/cli/fw/output/print/TableGeneratorTest.java new file mode 100644 index 00000000..f9ae0717 --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/output/print/TableGeneratorTest.java @@ -0,0 +1,185 @@ +/* + * 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.output.print; + +import static org.junit.Assert.assertEquals; + +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class TableGeneratorTest { + private TableGenerator table; + + @Before + public void setUp() throws Exception { + this.table = new TableGenerator(); + } + + @Test + public void printTableNoColumnTest() { + System.out.println("printTableNoColumnTest..."); + List row = new ArrayList(); + List> rows = new ArrayList>(); + rows.add(row); + String result = table.generateTable(rows, true); + System.out.println(result); + String expected = "\n\n\n"; + assertEquals(expected, result); + } + + @Test + public void printTableNoCellTest() { + System.out.println("printTableNoCellTest..."); + List> rows = new ArrayList>(); + rows.add(Arrays.asList(new Object[] { "column1", "column2" })); + String result = table.generateTable(rows, true); + System.out.println(result); + String expected = "+----------+----------+\n|column1 |column2 |\n+----------+----------+\n"; + assertEquals(expected, result); + } + + @Test + public void printTableNullCellTest() { + + System.out.println("printTableNullCellTest..."); + List> rows = new ArrayList>(); + rows.add(Arrays.asList(new Object[] { "column1", "column2" })); + rows.add(Arrays.asList(new Object[] { "value1", null })); + String result = table.generateTable(rows, true); + System.out.println(result); + String expected = "+----------+----------+\n" + "|column1 |column2 |\n" + "+----------+----------+\n" + + "|value1 | |\n" + "+----------+----------+\n"; + assertEquals(expected, result); + + } + + @Test + public void printTableEmptyCellTest() { + System.out.println("printTableEmptyCellTest..."); + List> rows = new ArrayList>(); + rows.add(Arrays.asList(new Object[] { "column1", "column2" })); + rows.add(Arrays.asList(new Object[] { "value1", "" })); + String result = table.generateTable(rows, true); + System.out.println(result); + String expected = "+----------+----------+\n" + "|column1 |column2 |\n" + "+----------+----------+\n" + + "|value1 | |\n" + "+----------+----------+\n"; + assertEquals(expected, result); + } + + @Test + public void printTableNoCellBreakTest() { + System.out.println("printTableNoCellBreakTest..."); + List> rows = new ArrayList>(); + rows.add(Arrays.asList(new Object[] { "column1", "column2" })); + rows.add(Arrays.asList(new Object[] { "value1", "value2" })); + String result = table.generateTable(rows, true); + System.out.println(result); + String expected = "+----------+----------+\n" + "|column1 |column2 |\n" + "+----------+----------+\n" + + "|value1 |value2 |\n" + "+----------+----------+\n"; + assertEquals(expected, result); + } + + @Test + public void printTableCellBreakTest() { + System.out.println("printTableCellBreakTest..."); + List> rows = new ArrayList>(); + rows.add(Arrays.asList(new Object[] { "column1", "column2" })); + List list = new ArrayList(); + list.add("value1"); + list.add(new ArrayList( + Arrays.asList(new Object[] { "1234567891234567891234567891234567891234", "56789" }))); + rows.add(list); + String result = table.generateTable(rows, true); + System.out.println(result); + String expected = "+----------+------------------------------------------+\n" + + "|column1 |column2 |\n" + + "+----------+------------------------------------------+\n" + + "|value1 |1234567891234567891234567891234567891234 |\n" + + "| |56789 |\n" + + "+----------+------------------------------------------+\n"; + assertEquals(expected, result); + } + + @Test + public void printTableTwoCellBreakInSameRowTest() { + System.out.println("printTableTwoCellBreakInSameRowTest..."); + List> rows = new ArrayList>(); + rows.add(Arrays.asList(new Object[] { "column1", "column2" })); + List list = new ArrayList(); + list.add(new ArrayList( + Arrays.asList(new Object[] { "1234567891234567891234567891234567891234", "56789" }))); + list.add(new ArrayList( + Arrays.asList(new Object[] { "1234567891234567891234567891234567891234", "56789", "00" }))); + rows.add(list); + String result = table.generateTable(rows, true); + System.out.println(result); + String expected = "+------------------------------------------+------------------------------------------+\n" + + "|column1 |column2 |\n" + + "+------------------------------------------+------------------------------------------+\n" + + "|1234567891234567891234567891234567891234 |1234567891234567891234567891234567891234 |\n" + + "|56789 |56789 |\n" + + "| |00 |\n" + + "+------------------------------------------+------------------------------------------+\n"; + assertEquals(expected, result); + } + + @Test + public void printTableTwoCellBreakInDifferentRowTest() { + System.out.println("printTableTwoCellBreakInSameRowTest..."); + List> rows = new ArrayList>(); + rows.add(Arrays.asList(new Object[] { "column1", "column2" })); + List list1 = new ArrayList(); + list1.add("value1"); + list1.add(new ArrayList( + Arrays.asList(new Object[] { "1234567891234567891234567891234567891234", "56789" }))); + rows.add(list1); + List list2 = new ArrayList(); + list2.add(new ArrayList( + Arrays.asList(new Object[] { "1234567891234567891234567891234567891234", "hi" }))); + + list2.add("value2"); + rows.add(list2); + String result = table.generateTable(rows, true); + System.out.println(result); + String expected = "+------------------------------------------+------------------------------------------+\n" + + "|column1 |column2 |\n" + + "+------------------------------------------+------------------------------------------+\n" + + "|value1 |1234567891234567891234567891234567891234 |\n" + + "| |56789 |\n" + + "+------------------------------------------+------------------------------------------+\n" + + "|1234567891234567891234567891234567891234 |value2 |\n" + + "|hi | |\n" + + "+------------------------------------------+------------------------------------------+\n"; + assertEquals(expected, result); + } + + @Test + public void printTableWithoutPrintSeparatorTest() { + System.out.println("printTableWithoutPrintSeparatorTest..."); + List> rows = new ArrayList>(); + rows.add(Arrays.asList(new Object[] { "column1", "column2" })); + rows.add(Arrays.asList(new Object[] { "value1", "value2" })); + String result = table.generateTable(rows, false); + System.out.println(result); + String expected = "column1 column2 \nvalue1 value2 \n"; + assertEquals(expected, result); + } +} diff --git a/framework/src/test/java/org/onap/cli/fw/run/OnapCommandExecutorTest.java b/framework/src/test/java/org/onap/cli/fw/run/OnapCommandExecutorTest.java new file mode 100644 index 00000000..1236365c --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/run/OnapCommandExecutorTest.java @@ -0,0 +1,38 @@ +/* + * 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.run; + +import org.junit.Assert; +import org.junit.Test; + +public class OnapCommandExecutorTest { + + @Test + public void commandExecutorTest() { + OnapCommandExecutor exec = new OnapCommandExecutor(); + exec.setApi("api"); + exec.setClient("client"); + exec.setEntity("entity"); + exec.setException("exception"); + exec.setMethod("method"); + + Assert.assertTrue( + exec.getApi().equals("api") && exec.getClient().equals("client") && exec.getEntity().equals("entity") + && exec.getMethod().equals("method") && exec.getException().equals("exception")); + } + +} diff --git a/framework/src/test/java/org/onap/cli/fw/schema/ValidateSchemaTest.java b/framework/src/test/java/org/onap/cli/fw/schema/ValidateSchemaTest.java new file mode 100644 index 00000000..4c48683b --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/schema/ValidateSchemaTest.java @@ -0,0 +1,103 @@ +/* + * 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.junit.Test; +import org.onap.cli.fw.error.OnapCommandInvalidSchema; +import org.yaml.snakeyaml.scanner.ScannerException; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashSet; + +public class ValidateSchemaTest { + + @Test(expected = OnapCommandInvalidSchema.class) + public void invalidateTest1() throws OnapCommandInvalidSchema { + new SchemaValidator(new File("fdsfds")); + new SchemaValidator(new File("fdsfds.yaml")); + } + + @Test(expected = OnapCommandInvalidSchema.class) + public void invalidateTest2() throws OnapCommandInvalidSchema { + new SchemaValidator(new File("fdsfds")); + } + + @Test(expected = OnapCommandInvalidSchema.class) + public void invalidateTest4() throws OnapCommandInvalidSchema { + new SchemaValidator( + new File(ValidateSchemaTest.class.getClassLoader().getResource("onap.properties").getFile())); + } + + @Test(expected = OnapCommandInvalidSchema.class) + public void invalidateTest5() throws OnapCommandInvalidSchema { + new SchemaValidator(new File( + ValidateSchemaTest.class.getClassLoader().getResource("schema-invalid-file-null.yaml").getFile())); + } + + @Test + public void invalidate1Test5() throws OnapCommandInvalidSchema { + new SchemaValidator("schema-validate-pass.yaml"); + } + + @Test(expected = ScannerException.class) + public void invalidateTest3() throws OnapCommandInvalidSchema { + new SchemaValidator( + new File(ValidateSchemaTest.class.getClassLoader().getResource("schema-invalid-file.yaml").getFile())); + } + + @Test + public void validateTest() throws OnapCommandInvalidSchema { + new SchemaValidator( + new File(ValidateSchemaTest.class.getClassLoader().getResource("schema-validate-http.yaml").getFile())) + .validate(); + + new SchemaValidator( + new File(ValidateSchemaTest.class.getClassLoader().getResource("schema-validate-basic.yaml").getFile())) + .validate(); + new SchemaValidator(new File(ValidateSchemaTest.class.getClassLoader() + .getResource("schema-validate-invalidschematype.yaml").getFile())).validate(); + new SchemaValidator( + new File(ValidateSchemaTest.class.getClassLoader().getResource("schema-validate-invalid.yaml").getFile())) + .validate(); + new SchemaValidator( + new File(ValidateSchemaTest.class.getClassLoader().getResource("schema-validate-pass.yaml").getFile())) + .validate(); + + } + + @Test + public void schemaValidateInterfaceTest() throws OnapCommandInvalidSchema { + SchemaValidate.attributeNameExist("name", "section"); + SchemaValidate.emptyValue("section", "attribute"); + SchemaValidate.defaultYamlSchema("section"); + SchemaValidate.emptySection("section"); + SchemaValidate.invalidAttributeScope("name", new ArrayList()); + SchemaValidate.invalidAttrType("name", "section", new ArrayList()); + SchemaValidate.invalidBooleanValueMessage("section", "attribute", "value"); + SchemaValidate.invalidRequestParam("subSection", "attribute"); + SchemaValidate.invalidSections(new HashSet(), new ArrayList(), new ArrayList()); + SchemaValidate.attributeScopeEmpty("fsdf"); + SchemaValidate.invalidType("section", "attribute", new ArrayList()); + SchemaValidate.longOptionExist("name"); + SchemaValidate.shortOptionExist("name"); + SchemaValidate.optionExist("option", "attrValue", "name"); + SchemaValidate.optionDefaultExist("option", "attrValue", "name", new HashSet()); + SchemaValidate.nameExist("name", "section"); + SchemaValidate.mandatoryAttrEmpty("param", "section"); + } +} diff --git a/framework/src/test/java/org/onap/cli/fw/utils/FileUtil.java b/framework/src/test/java/org/onap/cli/fw/utils/FileUtil.java new file mode 100644 index 00000000..7da6230f --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/utils/FileUtil.java @@ -0,0 +1,55 @@ +/* + * 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.utils; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; + +public class FileUtil { + + /** + * Load file. + * @param srcName dir + * @return string + * @throws IOException exception + */ + public static String loadResource(String srcName) throws IOException { + ClassLoader classLoader = FileUtil.class.getClassLoader(); + File file = new File(classLoader.getResource(srcName).getFile()); + BufferedReader br = new BufferedReader(new FileReader(file)); + StringBuilder sb = new StringBuilder(""); + if (br != null) { + try { + + String line = br.readLine(); + + while (line != null) { + sb.append(line); + sb.append("\n"); + line = br.readLine(); + } + } finally { + br.close(); + } + } + + return sb.toString(); + + } +} diff --git a/framework/src/test/java/org/onap/cli/fw/utils/OnapCommandUtilsTest.java b/framework/src/test/java/org/onap/cli/fw/utils/OnapCommandUtilsTest.java new file mode 100644 index 00000000..b74027a0 --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/utils/OnapCommandUtilsTest.java @@ -0,0 +1,481 @@ +/* + * 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.utils; + + + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import mockit.Invocation; +import mockit.Mock; +import mockit.MockUp; + +import org.junit.FixMethodOrder; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runners.MethodSorters; +import org.onap.cli.fw.OnapCommand; +import org.onap.cli.fw.OnapCommandSchema; +import org.onap.cli.fw.ad.OnapCredentials; +import org.onap.cli.fw.cmd.OnapHttpCommand; +import org.onap.cli.fw.cmd.OnapSwaggerCommand; +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.OnapCommandInvalidParameterType; +import org.onap.cli.fw.error.OnapCommandInvalidPrintDirection; +import org.onap.cli.fw.error.OnapCommandInvalidResultAttributeScope; +import org.onap.cli.fw.error.OnapCommandInvalidSchema; +import org.onap.cli.fw.error.OnapCommandInvalidSchemaVersion; +import org.onap.cli.fw.error.OnapCommandParameterNameConflict; +import org.onap.cli.fw.error.OnapCommandParameterNotFound; +import org.onap.cli.fw.error.OnapCommandParameterOptionConflict; +import org.onap.cli.fw.error.OnapCommandSchemaNotFound; +import org.onap.cli.fw.http.HttpInput; +import org.onap.cli.fw.http.HttpResult; +import org.onap.cli.fw.input.OnapCommandParameter; +import org.onap.cli.fw.input.ParameterType; +import org.onap.cli.fw.output.OnapCommandResult; +import org.onap.cli.fw.run.OnapCommandExecutor; +import org.springframework.core.io.Resource; + + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class OnapCommandUtilsTest { + + @Test(expected = OnapCommandSchemaNotFound.class) + public void onapCommandUtilsInputStreamNullTest() throws OnapCommandException { + OnapCommandUtils.validateSchemaVersion("sample-test1-schema-http1.yaml", "1.0"); + } + + @Test + public void onapCommandUtilsInputStreamNotNullTest() throws OnapCommandException { + Map map = OnapCommandUtils.validateSchemaVersion("sample-test1-schema-http.yaml", "1.0"); + assertTrue(map != null); + } + + @Test + public void externalSchemaTest() { + ExternalSchema schema = new ExternalSchema(); + schema.setCmdName("cmdName"); + schema.setSchemaName("schemaName"); + schema.setVersion("version"); + + assertTrue("cmdName".equals(schema.getCmdName()) && "schemaName".equals(schema.getSchemaName()) + && "version".equals(schema.getVersion())); + } + + @Test + public void schemaFileNotFoundTest() throws OnapCommandException { + + Map map = OnapCommandUtils.validateSchemaVersion("sample-test-schema.yaml", "1.0"); + assertTrue(map.size() > 0); + } + + @Test + @Ignore + public void invalidSchemaFileTest() throws OnapCommandException { + Map map = null; + try { + map = OnapCommandUtils.validateSchemaVersion("sample-test-schema1.yaml", "1.0"); + } catch (OnapCommandInvalidSchemaVersion e) { + fail("Test should not have thrown this exception : " + e.getMessage()); + } catch (OnapCommandInvalidSchema e) { + fail("Test should not have thrown this exception : " + e.getMessage()); + } catch (OnapCommandSchemaNotFound e) { + assertEquals("0x0019::Command schema sample-test-schema1.yaml is not found", e.getMessage()); + } + } + + @Test + public void validateWrongSchemaVersionTest() throws OnapCommandException { + Map map = null; + try { + map = OnapCommandUtils.validateSchemaVersion("sample-test-invalid-schema.yaml", "1.0"); + } catch (OnapCommandInvalidSchemaVersion e) { + fail("Test should not have thrown this exception : " + e.getMessage()); + } catch (OnapCommandInvalidSchema e) { + assertTrue(e.getMessage().contains("0x0007::Command schema sample-test-invalid-schema.yaml is invalid")); + } catch (OnapCommandSchemaNotFound e) { + fail("Test should not have thrown this exception : " + e.getMessage()); + } + } + + @Test + public void validateSchemaVersionTest() throws OnapCommandException { + Map map = null; + try { + map = OnapCommandUtils.validateSchemaVersion("sample-test-schema.yaml", "1.1"); + } catch (OnapCommandInvalidSchemaVersion e) { + assertEquals("0x0008::Command schema onap_cmd_schema_version 1.0 is invalid or missing", e.getMessage()); + } catch (OnapCommandInvalidSchema e) { + fail("Test should not have thrown this exception : " + e.getMessage()); + } catch (OnapCommandSchemaNotFound e) { + fail("Test should not have thrown this exception : " + e.getMessage()); + } + } + + @Test + public void loadOnapCommandSchemaWithOutDefaultTest() throws OnapCommandException { + OnapCommand cmd = new OnapCommandSample(); + OnapCommandUtils.loadSchema(cmd, "sample-test-schema.yaml", false); + assertTrue("sample-test".equals(cmd.getName()) && cmd.getParameters().size() == 9); + } + + @Test(expected = OnapCommandParameterNameConflict.class) + public void loadOnapCommandSchemaWithDuplicateNameTest() throws OnapCommandException { + OnapCommand cmd = new OnapCommandSample(); + OnapCommandUtils.loadSchema(cmd, "sample-test-invalid-schema-duplicate-name.yaml", false); + } + + @Test(expected = OnapCommandParameterOptionConflict.class) + public void loadOnapCommandSchemaWithDuplicateShortOptionTest() throws OnapCommandException { + OnapCommand cmd = new OnapCommandSample(); + OnapCommandUtils.loadSchema(cmd, "sample-test-invalid-schema-duplicate-shortoption.yaml", false); + } + + @Test(expected = OnapCommandParameterOptionConflict.class) + public void loadOnapCommandSchemaWithDuplicateLongOptionTest() throws OnapCommandException { + OnapCommand cmd = new OnapCommandSample(); + OnapCommandUtils.loadSchema(cmd, "sample-test-invalid-schema-duplicate-longoption.yaml", false); + } + + @Test + public void loadOnapCommandSchemaWithDefaultTest() throws OnapCommandException { + OnapCommand cmd = new OnapCommandSample(); + OnapCommandUtils.loadSchema(cmd, "sample-test-schema.yaml", true); + assertTrue("sample-test".equals(cmd.getName()) && cmd.getParameters().size() > 9); + + for (OnapCommandParameter com : cmd.getParameters()) { + com.setValue("value"); + } + + OnapCredentials cre = OnapCommandUtils.fromParameters(cmd.getParameters()); + assertTrue(cre != null); + Map map = OnapCommandUtils.getInputMap(cmd.getParameters()); + assertTrue(map.size() == 19); + } + + @Test + public void loadSwaggerBasedSchemaExceptionTest() throws OnapCommandException { + OnapSwaggerCommand cmd = new OnapSwaggerBasedCommandSample(); + try { + OnapCommandUtils.loadSchema(cmd, "sample-test-schema.yaml"); + } catch (OnapCommandInvalidSchema e) { + assertTrue(e.getMessage().contains("0x0007::Command schema sample-test-schema.yaml is invalid")); + } + } + + @Test + public void loadSwaggerBasedSchemaTest() throws OnapCommandException { + OnapSwaggerCommand cmd = new OnapSwaggerBasedCommandSample(); + try { + OnapCommandUtils.loadSchema(cmd, "sample-test-schema-swagger.yaml"); + OnapCommandExecutor exe = cmd.getExecutor(); + assertTrue(exe != null); + } catch (OnapCommandInvalidSchema e) { + assertTrue(e.getMessage().contains("0x0007::Command schema sample-test-schema.yaml is invalid")); + } + } + + @Test + public void loadHttpBasedSchemaExceptionTest() throws OnapCommandException { + OnapHttpCommand cmd = new OnapHttpCommandSample(); + cmd.setName("sample-test-http"); + try { + OnapCommandUtils.loadSchema(cmd, "sample-test-schema.yaml"); + } catch (OnapCommandParameterNameConflict | OnapCommandParameterOptionConflict + | OnapCommandInvalidParameterType | OnapCommandInvalidPrintDirection + | OnapCommandInvalidResultAttributeScope | OnapCommandSchemaNotFound | OnapCommandInvalidSchema + | OnapCommandInvalidSchemaVersion e) { + assertTrue(e.getMessage().contains("0x0007::Command schema sample-test-schema.yaml is invalid")); + } + } + + @Test + public void loadHttpBasedSchemaTest() throws OnapCommandException { + OnapHttpCommand cmd = new OnapHttpCommandSample(); + cmd.setName("sample-create-http"); + try { + OnapCommandUtils.loadSchema(cmd, "sample-test-schema-http.yaml"); + assertTrue(cmd.getSuccessStatusCodes().size() == 2); + } catch (OnapCommandParameterNameConflict | OnapCommandParameterOptionConflict + | OnapCommandInvalidParameterType | OnapCommandInvalidPrintDirection + | OnapCommandInvalidResultAttributeScope | OnapCommandSchemaNotFound | OnapCommandInvalidSchema + | OnapCommandInvalidSchemaVersion e) { + fail("Test should not have thrown this exception : " + e.getMessage()); + } + } + + @Test + public void helpCommandTest() throws IOException, OnapCommandException { + OnapCommand cmd = new OnapCommandSample(); + OnapCommandUtils.loadSchema(cmd, "sample-test-schema.yaml", true); + + String actualResult = OnapCommandUtils.help(cmd); + + String expectedHelp = FileUtil.loadResource("sample-cmd-test-help.txt"); + } + + @Test + public void findOnapCommandsTest() { + List> cmds = OnapCommandUtils.findOnapCommands(); + assertTrue(cmds.size() == 3); + } + + @Test + public void sortTest() { + Set set = new HashSet(); + set.add("dbvc"); + set.add("bbvcb"); + set.add("aaa"); + set.add("c"); + set.add("z"); + List list = OnapCommandUtils.sort(set); + assertEquals("[aaa, bbvcb, c, dbvc, z]", list.toString()); + } + + @Test + public void jsonFlattenTest() { + List list = Arrays.asList(new String[] { "{\"menu1\": {\"id\": \"file1\",\"value\": \"File1\"}}" }); + List list1 = OnapCommandUtils.jsonFlatten(list); + String expected = "[{\"menu1\":{\"id\":\"file1\",\"value\":\"File1\"}}]"; + assertEquals(expected, list1.toString()); + + } + + @Test + public void jsonFlattenExceptionTest() { + List list = Arrays.asList(new String[] { "{\"menu1\"::{\"id\":\"file1\",\"value\":\"File1\"}}" }); + List list1 = OnapCommandUtils.jsonFlatten(list); + String expected = "[{\"menu1\"::{\"id\":\"file1\",\"value\":\"File1\"}}]"; + assertEquals(expected, list1.toString()); + + } + + @Test + public void formMethodNameFromAttributeTest() { + + String str = ""; + String name = OnapCommandUtils.formMethodNameFromAttributeName(str, "test"); + + assertEquals("", name); + + str = null; + name = OnapCommandUtils.formMethodNameFromAttributeName(str, "test"); + + assertEquals(null, name); + + str = "test-get"; + name = OnapCommandUtils.formMethodNameFromAttributeName(str, ""); + assertEquals("TestGet", name); + + } + + @Test + public void populateParametersTest() throws OnapCommandException { + + HttpInput input = new HttpInput(); + input.setBody("body"); + input.setMethod("method"); + Map mapHead = new HashMap<>(); + mapHead.put("key2", "${value2}"); + input.setReqHeaders(mapHead); + Map query = new HashMap<>(); + query.put("key3", "{${value3}}"); + input.setReqQueries(query); + input.setUri("uri"); + + Map params = new HashMap<>(); + OnapCommandParameter param = new OnapCommandParameter(); + param.setDefaultValue("defaultValue2"); + param.setParameterType(ParameterType.STRING); + params.put("value2", param); + OnapCommandParameter param1 = new OnapCommandParameter(); + param1.setDefaultValue("{\"defaultValue3\"}"); + param1.setParameterType(ParameterType.JSON); + params.put("value3", param1); + + HttpInput input1 = OnapCommandUtils.populateParameters(params, input); + String expected = "\nURL: uri\nMethod: method\nRequest Queries: {key3={\"defaultValue3\"}}\n" + + "Request Body: body\nRequest Headers: {key2=defaultValue2}\nRequest Cookies: {}\nbinaryData=false"; + assertEquals(expected, input1.toString()); + + input.setBody("${body}"); + + HttpInput input2 = null; + try { + input2 = OnapCommandUtils.populateParameters(params, input); + } catch (OnapCommandParameterNotFound e) { + assertEquals("0x0026::Command input parameter body is not valid", e.getMessage()); + } + + } + + @Test(expected = OnapCommandHttpHeaderNotFound.class) + public void populateOutputsTest() throws OnapCommandException { + HttpResult output = new HttpResult(); + output.setBody( + "{\"serviceName\":\"test\",\"version\":\"v1\",\"url\":\"/api/test/v1\",\"protocol\":\"REST\",\"visualRange\":\"1\",\"lb_policy\":\"hash\",\"nodes\":[{\"ip\":\"127.0.0.1\",\"port\":\"8012\",\"ttl\":0,\"nodeId\":\"test_127.0.0.1_8012\",\"expiration\":\"2017-02-10T05:33:25Z\",\"created_at\":\"2017-02-10T05:33:25Z\",\"updated_at\":\"2017-02-10T05:33:25Z\"}],\"status\":\"1\"}"); + Map mapHead = new HashMap<>(); + mapHead.put("head1", "value1"); + output.setRespHeaders(mapHead); + output.setStatus(0); + + Map params = new HashMap<>(); + params.put("head", "$h{head1}"); + params.put("body", "$b{$.serviceName}"); + params.put("key", "value"); + + Map> input1 = OnapCommandUtils.populateOutputs(params, output); + assertEquals("{head=[value1], body=[test], key=[value]}", input1.toString()); + + params.put("body", "$b{{$.serviceName}"); + try { + input1 = OnapCommandUtils.populateOutputs(params, output); + } catch (OnapCommandHttpInvalidResponseBody e) { + assertEquals( + "0x0028::Http response body does not have json entry {$.serviceName, Missing property in path $['{$']", + e.getMessage()); + } + output.setBody("{}"); + input1 = OnapCommandUtils.populateOutputs(params, output); + params.put("head", "$h{head2}"); + output.setBody("{\"test\"}"); + input1 = OnapCommandUtils.populateOutputs(params, output); + } + + @Test(expected = OnapCommandException.class) + public void zendExceptionTest1() throws OnapCommandException { + + mockExternalResources(); + OnapCommandUtils.loadSchema(new OnapSwaggerBasedCommandSample(), "schemaName"); + } + + @Test(expected = OnapCommandException.class) + public void zendExceptionTest2() throws OnapCommandException { + + mockExternalResources(); + OnapCommandUtils.loadSchema(new OnapHttpCommandSample(), "schemaName", false); + } + + @Test(expected = OnapCommandException.class) + public void zendExceptionTest3() throws OnapCommandException { + + mockExternalResources(); + OnapCommandUtils.validateSchemaVersion("schemaName", "version"); + } + + @Test(expected = OnapCommandException.class) + public void zendExceptionTest4() throws OnapCommandException { + + mockExternalResources(); + OnapCommandUtils.loadExternalSchemasFromJson(); + } + + @Test(expected = OnapCommandException.class) + public void zendExceptionTest5() throws OnapCommandException { + + mockExternalResources(); + OnapCommandUtils.findAllExternalSchemas(); + } + + @Test(expected = OnapCommandException.class) + public void zendExceptionTest6() throws OnapCommandException { + + mockExternalResources(); + OnapCommandUtils.persist(new ArrayList()); + } + + @Test(expected = OnapCommandHelpFailed.class) + public void zendExceptionHelpTest1() throws OnapCommandException { + + mockPrintMethodException(); + OnapCommand cmd = new OnapCommandSample(); + OnapCommandUtils.loadSchema(cmd, "sample-test-schema.yaml", true); + + OnapCommandUtils.help(cmd); + + } + + @OnapCommandSchema(name = "sample-test", schema = "sample-test-schema.yaml") + class OnapCommandSample extends OnapCommand { + @Override + protected void run() throws OnapCommandException { + } + } + + @OnapCommandSchema(name = "sample-swagger-test", schema = "sample-test-schema-swagger.yaml") + class OnapSwaggerBasedCommandSample extends OnapSwaggerCommand { + + @Override + protected void run() throws OnapCommandException { + } + } + + @OnapCommandSchema(name = "sample-http-test", schema = "sample-test-schema-http.yaml") + class OnapHttpCommandSample extends OnapHttpCommand { + + @Override + protected void run() throws OnapCommandException { + } + } + + private void mockExternalResources() { + new MockUp() { + boolean isMock = true; + + @Mock + public Resource[] getExternalResources(Invocation inv, String pattern) throws IOException { + if (isMock) { + isMock = false; + throw new IOException(); + } else { + return inv.proceed(pattern); + } + } + }; + } + + private void mockPrintMethodException() { + new MockUp() { + boolean isMock = true; + + @Mock + public String print(Invocation inv) throws OnapCommandException { + if (isMock) { + isMock = false; + throw new OnapCommandException("", ""); + } else { + return inv.proceed(); + } + } + }; + } +} diff --git a/framework/src/test/java/org/onap/cli/fw/utils/OpenCommandRegistrarTest.java b/framework/src/test/java/org/onap/cli/fw/utils/OpenCommandRegistrarTest.java new file mode 100644 index 00000000..fa73ea6e --- /dev/null +++ b/framework/src/test/java/org/onap/cli/fw/utils/OpenCommandRegistrarTest.java @@ -0,0 +1,42 @@ +/* + * 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.utils; + +import org.junit.Before; +import org.junit.Test; +import org.onap.cli.fw.OnapCommand; +import org.onap.cli.fw.OnapCommandRegistrar; +import org.onap.cli.fw.error.OnapCommandException; + + +public class OpenCommandRegistrarTest { + + @Before + public void setUp() throws Exception { + + } + + @Test + public void test() throws OnapCommandException { + OnapCommandRegistrar registrar = OnapCommandRegistrar.getRegistrar(); + OnapCommand cmd = registrar.get("sample-test"); + registrar.listCommands(); + registrar.getAllCommandToSchemaMap(); + cmd.printVersion(); + } + +} diff --git a/framework/src/test/resources/META-INF/services/org.onap.cli.fw.OnapCommand b/framework/src/test/resources/META-INF/services/org.onap.cli.fw.OnapCommand new file mode 100644 index 00000000..a01b9d53 --- /dev/null +++ b/framework/src/test/resources/META-INF/services/org.onap.cli.fw.OnapCommand @@ -0,0 +1 @@ +org.onap.cli.cmd.sample.OnapCommandSample \ No newline at end of file diff --git a/framework/src/test/resources/onap-cli-schema/sample-test1-schema-http.yaml b/framework/src/test/resources/onap-cli-schema/sample-test1-schema-http.yaml new file mode 100644 index 00000000..18a7bb16 --- /dev/null +++ b/framework/src/test/resources/onap-cli-schema/sample-test1-schema-http.yaml @@ -0,0 +1,91 @@ +onap_cmd_schema_version: 1.0 +name: sample-test1 +description: Onap sample command to test the command features +service: + name: sample + version: v1 +parameters: + - name: bool-param + type: bool + description: Onap boolean param, by default its always false. + short_option: b + long_option: bool + is_optional: true + default_value: false + - name: secure-param + type: string + description: Onap secure param such as password + short_option: x + long_option: secure + is_secured: true + is_optional: false + default_Value: pass123# + - name: string-param + type: string + description: Onap string param + long_option: string-param + short_option: c + is_optional: false + default_Value: test + - name: yaml-param + type: json + description: Onap yaml file location param + long_option: yaml-param + short_option: y + is_optional: false + - name: json-param + type: json + description: Onap json file location param + long_option: json-param + short_option: j + is_optional: false + - name: long-param + type: long + description: Onap long param + short_option: l + long_option: long-opt + is_optional: false + default_value: 10 + - name: url-param + type: url + description: Onap url param + short_option: r + long_option: url + is_optional: false + default_value: http://localhost:8082/file.txt + - name: env-param + type: string + description: Onap env param. + short_option: z + long_option: env + is_optional: false + default_value: ${ENV_VAR} + - name: positional-args + type: string + description: Onap positional args, if no short option and no long option given for it + is_optional: false + default_value: http://localhost:8082/file.txt +http: + request: + uri: /vims + method: POST + body: '{"name":"${name}","vendor":"${vendor}","version":"${vim-version}","description":"${description}","type":"${type}","url":"${url}","userName":"${username}","password":"${password}","domain":"${domain}","tenant":"${tenant}"}' + headers: + success_codes: + - 201 + - 200 + result_map: + id: $b{$.vimId} + name: $b{$.name} + vendor: $b{$.vendor} + type: $b{$.type} + version: $b{$.version} + url: $b{$.url} + description: $b{$.description} + username: $b{$.userName} + password: $b{$.password} + domain: $b{$.domain} + tenant: $b{$.tenant} + create-time: $b{$.createTime} + sample_response: + body:'{"id":"string","name":"string","vendor":"string","version":"string","description":"string","type":"string","createTime":"string","url":"string","userName":"string","password":"string","domain":"string","tenant":"string"}' \ No newline at end of file diff --git a/framework/src/test/resources/onap-test-schema.yaml b/framework/src/test/resources/onap-test-schema.yaml new file mode 100644 index 00000000..df260502 --- /dev/null +++ b/framework/src/test/resources/onap-test-schema.yaml @@ -0,0 +1,81 @@ +onap_cmd_schema_version: 1.0 +name: sample-test +description: Onap sample command to test the command features +service: + name: sample + version: v1 + no-auth: true +parameters: + - name: bool-param + type: bool + description: Onap boolean param, by default its always false. + short_option: b + long_option: bool + is_optional: true + default_value: false + - name: secure-param + type: string + description: Onap secure param such as password + short_option: x + long_option: secure + is_secured: true + is_optional: false + default_Value: pass123# + - name: string-param + type: string + description: Onap string param + long_option: string-param + short_option: c + is_optional: false + default_Value: test + - name: yaml-param + type: json + description: Onap yaml file location param + long_option: yaml-param + short_option: y + is_optional: false + - name: json-param + type: json + description: Onap json file location param + long_option: json-param + short_option: j + is_optional: false + - name: long-param + type: long + description: Onap long param + short_option: l + long_option: long-opt + is_optional: false + default_value: 10 + - name: url-param + type: url + description: Onap url param + short_option: r + long_option: url + is_optional: false + default_value: http://localhost:8082/file.txt + - name: env-param + type: string + description: Onap env param. + short_option: z + long_option: env + is_optional: false + default_value: ${ENV_VAR} + - name: positional-args + type: string + description: Onap positional args, if no short option and no long option given for it + is_optional: false + default_value: http://localhost:8082/file.txt +results: + direction: portrait + attributes: + - name: output-1 + description: Onap output attribute marked in short + scope: short + type: string + is_secured: true + - name: output-2 + description: Onap output attribute marked in long + scope: short + is_secured: false + type: string \ No newline at end of file diff --git a/framework/src/test/resources/onap.properties b/framework/src/test/resources/onap.properties new file mode 100644 index 00000000..3b185174 --- /dev/null +++ b/framework/src/test/resources/onap.properties @@ -0,0 +1,4 @@ +cli.ignore_auth=true +cli.version=1.0 +http.api_key=X-Auth-Token +http.api_key_use_cookies=true \ No newline at end of file diff --git a/framework/src/test/resources/sample-cmd-test-help.txt b/framework/src/test/resources/sample-cmd-test-help.txt new file mode 100644 index 00000000..d8ce1ef5 --- /dev/null +++ b/framework/src/test/resources/sample-cmd-test-help.txt @@ -0,0 +1,72 @@ +usage: onap sample-test + +Onap sample command to test the command features + +Onap service: sample v1 + +Options: +[-u | --onap-username] [-p | --onap-password] [-m | --msb-url] +[-h | --help] [-v | --version] [-d | --debug] +[-f | --format] [-s | --long] [-t | --no-title] +[-a | --no-auth] [-b | --bool] [-x | --secure] +[-c | --string-param] [-y | --yaml-param] [-j | --json-param] +[-l | --long-opt] [-r | --url] [-z | --env] + +where, +-u | --onap-username Onap user name. It is of type STRING. By + default, it is read from environment variable + ONAP_USERNAME. +-p | --onap-password Onap user password. It is of type STRING. By + default, it is read from environment variable + ONAP_PASSWORD. Secured. +-m | --msb-url Onap MSB url. It is of type URL. By default, it + is read from environment variable ONAP_MSB_URL. +-h | --help Onap command help message. It is of type STRING. + By default, it is false. +-v | --version Onap command service version. It is of type + STRING. By default, it is false. +-d | --debug Enable debug output. It is of type BOOL. By + default, it is false. +-f | --format Output formats, supported formats such as table, + csv, json, yaml. It is of type STRING. By default, + it is table. +-s | --long whether to print all attributes or only short + attributes. It is of type BOOL. By default, it is + false. +-t | --no-title whether to print title or not. It is of type BOOL. + By default, it is false. +-a | --no-auth whether to authenticate user or not. It is of type + BOOL. By default, it is false. +-b | --bool Onap boolean param, by default its always false. + It is of type BOOL. It is optional. By default, it + is false. +-x | --secure Onap secure param such as password. It is of + type STRING. Secured. +-c | --string-param Onap string param. It is of type STRING. +-y | --yaml-param Onap yaml file location param. It is of type + JSON. It's recommended to input the complete path + of the file, which is having the value for it. +-j | --json-param Onap json file location param. It is of type + JSON. It's recommended to input the complete path + of the file, which is having the value for it. +-l | --long-opt Onap long param. It is of type LONG. By default, + it is 10. +-r | --url Onap url param. It is of type URL. By default, + it is http://localhost:8082/file.txt. +-z | --env Onap env param. It is of type STRING. By + default, it is read from environment variable + ENV_VAR. +positional-args Onap positional args, if no short option and no + long option given for it. It is of type STRING. By + default, it is http://localhost:8082/file.txt. + + +Results: +output-1 Onap output attribute marked in short and is of + type STRING. It is secured. +output-2 Onap output attribute marked in long and is of + type STRING. + + +Error: +On error, it prints :::: diff --git a/framework/src/test/resources/sample-test-invalid-schema-duplicate-longoption.yaml b/framework/src/test/resources/sample-test-invalid-schema-duplicate-longoption.yaml new file mode 100644 index 00000000..8761bb30 --- /dev/null +++ b/framework/src/test/resources/sample-test-invalid-schema-duplicate-longoption.yaml @@ -0,0 +1,78 @@ +onap_cmd_schema_version: 1.0 +name: sample-test +description: Onap sample command to test the command features +service: + name: sample + version: v1 +parameters: + - name: bool-param + type: bool + description: Onap boolean param, by default its always false. + short_option: b + long_option: bool + is_optional: true + default_value: false + - name: secure-param + type: string + description: Onap secure param such as password + short_option: x + long_option: secure + is_secured: true + is_optional: false + default_Value: pass123# + - name: string-param + type: string + description: Onap string param + long_option: secure + short_option: c + is_optional: false + default_Value: test + - name: yaml-param + type: json + description: Onap yaml file location param + long_option: yaml-param + short_option: y + is_optional: false + - name: json-param + type: json + description: Onap json file location param + long_option: json-param + short_option: j + is_optional: false + - name: long-param + type: long + description: Onap long param + short_option: l + long_option: long-opt + is_optional: false + default_value: 10 + - name: url-param + type: url + description: Onap url param + short_option: r + long_option: url + is_optional: false + default_value: http://localhost:8082/file.txt + - name: env-param + type: string + description: Onap env param. + short_option: z + long_option: env + is_optional: false + default_value: ${ENV_VAR} + - name: positional-args + type: string + description: Onap positional args, if no short option and no long option given for it + is_optional: false + default_value: http://localhost:8082/file.txt +results: + direction: portrait + attributes: + - name: output-1 + description: Onap output attribute marked in short + scope: short + type: string + - name: output-2 + description: Onap output attribute marked in long + scope: short + type: string \ No newline at end of file diff --git a/framework/src/test/resources/sample-test-invalid-schema-duplicate-name.yaml b/framework/src/test/resources/sample-test-invalid-schema-duplicate-name.yaml new file mode 100644 index 00000000..df4ed316 --- /dev/null +++ b/framework/src/test/resources/sample-test-invalid-schema-duplicate-name.yaml @@ -0,0 +1,85 @@ +onap_cmd_schema_version: 1.0 +name: sample-test +description: Onap sample command to test the command features +service: + name: sample + version: v1 +parameters: + - name: bool-param + type: bool + description: Onap boolean param, by default its always false. + short_option: b + long_option: bool + is_optional: true + default_value: false + - name: bool-param + type: bool + description: Onap boolean param, by default its always false. + short_option: b + long_option: bool + is_optional: true + default_value: false + - name: secure-param + type: string + description: Onap secure param such as password + short_option: x + long_option: secure + is_secured: true + is_optional: false + default_Value: pass123# + - name: string-param + type: string + description: Onap string param + long_option: string-param + short_option: c + is_optional: false + default_Value: test + - name: yaml-param + type: json + description: Onap yaml file location param + long_option: yaml-param + short_option: y + is_optional: false + - name: json-param + type: json + description: Onap json file location param + long_option: json-param + short_option: j + is_optional: false + - name: long-param + type: long + description: Onap long param + short_option: l + long_option: long-opt + is_optional: false + default_value: 10 + - name: url-param + type: url + description: Onap url param + short_option: r + long_option: url + is_optional: false + default_value: http://localhost:8082/file.txt + - name: env-param + type: string + description: Onap env param. + short_option: z + long_option: env + is_optional: false + default_value: ${ENV_VAR} + - name: positional-args + type: string + description: Onap positional args, if no short option and no long option given for it + is_optional: false + default_value: http://localhost:8082/file.txt +results: + direction: portrait + attributes: + - name: output-1 + description: Onap output attribute marked in short + scope: short + type: string + - name: output-2 + description: Onap output attribute marked in long + scope: short + type: string \ No newline at end of file diff --git a/framework/src/test/resources/sample-test-invalid-schema-duplicate-shortoption.yaml b/framework/src/test/resources/sample-test-invalid-schema-duplicate-shortoption.yaml new file mode 100644 index 00000000..519f6e3b --- /dev/null +++ b/framework/src/test/resources/sample-test-invalid-schema-duplicate-shortoption.yaml @@ -0,0 +1,79 @@ +onap_cmd_schema_version: 1.0 +name: sample-test +description: Onap sample command to test the command features +service: + name: sample + version: v1 +parameters: + - name: bool-param + type: bool + description: Onap boolean param, by default its always false. + short_option: b + long_option: bool + is_optional: true + default_value: false + - name: secure-param + type: string + description: Onap secure param such as password + short_option: x + short_option: y + long_option: secure + is_secured: true + is_optional: false + default_Value: pass123# + - name: string-param + type: string + description: Onap string param + long_option: string-param + short_option: c + is_optional: false + default_Value: test + - name: yaml-param + type: json + description: Onap yaml file location param + long_option: yaml-param + short_option: y + is_optional: false + - name: json-param + type: json + description: Onap json file location param + long_option: json-param + short_option: j + is_optional: false + - name: long-param + type: long + description: Onap long param + short_option: l + long_option: long-opt + is_optional: false + default_value: 10 + - name: url-param + type: url + description: Onap url param + short_option: r + long_option: url + is_optional: false + default_value: http://localhost:8082/file.txt + - name: env-param + type: string + description: Onap env param. + short_option: z + long_option: env + is_optional: false + default_value: ${ENV_VAR} + - name: positional-args + type: string + description: Onap positional args, if no short option and no long option given for it + is_optional: false + default_value: http://localhost:8082/file.txt +results: + direction: portrait + attributes: + - name: output-1 + description: Onap output attribute marked in short + scope: short + type: string + - name: output-2 + description: Onap output attribute marked in long + scope: short + type: string \ No newline at end of file diff --git a/framework/src/test/resources/sample-test-invalid-schema.yaml b/framework/src/test/resources/sample-test-invalid-schema.yaml new file mode 100644 index 00000000..ed21772c --- /dev/null +++ b/framework/src/test/resources/sample-test-invalid-schema.yaml @@ -0,0 +1,78 @@ +onap_cmd_schema_version: 1.0 +name: sample-test +description: Onap sample command to test the command features +service: + name: sample + version: v1 +parameters: + -- name: bool-param + type: bool + description: Onap boolean param, by default its always false. + short_option: b + long_option: bool + is_optional: true + default_value: false + - name: secure-param + type: string + description: Onap secure param such as password + short_option: x + long_option: secure + is_secured: true + is_optional: false + default_Value: pass123# + - name: string-param + type: string + description: Onap string param + long_option: string-param + short_option: c + is_optional: false + default_Value: test + - name: yaml-param + type: json + description: Onap yaml file location param + long_option: yaml-param + short_option: y + is_optional: false + - name: json-param + type: json + description: Onap json file location param + long_option: json-param + short_option: j + is_optional: false + - name: long-param + type: long + description: Onap long param + short_option: l + long_option: long-opt + is_optional: false + default_value: 10 + - name: url-param + type: url + description: Onap url param + short_option: r + long_option: url + is_optional: false + default_value: http://localhost:8082/file.txt + - name: env-param + type: string + description: Onap env param. + short_option: z + long_option: env + is_optional: false + default_value: ${ENV_VAR} + - name: positional-args + type: string + description: Onap positional args, if no short option and no long option given for it + is_optional: false + default_value: http://localhost:8082/file.txt +results: + direction: portrait + attributes: + - name: output-1 + description: Onap output attribute marked in short + scope: short + type: string + - name: output-2 + description: Onap output attribute marked in long + scope: short + type: string \ No newline at end of file diff --git a/framework/src/test/resources/sample-test-schema-http.yaml b/framework/src/test/resources/sample-test-schema-http.yaml new file mode 100644 index 00000000..7bbf6775 --- /dev/null +++ b/framework/src/test/resources/sample-test-schema-http.yaml @@ -0,0 +1,90 @@ +onap_cmd_schema_version: 1.0 +name: sample-create-http +description: Register microservice into Onap +service: + name: msb + version: v1 +parameters: + - name: service-name + description: Onap service name + type: string + short_option: x + long_option: service-name + is_optional: false + - name: service-version + description: Onap service version + type: string + short_option: y + long_option: service-version + is_optional: false + - name: service-url + description: Onap service base url + type: url + short_option: r + long_option: service-url + is_optional: false + - name: status + description: Onap service status + type: long + short_option: z + long_option: service-status + is_optional: true + default_value: 1 + - name: node-ip + description: Onap service running node IP + type: string + - name: node-port + description: Onap service running node port + type: string + - name: create-or-update + description: Onap service create or update + type: bool + default_value: true +results: + direction: portrait + attributes: + - name: name + description: Onap service name + scope: short + type: string + - name: version + description: Onap service version + scope: short + type: string + - name: url + description: Onap service base url + scope: short + type: url + - name: status + description: Onap service status + scope: short + type: long + - name: nodes + description: Onap service running nodes + scope: long + type: string + - name: location + description: Onap service location + scope: long + type: url +http: + request: + uri: /services + method: POST + body: '{"serviceName":"${service-name}","version":"${service-version}","url":"${service-url}","protocol":"REST","visualRange":"1","lb_policy":"hash","nodes":[{"ip":"${node-ip}","port":"${node-port}","ttl":0}]}' + headers: + queries: + createOrUpdate: ${create-or-update} + success_codes: + - 201 + - 200 + result_map: + name: $b{$.serviceName} + version: $b{$.version} + url: $b{$.url} + status: $b{$.status} + nodes: $b{$.nodes[*].ip}:$b{$.nodes[*].port} + location: $h{Location} + + sample_response: + body: {"serviceName":"test","version":"v1","url":"/api/test/v1","protocol":"REST","visualRange":"1","lb_policy":"hash","nodes":[{"ip":"127.0.0.1","port":"8012","ttl":0,"nodeId":"test_127.0.0.1_8012","expiration":"2017-02-10T05:33:25Z","created_at":"2017-02-10T05:33:25Z","updated_at":"2017-02-10T05:33:25Z"}],"status":"1"} \ No newline at end of file diff --git a/framework/src/test/resources/sample-test-schema-swagger.yaml b/framework/src/test/resources/sample-test-schema-swagger.yaml new file mode 100644 index 00000000..c88ddb7a --- /dev/null +++ b/framework/src/test/resources/sample-test-schema-swagger.yaml @@ -0,0 +1,26 @@ +onap_cmd_schema_version: 1.0 +name: sample-test-swagger +description: Sample swagger command test. +service: + name: sample + version: v1 +parameters: + - name: user + type: string + description: Onap user + short_option: n + long_option: username + is_optional: false +results: + direction: portrait + attributes: + - name: name + description: Onap user + scope: short + type: string +exec: + api: org.onap.common_services.auth.auth_service.client.api.DefaultApi + client: org.onap.common_services.auth.auth_service.client.invoker.ApiClient + entity: org.onap.common_services.auth.auth_service.client.model.User, username(userName), password, description + method: create + exception: org.onap.common_services.auth.auth_service.client.invoker.ApiException \ No newline at end of file diff --git a/framework/src/test/resources/sample-test-schema.yaml b/framework/src/test/resources/sample-test-schema.yaml new file mode 100644 index 00000000..a480147d --- /dev/null +++ b/framework/src/test/resources/sample-test-schema.yaml @@ -0,0 +1,82 @@ +onap_cmd_schema_version: 1.0 +name: sample-test +description: Onap sample command to test the command features +service: + name: sample + version: v1 + no-auth: true +parameters: + - name: bool-param + type: bool + description: Onap boolean param, by default its always false. + short_option: b + long_option: bool + is_optional: true + default_value: false + - name: secure-param + type: string + description: Onap secure param such as password + short_option: x + long_option: secure + is_secured: true + is_optional: false + default_Value: pass123# + - name: string-param + type: string + description: Onap string param + long_option: string-param + short_option: c + is_optional: false + default_Value: test + - name: yaml-param + type: json + description: Onap yaml file location param + long_option: yaml-param + short_option: y + is_optional: false + - name: json-param + type: json + description: Onap json file location param + long_option: json-param + short_option: j + is_optional: false + is_secured: false + - name: long-param + type: long + description: Onap long param + short_option: l + long_option: long-opt + is_optional: false + default_value: 10 + - name: url-param + type: url + description: Onap url param + short_option: r + long_option: url + is_optional: false + default_value: http://localhost:8082/file.txt + - name: env-param + type: string + description: Onap env param. + short_option: z + long_option: env + is_optional: false + default_value: ${ENV_VAR} + - name: positional-args + type: string + description: Onap positional args, if no short option and no long option given for it + is_optional: false + default_value: http://localhost:8082/file.txt +results: + direction: portrait + attributes: + - name: output-1 + description: Onap output attribute marked in short + scope: short + type: string + is_secured: true + - name: output-2 + description: Onap output attribute marked in long + scope: short + is_secured: false + type: string \ No newline at end of file diff --git a/framework/src/test/resources/schema-invalid-file-null.yaml b/framework/src/test/resources/schema-invalid-file-null.yaml new file mode 100644 index 00000000..e69de29b diff --git a/framework/src/test/resources/schema-invalid-file.yaml b/framework/src/test/resources/schema-invalid-file.yaml new file mode 100644 index 00000000..7b5937d5 --- /dev/null +++ b/framework/src/test/resources/schema-invalid-file.yaml @@ -0,0 +1,6 @@ +onap_cmd_schema_version: 1.0 +description: Register microservice into Onap +name: schema-validate +service:dasd + name: msbdsa + - name: service-name1 \ No newline at end of file diff --git a/framework/src/test/resources/schema-validate-basic.yaml b/framework/src/test/resources/schema-validate-basic.yaml new file mode 100644 index 00000000..80a9e1c6 --- /dev/null +++ b/framework/src/test/resources/schema-validate-basic.yaml @@ -0,0 +1,68 @@ +onap_cmd_schema_version: 1.0 +description: Register microservice into Onap +name: schema-validate +service: + name: msb +parameters: + - name: service-name1 + description: Onap service name + type: string + short_option: x + long_option: service-name + is_optional: false + - name: service-version + description: Onap service version + type: string + short_option: x + long_option: service-version + is_optional: false + - name: service-url + description: Onap service base url + type: url1 + short_option: u + long_option: service-url + is_optional: false1 + - name: status + description: Onap service status + type: long + short_option: z + long_option: service-version + is_optional: true + default_value: 1 + - name: node-ip + description: Onap service running node IP + type: string + - name: node-port + description: Onap service running node port + type: string + - name: create-or-update + description: Onap service create or update + type: cfbcv + default_value: true +results: + direction: portrait1 + attributes: + - name: name + description: Onap service name + scope: short + type: string + - name: version + description: Onap service version + scope: short + type: string + - name: status + description: Onap service base url + scope: short + type: url + - name: status + description: Onap service status + scope: short1 + type: long + - name: nodes + description: Onap service running nodes + scope: long + type: string + - name: location + description: Onap service location + scope: long + type: url \ No newline at end of file diff --git a/framework/src/test/resources/schema-validate-http.yaml b/framework/src/test/resources/schema-validate-http.yaml new file mode 100644 index 00000000..82f44aed --- /dev/null +++ b/framework/src/test/resources/schema-validate-http.yaml @@ -0,0 +1,89 @@ +onap_cmd_schema_version: 1.0 +description: Register microservice into Onap +name: schema-validate +service: + name: msb +parameters: + - name: service-name1 + description: Onap service name + type: string + short_option: x + long_option: service-name + is_optional: false + - name: service-version + description: Onap service version + type: string + short_option: x + long_option: service-version + is_optional: false + - name: service-url + description: Onap service base url + type: url1 + short_option: u + long_option: service-url + is_optional: false1 + - name: status + description: Onap service status + type: long + short_option: z + long_option: service-version + is_optional: true + default_value: 1 + - name: node-ip + description: Onap service running node IP + type: string + - name: node-port + description: Onap service running node port + type: string + - name: create-or-update + description: Onap service create or update + type: cfbcv + default_value: true +results: + direction: portrait + attributes: + - name: name + description: Onap service name + scope: short + type: string + - name: version + description: Onap service version + scope: short + type: string + - name: status + description: Onap service base url + scope: short + type: url + - name: status + description: Onap service status + scope: short1 + type: long + - name: nodes + description: Onap service running nodes + scope: long + type: string + - name: location + description: Onap service location + scope: long + type: url +http: + request: + uri: /services + method: POST1 + body: '{"serviceName":"${service}","serviceName":"${service-name}","version":"${service-version}","url":"${service-url}","protocol":"REST","visualRange":"1","lb_policy":"hash","nodes":[{"ip":"${node-ip}","port":"${node-port}","ttl":0}]}' + headers: + queries: + createOrUpdate: ${create-or-update1} + success_codes: + - 201 + - 300 + result_map: + name: $b{$.serviceName} + version: $b{$.version} + url: $b{$.url} + status1: $b{$.status} + nodes: $b{$.nodes[*].ip}:$b{$.nodes[*].port} + location: $h{Location} + sample_response: + body: {"serviceName":"test","version":"v1","url":"/api/test/v1","protocol":"REST","visualRange":"1","lb_policy":"hash","nodes":[{"ip":"127.0.0.1","port":"8012","ttl":0,"nodeId":"test_127.0.0.1_8012","expiration":"2017-02-10T05:33:25Z","created_at":"2017-02-10T05:33:25Z","updated_at":"2017-02-10T05:33:25Z"}],"status":"1"} + diff --git a/framework/src/test/resources/schema-validate-invalid.yaml b/framework/src/test/resources/schema-validate-invalid.yaml new file mode 100644 index 00000000..61f3eeba --- /dev/null +++ b/framework/src/test/resources/schema-validate-invalid.yaml @@ -0,0 +1,151 @@ +onap_cmd_schema_version: 1.0 +name: sdnc-create +description: Register SDNC into Onap +service: + name: extsys + version: v1 +parameters: + - name: name + description: Onap SDNC name + scope: short + type: string + short_option: n + long_option: name + is_optional: false + - name: vendor + description: Onap SDNC vendor + scope: short + type: string + short_option: e + long_option: vendor + is_optional: false + - name: type + description: Onap SDNC type + scope: short + type: string + short_option: y + long_option: type + is_optional: false + - name: sdnc-version + description: Onap SDNC version + scope: short + type: string + short_option: r + long_option: sdnc-version + is_optional: false + - name: url + description: Onap SDNC base url + scope: short + type: url + short_option: l + long_option: url + is_optional: false + - name: description + description: Onap SDNC description + scope: short + type: string + short_option: i + long_option: description + is_optional: false + - name: username + description: Onap SDNC username + scope: short + type: string + short_option: g + long_option: username + is_optional: false + - name: password + description: Onap SDNC password + scope: short + type: string + is_secured: true + short_option: j + long_option: password + is_optional: false + - name: product-name + description: Onap SDNC product-name + scope: short + type: string + short_option: o + long_option: product-name + is_optional: false + - name: protocol + description: Onap SDNC protocol + scope: short + type: string + short_option: k + long_option: protocol + is_optional: false +results: + direction: portrait + attributes: + - name: id + description: Onap SDNC ID + scope: short + type: string + - name: name + description: Onap SDNC name + scope: short + type: string + - name: vendor + description: Onap SDNC vendor + scope: short + type: string + - name: type + description: Onap SDNC type + scope: short + type: string + - name: version + description: Onap SDNC version + scope: short + type: string + - name: url + description: Onap SDNC base url + scope: short + type: url + - name: description + description: Onap SDNC description + scope: short + type: string + - name: username + description: Onap SDNC username + scope: short + type: string + - name: password + description: Onap SDNC password + scope: short + type: string + is_secured: true + - name: product-name + description: Onap SDNC product name + scope: short + type: string + - name: protocol + description: Onap SDNC protocol + scope: short + type: string + - name: create-time + description: Onap SDNC create-time + scope: long + type: string +http: + request: + headers: + createOrUpdate: ${create-or-update1} + body: + success_codes: + result_map: + id: $b{$.sdnControllerId} + name: $b{$.name} + vendor: $b{$.vendor} + type: $b{$.type} + version: $b{$.version} + url: $b{$.url} + description: $b{$.description} + username: $b{$.userName} + password: $b{$.password} + protocol: $b{$.protocol} + product-name: $b{$.productName} + create-time: $b{$.createTime} + sample_response: + body: diff --git a/framework/src/test/resources/schema-validate-invalidschematype.yaml b/framework/src/test/resources/schema-validate-invalidschematype.yaml new file mode 100644 index 00000000..cacf9c06 --- /dev/null +++ b/framework/src/test/resources/schema-validate-invalidschematype.yaml @@ -0,0 +1,88 @@ +onap_cmd_schema_version: 1.0 +description: Register microservice into Onap +name: schema-validate +parameters: + - name: service-name1 + description: Onap service name + type: string + short_option: x + long_option: service-name + is_optional: false + - name: service-version + description: Onap service version + type: string + short_option: x + long_option: service-version + is_optional: false + - name: service-url + description: Onap service base url + type: url1 + short_option: u + long_option: service-url + is_optional: false1 + - name: status + description: Onap service status + type: long + short_option: z + long_option: service-version + is_optional: true + default_value: 1 + - name: node-ip + description: Onap service running node IP + type: string + - name: node-port + description: Onap service running node port + type: string + - name: create-or-update + description: Onap service create or update + type: cfbcv + default_value: true +results: + direction: portrait + attributes: + - name: name + description: Onap service name + scope: short + type: string + - name: version + description: Onap service version + scope: short + type: string + - name: status + description: Onap service base url + scope: short + type: url + - name: status + description: Onap service status + scope: short1 + type: long + - name: nodes + description: Onap service running nodes + scope: long + type: string + - name: location + description: Onap service location + scope: long + type: url +http: + request: + uri: + method: POST + body: + headers: + queries: + createOrUpdate: ${create-or-update1} + success_codes: + - 201 + - 300 + result_map: + name: $b{$.serviceName} + version: $b{$.version} + url: $b{$.url} + status1: $b{$.status} + nodes: $b{$.nodes[*].ip}:$b{$.nodes[*].port} + location: $h{Location} + + sample_response: + body: {"serviceName":"test","version":"v1","url":"/api/test/v1","protocol":"REST","visualRange":"1","lb_policy":"hash","nodes":[{"ip":"127.0.0.1","port":"8012","ttl":0,"nodeId":"test_127.0.0.1_8012","expiration":"2017-02-10T05:33:25Z","created_at":"2017-02-10T05:33:25Z","updated_at":"2017-02-10T05:33:25Z"}],"status":"1"} + diff --git a/framework/src/test/resources/schema-validate-pass.yaml b/framework/src/test/resources/schema-validate-pass.yaml new file mode 100644 index 00000000..91fb3141 --- /dev/null +++ b/framework/src/test/resources/schema-validate-pass.yaml @@ -0,0 +1,153 @@ +onap_cmd_schema_version: 1.0 +name: sdnc-create +description: Register SDNC into Onap +service: + name: extsys + version: v1 +parameters: + - name: name + description: Onap SDNC name + scope: short + type: string + short_option: n + long_option: name + is_optional: false + - name: vendor + description: Onap SDNC vendor + scope: short + type: string + short_option: e + long_option: vendor + is_optional: false + - name: type + description: Onap SDNC type + scope: short + type: string + short_option: y + long_option: type + is_optional: false + - name: sdnc-version + description: Onap SDNC version + scope: short + type: string + short_option: r + long_option: sdnc-version + is_optional: false + - name: url + description: Onap SDNC base url + scope: short + type: url + short_option: l + long_option: url + is_optional: false + - name: description + description: Onap SDNC description + scope: short + type: string + short_option: i + long_option: description + is_optional: false + - name: username + description: Onap SDNC username + scope: short + type: string + short_option: g + long_option: username + is_optional: false + - name: password + description: Onap SDNC password + scope: short + type: string + is_secured: true + short_option: j + long_option: password + is_optional: false + - name: product-name + description: Onap SDNC product-name + scope: short + type: string + short_option: o + long_option: product-name + is_optional: false + - name: protocol + description: Onap SDNC protocol + scope: short + type: string + short_option: k + long_option: protocol + is_optional: false +results: + direction: portrait + attributes: + - name: id + description: Onap SDNC ID + scope: short + type: string + - name: name + description: Onap SDNC name + scope: short + type: string + - name: vendor + description: Onap SDNC vendor + scope: short + type: string + - name: type + description: Onap SDNC type + scope: short + type: string + - name: version + description: Onap SDNC version + scope: short + type: string + - name: url + description: Onap SDNC base url + scope: short + type: url + - name: description + description: Onap SDNC description + scope: short + type: string + - name: username + description: Onap SDNC username + scope: short + type: string + - name: password + description: Onap SDNC password + scope: short + type: string + is_secured: true + - name: product-name + description: Onap SDNC product name + scope: short + type: string + - name: protocol + description: Onap SDNC protocol + scope: short + type: string + - name: create-time + description: Onap SDNC create-time + scope: long + type: string +http: + request: + headers: + createOrUpdate: ${create-or-update1} + body: {"name":"${name}","vendor":"${vendor}","version":"${sdnc-version}","description":"${description}","type":"${type}","url":"${url}","userName":"${username}","password":"${password}","productName":"${product-name}","protocol":"${protocol}"} + success_codes: + - 201 + - 200 + result_map: + id: $b{$.sdnControllerId} + name: $b{$.name} + vendor: $b{$.vendor} + type: $b{$.type} + version: $b{$.version} + url: $b{$.url} + description: $b{$.description} + username: $b{$.userName} + password: $b{$.password} + protocol: $b{$.protocol} + product-name: $b{$.productName} + create-time: $b{$.createTime} + sample_response: + body: '{"id":"string","name":"string","vendor":"string","version":"string","description":"string","type":"string","createTime":"string","url":"string","userName":"string","password":"string","productName":"string","protocol":"string"}' diff --git a/main/pom.xml b/main/pom.xml new file mode 100644 index 00000000..d1bc138c --- /dev/null +++ b/main/pom.xml @@ -0,0 +1,106 @@ + + + + + 4.0.0 + + + org.onap.cli + cli + 1.0.0-SNAPSHOT + + + cli-main + cli/main + jar + + + junit + junit + 4.11 + test + + + org.onap.cli + cli-framework + ${project.parent.version} + + + org.onap.cli + cli-plugin-common-service + ${project.parent.version} + + + commons-io + commons-io + 1.3.2 + + + jline + jline + 2.14.3 + + + org.jmockit + jmockit + 1.19 + test + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + true + org.onap.cli.main.OnapCli + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + 3.0.0 + + + copy-dependencies + package + + copy-dependencies + + + ${project.build.directory}/lib + false + false + true + junit,jmockit + + + + + + + + diff --git a/main/src/main/java/org/onap/cli/main/OnapCli.java b/main/src/main/java/org/onap/cli/main/OnapCli.java new file mode 100644 index 00000000..05daf116 --- /dev/null +++ b/main/src/main/java/org/onap/cli/main/OnapCli.java @@ -0,0 +1,267 @@ +/* + * 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.main; + +import org.apache.commons.io.IOUtils; +import org.onap.cli.fw.OnapCommand; +import org.onap.cli.fw.OnapCommandRegistrar; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandWarning; +import org.onap.cli.fw.input.OnapCommandParameter; +import org.onap.cli.fw.output.OnapCommandResult; +import org.onap.cli.main.conf.OnapCliConstants; +import org.onap.cli.main.interactive.StringCompleter; +import org.onap.cli.main.utils.OnapCliUtils; + +import jline.TerminalFactory; +import jline.console.ConsoleReader; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Onap Command Line Interface (CLI). + * + */ +public class OnapCli { + + private List args = new ArrayList<>(); + + private int exitCode = -1; + + public OnapCli(String[] args) { + this.args = Arrays.asList(args); + } + + private void exitSuccessfully() { + this.exitCode = OnapCliConstants.EXIT_SUCCESS; + } + + private void exitFailure() { + this.exitCode = OnapCliConstants.EXIT_FAILURE; + } + + private void print(String msg) { + System.out.println(msg); + } + + private void print(Throwable throwable) { + System.out.println(throwable.getMessage()); + } + + private String getShortOption(String opt) { + return OnapCommandParameter.printShortOption(opt); + } + + private String getLongOption(String opt) { + return OnapCommandParameter.printLongOption(opt); + } + + public int getExitCode() { + return this.exitCode; + } + + /** + * Handles help. --help or -h + */ + public void handleHelp() { + try { + // By default, it prints help + if ((args.isEmpty()) + || ((args.size() == 1) && (this.getLongOption(OnapCliConstants.PARAM_HELP_LOGN).equals(args.get(0)) + || this.getShortOption(OnapCliConstants.PARAM_HELP_SHORT).equals(args.get(0))))) { + this.print(IOUtils.toString(this.getClass().getClassLoader().getResourceAsStream("onap-readme.txt"))); + String help = OnapCommandRegistrar.getRegistrar().getHelp(); + this.print(help); + this.exitSuccessfully(); + } + } catch (Exception e) { + this.print(e); + this.exitFailure(); + } + } + + /** + * Handles version. --version or -v + */ + public void handleVersion() { + try { + if ((args.size() == 1) && (this.getLongOption(OnapCliConstants.PARAM_VERSION_LONG).equals(args.get(0)) + || this.getShortOption(OnapCliConstants.PARAM_VERSION_SHORT).equals(args.get(0)))) { + String version = OnapCommandRegistrar.getRegistrar().getVersion(); + this.print(version); + this.exitSuccessfully(); + } + } catch (Exception e) { + this.print(e); + this.exitFailure(); + } + } + + /** + * Handles Interactive Mode. --interactive or -i + */ + public void handleInteractive() { // NOSONAR + if (isInteractive()) { + ConsoleReader console = null; + try { + console = createConsoleReader(); + String line = null; + while ((line = console.readLine()) != null) { + if (OnapCliConstants.PARAM_INTERACTIVE_EXIT.equalsIgnoreCase(line) + || OnapCliConstants.PARAM_INTERACTIVE_BYE.equalsIgnoreCase(line)) { + break; + } else if (OnapCliConstants.PARAM_INTERACTIVE_CLEAR.equalsIgnoreCase(line)) { + console.clearScreen(); + continue; + } + this.args = Arrays.asList(line.split(OnapCliConstants.PARAM_INTERACTIVE_ARG_SPLIT_PATTERN)); + handleCommand(); + } + } catch (IOException e) { // NOSONAR + this.print("Failed to read console, " + e.getMessage()); + } finally { + try { + TerminalFactory.get().restore(); + } catch (Exception e) { // NOSONAR + } + if (console != null) { + console.close(); + } + this.exitSuccessfully(); + } + } + } + + /** + * Checks if the command is interactive. + * + * @return boolean + */ + public boolean isInteractive() { + if ((args.size() == 1) && (this.getLongOption(OnapCliConstants.PARAM_INTERACTIVE_LONG).equals(args.get(0)) + || this.getShortOption(OnapCliConstants.PARAM_INTERACTIVE_SHORT).equals(args.get(0)))) { + return true; + } + + return false; + } + + /** + * Creates console reader object. + * + * @return ConsoleReader + * @throws IOException + * exception + */ + private ConsoleReader createConsoleReader() throws IOException { + ConsoleReader console = new ConsoleReader(); + try { + StringCompleter strCompleter = new StringCompleter(OnapCommandRegistrar.getRegistrar().listCommands()); + strCompleter.add(OnapCliConstants.PARAM_INTERACTIVE_EXIT, + OnapCliConstants.PARAM_INTERACTIVE_CLEAR); + console.addCompleter(strCompleter); + console.setPrompt(OnapCliConstants.PARAM_INTERACTIVE_PROMPT); + } catch (OnapCommandException e) { // NOSONAR + this.print("Failed to load onap commands," + e.getMessage()); + } + + return console; + } + + /** + * Handles command. + */ + public void handleCommand() { + OnapCommand cmd; + if (!args.isEmpty()) { + try { + cmd = OnapCommandRegistrar.getRegistrar().get(args.get(0)); + } catch (Exception e) { + this.print(e); + this.exitFailure(); + return; + } + try { + // check for help or version + if (args.size() == 2) { + if (this.getLongOption(OnapCliConstants.PARAM_HELP_LOGN).equals(args.get(1)) + || this.getShortOption(OnapCliConstants.PARAM_HELP_SHORT).equals(args.get(1))) { + String help = cmd.printHelp(); + this.print(help); + this.exitSuccessfully(); + return; + } else if (this.getLongOption(OnapCliConstants.PARAM_VERSION_LONG).equals(args.get(1)) + || this.getShortOption(OnapCliConstants.PARAM_VERSION_SHORT).equals(args.get(1))) { + String version = cmd.printVersion(); + this.print(version); + this.exitSuccessfully(); + return; + } + } + + OnapCliUtils.populateParams(cmd.getParameters(), args); + OnapCommandResult result = cmd.execute(); + this.print(result.getDebugInfo()); + this.print(result.print()); + this.exitSuccessfully(); + } catch (Exception e) { + this.print(cmd.getResult().getDebugInfo()); + if (e instanceof OnapCommandWarning) { + this.exitSuccessfully(); + } else { + this.print(e); + this.exitFailure(); + } + } + } + } + + /** + * Handles all client input. + */ + public void handle() { + this.handleHelp(); + + if (this.exitCode == -1) { + this.handleVersion(); + } + + if (this.exitCode == -1) { + this.handleInteractive(); + } + + if (this.exitCode == -1) { + this.handleCommand(); + } + } + + /** + * Main method. + * + * @param args + * array + */ + public static void main(String[] args) { + OnapCli cli = new OnapCli(args); + cli.handle(); + System.exit(cli.getExitCode()); + } + +} diff --git a/main/src/main/java/org/onap/cli/main/conf/OnapCliConstants.java b/main/src/main/java/org/onap/cli/main/conf/OnapCliConstants.java new file mode 100644 index 00000000..7fb51cbe --- /dev/null +++ b/main/src/main/java/org/onap/cli/main/conf/OnapCliConstants.java @@ -0,0 +1,39 @@ +/* + * 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.main.conf; + +public final class OnapCliConstants { + + public static final String PARAM_HELP_SHORT = "h"; + public static final String PARAM_HELP_LOGN = "help"; + + public static final String PARAM_VERSION_SHORT = "v"; + public static final String PARAM_VERSION_LONG = "version"; + + public static final int EXIT_SUCCESS = 0; + public static final int EXIT_FAILURE = 1; + + public static final String PARAM_INTERACTIVE_SHORT = "i"; + public static final String PARAM_INTERACTIVE_LONG = "interactive"; + public static final String PARAM_INTERACTIVE_PROMPT = "onap>"; + public static final String PARAM_INTERACTIVE_EXIT = "exit"; + public static final String PARAM_INTERACTIVE_BYE = "bye"; + public static final String PARAM_INTERACTIVE_CLEAR = "clear"; + public static final String PARAM_INTERACTIVE_ARG_SPLIT_PATTERN = "\\s+"; + + private OnapCliConstants(){} +} diff --git a/main/src/main/java/org/onap/cli/main/error/OnapCliArgumentValueMissing.java b/main/src/main/java/org/onap/cli/main/error/OnapCliArgumentValueMissing.java new file mode 100644 index 00000000..f8f86e46 --- /dev/null +++ b/main/src/main/java/org/onap/cli/main/error/OnapCliArgumentValueMissing.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.main.error; + +import org.onap.cli.fw.error.OnapCommandException; + +/** + * CLI argument missing. + * + */ +public class OnapCliArgumentValueMissing extends OnapCommandException { + + private static final long serialVersionUID = -6362824415803063442L; + + public OnapCliArgumentValueMissing(String arg) { + super("0x1001", "Value for argument " + arg + " is missing"); + } +} diff --git a/main/src/main/java/org/onap/cli/main/error/OnapCliInvalidArgument.java b/main/src/main/java/org/onap/cli/main/error/OnapCliInvalidArgument.java new file mode 100644 index 00000000..32d8ef6f --- /dev/null +++ b/main/src/main/java/org/onap/cli/main/error/OnapCliInvalidArgument.java @@ -0,0 +1,42 @@ +/* + * 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.main.error; + +import org.onap.cli.fw.error.OnapCommandException; + +/** + * CLI argument missing. + * + */ +public class OnapCliInvalidArgument extends OnapCommandException { + + private static final long serialVersionUID = -1438492553530993246L; + private static final String ERROR_CODE = "0x1000"; + private static final String ERROR_MESSAGE1 = "Invalid argument "; + + public OnapCliInvalidArgument(String arg) { + super(ERROR_CODE, ERROR_MESSAGE1 + arg); + } + + public OnapCliInvalidArgument(String arg, String errorMessage) { + super(ERROR_CODE, ERROR_MESSAGE1 + arg + " , " + errorMessage); + } + + public OnapCliInvalidArgument(String arg, Throwable throwable) { + this(arg , throwable.getMessage()); + } +} diff --git a/main/src/main/java/org/onap/cli/main/interactive/StringCompleter.java b/main/src/main/java/org/onap/cli/main/interactive/StringCompleter.java new file mode 100644 index 00000000..cf2a6c55 --- /dev/null +++ b/main/src/main/java/org/onap/cli/main/interactive/StringCompleter.java @@ -0,0 +1,79 @@ +/* + * 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.main.interactive; + +import jline.console.completer.Completer; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.SortedSet; +import java.util.TreeSet; + +/** + * String completer for autocomplete commands. + * + */ +public class StringCompleter implements Completer { + private final SortedSet strings = new TreeSet(); + + /** + * Public Constructor takes collection of strings. + * + * @param strings collection + */ + public StringCompleter(Collection strings) { + this.strings.addAll(strings); + } + + /** + * Public Constructor takes array of strings. + * + * @param strings array of strings + */ + public void add(String... strings) { + this.strings.addAll(Arrays.asList(strings)); + } + + /** + * String completion. + * + * @param buffer + * string + * @param cursor + * int + * @param candidates + * list + * @return int + */ + public int complete(String buffer, int cursor, List candidates) { + if (buffer == null) { + candidates.addAll(strings); + } else { + for (String match : strings.tailSet(buffer)) { + if (!match.startsWith(buffer)) { + break; + } + candidates.add(match); + } + } + if (candidates.size() == 1) { + candidates.set(0, candidates.get(0) + " "); + } + return candidates.isEmpty() ? -1 : 0; + } +} diff --git a/main/src/main/java/org/onap/cli/main/utils/OnapCliUtils.java b/main/src/main/java/org/onap/cli/main/utils/OnapCliUtils.java new file mode 100644 index 00000000..ed47bc68 --- /dev/null +++ b/main/src/main/java/org/onap/cli/main/utils/OnapCliUtils.java @@ -0,0 +1,270 @@ +/* + * 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.main.utils; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +import net.minidev.json.JSONObject; + +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandInvalidParameterValue; +import org.onap.cli.fw.input.OnapCommandParameter; +import org.onap.cli.fw.input.ParameterType; +import org.onap.cli.main.error.OnapCliArgumentValueMissing; +import org.onap.cli.main.error.OnapCliInvalidArgument; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Onap CLI utilities. + * + */ +public class OnapCliUtils { + + /** + * private Constructor. + */ + private OnapCliUtils() { + + } + + /** + * It read thru the args and populate the given params for short optional, long option and postional args the idx of + * positional args, is calculated based on the position at which it present in the params and args. + * + * @param params + * List of command paramters + * @param args + * Array of arguments + * @throws OnapCliArgumentValueMissing + * ArgumentValueMissing exception + * @throws OnapCliInvalidArgument + * Invalid argument exception + * @throws OnapCommandInvalidParameterValue + * exception + */ + public static void populateParams(List params, List args) + throws OnapCommandException { + Map shortOptionMap = new HashMap<>(); + Map longOptionMap = new HashMap<>(); + List positionArgs = new ArrayList<>(); + Map paramMap = new HashMap<>(); + + for (OnapCommandParameter param : params) { + boolean positional = true; + if (param.getShortOption() != null) { + shortOptionMap.put(OnapCommandParameter.printShortOption(param.getShortOption()), param.getName()); + positional = false; + } + if (param.getLongOption() != null) { + longOptionMap.put(OnapCommandParameter.printLongOption(param.getLongOption()), param.getName()); + positional = false; + } + + if (positional) { + positionArgs.add(param.getName()); + } + + paramMap.put(param.getName(), param); + } + + int positionalIdx = 0; + // Skip the first args onap cmd name, so start from 1 + for (int i = 1; i < args.size(); i++) { + // check if short option exist + // (mrkanag) Optimize the below code to handle short and long options in one iteration + // now its redundant + if (shortOptionMap.containsKey(args.get(i))) { + // end of the list or if its option rather than a value + if ((i + 1) == args.size() || args.get(i + 1).startsWith("-")) { + if (paramMap.get(shortOptionMap.get(args.get(i))).getParameterType().equals(ParameterType.BOOL)) { + paramMap.get(shortOptionMap.get(args.get(i))).setValue("true"); + continue; + } + throw new OnapCliArgumentValueMissing(args.get(i)); + } + + if (paramMap.get(shortOptionMap.get(args.get(i))).getParameterType().equals(ParameterType.JSON)) { + paramMap.get(shortOptionMap.get(args.get(i))).setValue(readJsonStringFromUrl(args.get(i + 1), + paramMap.get(shortOptionMap.get(args.get(i))).getName())); + i++; + continue; + } else if (paramMap.get(shortOptionMap.get(args.get(i))).getParameterType() + .equals(ParameterType.ARRAY)) { + Object value = paramMap.get(shortOptionMap.get(args.get(i))).getValue(); + List list; + if (value == "") { + list = new ArrayList<>(); + } else { + list = convertJsonToListString(paramMap.get(shortOptionMap.get(args.get(i))).getName(), + value.toString()); + } + list.add(args.get(i + 1)); + paramMap.get(shortOptionMap.get(args.get(i))).setValue(list); + i++; + continue; + } else if (paramMap.get(shortOptionMap.get(args.get(i))).getParameterType().equals(ParameterType.MAP)) { + Object value = paramMap.get(shortOptionMap.get(args.get(i))).getValue(); + + Map map; + + if (value == "") { + map = new HashMap<>(); + } else { + map = convertJsonToMapString(paramMap.get(shortOptionMap.get(args.get(i))).getName(), + value.toString()); + } + + String arg = args.get(i + 1); + String[] argArr = arg.split("="); + + if (argArr.length != 2) { + throw new OnapCliInvalidArgument(paramMap.get(shortOptionMap.get(args.get(i))).getName()); + } + + map.put(argArr[0], argArr[1]); + paramMap.get(shortOptionMap.get(args.get(i))).setValue(map); + i++; + continue; + } + + paramMap.get(shortOptionMap.get(args.get(i))).setValue(args.get(i + 1)); + + i++; + continue; + } + + // check if long option exist + if (longOptionMap.containsKey(args.get(i))) { + // end of the list or if its option rather than a value + if ((i + 1) == args.size() || args.get(i + 1).startsWith("-")) { + if (paramMap.get(longOptionMap.get(args.get(i))).getParameterType().equals(ParameterType.BOOL)) { + paramMap.get(longOptionMap.get(args.get(i))).setValue("true"); + continue; + } + throw new OnapCliArgumentValueMissing(args.get(i)); + } + + if (paramMap.get(longOptionMap.get(args.get(i))).getParameterType().equals(ParameterType.JSON)) { + paramMap.get(longOptionMap.get(args.get(i))).setValue(readJsonStringFromUrl(args.get(i + 1), + paramMap.get(longOptionMap.get(args.get(i))).getName())); + i++; + continue; + } else if (paramMap.get(longOptionMap.get(args.get(i))).getParameterType() + .equals(ParameterType.ARRAY)) { + Object value = paramMap.get(longOptionMap.get(args.get(i))).getValue(); + List list; + if (value == "") { + list = new ArrayList<>(); + } else { + list = convertJsonToListString(paramMap.get(longOptionMap.get(args.get(i))).getName(), + value.toString()); + } + list.add(args.get(i + 1)); + paramMap.get(longOptionMap.get(args.get(i))).setValue(list); + i++; + continue; + } else if (paramMap.get(longOptionMap.get(args.get(i))).getParameterType().equals(ParameterType.MAP)) { + + Object value = paramMap.get(longOptionMap.get(args.get(i))).getValue(); + + Map map; + + if (value == "") { + map = new HashMap<>(); + } else { + map = convertJsonToMapString(paramMap.get(longOptionMap.get(args.get(i))).getName(), + value.toString()); + } + + String arg = args.get(i + 1); + String[] argArr = arg.split("="); + + if (argArr.length != 2) { + throw new OnapCliInvalidArgument(paramMap.get(longOptionMap.get(args.get(i))).getName()); + } + + map.put(argArr[0], argArr[1]); + paramMap.get(longOptionMap.get(args.get(i))).setValue(map); + i++; + continue; + } + + paramMap.get(longOptionMap.get(args.get(i))).setValue(args.get(i + 1)); + + i++; + continue; + } + + // it is positional option + // Positional arg is missing from the params + if (positionalIdx >= positionArgs.size()) { + throw new OnapCliInvalidArgument(args.get(i)); + } + + paramMap.get(positionArgs.get(positionalIdx)).setValue(args.get(i)); + positionalIdx++; + } + + params.clear(); + params.addAll(paramMap.values()); + } + + private static String readJsonStringFromUrl(String input, String argName) throws OnapCliInvalidArgument { + ObjectMapper mapper = new ObjectMapper(); + try { + File file = new File(input); + if (file.isFile()) { + return mapper.readValue(file, JSONObject.class).toJSONString(); + } else if (input.startsWith("file:") || input.startsWith("http:") || input.startsWith("ftp:")) { + URL jsonUrl = new URL(input); + return mapper.readValue(jsonUrl, JSONObject.class).toJSONString(); + } else { + return mapper.readValue(input, JSONObject.class).toJSONString(); + } + } catch (IOException e) { + throw new OnapCliInvalidArgument(argName, e); + } + } + + private static List convertJsonToListString(String arg, String json) throws OnapCliInvalidArgument { + TypeReference> mapType = new TypeReference>() { + }; + try { + return new ObjectMapper().readValue(json, mapType); + } catch (IOException e) { + throw new OnapCliInvalidArgument(arg, e); + } + } + + private static Map convertJsonToMapString(String arg, String json) throws OnapCliInvalidArgument { + TypeReference> mapType = new TypeReference>() { + }; + try { + return new ObjectMapper().readValue(json, mapType); + } catch (IOException e) { + throw new OnapCliInvalidArgument(arg, e); + } + } +} diff --git a/main/src/main/resources/onap-readme.txt b/main/src/main/resources/onap-readme.txt new file mode 100644 index 00000000..737cd04d --- /dev/null +++ b/main/src/main/resources/onap-readme.txt @@ -0,0 +1,15 @@ +Onap Command-line interface (CLI). + +One Command to command whole Onap !! It provides the unified commands +to access and operate Onap functionalities. To use this CLI, please +configure the following environment variables: + +1. ONAP_MSB_URL - Onap Micro service bus(MSB) URL +2. ONAP_USERNAME - Onap user name +3. ONAP_PASSWORD - Onap user password + +To know the CLI version, type onap [-v|--version] +To know the CLI usage, type onap [-h|--help] +To know the usage of sub commands, type onap [-h|--help] + +To know more, please refer the Onap wiki https://wiki.onap.org \ No newline at end of file diff --git a/main/src/test/java/org/onap/cli/main/OnapCliMainTest.java b/main/src/test/java/org/onap/cli/main/OnapCliMainTest.java new file mode 100644 index 00000000..ca955cc9 --- /dev/null +++ b/main/src/test/java/org/onap/cli/main/OnapCliMainTest.java @@ -0,0 +1,347 @@ +/* + * 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.main; + +import static org.junit.Assert.assertTrue; + +import jline.console.ConsoleReader; +import mockit.Invocation; +import mockit.Mock; +import mockit.MockUp; + +import org.aspectj.lang.annotation.After; +import org.junit.Ignore; +import org.junit.Test; +import org.onap.cli.fw.OnapCommand; +import org.onap.cli.fw.OnapCommandRegistrar; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.main.utils.OnapCliUtils; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class OnapCliMainTest { + + OnapCli cli = null; + + /** + * Clean up. + */ + @After(value = "") + public void cleanup() { + if (this.cli != null) { + if (cli.getExitCode() != 0) { + // Fail test case + } + } + } + + private void handle(String[] args) { + cli = new OnapCli(args); + cli.handle(); + } + + @Test + public void testHelp() { + this.handle(new String[] { "--help" }); + } + + @Test + public void testHelpShort() { + this.handle(new String[] { "-h" }); + } + + @Test + public void testVersion() { + this.handle(new String[] { "--version" }); + } + + @Test + public void testVersionShort() { + this.handle(new String[] { "--v" }); + } + + @Test + public void testHelpSampleCommand() { + this.handle(new String[] { "sample-test", "--help" }); + } + + @Test + public void testHelpSampleCreateCommand() throws OnapCommandException { + ClassLoader cl = ClassLoader.getSystemClassLoader(); + URL[] urls = ((URLClassLoader) cl).getURLs(); + for (URL url : urls) { + if (url.getPath().contains("main/target/test-classes")) { + File file = new File(url.getPath() + "data"); + if (!file.exists()) { + file.mkdirs(); + } + break; + } + } + this.handle(new String[] { "sample-create", "--help" }); + OnapCommand cmd = OnapCommandRegistrar.getRegistrar().get("sample-create"); + List args = new ArrayList<>(Arrays.asList(new String[] { "sample-create", "-u", "admin", "-p", + "Changeme_123", "-m", "http://192.168.99.100:80", "--service-name", "test-service", "-i", "ip1", "-i", + "ip2", "-o", "port1=value1", "-o", "port2=value2" })); + OnapCliUtils.populateParams(cmd.getParameters(), args); + } + + @Test + public void testHelpSampleCommandShort() { + this.handle(new String[] { "sample-test", "-h" }); + } + + @Test + public void testHelpServiceListCommandShort() { + this.handle(new String[] { "microservice-list", "-h" }); + } + + @Test + public void testHelpUserCreateCommand() { + this.handle(new String[] { "user-create", "--help" }); + } + + @Test + @Ignore + public void testUserCreateCommand() { + this.handle(new String[] { "user-create", "-u", "admin", "-p", "Changeme_123", "-m", "http://192.168.99.100:80", + "--username", "test", "--password", "sss", "--description", "test user", "-d" }); + } + + @Test + @Ignore + public void testHelpVimShowCommand() { + this.handle(new String[] { "vim-show", "--help" }); + } + + @Test + @Ignore + public void testVimListCommand() { + this.handle(new String[] { "vim-list", "-u", "admin", "-p", "Changeme_123", "-m", "http://192.168.99.100:80", + "--long", "--format", "table" }); + } + + @Test + public void tesVersionServiceListCommand() { + this.handle(new String[] { "microservice-list", "--version" }); + } + + @Test + public void tesVersionServiceListCommandShort() { + this.handle(new String[] { "microservice-list", "-v" }); + } + + @Test + @Ignore + public void testServiceListCommand() { + this.handle(new String[] { "microservice-list", "-u", "root1", "-p", "root123", "-m", "http://192.168.4.47:80", + "--long", "--no-title", "true", "-d" }); + } + + @Test + @Ignore + public void testServiceCreateCommand() { + this.handle(new String[] { "microservice-create", "-u", "admin", "-p", "Changeme_123", "-m", + "http://192.168.99.100:80", "--service-name", "test-service", "--service-version", "v1", + "--service-url", "/openapi/sampletest/v1", "127.0.0.1", "8080", "--debug", "--long" }); + } + + @Test + @Ignore + public void testServiceShowCommand() { + this.handle(new String[] { "microservice-show", "-u", "admin", "-p", "Changeme_123", "-m", + "http://192.168.99.100:80", "--service-name", "test-service", "--service-version", "v1", "--debug", + "--long" }); + } + + @Test + @Ignore + public void testServiceDeleteCommand() { + this.handle(new String[] { "microservice-delete", "-u", "admin", "-p", "Changeme_123", "-m", + "http://192.168.99.100:80", "--service-name", "test-service", "--service-version", "v1", "--debug", + "--long" }); + } + + @Test + @Ignore + public void testSdncCreate() { + + this.handle(new String[] { "sdnc-create", "-u", "root1", "-p", "root123", "-m", "http://192.168.4.47:80", + "--name", "testcontroller", "--vendor", "testvendor", "--sdnc-version", "v1", "--description", + "testingSDNC", "--type", "string", "--url", "onapapi/extsys/v1", "--username", "test", "--password", + "test", "--product-name", "testproduct", "--protocol", "http", "-d" }); + } + + @Test + @Ignore + public void testSdnclist() { + + this.handle(new String[] { "sdnc-list", "-p", "root123", "--msb-url", "http://192.168.99.100", "-u", "root1", + "-d" }); + } + + @Test + @Ignore + public void testNFVResourcelist() { + this.handle(new String[] { "resource-datacenter-show", "--id", "test", "-u", "root", "-p", "root123", + "--msb-url", "http://192.168.99.100", "-a", "-d" }); + } + + @Test + @Ignore + public void testNFVResourceShow() { + + this.handle(new String[] { "resource-datacenter-show", "--id", "test", "-u", "root", "-p", "root123", + "--msb-url", "http://192.168.99.100", "-a", "-d" }); + } + + @Test + @Ignore + public void testSdncdelete() { + + this.handle(new String[] { "sdnc-delete", "-p", "root123", "--msb-url", "http://192.168.4.47", "-u", "root1", + "--id", "053104c1-0f8b-481d-9456-f7b02e87c0e7" }); + } + + @Test + @Ignore + public void testServiceCreateHelpCommand() { + this.handle(new String[] { "microservice-create", "--help" }); + } + + @Test + @Ignore + public void testGsoServiceCreateCommand() { + this.handle(new String[] { "service-create", "-m", "http://192.168.4.47:80", "-u", "root1", "-p", "root123", + "-x", "test", "-z", "test", "-n", "test", "-r", "123", "-j", + "D:/workspace/onap/integration/test/csit/plans/gso/sanity-check/jsoninput/lcm_CreateServiceReq.json", + "-d" }); + } + + @Test + @Ignore + public void testCsrUpload() { + this.handle(new String[] { "catalog-csar-create", "-u", "root", "-p", "root123", "--msb-url", + "http://192.168.4.47", "-d", "-a", "-z", "D:\\enterprise2DC.csar" }); + } + + @Test + @Ignore + public void testCsrDelete() { + this.handle(new String[] { "catalog-csar-delete", "-u", "root", "-p", "root123", "--msb-url", + "http://192.168.4.47", "-d", "-a", "-i", "7aa791f9-4e5f-433a-afeb-3555bcbabb47" }); + } + + @Test + @Ignore + public void testPortCreate() { + this.handle(new String[] { "resource-link-create", "-u", "root", "-p", "root123", "--msb-url", + "http://192.168.4.213", "-d", "-n", "PradeepLink1", "-b", "19.5.6.13", "-c", "193.4.57.13", "-g", + "193.5.6.13", "-q", "189.78.6.13", "-y", "fiberLink" }); + } + + @Test + public void validateCommands() throws IOException, OnapCommandException { + Map cmdSchemaMap = OnapCommandRegistrar.getRegistrar().getAllCommandToSchemaMap(); + for (String cmdName : cmdSchemaMap.keySet()) { + System.out.println( + "************************* '" + cmdSchemaMap.get(cmdName) + "' *******************************"); + this.handle(new String[] { "schema-validate", "-l", cmdSchemaMap.get(cmdName), "-i", "true", "-m", + "http://192.168.4.47:80", "-u", "root1", "-p", "root123" }); + } + } + + @Test + public void commandHelpTest() throws OnapCommandException { + Set cmds = OnapCommandRegistrar.getRegistrar().listCommands(); + + for (String cmdName : cmds) { + System.out.println("************************* '" + cmdName + "' *******************************"); + this.handle(new String[] { cmdName, "-h" }); + } + + } + + @Test + public void interactiveTest() { + cli = new OnapCli(new String[] { "-i" }); + boolean isInter = cli.isInteractive(); + + assertTrue(isInter); + cli = new OnapCli(new String[] { "--interactive" }); + isInter = cli.isInteractive(); + assertTrue(isInter); + cli.getExitCode(); + + mockConsole("exit"); + cli.handleInteractive(); + + mockConsole("bye"); + cli.handleInteractive(); + + mockConsole("clear"); + try { + cli.handleInteractive(); + } catch (Exception e) { + } + + mockConsole("microservice-create -h"); + + try { + cli.handleInteractive(); + } catch (Exception e) { + } + + mockConsoleReader(); + cli.handleInteractive(); + + } + + private static void mockConsoleReader() { + new MockUp() { + @Mock + public ConsoleReader createConsoleReader() throws IOException { + throw new IOException("Exception mock"); + } + }; + } + + private static void mockConsole(String input) { + new MockUp() { + boolean isMock = true; + + @Mock + public String readLine(Invocation inv) throws IOException { + if (isMock) { + isMock = false; + return input; + } else { + return inv.proceed(input); + } + } + }; + } + +} diff --git a/main/src/test/java/org/onap/cli/main/OnapCommandSampleTest.java b/main/src/test/java/org/onap/cli/main/OnapCommandSampleTest.java new file mode 100644 index 00000000..517d6c4f --- /dev/null +++ b/main/src/test/java/org/onap/cli/main/OnapCommandSampleTest.java @@ -0,0 +1,35 @@ +/* + * 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.main; + +import org.onap.cli.fw.OnapCommand; +import org.onap.cli.fw.OnapCommandSchema; +import org.onap.cli.fw.error.OnapCommandException; + +/** + * This command helps to test the Command functionalities. + * + */ +@OnapCommandSchema(name = "sample-test", schema = "sample-test-schema.yaml") +public class OnapCommandSampleTest extends OnapCommand { + + @Override + protected void run() throws OnapCommandException { + + } + +} diff --git a/main/src/test/java/org/onap/cli/main/conf/OnapCliConstantsTest.java b/main/src/test/java/org/onap/cli/main/conf/OnapCliConstantsTest.java new file mode 100644 index 00000000..af19836a --- /dev/null +++ b/main/src/test/java/org/onap/cli/main/conf/OnapCliConstantsTest.java @@ -0,0 +1,33 @@ +/* + * 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.main.conf; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class OnapCliConstantsTest { + + @Test + public void test() { + assertTrue(1 == OnapCliConstants.EXIT_FAILURE && 0 == OnapCliConstants.EXIT_SUCCESS + && "help".equals(OnapCliConstants.PARAM_HELP_LOGN) && "h".equals(OnapCliConstants.PARAM_HELP_SHORT) + && "v".equals(OnapCliConstants.PARAM_VERSION_SHORT) + && "version".equals(OnapCliConstants.PARAM_VERSION_LONG)); + } + +} diff --git a/main/src/test/java/org/onap/cli/main/error/OnapCliArgumentTest.java b/main/src/test/java/org/onap/cli/main/error/OnapCliArgumentTest.java new file mode 100644 index 00000000..3916c630 --- /dev/null +++ b/main/src/test/java/org/onap/cli/main/error/OnapCliArgumentTest.java @@ -0,0 +1,39 @@ +/* + * 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.main.error; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class OnapCliArgumentTest { + + @Test + public void onapCliArgumentValueMissingTest() { + OnapCliArgumentValueMissing failed = new OnapCliArgumentValueMissing("Argument value missing"); + assertEquals("0x1001::Value for argument Argument value missing is missing", failed.getMessage()); + } + + @Test + public void onapCliInvalidArgumentTest() { + OnapCliInvalidArgument failed = new OnapCliInvalidArgument("Invalid Argument"); + assertEquals("0x1000::Invalid argument Invalid Argument", failed.getMessage()); + failed = new OnapCliInvalidArgument("Invalid Argument", new Exception("")); + assertEquals("0x1000::Invalid argument Invalid Argument , ", failed.getMessage()); + } + +} diff --git a/main/src/test/java/org/onap/cli/main/interactive/StringCompleterTest.java b/main/src/test/java/org/onap/cli/main/interactive/StringCompleterTest.java new file mode 100644 index 00000000..9d5cbf17 --- /dev/null +++ b/main/src/test/java/org/onap/cli/main/interactive/StringCompleterTest.java @@ -0,0 +1,48 @@ +/* + * 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.main.interactive; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; + +public class StringCompleterTest { + + @Test + public void completeTest() { + StringCompleter com = new StringCompleter(Arrays.asList(new String[] { "test", "testing1", "testing2" })); + int result = com.complete("test", 1, new ArrayList()); + assertTrue(result == 0); + result = com.complete(null, 1, new ArrayList()); + assertTrue(result == 0); + + com.add("test", "testing1", "testing2"); + result = com.complete("test", 1, new ArrayList()); + assertTrue(result == 0); + + result = com.complete("sfds", 1, new ArrayList()); + assertTrue(result == -1); + + + result = com.complete("test", 1, new ArrayList()); + assertTrue(result == 0); + } + +} diff --git a/main/src/test/java/org/onap/cli/main/utils/OnapCliUtilsTest.java b/main/src/test/java/org/onap/cli/main/utils/OnapCliUtilsTest.java new file mode 100644 index 00000000..c7fb7985 --- /dev/null +++ b/main/src/test/java/org/onap/cli/main/utils/OnapCliUtilsTest.java @@ -0,0 +1,330 @@ +/* + * 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.main.utils; + +import org.junit.Assert; +import org.junit.Test; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.input.OnapCommandParameter; +import org.onap.cli.fw.input.ParameterType; +import org.onap.cli.main.error.OnapCliArgumentValueMissing; +import org.onap.cli.main.error.OnapCliInvalidArgument; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class OnapCliUtilsTest { + + @Test + public void testpopulateParamsLong() throws OnapCommandException { + OnapCommandParameter param1 = new OnapCommandParameter(); + param1.setLongOption("onap-username"); + param1.setName("onap-username"); + param1.setParameterType(ParameterType.STRING); + OnapCommandParameter param2 = new OnapCommandParameter(); + param2.setLongOption("onap-password"); + param2.setName("onap-password"); + param2.setParameterType(ParameterType.STRING); + OnapCommandParameter param3 = new OnapCommandParameter(); + param3.setLongOption("msb-url"); + param3.setName("msb-url"); + param3.setParameterType(ParameterType.STRING); + OnapCommandParameter param4 = new OnapCommandParameter(); + param4.setLongOption("string-param"); + param4.setName("string-param"); + param4.setParameterType(ParameterType.STRING); + OnapCommandParameter param5 = new OnapCommandParameter(); + param5.setLongOption("long-opt"); + param5.setName("long-opt"); + param5.setParameterType(ParameterType.STRING); + + List paramslist = new ArrayList<>(); + paramslist.add(param1); + paramslist.add(param2); + paramslist.add(param3); + paramslist.add(param4); + paramslist.add(param5); + + String[] args = new String[] { "sample-create", "--onap-username", "admin", "--onap-password", "123", + "--msb-url", "a@b.com", "--string-param", "blah", "--long-opt", "10" }; + OnapCliUtils.populateParams(paramslist, Arrays.asList(args)); + List expectedList = Arrays.asList(args); + + Assert.assertEquals("onap-username", expectedList.get(2), param1.getValue()); + Assert.assertEquals("onap-password", expectedList.get(4), param2.getValue()); + Assert.assertEquals("msb-url", expectedList.get(6), param3.getValue()); + Assert.assertEquals("string-param", expectedList.get(8), param4.getValue()); + Assert.assertEquals("long-opt", expectedList.get(10), param5.getValue()); + + } + + @Test + public void testpositionalargs() throws OnapCommandException { + OnapCommandParameter paramargs = new OnapCommandParameter(); + paramargs.setName("http://localhost:8082/file.txt"); + List paramslist = new ArrayList<>(); + paramslist.add(paramargs); + String[] args = new String[] { "positional-args", "http://localhost:8082/file.txt" }; + paramargs.setParameterType(ParameterType.STRING); + OnapCliUtils.populateParams(paramslist, Arrays.asList(args)); + List expectedList = Arrays.asList(args); + Assert.assertEquals("positional-args", expectedList.get(1), paramslist.get(0).getValue()); + } + + @Test + public void testboolparamslong() throws OnapCommandException { + OnapCommandParameter boolparam = new OnapCommandParameter(); + boolparam.setLongOption("bool"); + boolparam.setName("bool-param"); + List paramslist = new ArrayList<>(); + paramslist.add(boolparam); + String[] args = new String[] { "sample-create", "--bool" }; + + boolparam.setParameterType(ParameterType.BOOL); + OnapCliUtils.populateParams(paramslist, Arrays.asList(args)); + List expectedList = Arrays.asList(args); + Assert.assertNotNull(expectedList.get(1), paramslist.get(0).getValue()); + + } + + @Test + public void testboolparamsshort() throws OnapCommandException { + OnapCommandParameter boolparam = new OnapCommandParameter(); + boolparam.setShortOption("b"); + boolparam.setName("bool-param"); + List paramslist = new ArrayList<>(); + paramslist.add(boolparam); + String[] args = new String[] { "sample-create", "-b", }; + + boolparam.setParameterType(ParameterType.BOOL); + OnapCliUtils.populateParams(paramslist, Arrays.asList(args)); + List expectedList = Arrays.asList(args); + Assert.assertNotNull(expectedList.get(1), paramslist.get(0).getValue()); + } + + @Test + public void testjsonparamsshort() throws OnapCommandException { + OnapCommandParameter jsonparam = new OnapCommandParameter(); + jsonparam.setShortOption("j"); + jsonparam.setName("json-param"); + List paramslist = new ArrayList<>(); + paramslist.add(jsonparam); + File resourcesDirectory = new File("src/test/resources/sampletest.json"); + String[] args = new String[] { "sample-create", "-j", "file:" + resourcesDirectory }; + jsonparam.setParameterType(ParameterType.JSON); + OnapCliUtils.populateParams(paramslist, Arrays.asList(args)); + List expectedList = Arrays.asList(args); + Assert.assertNotNull(expectedList.get(1), paramslist.get(0).getValue()); + } + + @Test + public void testjsonparamslong() throws OnapCommandException { + OnapCommandParameter jsonparam = new OnapCommandParameter(); + jsonparam.setLongOption("json-param"); + jsonparam.setName("json-param"); + List paramslist = new ArrayList<>(); + paramslist.add(jsonparam); + File resourcesDirectory = new File("src/test/resources/sampletest.json"); + String[] args = new String[] { "sample-create", "--json-param", "file:" + resourcesDirectory }; + jsonparam.setParameterType(ParameterType.JSON); + OnapCliUtils.populateParams(paramslist, Arrays.asList(args)); + List expectedList = Arrays.asList(args); + Assert.assertNotNull(expectedList.get(1), paramslist.get(0).getValue()); + } + + @Test + public void testpopulateParamsShort() throws OnapCommandException { + + OnapCommandParameter param1 = new OnapCommandParameter(); + param1.setShortOption("u"); + param1.setName("onap-username"); + param1.setParameterType(ParameterType.STRING); + OnapCommandParameter param2 = new OnapCommandParameter(); + param2.setShortOption("p"); + param2.setName("onap-password"); + param2.setParameterType(ParameterType.STRING); + OnapCommandParameter param3 = new OnapCommandParameter(); + param3.setShortOption("r"); + param3.setName("msb-url"); + param3.setParameterType(ParameterType.STRING); + OnapCommandParameter param4 = new OnapCommandParameter(); + param4.setShortOption("c"); + param4.setName("string-param"); + param4.setParameterType(ParameterType.STRING); + OnapCommandParameter param5 = new OnapCommandParameter(); + param5.setShortOption("l"); + param5.setName("long-opt"); + param5.setParameterType(ParameterType.STRING); + + List paramslist = new ArrayList<>(); + paramslist.add(param1); + paramslist.add(param2); + paramslist.add(param3); + paramslist.add(param4); + paramslist.add(param5); + + String[] args11 = new String[] { "sample-create", "-u", "admin", "-p", "123", "-r", "a@b.com", "-c", "blah", + "-l", "10", }; + OnapCliUtils.populateParams(paramslist, Arrays.asList(args11)); + + List expectedList = Arrays.asList(args11); + + Assert.assertEquals("u", expectedList.get(2), param1.getValue()); + Assert.assertEquals("-p", expectedList.get(4), param2.getValue()); + Assert.assertEquals("r", expectedList.get(6), param3.getValue()); + Assert.assertEquals("c", expectedList.get(8), param4.getValue()); + Assert.assertEquals("l", expectedList.get(10), param5.getValue()); + } + + @Test + public void testArrayparamslong() throws OnapCommandException { + OnapCommandParameter arrayval = new OnapCommandParameter(); + arrayval.setLongOption("node-ip"); + arrayval.setName("node-ip"); + + String[] args = new String[] { "sample-create", "--node-ip", "{}" }; + List paramslist = new ArrayList<>(); + paramslist.add(arrayval); + + arrayval.setParameterType(ParameterType.ARRAY); + OnapCliUtils.populateParams(paramslist, Arrays.asList(args)); + + List expectedList = Arrays.asList(args); + Assert.assertNotNull(expectedList.get(1), paramslist.get(0).getValue()); + } + + @Test + public void testMapparamsShort() throws OnapCommandException { + OnapCommandParameter param1 = new OnapCommandParameter(); + param1.setLongOption("map"); + param1.setName("MAP"); + param1.setParameterType(ParameterType.MAP); + List paramslist = new ArrayList<>(); + paramslist.add(param1); + + param1.setParameterType(ParameterType.MAP); + OnapCliUtils.populateParams(paramslist, + Arrays.asList("show", "--map", "param1=value1", "--map", "param2=value2")); + + Assert.assertEquals("{\"param1\":\"value1\",\"param2\":\"value2\"}", paramslist.get(0).getValue().toString()); + } + + @Test(expected = OnapCliInvalidArgument.class) + public void testMapparamsLongfail() throws OnapCommandException { + OnapCommandParameter param1 = new OnapCommandParameter(); + param1.setLongOption("map"); + param1.setName("MAP"); + param1.setParameterType(ParameterType.MAP); + List paramslist = new ArrayList<>(); + paramslist.add(param1); + + param1.setParameterType(ParameterType.MAP); + OnapCliUtils.populateParams(paramslist, Arrays.asList("show", "--map", "param1=value1", "--map", "param2")); + Assert.assertEquals("{\"param1\":\"value1\",\"param2\"}", paramslist.get(0).getValue().toString()); + } + + @Test(expected = OnapCliInvalidArgument.class) + public void testMapparamsShortfail() throws OnapCommandException { + OnapCommandParameter param1 = new OnapCommandParameter(); + param1.setShortOption("o"); + param1.setName("node-port"); + param1.setParameterType(ParameterType.MAP); + List paramslist = new ArrayList<>(); + paramslist.add(param1); + param1.setParameterType(ParameterType.MAP); + OnapCliUtils.populateParams(paramslist, Arrays.asList("show", "-o", "param1=value1", "-o", "param2")); + Assert.assertEquals("{\"param1\":\"value1\",\"param2\"}", paramslist.get(0).getValue().toString()); + } + + @Test(expected = OnapCliInvalidArgument.class) + public void testpositionalargsfails() throws OnapCommandException { + OnapCommandParameter paramargs = new OnapCommandParameter(); + paramargs.setName("http://localhost:8082/file.txt"); + List paramslist = new ArrayList<>(); + paramslist.add(paramargs); + String[] args = new String[] { "positional-args", "http://localhost:8082/file.txt", + "http://localhost:8082/file.txt" }; + paramargs.setParameterType(ParameterType.STRING); + OnapCliUtils.populateParams(paramslist, Arrays.asList(args)); + List expectedList = Arrays.asList(args); + Assert.assertEquals("positional-args", expectedList.get(1), paramslist.get(0).getValue()); + } + + @Test(expected = OnapCliInvalidArgument.class) + public void testboolparamsshortfails() throws OnapCommandException { + OnapCommandParameter boolparam = new OnapCommandParameter(); + boolparam.setShortOption("b"); + boolparam.setName("bool-param"); + List paramslist = new ArrayList<>(); + paramslist.add(boolparam); + String[] args = new String[] { "sample-create", "-b", "-b", "-h" }; + + boolparam.setParameterType(ParameterType.BOOL); + OnapCliUtils.populateParams(paramslist, Arrays.asList(args)); + List expectedList = Arrays.asList(args); + Assert.assertEquals("true", paramslist.get(0).getValue()); + } + + @Test(expected = OnapCliInvalidArgument.class) + public void testboolparamsLongfails() throws OnapCommandException { + OnapCommandParameter boolparam = new OnapCommandParameter(); + boolparam.setShortOption("bool"); + boolparam.setName("bool-param"); + List paramslist = new ArrayList<>(); + paramslist.add(boolparam); + String[] args = new String[] { "sample-create", "--bool", "--bool", "--help" }; + + boolparam.setParameterType(ParameterType.BOOL); + OnapCliUtils.populateParams(paramslist, Arrays.asList(args)); + List expectedList = Arrays.asList(args); + Assert.assertEquals("true", paramslist.get(0).getValue()); + } + + @Test(expected = OnapCliArgumentValueMissing.class) + public void testjsonparamslongfails() throws OnapCommandException { + OnapCommandParameter jsonparam = new OnapCommandParameter(); + jsonparam.setLongOption("json-param"); + jsonparam.setName("json-param"); + List paramslist = new ArrayList<>(); + paramslist.add(jsonparam); + File resourcesDirectory = new File("src/test/resources/sampletest.json"); + String[] args = new String[] { "sample-create", "--json-param", "file:" + resourcesDirectory, "--json-param" }; + jsonparam.setParameterType(ParameterType.JSON); + OnapCliUtils.populateParams(paramslist, Arrays.asList(args)); + List expectedList = Arrays.asList(args); + Assert.assertEquals("--json-param", paramslist.get(0).getValue()); + + } + + @Test(expected = OnapCliArgumentValueMissing.class) + public void testjsonparamsshortfails() throws OnapCommandException { + OnapCommandParameter jsonparam = new OnapCommandParameter(); + jsonparam.setShortOption("j"); + jsonparam.setName("json-param"); + List paramslist = new ArrayList<>(); + paramslist.add(jsonparam); + File resourcesDirectory = new File("src/test/resources/sampletest.json"); + String[] args = new String[] { "sample-create", "-j", "file:" + resourcesDirectory, "-j" }; + jsonparam.setParameterType(ParameterType.JSON); + OnapCliUtils.populateParams(paramslist, Arrays.asList(args)); + List expectedList = Arrays.asList(args); + Assert.assertEquals("--json-param", paramslist.get(0).getValue()); + + } +} \ No newline at end of file diff --git a/main/src/test/resources/META-INF/services/org.onap.cli.fw.OnapCommand b/main/src/test/resources/META-INF/services/org.onap.cli.fw.OnapCommand new file mode 100644 index 00000000..16dd879a --- /dev/null +++ b/main/src/test/resources/META-INF/services/org.onap.cli.fw.OnapCommand @@ -0,0 +1 @@ +org.onap.cli.main.OnapCommandSampleTest \ No newline at end of file diff --git a/main/src/test/resources/onap-cli-schema/sample-create-schema.yaml b/main/src/test/resources/onap-cli-schema/sample-create-schema.yaml new file mode 100644 index 00000000..6e775334 --- /dev/null +++ b/main/src/test/resources/onap-cli-schema/sample-create-schema.yaml @@ -0,0 +1,71 @@ +onap_cmd_schema_version: 1.0 +name: sample-create +description: Sample create into Onap +service: + name: sample + version: v1 + no-auth: true +parameters: + - name: service-name + description: Onap service name + type: string + short_option: x + long_option: service-name + is_optional: false + - name: node-ip + description: Onap service running node IP + type: array + short_option: i + long_option: node-ip + - name: node-port + description: Onap service running node port + type: map + short_option: o + long_option: node-port +results: + direction: portrait + attributes: + - name: name + description: Onap service name + scope: short + type: string + - name: version + description: Onap service version + scope: short + type: string + - name: url + description: Onap service base url + scope: short + type: url + - name: status + description: Onap service status + scope: short + type: long + - name: nodes + description: Onap service running nodes + scope: long + type: string + - name: location + description: Onap service location + scope: long + type: url +http: + request: + uri: /services + method: POST + body: '{"serviceName":"${service-name}","nodeIp":"${node-ip}","nodePort":"${node-port}"}' + headers: + queries: + success_codes: + - 201 + - 200 + result_map: + name: $b{$.serviceName} + version: $b{$.version} + url: $b{$.url} + status: $b{$.status} + nodes: $b{$.nodes[*].ip}:$b{$.nodes[*].port} + location: $h{Location} + + sample_response: + body: {"serviceName":"test","version":"v1","url":"/api/test/v1","protocol":"REST","visualRange":"1","lb_policy":"hash","nodes":[{"ip":"127.0.0.1","port":"8012","ttl":0,"nodeId":"test_127.0.0.1_8012","expiration":"2017-02-10T05:33:25Z","created_at":"2017-02-10T05:33:25Z","updated_at":"2017-02-10T05:33:25Z"}],"status":"1"} \ No newline at end of file diff --git a/main/src/test/resources/sample-test-schema.yaml b/main/src/test/resources/sample-test-schema.yaml new file mode 100644 index 00000000..419f416c --- /dev/null +++ b/main/src/test/resources/sample-test-schema.yaml @@ -0,0 +1,79 @@ +onap_cmd_schema_version: 1.0 +name: sample-test +description: Onap sample command to test the command features +service: + name: sample + version: v1 +parameters: + - name: bool-param + type: bool + description: Onap boolean param, by default its always false. + short_option: b + long_option: bool + is_optional: true + default_value: false + - name: secure-param + type: string + description: Onap secure param such as password + short_option: x + long_option: secure + is_secured: true + is_optional: false + default_Value: pass123# + - name: string-param + type: string + description: Onap string param + long_option: string-param + short_option: c + is_optional: false + default_Value: test + - name: yaml-param + type: json + description: Onap yaml file location param + long_option: yaml-param + short_option: y + is_optional: false + - name: json-param + type: json + description: Onap json file location param + long_option: json-param + short_option: j + is_optional: false + - name: long-param + type: long + description: Onap long param + short_option: l + long_option: long-opt + is_optional: false + default_value: 10 + - name: url-param + type: url + description: Onap url param + short_option: r + long_option: url + is_optional: false + default_value: http://localhost:8082/file.txt + - name: env-param + type: string + description: Onap env param. + short_option: z + long_option: env + is_optional: false + default_value: ${ENV_VAR} + default_value: http://localhost:8082/file.txt + - name: positional-args + type: string + description: Onap positional args, if no short option and no long option given for it + is_optional: false + default_value: http://localhost:8082/file.txt +results: + direction: portrait + attributes: + - name: output-1 + description: Onap output attribute marked in short + scope: short + type: string + - name: output-2 + description: Onap output attribute marked in long + scope: short + type: string \ No newline at end of file diff --git a/main/src/test/resources/sampletest.json b/main/src/test/resources/sampletest.json new file mode 100644 index 00000000..44c101ce --- /dev/null +++ b/main/src/test/resources/sampletest.json @@ -0,0 +1,8 @@ +{ + "name": "test", + "messages": [ + "hello jackson 1", + "hello jackson 2", + "hello jackson 3" + ] +} \ No newline at end of file diff --git a/plugins/common-service/pom.xml b/plugins/common-service/pom.xml new file mode 100644 index 00000000..0ca644ed --- /dev/null +++ b/plugins/common-service/pom.xml @@ -0,0 +1,33 @@ + + + + + 4.0.0 + + + org.onap.cli + cli-plugins + 1.0.0-SNAPSHOT + + + cli-plugin-common-service + cli/plugins/common-service + jar + diff --git a/plugins/common-service/src/main/java/org/onap/cli/cmd/cs/msb/OnapServiceCreateCommand.java b/plugins/common-service/src/main/java/org/onap/cli/cmd/cs/msb/OnapServiceCreateCommand.java new file mode 100644 index 00000000..8b46e6b8 --- /dev/null +++ b/plugins/common-service/src/main/java/org/onap/cli/cmd/cs/msb/OnapServiceCreateCommand.java @@ -0,0 +1,24 @@ +/* + * 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.cmd.cs.msb; + +import org.onap.cli.fw.OnapCommandSchema; +import org.onap.cli.fw.cmd.OnapHttpCommand; + +@OnapCommandSchema(name = "microservice-create", schema = "microservice-create-schema.yaml") +public class OnapServiceCreateCommand extends OnapHttpCommand { +} diff --git a/plugins/common-service/src/main/java/org/onap/cli/cmd/cs/msb/OnapServiceDeleteCommand.java b/plugins/common-service/src/main/java/org/onap/cli/cmd/cs/msb/OnapServiceDeleteCommand.java new file mode 100644 index 00000000..595934d9 --- /dev/null +++ b/plugins/common-service/src/main/java/org/onap/cli/cmd/cs/msb/OnapServiceDeleteCommand.java @@ -0,0 +1,24 @@ +/* + * 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.cmd.cs.msb; + +import org.onap.cli.fw.OnapCommandSchema; +import org.onap.cli.fw.cmd.OnapHttpCommand; + +@OnapCommandSchema(name = "microservice-delete", schema = "microservice-delete-schema.yaml") +public class OnapServiceDeleteCommand extends OnapHttpCommand { +} diff --git a/plugins/common-service/src/main/java/org/onap/cli/cmd/cs/msb/OnapServiceListCommand.java b/plugins/common-service/src/main/java/org/onap/cli/cmd/cs/msb/OnapServiceListCommand.java new file mode 100644 index 00000000..436d187b --- /dev/null +++ b/plugins/common-service/src/main/java/org/onap/cli/cmd/cs/msb/OnapServiceListCommand.java @@ -0,0 +1,24 @@ +/* + * 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.cmd.cs.msb; + +import org.onap.cli.fw.OnapCommandSchema; +import org.onap.cli.fw.cmd.OnapHttpCommand; + +@OnapCommandSchema(name = "microservice-list", schema = "microservice-list-schema.yaml") +public class OnapServiceListCommand extends OnapHttpCommand { +} diff --git a/plugins/common-service/src/main/java/org/onap/cli/cmd/cs/msb/OnapServiceShowCommand.java b/plugins/common-service/src/main/java/org/onap/cli/cmd/cs/msb/OnapServiceShowCommand.java new file mode 100644 index 00000000..2256cc61 --- /dev/null +++ b/plugins/common-service/src/main/java/org/onap/cli/cmd/cs/msb/OnapServiceShowCommand.java @@ -0,0 +1,24 @@ +/* + * 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.cmd.cs.msb; + +import org.onap.cli.fw.OnapCommandSchema; +import org.onap.cli.fw.cmd.OnapHttpCommand; + +@OnapCommandSchema(name = "microservice-show", schema = "microservice-show-schema.yaml") +public class OnapServiceShowCommand extends OnapHttpCommand { +} diff --git a/plugins/common-service/src/main/resources/META-INF/services/org.onap.cli.fw.OnapCommand b/plugins/common-service/src/main/resources/META-INF/services/org.onap.cli.fw.OnapCommand new file mode 100644 index 00000000..527abe0c --- /dev/null +++ b/plugins/common-service/src/main/resources/META-INF/services/org.onap.cli.fw.OnapCommand @@ -0,0 +1,4 @@ +org.onap.cli.cmd.cs.msb.OnapServiceListCommand +org.onap.cli.cmd.cs.msb.OnapServiceShowCommand +org.onap.cli.cmd.cs.msb.OnapServiceDeleteCommand +org.onap.cli.cmd.cs.msb.OnapServiceCreateCommand \ No newline at end of file diff --git a/plugins/common-service/src/main/resources/microservice-create-schema.yaml b/plugins/common-service/src/main/resources/microservice-create-schema.yaml new file mode 100644 index 00000000..13bd53b1 --- /dev/null +++ b/plugins/common-service/src/main/resources/microservice-create-schema.yaml @@ -0,0 +1,85 @@ +onap_cmd_schema_version: 1.0 +name: microservice-create +description: Register microservice into Onap +service: + name: msb + version: v1 + +parameters: + - name: service-name + description: Onap service name + type: string + short_option: x + long_option: service-name + is_optional: false + - name: service-version + description: Onap service version + type: string + short_option: y + long_option: service-version + is_optional: false + - name: service-url + description: Onap service base url + type: url + short_option: r + long_option: service-url + is_optional: false + - name: node-ip + description: Onap service running node IP + type: string + - name: node-port + description: Onap service running node port + type: string + - name: create-or-update + description: Onap service create or update + type: bool + default_value: true +results: + direction: portrait + attributes: + - name: name + description: Onap service name + scope: short + type: string + - name: version + description: Onap service version + scope: short + type: string + - name: url + description: Onap service base url + scope: short + type: url + - name: status + description: Onap service status + scope: short + type: long + - name: nodes + description: Onap service running nodes + scope: long + type: string + - name: location + description: Onap service location + scope: long + type: url +http: + request: + uri: /services + method: POST + body: '{"serviceName":"${service-name}","version":"${service-version}","url":"${service-url}","protocol":"REST","visualRange":"1","lb_policy":"hash","nodes":[{"ip":"${node-ip}","port":"${node-port}","ttl":0}]}' + headers: + queries: + createOrUpdate: ${create-or-update} + success_codes: + - 201 + - 200 + result_map: + name: $b{$.serviceName} + version: $b{$.version} + url: $b{$.url} + status: $b{$.status} + nodes: $b{$.nodes[*].ip}:$b{$.nodes[*].port} + location: $h{Location} + + sample_response: + body: '{"serviceName":"test","version":"v1","url":"/api/test/v1","protocol":"REST","visualRange":"1","lb_policy":"hash","nodes":[{"ip":"127.0.0.1","port":"8012","ttl":0,"nodeId":"test_127.0.0.1_8012","expiration":"2017-02-10T05:33:25Z","created_at":"2017-02-10T05:33:25Z","updated_at":"2017-02-10T05:33:25Z"}],"status":"1"}' + diff --git a/plugins/common-service/src/main/resources/microservice-delete-schema.yaml b/plugins/common-service/src/main/resources/microservice-delete-schema.yaml new file mode 100644 index 00000000..695efe1e --- /dev/null +++ b/plugins/common-service/src/main/resources/microservice-delete-schema.yaml @@ -0,0 +1,31 @@ +onap_cmd_schema_version: 1.0 +name: microservice-delete +description: Deletes the micro service from Onap +service: + name: msb + version: v1 + +parameters: + - name: service-name + description: Onap service name + type: string + short_option: x + long_option: service-name + is_optional: false + - name: service-version + description: Onap service version + type: string + short_option: y + long_option: service-version + is_optional: false +http: + request: + uri: /services/${service-name}/version/${service-version} + method: DELETE + success_codes: + - 201 + - 200 + - 204 + + + diff --git a/plugins/common-service/src/main/resources/microservice-list-schema.yaml b/plugins/common-service/src/main/resources/microservice-list-schema.yaml new file mode 100644 index 00000000..79dca5b1 --- /dev/null +++ b/plugins/common-service/src/main/resources/microservice-list-schema.yaml @@ -0,0 +1,49 @@ +onap_cmd_schema_version: 1.0 +name: microservice-list +description: Lists the registetred micro services in Onap +service: + name: msb + version: v1 + no-auth: true +results: + direction: landscape + attributes: + - name: name + description: Onap service name + scope: short + type: string + - name: version + description: Onap service version + scope: short + type: string + - name: url + description: Onap service base url + scope: short + type: url + - name: status + description: Onap service status + scope: short + type: long + - name: nodes + description: Onap service running nodes + scope: long + type: json +http: + request: + uri: /services + method: GET + success_codes: + - 201 + - 200 + result_map: + name: $b{$.[*].serviceName} + version: $b{$.[*].version} + url: $b{$.[*].url} + status: $b{$.[*].status} + nodes: $b{$.[*].nodes[*].ip}:$b{$.[*].nodes[*].port} + sample_response: + body: '[{"serviceName":"test","version":"v1","url":"/api/test/v1","protocol":"REST","visualRange":"1","lb_policy":"hash","nodes":[{"ip":"127.0.0.1","port":"8012","ttl":0,"nodeId":"test_127.0.0.1_8012","expiration":"2017-02-10T05:33:25Z","created_at":"2017-02-10T05:33:25Z","updated_at":"2017-02-10T05:33:25Z"}],"status":"1"}]' + + + + diff --git a/plugins/common-service/src/main/resources/microservice-show-schema.yaml b/plugins/common-service/src/main/resources/microservice-show-schema.yaml new file mode 100644 index 00000000..47e33c6a --- /dev/null +++ b/plugins/common-service/src/main/resources/microservice-show-schema.yaml @@ -0,0 +1,62 @@ +onap_cmd_schema_version: 1.0 +name: microservice-show +description: Details the registered microservice in Onap +service: + name: msb + version: v1 + no-auth: true +parameters: + - name: service-name + description: Onap service name + type: string + short_option: x + long_option: service-name + is_optional: false + - name: service-version + description: Onap service version + type: string + short_option: y + long_option: service-version + is_optional: false +results: + direction: landscape + attributes: + - name: name + description: Onap service name + scope: short + type: string + - name: version + description: Onap service version + scope: short + type: string + - name: url + description: Onap service base url + scope: short + type: url + - name: status + description: Onap service status + scope: short + type: long + - name: nodes + description: Onap service running nodes + scope: long + type: json +http: + request: + uri: /services/${service-name}/version/${service-version} + method: GET + success_codes: + - 201 + - 200 + result_map: + name: $b{$.serviceName} + version: $b{$.version} + url: $b{$.url} + status: $b{$.status} + nodes: $b{$.nodes[*].ip}:$b{$.nodes[*].port} + sample_response: + body: '{"serviceName":"test","version":"v1","url":"/api/test/v1","protocol":"REST","visualRange":"1","lb_policy":"hash","nodes":[{"ip":"127.0.0.1","port":"8012","ttl":0,"nodeId":"test_127.0.0.1_8012","expiration":"2017-02-10T05:33:25Z","created_at":"2017-02-10T05:33:25Z","updated_at":"2017-02-10T05:33:25Z"}],"status":"1"}' + + + + diff --git a/plugins/common-service/src/test/resources/service-list-schema.yaml b/plugins/common-service/src/test/resources/service-list-schema.yaml new file mode 100644 index 00000000..72e774b8 --- /dev/null +++ b/plugins/common-service/src/test/resources/service-list-schema.yaml @@ -0,0 +1,59 @@ +onap_cmd_schema_version: 1.0 +name: service-list +description: Onap Service list +service: + name: msb + version: v1 +results: + direction: landscape + attributes: + - name: name + description: Onap service name + scope: short + type: string + - name: version + description: Onap service version + scope: short + type: string + - name: url + description: Onap service base url + scope: short + type: url + - name: status + description: Onap service status + scope: short + type: long + - name: nodes + description: Onap service running nodes + scope: long + type: json + - name: server + description: test + scope: long + type: string +exec: + api: org.onap.common_services.microservice_bus.apiroute_service.client.api.MSBServiceResourceApi + client: org.onap.common_services.microservice_bus.apiroute_service.client.invoker.ApiClient + entity: org.onap.common_services.microservice_bus.apiroute_service.client.model.MicroServiceFullInfo + method: getMicroService + exception: org.onap.common_services.microservice_bus.apiroute_service.client.invoker.ApiException +http: + request: + uri: /services + method: GET + success_codes: + - 201 + - 200 + result_map: + name: $b{$.[*].serviceName} + version: $b{$.[*].version} + url: $b{$.[*].url} + status: $b{$.[*].status} + nodes: $b{$.[*].nodes[*].nodeId} + server: $h{Server}-$b{$.[*].nodes[*].nodeId} + sample_response: + body: [{"serviceName":"test","version":"v1","url":"/api/test/v1","protocol":"REST","visualRange":"1","lb_policy":"hash","nodes":[{"ip":"127.0.0.1","port":"8012","ttl":0,"nodeId":"test_127.0.0.1_8012","expiration":"2017-02-10T05:33:25Z","created_at":"2017-02-10T05:33:25Z","updated_at":"2017-02-10T05:33:25Z"}],"status":"1"}] + + + + diff --git a/plugins/common-service/src/test/resources/user-create-schema.yaml b/plugins/common-service/src/test/resources/user-create-schema.yaml new file mode 100644 index 00000000..3f1e8866 --- /dev/null +++ b/plugins/common-service/src/test/resources/user-create-schema.yaml @@ -0,0 +1,47 @@ +onap_cmd_schema_version: 1.0 +name: user-create +description: Onap user create command. +service: + name: auth + version: v1 +parameters: + - name: username + type: string + description: Onap user name + short_option: n + long_option: username + is_optional: false + - name: password + type: string + description: Onap user password + short_option: c + long_option: password + is_secured: true + is_optional: false + - name: description + type: string + description: Onap user description + short_option: e + long_option: description + is_optional: true +results: + direction: portrait + attributes: + - name: name + description: Onap user name + scope: short + type: string + - name: id + description: Onap user id + scope: short + type: string + - name: description + description: Onap user description + scope: short + type: string +exec: + api: org.onap.common_services.auth.auth_service.client.api.DefaultApi + client: org.onap.common_services.auth.auth_service.client.invoker.ApiClient + entity: org.onap.common_services.auth.auth_service.client.model.User, username(userName), password, description + method: create + exception: org.onap.common_services.auth.auth_service.client.invoker.ApiException \ No newline at end of file diff --git a/plugins/pom.xml b/plugins/pom.xml new file mode 100644 index 00000000..ecccc79e --- /dev/null +++ b/plugins/pom.xml @@ -0,0 +1,49 @@ + + + + + 4.0.0 + + + org.onap.cli + cli + 1.0.0-SNAPSHOT + + + cli-plugins + cli/plugins + pom + + + junit + junit + 4.11 + test + + + org.onap.cli + cli-framework + 1.0.0-SNAPSHOT + + + + common-service + + diff --git a/pom.xml b/pom.xml new file mode 100644 index 00000000..258247dd --- /dev/null +++ b/pom.xml @@ -0,0 +1,76 @@ + + + + 4.0.0 + + + org.onap.oparent + version + 1.0.0-SNAPSHOT + + + org.onap.cli + cli + pom + cli + + + UTF-8 + cli + + + + framework + plugins + main + deployment + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.0.2 + + + + true + true + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-jar-plugin + + + +