This is an automated email from the ASF dual-hosted git repository.
sergeykamov 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 78eea74 REST requests metadata processing changed.
78eea74 is described below
commit 78eea74a8d41c0da476a373e19393aa67412fbca
Author: Sergey Kamov <[email protected]>
AuthorDate: Mon May 17 23:52:30 2021 +0300
REST requests metadata processing changed.
---
nlpcraft/src/main/resources/sql/create_schema.sql | 27 +-
nlpcraft/src/main/resources/sql/drop_schema.sql | 2 -
.../org/apache/nlpcraft/common/util/NCUtils.scala | 40 ++-
.../model/intent/compiler/NCIdlCompiler.scala | 1 -
.../model/tools/embedded/NCEmbeddedResult.java | 9 +-
.../model/tools/test/NCTestClientBuilder.java | 32 ++-
.../nlpcraft/model/tools/test/NCTestResult.java | 12 +-
.../probe/mgrs/nlp/NCProbeEnrichmentManager.scala | 15 +-
.../probe/mgrs/nlp/impl/NCRequestImpl.scala | 15 +-
.../nlpcraft/server/company/NCCompanyManager.scala | 22 +-
.../apache/nlpcraft/server/mdo/NCCompanyMdo.scala | 1 +
.../nlpcraft/server/mdo/NCCompanyPropertyMdo.scala | 41 ---
.../nlpcraft/server/mdo/NCQueryStateMdo.scala | 4 +-
.../org/apache/nlpcraft/server/mdo/NCUserMdo.scala | 7 +-
.../nlpcraft/server/mdo/NCUserPropertyMdo.scala | 41 ---
.../nlpcraft/server/probe/NCProbeManager.scala | 28 +-
.../server/proclog/NCProcessLogManager.scala | 3 +
.../nlpcraft/server/query/NCQueryManager.scala | 29 ++-
.../nlpcraft/server/rest/NCBasicRestApi.scala | 190 ++++++++------
.../apache/nlpcraft/server/sql/NCSqlManager.scala | 283 ++++++++-------------
.../nlpcraft/server/user/NCUserManager.scala | 22 +-
.../main/scala/org/apache/nlpcraft/utils/README.md | 2 -
.../nlpcraft/model/meta/NCMetaResultSpec.scala | 77 ++++++
.../nlpcraft/server/rest/NCRestAskSpec.scala | 16 ++
.../apache/nlpcraft/server/rest/NCRestSpec.scala | 3 +
.../nlpcraft/server/rest/RestTestModel.scala | 39 ++-
openapi/nlpcraft_swagger.yml | 17 +-
sql/mysql/drop_schema.sql | 2 -
sql/mysql/schema.sql | 29 +--
sql/oracle/drop_schema.sql | 16 --
sql/oracle/schema.sql | 33 +--
sql/postgres/drop_schema.sql | 2 -
sql/postgres/schema.sql | 33 +--
33 files changed, 506 insertions(+), 587 deletions(-)
diff --git a/nlpcraft/src/main/resources/sql/create_schema.sql
b/nlpcraft/src/main/resources/sql/create_schema.sql
index 570e215..1965ca0 100644
--- a/nlpcraft/src/main/resources/sql/create_schema.sql
+++ b/nlpcraft/src/main/resources/sql/create_schema.sql
@@ -30,6 +30,7 @@ CREATE TABLE nc_company (
postal_code VARCHAR,
auth_token VARCHAR NOT NULL, -- Unique.
auth_token_hash VARCHAR NOT NULL, -- Unique.
+ properties_gzip VARCHAR NULL,
created_on TIMESTAMP NOT NULL,
last_modified_on TIMESTAMP NOT NULL
) WITH "template=replicated, atomicity=transactional";
@@ -38,18 +39,6 @@ CREATE INDEX nc_company_idx_1 ON nc_company(name);
CREATE INDEX nc_company_idx_2 ON nc_company(auth_token);
CREATE INDEX nc_company_idx_3 ON nc_company(auth_token_hash);
-DROP TABLE IF EXISTS nc_company_property;
-CREATE TABLE nc_company_property (
- id LONG PRIMARY KEY,
- company_id LONG NOT NULL, -- Foreign key nc_company.id.
- property VARCHAR NOT NULL,
- value VARCHAR NULL,
- created_on TIMESTAMP NOT NULL,
- last_modified_on TIMESTAMP NOT NULL
-) WITH "template=replicated, atomicity=transactional";
-
-CREATE INDEX nc_company_property_idx_1 ON nc_company_property(company_id);
-
DROP TABLE IF EXISTS nc_user;
CREATE TABLE nc_user (
id LONG PRIMARY KEY,
@@ -61,6 +50,7 @@ CREATE TABLE nc_user (
last_name VARCHAR NULL,
is_admin BOOL NOT NULL,
passwd_salt VARCHAR NULL,
+ properties_gzip VARCHAR NULL,
created_on TIMESTAMP NOT NULL,
last_modified_on TIMESTAMP NOT NULL
) WITH "template=replicated, atomicity=transactional";
@@ -69,18 +59,6 @@ CREATE INDEX nc_user_idx_1 ON nc_user(email);
CREATE INDEX nc_user_idx_2 ON nc_user(company_id, ext_id);
CREATE INDEX nc_user_idx_3 ON nc_user(company_id);
-DROP TABLE IF EXISTS nc_user_property;
-CREATE TABLE nc_user_property (
- id LONG PRIMARY KEY,
- user_id LONG NOT NULL, -- Foreign key nc_user.id.
- property VARCHAR NOT NULL,
- value VARCHAR NULL,
- created_on TIMESTAMP NOT NULL,
- last_modified_on TIMESTAMP NOT NULL
-) WITH "template=replicated, atomicity=transactional";
-
-CREATE INDEX nc_user_property_idx_1 ON nc_user_property(user_id);
-
DROP TABLE IF EXISTS passwd_pool;
CREATE TABLE passwd_pool (
id LONG PRIMARY KEY,
@@ -103,6 +81,7 @@ CREATE TABLE proc_log (
cancel_tstamp TIMESTAMP NULL,
res_type VARCHAR NULL,
res_body_gzip VARCHAR NULL,
+ res_meta_gzip VARCHAR NULL,
intent_id VARCHAR NULL,
error VARCHAR NULL,
probe_token VARCHAR NULL,
diff --git a/nlpcraft/src/main/resources/sql/drop_schema.sql
b/nlpcraft/src/main/resources/sql/drop_schema.sql
index b1ce0b9..f985bae 100644
--- a/nlpcraft/src/main/resources/sql/drop_schema.sql
+++ b/nlpcraft/src/main/resources/sql/drop_schema.sql
@@ -16,9 +16,7 @@
--
DROP TABLE IF EXISTS proc_log;
-DROP TABLE IF EXISTS nc_user_property;
DROP TABLE IF EXISTS nc_user;
-DROP TABLE IF EXISTS nc_company_property;
DROP TABLE IF EXISTS nc_company;
DROP TABLE IF EXISTS passwd_pool;
DROP TABLE IF EXISTS feedback;
\ No newline at end of file
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/common/util/NCUtils.scala
b/nlpcraft/src/main/scala/org/apache/nlpcraft/common/util/NCUtils.scala
index 0248b56..4e2e7bd 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/common/util/NCUtils.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/common/util/NCUtils.scala
@@ -1149,14 +1149,20 @@ object NCUtils extends LazyLogging {
* @param rawStr String to compress.
* @return Compressed Base64-encoded string.
*/
+ @throws[NCE]
def compress(rawStr: String): String = {
val arr = new ByteArrayOutputStream(1024)
- managed(new GOS(arr)) acquireAndGet { zip ⇒
- zip.write(rawStr.getBytes)
- }
+ try {
+ managed(new GOS(arr)) acquireAndGet { zip ⇒
+ zip.write(rawStr.getBytes)
+ }
- Base64.encodeBase64String(arr.toByteArray)
+ Base64.encodeBase64String(arr.toByteArray)
+ }
+ catch {
+ case e: Exception ⇒ throw new NCE("Error during data
compression.", e)
+ }
}
/**
@@ -1165,8 +1171,13 @@ object NCUtils extends LazyLogging {
* @param zipStr Compressed string.
* @return Uncompressed string.
*/
+ @throws[NCE]
def uncompress(zipStr: String): String =
- IOUtils.toString(new GIS(new
ByteArrayInputStream(Base64.decodeBase64(zipStr))), Charset.defaultCharset())
+ try
+ IOUtils.toString(new GIS(new
ByteArrayInputStream(Base64.decodeBase64(zipStr))), Charset.defaultCharset())
+ catch {
+ case e: Exception ⇒ throw new NCE("Error during data
decompression.", e)
+ }
/**
* Sleeps number of milliseconds properly handling exceptions.
@@ -1672,6 +1683,7 @@ object NCUtils extends LazyLogging {
* @param json JSON to convert.
* @return
*/
+ @throws[Exception]
def jsonToScalaMap(json: String): Map[String, Object] =
GSON.fromJson(json, classOf[java.util.HashMap[String,
Object]]).asScala.toMap
@@ -1681,8 +1693,14 @@ object NCUtils extends LazyLogging {
* @param json JSON to convert.
* @return
*/
- def jsonToJavaMap(json: String): java.util.Map[String, Object] =
- GSON.fromJson(json, classOf[java.util.HashMap[String, Object]])
+ @throws[NCE]
+ def jsonToJavaMap(json: String): java.util.Map[String, Object] = {
+ try
+ GSON.fromJson(json, classOf[java.util.HashMap[String, Object]])
+ catch {
+ case e: Exception ⇒ throw new NCE(s"Cannot deserialize JSON to
map: '$json'", e)
+ }
+ }
/**
*
@@ -1690,9 +1708,13 @@ object NCUtils extends LazyLogging {
* @param field
* @return
*/
- @throws[Exception]
+ @throws[NCE]
def getJsonBooleanField(json: String, field: String): Boolean =
-
GSON.getAdapter(classOf[JsonElement]).fromJson(json).getAsJsonObject.get(field).getAsBoolean
+ try
+
GSON.getAdapter(classOf[JsonElement]).fromJson(json).getAsJsonObject.get(field).getAsBoolean
+ catch {
+ case e: Exception ⇒ throw new NCE(s"Cannot deserialize JSON to
map: '$json'", e)
+ }
/**
*
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCIdlCompiler.scala
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCIdlCompiler.scala
index 3e9f737..50c4959 100644
---
a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCIdlCompiler.scala
+++
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCIdlCompiler.scala
@@ -86,7 +86,6 @@ object NCIdlCompiler extends LazyLogging {
// List of instructions for the current expression.
private var expr = mutable.Buffer.empty[SI]
-
/**
*
* @return
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/embedded/NCEmbeddedResult.java
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/embedded/NCEmbeddedResult.java
index 3ece971..e18d2f6 100644
---
a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/embedded/NCEmbeddedResult.java
+++
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/embedded/NCEmbeddedResult.java
@@ -18,6 +18,7 @@
package org.apache.nlpcraft.model.tools.embedded;
import org.apache.nlpcraft.model.*;
+
import java.util.function.*;
/**
@@ -30,7 +31,7 @@ import java.util.function.*;
* @see NCResult
* @see NCEmbeddedProbe
*/
-public interface NCEmbeddedResult {
+public interface NCEmbeddedResult extends NCMetadata {
/**
* Gets the ID of the model that produced this result. Note that embedded
probe can host more than one
* data model hence this parameter is important to distinguish to which
model this result belongs.
@@ -173,11 +174,11 @@ public interface NCEmbeddedResult {
String getProbeId();
/**
- * Gets request processing log holder as JSON string.
+ * Gets request processing log as JSON string.
*
- * @return Request processing log holder as JSON string.
+ * @return Request processing log as JSON string.
*/
- String getLogHolderJson();
+ String getLogJson();
/**
* Gets ID of the intent that was matched against the input sentence. Only
set if result was
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/test/NCTestClientBuilder.java
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/test/NCTestClientBuilder.java
index df39787..434a773 100644
---
a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/test/NCTestClientBuilder.java
+++
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/test/NCTestClientBuilder.java
@@ -192,6 +192,7 @@ public class NCTestClientBuilder {
@SerializedName("usrId") private long userId;
@SerializedName("resType") private String resType;
@SerializedName("resBody") private Object resBody;
+ @SerializedName("resMeta") private Map<String, Object> resMeta;
@SerializedName("status") private String status;
@SerializedName("error") private String error;
@SerializedName("createTstamp") private long createTstamp;
@@ -288,6 +289,22 @@ public class NCTestClientBuilder {
/**
*
+ * @return
+ */
+ public Map<String, Object> getResultMeta() {
+ return resMeta;
+ }
+
+ /**
+ *
+ * @param resMeta
+ */
+ public void setResultMeta(Map<String, Object> resMeta) {
+ this.resMeta = resMeta;
+ }
+
+ /**
+ *
* @param resBody
*/
public void setResultBody(String resBody) {
@@ -557,7 +574,7 @@ public class NCTestClientBuilder {
e.getLocalizedMessage()
);
- return mkResult(txt, mdlId, null, null,
e.getLocalizedMessage(), null, 0);
+ return mkResult(txt, mdlId, null, null, null,
e.getLocalizedMessage(), null, 0);
}
NCRequestStateJson state = resJs.getState();
@@ -573,6 +590,7 @@ public class NCTestClientBuilder {
gson.toJson(state.getResultBody()) :
(String)state.getResultBody() :
null,
+ state.getResultMeta(),
state.getError(),
state.getIntentId(),
System.currentTimeMillis() - now
@@ -600,7 +618,7 @@ public class NCTestClientBuilder {
e.getLocalizedMessage()
);
- return mkResult(txt, mdlId, null, null,
e.getLocalizedMessage(), null,0);
+ return mkResult(txt, mdlId, null, null, null,
e.getLocalizedMessage(), null,0);
}
long maxTime = System.currentTimeMillis() + DFLT_MAX_WAIT_TIME;
@@ -637,6 +655,7 @@ public class NCTestClientBuilder {
res.getBody() != null ?
"json".equals(res.getType()) ?
gson.toJson(res.getBody()) : res.getBody() :
null,
+ res.getMetadata(),
res.getErrorMessage(),
res.getIntentId(),
System.currentTimeMillis() - now
@@ -1007,6 +1026,7 @@ public class NCTestClientBuilder {
* @param mdlId Model ID.
* @param resType
* @param resBody
+ * @param resMeta
* @param errMsg
* @param intentId
* @param time
@@ -1017,6 +1037,7 @@ public class NCTestClientBuilder {
String mdlId,
String resType,
String resBody,
+ Map<String, Object> resMeta,
String errMsg,
String intentId,
long time
@@ -1026,7 +1047,7 @@ public class NCTestClientBuilder {
assert (resType != null && resBody != null) ^ errMsg != null;
return new NCTestResult() {
- private Optional<String> convert(String s) {
+ private<T> Optional<T> convert(T s) {
return s == null ? Optional.empty() : Optional.of(s);
}
@@ -1064,6 +1085,11 @@ public class NCTestClientBuilder {
public String getIntentId() {
return intentId;
}
+
+ @Override
+ public Optional<Map<String, Object>> getResultMeta() {
+ return convert(resMeta);
+ }
};
}
}
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/test/NCTestResult.java
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/test/NCTestResult.java
index 44157be..130388b 100644
---
a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/test/NCTestResult.java
+++
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/test/NCTestResult.java
@@ -17,6 +17,7 @@
package org.apache.nlpcraft.model.tools.test;
+import java.util.Map;
import java.util.Optional;
/**
@@ -61,7 +62,16 @@ public interface NCTestResult {
* @see #isOk()
*/
Optional<String> getResultType();
-
+
+ /**
+ * Gets optional execution result metadata. Only provided if processing
succeeded.
+ *
+ * @return Optional execution result metadata.
+ * @see #isFailed()
+ * @see #isOk()
+ */
+ Optional<Map<String, Object>> getResultMeta();
+
/**
* Gets optional execution error. Only provided if processing failed.
*
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/NCProbeEnrichmentManager.scala
b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/NCProbeEnrichmentManager.scala
index 398d1c2..c0c7a21 100644
---
a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/NCProbeEnrichmentManager.scala
+++
b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/NCProbeEnrichmentManager.scala
@@ -275,6 +275,7 @@ object NCProbeEnrichmentManager extends NCService with
NCOpenCensusModelStats {
*
* @param resType Result type.
* @param resBody Result body.
+ * @param resMeta Result meta.
* @param errMsg Error message.
* @param errCode Error code.
* @param msgName Message name.
@@ -284,6 +285,7 @@ object NCProbeEnrichmentManager extends NCService with
NCOpenCensusModelStats {
def respond(
resType: Option[String],
resBody: Option[String],
+ resMeta: Option[JavaMeta],
errMsg: Option[String],
errCode: Option[Int],
msgName: String,
@@ -302,6 +304,10 @@ object NCProbeEnrichmentManager extends NCService with
NCOpenCensusModelStats {
if (vOpt.isDefined)
msg += name → vOpt.get
+ def addMeta(name: String, vOpt: Option[JavaMeta]): Unit =
+ if (vOpt.isDefined)
+ msg += name → vOpt.get.asInstanceOf[Serializable]
+
if (resBody.isDefined && resBody.get.length >
Config.resultMaxSize) {
addOptional("error", Some("Result is too big. Model result
must be corrected."))
addOptional("errorCode", Some(RESULT_TOO_BIG))
@@ -311,6 +317,7 @@ object NCProbeEnrichmentManager extends NCService with
NCOpenCensusModelStats {
addOptional("errorCode", errCode.map(Integer.valueOf))
addOptional("resType", resType)
addOptional("resBody", resBody)
+ addMeta("resMeta", resMeta)
addOptional("log", log)
addOptional("intentId", intentId)
}
@@ -322,11 +329,12 @@ object NCProbeEnrichmentManager extends NCService with
NCOpenCensusModelStats {
override val getOriginalText: String = txt
override val getUserId: Long = usrId
override val getBody: String =
msg.dataOpt[String]("resBody").orNull
+ override val getMetadata: JavaMeta =
msg.dataOpt[JavaMeta]("resMeta").orNull
override val getType: String =
msg.dataOpt[String]("resType").orNull
override val getErrorMessage: String =
msg.dataOpt[String]("error").orNull
override val getErrorCode: Int =
msg.dataOpt[Int]("errorCode").getOrElse(0)
override def getProbeId: String = Config.id
- override def getLogHolderJson: String = log.orNull
+ override def getLogJson: String = log.orNull
override def getIntentId: String = intentId.orNull
}
@@ -394,6 +402,7 @@ object NCProbeEnrichmentManager extends NCService with
NCOpenCensusModelStats {
respond(
None,
None,
+ None,
Some(errMsg),
Some(errCode),
"P2S_ASK_RESULT",
@@ -531,6 +540,7 @@ object NCProbeEnrichmentManager extends NCService with
NCOpenCensusModelStats {
respond(
None,
None,
+ None,
Some(errMsg),
Some(errCode),
"P2S_ASK_RESULT",
@@ -621,6 +631,7 @@ object NCProbeEnrichmentManager extends NCService with
NCOpenCensusModelStats {
def respondWithResult(res: NCResult, log: Option[String]): Unit =
respond(
Some(res.getType),
Some(res.getBody),
+ Some(res.getMetadata),
None,
None,
"P2S_ASK_RESULT",
@@ -693,6 +704,7 @@ object NCProbeEnrichmentManager extends NCService with
NCOpenCensusModelStats {
respond(
None,
None,
+ None,
Some(e.getMessage), // User provided rejection
message.
Some(MODEL_REJECTION),
"P2S_ASK_RESULT",
@@ -722,6 +734,7 @@ object NCProbeEnrichmentManager extends NCService with
NCOpenCensusModelStats {
respond(
None,
None,
+ None,
Some("Processing failed with unexpected
error."), // System error message.
Some(UNEXPECTED_ERROR),
"P2S_ASK_RESULT",
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/impl/NCRequestImpl.scala
b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/impl/NCRequestImpl.scala
index d828961..394a96e 100644
---
a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/impl/NCRequestImpl.scala
+++
b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/impl/NCRequestImpl.scala
@@ -17,14 +17,13 @@
package org.apache.nlpcraft.probe.mgrs.nlp.impl
-import java.util.{Collections, Optional}
import org.apache.nlpcraft.common._
import org.apache.nlpcraft.model._
import org.apache.nlpcraft.model.impl._
-import java.util
-import scala.collection._
+import java.util.{Collections, Optional}
import scala.collection.JavaConverters._
+import scala.collection._
import scala.compat.java8.OptionConverters._
/**
@@ -55,7 +54,7 @@ case class NCRequestImpl(nlpMeta: Map[String, Any], srvReqId:
String) extends NC
getOpt("COMPANY_CITY"),
getOpt("COMPANY_ADDRESS"),
getOpt("COMPANY_POSTAL"),
- getMap("COMPANY_META")
+ getOpt("COMPANY_META").orElse(Collections.emptyMap())
)
override lazy val getUser: NCUser = new NCUserImpl(
nlpMeta("USER_ID").asInstanceOf[Long],
@@ -63,7 +62,7 @@ case class NCRequestImpl(nlpMeta: Map[String, Any], srvReqId:
String) extends NC
getOpt("LAST_NAME"),
getOpt("EMAIL"),
getOpt("AVATAR_URL"),
- getMap("META"),
+ getOpt("META").orElse(Collections.emptyMap()),
nlpMeta("IS_ADMIN").asInstanceOf[Boolean],
nlpMeta("SIGNUP_TSTAMP").asInstanceOf[Long]
)
@@ -73,10 +72,4 @@ case class NCRequestImpl(nlpMeta: Map[String, Any],
srvReqId: String) extends NC
case Some(v) ⇒ Optional.of(v.asInstanceOf[T])
case None ⇒ Optional.empty()
}
-
- private def getMap(key: String): util.Map[String, AnyRef] = {
- val m: Optional[JavaMeta] = getOpt(key)
-
- if (m.isPresent) m.get() else Collections.emptyMap()
- }
}
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/company/NCCompanyManager.scala
b/nlpcraft/src/main/scala/org/apache/nlpcraft/server/company/NCCompanyManager.scala
index 41a6444..0e3937f 100644
---
a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/company/NCCompanyManager.scala
+++
b/nlpcraft/src/main/scala/org/apache/nlpcraft/server/company/NCCompanyManager.scala
@@ -21,7 +21,7 @@ import io.opencensus.trace.Span
import org.apache.ignite.{IgniteAtomicSequence, IgniteSemaphore}
import org.apache.nlpcraft.common.{NCService, _}
import org.apache.nlpcraft.server.ignite.NCIgniteInstance
-import org.apache.nlpcraft.server.mdo.{NCCompanyMdo, NCCompanyPropertyMdo}
+import org.apache.nlpcraft.server.mdo.NCCompanyMdo
import org.apache.nlpcraft.server.sql.{NCSql, NCSqlManager}
import org.apache.nlpcraft.server.user.NCUserManager
@@ -168,7 +168,7 @@ object NCCompanyManager extends NCService with
NCIgniteInstance {
city: Option[String],
address: Option[String],
postalCode: Option[String],
- props: Option[Map[String, String]],
+ props: Option[String],
parent: Span = null
): Unit =
startScopedSpan("updateCompany", parent, "id" → id) { span ⇒
@@ -282,7 +282,7 @@ object NCCompanyManager extends NCService with
NCIgniteInstance {
adminFirstName: String,
adminLastName: String,
adminAvatarUrl: Option[String],
- props: Option[Map[String, String]],
+ props: Option[String],
mkToken: () ⇒ String,
parent: Span = null
): NCCompanyCreationData = {
@@ -371,7 +371,7 @@ object NCCompanyManager extends NCService with
NCIgniteInstance {
adminFirstName: String,
adminLastName: String,
adminAvatarUrl: Option[String],
- props: Option[Map[String, String]],
+ props: Option[String],
parent: Span = null
): NCCompanyCreationData = startScopedSpan("addCompany", parent, "name" →
name) { _ ⇒
addCompany0(
@@ -391,18 +391,4 @@ object NCCompanyManager extends NCService with
NCIgniteInstance {
() ⇒ mkToken()
)
}
-
- /**
- * Gets company properties for given company ID.
- *
- * @param id User ID.
- * @param parent Optional parent span.
- */
- @throws[NCE]
- def getCompanyProperties(id: Long, parent: Span = null):
Seq[NCCompanyPropertyMdo] =
- startScopedSpan("getCompanyProperties", parent, "companyId" → id) {
span ⇒
- NCSql.sql {
- NCSqlManager.getCompanyProperties(id, span)
- }
- }
}
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/mdo/NCCompanyMdo.scala
b/nlpcraft/src/main/scala/org/apache/nlpcraft/server/mdo/NCCompanyMdo.scala
index c4aa5a8..2405bf2 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/mdo/NCCompanyMdo.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/server/mdo/NCCompanyMdo.scala
@@ -37,6 +37,7 @@ case class NCCompanyMdo(
@NCMdoField(column = "postal_code") postalCode: Option[String],
@NCMdoField(column = "auth_token") authToken: String,
@NCMdoField(column = "auth_token_hash") authTokenHash: String,
+ @NCMdoField(column = "properties_gzip") propertiesGzip: Option[String],
@NCMdoField(column = "created_on") createdOn: Timestamp,
@NCMdoField(column = "last_modified_on") lastModifiedOn: Timestamp
) extends NCAnnotatedMdo[NCCompanyMdo]
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/mdo/NCCompanyPropertyMdo.scala
b/nlpcraft/src/main/scala/org/apache/nlpcraft/server/mdo/NCCompanyPropertyMdo.scala
deleted file mode 100644
index 695a41c..0000000
---
a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/mdo/NCCompanyPropertyMdo.scala
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.server.mdo
-
-import org.apache.nlpcraft.server.mdo.impl._
-import org.apache.nlpcraft.server.sql.NCSql.Implicits.RsParser
-
-import java.sql.Timestamp
-
-/**
- * Company property MDO.
- */
-@NCMdoEntity(table = "nc_company_property")
-case class NCCompanyPropertyMdo(
- @NCMdoField(column = "id", pk = true) id: Long,
- @NCMdoField(column = "company_id") userId: Long,
- @NCMdoField(column = "property") property: String,
- @NCMdoField(column = "value") value: String,
- @NCMdoField(column = "created_on") createdOn: Timestamp,
- @NCMdoField(column = "last_modified_on") lastModifiedOn: Timestamp
-) extends NCAnnotatedMdo[NCCompanyPropertyMdo]
-
-object NCCompanyPropertyMdo {
- implicit val x: RsParser[NCCompanyPropertyMdo] =
- NCAnnotatedMdo.mkRsParser(classOf[NCCompanyPropertyMdo])
-}
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/mdo/NCQueryStateMdo.scala
b/nlpcraft/src/main/scala/org/apache/nlpcraft/server/mdo/NCQueryStateMdo.scala
index 27f440a..7677b36 100644
---
a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/mdo/NCQueryStateMdo.scala
+++
b/nlpcraft/src/main/scala/org/apache/nlpcraft/server/mdo/NCQueryStateMdo.scala
@@ -17,8 +17,9 @@
package org.apache.nlpcraft.server.mdo
-import java.sql.Timestamp
+import org.apache.nlpcraft.common.JavaMeta
+import java.sql.Timestamp
import org.apache.nlpcraft.server.sql.NCSql.Implicits.RsParser
import org.apache.nlpcraft.server.mdo.impl._
@@ -45,6 +46,7 @@ case class NCQueryStateMdo(
// Query OK.
@NCMdoField var resultType: Option[String] = None,
@NCMdoField var resultBody: Option[String] = None,
+ @NCMdoField var resultMeta: Option[JavaMeta] = None,
// Query ERROR.
@NCMdoField var error: Option[String] = None,
@NCMdoField var errorCode: Option[Int] = None
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/mdo/NCUserMdo.scala
b/nlpcraft/src/main/scala/org/apache/nlpcraft/server/mdo/NCUserMdo.scala
index 9d7be9d..063a4be 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/mdo/NCUserMdo.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/server/mdo/NCUserMdo.scala
@@ -36,6 +36,7 @@ case class NCUserMdo(
@NCMdoField(column = "last_name") lastName: Option[String],
@NCMdoField(column = "avatar_url") avatarUrl: Option[String],
@NCMdoField(column = "passwd_salt") passwordSalt: Option[String],
+ @NCMdoField(column = "properties_gzip") propertiesGzip: Option[String],
@NCMdoField(column = "is_admin") isAdmin: Boolean,
@NCMdoField(column = "created_on") createdOn: Timestamp,
@NCMdoField(column = "last_modified_on") lastModifiedOn: Timestamp
@@ -54,11 +55,12 @@ object NCUserMdo {
lastName: Option[String],
avatarUrl: Option[String],
passwordSalt: Option[String],
+ propertiesGzip: Option[String],
isAdmin: Boolean
): NCUserMdo = {
val now = U.nowUtcTs()
- NCUserMdo(id, companyId, extId, email, firstName, lastName, avatarUrl,
passwordSalt, isAdmin, now, now)
+ NCUserMdo(id, companyId, extId, email, firstName, lastName, avatarUrl,
passwordSalt, propertiesGzip, isAdmin, now, now)
}
def apply(
@@ -70,11 +72,12 @@ object NCUserMdo {
lastName: Option[String],
avatarUrl: Option[String],
passwordSalt: Option[String],
+ propertiesGzip: Option[String],
isAdmin: Boolean,
createdOn: Timestamp
): NCUserMdo = {
require(createdOn != null, "Created date cannot be null.")
- NCUserMdo(id, companyId, extId, email, firstName, lastName, avatarUrl,
passwordSalt, isAdmin, createdOn, createdOn)
+ NCUserMdo(id, companyId, extId, email, firstName, lastName, avatarUrl,
passwordSalt, propertiesGzip, isAdmin, createdOn, createdOn)
}
}
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/mdo/NCUserPropertyMdo.scala
b/nlpcraft/src/main/scala/org/apache/nlpcraft/server/mdo/NCUserPropertyMdo.scala
deleted file mode 100644
index f1813cd..0000000
---
a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/mdo/NCUserPropertyMdo.scala
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.server.mdo
-
-import java.sql.Timestamp
-
-import org.apache.nlpcraft.server.mdo.impl._
-import org.apache.nlpcraft.server.sql.NCSql.Implicits.RsParser
-
-/**
- * User property MDO.
- */
-@NCMdoEntity(table = "nc_user_property")
-case class NCUserPropertyMdo(
- @NCMdoField(column = "id", pk = true) id: Long,
- @NCMdoField(column = "user_id") userId: Long,
- @NCMdoField(column = "property") property: String,
- @NCMdoField(column = "value") value: String,
- @NCMdoField(column = "created_on") createdOn: Timestamp,
- @NCMdoField(column = "last_modified_on") lastModifiedOn: Timestamp
-) extends NCAnnotatedMdo[NCUserPropertyMdo]
-
-object NCUserPropertyMdo {
- implicit val x: RsParser[NCUserPropertyMdo] =
- NCAnnotatedMdo.mkRsParser(classOf[NCUserPropertyMdo])
-}
\ No newline at end of file
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/probe/NCProbeManager.scala
b/nlpcraft/src/main/scala/org/apache/nlpcraft/server/probe/NCProbeManager.scala
index 34b654b..9452b83 100644
---
a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/probe/NCProbeManager.scala
+++
b/nlpcraft/src/main/scala/org/apache/nlpcraft/server/probe/NCProbeManager.scala
@@ -722,6 +722,7 @@ object NCProbeManager extends NCService {
val errCodeOpt = probeMsg.dataOpt[Int]("errorCode")
val resTypeOpt = probeMsg.dataOpt[String]("resType")
val resBodyOpt = probeMsg.dataOpt[String]("resBody")
+ val resMetaOpt = probeMsg.dataOpt[JavaMeta]("resMeta")
val logJson = probeMsg.dataOpt[String]("log")
val intentId = probeMsg.dataOpt[String]("intentId")
@@ -740,13 +741,11 @@ object NCProbeManager extends NCService {
else { // OK result.
require(resTypeOpt.isDefined &&
resBodyOpt.isDefined, "Result defined")
- val resType = resTypeOpt.get
- val resBody = resBodyOpt.get
-
NCQueryManager.setResult(
srvReqId,
- resType,
- resBody,
+ resTypeOpt.get,
+ resBodyOpt.get,
+ resMetaOpt,
logJson,
intentId
)
@@ -849,22 +848,11 @@ object NCProbeManager extends NCService {
usrAgent: Option[String],
rmtAddr: Option[String],
data: Option[String],
- usrMeta: Option[Map[String, String]],
- companyMeta: Option[Map[String, String]],
+ usrMeta: Option[JavaMeta],
+ companyMeta: Option[JavaMeta],
enableLog: Boolean,
parent: Span = null): Unit = {
startScopedSpan("askProbe", parent, "srvReqId" → srvReqId, "usrId" →
usr.id, "mdlId" → mdlId, "txt" → txt) { span ⇒
- def convertMeta(metaOpt: Option[Map[String, String]]):
util.HashMap[String, String] =
- metaOpt match {
- case Some(meta) ⇒
- val map = new util.HashMap[String, String]()
-
- meta.foreach { case (k, v) ⇒ map.put(k, v) }
-
- map
- case None ⇒ null
- }
-
val senMeta = new util.HashMap[String, java.io.Serializable]()
Map(
@@ -880,7 +868,7 @@ object NCProbeManager extends NCService {
"IS_ADMIN" → usr.isAdmin,
"AVATAR_URL" → usr.avatarUrl.orNull,
"DATA" → data.orNull,
- "META" → convertMeta(usrMeta),
+ "META" → usrMeta.orNull,
"COMPANY_ID" → company.id,
"COMPANY_NAME" → company.name,
"COMPANY_WEBSITE" → company.website.orNull,
@@ -889,7 +877,7 @@ object NCProbeManager extends NCService {
"COMPANY_CITY" → company.city.orNull,
"COMPANY_ADDRESS" → company.address.orNull,
"COMPANY_POSTAL" → company.postalCode.orNull,
- "COMPANY_META" → convertMeta(companyMeta)
+ "COMPANY_META" → companyMeta.orNull
).
filter(_._2 != null).
foreach(p ⇒ senMeta.put(p._1,
p._2.asInstanceOf[java.io.Serializable]))
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/proclog/NCProcessLogManager.scala
b/nlpcraft/src/main/scala/org/apache/nlpcraft/server/proclog/NCProcessLogManager.scala
index f7958b9..436a0e1 100644
---
a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/proclog/NCProcessLogManager.scala
+++
b/nlpcraft/src/main/scala/org/apache/nlpcraft/server/proclog/NCProcessLogManager.scala
@@ -91,6 +91,7 @@ object NCProcessLogManager extends NCService with
NCIgniteInstance {
* @param errMsg
* @param resType
* @param resBody
+ * @param resMeta
* @param intentId
* @param parent Optional parent span.
*/
@@ -101,6 +102,7 @@ object NCProcessLogManager extends NCService with
NCIgniteInstance {
errMsg: Option[String],
resType: Option[String],
resBody: Option[String],
+ resMeta: Option[JavaMeta],
intentId: Option[String],
parent: Span = null
): Unit =
@@ -115,6 +117,7 @@ object NCProcessLogManager extends NCService with
NCIgniteInstance {
errMsg.orNull,
resType.orNull,
resBody.orNull,
+ resMeta.orNull,
intentId.orNull,
tstamp,
span
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/query/NCQueryManager.scala
b/nlpcraft/src/main/scala/org/apache/nlpcraft/server/query/NCQueryManager.scala
index ad6fdb1..2b762f3 100644
---
a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/query/NCQueryManager.scala
+++
b/nlpcraft/src/main/scala/org/apache/nlpcraft/server/query/NCQueryManager.scala
@@ -22,6 +22,7 @@ import org.apache.ignite.IgniteCache
import org.apache.ignite.events.{CacheEvent, EventType}
import org.apache.nlpcraft.common.ascii.NCAsciiTable
import org.apache.nlpcraft.common.pool.NCThreadPoolManager
+import org.apache.nlpcraft.common.util.NCUtils.{jsonToJavaMap, uncompress}
import org.apache.nlpcraft.common.{NCService, _}
import org.apache.nlpcraft.server.apicodes.NCApiStatusCode._
import org.apache.nlpcraft.server.company.NCCompanyManager
@@ -221,18 +222,6 @@ object NCQueryManager extends NCService with
NCIgniteInstance with NCOpenCensusS
val usr = NCUserManager.getUserById(usrId, parent).getOrElse(throw new
NCE(s"Unknown user ID: $usrId"))
val company = NCCompanyManager.getCompany(usr.companyId,
parent).getOrElse(throw new NCE(s"Unknown company ID: ${usr.companyId}"))
- val usrMeta = {
- val m = NCUserManager.getUserProperties(usrId, parent)
-
- if (m.isEmpty) None else Some(m.map(p ⇒ p.property →
p.value).toMap)
- }
-
- val compMeta = {
- val m = NCCompanyManager.getCompanyProperties(usr.companyId,
parent)
-
- if (m.isEmpty) None else Some(m.map(p ⇒ p.property →
p.value).toMap)
- }
-
// Check input length.
if (txt0.split(" ").length > MAX_WORDS)
throw new NCE(s"User input is too long (max is $MAX_WORDS words).")
@@ -285,6 +274,13 @@ object NCQueryManager extends NCService with
NCIgniteInstance with NCOpenCensusS
val enabledBuiltInToks = NCProbeManager.getModel(mdlId,
span).enabledBuiltInTokens
+ @throws[NCE]
+ def unzipProperties(gzipOpt: Option[String]): Option[JavaMeta]
=
+ gzipOpt match {
+ case Some(gzip) ⇒ Some(jsonToJavaMap(uncompress(gzip)))
+ case None ⇒ None
+ }
+
// Enrich the user input and send it to the probe.
NCProbeManager.askProbe(
srvReqId,
@@ -296,8 +292,8 @@ object NCQueryManager extends NCService with
NCIgniteInstance with NCOpenCensusS
usrAgent,
rmtAddr,
data,
- usrMeta,
- compMeta,
+ unzipProperties(usr.propertiesGzip),
+ unzipProperties(company.propertiesGzip),
enableLog,
span
)
@@ -369,6 +365,7 @@ object NCQueryManager extends NCService with
NCIgniteInstance with NCOpenCensusS
None,
None,
None,
+ None,
span
)
}
@@ -379,6 +376,7 @@ object NCQueryManager extends NCService with
NCIgniteInstance with NCOpenCensusS
* @param srvReqId Server request ID.
* @param resType
* @param resBody
+ * @param resMeta
* @param logJson
* @param intentId
* @param parent Optional parent span.
@@ -388,6 +386,7 @@ object NCQueryManager extends NCService with
NCIgniteInstance with NCOpenCensusS
srvReqId: String,
resType: String,
resBody: String,
+ resMeta: Option[JavaMeta],
logJson: Option[String],
intentId: Option[String],
parent: Span = null
@@ -407,6 +406,7 @@ object NCQueryManager extends NCService with
NCIgniteInstance with NCOpenCensusS
copy.status = QRY_READY.toString
copy.resultType = Some(resType)
copy.resultBody = Some(resBody)
+ copy.resultMeta = resMeta
copy.logJson = logJson
copy.intentId = intentId
@@ -430,6 +430,7 @@ object NCQueryManager extends NCService with
NCIgniteInstance with NCOpenCensusS
None,
resType = Some(resType),
resBody = Some(resBody),
+ resMeta = resMeta,
intentId = intentId,
span
)
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/rest/NCBasicRestApi.scala
b/nlpcraft/src/main/scala/org/apache/nlpcraft/server/rest/NCBasicRestApi.scala
index a681a8f..4d9750b 100644
---
a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/rest/NCBasicRestApi.scala
+++
b/nlpcraft/src/main/scala/org/apache/nlpcraft/server/rest/NCBasicRestApi.scala
@@ -24,14 +24,17 @@ import akka.http.scaladsl.model._
import akka.http.scaladsl.model.headers._
import akka.http.scaladsl.server.Directives.{entity, _}
import akka.http.scaladsl.server._
-import com.google.gson.Gson
+import com.fasterxml.jackson.core.JsonProcessingException
+import com.fasterxml.jackson.databind.ObjectMapper
+import com.fasterxml.jackson.module.scala.DefaultScalaModule
import com.typesafe.scalalogging.LazyLogging
import io.opencensus.stats.Measure
import io.opencensus.trace.{Span, Status}
import org.apache.commons.validator.routines.UrlValidator
import org.apache.nlpcraft.common.opencensus.NCOpenCensusTrace
import org.apache.nlpcraft.common.pool.NCThreadPoolManager
-import org.apache.nlpcraft.common.{NCE, U}
+import org.apache.nlpcraft.common.util.NCUtils.{jsonToJavaMap, uncompress}
+import org.apache.nlpcraft.common.{JavaMeta, NCE, U}
import org.apache.nlpcraft.model.NCModelView
import org.apache.nlpcraft.server.apicodes.NCApiStatusCode.{API_OK, _}
import org.apache.nlpcraft.server.company.NCCompanyManager
@@ -52,12 +55,10 @@ import scala.concurrent.{ExecutionContext, Future}
* REST API default implementation.
*/
class NCBasicRestApi extends NCRestApi with LazyLogging with NCOpenCensusTrace
with NCOpenCensusServerStats {
- protected final val GSON = new Gson()
protected final val URL_VALIDATOR = new UrlValidator(Array("http",
"https"), UrlValidator.ALLOW_LOCAL_URLS)
final val API_VER = 1
final val API = "api" / s"v$API_VER"
-
/** */
private final val CORS_HDRS = List(
`Access-Control-Allow-Origin`.*,
@@ -65,6 +66,10 @@ class NCBasicRestApi extends NCRestApi with LazyLogging with
NCOpenCensusTrace w
`Access-Control-Allow-Headers`("Authorization", "Content-Type",
"X-Requested-With")
)
+ private final val JS_MAPPER = new ObjectMapper()
+
+ JS_MAPPER.registerModule(DefaultScalaModule)
+
/*
* General control exception.
* Note that these classes must be public because scala 2.11 internal
errors (compilations problems).
@@ -132,6 +137,20 @@ class NCBasicRestApi extends NCRestApi with LazyLogging
with NCOpenCensusTrace w
/**
*
+ * @param o
+ * @throws
+ * @return
+ */
+ @throws[NCE]
+ private def toJs(o: AnyRef): String =
+ try
+ JS_MAPPER.writeValueAsString(o)
+ catch {
+ case e: JsonProcessingException ⇒ throw new NCE(s"JSON
serialization error for: $o", e)
+ }
+
+ /**
+ *
* @param acsTkn Access token to check.
* @param shouldBeAdmin Admin flag.
* @return
@@ -220,28 +239,38 @@ class NCBasicRestApi extends NCRestApi with LazyLogging
with NCOpenCensusTrace w
else
s.resultBody.orNull
),
+ "resMeta" → s.resultMeta.orNull,
"error" → s.error.orNull,
"errorCode" → s.errorCode.map(Integer.valueOf).orNull,
"logHolder" → (if (s.logJson.isDefined)
U.jsonToObject(s.logJson.get) else null),
"intentId" → s.intentId.orNull
).filter(_._2 != null).asJava
+
/**
- * Checks properties.
+ * Extracts and checks JSON.
*
- * @param propsOpt Optional properties.
+ * @param jsOpt JSON value. Optional.
+ * @param name Property name.
*/
@throws[TooLargeField]
- private def checkProperties(propsOpt: Option[Map[String, String]]): Unit =
- propsOpt match {
- case Some(props) ⇒
- props.foreach { case (k, v) ⇒
- checkLength(k, k, 64)
-
- if (v != null && v.nonEmpty && v.length > 512)
- throw TooLargeField(v, 512)
+ @throws[InvalidField]
+ private def extractJson(jsOpt: Option[spray.json.JsValue], name: String):
Option[String] =
+ jsOpt match {
+ case Some(js) ⇒
+ val s = js.compactPrint
+
+ checkLength(name, s, 512000)
+
+ // Validates.
+ try
+ U.jsonToJavaMap(s)
+ catch {
+ case _: NCE ⇒ throw InvalidField(name)
}
- case None ⇒ // No-op.
+
+ Some(s)
+ case None ⇒ None
}
/**
@@ -526,9 +555,28 @@ class NCBasicRestApi extends NCRestApi with LazyLogging
with NCOpenCensusTrace w
*
* @param fut
*/
- private def successWithJs(fut: Future[String]): Route = onSuccess(fut) {
- js ⇒ complete(HttpResponse(entity =
HttpEntity(ContentTypes.`application/json`, js)))
- }
+ private def successWithJs(fut: Future[String]): Route =
+ onSuccess(fut) {
+ js ⇒ complete(HttpResponse(entity =
HttpEntity(ContentTypes.`application/json`, js)))
+ }
+
+ /**
+ *
+ * @param o
+ */
+ private def completeJs(o: Object): Route =
+ complete(HttpResponse(entity =
HttpEntity(ContentTypes.`application/json`, toJs(o))))
+
+ /**
+ *
+ * @param gzipOpt
+ */
+ @throws[NCE]
+ private def unzipProperties(gzipOpt: Option[String]): Option[JavaMeta] =
+ gzipOpt match {
+ case Some(gzip) ⇒ Some(jsonToJavaMap(uncompress(gzip)))
+ case None ⇒ None
+ }
/**
*
@@ -559,14 +607,7 @@ class NCBasicRestApi extends NCRestApi with LazyLogging
with NCOpenCensusTrace w
"acsTok" → req.acsTok, "usrExtId" → req.usrExtId, "mdlId"
→ req.mdlId, "txt" → req.txt
)
- val dataJsOpt =
- req.data match {
- case Some(data) ⇒ Some(data.compactPrint)
- case None ⇒ None
- }
-
- checkLengthOpt("data", dataJsOpt,512000)
-
+ val dataJs = extractJson(req.data, "data")
val acsUsr = authenticate(req.acsTok)
checkModelId(req.mdlId, acsUsr.companyId)
@@ -579,7 +620,7 @@ class NCBasicRestApi extends NCRestApi with LazyLogging
with NCOpenCensusTrace w
mdlId = req.mdlId,
usrAgent = usrAgent,
rmtAddr = getAddress(rmtAddr),
- data = dataJsOpt,
+ data = dataJs,
req.enableLog.getOrElse(false),
parent = span
))
@@ -640,8 +681,8 @@ class NCBasicRestApi extends NCRestApi with LazyLogging
with NCOpenCensusTrace w
successWithJs(
fut.collect {
- // We have to use GSON (not spray) here to serialize
'resBody' field.
- case res ⇒ GSON.toJson(
+ // We have to use Jackson (not spray) here to
serialize 'resBody' field.
+ case res ⇒ toJs(
Map(
"status" → API_OK.toString,
"state" → queryStateToMap(res)
@@ -724,8 +765,8 @@ class NCBasicRestApi extends NCRestApi with LazyLogging
with NCOpenCensusTrace w
toSeq.sortBy(-_.createTstamp.getTime).
take(req.maxRows.getOrElse(Integer.MAX_VALUE))
- // We have to use GSON (not spray) here to serialize 'resBody'
field.
- val js = GSON.toJson(
+ // We have to use Jackson (not spray) here to serialize
'resBody' field.
+ val js = toJs(
Map(
"status" → API_OK.toString,
"states" → states.map(queryStateToMap).asJava
@@ -772,8 +813,8 @@ class NCBasicRestApi extends NCRestApi with LazyLogging
with NCOpenCensusTrace w
successWithJs(
fut.collect {
- // We have to use GSON (not spray) here to serialize
'result' field.
- case res ⇒ GSON.toJson(Map("status" → API_OK.toString,
"result" → res).asJava)
+ // We have to use Jackson (not spray) here to
serialize 'result' field.
+ case res ⇒ toJs(Map("status" → API_OK.toString,
"result" → res).asJava)
}
)
}
@@ -881,7 +922,7 @@ class NCBasicRestApi extends NCRestApi with LazyLogging
with NCOpenCensusTrace w
adminFirstName: String,
adminLastName: String,
adminAvatarUrl: Option[String],
- properties: Option[Map[String, String]]
+ properties: Option[spray.json.JsValue]
)
case class Res$Company$Add(
status: String,
@@ -911,7 +952,7 @@ class NCBasicRestApi extends NCRestApi with LazyLogging
with NCOpenCensusTrace w
"adminAvatarUrl" → req.adminAvatarUrl
)
- checkProperties(req.properties)
+ val propsJs = extractJson(req.properties, "properties")
// Via REST only administrators of already created companies
can create new companies.
authenticateAsAdmin(req.acsTok)
@@ -929,7 +970,7 @@ class NCBasicRestApi extends NCRestApi with LazyLogging
with NCOpenCensusTrace w
req.adminFirstName,
req.adminLastName,
req.adminAvatarUrl,
- req.properties,
+ propsJs,
span
)
@@ -958,11 +999,10 @@ class NCBasicRestApi extends NCRestApi with LazyLogging
with NCOpenCensusTrace w
city: Option[String],
address: Option[String],
postalCode: Option[String],
- properties: Option[Map[String, String]]
+ properties: Option[JavaMeta]
)
implicit val reqFmt: RootJsonFormat[Req$Company$Get] =
jsonFormat1(Req$Company$Get)
- implicit val resFmt: RootJsonFormat[Res$Company$Get] =
jsonFormat10(Res$Company$Get)
entity(as[Req$Company$Get]) { req ⇒
startScopedSpan("company$get", "acsTok" → req.acsTok) { span ⇒
@@ -974,9 +1014,7 @@ class NCBasicRestApi extends NCRestApi with LazyLogging
with NCOpenCensusTrace w
getCompany(acsUsr.companyId, span).
getOrElse(throw new NCE(s"Company not found:
${acsUsr.companyId}"))
- val props =
NCCompanyManager.getCompanyProperties(acsUsr.companyId, span)
-
- complete {
+ completeJs {
Res$Company$Get(API_OK,
company.id,
company.name,
@@ -986,7 +1024,7 @@ class NCBasicRestApi extends NCRestApi with LazyLogging
with NCOpenCensusTrace w
company.city,
company.address,
company.postalCode,
- if (props.isEmpty) None else Some(props.map(p ⇒
p.property → p.value).toMap)
+ unzipProperties(company.propertiesGzip)
)
}
}
@@ -1010,7 +1048,7 @@ class NCBasicRestApi extends NCRestApi with LazyLogging
with NCOpenCensusTrace w
city: Option[String],
address: Option[String],
postalCode: Option[String],
- properties: Option[Map[String, String]]
+ properties: Option[spray.json.JsValue]
)
case class Res$Company$Update(
status: String
@@ -1031,8 +1069,7 @@ class NCBasicRestApi extends NCRestApi with LazyLogging
with NCOpenCensusTrace w
"postalCode" → req.postalCode
)
- checkProperties(req.properties)
-
+ val propsJs = extractJson(req.properties, "properties")
val admUsr = authenticateAsAdmin(req.acsTok)
NCCompanyManager.updateCompany(
@@ -1044,7 +1081,7 @@ class NCBasicRestApi extends NCRestApi with LazyLogging
with NCOpenCensusTrace w
req.city,
req.address,
req.postalCode,
- req.properties,
+ propsJs,
span
)
@@ -1314,7 +1351,7 @@ class NCBasicRestApi extends NCRestApi with LazyLogging
with NCOpenCensusTrace w
lastName: String,
avatarUrl: Option[String],
isAdmin: Boolean,
- properties: Option[Map[String, String]],
+ properties: Option[spray.json.JsValue],
usrExtId: Option[String]
)
case class Res$User$Add(
@@ -1337,8 +1374,7 @@ class NCBasicRestApi extends NCRestApi with LazyLogging
with NCOpenCensusTrace w
"usrExtId" → req.usrExtId
)
- checkProperties(req.properties)
-
+ val propsJs = extractJson(req.properties, "properties")
val admUsr = authenticateAsAdmin(req.acsTok)
val id = NCUserManager.addUser(
@@ -1349,7 +1385,7 @@ class NCBasicRestApi extends NCRestApi with LazyLogging
with NCOpenCensusTrace w
req.lastName,
req.avatarUrl,
req.isAdmin,
- req.properties,
+ propsJs,
req.usrExtId,
span
)
@@ -1375,7 +1411,7 @@ class NCBasicRestApi extends NCRestApi with LazyLogging
with NCOpenCensusTrace w
firstName: String,
lastName: String,
avatarUrl: Option[String],
- properties: Option[Map[String, String]]
+ properties: Option[spray.json.JsValue]
)
case class Res$User$Update(
status: String
@@ -1393,8 +1429,7 @@ class NCBasicRestApi extends NCRestApi with LazyLogging
with NCOpenCensusTrace w
"avatarUrl" → req.avatarUrl
)
- checkProperties(req.properties)
-
+ val propsJs = extractJson(req.properties, "properties")
val acsUsr = authenticate(req.acsTok)
NCUserManager.updateUser(
@@ -1402,7 +1437,7 @@ class NCBasicRestApi extends NCRestApi with LazyLogging
with NCOpenCensusTrace w
req.firstName,
req.lastName,
req.avatarUrl,
- req.properties,
+ propsJs,
span
)
@@ -1454,7 +1489,6 @@ class NCBasicRestApi extends NCRestApi with LazyLogging
with NCOpenCensusTrace w
NCUserManager.
getAllUsers(acsUsr.companyId, span).
- keys.
filter(_.id != acsUsr.id).
map(_.id).
foreach(delete)
@@ -1575,7 +1609,7 @@ class NCBasicRestApi extends NCRestApi with LazyLogging
with NCOpenCensusTrace w
avatarUrl: Option[String],
isAdmin: Boolean,
companyId: Long,
- properties: Option[Map[String, String]]
+ properties: Option[JavaMeta]
)
case class Res$User$All(
status: String,
@@ -1583,8 +1617,6 @@ class NCBasicRestApi extends NCRestApi with LazyLogging
with NCOpenCensusTrace w
)
implicit val reqFmt: RootJsonFormat[Req$User$All] =
jsonFormat1(Req$User$All)
- implicit val usrFmt: RootJsonFormat[ResUser_User$All] =
jsonFormat9(ResUser_User$All)
- implicit val resFmt: RootJsonFormat[Res$User$All] =
jsonFormat2(Res$User$All)
entity(as[Req$User$All]) { req ⇒
startScopedSpan("user$All", "acsTok" → req.acsTok) { span ⇒
@@ -1592,23 +1624,23 @@ class NCBasicRestApi extends NCRestApi with LazyLogging
with NCOpenCensusTrace w
val admUSr = authenticateAsAdmin(req.acsTok)
- val usrLst =
- NCUserManager.getAllUsers(admUSr.companyId, span).map {
case (u, props) ⇒
- ResUser_User$All(
- u.id,
- u.email,
- u.extId,
- u.firstName,
- u.lastName,
- u.avatarUrl,
- u.isAdmin,
- u.companyId,
- if (props.isEmpty) None else Some(props.map(p ⇒
p.property → p.value).toMap)
+ completeJs {
+ Res$User$All(
+ API_OK,
+ NCUserManager.getAllUsers(admUSr.companyId,
span).map(u ⇒
+ ResUser_User$All(
+ u.id,
+ u.email,
+ u.extId,
+ u.firstName,
+ u.lastName,
+ u.avatarUrl,
+ u.isAdmin,
+ u.companyId,
+ unzipProperties(u.propertiesGzip)
+ )
)
- }.toSeq
-
- complete {
- Res$User$All(API_OK, usrLst)
+ )
}
}
}
@@ -1634,11 +1666,10 @@ class NCBasicRestApi extends NCRestApi with LazyLogging
with NCOpenCensusTrace w
lastName: Option[String],
avatarUrl: Option[String],
isAdmin: Boolean,
- properties: Option[Map[String, String]]
+ properties: Option[JavaMeta]
)
implicit val reqFmt: RootJsonFormat[Req$User$Get] =
jsonFormat3(Req$User$Get)
- implicit val resFmt: RootJsonFormat[Res$User$Get] =
jsonFormat9(Res$User$Get)
entity(as[Req$User$Get]) { req ⇒
startScopedSpan(
@@ -1653,9 +1684,8 @@ class NCBasicRestApi extends NCRestApi with LazyLogging
with NCOpenCensusTrace w
throw AdminRequired(acsUsr.email.get)
val usr = NCUserManager.getUserById(usrId,
span).getOrElse(throw new NCE(s"User not found: $usrId"))
- val props = NCUserManager.getUserProperties(usrId, span)
- complete {
+ completeJs {
Res$User$Get(API_OK,
usr.id,
usr.email,
@@ -1664,7 +1694,7 @@ class NCBasicRestApi extends NCRestApi with LazyLogging
with NCOpenCensusTrace w
usr.lastName,
usr.avatarUrl,
usr.isAdmin,
- if (props.isEmpty) None else Some(props.map(p ⇒
p.property → p.value).toMap)
+ unzipProperties(usr.propertiesGzip)
)
}
}
@@ -1771,7 +1801,7 @@ class NCBasicRestApi extends NCRestApi with LazyLogging
with NCOpenCensusTrace w
status = statusCode,
entity = HttpEntity(
ContentTypes.`application/json`,
- GSON.toJson(Map("code" → errCode, "msg" →
errMsg).asJava)
+ toJs(Map("code" → errCode, "msg" → errMsg).asJava)
)
)
)
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/sql/NCSqlManager.scala
b/nlpcraft/src/main/scala/org/apache/nlpcraft/server/sql/NCSqlManager.scala
index 00fe81b..50ef05d 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/sql/NCSqlManager.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/server/sql/NCSqlManager.scala
@@ -17,8 +17,10 @@
package org.apache.nlpcraft.server.sql
+import com.fasterxml.jackson.core.JsonProcessingException
+import com.fasterxml.jackson.databind.ObjectMapper
+import com.fasterxml.jackson.module.scala.DefaultScalaModule
import io.opencensus.trace.Span
-import org.apache.ignite.IgniteAtomicSequence
import org.apache.nlpcraft.common.config.NCConfigurable
import org.apache.nlpcraft.common.{NCService, _}
import org.apache.nlpcraft.server.apicodes.NCApiStatusCode._
@@ -27,7 +29,6 @@ import org.apache.nlpcraft.server.mdo._
import org.apache.nlpcraft.server.sql.NCSql.Implicits._
import java.sql.Timestamp
-import scala.util.control.Exception.catching
/**
* Provides basic CRUD and often used operations on RDBMS.
@@ -35,7 +36,7 @@ import scala.util.control.Exception.catching
*/
object NCSqlManager extends NCService with NCIgniteInstance {
private final val DB_TABLES = Seq(
- "nc_company", "nc_company_property", "nc_user", "nc_user_property",
"passwd_pool", "proc_log", "feedback"
+ "nc_company", "nc_user", "passwd_pool", "proc_log", "feedback"
)
private final val CACHE_2_CLEAR = Seq(
"user-token-signin-cache",
@@ -45,13 +46,45 @@ object NCSqlManager extends NCService with NCIgniteInstance
{
"stanford-cache",
"opennlp-cache"
)
-
+
+ private final val JS_MAPPER = new ObjectMapper()
+
+ JS_MAPPER.registerModule(DefaultScalaModule)
+
private object Config extends NCConfigurable {
def init: Boolean =
getBoolOpt("nlpcraft.server.database.igniteDbInitialize").getOrElse(false)
}
- @volatile private var usersPropsSeq: IgniteAtomicSequence = _
- @volatile private var compPropsSeq: IgniteAtomicSequence = _
+ /**
+ *
+ * @param opt
+ */
+ @throws[NCE]
+ private def gzip(opt: Option[String]): String =
+ opt match {
+ case Some(s) ⇒ U.compress(s)
+ case None ⇒ null
+ }
+
+ /**
+ *
+ * @param nullable
+ */
+ @throws[NCE]
+ private def gzip(nullable: String): String = if (nullable != null)
U.compress(nullable) else null
+
+ /**
+ *
+ * @param m
+ */
+ @throws[NCE]
+ private def gzip(m: JavaMeta): String = {
+ try
+ if (m != null) U.compress(JS_MAPPER.writeValueAsString(m)) else
null
+ catch {
+ case e: JsonProcessingException ⇒ throw new NCE(s"JSON
serialization error for: $m", e)
+ }
+ }
/**
*
@@ -68,11 +101,6 @@ object NCSqlManager extends NCService with NCIgniteInstance
{
if (NCSql.isIgniteDb)
prepareIgniteSchema()
- catching(wrapIE) {
- usersPropsSeq = NCSql.mkSeq(ignite, "usersPropsSeq",
"nc_user_property", "id")
- compPropsSeq = NCSql.mkSeq(ignite, "companiesPropsSeq",
"nc_company_property", "id")
- }
-
ackStarted()
}
@@ -163,7 +191,6 @@ object NCSqlManager extends NCService with NCIgniteInstance
{
@throws[NCE]
def deleteUser(id: Long, parent: Span): Int =
startScopedSpan("deleteUser", parent, "usrId" → id) { _ ⇒
- NCSql.delete("DELETE FROM nc_user_property WHERE user_id = ?", id)
NCSql.delete("DELETE FROM nc_user WHERE id = ?", id)
}
@@ -176,7 +203,6 @@ object NCSqlManager extends NCService with NCIgniteInstance
{
@throws[NCE]
def deleteCompany(id: Long, parent: Span): Int =
startScopedSpan("deleteCompany", parent, "compId" → id) { _ ⇒
- NCSql.delete("DELETE FROM nc_user_property WHERE user_id IN
(SELECT id FROM nc_user WHERE company_id = ?)", id)
NCSql.delete("DELETE FROM nc_user WHERE company_id = ?", id)
NCSql.delete("DELETE FROM nc_company WHERE id = ?", id)
}
@@ -197,33 +223,28 @@ object NCSqlManager extends NCService with
NCIgniteInstance {
firstName: String,
lastName: String,
avatarUrl: Option[String],
- propsOpt: Option[Map[String, String]],
+ propsOpt: Option[String],
parent: Span
): Int =
- startScopedSpan("updateUser", parent, "usrId" → id) { span ⇒
- val n =
- NCSql.update(
- s"""
- |UPDATE nc_user
- |SET
- | first_name = ?,
- | last_name = ?,
- | avatar_url = ?,
- | last_modified_on = ?
- |WHERE id = ?
- """.stripMargin,
- firstName,
- lastName,
- avatarUrl.orNull,
- U.nowUtcTs(),
- id
- )
-
- NCSql.delete("DELETE FROM nc_user_property WHERE user_id = ?", id)
-
- addUserProperties(id, propsOpt, span)
-
- n
+ startScopedSpan("updateUser", parent, "usrId" → id) { _ ⇒
+ NCSql.update(
+ s"""
+ |UPDATE nc_user
+ |SET
+ | first_name = ?,
+ | last_name = ?,
+ | avatar_url = ?,
+ | properties_gzip = ?,
+ | last_modified_on = ?
+ |WHERE id = ?
+ """.stripMargin,
+ firstName,
+ lastName,
+ avatarUrl.orNull,
+ gzip(propsOpt),
+ U.nowUtcTs(),
+ id
+ )
}
/**
@@ -246,97 +267,32 @@ object NCSqlManager extends NCService with
NCIgniteInstance {
firstName: String,
lastName: String,
avatarUrl: Option[String],
- propsOpt: Option[Map[String, String]],
+ propsOpt: Option[String],
parent: Span
): Int =
startScopedSpan("updateUser", parent, "usrId" → id) { span ⇒
- val n =
- NCSql.update(
- s"""
- |UPDATE nc_user
- |SET
- | email = ?,
- | passwd_salt = ?,
- | first_name = ?,
- | last_name = ?,
- | avatar_url = ?,
- | last_modified_on = ?
- |WHERE id = ?
- """.stripMargin,
- email,
- passwdSalt,
- firstName,
- lastName,
- avatarUrl.orNull,
- U.nowUtcTs(),
- id
- )
-
- NCSql.delete("DELETE FROM nc_user_property WHERE user_id = ?", id)
-
- addUserProperties(id, propsOpt, span)
-
- n
- }
-
- /**
- *
- * @param id
- * @param propsOpt
- * @param parent Optional parent span.
- */
- private def addUserProperties(id: Long, propsOpt: Option[Map[String,
String]], parent: Span): Unit =
- startScopedSpan("addUserProperties", parent, "usrId" → id) { _ ⇒
- propsOpt match {
- case Some(props) ⇒
- val now = U.nowUtcTs()
-
- props.foreach { case (k, v) ⇒
- NCSql.insert(
- s"""
- |INSERT INTO nc_user_property (id, user_id,
property, value, created_on, last_modified_on)
- |VALUES(?, ?, ?, ?, ?, ?)
- """.stripMargin,
- usersPropsSeq.getAndIncrement(),
- id,
- k,
- v,
- now,
- now
- )
- }
- case None ⇒ // No-op.
- }
- }
-
- /**
- *
- * @param id
- * @param propsOpt
- * @param parent Optional parent span.
- */
- private def addCompanyProperties(id: Long, propsOpt: Option[Map[String,
String]], parent: Span): Unit =
- startScopedSpan("addCompanyProperties", parent, "companyId" → id) { _ ⇒
- propsOpt match {
- case Some(props) ⇒
- val now = U.nowUtcTs()
-
- props.foreach { case (k, v) ⇒
- NCSql.insert(
- s"""
- |INSERT INTO nc_company_property (id,
company_id, property, value, created_on, last_modified_on)
- |VALUES(?, ?, ?, ?, ?, ?)
- """.stripMargin,
- compPropsSeq.getAndIncrement(),
- id,
- k,
- v,
- now,
- now
- )
- }
- case None ⇒ // No-op.
- }
+ NCSql.update(
+ s"""
+ |UPDATE nc_user
+ |SET
+ | email = ?,
+ | passwd_salt = ?,
+ | first_name = ?,
+ | last_name = ?,
+ | avatar_url = ?,
+ | properties_gzip = ?,
+ | last_modified_on = ?
+ |WHERE id = ?
+ """.stripMargin,
+ email,
+ passwdSalt,
+ firstName,
+ lastName,
+ avatarUrl.orNull,
+ gzip(propsOpt),
+ U.nowUtcTs(),
+ id
+ )
}
/**
@@ -387,11 +343,11 @@ object NCSqlManager extends NCService with
NCIgniteInstance {
city: Option[String],
address: Option[String],
postalCode: Option[String],
- propsOpt: Option[Map[String, String]],
+ propsOpt: Option[String],
parent: Span
): Int =
startScopedSpan("updateCompany", parent, "compId" → id) { _ ⇒
- val res = NCSql.update(
+ NCSql.update(
s"""
|UPDATE nc_company
|SET
@@ -402,6 +358,7 @@ object NCSqlManager extends NCService with NCIgniteInstance
{
| city = ?,
| address = ?,
| postal_code = ?,
+ | properties_gzip = ?,
| last_modified_on = ?
|WHERE id = ?
""".stripMargin,
@@ -412,15 +369,10 @@ object NCSqlManager extends NCService with
NCIgniteInstance {
city.orNull,
address.orNull,
postalCode.orNull,
+ gzip(propsOpt),
U.nowUtcTs(),
id
)
-
- NCSql.delete("DELETE FROM nc_company_property WHERE company_id =
?", id)
-
- addCompanyProperties(id, propsOpt, parent)
-
- res
}
/**
@@ -530,34 +482,6 @@ object NCSqlManager extends NCService with
NCIgniteInstance {
}
/**
- * Gets user properties for given ID.
- *
- * @param id User ID.
- * @param parent Optional parent span.
- * @return User properties.
- *
- */
- @throws[NCE]
- def getUserProperties(id: Long, parent: Span): Seq[NCUserPropertyMdo] =
- startScopedSpan("getUserProperties", parent, "usrId" → id) { _ ⇒
- NCSql.select[NCUserPropertyMdo]("SELECT * FROM nc_user_property
WHERE user_id = ?", id)
- }
-
- /**
- * Gets company properties for given ID.
- *
- * @param id User ID.
- * @param parent Optional parent span.
- * @return Company properties.
- *
- */
- @throws[NCE]
- def getCompanyProperties(id: Long, parent: Span):
Seq[NCCompanyPropertyMdo] =
- startScopedSpan("getCompanyProperties", parent, "usrId" → id) { _ ⇒
- NCSql.select[NCCompanyPropertyMdo]("SELECT * FROM
nc_company_property WHERE company_id = ?", id)
- }
-
- /**
* Gets user properties for given external ID.
*
* @param companyId Company ID.
@@ -593,15 +517,9 @@ object NCSqlManager extends NCService with
NCIgniteInstance {
* @param parent Optional parent span.
*/
@throws[NCE]
- def getAllUsers(compId: Long, parent: Span): Map[NCUserMdo,
Seq[NCUserPropertyMdo]] =
+ def getAllUsers(compId: Long, parent: Span): Seq[NCUserMdo] =
startScopedSpan("getAllUsers", parent, "compId" → compId) { _ ⇒
- val props = NCSql.select[NCUserPropertyMdo](
- "SELECT * FROM nc_user_property WHERE user_id IN (SELECT id
FROM nc_user WHERE company_id = ?)",
- compId
- ).groupBy(_.userId)
-
- NCSql.select[NCUserMdo]("SELECT * FROM nc_user WHERE company_id =
?", compId).
- map(p ⇒ p → props.getOrElse(p.id, Nil)).toMap
+ NCSql.select[NCUserMdo]("SELECT * FROM nc_user WHERE company_id =
?", compId)
}
/**
@@ -643,7 +561,7 @@ object NCSqlManager extends NCService with NCIgniteInstance
{
city: Option[String],
address: Option[String],
postalCode: Option[String],
- propsOpt: Option[Map[String, String]],
+ propsOpt: Option[String],
parent: Span
): Unit =
startScopedSpan("addCompany", parent, "compId" → id, "name" → name,
"tkn" → tkn) { _ ⇒
@@ -663,10 +581,11 @@ object NCSqlManager extends NCService with
NCIgniteInstance {
| postal_code,
| auth_token,
| auth_token_hash,
+ | properties_gzip,
| created_on,
| last_modified_on
|)
- | VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+ | VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""".stripMargin,
id,
name,
@@ -678,11 +597,10 @@ object NCSqlManager extends NCService with
NCIgniteInstance {
postalCode.orNull,
tkn,
U.mkSha256Hash(tkn),
+ gzip(propsOpt),
now,
now
)
-
- addCompanyProperties(id, propsOpt, parent)
}
/**
@@ -711,7 +629,7 @@ object NCSqlManager extends NCService with NCIgniteInstance
{
avatarUrl: Option[String],
passwdSalt: Option[String],
isAdmin: Boolean,
- propsOpt: Option[Map[String, String]],
+ propsOpt: Option[String],
parent: Span
): Unit = {
require(usrExtId.isDefined ^ email.isDefined)
@@ -739,11 +657,12 @@ object NCSqlManager extends NCService with
NCIgniteInstance {
| email,
| passwd_salt,
| avatar_url,
+ | properties_gzip,
| is_admin,
| created_on,
| last_modified_on
| )
- | VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+ | VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""".stripMargin,
id,
compId,
@@ -753,12 +672,11 @@ object NCSqlManager extends NCService with
NCIgniteInstance {
email.orNull,
passwdSalt.orNull,
avatarUrl.orNull,
+ gzip(propsOpt),
isAdmin,
now,
now
)
-
- addUserProperties(id, propsOpt, span)
}
}
@@ -852,6 +770,7 @@ object NCSqlManager extends NCService with NCIgniteInstance
{
* @param errMsg
* @param resType
* @param resBody
+ * @param resMeta
* @param intentId
* @param tstamp
* @param parent Optional parent span.
@@ -862,9 +781,11 @@ object NCSqlManager extends NCService with
NCIgniteInstance {
errMsg: String,
resType: String,
resBody: String,
+ resMeta: JavaMeta,
intentId: String,
tstamp: Timestamp,
- parent: Span): Unit =
+ parent: Span
+ ): Unit =
startScopedSpan("updateReadyProcessingLog", parent, "srvReqId" →
srvReqId) { _ ⇒
NCSql.update(
"""
@@ -874,6 +795,7 @@ object NCSqlManager extends NCService with NCIgniteInstance
{
| error = ?,
| res_type = ?,
| res_body_gzip = ?,
+ | res_meta_gzip = ?,
| intent_id = ?,
| resp_tstamp = ?
|WHERE srv_req_id = ?
@@ -881,7 +803,8 @@ object NCSqlManager extends NCService with NCIgniteInstance
{
QRY_READY.toString,
errMsg,
resType,
- if (resBody == null) null else U.compress(resBody),
+ gzip(resBody),
+ gzip(resMeta),
intentId,
tstamp,
srvReqId
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/user/NCUserManager.scala
b/nlpcraft/src/main/scala/org/apache/nlpcraft/server/user/NCUserManager.scala
index 4471b31..7107085 100644
---
a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/user/NCUserManager.scala
+++
b/nlpcraft/src/main/scala/org/apache/nlpcraft/server/user/NCUserManager.scala
@@ -27,7 +27,7 @@ import org.apache.nlpcraft.common.config.NCConfigurable
import org.apache.nlpcraft.common.{NCService, _}
import org.apache.nlpcraft.server.ignite.NCIgniteHelpers._
import org.apache.nlpcraft.server.ignite.NCIgniteInstance
-import org.apache.nlpcraft.server.mdo.{NCUserMdo, NCUserPropertyMdo}
+import org.apache.nlpcraft.server.mdo.NCUserMdo
import org.apache.nlpcraft.server.sql.{NCSql, NCSqlManager}
import org.apache.nlpcraft.server.tx.NCTxManager
@@ -190,7 +190,7 @@ object NCUserManager extends NCService with
NCIgniteInstance {
* @param parent Optional parent span.
*/
@throws[NCE]
- def getAllUsers(compId: Long, parent: Span = null): Map[NCUserMdo,
Seq[NCUserPropertyMdo]] =
+ def getAllUsers(compId: Long, parent: Span = null): Seq[NCUserMdo] =
NCSql.sql {
NCSqlManager.getAllUsers(compId, parent)
}
@@ -313,20 +313,6 @@ object NCUserManager extends NCService with
NCIgniteInstance {
}
/**
- * Gets user properties for given user ID.
- *
- * @param id User ID.
- * @param parent Optional parent span.
- */
- @throws[NCE]
- def getUserProperties(id: Long, parent: Span = null):
Seq[NCUserPropertyMdo] =
- startScopedSpan("getUserProperties", parent, "usrId" → id) { span ⇒
- NCSql.sql {
- NCSqlManager.getUserProperties(id, span)
- }
- }
-
- /**
*
* @param email User email (as username).
* @param passwd User password.
@@ -391,7 +377,7 @@ object NCUserManager extends NCService with
NCIgniteInstance {
firstName: String,
lastName: String,
avatarUrl: Option[String],
- props: Option[Map[String, String]],
+ props: Option[String],
parent: Span = null
): Unit =
startScopedSpan("updateUser", parent, "usrId" → id) { span ⇒
@@ -488,7 +474,7 @@ object NCUserManager extends NCService with
NCIgniteInstance {
lastName: String,
avatarUrl: Option[String],
isAdmin: Boolean,
- props: Option[Map[String, String]],
+ props: Option[String],
usrExtIdOpt: Option[String],
parent: Span = null
): Long =
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/utils/README.md
b/nlpcraft/src/main/scala/org/apache/nlpcraft/utils/README.md
index 36ad1e9..69334bf 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/utils/README.md
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/utils/README.md
@@ -15,8 +15,6 @@
limitations under the License.
-->
-TODO: add here that we need it for tests (examples).
-
<img src="https://nlpcraft.apache.org/images/nlpcraft_logo_black.gif"
height="80px">
<br>
diff --git
a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/meta/NCMetaResultSpec.scala
b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/meta/NCMetaResultSpec.scala
new file mode 100644
index 0000000..8aec5cb
--- /dev/null
+++
b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/meta/NCMetaResultSpec.scala
@@ -0,0 +1,77 @@
+/*
+ * 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.meta
+
+import org.apache.nlpcraft.model.`abstract`.NCAbstractTokensModel
+import org.apache.nlpcraft.model.{NCElement, NCIntent, NCResult}
+import org.apache.nlpcraft.{NCTestElement, NCTestEnvironment}
+import org.junit.jupiter.api.Test
+
+import java.util
+
+/**
+ * Test model.
+ */
+object NCMetaResultSpecModel {
+ final val K1 = "k1"
+ final val K2 = "k2"
+ final val K3 = "k3"
+
+ final val V1 = "v1"
+ final val V2 = 2.2.asInstanceOf[AnyRef]
+ final val V3 = new util.HashMap[String, AnyRef]()
+
+ V3.put(K1, V1)
+ V3.put(K2, V2)
+}
+
+import org.apache.nlpcraft.model.meta.NCMetaResultSpecModel._
+
+class NCMetaResultSpecModel extends NCAbstractTokensModel {
+ override def getElements: util.Set[NCElement] = Set(NCTestElement("a"))
+
+ @NCIntent("intent=i term(t)={tok_id() == 'a'}")
+ def onIntent(): NCResult = {
+ val res = NCResult.text("OK")
+
+ res.getMetadata.put(K1, V1)
+ res.getMetadata.put(K2, V2)
+ res.getMetadata.put(K3, V3)
+
+ res
+ }
+}
+
+@NCTestEnvironment(model = classOf[NCMetaResultSpecModel], startClient = true)
+class NCMetaResultSpec extends NCMetaSpecAdapter {
+ @Test
+ def test(): Unit = {
+ val res = getClient.ask("a")
+
+ require(res.isOk)
+ require(res.getResultMeta.isPresent)
+
+ val meta = res.getResultMeta.get()
+
+ println(s"Meta received: $meta")
+
+ require(meta.get(K1) == V1)
+ require(meta.get(K2) == V2)
+ require(meta.get(K3) == V3)
+ }
+}
diff --git
a/nlpcraft/src/test/scala/org/apache/nlpcraft/server/rest/NCRestAskSpec.scala
b/nlpcraft/src/test/scala/org/apache/nlpcraft/server/rest/NCRestAskSpec.scala
index 56fc5ba..8013c0a 100644
---
a/nlpcraft/src/test/scala/org/apache/nlpcraft/server/rest/NCRestAskSpec.scala
+++
b/nlpcraft/src/test/scala/org/apache/nlpcraft/server/rest/NCRestAskSpec.scala
@@ -152,4 +152,20 @@ class NCRestAskSpec extends NCRestSpec {
post("cancel")()
}
+
+ @Test
+ def testSyncMeta(): Unit = {
+ post(
+ "ask/sync",
+ "txt" → "meta",
+ "mdlId" → "rest.test.model"
+ )(
+ ("$.state.status", (status: String) ⇒ assertEquals("QRY_READY",
status)),
+ ("$.state.resMeta", (meta: java.util.Map[String, Object]) ⇒ {
+ import RestTestModel._
+
+ assertEquals(Map(K1 → V1, K2 → V2, K3 → V3).asJava, meta)
+ })
+ )
+ }
}
diff --git
a/nlpcraft/src/test/scala/org/apache/nlpcraft/server/rest/NCRestSpec.scala
b/nlpcraft/src/test/scala/org/apache/nlpcraft/server/rest/NCRestSpec.scala
index 98bc498..098b582 100644
--- a/nlpcraft/src/test/scala/org/apache/nlpcraft/server/rest/NCRestSpec.scala
+++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/server/rest/NCRestSpec.scala
@@ -48,6 +48,9 @@ object NCRestSpec {
val code = resp.getStatusLine.getStatusCode
val js = mkJs(code, resp.getEntity)
+ if (js == null)
+ throw new RuntimeException(s"Unexpected response [code=$code,
response=$js]")
+
code match {
case 200 ⇒ GSON.fromJson(js, TYPE_RESP)
diff --git
a/nlpcraft/src/test/scala/org/apache/nlpcraft/server/rest/RestTestModel.scala
b/nlpcraft/src/test/scala/org/apache/nlpcraft/server/rest/RestTestModel.scala
index 115caa5..621be18 100644
---
a/nlpcraft/src/test/scala/org/apache/nlpcraft/server/rest/RestTestModel.scala
+++
b/nlpcraft/src/test/scala/org/apache/nlpcraft/server/rest/RestTestModel.scala
@@ -18,11 +18,29 @@
package org.apache.nlpcraft.server.rest
import org.apache.nlpcraft.NCTestElement
-import org.apache.nlpcraft.model.{NCElement, NCIntent, NCIntentMatch,
NCIntentRef, NCIntentSample, NCModelAdapter, NCResult}
+import org.apache.nlpcraft.model.{NCElement, NCIntent, NCIntentSample,
NCModelAdapter, NCResult}
import java.util
/**
+ * REST test model helper.
+ */
+object RestTestModel {
+ final val K1 = "k1"
+ final val K2 = "k2"
+ final val K3 = "k3"
+
+ final val V1 = "v1"
+ final val V2 = 2.2.asInstanceOf[AnyRef]
+ final val V3 = new util.HashMap[String, AnyRef]()
+
+ V3.put(K1, V1)
+ V3.put(K2, V2)
+}
+
+import RestTestModel._
+
+/**
* REST test model.
*/
class RestTestModel extends NCModelAdapter("rest.test.model", "REST test
model", "1.0.0") {
@@ -30,14 +48,27 @@ class RestTestModel extends
NCModelAdapter("rest.test.model", "REST test model",
Set(
NCTestElement("a"),
NCTestElement("b"),
- NCTestElement("x", "cat")
+ NCTestElement("x", "cat"),
+ NCTestElement("meta")
)
@NCIntent("intent=onA term(t)={tok_id() == 'a'}")
@NCIntentSample(Array("My A"))
- private def a(ctx: NCIntentMatch): NCResult = NCResult.text("OK")
+ private def a(): NCResult = NCResult.text("OK")
@NCIntent("intent=onB term(t)={tok_id() == 'b'}")
@NCIntentSample(Array("My B"))
- private def b(ctx: NCIntentMatch): NCResult = NCResult.text("OK")
+ private def b(): NCResult = NCResult.text("OK")
+
+ @NCIntent("intent=onMeta term(t)={tok_id() == 'meta'}")
+ @NCIntentSample(Array("meta"))
+ private def meta(): NCResult = {
+ val res = NCResult.text("OK")
+
+ res.getMetadata.put(K1, V1)
+ res.getMetadata.put(K2, V2)
+ res.getMetadata.put(K3, V3)
+
+ res
+ }
}
diff --git a/openapi/nlpcraft_swagger.yml b/openapi/nlpcraft_swagger.yml
index f8b0114..8b239c3 100644
--- a/openapi/nlpcraft_swagger.yml
+++ b/openapi/nlpcraft_swagger.yml
@@ -352,6 +352,11 @@ paths:
Optional body (string or JSON object) of the result if
returned by model
(provided only if status is <code>QRY_READY</code> and
processing was
not rejected or terminated due to an exception).
+ resMeta:
+ type: object
+ description: >-
+ Optional result metadata as JSON object (provided only
if status is
+ <code>QRY_READY</code> and processing was not rejected
or terminated due to an exception).
error:
type: string
description: >-
@@ -650,6 +655,10 @@ paths:
Optional body (string or JSON object) of the result if
returned by model
(provided only if status is <code>QRY_READY</code> and
processing was
not rejected or terminated due to an exception).
+ resMeta:
+ type: object
+ description: >-
+ Optional meta JSON object. TODO:
error:
type: string
description: >-
@@ -871,7 +880,7 @@ paths:
maxLength: 512000
properties:
type: object
- description: <em>Optional.</em> Additional user properties.
+ description: <em>Optional.</em> Additional user properties
with maximum JSON length of 512000 bytes.
additionalProperties:
type: string
responses:
@@ -1064,7 +1073,7 @@ paths:
description: Admin flag.
properties:
type: object
- description: <em>Optional.</em> Additional user properties.
+ description: <em>Optional.</em> Additional user properties
with maximum JSON length of 512000 bytes.
additionalProperties:
type: string
usrExtId:
@@ -1240,7 +1249,7 @@ paths:
maxLength: 512000
properties:
type: object
- description: <em>Optional.</em> Additional company properties.
+ description: <em>Optional.</em> Additional company properties
with maximum JSON length of 512000 bytes.
additionalProperties:
type: string
responses:
@@ -1323,7 +1332,7 @@ paths:
maxLength: 512
properties:
type: object
- description: <em>Optional.</em> Additional company properties.
+ description: <em>Optional.</em> Additional company properties
with maximum JSON length of 512000 bytes.
additionalProperties:
type: string
responses:
diff --git a/sql/mysql/drop_schema.sql b/sql/mysql/drop_schema.sql
index fba01aa..e1ead27 100644
--- a/sql/mysql/drop_schema.sql
+++ b/sql/mysql/drop_schema.sql
@@ -18,9 +18,7 @@
USE nlpcraft;
DROP TABLE IF EXISTS proc_log;
-DROP TABLE IF EXISTS nc_user_property;
DROP TABLE IF EXISTS nc_user;
-DROP TABLE IF EXISTS nc_company_property;
DROP TABLE IF EXISTS nc_company;
DROP TABLE IF EXISTS passwd_pool;
DROP TABLE IF EXISTS feedback;
diff --git a/sql/mysql/schema.sql b/sql/mysql/schema.sql
index cac0bf8..9022ab6 100644
--- a/sql/mysql/schema.sql
+++ b/sql/mysql/schema.sql
@@ -39,6 +39,7 @@ CREATE TABLE nc_company (
postal_code VARCHAR(32),
auth_token VARCHAR(64) NOT NULL,
auth_token_hash VARCHAR(64) NOT NULL,
+ properties_gzip TEXT NULL,
created_on TIMESTAMP(3) NOT NULL DEFAULT current_timestamp(3),
last_modified_on TIMESTAMP(3) NOT NULL DEFAULT current_timestamp(3)
);
@@ -48,19 +49,6 @@ CREATE UNIQUE INDEX nc_company_idx_2 ON
nc_company(auth_token);
CREATE UNIQUE INDEX nc_company_idx_3 ON nc_company(auth_token_hash);
--
--- Company properties table.
---
-CREATE TABLE nc_company_property (
- id SERIAL PRIMARY KEY,
- company_id BIGINT UNSIGNED NOT NULL,
- property VARCHAR(64) NOT NULL,
- value VARCHAR(512) NULL,
- created_on TIMESTAMP(3) NOT NULL DEFAULT current_timestamp(3),
- last_modified_on TIMESTAMP(3) NOT NULL DEFAULT current_timestamp(3),
- FOREIGN KEY (company_id) REFERENCES nc_company(id)
-);
-
---
-- User table.
--
CREATE TABLE nc_user (
@@ -73,6 +61,7 @@ CREATE TABLE nc_user (
last_name VARCHAR(64) NULL,
is_admin BOOLEAN NOT NULL, -- Whether or not created with admin token.
passwd_salt VARCHAR(64) NULL,
+ properties_gzip TEXT NULL,
created_on TIMESTAMP(3) NOT NULL DEFAULT current_timestamp(3),
last_modified_on TIMESTAMP(3) NOT NULL DEFAULT current_timestamp(3),
FOREIGN KEY (company_id) REFERENCES nc_company(id)
@@ -82,19 +71,6 @@ CREATE UNIQUE INDEX nc_user_idx_1 ON nc_user(email);
CREATE UNIQUE INDEX nc_user_idx_2 ON nc_user(company_id, ext_id);
--
--- User properties table.
---
-CREATE TABLE nc_user_property (
- id SERIAL PRIMARY KEY,
- user_id BIGINT UNSIGNED NOT NULL,
- property VARCHAR(64) NOT NULL,
- value VARCHAR(512) NULL,
- created_on TIMESTAMP(3) NOT NULL DEFAULT current_timestamp(3),
- last_modified_on TIMESTAMP(3) NOT NULL DEFAULT current_timestamp(3),
- FOREIGN KEY (user_id) REFERENCES nc_user(id)
-);
-
---
-- Pool of password hashes.
--
CREATE TABLE passwd_pool (
@@ -122,6 +98,7 @@ CREATE TABLE proc_log (
-- Result parts.
res_type VARCHAR(32) NULL,
res_body_gzip TEXT NULL, -- GZIP-ed result body.
+ res_body_meta TEXT NULL, -- GZIP-ed result meta.
intent_id VARCHAR(256) NULL,
error TEXT NULL,
-- Probe information for this request.
diff --git a/sql/oracle/drop_schema.sql b/sql/oracle/drop_schema.sql
index 652bdb8..78bd027 100644
--- a/sql/oracle/drop_schema.sql
+++ b/sql/oracle/drop_schema.sql
@@ -24,14 +24,6 @@ EXCEPTION WHEN OTHERS THEN
END;
BEGIN
- EXECUTE IMMEDIATE 'DROP TABLE nc_user_property';
-EXCEPTION WHEN OTHERS THEN
- IF SQLCODE != -942 THEN
- RAISE;
- END IF;
-END;
-
-BEGIN
EXECUTE IMMEDIATE 'DROP TABLE nc_user';
EXCEPTION WHEN OTHERS THEN
IF SQLCODE != -942 THEN
@@ -40,14 +32,6 @@ EXCEPTION WHEN OTHERS THEN
END;
BEGIN
- EXECUTE IMMEDIATE 'DROP TABLE nc_company_property';
-EXCEPTION WHEN OTHERS THEN
- IF SQLCODE != -942 THEN
- RAISE;
-END IF;
-END;
-
-BEGIN
EXECUTE IMMEDIATE 'DROP TABLE nc_company';
EXCEPTION WHEN OTHERS THEN
IF SQLCODE != -942 THEN
diff --git a/sql/oracle/schema.sql b/sql/oracle/schema.sql
index 1ad495c..da243b9 100644
--- a/sql/oracle/schema.sql
+++ b/sql/oracle/schema.sql
@@ -37,6 +37,7 @@ CREATE TABLE nc_company (
postal_code VARCHAR2(32),
auth_token VARCHAR2(64) NOT NULL,
auth_token_hash VARCHAR2(64) NOT NULL,
+ properties_gzip CLOB NULL,
created_on DATE DEFAULT sysdate NOT NULL,
last_modified_on DATE DEFAULT sysdate NOT NULL
);
@@ -46,21 +47,6 @@ CREATE UNIQUE INDEX nc_company_idx_2 ON
nc_company(auth_token);
CREATE UNIQUE INDEX nc_company_idx_3 ON nc_company(auth_token_hash);
--
--- Company properties table.
---
-CREATE TABLE nc_company_property (
- id NUMBER PRIMARY KEY,
- company_id NUMBER NOT NULL,
- property VARCHAR2(64) NOT NULL,
- value VARCHAR2(512) NULL,
- created_on DATE DEFAULT sysdate NOT NULL,
- last_modified_on DATE DEFAULT sysdate NOT NULL,
- CONSTRAINT fk_company_id_company_property FOREIGN KEY (company_id)
REFERENCES nc_company(id)
-);
-
-CREATE INDEX nc_company_property_idx1 ON nc_company_property(company_id);
-
---
-- User table.
--
CREATE TABLE nc_user (
@@ -73,6 +59,7 @@ CREATE TABLE nc_user (
last_name VARCHAR2(64) NULL,
is_admin NUMBER(1) NOT NULL, -- Whether or not created with admin token.
passwd_salt VARCHAR2(64) NULL,
+ properties_gzip CLOB NULL,
created_on DATE DEFAULT sysdate NOT NULL,
last_modified_on DATE DEFAULT sysdate NOT NULL,
CONSTRAINT fk_company_id_user FOREIGN KEY (company_id) REFERENCES
nc_company(id)
@@ -83,21 +70,6 @@ CREATE UNIQUE INDEX nc_user_idx_2 ON nc_user(company_id,
ext_id);
CREATE INDEX nc_user_idx_3 ON nc_user(company_id);
--
--- User properties table.
---
-CREATE TABLE nc_user_property (
- id NUMBER PRIMARY KEY,
- user_id NUMBER NOT NULL,
- property VARCHAR2(64) NOT NULL,
- value VARCHAR2(512) NULL,
- created_on DATE DEFAULT sysdate NOT NULL,
- last_modified_on DATE DEFAULT sysdate NOT NULL,
- CONSTRAINT fk_user_id_user_property FOREIGN KEY (user_id) REFERENCES
nc_user(id)
-);
-
-CREATE INDEX nc_user_property_idx1 ON nc_user_property(user_id);
-
---
-- Pool of password hashes.
--
CREATE TABLE passwd_pool (
@@ -125,6 +97,7 @@ CREATE TABLE proc_log (
-- Result parts.
res_type VARCHAR2(32) NULL,
res_body_gzip CLOB NULL, -- GZIP-ed result body.
+ res_body_meta CLOB NULL, -- GZIP-ed result meta.
intent_id VARCHAR2(256) NULL,
error CLOB NULL,
-- Probe information for this request.
diff --git a/sql/postgres/drop_schema.sql b/sql/postgres/drop_schema.sql
index b1ce0b9..f985bae 100644
--- a/sql/postgres/drop_schema.sql
+++ b/sql/postgres/drop_schema.sql
@@ -16,9 +16,7 @@
--
DROP TABLE IF EXISTS proc_log;
-DROP TABLE IF EXISTS nc_user_property;
DROP TABLE IF EXISTS nc_user;
-DROP TABLE IF EXISTS nc_company_property;
DROP TABLE IF EXISTS nc_company;
DROP TABLE IF EXISTS passwd_pool;
DROP TABLE IF EXISTS feedback;
\ No newline at end of file
diff --git a/sql/postgres/schema.sql b/sql/postgres/schema.sql
index 561418e..8329ed7 100644
--- a/sql/postgres/schema.sql
+++ b/sql/postgres/schema.sql
@@ -37,6 +37,7 @@ CREATE TABLE nc_company (
postal_code VARCHAR(32),
auth_token VARCHAR(64) NOT NULL,
auth_token_hash VARCHAR(64) NOT NULL,
+ properties_gzip TEXT NULL,
created_on TIMESTAMP(3) NOT NULL DEFAULT current_timestamp(3),
last_modified_on TIMESTAMP(3) NOT NULL DEFAULT current_timestamp(3)
);
@@ -46,21 +47,6 @@ CREATE UNIQUE INDEX nc_company_idx_2 ON
nc_company(auth_token);
CREATE UNIQUE INDEX nc_company_idx_3 ON nc_company(auth_token_hash);
--
--- Company properties table.
---
-CREATE TABLE nc_company_property (
- id SERIAL PRIMARY KEY,
- company_id BIGINT NOT NULL,
- property VARCHAR(64) NOT NULL,
- value VARCHAR(512) NULL,
- created_on TIMESTAMP(3) NOT NULL DEFAULT current_timestamp(3),
- last_modified_on TIMESTAMP(3) NOT NULL DEFAULT current_timestamp(3),
- FOREIGN KEY (company_id) REFERENCES nc_company(id)
-);
-
-CREATE INDEX nc_company_property_idx1 ON nc_company_property(company_id);
-
---
--
-- User table.
--
@@ -74,6 +60,7 @@ CREATE TABLE nc_user (
last_name VARCHAR(64) NULL,
is_admin BOOL NOT NULL, -- Whether or not created with admin token.
passwd_salt VARCHAR(64) NULL,
+ properties_gzip TEXT NULL,
created_on TIMESTAMP(3) NOT NULL DEFAULT current_timestamp(3),
last_modified_on TIMESTAMP(3) NOT NULL DEFAULT current_timestamp(3),
FOREIGN KEY (company_id) REFERENCES nc_company(id)
@@ -92,21 +79,6 @@ CREATE TABLE passwd_pool (
);
--
--- User properties table.
---
-CREATE TABLE nc_user_property (
- id SERIAL PRIMARY KEY,
- user_id BIGINT NOT NULL,
- property VARCHAR(64) NOT NULL,
- value VARCHAR(512) NULL,
- created_on TIMESTAMP(3) NOT NULL DEFAULT current_timestamp(3),
- last_modified_on TIMESTAMP(3) NOT NULL DEFAULT current_timestamp(3),
- FOREIGN KEY (user_id) REFERENCES nc_user(id)
-);
-
-CREATE INDEX nc_user_property_idx1 ON nc_user_property(user_id);
-
---
-- Processing log.
--
CREATE TABLE proc_log (
@@ -126,6 +98,7 @@ CREATE TABLE proc_log (
-- Result parts.
res_type VARCHAR(32) NULL,
res_body_gzip TEXT NULL, -- GZIP-ed result body.
+ res_body_meta TEXT NULL, -- GZIP-ed result body.
intent_id VARCHAR(256) NULL,
error TEXT NULL,
-- Probe information for this request.