This is an automated email from the ASF dual-hosted git repository.
aradzinski pushed a commit to branch NLPCRAFT-356
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git
The following commit(s) were added to refs/heads/NLPCRAFT-356 by this push:
new b36f012 WIP on NLPCRAFT-356.
b36f012 is described below
commit b36f0120830235683490c05ad802938cbabf4bb0
Author: Aaron Radzinski <[email protected]>
AuthorDate: Sat Jul 3 12:04:43 2021 -0700
WIP on NLPCRAFT-356.
---
.../nlpcraft/model/tools/cmdline/NCCli.scala | 81 ++++++++++++++--------
.../model/tools/cmdline/NCCliCommands.scala | 11 +--
.../tools/cmdline/NCCliModelClassCompleter.java | 23 +++---
.../cmdline/NCCliModelClassCompleterTest.scala | 48 +++++++++++++
4 files changed, 120 insertions(+), 43 deletions(-)
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 bcab344..c7bfb79 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
@@ -178,7 +178,7 @@ object NCCli extends NCCliBase {
*/
@throws[InvalidParameter]
private def getIntParam(cmd: Command, args: Seq[Argument], id: String,
dflt: Int): Int = {
- getParamOpt(cmd, args, id) match {
+ getParamOpt(args, id) match {
case Some(num) =>
try
Integer.parseInt(num)
@@ -200,7 +200,7 @@ object NCCli extends NCCliBase {
*/
@throws[InvalidParameter]
private def getDoubleParam(cmd: Command, args: Seq[Argument], id: String,
dflt: Double): Double = {
- getParamOpt(cmd, args, id) match {
+ getParamOpt(args, id) match {
case Some(num) =>
try
java.lang.Double.parseDouble(num)
@@ -213,11 +213,10 @@ object NCCli extends NCCliBase {
}
/**
- * @param cmd
* @param args
* @param id
*/
- private def getParamOpt(cmd: Command, args: Seq[Argument], id: String):
Option[String] =
+ private def getParamOpt(args: Seq[Argument], id: String): Option[String] =
args.find(_.parameter.id == id).flatMap(_.value)
/**
@@ -229,24 +228,45 @@ object NCCli extends NCCliBase {
args.exists(_.parameter.id == id)
/**
- * @param cmd
* @param args
* @param id
*/
- private def getParamOrNull(cmd: Command, args: Seq[Argument], id: String):
String =
+ private def getParamOrNull(args: Seq[Argument], id: String): String =
args.find(_.parameter.id == id) match {
case Some(arg) => U.trimQuotes(arg.value.get)
case None => null
}
/**
+ * @param args
+ * @param id
+ */
+ private def getParams(args: Seq[Argument], id: String): Seq[String] =
+ args.filter(_.parameter.id == id).map(arg =>
U.trimQuotes(arg.value.getOrElse("")))
+
+ /**
+ *
+ * @param args
+ * @return
+ */
+ private def getModelsParams(args: Seq[Argument]): String =
+ U.splitTrimFilter(getParams( args, "models").mkString(","),
",").mkString(",")
+
+ /**
+ *
+ * @param args
+ * @return
+ */
+ private def getCpParams(args: Seq[Argument]): String =
+ U.splitTrimFilter(getParams( args, "cp").mkString(CP_SEP),
CP_SEP).mkString(CP_SEP)
+
+ /**
*
- * @param cmd
* @param args
* @param id
* @return
*/
- private def getFlagParam(cmd: Command, args: Seq[Argument], id: String,
dflt: Boolean): Boolean =
+ private def getFlagParam(args: Seq[Argument], id: String, dflt: Boolean):
Boolean =
args.find(_.parameter.id == id) match {
case Some(_) => true
case None => dflt
@@ -268,7 +288,7 @@ object NCCli extends NCCliBase {
* @return
*/
private def getCpParamOpt(cmd: Command, args: Seq[Argument]): String =
- getParamOpt(cmd, args, "cp") match {
+ getParamOpt(args, "cp") match {
case Some(path) => normalizeCp(U.trimQuotes(path))
case None => null
}
@@ -289,7 +309,7 @@ object NCCli extends NCCliBase {
normPath
}
- getParamOpt(cmd, args, id) match {
+ getParamOpt(args, id) match {
case Some(path) => makePath(path)
case None => if (dflt == null) null else makePath(dflt)
}
@@ -381,9 +401,9 @@ object NCCli extends NCCliBase {
private [cmdline] def cmdStartServer(cmd: Command, args: Seq[Argument],
repl: Boolean): Unit = {
val cfgPath = getPathParam(cmd, args, "config")
val igniteCfgPath = getPathParam(cmd, args, "igniteConfig")
- val noWait = getFlagParam(cmd, args, "noWait", dflt = false)
+ val noWait = getFlagParam(args, "noWait", dflt = false)
val timeoutMins = getIntParam(cmd, args, "timeoutMins", 2)
- val jvmOpts = getParamOpt(cmd, args, "jvmopts") match {
+ val jvmOpts = getParamOpt(args, "jvmopts") match {
case Some(opts) => U.splitTrimFilter(U.trimQuotes(opts), " ")
case None => Seq("-ea", "-Xms2048m", "-XX:+UseG1GC")
}
@@ -576,8 +596,8 @@ object NCCli extends NCCliBase {
val cfgPath = getPathParam(cmd, args, "config")
val addCp = getCpParam(cmd, args)
- val mdls = getParamOrNull(cmd, args, "models")
- val jvmOpts = getParamOpt(cmd, args, "jvmopts") match {
+ val mdls = getModelsParams(args)
+ val jvmOpts = getParamOpt(args, "jvmopts") match {
case Some(opts) => U.splitTrimFilter(U.trimQuotes(opts), " ")
case None => Seq("-ea", "-Xms1024m")
}
@@ -593,7 +613,7 @@ object NCCli extends NCCliBase {
if (cfgPath != null)
jvmArgs += s"-DNLPCRAFT_PROBE_CONFIG=$cfgPath"
- if (mdls != null)
+ if (mdls.nonEmpty)
jvmArgs += s"-DNLPCRAFT_TEST_MODELS=$mdls"
if (!NCAnsi.isEnabled)
@@ -684,11 +704,11 @@ object NCCli extends NCCliBase {
}
val cfgPath = getPathParam(cmd, args, "config")
- val noWait = getFlagParam(cmd, args, "noWait", dflt = false)
+ val noWait = getFlagParam(args, "noWait", dflt = false)
val addCp = getCpParam(cmd, args)
val timeoutMins = getIntParam(cmd, args, "timeoutMins", 1)
- val mdls = getParamOrNull(cmd, args, "models")
- val jvmOpts = getParamOpt(cmd, args, "jvmopts") match {
+ val mdls = getModelsParams(args)
+ val jvmOpts = getParamOpt(args, "jvmopts") match {
case Some(opts) => U.splitTrimFilter(U.trimQuotes(opts), " ")
case None => Seq("-ea", "-Xms1024m")
}
@@ -711,7 +731,7 @@ object NCCli extends NCCliBase {
prbArgs += "-DNLPCRAFT_ANSI_COLOR_DISABLED=true" // No ANSI colors for
text log output to the file.
- if (mdls != null)
+ if (mdls.nonEmpty)
prbArgs += "-Dconfig.override_with_env_vars=true"
prbArgs += "-cp"
@@ -724,7 +744,8 @@ object NCCli extends NCCliBase {
val prbPb = new ProcessBuilder(prbArgs.asJava)
- if (mdls != null)
+ if (mdls.nonEmpty)
+ // Combine multiple '--mdls' parameter into one comma-separate
string.
prbPb.environment().put("CONFIG_FORCE_nlpcraft_probe_models", mdls)
prbPb.directory(new File(USR_WORK_DIR))
@@ -746,7 +767,7 @@ object NCCli extends NCCliBase {
logln(s" ${y("|--")} Log: ${c(output.getAbsolutePath)}")
logln(s" ${y("|--")} Probe config: ${if (cfgPath == null)
y("<default>") else c(cfgPath)}")
- if (mdls != null)
+ if (mdls.nonEmpty)
logln(s" ${y("|--")} Environment variables: \n
${c("CONFIG_FORCE_nlpcraft_probe_models=")}${c(mdls)}")
logln(s" ${y("+--")} Command: \n ${c(prbArgs.mkString("\n
"))}")
@@ -1680,7 +1701,7 @@ object NCCli extends NCCliBase {
}
val addCp = getCpParamOpt(cmd, args)
- val jvmOpts = getParamOpt(cmd, args, "jvmopts") match {
+ val jvmOpts = getParamOpt(args, "jvmopts") match {
case Some(opts) => U.splitTrimFilter(U.trimQuotes(opts), " ")
case None => Seq("-ea", "-Xms1024m")
}
@@ -1738,7 +1759,7 @@ object NCCli extends NCCliBase {
private [cmdline] def cmdSugSyn(cmd: Command, args: Seq[Argument], repl:
Boolean): Unit =
state.accessToken match {
case Some(acsTok) =>
- val mdlId = getParamOpt(cmd, args, "mdlId") match {
+ val mdlId = getParamOpt(args, "mdlId") match {
case Some(id) => id
case None =>
if (state.probes.size == 1 &&
state.probes.head.models.length == 1)
@@ -1772,7 +1793,7 @@ object NCCli extends NCCliBase {
private [cmdline] def cmdAsk(cmd: Command, args: Seq[Argument], repl:
Boolean): Unit =
state.accessToken match {
case Some(acsTok) =>
- val mdlId = getParamOpt(cmd, args, "mdlId") match {
+ val mdlId = getParamOpt(args, "mdlId") match {
case Some(id) => id
case None =>
if (state.probes.size == 1 &&
state.probes.head.models.length == 1)
@@ -1781,8 +1802,8 @@ object NCCli extends NCCliBase {
throw MissingOptionalParameter(cmd, "mdlId")
}
val txt = getParam(cmd, args, "txt")
- val data = getParamOrNull(cmd, args, "data")
- val enableLog = getFlagParam(cmd, args, "enableLog", dflt =
false)
+ val data = getParamOrNull(args, "data")
+ val enableLog = getFlagParam(args, "enableLog", dflt = false)
httpRest(
cmd,
@@ -2002,7 +2023,7 @@ object NCCli extends NCCliBase {
*/
private [cmdline] def cmdGenModel(cmd: Command, args: Seq[Argument], repl:
Boolean): Unit = {
val filePath = replacePathTilda(getParam(cmd, args, "filePath"))
- val overrideFlag = getFlagParam(cmd, args, "override", dflt = false)
+ val overrideFlag = getFlagParam(args, "override", dflt = false)
val mdlId = getParam(cmd, args, "modelId")
val out = new File(filePath)
@@ -2055,7 +2076,7 @@ object NCCli extends NCCliBase {
val buildTool = getParam(cmd, args, "buildTool", "mvn").toLowerCase
val pkgName = getParam(cmd, args, "packageName",
"org.apache.nlpcraft.demo").toLowerCase
val fileType = getParam(cmd, args, "modelType", "yaml").toLowerCase
- val overrideFlag = getFlagParam(cmd, args, "override", dflt = false)
+ val overrideFlag = getFlagParam(args, "override", dflt = false)
val dst = new File(outputDir, baseName)
val pkgDir = pkgName.replaceAll("\\.", "/")
@@ -2747,8 +2768,8 @@ object NCCli extends NCCliBase {
* @param repl Whether or not executing from REPL.
*/
private [cmdline] def cmdVersion(cmd: Command, args: Seq[Argument], repl:
Boolean): Unit = {
- val isS = getFlagParam(cmd, args, "semver", dflt = false)
- val isD = getFlagParam(cmd, args, "reldate", dflt = false)
+ val isS = getFlagParam(args, "semver", dflt = false)
+ val isD = getFlagParam(args, "reldate", dflt = false)
if (!isS && !isD)
logln((
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
index c9e1486..ed88e0a 100644
---
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
@@ -762,13 +762,14 @@ private [cmdline] object NCCliCommands {
Parameter(
id = "models",
names = Seq("--mdls", "-m"),
- value = Some("<model list>"),
+ value = Some("my.Model1,my.Model2"),
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 ${c("--cfg")} parameter. Note
that you also must provide the additional " +
- s"classpath in this case via ${c("--cp")} parameter."
+ s"classpath in this case via ${c("--cp")} parameter.
Note also that you can have multiple '${c("--mdls")} " +
+ s"parameters - each specifying one or more model class
names - and they will be automatically combined together."
),
Parameter(
id = "jvmopts",
@@ -872,12 +873,14 @@ private [cmdline] object NCCliCommands {
Parameter(
id = "models",
names = Seq("--mdls", "-m"),
- value = Some("<model list>"),
+ value = Some("my.Model1,my.Model2"),
optional = true,
desc =
s"Comma separated list of fully qualified class names
for models to deploy and test. Note that you also " +
s"must provide the additional classpath via
${c("--cp")} parameter. If not provided, the models " +
- s"specified in configuration file (${c("--cfg")}
parameter) will be used instead."
+ s"specified in configuration file (${c("--cfg")}
parameter) will be used instead. Note that " +
+ s"you can have multiple '${c("--mdls")} parameters -
each specifying one or more model class " +
+ s"names - and they will be automatically combined
together."
),
Parameter(
id = "jvmopts",
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCliModelClassCompleter.java
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCliModelClassCompleter.java
index 6e6db2b..497c360 100644
---
a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCliModelClassCompleter.java
+++
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCliModelClassCompleter.java
@@ -37,8 +37,8 @@ class NCCliModelClassCompleter {
* @return Set of class names from the given JAR file.
* @throws IOException Thrown in case of any I/O errors.
*/
- private Set<String> getClassNamesFromJar(String jarPath) throws
IOException {
- assert jarPath != null && jarPath.toLowerCase().endsWith(".jar");
+ private Set<String> getClassNamesFromJar(File jarPath) throws IOException {
+ assert jarPath != null &&
jarPath.getAbsolutePath().toLowerCase().endsWith(".jar");
Set<String> classNames = new HashSet<>();
@@ -65,10 +65,10 @@ class NCCliModelClassCompleter {
* @return Set of model class name for the given classpath.
* @throws IOException Thrown in case of any I/O errors.
*/
- public Set<String> getModelClassNamesFromClasspath(List<String> cp) throws
IOException, ClassNotFoundException {
+ public Set<String> getModelClassNamesFromClasspath(List<String> cp) throws
IOException {
Set<URL> urls = cp.stream().map(entry -> {
try {
- return new URL("jar:file" + entry + "!/");
+ return new URL("jar:file:" + entry + "!/");
}
catch (MalformedURLException e) {
return null;
@@ -84,13 +84,18 @@ class NCCliModelClassCompleter {
try (URLClassLoader clsLdr = URLClassLoader.newInstance(urlsArr)) {
for (String cpEntry : cp) {
try {
- Set<String> classNames = getClassNamesFromJar(cpEntry);
+ Set<String> classNames = getClassNamesFromJar(new
File(cpEntry));
for (String name : classNames) {
- Class<?> clazz = clsLdr.loadClass(name);
-
- if (NCModel.class.isAssignableFrom(clazz))
- mdlClasses.add(clazz.getName());
+ try {
+ Class<?> clazz = clsLdr.loadClass(name);
+
+ if (NCModel.class.isAssignableFrom(clazz))
+ mdlClasses.add(clazz.getName());
+ }
+ catch (Throwable e) {
+ // Ignoring.
+ }
}
}
catch (Exception e) {
diff --git
a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/tools/cmdline/NCCliModelClassCompleterTest.scala
b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/tools/cmdline/NCCliModelClassCompleterTest.scala
new file mode 100644
index 0000000..6061df4
--- /dev/null
+++
b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/tools/cmdline/NCCliModelClassCompleterTest.scala
@@ -0,0 +1,48 @@
+/*
+ * 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
+ *
+ * https://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.nlpcraft.common.version.NCVersion
+import org.junit.jupiter.api.Test
+
+import java.util
+import scala.jdk.CollectionConverters.SetHasAsScala
+
+/**
+ * Unit test for the classpath completer. Note that working directory must be
set
+ * properly for this test to work.
+ */
+class NCCliModelClassCompleterTest {
+ @Test
+ def testClasspathCompleter(): Unit = {
+ val cp = new util.ArrayList[String]()
+ val completer = new NCCliModelClassCompleter()
+ val ver = NCVersion.getCurrent.version
+
+ // NOTE: make sure to properly set the current working directory for
the runtime configuration
+ // when running this test.
+
cp.add(s".\\nlpcraft-examples\\lightswitch\\target\\nlpcraft-example-lightswitch-$ver.jar")
+
cp.add(s".\\nlpcraft-examples\\alarm\\target\\nlpcraft-example-alarm-$ver.jar")
+
cp.add(s".\\nlpcraft-examples\\weather\\target\\nlpcraft-example-weather-$ver.jar")
+
cp.add(s".\\nlpcraft-examples\\time\\target\\nlpcraft-example-time-$ver.jar")
+
+ val mdlClasses = completer.getModelClassNamesFromClasspath(cp).asScala
+
+ mdlClasses.foreach(println)
+ }
+}