aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/main')
-rw-r--r--framework/src/main/java/org/onap/cli/fw/OnapCommand.java304
-rw-r--r--framework/src/main/java/org/onap/cli/fw/OnapCommandRegistrar.java243
-rw-r--r--framework/src/main/java/org/onap/cli/fw/OnapCommandSchema.java48
-rw-r--r--framework/src/main/java/org/onap/cli/fw/ad/OnapAuthClient.java194
-rw-r--r--framework/src/main/java/org/onap/cli/fw/ad/OnapCredentials.java67
-rw-r--r--framework/src/main/java/org/onap/cli/fw/ad/OnapService.java74
-rw-r--r--framework/src/main/java/org/onap/cli/fw/cmd/OnapHttpCommand.java97
-rw-r--r--framework/src/main/java/org/onap/cli/fw/cmd/OnapSchemaRefreshCommand.java68
-rw-r--r--framework/src/main/java/org/onap/cli/fw/cmd/OnapSchemaValidateCommand.java62
-rw-r--r--framework/src/main/java/org/onap/cli/fw/cmd/OnapSwaggerCommand.java97
-rw-r--r--framework/src/main/java/org/onap/cli/fw/conf/Constants.java160
-rw-r--r--framework/src/main/java/org/onap/cli/fw/conf/OnapCommandConfg.java79
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandClientInitialzationFailed.java37
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandDiscoveryFailed.java44
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandException.java73
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandExecutionFailed.java55
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandExecutorInfoMissing.java30
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandHelpFailed.java39
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandHttpFailure.java44
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandHttpHeaderNotFound.java30
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandHttpInvalidResponseBody.java34
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandInvalidParameterType.java32
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandInvalidParameterValue.java35
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandInvalidPrintDirection.java31
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandInvalidRegistration.java33
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandInvalidResultAttributeScope.java31
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandInvalidSchema.java35
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandInvalidSchemaVersion.java31
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandLoginFailed.java41
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandLogoutFailed.java40
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandNotFound.java30
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandNotInitialized.java30
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandOutputFormatNotsupported.java30
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandOutputPrintingFailed.java34
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandParameterMissing.java32
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandParameterNameConflict.java31
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandParameterNotFound.java30
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandParameterOptionConflict.java31
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandRegistrationFailed.java34
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandResultEmpty.java33
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandResultInitialzationFailed.java34
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandResultMapProcessingFailed.java35
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandSchemaNotFound.java34
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandServiceNotFound.java30
-rw-r--r--framework/src/main/java/org/onap/cli/fw/error/OnapCommandWarning.java33
-rw-r--r--framework/src/main/java/org/onap/cli/fw/http/HttpInput.java128
-rw-r--r--framework/src/main/java/org/onap/cli/fw/http/HttpResult.java77
-rw-r--r--framework/src/main/java/org/onap/cli/fw/http/OnapHttpConnection.java346
-rw-r--r--framework/src/main/java/org/onap/cli/fw/input/OnapCommandParameter.java254
-rw-r--r--framework/src/main/java/org/onap/cli/fw/input/ParameterType.java71
-rw-r--r--framework/src/main/java/org/onap/cli/fw/log/OnapCommandLogger.java53
-rw-r--r--framework/src/main/java/org/onap/cli/fw/output/OnapCommandResult.java249
-rw-r--r--framework/src/main/java/org/onap/cli/fw/output/OnapCommandResultAttribute.java102
-rw-r--r--framework/src/main/java/org/onap/cli/fw/output/OnapCommandResultAttributeScope.java55
-rw-r--r--framework/src/main/java/org/onap/cli/fw/output/PrintDirection.java45
-rw-r--r--framework/src/main/java/org/onap/cli/fw/output/ResultType.java63
-rw-r--r--framework/src/main/java/org/onap/cli/fw/output/print/OnapCommandPrint.java252
-rw-r--r--framework/src/main/java/org/onap/cli/fw/output/print/TableGenerator.java313
-rw-r--r--framework/src/main/java/org/onap/cli/fw/run/OnapCommandExecutor.java71
-rw-r--r--framework/src/main/java/org/onap/cli/fw/schema/AbstractSchemaValidate.java563
-rw-r--r--framework/src/main/java/org/onap/cli/fw/schema/SchemaValidate.java324
-rw-r--r--framework/src/main/java/org/onap/cli/fw/schema/SchemaValidator.java292
-rw-r--r--framework/src/main/java/org/onap/cli/fw/utils/ExternalSchema.java49
-rw-r--r--framework/src/main/java/org/onap/cli/fw/utils/OnapCommandUtils.java1087
-rw-r--r--framework/src/main/resources/META-INF/services/org.onap.cli.fw.OnapCommand2
-rw-r--r--framework/src/main/resources/default_input_parameters.yaml64
-rw-r--r--framework/src/main/resources/log4j.properties2
-rw-r--r--framework/src/main/resources/onap.properties4
-rw-r--r--framework/src/main/resources/schema-refresh.yaml26
-rw-r--r--framework/src/main/resources/schema-validate.yaml31
70 files changed, 7192 insertions, 0 deletions
diff --git a/framework/src/main/java/org/onap/cli/fw/OnapCommand.java b/framework/src/main/java/org/onap/cli/fw/OnapCommand.java
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<OnapCommandParameter> 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<OnapCommandParameter> parameters) {
+ this.cmdParameters = parameters;
+ }
+
+ /*
+ * Onap command input parameters, defined by derived command
+ */
+ public List<OnapCommandParameter> getParameters() {
+ return this.cmdParameters;
+ }
+
+ /*
+ * Onap command input parameters, defined by derived command
+ */
+ public Map<String, OnapCommandParameter> 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<String, OnapCommandParameter> 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<String, Class<? extends OnapCommand>> 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<? extends OnapCommand> 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<String> listCommands() {
+ return this.registry.keySet();
+ }
+
+ /**
+ * Returns map of command to schema.
+ *
+ * @return map
+ * @throws OnapCommandException
+ * exception
+ */
+ public Map<String, String> getAllCommandToSchemaMap() throws OnapCommandException {
+ Map<String, String> map = new HashMap<>();
+ List<ExternalSchema> 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<? extends OnapCommand> 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<Class<OnapCommand>> cmds = OnapCommandUtils.findOnapCommands();
+
+ for (Class<OnapCommand> cmd : cmds) {
+ if (cmd.isAnnotationPresent(OnapCommandSchema.class)) {
+ OnapCommandSchema ano = cmd.getAnnotation(OnapCommandSchema.class);
+ this.register(ano.name(), cmd);
+ }
+ }
+ }
+
+ private void autoDiscoverHttpSchemas() throws OnapCommandException {
+ List<ExternalSchema> schemas = OnapCommandUtils.loadExternalSchemasFromJson();
+ for (ExternalSchema schema : schemas) {
+ this.register(schema.getCmdName(), OnapHttpCommand.class);
+ }
+ }
+
+ private String getSchemaFileName(Class<? extends OnapCommand> 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<Integer> successStatusCodes = new ArrayList<>();
+
+ private Map<String, String> 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<Integer> successStatusCodes) {
+ this.successStatusCodes = successStatusCodes;
+ }
+
+ public void setResultMap(Map<String, String> resultMap) {
+ this.resultMap = resultMap;
+ }
+
+ public HttpInput getInput() {
+ return input;
+ }
+
+ public List<Integer> getSuccessStatusCodes() {
+ return successStatusCodes;
+ }
+
+ public Map<String, String> 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<String, ArrayList<String>> 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<ExternalSchema> schemas = OnapCommandUtils.findAllExternalSchemas();
+ // Will override the existing json file
+ OnapCommandUtils.persist(schemas);
+
+ List<String> slNumbers = new ArrayList<>();
+ List<String> cmdNames = new ArrayList<>();
+ List<String> cmdFiles = new ArrayList<>();
+ List<String> 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<String, OnapCommandParameter> 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<String> error = schema.validate();
+ List<String> 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> 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 <T> void initializeResult(T obj) throws OnapCommandResultInitialzationFailed {
+ this.getResult().setOutput(obj);
+ if (obj instanceof List) {
+ this.initializeListResult((List) obj);
+ } else {
+ this.initializeRow(obj);
+ }
+ }
+
+ private <T> 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 <T> void initializeListResult(List<T> 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. <br>
+ */
+public class HttpInput {
+
+ private String reqUri = "";
+
+ private String reqBody = "";
+
+ private String reqMethod = "";
+
+ private Map<String, String> reqHeaders = new HashMap<>();
+
+ private Map<String, String> reqQueries = new HashMap<>();
+
+ private Map<String, String> 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<String, String> getReqHeaders() {
+ return this.reqHeaders;
+ }
+
+ /**
+ * header parameter setter.
+ *
+ * @param reqHeaders
+ * header map
+ * @return HttpInput
+ */
+ public HttpInput setReqHeaders(Map<String, String> 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<String, String> getReqQueries() {
+ return reqQueries;
+ }
+
+ /**
+ * Request query parameters.
+ *
+ * @param reqQueries
+ * request queries
+ * @return HttpInput
+ */
+ public HttpInput setReqQueries(Map<String, String> reqQueries) {
+ if (reqQueries != null) {
+ this.reqQueries = reqQueries;
+ }
+ return this;
+ }
+
+ public Map<String, String> getReqCookies() {
+ return reqCookies;
+ }
+
+ public HttpInput setReqCookies(Map<String, String> 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. <br>
+ *
+ */
+public class HttpResult {
+
+ private int status;
+
+ private String resBody;
+
+ private Map<String, String> respHeaders = new HashMap<>();
+
+ private Map<String, String> 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<String, String> respHeaders) {
+ this.respHeaders = respHeaders;
+ }
+
+ public Map<String, String> getRespHeaders() {
+ return this.respHeaders;
+ }
+
+ public Map<String, String> getRespCookies() {
+ return respCookies;
+ }
+
+ public void setRespCookies(Map<String, String> 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.<br>
+ */
+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<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
+ .<ConnectionSocketFactory>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<String, String> getHttpHeaders(HttpResponse resp) {
+ Map<String, String> 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. <br>
+ *
+ * @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. <br>
+ *
+ * @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. <br>
+ *
+ * @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. <br>
+ *
+ * @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<Cookie> 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<String, String> 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<String> list = (List<String>) 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<String, String> map = (Map<String, String>) 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<OnapCommandResultAttribute> 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<OnapCommandResultAttribute> getRecords() {
+ return records;
+ }
+
+ public void setRecords(List<OnapCommandResultAttribute> records) {
+ this.records = records;
+ }
+
+ /**
+ * Record mapping.
+ *
+ * @return attributes
+ */
+ public Map<String, OnapCommandResultAttribute> getRecordsMap() {
+ Map<String, OnapCommandResultAttribute> 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<OnapCommandResultAttribute> getScopedRecords() {
+ List<OnapCommandResultAttribute> 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<String> values = new ArrayList<>();
+
+ /*
+ * Output scope
+ */
+ private OnapCommandResultAttributeScope outScope = OnapCommandResultAttributeScope.SHORT;
+
+ private ParameterType paramType = ParameterType.STRING;
+
+ private boolean isSecured = false;
+
+ public void setValues(List<String> 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<String> 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<String, List<String>> 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<String> data) {
+ this.data.put(header, data);
+ }
+
+ /**
+ * Get column.
+ *
+ * @param header
+ * string
+ * @return list
+ */
+ public List<String> getColumn(String header) {
+ if (this.data.get(header) == null) {
+ this.data.put(header, new ArrayList<String>());
+ }
+ 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<String> 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<List<Object>> formRows(boolean isNormalize) {
+ List<List<Object>> rows = new ArrayList<>();
+
+ // add title
+ if (this.isPrintTitle()) {
+ List<Object> 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<Object> row = new ArrayList<>();
+ for (List<String> 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<String> 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<List<Object>> 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<List<Object>> 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<List<Object>> rowsList, boolean printSeparator) {
+ StringBuilder stringBuilder = new StringBuilder();
+
+ if (rowsList.isEmpty()) {
+ return stringBuilder.toString();
+ }
+
+ Map<Integer, Integer> columnMaxWidthMapping = getMaximumWidhtofColumns(rowsList);
+ Map<Integer, Integer> 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<Object> 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<String>) 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<String> list = (List<String>) 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<Integer, Integer> 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<Integer, Integer> getMaximumWidhtofColumns(List<List<Object>> rowsList) {
+ Map<Integer, Integer> 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<Object> 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<Object> row, Map<Integer, Integer> 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<String> list = (List<String>) 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<Integer, Integer> getMaximumWidhtofRows(List<List<Object>> rowsList) {
+ Map<Integer, Integer> 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<Integer, Integer> 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<Integer, Integer> 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<String> schemaErrors = new ArrayList<>();
+ protected Map<String, Object> yamlMap = new HashMap<>();
+ protected Map<String, Object> defaultYamlMap = new HashMap<>();
+
+ protected static final List<String> HTTP_SCHEMA_LIST = Arrays.asList(ONAP_CMD_SCHEMA_VERSION, NAME, DESCRIPTION,
+ SERVICE, PARAMETERS, RESULTS, HTTP);
+
+ protected static final List<String> HTTP_SCHEMA_MANDATORY_LIST = Arrays.asList(ONAP_CMD_SCHEMA_VERSION, NAME,
+ DESCRIPTION, SERVICE, HTTP);
+ protected static final List<String> BASIC_SCHEMA_LIST = Arrays.asList(ONAP_CMD_SCHEMA_VERSION, NAME, DESCRIPTION,
+ PARAMETERS, RESULTS);
+
+ protected static final List<String> BASIC_SCHEMA_MANDATORY_LIST = Arrays.asList(ONAP_CMD_SCHEMA_VERSION, NAME,
+ DESCRIPTION, PARAMETERS);
+
+ protected static final List<String> TOP_LEVEL_PARAMS_LIST = Arrays.asList(ONAP_CMD_SCHEMA_VERSION, NAME,
+ DESCRIPTION);
+
+ protected static final List<String> TOP_LEVEL_MANDATORY_LIST = Arrays.asList(ONAP_CMD_SCHEMA_VERSION, NAME,
+ DESCRIPTION);
+
+ protected static final List<String> SERVICE_PARAMS_LIST = Arrays.asList(NAME, VERSION, NO_AUTH);
+
+ protected static final List<String> SERVICE_PARAMS_MANDATORY_LIST = Arrays.asList(NAME, VERSION);
+
+ protected static final List<String> INPUT_PARAMS_LIST = Arrays.asList(NAME, DESCRIPTION, TYPE, SHORT_OPTION,
+ LONG_OPTION, IS_OPTIONAL, DEFAULT_VALUE, IS_SECURED);
+
+ protected static final List<String> INPUT_PARAMS_MANDATORY_LIST = Arrays.asList(NAME, DESCRIPTION, TYPE);
+
+ protected static final List<String> PARAMETER_TYPES = Arrays.asList(PARAMETER_TYPE_JSON, PARAMETER_TYPE_YAML,
+ PARAMETER_TYPE_STRING, PARAMETER_TYPE_LONG, PARAMETER_TYPE_URL, PARAMETER_TYPE_BOOL, PARAMETER_TYPE_ARRAY,
+ PARAMETER_TYPE_MAP, PARAMETER_TYPE_BINARY);
+
+ protected static final List<String> RESULT_PARAMS_LIST = Arrays.asList(NAME, DESCRIPTION, TYPE, SHORT_OPTION,
+ LONG_OPTION, IS_OPTIONAL, DEFAULT_VALUE, IS_SECURED);
+
+ protected static final List<String> RESULT_PARAMS_MANDATORY_LIST = Arrays.asList(NAME, DESCRIPTION, TYPE);
+
+ protected static final List<String> HTTP_PARAMS_LIST = Arrays.asList(URI, METHOD, BODY, HEADERS, QUERIES);
+
+ protected static final List<String> HTTP_PARAMS_MANDATORY_LIST = Arrays.asList(URI, METHOD, BODY, HEADERS, QUERIES);
+
+ protected static final List<String> HTTP_MANDATORY_SECTIONS = Arrays.asList(REQUEST, SUCCESS_CODES);
+
+ protected static final List<String> HTTP_SECTIONS = Arrays.asList(REQUEST, SUCCESS_CODES, RESULT_MAP,
+ SAMPLE_RESPONSE);
+
+ protected static final List<String> HTTP_REQUEST_MANDATORY_PARAMS = Arrays.asList(URI, METHOD);
+
+ protected static final List<String> HTTP_REQUEST_PARAMS = Arrays.asList(URI, METHOD, BODY, HEADERS, QUERIES);
+
+ protected static final List<String> BOOLEAN_VALUES = Arrays.asList(BOOLEAN_TRUE, BOOLEAN_FALSE);
+ protected static final List<String> DIRECTIONS = Arrays.asList(DIRECTION_PORTRAIT, DIRECTION_LANDSCAPE);
+ protected static final List<String> RESULT_SCOPES = Arrays.asList(RESULT_SCOPE_SHORT, RESULT_SCOPE_LONG);
+
+ protected static final List<String> HTTP_METHODS = Arrays.asList(POST, GET, DELETE, PUT, HEAD);
+
+ /**
+ * Constructor.
+ *
+ * @param schemaFile
+ * schemafile
+ * @throws OnapCommandInvalidSchema
+ * exception
+ */
+ public AbstractSchemaValidate(File schemaFile) throws OnapCommandInvalidSchema {
+ loadYaml(schemaFile);
+ loadDefaultYaml();
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param schemaFile
+ * resourceName
+ * @throws OnapCommandInvalidSchema
+ * exception
+ */
+ public AbstractSchemaValidate(String schemaFile) throws OnapCommandInvalidSchema {
+
+ try {
+ Resource res = OnapCommandUtils.getExternalResource(schemaFile, EXTERNAL_SCHEMA_PATH_PATERN);
+ InputStream inputStream;
+ if (res == null) {
+ inputStream = OnapCommandUtils.class.getClassLoader().getResourceAsStream(schemaFile);
+ } else {
+ inputStream = res.getInputStream();
+ }
+
+ if (inputStream != null) {
+ loadYamlFromInputStream(schemaFile, inputStream);
+ } else {
+ throw new OnapCommandInvalidSchema(schemaFile, SCHEMA_FILE_NOT_EXIST);
+ }
+
+ } catch (IOException e) {
+ throw new OnapCommandInvalidSchema(schemaFile, e);
+ }
+ loadDefaultYaml();
+ }
+
+ private final void loadYaml(File schemaFile) throws OnapCommandInvalidSchema {
+ if (!schemaFile.isFile()) {
+ throw new OnapCommandInvalidSchema(schemaFile.getName(), SCHEMA_FILE_NOT_EXIST);
+ }
+ String fileName = schemaFile.getName();
+
+ if (!fileName.endsWith(".yaml")) {
+ throw new OnapCommandInvalidSchema(fileName, SCHEMA_FILE_WRONG_EXTN);
+ }
+
+ try {
+ InputStream inputStream = new FileInputStream(schemaFile);
+ loadYamlFromInputStream(schemaFile.getName(), inputStream);
+ } catch (FileNotFoundException e) {
+ throw new OnapCommandInvalidSchema(fileName, e);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private final void loadYamlFromInputStream(String fileName, InputStream inputStream)
+ throws OnapCommandInvalidSchema {
+ try {
+ yamlMap = (Map<String, Object>) new Yaml().load(inputStream);
+ } catch (ParserException e) {
+ throw new OnapCommandInvalidSchema(fileName, e);
+ } finally {
+ if (inputStream != null) {
+ try {
+ inputStream.close();
+ } catch (IOException e) {
+ throw new OnapCommandInvalidSchema(fileName, e); // NOSONAR
+ }
+ }
+ }
+
+ if (yamlMap == null) {
+ throw new OnapCommandInvalidSchema(fileName, SCHEMA_FILE_EMPTY);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private final void loadDefaultYaml() throws OnapCommandInvalidSchema {
+ InputStream inputStream = AbstractSchemaValidate.class.getClassLoader()
+ .getResourceAsStream(DEFAULT_SCHEMA_FILE_NAME);
+ try {
+ defaultYamlMap = (Map<String, Object>) new Yaml().load(inputStream);
+ } catch (ParserException e) {
+ throw new OnapCommandInvalidSchema(DEFAULT_SCHEMA_FILE_NAME, e);
+ }
+
+ if (defaultYamlMap == null) {
+ throw new OnapCommandInvalidSchema(DEFAULT_SCHEMA_FILE_NAME, SCHEMA_FILE_EMPTY);
+ }
+ }
+
+ /*
+ * Validate method.
+ *
+ * @throws OnapCommandInvalidSchema exception
+ */
+ @Override
+ public List<String> validate() throws OnapCommandInvalidSchema {
+
+ SchemaType type;
+ Set<String> mainSections = yamlMap.keySet();
+ if (mainSections.containsAll(HTTP_SCHEMA_MANDATORY_LIST)) {
+ type = SchemaType.HTTP;
+ } else if (mainSections.containsAll(BASIC_SCHEMA_MANDATORY_LIST)) {
+ type = SchemaType.BASIC;
+ } else {
+ schemaErrors.add(SchemaValidate.invalidSections(mainSections, HTTP_SCHEMA_MANDATORY_LIST,
+ BASIC_SCHEMA_MANDATORY_LIST));
+ return schemaErrors;
+ }
+
+ if (type.equals(SchemaType.BASIC)) {
+ validateTopLevelAttributes();
+ validateInputParameters();
+ validateResultParameters();
+ } else {
+ validateTopLevelAttributes();
+ validateServiceAttributes();
+ validateInputParameters();
+ validateResultParameters();
+ validateSpecificSchema(SchemaType.HTTP);
+ }
+ return schemaErrors;
+ }
+
+ private void validateResultAttributes(List<Map<String, Object>> resultAttributes) {
+ Set<String> resultParamNames = new HashSet<>();
+ for (Map<String, Object> attribute : resultAttributes) {
+
+ // Validate mandatory parameters
+ validateMandatoryParams(attribute, RESULT_PARAMS_LIST, RESULT_PARAMS_MANDATORY_LIST, ATTRIBUTES);
+
+ String name = String.valueOf(attribute.get(NAME));
+
+ if (resultParamNames.contains(name)) {
+ schemaErrors.add(SchemaValidate.attributeNameExist(name, ATTRIBUTES));
+ } else {
+ resultParamNames.add(name);
+ }
+
+ // Validate specific parameters
+ Object type = attribute.get(TYPE);
+ String value = String.valueOf(type);
+ if (!PARAMETER_TYPES.contains(value.toLowerCase())) {
+ schemaErrors.add(SchemaValidate.invalidType(ATTRIBUTES, name, PARAMETER_TYPES));
+ }
+
+ Object scope = attribute.get(SCOPE);
+ if (scope == null) {
+ schemaErrors.add(SchemaValidate.attributeScopeEmpty(name));
+ } else if (!RESULT_SCOPES.contains(scope)) {
+ schemaErrors.add(SchemaValidate.invalidAttributeScope(name, RESULT_SCOPES));
+ }
+
+ Object isSecured = attribute.get(IS_SECURED);
+ if (isSecured != null) {
+ String value2 = String.valueOf(isSecured);
+ if (!validateBoolean(value2)) {
+ schemaErrors.add(SchemaValidate.invalidBooleanValueMessage(ATTRIBUTES, IS_SECURED, value2));
+ }
+ }
+ }
+
+ }
+
+ private void validateResultParameters() {
+ @SuppressWarnings("unchecked")
+ Map<String, Object> resultParams = (Map<String, Object>) yamlMap.get(RESULTS);
+
+ if (resultParams == null || resultParams.isEmpty()) {
+ return;
+ }
+
+ Object direction = resultParams.get(DIRECTION);
+
+ if (direction != null && !DIRECTIONS.contains(direction)) {
+ schemaErrors.add(SchemaValidate.invalidType(PARAMETERS, DIRECTION, DIRECTIONS));
+ }
+
+ @SuppressWarnings("unchecked")
+ List<Map<String, Object>> resultAttributes = (List<Map<String, Object>>) resultParams.get(ATTRIBUTES);
+ validateResultAttributes(resultAttributes);
+ }
+
+ /**
+ * Get all default short options.
+ *
+ * @return set
+ */
+ protected Set<String> getDefaultShortOptions() {
+
+ Set<String> set = new HashSet<>();
+
+ @SuppressWarnings("unchecked")
+ List<Map<String, Object>> inputParams = (List<Map<String, Object>>) defaultYamlMap.get(PARAMETERS);
+ for (Map<String, Object> parameter : inputParams) {
+ Object name = parameter.get(SHORT_OPTION);
+ if (name != null && !String.valueOf(name).isEmpty() && !"null".equals(name)) {
+ set.add(String.valueOf(name));
+ }
+ }
+
+ return set;
+ }
+
+ /**
+ * Get all default long options.
+ *
+ * @return set
+ */
+ protected Set<String> getDefaultLongOptions() {
+
+ Set<String> set = new HashSet<>();
+
+ @SuppressWarnings("unchecked")
+ List<Map<String, Object>> inputParams = (List<Map<String, Object>>) defaultYamlMap.get(PARAMETERS);
+ for (Map<String, Object> parameter : inputParams) {
+ Object name = parameter.get(LONG_OPTION);
+ if (name != null && !String.valueOf(name).isEmpty() && !"null".equals(name)) {
+ set.add(String.valueOf(name));
+ }
+ }
+
+ return set;
+ }
+
+ private void validateTopLevelAttributes() {
+ validateMandatoryParams(yamlMap, TOP_LEVEL_PARAMS_LIST, TOP_LEVEL_MANDATORY_LIST, "root level");
+ }
+
+ private void validateServiceAttributes() {
+
+ @SuppressWarnings("unchecked")
+ Map<String, Object> serviceMap = (Map<String, Object>) yamlMap.get(SERVICE);
+
+ if (serviceMap == null) {
+ schemaErrors.add(SchemaValidate.emptySection(SERVICE));
+ return;
+ }
+
+ validateMandatoryParams(serviceMap, SERVICE_PARAMS_LIST, SERVICE_PARAMS_MANDATORY_LIST, SERVICE);
+
+ // Validate specific parameters
+
+ if (serviceMap.containsKey(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<Map<String, Object>> inputParams = (List<Map<String, Object>>) yamlMap.get(PARAMETERS);
+ if (inputParams == null) {
+ return;
+ }
+ validateInputAttributes(inputParams);
+ }
+
+ protected abstract void validateSpecificSchema(SchemaType type) throws OnapCommandInvalidSchema;
+
+ private void validateInputAttributes(List<Map<String, Object>> inputParams) {
+ Set<String> inputParamNames = new HashSet<>();
+ Set<String> inputShortOptions = new HashSet<>();
+ Set<String> inputLongOptions = new HashSet<>();
+
+ Set<String> defaultShortOptions = getDefaultShortOptions();
+ Set<String> defaultLongOptions = getDefaultLongOptions();
+
+ for (Map<String, Object> parameter : inputParams) {
+
+ // Validate mandatory parameters
+ validateMandatoryParams(parameter, INPUT_PARAMS_LIST, INPUT_PARAMS_MANDATORY_LIST, PARAMETERS);
+
+ // Validate specific parameters
+
+ String name = String.valueOf(parameter.get(NAME));
+
+ if (inputParamNames.contains(name)) {
+ schemaErrors.add(SchemaValidate.nameExist(name, PARAMETERS));
+ } else {
+ inputParamNames.add(name);
+ }
+
+ String value = String.valueOf(parameter.get(TYPE));
+
+ if (!PARAMETER_TYPES.contains(value.toLowerCase())) {
+ schemaErrors.add(SchemaValidate.invalidAttrType(name, PARAMETERS, PARAMETER_TYPES));
+ }
+
+ Object isOptional = parameter.get(IS_OPTIONAL);
+ if (isOptional != null) {
+ String value1 = String.valueOf(isOptional);
+ if (!validateBoolean(value1)) {
+ schemaErrors.add(SchemaValidate.invalidBooleanValueMessage(name, IS_OPTIONAL, value1));
+ }
+ }
+
+ Object isSecured = parameter.get(IS_SECURED);
+ if (isSecured != null) {
+ String value2 = String.valueOf(isSecured);
+ if (!validateBoolean(value2)) {
+ schemaErrors.add(SchemaValidate.invalidBooleanValueMessage(name, IS_SECURED, value2));
+ }
+ }
+
+ String shortOption = String.valueOf(parameter.get(SHORT_OPTION));
+ String longOption = String.valueOf(parameter.get(LONG_OPTION));
+
+ if (inputShortOptions.contains(shortOption)) {
+ schemaErrors.add(SchemaValidate.optionExist(SHORT_OPTION, shortOption, name));
+ } else if (defaultShortOptions.contains(shortOption)) {
+
+ schemaErrors
+ .add(SchemaValidate.optionDefaultExist(SHORT_OPTION, shortOption, name, defaultShortOptions));
+
+ } else if (shortOption != null && !shortOption.isEmpty() && !"null".equals(shortOption)) {
+ inputShortOptions.add(shortOption);
+ }
+
+ if (inputLongOptions.contains(longOption)) {
+ schemaErrors.add(SchemaValidate.optionExist(LONG_OPTION, longOption, name));
+ } else if (defaultLongOptions.contains(longOption)) {
+
+ schemaErrors.add(SchemaValidate.optionDefaultExist(LONG_OPTION, longOption, name, defaultLongOptions));
+ } else if (longOption != null && !longOption.isEmpty() && !"null".equals(shortOption)) {
+ inputLongOptions.add(longOption);
+ }
+
+ }
+
+ }
+
+ /**
+ * Validate mandatory parameters.
+ *
+ * @param yamlMap
+ * yaml map
+ * @param totalParams
+ * list
+ * @param mandatoryParams
+ * list
+ * @param section
+ * section
+ */
+ protected void validateMandatoryParams(Map<String, Object> yamlMap, List<String> totalParams,
+ List<String> mandatoryParams, String section) {
+
+ for (String param : totalParams) {
+ boolean isMandatory = mandatoryParams.contains(param);
+ boolean isYamlContains = yamlMap.containsKey(param);
+ if (isMandatory) {
+ if (!isYamlContains) {
+ schemaErrors.add(SchemaValidate.mandatoryAttrMissing(param, section));
+ } else {
+ String value = String.valueOf(yamlMap.get(param));
+ if (value == null || "".equals(value) || "null".equals(value)) {
+ schemaErrors.add(SchemaValidate.mandatoryAttrEmpty(param, section));
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Load result attributes.
+ *
+ * @return set
+ */
+ @SuppressWarnings("unchecked")
+ protected Set<String> getResultAttributes() {
+
+ Set<String> set = new HashSet<>();
+
+ List<Map<String, Object>> resultAttributes = yamlMap.get(RESULTS) != null
+ ? (List<Map<String, Object>>) ((Map<String, Object>) yamlMap.get(RESULTS)).get(ATTRIBUTES)
+ : Collections.emptyList();
+
+ if (resultAttributes != null) {
+ for (Map<String, Object> map : resultAttributes) {
+ for (Entry<String, Object> entry : map.entrySet()) {
+ Object key = entry.getKey();
+
+ if (NAME.equals(key)) {
+ set.add(String.valueOf(entry.getValue()));
+ break;
+ }
+ }
+ }
+ }
+
+ return set;
+ }
+
+ /**
+ * Get request parameters.
+ *
+ * @return set
+ */
+ protected Set<String> getRequestParams() {
+
+ Set<String> set = new HashSet<>();
+
+ @SuppressWarnings("unchecked")
+ List<Map<String, Object>> inputParams = (List<Map<String, Object>>) yamlMap.get(PARAMETERS);
+
+ if (inputParams != null) {
+ for (Map<String, Object> map : inputParams) {
+ for (Entry<String, Object> entry : map.entrySet()) {
+ Object key = entry.getKey();
+
+ if (NAME.equals(key)) {
+ set.add(String.valueOf(entry.getValue()));
+ break;
+ }
+ }
+ }
+ }
+
+ return set;
+ }
+
+ /**
+ * Validate Boolean.
+ *
+ * @param toValidate
+ * string
+ * @return boolean
+ */
+ protected static boolean validateBoolean(String toValidate) {
+ return BOOLEAN_VALUES.contains(toValidate.toLowerCase());
+ }
+}
diff --git a/framework/src/main/java/org/onap/cli/fw/schema/SchemaValidate.java b/framework/src/main/java/org/onap/cli/fw/schema/SchemaValidate.java
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<String> validate() throws OnapCommandInvalidSchema;
+
+ /**
+ * Static interface method.
+ *
+ * @param section
+ * section
+ * @return errorMessage
+ */
+ public static String defaultYamlSchema(String section) {
+ return "The section '" + section + ":' cann't be null or empty";
+ }
+
+ /**
+ * Static interface method.
+ *
+ * @param section
+ * string
+ * @param attribute
+ * string
+ * @param value
+ * string
+ * @return string
+ */
+ public static String invalidBooleanValueMessage(String section, String attribute, String value) {
+ return "The value '" + value + "' of '" + attribute + "' present under '" + section + "' should be boolean";
+ }
+
+ /**
+ * Static interface method.
+ *
+ * @param section
+ * string
+ * @param attribute
+ * string
+ * @return string
+ */
+ public static String emptyValue(String section, String attribute) {
+ return "Attribute '" + attribute + "' under '" + section + "' is null or empty";
+ }
+
+ /**
+ * Static interface method.
+ *
+ * @param section
+ * string
+ * @param attribute
+ * string
+ * @param types
+ * list
+ * @return string
+ */
+ public static String invalidType(String section, String attribute, List<String> types) {
+ return "Attribute '" + attribute + "' under '" + section + "' is invalid, correct types are "
+ + types.toString();
+ }
+
+ /**
+ * Static interface method.
+ *
+ * @param subSection
+ * string
+ * @param attribute
+ * string
+ * @return string
+ */
+ public static String invalidRequestParam(String subSection, String attribute) {
+ return "The http request '" + subSection + "' parameter '" + attribute
+ + "' is not declared under 'parameters:' section";
+ }
+
+ /**
+ * Static interface method.
+ *
+ * @param section
+ * string
+ * @return string
+ */
+ public static String emptySection(String section) {
+ return "The section '" + section + ":' cann't be null or empty";
+ }
+
+ /**
+ * Static interface method.
+ *
+ * @param mainSections
+ * list
+ * @param http
+ * list
+ * @param basic
+ * list
+ * @return string
+ */
+ public static String invalidSections(Set<String> mainSections, List<String> http, List<String> basic) {
+ return "No matching schema type found due to extra or missing sections in the file" + mainSections.toString()
+ + " , Supported schema sections are http" + http.toString() + " and basic" + basic.toString();
+ }
+
+ /**
+ * Static interface method.
+ *
+ * @param name
+ * string
+ * @param section
+ * string
+ * @return string
+ */
+ public static String attributeNameExist(String name, String section) {
+ return "Attribute name='" + name + "' under '" + section + ":' is already used, Take different one.";
+ }
+
+ /**
+ * Static interface method.
+ *
+ * @param name
+ * string
+ * @param scopes
+ * list
+ * @return string
+ */
+ public static String invalidAttributeScope(String name, List<String> scopes) {
+ return "The attribute '" + name + "' scope is invalid, valid scopes are " + scopes.toString();
+ }
+
+ /**
+ * Static interface method.
+ *
+ * @param name
+ * string
+ * @return string
+ */
+ public static String attributeScopeEmpty(String name) {
+ return "The attribute '" + name + "' scope is null or empty.";
+ }
+
+ /**
+ * Static interface method.
+ *
+ * @param option
+ * string
+ * @param attrValue
+ * string
+ * @param name
+ * string
+ * @return string
+ */
+ public static String optionExist(String option, String attrValue, String name) {
+ return "Attribute " + option + " option '" + attrValue + "' of parameter '" + name
+ + "' is already used, Take different one.";
+ }
+
+ /**
+ * Static interface method.
+ *
+ * @param option
+ * string
+ * @param attrValue
+ * string
+ * @param name
+ * string
+ * @param list
+ * list
+ * @return string
+ */
+ public static String optionDefaultExist(String option, String attrValue, String name, Set<String> list) {
+ return "Attribute " + option + " option '" + attrValue + "' of parameter '" + name
+ + "' is already used in default parameters list " + list.toString() + ", Take different one.";
+ }
+
+ /**
+ * Static interface method.
+ *
+ * @param name
+ * string
+ * @return string
+ */
+ public static String longOptionExist(String name) {
+ return "The attribute '" + name + "' scope is null or empty.";
+ }
+
+ /**
+ * Static interface method.
+ *
+ * @param name
+ * string
+ * @return string
+ */
+ public static String shortOptionExist(String name) {
+ return "The attribute '" + name + "' scope is null or empty.";
+ }
+
+ /**
+ * Static interface method.
+ *
+ * @param name
+ * string
+ * @param section
+ * string
+ * @return string
+ */
+ public static String nameExist(String name, String section) {
+
+ return "Attribute name='" + name + "' under '" + section + ":' is already used, Take different one.";
+ }
+
+ /**
+ * Static interface method.
+ *
+ * @param name
+ * string
+ * @param section
+ * string
+ * @param types
+ * list
+ * @return string
+ */
+ public static String invalidAttrType(String name, String section, List<String> types) {
+ return "Attribute type of '" + name + "' under '" + section + "' is invalid, correct types are "
+ + types.toString();
+ }
+
+ /**
+ * Static interface method.
+ *
+ * @param param
+ * string
+ * @param section
+ * string
+ * @return string
+ */
+ public static String mandatoryAttrMissing(String param, String section) {
+
+ return "Mandatory attribute '" + param + "' is missing under '" + section + "'";
+ }
+
+ /**
+ * Static interface method.
+ *
+ * @param param
+ * string
+ * @param section
+ * string
+ * @return string
+ */
+ public static String mandatoryAttrEmpty(String param, String section) {
+
+ return "Mandatory attribute '" + param + "' under '" + section + "' shouldn't be null or empty";
+ }
+
+ /**
+ * Static interface method.
+ *
+ * @param attribute
+ * string
+ * @return string
+ */
+ public static String missingInResultMap(String attribute) {
+
+ return "The attribute '" + attribute
+ + "' declared under result 'attributes:' section is missing from http 'result_map:'.";
+ }
+
+ /**
+ * Static interface method.
+ *
+ * @param attribute
+ * string
+ * @return string
+ */
+ public static String missingInResultAttribute(String attribute) {
+
+ return "Mapped attribute '" + attribute + "' is missing declaration in result attributes section.";
+ }
+
+ /**
+ * Static interface method.
+ *
+ * @param declaredParam
+ * string
+ * @return string
+ */
+ public static String parameterNotMapped(String declaredParam) {
+
+ return "The parameter '" + declaredParam
+ + "' declared under 'parameters:' section is not mapped into request section.";
+ }
+
+}
diff --git a/framework/src/main/java/org/onap/cli/fw/schema/SchemaValidator.java b/framework/src/main/java/org/onap/cli/fw/schema/SchemaValidator.java
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<String, Object> httpMap = (Map<String, Object>) yamlMap.get(HTTP);
+
+ if (httpMap == null || httpMap.isEmpty()) {
+ schemaErrors.add(HTTP_SECTION_EMPTY);
+ return;
+ }
+
+ validateMandatoryParams(httpMap, HTTP_SECTIONS, HTTP_MANDATORY_SECTIONS, PARAMETERS);
+
+ Map<String, Object> requestMap = (Map<String, Object>) httpMap.get(REQUEST);
+
+ if (requestMap != null && !requestMap.isEmpty()) {
+ validateHttpRequestParams(requestMap);
+ } else {
+ schemaErrors.add(SchemaValidate.emptySection(REQUEST));
+ }
+
+ List<Object> requestSuccessCodes = (List<Object>) httpMap.get(SUCCESS_CODES);
+ if (requestSuccessCodes != null && !requestSuccessCodes.isEmpty()) {
+ validateHttpSccessCodes(requestSuccessCodes);
+ } else {
+ schemaErrors.add(SchemaValidate.emptySection(SUCCESS_CODES));
+ }
+
+ Map<String, Object> resultMap = (Map<String, Object>) httpMap.get(RESULT_MAP);
+
+ if (resultMap != null && !resultMap.isEmpty()) {
+ validateHttpResultMapping(resultMap);
+ }
+
+ Object object = httpMap.get(SAMPLE_RESPONSE);
+ if (object != null) {
+ if (object instanceof String) {
+ schemaErrors.add(HTTP_SAMPLE_RESPONSE_FAILED_PARSING);
+ } else {
+ validateSampleResponse((Map<String, Object>) object);
+ }
+ }
+ }
+
+ private void validateHttpRequestParams(Map<String, Object> requestMap) {
+
+ if (requestMap == null || requestMap.isEmpty()) {
+ return;
+ }
+ // validate mandatory parameters
+ validateMandatoryParams(requestMap, HTTP_REQUEST_PARAMS, HTTP_REQUEST_MANDATORY_PARAMS, REQUEST);
+
+ // Validate method types
+ String method = (String) requestMap.get(METHOD);
+ if (method != null && !method.isEmpty()) {
+ if (!HTTP_METHODS.contains(method.toLowerCase())) {
+ schemaErrors.add(SchemaValidate.invalidType(REQUEST, METHOD, HTTP_METHODS));
+ }
+ } else {
+ schemaErrors.add("Http request method cann't be null or empty");
+ }
+
+ Set<String> requestParams = getRequestParams();
+
+ // validate uriParams
+ Set<String> uriParams = validateHttpUri(requestMap);
+
+ // validate body
+ Set<String> bodyParams = validateHttpBody(requestMap);
+
+ // validate header
+ Set<String> headerParams = validateHttpHeaders(requestMap);
+
+ // validate queries
+ Set<String> queryParams = validateHttpQueries(requestMap);
+
+ for (String declaredParam : requestParams) {
+ if (!uriParams.contains(declaredParam) && !bodyParams.contains(declaredParam)
+ && !headerParams.contains(declaredParam) && !queryParams.contains(declaredParam)) {
+ schemaErrors.add(SchemaValidate.parameterNotMapped(declaredParam));
+ }
+ }
+
+ Set<String> totalParams = new HashSet<>();
+ totalParams.addAll(uriParams);
+ totalParams.addAll(bodyParams);
+ totalParams.addAll(queryParams);
+ totalParams.addAll(headerParams);
+
+ for (String definedParam : totalParams) {
+ if (!requestParams.contains(definedParam)) {
+ if (uriParams.contains(definedParam)) {
+ schemaErrors.add(SchemaValidate.invalidRequestParam(URI, definedParam));
+ } else if (bodyParams.contains(definedParam)) {
+ schemaErrors.add(SchemaValidate.invalidRequestParam(BODY, definedParam));
+ } else if (queryParams.contains(definedParam)) {
+ schemaErrors.add(SchemaValidate.invalidRequestParam(QUERIES, definedParam));
+ } else if (headerParams.contains(definedParam)) {
+ schemaErrors.add(SchemaValidate.invalidRequestParam(HEADERS, definedParam));
+ }
+ }
+ }
+
+ }
+
+ private Set<String> validateHttpUri(Map<String, Object> requestMap) {
+ Set<String> uriParamNames = new HashSet<>();
+ String uri = (String) requestMap.get(URI);
+ if (uri == null || uri.isEmpty()) {
+ schemaErrors.add(SchemaValidate.emptySection(URI));
+ return uriParamNames;
+ }
+ parseParameters(uri, uriParamNames);
+ return uriParamNames;
+ }
+
+ @SuppressWarnings("unchecked")
+ private Set<String> validateHttpHeaders(Map<String, Object> requestMap) {
+
+ Map<String, Object> headers = (Map<String, Object>) requestMap.get(HEADERS);
+ Set<String> headerParamNames = new HashSet<>();
+ if (headers != null) {
+ for (Entry<String, Object> entry : headers.entrySet()) {
+ parseParameters(String.valueOf(entry.getValue()), headerParamNames);
+ }
+ }
+ return headerParamNames;
+ }
+
+ @SuppressWarnings("unchecked")
+ private Set<String> validateHttpQueries(Map<String, Object> requestMap) {
+ Map<String, Object> queries = (Map<String, Object>) requestMap.get(QUERIES);
+ Set<String> queryParamNames = new HashSet<>();
+ if (queries != null) {
+ for (Entry<String, Object> entry : queries.entrySet()) {
+ parseParameters(String.valueOf(entry.getValue()), queryParamNames);
+ }
+ }
+ return queryParamNames;
+ }
+
+ private Set<String> validateHttpBody(Map<String, Object> requestMap) {
+ Set<String> bodyParamNames = new HashSet<>();
+ Object bodyString = requestMap.get(BODY);
+ if (bodyString == null) {
+ return bodyParamNames;
+ }
+
+ String body = String.valueOf(bodyString);
+ JSONObject obj = null;
+ try {
+ obj = new ObjectMapper().readValue(body, JSONObject.class);
+ } catch (IOException e1) { // NOSONAR
+ schemaErrors.add(HTTP_BODY_FAILED_PARSING);
+ }
+ if (obj == null || "".equals(obj.toString())) {
+ schemaErrors.add(HTTP_BODY_JSON_EMPTY);
+ }
+ parseParameters(body, bodyParamNames);
+
+ return bodyParamNames;
+ }
+
+ private void parseParameters(String line, Set<String> paramNames) {
+
+ int currentIdx = 0;
+ while (currentIdx < line.length()) {
+ int idxS = line.indexOf("${", currentIdx);
+ if (idxS == -1) {
+ break;
+ }
+ int idxE = line.indexOf("}", idxS);
+ String paramName = line.substring(idxS + 2, idxE);
+ paramNames.add(paramName.trim());
+
+ currentIdx = idxE + 1;
+ }
+
+ }
+
+ private void validateHttpSccessCodes(List<Object> requestSuccessCodes) {
+
+ for (Object successCode : requestSuccessCodes) {
+ Integer code = (Integer) successCode;
+ if (code < 200 || code >= 300) {
+ schemaErrors.add(HTTP_SUCCESS_CODE_INVALID);
+ }
+ }
+
+ }
+
+ private void validateHttpResultMapping(Map<String, Object> resultMap) {
+ Set<String> resultAttributes = getResultAttributes();
+
+ // Validate if all result attributes are used in the result mapping
+ for (String attribute : resultAttributes) {
+ if (!resultMap.containsKey(attribute)) {
+ schemaErrors.add(SchemaValidate.missingInResultMap(attribute));
+ }
+ }
+
+ // Validate if all result mapping keys are defined in the result attributes
+ for (Entry<String, Object> entry : resultMap.entrySet()) {
+ if (!resultAttributes.contains(entry.getKey())) {
+ schemaErrors.add(SchemaValidate.missingInResultAttribute(entry.getKey()));
+ }
+ }
+ }
+
+ private void validateSampleResponse(Map<String, Object> sampleResponseBodyMap) {
+
+ // validate the json
+ Object json = sampleResponseBodyMap.get(BODY);
+ if (json == null) {
+ schemaErrors.add(HTTP_SAMPLE_RESPONSE_EMPTY);
+ return;
+ }
+ String jsonString = json.toString();
+ try {
+ if (jsonString.startsWith("[")) {
+ new ObjectMapper().readValue(jsonString, JSONObject[].class);
+ } else {
+ new ObjectMapper().readValue(jsonString, JSONObject.class);
+ }
+ } catch (IOException e1) { // NOSONAR
+ schemaErrors.add(HTTP_SAMPLE_RESPONSE_FAILED_PARSING);
+ }
+ }
+
+}
diff --git a/framework/src/main/java/org/onap/cli/fw/utils/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<String, ?> 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<String, ?> values = null;
+ try {
+ values = (Map<String, ?>) 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<String> shortOptions = new ArrayList<>();
+ List<String> longOptions = new ArrayList<>();
+ List<String> 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<String> shortOptions,
+ List<String> longOptions, List<String> names) throws OnapCommandException {
+ try {
+ Map<String, ?> values = validateSchemaVersion(schemaName, cmd.getSchemaVersion());
+
+ for (Map.Entry<String, ?> 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<String, String> map = (Map<String, String>) values.get(key);
+ OnapService srv = new OnapService();
+
+ for (Map.Entry<String, String> 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<Map<String, String>> list = (ArrayList) values.get(key);
+
+ for (Map<String, String> map : list) {
+ OnapCommandParameter param = new OnapCommandParameter();
+
+ for (Map.Entry<String, String> 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<String, ?> valueMap = (Map<String, ?>) values.get(key);
+ OnapCommandResult result = new OnapCommandResult();
+ for (Map.Entry<String, ?> entry1 : valueMap.entrySet()) {
+ String key3 = entry1.getKey();
+
+ if (Constants.DIRECTION.equals(key3)) {
+ result.setPrintDirection(PrintDirection.get((String) valueMap.get(key3)));
+ } else if (Constants.ATTRIBUTES.equals(key3)) {
+ List<Map<String, String>> attrs = (ArrayList) valueMap.get(key3);
+
+ for (Map<String, String> map : attrs) {
+ OnapCommandResultAttribute attr = new OnapCommandResultAttribute();
+ for (Map.Entry<String, String> entry4 : map.entrySet()) {
+ String key4 = entry4.getKey();
+
+ if (Constants.NAME.equals(key4)) {
+ attr.setName(map.get(key4));
+ } else if (Constants.DESCRIPTION.equals(key4)) {
+ 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<String, ?> values = (Map<String, ?>) validateSchemaVersion(schemaName, cmd.getSchemaVersion());
+ Map<String, String> valueMap = (Map<String, String>) values.get(Constants.EXECUTOR);
+ OnapCommandExecutor exec = new OnapCommandExecutor();
+
+ for (Map.Entry<String, String> 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<String, ?> values = (Map<String, ?>) validateSchemaVersion(schemaName, cmd.getSchemaVersion());
+ Map<String, ?> valMap = (Map<String, ?>) values.get(Constants.HTTP);
+
+ for (Map.Entry<String, ?> entry1 : valMap.entrySet()) {
+ String key1 = entry1.getKey();
+ if (Constants.REQUEST.equals(key1)) {
+ Map<String, ?> map = (Map<String, ?>) valMap.get(key1);
+
+ for (Map.Entry<String, ?> entry2 : map.entrySet()) {
+ String key2 = entry2.getKey();
+
+ if (Constants.URI.equals(key2)) {
+ Object obj = map.get(key2);
+ cmd.getInput().setUri(obj.toString());
+ } else if (Constants.MERHOD.equals(key2)) {
+ Object obj = map.get(key2);
+ cmd.getInput().setMethod(obj.toString());
+ } else if (Constants.BODY.equals(key2)) {
+ Object obj = map.get(key2);
+ cmd.getInput().setBody(obj.toString());
+ } else if (Constants.HEADERS.equals(key2)) {
+ Map<String, String> head = (Map<String, String>) map.get(key2);
+ cmd.getInput().setReqHeaders(head);
+ } else if (Constants.QUERIES.equals(key2)) {
+ Map<String, String> query = (Map<String, String>) map.get(key2);
+
+ cmd.getInput().setReqQueries(query);
+ }
+ }
+ } else if (Constants.SUCCESS_CODES.equals(key1)) {
+ cmd.setSuccessStatusCodes((ArrayList) valMap.get(key1));
+ } else if (Constants.RESULT_MAP.equals(key1)) {
+ cmd.setResultMap((Map<String, String>) valMap.get(key1));
+ } else if (Constants.SAMPLE_RESPONSE.equals(key1)) {
+ // (mrkanag) implement sample response handling
+ }
+ }
+
+ } catch (OnapCommandException e) {
+ 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 <HTTP STATUS CODE>::<ERROR CODE>::<ERROR MESSAGE>\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<OnapCommandParameter> params)
+ throws OnapCommandInvalidParameterValue {
+ Map<String, String> 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<String, OnapCommandParameter> getInputMap(List<OnapCommandParameter> inputs) {
+ Map<String, OnapCommandParameter> map = new HashMap<>();
+ for (OnapCommandParameter param : inputs) {
+ map.put(param.getName(), param);
+ }
+ return map;
+ }
+
+ /**
+ * Discover the Onap commands.
+ *
+ * @return list
+ */
+ public static List<Class<OnapCommand>> findOnapCommands() {
+ ServiceLoader<OnapCommand> loader = ServiceLoader.load(OnapCommand.class);
+ List<Class<OnapCommand>> clss = new ArrayList<>();
+ for (OnapCommand implClass : loader) {
+ clss.add((Class<OnapCommand>) implClass.getClass());
+ }
+
+ return clss;
+ }
+
+ /**
+ * sort the set.
+ *
+ * @param col
+ * set
+ * @return list
+ */
+ public static List<String> sort(Set<String> col) {
+ List<String> 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<String> jsonFlatten(List<String> jsons) {
+ List<String> 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<String, OnapCommandParameter> 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<String> replaceLineFromOutputResults(String line, HttpResult resultHttp)
+ throws OnapCommandHttpHeaderNotFound, OnapCommandHttpInvalidResponseBody,
+ OnapCommandResultMapProcessingFailed, OnapCommandResultEmpty {
+ String headerProcessedLine = "";
+
+ ArrayList<String> 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<Object> 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<String, OnapCommandParameter> 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<String, ArrayList<String>> populateOutputs(Map<String, String> resultMap, HttpResult resultHttp)
+ throws OnapCommandException {
+ Map<String, ArrayList<String>> resultsProcessed = new HashMap<>();
+
+ for (Entry<String, String> 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<ExternalSchema> findAllExternalSchemas() throws OnapCommandException {
+ List<ExternalSchema> extSchemas = new ArrayList<>();
+ try {
+ Resource[] res = getExternalResources(Constants.EXTERNAL_SCHEMA_PATH_PATERN);
+ if (res != null && res.length > 0) {
+ Map<String, ?> 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<String, ?> getExternalSchemaMap(Resource resource) throws OnapCommandInvalidSchema {
+ Map<String, ?> values = null;
+ try {
+ values = (Map<String, ?>) 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<ExternalSchema> 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<ExternalSchema> loadExternalSchemasFromJson() throws OnapCommandException {
+ List<ExternalSchema> 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<ExternalSchema> 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