This is an automated email from the ASF dual-hosted git repository.

aradzinski pushed a commit to branch NLPCRAFT-108
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git


The following commit(s) were added to refs/heads/NLPCRAFT-108 by this push:
     new a76cc94  WIP.
a76cc94 is described below

commit a76cc9492222ccb94d504e118bd598479b15695c
Author: Aaron Radzinski <[email protected]>
AuthorDate: Sun Sep 27 22:11:11 2020 -0700

    WIP.
---
 .../model/tools/cmdline/NCCommandLine.scala        | 233 +++++++++++++--------
 .../model/tools/test/NCTestClientBuilder.java      |   6 +-
 2 files changed, 149 insertions(+), 90 deletions(-)

diff --git 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCommandLine.scala
 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCommandLine.scala
index d1c3ae9..06d2c27 100644
--- 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCommandLine.scala
+++ 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCommandLine.scala
@@ -17,9 +17,14 @@
 
 package org.apache.nlpcraft.model.tools.cmdline
 
-import java.io.{File, FileInputStream, ObjectInputStream}
+import java.io.{File, FileInputStream, IOException, ObjectInputStream}
 
+import com.google.gson._
 import org.apache.commons.lang3.SystemUtils
+import org.apache.http.client.ResponseHandler
+import org.apache.http.client.methods.HttpPost
+import org.apache.http.entity.StringEntity
+import org.apache.http.impl.client.HttpClients
 import org.apache.nlpcraft.common.ascii.NCAsciiTable
 import org.apache.nlpcraft.common._
 import org.apache.nlpcraft.common.ansi.NCAnsi
@@ -30,6 +35,7 @@ import resource.managed
 import scala.collection.mutable
 import scala.compat.java8.OptionConverters._
 import scala.util.Try
+import scala.collection.JavaConverters._
 
 /**
  * 'nlpcraft' script entry point.
@@ -52,6 +58,8 @@ object NCCommandLine extends App {
 
     private var exitStatus = 0
 
+    private val gson = new GsonBuilder().setPrettyPrinting().create
+
     // Single CLI command.
     case class Command(
         id: String,
@@ -60,7 +68,7 @@ object NCCommandLine extends App {
         desc: Option[String] = None,
         params: Seq[Parameter] = Seq.empty,
         examples: Seq[Example] = Seq.empty,
-        body: (Command, Seq[String]) ⇒ Unit
+        body: (Command, Seq[Argument]) ⇒ Unit
     ) {
         final val extNames = names.flatMap(name ⇒ // Safeguard against 
"common" errors.
             Seq(
@@ -76,12 +84,19 @@ object NCCommandLine extends App {
 
         /**
          *
-         * @param paramId
-         * @param cliParams
+         * @param name
          * @return
          */
-        def isParamPresent(paramId: String, cliParams: Seq[String]): Boolean =
-            params.find(_.id == 
paramId).get.names.intersect(cliParams).nonEmpty
+        def findParameterByName(name: String): Option[Parameter] =
+            params.find(_.names.contains(name))
+
+        /**
+         *
+         * @param id
+         * @return
+         */
+        def findParameterById(id: String): Option[Parameter] =
+            params.find(_.id == id)
     }
     // Single command's example.
     case class Example(
@@ -92,11 +107,17 @@ object NCCommandLine extends App {
     case class Parameter(
         id: String,
         names: Seq[String],
-        valueDesc: Option[String] = None,
+        value: Option[String] = None,
         optional: Boolean = false, // Mandatory by default.
         desc: String
     )
 
+    // Parsed command line argument.
+    case class Argument(
+        parameter: Parameter, // Formal parameter this argument refers to.
+        value: Option[String]
+    )
+
     // All supported commands.
     private final val CMDS = Seq(
         Command(
@@ -111,7 +132,7 @@ object NCCommandLine extends App {
                 Parameter(
                     id = "config",
                     names = Seq("--config", "-c"),
-                    valueDesc = Some("path"),
+                    value = Some("path"),
                     optional = true,
                     desc =
                         "Configuration absolute file path. Server will 
automatically look for 'nlpcraft.conf' " +
@@ -122,7 +143,7 @@ object NCCommandLine extends App {
                 Parameter(
                     id = "igniteConfig",
                     names = Seq("--ignite-config", "-i"),
-                    valueDesc = Some("path"),
+                    value = Some("path"),
                     optional = true,
                     desc =
                         "Apache Ignite configuration absolute file path. Note 
that Apache Ignite is used as a cluster " +
@@ -134,7 +155,7 @@ object NCCommandLine extends App {
                 Parameter(
                     id = "outputPath",
                     names = Seq("--output-path", "-o"),
-                    valueDesc = Some("path"),
+                    value = Some("path"),
                     optional = true,
                     desc =
                         "File path for both REST server stdout and stderr 
output. If not provided, the REST server" +
@@ -179,7 +200,7 @@ object NCCommandLine extends App {
                 Parameter(
                     id = "endpoint",
                     names = Seq("--endpoint", "-e"),
-                    valueDesc = Some("url"),
+                    value = Some("url"),
                     optional = true,
                     desc =
                         "REST server endpoint in 'http{s}://hostname:port' 
format. " +
@@ -188,7 +209,7 @@ object NCCommandLine extends App {
                 Parameter(
                     id = "number",
                     names = Seq("--number", "-n"),
-                    valueDesc = Some("num"),
+                    value = Some("num"),
                     optional = true,
                     desc =
                         "Number of pings to perform. Must be an integer > 0."
@@ -231,7 +252,7 @@ object NCCommandLine extends App {
                 Parameter(
                     id = "cmd",
                     names = Seq("--cmd", "-c"),
-                    valueDesc = Some("cmd"),
+                    value = Some("cmd"),
                     optional = true,
                     desc = "Set of commands to show the manual for. Can be 
used multiple times."
                 ),
@@ -265,14 +286,14 @@ object NCCommandLine extends App {
                 Parameter(
                     id = "semver",
                     names = Seq("--sem-ver", "-s"),
-                    valueDesc = None,
+                    value = None,
                     optional = true,
                     desc = s"Display only the semantic version value, e.g. 
${VER.version}."
                 ),
                 Parameter(
                     id = "reldate",
                     names = Seq("--rel-date", "-d"),
-                    valueDesc = None,
+                    value = None,
                     optional = true,
                     desc = s"Display only the release date, e.g. ${VER.date}."
                 )
@@ -291,34 +312,10 @@ object NCCommandLine extends App {
     private final val NO_ANSI_CMD = CMDS.find(_.id ==  "no-ansi").get
 
     /**
-     *
-     * @param param Expected parameter.
-     * @param str String to parse.
-     * @return
-     */
-    private def getParamValue(param: Parameter, str: String): Option[String] = 
{
-        val arr = str.split("=")
-
-        if (arr.size != 2) {
-            error(s"Invalid parameter format: $str")
-
-            None
-        }
-        else if (!param.names.contains(arr.head)) {
-            error(s"Unknown parameter in: $str")
-
-            None
-
-        }
-        else
-            Some(arr.last)
-    }
-
-    /**
      * @param cmd Command descriptor.
-     * @param params Parameters, if any, for this command.
+     * @param args Arguments, if any, for this command.
      */
-    private def cmdStartServer(cmd: Command, params: Seq[String]): Unit = {
+    private def cmdStartServer(cmd: Command, args: Seq[Argument]): Unit = {
         title()
 
         // TODO
@@ -326,19 +323,25 @@ object NCCommandLine extends App {
 
     /**
      * @param cmd Command descriptor.
-     * @param params Parameters, if any, for this command.
+     * @param args Arguments, if any, for this command.
      */
-    private def cmdPingServer(cmd: Command, params: Seq[String]): Unit = {
+    private def cmdPingServer(cmd: Command, args: Seq[Argument]): Unit = {
         title()
 
+        var endpoint = "https://localhost:8081";
+        var num = 1
+
+        val endpointParam = cmd.params.find(_.id == "endpoint").get
+        val numberParam = cmd.params.find(_.id == "number").get
+
         // TODO
     }
 
     /**
      * @param cmd Command descriptor.
-     * @param params Parameters, if any, for this command.
+     * @param args Arguments, if any, for this command.
      */
-    private def cmdStopServer(cmd: Command, params: Seq[String]): Unit = {
+    private def cmdStopServer(cmd: Command, args: Seq[Argument]): Unit = {
         title()
 
         val path = new File(SystemUtils.getUserHome, SRV_PID_PATH)
@@ -357,7 +360,7 @@ object NCCommandLine extends App {
             ProcessHandle.of(pid).asScala match {
                 case Some(ph) ⇒
                     if (ph.destroy())
-                        confirm("Local server has been stopped.")
+                        `>`("Local server has been stopped.")
                     else
                         error(s"Unable to stop the local server [pid=$pid]")
 
@@ -369,17 +372,17 @@ object NCCommandLine extends App {
 
     /**
      * @param cmd Command descriptor.
-     * @param params Parameters, if any, for this command.
+     * @param args Arguments, if any, for this command.
      */
-    private def cmdNoAnsi(cmd: Command, params: Seq[String]): Unit = {
+    private def cmdNoAnsi(cmd: Command, args: Seq[Argument]): Unit = {
         NCAnsi.setEnabled(false)
     }
 
     /**
      * @param cmd Command descriptor.
-     * @param params Parameters, if any, for this command.
+     * @param args Arguments, if any, for this command.
      */
-    private def cmdHelp(cmd: Command, params: Seq[String]): Unit = {
+    private def cmdHelp(cmd: Command, args: Seq[Argument]): Unit = {
         title()
 
         /**
@@ -415,8 +418,8 @@ object NCCommandLine extends App {
 
                 for (param ← cmd.params) {
                     val line =
-                        if (param.valueDesc.isDefined)
-                            T___ + 
param.names.zip(Stream.continually(param.valueDesc.get)).map(t ⇒ 
s"${t._1}=${t._2}").mkString(", ")
+                        if (param.value.isDefined)
+                            T___ + 
param.names.zip(Stream.continually(param.value.get)).map(t ⇒ 
s"${t._1}=${t._2}").mkString(", ")
                         else
                             s"$T___${param.names.mkString(", ")}"
 
@@ -447,7 +450,7 @@ object NCCommandLine extends App {
 
         val tbl = NCAsciiTable().margin(left = 4)
 
-        if (params.isEmpty) { // Default - show abbreviated help.
+        if (args.isEmpty) { // Default - show abbreviated help.
             header()
 
             CMDS.foreach(cmd ⇒ tbl +/ (
@@ -457,7 +460,7 @@ object NCCommandLine extends App {
 
             log(tbl.toString)
         }
-        else if (cmd.isParamPresent("all", params)) { // Show a full format 
help for all commands.
+        else if (args.size == 1 && args.head.parameter.id == "all") { // Show 
a full format help for all commands.
             header()
 
             CMDS.foreach(cmd ⇒
@@ -471,29 +474,24 @@ object NCCommandLine extends App {
         }
         else { // Help for individual commands.
             var err = false
-            val cmdParam = cmd.params.find(_.id == "cmd").get
             val seen = mutable.Buffer.empty[String]
 
-            // At this point it should only be '--cmd' parameters.
-            for (param ← params) {
-                getParamValue(cmdParam, param) match {
-                    case Some(value) ⇒
-                        CMDS.find(_.names.contains(value)) match {
-                            case Some(c) ⇒
-                                if (!seen.contains(c.id)) {
-                                    tbl +/ (
-                                        "" → c.names.mkString(ansiGreenFg, ", 
", ansiReset),
-                                        "align:left, maxWidth:85" → 
mkCmdLines(c)
-                                    )
-
-                                    seen += c.id
-                                }
-                            case None ⇒
-                                err = true
-                                error(s"Unknown command '$value' to get help 
for in: $param")
-                        }
+            for (arg ← args) {
+                val cmdName = arg.value.get
+
+                CMDS.find(_.names.contains(cmdName)) match {
+                    case Some(c) ⇒
+                        if (!seen.contains(c.id)) {
+                            tbl +/ (
+                                "" → c.names.mkString(ansiGreenFg, ", ", 
ansiReset),
+                                "align:left, maxWidth:85" → mkCmdLines(c)
+                            )
 
-                    case None ⇒ err = true
+                            seen += c.id
+                        }
+                    case None ⇒
+                        err = true
+                        error(s"Unknown command to get help for: $cmdName")
                 }
             }
 
@@ -508,9 +506,9 @@ object NCCommandLine extends App {
     /**
      *
      * @param cmd Command descriptor.
-     * @param params Parameters, if any, for this command.
+     * @param args Arguments, if any, for this command.
      */
-    private def cmdRepl(cmd: Command, params: Seq[String]): Unit = {
+    private def cmdRepl(cmd: Command, args: Seq[Argument]): Unit = {
         title()
 
         // TODO
@@ -519,23 +517,23 @@ object NCCommandLine extends App {
     /**
      *
      * @param cmd Command descriptor.
-     * @param params Parameters, if any, for this command.
+     * @param args Arguments, if any, for this command.
      */
-    private def cmdVersion(cmd: Command, params: Seq[String]): Unit =
-        if (params.isEmpty)
-            confirm(s"$NAME ver. ${VER.version}, released on ${VER.date}")
+    private def cmdVersion(cmd: Command, args: Seq[Argument]): Unit =
+        if (args.isEmpty)
+            `>`(s"$NAME ver. ${VER.version}, released on ${VER.date}")
         else {
-            val isS = cmd.isParamPresent("semver", params)
-            val isD = cmd.isParamPresent("reldate", params)
+            val isS = args.exists(_.parameter.id == "semver")
+            val isD = args.exists(_.parameter.id == "reldate")
 
             if (isS || isD) {
                 if (isS)
-                    confirm(s"${VER.version}")
+                    `>`(s"${VER.version}")
                 if (isD)
-                    confirm(s"${VER.date}")
+                    `>`(s"${VER.date}")
             }
             else
-                error(s"Invalid parameters for command '${cmd.mainName}': 
${params.mkString(", ")}")
+                error(s"Invalid parameters for command '${cmd.mainName}': 
${args.mkString(", ")}")
         }
 
 
@@ -560,7 +558,13 @@ object NCCommandLine extends App {
      *
      * @param msg
      */
-    private def confirm(msg: String): Unit = 
System.out.println(s"${ansiGreen(">")} $msg")
+    private def `>`(msg: String): Unit = 
System.out.println(s"${ansiGreen(">")} $msg")
+
+    /**
+     *
+     * @param msg
+     */
+    private def `>>`(msg: String): Unit = System.out.print(s"${ansiGreen(">")} 
$msg")
 
     /**
      *
@@ -577,6 +581,55 @@ object NCCommandLine extends App {
     }
 
     /**
+     * Posts REST request.
+     *
+     * @param url
+     * @param resp
+     * @param jsParams
+     * @return
+     * @throws IOException
+     */
+    private def post[T](url: String, resp: ResponseHandler[T], jsParams: 
(String, AnyRef)*): T = {
+        val post = new HttpPost(url)
+
+        post.setHeader("Content-Type", "application/json")
+        post.setEntity(new StringEntity(gson.toJson(jsParams.filter(_._2 != 
null).toMap.asJava), "UTF-8"))
+
+        try
+            HttpClients.createDefault().execute(post, resp)
+        finally
+            post.releaseConnection()
+    }
+
+    /**
+     *
+     * @param cmd
+     * @param args
+     * @return
+     */
+    private def processParameters(cmd: Command, args: Seq[String]): 
Seq[Argument] =
+        args.map { arg ⇒
+            val parts = arg.split("=")
+
+            def mkError() = new IllegalArgumentException(s"Invalid parameter: 
${ansiCyan(arg)}")
+
+            if (parts.size > 2)
+                throw mkError()
+
+            val name = if (parts.size == 1) arg else parts(0)
+            val value = if (parts.size == 1) None else Some(parts(1))
+
+            cmd.findParameterByName(name) match {
+                case None ⇒ throw mkError()
+                case Some(param) ⇒
+                    if ((param.value.isDefined && value.isEmpty) || 
(param.value.isEmpty && value.isDefined))
+                        throw mkError()
+
+                    Argument(param, value)
+            }
+        }
+
+    /**
      *
      * @param args
      */
@@ -595,7 +648,13 @@ object NCCommandLine extends App {
             val cmdName = xargs.head
 
             CMDS.find(_.extNames.contains(cmdName)) match {
-                case Some(cmd) ⇒ cmd.body(cmd, xargs.tail)
+                case Some(cmd) ⇒
+                    try
+                        cmd.body(cmd, processParameters(cmd, xargs.tail))
+                    catch {
+                        case e: IllegalArgumentException ⇒ 
error(e.getLocalizedMessage)
+                    }
+
                 case None ⇒ error(s"Unknown command: $cmdName")
             }
         }
diff --git 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/test/NCTestClientBuilder.java
 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/test/NCTestClientBuilder.java
index f8da2bd..059f931 100644
--- 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/test/NCTestClientBuilder.java
+++ 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/test/NCTestClientBuilder.java
@@ -814,13 +814,13 @@ public class NCTestClientBuilder {
         /**
          *
          * @param url
-         * @param ps
+         * @param params
          * @return
          * @throws NCTestClientException
          * @throws IOException
          */
         @SafeVarargs
-        private String post(String url, Pair<String, Object>... ps) throws 
NCTestClientException, IOException {
+        private String post(String url, Pair<String, Object>... params) throws 
NCTestClientException, IOException {
             HttpPost post = new HttpPost(baseUrl + url);
 
             try {
@@ -828,7 +828,7 @@ public class NCTestClientBuilder {
                     post.setConfig(reqCfg);
 
                 StringEntity entity = new StringEntity(
-                    gson.toJson(Arrays.stream(ps).
+                    gson.toJson(Arrays.stream(params).
                         filter(p -> p.getValue() != null).
                         collect(Collectors.toMap(Pair::getKey, 
Pair::getValue))),
                     "UTF-8"

Reply via email to