You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nlpcraft.apache.org by ar...@apache.org on 2020/12/17 21:10:30 UTC
[incubator-nlpcraft] branch master updated: NLPCRAFT-194 fix.
This is an automated email from the ASF dual-hosted git repository.
aradzinski pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git
The following commit(s) were added to refs/heads/master by this push:
new 50fcffd NLPCRAFT-194 fix.
50fcffd is described below
commit 50fcffd56992380d4632590d6b4ee9f75d51302c
Author: Aaron Radzinski <ar...@datalingvo.com>
AuthorDate: Thu Dec 17 13:10:16 2020 -0800
NLPCRAFT-194 fix.
---
.../nlpcraft/common/config/NCConfigurable.scala | 18 +-
.../nlpcraft/examples/time/TimeModelApp.java | 4 +-
.../nlpcraft/model/tools/cmdline/NCCli.scala | 1584 ++------------------
.../model/tools/cmdline/NCCliCommands.scala | 1135 ++++++++++++++
.../model/tools/cmdline/NCCliRestSpec.scala | 326 ++++
.../model/tools/embedded/NCEmbeddedProbe.java | 4 +-
.../model/tools/test/NCTestAutoModelValidator.java | 6 +-
.../test/impl/NCTestAutoModelValidatorImpl.scala | 9 +-
.../scala/org/apache/nlpcraft/probe/NCProbe.scala | 7 +-
.../org/apache/nlpcraft/probe/NCProbeBoot.scala | 9 +-
.../scala/org/apache/nlpcraft/NCTestContext.scala | 4 +-
.../nlpcraft/model/intent/dsl/NCDslSpec.scala | 5 +-
12 files changed, 1637 insertions(+), 1474 deletions(-)
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/common/config/NCConfigurable.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/common/config/NCConfigurable.scala
index 5df0d27..bdbaa53 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/common/config/NCConfigurable.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/common/config/NCConfigurable.scala
@@ -303,19 +303,21 @@ object NCConfigurable extends LazyLogging {
else {
val name = cfgFileOpt.get
- logger.info(s"Attempting to load/merge configuration from specified configuration file: $name")
+ logger.info(s"Attempting to load/merge configuration from configuration file: $name")
tmpCfg =
if (dfltCfg.isDefined)
- ConfigFactory.load(ConfigFactory.
- parseFile(new java.io.File(name)).
- withFallback(ConfigFactory.parseResources(name)).
- withFallback(dfltCfg.get)
+ ConfigFactory.load(
+ ConfigFactory.
+ parseFile(new java.io.File(name)).
+ withFallback(ConfigFactory.parseResources(name)).
+ withFallback(dfltCfg.get)
)
else
- ConfigFactory.load(ConfigFactory.
- parseFile(new java.io.File(name)).
- withFallback(ConfigFactory.parseResources(name))
+ ConfigFactory.load(
+ ConfigFactory.
+ parseFile(new java.io.File(name)).
+ withFallback(ConfigFactory.parseResources(name))
)
}
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/examples/time/TimeModelApp.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/examples/time/TimeModelApp.java
index d6ddf54..8f52122 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/examples/time/TimeModelApp.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/examples/time/TimeModelApp.java
@@ -19,6 +19,8 @@ package org.apache.nlpcraft.examples.time;
import org.apache.nlpcraft.model.tools.embedded.NCEmbeddedProbe;
+import java.util.Collections;
+
/**
* An app that demo the usage of embedded probe. This is an alternative way to
* deploy data models using embedded probe that can run in any host JVM application.
@@ -32,7 +34,7 @@ public class TimeModelApp {
*/
public static void main(String[] args) throws Exception {
// Start the data probe "in place" with 'TimeModel' model.
- if (NCEmbeddedProbe.start(null, TimeModel.class.getName()))
+ if (NCEmbeddedProbe.start(null, Collections.singletonList(TimeModel.class.getName())))
Thread.currentThread().join();
}
}
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCli.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCli.scala
index 3e6da2b..71e5c7e 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCli.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCli.scala
@@ -55,6 +55,8 @@ import org.jline.reader.impl.history.DefaultHistory
import org.jline.terminal.{Terminal, TerminalBuilder}
import org.jline.utils.AttributedString
import org.jline.utils.InfoCmp.Capability
+import org.apache.nlpcraft.model.tools.cmdline.NCCliRestSpec._
+import org.apache.nlpcraft.model.tools.cmdline.NCCliCommands._
import resource.managed
import scala.annotation.tailrec
@@ -89,6 +91,9 @@ object NCCli extends App {
private final val PRB_BEACON_PATH = ".nlpcraft/probe_beacon"
private final val HIST_PATH = ".nlpcraft/.cli_history"
+ private final val DFLT_USER_EMAIL = "admin@admin.com"
+ private final val DFLT_USER_PASSWD = "admin"
+
private final lazy val VER = NCVersion.getCurrent
private final lazy val JAVA = U.sysEnv("NLPCRAFT_CLI_JAVA").getOrElse(new File(SystemUtils.getJavaHome, s"bin/java${if (SystemUtils.IS_OS_UNIX) "" else ".exe"}").getAbsolutePath)
private final lazy val INSTALL_HOME = U.sysEnv("NLPCRAFT_CLI_INSTALL_HOME").getOrElse(SystemUtils.USER_DIR)
@@ -147,10 +152,10 @@ object NCCli extends App {
extends Exception
case class NoLocalServer()
- extends IllegalStateException(s"Local server not found.")
+ extends IllegalStateException(s"Local server not found, use $C'start-server'$RST command to start one.")
case class NoLocalProbe()
- extends IllegalStateException(s"Local probe not found.")
+ extends IllegalStateException(s"Local probe not found, use $C'start-probe'$RST command to start one.")
case class MissingParameter(cmd: Command, paramId: String)
extends IllegalArgumentException(
@@ -180,7 +185,7 @@ object NCCli extends App {
extends IllegalStateException(s"REST error (HTTP ${c(httpCode)}).")
case class MalformedJson()
- extends IllegalStateException("Malformed JSON.")
+ extends IllegalStateException(s"Malformed JSON. ${c("Tip:")} on Windows make sure to escape double quotes.")
case class TooManyArguments(cmd: Command)
extends IllegalArgumentException(s"Too many arguments, type $C'help --cmd=${cmd.name}'$RST to get help.")
@@ -188,27 +193,6 @@ object NCCli extends App {
case class NotEnoughArguments(cmd: Command)
extends IllegalArgumentException(s"Not enough arguments, type $C'help --cmd=${cmd.name}'$RST to get help.")
- case class RestSpec(
- path: String,
- desc: String,
- group: String,
- params: Seq[RestSpecParameter]
- )
-
- sealed trait JsonType
-
- case object STRING extends JsonType
- case object BOOLEAN extends JsonType
- case object NUMERIC extends JsonType
- case object OBJECT extends JsonType
- case object ARRAY extends JsonType
-
- case class RestSpecParameter(
- name: String,
- kind: JsonType,
- optional: Boolean = false // Mandatory by default.
- )
-
// Project templates for 'gen-project' command.
private lazy val PRJ_TEMPLATES: Map[String, Seq[String]] = {
val m = mutable.HashMap.empty[String, Seq[String]]
@@ -234,288 +218,6 @@ object NCCli extends App {
m.toMap
}
- //noinspection DuplicatedCode
- // TODO: this needs to be loaded dynamically from OpenAPI spec.
- private final val REST_SPEC = Seq(
- RestSpec(
- path = "clear/conversation",
- desc = "Clears conversation STM",
- group = "Asking",
- params = Seq(
- RestSpecParameter(name = "acsTok", kind = STRING),
- RestSpecParameter(name = "mdlId", kind = STRING),
- RestSpecParameter(name = "usrId", kind = STRING, optional = true),
- RestSpecParameter(name = "usrExtId", kind = STRING, optional = true)
- )
- ),
- RestSpec(
- "clear/dialog",
- "Clears dialog flow",
- "Asking",
- params = Seq(
- RestSpecParameter(name = "acsTok", kind = STRING),
- RestSpecParameter(name = "mdlId", kind = STRING),
- RestSpecParameter(name = "usrId", kind = STRING, optional = true),
- RestSpecParameter(name = "usrExtId", kind = STRING, optional = true)
- )
- ),
- RestSpec(
- "model/sugsyn",
- "Runs model synonym suggestion tool",
- "Tools",
- params = Seq(
- RestSpecParameter(name = "acsTok", kind = STRING),
- RestSpecParameter(name = "mdlId", kind = STRING),
- RestSpecParameter(name = "minScore", kind = NUMERIC)
- )
- ),
- RestSpec(
- "check",
- "Gets status and result of submitted requests",
- "Asking",
- params = Seq(
- RestSpecParameter(name = "acsTok", kind = STRING),
- RestSpecParameter(name = "usrId", kind = STRING, optional = true),
- RestSpecParameter(name = "usrExtId", kind = STRING, optional = true),
- RestSpecParameter(name = "srvReqIds", kind = ARRAY, optional = true),
- RestSpecParameter(name = "maxRows", kind = NUMERIC, optional = true)
- )
- ),
- RestSpec(
- "cancel",
- "Cancels a question",
- "Asking",
- params = Seq(
- RestSpecParameter(name = "acsTok", kind = STRING),
- RestSpecParameter(name = "usrId", kind = STRING, optional = true),
- RestSpecParameter(name = "usrExtId", kind = STRING, optional = true),
- RestSpecParameter(name = "srvReqIds", kind = ARRAY, optional = true),
- )
- ),
- RestSpec(
- "ask",
- "Asks a question",
- "Asking",
- params = Seq(
- RestSpecParameter(name = "acsTok", kind = STRING),
- RestSpecParameter(name = "usrId", kind = STRING, optional = true),
- RestSpecParameter(name = "usrExtId", kind = STRING, optional = true),
- RestSpecParameter(name = "txt", kind = STRING),
- RestSpecParameter(name = "mdlId", kind = STRING),
- RestSpecParameter(name = "data", kind = OBJECT, optional = true),
- RestSpecParameter(name = "enableLog", kind = BOOLEAN, optional = true),
- )
- ),
- RestSpec(
- "ask/sync",
- "Asks a question in synchronous mode",
- "Asking",
- params = Seq(
- RestSpecParameter(name = "acsTok", kind = STRING),
- RestSpecParameter(name = "usrId", kind = STRING, optional = true),
- RestSpecParameter(name = "usrExtId", kind = STRING, optional = true),
- RestSpecParameter(name = "txt", kind = STRING),
- RestSpecParameter(name = "mdlId", kind = STRING),
- RestSpecParameter(name = "data", kind = OBJECT, optional = true),
- RestSpecParameter(name = "enableLog", kind = BOOLEAN, optional = true),
- )
- ),
- RestSpec(
- "user/get",
- "Gets current user information",
- "User",
- params = Seq(
- RestSpecParameter(name = "acsTok", kind = STRING),
- RestSpecParameter(name = "id", kind = STRING, optional = true),
- RestSpecParameter(name = "usrExtId", kind = STRING, optional = true)
- )
- ),
- RestSpec(
- "user/all",
- "Gets all users",
- "User",
- params = Seq(
- RestSpecParameter(name = "acsTok", kind = STRING),
- )
- ),
- RestSpec(
- "user/update",
- "Updates regular user",
- "User",
- params = Seq(
- RestSpecParameter(name = "acsTok", kind = STRING),
- RestSpecParameter(name = "firstName", kind = STRING),
- RestSpecParameter(name = "lastName", kind = STRING),
- RestSpecParameter(name = "id", kind = STRING, optional = true),
- RestSpecParameter(name = "avatarUrl", kind = STRING, optional = true),
- RestSpecParameter(name = "properties", kind = OBJECT, optional = true)
- )
- ),
- RestSpec(
- "user/delete",
- "Deletes user",
- "User",
- params = Seq(
- RestSpecParameter(name = "acsTok", kind = STRING),
- RestSpecParameter(name = "id", kind = STRING, optional = true),
- RestSpecParameter(name = "usrExtId", kind = STRING, optional = true)
- )
- ),
- RestSpec(
- "user/admin",
- "Updates user admin permissions",
- "User",
- params = Seq(
- RestSpecParameter(name = "acsTok", kind = STRING),
- RestSpecParameter(name = "id", kind = STRING, optional = true),
- RestSpecParameter(name = "isAdmin", kind = BOOLEAN)
- )
- ),
- RestSpec(
- "user/passwd/reset",
- "Resets password for the user",
- "User",
- params = Seq(
- RestSpecParameter(name = "acsTok", kind = STRING),
- RestSpecParameter(name = "id", kind = STRING, optional = true),
- RestSpecParameter(name = "newPasswd", kind = STRING)
- )
- ),
- RestSpec(
- "user/add",
- "Adds new user",
- "User",
- params = Seq(
- RestSpecParameter(name = "acsTok", kind = STRING),
- RestSpecParameter(name = "firstName", kind = STRING),
- RestSpecParameter(name = "lastName", kind = STRING),
- RestSpecParameter(name = "email", kind = STRING),
- RestSpecParameter(name = "passwd", kind = STRING),
- RestSpecParameter(name = "isAdmin", kind = BOOLEAN),
- RestSpecParameter(name = "usrExtId", kind = STRING, optional = true),
- RestSpecParameter(name = "avatarUrl", kind = STRING, optional = true),
- RestSpecParameter(name = "properties", kind = OBJECT, optional = true)
- )
- ),
- RestSpec(
- "company/get",
- "Gets current user company information",
- "Company",
- params = Seq(
- RestSpecParameter(name = "acsTok", kind = STRING),
- )
- ),
- RestSpec(
- "company/add",
- "Adds new company",
- "Company",
- params = Seq(
- RestSpecParameter(name = "acsTok", kind = STRING),
- RestSpecParameter(name = "name", kind = STRING),
- RestSpecParameter(name = "website", kind = STRING, optional = true),
- RestSpecParameter(name = "country", kind = STRING, optional = true),
- RestSpecParameter(name = "region", kind = STRING, optional = true),
- RestSpecParameter(name = "city", kind = STRING, optional = true),
- RestSpecParameter(name = "address", kind = STRING, optional = true),
- RestSpecParameter(name = "postalCode", kind = STRING, optional = true),
- RestSpecParameter(name = "adminEmail", kind = STRING),
- RestSpecParameter(name = "adminPasswd", kind = STRING),
- RestSpecParameter(name = "adminFirstName", kind = STRING),
- RestSpecParameter(name = "adminLastName", kind = STRING),
- RestSpecParameter(name = "adminAvatarUrl", kind = STRING, optional = true)
- )
- ),
- RestSpec(
- "company/update",
- "Updates company data",
- "Company",
- params = Seq(
- RestSpecParameter(name = "acsTok", kind = STRING),
- RestSpecParameter(name = "name", kind = STRING),
- RestSpecParameter(name = "website", kind = STRING, optional = true),
- RestSpecParameter(name = "country", kind = STRING, optional = true),
- RestSpecParameter(name = "region", kind = STRING, optional = true),
- RestSpecParameter(name = "city", kind = STRING, optional = true),
- RestSpecParameter(name = "address", kind = STRING, optional = true),
- RestSpecParameter(name = "postalCode", kind = STRING, optional = true)
- )
- ),
- RestSpec(
- "company/delete",
- "Deletes company",
- "Company",
- params = Seq(
- RestSpecParameter(name = "acsTok", kind = STRING),
- )
- ),
- RestSpec(
- "company/token/reset",
- "Resets company probe auth token",
- "Company",
- params = Seq(
- RestSpecParameter(name = "acsTok", kind = STRING),
- )
- ),
- RestSpec(
- "feedback/add",
- "Adds feedback",
- "Asking",
- params = Seq(
- RestSpecParameter(name = "acsTok", kind = STRING),
- RestSpecParameter(name = "usrId", kind = STRING, optional = true),
- RestSpecParameter(name = "extUsrId", kind = STRING, optional = true),
- RestSpecParameter(name = "comment", kind = STRING, optional = true),
- RestSpecParameter(name = "srvReqId", kind = STRING),
- RestSpecParameter(name = "score", kind = STRING)
- )
- ),
- RestSpec(
- "feedback/delete",
- "Deletes feedback",
- "Asking",
- params = Seq(
- RestSpecParameter(name = "acsTok", kind = STRING),
- RestSpecParameter(name = "id", kind = NUMERIC)
- )
- ),
- RestSpec(
- "feedback/all",
- "Gets all feedback",
- "Asking",
- params = Seq(
- RestSpecParameter(name = "acsTok", kind = STRING),
- RestSpecParameter(name = "usrId", kind = STRING, optional = true),
- RestSpecParameter(name = "extUsrId", kind = STRING, optional = true),
- RestSpecParameter(name = "srvReqId", kind = STRING, optional = true)
- )
- ),
- RestSpec(
- "signin",
- "Signs in and obtains new access token",
- "Authentication",
- params = Seq(
- RestSpecParameter(name = "email", kind = STRING),
- RestSpecParameter(name = "passwd", kind = STRING)
- )
- ),
- RestSpec(
- "signout",
- "Signs out and releases access token",
- "Authentication",
- params = Seq(
- RestSpecParameter(name = "acsTok", kind = STRING),
- )
- ),
- RestSpec(
- "probe/all",
- "Gets all probes",
- "Probe",
- params = Seq(
- RestSpecParameter(name = "acsTok", kind = STRING),
- )
- )
- )
-
case class HttpRestResponse(
code: Int,
data: String
@@ -524,7 +226,8 @@ object NCCli extends App {
case class ReplState(
var isServerOnline: Boolean = false,
var isProbeOnline: Boolean = false,
- var accessToken: Option[String] = None,
+ var accessToken: Option[String] = None, // Access token obtain with 'userEmail'.
+ var userEmail: Option[String] = None, // Email of the user with 'accessToken'.
var serverLog: Option[File] = None,
var probeLog: Option[File] = None,
var probes: List[Probe] = Nil // List of connected probes.
@@ -535,6 +238,7 @@ object NCCli extends App {
def resetServer(): Unit = {
isServerOnline = false
accessToken = None
+ userEmail = None
serverLog = None
probes = Nil
}
@@ -550,1098 +254,6 @@ object NCCli extends App {
private val state = ReplState()
- // Single CLI command.
- case class Command(
- name: String,
- group: String,
- synopsis: String,
- desc: Option[String] = None,
- params: Seq[Parameter] = Seq.empty,
- examples: Seq[Example] = Seq.empty,
- body: (Command, Seq[Argument], Boolean) ⇒ Unit
- ) {
- /**
- *
- * @param name
- * @return
- */
- def findParameterByNameOpt(name: String): Option[Parameter] =
- params.find(_.names.contains(name))
-
- /**
- *
- * @param id
- * @return
- */
- def findParameterByIdOpt(id: String): Option[Parameter] =
- params.find(_.id == id)
-
- /**
- *
- * @param id
- * @return
- */
- def findParameterById(id: String): Parameter =
- findParameterByIdOpt(id).get
- }
-
- // Single command's example.
- case class Example(
- usage: Seq[String],
- desc: String
- )
-
- // Single command's parameter.
- case class Parameter(
- id: String,
- names: Seq[String],
- value: Option[String] = None,
- optional: Boolean = false, // Mandatory by default.
- synthetic: Boolean = false,
- desc: String
- )
-
- // Parsed command line argument.
- case class Argument(
- parameter: Parameter, // Formal parameter this argument refers to.
- value: Option[String]
- ) {
- /**
- * Gets the original argument string.
- *
- * @return
- */
- def origString(): String = value match {
- case Some(s) ⇒ s"${parameter.names.head}=$s"
- case None ⇒ parameter.names.head
- }
- }
-
- //noinspection DuplicatedCode
- // All supported commands.
- private final val CMDS = Seq(
- Command(
- name = "rest",
- group = "2. REST Commands",
- synopsis = s"REST call in a convenient way for command line mode.",
- desc = Some(
- s"When using this command you supply all call parameters as a single ${y("'--json'")} parameter with a JSON string. " +
- s"In REPL mode, you can hit ${rv(" Tab ")} to see auto-suggestion and auto-completion candidates for " +
- s"commonly used paths. However, ${y("'call'")} command provides more convenient way to issue REST " +
- s"calls when in REPL mode."
- ),
- body = cmdRest,
- params = Seq(
- Parameter(
- id = "path",
- names = Seq("--path", "-p"),
- value = Some("path"),
- desc =
- s"REST path, e.g. ${y("'signin'")} or ${y("'ask/sync'")}. " +
- s"Note that you don't need supply '/' at the beginning. " +
- s"See more details at https://nlpcraft.apache.org/using-rest.html " +
- s"In REPL mode, hit ${rv(" Tab ")} to see auto-suggestion for possible REST paths."
- ),
- Parameter(
- id = "json",
- names = Seq("--json", "-j"),
- value = Some("'json'"),
- desc =
- s"REST call parameters as JSON object. Since standard JSON only supports double " +
- s"quotes the entire JSON string should be enclosed in single quotes. You can " +
- s"find full OpenAPI specification for NLPCraft REST API at " +
- s"https://nlpcraft.apache.org/using-rest.html"
- )
- ),
- examples = Seq(
- Example(
- usage = Seq(
- s"$$ nlpcraft.sh rest ",
- " -p=signin",
- " -j='{\"email\": \"admin@admin.com\", \"passwd\": \"admin\"}'"
- ),
- desc = s"${bo("Unix/Linux:")} issues ${y("'signin'")} REST call with given JSON payload."
- ),
- Example(
- usage = Seq(
- s"> nlpcraft.cmd rest ",
- " -p=signin",
- " -j='{\\\"email\\\": \\\"admin@admin.com\\\", \\\"passwd\\\": \\\"admin\\\"}'"
- ),
- desc =
- s"${bo("Windows:")} issues ${y("'signin'")} REST call with given JSON payload. " +
- s"Note the necessary escaping of double quotes."
- )
- )
- ),
- Command(
- name = "signin",
- group = "2. REST Commands",
- synopsis = s"Wrapper for ${c("'/signin'")} REST call.",
- desc = Some(
- s"If no arguments provided, it signs in with the " +
- s"default 'admin@admin.com' user account. NOTE: please make sure to remove this account when " +
- s"running in production."
- ),
- body = cmdSignIn,
- params = Seq(
- Parameter(
- id = "email",
- names = Seq("--email", "-e"),
- value = Some("email"),
- optional = true,
- desc =
- s"Email of the user. If not provided, 'admin@admin.com' will be used."
- ),
- Parameter(
- id = "passwd",
- names = Seq("--passwd", "-p"),
- value = Some("****"),
- optional = true,
- desc =
- s"User password to sign in. If not provided, the default password will be used."
- )
- ),
- examples = Seq(
- Example(
- usage = Seq(
- s"$PROMPT $SCRIPT_NAME signin"
- ),
- desc = s"Signs in with the default ${c("admin@admin.com")} user account."
- )
- )
- ),
- Command(
- name = "signout",
- group = "2. REST Commands",
- synopsis = s"Wrapper for ${c("'/signout'")} REST call in REPL mode.",
- desc = Some(
- s"Signs out currently signed in user. Note that this command makes sense only in REPL mode."
- ),
- body = cmdSignOut,
- examples = Seq(
- Example(
- usage = Seq(
- s"$PROMPT $SCRIPT_NAME signout"
- ),
- desc = s"Signs out currently signed in user, if any."
- )
- )
- ),
- Command(
- name = "call",
- group = "2. REST Commands",
- synopsis = s"REST call in a convenient way for REPL mode.",
- desc = Some(
- s"When using this command you supply all call parameters separately through their own parameters named " +
- s"after their corresponding parameters in REST specification. " +
- s"In REPL mode, hit ${rv(" Tab ")} to see auto-suggestion and " +
- s"auto-completion candidates for commonly used paths and call parameters."
- ),
- body = cmdCall,
- params = Seq(
- Parameter(
- id = "path",
- names = Seq("--path", "-p"),
- value = Some("path"),
- desc =
- s"REST path, e.g. ${y("'signin'")} or ${y("'ask/sync'")}. " +
- s"Note that you don't need supply '/' at the beginning. " +
- s"See more details at https://nlpcraft.apache.org/using-rest.html " +
- s"In REPL mode, hit ${rv(" Tab ")} to see auto-suggestion for possible REST paths."
- ),
- Parameter(
- id = "xxx",
- names = Seq("--xxx"),
- value = Some("value"),
- optional = true,
- synthetic = true,
- desc =
- s"${y("'xxx'")} name corresponds to the REST call parameter that can be found at https://nlpcraft.apache.org/using-rest.html " +
- s"The value of this parameter should be a valid JSON value using valid JSON syntax. Note that strings " +
- s"don't have to be in double quotes. JSON objects and arrays should be specified as a JSON string in single quotes. You can have " +
- s"as many ${y("'--xxx=value'")} parameters as requires by the ${y("'--path'")} parameter. " +
- s"In REPL mode, hit ${rv(" Tab ")} to see auto-suggestion for possible parameters and their values."
- )
- ),
- examples = Seq(
- Example(
- usage = Seq(
- s"$PROMPT $SCRIPT_NAME call -p=signin",
- " --email=admin@admin.com",
- " --passwd=admin"
- ),
- desc =
- s"Issues ${y("'signin'")} REST call with given JSON payload provided as a set of parameters. " +
- s"Note that ${y("'--email'")} and ${y("'--passwd'")} parameters correspond to the REST call " +
- s"specification for ${y("'/signin'")} path."
- ),
- Example(
- usage = Seq(
- s"$$ nlpcraft.sh call --path=ask/sync",
- " --acsTok=qwerty123456",
- " --txt=\"User request\"",
- " --mdlId=my.model.id",
- " --data='{\"data1\": true, \"data2\": 123, \"data3\": \"some text\"}'",
- " --enableLog=false"
- ),
- desc =
- s"${bo("Unix/Linux:")} issues ${y("'ask/sync'")} REST call with given JSON payload provided as a set of parameters."
- ),
- Example(
- usage = Seq(
- s"> nlpcraft.cmd call --path=ask/sync",
- " --acsTok=qwerty123456",
- " --txt=\"User request\"",
- " --mdlId=my.model.id",
- " --data='{\\\"data1\\\": true, \\\"data2\\\": 123, \\\"data3\\\": \\\"some text\\\"}'",
- " --enableLog=false"
- ),
- desc =
- s"${bo("Windows:")} issues ${y("'ask/sync'")} REST call with given JSON payload provided " +
- s"as a set of parameters. Note the necessary double quote escaping."
- )
- )
- ),
- Command(
- name = "ask",
- group = "2. REST Commands",
- synopsis = s"Wrapper for ${c("'/ask/sync'")} REST call.",
- desc = Some(
- s"Requires user to be already signed in. This command ${bo("only makes sense in the REPL mode")} as " +
- s"it requires user to be signed in. REPL session keeps the currently active access " +
- s"token after user signed in. For command line mode, use ${c("'rest'")} command with " +
- s"corresponding parameters."
- ),
- body = cmdAsk,
- params = Seq(
- Parameter(
- id = "mdlId",
- names = Seq("--mdlId"),
- value = Some("model.id"),
- desc =
- s"ID of the data model to send the request to. " +
- s"In REPL mode, hit ${rv(" Tab ")} to see auto-suggestion for possible model IDs."
- ),
- Parameter(
- id = "txt",
- names = Seq("--txt"),
- value = Some("txt"),
- desc =
- s"Text of the question."
- ),
- Parameter(
- id = "data",
- names = Seq("--data"),
- value = Some("'{}'"),
- optional = true,
- desc = s"Additional JSON data with maximum JSON length of 512000 bytes. Default is ${c("'null'")}."
- ),
- Parameter(
- id = "enableLog",
- names = Seq("--enableLog"),
- value = Some("true|false"),
- optional = true,
- desc = s"Flag to enable detailed processing log to be returned with the result. Default is ${c("'false'")}."
- )
- ),
- examples = Seq(
- Example(
- usage = Seq(
- s"""> ask --txt="User request" --mdlId=my.model.id"""
- ),
- desc =
- s"Issues ${y("'ask/sync'")} REST call with given text and model ID."
- )
- )
- ),
- Command(
- name = "gen-sql",
- group = "3. Miscellaneous",
- synopsis = s"Generates NLPCraft model stub from SQL databases.",
- desc = Some(
- s"You can choose database schema, set of tables and columns for which you want to generate NLPCraft " +
- s"model. After the model is generated you can further configure and customize it for your specific needs. " +
- s"Find more information at ${y("https://nlpcraft.apache.org/tools/sql_model_gen.html")}"
- ),
- body = cmdSqlGen,
- params = Seq(
- Parameter(
- id = "url",
- names = Seq("--url", "-r"),
- value = Some("url"),
- desc =
- s"Database JDBC URL."
- ),
- Parameter(
- id = "driver",
- names = Seq("--driver", "-d"),
- value = Some("class"),
- desc =
- s"Mandatory JDBC driver class. Note that 'class' must be a fully qualified class name. " +
- s"It should also be available on the classpath."
- ),
- Parameter(
- id = "schema",
- names = Seq("--schema", "-s"),
- value = Some("schema"),
- desc =
- s"Database schema to scan."
- ),
- Parameter(
- id = "out",
- names = Seq("--out", "-o"),
- value = Some("filename"),
- desc =
- s"Name of the output JSON or YAML model file. " +
- s"It should have one of the following extensions: .js, .json, .yml, or .yaml. " +
- s"File extension determines the output file format."
- ),
- Parameter(
- id = "user",
- names = Seq("--user", "-u"),
- value = Some("username"),
- optional = true,
- desc = s"Database user name."
- ),
- Parameter(
- id = "password",
- names = Seq("--password", "-w"),
- value = Some("password"),
- optional = true,
- desc = s"Database password."
- ),
- Parameter(
- id = "modelId",
- names = Seq("--model-id", "-x"),
- value = Some("id"),
- optional = true,
- desc = s"Generated model ID. By default, the model ID is ${c("'sql.model.id'")}."
- ),
- Parameter(
- id = "modelVer",
- names = Seq("--model-ver", "-v"),
- value = Some("version"),
- optional = true,
- desc = s"Generated model version. By default, the model version is ${c("'1.0.0-timestamp'")}."
- ),
- Parameter(
- id = "modelName",
- names = Seq("--model-name", "-n"),
- value = Some("name"),
- optional = true,
- desc = s"Generated model name. By default, the model name is ${c("'SQL-based-model'")}."
- ),
- Parameter(
- id = "exclude",
- names = Seq("--exclude", "-e"),
- value = Some("list"),
- optional = true,
- desc =
- s"Semicolon-separate list of tables and/or columns to exclude. By default, none of the " +
- s"tables and columns in the schema are excluded. See ${c("--help")} parameter to get more details."
- ),
- Parameter(
- id = "include",
- names = Seq("--include", "-i"),
- value = Some("list"),
- optional = true,
- desc =
- s"Semicolon-separate list of tables and/or columns to include. By default, all of the " +
- s"tables and columns in the schema are included. See ${c("--help")} parameter to get more details."
- ),
- Parameter(
- id = "prefix",
- names = Seq("--prefix", "-f"),
- value = Some("list"),
- optional = true,
- desc =
- s"Comma-separate list of table or column name prefixes to remove. These prefixes will be " +
- s"removed when name is used for model elements synonyms. By default, no prefixes will be removed."
- ),
- Parameter(
- id = "suffix",
- names = Seq("--suffix", "-q"),
- value = Some("list"),
- optional = true,
- desc =
- s"Comma-separate list of table or column name suffixes to remove. These suffixes will be " +
- s"removed when name is used for model elements synonyms. By default, no suffixes will be removed."
- ),
- Parameter(
- id = "synonyms",
- names = Seq("--synonyms", "-y"),
- value = Some("true|false"),
- optional = true,
- desc = s"Flag on whether or not to generated auto synonyms for the model elements. Default is ${c("'true'")}."
- ),
- Parameter(
- id = "override",
- names = Seq("--override", "-z"),
- value = Some("true|false"),
- optional = true,
- desc =
- s"Flag to determine whether or not to override output file if it already exist. " +
- s"If override is disabled (default) and output file exists - a unique file name " +
- s"will be used instead. Default is ${c("'false'")}."
- ),
- Parameter(
- id = "parent",
- names = Seq("--parent", "-p"),
- value = Some("true|false"),
- optional = true,
- desc =
- s"Flag on whether or not to use element's parent relationship for defining " +
- s"SQL columns and their containing (i.e. parent) tables. Default is ${c("'false'")}."
- ),
- Parameter(
- id = "help",
- names = Seq("--help", "-h"),
- optional = true,
- desc =
- s"Gets extended help and usage information for the ${c("'gen-sql'")} command. " +
- s"Includes information on how to run this tool standalone."
- )
- ),
- examples = Seq(
- Example(
- usage = Seq(
- s"$PROMPT $SCRIPT_NAME gen-sql --help"
- ),
- desc =
- s"Shows full help and usage information for ${c("gen-sql")} command."
- ),
- Example(
- usage = Seq(
- s"$PROMPT $SCRIPT_NAME gen-sql",
- " --url=jdbc:postgresql://localhost:5432/mydb",
- " --driver=org.postgresql.Driver",
- """ --prefix="tbl_, col_"""",
- """ --suffix="_tmp, _old, _unused"""",
- " --schema=public",
- """ --exclude="#_.+"""",
- " --out=model.json"
- ),
- desc =
- s"Generates model stub from given SQL database connection."
- )
- )
- ),
- Command(
- name = "sugsyn",
- group = "2. REST Commands",
- synopsis = s"Wrapper for ${c("'/model/sugsyn'")} REST call.",
- desc = Some(
- s"Requires user to be already signed in. This command ${bo("only makes sense in the REPL mode")} as " +
- s"it requires user to be signed in. REPL session keeps the currently active access " +
- s"token after user signed in. For command line mode, use ${c("'rest'")} command with " +
- s"corresponding parameters. Note also that it requires a local probe running that hosts " +
- s"the specified model. Find more information about this tool at ${y("https://nlpcraft.apache.org/tools/syn_tool.html")}"
- ),
- body = cmdSugSyn,
- params = Seq(
- Parameter(
- id = "mdlId",
- names = Seq("--mdlId"),
- value = Some("model.id"),
- desc =
- s"ID of the model to run synonym suggestion on. " +
- s"In REPL mode, hit ${rv(" Tab ")} to see auto-suggestion for possible model IDs. " +
- s"Note that the probe hosting this model must be connected to the server."
- ),
- Parameter(
- id = "minScore",
- names = Seq("--minScore"),
- value = Some("0.5"),
- optional = true,
- desc = s"Minimal score to include into the result (from 0 to 1). Default is ${c("0.5")}."
- )
- ),
- examples = Seq(
- Example(
- usage = Seq(
- s"""> sugsyn --mdlId=my.model.id"""
- ),
- desc =
- s"Issues ${y("'model/sugsyn'")} REST call with default min score and given model ID."
- )
- )
- ),
- Command(
- name = "tail-server",
- group = "1. Server & Probe Commands",
- synopsis = s"Shows last N lines from the local server log.",
- desc = Some(
- s"Only works for the server started via this script."
- ),
- body = cmdTailServer,
- params = Seq(
- Parameter(
- id = "lines",
- names = Seq("--lines", "-l"),
- value = Some("num"),
- desc =
- s"Number of the server log lines from the end to display. Default is 20."
- )
- ),
- examples = Seq(
- Example(
- usage = Seq(s"$PROMPT $SCRIPT_NAME tail-server --lines=20 "),
- desc = s"Prints last 20 lines from the local server log."
- )
- )
- ),
- Command(
- name = "tail-probe",
- group = "1. Server & Probe Commands",
- synopsis = s"Shows last N lines from the local probe log.",
- desc = Some(
- s"Only works for the probe started via this script."
- ),
- body = cmdTailProbe,
- params = Seq(
- Parameter(
- id = "lines",
- names = Seq("--lines", "-l"),
- value = Some("num"),
- desc =
- s"Number of the probe log lines from the end to display. Default is 20."
- )
- ),
- examples = Seq(
- Example(
- usage = Seq(s"$PROMPT $SCRIPT_NAME tail-probe --lines=20 "),
- desc = s"Prints last 20 lines from the local probe log."
- )
- )
- ),
- Command(
- name = "start-server",
- group = "1. Server & Probe Commands",
- synopsis = s"Starts local server.",
- desc = Some(
- s"Server is started in the external JVM process with both stdout and stderr piped out into log file. " +
- s"Command will block until the server is started unless ${y("'--no-wait'")} parameter is used or timeout is expired."
- ),
- body = cmdStartServer,
- params = Seq(
- Parameter(
- id = "config",
- names = Seq("--config", "-c"),
- value = Some("path"),
- optional = true,
- desc =
- s"Configuration file path. Server will automatically look for ${y("'nlpcraft.conf'")} " +
- s"configuration file in the same directory as NLPCraft JAR file. If the configuration file has " +
- s"different name or in different location use this parameter to provide an alternative path. " +
- s"Note that the server and the probe can use the same file for their configuration."
- ),
- Parameter(
- id = "igniteConfig",
- names = Seq("--ignite-config", "-i"),
- value = Some("path"),
- optional = true,
- desc =
- s"Apache Ignite configuration file path. Note that Apache Ignite is used as a cluster " +
- s"computing plane and a default distributed storage. Server will automatically look for " +
- s"${y("'ignite.xml'")} configuration file in the same directory as NLPCraft JAR file. If the " +
- s"configuration file has different name or in different location use this parameter to " +
- s"provide an alternative path."
- ),
- Parameter(
- id = "jvmopts",
- names = Seq("--jvm-opts", "-j"),
- value = Some("<jvm flags>"),
- optional = true,
- desc =
- s"Space separated list of JVM flags to use. If not provided, the default ${y("'-ea -Xms2048m -XX:+UseG1GC'")} flags " +
- s"will be used."
- ),
- Parameter(
- id = "noWait",
- names = Seq("--no-wait"),
- optional = true,
- desc =
- s"Instructs command not to wait for the server startup and return immediately."
- ),
- Parameter(
- id = "timeoutMins",
- names = Seq("--timeout-mins", "-t"),
- optional = true,
- value = Some("3"),
- desc =
- s"Timeout in minutes to wait until server is started. If not specified the default is 2 minutes."
- )
- ),
- examples = Seq(
- Example(
- usage = Seq(s"$PROMPT $SCRIPT_NAME start-server"),
- desc = "Starts local server with default configuration."
- ),
- Example(
- usage = Seq(s"$PROMPT $SCRIPT_NAME start-server -c=/opt/nlpcraft/nlpcraft.conf -t=5"),
- desc = "Starts local server with alternative configuration file and timeout of 5 mins."
- )
- )
- ),
- Command(
- name = "start-probe",
- group = "1. Server & Probe Commands",
- synopsis = s"Starts local probe.",
- desc = Some(
- s"Probe is started in the external JVM process with both stdout and stderr piped out into log file. " +
- s"Command will block until the probe is started unless ${y("'--no-wait'")} parameter is used or timeout is expired."
- ),
- body = cmdStartProbe,
- params = Seq(
- Parameter(
- id = "config",
- names = Seq("--config", "-c"),
- value = Some("path"),
- optional = true,
- desc =
- s"Configuration file path. Probe will automatically look for ${y("'nlpcraft.conf'")} " +
- s"configuration file in the same directory as NLPCraft JAR file. If the configuration file has " +
- s"different name or in different location use this parameter to provide an alternative path. " +
- s"Note that the server and the probe can use the same file for their configuration."
- ),
- Parameter(
- id = "cp",
- names = Seq("--cp", "-p"),
- value = Some("path"),
- optional = true,
- desc =
- s"Additional JVM classpath that will be appended to the default NLPCraft JVM classpath. " +
- s"Although this configuration property is optional, when deploying your own models you must " +
- s"provide this additional classpath for the models and their dependencies this probe will be hosting. " +
- s"NOTE: this is only optional if you are running example models shipped with NLPCraft."
- ),
- Parameter(
- id = "models",
- names = Seq("--models", "-m"),
- value = Some("<model list>"),
- optional = true,
- desc =
- s"Comma separated list of fully qualified class names for models to deploy. This will override " +
- s"${y("'nlpcraft.probe.models'")} configuration property from either default configuration file " +
- s"or the one provided by ${y("--config")} parameter. NOTE: if you provide the list of your " +
- s"own models here or in configuration file - you must also provide the additional classpath " +
- s"for them via ${y("--cp")} parameter."
- ),
- Parameter(
- id = "jvmopts",
- names = Seq("--jvm-opts", "-j"),
- value = Some("<jvm flags>"),
- optional = true,
- desc =
- s"Space separated list of JVM flags to use. If not provided, the default ${y("'-ea -Xms1024m'")} flags " +
- s"will be used."
- ),
- Parameter(
- id = "noWait",
- names = Seq("--no-wait"),
- optional = true,
- desc =
- s"Instructs command not to wait for the probe startup and return immediately."
- ),
- Parameter(
- id = "timeoutMins",
- names = Seq("--timeout-mins", "-t"),
- optional = true,
- value = Some("3"),
- desc =
- s"Timeout to wait until probe is started. If not specified the default is 1 minute."
- )
- ),
- examples = Seq(
- Example(
- usage = Seq(s"$PROMPT $SCRIPT_NAME start-probe"),
- desc = "Starts local probe with default configuration and parameters."
- ),
- Example(
- usage = Seq(
- s"$PROMPT $SCRIPT_NAME start-probe ",
- " --config=/opt/nlpcraft.conf ",
- " --models=my.package.Model ",
- " --cp=/opt/target/classes ",
- " --jmv-opts=\"-ea -Xms2048m\" ",
- " --timeout-mins=5"
- ),
- desc =
- s"Starts local probe for ${y("'my.package.Model'")} model with alternative configuration " +
- s"file and additional parameters."
- )
- )
- ),
- Command(
- name = "test-model",
- group = "3. Miscellaneous",
- synopsis = s"Runs auto model validation.",
- desc = Some(
- s"Runs ${y("'NCTestAutoModelValidator'")} model auto-validator for given models."
- ),
- body = cmdTestModel,
- params = Seq(
- Parameter(
- id = "cp",
- names = Seq("--cp", "-p"),
- value = Some("path"),
- optional = true,
- desc =
- s"Additional JVM classpath that will be appended to the default NLPCraft JVM classpath. " +
- s"Although this configuration property is optional, when testing your own models you must " +
- s"provide this additional classpath for the models and their dependencies. " +
- s"NOTE: this is only optional if you are testing example models shipped with NLPCraft."
- ),
- Parameter(
- id = "models",
- names = Seq("--models", "-m"),
- value = Some("<model list>"),
- desc =
- s"Comma separated list of fully qualified class names for models to test. NOTE: if you provide " +
- s"the list of your own models here - you must also provide the additional classpath " +
- s"for them via ${y("--cp")} parameter."
- ),
- Parameter(
- id = "jvmopts",
- names = Seq("--jvm-opts", "-j"),
- value = Some("<jvm flags>"),
- optional = true,
- desc =
- s"Space separated list of JVM flags to use. If not provided, the default ${y("'-ea -Xms1024m'")} flags " +
- s"will be used."
- )
- ),
- examples = Seq(
- Example(
- usage = Seq(
- s"$PROMPT $SCRIPT_NAME test-model ",
- " --models=my.package.Model ",
- " --cp=/opt/target/classes ",
- " --jmv-opts=\"-ea -Xms2048m\""
- ),
- desc =
- s"Runs model auto-validator for ${y("'my.package.Model'")} model."
- )
- )
- ),
- Command(
- name = "info-server",
- group = "1. Server & Probe Commands",
- synopsis = s"Info about local server.",
- body = cmdInfoServer
- ),
- Command(
- name = "info-probe",
- group = "1. Server & Probe Commands",
- synopsis = s"Info about local probe.",
- body = cmdInfoProbe
- ),
- Command(
- name = "info",
- group = "1. Server & Probe Commands",
- synopsis = s"Info about local probe & server.",
- body = cmdInfo
- ),
- Command(
- name = "cls",
- group = "3. Miscellaneous",
- synopsis = s"Clears terminal screen.",
- body = cmdCls
- ),
- Command(
- name = "no-ansi",
- group = "3. Miscellaneous",
- synopsis = s"Disables ANSI escape codes for terminal colors & controls.",
- desc = Some(
- s"This is a special command that can be combined with any other commands."
- ),
- body = cmdNoAnsi,
- examples = Seq(
- Example(
- usage = Seq(s"$PROMPT $SCRIPT_NAME help -c=rest no-ansi"),
- desc = s"Displays help for ${y("'rest'")} commands without using ANSI color and escape sequences."
- )
- )
- ),
- Command(
- name = "no-logo",
- group = "3. Miscellaneous",
- synopsis = s"Disables showing NLPCraft logo at the start.",
- desc = Some(
- s"This is a special command that can be combined with any other command in a command line mode."
- ),
- body = cmdNoLogo,
- examples = Seq(
- Example(
- usage = Seq(s"$PROMPT $SCRIPT_NAME version -s no-logo"),
- desc =
- s"Displays just the version information without any additional logo output. " +
- s"This command makes sense only in command lime mode (NOT in REPL mode)."
- )
- )
- ),
- Command(
- name = "ansi",
- group = "3. Miscellaneous",
- synopsis = s"Enables ANSI escape codes for terminal colors & controls.",
- desc = Some(
- s"This is a special command that can be combined with any other commands."
- ),
- body = cmdAnsi,
- examples = Seq(
- Example(
- usage = Seq(s"$PROMPT $SCRIPT_NAME help -c=rest ansi"),
- desc = s"Displays help for ${y("'rest'")} commands with ANSI color and escape sequences."
- )
- )
- ),
- Command(
- name = "ping-server",
- group = "1. Server & Probe Commands",
- synopsis = s"Pings local server.",
- desc = Some(
- s"Server is pinged using ${y("'/health'")} REST call to check its online status."
- ),
- body = cmdPingServer,
- params = Seq(
- Parameter(
- id = "number",
- names = Seq("--number", "-n"),
- value = Some("num"),
- optional = true,
- desc =
- "Number of pings to perform. Must be a number > 0. Default is 1."
- )
- ),
- examples = Seq(
- Example(
- usage = Seq(
- s"$PROMPT $SCRIPT_NAME ping-server -n=10"
- ),
- desc = "Pings local server 10 times."
- )
- )
- ),
- Command(
- name = "stop-server",
- group = "1. Server & Probe Commands",
- synopsis = s"Stops local server.",
- desc = Some(
- s"Local server must be started via ${y(s"'$SCRIPT_NAME'")} or other compatible way."
- ),
- body = cmdStopServer
- ),
- Command(
- name = "stop-probe",
- group = "1. Server & Probe Commands",
- synopsis = s"Stops local probe.",
- desc = Some(
- s"Local probe must be started via ${y(s"'$SCRIPT_NAME'")} or other compatible way."
- ),
- body = cmdStopProbe
- ),
- Command(
- name = "stop",
- group = "1. Server & Probe Commands",
- synopsis = s"Stops both local server & probe.",
- desc = Some(
- s"Both local server & probe must be started via ${y(s"'$SCRIPT_NAME'")} or other compatible way."
- ),
- body = cmdStop
- ),
- Command(
- name = "quit",
- group = "3. Miscellaneous",
- synopsis = s"Quits REPL mode.",
- body = cmdQuit
- ),
- Command(
- name = "help",
- group = "3. Miscellaneous",
- synopsis = s"Displays help for ${y(s"'$SCRIPT_NAME'")}.",
- desc = Some(
- s"By default, without ${y("'--all'")} or ${y("'--cmd'")} parameters, displays the abbreviated form of manual " +
- s"only listing the commands without parameters or examples."
- ),
- body = cmdHelp,
- params = Seq(
- Parameter(
- id = "cmd",
- names = Seq("--cmd", "-c"),
- value = Some("cmd"),
- optional = true,
- desc = "Set of commands to show the manual for. Can be used multiple times."
- ),
- Parameter(
- id = "all",
- names = Seq("--all", "-a"),
- optional = true,
- desc = "Flag to show full manual for all commands."
- )
- ),
- examples = Seq(
- Example(
- usage = Seq(s"$PROMPT $SCRIPT_NAME help -c=rest --cmd=version"),
- desc = s"Displays help for ${y("'rest'")} and ${y("'version'")} commands."
- ),
- Example(
- usage = Seq(s"$PROMPT $SCRIPT_NAME help -all"),
- desc = "Displays help for all commands."
- )
- )
- ),
- Command(
- name = "version",
- group = "3. Miscellaneous",
- synopsis = s"Displays full version of ${y(s"'$SCRIPT_NAME'")} script.",
- desc = Some(
- "Depending on the additional parameters can display only the semantic version or the release date."
- ),
- body = cmdVersion,
- params = Seq(
- Parameter(
- id = "semver",
- names = Seq("--sem-ver", "-s"),
- value = None,
- optional = true,
- desc = s"Display only the semantic version value, e.g. ${VER.version}."
- ),
- Parameter(
- id = "reldate",
- names = Seq("--rel-date", "-d"),
- value = None,
- optional = true,
- desc = s"Display only the release date, e.g. ${VER.date}."
- )
- )
- ),
- Command(
- name = "gen-project",
- group = "3. Miscellaneous",
- synopsis = s"Generates project stub with default configuration.",
- desc = Some(
- "This command supports Java, Scala, and Kotlin languages with either Maven, Gradle or SBT " +
- "as a build tool. Generated projects compiles and runs and can be used as a quick development sandbox."
- ),
- body = cmdGenProject,
- params = Seq(
- Parameter(
- id = "outputDir",
- names = Seq("--outputDir", "-d"),
- value = Some("path"),
- optional = true,
- desc = s"Output directory. Default value is the current working directory."
- ),
- Parameter(
- id = "baseName",
- names = Seq("--baseName", "-n"),
- value = Some("name"),
- desc =
- s"Base name for the generated files. For example, if base name is ${y("'MyApp'")}, " +
- s"then generated Java file will be named as ${y("'MyAppModel.java'")} and model file as ${y("'my_app_model.yaml'")}."
- ),
- Parameter(
- id = "lang",
- names = Seq("--lang", "-l"),
- value = Some("name"),
- optional = true,
- desc =
- s"Language to generate source files in. Supported value are ${y("'java'")}, ${y("'scala'")}, ${y("'kotlin'")}. " +
- s"Default value is ${y("'java'")}."
- ),
- Parameter(
- id = "buildTool",
- names = Seq("--buildTool", "-b"),
- value = Some("name"),
- optional = true,
- desc =
- s"Build tool name to use. Supported values are ${y("'mvn'")} and ${y("'gradle'")} for ${y("'java'")}, " +
- s"${y("'scala'")}, ${y("'kotlin'")}, and ${y("'sbt'")} for ${y("'scala'")} language. Default value is ${y("'mvn'")}."
- ),
- Parameter(
- id = "packageName",
- names = Seq("--packageName", "-p"),
- value = Some("name"),
- optional = true,
- desc = s"JVM package name to use in generated source code. Default value is ${y("'org.apache.nlpcraft.demo'")}."
- ),
- Parameter(
- id = "modelType",
- names = Seq("--modelType", "-m"),
- value = Some("type"),
- optional = true,
- desc = s"Type of generated model file. Supported value are ${y("'yaml'")} or ${y("'json'")}. Default value is ${y("'yaml'")}."
- ),
- Parameter(
- id = "override",
- names = Seq("--override", "-o"),
- value = Some("true|false"),
- optional = true,
- desc = s"Whether or not to override existing output directory. Default value is ${y("'false'")}."
- )
- ),
- examples = Seq(
- Example(
- usage = Seq("> gen-project -n=MyProject -l=scala -b=sbt"),
- desc = s"Generates Scala SBT project."
- ),
- Example(
- usage = Seq("> gen-project -n=MyProject -l=kotlin -p=com.mycompany.nlp -o=true"),
- desc = s"Generates Kotlin Maven project."
- )
- )
- ),
- Command(
- name = "gen-model",
- group = "3. Miscellaneous",
- synopsis = s"Generates data model file stub.",
- desc = Some(
- "Generated model stub will have all default configuration. Model file can be either YAML or JSON."
- ),
- body = cmdGenModel,
- params = Seq(
- Parameter(
- id = "filePath",
- names = Seq("--filePath", "-f"),
- value = Some("path"),
- desc =
- s"File path for the model stub. File path can either be an absolute path, relative path or " +
- s"just a file name in which case the current folder will be used. File must have one of the " +
- s"following extensions: ${y("'json'")}, ${y("'js'")}, ${y("'yaml'")}, or ${y("'yml'")}."
- ),
- Parameter(
- id = "modelId",
- names = Seq("--modelId", "-n"),
- value = Some("id"),
- desc = "Model ID."
- ),
- Parameter(
- id = "override",
- names = Seq("--override", "-o"),
- value = Some("true|false"),
- optional = true,
- desc = s"Override output directory flag. Supported: ${y("'true'")}, ${y("'false'")}. Default value is ${y("'false'")}"
- )
- ),
- examples = Seq(
- Example(
- usage = Seq("> gen-model -f=myModel.json -n=my.model.id"),
- desc = s"Generates JSON model file stub in the current folder."
- ),
- Example(
- usage = Seq("> gen-model -f=c:/tmp/myModel.yaml -n=my.model.id --override=true"),
- desc = s"Generates YAML model file stub in ${y("'c:/temp'")} folder overriding existing file, if any."
- )
- )
- )
- ).sortBy(_.name)
-
- require(
- U.getDups(CMDS.map(_.name)).isEmpty,
- "Dup commands."
- )
-
private final val NO_LOGO_CMD = CMDS.find(_.name == "no-logo").get
private final val NO_ANSI_CMD = CMDS.find(_.name == "no-ansi").get
private final val ANSI_CMD = CMDS.find(_.name == "ansi").get
@@ -1683,21 +295,20 @@ object NCCli extends App {
*
* @param pathOpt
*/
- private def checkFilePath(pathOpt: Option[Argument]): Unit = {
+ private def checkFilePath(pathOpt: Option[Argument]): Unit =
if (pathOpt.isDefined) {
val file = new File(stripQuotes(pathOpt.get.value.get))
if (!file.exists() || !file.isFile)
throw new IllegalArgumentException(s"File not found: ${c(file.getAbsolutePath)}")
}
- }
/**
* @param cmd Command descriptor.
* @param args Arguments, if any, for this command.
* @param repl Whether or not running from REPL.
*/
- private def cmdStartServer(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
+ private [cmdline] def cmdStartServer(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
val cfgPath = args.find(_.parameter.id == "config")
val igniteCfgPath = args.find(_.parameter.id == "igniteConfig")
val noWait = args.exists(_.parameter.id == "noWait")
@@ -1721,7 +332,10 @@ object NCCli extends App {
// Ensure that there isn't another local server running.
loadServerBeacon() match {
- case Some(b) ⇒ throw new IllegalStateException(s"Existing server (pid ${c(b.pid)}) detected.")
+ case Some(b) ⇒ throw new IllegalStateException(
+ s"Existing server (pid ${c(b.pid)}) detected. " +
+ s"Use ${c("'stop-server'")} command to stop it, if necessary."
+ )
case None ⇒ ()
}
@@ -1896,7 +510,7 @@ object NCCli extends App {
if (state.accessToken.isDefined) {
val tbl = new NCAsciiTable()
- tbl += (s"${g("Email")}", "admin@admin.com")
+ tbl += (s"${g("Email")}", state.userEmail.get)
tbl += (s"${g("Access token")}", state.accessToken.get)
logln(s"Signed in with default user:\n$tbl")
@@ -1914,8 +528,56 @@ object NCCli extends App {
* @param args Arguments, if any, for this command.
* @param repl Whether or not running from REPL.
*/
- private def cmdTestModel(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
+ private [cmdline] def cmdTestModel(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
+ // TODO: in the future - we'll need add support here for remote servers.
+ if (loadServerBeacon().isEmpty)
+ throw NoLocalServer()
+ val cfgPath = args.find(_.parameter.id == "config")
+ val addCp = args.find(_.parameter.id == "cp") match {
+ case Some(cp) ⇒ cp.value.get
+ case None ⇒ null
+ }
+ val mdls = args.find(_.parameter.id == "models") match {
+ case Some(arg) ⇒ stripQuotes(arg.value.get)
+ case None ⇒ null
+ }
+ val jvmOpts = args.find(_.parameter.id == "jvmopts") match {
+ case Some(arg) ⇒ U.splitTrimFilter(stripQuotes(arg.value.get), " ")
+ case None ⇒ Seq("-ea", "-Xms1024m")
+ }
+
+ checkFilePath(cfgPath)
+
+ val sep = System.getProperty("path.separator")
+
+ var validatorArgs = mutable.ArrayBuffer.empty[String]
+
+ validatorArgs += JAVA
+ validatorArgs ++= jvmOpts
+
+ if (cfgPath.isDefined)
+ validatorArgs += s"-DNLPCRAFT_PROBE_CONFIG=${cfgPath.get}"
+
+ if (mdls != null)
+ validatorArgs += s"-DNLPCRAFT_TEST_MODELS=$mdls"
+
+ validatorArgs += "-cp"
+ validatorArgs += (if (addCp == null) JAVA_CP else s"$JAVA_CP$sep$addCp".replace(s"$sep$sep", sep))
+ validatorArgs += "org.apache.nlpcraft.model.tools.test.NCTestAutoModelValidator"
+
+ val validatorPb = new ProcessBuilder(validatorArgs.asJava)
+
+ validatorPb.directory(new File(INSTALL_HOME))
+ validatorPb.inheritIO()
+
+ try {
+ validatorPb.start().onExit().get()
+ }
+ catch {
+ case _: InterruptedException ⇒ () // Ignore.
+ case e: Exception ⇒ error(s"Failed to run model validator: ${y(e.getLocalizedMessage)}")
+ }
}
/**
@@ -1923,7 +585,7 @@ object NCCli extends App {
* @param args Arguments, if any, for this command.
* @param repl Whether or not running from REPL.
*/
- private def cmdStartProbe(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
+ private [cmdline] def cmdStartProbe(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
// Ensure that there is a local server running since probe
// cannot finish its start unless there's a server to connect to.
// TODO: in the future - we'll need add support here for remote servers.
@@ -1959,7 +621,10 @@ object NCCli extends App {
// Ensure that there isn't another local probe running.
loadProbeBeacon() match {
- case Some(b) ⇒ throw new IllegalStateException(s"Existing probe (pid ${c(b.pid)}) detected.")
+ case Some(b) ⇒ throw new IllegalStateException(
+ s"Existing probe (pid ${c(b.pid)}) detected. " +
+ s"Use ${c("'stop-probe'")} command to stop it, if necessary."
+ )
case None ⇒ ()
}
@@ -2164,7 +829,7 @@ object NCCli extends App {
* @param args Arguments, if any, for this command.
* @param repl Whether or not executing from REPL.
*/
- private def cmdTailServer(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
+ private [cmdline] def cmdTailServer(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
val lines = args.find(_.parameter.id == "lines") match {
case Some(arg) ⇒
try
@@ -2190,7 +855,7 @@ object NCCli extends App {
* @param args Arguments, if any, for this command.
* @param repl Whether or not executing from REPL.
*/
- private def cmdTailProbe(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
+ private [cmdline] def cmdTailProbe(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
val lines = args.find(_.parameter.id == "lines") match {
case Some(arg) ⇒
try
@@ -2216,7 +881,7 @@ object NCCli extends App {
* @param args Arguments, if any, for this command.
* @param repl Whether or not executing from REPL.
*/
- private def cmdPingServer(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
+ private [cmdline] def cmdPingServer(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
val endpoint = getRestEndpointFromBeacon
val num = args.find(_.parameter.id == "number") match {
@@ -2336,15 +1001,24 @@ object NCCli extends App {
state.isServerOnline = true
try {
- val baseUrl = "http://" + beacon.restEndpoint
+ val baseUrl = "http://" + beacon.restEndpoint // TODO: https?
// Attempt to signin with the default account.
if (autoSignIn && state.accessToken.isEmpty)
httpPostResponseJson(
baseUrl,
"signin",
- "{\"email\": \"admin@admin.com\", \"passwd\": \"admin\"}") match {
- case Some(json) ⇒ state.accessToken = Option(Try(U.getJsonStringField(json, "acsTok")).getOrElse(null))
+ s"""{"email": "$DFLT_USER_EMAIL", "passwd": "$DFLT_USER_PASSWD"}""") match {
+ case Some(json) ⇒
+ Option(Try(U.getJsonStringField(json, "acsTok"))) match {
+ case Some(tok) ⇒
+ state.userEmail = Some(DFLT_USER_EMAIL)
+ state.accessToken = Some(tok.get)
+ case None ⇒
+ state.userEmail = None
+ state.accessToken = None
+
+ }
case None ⇒ ()
}
@@ -2442,7 +1116,7 @@ object NCCli extends App {
* @param args Arguments, if any, for this command.
* @param repl Whether or not executing from REPL.
*/
- private def cmdQuit(cmd: Command, args: Seq[Argument], repl: Boolean): Unit =
+ private [cmdline] def cmdQuit(cmd: Command, args: Seq[Argument], repl: Boolean): Unit =
if (repl) {
loadServerBeacon() match {
case Some(b) ⇒ warn(s"Local server (pid ${c(b.pid)}) is still running.")
@@ -2460,7 +1134,7 @@ object NCCli extends App {
* @param args Arguments, if any, for this command.
* @param repl Whether or not executing from REPL.
*/
- private def cmdStop(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
+ private [cmdline] def cmdStop(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
doCommand(Seq(STOP_SRV_CMD.name), repl)
doCommand(Seq(STOP_PRB_CMD.name), repl)
}
@@ -2470,7 +1144,7 @@ object NCCli extends App {
* @param args Arguments, if any, for this command.
* @param repl Whether or not executing from REPL.
*/
- private def cmdStopServer(cmd: Command, args: Seq[Argument], repl: Boolean): Unit =
+ private [cmdline] def cmdStopServer(cmd: Command, args: Seq[Argument], repl: Boolean): Unit =
loadServerBeacon() match {
case Some(beacon) ⇒
val pid = beacon.pid
@@ -2497,7 +1171,7 @@ object NCCli extends App {
* @param args Arguments, if any, for this command.
* @param repl Whether or not executing from REPL.
*/
- private def cmdStopProbe(cmd: Command, args: Seq[Argument], repl: Boolean): Unit =
+ private [cmdline] def cmdStopProbe(cmd: Command, args: Seq[Argument], repl: Boolean): Unit =
loadProbeBeacon() match {
case Some(beacon) ⇒
val pid = beacon.pid
@@ -2522,7 +1196,7 @@ object NCCli extends App {
* @param args Arguments, if any, for this command.
* @param repl Whether or not executing from REPL.
*/
- private def cmdNoLogo(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
+ private [cmdline] def cmdNoLogo(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
warn("This command should be used together with other command in a command line mode.")
}
@@ -2531,7 +1205,7 @@ object NCCli extends App {
* @param args Arguments, if any, for this command.
* @param repl Whether or not executing from REPL.
*/
- private def cmdNoAnsi(cmd: Command, args: Seq[Argument], repl: Boolean): Unit =
+ private [cmdline] def cmdNoAnsi(cmd: Command, args: Seq[Argument], repl: Boolean): Unit =
NCAnsi.setEnabled(false)
/**
@@ -2539,7 +1213,7 @@ object NCCli extends App {
* @param args Arguments, if any, for this command.
* @param repl Whether or not executing from REPL.
*/
- private def cmdAnsi(cmd: Command, args: Seq[Argument], repl: Boolean): Unit =
+ private [cmdline] def cmdAnsi(cmd: Command, args: Seq[Argument], repl: Boolean): Unit =
NCAnsi.setEnabled(true)
/**
@@ -2547,7 +1221,7 @@ object NCCli extends App {
* @param args Arguments, if any, for this command.
* @param repl Whether or not executing from REPL.
*/
- private def cmdHelp(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
+ private [cmdline] def cmdHelp(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
/**
*
*/
@@ -2793,6 +1467,15 @@ object NCCli extends App {
state.probes.foreach(addProbeToTable(tbl, _))
logln(s"Connected probes (${state.probes.size}):\n${tbl.toString}")
+
+ if (state.accessToken.isDefined) {
+ val tbl = new NCAsciiTable()
+
+ tbl += (s"${g("Email")}", state.userEmail.get)
+ tbl += (s"${g("Access token")}", state.accessToken.get)
+
+ logln(s"Signed in user account:\n$tbl")
+ }
}
/**
@@ -2801,7 +1484,7 @@ object NCCli extends App {
* @param args Arguments, if any, for this command.
* @param repl Whether or not executing from REPL.
*/
- private def cmdInfo(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
+ private [cmdline] def cmdInfo(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
doCommand(Seq(SRV_INFO_CMD.name), repl)
doCommand(Seq(PRB_INFO_CMD.name), repl)
}
@@ -2812,7 +1495,7 @@ object NCCli extends App {
* @param args Arguments, if any, for this command.
* @param repl Whether or not executing from REPL.
*/
- private def cmdInfoServer(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
+ private [cmdline] def cmdInfoServer(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
loadServerBeacon() match {
case Some(beacon) ⇒ logServerInfo(beacon)
case None ⇒ throw NoLocalServer()
@@ -2825,7 +1508,7 @@ object NCCli extends App {
* @param args Arguments, if any, for this command.
* @param repl Whether or not executing from REPL.
*/
- private def cmdInfoProbe(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
+ private [cmdline] def cmdInfoProbe(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
loadProbeBeacon() match {
case Some(beacon) ⇒ logProbeInfo(beacon)
case None ⇒ throw NoLocalProbe()
@@ -2838,7 +1521,7 @@ object NCCli extends App {
* @param args Arguments, if any, for this command.
* @param repl Whether or not executing from REPL.
*/
- private def cmdCls(cmd: Command, args: Seq[Argument], repl: Boolean): Unit =
+ private [cmdline] def cmdClear(cmd: Command, args: Seq[Argument], repl: Boolean): Unit =
term.puts(Capability.clear_screen)
/**
@@ -2855,11 +1538,11 @@ object NCCli extends App {
* @param args Arguments, if any, for this command.
* @param repl Whether or not executing from REPL.
*/
- private def cmdSignIn(cmd: Command, args: Seq[Argument], repl: Boolean): Unit =
+ private [cmdline] def cmdSignIn(cmd: Command, args: Seq[Argument], repl: Boolean): Unit =
state.accessToken match {
case None ⇒
- val email = args.find(_.parameter.id == "email").flatMap(_.value).getOrElse("admin@admin.com")
- val passwd = args.find(_.parameter.id == "passwd").flatMap(_.value).getOrElse("admin")
+ val email = args.find(_.parameter.id == "email").flatMap(_.value).getOrElse(DFLT_USER_EMAIL)
+ val passwd = args.find(_.parameter.id == "passwd").flatMap(_.value).getOrElse(DFLT_USER_PASSWD)
httpRest(
cmd,
@@ -2881,7 +1564,7 @@ object NCCli extends App {
* @param args Arguments, if any, for this command.
* @param repl Whether or not executing from REPL.
*/
- private def cmdSignOut(cmd: Command, args: Seq[Argument], repl: Boolean): Unit =
+ private [cmdline] def cmdSignOut(cmd: Command, args: Seq[Argument], repl: Boolean): Unit =
state.accessToken match {
case Some(acsTok) ⇒
httpRest(
@@ -2920,7 +1603,7 @@ object NCCli extends App {
* @param args Arguments, if any, for this command.
* @param repl Whether or not executing from REPL.
*/
- private def cmdSqlGen(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
+ private [cmdline] def cmdSqlGen(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
val nativeArgs = args.flatMap { arg ⇒
val param = arg.parameter.names.head
@@ -2943,7 +1626,7 @@ object NCCli extends App {
* @param args Arguments, if any, for this command.
* @param repl Whether or not executing from REPL.
*/
- private def cmdSugSyn(cmd: Command, args: Seq[Argument], repl: Boolean): Unit =
+ private [cmdline] def cmdSugSyn(cmd: Command, args: Seq[Argument], repl: Boolean): Unit =
state.accessToken match {
case Some(acsTok) ⇒
val mdlId = args.find(_.parameter.id == "mdlId").flatMap(_.value).getOrElse(throw MissingParameter(cmd, "mdlId"))
@@ -2970,7 +1653,7 @@ object NCCli extends App {
* @param args Arguments, if any, for this command.
* @param repl Whether or not executing from REPL.
*/
- private def cmdAsk(cmd: Command, args: Seq[Argument], repl: Boolean): Unit =
+ private [cmdline] def cmdAsk(cmd: Command, args: Seq[Argument], repl: Boolean): Unit =
state.accessToken match {
case Some(acsTok) ⇒
val mdlId = args.find(_.parameter.id == "mdlId").flatMap(_.value).getOrElse(throw MissingParameter(cmd, "mdlId"))
@@ -3001,7 +1684,7 @@ object NCCli extends App {
* @param args Arguments, if any, for this command.
* @param repl Whether or not executing from REPL.
*/
- private def cmdCall(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
+ private [cmdline] def cmdCall(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
val normArgs = args.filter(!_.parameter.synthetic)
val synthArgs = args.filter(_.parameter.synthetic)
@@ -3052,7 +1735,7 @@ object NCCli extends App {
* @param args Arguments, if any, for this command.
* @param repl Whether or not executing from REPL.
*/
- private def cmdRest(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
+ private [cmdline] def cmdRest(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
val path = args.find(_.parameter.id == "path").getOrElse(throw MissingParameter(cmd, "path")).value.get
val json = stripQuotes(args.find(_.parameter.id == "json").getOrElse(throw MissingParameter(cmd, "json")).value.get)
@@ -3224,7 +1907,7 @@ object NCCli extends App {
* @param args Arguments, if any, for this command.
* @param repl Whether or not executing from REPL.
*/
- private def cmdGenModel(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
+ private [cmdline] def cmdGenModel(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
val filePath = get(cmd, args, "filePath")
val overrideFlag = get(cmd, args,"override", "false").toLowerCase
val modelId = get(cmd, args,"modelId")
@@ -3274,7 +1957,7 @@ object NCCli extends App {
* @param args Arguments, if any, for this command.
* @param repl Whether or not executing from REPL.
*/
- private def cmdGenProject(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
+ private [cmdline] def cmdGenProject(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
val outputDir = get(cmd, args, "outputDir", ".")
val baseName = get(cmd, args,"baseName")
val lang = get(cmd, args,"lang", "java").toLowerCase
@@ -3506,10 +2189,14 @@ object NCCli extends App {
}
if (resp.code == 200) {
- if (path == "signin")
+ if (path == "signin") {
+ state.userEmail = Some(U.getJsonStringField(json, "email"))
state.accessToken = Some(U.getJsonStringField(resp.data, "acsTok"))
- else if (path == "signout")
+ }
+ else if (path == "signout") {
+ state.userEmail = None
state.accessToken = None
+ }
}
}
@@ -3527,7 +2214,7 @@ object NCCli extends App {
}
if (state.accessToken.isDefined)
- logln(s"Server signed in with default '${c("admin@admin.com")}' user.")
+ logln(s"Server signed in with default '${c(DFLT_USER_EMAIL)}' user.")
val parser = new DefaultParser()
@@ -3692,7 +2379,7 @@ object NCCli extends App {
if (path == "signin") {
candidates.add(
mkCandidate(
- disp = "--email=admin@admin.com",
+ disp = s"--email=$DFLT_USER_EMAIL",
grp = DFTL_USER_GRP,
desc = null,
completed = true
@@ -3700,7 +2387,7 @@ object NCCli extends App {
)
candidates.add(
mkCandidate(
- disp = "--passwd=admin",
+ disp = s"--passwd=$DFLT_USER_PASSWD",
grp = DFTL_USER_GRP,
desc = null,
completed = true
@@ -3772,15 +2459,14 @@ object NCCli extends App {
while (!exit) {
val rawLine = try {
- val srvStr = bo(s"${if (state.isServerOnline) s"ON " else s"OFF "}")
- val prbStr = bo(s"${if (state.isProbeOnline) s"ON " else s"OFF "}")
- val acsTokStr = bo(s"${state.accessToken.getOrElse("n/a")} ")
+ val acsTokStr = bo(s"${state.accessToken.getOrElse("N/A")} ")
- val prompt1 = rb(w(s" srv:$srvStr")) + rb(w(s"prb:$prbStr")) // Server status.
- val prompt2 = wb(k(s" acsTok: $acsTokStr")) // Access toke, if any.
- val prompt3 = kb(g(s" ${Paths.get("").toAbsolutePath} ")) // Current working directory.
+ val prompt1 = if (state.isServerOnline) gb(k(s" server: ${BO}ON$RST$GB ")) else rb(w(s" server: ${BO}OFF$RST$RB "))
+ val prompt2 = if (state.isProbeOnline) gb(k(s" probe: ${BO}ON$RST$GB ")) else rb(w(s" probe: ${BO}OFF$RST$RB "))
+ val prompt3 = wb(k(s" acsTok: $acsTokStr")) // Access token, if any.
+ val prompt4 = kb(g(s" ${Paths.get("").toAbsolutePath} ")) // Current working directory.
- reader.printAbove("\n" + prompt1 + ":" + prompt2 + ":" + prompt3)
+ reader.printAbove("\n" + prompt1 + ":" + prompt2 + ":" + prompt3 + ":" + prompt4)
reader.readLine(s"${g(">")} ")
}
catch {
@@ -3832,7 +2518,7 @@ object NCCli extends App {
* @param args Arguments, if any, for this command.
* @param repl Whether or not executing from REPL.
*/
- private def cmdVersion(cmd: Command, args: Seq[Argument], repl: Boolean): Unit =
+ private [cmdline] def cmdVersion(cmd: Command, args: Seq[Argument], repl: Boolean): Unit =
if (args.isEmpty)
logln((
new NCAsciiTable
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCliCommands.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCliCommands.scala
new file mode 100644
index 0000000..9ccdce8
--- /dev/null
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCliCommands.scala
@@ -0,0 +1,1135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.nlpcraft.model.tools.cmdline
+
+import org.apache.commons.lang3.SystemUtils
+import org.apache.nlpcraft.common._
+import org.apache.nlpcraft.common.version.NCVersion
+
+// Parsed command line argument.
+private [cmdline] case class Argument(
+ parameter: Parameter, // Formal parameter this argument refers to.
+ value: Option[String]
+) {
+ /**
+ * Gets the original argument string.
+ *
+ * @return
+ */
+ def origString(): String = value match {
+ case Some(s) ⇒ s"${parameter.names.head}=$s"
+ case None ⇒ parameter.names.head
+ }
+}
+
+// Single CLI command.
+private [cmdline] case class Command(
+ name: String,
+ group: String,
+ synopsis: String,
+ desc: Option[String] = None,
+ params: Seq[Parameter] = Seq.empty,
+ examples: Seq[Example] = Seq.empty,
+ body: (Command, Seq[Argument], Boolean) ⇒ Unit
+) {
+ /**
+ *
+ * @param name
+ * @return
+ */
+ def findParameterByNameOpt(name: String): Option[Parameter] =
+ params.find(_.names.contains(name))
+
+ /**
+ *
+ * @param id
+ * @return
+ */
+ def findParameterByIdOpt(id: String): Option[Parameter] =
+ params.find(_.id == id)
+
+ /**
+ *
+ * @param id
+ * @return
+ */
+ def findParameterById(id: String): Parameter =
+ findParameterByIdOpt(id).get
+}
+
+// Single command's example.
+private [cmdline] case class Example(
+ usage: Seq[String],
+ desc: String
+)
+
+// Single command's parameter.
+private [cmdline] case class Parameter(
+ id: String,
+ names: Seq[String],
+ value: Option[String] = None,
+ optional: Boolean = false, // Mandatory by default.
+ synthetic: Boolean = false,
+ desc: String
+)
+
+private [cmdline] object NCCliCommands {
+ private final lazy val SCRIPT_NAME = U.sysEnv("NLPCRAFT_CLI_SCRIPT").getOrElse(s"nlpcraft.${if (SystemUtils.IS_OS_UNIX) "sh" else "cmd"}")
+ private final lazy val PROMPT = if (SCRIPT_NAME.endsWith("cmd")) ">" else "$"
+ private final lazy val VER = NCVersion.getCurrent
+
+ //noinspection DuplicatedCode
+ // All supported commands.
+ private [cmdline] final val CMDS = Seq(
+ Command(
+ name = "rest",
+ group = "2. REST Commands",
+ synopsis = s"REST call in a convenient way for command line mode.",
+ desc = Some(
+ s"When using this command you supply all call parameters as a single ${y("'--json'")} parameter with a JSON string. " +
+ s"In REPL mode, you can hit ${rv(" Tab ")} to see auto-suggestion and auto-completion candidates for " +
+ s"commonly used paths. However, ${y("'call'")} command provides more convenient way to issue REST " +
+ s"calls when in REPL mode."
+ ),
+ body = NCCli.cmdRest,
+ params = Seq(
+ Parameter(
+ id = "path",
+ names = Seq("--path", "-p"),
+ value = Some("path"),
+ desc =
+ s"REST path, e.g. ${y("'signin'")} or ${y("'ask/sync'")}. " +
+ s"Note that you don't need supply '/' at the beginning. " +
+ s"See more details at https://nlpcraft.apache.org/using-rest.html " +
+ s"In REPL mode, hit ${rv(" Tab ")} to see auto-suggestion for possible REST paths."
+ ),
+ Parameter(
+ id = "json",
+ names = Seq("--json", "-j"),
+ value = Some("'json'"),
+ desc =
+ s"REST call parameters as JSON object. Since standard JSON only supports double " +
+ s"quotes the entire JSON string should be enclosed in single quotes. You can " +
+ s"find full OpenAPI specification for NLPCraft REST API at " +
+ s"https://nlpcraft.apache.org/using-rest.html"
+ )
+ ),
+ examples = Seq(
+ Example(
+ usage = Seq(
+ s"$$ nlpcraft.sh rest ",
+ " -p=signin",
+ " -j='{\"email\": \"admin@admin.com\", \"passwd\": \"admin\"}'"
+ ),
+ desc = s"${bo("Unix/Linux:")} issues ${y("'signin'")} REST call with given JSON payload."
+ ),
+ Example(
+ usage = Seq(
+ s"> nlpcraft.cmd rest ",
+ " -p=signin",
+ " -j='{\\\"email\\\": \\\"admin@admin.com\\\", \\\"passwd\\\": \\\"admin\\\"}'"
+ ),
+ desc =
+ s"${bo("Windows:")} issues ${y("'signin'")} REST call with given JSON payload. " +
+ s"Note the necessary escaping of double quotes."
+ )
+ )
+ ),
+ Command(
+ name = "signin",
+ group = "2. REST Commands",
+ synopsis = s"Wrapper for ${c("'/signin'")} REST call.",
+ desc = Some(
+ s"If no arguments provided, it signs in with the " +
+ s"default 'admin@admin.com' user account. NOTE: please make sure to remove this account when " +
+ s"running in production."
+ ),
+ body = NCCli.cmdSignIn,
+ params = Seq(
+ Parameter(
+ id = "email",
+ names = Seq("--email", "-e"),
+ value = Some("email"),
+ optional = true,
+ desc =
+ s"Email of the user. If not provided, 'admin@admin.com' will be used."
+ ),
+ Parameter(
+ id = "passwd",
+ names = Seq("--passwd", "-p"),
+ value = Some("****"),
+ optional = true,
+ desc =
+ s"User password to sign in. If not provided, the default password will be used."
+ )
+ ),
+ examples = Seq(
+ Example(
+ usage = Seq(
+ s"$PROMPT $SCRIPT_NAME signin"
+ ),
+ desc = s"Signs in with the default ${c("admin@admin.com")} user account."
+ )
+ )
+ ),
+ Command(
+ name = "signout",
+ group = "2. REST Commands",
+ synopsis = s"Wrapper for ${c("'/signout'")} REST call in REPL mode.",
+ desc = Some(
+ s"Signs out currently signed in user. Note that this command makes sense only in REPL mode."
+ ),
+ body = NCCli.cmdSignOut,
+ examples = Seq(
+ Example(
+ usage = Seq(
+ s"$PROMPT $SCRIPT_NAME signout"
+ ),
+ desc = s"Signs out currently signed in user, if any."
+ )
+ )
+ ),
+ Command(
+ name = "call",
+ group = "2. REST Commands",
+ synopsis = s"REST call in a convenient way for REPL mode.",
+ desc = Some(
+ s"When using this command you supply all call parameters separately through their own parameters named " +
+ s"after their corresponding parameters in REST specification. " +
+ s"In REPL mode, hit ${rv(" Tab ")} to see auto-suggestion and " +
+ s"auto-completion candidates for commonly used paths and call parameters."
+ ),
+ body = NCCli.cmdCall,
+ params = Seq(
+ Parameter(
+ id = "path",
+ names = Seq("--path", "-p"),
+ value = Some("path"),
+ desc =
+ s"REST path, e.g. ${y("'signin'")} or ${y("'ask/sync'")}. " +
+ s"Note that you don't need supply '/' at the beginning. " +
+ s"See more details at https://nlpcraft.apache.org/using-rest.html " +
+ s"In REPL mode, hit ${rv(" Tab ")} to see auto-suggestion for possible REST paths."
+ ),
+ Parameter(
+ id = "xxx",
+ names = Seq("--xxx"),
+ value = Some("value"),
+ optional = true,
+ synthetic = true,
+ desc =
+ s"${y("'xxx'")} name corresponds to the REST call parameter that can be found at https://nlpcraft.apache.org/using-rest.html " +
+ s"The value of this parameter should be a valid JSON value using valid JSON syntax. Note that strings " +
+ s"don't have to be in double quotes. JSON objects and arrays should be specified as a JSON string in single quotes. You can have " +
+ s"as many ${y("'--xxx=value'")} parameters as requires by the ${y("'--path'")} parameter. " +
+ s"In REPL mode, hit ${rv(" Tab ")} to see auto-suggestion for possible parameters and their values."
+ )
+ ),
+ examples = Seq(
+ Example(
+ usage = Seq(
+ s"$PROMPT $SCRIPT_NAME call -p=signin",
+ " --email=admin@admin.com",
+ " --passwd=admin"
+ ),
+ desc =
+ s"Issues ${y("'signin'")} REST call with given JSON payload provided as a set of parameters. " +
+ s"Note that ${y("'--email'")} and ${y("'--passwd'")} parameters correspond to the REST call " +
+ s"specification for ${y("'/signin'")} path."
+ ),
+ Example(
+ usage = Seq(
+ s"$$ nlpcraft.sh call --path=ask/sync",
+ " --acsTok=qwerty123456",
+ " --txt=\"User request\"",
+ " --mdlId=my.model.id",
+ " --data='{\"data1\": true, \"data2\": 123, \"data3\": \"some text\"}'",
+ " --enableLog=false"
+ ),
+ desc =
+ s"${bo("Unix/Linux:")} issues ${y("'ask/sync'")} REST call with given JSON payload provided as a set of parameters."
+ ),
+ Example(
+ usage = Seq(
+ s"> nlpcraft.cmd call --path=ask/sync",
+ " --acsTok=qwerty123456",
+ " --txt=\"User request\"",
+ " --mdlId=my.model.id",
+ " --data='{\\\"data1\\\": true, \\\"data2\\\": 123, \\\"data3\\\": \\\"some text\\\"}'",
+ " --enableLog=false"
+ ),
+ desc =
+ s"${bo("Windows:")} issues ${y("'ask/sync'")} REST call with given JSON payload provided " +
+ s"as a set of parameters. Note the necessary double quote escaping."
+ )
+ )
+ ),
+ Command(
+ name = "ask",
+ group = "2. REST Commands",
+ synopsis = s"Wrapper for ${c("'/ask/sync'")} REST call.",
+ desc = Some(
+ s"Requires user to be already signed in. This command ${bo("only makes sense in the REPL mode")} as " +
+ s"it requires user to be signed in. REPL session keeps the currently active access " +
+ s"token after user signed in. For command line mode, use ${c("'rest'")} command with " +
+ s"corresponding parameters."
+ ),
+ body = NCCli.cmdAsk,
+ params = Seq(
+ Parameter(
+ id = "mdlId",
+ names = Seq("--mdlId"),
+ value = Some("model.id"),
+ desc =
+ s"ID of the data model to send the request to. " +
+ s"In REPL mode, hit ${rv(" Tab ")} to see auto-suggestion for possible model IDs."
+ ),
+ Parameter(
+ id = "txt",
+ names = Seq("--txt"),
+ value = Some("txt"),
+ desc =
+ s"Text of the question."
+ ),
+ Parameter(
+ id = "data",
+ names = Seq("--data"),
+ value = Some("'{}'"),
+ optional = true,
+ desc = s"Additional JSON data with maximum JSON length of 512000 bytes. Default is ${c("'null'")}."
+ ),
+ Parameter(
+ id = "enableLog",
+ names = Seq("--enableLog"),
+ value = Some("true|false"),
+ optional = true,
+ desc = s"Flag to enable detailed processing log to be returned with the result. Default is ${c("'false'")}."
+ )
+ ),
+ examples = Seq(
+ Example(
+ usage = Seq(
+ s"""> ask --txt="User request" --mdlId=my.model.id"""
+ ),
+ desc =
+ s"Issues ${y("'ask/sync'")} REST call with given text and model ID."
+ )
+ )
+ ),
+ Command(
+ name = "gen-sql",
+ group = "3. Miscellaneous",
+ synopsis = s"Generates NLPCraft model stub from SQL databases.",
+ desc = Some(
+ s"You can choose database schema, set of tables and columns for which you want to generate NLPCraft " +
+ s"model. After the model is generated you can further configure and customize it for your specific needs. " +
+ s"Find more information at https://nlpcraft.apache.org/tools/sql_model_gen.html"
+ ),
+ body = NCCli.cmdSqlGen,
+ params = Seq(
+ Parameter(
+ id = "url",
+ names = Seq("--url", "-r"),
+ value = Some("url"),
+ desc =
+ s"Database JDBC URL."
+ ),
+ Parameter(
+ id = "driver",
+ names = Seq("--driver", "-d"),
+ value = Some("class"),
+ desc =
+ s"Mandatory JDBC driver class. Note that 'class' must be a fully qualified class name. " +
+ s"It should also be available on the classpath."
+ ),
+ Parameter(
+ id = "schema",
+ names = Seq("--schema", "-s"),
+ value = Some("schema"),
+ desc =
+ s"Database schema to scan."
+ ),
+ Parameter(
+ id = "out",
+ names = Seq("--out", "-o"),
+ value = Some("filename"),
+ desc =
+ s"Name of the output JSON or YAML model file. " +
+ s"It should have one of the following extensions: .js, .json, .yml, or .yaml. " +
+ s"File extension determines the output file format."
+ ),
+ Parameter(
+ id = "user",
+ names = Seq("--user", "-u"),
+ value = Some("username"),
+ optional = true,
+ desc = s"Database user name."
+ ),
+ Parameter(
+ id = "password",
+ names = Seq("--password", "-w"),
+ value = Some("password"),
+ optional = true,
+ desc = s"Database password."
+ ),
+ Parameter(
+ id = "modelId",
+ names = Seq("--model-id", "-x"),
+ value = Some("id"),
+ optional = true,
+ desc = s"Generated model ID. By default, the model ID is ${c("'sql.model.id'")}."
+ ),
+ Parameter(
+ id = "modelVer",
+ names = Seq("--model-ver", "-v"),
+ value = Some("version"),
+ optional = true,
+ desc = s"Generated model version. By default, the model version is ${c("'1.0.0-timestamp'")}."
+ ),
+ Parameter(
+ id = "modelName",
+ names = Seq("--model-name", "-n"),
+ value = Some("name"),
+ optional = true,
+ desc = s"Generated model name. By default, the model name is ${c("'SQL-based-model'")}."
+ ),
+ Parameter(
+ id = "exclude",
+ names = Seq("--exclude", "-e"),
+ value = Some("list"),
+ optional = true,
+ desc =
+ s"Semicolon-separate list of tables and/or columns to exclude. By default, none of the " +
+ s"tables and columns in the schema are excluded. See ${c("--help")} parameter to get more details."
+ ),
+ Parameter(
+ id = "include",
+ names = Seq("--include", "-i"),
+ value = Some("list"),
+ optional = true,
+ desc =
+ s"Semicolon-separate list of tables and/or columns to include. By default, all of the " +
+ s"tables and columns in the schema are included. See ${c("--help")} parameter to get more details."
+ ),
+ Parameter(
+ id = "prefix",
+ names = Seq("--prefix", "-f"),
+ value = Some("list"),
+ optional = true,
+ desc =
+ s"Comma-separate list of table or column name prefixes to remove. These prefixes will be " +
+ s"removed when name is used for model elements synonyms. By default, no prefixes will be removed."
+ ),
+ Parameter(
+ id = "suffix",
+ names = Seq("--suffix", "-q"),
+ value = Some("list"),
+ optional = true,
+ desc =
+ s"Comma-separate list of table or column name suffixes to remove. These suffixes will be " +
+ s"removed when name is used for model elements synonyms. By default, no suffixes will be removed."
+ ),
+ Parameter(
+ id = "synonyms",
+ names = Seq("--synonyms", "-y"),
+ value = Some("true|false"),
+ optional = true,
+ desc = s"Flag on whether or not to generated auto synonyms for the model elements. Default is ${c("'true'")}."
+ ),
+ Parameter(
+ id = "override",
+ names = Seq("--override", "-z"),
+ value = Some("true|false"),
+ optional = true,
+ desc =
+ s"Flag to determine whether or not to override output file if it already exist. " +
+ s"If override is disabled (default) and output file exists - a unique file name " +
+ s"will be used instead. Default is ${c("'false'")}."
+ ),
+ Parameter(
+ id = "parent",
+ names = Seq("--parent", "-p"),
+ value = Some("true|false"),
+ optional = true,
+ desc =
+ s"Flag on whether or not to use element's parent relationship for defining " +
+ s"SQL columns and their containing (i.e. parent) tables. Default is ${c("'false'")}."
+ ),
+ Parameter(
+ id = "help",
+ names = Seq("--help", "-h"),
+ optional = true,
+ desc =
+ s"Gets extended help and usage information for the ${c("'gen-sql'")} command. " +
+ s"Includes information on how to run this tool standalone."
+ )
+ ),
+ examples = Seq(
+ Example(
+ usage = Seq(
+ s"$PROMPT $SCRIPT_NAME gen-sql --help"
+ ),
+ desc =
+ s"Shows full help and usage information for ${c("gen-sql")} command."
+ ),
+ Example(
+ usage = Seq(
+ s"$PROMPT $SCRIPT_NAME gen-sql",
+ " --url=jdbc:postgresql://localhost:5432/mydb",
+ " --driver=org.postgresql.Driver",
+ """ --prefix="tbl_, col_"""",
+ """ --suffix="_tmp, _old, _unused"""",
+ " --schema=public",
+ """ --exclude="#_.+"""",
+ " --out=model.json"
+ ),
+ desc =
+ s"Generates model stub from given SQL database connection."
+ )
+ )
+ ),
+ Command(
+ name = "sugsyn",
+ group = "2. REST Commands",
+ synopsis = s"Wrapper for ${c("'/model/sugsyn'")} REST call.",
+ desc = Some(
+ s"Requires user to be already signed in. This command ${bo("only makes sense in the REPL mode")} as " +
+ s"it requires user to be signed in. REPL session keeps the currently active access " +
+ s"token after user signed in. For command line mode, use ${c("'rest'")} command with " +
+ s"corresponding parameters. Note also that it requires a local probe running that hosts " +
+ s"the specified model. Find more information about this tool at https://nlpcraft.apache.org/tools/syn_tool.html"
+ ),
+ body = NCCli.cmdSugSyn,
+ params = Seq(
+ Parameter(
+ id = "mdlId",
+ names = Seq("--mdlId"),
+ value = Some("model.id"),
+ desc =
+ s"ID of the model to run synonym suggestion on. " +
+ s"In REPL mode, hit ${rv(" Tab ")} to see auto-suggestion for possible model IDs. " +
+ s"Note that the probe hosting this model must be connected to the server."
+ ),
+ Parameter(
+ id = "minScore",
+ names = Seq("--minScore"),
+ value = Some("0.5"),
+ optional = true,
+ desc = s"Minimal score to include into the result (from 0 to 1). Default is ${c("0.5")}."
+ )
+ ),
+ examples = Seq(
+ Example(
+ usage = Seq(
+ s"""> sugsyn --mdlId=my.model.id"""
+ ),
+ desc =
+ s"Issues ${y("'model/sugsyn'")} REST call with default min score and given model ID."
+ )
+ )
+ ),
+ Command(
+ name = "tail-server",
+ group = "1. Server & Probe Commands",
+ synopsis = s"Shows last N lines from the local server log.",
+ desc = Some(
+ s"Only works for the server started via this script."
+ ),
+ body = NCCli.cmdTailServer,
+ params = Seq(
+ Parameter(
+ id = "lines",
+ names = Seq("--lines", "-l"),
+ value = Some("num"),
+ desc =
+ s"Number of the server log lines from the end to display. Default is 20."
+ )
+ ),
+ examples = Seq(
+ Example(
+ usage = Seq(s"$PROMPT $SCRIPT_NAME tail-server --lines=20 "),
+ desc = s"Prints last 20 lines from the local server log."
+ )
+ )
+ ),
+ Command(
+ name = "tail-probe",
+ group = "1. Server & Probe Commands",
+ synopsis = s"Shows last N lines from the local probe log.",
+ desc = Some(
+ s"Only works for the probe started via this script."
+ ),
+ body = NCCli.cmdTailProbe,
+ params = Seq(
+ Parameter(
+ id = "lines",
+ names = Seq("--lines", "-l"),
+ value = Some("num"),
+ desc =
+ s"Number of the probe log lines from the end to display. Default is 20."
+ )
+ ),
+ examples = Seq(
+ Example(
+ usage = Seq(s"$PROMPT $SCRIPT_NAME tail-probe --lines=20 "),
+ desc = s"Prints last 20 lines from the local probe log."
+ )
+ )
+ ),
+ Command(
+ name = "start-server",
+ group = "1. Server & Probe Commands",
+ synopsis = s"Starts local server.",
+ desc = Some(
+ s"Server is started in the external JVM process with both stdout and stderr piped out into log file. " +
+ s"Command will block until the server is started unless ${y("'--no-wait'")} parameter is used or timeout is expired."
+ ),
+ body = NCCli.cmdStartServer,
+ params = Seq(
+ Parameter(
+ id = "config",
+ names = Seq("--config", "-c"),
+ value = Some("path"),
+ optional = true,
+ desc =
+ s"Configuration file path. Server will automatically look for ${y("'nlpcraft.conf'")} " +
+ s"configuration file in the same directory as NLPCraft JAR file. If the configuration file has " +
+ s"different name or in different location use this parameter to provide an alternative path. " +
+ s"Note that the server and the probe can use the same file for their configuration."
+ ),
+ Parameter(
+ id = "igniteConfig",
+ names = Seq("--ignite-config", "-i"),
+ value = Some("path"),
+ optional = true,
+ desc =
+ s"Apache Ignite configuration file path. Note that Apache Ignite is used as a cluster " +
+ s"computing plane and a default distributed storage. Server will automatically look for " +
+ s"${y("'ignite.xml'")} configuration file in the same directory as NLPCraft JAR file. If the " +
+ s"configuration file has different name or in different location use this parameter to " +
+ s"provide an alternative path."
+ ),
+ Parameter(
+ id = "jvmopts",
+ names = Seq("--jvm-opts", "-j"),
+ value = Some("<jvm flags>"),
+ optional = true,
+ desc =
+ s"Space separated quoted string of JVM flags to use. If not provided, the " +
+ s"default ${y("'-ea -Xms2048m -XX:+UseG1GC'")} flags will be used."
+ ),
+ Parameter(
+ id = "noWait",
+ names = Seq("--no-wait"),
+ optional = true,
+ desc =
+ s"Instructs command not to wait for the server startup and return immediately."
+ ),
+ Parameter(
+ id = "timeoutMins",
+ names = Seq("--timeout-mins", "-t"),
+ optional = true,
+ value = Some("3"),
+ desc =
+ s"Timeout in minutes to wait until server is started. If not specified the default is 2 minutes."
+ )
+ ),
+ examples = Seq(
+ Example(
+ usage = Seq(s"$PROMPT $SCRIPT_NAME start-server"),
+ desc = "Starts local server with default configuration."
+ ),
+ Example(
+ usage = Seq(s"$PROMPT $SCRIPT_NAME start-server -c=/opt/nlpcraft/nlpcraft.conf -t=5"),
+ desc = "Starts local server with alternative configuration file and timeout of 5 mins."
+ )
+ )
+ ),
+ Command(
+ name = "start-probe",
+ group = "1. Server & Probe Commands",
+ synopsis = s"Starts local probe.",
+ desc = Some(
+ s"Probe is started in the external JVM process with both stdout and stderr piped out into log file. " +
+ s"Command will block until the probe is started unless ${y("'--no-wait'")} parameter is used or timeout is expired."
+ ),
+ body = NCCli.cmdStartProbe,
+ params = Seq(
+ Parameter(
+ id = "config",
+ names = Seq("--config", "-c"),
+ value = Some("path"),
+ optional = true,
+ desc =
+ s"Configuration file path. Probe will automatically look for ${y("'nlpcraft.conf'")} " +
+ s"configuration file in the same directory as NLPCraft JAR file. If the configuration file has " +
+ s"different name or in different location use this parameter to provide an alternative path. " +
+ s"Note that the server and the probe can use the same file for their configuration."
+ ),
+ Parameter(
+ id = "cp",
+ names = Seq("--cp", "-p"),
+ value = Some("path"),
+ optional = true,
+ desc =
+ s"Additional JVM classpath that will be appended to the default NLPCraft JVM classpath. " +
+ s"Although this configuration property is optional, when deploying your own models you must " +
+ s"provide this additional classpath for the models and their dependencies this probe will be hosting. " +
+ s"NOTE: this is only optional if you are running example models shipped with NLPCraft."
+ ),
+ Parameter(
+ id = "models",
+ names = Seq("--models", "-m"),
+ value = Some("<model list>"),
+ optional = true,
+ desc =
+ s"Comma separated list of fully qualified class names for models to deploy. This will override " +
+ s"${y("'nlpcraft.probe.models'")} configuration property from either default configuration file " +
+ s"or the one provided by ${y("--config")} parameter. NOTE: if you provide the list of your " +
+ s"own models here or in configuration file - you must also provide the additional classpath " +
+ s"for them via ${y("--cp")} parameter."
+ ),
+ Parameter(
+ id = "jvmopts",
+ names = Seq("--jvm-opts", "-j"),
+ value = Some("<jvm flags>"),
+ optional = true,
+ desc =
+ s"Space separated quoted string of JVM flags to use. If not provided, the " +
+ s"default ${y("'-ea -Xms1024m'")} flags will be used."
+ ),
+ Parameter(
+ id = "noWait",
+ names = Seq("--no-wait"),
+ optional = true,
+ desc =
+ s"Instructs command not to wait for the probe startup and return immediately."
+ ),
+ Parameter(
+ id = "timeoutMins",
+ names = Seq("--timeout-mins", "-t"),
+ optional = true,
+ value = Some("3"),
+ desc =
+ s"Timeout to wait until probe is started. If not specified the default is 1 minute."
+ )
+ ),
+ examples = Seq(
+ Example(
+ usage = Seq(s"$PROMPT $SCRIPT_NAME start-probe"),
+ desc = "Starts local probe with default configuration and parameters."
+ ),
+ Example(
+ usage = Seq(
+ s"$PROMPT $SCRIPT_NAME start-probe ",
+ " --config=/opt/nlpcraft.conf ",
+ " --models=my.package.Model ",
+ " --cp=/opt/target/classes ",
+ " --jmv-opts=\"-ea -Xms2048m\" ",
+ " --timeout-mins=5"
+ ),
+ desc =
+ s"Starts local probe for ${y("'my.package.Model'")} model with alternative configuration " +
+ s"file and additional parameters."
+ )
+ )
+ ),
+ Command(
+ name = "test-model",
+ group = "3. Miscellaneous",
+ synopsis = s"Runs ${y("'NCTestAutoModelValidator'")} model auto-validator.",
+ desc = Some(
+ s"Validation consists " +
+ s"of starting an embedded probe, scanning all deployed models for ${y("'NCIntentSample'")} annotations and their corresponding " +
+ s"callback methods, submitting each sample input sentences from ${y("'NCIntentSample'")} annotation and " +
+ s"checking that resulting intent matches the intent the sample was attached to. " +
+ s"See more details at https://nlpcraft.apache.org/tools/test_framework.html"
+ ),
+ body = NCCli.cmdTestModel,
+ params = Seq(
+ Parameter(
+ id = "config",
+ names = Seq("--config", "-c"),
+ value = Some("path"),
+ optional = true,
+ desc =
+ s"Configuration file path. By default, the embedded probe will automatically look for ${y("'nlpcraft.conf'")} " +
+ s"configuration file in the same directory as NLPCraft JAR file. If the configuration file has " +
+ s"different name or in different location use this parameter to provide an alternative path."
+ ),
+ Parameter(
+ id = "cp",
+ names = Seq("--cp", "-p"),
+ value = Some("path"),
+ optional = true,
+ desc =
+ s"Additional JVM classpath that will be appended to the default NLPCraft JVM classpath. " +
+ s"Although this configuration property is optional, when testing your own models you must " +
+ s"provide this additional classpath for the models and their dependencies. " +
+ s"NOTE: this is only optional if you are testing example models shipped with NLPCraft."
+ ),
+ Parameter(
+ id = "models",
+ names = Seq("--models", "-m"),
+ value = Some("<model list>"),
+ optional = true,
+ desc =
+ s"Comma separated list of fully qualified class names for models to test. NOTE: if you provide " +
+ s"the list of your own models here - you must also provide the additional classpath " +
+ s"for them via ${y("--cp")} parameter."
+ ),
+ Parameter(
+ id = "jvmopts",
+ names = Seq("--jvm-opts", "-j"),
+ value = Some("<jvm flags>"),
+ optional = true,
+ desc =
+ s"Space separated quoted string of JVM flags to use. If not provided, the " +
+ s"default ${y("'-ea -Xms1024m'")} flags will be used."
+ )
+ ),
+ examples = Seq(
+ Example(
+ usage = Seq(
+ s"$PROMPT $SCRIPT_NAME test-model ",
+ " --models=my.package.Model ",
+ " --cp=/opt/target/classes ",
+ " --jmv-opts=\"-ea -Xms2048m\""
+ ),
+ desc =
+ s"Runs model auto-validator for ${y("'my.package.Model'")} model."
+ )
+ )
+ ),
+ Command(
+ name = "info-server",
+ group = "1. Server & Probe Commands",
+ synopsis = s"Info about local server.",
+ body = NCCli.cmdInfoServer
+ ),
+ Command(
+ name = "info-probe",
+ group = "1. Server & Probe Commands",
+ synopsis = s"Info about local probe.",
+ body = NCCli.cmdInfoProbe
+ ),
+ Command(
+ name = "info",
+ group = "1. Server & Probe Commands",
+ synopsis = s"Info about local probe & server.",
+ body = NCCli.cmdInfo
+ ),
+ Command(
+ name = "clear",
+ group = "3. Miscellaneous",
+ synopsis = s"Clears terminal screen.",
+ body = NCCli.cmdClear
+ ),
+ Command(
+ name = "no-ansi",
+ group = "3. Miscellaneous",
+ synopsis = s"Disables ANSI escape codes for terminal colors & controls.",
+ desc = Some(
+ s"This is a special command that can be combined with any other commands."
+ ),
+ body = NCCli.cmdNoAnsi,
+ examples = Seq(
+ Example(
+ usage = Seq(s"$PROMPT $SCRIPT_NAME help -c=rest no-ansi"),
+ desc = s"Displays help for ${y("'rest'")} commands without using ANSI color and escape sequences."
+ )
+ )
+ ),
+ Command(
+ name = "no-logo",
+ group = "3. Miscellaneous",
+ synopsis = s"Disables showing NLPCraft logo at the start.",
+ desc = Some(
+ s"This is a special command that can be combined with any other command in a command line mode."
+ ),
+ body = NCCli.cmdNoLogo,
+ examples = Seq(
+ Example(
+ usage = Seq(s"$PROMPT $SCRIPT_NAME version -s no-logo"),
+ desc =
+ s"Displays just the version information without any additional logo output. " +
+ s"This command makes sense only in command lime mode (NOT in REPL mode)."
+ )
+ )
+ ),
+ Command(
+ name = "ansi",
+ group = "3. Miscellaneous",
+ synopsis = s"Enables ANSI escape codes for terminal colors & controls.",
+ desc = Some(
+ s"This is a special command that can be combined with any other commands."
+ ),
+ body = NCCli.cmdAnsi,
+ examples = Seq(
+ Example(
+ usage = Seq(s"$PROMPT $SCRIPT_NAME help -c=rest ansi"),
+ desc = s"Displays help for ${y("'rest'")} commands with ANSI color and escape sequences."
+ )
+ )
+ ),
+ Command(
+ name = "ping-server",
+ group = "1. Server & Probe Commands",
+ synopsis = s"Pings local server.",
+ desc = Some(
+ s"Server is pinged using ${y("'/health'")} REST call to check its online status."
+ ),
+ body = NCCli.cmdPingServer,
+ params = Seq(
+ Parameter(
+ id = "number",
+ names = Seq("--number", "-n"),
+ value = Some("num"),
+ optional = true,
+ desc =
+ "Number of pings to perform. Must be a number > 0. Default is 1."
+ )
+ ),
+ examples = Seq(
+ Example(
+ usage = Seq(
+ s"$PROMPT $SCRIPT_NAME ping-server -n=10"
+ ),
+ desc = "Pings local server 10 times."
+ )
+ )
+ ),
+ Command(
+ name = "stop-server",
+ group = "1. Server & Probe Commands",
+ synopsis = s"Stops local server.",
+ desc = Some(
+ s"Local server must be started via ${y(s"'$SCRIPT_NAME'")} or other compatible way."
+ ),
+ body = NCCli.cmdStopServer
+ ),
+ Command(
+ name = "stop-probe",
+ group = "1. Server & Probe Commands",
+ synopsis = s"Stops local probe.",
+ desc = Some(
+ s"Local probe must be started via ${y(s"'$SCRIPT_NAME'")} or other compatible way."
+ ),
+ body = NCCli.cmdStopProbe
+ ),
+ Command(
+ name = "stop",
+ group = "1. Server & Probe Commands",
+ synopsis = s"Stops both local server & probe.",
+ desc = Some(
+ s"Both local server & probe must be started via ${y(s"'$SCRIPT_NAME'")} or other compatible way."
+ ),
+ body = NCCli.cmdStop
+ ),
+ Command(
+ name = "quit",
+ group = "3. Miscellaneous",
+ synopsis = s"Quits REPL mode. Note that started server and probe, if any, will remain running.",
+ body = NCCli.cmdQuit
+ ),
+ Command(
+ name = "help",
+ group = "3. Miscellaneous",
+ synopsis = s"Displays help for ${y(s"'$SCRIPT_NAME'")}.",
+ desc = Some(
+ s"By default, without ${y("'--all'")} or ${y("'--cmd'")} parameters, displays the abbreviated form of manual " +
+ s"only listing the commands without parameters or examples."
+ ),
+ body = NCCli.cmdHelp,
+ params = Seq(
+ Parameter(
+ id = "cmd",
+ names = Seq("--cmd", "-c"),
+ value = Some("cmd"),
+ optional = true,
+ desc = "Set of commands to show the manual for. Can be used multiple times."
+ ),
+ Parameter(
+ id = "all",
+ names = Seq("--all", "-a"),
+ optional = true,
+ desc = "Flag to show full manual for all commands."
+ )
+ ),
+ examples = Seq(
+ Example(
+ usage = Seq(s"$PROMPT $SCRIPT_NAME help -c=rest --cmd=version"),
+ desc = s"Displays help for ${y("'rest'")} and ${y("'version'")} commands."
+ ),
+ Example(
+ usage = Seq(s"$PROMPT $SCRIPT_NAME help -all"),
+ desc = "Displays help for all commands."
+ )
+ )
+ ),
+ Command(
+ name = "version",
+ group = "3. Miscellaneous",
+ synopsis = s"Displays full version of ${y(s"'$SCRIPT_NAME'")} script.",
+ desc = Some(
+ "Depending on the additional parameters can display only the semantic version or the release date."
+ ),
+ body = NCCli.cmdVersion,
+ params = Seq(
+ Parameter(
+ id = "semver",
+ names = Seq("--sem-ver", "-s"),
+ value = None,
+ optional = true,
+ desc = s"Display only the semantic version value, e.g. ${VER.version}."
+ ),
+ Parameter(
+ id = "reldate",
+ names = Seq("--rel-date", "-d"),
+ value = None,
+ optional = true,
+ desc = s"Display only the release date, e.g. ${VER.date}."
+ )
+ )
+ ),
+ Command(
+ name = "gen-project",
+ group = "3. Miscellaneous",
+ synopsis = s"Generates project stub with default configuration.",
+ desc = Some(
+ "This command supports Java, Scala, and Kotlin languages with either Maven, Gradle or SBT " +
+ "as a build tool. Generated projects compiles and runs and can be used as a quick development sandbox."
+ ),
+ body = NCCli.cmdGenProject,
+ params = Seq(
+ Parameter(
+ id = "outputDir",
+ names = Seq("--outputDir", "-d"),
+ value = Some("path"),
+ optional = true,
+ desc = s"Output directory. Default value is the current working directory."
+ ),
+ Parameter(
+ id = "baseName",
+ names = Seq("--baseName", "-n"),
+ value = Some("name"),
+ desc =
+ s"Base name for the generated files. For example, if base name is ${y("'MyApp'")}, " +
+ s"then generated Java file will be named as ${y("'MyAppModel.java'")} and model file as ${y("'my_app_model.yaml'")}."
+ ),
+ Parameter(
+ id = "lang",
+ names = Seq("--lang", "-l"),
+ value = Some("name"),
+ optional = true,
+ desc =
+ s"Language to generate source files in. Supported value are ${y("'java'")}, ${y("'scala'")}, ${y("'kotlin'")}. " +
+ s"Default value is ${y("'java'")}."
+ ),
+ Parameter(
+ id = "buildTool",
+ names = Seq("--buildTool", "-b"),
+ value = Some("name"),
+ optional = true,
+ desc =
+ s"Build tool name to use. Supported values are ${y("'mvn'")} and ${y("'gradle'")} for ${y("'java'")}, " +
+ s"${y("'scala'")}, ${y("'kotlin'")}, and ${y("'sbt'")} for ${y("'scala'")} language. Default value is ${y("'mvn'")}."
+ ),
+ Parameter(
+ id = "packageName",
+ names = Seq("--packageName", "-p"),
+ value = Some("name"),
+ optional = true,
+ desc = s"JVM package name to use in generated source code. Default value is ${y("'org.apache.nlpcraft.demo'")}."
+ ),
+ Parameter(
+ id = "modelType",
+ names = Seq("--modelType", "-m"),
+ value = Some("type"),
+ optional = true,
+ desc = s"Type of generated model file. Supported value are ${y("'yaml'")} or ${y("'json'")}. Default value is ${y("'yaml'")}."
+ ),
+ Parameter(
+ id = "override",
+ names = Seq("--override", "-o"),
+ value = Some("true|false"),
+ optional = true,
+ desc = s"Whether or not to override existing output directory. Default value is ${y("'false'")}."
+ )
+ ),
+ examples = Seq(
+ Example(
+ usage = Seq("> gen-project -n=MyProject -l=scala -b=sbt"),
+ desc = s"Generates Scala SBT project."
+ ),
+ Example(
+ usage = Seq("> gen-project -n=MyProject -l=kotlin -p=com.mycompany.nlp -o=true"),
+ desc = s"Generates Kotlin Maven project."
+ )
+ )
+ ),
+ Command(
+ name = "gen-model",
+ group = "3. Miscellaneous",
+ synopsis = s"Generates data model file stub.",
+ desc = Some(
+ "Generated model stub will have all default configuration. Model file can be either YAML or JSON."
+ ),
+ body = NCCli.cmdGenModel,
+ params = Seq(
+ Parameter(
+ id = "filePath",
+ names = Seq("--filePath", "-f"),
+ value = Some("path"),
+ desc =
+ s"File path for the model stub. File path can either be an absolute path, relative path or " +
+ s"just a file name in which case the current folder will be used. File must have one of the " +
+ s"following extensions: ${y("'json'")}, ${y("'js'")}, ${y("'yaml'")}, or ${y("'yml'")}."
+ ),
+ Parameter(
+ id = "modelId",
+ names = Seq("--modelId", "-n"),
+ value = Some("id"),
+ desc = "Model ID."
+ ),
+ Parameter(
+ id = "override",
+ names = Seq("--override", "-o"),
+ value = Some("true|false"),
+ optional = true,
+ desc = s"Override output directory flag. Supported: ${y("'true'")}, ${y("'false'")}. Default value is ${y("'false'")}"
+ )
+ ),
+ examples = Seq(
+ Example(
+ usage = Seq("> gen-model -f=myModel.json -n=my.model.id"),
+ desc = s"Generates JSON model file stub in the current folder."
+ ),
+ Example(
+ usage = Seq("> gen-model -f=c:/tmp/myModel.yaml -n=my.model.id --override=true"),
+ desc = s"Generates YAML model file stub in ${y("'c:/temp'")} folder overriding existing file, if any."
+ )
+ )
+ )
+ ).sortBy(_.name)
+
+ require(
+ U.getDups(CMDS.map(_.name)).isEmpty,
+ "Dup commands."
+ )
+}
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCliRestSpec.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCliRestSpec.scala
new file mode 100644
index 0000000..47dfca1
--- /dev/null
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCliRestSpec.scala
@@ -0,0 +1,326 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.nlpcraft.model.tools.cmdline
+
+private [cmdline] case class RestSpec(
+ path: String,
+ desc: String,
+ group: String,
+ params: Seq[RestSpecParameter]
+)
+
+private [cmdline] sealed trait JsonType
+
+private [cmdline] case object STRING extends JsonType
+private [cmdline] case object BOOLEAN extends JsonType
+private [cmdline] case object NUMERIC extends JsonType
+private [cmdline] case object OBJECT extends JsonType
+private [cmdline] case object ARRAY extends JsonType
+
+private [cmdline] case class RestSpecParameter(
+ name: String,
+ kind: JsonType,
+ optional: Boolean = false // Mandatory by default.
+)
+
+/**
+ * NLPCraft REST specification.
+ * TODO: this needs to be loaded dynamically from OpenAPI spec.
+ */
+private [cmdline] object NCCliRestSpec {
+ //noinspection DuplicatedCode
+ private [cmdline] final val REST_SPEC = Seq(
+ RestSpec(
+ path = "clear/conversation",
+ desc = "Clears conversation STM",
+ group = "Asking",
+ params = Seq(
+ RestSpecParameter(name = "acsTok", kind = STRING),
+ RestSpecParameter(name = "mdlId", kind = STRING),
+ RestSpecParameter(name = "usrId", kind = STRING, optional = true),
+ RestSpecParameter(name = "usrExtId", kind = STRING, optional = true)
+ )
+ ),
+ RestSpec(
+ "clear/dialog",
+ "Clears dialog flow",
+ "Asking",
+ params = Seq(
+ RestSpecParameter(name = "acsTok", kind = STRING),
+ RestSpecParameter(name = "mdlId", kind = STRING),
+ RestSpecParameter(name = "usrId", kind = STRING, optional = true),
+ RestSpecParameter(name = "usrExtId", kind = STRING, optional = true)
+ )
+ ),
+ RestSpec(
+ "model/sugsyn",
+ "Runs model synonym suggestion tool",
+ "Tools",
+ params = Seq(
+ RestSpecParameter(name = "acsTok", kind = STRING),
+ RestSpecParameter(name = "mdlId", kind = STRING),
+ RestSpecParameter(name = "minScore", kind = NUMERIC)
+ )
+ ),
+ RestSpec(
+ "check",
+ "Gets status and result of submitted requests",
+ "Asking",
+ params = Seq(
+ RestSpecParameter(name = "acsTok", kind = STRING),
+ RestSpecParameter(name = "usrId", kind = STRING, optional = true),
+ RestSpecParameter(name = "usrExtId", kind = STRING, optional = true),
+ RestSpecParameter(name = "srvReqIds", kind = ARRAY, optional = true),
+ RestSpecParameter(name = "maxRows", kind = NUMERIC, optional = true)
+ )
+ ),
+ RestSpec(
+ "cancel",
+ "Cancels a question",
+ "Asking",
+ params = Seq(
+ RestSpecParameter(name = "acsTok", kind = STRING),
+ RestSpecParameter(name = "usrId", kind = STRING, optional = true),
+ RestSpecParameter(name = "usrExtId", kind = STRING, optional = true),
+ RestSpecParameter(name = "srvReqIds", kind = ARRAY, optional = true),
+ )
+ ),
+ RestSpec(
+ "ask",
+ "Asks a question",
+ "Asking",
+ params = Seq(
+ RestSpecParameter(name = "acsTok", kind = STRING),
+ RestSpecParameter(name = "usrId", kind = STRING, optional = true),
+ RestSpecParameter(name = "usrExtId", kind = STRING, optional = true),
+ RestSpecParameter(name = "txt", kind = STRING),
+ RestSpecParameter(name = "mdlId", kind = STRING),
+ RestSpecParameter(name = "data", kind = OBJECT, optional = true),
+ RestSpecParameter(name = "enableLog", kind = BOOLEAN, optional = true),
+ )
+ ),
+ RestSpec(
+ "ask/sync",
+ "Asks a question in synchronous mode",
+ "Asking",
+ params = Seq(
+ RestSpecParameter(name = "acsTok", kind = STRING),
+ RestSpecParameter(name = "usrId", kind = STRING, optional = true),
+ RestSpecParameter(name = "usrExtId", kind = STRING, optional = true),
+ RestSpecParameter(name = "txt", kind = STRING),
+ RestSpecParameter(name = "mdlId", kind = STRING),
+ RestSpecParameter(name = "data", kind = OBJECT, optional = true),
+ RestSpecParameter(name = "enableLog", kind = BOOLEAN, optional = true),
+ )
+ ),
+ RestSpec(
+ "user/get",
+ "Gets current user information",
+ "User",
+ params = Seq(
+ RestSpecParameter(name = "acsTok", kind = STRING),
+ RestSpecParameter(name = "id", kind = STRING, optional = true),
+ RestSpecParameter(name = "usrExtId", kind = STRING, optional = true)
+ )
+ ),
+ RestSpec(
+ "user/all",
+ "Gets all users",
+ "User",
+ params = Seq(
+ RestSpecParameter(name = "acsTok", kind = STRING),
+ )
+ ),
+ RestSpec(
+ "user/update",
+ "Updates regular user",
+ "User",
+ params = Seq(
+ RestSpecParameter(name = "acsTok", kind = STRING),
+ RestSpecParameter(name = "firstName", kind = STRING),
+ RestSpecParameter(name = "lastName", kind = STRING),
+ RestSpecParameter(name = "id", kind = STRING, optional = true),
+ RestSpecParameter(name = "avatarUrl", kind = STRING, optional = true),
+ RestSpecParameter(name = "properties", kind = OBJECT, optional = true)
+ )
+ ),
+ RestSpec(
+ "user/delete",
+ "Deletes user",
+ "User",
+ params = Seq(
+ RestSpecParameter(name = "acsTok", kind = STRING),
+ RestSpecParameter(name = "id", kind = STRING, optional = true),
+ RestSpecParameter(name = "usrExtId", kind = STRING, optional = true)
+ )
+ ),
+ RestSpec(
+ "user/admin",
+ "Updates user admin permissions",
+ "User",
+ params = Seq(
+ RestSpecParameter(name = "acsTok", kind = STRING),
+ RestSpecParameter(name = "id", kind = STRING, optional = true),
+ RestSpecParameter(name = "isAdmin", kind = BOOLEAN)
+ )
+ ),
+ RestSpec(
+ "user/passwd/reset",
+ "Resets password for the user",
+ "User",
+ params = Seq(
+ RestSpecParameter(name = "acsTok", kind = STRING),
+ RestSpecParameter(name = "id", kind = STRING, optional = true),
+ RestSpecParameter(name = "newPasswd", kind = STRING)
+ )
+ ),
+ RestSpec(
+ "user/add",
+ "Adds new user",
+ "User",
+ params = Seq(
+ RestSpecParameter(name = "acsTok", kind = STRING),
+ RestSpecParameter(name = "firstName", kind = STRING),
+ RestSpecParameter(name = "lastName", kind = STRING),
+ RestSpecParameter(name = "email", kind = STRING),
+ RestSpecParameter(name = "passwd", kind = STRING),
+ RestSpecParameter(name = "isAdmin", kind = BOOLEAN),
+ RestSpecParameter(name = "usrExtId", kind = STRING, optional = true),
+ RestSpecParameter(name = "avatarUrl", kind = STRING, optional = true),
+ RestSpecParameter(name = "properties", kind = OBJECT, optional = true)
+ )
+ ),
+ RestSpec(
+ "company/get",
+ "Gets current user company information",
+ "Company",
+ params = Seq(
+ RestSpecParameter(name = "acsTok", kind = STRING),
+ )
+ ),
+ RestSpec(
+ "company/add",
+ "Adds new company",
+ "Company",
+ params = Seq(
+ RestSpecParameter(name = "acsTok", kind = STRING),
+ RestSpecParameter(name = "name", kind = STRING),
+ RestSpecParameter(name = "website", kind = STRING, optional = true),
+ RestSpecParameter(name = "country", kind = STRING, optional = true),
+ RestSpecParameter(name = "region", kind = STRING, optional = true),
+ RestSpecParameter(name = "city", kind = STRING, optional = true),
+ RestSpecParameter(name = "address", kind = STRING, optional = true),
+ RestSpecParameter(name = "postalCode", kind = STRING, optional = true),
+ RestSpecParameter(name = "adminEmail", kind = STRING),
+ RestSpecParameter(name = "adminPasswd", kind = STRING),
+ RestSpecParameter(name = "adminFirstName", kind = STRING),
+ RestSpecParameter(name = "adminLastName", kind = STRING),
+ RestSpecParameter(name = "adminAvatarUrl", kind = STRING, optional = true)
+ )
+ ),
+ RestSpec(
+ "company/update",
+ "Updates company data",
+ "Company",
+ params = Seq(
+ RestSpecParameter(name = "acsTok", kind = STRING),
+ RestSpecParameter(name = "name", kind = STRING),
+ RestSpecParameter(name = "website", kind = STRING, optional = true),
+ RestSpecParameter(name = "country", kind = STRING, optional = true),
+ RestSpecParameter(name = "region", kind = STRING, optional = true),
+ RestSpecParameter(name = "city", kind = STRING, optional = true),
+ RestSpecParameter(name = "address", kind = STRING, optional = true),
+ RestSpecParameter(name = "postalCode", kind = STRING, optional = true)
+ )
+ ),
+ RestSpec(
+ "company/delete",
+ "Deletes company",
+ "Company",
+ params = Seq(
+ RestSpecParameter(name = "acsTok", kind = STRING),
+ )
+ ),
+ RestSpec(
+ "company/token/reset",
+ "Resets company probe auth token",
+ "Company",
+ params = Seq(
+ RestSpecParameter(name = "acsTok", kind = STRING),
+ )
+ ),
+ RestSpec(
+ "feedback/add",
+ "Adds feedback",
+ "Asking",
+ params = Seq(
+ RestSpecParameter(name = "acsTok", kind = STRING),
+ RestSpecParameter(name = "usrId", kind = STRING, optional = true),
+ RestSpecParameter(name = "extUsrId", kind = STRING, optional = true),
+ RestSpecParameter(name = "comment", kind = STRING, optional = true),
+ RestSpecParameter(name = "srvReqId", kind = STRING),
+ RestSpecParameter(name = "score", kind = STRING)
+ )
+ ),
+ RestSpec(
+ "feedback/delete",
+ "Deletes feedback",
+ "Asking",
+ params = Seq(
+ RestSpecParameter(name = "acsTok", kind = STRING),
+ RestSpecParameter(name = "id", kind = NUMERIC)
+ )
+ ),
+ RestSpec(
+ "feedback/all",
+ "Gets all feedback",
+ "Asking",
+ params = Seq(
+ RestSpecParameter(name = "acsTok", kind = STRING),
+ RestSpecParameter(name = "usrId", kind = STRING, optional = true),
+ RestSpecParameter(name = "extUsrId", kind = STRING, optional = true),
+ RestSpecParameter(name = "srvReqId", kind = STRING, optional = true)
+ )
+ ),
+ RestSpec(
+ "signin",
+ "Signs in and obtains new access token",
+ "Authentication",
+ params = Seq(
+ RestSpecParameter(name = "email", kind = STRING),
+ RestSpecParameter(name = "passwd", kind = STRING)
+ )
+ ),
+ RestSpec(
+ "signout",
+ "Signs out and releases access token",
+ "Authentication",
+ params = Seq(
+ RestSpecParameter(name = "acsTok", kind = STRING),
+ )
+ ),
+ RestSpec(
+ "probe/all",
+ "Gets all probes",
+ "Probe",
+ params = Seq(
+ RestSpecParameter(name = "acsTok", kind = STRING),
+ )
+ )
+ )
+}
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/embedded/NCEmbeddedProbe.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/embedded/NCEmbeddedProbe.java
index 7786ea4..3ab85d8 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/embedded/NCEmbeddedProbe.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/embedded/NCEmbeddedProbe.java
@@ -21,6 +21,8 @@ import org.apache.nlpcraft.common.*;
import org.apache.nlpcraft.model.tools.test.*;
import org.apache.nlpcraft.probe.*;
import org.apache.nlpcraft.probe.mgrs.nlp.*;
+
+import java.util.Collection;
import java.util.concurrent.*;
import java.util.function.*;
@@ -93,7 +95,7 @@ public class NCEmbeddedProbe {
* @throws NCException Thrown in case of any errors starting the data probe.
* @return Whether or not probe started ok.
*/
- public static boolean start(String cfgFile, String... mdlClasses) {
+ public static boolean start(String cfgFile, Collection<String> mdlClasses) {
CompletableFuture<Integer> fut = new CompletableFuture<>();
NCProbeBoot$.MODULE$.startEmbedded(cfgFile, mdlClasses, fut);
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/test/NCTestAutoModelValidator.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/test/NCTestAutoModelValidator.java
index 21321a2..885149f 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/test/NCTestAutoModelValidator.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/test/NCTestAutoModelValidator.java
@@ -22,9 +22,9 @@ import org.apache.nlpcraft.model.tools.test.impl.*;
/**
* Data model auto-validator is based on {@link NCIntentSample} annotations. Validation consists of starting an embedded
- * probe, scanning for {@link NCIntentSample} annotations and their corresponding callback methods, submitting each sample input
- * sentences from {@link NCIntentSample} annotation and checking that resulting intent matches the intent the sample
- * was attached to.
+ * probe, scanning all deployed models for {@link NCIntentSample} annotations and their corresponding callback methods,
+ * submitting each sample input sentences from {@link NCIntentSample} annotation and checking that resulting intent
+ * matches the intent the sample was attached to.
* <p>
* Note that there can be more than one {@link NCIntentSample} annotation attached to the intent callback. Each such
* annotation will trigger conversation STM reset before its samples will be submitted. This gives an opportunity
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/test/impl/NCTestAutoModelValidatorImpl.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/test/impl/NCTestAutoModelValidatorImpl.scala
index 2a72c77..30dca04 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/test/impl/NCTestAutoModelValidatorImpl.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/test/impl/NCTestAutoModelValidatorImpl.scala
@@ -24,6 +24,8 @@ import org.apache.nlpcraft.model.tools.embedded.NCEmbeddedProbe
import org.apache.nlpcraft.model.tools.test.NCTestClientBuilder
import org.apache.nlpcraft.probe.mgrs.model.NCModelManager
+import scala.collection.JavaConverters._
+
/**
* Implementation for `NCTestAutoModelValidator` class.
*/
@@ -38,10 +40,13 @@ private [test] object NCTestAutoModelValidatorImpl extends LazyLogging {
*/
@throws[Exception]
def isValid: Boolean = {
- val classes = U.sysEnv(PROP_MODELS).orNull
+ val classes = U.sysEnv(PROP_MODELS) match {
+ case Some(s) ⇒ U.splitTrimFilter(s, ",")
+ case None ⇒ null
+ }
val cfgFile = U.sysEnv(PROP_PROBE_CFG).orNull
- if (NCEmbeddedProbe.start(cfgFile, classes))
+ if (NCEmbeddedProbe.start(cfgFile, classes.asJava))
try
process(NCModelManager.getAllModels().map(p ⇒ p.model.getId → p.samples.toMap).toMap.filter(_._2.nonEmpty))
finally
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/NCProbe.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/NCProbe.scala
index 44abbef..d071837 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/NCProbe.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/NCProbe.scala
@@ -27,10 +27,10 @@ import scala.util.control.Exception.ignoring
* Data probe main app.
*/
object NCProbe extends App {
- val fut = new CompletableFuture[Integer]
-
NCAnsi.ackStatus()
+ val fut = new CompletableFuture[Integer]
+
NCProbeBoot.start(args, fut)
while (!fut.isDone)
@@ -38,5 +38,6 @@ object NCProbe extends App {
fut.get()
}
- System.exit(fut.get)
+ if (fut.get != 0)
+ System.exit(fut.get)
}
\ No newline at end of file
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/NCProbeBoot.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/NCProbeBoot.scala
index 96120b9..a54e22f 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/NCProbeBoot.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/NCProbeBoot.scala
@@ -100,7 +100,6 @@ private [probe] object NCProbeBoot extends LazyLogging with NCOpenCensusTrace {
withValue(s"$prefix.token", fromAnyRef("3141592653589793")).
withValue(s"$prefix.upLink", fromAnyRef("localhost:8201")).
withValue(s"$prefix.downLink", fromAnyRef("localhost:8202")).
- withValue(s"$prefix.model", fromAnyRef(null)).
withValue(s"$prefix.models", fromAnyRef("")).
withValue(s"$prefix.lifecycle", fromIterable(Seq().asJava)).
withValue(s"$prefix.resultMaxSizeBytes", fromAnyRef(1048576)).
@@ -156,6 +155,8 @@ private [probe] object NCProbeBoot extends LazyLogging with NCOpenCensusTrace {
val models: String = getString(s"$prefix.models")
val lifecycle: Seq[String] = getStringList(s"$prefix.lifecycle")
}
+
+ println(s"Models -> ${Cfg.models}")
ProbeConfig(
Cfg.id,
@@ -337,7 +338,7 @@ private [probe] object NCProbeBoot extends LazyLogging with NCOpenCensusTrace {
*/
private [probe] def startEmbedded(
cfgFile: String,
- mdlClasses: Array[String],
+ mdlClasses: java.util.Collection[String],
fut: CompletableFuture[Integer]): Unit = {
checkStarted()
@@ -351,7 +352,7 @@ private [probe] object NCProbeBoot extends LazyLogging with NCOpenCensusTrace {
Some(
ConfigFactory.empty().withValue(
"nlpcraft.probe.models",
- fromAnyRef(mdlClasses.mkString(","))
+ fromAnyRef(mdlClasses.asScala.mkString(","))
)
)
)
@@ -449,7 +450,7 @@ private [probe] object NCProbeBoot extends LazyLogging with NCOpenCensusTrace {
tbl += (s"${B}Down-Link$RST", cfg.downLinkString)
tbl += (s"${B}Up-Link$RST", cfg.upLinkString)
tbl += (s"${B}Lifecycle$RST", cfg.lifecycle)
- tbl += (s"${B}Models (${cfg.modelsSeq.size})$RST" , cfg.modelsSeq)
+ tbl += (s"${B}Models (${cfg.modelsSeq.size})$RST", cfg.modelsSeq)
tbl += (s"${B}JARs Folder$RST", cfg.jarsFolder.getOrElse(""))
tbl.info(logger, Some("Probe Configuration:"))
diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/NCTestContext.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/NCTestContext.scala
index a48c934..8bb384b 100644
--- a/nlpcraft/src/test/scala/org/apache/nlpcraft/NCTestContext.scala
+++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/NCTestContext.scala
@@ -23,6 +23,8 @@ import org.apache.nlpcraft.probe.mgrs.model.NCModelManager
import org.junit.jupiter.api.TestInstance.Lifecycle
import org.junit.jupiter.api._
+import java.util.Collections
+
/**
*
*/
@@ -74,7 +76,7 @@ abstract class NCTestContext {
probeStarted = false
- if (NCEmbeddedProbe.start(null, ann.model().getName)) {
+ if (NCEmbeddedProbe.start(null, Collections.singletonList(ann.model().getName))) {
probeStarted = true
if (ann.startClient()) {
diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/dsl/NCDslSpec.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/dsl/NCDslSpec.scala
index 8dc75c5..8487dc5 100644
--- a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/dsl/NCDslSpec.scala
+++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/dsl/NCDslSpec.scala
@@ -18,13 +18,14 @@
package org.apache.nlpcraft.model.intent.dsl
import java.io.IOException
-
import org.apache.nlpcraft.common.NCException
import org.apache.nlpcraft.model.tools.embedded.NCEmbeddedProbe
import org.apache.nlpcraft.model.tools.test.{NCTestClient, NCTestClientBuilder}
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.{AfterEach, BeforeEach, Test}
+import java.util.Collections
+
/**
* DSL test model test. Make sure to start up the NLPCraft server before running this test.
*/
@@ -36,7 +37,7 @@ class NCDslSpec {
@throws[IOException]
private[dsl] def setUp(): Unit = {
// Start embedded probe with the test model.
- if (NCEmbeddedProbe.start(null, classOf[NCDslTestModel].getName)) {
+ if (NCEmbeddedProbe.start(null, Collections.singletonList(classOf[NCDslTestModel].getName))) {
cli = new NCTestClientBuilder().newBuilder.build
cli.open("nlpcraft.dsl.test")